Changeset 260753 in webkit


Ignore:
Timestamp:
Apr 27, 2020 8:05:00 AM (4 years ago)
Author:
Darin Adler
Message:

Replace more uses of live ranges with SimpleRange
https://bugs.webkit.org/show_bug.cgi?id=211058

Reviewed by Antti Koivisto.

Source/WebCore:

  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::textUnderElement const): Use SimpleRange.

  • dom/BoundaryPoint.h: Moved makeBoundaryPointAfterNodeContents here so it

can be used more places.

  • dom/Node.cpp:

(WebCore::commonInclusiveAncestor): Moved the commonAncestorContainer function
here from Range, decided to use the "inclusive ancestor" naming from the
DOM specification, and used RefPtr for the result since it's part of our modern
safer design to always use smart pointers for return values.

  • dom/Node.h: Added commonInclusiveAncestor.
  • dom/Position.cpp:

(WebCore::commonShadowIncludingAncestor): Call commonInclusiveAncestor.

  • dom/Range.cpp:

(WebCore::Range::commonAncestorContainer): Deleted.
(WebCore::Range::isPointInRange): Call commonInclusiveAncestor.
(WebCore::Range::comparePoint const): Ditto.
(WebCore::Range::compareBoundaryPoints): Ditto.
(WebCore::Range::collectSelectionRectsWithoutUnionInteriorLines const): Ditto.

  • dom/Range.h:

(WebCore::Range::commonAncestorContainer const): Call commonInclusiveAncestor.

  • dom/SimpleRange.cpp:

(WebCore::makeBoundaryPointAfterNodeContents): Moved to BoundaryPoint.h.

  • editing/AlternativeTextController.cpp:

(WebCore::AlternativeTextController::respondToUnappliedSpellCorrection): Use
SimpleRange instead of live range.
(WebCore::AlternativeTextController::respondToUnappliedEditing): Ditto.
(WebCore::AlternativeTextController::markPrecedingWhitespaceForDeletedAutocorrectionAfterCommand): Ditto.
(WebCore::AlternativeTextController::processMarkersOnTextToBeReplacedByResult): Ditto.

  • editing/ChangeListTypeCommand.cpp:

(WebCore::listConversionTypeForSelection): use commonInclusiveAncestor.

  • editing/Editing.cpp:

(WebCore::isNodeVisiblyContainedWithin): Take a SimpleRange argument.

  • editing/Editing.h: Updated for the above.
  • editing/Editor.cpp:

(WebCore::Editor::addRangeToKillRing): Take a SimpleRange argument.
(WebCore::Editor::shouldDetectTelephoneNumbers const): Made this const and
tweaked coding style a bit.
(WebCore::scanForTelephoneNumbers): Moved this, made it a non-member function,
renamed from scanRangeForTelephoneNumbers, use SimpleRange.
(WebCore::extendSelection): Added. Factored out some logic from the function below.
(WebCore::Editor::scanSelectionForTelephoneNumbers): Use SimpleRange. Removed
some unnecessary code that subtracts 1 and then adds 1 again.

  • editing/Editor.h: Updated for the above.
  • editing/TextManipulationController.cpp:

(WebCore::TextManipulationController::replace): Use commonInclusiveAncestor.

  • editing/VisibleSelection.cpp:

(WebCore::makeSearchRange): Return a SimpleRange.
(WebCore::VisibleSelection::appendTrailingWhitespace): Use SimpleRange.

  • editing/WebContentReader.h: Use SimpleRange instead of a live range.
  • editing/cocoa/DataDetection.h: Use a struct, DetectedItem, for the return value

from the detection functions. Also changed DataDetectorTypes to an enum class so
it can be forward-declared instead of having to include this header.

  • editing/cocoa/DataDetection.mm:

(WebCore::detectItem): Renamed from detectItemAtPositionWithRange. Return the
DetectedItem struct, with a SimpleRange rather than an out argument live range.
(WebCore::DataDetection::detectItemAroundHitTestResult): Ditto.
(WebCore::contains): Added a helper function for testing bits in the
DataDetectorType enum. Later we can make this better using OptionSet.
(WebCore::constructURLStringForResult): Refactored a bit, updated for the new
DataDetectorTypes enum class, and to use CFEqual instead of CFStringCompare.
(WebCore::DataDetection::detectContentInRange): Ditto.

  • editing/cocoa/EditorCocoa.mm:

(WebCore::Editor::webContentFromPasteboard): Use SimpleRange.

  • editing/cocoa/WebContentReaderCocoa.mm:

(WebCore::WebContentReader::readPlainText): Updated since context is SimpleRange.

  • editing/gtk/EditorGtk.cpp:

(WebCore::createFragmentFromPasteboardData): Use SimpleRange.
(WebCore::Editor::webContentFromPasteboard): Use SimpleRange.

  • editing/win/EditorWin.cpp:

(WebCore::Editor::webContentFromPasteboard): Use SimpleRange.

  • editing/mac/EditorMac.mm:

(WebCore::Editor::replaceNodeFromPasteboard): Use SimpleRange.

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::checkLoadCompleteForThisFrame): Use SimpleRange.

  • page/EventHandler.cpp:

(WebCore::targetNodeForClickEvent): Use commonInclusiveAncestor. Also updated
to return a RefPtr.
(WebCore::EventHandler::handleMouseReleaseEvent): Updated for the above.

  • page/Settings.yaml: Changed the default for DataDetectorTypes to be the empty

string rather than a named constant.

  • page/SettingsBase.h: Forward-declare DataDetectorTypes instead of including

the DataDetection.h header.

  • page/TextIndicator.cpp:

(WebCore::TextIndicator::createWithRange): Take a SimpleRange.
(WebCore::TextIndicator::createWithSelectionInFrame): Ditto.
(WebCore::hasNonInlineOrReplacedElements): Ditto.
(WebCore::selectionRects): Ditto. Also renamed from getSelectionRectsForRange.
(WebCore::styleContainsComplexBackground): Tweaked implementation.
(WebCore::estimatedTextColorsForRange): Take a SimpleRange.
(WebCore::absoluteBoundingRectForRange): Ditto.
(WebCore::estimatedBackgroundColorForRange): Ditto.
(WebCore::containsOnlyWhiteSpaceText): Ditto.
(WebCore::initializeIndicator): Ditto.

  • page/TextIndicator.h: Updated for the above.
  • page/mac/ServicesOverlayController.h: Use SimpleRange instead of a live

range for highlights.

  • page/mac/ServicesOverlayController.mm:

(WebCore::ServicesOverlayController::Highlight::createForSelection): Take SimpleRange.
(WebCore::ServicesOverlayController::Highlight::createForTelephoneNumber): Ditto.
(WebCore::ServicesOverlayController::Highlight::Highlight): Ditto.
(WebCore::ServicesOverlayController::buildPhoneNumberHighlights): Ditto.
(WebCore::ServicesOverlayController::buildSelectionHighlight): Ditto.
(WebCore::ServicesOverlayController::telephoneNumberRangesForFocusedFrame): Ditto.
(WebCore::ServicesOverlayController::highlightsAreEquivalent): Ditto.
(WebCore::ServicesOverlayController::findTelephoneNumberHighlightContainingSelectionHighlight): Ditto.
(WebCore::ServicesOverlayController::handleClick): Ditto.

  • platform/ios/DragImageIOS.mm:

(WebCore::createDragImageForLink): Use SimpleRange.
(WebCore::createDragImageForSelection): Tweaked a bit.

Source/WebKit:

  • Shared/API/Cocoa/WKDataDetectorTypesInternal.h:

(fromWKDataDetectorTypes): Updated since DataDetectorTypes
is now an enum class. Also got rid of special "none" and "all" values.

  • WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInRangeHandle.mm:

(-[WKWebProcessPlugInRangeHandle detectDataWithTypes:context:]): Updated
since DataDetection now takes a SimpleRange.

  • WebProcess/WebPage/ViewGestureGeometryCollector.cpp:

(WebKit::ViewGestureGeometryCollector::computeTextLegibilityScales):
Use SimpleRange.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::detectDataInAllFrames): Ditto.

  • WebProcess/WebPage/WebPage.h: Removed unneeded include of DataDetection.h.
  • WebProcess/WebPage/mac/WebPageMac.mm:

(WebKit::WebPage::performImmediateActionHitTestAtLocation): Use SimpleRange.

Source/WebKitLegacy/mac:

  • DOM/DOM.mm:

(-[DOMNode getPreviewSnapshotImage:andRects:]): Use SimpleRange.

  • WebCoreSupport/WebContextMenuClient.mm:

(WebContextMenuClient::imageForCurrentSharingServicePickerItem): Ditto.

  • WebView/WebImmediateActionController.mm:

(-[WebImmediateActionController _animationControllerForDataDetectedText]):
Updated to use DetectedItem and SimpleRange.
(+[WebImmediateActionController _dictionaryPopupInfoForRange:inFrame:withLookupOptions:indicatorOptions:transition:]):
Ditto.

Location:
trunk/Source
Files:
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r260752 r260753  
     12020-04-26  Darin Adler  <darin@apple.com>
     2
     3        Replace more uses of live ranges with SimpleRange
     4        https://bugs.webkit.org/show_bug.cgi?id=211058
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * accessibility/AccessibilityRenderObject.cpp:
     9        (WebCore::AccessibilityRenderObject::textUnderElement const): Use SimpleRange.
     10
     11        * dom/BoundaryPoint.h: Moved makeBoundaryPointAfterNodeContents here so it
     12        can be used more places.
     13
     14        * dom/Node.cpp:
     15        (WebCore::commonInclusiveAncestor): Moved the commonAncestorContainer function
     16        here from Range, decided to use the "inclusive ancestor" naming from the
     17        DOM specification, and used RefPtr for the result since it's part of our modern
     18        safer design to always use smart pointers for return values.
     19        * dom/Node.h: Added commonInclusiveAncestor.
     20
     21        * dom/Position.cpp:
     22        (WebCore::commonShadowIncludingAncestor): Call commonInclusiveAncestor.
     23
     24        * dom/Range.cpp:
     25        (WebCore::Range::commonAncestorContainer): Deleted.
     26        (WebCore::Range::isPointInRange): Call commonInclusiveAncestor.
     27        (WebCore::Range::comparePoint const): Ditto.
     28        (WebCore::Range::compareBoundaryPoints): Ditto.
     29        (WebCore::Range::collectSelectionRectsWithoutUnionInteriorLines const): Ditto.
     30        * dom/Range.h:
     31        (WebCore::Range::commonAncestorContainer const): Call commonInclusiveAncestor.
     32
     33        * dom/SimpleRange.cpp:
     34        (WebCore::makeBoundaryPointAfterNodeContents): Moved to BoundaryPoint.h.
     35
     36        * editing/AlternativeTextController.cpp:
     37        (WebCore::AlternativeTextController::respondToUnappliedSpellCorrection): Use
     38        SimpleRange instead of live range.
     39        (WebCore::AlternativeTextController::respondToUnappliedEditing): Ditto.
     40        (WebCore::AlternativeTextController::markPrecedingWhitespaceForDeletedAutocorrectionAfterCommand): Ditto.
     41        (WebCore::AlternativeTextController::processMarkersOnTextToBeReplacedByResult): Ditto.
     42
     43        * editing/ChangeListTypeCommand.cpp:
     44        (WebCore::listConversionTypeForSelection): use commonInclusiveAncestor.
     45
     46        * editing/Editing.cpp:
     47        (WebCore::isNodeVisiblyContainedWithin): Take a SimpleRange argument.
     48        * editing/Editing.h: Updated for the above.
     49
     50        * editing/Editor.cpp:
     51        (WebCore::Editor::addRangeToKillRing): Take a SimpleRange argument.
     52        (WebCore::Editor::shouldDetectTelephoneNumbers const): Made this const and
     53        tweaked coding style a bit.
     54        (WebCore::scanForTelephoneNumbers): Moved this, made it a non-member function,
     55        renamed from scanRangeForTelephoneNumbers, use SimpleRange.
     56        (WebCore::extendSelection): Added. Factored out some logic from the function below.
     57        (WebCore::Editor::scanSelectionForTelephoneNumbers): Use SimpleRange. Removed
     58        some unnecessary code that subtracts 1 and then adds 1 again.
     59        * editing/Editor.h: Updated for the above.
     60
     61        * editing/TextManipulationController.cpp:
     62        (WebCore::TextManipulationController::replace): Use commonInclusiveAncestor.
     63
     64        * editing/VisibleSelection.cpp:
     65        (WebCore::makeSearchRange): Return a SimpleRange.
     66        (WebCore::VisibleSelection::appendTrailingWhitespace): Use SimpleRange.
     67
     68        * editing/WebContentReader.h: Use SimpleRange instead of a live range.
     69
     70        * editing/cocoa/DataDetection.h: Use a struct, DetectedItem, for the return value
     71        from the detection functions. Also changed DataDetectorTypes to an enum class so
     72        it can be forward-declared instead of having to include this header.
     73        * editing/cocoa/DataDetection.mm:
     74        (WebCore::detectItem): Renamed from detectItemAtPositionWithRange. Return the
     75        DetectedItem struct, with a SimpleRange rather than an out argument live range.
     76        (WebCore::DataDetection::detectItemAroundHitTestResult): Ditto.
     77        (WebCore::contains): Added a helper function for testing bits in the
     78        DataDetectorType enum. Later we can make this better using OptionSet.
     79        (WebCore::constructURLStringForResult): Refactored a bit, updated for the new
     80        DataDetectorTypes enum class, and to use CFEqual instead of CFStringCompare.
     81        (WebCore::DataDetection::detectContentInRange): Ditto.
     82
     83        * editing/cocoa/EditorCocoa.mm:
     84        (WebCore::Editor::webContentFromPasteboard): Use SimpleRange.
     85        * editing/cocoa/WebContentReaderCocoa.mm:
     86        (WebCore::WebContentReader::readPlainText): Updated since context is SimpleRange.
     87        * editing/gtk/EditorGtk.cpp:
     88        (WebCore::createFragmentFromPasteboardData): Use SimpleRange.
     89        (WebCore::Editor::webContentFromPasteboard): Use SimpleRange.
     90        * editing/win/EditorWin.cpp:
     91        (WebCore::Editor::webContentFromPasteboard): Use SimpleRange.
     92        * editing/mac/EditorMac.mm:
     93        (WebCore::Editor::replaceNodeFromPasteboard): Use SimpleRange.
     94        * loader/FrameLoader.cpp:
     95        (WebCore::FrameLoader::checkLoadCompleteForThisFrame): Use SimpleRange.
     96        * page/EventHandler.cpp:
     97        (WebCore::targetNodeForClickEvent): Use commonInclusiveAncestor. Also updated
     98        to return a RefPtr.
     99        (WebCore::EventHandler::handleMouseReleaseEvent): Updated for the above.
     100
     101        * page/Settings.yaml: Changed the default for DataDetectorTypes to be the empty
     102        string rather than a named constant.
     103        * page/SettingsBase.h: Forward-declare DataDetectorTypes instead of including
     104        the DataDetection.h header.
     105
     106        * page/TextIndicator.cpp:
     107        (WebCore::TextIndicator::createWithRange): Take a SimpleRange.
     108        (WebCore::TextIndicator::createWithSelectionInFrame): Ditto.
     109        (WebCore::hasNonInlineOrReplacedElements): Ditto.
     110        (WebCore::selectionRects): Ditto. Also renamed from getSelectionRectsForRange.
     111        (WebCore::styleContainsComplexBackground): Tweaked implementation.
     112        (WebCore::estimatedTextColorsForRange): Take a SimpleRange.
     113        (WebCore::absoluteBoundingRectForRange): Ditto.
     114        (WebCore::estimatedBackgroundColorForRange): Ditto.
     115        (WebCore::containsOnlyWhiteSpaceText): Ditto.
     116        (WebCore::initializeIndicator): Ditto.
     117        * page/TextIndicator.h: Updated for the above.
     118
     119        * page/mac/ServicesOverlayController.h: Use SimpleRange instead of a live
     120        range for highlights.
     121        * page/mac/ServicesOverlayController.mm:
     122        (WebCore::ServicesOverlayController::Highlight::createForSelection): Take SimpleRange.
     123        (WebCore::ServicesOverlayController::Highlight::createForTelephoneNumber): Ditto.
     124        (WebCore::ServicesOverlayController::Highlight::Highlight): Ditto.
     125        (WebCore::ServicesOverlayController::buildPhoneNumberHighlights): Ditto.
     126        (WebCore::ServicesOverlayController::buildSelectionHighlight): Ditto.
     127        (WebCore::ServicesOverlayController::telephoneNumberRangesForFocusedFrame): Ditto.
     128        (WebCore::ServicesOverlayController::highlightsAreEquivalent): Ditto.
     129        (WebCore::ServicesOverlayController::findTelephoneNumberHighlightContainingSelectionHighlight): Ditto.
     130        (WebCore::ServicesOverlayController::handleClick): Ditto.
     131
     132        * platform/ios/DragImageIOS.mm:
     133        (WebCore::createDragImageForLink): Use SimpleRange.
     134        (WebCore::createDragImageForSelection): Tweaked a bit.
     135
    11362020-04-27  Carlos Garcia Campos  <cgarcia@igalia.com>
    2137
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r260725 r260753  
    634634        // is handled consistently.
    635635        Document* nodeDocument = nullptr;
    636         RefPtr<Range> textRange;
     636        Optional<SimpleRange> textRange;
    637637        if (Node* node = m_renderer->node()) {
    638638            nodeDocument = &node->document();
    639             textRange = rangeOfContents(*node);
     639            textRange = makeRangeSelectingNodeContents(*node);
    640640        } else {
    641641            // For anonymous blocks, we work around not having a direct node to create a range from
     
    651651
    652652                nodeDocument = &firstNodeInBlock->document();
    653                 textRange = Range::create(*nodeDocument, startPosition, endPosition);
     653                textRange = { { *makeBoundaryPoint(startPosition), *makeBoundaryPoint(endPosition) } };
    654654            }
    655655        }
  • trunk/Source/WebCore/dom/BoundaryPoint.h

    r259401 r260753  
    4848
    4949BoundaryPoint makeBoundaryPointBeforeNodeContents(Node&);
     50BoundaryPoint makeBoundaryPointAfterNodeContents(Node&);
    5051
    5152inline BoundaryPoint::BoundaryPoint(Ref<Node>&& container, unsigned offset)
     
    8384}
    8485
     86inline BoundaryPoint makeBoundaryPointAfterNodeContents(Node& node)
     87{
     88    return { node, node.length() };
    8589}
     90
     91}
  • trunk/Source/WebCore/dom/Node.cpp

    r259933 r260753  
    26132613}
    26142614
     2615RefPtr<Node> commonInclusiveAncestor(Node& a, Node& b)
     2616{
     2617    for (auto ancestorA = &a; ancestorA; ancestorA = ancestorA->parentNode()) {
     2618        for (auto ancestorB = &b; ancestorB; ancestorB = ancestorB->parentNode()) {
     2619            if (ancestorA == ancestorB)
     2620                return ancestorA;
     2621        }
     2622    }
     2623    return nullptr;
     2624}
     2625
    26152626TextStream& operator<<(TextStream& ts, const Node& node)
    26162627{
  • trunk/Source/WebCore/dom/Node.h

    r259933 r260753  
    671671};
    672672
     673WEBCORE_EXPORT RefPtr<Node> commonInclusiveAncestor(Node&, Node&);
     674
    673675#if ASSERT_ENABLED
    674676
  • trunk/Source/WebCore/dom/Position.cpp

    r259930 r260753  
    15711571    auto* nodeB = commonScope->ancestorNodeInThisScope(b.containerNode());
    15721572    ASSERT(nodeB);
    1573     return Range::commonAncestorContainer(nodeA, nodeB);
     1573    return commonInclusiveAncestor(*nodeA, *nodeB);
    15741574}
    15751575
  • trunk/Source/WebCore/dom/Range.cpp

    r259933 r260753  
    144144}
    145145
    146 Node* Range::commonAncestorContainer(Node* containerA, Node* containerB)
    147 {
    148     for (Node* parentA = containerA; parentA; parentA = parentA->parentNode()) {
    149         for (Node* parentB = containerB; parentB; parentB = parentB->parentNode()) {
    150             if (parentA == parentB)
    151                 return parentA;
    152         }
    153     }
    154     return nullptr;
    155 }
    156 
    157146static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& start, const RangeBoundaryPoint& end)
    158147{
     
    240229        // DOM4 spec requires us to check whether refNode and start container have the same root first
    241230        // but we do it in the reverse order to avoid O(n) operation here in common case.
    242         if (!commonAncestorContainer(&refNode, &startContainer()))
     231        if (!commonInclusiveAncestor(refNode, startContainer()))
    243232            return false;
    244233        return checkNodeResult.releaseException();
     
    264253        // DOM4 spec requires us to check whether refNode and start container have the same root first
    265254        // but we do it in the reverse order to avoid O(n) operation here in common case.
    266         if (!refNode.isConnected() && !commonAncestorContainer(&refNode, &startContainer()))
     255        if (!refNode.isConnected() && !commonInclusiveAncestor(refNode, startContainer()))
    267256            return Exception { WrongDocumentError };
    268257        return checkNodeResult.releaseException();
     
    422411    // case 4: containers A & B are siblings, or children of siblings
    423412    // ### we need to do a traversal here instead
    424     auto* commonAncestor = commonAncestorContainer(containerA, containerB);
     413    auto commonAncestor = commonInclusiveAncestor(*containerA, *containerB);
    425414    if (!commonAncestor)
    426415        return Exception { WrongDocumentError };
     
    429418        childA = childA->parentNode();
    430419    if (!childA)
    431         childA = commonAncestor;
     420        childA = commonAncestor.get();
    432421    Node* childB = containerB;
    433422    while (childB && childB->parentNode() != commonAncestor)
    434423        childB = childB->parentNode();
    435424    if (!childB)
    436         childB = commonAncestor;
     425        childB = commonAncestor.get();
    437426
    438427    if (childA == childB)
     
    12911280    }
    12921281
    1293     // The range could span over nodes with different writing modes.
     1282    // The range could span nodes with different writing modes.
    12941283    // If this is the case, we use the writing mode of the common ancestor.
    12951284    if (containsDifferentWritingModes) {
    1296         if (Node* ancestor = commonAncestorContainer(&startContainer, &endContainer))
     1285        if (auto ancestor = commonInclusiveAncestor(startContainer, endContainer))
    12971286            hasFlippedWritingMode = ancestor->renderer()->style().isFlippedBlocksWritingMode();
    12981287    }
  • trunk/Source/WebCore/dom/Range.h

    r259933 r260753  
    6161    bool collapsed() const { return m_start == m_end; }
    6262
    63     Node* commonAncestorContainer() const { return commonAncestorContainer(&startContainer(), &endContainer()); }
    64     WEBCORE_EXPORT static Node* commonAncestorContainer(Node* containerA, Node* containerB);
     63    Node* commonAncestorContainer() const { return commonInclusiveAncestor(startContainer(), endContainer()).get(); }
    6564    WEBCORE_EXPORT ExceptionOr<void> setStart(Ref<Node>&& container, unsigned offset);
    6665    WEBCORE_EXPORT ExceptionOr<void> setEnd(Ref<Node>&& container, unsigned offset);
  • trunk/Source/WebCore/dom/SimpleRange.cpp

    r260725 r260753  
    6565}
    6666
    67 static BoundaryPoint makeBoundaryPointAfterNodeContents(Node& node)
    68 {
    69     return { node, node.length() };
    70 }
    71 
    7267SimpleRange makeRangeSelectingNodeContents(Node& node)
    7368{
  • trunk/Source/WebCore/editing/AlternativeTextController.cpp

    r260725 r260753  
    218218void AlternativeTextController::respondToUnappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction)
    219219{
    220     if (AlternativeTextClient* client = alternativeTextClient())
     220    if (auto client = alternativeTextClient())
    221221        client->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, corrected, correction);
    222222
    223223    Ref<Frame> protector(m_frame);
    224224    m_frame.document()->updateLayout();
     225
    225226    m_frame.selection().setSelection(selectionOfCorrected, FrameSelection::defaultSetSelectionOptions() | FrameSelection::SpellCorrectionTriggered);
    226     auto range = Range::create(*m_frame.document(), m_frame.selection().selection().start(), m_frame.selection().selection().end());
    227 
     227    auto range = m_frame.selection().selection().firstRange();
     228    if (!range)
     229        return;
    228230    auto& markers = m_frame.document()->markers();
    229     markers.removeMarkers(range, OptionSet<DocumentMarker::MarkerType> { DocumentMarker::Spelling, DocumentMarker::Autocorrected }, DocumentMarkerController::RemovePartiallyOverlappingMarker);
    230     markers.addMarker(range, DocumentMarker::Replacement);
    231     markers.addMarker(range, DocumentMarker::SpellCheckingExemption);
     231    markers.removeMarkers(*range, OptionSet<DocumentMarker::MarkerType> { DocumentMarker::Spelling, DocumentMarker::Autocorrected }, DocumentMarkerController::RemovePartiallyOverlappingMarker);
     232    markers.addMarker(*range, DocumentMarker::Replacement);
     233    markers.addMarker(*range, DocumentMarker::SpellCheckingExemption);
    232234}
    233235
     
    396398    if (!command->wasCreateLinkCommand())
    397399        return;
    398     auto range = Range::create(*m_frame.document(), command->startingSelection().start(), command->startingSelection().end());
     400    auto range = command->startingSelection().firstRange();
     401    if (!range)
     402        return;
    399403    auto& markers = m_frame.document()->markers();
    400     markers.addMarker(range, DocumentMarker::Replacement);
    401     markers.addMarker(range, DocumentMarker::SpellCheckingExemption);
     404    markers.addMarker(*range, DocumentMarker::Replacement);
     405    markers.addMarker(*range, DocumentMarker::SpellCheckingExemption);
    402406}
    403407
     
    472476        return;
    473477
    474     auto precedingCharacterRange = Range::create(*m_frame.document(), precedingCharacterPosition, endOfSelection);
     478    auto precedingCharacterRange = SimpleRange { *makeBoundaryPoint(precedingCharacterPosition), *makeBoundaryPoint(endOfSelection) };
    475479    String string = plainText(precedingCharacterRange);
    476480    if (string.isEmpty() || !deprecatedIsEditingWhitespace(string[string.length() - 1]))
     
    485489bool AlternativeTextController::processMarkersOnTextToBeReplacedByResult(const TextCheckingResult& result, Range& rangeWithAlternative, const String& stringToBeReplaced)
    486490{
    487     DocumentMarkerController& markerController = m_frame.document()->markers();
    488     if (markerController.hasMarkers(rangeWithAlternative, DocumentMarker::Replacement)) {
     491    auto& markers = m_frame.document()->markers();
     492    if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::Replacement)) {
    489493        if (result.type == TextCheckingType::Correction)
    490494            recordSpellcheckerResponseForModifiedCorrection(rangeWithAlternative, stringToBeReplaced, result.replacement);
     
    492496    }
    493497
    494     if (markerController.hasMarkers(rangeWithAlternative, DocumentMarker::RejectedCorrection))
    495         return false;
    496 
    497     if (markerController.hasMarkers(rangeWithAlternative, DocumentMarker::AcceptedCandidate))
     498    if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::RejectedCorrection))
     499        return false;
     500
     501    if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::AcceptedCandidate))
    498502        return false;
    499503
    500504    Position beginningOfRange = rangeWithAlternative.startPosition();
    501505    Position precedingCharacterPosition = beginningOfRange.previous();
    502     auto precedingCharacterRange = Range::create(*m_frame.document(), precedingCharacterPosition, beginningOfRange);
    503 
    504     Vector<RenderedDocumentMarker*> markers = markerController.markersInRange(precedingCharacterRange, DocumentMarker::DeletedAutocorrection);
    505     for (const auto* marker : markers) {
     506
     507    auto precedingCharacterRange = SimpleRange { *makeBoundaryPoint(precedingCharacterPosition), *makeBoundaryPoint(beginningOfRange) };
     508
     509    for (auto& marker : markers.markersInRange(precedingCharacterRange, DocumentMarker::DeletedAutocorrection)) {
    506510        if (marker->description() == stringToBeReplaced)
    507511            return false;
  • trunk/Source/WebCore/editing/ChangeListTypeCommand.cpp

    r244115 r260753  
    4141static Optional<std::pair<ChangeListTypeCommand::Type, Ref<HTMLElement>>> listConversionTypeForSelection(const VisibleSelection& selection)
    4242{
     43    auto startNode = selection.start().containerNode();
     44    auto endNode = selection.end().containerNode();
     45    if (!startNode || !endNode)
     46        return { };
     47    auto commonAncestor = commonInclusiveAncestor(*startNode, *endNode);
     48
    4349    RefPtr<HTMLElement> listToReplace;
    44     auto commonAncestor = makeRefPtr(Range::commonAncestorContainer(selection.start().containerNode(), selection.end().containerNode()));
    4550    if (is<HTMLUListElement>(commonAncestor) || is<HTMLOListElement>(commonAncestor))
    4651        listToReplace = downcast<HTMLElement>(commonAncestor.get());
  • trunk/Source/WebCore/editing/Editing.cpp

    r260725 r260753  
    11411141// Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
    11421142// Call this function to determine whether a node is visibly fit inside selectedRange
    1143 bool isNodeVisiblyContainedWithin(Node& node, const Range& range)
     1143bool isNodeVisiblyContainedWithin(Node& node, const SimpleRange& range)
    11441144{
    11451145    // If the node is inside the range, then it surely is contained within.
    1146     auto comparisonResult = range.compareNode(node);
     1146    auto comparisonResult = createLiveRange(range)->compareNode(node);
    11471147    if (!comparisonResult.hasException() && comparisonResult.releaseReturnValue() == Range::NODE_INSIDE)
    11481148        return true;
    11491149
    1150     bool startIsVisuallySame = visiblePositionBeforeNode(node) == range.startPosition();
    1151     if (startIsVisuallySame && comparePositions(positionInParentAfterNode(&node), range.endPosition()) < 0)
     1150    auto startPosition = createLegacyEditingPosition(range.start);
     1151    auto endPosition = createLegacyEditingPosition(range.end);
     1152
     1153    bool startIsVisuallySame = visiblePositionBeforeNode(node) == startPosition;
     1154    if (startIsVisuallySame && comparePositions(positionInParentAfterNode(&node), endPosition) < 0)
    11521155        return true;
    11531156
    1154     bool endIsVisuallySame = visiblePositionAfterNode(node) == range.endPosition();
    1155     if (endIsVisuallySame && comparePositions(range.startPosition(), positionInParentBeforeNode(&node)) < 0)
     1157    bool endIsVisuallySame = visiblePositionAfterNode(node) == endPosition;
     1158    if (endIsVisuallySame && comparePositions(startPosition, positionInParentBeforeNode(&node)) < 0)
    11561159        return true;
    11571160
  • trunk/Source/WebCore/editing/Editing.h

    r260725 r260753  
    3838class HTMLSpanElement;
    3939class HTMLTextFormControlElement;
    40 class Range;
    4140class RenderBlock;
    4241class VisiblePosition;
     
    102101bool isNonTableCellHTMLBlockElement(const Node*);
    103102
    104 bool isNodeVisiblyContainedWithin(Node&, const Range&);
     103bool isNodeVisiblyContainedWithin(Node&, const SimpleRange&);
    105104
    106105bool areIdenticalElements(const Node&, const Node&);
  • trunk/Source/WebCore/editing/Editor.cpp

    r260725 r260753  
    32123212}
    32133213
    3214 void Editor::addRangeToKillRing(const Range& range, KillRingInsertionMode mode)
     3214void Editor::addRangeToKillRing(const SimpleRange& range, KillRingInsertionMode mode)
    32153215{
    32163216    addTextToKillRing(plainText(range), mode);
     
    36863686}
    36873687
    3688 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS_FAMILY)
    3689 
    3690 bool Editor::shouldDetectTelephoneNumbers()
    3691 {
    3692     if (!m_frame.document())
    3693         return false;
    3694     return document().isTelephoneNumberParsingEnabled() && TelephoneNumberDetector::isSupported();
    3695 }
    3696 
    3697 void Editor::scanSelectionForTelephoneNumbers()
    3698 {
    3699     if (!shouldDetectTelephoneNumbers() || !client())
    3700         return;
    3701 
    3702     m_detectedTelephoneNumberRanges.clear();
    3703 
    3704     Vector<RefPtr<Range>> markedRanges;
    3705 
    3706     FrameSelection& frameSelection = m_frame.selection();
    3707     if (!frameSelection.isRange()) {
    3708         if (auto* page = m_frame.page())
    3709             page->servicesOverlayController().selectedTelephoneNumberRangesChanged();
    3710         return;
    3711     }
    3712     auto selectedRange = createLiveRange(frameSelection.selection().toNormalizedRange());
    3713 
    3714     // Extend the range a few characters in each direction to detect incompletely selected phone numbers.
    3715     static const int charactersToExtend = 15;
    3716     const VisibleSelection& visibleSelection = frameSelection.selection();
    3717     Position start = visibleSelection.start();
    3718     Position end = visibleSelection.end();
    3719     for (int i = 0; i < charactersToExtend; ++i) {
    3720         start = start.previous(Character);
    3721         end = end.next(Character);
    3722     }
    3723 
    3724     FrameSelection extendedSelection;
    3725     extendedSelection.setStart(start);
    3726     extendedSelection.setEnd(end);
    3727     auto extendedRange = extendedSelection.selection().toNormalizedRange();
    3728 
    3729     if (!extendedRange) {
    3730         if (auto* page = m_frame.page())
    3731             page->servicesOverlayController().selectedTelephoneNumberRangesChanged();
    3732         return;
    3733     }
    3734 
    3735     scanRangeForTelephoneNumbers(createLiveRange(*extendedRange), plainText(*extendedRange), markedRanges);
    3736 
    3737     // Only consider ranges with a detected telephone number if they overlap with the actual selection range.
    3738     for (auto& range : markedRanges) {
    3739         if (rangesOverlap(range.get(), selectedRange.get()))
    3740             m_detectedTelephoneNumberRanges.append(range);
    3741     }
    3742 
    3743     if (auto* page = m_frame.page())
    3744         page->servicesOverlayController().selectedTelephoneNumberRangesChanged();
    3745 }
    3746 
    3747 void Editor::scanRangeForTelephoneNumbers(Range& range, const StringView& stringView, Vector<RefPtr<Range>>& markedRanges)
     3688#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
     3689
     3690bool Editor::shouldDetectTelephoneNumbers() const
     3691{
     3692    return m_frame.document() && document().isTelephoneNumberParsingEnabled() && TelephoneNumberDetector::isSupported();
     3693}
     3694
     3695static Vector<SimpleRange> scanForTelephoneNumbers(const SimpleRange& range)
    37483696{
    37493697    // Don't scan for phone numbers inside editable regions.
    3750     Node& startNode = range.startContainer();
     3698    auto& startNode = range.startContainer();
    37513699    if (startNode.hasEditableStyle())
    3752         return;
    3753 
    3754     // relativeStartPosition and relativeEndPosition are the endpoints of the phone number range,
    3755     // relative to the scannerPosition
    3756     unsigned length = stringView.length();
     3700        return { };
     3701    auto text = plainText(range);
     3702    Vector<SimpleRange> result;
     3703    unsigned length = text.length();
    37573704    unsigned scannerPosition = 0;
    37583705    int relativeStartPosition = 0;
    37593706    int relativeEndPosition = 0;
    3760 
    3761     auto characters = stringView.upconvertedCharacters();
    3762 
     3707    auto characters = StringView { text }.upconvertedCharacters();
    37633708    while (scannerPosition < length && TelephoneNumberDetector::find(&characters[scannerPosition], length - scannerPosition, &relativeStartPosition, &relativeEndPosition)) {
    3764         // The convention in the Data Detectors framework is that the end position is the first character NOT in the phone number
    3765         // (that is, the length of the range is relativeEndPosition - relativeStartPosition). So subtract 1 to get the same
    3766         // convention as the old WebCore phone number parser (so that the rest of the code is still valid if we want to go back
    3767         // to the old parser).
    3768         --relativeEndPosition;
    3769 
    3770         ASSERT(scannerPosition + relativeEndPosition < length);
    3771 
    3772         auto subrange = resolveCharacterRange(range, CharacterRange(scannerPosition + relativeStartPosition, relativeEndPosition - relativeStartPosition + 1));
    3773 
    3774         markedRanges.append(createLiveRange(subrange));
    3775         range.ownerDocument().markers().addMarker(subrange, DocumentMarker::TelephoneNumber);
    3776 
    3777         scannerPosition += relativeEndPosition + 1;
    3778     }
     3709        ASSERT(scannerPosition + relativeEndPosition <= length);
     3710        result.append(resolveCharacterRange(range, CharacterRange(scannerPosition + relativeStartPosition, relativeEndPosition - relativeStartPosition)));
     3711        scannerPosition += relativeEndPosition;
     3712    }
     3713    return result;
     3714}
     3715
     3716static SimpleRange extendSelection(const SimpleRange& range, unsigned charactersToExtend)
     3717{
     3718    auto start = createLegacyEditingPosition(range.start);
     3719    auto end = createLegacyEditingPosition(range.end);
     3720    for (unsigned i = 0; i < charactersToExtend; ++i) {
     3721        start = start.previous(Character);
     3722        end = end.next(Character);
     3723    }
     3724    return { *makeBoundaryPoint(start), *makeBoundaryPoint(end)};
     3725}
     3726
     3727void Editor::scanSelectionForTelephoneNumbers()
     3728{
     3729    // FIXME: Why is it helpful here to check client for null?
     3730    if (!shouldDetectTelephoneNumbers() || !client())
     3731        return;
     3732
     3733    m_detectedTelephoneNumberRanges.clear();
     3734
     3735    auto& selection = m_frame.selection();
     3736    if (selection.isRange()) {
     3737        if (auto selectedRange = selection.selection().firstRange()) {
     3738            // Extend the range a few characters in each direction to detect incompletely selected phone numbers.
     3739            constexpr unsigned charactersToExtend = 15;
     3740            auto selectedLiveRange = createLiveRange(*selectedRange);
     3741            for (auto& range : scanForTelephoneNumbers(extendSelection(*selectedRange, charactersToExtend))) {
     3742                // FIXME: Why do we do this unconditionally and the code below this only when it overlaps the selection?
     3743                document().markers().addMarker(range, DocumentMarker::TelephoneNumber);
     3744
     3745                // Only consider ranges with a detected telephone number if they overlap with the actual selection range.
     3746                if (rangesOverlap(createLiveRange(range).ptr(), selectedLiveRange.ptr()))
     3747                    m_detectedTelephoneNumberRanges.append(range);
     3748            }
     3749        }
     3750    }
     3751
     3752    if (auto* page = m_frame.page())
     3753        page->servicesOverlayController().selectedTelephoneNumberRangesChanged();
    37793754}
    37803755
  • trunk/Source/WebCore/editing/Editor.h

    r259938 r260753  
    418418   
    419419    enum class KillRingInsertionMode { PrependText, AppendText };
    420     void addRangeToKillRing(const Range&, KillRingInsertionMode);
     420    void addRangeToKillRing(const SimpleRange&, KillRingInsertionMode);
    421421    void addTextToKillRing(const String&, KillRingInsertionMode);
    422422    void setStartNewKillRingSequence(bool);
     
    507507#endif
    508508
    509     RefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, Range& context, bool allowPlainText, bool& chosePlainText);
     509    RefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, const SimpleRange& context, bool allowPlainText, bool& chosePlainText);
    510510
    511511    WEBCORE_EXPORT const Font* fontForSelection(bool& hasMultipleFonts) const;
     
    517517    String stringSelectionForPasteboardWithImageAltText();
    518518    void takeFindStringFromSelection();
    519 #if !PLATFORM(IOS_FAMILY)
     519    WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
     520#endif
     521
     522#if PLATFORM(MAC)
    520523    WEBCORE_EXPORT void readSelectionFromPasteboard(const String& pasteboardName);
    521524    WEBCORE_EXPORT void replaceNodeFromPasteboard(Node*, const String& pasteboardName);
    522525    WEBCORE_EXPORT RefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName);
    523 #endif // !PLATFORM(IOS_FAMILY)
    524     WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
    525526#endif
    526527
     
    533534#endif
    534535
    535 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS_FAMILY)
     536#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
    536537    void scanSelectionForTelephoneNumbers();
    537     const Vector<RefPtr<Range>>& detectedTelephoneNumberRanges() const { return m_detectedTelephoneNumberRanges; }
     538    const Vector<SimpleRange>& detectedTelephoneNumberRanges() const { return m_detectedTelephoneNumberRanges; }
    538539#endif
    539540
     
    649650    bool m_isHandlingAcceptedCandidate { false };
    650651
    651 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS_FAMILY)
    652     bool shouldDetectTelephoneNumbers();
    653     void scanRangeForTelephoneNumbers(Range&, const StringView&, Vector<RefPtr<Range>>& markedRanges);
     652#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
     653    bool shouldDetectTelephoneNumbers() const;
    654654
    655655    Timer m_telephoneNumberDetectionUpdateTimer;
    656     Vector<RefPtr<Range>> m_detectedTelephoneNumberRanges;
     656    Vector<SimpleRange> m_detectedTelephoneNumberRanges;
    657657#endif
    658658
  • trunk/Source/WebCore/editing/TextManipulationController.cpp

    r260678 r260753  
    597597                commonAncestor = parent;
    598598            else if (!parent->isDescendantOf(commonAncestor.get())) {
    599                 commonAncestor = Range::commonAncestorContainer(commonAncestor.get(), parent.get());
     599                commonAncestor = commonInclusiveAncestor(*commonAncestor, *parent);
    600600                ASSERT(commonAncestor);
    601601            }
  • trunk/Source/WebCore/editing/VisibleSelection.cpp

    r260725 r260753  
    203203}
    204204
    205 static RefPtr<Range> makeSearchRange(const Position& position)
    206 {
    207     auto* node = position.deprecatedNode();
    208     if (!node)
    209         return nullptr;
    210     auto* boundary = deprecatedEnclosingBlockFlowElement(node);
    211     if (!boundary)
    212         return nullptr;
    213 
    214     auto searchRange = Range::create(node->document());
    215 
    216     auto result = searchRange->selectNodeContents(*boundary);
    217     if (result.hasException())
    218         return nullptr;
    219     Position start { position.parentAnchoredEquivalent() };
    220     result = searchRange->setStart(*start.containerNode(), start.offsetInContainerNode());
    221     if (result.hasException())
    222         return nullptr;
    223 
    224     return searchRange;
     205static Optional<SimpleRange> makeSearchRange(const Position& position)
     206{
     207    auto node = position.deprecatedNode();
     208    auto scope = deprecatedEnclosingBlockFlowElement(node);
     209    if (!scope)
     210        return { };
     211    auto start = makeBoundaryPoint(position.parentAnchoredEquivalent());
     212    if (!start)
     213        return { };
     214    return { { WTFMove(*start), makeBoundaryPointAfterNodeContents(*scope) } };
    225215}
    226216
     
    232222void VisibleSelection::appendTrailingWhitespace()
    233223{
    234     RefPtr<Range> searchRange = makeSearchRange(m_end);
     224    auto searchRange = makeSearchRange(m_end);
    235225    if (!searchRange)
    236226        return;
  • trunk/Source/WebCore/editing/WebContentReader.h

    r250256 r260753  
    2929#include "Frame.h"
    3030#include "Pasteboard.h"
    31 #include "Range.h"
     31#include "SimpleRange.h"
    3232#include "markup.h"
    3333
     
    3535
    3636class ArchiveResource;
    37 class Blob;
    3837
    3938class FrameWebContentReader : public PasteboardWebContentReader {
     
    5352class WebContentReader final : public FrameWebContentReader {
    5453public:
    55     Range& context;
     54    const SimpleRange context;
    5655    const bool allowPlainText;
    5756
     
    5958    bool madeFragmentFromPlainText;
    6059
    61     WebContentReader(Frame& frame, Range& context, bool allowPlainText)
     60    WebContentReader(Frame& frame, const SimpleRange& context, bool allowPlainText)
    6261        : FrameWebContentReader(frame)
    6362        , context(context)
  • trunk/Source/WebCore/editing/cocoa/DataDetection.h

    r238771 r260753  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(DATA_DETECTION)
    2929
    30 #import <wtf/RefPtr.h>
     30#import "FloatRect.h"
     31#import "SimpleRange.h"
    3132#import <wtf/RetainPtr.h>
    32 #import <wtf/text/WTFString.h>
    3333
    3434OBJC_CLASS DDActionContext;
     
    3838namespace WebCore {
    3939
    40 class Document;
    41 class Element;
    42 class FloatRect;
    4340class HitTestResult;
    44 class Range;
    4541
    46 enum DataDetectorTypes {
    47     DataDetectorTypeNone = 0,
    48     DataDetectorTypePhoneNumber = 1 << 0,
    49     DataDetectorTypeLink = 1 << 1,
    50     DataDetectorTypeAddress = 1 << 2,
    51     DataDetectorTypeCalendarEvent = 1 << 3,
    52     DataDetectorTypeTrackingNumber = 1 << 4,
    53     DataDetectorTypeFlightNumber = 1 << 5,
    54     DataDetectorTypeLookupSuggestion = 1 << 6,
    55     DataDetectorTypeAll = ULONG_MAX
     42// FIXME: Would be better to use an OptionSet and uint8_t.
     43enum class DataDetectorTypes : uint32_t {
     44    PhoneNumber = 1 << 0,
     45    Link = 1 << 1,
     46    Address = 1 << 2,
     47    CalendarEvent = 1 << 3,
     48    TrackingNumber = 1 << 4,
     49    FlightNumber = 1 << 5,
     50    LookupSuggestion = 1 << 6,
     51};
     52
     53struct DetectedItem {
     54    RetainPtr<DDActionContext> actionContext;
     55    FloatRect boundingBox;
     56    SimpleRange range;
    5657};
    5758
     
    5960public:
    6061#if PLATFORM(MAC)
    61     WEBCORE_EXPORT static RetainPtr<DDActionContext> detectItemAroundHitTestResult(const HitTestResult&, FloatRect& detectedDataBoundingBox, RefPtr<Range>& detectedDataRange);
     62    WEBCORE_EXPORT static Optional<DetectedItem> detectItemAroundHitTestResult(const HitTestResult&);
    6263#endif
    63     WEBCORE_EXPORT static NSArray *detectContentInRange(RefPtr<Range>& contextRange, DataDetectorTypes, NSDictionary *context);
     64    WEBCORE_EXPORT static NSArray *detectContentInRange(const SimpleRange&, DataDetectorTypes, NSDictionary *context);
    6465    WEBCORE_EXPORT static void removeDataDetectedLinksInDocument(Document&);
    6566#if PLATFORM(IOS_FAMILY)
     
    7879
    7980#endif
    80 
  • trunk/Source/WebCore/editing/cocoa/DataDetection.mm

    r259933 r260753  
    11/*
    2  * Copyright (C) 2014-2017 Apple, Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple, Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939#import "HTMLTextFormControlElement.h"
    4040#import "HitTestResult.h"
    41 #import "Node.h"
    4241#import "NodeList.h"
    4342#import "NodeTraversal.h"
     
    5756
    5857#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
    59 template <>
    60 struct WTF::CFTypeTrait<DDResultRef> {
     58template<> struct WTF::CFTypeTrait<DDResultRef> {
    6159    static inline CFTypeID typeID(void) { return DDResultGetCFTypeID(); }
    6260};
     
    6967#if PLATFORM(MAC)
    7068
    71 static RetainPtr<DDActionContext> detectItemAtPositionWithRange(VisiblePosition position, RefPtr<Range> contextRange, FloatRect& detectedDataBoundingBox, RefPtr<Range>& detectedDataRange)
    72 {
    73     auto start = contextRange->startPosition();
    74     if (start.isNull() || position.isNull())
    75         return nil;
    76     String fullPlainTextString = plainText(*contextRange);
    77     CFIndex hitLocation = characterCount({ *makeBoundaryPoint(start), *makeBoundaryPoint(position) });
     69static Optional<DetectedItem> detectItem(const VisiblePosition& position, const SimpleRange& contextRange)
     70{
     71    if (position.isNull())
     72        return { };
     73    String fullPlainTextString = plainText(contextRange);
     74    CFIndex hitLocation = characterCount({ contextRange.start, *makeBoundaryPoint(position) });
    7875
    7976    auto scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
     
    8178
    8279    if (!DDScannerScanQuery(scanner.get(), scanQuery.get()))
    83         return nil;
     80        return { };
    8481
    8582    auto results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
     
    8784    // Find the DDResultRef that intersects the hitTestResult's VisiblePosition.
    8885    DDResultRef mainResult = nullptr;
    89     RefPtr<Range> mainResultRange;
     86    Optional<SimpleRange> mainResultRange;
    9087    CFIndex resultCount = CFArrayGetCount(results.get());
    9188    for (CFIndex i = 0; i < resultCount; i++) {
     
    9895        if (hitLocation >= resultRangeInContext.location && (hitLocation - resultRangeInContext.location) < resultRangeInContext.length) {
    9996            mainResult = result;
    100             mainResultRange = createLiveRange(resolveCharacterRange(*contextRange, resultRangeInContext));
     97            mainResultRange = resolveCharacterRange(contextRange, resultRangeInContext);
    10198            break;
    10299        }
     
    104101
    105102    if (!mainResult)
    106         return nil;
    107 
    108     auto view = mainResultRange->ownerDocument().view();
     103        return { };
     104
     105    auto view = mainResultRange->start.document().view();
    109106    if (!view)
    110         return nil;
     107        return { };
    111108
    112109    auto actionContext = adoptNS([allocDDActionContextInstance() init]);
     
    114111    [actionContext setMainResult:mainResult];
    115112
    116     detectedDataBoundingBox = view->contentsToWindow(enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(*mainResultRange))));
    117     detectedDataRange = mainResultRange;
    118 
    119     return actionContext;
    120 }
    121 
    122 RetainPtr<DDActionContext> DataDetection::detectItemAroundHitTestResult(const HitTestResult& hitTestResult, FloatRect& detectedDataBoundingBox, RefPtr<Range>& detectedDataRange)
     113    return { {
     114        WTFMove(actionContext),
     115        view->contentsToWindow(enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(*mainResultRange)))),
     116        *mainResultRange,
     117    } };
     118}
     119
     120Optional<DetectedItem> DataDetection::detectItemAroundHitTestResult(const HitTestResult& hitTestResult)
    123121{
    124122    if (!DataDetectorsLibrary())
    125         return nullptr;
     123        return { };
    126124
    127125    Node* node = hitTestResult.innerNonSharedNode();
    128126    if (!node)
    129         return nullptr;
     127        return { };
    130128    auto renderer = node->renderer();
    131129    if (!renderer)
    132         return nullptr;
     130        return { };
    133131
    134132    VisiblePosition position;
     
    141139
    142140        contextRange = rangeExpandedAroundPositionByCharacters(position, 250);
    143         if (!contextRange)
    144             return nullptr;
    145141    } else {
    146142        Frame* frame = node->document().frame();
    147143        if (!frame)
    148             return nullptr;
     144            return { };
    149145
    150146        IntPoint framePoint = hitTestResult.roundedPointInInnerNodeFrame();
    151147        if (!frame->rangeForPoint(framePoint))
    152             return nullptr;
    153 
    154         VisiblePosition position = frame->visiblePositionForPoint(framePoint);
     148            return { };
     149
     150        position = frame->visiblePositionForPoint(framePoint);
    155151        if (position.isNull())
    156             return nullptr;
     152            return { };
    157153
    158154        contextRange = enclosingTextUnitOfGranularity(position, LineGranularity, DirectionForward);
    159         if (!contextRange)
    160             return nullptr;
    161     }
    162 
    163     return detectItemAtPositionWithRange(position, contextRange, detectedDataBoundingBox, detectedDataRange);
     155    }
     156
     157    if (!contextRange)
     158        return { };
     159
     160    return detectItem(position, *contextRange);
    164161}
    165162
     
    224221}
    225222
     223// Poor man's OptionSet.
     224static bool contains(DataDetectorTypes types, DataDetectorTypes singleType)
     225{
     226    return static_cast<uint32_t>(types) & static_cast<uint32_t>(singleType);
     227}
     228
    226229static NSString *constructURLStringForResult(DDResultRef currentResult, NSString *resultIdentifier, NSDate *referenceDate, NSTimeZone *referenceTimeZone, DataDetectorTypes detectionTypes)
    227230{
    228231    if (!softLink_DataDetectorsCore_DDResultHasProperties(currentResult, DDResultPropertyPassiveDisplay))
    229232        return nil;
    230    
    231     DDURLifierPhoneNumberDetectionTypes phoneTypes = (detectionTypes & DataDetectorTypePhoneNumber) ? DDURLifierPhoneNumberDetectionRegular : DDURLifierPhoneNumberDetectionNone;
    232     DDResultCategory category = softLink_DataDetectorsCore_DDResultGetCategory(currentResult);
    233     CFStringRef type = softLink_DataDetectorsCore_DDResultGetType(currentResult);
    234    
    235     if (((detectionTypes & DataDetectorTypeAddress) && (DDResultCategoryAddress == category))
    236         || ((detectionTypes & DataDetectorTypeTrackingNumber) && (CFStringCompare(get_DataDetectorsCore_DDBinderTrackingNumberKey(), type, 0) == kCFCompareEqualTo))
    237         || ((detectionTypes & DataDetectorTypeFlightNumber) && (CFStringCompare(get_DataDetectorsCore_DDBinderFlightInformationKey(), type, 0) == kCFCompareEqualTo))
    238         || ((detectionTypes & DataDetectorTypeLookupSuggestion) && (CFStringCompare(get_DataDetectorsCore_DDBinderParsecSourceKey(), type, 0) == kCFCompareEqualTo))
    239         || ((detectionTypes & DataDetectorTypePhoneNumber) && (DDResultCategoryPhoneNumber == category))
    240         || ((detectionTypes & DataDetectorTypeLink) && resultIsURL(currentResult))) {
    241        
     233
     234    auto phoneTypes = contains(detectionTypes, DataDetectorTypes::PhoneNumber) ? DDURLifierPhoneNumberDetectionRegular : DDURLifierPhoneNumberDetectionNone;
     235    auto category = softLink_DataDetectorsCore_DDResultGetCategory(currentResult);
     236    auto type = softLink_DataDetectorsCore_DDResultGetType(currentResult);
     237
     238    if ((contains(detectionTypes, DataDetectorTypes::Address) && DDResultCategoryAddress == category)
     239        || (contains(detectionTypes, DataDetectorTypes::TrackingNumber) && CFEqual(get_DataDetectorsCore_DDBinderTrackingNumberKey(), type))
     240        || (contains(detectionTypes, DataDetectorTypes::FlightNumber) && CFEqual(get_DataDetectorsCore_DDBinderFlightInformationKey(), type))
     241        || (contains(detectionTypes, DataDetectorTypes::LookupSuggestion) && CFEqual(get_DataDetectorsCore_DDBinderParsecSourceKey(), type))
     242        || (contains(detectionTypes, DataDetectorTypes::PhoneNumber) && DDResultCategoryPhoneNumber == category)
     243        || (contains(detectionTypes, DataDetectorTypes::Link) && resultIsURL(currentResult))) {
    242244        return softLink_DataDetectorsCore_DDURLStringForResult(currentResult, resultIdentifier, phoneTypes, referenceDate, referenceTimeZone);
    243245    }
    244     if ((detectionTypes & DataDetectorTypeCalendarEvent) && (DDResultCategoryCalendarEvent == category)) {
     246    if (contains(detectionTypes, DataDetectorTypes::CalendarEvent) && DDResultCategoryCalendarEvent == category) {
    245247        if (!softLink_DataDetectorsCore_DDResultIsPastDate(currentResult, (CFDateRef)referenceDate, (CFTimeZoneRef)referenceTimeZone))
    246248            return softLink_DataDetectorsCore_DDURLStringForResult(currentResult, resultIdentifier, phoneTypes, referenceDate, referenceTimeZone);
     
    444446}
    445447
    446 NSArray *DataDetection::detectContentInRange(RefPtr<Range>& contextRange, DataDetectorTypes types, NSDictionary *context)
    447 {
    448     if (!contextRange)
    449         return nil;
    450 
    451     RetainPtr<DDScannerRef> scanner = adoptCF(softLink_DataDetectorsCore_DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
    452     RetainPtr<DDScanQueryRef> scanQuery = adoptCF(softLink_DataDetectorsCore_DDScanQueryCreate(NULL));
    453     buildQuery(scanQuery.get(), *contextRange);
    454    
    455     if (types & DataDetectorTypeLookupSuggestion)
     448NSArray *DataDetection::detectContentInRange(const SimpleRange& contextRange, DataDetectorTypes types, NSDictionary *context)
     449{
     450    auto scanner = adoptCF(softLink_DataDetectorsCore_DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
     451    auto scanQuery = adoptCF(softLink_DataDetectorsCore_DDScanQueryCreate(NULL));
     452    buildQuery(scanQuery.get(), contextRange);
     453   
     454    if (contains(types, DataDetectorTypes::LookupSuggestion))
    456455        softLink_DataDetectorsCore_DDScannerEnableOptionalSource(scanner.get(), DDScannerSourceSpotlight, true);
    457456
     
    460459        return nil;
    461460
    462     RetainPtr<CFArrayRef> scannerResults = adoptCF(softLink_DataDetectorsCore_DDScannerCopyResultsWithOptions(scanner.get(), get_DataDetectorsCore_DDScannerCopyResultsOptionsForPassiveUse() | DDScannerCopyResultsOptionsCoalesceSignatures));
     461    auto scannerResults = adoptCF(softLink_DataDetectorsCore_DDScannerCopyResultsWithOptions(scanner.get(), get_DataDetectorsCore_DDScannerCopyResultsOptionsForPassiveUse() | DDScannerCopyResultsOptionsCoalesceSignatures));
    463462    if (!scannerResults)
    464463        return nil;
    465464
    466     CFIndex resultCount = CFArrayGetCount(scannerResults.get());
    467     if (!resultCount)
     465    if (!CFArrayGetCount(scannerResults.get()))
    468466        return nil;
    469467
     
    477475        DDResultRef result = (DDResultRef)resultObject;
    478476        NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:currentTopLevelIndex];
    479         if (CFStringCompare(softLink_DataDetectorsCore_DDResultGetType(result), get_DataDetectorsCore_DDBinderSignatureBlockKey(), 0) == kCFCompareEqualTo) {
     477        if (CFEqual(softLink_DataDetectorsCore_DDResultGetType(result), get_DataDetectorsCore_DDBinderSignatureBlockKey())) {
    480478            NSArray *subresults = (NSArray *)softLink_DataDetectorsCore_DDResultGetSubResults(result);
    481479           
     
    492490
    493491    Vector<Vector<SimpleRange>> allResultRanges;
    494     TextIterator iterator(*contextRange);
     492    TextIterator iterator(contextRange);
    495493    CFIndex iteratorCount = 0;
    496494
     
    537535    auto tz = adoptCF(CFTimeZoneCopyDefault());
    538536    NSDate *referenceDate = [context objectForKey:getkDataDetectorsReferenceDateKey()] ?: [NSDate date];
    539     Text* lastTextNodeToUpdate = nullptr;
     537    RefPtr<Text> lastTextNodeToUpdate;
    540538    String lastNodeContent;
    541     size_t contentOffset = 0;
     539    unsigned contentOffset = 0;
    542540    DDQueryOffset lastModifiedQueryOffset = { -1, 0 };
    543    
     541
    544542    // For each result add the link.
    545543    // Since there could be multiple results in the same text node, the node is only modified when
    546544    // we are about to process a different text node.
    547     resultCount = allResults.size();
    548    
     545    CFIndex resultCount = allResults.size();
    549546    for (CFIndex resultIndex = 0; resultIndex < resultCount; ++resultIndex) {
    550547        DDResultRef coreResult = allResults[resultIndex].get();
     
    579576            resultRanges.shrink(0); // Keep capacity as we are going to repopulate the Vector right away with the same number of items.
    580577            for (auto& rangeBoundary : rangeBoundaries)
    581                 resultRanges.uncheckedAppend(Range::create(*rangeBoundary.first.document(), rangeBoundary.first, rangeBoundary.second));
     578                resultRanges.uncheckedAppend({ *makeBoundaryPoint(rangeBoundary.first), *makeBoundaryPoint(rangeBoundary.second) });
    582579        }
    583580       
     
    613610            // Create the actual anchor node and insert it before the current node.
    614611            textNodeData = currentTextNode.data().substring(range.start.offset, range.end.offset - range.start.offset);
    615             Ref<Text> newTextNode = Text::create(document, textNodeData);
     612            auto newTextNode = Text::create(document, textNodeData);
    616613            parentNode->insertBefore(newTextNode.copyRef(), &currentTextNode);
    617614           
     
    660657    if (lastTextNodeToUpdate)
    661658        lastTextNodeToUpdate->setData(lastNodeContent);
    662    
     659
    663660    return [getDDScannerResultClass() resultsFromCoreResults:scannerResults.get()];
    664661}
     
    666663#else
    667664
    668 NSArray *DataDetection::detectContentInRange(RefPtr<Range>&, DataDetectorTypes, NSDictionary *)
     665NSArray *DataDetection::detectContentInRange(const SimpleRange&, DataDetectorTypes, NSDictionary *)
    669666{
    670667    return nil;
  • trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm

    r260739 r260753  
    226226// FIXME: Should give this function a name that makes it clear it adds resources to the document loader as a side effect.
    227227// Or refactor so it does not do that.
    228 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)
     228RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
    229229{
    230230    WebContentReader reader(m_frame, context, allowPlainText);
  • trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm

    r260709 r260753  
    676676        return false;
    677677
    678     addFragment(createFragmentFromText(context, [text precomposedStringWithCanonicalMapping]));
     678    addFragment(createFragmentFromText(createLiveRange(context), [text precomposedStringWithCanonicalMapping]));
    679679
    680680    madeFragmentFromPlainText = true;
  • trunk/Source/WebCore/editing/gtk/EditorGtk.cpp

    r250061 r260753  
    5151namespace WebCore {
    5252
    53 static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, Range& range, bool allowPlainText, bool& chosePlainText)
     53static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, const SimpleRange& range, bool allowPlainText, bool& chosePlainText)
    5454{
    5555    chosePlainText = false;
     
    8282    if (selection.hasText()) {
    8383        chosePlainText = true;
    84         return createFragmentFromText(range, selection.text());
     84        return createFragmentFromText(createLiveRange(range), selection.text());
    8585    }
    8686
     
    153153}
    154154
    155 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)
     155RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
    156156{
    157157    return createFragmentFromPasteboardData(pasteboard, m_frame, context, allowPlainText, chosePlainText);
  • trunk/Source/WebCore/editing/mac/EditorMac.mm

    r260739 r260753  
    141141
    142142    Ref<Frame> protector(m_frame);
    143     auto range = Range::create(node->document(), Position(node, Position::PositionIsBeforeAnchor), Position(node, Position::PositionIsAfterAnchor));
    144     m_frame.selection().setSelection(VisibleSelection(range.get()), FrameSelection::DoNotSetFocus);
     143
     144    auto range = makeRangeSelectingNodeContents(*node);
     145    m_frame.selection().setSelection(VisibleSelection(range), FrameSelection::DoNotSetFocus);
    145146
    146147    Pasteboard pasteboard(pasteboardName);
     
    157158
    158159    bool chosePlainText;
    159     if (RefPtr<DocumentFragment> fragment = webContentFromPasteboard(pasteboard, range.get(), true, chosePlainText)) {
     160    if (auto fragment = webContentFromPasteboard(pasteboard, range, true, chosePlainText)) {
    160161        maybeCopyNodeAttributesToFragment(*node, *fragment);
    161         if (shouldInsertFragment(*fragment, range.ptr(), EditorInsertAction::Pasted))
     162        if (shouldInsertFragment(*fragment, createLiveRange(range).ptr(), EditorInsertAction::Pasted))
    162163            pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(pasteboard), false, MailBlockquoteHandling::IgnoreBlockquote);
    163164    }
  • trunk/Source/WebCore/editing/win/EditorWin.cpp

    r235955 r260753  
    6767}
    6868
    69 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range&, bool /*allowPlainText*/, bool& /*chosePlainText*/)
     69RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange&, bool /*allowPlainText*/, bool& /*chosePlainText*/)
    7070{
    7171    if (COMPtr<IDataObject> platformDragData = pasteboard.dataObject())
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r260709 r260753  
    25992599                FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load");
    26002600#if ENABLE(DATA_DETECTION)
    2601                 auto* document = m_frame.document();
    2602                 if (m_frame.settings().dataDetectorTypes() != DataDetectorTypeNone && document) {
    2603                     if (auto* documentElement = document->documentElement()) {
    2604                         RefPtr<Range> documentRange = makeRange(firstPositionInNode(documentElement), lastPositionInNode(documentElement));
    2605                         m_frame.setDataDetectionResults(DataDetection::detectContentInRange(documentRange, m_frame.settings().dataDetectorTypes(), m_client->dataDetectionContext()));
    2606                         if (m_frame.isMainFrame())
    2607                             m_client->dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
    2608                     }
     2601                auto document = m_frame.document();
     2602                auto types = m_frame.settings().dataDetectorTypes();
     2603                if (document && static_cast<uint32_t>(types)) {
     2604                    m_frame.setDataDetectionResults(DataDetection::detectContentInRange(makeRangeSelectingNodeContents(*document), types, m_client->dataDetectionContext()));
     2605                    if (m_frame.isMainFrame())
     2606                        m_client->dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
    26092607                }
    26102608#endif
  • trunk/Source/WebCore/page/EventHandler.cpp

    r260725 r260753  
    20672067}
    20682068
    2069 static Node* targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode)
     2069static RefPtr<Node> targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode)
    20702070{
    20712071    if (!mousePressNode || !mouseReleaseNode)
     
    20772077    // If mousePressNode and mouseReleaseNode differ, we should fire the event at their common ancestor if there is one.
    20782078    if (&mousePressNode->document() == &mouseReleaseNode->document()) {
    2079         if (auto* commonAncestor = Range::commonAncestorContainer(mousePressNode, mouseReleaseNode))
     2079        if (auto commonAncestor = commonInclusiveAncestor(*mousePressNode, *mouseReleaseNode))
    20802080            return commonAncestor;
    20812081    }
    20822082
    2083     Element* mouseReleaseShadowHost = mouseReleaseNode->shadowHost();
     2083    auto mouseReleaseShadowHost = mouseReleaseNode->shadowHost();
    20842084    if (mouseReleaseShadowHost && mouseReleaseShadowHost == mousePressNode->shadowHost()) {
    20852085        // We want to dispatch the click to the shadow tree host element to give listeners the illusion that the
     
    20882088        return mouseReleaseShadowHost;
    20892089    }
     2090
    20902091    return nullptr;
    20912092}
     
    21602161    bool contextMenuEvent = platformMouseEvent.button() == RightButton;
    21612162
    2162     Node* nodeToClick = targetNodeForClickEvent(m_clickNode.get(), mouseEvent.targetNode());
    2163     bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && nodeToClick && !dispatchMouseEvent(eventNames().clickEvent, nodeToClick, true, m_clickCount, platformMouseEvent, true);
     2163    auto nodeToClick = targetNodeForClickEvent(m_clickNode.get(), mouseEvent.targetNode());
     2164    bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && nodeToClick && !dispatchMouseEvent(eventNames().clickEvent, nodeToClick.get(), true, m_clickCount, platformMouseEvent, true);
    21642165
    21652166    if (m_resizeLayer) {
  • trunk/Source/WebCore/page/Settings.yaml

    r259275 r260753  
    542542dataDetectorTypes:
    543543  type: DataDetectorTypes
    544   initial: DataDetectorTypeNone
     544  initial:
    545545  conditional: DATA_DETECTION
    546546
  • trunk/Source/WebCore/page/SettingsBase.h

    r260547 r260753  
    4444#include <wtf/text/AtomStringHash.h>
    4545
    46 #if ENABLE(DATA_DETECTION)
    47 #include "DataDetection.h"
    48 #endif
    49 
    5046namespace WebCore {
    5147
    5248class FontGenericFamilies;
    5349class Page;
     50
     51enum class DataDetectorTypes : uint32_t;
    5452
    5553enum EditableLinkBehavior {
  • trunk/Source/WebCore/page/TextIndicator.cpp

    r260725 r260753  
    5353namespace WebCore {
    5454
    55 static bool initializeIndicator(TextIndicatorData&, Frame&, const Range&, FloatSize margin, bool indicatesCurrentSelection);
     55static bool initializeIndicator(TextIndicatorData&, Frame&, const SimpleRange&, FloatSize margin, bool indicatesCurrentSelection);
    5656
    5757TextIndicator::TextIndicator(const TextIndicatorData& data)
     
    6767}
    6868
    69 RefPtr<TextIndicator> TextIndicator::createWithRange(const Range& range, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin)
    70 {
    71     Frame* frame = range.startContainer().document().frame();
    72 
     69RefPtr<TextIndicator> TextIndicator::createWithRange(const SimpleRange& range, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin)
     70{
     71    auto frame = makeRefPtr(range.startContainer().document().frame());
    7372    if (!frame)
    7473        return nullptr;
    7574
    76     Ref<Frame> protector(*frame);
    77 
    78     VisibleSelection oldSelection = frame->selection().selection();
     75    bool indicatesCurrentSelection = range == frame->selection().selection().toNormalizedRange();
     76
    7977    OptionSet<TemporarySelectionOption> temporarySelectionOptions;
    8078    temporarySelectionOptions.add(TemporarySelectionOption::DoNotSetFocus);
     
    8381    temporarySelectionOptions.add(TemporarySelectionOption::EnableAppearanceUpdates);
    8482#endif
    85     TemporarySelectionChange selectionChange(*frame, { SimpleRange { range } }, temporarySelectionOptions);
     83    TemporarySelectionChange selectionChange(*frame, { range }, temporarySelectionOptions);
    8684
    8785    TextIndicatorData data;
     
    9088    data.options = options;
    9189
    92     bool indicatesCurrentSelection = areRangesEqual(&range, createLiveRange(oldSelection.toNormalizedRange()).get());
    93 
    9490    if (!initializeIndicator(data, *frame, range, margin, indicatesCurrentSelection))
    9591        return nullptr;
     
    109105    data.options = options;
    110106
    111     if (!initializeIndicator(data, frame, createLiveRange(*range), margin, true))
     107    if (!initializeIndicator(data, frame, *range, margin, true))
    112108        return nullptr;
    113109
     
    115111}
    116112
    117 static bool hasNonInlineOrReplacedElements(const Range& range)
    118 {
    119     Node* stopNode = range.pastLastNode();
    120     for (Node* node = range.firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
    121         if (!node)
    122             continue;
    123         RenderObject* renderer = node->renderer();
    124         if (!renderer)
    125             continue;
    126         if ((!renderer->isInline() || renderer->isReplaced()) && range.intersectsNode(*node).releaseReturnValue())
     113static bool hasNonInlineOrReplacedElements(const SimpleRange& range)
     114{
     115    for (auto& node : intersectingNodes(range)) {
     116        auto renderer = node.renderer();
     117        if (renderer && (!renderer->isInline() || renderer->isReplaced()))
    127118            return true;
    128119    }
    129 
    130120    return false;
    131121}
     
    185175#if PLATFORM(IOS_FAMILY)
    186176
    187 static void getSelectionRectsForRange(Vector<FloatRect>& resultingRects, const Range& range)
    188 {
    189     Vector<SelectionRect> selectionRectsForRange;
    190     Vector<FloatRect> selectionRectsForRangeInBoundingRectCoordinates;
    191     range.collectSelectionRects(selectionRectsForRange);
    192     for (auto selectionRect : selectionRectsForRange)
    193         resultingRects.append(selectionRect.rect());
     177static Vector<FloatRect> selectionRects(const SimpleRange& range)
     178{
     179    Vector<SelectionRect> selectionRects;
     180    createLiveRange(range)->collectSelectionRects(selectionRects);
     181    Vector<FloatRect> rects;
     182    for (auto& selectionRect : selectionRects)
     183        rects.append(selectionRect.rect());
     184    return rects;
    194185}
    195186
     
    198189static bool styleContainsComplexBackground(const RenderStyle& style)
    199190{
    200     if (style.hasBlendMode())
    201         return true;
    202 
    203     if (style.hasBackgroundImage())
    204         return true;
    205 
    206     if (style.hasBackdropFilter())
    207         return true;
    208 
    209     return false;
    210 }
    211 
    212 static HashSet<Color> estimatedTextColorsForRange(const Range& range)
     191    return style.hasBlendMode() || style.hasBackgroundImage() || style.hasBackdropFilter();
     192}
     193
     194static HashSet<Color> estimatedTextColorsForRange(const SimpleRange& range)
    213195{
    214196    HashSet<Color> colors;
    215197    for (TextIterator iterator(range); !iterator.atEnd(); iterator.advance()) {
    216         auto* node = iterator.node();
    217         if (!is<Text>(node) || !is<RenderText>(node->renderer()))
    218             continue;
    219 
    220         colors.add(node->renderer()->style().color());
     198        auto renderer = iterator.node()->renderer();
     199        if (is<RenderText>(renderer))
     200            colors.add(renderer->style().color());
    221201    }
    222202    return colors;
    223203}
    224    
    225 static FloatRect absoluteBoundingRectForRange(const Range& range)
    226 {
    227     return range.absoluteBoundingRect({
     204
     205static FloatRect absoluteBoundingRectForRange(const SimpleRange& range)
     206{
     207    return createLiveRange(range)->absoluteBoundingRect({
    228208        Range::BoundingRectBehavior::RespectClipping,
    229209        Range::BoundingRectBehavior::UseVisibleBounds,
     
    232212}
    233213
    234 static Color estimatedBackgroundColorForRange(const Range& range, const Frame& frame)
     214static Color estimatedBackgroundColorForRange(const SimpleRange& range, const Frame& frame)
    235215{
    236216    auto estimatedBackgroundColor = frame.view() ? frame.view()->documentBackgroundColor() : Color::transparent;
    237217
    238218    RenderElement* renderer = nullptr;
    239     auto commonAncestor = range.commonAncestorContainer();
     219    auto commonAncestor = commonInclusiveAncestor(range.start.container, range.end.container);
    240220    while (commonAncestor) {
    241221        if (is<RenderElement>(commonAncestor->renderer())) {
     
    292272}
    293273
    294 static bool containsOnlyWhiteSpaceText(const Range& range)
    295 {
    296     auto* stop = range.pastLastNode();
    297     for (auto* node = range.firstNode(); node && node != stop; node = NodeTraversal::next(*node)) {
    298         if (!is<RenderText>(node->renderer()))
     274static bool containsOnlyWhiteSpaceText(const SimpleRange& range)
     275{
     276    for (auto& node : intersectingNodes(range)) {
     277        if (!is<RenderText>(node.renderer()))
    299278            return false;
    300279    }
     
    302281}
    303282
    304 static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Range& range, FloatSize margin, bool indicatesCurrentSelection)
     283static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const SimpleRange& range, FloatSize margin, bool indicatesCurrentSelection)
    305284{
    306285    if (auto* document = frame.document())
     
    312291        treatRangeAsComplexDueToIllegibleTextColors = hasAnyIllegibleColors(data, data.estimatedBackgroundColor, estimatedTextColorsForRange(range));
    313292    }
    314 
    315     Vector<FloatRect> textRects;
    316293
    317294    // FIXME (138888): Ideally we wouldn't remove the margin in this case, but we need to
     
    321298        margin = FloatSize();
    322299
    323     FrameSelection::TextRectangleHeight textRectHeight = (data.options & TextIndicatorOptionTightlyFitContent) ? FrameSelection::TextRectangleHeight::TextHeight : FrameSelection::TextRectangleHeight::SelectionHeight;
     300    Vector<FloatRect> textRects;
    324301
    325302    bool useBoundingRectAndPaintAllContentForComplexRanges = data.options & TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges;
    326303    if (useBoundingRectAndPaintAllContentForComplexRanges && containsOnlyWhiteSpaceText(range)) {
    327         auto commonAncestorContainer = makeRefPtr(range.commonAncestorContainer());
    328         if (auto* containerRenderer = commonAncestorContainer->renderer()) {
     304        if (auto* containerRenderer = commonInclusiveAncestor(range.start.container, range.end.container)->renderer()) {
    329305            data.options |= TextIndicatorOptionPaintAllContent;
    330306            textRects.append(containerRenderer->absoluteBoundingBoxRect());
     
    334310#if PLATFORM(IOS_FAMILY)
    335311    else if (data.options & TextIndicatorOptionUseSelectionRectForSizing)
    336         getSelectionRectsForRange(textRects, range);
     312        textRects = selectionRects(range);
    337313#endif
    338314    else {
    339         Vector<IntRect> absoluteTextRects;
    340         range.absoluteTextRects(absoluteTextRects, textRectHeight == FrameSelection::TextRectangleHeight::SelectionHeight, Range::BoundingRectBehavior::RespectClipping);
    341 
    342         textRects.reserveInitialCapacity(absoluteTextRects.size());
    343         for (auto& rect : absoluteTextRects)
    344             textRects.uncheckedAppend(rect);
     315        auto textRectHeight = (data.options & TextIndicatorOptionTightlyFitContent) ? FrameSelection::TextRectangleHeight::TextHeight : FrameSelection::TextRectangleHeight::SelectionHeight;
     316        Vector<IntRect> intRects;
     317        createLiveRange(range)->absoluteTextRects(intRects, textRectHeight == FrameSelection::TextRectangleHeight::SelectionHeight, Range::BoundingRectBehavior::RespectClipping);
     318        textRects.reserveInitialCapacity(intRects.size());
     319        for (auto& intRect : intRects)
     320            textRects.uncheckedAppend(intRect);
    345321    }
    346322
  • trunk/Source/WebCore/page/TextIndicator.h

    r218068 r260753  
    3535class Frame;
    3636class GraphicsContext;
    37 class Range;
     37
     38struct SimpleRange;
    3839
    3940// FIXME: Move PresentationTransition to TextIndicatorWindow, because it's about presentation.
     
    124125    WEBCORE_EXPORT static Ref<TextIndicator> create(const TextIndicatorData&);
    125126    WEBCORE_EXPORT static RefPtr<TextIndicator> createWithSelectionInFrame(Frame&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin));
    126     WEBCORE_EXPORT static RefPtr<TextIndicator> createWithRange(const Range&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin));
     127    WEBCORE_EXPORT static RefPtr<TextIndicator> createWithRange(const SimpleRange&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin));
    127128
    128129    WEBCORE_EXPORT ~TextIndicator();
  • trunk/Source/WebCore/page/mac/ServicesOverlayController.h

    r257465 r260753  
    5656        WTF_MAKE_NONCOPYABLE(Highlight);
    5757    public:
    58         static Ref<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>, Ref<Range>&&);
    59         static Ref<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, Ref<Range>&&);
     58        static Ref<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>&&, SimpleRange&&);
     59        static Ref<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>&&, SimpleRange&&);
    6060        ~Highlight();
    6161
     
    6363
    6464        DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
    65         Range& range() const { return m_range.get(); }
     65        const SimpleRange& range() const { return m_range; }
    6666        GraphicsLayer& layer() const { return m_graphicsLayer.get(); }
    6767
     
    7979
    8080    private:
    81         Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, Ref<Range>&&);
     81        Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>&&, SimpleRange&&);
    8282
    8383        // GraphicsLayerClient
     
    9090        ServicesOverlayController* m_controller;
    9191        RetainPtr<DDHighlightRef> m_ddHighlight;
    92         Ref<Range> m_range;
     92        SimpleRange m_range;
    9393        Ref<GraphicsLayer> m_graphicsLayer;
    9494        Type m_type;
     
    127127    void determineActiveHighlightTimerFired();
    128128
    129     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
     129    static bool highlightsAreEquivalent(const Highlight*, const Highlight*);
    130130
    131     Vector<RefPtr<Range>> telephoneNumberRangesForFocusedFrame();
     131    Vector<SimpleRange> telephoneNumberRangesForFocusedFrame();
    132132
    133133    void didCreateHighlight(Highlight*);
  • trunk/Source/WebCore/page/mac/ServicesOverlayController.mm

    r260725 r260753  
    5656namespace WebCore {
    5757
    58 Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForSelection(ServicesOverlayController& controller, RetainPtr<DDHighlightRef> ddHighlight, Ref<Range>&& range)
    59 {
    60     return adoptRef(*new Highlight(controller, Highlight::SelectionType, ddHighlight, WTFMove(range)));
    61 }
    62 
    63 Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForTelephoneNumber(ServicesOverlayController& controller, RetainPtr<DDHighlightRef> ddHighlight, Ref<Range>&& range)
    64 {
    65     return adoptRef(*new Highlight(controller, Highlight::TelephoneNumberType, ddHighlight, WTFMove(range)));
    66 }
    67 
    68 ServicesOverlayController::Highlight::Highlight(ServicesOverlayController& controller, Type type, RetainPtr<DDHighlightRef> ddHighlight, Ref<WebCore::Range>&& range)
     58Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForSelection(ServicesOverlayController& controller, RetainPtr<DDHighlightRef>&& ddHighlight, SimpleRange&& range)
     59{
     60    return adoptRef(*new Highlight(controller, Highlight::SelectionType, WTFMove(ddHighlight), WTFMove(range)));
     61}
     62
     63Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForTelephoneNumber(ServicesOverlayController& controller, RetainPtr<DDHighlightRef>&& ddHighlight, SimpleRange&& range)
     64{
     65    return adoptRef(*new Highlight(controller, Highlight::TelephoneNumberType, WTFMove(ddHighlight), WTFMove(range)));
     66}
     67
     68ServicesOverlayController::Highlight::Highlight(ServicesOverlayController& controller, Type type, RetainPtr<DDHighlightRef>&& ddHighlight, SimpleRange&& range)
    6969    : m_controller(&controller)
    7070    , m_range(WTFMove(range))
     
    475475void ServicesOverlayController::buildPhoneNumberHighlights()
    476476{
    477     Vector<RefPtr<Range>> phoneNumberRanges;
     477    Vector<SimpleRange> phoneNumberRanges;
    478478    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
    479479        phoneNumberRanges.appendVector(frame->editor().detectedTelephoneNumberRanges());
     
    493493    for (auto& range : phoneNumberRanges) {
    494494        // FIXME: This makes a big rect if the range extends from the end of one line to the start of the next. Handle that case better?
    495         auto rect = enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(*range)));
     495        auto rect = enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(range)));
    496496
    497497        // Convert to the main document's coordinate space.
     
    499499        // We should consider adding conversion functions to ScrollView for contentsToDocument(). Right now, contentsToRootView() is
    500500        // not equivalent to what we need when you have a topContentInset or a header banner.
    501         auto* viewForRange = range->ownerDocument().view();
     501        auto* viewForRange = range.start.document().view();
    502502        if (!viewForRange)
    503503            continue;
     
    506506
    507507        CGRect cgRect = rect;
    508        
    509508#if HAVE(DD_HIGHLIGHT_CREATE_WITH_SCALE)
    510         RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleScaleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightStyleBubbleStandard | DDHighlightStyleStandardIconArrow, YES, NSWritingDirectionNatural, NO, YES, 0));
     509        auto ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleScaleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightStyleBubbleStandard | DDHighlightStyleStandardIconArrow, YES, NSWritingDirectionNatural, NO, YES, 0));
    511510#else
    512         RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightStyleBubbleStandard | DDHighlightStyleStandardIconArrow, YES, NSWritingDirectionNatural, NO, YES));
     511        auto ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, &cgRect, 1, mainFrameView.visibleContentRect(), DDHighlightStyleBubbleStandard | DDHighlightStyleStandardIconArrow, YES, NSWritingDirectionNatural, NO, YES));
    513512#endif
    514         newPotentialHighlights.add(Highlight::createForTelephoneNumber(*this, ddHighlight, range.releaseNonNull()));
     513        newPotentialHighlights.add(Highlight::createForTelephoneNumber(*this, WTFMove(ddHighlight), WTFMove(range)));
    515514    }
    516515
     
    545544            IntRect currentRect = snappedIntRect(rect);
    546545            currentRect.setLocation(mainFrameView->windowToContents(viewForRange->contentsToWindow(currentRect.location())));
    547             cgRects.append((CGRect)currentRect);
     546            cgRects.append(currentRect);
    548547        }
    549548
     
    551550            CGRect visibleRect = mainFrameView->visibleContentRect();
    552551#if HAVE(DD_HIGHLIGHT_CREATE_WITH_SCALE)
    553             RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleScaleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightStyleBubbleNone | DDHighlightStyleStandardIconArrow | DDHighlightStyleButtonShowAlways, YES, NSWritingDirectionNatural, NO, YES, 0));
     552            auto ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleScaleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightStyleBubbleNone | DDHighlightStyleStandardIconArrow | DDHighlightStyleButtonShowAlways, YES, NSWritingDirectionNatural, NO, YES, 0));
    554553#else
    555             RetainPtr<DDHighlightRef> ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightStyleBubbleNone | DDHighlightStyleStandardIconArrow | DDHighlightStyleButtonShowAlways, YES, NSWritingDirectionNatural, NO, YES));
     554            auto ddHighlight = adoptCF(DDHighlightCreateWithRectsInVisibleRectWithStyleAndDirection(nullptr, cgRects.begin(), cgRects.size(), visibleRect, DDHighlightStyleBubbleNone | DDHighlightStyleStandardIconArrow | DDHighlightStyleButtonShowAlways, YES, NSWritingDirectionNatural, NO, YES));
    556555#endif
    557             newPotentialHighlights.add(Highlight::createForSelection(*this, ddHighlight, createLiveRange(*selectionRange)));
     556            newPotentialHighlights.add(Highlight::createForSelection(*this, WTFMove(ddHighlight), WTFMove(*selectionRange)));
    558557        }
    559558    }
     
    608607}
    609608
    610 Vector<RefPtr<Range>> ServicesOverlayController::telephoneNumberRangesForFocusedFrame()
     609Vector<SimpleRange> ServicesOverlayController::telephoneNumberRangesForFocusedFrame()
    611610{
    612611    return m_page.focusController().focusedOrMainFrame().editor().detectedTelephoneNumberRanges();
     
    619618    if (!a || !b)
    620619        return false;
    621     return a->type() == b->type() && areRangesEqual(&a->range(), &b->range());
     620    return a->type() == b->type() && a->range() == b->range();
    622621}
    623622
     
    632631
    633632    for (auto& highlight : m_potentialHighlights) {
    634         if (highlight->type() == Highlight::TelephoneNumberType && highlight->range().contains(createLiveRange(*selectionRange)))
     633        if (highlight->type() == Highlight::TelephoneNumberType && createLiveRange(highlight->range())->contains(createLiveRange(*selectionRange)))
    635634            return highlight.get();
    636635    }
     
    788787        selectedTelephoneNumbers.reserveCapacity(telephoneNumberRanges.size());
    789788        for (auto& range : telephoneNumberRanges)
    790             selectedTelephoneNumbers.append(range->text());
     789            selectedTelephoneNumbers.append(plainText(range));
    791790
    792791        m_page.chrome().client().handleSelectionServiceClick(m_page.focusController().focusedOrMainFrame().selection(), selectedTelephoneNumbers, windowPoint);
    793792    } else if (highlight.type() == Highlight::TelephoneNumberType)
    794         m_page.chrome().client().handleTelephoneNumberClick(highlight.range().text(), windowPoint);
     793        m_page.chrome().client().handleTelephoneNumberClick(plainText(highlight.range()), windowPoint);
    795794}
    796795
  • trunk/Source/WebCore/platform/ios/DragImageIOS.mm

    r249217 r260753  
    4141#import "Page.h"
    4242#import "Range.h"
     43#import "SimpleRange.h"
    4344#import "StringTruncator.h"
    4445#import "TextIndicator.h"
     
    136137    CGRect imageRect = CGRectMake(0, 0, textWidth + 2 * dragImagePadding, textHeight + 2 * dragImagePadding);
    137138
    138     RetainPtr<UIGraphicsImageRenderer> render = adoptNS([PAL::allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size]);
    139     UIImage *image = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
     139    auto renderer = adoptNS([PAL::allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size]);
     140    auto image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
    140141        GraphicsContext context(rendererContext.CGContext);
    141142        context.translate(0, CGRectGetHeight(imageRect));
     
    147148    }];
    148149
    149     auto linkRange = rangeOfContents(linkElement);
    150     if (auto textIndicator = TextIndicator::createWithRange(linkRange, defaultLinkIndicatorOptions, TextIndicatorPresentationTransition::None, FloatSize()))
     150    if (auto textIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(linkElement), defaultLinkIndicatorOptions, TextIndicatorPresentationTransition::None, FloatSize()))
    151151        indicatorData = textIndicator->data();
    152152
     
    192192
    193193
    194     RetainPtr<UIGraphicsImageRenderer> render = adoptNS([PAL::allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size()]);
    195     UIImage *finalImage = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
     194    auto renderer = adoptNS([PAL::allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size()]);
     195    return [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
    196196        GraphicsContext context(rendererContext.CGContext);
    197197        // FIXME: The context flip here should not be necessary, and suggests that somewhere else in the regular
     
    200200        context.scale({ 1, -1 });
    201201        context.drawImage(*image, imageRect);
    202     }];
    203 
    204     return finalImage.CGImage;
     202    }].CGImage;
    205203}
    206204
  • trunk/Source/WebKit/ChangeLog

    r260752 r260753  
     12020-04-26  Darin Adler  <darin@apple.com>
     2
     3        Replace more uses of live ranges with SimpleRange
     4        https://bugs.webkit.org/show_bug.cgi?id=211058
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * Shared/API/Cocoa/WKDataDetectorTypesInternal.h:
     9        (fromWKDataDetectorTypes): Updated since DataDetectorTypes
     10        is now an enum class. Also got rid of special "none" and "all" values.
     11
     12        * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInRangeHandle.mm:
     13        (-[WKWebProcessPlugInRangeHandle detectDataWithTypes:context:]): Updated
     14        since DataDetection now takes a SimpleRange.
     15
     16        * WebProcess/WebPage/ViewGestureGeometryCollector.cpp:
     17        (WebKit::ViewGestureGeometryCollector::computeTextLegibilityScales):
     18        Use SimpleRange.
     19        * WebProcess/WebPage/WebPage.cpp:
     20        (WebKit::WebPage::detectDataInAllFrames): Ditto.
     21
     22        * WebProcess/WebPage/WebPage.h: Removed unneeded include of DataDetection.h.
     23
     24        * WebProcess/WebPage/mac/WebPageMac.mm:
     25        (WebKit::WebPage::performImmediateActionHitTestAtLocation): Use SimpleRange.
     26
    1272020-04-27  Carlos Garcia Campos  <cgarcia@igalia.com>
    228
  • trunk/Source/WebKit/Shared/API/Cocoa/WKDataDetectorTypesInternal.h

    r242339 r260753  
    3232static inline WebCore::DataDetectorTypes fromWKDataDetectorTypes(uint64_t types)
    3333{
    34     if (static_cast<WKDataDetectorTypes>(types) == WKDataDetectorTypeNone)
    35         return WebCore::DataDetectorTypeNone;
    36     if (static_cast<WKDataDetectorTypes>(types) == WKDataDetectorTypeAll)
    37         return WebCore::DataDetectorTypeAll;
    38 
    39     uint32_t value = WebCore::DataDetectorTypeNone;
     34    uint32_t value = 0;
    4035    if (types & WKDataDetectorTypePhoneNumber)
    41         value |= WebCore::DataDetectorTypePhoneNumber;
     36        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::PhoneNumber);
    4237    if (types & WKDataDetectorTypeLink)
    43         value |= WebCore::DataDetectorTypeLink;
     38        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::Link);
    4439    if (types & WKDataDetectorTypeAddress)
    45         value |= WebCore::DataDetectorTypeAddress;
     40        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::Address);
    4641    if (types & WKDataDetectorTypeCalendarEvent)
    47         value |= WebCore::DataDetectorTypeCalendarEvent;
     42        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::CalendarEvent);
    4843    if (types & WKDataDetectorTypeTrackingNumber)
    49         value |= WebCore::DataDetectorTypeTrackingNumber;
     44        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::TrackingNumber);
    5045    if (types & WKDataDetectorTypeFlightNumber)
    51         value |= WebCore::DataDetectorTypeFlightNumber;
     46        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::FlightNumber);
    5247    if (types & WKDataDetectorTypeLookupSuggestion)
    53         value |= WebCore::DataDetectorTypeLookupSuggestion;
    54 
     48        value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::LookupSuggestion);
    5549    return static_cast<WebCore::DataDetectorTypes>(value);
    5650}
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInRangeHandle.mm

    r242339 r260753  
    6464
    6565#if TARGET_OS_IPHONE
     66
    6667- (NSArray *)detectDataWithTypes:(WKDataDetectorTypes)types context:(NSDictionary *)context
    6768{
    6869#if ENABLE(DATA_DETECTION)
    69     RefPtr<WebCore::Range> coreRange = &_rangeHandle->coreRange();
    70     return WebCore::DataDetection::detectContentInRange(coreRange, fromWKDataDetectorTypes(types), context);
     70    return WebCore::DataDetection::detectContentInRange(_rangeHandle->coreRange(), fromWKDataDetectorTypes(types), context);
    7171#else
    7272    return nil;
    7373#endif
    7474}
     75
    7576#endif
    7677
  • trunk/Source/WebKit/WebProcess/WebPage/ViewGestureGeometryCollector.cpp

    r259200 r260753  
    157157    document->updateLayoutIgnorePendingStylesheets();
    158158
    159     auto documentRange = Range::create(*document, {{ document->documentElement(), Position::PositionIsBeforeAnchor }}, {{ document->documentElement(), Position::PositionIsAfterAnchor }});
    160159    HashSet<Node*> allTextNodes;
    161160    HashMap<unsigned, unsigned> fontSizeToCountMap;
     
    163162    unsigned totalSampledTextLength = 0;
    164163
    165     for (TextIterator documentTextIterator { documentRange.get(), TextIteratorEntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) {
     164    for (TextIterator documentTextIterator { makeRangeSelectingNodeContents(*document), TextIteratorEntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) {
    166165        if (++numberOfIterations >= maximumNumberOfTextRunsToConsider)
    167166            break;
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r260752 r260753  
    37323732        if (!document)
    37333733            continue;
    3734 
    3735         RefPtr<Range> range = Range::create(*document, Position { document.get(), Position::PositionIsBeforeChildren }, Position { document.get(), Position::PositionIsAfterChildren });
    3736         frame->setDataDetectionResults(DataDetection::detectContentInRange(range, dataDetectorTypes, m_dataDetectionContext.get()));
     3734        frame->setDataDetectionResults(DataDetection::detectContentInRange(makeRangeSelectingNodeContents(*document), dataDetectorTypes, m_dataDetectionContext.get()));
    37373735    }
    37383736    completionHandler({ m_page->mainFrame().dataDetectionResults() });
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r260752 r260753  
    130130#endif
    131131
    132 #if ENABLE(DATA_DETECTION)
    133 #include <WebCore/DataDetection.h>
    134 #endif
    135 
    136132#if ENABLE(MAC_GESTURE_EVENTS)
    137133#include <WebKitAdditions/PlatformGestureEventMac.h>
  • trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm

    r260739 r260753  
    858858    Element* URLElement = hitTestResult.URLElement();
    859859    if (!absoluteLinkURL.isEmpty() && URLElement)
    860         immediateActionResult.linkTextIndicator = TextIndicator::createWithRange(rangeOfContents(*URLElement), TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn);
     860        immediateActionResult.linkTextIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(*URLElement), TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn);
    861861
    862862    auto lookupResult = lookupTextAtLocation(locationInViewCoordinates);
     
    896896    // FIXME: Avoid scanning if we will just throw away the result (e.g. we're over a link).
    897897    if (!pageOverlayDidOverrideDataDetectors && hitTestResult.innerNode() && (hitTestResult.innerNode()->isTextNode() || hitTestResult.isOverTextInsideFormControlElement())) {
    898         FloatRect detectedDataBoundingBox;
    899         RefPtr<Range> detectedDataRange;
    900         immediateActionResult.detectedDataActionContext = DataDetection::detectItemAroundHitTestResult(hitTestResult, detectedDataBoundingBox, detectedDataRange);
    901         if (immediateActionResult.detectedDataActionContext && detectedDataRange) {
    902             immediateActionResult.detectedDataBoundingBox = detectedDataBoundingBox;
    903             immediateActionResult.detectedDataTextIndicator = TextIndicator::createWithRange(*detectedDataRange, TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn);
     898        if (auto result = DataDetection::detectItemAroundHitTestResult(hitTestResult)) {
     899            immediateActionResult.detectedDataActionContext = WTFMove(result->actionContext);
     900            immediateActionResult.detectedDataBoundingBox = result->boundingBox;
     901            immediateActionResult.detectedDataTextIndicator = TextIndicator::createWithRange(result->range,
     902                TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn);
    904903        }
    905904    }
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r260751 r260753  
     12020-04-26  Darin Adler  <darin@apple.com>
     2
     3        Replace more uses of live ranges with SimpleRange
     4        https://bugs.webkit.org/show_bug.cgi?id=211058
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * DOM/DOM.mm:
     9        (-[DOMNode getPreviewSnapshotImage:andRects:]): Use SimpleRange.
     10        * WebCoreSupport/WebContextMenuClient.mm:
     11        (WebContextMenuClient::imageForCurrentSharingServicePickerItem): Ditto.
     12
     13        * WebView/WebImmediateActionController.mm:
     14        (-[WebImmediateActionController _animationControllerForDataDetectedText]):
     15        Updated to use DetectedItem and SimpleRange.
     16        (+[WebImmediateActionController _dictionaryPopupInfoForRange:inFrame:withLookupOptions:indicatorOptions:transition:]):
     17        Ditto.
     18
    1192020-04-27  Rob Buis  <rbuis@igalia.com>
    220
  • trunk/Source/WebKitLegacy/mac/DOM/DOM.mm

    r260485 r260753  
    524524    auto& node = *core(self);
    525525
    526     auto range = rangeOfContents(node);
    527 
    528526    const float margin = 4 / node.document().page()->pageScaleFactor();
    529     auto textIndicator = TextIndicator::createWithRange(range, TextIndicatorOptionTightlyFitContent |
     527    auto textIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(node), TextIndicatorOptionTightlyFitContent |
    530528        TextIndicatorOptionRespectTextColor |
    531529        TextIndicatorOptionPaintBackgrounds |
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebContextMenuClient.mm

    r258129 r260753  
    149149
    150150#if ENABLE(SERVICE_CONTROLS)
     151
    151152void WebContextMenuClient::sharingServicePickerWillBeDestroyed(WebSharingServicePickerController &)
    152153{
     
    184185RetainPtr<NSImage> WebContextMenuClient::imageForCurrentSharingServicePickerItem(WebSharingServicePickerController &)
    185186{
    186     Page* page = [m_webView page];
    187     if (!page)
    188         return nil;
    189 
    190     Node* node = page->contextMenuController().context().hitTestResult().innerNode();
     187    auto page = [m_webView page];
     188    if (!page)
     189        return nil;
     190
     191    auto node = makeRefPtr(page->contextMenuController().context().hitTestResult().innerNode());
    191192    if (!node)
    192193        return nil;
    193194
    194     FrameView* frameView = node->document().view();
     195    auto frameView = makeRefPtr(node->document().view());
    195196    if (!frameView) {
    196197        // This method shouldn't be called in cases where the controlled node isn't in a rendered view.
     
    204205
    205206    // This is effectively a snapshot, and will be painted in an unaccelerated fashion in line with FrameSnapshotting.
    206     std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(rect.size(), RenderingMode::Unaccelerated);
     207    auto buffer = ImageBuffer::create(rect.size(), RenderingMode::Unaccelerated);
    207208    if (!buffer)
    208209        return nil;
    209210
    210     VisibleSelection oldSelection = frameView->frame().selection().selection();
    211     auto range = Range::create(node->document(), Position(node, Position::PositionIsBeforeAnchor), Position(node, Position::PositionIsAfterAnchor));
    212     frameView->frame().selection().setSelection(VisibleSelection(range.get()), FrameSelection::DoNotSetFocus);
    213 
    214     OptionSet<PaintBehavior> oldPaintBehavior = frameView->paintBehavior();
     211    auto oldSelection = frameView->frame().selection().selection();
     212    frameView->frame().selection().setSelection(*makeRangeSelectingNode(*node), FrameSelection::DoNotSetFocus);
     213
     214    auto oldPaintBehavior = frameView->paintBehavior();
    215215    frameView->setPaintBehavior(PaintBehavior::SelectionOnly);
    216216
     
    221221    frameView->setPaintBehavior(oldPaintBehavior);
    222222
    223     RefPtr<Image> image = ImageBuffer::sinkIntoImage(WTFMove(buffer));
     223    auto image = ImageBuffer::sinkIntoImage(WTFMove(buffer));
    224224    if (!image)
    225225        return nil;
     
    227227    return image->snapshotNSImage();
    228228}
     229
    229230#endif
    230231
  • trunk/Source/WebKitLegacy/mac/WebView/WebImmediateActionController.mm

    r260739 r260753  
    412412        return nil;
    413413
    414     RefPtr<WebCore::Range> detectedDataRange;
    415     WebCore::FloatRect detectedDataBoundingBox;
    416     RetainPtr<DDActionContext> actionContext;
     414    Optional<WebCore::DetectedItem> detectedItem;
    417415
    418416    if ([[_webView UIDelegate] respondsToSelector:@selector(_webView:actionContextForHitTestResult:range:)]) {
    419         RetainPtr<WebElementDictionary> hitTestDictionary = adoptNS([[WebElementDictionary alloc] initWithHitTestResult:_hitTestResult]);
    420 
    421417        DOMRange *customDataDetectorsRange;
    422         actionContext = [(id)[_webView UIDelegate] _webView:_webView actionContextForHitTestResult:hitTestDictionary.get() range:&customDataDetectorsRange];
    423 
    424         if (actionContext && customDataDetectorsRange)
    425             detectedDataRange = core(customDataDetectorsRange);
     418        auto actionContext = [(id)[_webView UIDelegate] _webView:_webView
     419            actionContextForHitTestResult:adoptNS([[WebElementDictionary alloc] initWithHitTestResult:_hitTestResult]).get()
     420            range:&customDataDetectorsRange];
     421        if (actionContext && customDataDetectorsRange) {
     422            detectedItem = { {
     423                actionContext,
     424                { }, // FIXME: Seems like an empty rect isn't really OK.
     425                *core(customDataDetectorsRange)
     426            } };
     427        }
    426428    }
    427429
    428430    // If the client didn't give us an action context, try to scan around the hit point.
    429     if (!actionContext || !detectedDataRange)
    430         actionContext = WebCore::DataDetection::detectItemAroundHitTestResult(_hitTestResult, detectedDataBoundingBox, detectedDataRange);
    431 
    432     if (!actionContext || !detectedDataRange)
    433         return nil;
    434 
    435     [actionContext setAltMode:YES];
    436     [actionContext setImmediate:YES];
    437     if (![[getDDActionsManagerClass() sharedManager] hasActionsForResult:[actionContext mainResult] actionContext:actionContext.get()])
    438         return nil;
    439 
    440     auto indicator = WebCore::TextIndicator::createWithRange(*detectedDataRange, WebCore::TextIndicatorOptionDefault, WebCore::TextIndicatorPresentationTransition::FadeIn);
    441 
    442     _currentActionContext = [actionContext contextForView:_webView altMode:YES interactionStartedHandler:^() {
     431    if (!detectedItem)
     432        detectedItem = WebCore::DataDetection::detectItemAroundHitTestResult(_hitTestResult);
     433
     434    if (!detectedItem)
     435        return nil;
     436
     437    [detectedItem->actionContext setAltMode:YES];
     438    [detectedItem->actionContext setImmediate:YES];
     439    if (![[getDDActionsManagerClass() sharedManager] hasActionsForResult:[detectedItem->actionContext mainResult] actionContext:detectedItem->actionContext.get()])
     440        return nil;
     441
     442    auto indicator = WebCore::TextIndicator::createWithRange(createLiveRange(detectedItem->range), WebCore::TextIndicatorOptionDefault, WebCore::TextIndicatorPresentationTransition::FadeIn);
     443
     444    _currentActionContext = [detectedItem->actionContext contextForView:_webView altMode:YES interactionStartedHandler:^() {
    443445    } interactionChangedHandler:^() {
    444446        if (indicator)
     
    448450    }];
    449451
    450     [_currentActionContext setHighlightFrame:[_webView.window convertRectToScreen:detectedDataBoundingBox]];
     452    [_currentActionContext setHighlightFrame:[_webView.window convertRectToScreen:detectedItem->boundingBox]];
    451453
    452454    NSArray *menuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForResult:[_currentActionContext mainResult] actionContext:_currentActionContext.get()];
     
    537539    popupInfo.attributedString = scaledAttributedString.get();
    538540
    539     if (auto textIndicator = WebCore::TextIndicator::createWithRange(createLiveRange(range), indicatorOptions, presentationTransition))
     541    if (auto textIndicator = WebCore::TextIndicator::createWithRange(range, indicatorOptions, presentationTransition))
    540542        popupInfo.textIndicator = textIndicator->data();
    541543
Note: See TracChangeset for help on using the changeset viewer.