Changeset 211356 in webkit
- Timestamp:
- Jan 29, 2017 9:03:11 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r211352 r211356 1 2017-01-29 Nan Wang <n_wang@apple.com> 2 3 AX: WKContentView needs to implement UITextInput methods to make speak selection highlighting work 4 https://bugs.webkit.org/show_bug.cgi?id=166955 5 6 Reviewed by Ryosuke Niwa. 7 8 * editing/text-iterator/range-of-string-closest-to-position-expected.txt: Added. 9 * editing/text-iterator/range-of-string-closest-to-position.html: Added. 10 1 11 2017-01-29 Yoav Weiss <yoav@yoav.ws> 2 12 -
trunk/Source/WebCore/ChangeLog
r211355 r211356 1 2017-01-29 Nan Wang <n_wang@apple.com> 2 3 AX: WKContentView needs to implement UITextInput methods to make speak selection highlighting work 4 https://bugs.webkit.org/show_bug.cgi?id=166955 5 6 Reviewed by Ryosuke Niwa. 7 8 Created a new version of Range::collectSelectionRect() that returns rects for each 9 line, so that Speak Selection doesn't need to handle searching for soft line breaks. 10 Also added a variant of findPlainText to search for the closest matched range to the given position. 11 12 Test: editing/text-iterator/range-of-string-closest-to-position.html 13 14 * dom/Range.cpp: 15 (WebCore::Range::collectSelectionRectsWithoutUnionInteriorLines): 16 (WebCore::Range::collectSelectionRects): 17 * dom/Range.h: 18 * editing/TextIterator.cpp: 19 (WebCore::findPlainTextMatches): 20 (WebCore::updateSearchBuffer): 21 (WebCore::findIteratorOptions): 22 (WebCore::rangeMatches): 23 (WebCore::findClosestPlainText): 24 (WebCore::findPlainText): 25 (WebCore::findPlainTextOffset): Deleted. 26 * editing/TextIterator.h: 27 * editing/htmlediting.h: 28 * testing/Internals.cpp: 29 (WebCore::Internals::rangeOfStringNearLocation): 30 * testing/Internals.h: 31 * testing/Internals.idl: 32 1 33 2017-01-29 Andy Estes <aestes@apple.com> 2 34 -
trunk/Source/WebCore/dom/Range.cpp
r210833 r211356 1267 1267 // This function is similar in spirit to addLineBoxRects, but annotates the returned rectangles 1268 1268 // with additional state which helps iOS draw selections in its unique way. 1269 void Range::collectSelectionRects(Vector<SelectionRect>& rects)1269 int Range::collectSelectionRectsWithoutUnionInteriorLines(Vector<SelectionRect>& rects) 1270 1270 { 1271 1271 auto& startContainer = this->startContainer(); … … 1326 1326 VisiblePosition brPosition(createLegacyEditingPosition(stopNode, 0), VP_DEFAULT_AFFINITY); 1327 1327 if (endPosition == brPosition) 1328 rects.last().setIsLineBreak(true); 1328 rects.last().setIsLineBreak(true); 1329 1329 } 1330 1330 … … 1423 1423 selectionRect.setLogicalWidth(selectionRect.maxX() - selectionRect.logicalLeft()); 1424 1424 } 1425 1425 1426 return maxLineNumber; 1427 } 1428 1429 void Range::collectSelectionRects(Vector<SelectionRect>& rects) 1430 { 1431 int maxLineNumber = collectSelectionRectsWithoutUnionInteriorLines(rects); 1432 const size_t numberOfRects = rects.size(); 1433 1426 1434 // Union all the rectangles on interior lines (i.e. not first or last). 1427 1435 // On first and last lines, just avoid having overlaps by merging intersecting rectangles. -
trunk/Source/WebCore/dom/Range.h
r210758 r211356 126 126 #if PLATFORM(IOS) 127 127 WEBCORE_EXPORT void collectSelectionRects(Vector<SelectionRect>&); 128 WEBCORE_EXPORT int collectSelectionRectsWithoutUnionInteriorLines(Vector<SelectionRect>&); 128 129 #endif 129 130 -
trunk/Source/WebCore/editing/TextIterator.cpp
r210432 r211356 2657 2657 } 2658 2658 2659 static std::optional<std::pair<size_t, size_t>> findPlainTextOffset(SearchBuffer& buffer, CharacterIterator& findIterator, bool searchForward) 2660 { 2661 size_t matchStart = 0; 2662 size_t matchLength = 0; 2659 static TextIteratorBehavior findIteratorOptions(FindOptions options) 2660 { 2661 TextIteratorBehavior iteratorOptions = TextIteratorEntersTextControls | TextIteratorClipsToFrameAncestors; 2662 if (!(options & DoNotTraverseFlatTree)) 2663 iteratorOptions |= TextIteratorTraversesFlatTree; 2664 return iteratorOptions; 2665 } 2666 2667 static void findPlainTextMatches(const Range& range, const String& target, FindOptions options, const std::function<bool(size_t, size_t)>& match) 2668 { 2669 SearchBuffer buffer(target, options); 2670 if (buffer.needsMoreContext()) { 2671 Ref<Range> beforeStartRange = range.ownerDocument().createRange(); 2672 beforeStartRange->setEnd(range.startContainer(), range.startOffset()); 2673 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) { 2674 buffer.prependContext(backwardsIterator.text()); 2675 if (!buffer.needsMoreContext()) 2676 break; 2677 } 2678 } 2679 2680 CharacterIterator findIterator(range, findIteratorOptions(options)); 2663 2681 while (!findIterator.atEnd()) { 2664 2682 findIterator.advance(buffer.append(findIterator.text())); … … 2675 2693 size_t lastCharacterInBufferOffset = findIterator.characterOffset(); 2676 2694 ASSERT(lastCharacterInBufferOffset >= matchStartOffset); 2677 matchStart = lastCharacterInBufferOffset - matchStartOffset; 2678 matchLength = newMatchLength; 2679 if (searchForward) // Look for the last match when searching backwards instead. 2680 return std::pair<size_t, size_t> { matchStart, matchLength }; 2681 } 2682 } 2683 2695 if (match(lastCharacterInBufferOffset - matchStartOffset, newMatchLength)) 2696 return; 2697 } 2698 } 2699 } 2700 2701 static Ref<Range> rangeForMatch(const Range& range, FindOptions options, size_t matchStart, size_t matchLength, bool searchForward) 2702 { 2684 2703 if (!matchLength) 2685 return std::nullopt; 2686 2687 return std::pair<size_t, size_t> { matchStart, matchLength }; 2704 return collapsedToBoundary(range, searchForward); 2705 CharacterIterator rangeComputeIterator(range, findIteratorOptions(options)); 2706 return characterSubrange(range.ownerDocument(), rangeComputeIterator, matchStart, matchLength); 2707 } 2708 2709 Ref<Range> findClosestPlainText(const Range& range, const String& target, FindOptions options, unsigned targetOffset) 2710 { 2711 size_t matchStart = 0; 2712 size_t matchLength = 0; 2713 size_t distance = std::numeric_limits<size_t>::max(); 2714 auto match = [targetOffset, &distance, &matchStart, &matchLength] (size_t start, size_t length) { 2715 size_t newDistance = std::min(abs(static_cast<signed>(start - targetOffset)), abs(static_cast<signed>(start + length - targetOffset))); 2716 if (newDistance < distance) { 2717 matchStart = start; 2718 matchLength = length; 2719 distance = newDistance; 2720 } 2721 return false; 2722 }; 2723 2724 findPlainTextMatches(range, target, options, match); 2725 return rangeForMatch(range, options, matchStart, matchLength, !(options & Backwards)); 2688 2726 } 2689 2727 2690 2728 Ref<Range> findPlainText(const Range& range, const String& target, FindOptions options) 2691 2729 { 2692 SearchBuffer buffer(target, options);2693 2694 if (buffer.needsMoreContext()) {2695 Ref<Range> beforeStartRange = range.ownerDocument().createRange();2696 beforeStartRange->setEnd(range.startContainer(), range.startOffset());2697 for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) {2698 buffer.prependContext(backwardsIterator.text());2699 if (!buffer.needsMoreContext())2700 break;2701 }2702 }2703 2704 2730 bool searchForward = !(options & Backwards); 2705 TextIteratorBehavior iteratorOptions = TextIteratorEntersTextControls | TextIteratorClipsToFrameAncestors;2706 if (!(options & DoNotTraverseFlatTree))2707 iteratorOptions |= TextIteratorTraversesFlatTree;2708 2709 CharacterIterator findIterator(range, iteratorOptions);2710 auto result = findPlainTextOffset(buffer, findIterator, searchForward);2711 if (!result)2712 return collapsedToBoundary(range, searchForward);2713 2714 CharacterIterator rangeComputeIterator(range, iteratorOptions);2715 return characterSubrange(range.ownerDocument(), rangeComputeIterator, result->first, result->second);2716 } 2717 2718 } 2731 size_t matchStart = 0; 2732 size_t matchLength = 0; 2733 auto match = [searchForward, &matchStart, &matchLength] (size_t start, size_t length) { 2734 matchStart = start; 2735 matchLength = length; 2736 // Look for the last match when searching backwards instead. 2737 return searchForward; 2738 }; 2739 2740 findPlainTextMatches(range, target, options, match); 2741 return rangeForMatch(range, options, matchStart, matchLength, searchForward); 2742 } 2743 2744 } -
trunk/Source/WebCore/editing/TextIterator.h
r210131 r211356 46 46 WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false); 47 47 Ref<Range> findPlainText(const Range&, const String&, FindOptions); 48 WEBCORE_EXPORT Ref<Range> findClosestPlainText(const Range&, const String&, FindOptions, unsigned); 48 49 49 50 // FIXME: Move this somewhere else in the editing directory. It doesn't belong here. -
trunk/Source/WebCore/editing/htmlediting.h
r210842 r211356 145 145 int comparePositions(const VisiblePosition&, const VisiblePosition&); 146 146 147 int indexForVisiblePosition(const VisiblePosition&, RefPtr<ContainerNode>& scope);147 WEBCORE_EXPORT int indexForVisiblePosition(const VisiblePosition&, RefPtr<ContainerNode>& scope); 148 148 int indexForVisiblePosition(Node&, const VisiblePosition&, bool forSelectionPreservation); 149 VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope);149 WEBCORE_EXPORT VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope); 150 150 VisiblePosition visiblePositionForIndexUsingCharacterIterator(Node&, int index); // FIXME: Why do we need this version? 151 151 -
trunk/Source/WebCore/testing/Internals.cpp
r211324 r211356 1457 1457 } 1458 1458 1459 RefPtr<Range> Internals::rangeOfStringNearLocation(const Range& searchRange, const String& text, unsigned targetOffset) 1460 { 1461 return findClosestPlainText(searchRange, text, 0, targetOffset); 1462 } 1463 1459 1464 ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int x, int y) 1460 1465 { -
trunk/Source/WebCore/testing/Internals.h
r211324 r211356 202 202 Ref<Range> subrange(Range&, int rangeLocation, int rangeLength); 203 203 ExceptionOr<RefPtr<Range>> rangeForDictionaryLookupAtLocation(int x, int y); 204 RefPtr<Range> rangeOfStringNearLocation(const Range&, const String&, unsigned); 204 205 205 206 ExceptionOr<void> setDelegatesScrolling(bool enabled); -
trunk/Source/WebCore/testing/Internals.idl
r211253 r211356 196 196 Range subrange(Range range, long rangeLocation, long rangeLength); 197 197 [MayThrowException] Range? rangeForDictionaryLookupAtLocation(long x, long y); 198 Range? rangeOfStringNearLocation(Range range, DOMString text, long targetOffset); 198 199 199 200 [MayThrowException] void setDelegatesScrolling(boolean enabled); -
trunk/Source/WebKit2/ChangeLog
r211354 r211356 1 2017-01-29 Nan Wang <n_wang@apple.com> 2 3 AX: WKContentView needs to implement UITextInput methods to make speak selection highlighting work 4 https://bugs.webkit.org/show_bug.cgi?id=166955 5 6 Reviewed by Ryosuke Niwa. 7 8 Implemented methods that Speak Selection can use to retrieve the word/sentence highlighting rects. 9 10 * Scripts/webkit/messages.py: 11 (headers_for_type): 12 * UIProcess/WebPageProxy.h: 13 * UIProcess/WebPageProxy.messages.in: 14 * UIProcess/ios/WKContentViewInteraction.h: 15 * UIProcess/ios/WKContentViewInteraction.mm: 16 (-[WKContentView webSelectionRectsForSelectionRects:]): 17 (-[WKContentView webSelectionRects]): 18 (-[WKContentView _accessibilityRetrieveRectsEnclosingSelectionOffset:withGranularity:]): 19 (-[WKContentView _accessibilityRetrieveRectsAtSelectionOffset:withText:]): 20 * UIProcess/ios/WebPageProxyIOS.mm: 21 (WebKit::WebPageProxy::selectionRectsCallback): 22 (WebKit::WebPageProxy::requestRectsForGranularityWithSelectionOffset): 23 (WebKit::WebPageProxy::requestRectsAtSelectionOffsetWithText): 24 * WebProcess/WebPage/WebPage.h: 25 * WebProcess/WebPage/WebPage.messages.in: 26 * WebProcess/WebPage/ios/WebPageIOS.mm: 27 (WebKit::visiblePositionForPositionWithOffset): 28 (WebKit::WebPage::getRectsForGranularityWithSelectionOffset): 29 (WebKit::rangeNearPositionMatchesText): 30 (WebKit::WebPage::getRectsAtSelectionOffsetWithText): 31 1 32 2017-01-29 Dan Bernstein <mitz@apple.com> 2 33 -
trunk/Source/WebKit2/Scripts/webkit/messages.py
r210887 r211356 366 366 'WebCore::TextureMapperAnimations': ['<WebCore/TextureMapperAnimation.h>'], 367 367 'WebCore::ViewportAttributes': ['<WebCore/ViewportArguments.h>'], 368 'WebCore::SelectionRect': ['"EditorState.h"'], 368 369 'WebKit::BackForwardListItemState': ['"SessionState.h"'], 369 370 'WebKit::LayerHostingMode': ['"LayerTreeContext.h"'], -
trunk/Source/WebKit2/UIProcess/WebPageProxy.h
r211226 r211356 257 257 typedef GenericCallback<const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t> GestureCallback; 258 258 typedef GenericCallback<const WebCore::IntPoint&, uint32_t, uint32_t> TouchesCallback; 259 typedef GenericCallback<const Vector<WebCore::SelectionRect>&> SelectionRectsCallback; 259 260 struct NodeAssistanceArguments { 260 261 AssistedNodeInformation m_nodeInformation; … … 546 547 void setForceAlwaysUserScalable(bool); 547 548 void setIsScrollingOrZooming(bool); 549 void requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity, uint32_t offset, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>); 550 void requestRectsAtSelectionOffsetWithText(int32_t offset, const String&, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>); 548 551 #if ENABLE(DATA_INTERACTION) 549 552 void didPerformDataInteractionControllerOperation(); … … 1478 1481 void interpretKeyEvent(const EditorState&, bool isCharEvent, bool& handled); 1479 1482 void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect); 1483 void selectionRectsCallback(const Vector<WebCore::SelectionRect>&, uint64_t); 1480 1484 #endif 1481 1485 #if PLATFORM(GTK) -
trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in
r211226 r211356 196 196 DisableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) 197 197 DrawToPDFCallback(IPC::DataReference pdfData, uint64_t callbackID) 198 SelectionRectsCallback(Vector<WebCore::SelectionRect> selectionRects, uint64_t callbackID); 198 199 #endif 199 200 #if ENABLE(DATA_DETECTION) -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
r211342 r211356 248 248 - (NSArray<NSValue *> *)_uiTextSelectionRects; 249 249 - (void)accessibilityRetrieveSpeakSelectionContent; 250 - (void)_accessibilityRetrieveRectsEnclosingSelectionOffset:(NSInteger)offset withGranularity:(UITextGranularity)granularity; 251 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text; 250 252 251 253 #if ENABLE(DATA_INTERACTION) -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
r211342 r211356 496 496 @interface WKContentView (WKInteractionPrivate) 497 497 - (void)accessibilitySpeakSelectionSetContent:(NSString *)string; 498 - (NSArray *)webSelectionRectsForSelectionRects:(const Vector<WebCore::SelectionRect>&)selectionRects; 499 - (void)_accessibilityDidGetSelectionRects:(NSArray *)selectionRects withGranularity:(UITextGranularity)granularity atOffset:(NSInteger)offset; 498 500 @end 499 501 … … 1497 1499 } 1498 1500 1499 - (NSArray *)webSelectionRects 1500 { 1501 if (_page->editorState().selectionIsNone) 1502 return nil; 1503 const auto& selectionRects = _page->editorState().postLayoutData().selectionRects; 1501 - (NSArray *)webSelectionRectsForSelectionRects:(const Vector<WebCore::SelectionRect>&)selectionRects 1502 { 1504 1503 unsigned size = selectionRects.size(); 1505 1504 if (!size) … … 1523 1522 1524 1523 return webRects; 1524 } 1525 1526 - (NSArray *)webSelectionRects 1527 { 1528 if (_page->editorState().selectionIsNone) 1529 return nil; 1530 const auto& selectionRects = _page->editorState().postLayoutData().selectionRects; 1531 return [self webSelectionRectsForSelectionRects:selectionRects]; 1525 1532 } 1526 1533 … … 2195 2202 if ([view respondsToSelector:@selector(accessibilitySpeakSelectionSetContent:)]) 2196 2203 [view accessibilitySpeakSelectionSetContent:string]; 2204 }); 2205 } 2206 2207 - (void)_accessibilityRetrieveRectsEnclosingSelectionOffset:(NSInteger)offset withGranularity:(UITextGranularity)granularity 2208 { 2209 RetainPtr<WKContentView> view = self; 2210 _page->requestRectsForGranularityWithSelectionOffset(toWKTextGranularity(granularity), offset , [view, offset, granularity](const Vector<WebCore::SelectionRect>& selectionRects, CallbackBase::Error error) { 2211 if (error != WebKit::CallbackBase::Error::None) 2212 return; 2213 if ([view respondsToSelector:@selector(_accessibilityDidGetSelectionRects:withGranularity:atOffset:)]) 2214 [view _accessibilityDidGetSelectionRects:[view webSelectionRectsForSelectionRects:selectionRects] withGranularity:granularity atOffset:offset]; 2215 }); 2216 } 2217 2218 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text 2219 { 2220 RetainPtr<WKContentView> view = self; 2221 _page->requestRectsAtSelectionOffsetWithText(offset, text, [view, offset](const Vector<WebCore::SelectionRect>& selectionRects, CallbackBase::Error error) { 2222 if (error != WebKit::CallbackBase::Error::None) 2223 return; 2224 if ([view respondsToSelector:@selector(_accessibilityDidGetSelectionRects:withGranularity:atOffset:)]) 2225 [view _accessibilityDidGetSelectionRects:[view webSelectionRectsForSelectionRects:selectionRects] withGranularity:UITextGranularityWord atOffset:offset]; 2197 2226 }); 2198 2227 } -
trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm
r211199 r211356 187 187 } 188 188 189 void WebPageProxy::selectionRectsCallback(const Vector<WebCore::SelectionRect>& selectionRects, uint64_t callbackID) 190 { 191 auto callback = m_callbacks.take<SelectionRectsCallback>(callbackID); 192 if (!callback) { 193 ASSERT_NOT_REACHED(); 194 return; 195 } 196 197 callback->performCallbackWithReturnValue(selectionRects); 198 } 199 189 200 void WebPageProxy::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdate) 190 201 { … … 723 734 } 724 735 736 void WebPageProxy::requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity granularity, uint32_t offset, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)> callbackFunction) 737 { 738 if (!isValid()) { 739 callbackFunction(Vector<WebCore::SelectionRect>(), CallbackBase::Error::Unknown); 740 return; 741 } 742 743 uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); 744 m_process->send(Messages::WebPage::GetRectsForGranularityWithSelectionOffset(static_cast<uint32_t>(granularity), offset, callbackID), m_pageID); 745 } 746 747 void WebPageProxy::requestRectsAtSelectionOffsetWithText(int32_t offset, const String& text, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)> callbackFunction) 748 { 749 if (!isValid()) { 750 callbackFunction(Vector<WebCore::SelectionRect>(), CallbackBase::Error::Unknown); 751 return; 752 } 753 754 uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); 755 m_process->send(Messages::WebPage::GetRectsAtSelectionOffsetWithText(offset, text, callbackID), m_pageID); 756 } 757 725 758 void WebPageProxy::moveSelectionByOffset(int32_t offset, std::function<void (CallbackBase::Error)> callbackFunction) 726 759 { -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h
r211312 r211356 578 578 void getSelectionContext(uint64_t callbackID); 579 579 void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID); 580 void getRectsForGranularityWithSelectionOffset(uint32_t, int32_t, uint64_t callbackID); 581 void getRectsAtSelectionOffsetWithText(int32_t, const String&, uint64_t callbackID); 580 582 #if ENABLE(IOS_TOUCH_EVENTS) 581 583 void dispatchAsynchronousTouchEvents(const Vector<WebTouchEvent, 1>& queue); -
trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
r211221 r211356 97 97 HandleTwoFingerTapAtPoint(WebCore::IntPoint point, uint64_t requestID) 98 98 SetForceAlwaysUserScalable(bool userScalable) 99 GetRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, uint64_t callbackID); 100 GetRectsAtSelectionOffsetWithText(int32_t offset, String text, uint64_t callbackID); 99 101 #endif 100 102 -
trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
r211343 r211356 106 106 #import <WebCore/WKContentObservation.h> 107 107 #import <WebCore/WebEvent.h> 108 #import <WebCore/htmlediting.h> 108 109 #import <wtf/MathExtras.h> 109 110 #import <wtf/SetForScope.h> … … 1818 1819 frame.selection().setSelectedRange(Range::create(*frame.document(), position, position).ptr(), position.affinity(), true); 1819 1820 send(Messages::WebPageProxy::VoidCallback(callbackID)); 1821 } 1822 1823 static VisiblePosition visiblePositionForPositionWithOffset(const VisiblePosition& position, int32_t offset) 1824 { 1825 RefPtr<ContainerNode> root; 1826 unsigned startIndex = indexForVisiblePosition(position, root); 1827 return visiblePositionForIndex(startIndex + offset, root.get()); 1828 } 1829 1830 void WebPage::getRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, uint64_t callbackID) 1831 { 1832 Frame& frame = m_page->focusController().focusedOrMainFrame(); 1833 VisibleSelection selection = frame.selection().selection(); 1834 VisiblePosition selectionStart = selection.visibleStart(); 1835 1836 if (selectionStart.isNull()) { 1837 send(Messages::WebPageProxy::SelectionRectsCallback({ }, callbackID)); 1838 return; 1839 } 1840 1841 auto position = visiblePositionForPositionWithOffset(selectionStart, offset); 1842 SelectionDirection direction = offset < 0 ? DirectionBackward : DirectionForward; 1843 1844 auto range = enclosingTextUnitOfGranularity(position, static_cast<WebCore::TextGranularity>(granularity), direction); 1845 if (!range || range->collapsed()) { 1846 send(Messages::WebPageProxy::SelectionRectsCallback({ }, callbackID)); 1847 return; 1848 } 1849 1850 Vector<WebCore::SelectionRect> selectionRects; 1851 range->collectSelectionRectsWithoutUnionInteriorLines(selectionRects); 1852 convertSelectionRectsToRootView(frame.view(), selectionRects); 1853 send(Messages::WebPageProxy::SelectionRectsCallback(selectionRects, callbackID)); 1854 } 1855 1856 static RefPtr<Range> rangeNearPositionMatchesText(const VisiblePosition& position, RefPtr<Range> originalRange, const String& matchText, RefPtr<Range> selectionRange) 1857 { 1858 auto range = Range::create(selectionRange->ownerDocument(), selectionRange->startPosition(), position.deepEquivalent().parentAnchoredEquivalent()); 1859 unsigned targetOffset = TextIterator::rangeLength(range.ptr(), true); 1860 return findClosestPlainText(*selectionRange.get(), matchText, 0, targetOffset); 1861 } 1862 1863 void WebPage::getRectsAtSelectionOffsetWithText(int32_t offset, const String& text, uint64_t callbackID) 1864 { 1865 Frame& frame = m_page->focusController().focusedOrMainFrame(); 1866 uint32_t length = text.length(); 1867 VisibleSelection selection = frame.selection().selection(); 1868 VisiblePosition selectionStart = selection.visibleStart(); 1869 VisiblePosition selectionEnd = selection.visibleEnd(); 1870 1871 if (selectionStart.isNull() || selectionEnd.isNull()) { 1872 send(Messages::WebPageProxy::SelectionRectsCallback({ }, callbackID)); 1873 return; 1874 } 1875 1876 auto startPosition = visiblePositionForPositionWithOffset(selectionStart, offset); 1877 auto endPosition = visiblePositionForPositionWithOffset(startPosition, length); 1878 auto range = Range::create(*frame.document(), startPosition, endPosition); 1879 1880 if (range->collapsed()) { 1881 send(Messages::WebPageProxy::SelectionRectsCallback({ }, callbackID)); 1882 return; 1883 } 1884 1885 String rangeText = plainTextReplacingNoBreakSpace(range.ptr(), TextIteratorDefaultBehavior, true); 1886 if (rangeText != text) { 1887 auto selectionRange = selection.toNormalizedRange(); 1888 // Try to search for a range which is the closest to the position within the selection range that matches the passed in text. 1889 if (auto wordRange = rangeNearPositionMatchesText(startPosition, range.ptr(), text, selectionRange)) { 1890 if (!wordRange->collapsed()) 1891 range = *wordRange; 1892 } 1893 } 1894 1895 Vector<WebCore::SelectionRect> selectionRects; 1896 range->collectSelectionRectsWithoutUnionInteriorLines(selectionRects); 1897 convertSelectionRectsToRootView(frame.view(), selectionRects); 1898 send(Messages::WebPageProxy::SelectionRectsCallback(selectionRects, callbackID)); 1820 1899 } 1821 1900
Note: See TracChangeset
for help on using the changeset viewer.