Changeset 258871 in webkit


Ignore:
Timestamp:
Mar 23, 2020 1:50:15 PM (4 years ago)
Author:
Darin Adler
Message:

Change TextIterator::rangeLength to not require a live range
https://bugs.webkit.org/show_bug.cgi?id=209207

Reviewed by Antti Koivisto.

Source/WebCore:

  • Renamed TextIterator::rangeLength to characterCount.
  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::rangeMatchesTextNearRange): Use characterCount.
(WebCore::resetNodeAndOffsetForReplacedNode): Ditto.
(WebCore::AXObjectCache::nextCharacterOffset): Ditto.

  • accessibility/atk/AXObjectCacheAtk.cpp:

(WebCore::AXObjectCache::nodeTextChangePlatformNotification): Ditto.

  • accessibility/atk/WebKitAccessibleHyperlink.cpp:

(rangeLengthForObject): Ditto.

  • accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:

(-[WebAccessibilityObjectWrapper _convertToNSRange:]): Ditto.

  • dom/SimpleRange.h: Export another constructor.
  • editing/AlternativeTextController.cpp:

(WebCore::AlternativeTextController::applyAlternativeTextToRange):
Use characterCount.

  • editing/ApplyStyleCommand.cpp:

(WebCore::ApplyStyleCommand::applyBlockStyle): Ditto.

  • editing/CompositeEditCommand.cpp:

(WebCore::CompositeEditCommand::moveParagraphs): Ditto.

  • editing/Editing.cpp:

(WebCore::indexForVisiblePosition): Ditto.

  • editing/TextCheckingHelper.cpp:

(WebCore::TextCheckingParagraph::rangeLength const): Ditto.
(WebCore::TextCheckingParagraph::offsetTo const): Ditto.
(WebCore::TextCheckingParagraph::checkingStart const): Ditto.
(WebCore::TextCheckingParagraph::checkingEnd const): Ditto.
(WebCore::TextCheckingParagraph::checkingLength const): Ditto.
(WebCore::TextCheckingParagraph::automaticReplacementStart const): Ditto.
(WebCore::TextCheckingParagraph::automaticReplacementLength const): Ditto.
(WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): Ditto.
(WebCore::TextCheckingHelper::isUngrammatical const): Ditto.

  • editing/TextIterator.cpp:

(WebCore::TextIterator::rangeLength): Deleted.
(WebCore::characterCount): Like the baove but the argument is SimpleRange
and return is CharacterCount. Even though each individual node is limited
to 32-bit size, ranges covering multiple nodes could have a count of
characters that exceeds 32 bits, so CharacterCount is size_t.
(WebCore::TextIterator::getLocationAndLengthFromRange): Use characterCount.

  • editing/TextIterator.h: Added characterCount function,

CharacterCount and CharacterRange types. Removed TextIterator::rangeLength.
Added FIXME comments about the next steps.

  • editing/VisiblePosition.cpp:

(WebCore::makeBoundaryPoint): Added.

  • editing/VisiblePosition.h: Added makeBoundaryPoint. Also removed

extraneous forward declarations and moved some function bodies out of the
class definition.

  • editing/VisibleUnits.cpp:

(WebCore::distanceBetweenPositions): Changed return type to ptrdiff_t.
Use characterCount.

  • editing/VisibleUnits.h: Updated for the above.
  • editing/cocoa/DataDetection.mm:

(WebCore::detectItemAtPositionWithRange): Use characterCount.

  • editing/cocoa/DictionaryLookup.mm:

(WebCore::DictionaryLookup::rangeForSelection): Ditto.
(WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto.

  • editing/ios/DictationCommandIOS.cpp:

(WebCore::DictationCommandIOS::doApply): Ditto.

  • editing/mac/DictionaryLookupLegacy.mm:

(WebCore::DictionaryLookup::rangeForSelection): Ditto.
(WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto.

  • page/EventHandler.cpp:

(WebCore::textDistance): Ditto.

Source/WebKit:

  • Shared/EditingRange.cpp:

(WebKit::EditingRange::toRange): Use characterCount.

  • WebProcess/WebCoreSupport/WebEditorClient.cpp:

(WebKit::insertionPointFromCurrentSelection): Changed return type to
CharacterCount and use characterCount.
(WebKit::WebEditorClient::supportsGlobalSelection): Tweaked #if.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::targetFrameForEditing): Use characterCount.

  • WebProcess/WebPage/glib/WebPageGLib.cpp:

(WebKit::WebPage::platformEditorState const): Ditto.

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::rangeNearPositionMatchesText): Ditto.

  • WebProcess/WebPage/mac/WebPageMac.mm:

(WebKit::WebPage::platformEditorState const): Ditto.

Source/WebKitLegacy/mac:

  • WebCoreSupport/WebEditorClient.mm:

(insertionPointFromCurrentSelection): Use characterCount.
(WebEditorClient::requestCandidatesForSelection): Ditto.

  • WebView/WebFrame.mm:

(-[WebFrame _convertToDOMRange:rangeIsRelativeTo:]): Ditto.

LayoutTests:

  • editing/mac/spelling/autocorrection-contraction-expected.txt: Update these expected

results because of changes to delegate callbacks. The test is still passing and this
change is only in the legacy WebKit case (there is a separate result for modern WebKit).
This seems to be a progression, not evidence of a bug.

Location:
trunk
Files:
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r258866 r258871  
     12020-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
    1132020-03-23  Rob Buis  <rbuis@igalia.com>
    214
  • trunk/LayoutTests/editing/mac/spelling/autocorrection-contraction-expected.txt

    r199054 r258871  
    152152EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    153153EDITING 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
     154EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     155EDITING 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
     156EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     157EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     158EDITING 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
     159EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     160EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     161EDITING 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
     162EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     163EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     164EDITING 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
     165EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     166EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     167EDITING 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
     168EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     169EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     170EDITING 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
     171EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     172EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     173EDITING 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
     174EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     175EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
     176EDITING 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
    155177EDITING 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 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
    157 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
     178EDITING 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
     179EDITING 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
    158180EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    159181EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
     
    162184EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    163185EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    164 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    165 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:FALSE
    166 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    167 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    168 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:FALSE
    169 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    170 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    171 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
    172 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    173 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    174 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
    175 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    176 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    177 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
    178 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    179 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    180 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
    181 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    182 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    183 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
    184 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    185 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
    186186EDITING 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
    187187EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
  • trunk/Source/WebCore/ChangeLog

    r258869 r258871  
     12020-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
    1792020-03-23  youenn fablet  <youenn@apple.com>
    280
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r258780 r258871  
    19391939    auto startPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), -textLength);
    19401940    auto endPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), 2 * textLength);
    1941 
    19421941    if (startPosition.isNull())
    19431942        startPosition = firstPositionInOrBeforeNode(originalRange.start.container.ptr());
     
    19451944        endPosition = lastPositionInOrAfterNode(originalRange.end.container.ptr());
    19461945
    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())
    19491948        return WTF::nullopt;
    19501949
    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);
    19531951    return findClosestPlainText(searchRange, matchText, { }, targetOffset);
    19541952}
     
    19931991{
    19941992    // 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);
    20011998    return replacedNode->parentNode();
    20021999}
     
    24142411   
    24152412    // We don't always move one 'character' at a time since there might be composed characters.
    2416     int nextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset);
     2413    unsigned nextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset);
    24172414    CharacterOffset next = characterOffsetForNodeAndOffset(*characterOffset.node, nextOffset);
    24182415   
    24192416    // To be consistent with VisiblePosition, we should consider the case that current node end to next node start counts 1 offset.
    24202417    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        }
    24242423    }
    24252424   
  • trunk/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp

    r254566 r258871  
    356356        // right offset (e.g. multiline text areas).
    357357        auto range = Range::create(document, node->parentNode(), 0, node, 0);
    358         offsetToEmit = offset + TextIterator::rangeLength(range.ptr());
     358        offsetToEmit = offset + characterCount(range.get());
    359359    }
    360360
  • trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp

    r256563 r258871  
    155155{
    156156    // 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);
    158158
    159159    // Check whether the current hyperlink belongs to a list item.
  • trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp

    r256563 r258871  
    411411    // Set values for start offsets and calculate initial range length.
    412412    // 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));
    414414    auto nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
    415     int rangeLength = TextIterator::rangeLength(nodeRange.ptr(), true);
     415    int rangeLength = characterCount(nodeRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
    416416
    417417    // Special cases that are only relevant when working with *_END boundaries.
  • trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp

    r256563 r258871  
    248248    else if (!isStartOfLine(endPosition)) {
    249249        RefPtr<Range> range = makeRange(startPosition, endPosition.previous());
    250         offset = TextIterator::rangeLength(range.get(), true) + 1;
     250        offset = (range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0) + 1;
    251251    } else {
    252252        RefPtr<Range> range = makeRange(startPosition, endPosition);
    253         offset = TextIterator::rangeLength(range.get(), true);
     253        offset = range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0;
    254254    }
    255255
  • trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm

    r258525 r258871  
    23112311}
    23122312
    2313 - (NSRange)_convertToNSRange:(Range *)range
    2314 {
    2315     if (!range)
     2313- (NSRange)_convertToNSRange:(Range *)liveRange
     2314{
     2315    if (!liveRange)
    23162316        return NSMakeRange(NSNotFound, 0);
    23172317
    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);
    23212329
    23222330    // 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.  These checks ensure we don't produce
     2331    // that is not inside the current editable region. These checks ensure we don't produce
    23242332    // 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()))
    23262334        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));
    23372337}
    23382338
  • trunk/Source/WebCore/dom/SimpleRange.h

    r258525 r258871  
    4343    bool collapsed() const { return start == end; }
    4444
    45     SimpleRange(const BoundaryPoint&, const BoundaryPoint&);
     45    WEBCORE_EXPORT SimpleRange(const BoundaryPoint&, const BoundaryPoint&);
    4646    WEBCORE_EXPORT SimpleRange(BoundaryPoint&&, BoundaryPoint&&);
    4747
  • trunk/Source/WebCore/editing/AlternativeTextController.cpp

    r258087 r258871  
    581581void AlternativeTextController::applyAlternativeTextToRange(const Range& range, const String& alternative, AlternativeTextType alternativeType, OptionSet<DocumentMarker::MarkerType> markerTypesToAdd)
    582582{
    583     auto paragraphRangeContainingCorrection = range.cloneRange();
    584 
    585     setStart(paragraphRangeContainingCorrection.ptr(), startOfParagraph(range.startPosition()));
    586     setEnd(paragraphRangeContainingCorrection.ptr(), endOfParagraph(range.endPosition()));
    587 
    588583    // 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.
    602586
    603587    // 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, &paragraphRangeContainingCorrection->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
    612601    // 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());
    614603    if (!updatedParagraphRangeContainingCorrection)
    615604        return;
    616 
    617605    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());
    620607
    621608    // 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();
    627613    for (auto markerType : markerTypesToAdd)
    628         markers.addMarker(*replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));
     614        markers.addMarker(replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));
    629615}
    630616
  • trunk/Source/WebCore/editing/ApplyStyleCommand.cpp

    r258525 r258871  
    224224void ApplyStyleCommand::applyBlockStyle(EditingStyle& style)
    225225{
    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.
    229228    document().updateLayoutIgnorePendingStylesheets();
    230229
    231     // get positions we want to use for applying style
    232230    Position start = startPosition();
    233231    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);
    239234
    240235    VisiblePosition visibleStart(start);
     
    247242    // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints.
    248243    // 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()));
    250245    if (!scope)
    251246        return;
    252247
    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);
    257256
    258257    VisiblePosition paragraphStart(startOfParagraph(visibleStart));
     
    286285   
    287286    {
    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);
    290289        if (startRange && endRange)
    291290            updateStartEnd(startRange->startPosition(), endRange->startPosition());
  • trunk/Source/WebCore/editing/CompositeEditCommand.cpp

    r258129 r258871  
    14181418    int startIndex = -1;
    14191419    int endIndex = -1;
    1420     int destinationIndex = -1;
    14211420    bool originalIsDirectional = endingSelection().isDirectional();
    14221421    if (preserveSelection && !endingSelection().isNone()) {
     
    14331432            startIndex = 0;
    14341433            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);
    14371438            }
    14381439
    14391440            endIndex = 0;
    14401441            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);
    14431446            }
    14441447        }
    14451448    }
    1446    
     1449
    14471450    VisiblePosition beforeParagraph = startOfParagraphToMove.previous(CannotCrossEditingBoundary);
    14481451    VisiblePosition afterParagraph(endOfParagraphToMove.next(CannotCrossEditingBoundary));
     
    14791482        styleInEmptyParagraph->removeBlockProperties();
    14801483    }
    1481    
     1484
    14821485    // FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here.
    1483    
     1486
    14841487    setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
    14851488    frame().editor().clearMisspellingsAndBadGrammar(endingSelection());
     
    15101513        editableRoot = &document();
    15111514
    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);
    15141516
    15151517    setEndingSelection(VisibleSelection(destination, originalIsDirectional));
  • trunk/Source/WebCore/editing/Editing.cpp

    r258525 r258871  
    10841084    }
    10851085
    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);
    10881092}
    10891093
     
    10911095int indexForVisiblePosition(Node& node, const VisiblePosition& visiblePosition, bool forSelectionPreservation)
    10921096{
    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);
    10951103}
    10961104
  • trunk/Source/WebCore/editing/TextCheckingHelper.cpp

    r243195 r258871  
    149149int TextCheckingParagraph::rangeLength() const
    150150{
    151     return TextIterator::rangeLength(&paragraphRange());
     151    return characterCount(paragraphRange());
    152152}
    153153
     
    166166ExceptionOr<int> TextCheckingParagraph::offsetTo(const Position& position) const
    167167{
    168     if (!position.containerNode())
     168    auto start = makeBoundaryPoint(paragraphRange().startPosition());
     169    auto end = makeBoundaryPoint(position);
     170    if (!start || !end)
    169171        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 });
    176173}
    177174
     
    201198{
    202199    if (!m_checkingStart)
    203         m_checkingStart = TextIterator::rangeLength(&offsetAsRange());
     200        m_checkingStart = characterCount(offsetAsRange());
    204201    return *m_checkingStart;
    205202}
     
    208205{
    209206    if (!m_checkingEnd)
    210         m_checkingEnd = checkingStart() + TextIterator::rangeLength(m_checkingRange.ptr());
     207        m_checkingEnd = checkingStart() + checkingLength();
    211208    return *m_checkingEnd;
    212209}
     
    215212{
    216213    if (!m_checkingLength)
    217         m_checkingLength = TextIterator::rangeLength(m_checkingRange.ptr());
     214        m_checkingLength = characterCount(m_checkingRange);
    218215    return *m_checkingLength;
    219216}
     
    224221        return *m_automaticReplacementStart;
    225222
    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 });
    228229    return *m_automaticReplacementStart;
    229230}
     
    234235        return *m_automaticReplacementLength;
    235236
    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);
    238238    return *m_automaticReplacementLength;
    239239}
     
    324324    Ref<Range> paragraphRange = m_range->cloneRange();
    325325    setStart(paragraphRange.ptr(), startOfParagraph(m_range->startPosition()));
    326     int totalRangeLength = TextIterator::rangeLength(paragraphRange.ptr());
     326    auto totalRangeLength = characterCount(paragraphRange);
    327327    setEnd(paragraphRange.ptr(), endOfParagraph(m_range->startPosition()));
    328328   
    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;
    332331   
    333332    bool firstIteration = true;
     
    335334    while (totalLengthProcessed < totalRangeLength) {
    336335        // 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);
    338337        int currentStartOffset = firstIteration ? rangeStartOffset : 0;
    339338        int currentEndOffset = currentLength;
     
    341340            // Determine the character offset from the end of the original search range to the end of the paragraph,
    342341            // 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()) });
    345343            lastIteration = true;
    346344        }
     
    400398                if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) {
    401399                    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()) });
    406402                    outIsSpelling = true;
    407403                    outFirstFoundOffset = spellingOffset;
     
    411407                if (checkGrammar && !badGrammarPhrase.isEmpty()) {
    412408                    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()) });
    417411                    outIsSpelling = false;
    418412                    outFirstFoundOffset = grammarPhraseOffset;
     
    557551   
    558552    // 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))
    560554        return false;
    561555   
  • trunk/Source/WebCore/editing/TextIterator.cpp

    r258525 r258871  
    23442344// --------
    23452345
    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())
     2346CharacterCount characterCount(const SimpleRange& range, TextIteratorBehavior behavior)
     2347{
     2348    CharacterCount length = 0;
     2349    for (TextIterator it(range, behavior); !it.atEnd(); it.advance())
    23522350        length += it.text().length();
    23532351    return length;
     
    24572455    // The critical assumption is that this only gets called with ranges that
    24582456    // 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 a
    2461     // boundary of 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.
    24622460    if (&range->startContainer() != scope && !range->startContainer().isDescendantOf(scope))
    24632461        return false;
     
    24652463        return false;
    24662464
    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;
    24742467    return true;
    24752468}
  • trunk/Source/WebCore/editing/TextIterator.h

    r258525 r258871  
    3737class RenderTextFragment;
    3838
     39// FIXME: Delete this overload after moving all the callers to the SimpleRange version.
    3940WEBCORE_EXPORT String plainText(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
     41
    4042WEBCORE_EXPORT String plainText(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
    4143WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
     
    101103    void appendTextToStringBuilder(StringBuilder& builder) const { copyableText().appendToStringBuilder(builder); }
    102104
    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).
    104106    WEBCORE_EXPORT static RefPtr<Range> rangeFromLocationAndLength(ContainerNode* scope, int rangeLocation, int rangeLength, bool spacesForReplacedElements = false);
    105107    WEBCORE_EXPORT static bool getLocationAndLengthFromRange(Node* scope, const Range*, size_t& location, size_t& length);
     
    288290};
    289291
     292using CharacterCount = std::size_t;
     293
     294struct CharacterRange {
     295    CharacterCount location { 0 };
     296    CharacterCount length { 0 };
     297};
     298
     299WEBCORE_EXPORT CharacterCount characterCount(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
     300
    290301} // namespace WebCore
  • trunk/Source/WebCore/editing/VisiblePosition.cpp

    r255046 r258871  
    11/*
    2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
    33 * Portions Copyright (c) 2011 Motorola Mobility, Inc.  All rights reserved.
    44 *
     
    820820}
    821821
     822Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition& position)
     823{
     824    return makeBoundaryPoint(position.deepEquivalent());
     825}
     826
    822827TextStream& operator<<(TextStream& stream, EAffinity affinity)
    823828{
  • trunk/Source/WebCore/editing/VisiblePosition.h

    r258475 r258871  
    11/*
    2  * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#include "Position.h"
    3030
    31 namespace WTF {
    32 class TextStream;
    33 }
    34 
    3531namespace WebCore {
    3632
     
    4945// position is not at a line break.
    5046#define VP_UPSTREAM_IF_POSSIBLE UPSTREAM
    51 
    52 class InlineBox;
    53 class Node;
    5447
    5548class VisiblePosition {
     
    8679    // FIXME: This does not handle [table, 0] correctly.
    8780    Element* rootEditableElement() const { return m_deepPosition.isNotNull() ? m_deepPosition.deprecatedNode()->rootEditableElement() : 0; }
    88    
    89     void getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const
    90     {
    91         m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);
    92     }
    9381
    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;
    9884
    9985    // Rect is local to the returned renderer
    10086    WEBCORE_EXPORT LayoutRect localCaretRect(RenderObject*&) const;
     87
    10188    // Bounds of (possibly transformed) caret in absolute coords
    10289    WEBCORE_EXPORT IntRect absoluteCaretBounds(bool* insideFixed = nullptr) const;
     90
    10391    // Abs x/y position of the caret ignoring transforms.
    10492    // FIXME: navigation with transforms should be smarter.
     
    10896
    10997    // 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==.
    11199    bool equals(const VisiblePosition&) const;
    112100
     
    116104    void showTreeForThis() const;
    117105#endif
    118    
     106
    119107private:
    120108    void init(const Position&, EAffinity);
     
    128116};
    129117
    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 }
     118bool operator==(const VisiblePosition&, const VisiblePosition&);
     119bool operator!=(const VisiblePosition&, const VisiblePosition&);
     120bool operator<(const VisiblePosition&, const VisiblePosition&);
     121bool operator>(const VisiblePosition&, const VisiblePosition&);
     122bool operator<=(const VisiblePosition&, const VisiblePosition&);
     123bool operator>=(const VisiblePosition&, const VisiblePosition&);
    145124
    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 }   
     125WEBCORE_EXPORT Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition&);
    160126
    161127WEBCORE_EXPORT RefPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&);
     
    175141WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const VisiblePosition&);
    176142
     143// inlines
     144
     145// FIXME: This shouldn't ignore affinity.
     146inline bool operator==(const VisiblePosition& a, const VisiblePosition& b)
     147{
     148    return a.deepEquivalent() == b.deepEquivalent();
     149}
     150
     151inline bool operator!=(const VisiblePosition& a, const VisiblePosition& b)
     152{
     153    return !(a == b);
     154}
     155
     156inline bool operator<(const VisiblePosition& a, const VisiblePosition& b)
     157{
     158    return a.deepEquivalent() < b.deepEquivalent();
     159}
     160
     161inline bool operator>(const VisiblePosition& a, const VisiblePosition& b)
     162{
     163    return a.deepEquivalent() > b.deepEquivalent();
     164}
     165
     166inline bool operator<=(const VisiblePosition& a, const VisiblePosition& b)
     167{
     168    return a.deepEquivalent() <= b.deepEquivalent();
     169}
     170
     171inline bool operator>=(const VisiblePosition& a, const VisiblePosition& b)
     172{
     173    return a.deepEquivalent() >= b.deepEquivalent();
     174}
     175
     176inline void VisiblePosition::getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const
     177{
     178    m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);
     179}
     180
     181inline void VisiblePosition::getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
     182{
     183    m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset);
     184}
     185
    177186} // namespace WebCore
    178187
  • trunk/Source/WebCore/editing/VisibleUnits.cpp

    r258525 r258871  
    19021902}
    19031903
    1904 int distanceBetweenPositions(const VisiblePosition& vp, const VisiblePosition& other)
    1905 {
    1906     if (vp.isNull() || other.isNull())
     1904std::ptrdiff_t distanceBetweenPositions(const VisiblePosition& a, const VisiblePosition& b)
     1905{
     1906    if (a.isNull() || b.isNull())
    19071907        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) });
    19181911}
    19191912
  • trunk/Source/WebCore/editing/VisibleUnits.h

    r249838 r258871  
    103103WEBCORE_EXPORT VisiblePosition positionOfNextBoundaryOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection);
    104104WEBCORE_EXPORT RefPtr<Range> enclosingTextUnitOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection);
    105 WEBCORE_EXPORT int distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&);
     105WEBCORE_EXPORT std::ptrdiff_t distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&);
    106106WEBCORE_EXPORT RefPtr<Range> wordRangeFromPosition(const VisiblePosition&);
    107107WEBCORE_EXPORT VisiblePosition closestWordBoundaryForPosition(const VisiblePosition& position);
  • trunk/Source/WebCore/editing/cocoa/DataDetection.mm

    r258525 r258871  
    7272{
    7373    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())));
    7881
    7982    if (!DDScannerScanQuery(scanner.get(), scanQuery.get()))
    80         return nullptr;
    81 
    82     RetainPtr<CFArrayRef> results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
     83        return nil;
     84
     85    auto results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
    8386
    8487    // Find the DDResultRef that intersects the hitTestResult's VisiblePosition.
     
    101104
    102105    if (!mainResult)
    103         return nullptr;
     106        return nil;
    104107
    105108    RetainPtr<DDActionContext> actionContext = adoptNS([allocDDActionContextInstance() init]);
     
    113116    for (const auto& quad : quads)
    114117        detectedDataBoundingBox.unite(frameView->contentsToWindow(quad.enclosingBoundingBox()));
    115    
     118
    116119    detectedDataRange = mainResultRange;
    117    
     120
    118121    return actionContext;
    119122}
  • trunk/Source/WebCore/editing/cocoa/DictionaryLookup.mm

    r258525 r258871  
    11/*
    2  * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    265265{
    266266    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    267    
     267
    268268    if (!RevealLibrary() || !RevealCoreLibrary() || !getRVItemClass())
    269269        return { nullptr, nil };
    270    
    271     auto selectedRange = selection.toNormalizedRange();
    272     if (!selectedRange)
     270
     271    if (!selection.toNormalizedRange())
    273272        return { nullptr, nil };
    274273
     
    280279    auto paragraphStart = startOfParagraph(selectionStart);
    281280    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
    287288    RefPtr<Range> fullCharacterRange = makeRange(paragraphStart, paragraphEnd);
    288289    String itemString = plainText(fullCharacterRange.get());
    289290    RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:rangeToPass]);
    290291    NSRange highlightRange = item.get().highlightRange;
    291    
     292
    292293    return { TextIterator::subrange(*fullCharacterRange, highlightRange.location, highlightRange.length), nil };
    293    
     294
    294295    END_BLOCK_OBJC_EXCEPTIONS;
    295    
     296
    296297    return { nullptr, nil };
    297298}
     
    323324    auto selection = frame->page()->focusController().focusedOrMainFrame().selection().selection();
    324325    NSRange selectionRange;
    325     int hitIndex;
     326    NSUInteger hitIndex;
    326327    RefPtr<Range> fullCharacterRange;
    327328   
     
    329330        auto selectionStart = selection.visibleStart();
    330331        auto selectionEnd = selection.visibleEnd();
    331        
     332
    332333        // As context, we are going to use the surrounding paragraphs of text.
    333334        auto paragraphStart = startOfParagraph(selectionStart);
    334335        auto paragraphEnd = endOfParagraph(selectionEnd);
    335336       
    336         auto rangeToSelectionStart = makeRange(paragraphStart, selectionStart);
    337         auto rangeToSelectionEnd = makeRange(paragraphStart, selectionEnd);
    338        
    339337        fullCharacterRange = makeRange(paragraphStart, paragraphEnd);
    340338        if (!fullCharacterRange)
    341339            return { nullptr, nil };
    342340
    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) });
    346344    } else {
    347345        VisibleSelection selectionAccountingForLineRules { position };
    348346        selectionAccountingForLineRules.expandUsingGranularity(WordGranularity);
    349347        position = selectionAccountingForLineRules.start();
     348
    350349        // As context, we are going to use 250 characters of text before and after the point.
    351350        fullCharacterRange = rangeExpandedAroundPositionByCharacters(position, 250);
    352        
    353351        if (!fullCharacterRange)
    354352            return { nullptr, nil };
    355        
     353
    356354        selectionRange = NSMakeRange(NSNotFound, 0);
    357         hitIndex = TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get());
     355        hitIndex = characterCount({ *makeBoundaryPoint(fullCharacterRange->startPosition()), *makeBoundaryPoint(position) });
    358356    }
    359    
     357
    360358    NSRange selectedRange = [getRVSelectionClass() revealRangeAtIndex:hitIndex selectedRanges:@[[NSValue valueWithRange:selectionRange]] shouldUpdateSelection:nil];
    361    
     359
    362360    String itemString = plainText(*fullCharacterRange);
    363361    RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:selectedRange]);
  • trunk/Source/WebCore/editing/ios/DictationCommandIOS.cpp

    r256563 r258871  
    4949void DictationCommandIOS::doApply()
    5050{
    51     VisiblePosition insertionPosition(startingSelection().visibleStart());
    52 
    53     unsigned resultLength = 0;
     51    CharacterCount resultLength = 0;
    5452    for (auto& interpretations : m_dictationPhrases) {
    5553        const String& firstInterpretation = interpretations[0];
     
    6361    }
    6462
    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.
    6664
    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;
    6870
    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;
    7374
    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);
    7980}
    8081
  • trunk/Source/WebCore/editing/mac/DictionaryLookupLegacy.mm

    r240494 r258871  
    11/*
    2  * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    9090    auto paragraphStart = startOfParagraph(selectionStart);
    9191    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);
    9698
    9799    NSDictionary *options = nil;
     
    134136        return { nullptr, nil };
    135137
    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);
    137144    NSDictionary *options = nil;
    138145    NSRange extractedRange = tokenRange(plainText(fullCharacterRange.get()), rangeToPass, &options);
  • trunk/Source/WebCore/page/EventHandler.cpp

    r258679 r258871  
    655655}
    656656
    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);
     657static 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);
    661664}
    662665
  • trunk/Source/WebKit/ChangeLog

    r258869 r258871  
     12020-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
    1232020-03-23  youenn fablet  <youenn@apple.com>
    224
  • trunk/Source/WebKit/Shared/EditingRange.cpp

    r258129 r258871  
    5959    ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::Paragraph);
    6060
    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())
    6463        return nullptr;
    6564
    66     RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());
    67     if (!paragraphRange)
     65    auto paragraphStart = makeBoundaryPoint(startOfParagraph(selection.visibleStart()));
     66    if (!paragraphStart)
    6867        return nullptr;
     68    auto& rootNode = paragraphStart->container->treeScope().rootNode();
    6969
    70     auto& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode();
    71     int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, &paragraphRange->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);
    7372}
    7473
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp

    r254656 r258871  
    362362
    363363#if !PLATFORM(COCOA) && !USE(GLIB)
     364
    364365void WebEditorClient::handleKeyboardEvent(KeyboardEvent& event)
    365366{
     
    372373    notImplemented();
    373374}
     375
    374376#endif // !PLATFORM(COCOA) && !USE(GLIB)
    375377
     
    421423
    422424#if !PLATFORM(IOS_FAMILY)
     425
    423426void WebEditorClient::overflowScrollPositionChanged()
    424427{
     
    430433    notImplemented();
    431434}
     435
    432436#endif
    433437
     
    550554}
    551555
    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());
     556static 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 });
    557564}
    558565
    559566#if USE(UNIFIED_TEXT_CHECKING)
     567
    560568Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView stringView, OptionSet<WebCore::TextCheckingType> checkingTypes, const VisibleSelection& currentSelection)
    561569{
     
    564572    return results;
    565573}
     574
    566575#endif
    567576
     
    617626bool WebEditorClient::supportsGlobalSelection()
    618627{
    619 #if PLATFORM(GTK)
    620 #if PLATFORM(X11)
     628#if PLATFORM(GTK) && PLATFORM(X11)
    621629    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11)
    622630        return true;
    623631#endif
    624 #if PLATFORM(WAYLAND)
     632#if PLATFORM(GTK) && PLATFORM(WAYLAND)
    625633    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
    626634        return true;
    627635#endif
    628 #endif
    629636    return false;
    630637}
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r258869 r258871  
    54295429
    54305430#if PLATFORM(GTK) || PLATFORM(WPE)
     5431
    54315432static Frame* targetFrameForEditing(WebPage& page)
    54325433{
     
    54685469    auto selectionStart = selection.visibleStart();
    54695470    auto surroundingRange = makeRange(startOfEditableContent(selectionStart), selectionStart);
    5470     auto cursorPosition = TextIterator::rangeLength(surroundingRange.get());
     5471    auto cursorPosition = WebCore::characterCount(*surroundingRange);
    54715472    auto& rootNode = surroundingRange->startContainer().treeScope().rootNode();
    54725473    auto selectionRange = TextIterator::rangeFromLocationAndLength(&rootNode, cursorPosition + offset, characterCount);
     
    54805481    sendEditorStateUpdate();
    54815482}
     5483
    54825484#endif
    54835485
  • trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp

    r258131 r258871  
    117117            clonedRange->setStart(compositionRange->endPosition());
    118118            postLayoutData.surroundingContext = plainText(surroundingRange.get()) + plainText(clonedRange.ptr());
    119             postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(surroundingRange.get());
     119            postLayoutData.surroundingContextCursorPosition = characterCount(*surroundingRange);
    120120            postLayoutData.surroundingContextSelectionPosition = postLayoutData.surroundingContextCursorPosition;
    121121        } else {
    122122            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()));
    125125        }
    126126    }
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r258804 r258871  
    19901990}
    19911991
    1992 static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, RefPtr<Range> selectionRange)
    1993 {
    1994     if (!selectionRange)
     1992static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, const VisibleSelection& selection)
     1993{
     1994    auto liveRange = selection.firstRange();
     1995    if (!liveRange)
    19951996        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));
    19992002}
    20002003
     
    20232026    if (plainTextForDisplay(range.ptr()) != text) {
    20242027        // 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)) {
    20262029            if (!wordRange->collapsed())
    20272030                range = createLiveRange(*wordRange);
  • trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm

    r258525 r258871  
    141141    }
    142142
    143     const VisibleSelection& selection = frame.selection().selection();
     143    auto& selection = frame.selection().selection();
    144144    RefPtr<Range> selectedRange = selection.toNormalizedRange();
    145145    if (!selectedRange)
     
    148148    auto& postLayoutData = result.postLayoutData();
    149149    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 });
    156159    postLayoutData.paragraphContextForCandidateRequest = plainText(frame.editor().contextRangeForCandidateRequest().get());
    157160    postLayoutData.stringForCandidateRequest = frame.editor().stringForCandidateRequest();
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r258869 r258871  
     12020-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
    1142020-03-23  youenn fablet  <youenn@apple.com>
    215
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm

    r258182 r258871  
    10321032}
    10331033
    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());
     1034static 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 });
    10391042}
    10401043
    10411044Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView string, OptionSet<TextCheckingType> coreCheckingTypes, const VisibleSelection& currentSelection)
    10421045{
    1043     NSDictionary *options = @{ NSTextCheckingInsertionPointKey :  [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
     1046    NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) };
    10441047    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);
    10451048}
     
    10841087    NSOrthography* orthography = nil;
    10851088    NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
    1086     NSDictionary *options = @{ NSTextCheckingInsertionPointKey :  [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
     1089    NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) };
    10871090    if (context.length()) {
    10881091        [checker checkString:context range:NSMakeRange(0, context.length()) types:NSTextCheckingTypeOrthography options:options inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:&orthography wordCount:0];
     
    11171120        return;
    11181121
    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]);
    11241126    if (!frame)
    11251127        return;
     
    11271129    m_lastSelectionForRequestedCandidates = selection;
    11281130
    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);
    11371136    m_paragraphContextForCandidateRequest = plainText(frame->editor().contextRangeForCandidateRequest().get());
    11381137
  • trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm

    r258869 r258871  
    836836        auto* element = _private->coreFrame->selection().rootEditableElementOrDocumentElement();
    837837        if (!element)
    838             return nil;
     838            return nullptr;
    839839        return WebCore::TextIterator::rangeFromLocationAndLength(element, nsrange.location, nsrange.length);
    840840    }
     
    842842    ASSERT(rangeIsRelativeTo == WebRangeIsRelativeTo::Paragraph);
    843843
    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)
    847846        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, &paragraphRange->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);
    856851}
    857852
Note: See TracChangeset for help on using the changeset viewer.