Diff
Modified: trunk/LayoutTests/ChangeLog (258870 => 258871)
--- trunk/LayoutTests/ChangeLog 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/LayoutTests/ChangeLog 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,3 +1,15 @@
+2020-03-23 Darin Adler <[email protected]>
+
+ Change TextIterator::rangeLength to not require a live range
+ https://bugs.webkit.org/show_bug.cgi?id=209207
+
+ Reviewed by Antti Koivisto.
+
+ * 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.
+
2020-03-23 Rob Buis <[email protected]>
XMLHttpRequest: getAllResponseHeaders() sorting
Modified: trunk/LayoutTests/editing/mac/spelling/autocorrection-contraction-expected.txt (258870 => 258871)
--- trunk/LayoutTests/editing/mac/spelling/autocorrection-contraction-expected.txt 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/LayoutTests/editing/mac/spelling/autocorrection-contraction-expected.txt 2020-03-23 20:50:15 UTC (rev 258871)
@@ -151,23 +151,10 @@
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 7 of #text > DIV > DIV > BODY > HTML > #document to 7 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-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
-EDITING DELEGATE: shouldInsertText:would replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
-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
-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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 6 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 8 of #text > DIV > DIV > BODY > HTML > #document to 8 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 5 of #text > DIV > DIV > BODY > HTML > #document to 5 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-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
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-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
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
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
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
@@ -186,6 +173,19 @@
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldInsertText:would replacingDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionTyped
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 6 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document toDOMRange:range from 5 of #text > DIV > DIV > BODY > HTML > #document to 5 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 13 of #text > DIV > DIV > BODY > HTML > #document to 13 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 14 of #text > DIV > DIV > BODY > HTML > #document to 14 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
Modified: trunk/Source/WebCore/ChangeLog (258870 => 258871)
--- trunk/Source/WebCore/ChangeLog 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/ChangeLog 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,3 +1,81 @@
+2020-03-23 Darin Adler <[email protected]>
+
+ Change TextIterator::rangeLength to not require a live range
+ https://bugs.webkit.org/show_bug.cgi?id=209207
+
+ Reviewed by Antti Koivisto.
+
+ - 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.
+
2020-03-23 youenn fablet <[email protected]>
Rename blankURL to aboutBlankURL
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (258870 => 258871)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1938,18 +1938,16 @@
unsigned textLength = matchText.length();
auto startPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), -textLength);
auto endPosition = visiblePositionForPositionWithOffset(createLegacyEditingPosition(originalRange.start), 2 * textLength);
-
if (startPosition.isNull())
startPosition = firstPositionInOrBeforeNode(originalRange.start.container.ptr());
if (endPosition.isNull())
endPosition = lastPositionInOrAfterNode(originalRange.end.container.ptr());
- auto searchRange = Range::create(m_document, startPosition, endPosition);
- if (searchRange->collapsed())
+ auto searchRange = SimpleRange { *makeBoundaryPoint(startPosition), *makeBoundaryPoint(endPosition) };
+ if (searchRange.collapsed())
return WTF::nullopt;
- auto range = Range::create(m_document, startPosition, createLegacyEditingPosition(originalRange.start));
- unsigned targetOffset = TextIterator::rangeLength(range.ptr(), true);
+ auto targetOffset = characterCount({ searchRange.start, originalRange.start }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
return findClosestPlainText(searchRange, matchText, { }, targetOffset);
}
@@ -1992,12 +1990,11 @@
static Node* resetNodeAndOffsetForReplacedNode(Node* replacedNode, int& offset, int characterCount)
{
// Use this function to include the replaced node itself in the range we are creating.
- if (!replacedNode)
+ auto nodeRange = AXObjectCache::rangeForNodeContents(replacedNode);
+ if (!nodeRange)
return nullptr;
-
- RefPtr<Range> nodeRange = AXObjectCache::rangeForNodeContents(replacedNode);
- int nodeLength = TextIterator::rangeLength(nodeRange.get());
- offset = characterCount <= nodeLength ? replacedNode->computeNodeIndex() : replacedNode->computeNodeIndex() + 1;
+ bool isInNode = static_cast<unsigned>(characterCount) <= WebCore::characterCount(*nodeRange);
+ offset = replacedNode->computeNodeIndex() + (isInNode ? 0 : 1);
return replacedNode->parentNode();
}
@@ -2413,14 +2410,16 @@
return CharacterOffset();
// We don't always move one 'character' at a time since there might be composed characters.
- int nextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset);
+ unsigned nextOffset = Position::uncheckedNextOffset(characterOffset.node, characterOffset.offset);
CharacterOffset next = characterOffsetForNodeAndOffset(*characterOffset.node, nextOffset);
// To be consistent with VisiblePosition, we should consider the case that current node end to next node start counts 1 offset.
if (!ignoreNextNodeStart && !next.isNull() && !isReplacedNodeOrBR(next.node) && next.node != characterOffset.node) {
- int length = TextIterator::rangeLength(rangeForUnorderedCharacterOffsets(characterOffset, next).get());
- if (length > nextOffset - characterOffset.offset)
- next = characterOffsetForNodeAndOffset(*next.node, 0, TraverseOptionIncludeStart);
+ if (auto range = rangeForUnorderedCharacterOffsets(characterOffset, next)) {
+ auto length = characterCount(*range);
+ if (length > nextOffset - characterOffset.offset)
+ next = characterOffsetForNodeAndOffset(*next.node, 0, TraverseOptionIncludeStart);
+ }
}
return next;
Modified: trunk/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp (258870 => 258871)
--- trunk/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -355,7 +355,7 @@
// the current accessibility object to ensure we emit the
// right offset (e.g. multiline text areas).
auto range = Range::create(document, node->parentNode(), 0, node, 0);
- offsetToEmit = offset + TextIterator::rangeLength(range.ptr());
+ offsetToEmit = offset + characterCount(range.get());
}
g_signal_emit_by_name(wrapper, detail.data(), offsetToEmit, textToEmit.length(), textToEmit.utf8().data());
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp (258870 => 258871)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -154,7 +154,7 @@
static gint rangeLengthForObject(AccessibilityObject& obj, Range* range)
{
// This is going to be the actual length in most of the cases
- int baseLength = TextIterator::rangeLength(range, true);
+ int baseLength = characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
// Check whether the current hyperlink belongs to a list item.
// If so, we need to consider the length of the item's marker
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp (258870 => 258871)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -410,9 +410,9 @@
// Set values for start offsets and calculate initial range length.
// These values might be adjusted later to cover special cases.
- startOffset = webCoreOffsetToAtkOffset(coreObject, TextIterator::rangeLength(rangeInParent.ptr(), true));
+ startOffset = webCoreOffsetToAtkOffset(coreObject, characterCount(rangeInParent.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions));
auto nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
- int rangeLength = TextIterator::rangeLength(nodeRange.ptr(), true);
+ int rangeLength = characterCount(nodeRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
// Special cases that are only relevant when working with *_END boundaries.
if (selection.affinity() == UPSTREAM) {
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp (258870 => 258871)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -247,10 +247,10 @@
offset = 0;
else if (!isStartOfLine(endPosition)) {
RefPtr<Range> range = makeRange(startPosition, endPosition.previous());
- offset = TextIterator::rangeLength(range.get(), true) + 1;
+ offset = (range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0) + 1;
} else {
RefPtr<Range> range = makeRange(startPosition, endPosition);
- offset = TextIterator::rangeLength(range.get(), true);
+ offset = range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0;
}
return firstUnignoredParent;
Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (258870 => 258871)
--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -2310,30 +2310,30 @@
return [array autorelease];
}
-- (NSRange)_convertToNSRange:(Range *)range
+- (NSRange)_convertToNSRange:(Range *)liveRange
{
- if (!range)
+ if (!liveRange)
return NSMakeRange(NSNotFound, 0);
- Document* document = self.axBackingObject->document();
- Element* selectionRoot = document->frame()->selection().selection().rootEditableElement();
- Element* scope = selectionRoot ? selectionRoot : document->documentElement();
+ auto range = SimpleRange { *liveRange };
+ auto& document = range.start.document();
+ auto* frame = document.frame();
+ if (!frame)
+ return NSMakeRange(NSNotFound, 0);
+
+ auto* rootEditableElement = frame->selection().selection().rootEditableElement();
+ auto* scope = rootEditableElement ? rootEditableElement : document.documentElement();
+ if (!scope)
+ return NSMakeRange(NSNotFound, 0);
+
// Mouse events may cause TSM to attempt to create an NSRange for a portion of the view
- // that is not inside the current editable region. These checks ensure we don't produce
+ // that is not inside the current editable region. These checks ensure we don't produce
// potentially invalid data when responding to such requests.
- if (&range->startContainer() != scope && !range->startContainer().isDescendantOf(scope))
+ if (!scope->contains(range.start.container.ptr()) || !scope->contains(range.end.container.ptr()))
return NSMakeRange(NSNotFound, 0);
- if (&range->endContainer() != scope && !range->endContainer().isDescendantOf(scope))
- return NSMakeRange(NSNotFound, 0);
- auto testRange = Range::create(scope->document(), scope, 0, &range->startContainer(), range->startOffset());
- ASSERT(&testRange->startContainer() == scope);
- int startPosition = TextIterator::rangeLength(testRange.ptr());
- testRange->setEnd(range->endContainer(), range->endOffset());
- ASSERT(&testRange->startContainer() == scope);
- int endPosition = TextIterator::rangeLength(testRange.ptr());
- return NSMakeRange(startPosition, endPosition - startPosition);
+ return NSMakeRange(characterCount({ { *scope, 0 }, range.start }), characterCount(range));
}
- (RefPtr<Range>)_convertToDOMRange:(NSRange)nsrange
Modified: trunk/Source/WebCore/dom/SimpleRange.h (258870 => 258871)
--- trunk/Source/WebCore/dom/SimpleRange.h 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/dom/SimpleRange.h 2020-03-23 20:50:15 UTC (rev 258871)
@@ -42,7 +42,7 @@
bool collapsed() const { return start == end; }
- SimpleRange(const BoundaryPoint&, const BoundaryPoint&);
+ WEBCORE_EXPORT SimpleRange(const BoundaryPoint&, const BoundaryPoint&);
WEBCORE_EXPORT SimpleRange(BoundaryPoint&&, BoundaryPoint&&);
// Convenience overloads to help with transition from using a lot of live ranges.
Modified: trunk/Source/WebCore/editing/AlternativeTextController.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/AlternativeTextController.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/AlternativeTextController.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -580,52 +580,38 @@
void AlternativeTextController::applyAlternativeTextToRange(const Range& range, const String& alternative, AlternativeTextType alternativeType, OptionSet<DocumentMarker::MarkerType> markerTypesToAdd)
{
- auto paragraphRangeContainingCorrection = range.cloneRange();
-
- setStart(paragraphRangeContainingCorrection.ptr(), startOfParagraph(range.startPosition()));
- setEnd(paragraphRangeContainingCorrection.ptr(), endOfParagraph(range.endPosition()));
-
// After we replace the word at range rangeWithAlternative, we need to add markers to that range.
- // However, once the replacement took place, the value of rangeWithAlternative is not valid anymore.
- // So before we carry out the replacement, we need to store the start position of rangeWithAlternative
- // relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph
- // to store this value. In order to obtain this offset, we need to first create a range
- // which spans from the start of paragraph to the start position of rangeWithAlternative.
- auto correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer().document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition());
+ // So before we carry out the replacement,store the start position relative to the start position
+ // of the containing paragraph.
- Position startPositionOfRangeWithAlternative = range.startPosition();
- if (!startPositionOfRangeWithAlternative.containerNode())
+ // Take note of the location of autocorrection so that we can add marker after the replacement took place.
+ auto correctionStartPosition = range.startPosition();
+ auto correctionStart { makeBoundaryPoint(correctionStartPosition) };
+ auto paragraphStart { makeBoundaryPoint(startOfParagraph(correctionStartPosition)) };
+ if (!correctionStart || !paragraphStart)
return;
- auto setEndResult = correctionStartOffsetInParagraphAsRange->setEnd(*startPositionOfRangeWithAlternative.containerNode(), startPositionOfRangeWithAlternative.computeOffsetInContainerNode());
- if (setEndResult.hasException())
- return;
+ auto treeScopeRoot = makeRef(correctionStart->container->treeScope().rootNode());
+ auto treeScopeStart = BoundaryPoint { treeScopeRoot.get(), 0 };
+ auto correctionOffsetInParagraph = characterCount({ *paragraphStart, *correctionStart });
+ auto paragraphOffsetInTreeScope = characterCount({ treeScopeStart, *paragraphStart });
- // Take note of the location of autocorrection so that we can add marker after the replacement took place.
- int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.ptr());
+ // Clone the range, since the caller of may keep a refernece to the original range and modify it.
+ SpellingCorrectionCommand::create(range.cloneRange(), alternative)->apply();
- // Clone the range, since the caller of this method may want to keep the original range around.
- auto rangeWithAlternative = range.cloneRange();
-
- ContainerNode& rootNode = paragraphRangeContainingCorrection->startContainer().treeScope().rootNode();
- int paragraphStartIndex = TextIterator::rangeLength(Range::create(rootNode.document(), &rootNode, 0, ¶graphRangeContainingCorrection->startContainer(), paragraphRangeContainingCorrection->startOffset()).ptr());
- SpellingCorrectionCommand::create(rangeWithAlternative, alternative)->apply();
// Recalculate pragraphRangeContainingCorrection, since SpellingCorrectionCommand modified the DOM, such that the original paragraphRangeContainingCorrection is no longer valid. Radar: 10305315 Bugzilla: 89526
- auto updatedParagraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex, correctionStartOffsetInParagraph + alternative.length());
+ auto updatedParagraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength(treeScopeRoot.ptr(), paragraphOffsetInTreeScope, correctionOffsetInParagraph + alternative.length());
if (!updatedParagraphRangeContainingCorrection)
return;
-
setEnd(updatedParagraphRangeContainingCorrection.get(), m_frame.selection().selection().start());
- RefPtr<Range> replacementRange = TextIterator::subrange(*updatedParagraphRangeContainingCorrection, correctionStartOffsetInParagraph, alternative.length());
- String newText = plainText(replacementRange.get());
+ auto replacementRange = TextIterator::subrange(*updatedParagraphRangeContainingCorrection, correctionOffsetInParagraph, alternative.length());
// Check to see if replacement succeeded.
- if (newText != alternative)
+ if (plainText(replacementRange.get()) != alternative)
return;
- DocumentMarkerController& markers = replacementRange->startContainer().document().markers();
-
+ auto& markers = replacementRange->ownerDocument().markers();
for (auto markerType : markerTypesToAdd)
- markers.addMarker(*replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));
+ markers.addMarker(replacementRange, markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));
}
#endif
Modified: trunk/Source/WebCore/editing/ApplyStyleCommand.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -223,19 +223,14 @@
void ApplyStyleCommand::applyBlockStyle(EditingStyle& style)
{
- // update document layout once before removing styles
- // so that we avoid the expense of updating before each and every call
- // to check a computed style
+ // Update document layout once before removing styles so that we avoid the expense of
+ // updating before each and every call to check a computed style.
document().updateLayoutIgnorePendingStylesheets();
- // get positions we want to use for applying style
Position start = startPosition();
Position end = endPosition();
- if (comparePositions(end, start) < 0) {
- Position swap = start;
- start = end;
- end = swap;
- }
+ if (comparePositions(end, start) < 0)
+ std::swap(start, end);
VisiblePosition visibleStart(start);
VisiblePosition visibleEnd(end);
@@ -246,15 +241,19 @@
// Save and restore the selection endpoints using their indices in the editable root, since
// addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints.
// Calculate start and end indices from the start of the tree that they're in.
- auto* scope = highestEditableRoot(visibleStart.deepEquivalent());
+ auto scope = makeRefPtr(highestEditableRoot(visibleStart.deepEquivalent()));
if (!scope)
return;
- auto startRange = Range::create(document(), firstPositionInNode(scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
- auto endRange = Range::create(document(), firstPositionInNode(scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
- int startIndex = TextIterator::rangeLength(startRange.ptr(), true);
- int endIndex = TextIterator::rangeLength(endRange.ptr(), true);
+ auto scopeStart = BoundaryPoint { *scope, 0 };
+ auto startBoundaryPoint = makeBoundaryPoint(visibleStart.deepEquivalent().parentAnchoredEquivalent());
+ auto endBoundaryPoint = makeBoundaryPoint(visibleEnd.deepEquivalent().parentAnchoredEquivalent());
+ if (!startBoundaryPoint || !endBoundaryPoint)
+ return;
+ auto startIndex = characterCount({ scopeStart, *startBoundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ auto endIndex = characterCount({ scopeStart, *endBoundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+
VisiblePosition paragraphStart(startOfParagraph(visibleStart));
VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next());
if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
@@ -285,8 +284,8 @@
}
{
- auto startRange = TextIterator::rangeFromLocationAndLength(scope, startIndex, 0, true);
- auto endRange = TextIterator::rangeFromLocationAndLength(scope, endIndex, 0, true);
+ auto startRange = TextIterator::rangeFromLocationAndLength(scope.get(), startIndex, 0, true);
+ auto endRange = TextIterator::rangeFromLocationAndLength(scope.get(), endIndex, 0, true);
if (startRange && endRange)
updateStartEnd(startRange->startPosition(), endRange->startPosition());
}
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1417,7 +1417,6 @@
int startIndex = -1;
int endIndex = -1;
- int destinationIndex = -1;
bool originalIsDirectional = endingSelection().isDirectional();
if (preserveSelection && !endingSelection().isNone()) {
VisiblePosition visibleStart = endingSelection().visibleStart();
@@ -1432,18 +1431,22 @@
startIndex = 0;
if (startInParagraph) {
- auto startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStart.deepEquivalent().parentAnchoredEquivalent());
- startIndex = TextIterator::rangeLength(startRange.ptr(), true);
+ auto paragraphStart = makeBoundaryPoint(startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent());
+ auto selectionStart = makeBoundaryPoint(visibleStart.deepEquivalent().parentAnchoredEquivalent());
+ if (paragraphStart && selectionStart)
+ startIndex = characterCount({ *paragraphStart, *selectionStart }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
}
endIndex = 0;
if (endInParagraph) {
- auto endRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
- endIndex = TextIterator::rangeLength(endRange.ptr(), true);
+ auto paragraphStart = makeBoundaryPoint(startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent());
+ auto selectionEnd = makeBoundaryPoint(visibleEnd.deepEquivalent().parentAnchoredEquivalent());
+ if (paragraphStart && selectionEnd)
+ endIndex = characterCount({ *paragraphStart, *selectionEnd }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
}
}
}
-
+
VisiblePosition beforeParagraph = startOfParagraphToMove.previous(CannotCrossEditingBoundary);
VisiblePosition afterParagraph(endOfParagraphToMove.next(CannotCrossEditingBoundary));
@@ -1478,9 +1481,9 @@
// The moved paragraph should assume the block style of the destination.
styleInEmptyParagraph->removeBlockProperties();
}
-
+
// FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here.
-
+
setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
frame().editor().clearMisspellingsAndBadGrammar(endingSelection());
deleteSelection(false, false, false, false);
@@ -1509,8 +1512,7 @@
if (!editableRoot)
editableRoot = &document();
- auto startToDestinationRange = Range::create(document(), firstPositionInNode(editableRoot.get()), destination.deepEquivalent().parentAnchoredEquivalent());
- destinationIndex = TextIterator::rangeLength(startToDestinationRange.ptr(), true);
+ auto destinationIndex = characterCount({ { *editableRoot, 0 }, *makeBoundaryPoint(destination.deepEquivalent().parentAnchoredEquivalent()) }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
setEndingSelection(VisibleSelection(destination, originalIsDirectional));
ASSERT(endingSelection().isCaretOrRange());
Modified: trunk/Source/WebCore/editing/Editing.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/Editing.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/Editing.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1083,15 +1083,23 @@
scope = &document;
}
- auto range = Range::create(document, firstPositionInNode(scope.get()), position.parentAnchoredEquivalent());
- return TextIterator::rangeLength(range.ptr(), true);
+ auto start = makeBoundaryPoint(firstPositionInNode(scope.get()));
+ auto end = makeBoundaryPoint(position.parentAnchoredEquivalent());
+ if (!start || !end)
+ return 0;
+
+ return characterCount({ *start, *end }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
}
// FIXME: Merge this function with the one above.
int indexForVisiblePosition(Node& node, const VisiblePosition& visiblePosition, bool forSelectionPreservation)
{
- auto range = Range::create(node.document(), firstPositionInNode(&node), visiblePosition.deepEquivalent().parentAnchoredEquivalent());
- return TextIterator::rangeLength(range.ptr(), forSelectionPreservation);
+ auto start = makeBoundaryPoint(firstPositionInNode(&node));
+ auto end = makeBoundaryPoint(visiblePosition.deepEquivalent().parentAnchoredEquivalent());
+ if (!start || !end)
+ return 0;
+
+ return characterCount({ *start, *end }, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior);
}
VisiblePosition visiblePositionForPositionWithOffset(const VisiblePosition& position, int offset)
Modified: trunk/Source/WebCore/editing/TextCheckingHelper.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/TextCheckingHelper.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/TextCheckingHelper.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -148,7 +148,7 @@
int TextCheckingParagraph::rangeLength() const
{
- return TextIterator::rangeLength(¶graphRange());
+ return characterCount(paragraphRange());
}
Range& TextCheckingParagraph::paragraphRange() const
@@ -165,14 +165,11 @@
ExceptionOr<int> TextCheckingParagraph::offsetTo(const Position& position) const
{
- if (!position.containerNode())
+ auto start = makeBoundaryPoint(paragraphRange().startPosition());
+ auto end = makeBoundaryPoint(position);
+ if (!start || !end)
return Exception { TypeError };
-
- auto range = offsetAsRange().cloneRange();
- auto result = range->setEnd(*position.containerNode(), position.computeOffsetInContainerNode());
- if (result.hasException())
- return result.releaseException();
- return TextIterator::rangeLength(range.ptr());
+ return characterCount({ *start, *end });
}
bool TextCheckingParagraph::isEmpty() const
@@ -200,7 +197,7 @@
int TextCheckingParagraph::checkingStart() const
{
if (!m_checkingStart)
- m_checkingStart = TextIterator::rangeLength(&offsetAsRange());
+ m_checkingStart = characterCount(offsetAsRange());
return *m_checkingStart;
}
@@ -207,7 +204,7 @@
int TextCheckingParagraph::checkingEnd() const
{
if (!m_checkingEnd)
- m_checkingEnd = checkingStart() + TextIterator::rangeLength(m_checkingRange.ptr());
+ m_checkingEnd = checkingStart() + checkingLength();
return *m_checkingEnd;
}
@@ -214,7 +211,7 @@
int TextCheckingParagraph::checkingLength() const
{
if (!m_checkingLength)
- m_checkingLength = TextIterator::rangeLength(m_checkingRange.ptr());
+ m_checkingLength = characterCount(m_checkingRange);
return *m_checkingLength;
}
@@ -223,8 +220,12 @@
if (m_automaticReplacementStart)
return *m_automaticReplacementStart;
- auto startOffsetRange = Range::create(paragraphRange().startContainer().document(), paragraphRange().startPosition(), m_automaticReplacementRange->startPosition());
- m_automaticReplacementStart = TextIterator::rangeLength(startOffsetRange.ptr());
+ auto start = makeBoundaryPoint(paragraphRange().startPosition());
+ auto end = makeBoundaryPoint(m_automaticReplacementRange->startPosition());
+ if (!start || !end)
+ return 0;
+
+ m_automaticReplacementStart = characterCount({ *start, *end });
return *m_automaticReplacementStart;
}
@@ -233,8 +234,7 @@
if (m_automaticReplacementLength)
return *m_automaticReplacementLength;
- auto endOffsetRange = Range::create(paragraphRange().startContainer().document(), paragraphRange().startPosition(), m_automaticReplacementRange->endPosition());
- m_automaticReplacementLength = TextIterator::rangeLength(endOffsetRange.ptr()) - automaticReplacementStart();
+ m_automaticReplacementLength = characterCount(m_automaticReplacementRange);
return *m_automaticReplacementLength;
}
@@ -323,25 +323,23 @@
// since we will want to ignore results in this area.
Ref<Range> paragraphRange = m_range->cloneRange();
setStart(paragraphRange.ptr(), startOfParagraph(m_range->startPosition()));
- int totalRangeLength = TextIterator::rangeLength(paragraphRange.ptr());
+ auto totalRangeLength = characterCount(paragraphRange);
setEnd(paragraphRange.ptr(), endOfParagraph(m_range->startPosition()));
- Ref<Range> offsetAsRange = Range::create(paragraphRange->startContainer().document(), paragraphRange->startPosition(), m_range->startPosition());
- int rangeStartOffset = TextIterator::rangeLength(offsetAsRange.ptr());
- int totalLengthProcessed = 0;
+ auto rangeStartOffset = characterCount({ *makeBoundaryPoint(paragraphRange->startPosition()), *makeBoundaryPoint(m_range->startPosition()) });
+ CharacterCount totalLengthProcessed = 0;
bool firstIteration = true;
bool lastIteration = false;
while (totalLengthProcessed < totalRangeLength) {
// Iterate through the search range by paragraphs, checking each one for spelling and grammar.
- int currentLength = TextIterator::rangeLength(paragraphRange.ptr());
+ auto currentLength = characterCount(paragraphRange);
int currentStartOffset = firstIteration ? rangeStartOffset : 0;
int currentEndOffset = currentLength;
if (inSameParagraph(paragraphRange->startPosition(), m_range->endPosition())) {
// Determine the character offset from the end of the original search range to the end of the paragraph,
// since we will want to ignore results in this area.
- auto endOffsetAsRange = Range::create(paragraphRange->startContainer().document(), paragraphRange->startPosition(), m_range->endPosition());
- currentEndOffset = TextIterator::rangeLength(endOffsetAsRange.ptr());
+ currentEndOffset = characterCount({ *makeBoundaryPoint(paragraphRange->startPosition()), *makeBoundaryPoint(m_range->endPosition()) });
lastIteration = true;
}
if (currentStartOffset < currentEndOffset) {
@@ -399,10 +397,8 @@
if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) {
int spellingOffset = spellingLocation - currentStartOffset;
- if (!firstIteration) {
- auto paragraphOffsetAsRange = Range::create(paragraphRange->startContainer().document(), m_range->startPosition(), paragraphRange->startPosition());
- spellingOffset += TextIterator::rangeLength(paragraphOffsetAsRange.ptr());
- }
+ if (!firstIteration)
+ spellingOffset += characterCount({ *makeBoundaryPoint(m_range->startPosition()), *makeBoundaryPoint(paragraphRange->startPosition()) });
outIsSpelling = true;
outFirstFoundOffset = spellingOffset;
firstFoundItem = misspelledWord;
@@ -410,10 +406,8 @@
}
if (checkGrammar && !badGrammarPhrase.isEmpty()) {
int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset;
- if (!firstIteration) {
- auto paragraphOffsetAsRange = Range::create(paragraphRange->startContainer().document(), m_range->startPosition(), paragraphRange->startPosition());
- grammarPhraseOffset += TextIterator::rangeLength(paragraphOffsetAsRange.ptr());
- }
+ if (!firstIteration)
+ grammarPhraseOffset += characterCount({ *makeBoundaryPoint(m_range->startPosition()), *makeBoundaryPoint(paragraphRange->startPosition()) });
outIsSpelling = false;
outFirstFoundOffset = grammarPhraseOffset;
firstFoundItem = badGrammarPhrase;
@@ -556,7 +550,7 @@
return false;
// Bad grammar at start of range, but end of bad grammar is before or after end of range
- if (grammarDetail.length != TextIterator::rangeLength(m_range.ptr()))
+ if (static_cast<unsigned>(grammarDetail.length) != characterCount(m_range))
return false;
// Update the spelling panel to be displaying this error (whether or not the spelling panel is on screen).
Modified: trunk/Source/WebCore/editing/TextIterator.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/TextIterator.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/TextIterator.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -2343,12 +2343,10 @@
// --------
-int TextIterator::rangeLength(const Range* range, bool forSelectionPreservation)
+CharacterCount characterCount(const SimpleRange& range, TextIteratorBehavior behavior)
{
- if (!range)
- return 0;
- unsigned length = 0;
- for (TextIterator it(*range, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior); !it.atEnd(); it.advance())
+ CharacterCount length = 0;
+ for (TextIterator it(range, behavior); !it.atEnd(); it.advance())
length += it.text().length();
return length;
}
@@ -2456,21 +2454,16 @@
// The critical assumption is that this only gets called with ranges that
// concentrate on a given area containing the selection root. This is done
- // because of text fields and textareas. The DOM for those is not
- // directly in the document DOM, so ensure that the range does not cross a
- // boundary of one of those.
+ // because of text fields and textareas. The DOM for those is not directly
+ // in the document DOM, so ensure that the range does not cross a boundary
+ // of one of those.
if (&range->startContainer() != scope && !range->startContainer().isDescendantOf(scope))
return false;
if (&range->endContainer() != scope && !range->endContainer().isDescendantOf(scope))
return false;
- Ref<Range> testRange = Range::create(scope->document(), scope, 0, &range->startContainer(), range->startOffset());
- ASSERT(&testRange->startContainer() == scope);
- location = TextIterator::rangeLength(testRange.ptr());
-
- testRange->setEnd(range->endContainer(), range->endOffset());
- ASSERT(&testRange->startContainer() == scope);
- length = TextIterator::rangeLength(testRange.ptr()) - location;
+ location = characterCount({ { *scope, 0 }, { range->startContainer(), range->startOffset() } });
+ length = characterCount({ { *scope, 0 }, { range->endContainer(), range->endOffset() } }) - location;
return true;
}
Modified: trunk/Source/WebCore/editing/TextIterator.h (258870 => 258871)
--- trunk/Source/WebCore/editing/TextIterator.h 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/TextIterator.h 2020-03-23 20:50:15 UTC (rev 258871)
@@ -36,7 +36,9 @@
class Range;
class RenderTextFragment;
+// FIXME: Delete this overload after moving all the callers to the SimpleRange version.
WEBCORE_EXPORT String plainText(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
+
WEBCORE_EXPORT String plainText(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
WEBCORE_EXPORT String plainTextUsingBackwardsTextIteratorForTesting(const SimpleRange&);
@@ -100,7 +102,7 @@
const TextIteratorCopyableText& copyableText() const { ASSERT(!atEnd()); return m_copyableText; }
void appendTextToStringBuilder(StringBuilder& builder) const { copyableText().appendToStringBuilder(builder); }
- WEBCORE_EXPORT static int rangeLength(const Range*, bool spacesForReplacedElements = false);
+ // FIXME: Move these to SimpleRange, CharacterRange, and CharacterCount and move out of this class to the top level (bottom of this file).
WEBCORE_EXPORT static RefPtr<Range> rangeFromLocationAndLength(ContainerNode* scope, int rangeLocation, int rangeLength, bool spacesForReplacedElements = false);
WEBCORE_EXPORT static bool getLocationAndLengthFromRange(Node* scope, const Range*, size_t& location, size_t& length);
WEBCORE_EXPORT static Ref<Range> subrange(Range& entireRange, int characterOffset, int characterCount);
@@ -287,4 +289,13 @@
bool m_didLookAhead { true };
};
+using CharacterCount = std::size_t;
+
+struct CharacterRange {
+ CharacterCount location { 0 };
+ CharacterCount length { 0 };
+};
+
+WEBCORE_EXPORT CharacterCount characterCount(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
+
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/VisiblePosition.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/VisiblePosition.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/VisiblePosition.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
* Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -819,6 +819,11 @@
return m_affinity == other.m_affinity && m_deepPosition.equals(other.m_deepPosition);
}
+Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition& position)
+{
+ return makeBoundaryPoint(position.deepEquivalent());
+}
+
TextStream& operator<<(TextStream& stream, EAffinity affinity)
{
switch (affinity) {
Modified: trunk/Source/WebCore/editing/VisiblePosition.h (258870 => 258871)
--- trunk/Source/WebCore/editing/VisiblePosition.h 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/VisiblePosition.h 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,10 +28,6 @@
#include "EditingBoundary.h"
#include "Position.h"
-namespace WTF {
-class TextStream;
-}
-
namespace WebCore {
class Range;
@@ -49,9 +45,6 @@
// position is not at a line break.
#define VP_UPSTREAM_IF_POSSIBLE UPSTREAM
-class InlineBox;
-class Node;
-
class VisiblePosition {
public:
// NOTE: UPSTREAM affinity will be used only if pos is at end of a wrapped line,
@@ -85,21 +78,16 @@
// FIXME: This does not handle [table, 0] correctly.
Element* rootEditableElement() const { return m_deepPosition.isNotNull() ? m_deepPosition.deprecatedNode()->rootEditableElement() : 0; }
-
- void getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const
- {
- m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);
- }
- void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
- {
- m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset);
- }
+ void getInlineBoxAndOffset(InlineBox*&, int& caretOffset) const;
+ void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*&, int& caretOffset) const;
// Rect is local to the returned renderer
WEBCORE_EXPORT LayoutRect localCaretRect(RenderObject*&) const;
+
// Bounds of (possibly transformed) caret in absolute coords
WEBCORE_EXPORT IntRect absoluteCaretBounds(bool* insideFixed = nullptr) const;
+
// Abs x/y position of the caret ignoring transforms.
// FIXME: navigation with transforms should be smarter.
WEBCORE_EXPORT int lineDirectionPointForBlockDirectionNavigation() const;
@@ -107,7 +95,7 @@
WEBCORE_EXPORT FloatRect absoluteSelectionBoundsForLine() const;
// This is a tentative enhancement of operator== to account for affinity.
- // FIXME: Combine this function with operator==
+ // FIXME: Combine this function with operator==.
bool equals(const VisiblePosition&) const;
#if ENABLE(TREE_DEBUGGING)
@@ -115,7 +103,7 @@
void formatForDebugger(char* buffer, unsigned length) const;
void showTreeForThis() const;
#endif
-
+
private:
void init(const Position&, EAffinity);
Position canonicalPosition(const Position&);
@@ -127,23 +115,50 @@
EAffinity m_affinity;
};
+bool operator==(const VisiblePosition&, const VisiblePosition&);
+bool operator!=(const VisiblePosition&, const VisiblePosition&);
+bool operator<(const VisiblePosition&, const VisiblePosition&);
+bool operator>(const VisiblePosition&, const VisiblePosition&);
+bool operator<=(const VisiblePosition&, const VisiblePosition&);
+bool operator>=(const VisiblePosition&, const VisiblePosition&);
+
+WEBCORE_EXPORT Optional<BoundaryPoint> makeBoundaryPoint(const VisiblePosition&);
+
+WEBCORE_EXPORT RefPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&);
+bool setStart(Range*, const VisiblePosition&);
+bool setEnd(Range*, const VisiblePosition&);
+VisiblePosition startVisiblePosition(const Range*, EAffinity);
+VisiblePosition endVisiblePosition(const Range*, EAffinity);
+
+WEBCORE_EXPORT Element* enclosingBlockFlowElement(const VisiblePosition&);
+
+bool isFirstVisiblePositionInNode(const VisiblePosition&, const Node*);
+bool isLastVisiblePositionInNode(const VisiblePosition&, const Node*);
+
+bool areVisiblePositionsInSameTreeScope(const VisiblePosition&, const VisiblePosition&);
+
+WTF::TextStream& operator<<(WTF::TextStream&, EAffinity);
+WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const VisiblePosition&);
+
+// inlines
+
// FIXME: This shouldn't ignore affinity.
inline bool operator==(const VisiblePosition& a, const VisiblePosition& b)
{
return a.deepEquivalent() == b.deepEquivalent();
}
-
+
inline bool operator!=(const VisiblePosition& a, const VisiblePosition& b)
{
return !(a == b);
}
-
+
inline bool operator<(const VisiblePosition& a, const VisiblePosition& b)
{
return a.deepEquivalent() < b.deepEquivalent();
}
-inline bool operator>(const VisiblePosition& a, const VisiblePosition& b)
+inline bool operator>(const VisiblePosition& a, const VisiblePosition& b)
{
return a.deepEquivalent() > b.deepEquivalent();
}
@@ -153,27 +168,21 @@
return a.deepEquivalent() <= b.deepEquivalent();
}
-inline bool operator>=(const VisiblePosition& a, const VisiblePosition& b)
+inline bool operator>=(const VisiblePosition& a, const VisiblePosition& b)
{
return a.deepEquivalent() >= b.deepEquivalent();
-}
+}
-WEBCORE_EXPORT RefPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&);
-bool setStart(Range*, const VisiblePosition&);
-bool setEnd(Range*, const VisiblePosition&);
-VisiblePosition startVisiblePosition(const Range*, EAffinity);
-VisiblePosition endVisiblePosition(const Range*, EAffinity);
+inline void VisiblePosition::getInlineBoxAndOffset(InlineBox*& inlineBox, int& caretOffset) const
+{
+ m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);
+}
-WEBCORE_EXPORT Element* enclosingBlockFlowElement(const VisiblePosition&);
+inline void VisiblePosition::getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
+{
+ m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset);
+}
-bool isFirstVisiblePositionInNode(const VisiblePosition&, const Node*);
-bool isLastVisiblePositionInNode(const VisiblePosition&, const Node*);
-
-bool areVisiblePositionsInSameTreeScope(const VisiblePosition&, const VisiblePosition&);
-
-WTF::TextStream& operator<<(WTF::TextStream&, EAffinity);
-WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const VisiblePosition&);
-
} // namespace WebCore
#if ENABLE(TREE_DEBUGGING)
Modified: trunk/Source/WebCore/editing/VisibleUnits.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/VisibleUnits.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/VisibleUnits.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1901,20 +1901,13 @@
return Range::create(prevBoundary.deepEquivalent().deprecatedNode()->document(), prevBoundary, nextBoundary);
}
-int distanceBetweenPositions(const VisiblePosition& vp, const VisiblePosition& other)
+std::ptrdiff_t distanceBetweenPositions(const VisiblePosition& a, const VisiblePosition& b)
{
- if (vp.isNull() || other.isNull())
+ if (a.isNull() || b.isNull())
return 0;
-
- bool thisIsStart = (vp < other);
-
- // Start must come first in the Range constructor.
- auto range = Range::create(vp.deepEquivalent().deprecatedNode()->document(),
- (thisIsStart ? vp : other),
- (thisIsStart ? other : vp));
- int distance = TextIterator::rangeLength(range.ptr());
-
- return (thisIsStart ? -distance : distance);
+ return a < b
+ ? -characterCount({ *makeBoundaryPoint(a), *makeBoundaryPoint(b) })
+ : characterCount({ *makeBoundaryPoint(b), *makeBoundaryPoint(a) });
}
void charactersAroundPosition(const VisiblePosition& position, UChar32& oneAfter, UChar32& oneBefore, UChar32& twoBefore)
Modified: trunk/Source/WebCore/editing/VisibleUnits.h (258870 => 258871)
--- trunk/Source/WebCore/editing/VisibleUnits.h 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/VisibleUnits.h 2020-03-23 20:50:15 UTC (rev 258871)
@@ -102,7 +102,7 @@
WEBCORE_EXPORT bool withinTextUnitOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection);
WEBCORE_EXPORT VisiblePosition positionOfNextBoundaryOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection);
WEBCORE_EXPORT RefPtr<Range> enclosingTextUnitOfGranularity(const VisiblePosition&, TextGranularity, SelectionDirection);
-WEBCORE_EXPORT int distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&);
+WEBCORE_EXPORT std::ptrdiff_t distanceBetweenPositions(const VisiblePosition&, const VisiblePosition&);
WEBCORE_EXPORT RefPtr<Range> wordRangeFromPosition(const VisiblePosition&);
WEBCORE_EXPORT VisiblePosition closestWordBoundaryForPosition(const VisiblePosition& position);
WEBCORE_EXPORT void charactersAroundPosition(const VisiblePosition&, UChar32& oneAfter, UChar32& oneBefore, UChar32& twoBefore);
Modified: trunk/Source/WebCore/editing/cocoa/DataDetection.mm (258870 => 258871)
--- trunk/Source/WebCore/editing/cocoa/DataDetection.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/cocoa/DataDetection.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -71,15 +71,18 @@
static RetainPtr<DDActionContext> detectItemAtPositionWithRange(VisiblePosition position, RefPtr<Range> contextRange, FloatRect& detectedDataBoundingBox, RefPtr<Range>& detectedDataRange)
{
String fullPlainTextString = plainText(contextRange.get());
- int hitLocation = TextIterator::rangeLength(makeRange(contextRange->startPosition(), position).get());
+ auto start = contextRange->startPosition();
+ if (start.isNull() || position.isNull())
+ return nil;
+ CFIndex hitLocation = characterCount({ *makeBoundaryPoint(start), *makeBoundaryPoint(position) });
- RetainPtr<DDScannerRef> scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
- RetainPtr<DDScanQueryRef> scanQuery = adoptCF(DDScanQueryCreateFromString(kCFAllocatorDefault, fullPlainTextString.createCFString().get(), CFRangeMake(0, fullPlainTextString.length())));
+ auto scanner = adoptCF(DDScannerCreate(DDScannerTypeStandard, 0, nullptr));
+ auto scanQuery = adoptCF(DDScanQueryCreateFromString(kCFAllocatorDefault, fullPlainTextString.createCFString().get(), CFRangeMake(0, fullPlainTextString.length())));
if (!DDScannerScanQuery(scanner.get(), scanQuery.get()))
- return nullptr;
+ return nil;
- RetainPtr<CFArrayRef> results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
+ auto results = adoptCF(DDScannerCopyResultsWithOptions(scanner.get(), DDScannerCopyResultsOptionsNoOverlap));
// Find the DDResultRef that intersects the hitTestResult's VisiblePosition.
DDResultRef mainResult = nullptr;
@@ -100,7 +103,7 @@
}
if (!mainResult)
- return nullptr;
+ return nil;
RetainPtr<DDActionContext> actionContext = adoptNS([allocDDActionContextInstance() init]);
[actionContext setAllResults:@[ (__bridge id)mainResult ]];
@@ -112,9 +115,9 @@
FrameView* frameView = mainResultRange->ownerDocument().view();
for (const auto& quad : quads)
detectedDataBoundingBox.unite(frameView->contentsToWindow(quad.enclosingBoundingBox()));
-
+
detectedDataRange = mainResultRange;
-
+
return actionContext;
}
Modified: trunk/Source/WebCore/editing/cocoa/DictionaryLookup.mm (258870 => 258871)
--- trunk/Source/WebCore/editing/cocoa/DictionaryLookup.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/cocoa/DictionaryLookup.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -264,12 +264,11 @@
std::tuple<RefPtr<Range>, NSDictionary *> DictionaryLookup::rangeForSelection(const VisibleSelection& selection)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
+
if (!RevealLibrary() || !RevealCoreLibrary() || !getRVItemClass())
return { nullptr, nil };
-
- auto selectedRange = selection.toNormalizedRange();
- if (!selectedRange)
+
+ if (!selection.toNormalizedRange())
return { nullptr, nil };
// Since we already have the range we want, we just need to grab the returned options.
@@ -279,20 +278,22 @@
// As context, we are going to use the surrounding paragraphs of text.
auto paragraphStart = startOfParagraph(selectionStart);
auto paragraphEnd = endOfParagraph(selectionEnd);
+ if (paragraphStart.isNull() || paragraphEnd.isNull())
+ return { nullptr, nil };
- int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
- int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get());
- NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart);
-
+ auto lengthToSelectionStart = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) });
+ auto selectionCharacterCount = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) });
+ NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, selectionCharacterCount);
+
RefPtr<Range> fullCharacterRange = makeRange(paragraphStart, paragraphEnd);
String itemString = plainText(fullCharacterRange.get());
RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:rangeToPass]);
NSRange highlightRange = item.get().highlightRange;
-
+
return { TextIterator::subrange(*fullCharacterRange, highlightRange.location, highlightRange.length), nil };
-
+
END_BLOCK_OBJC_EXCEPTIONS;
-
+
return { nullptr, nil };
}
@@ -322,43 +323,40 @@
auto selection = frame->page()->focusController().focusedOrMainFrame().selection().selection();
NSRange selectionRange;
- int hitIndex;
+ NSUInteger hitIndex;
RefPtr<Range> fullCharacterRange;
if (selection.selectionType() == VisibleSelection::RangeSelection) {
auto selectionStart = selection.visibleStart();
auto selectionEnd = selection.visibleEnd();
-
+
// As context, we are going to use the surrounding paragraphs of text.
auto paragraphStart = startOfParagraph(selectionStart);
auto paragraphEnd = endOfParagraph(selectionEnd);
- auto rangeToSelectionStart = makeRange(paragraphStart, selectionStart);
- auto rangeToSelectionEnd = makeRange(paragraphStart, selectionEnd);
-
fullCharacterRange = makeRange(paragraphStart, paragraphEnd);
if (!fullCharacterRange)
return { nullptr, nil };
- selectionRange = NSMakeRange(TextIterator::rangeLength(rangeToSelectionStart.get()), TextIterator::rangeLength(makeRange(selectionStart, selectionEnd).get()));
-
- hitIndex = TextIterator::rangeLength(makeRange(paragraphStart, position).get());
+ selectionRange = NSMakeRange(characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) }),
+ characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) }));
+ hitIndex = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(position) });
} else {
VisibleSelection selectionAccountingForLineRules { position };
selectionAccountingForLineRules.expandUsingGranularity(WordGranularity);
position = selectionAccountingForLineRules.start();
+
// As context, we are going to use 250 characters of text before and after the point.
fullCharacterRange = rangeExpandedAroundPositionByCharacters(position, 250);
-
if (!fullCharacterRange)
return { nullptr, nil };
-
+
selectionRange = NSMakeRange(NSNotFound, 0);
- hitIndex = TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get());
+ hitIndex = characterCount({ *makeBoundaryPoint(fullCharacterRange->startPosition()), *makeBoundaryPoint(position) });
}
-
+
NSRange selectedRange = [getRVSelectionClass() revealRangeAtIndex:hitIndex selectedRanges:@[[NSValue valueWithRange:selectionRange]] shouldUpdateSelection:nil];
-
+
String itemString = plainText(*fullCharacterRange);
RetainPtr<RVItem> item = adoptNS([allocRVItemInstance() initWithText:itemString selectedRange:selectedRange]);
NSRange highlightRange = item.get().highlightRange;
Modified: trunk/Source/WebCore/editing/ios/DictationCommandIOS.cpp (258870 => 258871)
--- trunk/Source/WebCore/editing/ios/DictationCommandIOS.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/ios/DictationCommandIOS.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -48,9 +48,7 @@
void DictationCommandIOS::doApply()
{
- VisiblePosition insertionPosition(startingSelection().visibleStart());
-
- unsigned resultLength = 0;
+ CharacterCount resultLength = 0;
for (auto& interpretations : m_dictationPhrases) {
const String& firstInterpretation = interpretations[0];
resultLength += firstInterpretation.length();
@@ -62,20 +60,23 @@
setEndingSelection(VisibleSelection(endingSelection().visibleEnd()));
}
- VisiblePosition afterResults(endingSelection().visibleEnd());
+ // FIXME: Add the result marker using a Position cached before results are inserted, instead of relying on character counts.
- Element* root = afterResults.rootEditableElement();
+ auto endPosition = endingSelection().visibleEnd();
+ auto end = makeBoundaryPoint(endPosition);
+ auto* root = endPosition.rootEditableElement();
+ if (!end || !root)
+ return;
- // FIXME: Add the result marker using a Position cached before results are inserted, instead of relying on TextIterators.
- auto rangeToEnd = Range::create(document(), createLegacyEditingPosition((Node *)root, 0), afterResults.deepEquivalent());
- int endIndex = TextIterator::rangeLength(rangeToEnd.ptr(), true);
- int startIndex = endIndex - resultLength;
+ auto endOffset = characterCount({ { *root, 0 }, WTFMove(*end) });
+ if (endOffset < resultLength)
+ return;
- if (startIndex >= 0) {
- RefPtr<Range> resultRange = TextIterator::rangeFromLocationAndLength(document().documentElement(), startIndex, endIndex, true);
- ASSERT(resultRange); // FIXME: What guarantees this?
- document().markers().addDictationResultMarker(*resultRange, m_metadata);
- }
+ auto resultRange = TextIterator::rangeFromLocationAndLength(root, endOffset - resultLength, endOffset);
+ if (!resultRange)
+ return;
+
+ document().markers().addDictationResultMarker(*resultRange, m_metadata);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/mac/DictionaryLookupLegacy.mm (258870 => 258871)
--- trunk/Source/WebCore/editing/mac/DictionaryLookupLegacy.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/editing/mac/DictionaryLookupLegacy.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -89,10 +89,12 @@
// As context, we are going to use the surrounding paragraphs of text.
auto paragraphStart = startOfParagraph(selectionStart);
auto paragraphEnd = endOfParagraph(selectionEnd);
+ if (paragraphStart.isNull() || paragraphEnd.isNull())
+ return { nullptr, nil };
- int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
- int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get());
- NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart);
+ auto lengthToSelectionStart = characterCount({ *makeBoundaryPoint(paragraphStart), *makeBoundaryPoint(selectionStart) });
+ auto selectionCharacterCount = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selectionEnd) });
+ NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, selectionCharacterCount);
NSDictionary *options = nil;
tokenRange(plainText(makeRange(paragraphStart, paragraphEnd).get()), rangeToPass, &options);
@@ -133,7 +135,12 @@
if (!fullCharacterRange)
return { nullptr, nil };
- NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get()), 0);
+ auto fullCharacterStart = makeBoundaryPoint(fullCharacterRange->startPosition());
+ auto positionBoundary = makeBoundaryPoint(position);
+ if (!fullCharacterStart || !positionBoundary)
+ return { nullptr, nil };
+
+ NSRange rangeToPass = NSMakeRange(characterCount({ *fullCharacterStart, *positionBoundary }), 0);
NSDictionary *options = nil;
NSRange extractedRange = tokenRange(plainText(fullCharacterRange.get()), rangeToPass, &options);
Modified: trunk/Source/WebCore/page/EventHandler.cpp (258870 => 258871)
--- trunk/Source/WebCore/page/EventHandler.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -654,10 +654,13 @@
return updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), ParagraphGranularity);
}
-static int textDistance(const Position& start, const Position& end)
+static CharacterCount textDistance(const Position& start, const Position& end)
{
- auto range = Range::create(start.anchorNode()->document(), start, end);
- return TextIterator::rangeLength(range.ptr(), true);
+ auto startBoundary = makeBoundaryPoint(start);
+ auto endBoundary = makeBoundaryPoint(end);
+ if (!startBoundary || !endBoundary)
+ return 0;
+ return characterCount({ *startBoundary, *endBoundary }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
}
bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
Modified: trunk/Source/WebKit/ChangeLog (258870 => 258871)
--- trunk/Source/WebKit/ChangeLog 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/ChangeLog 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,3 +1,25 @@
+2020-03-23 Darin Adler <[email protected]>
+
+ Change TextIterator::rangeLength to not require a live range
+ https://bugs.webkit.org/show_bug.cgi?id=209207
+
+ Reviewed by Antti Koivisto.
+
+ * 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.
+
2020-03-23 youenn fablet <[email protected]>
Rename blankURL to aboutBlankURL
Modified: trunk/Source/WebKit/Shared/EditingRange.cpp (258870 => 258871)
--- trunk/Source/WebKit/Shared/EditingRange.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/Shared/EditingRange.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -58,18 +58,17 @@
ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::Paragraph);
- const WebCore::VisibleSelection& selection = frame.selection().selection();
- RefPtr<WebCore::Range> selectedRange = selection.toNormalizedRange();
- if (!selectedRange)
+ auto& selection = frame.selection().selection();
+ if (!selection.toNormalizedRange())
return nullptr;
- RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());
- if (!paragraphRange)
+ auto paragraphStart = makeBoundaryPoint(startOfParagraph(selection.visibleStart()));
+ if (!paragraphStart)
return nullptr;
+ auto& rootNode = paragraphStart->container->treeScope().rootNode();
- auto& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode();
- int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, ¶graphRange->startContainer(), paragraphRange->startOffset()).ptr());
- return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(range.location), length);
+ auto paragraphStartIndex = WebCore::characterCount({ { rootNode, 0 }, *paragraphStart });
+ return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + range.location, length);
}
EditingRange EditingRange::fromRange(WebCore::Frame& frame, const WebCore::Range* range, EditingRangeIsRelativeTo editingRangeIsRelativeTo)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp (258870 => 258871)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -361,6 +361,7 @@
}
#if !PLATFORM(COCOA) && !USE(GLIB)
+
void WebEditorClient::handleKeyboardEvent(KeyboardEvent& event)
{
if (m_page->handleEditingKeyboardEvent(event))
@@ -371,6 +372,7 @@
{
notImplemented();
}
+
#endif // !PLATFORM(COCOA) && !USE(GLIB)
void WebEditorClient::textFieldDidBeginEditing(Element* element)
@@ -420,6 +422,7 @@
}
#if !PLATFORM(IOS_FAMILY)
+
void WebEditorClient::overflowScrollPositionChanged()
{
notImplemented();
@@ -429,6 +432,7 @@
{
notImplemented();
}
+
#endif
static bool getActionTypeForKeyEvent(KeyboardEvent* event, WKInputFieldActionType& type)
@@ -549,14 +553,18 @@
*badGrammarLength = resultLength;
}
-static int32_t insertionPointFromCurrentSelection(const VisibleSelection& currentSelection)
+static CharacterCount insertionPointFromCurrentSelection(const VisibleSelection& currentSelection)
{
- VisiblePosition selectionStart = currentSelection.visibleStart();
- VisiblePosition paragraphStart = startOfParagraph(selectionStart);
- return TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
+ auto selectionStart = currentSelection.visibleStart();
+ auto selectionStartBoundary = makeBoundaryPoint(selectionStart);
+ auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart));
+ if (!selectionStartBoundary || !paragraphStart)
+ return 0;
+ return characterCount({ *paragraphStart, *selectionStartBoundary });
}
#if USE(UNIFIED_TEXT_CHECKING)
+
Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView stringView, OptionSet<WebCore::TextCheckingType> checkingTypes, const VisibleSelection& currentSelection)
{
Vector<TextCheckingResult> results;
@@ -563,6 +571,7 @@
m_page->sendSync(Messages::WebPageProxy::CheckTextOfParagraph(stringView.toStringWithoutCopying(), checkingTypes, insertionPointFromCurrentSelection(currentSelection)), Messages::WebPageProxy::CheckTextOfParagraph::Reply(results));
return results;
}
+
#endif
void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
@@ -616,16 +625,14 @@
bool WebEditorClient::supportsGlobalSelection()
{
-#if PLATFORM(GTK)
-#if PLATFORM(X11)
+#if PLATFORM(GTK) && PLATFORM(X11)
if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11)
return true;
#endif
-#if PLATFORM(WAYLAND)
+#if PLATFORM(GTK) && PLATFORM(WAYLAND)
if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
return true;
#endif
-#endif
return false;
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (258870 => 258871)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -5428,6 +5428,7 @@
#endif // PLATFORM(COCOA)
#if PLATFORM(GTK) || PLATFORM(WPE)
+
static Frame* targetFrameForEditing(WebPage& page)
{
Frame& targetFrame = page.corePage()->focusController().focusedOrMainFrame();
@@ -5467,7 +5468,7 @@
auto selectionStart = selection.visibleStart();
auto surroundingRange = makeRange(startOfEditableContent(selectionStart), selectionStart);
- auto cursorPosition = TextIterator::rangeLength(surroundingRange.get());
+ auto cursorPosition = WebCore::characterCount(*surroundingRange);
auto& rootNode = surroundingRange->startContainer().treeScope().rootNode();
auto selectionRange = TextIterator::rangeFromLocationAndLength(&rootNode, cursorPosition + offset, characterCount);
if (!selectionRange)
@@ -5479,6 +5480,7 @@
targetFrame->editor().setIgnoreSelectionChanges(false);
sendEditorStateUpdate();
}
+
#endif
void WebPage::didApplyStyle()
Modified: trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp (258870 => 258871)
--- trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp 2020-03-23 20:50:15 UTC (rev 258871)
@@ -116,12 +116,12 @@
surroundingRange->setEnd(compositionRange->startPosition());
clonedRange->setStart(compositionRange->endPosition());
postLayoutData.surroundingContext = plainText(surroundingRange.get()) + plainText(clonedRange.ptr());
- postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(surroundingRange.get());
+ postLayoutData.surroundingContextCursorPosition = characterCount(*surroundingRange);
postLayoutData.surroundingContextSelectionPosition = postLayoutData.surroundingContextCursorPosition;
} else {
postLayoutData.surroundingContext = plainText(surroundingRange.get());
- postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(makeRange(surroundingStart, selectionStart).get());
- postLayoutData.surroundingContextSelectionPosition = TextIterator::rangeLength(makeRange(surroundingStart, selection.visibleEnd()).get());
+ postLayoutData.surroundingContextCursorPosition = characterCount(*makeRange(surroundingStart, selectionStart));
+ postLayoutData.surroundingContextSelectionPosition = characterCount(*makeRange(surroundingStart, selection.visibleEnd()));
}
}
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (258870 => 258871)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1989,13 +1989,16 @@
}
}
-static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, RefPtr<Range> selectionRange)
+static Optional<SimpleRange> rangeNearPositionMatchesText(const VisiblePosition& position, const String& matchText, const VisibleSelection& selection)
{
- if (!selectionRange)
+ auto liveRange = selection.firstRange();
+ if (!liveRange)
return WTF::nullopt;
- auto range = Range::create(selectionRange->ownerDocument(), selectionRange->startPosition(), position.deepEquivalent().parentAnchoredEquivalent());
- unsigned targetOffset = TextIterator::rangeLength(range.ptr(), true);
- return findClosestPlainText(*selectionRange, matchText, { }, targetOffset);
+ SimpleRange range { *liveRange };
+ auto boundaryPoint = makeBoundaryPoint(position);
+ if (!boundaryPoint)
+ return WTF::nullopt;
+ return findClosestPlainText(range, matchText, { }, characterCount({ range.start, *boundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
}
void WebPage::getRectsAtSelectionOffsetWithText(int32_t offset, const String& text, CallbackID callbackID)
@@ -2022,7 +2025,7 @@
if (plainTextForDisplay(range.ptr()) != text) {
// Try to search for a range which is the closest to the position within the selection range that matches the passed in text.
- if (auto wordRange = rangeNearPositionMatchesText(startPosition, text, selection.toNormalizedRange())) {
+ if (auto wordRange = rangeNearPositionMatchesText(startPosition, text, selection)) {
if (!wordRange->collapsed())
range = createLiveRange(*wordRange);
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (258870 => 258871)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -140,7 +140,7 @@
return;
}
- const VisibleSelection& selection = frame.selection().selection();
+ auto& selection = frame.selection().selection();
RefPtr<Range> selectedRange = selection.toNormalizedRange();
if (!selectedRange)
return;
@@ -147,12 +147,15 @@
auto& postLayoutData = result.postLayoutData();
VisiblePosition selectionStart = selection.visibleStart();
- VisiblePosition selectionEnd = selection.visibleEnd();
- VisiblePosition paragraphStart = startOfParagraph(selectionStart);
- VisiblePosition paragraphEnd = endOfParagraph(selectionEnd);
+ auto selectionStartBoundary = makeBoundaryPoint(selectionStart);
+ auto selectionEnd = makeBoundaryPoint(selection.visibleEnd());
+ auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart));
- postLayoutData.candidateRequestStartPosition = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
- postLayoutData.selectedTextLength = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()) - postLayoutData.candidateRequestStartPosition;
+ if (!selectionStartBoundary || !selectionEnd || !paragraphStart)
+ return;
+
+ postLayoutData.candidateRequestStartPosition = characterCount({ *paragraphStart, *selectionStartBoundary });
+ postLayoutData.selectedTextLength = characterCount({ *selectionStartBoundary, *selectionEnd });
postLayoutData.paragraphContextForCandidateRequest = plainText(frame.editor().contextRangeForCandidateRequest().get());
postLayoutData.stringForCandidateRequest = frame.editor().stringForCandidateRequest();
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (258870 => 258871)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1,3 +1,16 @@
+2020-03-23 Darin Adler <[email protected]>
+
+ Change TextIterator::rangeLength to not require a live range
+ https://bugs.webkit.org/show_bug.cgi?id=209207
+
+ Reviewed by Antti Koivisto.
+
+ * WebCoreSupport/WebEditorClient.mm:
+ (insertionPointFromCurrentSelection): Use characterCount.
+ (WebEditorClient::requestCandidatesForSelection): Ditto.
+ * WebView/WebFrame.mm:
+ (-[WebFrame _convertToDOMRange:rangeIsRelativeTo:]): Ditto.
+
2020-03-23 youenn fablet <[email protected]>
Rename blankURL to aboutBlankURL
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm (258870 => 258871)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -1031,16 +1031,19 @@
return results;
}
-static int insertionPointFromCurrentSelection(const VisibleSelection& currentSelection)
+static NSUInteger insertionPointFromCurrentSelection(const VisibleSelection& selection)
{
- VisiblePosition selectionStart = currentSelection.visibleStart();
- VisiblePosition paragraphStart = startOfParagraph(selectionStart);
- return TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
+ auto selectionStart = selection.visibleStart();
+ auto selectionStartBoundary = makeBoundaryPoint(selectionStart);
+ auto paragraphStart = makeBoundaryPoint(startOfParagraph(selectionStart));
+ if (!selectionStartBoundary || !paragraphStart)
+ return 0;
+ return characterCount({ *paragraphStart, *selectionStartBoundary });
}
Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView string, OptionSet<TextCheckingType> coreCheckingTypes, const VisibleSelection& currentSelection)
{
- NSDictionary *options = @{ NSTextCheckingInsertionPointKey : [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
+ NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) };
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);
}
@@ -1083,7 +1086,7 @@
NSString *language = nil;
NSOrthography* orthography = nil;
NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
- NSDictionary *options = @{ NSTextCheckingInsertionPointKey : [NSNumber numberWithUnsignedInteger:insertionPointFromCurrentSelection(currentSelection)] };
+ NSDictionary *options = @{ NSTextCheckingInsertionPointKey : @(insertionPointFromCurrentSelection(currentSelection)) };
if (context.length()) {
[checker checkString:context range:NSMakeRange(0, context.length()) types:NSTextCheckingTypeOrthography options:options inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:&orthography wordCount:0];
language = [checker languageForWordRange:NSMakeRange(0, context.length()) inString:context orthography:orthography];
@@ -1116,24 +1119,20 @@
if (![m_webView shouldRequestCandidates])
return;
- RefPtr<Range> selectedRange = selection.toNormalizedRange();
- if (!selectedRange)
+ if (!selection.toNormalizedRange())
return;
-
- Frame* frame = core([m_webView _selectedOrMainFrame]);
+
+ auto* frame = core([m_webView _selectedOrMainFrame]);
if (!frame)
return;
m_lastSelectionForRequestedCandidates = selection;
- VisiblePosition selectionStart = selection.visibleStart();
- VisiblePosition selectionEnd = selection.visibleEnd();
- VisiblePosition paragraphStart = startOfParagraph(selectionStart);
- VisiblePosition paragraphEnd = endOfParagraph(selectionEnd);
+ auto selectionStart = selection.visibleStart();
+ auto selectionStartOffsetInParagraph = characterCount({ *makeBoundaryPoint(startOfParagraph(selectionStart)), *makeBoundaryPoint(selectionStart) });
+ auto selectionLength = characterCount({ *makeBoundaryPoint(selectionStart), *makeBoundaryPoint(selection.visibleEnd()) });
- int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
- int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get());
- m_rangeForCandidates = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart);
+ m_rangeForCandidates = NSMakeRange(selectionStartOffsetInParagraph, selectionLength);
m_paragraphContextForCandidateRequest = plainText(frame->editor().contextRangeForCandidateRequest().get());
NSTextCheckingTypes checkingTypes = NSTextCheckingTypeSpelling | NSTextCheckingTypeReplacement | NSTextCheckingTypeCorrection;
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm (258870 => 258871)
--- trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm 2020-03-23 20:19:38 UTC (rev 258870)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm 2020-03-23 20:50:15 UTC (rev 258871)
@@ -835,24 +835,19 @@
// That fits with AppKit's idea of an input context.
auto* element = _private->coreFrame->selection().rootEditableElementOrDocumentElement();
if (!element)
- return nil;
+ return nullptr;
return WebCore::TextIterator::rangeFromLocationAndLength(element, nsrange.location, nsrange.length);
}
ASSERT(rangeIsRelativeTo == WebRangeIsRelativeTo::Paragraph);
- const auto& selection = _private->coreFrame->selection().selection();
- RefPtr<WebCore::Range> selectedRange = selection.toNormalizedRange();
- if (!selectedRange)
+ auto paragraphStart = makeBoundaryPoint(startOfParagraph(_private->coreFrame->selection().selection().visibleStart()));
+ if (!paragraphStart)
return nullptr;
+ auto& rootNode = paragraphStart->container->treeScope().rootNode();
- RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());
- if (!paragraphRange)
- return nullptr;
-
- auto& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode();
- int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, ¶graphRange->startContainer(), paragraphRange->startOffset()).ptr());
- return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(nsrange.location), nsrange.length);
+ auto paragraphStartIndex = WebCore::characterCount({ { rootNode, 0 }, *paragraphStart });
+ return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + nsrange.location, nsrange.length);
}
- (DOMRange *)_convertNSRangeToDOMRange:(NSRange)nsrange