Changeset 260753 in webkit
- Timestamp:
- Apr 27, 2020 8:05:00 AM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 45 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r260752 r260753 1 2020-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 1 136 2020-04-27 Carlos Garcia Campos <cgarcia@igalia.com> 2 137 -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r260725 r260753 634 634 // is handled consistently. 635 635 Document* nodeDocument = nullptr; 636 RefPtr<Range> textRange;636 Optional<SimpleRange> textRange; 637 637 if (Node* node = m_renderer->node()) { 638 638 nodeDocument = &node->document(); 639 textRange = rangeOfContents(*node);639 textRange = makeRangeSelectingNodeContents(*node); 640 640 } else { 641 641 // For anonymous blocks, we work around not having a direct node to create a range from … … 651 651 652 652 nodeDocument = &firstNodeInBlock->document(); 653 textRange = Range::create(*nodeDocument, startPosition, endPosition);653 textRange = { { *makeBoundaryPoint(startPosition), *makeBoundaryPoint(endPosition) } }; 654 654 } 655 655 } -
trunk/Source/WebCore/dom/BoundaryPoint.h
r259401 r260753 48 48 49 49 BoundaryPoint makeBoundaryPointBeforeNodeContents(Node&); 50 BoundaryPoint makeBoundaryPointAfterNodeContents(Node&); 50 51 51 52 inline BoundaryPoint::BoundaryPoint(Ref<Node>&& container, unsigned offset) … … 83 84 } 84 85 86 inline BoundaryPoint makeBoundaryPointAfterNodeContents(Node& node) 87 { 88 return { node, node.length() }; 85 89 } 90 91 } -
trunk/Source/WebCore/dom/Node.cpp
r259933 r260753 2613 2613 } 2614 2614 2615 RefPtr<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 2615 2626 TextStream& operator<<(TextStream& ts, const Node& node) 2616 2627 { -
trunk/Source/WebCore/dom/Node.h
r259933 r260753 671 671 }; 672 672 673 WEBCORE_EXPORT RefPtr<Node> commonInclusiveAncestor(Node&, Node&); 674 673 675 #if ASSERT_ENABLED 674 676 -
trunk/Source/WebCore/dom/Position.cpp
r259930 r260753 1571 1571 auto* nodeB = commonScope->ancestorNodeInThisScope(b.containerNode()); 1572 1572 ASSERT(nodeB); 1573 return Range::commonAncestorContainer(nodeA,nodeB);1573 return commonInclusiveAncestor(*nodeA, *nodeB); 1574 1574 } 1575 1575 -
trunk/Source/WebCore/dom/Range.cpp
r259933 r260753 144 144 } 145 145 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 157 146 static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& start, const RangeBoundaryPoint& end) 158 147 { … … 240 229 // DOM4 spec requires us to check whether refNode and start container have the same root first 241 230 // but we do it in the reverse order to avoid O(n) operation here in common case. 242 if (!common AncestorContainer(&refNode, &startContainer()))231 if (!commonInclusiveAncestor(refNode, startContainer())) 243 232 return false; 244 233 return checkNodeResult.releaseException(); … … 264 253 // DOM4 spec requires us to check whether refNode and start container have the same root first 265 254 // but we do it in the reverse order to avoid O(n) operation here in common case. 266 if (!refNode.isConnected() && !common AncestorContainer(&refNode, &startContainer()))255 if (!refNode.isConnected() && !commonInclusiveAncestor(refNode, startContainer())) 267 256 return Exception { WrongDocumentError }; 268 257 return checkNodeResult.releaseException(); … … 422 411 // case 4: containers A & B are siblings, or children of siblings 423 412 // ### we need to do a traversal here instead 424 auto * commonAncestor = commonAncestorContainer(containerA,containerB);413 auto commonAncestor = commonInclusiveAncestor(*containerA, *containerB); 425 414 if (!commonAncestor) 426 415 return Exception { WrongDocumentError }; … … 429 418 childA = childA->parentNode(); 430 419 if (!childA) 431 childA = commonAncestor ;420 childA = commonAncestor.get(); 432 421 Node* childB = containerB; 433 422 while (childB && childB->parentNode() != commonAncestor) 434 423 childB = childB->parentNode(); 435 424 if (!childB) 436 childB = commonAncestor ;425 childB = commonAncestor.get(); 437 426 438 427 if (childA == childB) … … 1291 1280 } 1292 1281 1293 // The range could span overnodes with different writing modes.1282 // The range could span nodes with different writing modes. 1294 1283 // If this is the case, we use the writing mode of the common ancestor. 1295 1284 if (containsDifferentWritingModes) { 1296 if ( Node* ancestor = commonAncestorContainer(&startContainer, &endContainer))1285 if (auto ancestor = commonInclusiveAncestor(startContainer, endContainer)) 1297 1286 hasFlippedWritingMode = ancestor->renderer()->style().isFlippedBlocksWritingMode(); 1298 1287 } -
trunk/Source/WebCore/dom/Range.h
r259933 r260753 61 61 bool collapsed() const { return m_start == m_end; } 62 62 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(); } 65 64 WEBCORE_EXPORT ExceptionOr<void> setStart(Ref<Node>&& container, unsigned offset); 66 65 WEBCORE_EXPORT ExceptionOr<void> setEnd(Ref<Node>&& container, unsigned offset); -
trunk/Source/WebCore/dom/SimpleRange.cpp
r260725 r260753 65 65 } 66 66 67 static BoundaryPoint makeBoundaryPointAfterNodeContents(Node& node)68 {69 return { node, node.length() };70 }71 72 67 SimpleRange makeRangeSelectingNodeContents(Node& node) 73 68 { -
trunk/Source/WebCore/editing/AlternativeTextController.cpp
r260725 r260753 218 218 void AlternativeTextController::respondToUnappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction) 219 219 { 220 if ( AlternativeTextClient*client = alternativeTextClient())220 if (auto client = alternativeTextClient()) 221 221 client->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, corrected, correction); 222 222 223 223 Ref<Frame> protector(m_frame); 224 224 m_frame.document()->updateLayout(); 225 225 226 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; 228 230 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); 232 234 } 233 235 … … 396 398 if (!command->wasCreateLinkCommand()) 397 399 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; 399 403 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); 402 406 } 403 407 … … 472 476 return; 473 477 474 auto precedingCharacterRange = Range::create(*m_frame.document(), precedingCharacterPosition, endOfSelection);478 auto precedingCharacterRange = SimpleRange { *makeBoundaryPoint(precedingCharacterPosition), *makeBoundaryPoint(endOfSelection) }; 475 479 String string = plainText(precedingCharacterRange); 476 480 if (string.isEmpty() || !deprecatedIsEditingWhitespace(string[string.length() - 1])) … … 485 489 bool AlternativeTextController::processMarkersOnTextToBeReplacedByResult(const TextCheckingResult& result, Range& rangeWithAlternative, const String& stringToBeReplaced) 486 490 { 487 DocumentMarkerController& markerController= m_frame.document()->markers();488 if (marker Controller.hasMarkers(rangeWithAlternative, DocumentMarker::Replacement)) {491 auto& markers = m_frame.document()->markers(); 492 if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::Replacement)) { 489 493 if (result.type == TextCheckingType::Correction) 490 494 recordSpellcheckerResponseForModifiedCorrection(rangeWithAlternative, stringToBeReplaced, result.replacement); … … 492 496 } 493 497 494 if (marker Controller.hasMarkers(rangeWithAlternative, DocumentMarker::RejectedCorrection))495 return false; 496 497 if (marker Controller.hasMarkers(rangeWithAlternative, DocumentMarker::AcceptedCandidate))498 if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::RejectedCorrection)) 499 return false; 500 501 if (markers.hasMarkers(rangeWithAlternative, DocumentMarker::AcceptedCandidate)) 498 502 return false; 499 503 500 504 Position beginningOfRange = rangeWithAlternative.startPosition(); 501 505 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)) { 506 510 if (marker->description() == stringToBeReplaced) 507 511 return false; -
trunk/Source/WebCore/editing/ChangeListTypeCommand.cpp
r244115 r260753 41 41 static Optional<std::pair<ChangeListTypeCommand::Type, Ref<HTMLElement>>> listConversionTypeForSelection(const VisibleSelection& selection) 42 42 { 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 43 49 RefPtr<HTMLElement> listToReplace; 44 auto commonAncestor = makeRefPtr(Range::commonAncestorContainer(selection.start().containerNode(), selection.end().containerNode()));45 50 if (is<HTMLUListElement>(commonAncestor) || is<HTMLOListElement>(commonAncestor)) 46 51 listToReplace = downcast<HTMLElement>(commonAncestor.get()); -
trunk/Source/WebCore/editing/Editing.cpp
r260725 r260753 1141 1141 // Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range. 1142 1142 // Call this function to determine whether a node is visibly fit inside selectedRange 1143 bool isNodeVisiblyContainedWithin(Node& node, const Range& range)1143 bool isNodeVisiblyContainedWithin(Node& node, const SimpleRange& range) 1144 1144 { 1145 1145 // 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); 1147 1147 if (!comparisonResult.hasException() && comparisonResult.releaseReturnValue() == Range::NODE_INSIDE) 1148 1148 return true; 1149 1149 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) 1152 1155 return true; 1153 1156 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) 1156 1159 return true; 1157 1160 -
trunk/Source/WebCore/editing/Editing.h
r260725 r260753 38 38 class HTMLSpanElement; 39 39 class HTMLTextFormControlElement; 40 class Range;41 40 class RenderBlock; 42 41 class VisiblePosition; … … 102 101 bool isNonTableCellHTMLBlockElement(const Node*); 103 102 104 bool isNodeVisiblyContainedWithin(Node&, const Range&);103 bool isNodeVisiblyContainedWithin(Node&, const SimpleRange&); 105 104 106 105 bool areIdenticalElements(const Node&, const Node&); -
trunk/Source/WebCore/editing/Editor.cpp
r260725 r260753 3212 3212 } 3213 3213 3214 void Editor::addRangeToKillRing(const Range& range, KillRingInsertionMode mode)3214 void Editor::addRangeToKillRing(const SimpleRange& range, KillRingInsertionMode mode) 3215 3215 { 3216 3216 addTextToKillRing(plainText(range), mode); … … 3686 3686 } 3687 3687 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 3690 bool Editor::shouldDetectTelephoneNumbers() const 3691 { 3692 return m_frame.document() && document().isTelephoneNumberParsingEnabled() && TelephoneNumberDetector::isSupported(); 3693 } 3694 3695 static Vector<SimpleRange> scanForTelephoneNumbers(const SimpleRange& range) 3748 3696 { 3749 3697 // Don't scan for phone numbers inside editable regions. 3750 Node& startNode = range.startContainer();3698 auto& startNode = range.startContainer(); 3751 3699 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(); 3757 3704 unsigned scannerPosition = 0; 3758 3705 int relativeStartPosition = 0; 3759 3706 int relativeEndPosition = 0; 3760 3761 auto characters = stringView.upconvertedCharacters(); 3762 3707 auto characters = StringView { text }.upconvertedCharacters(); 3763 3708 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 3716 static 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 3727 void 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(); 3779 3754 } 3780 3755 -
trunk/Source/WebCore/editing/Editor.h
r259938 r260753 418 418 419 419 enum class KillRingInsertionMode { PrependText, AppendText }; 420 void addRangeToKillRing(const Range&, KillRingInsertionMode);420 void addRangeToKillRing(const SimpleRange&, KillRingInsertionMode); 421 421 void addTextToKillRing(const String&, KillRingInsertionMode); 422 422 void setStartNewKillRingSequence(bool); … … 507 507 #endif 508 508 509 RefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, Range& context, bool allowPlainText, bool& chosePlainText);509 RefPtr<DocumentFragment> webContentFromPasteboard(Pasteboard&, const SimpleRange& context, bool allowPlainText, bool& chosePlainText); 510 510 511 511 WEBCORE_EXPORT const Font* fontForSelection(bool& hasMultipleFonts) const; … … 517 517 String stringSelectionForPasteboardWithImageAltText(); 518 518 void takeFindStringFromSelection(); 519 #if !PLATFORM(IOS_FAMILY) 519 WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote); 520 #endif 521 522 #if PLATFORM(MAC) 520 523 WEBCORE_EXPORT void readSelectionFromPasteboard(const String& pasteboardName); 521 524 WEBCORE_EXPORT void replaceNodeFromPasteboard(Node*, const String& pasteboardName); 522 525 WEBCORE_EXPORT RefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName); 523 #endif // !PLATFORM(IOS_FAMILY)524 WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);525 526 #endif 526 527 … … 533 534 #endif 534 535 535 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS_FAMILY)536 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC) 536 537 void scanSelectionForTelephoneNumbers(); 537 const Vector< RefPtr<Range>>& detectedTelephoneNumberRanges() const { return m_detectedTelephoneNumberRanges; }538 const Vector<SimpleRange>& detectedTelephoneNumberRanges() const { return m_detectedTelephoneNumberRanges; } 538 539 #endif 539 540 … … 649 650 bool m_isHandlingAcceptedCandidate { false }; 650 651 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; 654 654 655 655 Timer m_telephoneNumberDetectionUpdateTimer; 656 Vector< RefPtr<Range>> m_detectedTelephoneNumberRanges;656 Vector<SimpleRange> m_detectedTelephoneNumberRanges; 657 657 #endif 658 658 -
trunk/Source/WebCore/editing/TextManipulationController.cpp
r260678 r260753 597 597 commonAncestor = parent; 598 598 else if (!parent->isDescendantOf(commonAncestor.get())) { 599 commonAncestor = Range::commonAncestorContainer(commonAncestor.get(), parent.get());599 commonAncestor = commonInclusiveAncestor(*commonAncestor, *parent); 600 600 ASSERT(commonAncestor); 601 601 } -
trunk/Source/WebCore/editing/VisibleSelection.cpp
r260725 r260753 203 203 } 204 204 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; 205 static 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) } }; 225 215 } 226 216 … … 232 222 void VisibleSelection::appendTrailingWhitespace() 233 223 { 234 RefPtr<Range>searchRange = makeSearchRange(m_end);224 auto searchRange = makeSearchRange(m_end); 235 225 if (!searchRange) 236 226 return; -
trunk/Source/WebCore/editing/WebContentReader.h
r250256 r260753 29 29 #include "Frame.h" 30 30 #include "Pasteboard.h" 31 #include " Range.h"31 #include "SimpleRange.h" 32 32 #include "markup.h" 33 33 … … 35 35 36 36 class ArchiveResource; 37 class Blob;38 37 39 38 class FrameWebContentReader : public PasteboardWebContentReader { … … 53 52 class WebContentReader final : public FrameWebContentReader { 54 53 public: 55 Range&context;54 const SimpleRange context; 56 55 const bool allowPlainText; 57 56 … … 59 58 bool madeFragmentFromPlainText; 60 59 61 WebContentReader(Frame& frame, Range& context, bool allowPlainText)60 WebContentReader(Frame& frame, const SimpleRange& context, bool allowPlainText) 62 61 : FrameWebContentReader(frame) 63 62 , context(context) -
trunk/Source/WebCore/editing/cocoa/DataDetection.h
r238771 r260753 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(DATA_DETECTION) 29 29 30 #import <wtf/RefPtr.h> 30 #import "FloatRect.h" 31 #import "SimpleRange.h" 31 32 #import <wtf/RetainPtr.h> 32 #import <wtf/text/WTFString.h>33 33 34 34 OBJC_CLASS DDActionContext; … … 38 38 namespace WebCore { 39 39 40 class Document;41 class Element;42 class FloatRect;43 40 class HitTestResult; 44 class Range;45 41 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. 43 enum 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 53 struct DetectedItem { 54 RetainPtr<DDActionContext> actionContext; 55 FloatRect boundingBox; 56 SimpleRange range; 56 57 }; 57 58 … … 59 60 public: 60 61 #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&); 62 63 #endif 63 WEBCORE_EXPORT static NSArray *detectContentInRange( RefPtr<Range>& contextRange, DataDetectorTypes, NSDictionary *context);64 WEBCORE_EXPORT static NSArray *detectContentInRange(const SimpleRange&, DataDetectorTypes, NSDictionary *context); 64 65 WEBCORE_EXPORT static void removeDataDetectedLinksInDocument(Document&); 65 66 #if PLATFORM(IOS_FAMILY) … … 78 79 79 80 #endif 80 -
trunk/Source/WebCore/editing/cocoa/DataDetection.mm
r259933 r260753 1 1 /* 2 * Copyright (C) 2014-20 17 Apple, Inc.All rights reserved.2 * Copyright (C) 2014-2020 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 39 39 #import "HTMLTextFormControlElement.h" 40 40 #import "HitTestResult.h" 41 #import "Node.h"42 41 #import "NodeList.h" 43 42 #import "NodeTraversal.h" … … 57 56 58 57 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 59 template <> 60 struct WTF::CFTypeTrait<DDResultRef> { 58 template<> struct WTF::CFTypeTrait<DDResultRef> { 61 59 static inline CFTypeID typeID(void) { return DDResultGetCFTypeID(); } 62 60 }; … … 69 67 #if PLATFORM(MAC) 70 68 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) }); 69 static 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) }); 78 75 79 76 auto scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr)); … … 81 78 82 79 if (!DDScannerScanQuery(scanner.get(), scanQuery.get())) 83 return nil;80 return { }; 84 81 85 82 auto results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap)); … … 87 84 // Find the DDResultRef that intersects the hitTestResult's VisiblePosition. 88 85 DDResultRef mainResult = nullptr; 89 RefPtr<Range> mainResultRange;86 Optional<SimpleRange> mainResultRange; 90 87 CFIndex resultCount = CFArrayGetCount(results.get()); 91 88 for (CFIndex i = 0; i < resultCount; i++) { … … 98 95 if (hitLocation >= resultRangeInContext.location && (hitLocation - resultRangeInContext.location) < resultRangeInContext.length) { 99 96 mainResult = result; 100 mainResultRange = createLiveRange(resolveCharacterRange(*contextRange, resultRangeInContext));97 mainResultRange = resolveCharacterRange(contextRange, resultRangeInContext); 101 98 break; 102 99 } … … 104 101 105 102 if (!mainResult) 106 return nil;107 108 auto view = mainResultRange-> ownerDocument().view();103 return { }; 104 105 auto view = mainResultRange->start.document().view(); 109 106 if (!view) 110 return nil;107 return { }; 111 108 112 109 auto actionContext = adoptNS([allocDDActionContextInstance() init]); … … 114 111 [actionContext setMainResult:mainResult]; 115 112 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 120 Optional<DetectedItem> DataDetection::detectItemAroundHitTestResult(const HitTestResult& hitTestResult) 123 121 { 124 122 if (!DataDetectorsLibrary()) 125 return nullptr;123 return { }; 126 124 127 125 Node* node = hitTestResult.innerNonSharedNode(); 128 126 if (!node) 129 return nullptr;127 return { }; 130 128 auto renderer = node->renderer(); 131 129 if (!renderer) 132 return nullptr;130 return { }; 133 131 134 132 VisiblePosition position; … … 141 139 142 140 contextRange = rangeExpandedAroundPositionByCharacters(position, 250); 143 if (!contextRange)144 return nullptr;145 141 } else { 146 142 Frame* frame = node->document().frame(); 147 143 if (!frame) 148 return nullptr;144 return { }; 149 145 150 146 IntPoint framePoint = hitTestResult.roundedPointInInnerNodeFrame(); 151 147 if (!frame->rangeForPoint(framePoint)) 152 return nullptr;153 154 VisiblePositionposition = frame->visiblePositionForPoint(framePoint);148 return { }; 149 150 position = frame->visiblePositionForPoint(framePoint); 155 151 if (position.isNull()) 156 return nullptr;152 return { }; 157 153 158 154 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); 164 161 } 165 162 … … 224 221 } 225 222 223 // Poor man's OptionSet. 224 static bool contains(DataDetectorTypes types, DataDetectorTypes singleType) 225 { 226 return static_cast<uint32_t>(types) & static_cast<uint32_t>(singleType); 227 } 228 226 229 static NSString *constructURLStringForResult(DDResultRef currentResult, NSString *resultIdentifier, NSDate *referenceDate, NSTimeZone *referenceTimeZone, DataDetectorTypes detectionTypes) 227 230 { 228 231 if (!softLink_DataDetectorsCore_DDResultHasProperties(currentResult, DDResultPropertyPassiveDisplay)) 229 232 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))) { 242 244 return softLink_DataDetectorsCore_DDURLStringForResult(currentResult, resultIdentifier, phoneTypes, referenceDate, referenceTimeZone); 243 245 } 244 if ( (detectionTypes & DataDetectorTypeCalendarEvent) && (DDResultCategoryCalendarEvent == category)) {246 if (contains(detectionTypes, DataDetectorTypes::CalendarEvent) && DDResultCategoryCalendarEvent == category) { 245 247 if (!softLink_DataDetectorsCore_DDResultIsPastDate(currentResult, (CFDateRef)referenceDate, (CFTimeZoneRef)referenceTimeZone)) 246 248 return softLink_DataDetectorsCore_DDURLStringForResult(currentResult, resultIdentifier, phoneTypes, referenceDate, referenceTimeZone); … … 444 446 } 445 447 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) 448 NSArray *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)) 456 455 softLink_DataDetectorsCore_DDScannerEnableOptionalSource(scanner.get(), DDScannerSourceSpotlight, true); 457 456 … … 460 459 return nil; 461 460 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)); 463 462 if (!scannerResults) 464 463 return nil; 465 464 466 CFIndex resultCount = CFArrayGetCount(scannerResults.get()); 467 if (!resultCount) 465 if (!CFArrayGetCount(scannerResults.get())) 468 466 return nil; 469 467 … … 477 475 DDResultRef result = (DDResultRef)resultObject; 478 476 NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:currentTopLevelIndex]; 479 if (CF StringCompare(softLink_DataDetectorsCore_DDResultGetType(result), get_DataDetectorsCore_DDBinderSignatureBlockKey(), 0) == kCFCompareEqualTo) {477 if (CFEqual(softLink_DataDetectorsCore_DDResultGetType(result), get_DataDetectorsCore_DDBinderSignatureBlockKey())) { 480 478 NSArray *subresults = (NSArray *)softLink_DataDetectorsCore_DDResultGetSubResults(result); 481 479 … … 492 490 493 491 Vector<Vector<SimpleRange>> allResultRanges; 494 TextIterator iterator( *contextRange);492 TextIterator iterator(contextRange); 495 493 CFIndex iteratorCount = 0; 496 494 … … 537 535 auto tz = adoptCF(CFTimeZoneCopyDefault()); 538 536 NSDate *referenceDate = [context objectForKey:getkDataDetectorsReferenceDateKey()] ?: [NSDate date]; 539 Text* lastTextNodeToUpdate = nullptr;537 RefPtr<Text> lastTextNodeToUpdate; 540 538 String lastNodeContent; 541 size_tcontentOffset = 0;539 unsigned contentOffset = 0; 542 540 DDQueryOffset lastModifiedQueryOffset = { -1, 0 }; 543 541 544 542 // For each result add the link. 545 543 // Since there could be multiple results in the same text node, the node is only modified when 546 544 // we are about to process a different text node. 547 resultCount = allResults.size(); 548 545 CFIndex resultCount = allResults.size(); 549 546 for (CFIndex resultIndex = 0; resultIndex < resultCount; ++resultIndex) { 550 547 DDResultRef coreResult = allResults[resultIndex].get(); … … 579 576 resultRanges.shrink(0); // Keep capacity as we are going to repopulate the Vector right away with the same number of items. 580 577 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) }); 582 579 } 583 580 … … 613 610 // Create the actual anchor node and insert it before the current node. 614 611 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); 616 613 parentNode->insertBefore(newTextNode.copyRef(), ¤tTextNode); 617 614 … … 660 657 if (lastTextNodeToUpdate) 661 658 lastTextNodeToUpdate->setData(lastNodeContent); 662 659 663 660 return [getDDScannerResultClass() resultsFromCoreResults:scannerResults.get()]; 664 661 } … … 666 663 #else 667 664 668 NSArray *DataDetection::detectContentInRange( RefPtr<Range>&, DataDetectorTypes, NSDictionary *)665 NSArray *DataDetection::detectContentInRange(const SimpleRange&, DataDetectorTypes, NSDictionary *) 669 666 { 670 667 return nil; -
trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm
r260739 r260753 226 226 // FIXME: Should give this function a name that makes it clear it adds resources to the document loader as a side effect. 227 227 // Or refactor so it does not do that. 228 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)228 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText) 229 229 { 230 230 WebContentReader reader(m_frame, context, allowPlainText); -
trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
r260709 r260753 676 676 return false; 677 677 678 addFragment(createFragmentFromText(c ontext, [text precomposedStringWithCanonicalMapping]));678 addFragment(createFragmentFromText(createLiveRange(context), [text precomposedStringWithCanonicalMapping])); 679 679 680 680 madeFragmentFromPlainText = true; -
trunk/Source/WebCore/editing/gtk/EditorGtk.cpp
r250061 r260753 51 51 namespace WebCore { 52 52 53 static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, Range& range, bool allowPlainText, bool& chosePlainText)53 static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, const SimpleRange& range, bool allowPlainText, bool& chosePlainText) 54 54 { 55 55 chosePlainText = false; … … 82 82 if (selection.hasText()) { 83 83 chosePlainText = true; 84 return createFragmentFromText( range, selection.text());84 return createFragmentFromText(createLiveRange(range), selection.text()); 85 85 } 86 86 … … 153 153 } 154 154 155 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range& context, bool allowPlainText, bool& chosePlainText)155 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText) 156 156 { 157 157 return createFragmentFromPasteboardData(pasteboard, m_frame, context, allowPlainText, chosePlainText); -
trunk/Source/WebCore/editing/mac/EditorMac.mm
r260739 r260753 141 141 142 142 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); 145 146 146 147 Pasteboard pasteboard(pasteboardName); … … 157 158 158 159 bool chosePlainText; 159 if ( RefPtr<DocumentFragment> fragment = webContentFromPasteboard(pasteboard, range.get(), true, chosePlainText)) {160 if (auto fragment = webContentFromPasteboard(pasteboard, range, true, chosePlainText)) { 160 161 maybeCopyNodeAttributesToFragment(*node, *fragment); 161 if (shouldInsertFragment(*fragment, range.ptr(), EditorInsertAction::Pasted))162 if (shouldInsertFragment(*fragment, createLiveRange(range).ptr(), EditorInsertAction::Pasted)) 162 163 pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(pasteboard), false, MailBlockquoteHandling::IgnoreBlockquote); 163 164 } -
trunk/Source/WebCore/editing/win/EditorWin.cpp
r235955 r260753 67 67 } 68 68 69 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, Range&, bool /*allowPlainText*/, bool& /*chosePlainText*/)69 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange&, bool /*allowPlainText*/, bool& /*chosePlainText*/) 70 70 { 71 71 if (COMPtr<IDataObject> platformDragData = pasteboard.dataObject()) -
trunk/Source/WebCore/loader/FrameLoader.cpp
r260709 r260753 2599 2599 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load"); 2600 2600 #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()); 2609 2607 } 2610 2608 #endif -
trunk/Source/WebCore/page/EventHandler.cpp
r260725 r260753 2067 2067 } 2068 2068 2069 static Node*targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode)2069 static RefPtr<Node> targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode) 2070 2070 { 2071 2071 if (!mousePressNode || !mouseReleaseNode) … … 2077 2077 // If mousePressNode and mouseReleaseNode differ, we should fire the event at their common ancestor if there is one. 2078 2078 if (&mousePressNode->document() == &mouseReleaseNode->document()) { 2079 if (auto * commonAncestor = Range::commonAncestorContainer(mousePressNode,mouseReleaseNode))2079 if (auto commonAncestor = commonInclusiveAncestor(*mousePressNode, *mouseReleaseNode)) 2080 2080 return commonAncestor; 2081 2081 } 2082 2082 2083 Element*mouseReleaseShadowHost = mouseReleaseNode->shadowHost();2083 auto mouseReleaseShadowHost = mouseReleaseNode->shadowHost(); 2084 2084 if (mouseReleaseShadowHost && mouseReleaseShadowHost == mousePressNode->shadowHost()) { 2085 2085 // We want to dispatch the click to the shadow tree host element to give listeners the illusion that the … … 2088 2088 return mouseReleaseShadowHost; 2089 2089 } 2090 2090 2091 return nullptr; 2091 2092 } … … 2160 2161 bool contextMenuEvent = platformMouseEvent.button() == RightButton; 2161 2162 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); 2164 2165 2165 2166 if (m_resizeLayer) { -
trunk/Source/WebCore/page/Settings.yaml
r259275 r260753 542 542 dataDetectorTypes: 543 543 type: DataDetectorTypes 544 initial: DataDetectorTypeNone544 initial: 545 545 conditional: DATA_DETECTION 546 546 -
trunk/Source/WebCore/page/SettingsBase.h
r260547 r260753 44 44 #include <wtf/text/AtomStringHash.h> 45 45 46 #if ENABLE(DATA_DETECTION)47 #include "DataDetection.h"48 #endif49 50 46 namespace WebCore { 51 47 52 48 class FontGenericFamilies; 53 49 class Page; 50 51 enum class DataDetectorTypes : uint32_t; 54 52 55 53 enum EditableLinkBehavior { -
trunk/Source/WebCore/page/TextIndicator.cpp
r260725 r260753 53 53 namespace WebCore { 54 54 55 static bool initializeIndicator(TextIndicatorData&, Frame&, const Range&, FloatSize margin, bool indicatesCurrentSelection);55 static bool initializeIndicator(TextIndicatorData&, Frame&, const SimpleRange&, FloatSize margin, bool indicatesCurrentSelection); 56 56 57 57 TextIndicator::TextIndicator(const TextIndicatorData& data) … … 67 67 } 68 68 69 RefPtr<TextIndicator> TextIndicator::createWithRange(const Range& range, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin) 70 { 71 Frame* frame = range.startContainer().document().frame(); 72 69 RefPtr<TextIndicator> TextIndicator::createWithRange(const SimpleRange& range, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin) 70 { 71 auto frame = makeRefPtr(range.startContainer().document().frame()); 73 72 if (!frame) 74 73 return nullptr; 75 74 76 Ref<Frame> protector(*frame); 77 78 VisibleSelection oldSelection = frame->selection().selection(); 75 bool indicatesCurrentSelection = range == frame->selection().selection().toNormalizedRange(); 76 79 77 OptionSet<TemporarySelectionOption> temporarySelectionOptions; 80 78 temporarySelectionOptions.add(TemporarySelectionOption::DoNotSetFocus); … … 83 81 temporarySelectionOptions.add(TemporarySelectionOption::EnableAppearanceUpdates); 84 82 #endif 85 TemporarySelectionChange selectionChange(*frame, { SimpleRange { range }}, temporarySelectionOptions);83 TemporarySelectionChange selectionChange(*frame, { range }, temporarySelectionOptions); 86 84 87 85 TextIndicatorData data; … … 90 88 data.options = options; 91 89 92 bool indicatesCurrentSelection = areRangesEqual(&range, createLiveRange(oldSelection.toNormalizedRange()).get());93 94 90 if (!initializeIndicator(data, *frame, range, margin, indicatesCurrentSelection)) 95 91 return nullptr; … … 109 105 data.options = options; 110 106 111 if (!initializeIndicator(data, frame, createLiveRange(*range), margin, true))107 if (!initializeIndicator(data, frame, *range, margin, true)) 112 108 return nullptr; 113 109 … … 115 111 } 116 112 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()) 113 static bool hasNonInlineOrReplacedElements(const SimpleRange& range) 114 { 115 for (auto& node : intersectingNodes(range)) { 116 auto renderer = node.renderer(); 117 if (renderer && (!renderer->isInline() || renderer->isReplaced())) 127 118 return true; 128 119 } 129 130 120 return false; 131 121 } … … 185 175 #if PLATFORM(IOS_FAMILY) 186 176 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()); 177 static 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; 194 185 } 195 186 … … 198 189 static bool styleContainsComplexBackground(const RenderStyle& style) 199 190 { 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 194 static HashSet<Color> estimatedTextColorsForRange(const SimpleRange& range) 213 195 { 214 196 HashSet<Color> colors; 215 197 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()); 221 201 } 222 202 return colors; 223 203 } 224 225 static FloatRect absoluteBoundingRectForRange(const Range& range)226 { 227 return range.absoluteBoundingRect({204 205 static FloatRect absoluteBoundingRectForRange(const SimpleRange& range) 206 { 207 return createLiveRange(range)->absoluteBoundingRect({ 228 208 Range::BoundingRectBehavior::RespectClipping, 229 209 Range::BoundingRectBehavior::UseVisibleBounds, … … 232 212 } 233 213 234 static Color estimatedBackgroundColorForRange(const Range& range, const Frame& frame)214 static Color estimatedBackgroundColorForRange(const SimpleRange& range, const Frame& frame) 235 215 { 236 216 auto estimatedBackgroundColor = frame.view() ? frame.view()->documentBackgroundColor() : Color::transparent; 237 217 238 218 RenderElement* renderer = nullptr; 239 auto commonAncestor = range.commonAncestorContainer();219 auto commonAncestor = commonInclusiveAncestor(range.start.container, range.end.container); 240 220 while (commonAncestor) { 241 221 if (is<RenderElement>(commonAncestor->renderer())) { … … 292 272 } 293 273 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())) 274 static bool containsOnlyWhiteSpaceText(const SimpleRange& range) 275 { 276 for (auto& node : intersectingNodes(range)) { 277 if (!is<RenderText>(node.renderer())) 299 278 return false; 300 279 } … … 302 281 } 303 282 304 static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Range& range, FloatSize margin, bool indicatesCurrentSelection)283 static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const SimpleRange& range, FloatSize margin, bool indicatesCurrentSelection) 305 284 { 306 285 if (auto* document = frame.document()) … … 312 291 treatRangeAsComplexDueToIllegibleTextColors = hasAnyIllegibleColors(data, data.estimatedBackgroundColor, estimatedTextColorsForRange(range)); 313 292 } 314 315 Vector<FloatRect> textRects;316 293 317 294 // FIXME (138888): Ideally we wouldn't remove the margin in this case, but we need to … … 321 298 margin = FloatSize(); 322 299 323 FrameSelection::TextRectangleHeight textRectHeight = (data.options & TextIndicatorOptionTightlyFitContent) ? FrameSelection::TextRectangleHeight::TextHeight : FrameSelection::TextRectangleHeight::SelectionHeight;300 Vector<FloatRect> textRects; 324 301 325 302 bool useBoundingRectAndPaintAllContentForComplexRanges = data.options & TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges; 326 303 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()) { 329 305 data.options |= TextIndicatorOptionPaintAllContent; 330 306 textRects.append(containerRenderer->absoluteBoundingBoxRect()); … … 334 310 #if PLATFORM(IOS_FAMILY) 335 311 else if (data.options & TextIndicatorOptionUseSelectionRectForSizing) 336 getSelectionRectsForRange(textRects,range);312 textRects = selectionRects(range); 337 313 #endif 338 314 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); 345 321 } 346 322 -
trunk/Source/WebCore/page/TextIndicator.h
r218068 r260753 35 35 class Frame; 36 36 class GraphicsContext; 37 class Range; 37 38 struct SimpleRange; 38 39 39 40 // FIXME: Move PresentationTransition to TextIndicatorWindow, because it's about presentation. … … 124 125 WEBCORE_EXPORT static Ref<TextIndicator> create(const TextIndicatorData&); 125 126 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)); 127 128 128 129 WEBCORE_EXPORT ~TextIndicator(); -
trunk/Source/WebCore/page/mac/ServicesOverlayController.h
r257465 r260753 56 56 WTF_MAKE_NONCOPYABLE(Highlight); 57 57 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&&); 60 60 ~Highlight(); 61 61 … … 63 63 64 64 DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); } 65 Range& range() const { return m_range.get(); }65 const SimpleRange& range() const { return m_range; } 66 66 GraphicsLayer& layer() const { return m_graphicsLayer.get(); } 67 67 … … 79 79 80 80 private: 81 Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef> , Ref<Range>&&);81 Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>&&, SimpleRange&&); 82 82 83 83 // GraphicsLayerClient … … 90 90 ServicesOverlayController* m_controller; 91 91 RetainPtr<DDHighlightRef> m_ddHighlight; 92 Ref<Range>m_range;92 SimpleRange m_range; 93 93 Ref<GraphicsLayer> m_graphicsLayer; 94 94 Type m_type; … … 127 127 void determineActiveHighlightTimerFired(); 128 128 129 static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);129 static bool highlightsAreEquivalent(const Highlight*, const Highlight*); 130 130 131 Vector< RefPtr<Range>> telephoneNumberRangesForFocusedFrame();131 Vector<SimpleRange> telephoneNumberRangesForFocusedFrame(); 132 132 133 133 void didCreateHighlight(Highlight*); -
trunk/Source/WebCore/page/mac/ServicesOverlayController.mm
r260725 r260753 56 56 namespace WebCore { 57 57 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)58 Ref<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 63 Ref<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 68 ServicesOverlayController::Highlight::Highlight(ServicesOverlayController& controller, Type type, RetainPtr<DDHighlightRef>&& ddHighlight, SimpleRange&& range) 69 69 : m_controller(&controller) 70 70 , m_range(WTFMove(range)) … … 475 475 void ServicesOverlayController::buildPhoneNumberHighlights() 476 476 { 477 Vector< RefPtr<Range>> phoneNumberRanges;477 Vector<SimpleRange> phoneNumberRanges; 478 478 for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) 479 479 phoneNumberRanges.appendVector(frame->editor().detectedTelephoneNumberRanges()); … … 493 493 for (auto& range : phoneNumberRanges) { 494 494 // 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))); 496 496 497 497 // Convert to the main document's coordinate space. … … 499 499 // We should consider adding conversion functions to ScrollView for contentsToDocument(). Right now, contentsToRootView() is 500 500 // 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(); 502 502 if (!viewForRange) 503 503 continue; … … 506 506 507 507 CGRect cgRect = rect; 508 509 508 #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)); 511 510 #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)); 513 512 #endif 514 newPotentialHighlights.add(Highlight::createForTelephoneNumber(*this, ddHighlight, range.releaseNonNull()));513 newPotentialHighlights.add(Highlight::createForTelephoneNumber(*this, WTFMove(ddHighlight), WTFMove(range))); 515 514 } 516 515 … … 545 544 IntRect currentRect = snappedIntRect(rect); 546 545 currentRect.setLocation(mainFrameView->windowToContents(viewForRange->contentsToWindow(currentRect.location()))); 547 cgRects.append( (CGRect)currentRect);546 cgRects.append(currentRect); 548 547 } 549 548 … … 551 550 CGRect visibleRect = mainFrameView->visibleContentRect(); 552 551 #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)); 554 553 #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)); 556 555 #endif 557 newPotentialHighlights.add(Highlight::createForSelection(*this, ddHighlight, createLiveRange(*selectionRange)));556 newPotentialHighlights.add(Highlight::createForSelection(*this, WTFMove(ddHighlight), WTFMove(*selectionRange))); 558 557 } 559 558 } … … 608 607 } 609 608 610 Vector< RefPtr<Range>> ServicesOverlayController::telephoneNumberRangesForFocusedFrame()609 Vector<SimpleRange> ServicesOverlayController::telephoneNumberRangesForFocusedFrame() 611 610 { 612 611 return m_page.focusController().focusedOrMainFrame().editor().detectedTelephoneNumberRanges(); … … 619 618 if (!a || !b) 620 619 return false; 621 return a->type() == b->type() && a reRangesEqual(&a->range(), &b->range());620 return a->type() == b->type() && a->range() == b->range(); 622 621 } 623 622 … … 632 631 633 632 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))) 635 634 return highlight.get(); 636 635 } … … 788 787 selectedTelephoneNumbers.reserveCapacity(telephoneNumberRanges.size()); 789 788 for (auto& range : telephoneNumberRanges) 790 selectedTelephoneNumbers.append( range->text());789 selectedTelephoneNumbers.append(plainText(range)); 791 790 792 791 m_page.chrome().client().handleSelectionServiceClick(m_page.focusController().focusedOrMainFrame().selection(), selectedTelephoneNumbers, windowPoint); 793 792 } 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); 795 794 } 796 795 -
trunk/Source/WebCore/platform/ios/DragImageIOS.mm
r249217 r260753 41 41 #import "Page.h" 42 42 #import "Range.h" 43 #import "SimpleRange.h" 43 44 #import "StringTruncator.h" 44 45 #import "TextIndicator.h" … … 136 137 CGRect imageRect = CGRectMake(0, 0, textWidth + 2 * dragImagePadding, textHeight + 2 * dragImagePadding); 137 138 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) { 140 141 GraphicsContext context(rendererContext.CGContext); 141 142 context.translate(0, CGRectGetHeight(imageRect)); … … 147 148 }]; 148 149 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())) 151 151 indicatorData = textIndicator->data(); 152 152 … … 192 192 193 193 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) { 196 196 GraphicsContext context(rendererContext.CGContext); 197 197 // FIXME: The context flip here should not be necessary, and suggests that somewhere else in the regular … … 200 200 context.scale({ 1, -1 }); 201 201 context.drawImage(*image, imageRect); 202 }]; 203 204 return finalImage.CGImage; 202 }].CGImage; 205 203 } 206 204 -
trunk/Source/WebKit/ChangeLog
r260752 r260753 1 2020-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 1 27 2020-04-27 Carlos Garcia Campos <cgarcia@igalia.com> 2 28 -
trunk/Source/WebKit/Shared/API/Cocoa/WKDataDetectorTypesInternal.h
r242339 r260753 32 32 static inline WebCore::DataDetectorTypes fromWKDataDetectorTypes(uint64_t types) 33 33 { 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; 40 35 if (types & WKDataDetectorTypePhoneNumber) 41 value |= WebCore::DataDetectorTypePhoneNumber;36 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::PhoneNumber); 42 37 if (types & WKDataDetectorTypeLink) 43 value |= WebCore::DataDetectorTypeLink;38 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::Link); 44 39 if (types & WKDataDetectorTypeAddress) 45 value |= WebCore::DataDetectorTypeAddress;40 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::Address); 46 41 if (types & WKDataDetectorTypeCalendarEvent) 47 value |= WebCore::DataDetectorTypeCalendarEvent;42 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::CalendarEvent); 48 43 if (types & WKDataDetectorTypeTrackingNumber) 49 value |= WebCore::DataDetectorTypeTrackingNumber;44 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::TrackingNumber); 50 45 if (types & WKDataDetectorTypeFlightNumber) 51 value |= WebCore::DataDetectorTypeFlightNumber;46 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::FlightNumber); 52 47 if (types & WKDataDetectorTypeLookupSuggestion) 53 value |= WebCore::DataDetectorTypeLookupSuggestion; 54 48 value |= static_cast<uint32_t>(WebCore::DataDetectorTypes::LookupSuggestion); 55 49 return static_cast<WebCore::DataDetectorTypes>(value); 56 50 } -
trunk/Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInRangeHandle.mm
r242339 r260753 64 64 65 65 #if TARGET_OS_IPHONE 66 66 67 - (NSArray *)detectDataWithTypes:(WKDataDetectorTypes)types context:(NSDictionary *)context 67 68 { 68 69 #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); 71 71 #else 72 72 return nil; 73 73 #endif 74 74 } 75 75 76 #endif 76 77 -
trunk/Source/WebKit/WebProcess/WebPage/ViewGestureGeometryCollector.cpp
r259200 r260753 157 157 document->updateLayoutIgnorePendingStylesheets(); 158 158 159 auto documentRange = Range::create(*document, {{ document->documentElement(), Position::PositionIsBeforeAnchor }}, {{ document->documentElement(), Position::PositionIsAfterAnchor }});160 159 HashSet<Node*> allTextNodes; 161 160 HashMap<unsigned, unsigned> fontSizeToCountMap; … … 163 162 unsigned totalSampledTextLength = 0; 164 163 165 for (TextIterator documentTextIterator { documentRange.get(), TextIteratorEntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) {164 for (TextIterator documentTextIterator { makeRangeSelectingNodeContents(*document), TextIteratorEntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) { 166 165 if (++numberOfIterations >= maximumNumberOfTextRunsToConsider) 167 166 break; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r260752 r260753 3732 3732 if (!document) 3733 3733 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())); 3737 3735 } 3738 3736 completionHandler({ m_page->mainFrame().dataDetectionResults() }); -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r260752 r260753 130 130 #endif 131 131 132 #if ENABLE(DATA_DETECTION)133 #include <WebCore/DataDetection.h>134 #endif135 136 132 #if ENABLE(MAC_GESTURE_EVENTS) 137 133 #include <WebKitAdditions/PlatformGestureEventMac.h> -
trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
r260739 r260753 858 858 Element* URLElement = hitTestResult.URLElement(); 859 859 if (!absoluteLinkURL.isEmpty() && URLElement) 860 immediateActionResult.linkTextIndicator = TextIndicator::createWithRange( rangeOfContents(*URLElement), TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn);860 immediateActionResult.linkTextIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(*URLElement), TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges, TextIndicatorPresentationTransition::FadeIn); 861 861 862 862 auto lookupResult = lookupTextAtLocation(locationInViewCoordinates); … … 896 896 // FIXME: Avoid scanning if we will just throw away the result (e.g. we're over a link). 897 897 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); 904 903 } 905 904 } -
trunk/Source/WebKitLegacy/mac/ChangeLog
r260751 r260753 1 2020-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 1 19 2020-04-27 Rob Buis <rbuis@igalia.com> 2 20 -
trunk/Source/WebKitLegacy/mac/DOM/DOM.mm
r260485 r260753 524 524 auto& node = *core(self); 525 525 526 auto range = rangeOfContents(node);527 528 526 const float margin = 4 / node.document().page()->pageScaleFactor(); 529 auto textIndicator = TextIndicator::createWithRange( range, TextIndicatorOptionTightlyFitContent |527 auto textIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(node), TextIndicatorOptionTightlyFitContent | 530 528 TextIndicatorOptionRespectTextColor | 531 529 TextIndicatorOptionPaintBackgrounds | -
trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebContextMenuClient.mm
r258129 r260753 149 149 150 150 #if ENABLE(SERVICE_CONTROLS) 151 151 152 void WebContextMenuClient::sharingServicePickerWillBeDestroyed(WebSharingServicePickerController &) 152 153 { … … 184 185 RetainPtr<NSImage> WebContextMenuClient::imageForCurrentSharingServicePickerItem(WebSharingServicePickerController &) 185 186 { 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()); 191 192 if (!node) 192 193 return nil; 193 194 194 FrameView* frameView = node->document().view();195 auto frameView = makeRefPtr(node->document().view()); 195 196 if (!frameView) { 196 197 // This method shouldn't be called in cases where the controlled node isn't in a rendered view. … … 204 205 205 206 // 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); 207 208 if (!buffer) 208 209 return nil; 209 210 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(); 215 215 frameView->setPaintBehavior(PaintBehavior::SelectionOnly); 216 216 … … 221 221 frameView->setPaintBehavior(oldPaintBehavior); 222 222 223 RefPtr<Image>image = ImageBuffer::sinkIntoImage(WTFMove(buffer));223 auto image = ImageBuffer::sinkIntoImage(WTFMove(buffer)); 224 224 if (!image) 225 225 return nil; … … 227 227 return image->snapshotNSImage(); 228 228 } 229 229 230 #endif 230 231 -
trunk/Source/WebKitLegacy/mac/WebView/WebImmediateActionController.mm
r260739 r260753 412 412 return nil; 413 413 414 RefPtr<WebCore::Range> detectedDataRange; 415 WebCore::FloatRect detectedDataBoundingBox; 416 RetainPtr<DDActionContext> actionContext; 414 Optional<WebCore::DetectedItem> detectedItem; 417 415 418 416 if ([[_webView UIDelegate] respondsToSelector:@selector(_webView:actionContextForHitTestResult:range:)]) { 419 RetainPtr<WebElementDictionary> hitTestDictionary = adoptNS([[WebElementDictionary alloc] initWithHitTestResult:_hitTestResult]);420 421 417 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 } 426 428 } 427 429 428 430 // 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:^() { 443 445 } interactionChangedHandler:^() { 444 446 if (indicator) … … 448 450 }]; 449 451 450 [_currentActionContext setHighlightFrame:[_webView.window convertRectToScreen:detected DataBoundingBox]];452 [_currentActionContext setHighlightFrame:[_webView.window convertRectToScreen:detectedItem->boundingBox]]; 451 453 452 454 NSArray *menuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForResult:[_currentActionContext mainResult] actionContext:_currentActionContext.get()]; … … 537 539 popupInfo.attributedString = scaledAttributedString.get(); 538 540 539 if (auto textIndicator = WebCore::TextIndicator::createWithRange( createLiveRange(range), indicatorOptions, presentationTransition))541 if (auto textIndicator = WebCore::TextIndicator::createWithRange(range, indicatorOptions, presentationTransition)) 540 542 popupInfo.textIndicator = textIndicator->data(); 541 543
Note: See TracChangeset
for help on using the changeset viewer.