Changeset 258871 in webkit
- Timestamp:
- Mar 23, 2020 1:50:15 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r258866 r258871 1 2020-03-23 Darin Adler <darin@apple.com> 2 3 Change TextIterator::rangeLength to not require a live range 4 https://bugs.webkit.org/show_bug.cgi?id=209207 5 6 Reviewed by Antti Koivisto. 7 8 * editing/mac/spelling/autocorrection-contraction-expected.txt: Update these expected 9 results because of changes to delegate callbacks. The test is still passing and this 10 change is only in the legacy WebKit case (there is a separate result for modern WebKit). 11 This seems to be a progression, not evidence of a bug. 12 1 13 2020-03-23 Rob Buis <rbuis@igalia.com> 2 14 -
trunk/LayoutTests/editing/mac/spelling/autocorrection-contraction-expected.txt
r199054 r258871 152 152 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 153 153 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 154 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 154 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 155 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 156 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 157 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 158 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 159 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 160 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 161 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 162 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 163 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 164 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 165 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 166 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 167 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 12 of #text > DIV > DIV > BODY > HTML > #document to 12 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 168 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 169 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 170 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 12 of #text > DIV > DIV > BODY > HTML > #document to 12 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 171 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 172 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 173 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 174 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 175 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 176 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 155 177 EDITING DELEGATE: shouldInsertText:would replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped 156 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE157 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE178 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 179 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 158 180 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 159 181 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification … … 162 184 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification 163 185 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification 164 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification165 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 5 of #text > DIV > DIV > BODY > HTML > #document to 5 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE166 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification167 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification168 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE169 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification170 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification171 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE172 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification173 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification174 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 9 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE175 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification176 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification177 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 10 of #text > DIV > DIV > BODY > HTML > #document to 10 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE178 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification179 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification180 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 12 of #text > DIV > DIV > BODY > HTML > #document to 12 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE181 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification182 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification183 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 12 of #text > DIV > DIV > BODY > HTML > #document to 12 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE184 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification185 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification186 186 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE 187 187 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -
trunk/Source/WebCore/ChangeLog
r258869 r258871 1 2020-03-23 Darin Adler <darin@apple.com> 2 3 Change TextIterator::rangeLength to not require a live range 4 https://bugs.webkit.org/show_bug.cgi?id=209207 5 6 Reviewed by Antti Koivisto. 7 8 - Renamed TextIterator::rangeLength to characterCount. 9 10 * accessibility/AXObjectCache.cpp: 11 (WebCore::AXObjectCache::rangeMatchesTextNearRange): Use characterCount. 12 (WebCore::resetNodeAndOffsetForReplacedNode): Ditto. 13 (WebCore::AXObjectCache::nextCharacterOffset): Ditto. 14 * accessibility/atk/AXObjectCacheAtk.cpp: 15 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): Ditto. 16 * accessibility/atk/WebKitAccessibleHyperlink.cpp: 17 (rangeLengthForObject): Ditto. 18 * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm: 19 (-[WebAccessibilityObjectWrapper _convertToNSRange:]): Ditto. 20 21 * dom/SimpleRange.h: Export another constructor. 22 23 * editing/AlternativeTextController.cpp: 24 (WebCore::AlternativeTextController::applyAlternativeTextToRange): 25 Use characterCount. 26 * editing/ApplyStyleCommand.cpp: 27 (WebCore::ApplyStyleCommand::applyBlockStyle): Ditto. 28 * editing/CompositeEditCommand.cpp: 29 (WebCore::CompositeEditCommand::moveParagraphs): Ditto. 30 * editing/Editing.cpp: 31 (WebCore::indexForVisiblePosition): Ditto. 32 * editing/TextCheckingHelper.cpp: 33 (WebCore::TextCheckingParagraph::rangeLength const): Ditto. 34 (WebCore::TextCheckingParagraph::offsetTo const): Ditto. 35 (WebCore::TextCheckingParagraph::checkingStart const): Ditto. 36 (WebCore::TextCheckingParagraph::checkingEnd const): Ditto. 37 (WebCore::TextCheckingParagraph::checkingLength const): Ditto. 38 (WebCore::TextCheckingParagraph::automaticReplacementStart const): Ditto. 39 (WebCore::TextCheckingParagraph::automaticReplacementLength const): Ditto. 40 (WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): Ditto. 41 (WebCore::TextCheckingHelper::isUngrammatical const): Ditto. 42 43 * editing/TextIterator.cpp: 44 (WebCore::TextIterator::rangeLength): Deleted. 45 (WebCore::characterCount): Like the baove but the argument is SimpleRange 46 and return is CharacterCount. Even though each individual node is limited 47 to 32-bit size, ranges covering multiple nodes could have a count of 48 characters that exceeds 32 bits, so CharacterCount is size_t. 49 (WebCore::TextIterator::getLocationAndLengthFromRange): Use characterCount. 50 51 * editing/TextIterator.h: Added characterCount function, 52 CharacterCount and CharacterRange types. Removed TextIterator::rangeLength. 53 Added FIXME comments about the next steps. 54 55 * editing/VisiblePosition.cpp: 56 (WebCore::makeBoundaryPoint): Added. 57 * editing/VisiblePosition.h: Added makeBoundaryPoint. Also removed 58 extraneous forward declarations and moved some function bodies out of the 59 class definition. 60 61 * editing/VisibleUnits.cpp: 62 (WebCore::distanceBetweenPositions): Changed return type to ptrdiff_t. 63 Use characterCount. 64 * editing/VisibleUnits.h: Updated for the above. 65 66 * editing/cocoa/DataDetection.mm: 67 (WebCore::detectItemAtPositionWithRange): Use characterCount. 68 * editing/cocoa/DictionaryLookup.mm: 69 (WebCore::DictionaryLookup::rangeForSelection): Ditto. 70 (WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto. 71 * editing/ios/DictationCommandIOS.cpp: 72 (WebCore::DictationCommandIOS::doApply): Ditto. 73 * editing/mac/DictionaryLookupLegacy.mm: 74 (WebCore::DictionaryLookup::rangeForSelection): Ditto. 75 (WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto. 76 * page/EventHandler.cpp: 77 (WebCore::textDistance): Ditto. 78 1 79 2020-03-23 youenn fablet <youenn@apple.com> 2 80 -
trunk/Source/WebCore/accessibility/AXObjectCache.cpp
r258780 r258871 1939 1939 auto startPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), -textLength); 1940 1940 auto endPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), 2 * textLength); 1941 1942 1941 if (startPosition.isNull()) 1943 1942 startPosition = firstPositionInOrBeforeNode(originalRange.start.container.ptr()); … … 1945 1944 endPosition = lastPositionInOrAfterNode(originalRange.end.container.ptr()); 1946 1945 1947 auto searchRange = Range::create(m_document, startPosition, endPosition);1948 if (searchRange ->collapsed())1946 auto searchRange = SimpleRange { *makeBoundaryPoint(startPosition), *makeBoundaryPoint(endPosition) }; 1947 if (searchRange.collapsed()) 1949 1948 return WTF::nullopt; 1950 1949 1951 auto range = Range::create(m_document, startPosition, createLegacyEditingPosition(originalRange.start)); 1952 unsigned targetOffset = TextIterator::rangeLength(range.ptr(), true); 1950 auto targetOffset = characterCount({ searchRange.start, originalRange.start }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 1953 1951 return findClosestPlainText(searchRange, matchText, { }, targetOffset); 1954 1952 } … … 1993 1991 { 1994 1992 // Use this function to include the replaced node itself in the range we are creating. 1995 if (!replacedNode) 1996 return nullptr; 1997 1998 RefPtr<Range> nodeRange = AXObjectCache::rangeForNodeContents(replacedNode); 1999 int nodeLength = TextIterator::rangeLength(nodeRange.get()); 2000 offset = characterCount <= nodeLength ? replacedNode->computeNodeIndex() : replacedNode->computeNodeIndex() + 1; 1993 auto nodeRange = AXObjectCache::rangeForNodeContents(replacedNode); 1994 if (!nodeRange) 1995 return nullptr; 1996 bool isInNode = static_cast<unsigned>(characterCount) <= WebCore::characterCount(*nodeRange); 1997 offset = replacedNode->computeNodeIndex() + (isInNode ? 0 : 1); 2001 1998 return replacedNode->parentNode(); 2002 1999 } … … 2414 2411 2415 2412 // We don't always move one 'character' at a time since there might be composed characters. 2416 intnextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset);2413 unsigned nextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset); 2417 2414 CharacterOffset next = characterOffsetForNodeAndOffset(*characterOffset.node, nextOffset); 2418 2415 2419 2416 // To be consistent with VisiblePosition, we should consider the case that current node end to next node start counts 1 offset. 2420 2417 if (!ignoreNextNodeStart && !next.isNull() && !isReplacedNodeOrBR(next.node) && next.node != characterOffset.node) { 2421 int length = TextIterator::rangeLength(rangeForUnorderedCharacterOffsets(characterOffset, next).get()); 2422 if (length > nextOffset - characterOffset.offset) 2423 next = characterOffsetForNodeAndOffset(*next.node, 0, TraverseOptionIncludeStart); 2418 if (auto range = rangeForUnorderedCharacterOffsets(characterOffset, next)) { 2419 auto length = characterCount(*range); 2420 if (length > nextOffset - characterOffset.offset) 2421 next = characterOffsetForNodeAndOffset(*next.node, 0, TraverseOptionIncludeStart); 2422 } 2424 2423 } 2425 2424 -
trunk/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp
r254566 r258871 356 356 // right offset (e.g. multiline text areas). 357 357 auto range = Range::create(document, node->parentNode(), 0, node, 0); 358 offsetToEmit = offset + TextIterator::rangeLength(range.ptr());358 offsetToEmit = offset + characterCount(range.get()); 359 359 } 360 360 -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp
r256563 r258871 155 155 { 156 156 // This is going to be the actual length in most of the cases 157 int baseLength = TextIterator::rangeLength(range, true);157 int baseLength = characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 158 158 159 159 // Check whether the current hyperlink belongs to a list item. -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp
r256563 r258871 411 411 // Set values for start offsets and calculate initial range length. 412 412 // These values might be adjusted later to cover special cases. 413 startOffset = webCoreOffsetToAtkOffset(coreObject, TextIterator::rangeLength(rangeInParent.ptr(), true));413 startOffset = webCoreOffsetToAtkOffset(coreObject, characterCount(rangeInParent.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions)); 414 414 auto nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd); 415 int rangeLength = TextIterator::rangeLength(nodeRange.ptr(), true);415 int rangeLength = characterCount(nodeRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions); 416 416 417 417 // Special cases that are only relevant when working with *_END boundaries. -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp
r256563 r258871 248 248 else if (!isStartOfLine(endPosition)) { 249 249 RefPtr<Range> range = makeRange(startPosition, endPosition.previous()); 250 offset = TextIterator::rangeLength(range.get(), true) + 1;250 offset = (range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0) + 1; 251 251 } else { 252 252 RefPtr<Range> range = makeRange(startPosition, endPosition); 253 offset = TextIterator::rangeLength(range.get(), true);253 offset = range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0; 254 254 } 255 255 -
trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
r258525 r258871 2311 2311 } 2312 2312 2313 - (NSRange)_convertToNSRange:(Range *) range2314 { 2315 if (! range)2313 - (NSRange)_convertToNSRange:(Range *)liveRange 2314 { 2315 if (!liveRange) 2316 2316 return NSMakeRange(NSNotFound, 0); 2317 2317 2318 Document* document = self.axBackingObject->document(); 2319 Element* selectionRoot = document->frame()->selection().selection().rootEditableElement(); 2320 Element* scope = selectionRoot ? selectionRoot : document->documentElement(); 2318 auto range = SimpleRange { *liveRange }; 2319 2320 auto& document = range.start.document(); 2321 auto* frame = document.frame(); 2322 if (!frame) 2323 return NSMakeRange(NSNotFound, 0); 2324 2325 auto* rootEditableElement = frame->selection().selection().rootEditableElement(); 2326 auto* scope = rootEditableElement ? rootEditableElement : document.documentElement(); 2327 if (!scope) 2328 return NSMakeRange(NSNotFound, 0); 2321 2329 2322 2330 // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view 2323 // that is not inside the current editable region. 2331 // that is not inside the current editable region. These checks ensure we don't produce 2324 2332 // potentially invalid data when responding to such requests. 2325 if ( &range->startContainer() != scope && !range->startContainer().isDescendantOf(scope))2333 if (!scope->contains(range.start.container.ptr()) || !scope->contains(range.end.container.ptr())) 2326 2334 return NSMakeRange(NSNotFound, 0); 2327 if (&range->endContainer() != scope && !range->endContainer().isDescendantOf(scope)) 2328 return NSMakeRange(NSNotFound, 0); 2329 2330 auto testRange = Range::create(scope->document(), scope, 0, &range->startContainer(), range->startOffset()); 2331 ASSERT(&testRange->startContainer() == scope); 2332 int startPosition = TextIterator::rangeLength(testRange.ptr()); 2333 testRange->setEnd(range->endContainer(), range->endOffset()); 2334 ASSERT(&testRange->startContainer() == scope); 2335 int endPosition = TextIterator::rangeLength(testRange.ptr()); 2336 return NSMakeRange(startPosition, endPosition - startPosition); 2335 2336 return NSMakeRange(characterCount({ { *scope, 0 }, range.start }), characterCount(range)); 2337 2337 } 2338 2338 -
trunk/Source/WebCore/dom/SimpleRange.h
r258525 r258871 43 43 bool collapsed() const { return start == end; } 44 44 45 SimpleRange(const BoundaryPoint&, const BoundaryPoint&);45 WEBCORE_EXPORT SimpleRange(const BoundaryPoint&, const BoundaryPoint&); 46 46 WEBCORE_EXPORT SimpleRange(BoundaryPoint&&, BoundaryPoint&&); 47 47 -
trunk/Source/WebCore/editing/AlternativeTextController.cpp
r258087 r258871 581 581 void AlternativeTextController::applyAlternativeTextToRange(const Range& range, const String& alternative, AlternativeTextType alternativeType, OptionSet<DocumentMarker::MarkerType> markerTypesToAdd) 582 582 { 583 auto paragraphRangeContainingCorrection = range.cloneRange();584 585 setStart(paragraphRangeContainingCorrection.ptr(), startOfParagraph(range.startPosition()));586 setEnd(paragraphRangeContainingCorrection.ptr(), endOfParagraph(range.endPosition()));587 588 583 // After we replace the word at range rangeWithAlternative, we need to add markers to that range. 589 // However, once the replacement took place, the value of rangeWithAlternative is not valid anymore. 590 // So before we carry out the replacement, we need to store the start position of rangeWithAlternative 591 // relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph 592 // to store this value. In order to obtain this offset, we need to first create a range 593 // which spans from the start of paragraph to the start position of rangeWithAlternative. 594 auto correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer().document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition()); 595 596 Position startPositionOfRangeWithAlternative = range.startPosition(); 597 if (!startPositionOfRangeWithAlternative.containerNode()) 598 return; 599 auto setEndResult = correctionStartOffsetInParagraphAsRange->setEnd(*startPositionOfRangeWithAlternative.containerNode(), startPositionOfRangeWithAlternative.computeOffsetInContainerNode()); 600 if (setEndResult.hasException()) 601 return; 584 // So before we carry out the replacement,store the start position relative to the start position 585 // of the containing paragraph. 602 586 603 587 // Take note of the location of autocorrection so that we can add marker after the replacement took place. 604 int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.ptr()); 605 606 // Clone the range, since the caller of this method may want to keep the original range around. 607 auto rangeWithAlternative = range.cloneRange(); 608 609 ContainerNode& rootNode = paragraphRangeContainingCorrection->startContainer().treeScope().rootNode(); 610 int paragraphStartIndex = TextIterator::rangeLength(Range::create(rootNode.document(), &rootNode, 0, ¶graphRangeContainingCorrection->startContainer(), paragraphRangeContainingCorrection->startOffset()).ptr()); 611 SpellingCorrectionCommand::create(rangeWithAlternative, alternative)->apply(); 588 auto correctionStartPosition = range.startPosition(); 589 auto correctionStart { makeBoundaryPoint(correctionStartPosition) }; 590 auto paragraphStart { makeBoundaryPoint(startOfParagraph(correctionStartPosition)) }; 591 if (!correctionStart || !paragraphStart) 592 return; 593 auto treeScopeRoot = makeRef(correctionStart->container->treeScope().rootNode()); 594 auto treeScopeStart = BoundaryPoint { treeScopeRoot.get(), 0 }; 595 auto correctionOffsetInParagraph = characterCount({ *paragraphStart, *correctionStart }); 596 auto paragraphOffsetInTreeScope = characterCount({ treeScopeStart, *paragraphStart }); 597 598 // Clone the range, since the caller of may keep a refernece to the original range and modify it. 599 SpellingCorrectionCommand::create(range.cloneRange(), alternative)->apply(); 600 612 601 // Recalculate pragraphRangeContainingCorrection, since SpellingCorrectionCommand modified the DOM, such that the original paragraphRangeContainingCorrection is no longer valid. Radar: 10305315 Bugzilla: 89526 613 auto updatedParagraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength( &rootNode, paragraphStartIndex, correctionStartOffsetInParagraph + alternative.length());602 auto updatedParagraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength(treeScopeRoot.ptr(), paragraphOffsetInTreeScope, correctionOffsetInParagraph + alternative.length()); 614 603 if (!updatedParagraphRangeContainingCorrection) 615 604 return; 616 617 605 setEnd(updatedParagraphRangeContainingCorrection.get(), m_frame.selection().selection().start()); 618 RefPtr<Range> replacementRange = TextIterator::subrange(*updatedParagraphRangeContainingCorrection, correctionStartOffsetInParagraph, alternative.length()); 619 String newText = plainText(replacementRange.get()); 606 auto replacementRange = TextIterator::subrange(*updatedParagraphRangeContainingCorrection, correctionOffsetInParagraph, alternative.length()); 620 607 621 608 // Check to see if replacement succeeded. 622 if (newText != alternative) 623 return; 624 625 DocumentMarkerController& markers = replacementRange->startContainer().document().markers(); 626 609 if (plainText(replacementRange.get()) != alternative) 610 return; 611 612 auto& markers = replacementRange->ownerDocument().markers(); 627 613 for (auto markerType : markerTypesToAdd) 628 markers.addMarker( *replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));614 markers.addMarker(replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType)); 629 615 } 630 616 -
trunk/Source/WebCore/editing/ApplyStyleCommand.cpp
r258525 r258871 224 224 void ApplyStyleCommand::applyBlockStyle(EditingStyle& style) 225 225 { 226 // update document layout once before removing styles 227 // so that we avoid the expense of updating before each and every call 228 // to check a computed style 226 // Update document layout once before removing styles so that we avoid the expense of 227 // updating before each and every call to check a computed style. 229 228 document().updateLayoutIgnorePendingStylesheets(); 230 229 231 // get positions we want to use for applying style232 230 Position start = startPosition(); 233 231 Position end = endPosition(); 234 if (comparePositions(end, start) < 0) { 235 Position swap = start; 236 start = end; 237 end = swap; 238 } 232 if (comparePositions(end, start) < 0) 233 std::swap(start, end); 239 234 240 235 VisiblePosition visibleStart(start); … … 247 242 // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints. 248 243 // Calculate start and end indices from the start of the tree that they're in. 249 auto * scope = highestEditableRoot(visibleStart.deepEquivalent());244 auto scope = makeRefPtr(highestEditableRoot(visibleStart.deepEquivalent())); 250 245 if (!scope) 251 246 return; 252 247 253 auto startRange = Range::create(document(), firstPositionInNode(scope), visibleStart.deepEquivalent().parentAnchoredEquivalent()); 254 auto endRange = Range::create(document(), firstPositionInNode(scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 255 int startIndex = TextIterator::rangeLength(startRange.ptr(), true); 256 int endIndex = TextIterator::rangeLength(endRange.ptr(), true); 248 auto scopeStart = BoundaryPoint { *scope, 0 }; 249 auto startBoundaryPoint = makeBoundaryPoint(visibleStart.deepEquivalent().parentAnchoredEquivalent()); 250 auto endBoundaryPoint = makeBoundaryPoint(visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 251 if (!startBoundaryPoint || !endBoundaryPoint) 252 return; 253 254 auto startIndex = characterCount({ scopeStart, *startBoundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 255 auto endIndex = characterCount({ scopeStart, *endBoundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 257 256 258 257 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); … … 286 285 287 286 { 288 auto startRange = TextIterator::rangeFromLocationAndLength(scope , startIndex, 0, true);289 auto endRange = TextIterator::rangeFromLocationAndLength(scope , endIndex, 0, true);287 auto startRange = TextIterator::rangeFromLocationAndLength(scope.get(), startIndex, 0, true); 288 auto endRange = TextIterator::rangeFromLocationAndLength(scope.get(), endIndex, 0, true); 290 289 if (startRange && endRange) 291 290 updateStartEnd(startRange->startPosition(), endRange->startPosition()); -
trunk/Source/WebCore/editing/CompositeEditCommand.cpp
r258129 r258871 1418 1418 int startIndex = -1; 1419 1419 int endIndex = -1; 1420 int destinationIndex = -1;1421 1420 bool originalIsDirectional = endingSelection().isDirectional(); 1422 1421 if (preserveSelection && !endingSelection().isNone()) { … … 1433 1432 startIndex = 0; 1434 1433 if (startInParagraph) { 1435 auto startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStart.deepEquivalent().parentAnchoredEquivalent()); 1436 startIndex = TextIterator::rangeLength(startRange.ptr(), true); 1434 auto paragraphStart = makeBoundaryPoint(startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent()); 1435 auto selectionStart = makeBoundaryPoint(visibleStart.deepEquivalent().parentAnchoredEquivalent()); 1436 if (paragraphStart && selectionStart) 1437 startIndex = characterCount({ *paragraphStart, *selectionStart }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 1437 1438 } 1438 1439 1439 1440 endIndex = 0; 1440 1441 if (endInParagraph) { 1441 auto endRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 1442 endIndex = TextIterator::rangeLength(endRange.ptr(), true); 1442 auto paragraphStart = makeBoundaryPoint(startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent()); 1443 auto selectionEnd = makeBoundaryPoint(visibleEnd.deepEquivalent().parentAnchoredEquivalent()); 1444 if (paragraphStart && selectionEnd) 1445 endIndex = characterCount({ *paragraphStart, *selectionEnd }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 1443 1446 } 1444 1447 } 1445 1448 } 1446 1449 1447 1450 VisiblePosition beforeParagraph = startOfParagraphToMove.previous(CannotCrossEditingBoundary); 1448 1451 VisiblePosition afterParagraph(endOfParagraphToMove.next(CannotCrossEditingBoundary)); … … 1479 1482 styleInEmptyParagraph->removeBlockProperties(); 1480 1483 } 1481 1484 1482 1485 // FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here. 1483 1486 1484 1487 setEndingSelection(VisibleSelection(start, end, DOWNSTREAM)); 1485 1488 frame().editor().clearMisspellingsAndBadGrammar(endingSelection()); … … 1510 1513 editableRoot = &document(); 1511 1514 1512 auto startToDestinationRange = Range::create(document(), firstPositionInNode(editableRoot.get()), destination.deepEquivalent().parentAnchoredEquivalent()); 1513 destinationIndex = TextIterator::rangeLength(startToDestinationRange.ptr(), true); 1515 auto destinationIndex = characterCount({ { *editableRoot, 0 }, *makeBoundaryPoint(destination.deepEquivalent().parentAnchoredEquivalent()) }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 1514 1516 1515 1517 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); -
trunk/Source/WebCore/editing/Editing.cpp
r258525 r258871 1084 1084 } 1085 1085 1086 auto range = Range::create(document, firstPositionInNode(scope.get()), position.parentAnchoredEquivalent()); 1087 return TextIterator::rangeLength(range.ptr(), true); 1086 auto start = makeBoundaryPoint(firstPositionInNode(scope.get())); 1087 auto end = makeBoundaryPoint(position.parentAnchoredEquivalent()); 1088 if (!start || !end) 1089 return 0; 1090 1091 return characterCount({ *start, *end }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 1088 1092 } 1089 1093 … … 1091 1095 int indexForVisiblePosition(Node& node, const VisiblePosition& visiblePosition, bool forSelectionPreservation) 1092 1096 { 1093 auto range = Range::create(node.document(), firstPositionInNode(&node), visiblePosition.deepEquivalent().parentAnchoredEquivalent()); 1094 return TextIterator::rangeLength(range.ptr(), forSelectionPreservation); 1097 auto start = makeBoundaryPoint(firstPositionInNode(&node)); 1098 auto end = makeBoundaryPoint(visiblePosition.deepEquivalent().parentAnchoredEquivalent()); 1099 if (!start || !end) 1100 return 0; 1101 1102 return characterCount({ *start, *end }, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior); 1095 1103 } 1096 1104 -
trunk/Source/WebCore/editing/TextCheckingHelper.cpp
r243195 r258871 149 149 int TextCheckingParagraph::rangeLength() const 150 150 { 151 return TextIterator::rangeLength(¶graphRange());151 return characterCount(paragraphRange()); 152 152 } 153 153 … … 166 166 ExceptionOr<int> TextCheckingParagraph::offsetTo(const Position& position) const 167 167 { 168 if (!position.containerNode()) 168 auto start = makeBoundaryPoint(paragraphRange().startPosition()); 169 auto end = makeBoundaryPoint(position); 170 if (!start || !end) 169 171 return Exception { TypeError }; 170 171 auto range = offsetAsRange().cloneRange(); 172 auto result = range->setEnd(*position.containerNode(), position.computeOffsetInContainerNode()); 173 if (result.hasException()) 174 return result.releaseException(); 175 return TextIterator::rangeLength(range.ptr()); 172 return characterCount({ *start, *end }); 176 173 } 177 174 … … 201 198 { 202 199 if (!m_checkingStart) 203 m_checkingStart = TextIterator::rangeLength(&offsetAsRange());200 m_checkingStart = characterCount(offsetAsRange()); 204 201 return *m_checkingStart; 205 202 } … … 208 205 { 209 206 if (!m_checkingEnd) 210 m_checkingEnd = checkingStart() + TextIterator::rangeLength(m_checkingRange.ptr());207 m_checkingEnd = checkingStart() + checkingLength(); 211 208 return *m_checkingEnd; 212 209 } … … 215 212 { 216 213 if (!m_checkingLength) 217 m_checkingLength = TextIterator::rangeLength(m_checkingRange.ptr());214 m_checkingLength = characterCount(m_checkingRange); 218 215 return *m_checkingLength; 219 216 } … … 224 221 return *m_automaticReplacementStart; 225 222 226 auto startOffsetRange = Range::create(paragraphRange().startContainer().document(), paragraphRange().startPosition(), m_automaticReplacementRange->startPosition()); 227 m_automaticReplacementStart = TextIterator::rangeLength(startOffsetRange.ptr()); 223 auto start = makeBoundaryPoint(paragraphRange().startPosition()); 224 auto end = makeBoundaryPoint(m_automaticReplacementRange->startPosition()); 225 if (!start || !end) 226 return 0; 227 228 m_automaticReplacementStart = characterCount({ *start, *end }); 228 229 return *m_automaticReplacementStart; 229 230 } … … 234 235 return *m_automaticReplacementLength; 235 236 236 auto endOffsetRange = Range::create(paragraphRange().startContainer().document(), paragraphRange().startPosition(), m_automaticReplacementRange->endPosition()); 237 m_automaticReplacementLength = TextIterator::rangeLength(endOffsetRange.ptr()) - automaticReplacementStart(); 237 m_automaticReplacementLength = characterCount(m_automaticReplacementRange); 238 238 return *m_automaticReplacementLength; 239 239 } … … 324 324 Ref<Range> paragraphRange = m_range->cloneRange(); 325 325 setStart(paragraphRange.ptr(), startOfParagraph(m_range->startPosition())); 326 int totalRangeLength = TextIterator::rangeLength(paragraphRange.ptr());326 auto totalRangeLength = characterCount(paragraphRange); 327 327 setEnd(paragraphRange.ptr(), endOfParagraph(m_range->startPosition())); 328 328 329 Ref<Range> offsetAsRange = Range::create(paragraphRange->startContainer().document(), paragraphRange->startPosition(), m_range->startPosition()); 330 int rangeStartOffset = TextIterator::rangeLength(offsetAsRange.ptr()); 331 int totalLengthProcessed = 0; 329 auto rangeStartOffset = characterCount({ *makeBoundaryPoint(paragraphRange->startPosition()), *makeBoundaryPoint(m_range->startPosition()) }); 330 CharacterCount totalLengthProcessed = 0; 332 331 333 332 bool firstIteration = true; … … 335 334 while (totalLengthProcessed < totalRangeLength) { 336 335 // Iterate through the search range by paragraphs, checking each one for spelling and grammar. 337 int currentLength = TextIterator::rangeLength(paragraphRange.ptr());336 auto currentLength = characterCount(paragraphRange); 338 337 int currentStartOffset = firstIteration ? rangeStartOffset : 0; 339 338 int currentEndOffset = currentLength; … … 341 340 // Determine the character offset from the end of the original search range to the end of the paragraph, 342 341 // since we will want to ignore results in this area. 343 auto endOffsetAsRange = Range::create(paragraphRange->startContainer().document(), paragraphRange->startPosition(), m_range->endPosition()); 344 currentEndOffset = TextIterator::rangeLength(endOffsetAsRange.ptr()); 342 currentEndOffset = characterCount({ *makeBoundaryPoint(paragraphRange->startPosition()), *makeBoundaryPoint(m_range->endPosition()) }); 345 343 lastIteration = true; 346 344 } … … 400 398 if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) { 401 399 int spellingOffset = spellingLocation - currentStartOffset; 402 if (!firstIteration) { 403 auto paragraphOffsetAsRange = Range::create(paragraphRange->startContainer().document(), m_range->startPosition(), paragraphRange->startPosition()); 404 spellingOffset += TextIterator::rangeLength(paragraphOffsetAsRange.ptr()); 405 } 400 if (!firstIteration) 401 spellingOffset += characterCount({ *makeBoundaryPoint(m_range->startPosition()), *makeBoundaryPoint(paragraphRange->startPosition()) }); 406 402 outIsSpelling = true; 407 403 outFirstFoundOffset = spellingOffset; … … 411 407 if (checkGrammar && !badGrammarPhrase.isEmpty()) { 412 408 int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset; 413 if (!firstIteration) { 414 auto paragraphOffsetAsRange = Range::create(paragraphRange->startContainer().document(), m_range->startPosition(), paragraphRange->startPosition()); 415 grammarPhraseOffset += TextIterator::rangeLength(paragraphOffsetAsRange.ptr()); 416 } 409 if (!firstIteration) 410 grammarPhraseOffset += characterCount({ *makeBoundaryPoint(m_range->startPosition()), *makeBoundaryPoint(paragraphRange->startPosition()) }); 417 411 outIsSpelling = false; 418 412 outFirstFoundOffset = grammarPhraseOffset; … … 557 551 558 552 // Bad grammar at start of range, but end of bad grammar is before or after end of range 559 if ( grammarDetail.length != TextIterator::rangeLength(m_range.ptr()))553 if (static_cast<unsigned>(grammarDetail.length) != characterCount(m_range)) 560 554 return false; 561 555 -
trunk/Source/WebCore/editing/TextIterator.cpp
r258525 r258871 2344 2344 // -------- 2345 2345 2346 int TextIterator::rangeLength(const Range* range, bool forSelectionPreservation) 2347 { 2348 if (!range) 2349 return 0; 2350 unsigned length = 0; 2351 for (TextIterator it(*range, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior); !it.atEnd(); it.advance()) 2346 CharacterCount characterCount(const SimpleRange& range, TextIteratorBehavior behavior) 2347 { 2348 CharacterCount length = 0; 2349 for (TextIterator it(range, behavior); !it.atEnd(); it.advance()) 2352 2350 length += it.text().length(); 2353 2351 return length; … … 2457 2455 // The critical assumption is that this only gets called with ranges that 2458 2456 // concentrate on a given area containing the selection root. This is done 2459 // because of text fields and textareas. The DOM for those is not 2460 // directly in the document DOM, so ensure that the range does not cross a2461 // boundaryof one of those.2457 // because of text fields and textareas. The DOM for those is not directly 2458 // in the document DOM, so ensure that the range does not cross a boundary 2459 // of one of those. 2462 2460 if (&range->startContainer() != scope && !range->startContainer().isDescendantOf(scope)) 2463 2461 return false; … … 2465 2463 return false; 2466 2464 2467 Ref<Range> testRange = Range::create(scope->document(), scope, 0, &range->startContainer(), range->startOffset()); 2468 ASSERT(&testRange->startContainer() == scope); 2469 location = TextIterator::rangeLength(testRange.ptr()); 2470 2471 testRange->setEnd(range->endContainer(), range->endOffset()); 2472 ASSERT(&testRange->startContainer() == scope); 2473 length = TextIterator::rangeLength(testRange.ptr()) - location; 2465 location = characterCount({ { *scope, 0 }, { range->startContainer(), range->startOffset() } }); 2466 length = characterCount({ { *scope, 0 }, { range->endContainer(), range->endOffset() } }) - location; 2474 2467 return true; 2475 2468 } -
trunk/Source/WebCore/editing/TextIterator.h
r258525 r258871 37 37 class RenderTextFragment; 38 38 39 // FIXME: Delete this overload after moving all the callers to the SimpleRange version. 39 40 WEBCORE_EXPORT String plainText(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false); 41 40 42 WEBCORE_EXPORT String plainText(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false); 41 43 WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false); … … 101 103 void appendTextToStringBuilder(StringBuilder& builder) const { copyableText().appendToStringBuilder(builder); } 102 104 103 WEBCORE_EXPORT static int rangeLength(const Range*, bool spacesForReplacedElements = false);105 // FIXME: Move these to SimpleRange, CharacterRange, and CharacterCount and move out of this class to the top level (bottom of this file). 104 106 WEBCORE_EXPORT static RefPtr<Range> rangeFromLocationAndLength(ContainerNode* scope, int rangeLocation, int rangeLength, bool spacesForReplacedElements = false); 105 107 WEBCORE_EXPORT static bool getLocationAndLengthFromRange(Node* scope, const Range*, size_t& location, size_t& length); … … 288 290 }; 289 291 292 using CharacterCount = std::size_t; 293 294 struct CharacterRange { 295 CharacterCount location { 0 }; 296 CharacterCount length { 0 }; 297 }; 298 299 WEBCORE_EXPORT CharacterCount characterCount(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior); 300 290 301 } // namespace WebCore -
trunk/Source/WebCore/editing/VisiblePosition.cpp
r255046 r258871 1 1 /* 2 * Copyright (C) 2004 , 2005, 2006, 2007, 2008, 2009Apple Inc. All rights reserved.2 * Copyright (C) 2004-2020 Apple Inc. All rights reserved. 3 3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. 4 4 * … … 820 820 } 821 821 822 Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition& position) 823 { 824 return makeBoundaryPoint(position.deepEquivalent()); 825 } 826 822 827 TextStream& operator<<(TextStream& stream, EAffinity affinity) 823 828 { -
trunk/Source/WebCore/editing/VisiblePosition.h
r258475 r258871 1 1 /* 2 * Copyright (C) 2004 , 2008Apple Inc. All rights reserved.2 * Copyright (C) 2004-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "Position.h" 30 30 31 namespace WTF {32 class TextStream;33 }34 35 31 namespace WebCore { 36 32 … … 49 45 // position is not at a line break. 50 46 #define VP_UPSTREAM_IF_POSSIBLE UPSTREAM 51 52 class InlineBox;53 class Node;54 47 55 48 class VisiblePosition { … … 86 79 // FIXME: This does not handle [table, 0] correctly. 87 80 Element* rootEditableElement() const { return m_deepPosition.isNotNull() ? m_deepPosition.deprecatedNode()->rootEditableElement() : 0; } 88 89 void getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const90 {91 m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);92 }93 81 94 void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const 95 { 96 m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset); 97 } 82 void getInlineBoxAndOffset(InlineBox*&, int& caretOffset) const; 83 void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*&, int& caretOffset) const; 98 84 99 85 // Rect is local to the returned renderer 100 86 WEBCORE_EXPORT LayoutRect localCaretRect(RenderObject*&) const; 87 101 88 // Bounds of (possibly transformed) caret in absolute coords 102 89 WEBCORE_EXPORT IntRect absoluteCaretBounds(bool* insideFixed = nullptr) const; 90 103 91 // Abs x/y position of the caret ignoring transforms. 104 92 // FIXME: navigation with transforms should be smarter. … … 108 96 109 97 // This is a tentative enhancement of operator== to account for affinity. 110 // FIXME: Combine this function with operator== 98 // FIXME: Combine this function with operator==. 111 99 bool equals(const VisiblePosition&) const; 112 100 … … 116 104 void showTreeForThis() const; 117 105 #endif 118 106 119 107 private: 120 108 void init(const Position&, EAffinity); … … 128 116 }; 129 117 130 // FIXME: This shouldn't ignore affinity. 131 inline bool operator==(const VisiblePosition& a, const VisiblePosition& b) 132 { 133 return a.deepEquivalent() == b.deepEquivalent(); 134 } 135 136 inline bool operator!=(const VisiblePosition& a, const VisiblePosition& b) 137 { 138 return !(a == b); 139 } 140 141 inline bool operator<(const VisiblePosition& a, const VisiblePosition& b) 142 { 143 return a.deepEquivalent() < b.deepEquivalent(); 144 } 118 bool operator==(const VisiblePosition&, const VisiblePosition&); 119 bool operator!=(const VisiblePosition&, const VisiblePosition&); 120 bool operator<(const VisiblePosition&, const VisiblePosition&); 121 bool operator>(const VisiblePosition&, const VisiblePosition&); 122 bool operator<=(const VisiblePosition&, const VisiblePosition&); 123 bool operator>=(const VisiblePosition&, const VisiblePosition&); 145 124 146 inline bool operator>(const VisiblePosition& a, const VisiblePosition& b) 147 { 148 return a.deepEquivalent() > b.deepEquivalent(); 149 } 150 151 inline bool operator<=(const VisiblePosition& a, const VisiblePosition& b) 152 { 153 return a.deepEquivalent() <= b.deepEquivalent(); 154 } 155 156 inline bool operator>=(const VisiblePosition& a, const VisiblePosition& b) 157 { 158 return a.deepEquivalent() >= b.deepEquivalent(); 159 } 125 WEBCORE_EXPORT Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition&); 160 126 161 127 WEBCORE_EXPORT RefPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&); … … 175 141 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const VisiblePosition&); 176 142 143 // inlines 144 145 // FIXME: This shouldn't ignore affinity. 146 inline bool operator==(const VisiblePosition& a, const VisiblePosition& b) 147 { 148 return a.deepEquivalent() == b.deepEquivalent(); 149 } 150 151 inline bool operator!=(const VisiblePosition& a, const VisiblePosition& b) 152 { 153 return !(a == b); 154 } 155 156 inline bool operator<(const VisiblePosition& a, const VisiblePosition& b) 157 { 158 return a.deepEquivalent() < b.deepEquivalent(); 159 } 160 161 inline bool operator>(const VisiblePosition& a, const VisiblePosition& b) 162 { 163 return a.deepEquivalent() > b.deepEquivalent(); 164 } 165 166 inline bool operator<=(const VisiblePosition& a, const VisiblePosition& b) 167 { 168 return a.deepEquivalent() <= b.deepEquivalent(); 169 } 170 171 inline bool operator>=(const VisiblePosition& a, const VisiblePosition& b) 172 { 173 return a.deepEquivalent() >= b.deepEquivalent(); 174 } 175 176 inline void VisiblePosition::getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const 177 { 178 m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset); 179 } 180 181 inline void VisiblePosition::getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const 182 { 183 m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset); 184 } 185 177 186 } // namespace WebCore 178 187 -
trunk/Source/WebCore/editing/VisibleUnits.cpp
r258525 r258871 1902 1902 } 1903 1903 1904 int distanceBetweenPositions(const VisiblePosition& vp, const VisiblePosition& other)1905 { 1906 if ( vp.isNull() || other.isNull())1904 std::ptrdiff_t distanceBetweenPositions(const VisiblePosition& a, const VisiblePosition& b) 1905 { 1906 if (a.isNull() || b.isNull()) 1907 1907 return 0; 1908 1909 bool thisIsStart = (vp < other); 1910 1911 // Start must come first in the Range constructor. 1912 auto range = Range::create(vp.deepEquivalent().deprecatedNode()->document(), 1913 (thisIsStart ? vp : other), 1914 (thisIsStart ? other : vp)); 1915 int distance = TextIterator::rangeLength(range.ptr()); 1916 1917 return (thisIsStart ? -distance : distance); 1908 return a < b 1909 ? -characterCount({ *makeBoundaryPoint(a), *makeBoundaryPoint(b) }) 1910 : characterCount({ *makeBoundaryPoint(b), *makeBoundaryPoint(a) }); 1918 1911 } 1919 1912 -
trunk/Source/WebCore/editing/VisibleUnits.h
r249838 r258871 103 103 WEBCORE_EXPORT VisiblePosition positionOfNextBoundaryOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection); 104 104 WEBCORE_EXPORT RefPtr<Range> enclosingTextUnitOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection); 105 WEBCORE_EXPORT int distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&);105 WEBCORE_EXPORT std::ptrdiff_t distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&); 106 106 WEBCORE_EXPORT RefPtr<Range> wordRangeFromPosition(const VisiblePosition&); 107 107 WEBCORE_EXPORT VisiblePosition closestWordBoundaryForPosition(const VisiblePosition& position); -
trunk/Source/WebCore/editing/cocoa/DataDetection.mm
r258525 r258871 72 72 { 73 73 String fullPlainTextString = plainText(contextRange.get()); 74 int hitLocation = TextIterator::rangeLength(makeRange(contextRange->startPosition(), position).get()); 75 76 RetainPtr<DDScannerRef> scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr)); 77 RetainPtr<DDScanQueryRef> scanQuery = adoptCF(DDScanQueryCreateFromString(kCFAllocatorDefault, fullPlainTextString.createCFString().get(), CFRangeMake(0, fullPlainTextString.length()))); 74 auto start = contextRange->startPosition(); 75 if (start.isNull() || position.isNull()) 76 return nil; 77 CFIndex hitLocation = characterCount({ *makeBoundaryPoint(start), *makeBoundaryPoint(position) }); 78 79 auto scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr)); 80 auto scanQuery = adoptCF(DDScanQueryCreateFromString(kCFAllocatorDefault, fullPlainTextString.createCFString().get(), CFRangeMake(0, fullPlainTextString.length()))); 78 81 79 82 if (!DDScannerScanQuery(scanner.get(), scanQuery.get())) 80 return n ullptr;81 82 RetainPtr<CFArrayRef>results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));83 return nil; 84 85 auto results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap)); 83 86 84 87 // Find the DDResultRef that intersects the hitTestResult's VisiblePosition. … … 101 104 102 105 if (!mainResult) 103 return n ullptr;106 return nil; 104 107 105 108 RetainPtr<DDActionContext> actionContext = adoptNS([allocDDActionContextInstance() init]); … … 113 116 for (const auto& quad : quads) 114 117 detectedDataBoundingBox.unite(frameView->contentsToWindow(quad.enclosingBoundingBox())); 115 118 116 119 detectedDataRange = mainResultRange; 117 120 118 121 return actionContext; 119 122 } -
trunk/Source/WebCore/editing/cocoa/DictionaryLookup.mm
r258525 r258871 1 1 /* 2 * Copyright (C) 2014-20 19Apple 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 … … 265 265 { 266 266 BEGIN_BLOCK_OBJC_EXCEPTIONS; 267 267 268 268 if (!RevealLibrary() || !RevealCoreLibrary() || !getRVItemClass()) 269 269 return { nullptr, nil }; 270 271 auto selectedRange = selection.toNormalizedRange(); 272 if (!selectedRange) 270 271 if (!selection.toNormalizedRange()) 273 272 return { nullptr, nil }; 274 273 … … 280 279 auto paragraphStart = startOfParagraph(selectionStart); 281 280 auto paragraphEnd = endOfParagraph(selectionEnd); 282 283 int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 284 int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()); 285 NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart); 286 281 if (paragraphStart.isNull() || paragraphEnd.isNull()) 282 return { nullptr, nil }; 283 284 auto lengthToSelectionStart = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) }); 285 auto selectionCharacterCount = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) }); 286 NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, selectionCharacterCount); 287 287 288 RefPtr<Range> fullCharacterRange = makeRange(paragraphStart, paragraphEnd); 288 289 String itemString = plainText(fullCharacterRange.get()); 289 290 RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:rangeToPass]); 290 291 NSRange highlightRange = item.get().highlightRange; 291 292 292 293 return { TextIterator::subrange(*fullCharacterRange, highlightRange.location, highlightRange.length), nil }; 293 294 294 295 END_BLOCK_OBJC_EXCEPTIONS; 295 296 296 297 return { nullptr, nil }; 297 298 } … … 323 324 auto selection = frame->page()->focusController().focusedOrMainFrame().selection().selection(); 324 325 NSRange selectionRange; 325 inthitIndex;326 NSUInteger hitIndex; 326 327 RefPtr<Range> fullCharacterRange; 327 328 … … 329 330 auto selectionStart = selection.visibleStart(); 330 331 auto selectionEnd = selection.visibleEnd(); 331 332 332 333 // As context, we are going to use the surrounding paragraphs of text. 333 334 auto paragraphStart = startOfParagraph(selectionStart); 334 335 auto paragraphEnd = endOfParagraph(selectionEnd); 335 336 336 auto rangeToSelectionStart = makeRange(paragraphStart, selectionStart);337 auto rangeToSelectionEnd = makeRange(paragraphStart, selectionEnd);338 339 337 fullCharacterRange = makeRange(paragraphStart, paragraphEnd); 340 338 if (!fullCharacterRange) 341 339 return { nullptr, nil }; 342 340 343 selectionRange = NSMakeRange( TextIterator::rangeLength(rangeToSelectionStart.get()), TextIterator::rangeLength(makeRange(selectionStart, selectionEnd).get()));344 345 hitIndex = TextIterator::rangeLength(makeRange(paragraphStart, position).get());341 selectionRange = NSMakeRange(characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) }), 342 characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) })); 343 hitIndex = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(position) }); 346 344 } else { 347 345 VisibleSelection selectionAccountingForLineRules { position }; 348 346 selectionAccountingForLineRules.expandUsingGranularity(WordGranularity); 349 347 position = selectionAccountingForLineRules.start(); 348 350 349 // As context, we are going to use 250 characters of text before and after the point. 351 350 fullCharacterRange = rangeExpandedAroundPositionByCharacters(position, 250); 352 353 351 if (!fullCharacterRange) 354 352 return { nullptr, nil }; 355 353 356 354 selectionRange = NSMakeRange(NSNotFound, 0); 357 hitIndex = TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get());355 hitIndex = characterCount({ *makeBoundaryPoint(fullCharacterRange->startPosition()), *makeBoundaryPoint(position) }); 358 356 } 359 357 360 358 NSRange selectedRange = [getRVSelectionClass() revealRangeAtIndex:hitIndex selectedRanges:@[[NSValue valueWithRange:selectionRange]] shouldUpdateSelection:nil]; 361 359 362 360 String itemString = plainText(*fullCharacterRange); 363 361 RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:selectedRange]); -
trunk/Source/WebCore/editing/ios/DictationCommandIOS.cpp
r256563 r258871 49 49 void DictationCommandIOS::doApply() 50 50 { 51 VisiblePosition insertionPosition(startingSelection().visibleStart()); 52 53 unsigned resultLength = 0; 51 CharacterCount resultLength = 0; 54 52 for (auto& interpretations : m_dictationPhrases) { 55 53 const String& firstInterpretation = interpretations[0]; … … 63 61 } 64 62 65 VisiblePosition afterResults(endingSelection().visibleEnd());63 // FIXME: Add the result marker using a Position cached before results are inserted, instead of relying on character counts. 66 64 67 Element* root = afterResults.rootEditableElement(); 65 auto endPosition = endingSelection().visibleEnd(); 66 auto end = makeBoundaryPoint(endPosition); 67 auto* root = endPosition.rootEditableElement(); 68 if (!end || !root) 69 return; 68 70 69 // FIXME: Add the result marker using a Position cached before results are inserted, instead of relying on TextIterators. 70 auto rangeToEnd = Range::create(document(), createLegacyEditingPosition((Node *)root, 0), afterResults.deepEquivalent()); 71 int endIndex = TextIterator::rangeLength(rangeToEnd.ptr(), true); 72 int startIndex = endIndex - resultLength; 71 auto endOffset = characterCount({ { *root, 0 }, WTFMove(*end) }); 72 if (endOffset < resultLength) 73 return; 73 74 74 if (startIndex >= 0) {75 RefPtr<Range> resultRange = TextIterator::rangeFromLocationAndLength(document().documentElement(), startIndex, endIndex, true);76 ASSERT(resultRange); // FIXME: What guarantees this?77 document().markers().addDictationResultMarker(*resultRange, m_metadata); 78 }75 auto resultRange = TextIterator::rangeFromLocationAndLength(root, endOffset - resultLength, endOffset); 76 if (!resultRange) 77 return; 78 79 document().markers().addDictationResultMarker(*resultRange, m_metadata); 79 80 } 80 81 -
trunk/Source/WebCore/editing/mac/DictionaryLookupLegacy.mm
r240494 r258871 1 1 /* 2 * Copyright (C) 2014-20 19Apple 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 … … 90 90 auto paragraphStart = startOfParagraph(selectionStart); 91 91 auto paragraphEnd = endOfParagraph(selectionEnd); 92 93 int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 94 int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()); 95 NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart); 92 if (paragraphStart.isNull() || paragraphEnd.isNull()) 93 return { nullptr, nil }; 94 95 auto lengthToSelectionStart = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) }); 96 auto selectionCharacterCount = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) }); 97 NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, selectionCharacterCount); 96 98 97 99 NSDictionary *options = nil; … … 134 136 return { nullptr, nil }; 135 137 136 NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get()), 0); 138 auto fullCharacterStart = makeBoundaryPoint(fullCharacterRange->startPosition()); 139 auto positionBoundary = makeBoundaryPoint(position); 140 if (!fullCharacterStart || !positionBoundary) 141 return { nullptr, nil }; 142 143 NSRange rangeToPass = NSMakeRange(characterCount({ *fullCharacterStart, *positionBoundary }), 0); 137 144 NSDictionary *options = nil; 138 145 NSRange extractedRange = tokenRange(plainText(fullCharacterRange.get()), rangeToPass, &options); -
trunk/Source/WebCore/page/EventHandler.cpp
r258679 r258871 655 655 } 656 656 657 static int textDistance(const Position& start, const Position& end) 658 { 659 auto range = Range::create(start.anchorNode()->document(), start, end); 660 return TextIterator::rangeLength(range.ptr(), true); 657 static CharacterCount textDistance(const Position& start, const Position& end) 658 { 659 auto startBoundary = makeBoundaryPoint(start); 660 auto endBoundary = makeBoundaryPoint(end); 661 if (!startBoundary || !endBoundary) 662 return 0; 663 return characterCount({ *startBoundary, *endBoundary }, TextIteratorEmitsCharactersBetweenAllVisiblePositions); 661 664 } 662 665 -
trunk/Source/WebKit/ChangeLog
r258869 r258871 1 2020-03-23 Darin Adler <darin@apple.com> 2 3 Change TextIterator::rangeLength to not require a live range 4 https://bugs.webkit.org/show_bug.cgi?id=209207 5 6 Reviewed by Antti Koivisto. 7 8 * Shared/EditingRange.cpp: 9 (WebKit::EditingRange::toRange): Use characterCount. 10 * WebProcess/WebCoreSupport/WebEditorClient.cpp: 11 (WebKit::insertionPointFromCurrentSelection): Changed return type to 12 CharacterCount and use characterCount. 13 (WebKit::WebEditorClient::supportsGlobalSelection): Tweaked #if. 14 * WebProcess/WebPage/WebPage.cpp: 15 (WebKit::targetFrameForEditing): Use characterCount. 16 * WebProcess/WebPage/glib/WebPageGLib.cpp: 17 (WebKit::WebPage::platformEditorState const): Ditto. 18 * WebProcess/WebPage/ios/WebPageIOS.mm: 19 (WebKit::rangeNearPositionMatchesText): Ditto. 20 * WebProcess/WebPage/mac/WebPageMac.mm: 21 (WebKit::WebPage::platformEditorState const): Ditto. 22 1 23 2020-03-23 youenn fablet <youenn@apple.com> 2 24 -
trunk/Source/WebKit/Shared/EditingRange.cpp
r258129 r258871 59 59 ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::Paragraph); 60 60 61 const WebCore::VisibleSelection& selection = frame.selection().selection(); 62 RefPtr<WebCore::Range> selectedRange = selection.toNormalizedRange(); 63 if (!selectedRange) 61 auto& selection = frame.selection().selection(); 62 if (!selection.toNormalizedRange()) 64 63 return nullptr; 65 64 66 RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());67 if (!paragraph Range)65 auto paragraphStart = makeBoundaryPoint(startOfParagraph(selection.visibleStart())); 66 if (!paragraphStart) 68 67 return nullptr; 68 auto& rootNode = paragraphStart->container->treeScope().rootNode(); 69 69 70 auto& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode(); 71 int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, ¶graphRange->startContainer(), paragraphRange->startOffset()).ptr()); 72 return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(range.location), length); 70 auto paragraphStartIndex = WebCore::characterCount({ { rootNode, 0 }, *paragraphStart }); 71 return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + range.location, length); 73 72 } 74 73 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp
r254656 r258871 362 362 363 363 #if !PLATFORM(COCOA) && !USE(GLIB) 364 364 365 void WebEditorClient::handleKeyboardEvent(KeyboardEvent& event) 365 366 { … … 372 373 notImplemented(); 373 374 } 375 374 376 #endif // !PLATFORM(COCOA) && !USE(GLIB) 375 377 … … 421 423 422 424 #if !PLATFORM(IOS_FAMILY) 425 423 426 void WebEditorClient::overflowScrollPositionChanged() 424 427 { … … 430 433 notImplemented(); 431 434 } 435 432 436 #endif 433 437 … … 550 554 } 551 555 552 static int32_t insertionPointFromCurrentSelection(const VisibleSelection& currentSelection) 553 { 554 VisiblePosition selectionStart = currentSelection.visibleStart(); 555 VisiblePosition paragraphStart = startOfParagraph(selectionStart); 556 return TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 556 static CharacterCount insertionPointFromCurrentSelection(const VisibleSelection& currentSelection) 557 { 558 auto selectionStart = currentSelection.visibleStart(); 559 auto selectionStartBoundary = makeBoundaryPoint(selectionStart); 560 auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart)); 561 if (!selectionStartBoundary || !paragraphStart) 562 return 0; 563 return characterCount({ *paragraphStart, *selectionStartBoundary }); 557 564 } 558 565 559 566 #if USE(UNIFIED_TEXT_CHECKING) 567 560 568 Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView stringView, OptionSet<WebCore::TextCheckingType> checkingTypes, const VisibleSelection& currentSelection) 561 569 { … … 564 572 return results; 565 573 } 574 566 575 #endif 567 576 … … 617 626 bool WebEditorClient::supportsGlobalSelection() 618 627 { 619 #if PLATFORM(GTK) 620 #if PLATFORM(X11) 628 #if PLATFORM(GTK) && PLATFORM(X11) 621 629 if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) 622 630 return true; 623 631 #endif 624 #if PLATFORM( WAYLAND)632 #if PLATFORM(GTK) && PLATFORM(WAYLAND) 625 633 if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland) 626 634 return true; 627 635 #endif 628 #endif629 636 return false; 630 637 } -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r258869 r258871 5429 5429 5430 5430 #if PLATFORM(GTK) || PLATFORM(WPE) 5431 5431 5432 static Frame* targetFrameForEditing(WebPage& page) 5432 5433 { … … 5468 5469 auto selectionStart = selection.visibleStart(); 5469 5470 auto surroundingRange = makeRange(startOfEditableContent(selectionStart), selectionStart); 5470 auto cursorPosition = TextIterator::rangeLength(surroundingRange.get());5471 auto cursorPosition = WebCore::characterCount(*surroundingRange); 5471 5472 auto& rootNode = surroundingRange->startContainer().treeScope().rootNode(); 5472 5473 auto selectionRange = TextIterator::rangeFromLocationAndLength(&rootNode, cursorPosition + offset, characterCount); … … 5480 5481 sendEditorStateUpdate(); 5481 5482 } 5483 5482 5484 #endif 5483 5485 -
trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp
r258131 r258871 117 117 clonedRange->setStart(compositionRange->endPosition()); 118 118 postLayoutData.surroundingContext = plainText(surroundingRange.get()) + plainText(clonedRange.ptr()); 119 postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(surroundingRange.get());119 postLayoutData.surroundingContextCursorPosition = characterCount(*surroundingRange); 120 120 postLayoutData.surroundingContextSelectionPosition = postLayoutData.surroundingContextCursorPosition; 121 121 } else { 122 122 postLayoutData.surroundingContext = plainText(surroundingRange.get()); 123 postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(makeRange(surroundingStart, selectionStart).get());124 postLayoutData.surroundingContextSelectionPosition = TextIterator::rangeLength(makeRange(surroundingStart, selection.visibleEnd()).get());123 postLayoutData.surroundingContextCursorPosition = characterCount(*makeRange(surroundingStart, selectionStart)); 124 postLayoutData.surroundingContextSelectionPosition = characterCount(*makeRange(surroundingStart, selection.visibleEnd())); 125 125 } 126 126 } -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r258804 r258871 1990 1990 } 1991 1991 1992 static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, RefPtr<Range> selectionRange) 1993 { 1994 if (!selectionRange) 1992 static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, const VisibleSelection& selection) 1993 { 1994 auto liveRange = selection.firstRange(); 1995 if (!liveRange) 1995 1996 return WTF::nullopt; 1996 auto range = Range::create(selectionRange->ownerDocument(), selectionRange->startPosition(), position.deepEquivalent().parentAnchoredEquivalent()); 1997 unsigned targetOffset = TextIterator::rangeLength(range.ptr(), true); 1998 return findClosestPlainText(*selectionRange, matchText, { }, targetOffset); 1997 SimpleRange range { *liveRange }; 1998 auto boundaryPoint = makeBoundaryPoint(position); 1999 if (!boundaryPoint) 2000 return WTF::nullopt; 2001 return findClosestPlainText(range, matchText, { }, characterCount({ range.start, *boundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions)); 1999 2002 } 2000 2003 … … 2023 2026 if (plainTextForDisplay(range.ptr()) != text) { 2024 2027 // Try to search for a range which is the closest to the position within the selection range that matches the passed in text. 2025 if (auto wordRange = rangeNearPositionMatchesText(startPosition, text, selection .toNormalizedRange())) {2028 if (auto wordRange = rangeNearPositionMatchesText(startPosition, text, selection)) { 2026 2029 if (!wordRange->collapsed()) 2027 2030 range = createLiveRange(*wordRange); -
trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
r258525 r258871 141 141 } 142 142 143 const VisibleSelection& selection = frame.selection().selection();143 auto& selection = frame.selection().selection(); 144 144 RefPtr<Range> selectedRange = selection.toNormalizedRange(); 145 145 if (!selectedRange) … … 148 148 auto& postLayoutData = result.postLayoutData(); 149 149 VisiblePosition selectionStart = selection.visibleStart(); 150 VisiblePosition selectionEnd = selection.visibleEnd(); 151 VisiblePosition paragraphStart = startOfParagraph(selectionStart); 152 VisiblePosition paragraphEnd = endOfParagraph(selectionEnd); 153 154 postLayoutData.candidateRequestStartPosition = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 155 postLayoutData.selectedTextLength = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()) - postLayoutData.candidateRequestStartPosition; 150 auto selectionStartBoundary = makeBoundaryPoint(selectionStart); 151 auto selectionEnd = makeBoundaryPoint(selection.visibleEnd()); 152 auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart)); 153 154 if (!selectionStartBoundary || !selectionEnd || !paragraphStart) 155 return; 156 157 postLayoutData.candidateRequestStartPosition = characterCount({ *paragraphStart, *selectionStartBoundary }); 158 postLayoutData.selectedTextLength = characterCount({ *selectionStartBoundary, *selectionEnd }); 156 159 postLayoutData.paragraphContextForCandidateRequest = plainText(frame.editor().contextRangeForCandidateRequest().get()); 157 160 postLayoutData.stringForCandidateRequest = frame.editor().stringForCandidateRequest(); -
trunk/Source/WebKitLegacy/mac/ChangeLog
r258869 r258871 1 2020-03-23 Darin Adler <darin@apple.com> 2 3 Change TextIterator::rangeLength to not require a live range 4 https://bugs.webkit.org/show_bug.cgi?id=209207 5 6 Reviewed by Antti Koivisto. 7 8 * WebCoreSupport/WebEditorClient.mm: 9 (insertionPointFromCurrentSelection): Use characterCount. 10 (WebEditorClient::requestCandidatesForSelection): Ditto. 11 * WebView/WebFrame.mm: 12 (-[WebFrame _convertToDOMRange:rangeIsRelativeTo:]): Ditto. 13 1 14 2020-03-23 youenn fablet <youenn@apple.com> 2 15 -
trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm
r258182 r258871 1032 1032 } 1033 1033 1034 static int insertionPointFromCurrentSelection(const VisibleSelection& currentSelection) 1035 { 1036 VisiblePosition selectionStart = currentSelection.visibleStart(); 1037 VisiblePosition paragraphStart = startOfParagraph(selectionStart); 1038 return TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 1034 static NSUInteger insertionPointFromCurrentSelection(const VisibleSelection& selection) 1035 { 1036 auto selectionStart = selection.visibleStart(); 1037 auto selectionStartBoundary = makeBoundaryPoint(selectionStart); 1038 auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart)); 1039 if (!selectionStartBoundary || !paragraphStart) 1040 return 0; 1041 return characterCount({ *paragraphStart, *selectionStartBoundary }); 1039 1042 } 1040 1043 1041 1044 Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView string, OptionSet<TextCheckingType> coreCheckingTypes, const VisibleSelection& currentSelection) 1042 1045 { 1043 NSDictionary *options = @{ NSTextCheckingInsertionPointKey : [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)]};1046 NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) }; 1044 1047 return core([[NSSpellChecker sharedSpellChecker] checkString:string.createNSStringWithoutCopying().get() range:NSMakeRange(0, string.length()) types:(nsTextCheckingTypes(coreCheckingTypes) | NSTextCheckingTypeOrthography) options:options inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:NULL wordCount:NULL], coreCheckingTypes); 1045 1048 } … … 1084 1087 NSOrthography* orthography = nil; 1085 1088 NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker]; 1086 NSDictionary *options = @{ NSTextCheckingInsertionPointKey : [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)]};1089 NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) }; 1087 1090 if (context.length()) { 1088 1091 [checker checkString:context range:NSMakeRange(0, context.length()) types:NSTextCheckingTypeOrthography options:options inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:&orthography wordCount:0]; … … 1117 1120 return; 1118 1121 1119 RefPtr<Range> selectedRange = selection.toNormalizedRange(); 1120 if (!selectedRange) 1121 return; 1122 1123 Frame* frame = core([m_webView _selectedOrMainFrame]); 1122 if (!selection.toNormalizedRange()) 1123 return; 1124 1125 auto* frame = core([m_webView _selectedOrMainFrame]); 1124 1126 if (!frame) 1125 1127 return; … … 1127 1129 m_lastSelectionForRequestedCandidates = selection; 1128 1130 1129 VisiblePosition selectionStart = selection.visibleStart(); 1130 VisiblePosition selectionEnd = selection.visibleEnd(); 1131 VisiblePosition paragraphStart = startOfParagraph(selectionStart); 1132 VisiblePosition paragraphEnd = endOfParagraph(selectionEnd); 1133 1134 int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); 1135 int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()); 1136 m_rangeForCandidates = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart); 1131 auto selectionStart = selection.visibleStart(); 1132 auto selectionStartOffsetInParagraph = characterCount({ *makeBoundaryPoint(startOfParagraph(selectionStart)), *makeBoundaryPoint(selectionStart) }); 1133 auto selectionLength = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selection.visibleEnd()) }); 1134 1135 m_rangeForCandidates = NSMakeRange(selectionStartOffsetInParagraph, selectionLength); 1137 1136 m_paragraphContextForCandidateRequest = plainText(frame->editor().contextRangeForCandidateRequest().get()); 1138 1137 -
trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm
r258869 r258871 836 836 auto* element = _private->coreFrame->selection().rootEditableElementOrDocumentElement(); 837 837 if (!element) 838 return n il;838 return nullptr; 839 839 return WebCore::TextIterator::rangeFromLocationAndLength(element, nsrange.location, nsrange.length); 840 840 } … … 842 842 ASSERT(rangeIsRelativeTo == WebRangeIsRelativeTo::Paragraph); 843 843 844 const auto& selection = _private->coreFrame->selection().selection(); 845 RefPtr<WebCore::Range> selectedRange = selection.toNormalizedRange(); 846 if (!selectedRange) 844 auto paragraphStart = makeBoundaryPoint(startOfParagraph(_private->coreFrame->selection().selection().visibleStart())); 845 if (!paragraphStart) 847 846 return nullptr; 848 849 RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd()); 850 if (!paragraphRange) 851 return nullptr; 852 853 auto& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode(); 854 int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, ¶graphRange->startContainer(), paragraphRange->startOffset()).ptr()); 855 return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(nsrange.location), nsrange.length); 847 auto& rootNode = paragraphStart->container->treeScope().rootNode(); 848 849 auto paragraphStartIndex = WebCore::characterCount({ { rootNode, 0 }, *paragraphStart }); 850 return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + nsrange.location, nsrange.length); 856 851 } 857 852
Note: See TracChangeset
for help on using the changeset viewer.