Changeset 249709 in webkit
- Timestamp:
- Sep 10, 2019, 3:53:59 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 12 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/editing/selection/ios/move-by-word-with-keyboard-expected.txt (added)
-
LayoutTests/editing/selection/ios/move-by-word-with-keyboard.html (added)
-
LayoutTests/editing/selection/ios/select-non-editable-text-using-keyboard-expected.txt (modified) (1 diff)
-
LayoutTests/editing/selection/ios/select-non-editable-text-using-keyboard.html (modified) (8 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/editing/FrameSelection.cpp (modified) (22 diffs)
-
Source/WebCore/editing/FrameSelection.h (modified) (1 diff)
-
Source/WebCore/editing/TextIterator.cpp (modified) (1 diff)
-
Source/WebCore/editing/VisibleUnits.cpp (modified) (3 diffs)
-
Source/WebCore/editing/VisibleUnits.h (modified) (2 diffs)
-
Source/WebCore/platform/text/TextBoundaries.cpp (modified) (1 diff)
-
Source/WebCore/platform/text/TextBoundaries.h (modified) (1 diff)
-
Source/WebCore/platform/text/mac/TextBoundaries.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r249702 r249709 1 2019-09-10 Ryosuke Niwa <rniwa@webkit.org> 2 3 Option + arrow moves caret past whitespace on iOS 4 https://bugs.webkit.org/show_bug.cgi?id=201575 5 6 Reviewed by Wenson Hsieh. 7 8 Added a new test for moving caret by word granularity on iOS. 9 10 * editing/selection/ios/move-by-word-with-keyboard-expected.txt: Added. 11 * editing/selection/ios/move-by-word-with-keyboard.html: Added. 12 * editing/selection/ios/select-non-editable-text-using-keyboard-expected.txt: Rebaselined. 13 * editing/selection/ios/select-non-editable-text-using-keyboard.html: Updated the expected 14 selection string due to the behavior change. Also fixed a bug that some test cases were 15 not waiting for a secondary selectionchange event that happens after an extra selection 16 update with character granularity introduced in r247524. 17 1 18 2019-09-09 Chris Dumez <cdumez@apple.com> 2 19 -
trunk/LayoutTests/editing/selection/ios/select-non-editable-text-using-keyboard-expected.txt
r246817 r249709 12 12 13 13 Press Shift + Option + right arrow to select to the end of the word: 14 PASS window.getSelection().toString() is "Here's "14 PASS window.getSelection().toString() is "Here's" 15 15 16 16 Press Shift + Option + left arrow to select to the beginning of the word: -
trunk/LayoutTests/editing/selection/ios/select-non-editable-text-using-keyboard.html
r246817 r249709 50 50 debug("<br>Press Shift + Option + right arrow to select to the end of the word:"); 51 51 await UIHelper.callFunctionAndWaitForEvent(() => window.testRunner && UIHelper.keyDown("rightArrow", ["shiftKey", "altKey"]) , document, "selectionchange"); 52 shouldBeEqualToString("window.getSelection().toString()", "Here's ");52 shouldBeEqualToString("window.getSelection().toString()", "Here's"); 53 53 } 54 54 … … 80 80 } 81 81 82 async function waitForSecondaryPresentationUpdateIfNeeded() 83 { 84 // There might be a secondary selectionchange event after moving by paragraph boundary. See webkit.org/b/199851 85 if (window.testRunner) 86 await UIHelper.ensurePresentationUpdate(); 87 } 88 82 89 async function testExtendSelectionUp() 83 90 { … … 87 94 await UIHelper.callFunctionAndWaitForEvent(() => window.testRunner && UIHelper.keyDown("upArrow", ["shiftKey"]) , document, "selectionchange"); 88 95 shouldBeEqualToString("window.getSelection().toString()", "Here's to the crazy ones.\n\nT"); 96 await waitForSecondaryPresentationUpdateIfNeeded(); 89 97 } 90 98 … … 96 104 await UIHelper.callFunctionAndWaitForEvent(() => window.testRunner && UIHelper.keyDown("downArrow", ["shiftKey"]) , document, "selectionchange"); 97 105 shouldBeEqualToString("window.getSelection().toString()", "The misfits.\n\nT"); 106 await waitForSecondaryPresentationUpdateIfNeeded(); 98 107 } 99 108 … … 108 117 shouldBeEqualToString("window.getSelection().toString()", "Here's to the crazy ones."); 109 118 119 await waitForSecondaryPresentationUpdateIfNeeded(); 120 110 121 toggleOnlyShowTestContainer(); 111 122 } … … 119 130 debug("<br>Press Shift + Option + up arrow to select to the beginning of the paragraph:"); 120 131 await UIHelper.callFunctionAndWaitForEvent(() => window.testRunner && UIHelper.keyDown("upArrow", ["shiftKey", "altKey"]) , document, "selectionchange"); 132 121 133 shouldBeEqualToString("window.getSelection().toString()", "The rebels."); 134 135 await waitForSecondaryPresentationUpdateIfNeeded(); 122 136 123 137 toggleOnlyShowTestContainer(); … … 134 148 shouldBeEqualToString("window.getSelection().toString()", "Here's to the crazy ones.\n\nThe misfits.\n\nThe rebels."); 135 149 150 await waitForSecondaryPresentationUpdateIfNeeded(); 151 136 152 toggleOnlyShowTestContainer(); 137 153 } … … 146 162 await UIHelper.callFunctionAndWaitForEvent(() => window.testRunner && UIHelper.keyDown("upArrow", ["shiftKey", "ctrlKey"]) , document, "selectionchange"); 147 163 shouldBeEqualToString("window.getSelection().toString()", "Here's to the crazy ones.\n\nThe misfits."); 164 165 await waitForSecondaryPresentationUpdateIfNeeded(); 148 166 149 167 toggleOnlyShowTestContainer(); -
trunk/Source/WebCore/ChangeLog
r249702 r249709 1 2019-09-10 Ryosuke Niwa <rniwa@webkit.org> 2 3 Option + arrow moves caret past whitespace on iOS 4 https://bugs.webkit.org/show_bug.cgi?id=201575 5 6 Reviewed by Wenson Hsieh. 7 8 The bug was caused by findNextWordFromIndex on iOS behaving differently from macOS and UIKit by skipping 9 trailing whitespace after a word when moving forward and not skipping leading whitespace when moving backward. 10 11 This patch introduces a new mode (StopAfterWord) of findNextWordFromIndex in iOS that better matches 12 the behavior of findNextWordFromIndex on macOS and UIKit, and use it in various modify* functions of 13 FrameSelection when the selection update is triggered by user. 14 15 The legacy mode (LegacyStopBeforeWord) is used in all other call sites as well as when modify* functions 16 are invoked from author scripts. 17 18 Test: editing/selection/ios/move-by-word-with-keyboard.html 19 20 * editing/FrameSelection.cpp: 21 (WebCore::nextWordWhitespaceModeInIOS): Added. A helper to convert EUserTriggered to NextWordModeInIOS. 22 (WebCore::FrameSelection::nextWordPositionForPlatform): 23 (WebCore::FrameSelection::modifyExtendingRight): 24 (WebCore::FrameSelection::modifyExtendingForward): 25 (WebCore::FrameSelection::modifyMovingRight): 26 (WebCore::FrameSelection::modifyMovingForward): 27 (WebCore::FrameSelection::modifyExtendingLeft): 28 (WebCore::FrameSelection::modifyExtendingBackward): 29 (WebCore::FrameSelection::modifyMovingLeft): 30 (WebCore::FrameSelection::modifyMovingBackward): 31 (WebCore::FrameSelection::modify): 32 (WebCore::FrameSelection::updateAppearance): 33 * editing/FrameSelection.h: 34 * editing/TextIterator.cpp: 35 (WebCore::SearchBuffer::isWordStartMatch const): 36 * editing/VisibleUnits.cpp: 37 (WebCore::previousWordPositionBoundary): 38 (WebCore::previousWordPosition): 39 (WebCore::nextWordPositionBoundary): 40 (WebCore::nextWordPosition): 41 * editing/VisibleUnits.h: 42 * platform/text/TextBoundaries.cpp: 43 (WebCore::findNextWordFromIndex): 44 * platform/text/TextBoundaries.h: 45 * platform/text/mac/TextBoundaries.mm: 46 (WebCore::findNextWordFromIndex): Added a new mode. 47 1 48 2019-09-09 Chris Dumez <cdumez@apple.com> 2 49 -
trunk/Source/WebCore/editing/FrameSelection.cpp
r247398 r249709 712 712 } 713 713 714 VisiblePosition FrameSelection::nextWordPositionForPlatform(const VisiblePosition &originalPosition) 715 { 716 VisiblePosition positionAfterCurrentWord = nextWordPosition(originalPosition); 714 static NextWordModeInIOS nextWordWhitespaceModeInIOS(EUserTriggered userTriggered) 715 { 716 return userTriggered == UserTriggered ? NextWordModeInIOS::StopAfterWord : NextWordModeInIOS::LegacyStopBeforeWord; 717 } 718 719 VisiblePosition FrameSelection::nextWordPositionForPlatform(const VisiblePosition &originalPosition, EUserTriggered userTriggered) 720 { 721 VisiblePosition positionAfterCurrentWord = nextWordPosition(originalPosition, nextWordWhitespaceModeInIOS(userTriggered)); 717 722 718 723 if (m_frame && m_frame->editor().behavior().shouldSkipSpaceWhenMovingRight()) { … … 721 726 // semantics of previousWordPosition() this will put us at the 722 727 // beginning of the word following. 723 VisiblePosition positionAfterSpacingAndFollowingWord = nextWordPosition(positionAfterCurrentWord); 728 auto whitespaceMode = nextWordWhitespaceModeInIOS(userTriggered); 729 VisiblePosition positionAfterSpacingAndFollowingWord = nextWordPosition(positionAfterCurrentWord, whitespaceMode); 724 730 if (positionAfterSpacingAndFollowingWord != positionAfterCurrentWord) 725 positionAfterCurrentWord = previousWordPosition(positionAfterSpacingAndFollowingWord );726 727 bool movingBackwardsMovedPositionToStartOfCurrentWord = positionAfterCurrentWord == previousWordPosition(nextWordPosition(originalPosition ));731 positionAfterCurrentWord = previousWordPosition(positionAfterSpacingAndFollowingWord, whitespaceMode); 732 733 bool movingBackwardsMovedPositionToStartOfCurrentWord = positionAfterCurrentWord == previousWordPosition(nextWordPosition(originalPosition, whitespaceMode), whitespaceMode); 728 734 if (movingBackwardsMovedPositionToStartOfCurrentWord) 729 735 positionAfterCurrentWord = positionAfterSpacingAndFollowingWord; … … 740 746 #endif 741 747 742 VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity )748 VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity, EUserTriggered userTriggered) 743 749 { 744 750 VisiblePosition pos(m_selection.extent(), m_selection.affinity()); … … 758 764 case WordGranularity: 759 765 if (directionOfEnclosingBlock() == TextDirection::LTR) 760 pos = nextWordPositionForPlatform(pos );766 pos = nextWordPositionForPlatform(pos, userTriggered); 761 767 else 762 pos = previousWordPosition(pos );768 pos = previousWordPosition(pos, nextWordWhitespaceModeInIOS(userTriggered)); 763 769 break; 764 770 case LineBoundary: 765 771 if (directionOfEnclosingBlock() == TextDirection::LTR) 766 pos = modifyExtendingForward(granularity );772 pos = modifyExtendingForward(granularity, userTriggered); 767 773 else 768 pos = modifyExtendingBackward(granularity );774 pos = modifyExtendingBackward(granularity, userTriggered); 769 775 break; 770 776 case SentenceGranularity: … … 775 781 case DocumentBoundary: 776 782 // FIXME: implement all of the above? 777 pos = modifyExtendingForward(granularity );783 pos = modifyExtendingForward(granularity, userTriggered); 778 784 break; 779 785 case DocumentGranularity: … … 787 793 } 788 794 789 VisiblePosition FrameSelection::modifyExtendingForward(TextGranularity granularity )795 VisiblePosition FrameSelection::modifyExtendingForward(TextGranularity granularity, EUserTriggered userTriggered) 790 796 { 791 797 VisiblePosition pos(m_selection.extent(), m_selection.affinity()); … … 795 801 break; 796 802 case WordGranularity: 797 pos = nextWordPositionForPlatform(pos );803 pos = nextWordPositionForPlatform(pos, userTriggered); 798 804 break; 799 805 case SentenceGranularity: … … 832 838 } 833 839 834 VisiblePosition FrameSelection::modifyMovingRight(TextGranularity granularity, bool* reachedBoundary)840 VisiblePosition FrameSelection::modifyMovingRight(TextGranularity granularity, EUserTriggered userTriggered, bool* reachedBoundary) 835 841 { 836 842 if (reachedBoundary) … … 862 868 case DocumentBoundary: 863 869 // FIXME: Implement all of the above. 864 pos = modifyMovingForward(granularity, reachedBoundary);870 pos = modifyMovingForward(granularity, userTriggered, reachedBoundary); 865 871 break; 866 872 case LineBoundary: … … 874 880 } 875 881 876 VisiblePosition FrameSelection::modifyMovingForward(TextGranularity granularity, bool* reachedBoundary)882 VisiblePosition FrameSelection::modifyMovingForward(TextGranularity granularity, EUserTriggered userTriggered, bool* reachedBoundary) 877 883 { 878 884 if (reachedBoundary) … … 904 910 break; 905 911 case WordGranularity: 906 pos = nextWordPositionForPlatform(currentPosition );912 pos = nextWordPositionForPlatform(currentPosition, userTriggered); 907 913 break; 908 914 case SentenceGranularity: … … 957 963 } 958 964 959 VisiblePosition FrameSelection::modifyExtendingLeft(TextGranularity granularity )965 VisiblePosition FrameSelection::modifyExtendingLeft(TextGranularity granularity, EUserTriggered userTriggered) 960 966 { 961 967 VisiblePosition pos(m_selection.extent(), m_selection.affinity()); … … 975 981 case WordGranularity: 976 982 if (directionOfEnclosingBlock() == TextDirection::LTR) 977 pos = previousWordPosition(pos );983 pos = previousWordPosition(pos, nextWordWhitespaceModeInIOS(userTriggered)); 978 984 else 979 pos = nextWordPositionForPlatform(pos );985 pos = nextWordPositionForPlatform(pos, userTriggered); 980 986 break; 981 987 case LineBoundary: 982 988 if (directionOfEnclosingBlock() == TextDirection::LTR) 983 pos = modifyExtendingBackward(granularity );989 pos = modifyExtendingBackward(granularity, userTriggered); 984 990 else 985 pos = modifyExtendingForward(granularity );991 pos = modifyExtendingForward(granularity, userTriggered); 986 992 break; 987 993 case SentenceGranularity: … … 991 997 case ParagraphBoundary: 992 998 case DocumentBoundary: 993 pos = modifyExtendingBackward(granularity );999 pos = modifyExtendingBackward(granularity, userTriggered); 994 1000 break; 995 1001 case DocumentGranularity: … … 1003 1009 } 1004 1010 1005 VisiblePosition FrameSelection::modifyExtendingBackward(TextGranularity granularity )1011 VisiblePosition FrameSelection::modifyExtendingBackward(TextGranularity granularity, EUserTriggered userTriggered) 1006 1012 { 1007 1013 VisiblePosition pos(m_selection.extent(), m_selection.affinity()); … … 1016 1022 break; 1017 1023 case WordGranularity: 1018 pos = previousWordPosition(pos );1024 pos = previousWordPosition(pos, nextWordWhitespaceModeInIOS(userTriggered)); 1019 1025 break; 1020 1026 case SentenceGranularity: … … 1053 1059 } 1054 1060 1055 VisiblePosition FrameSelection::modifyMovingLeft(TextGranularity granularity, bool* reachedBoundary)1061 VisiblePosition FrameSelection::modifyMovingLeft(TextGranularity granularity, EUserTriggered userTriggered, bool* reachedBoundary) 1056 1062 { 1057 1063 if (reachedBoundary) … … 1083 1089 case DocumentBoundary: 1084 1090 // FIXME: Implement all of the above. 1085 pos = modifyMovingBackward(granularity, reachedBoundary);1091 pos = modifyMovingBackward(granularity, userTriggered, reachedBoundary); 1086 1092 break; 1087 1093 case LineBoundary: … … 1095 1101 } 1096 1102 1097 VisiblePosition FrameSelection::modifyMovingBackward(TextGranularity granularity, bool* reachedBoundary)1103 VisiblePosition FrameSelection::modifyMovingBackward(TextGranularity granularity, EUserTriggered userTriggered, bool* reachedBoundary) 1098 1104 { 1099 1105 if (reachedBoundary) … … 1124 1130 break; 1125 1131 case WordGranularity: 1126 pos = previousWordPosition(currentPosition );1132 pos = previousWordPosition(currentPosition, nextWordWhitespaceModeInIOS(userTriggered)); 1127 1133 break; 1128 1134 case SentenceGranularity: … … 1331 1337 case DirectionRight: 1332 1338 if (alter == AlterationMove) 1333 position = modifyMovingRight(granularity, &reachedBoundary);1339 position = modifyMovingRight(granularity, userTriggered, &reachedBoundary); 1334 1340 else 1335 position = modifyExtendingRight(granularity );1341 position = modifyExtendingRight(granularity, userTriggered); 1336 1342 break; 1337 1343 case DirectionForward: 1338 1344 if (alter == AlterationExtend) 1339 position = modifyExtendingForward(granularity );1345 position = modifyExtendingForward(granularity, userTriggered); 1340 1346 else 1341 position = modifyMovingForward(granularity, &reachedBoundary);1347 position = modifyMovingForward(granularity, userTriggered, &reachedBoundary); 1342 1348 break; 1343 1349 case DirectionLeft: 1344 1350 if (alter == AlterationMove) 1345 position = modifyMovingLeft(granularity, &reachedBoundary);1351 position = modifyMovingLeft(granularity, userTriggered, &reachedBoundary); 1346 1352 else 1347 position = modifyExtendingLeft(granularity );1353 position = modifyExtendingLeft(granularity, userTriggered); 1348 1354 break; 1349 1355 case DirectionBackward: 1350 1356 if (alter == AlterationExtend) 1351 position = modifyExtendingBackward(granularity );1357 position = modifyExtendingBackward(granularity, userTriggered); 1352 1358 else 1353 position = modifyMovingBackward(granularity, &reachedBoundary);1359 position = modifyMovingBackward(granularity, userTriggered, &reachedBoundary); 1354 1360 break; 1355 1361 } … … 2146 2152 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69563> and <rdar://problem/10232866>. 2147 2153 #if ENABLE(TEXT_CARET) 2148 VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingForward(CharacterGranularity ) : oldSelection.visibleEnd();2154 VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingForward(CharacterGranularity, NotUserTriggered) : oldSelection.visibleEnd(); 2149 2155 VisibleSelection selection(oldSelection.visibleStart(), endVisiblePosition); 2150 2156 #else -
trunk/Source/WebCore/editing/FrameSelection.h
r247367 r249709 300 300 VisiblePosition startForPlatform() const; 301 301 VisiblePosition endForPlatform() const; 302 VisiblePosition nextWordPositionForPlatform(const VisiblePosition& );303 304 VisiblePosition modifyExtendingRight(TextGranularity );305 VisiblePosition modifyExtendingForward(TextGranularity );306 VisiblePosition modifyMovingRight(TextGranularity, bool* reachedBoundary = nullptr);307 VisiblePosition modifyMovingForward(TextGranularity, bool* reachedBoundary = nullptr);308 VisiblePosition modifyExtendingLeft(TextGranularity );309 VisiblePosition modifyExtendingBackward(TextGranularity );310 VisiblePosition modifyMovingLeft(TextGranularity, bool* reachedBoundary = nullptr);311 VisiblePosition modifyMovingBackward(TextGranularity, bool* reachedBoundary = nullptr);302 VisiblePosition nextWordPositionForPlatform(const VisiblePosition&, EUserTriggered); 303 304 VisiblePosition modifyExtendingRight(TextGranularity, EUserTriggered); 305 VisiblePosition modifyExtendingForward(TextGranularity, EUserTriggered); 306 VisiblePosition modifyMovingRight(TextGranularity, EUserTriggered, bool* reachedBoundary = nullptr); 307 VisiblePosition modifyMovingForward(TextGranularity, EUserTriggered, bool* reachedBoundary = nullptr); 308 VisiblePosition modifyExtendingLeft(TextGranularity, EUserTriggered); 309 VisiblePosition modifyExtendingBackward(TextGranularity, EUserTriggered); 310 VisiblePosition modifyMovingLeft(TextGranularity, EUserTriggered, bool* reachedBoundary = nullptr); 311 VisiblePosition modifyMovingBackward(TextGranularity, EUserTriggered, bool* reachedBoundary = nullptr); 312 312 313 313 LayoutUnit lineDirectionPointForBlockDirectionNavigation(EPositionType); -
trunk/Source/WebCore/editing/TextIterator.cpp
r249074 r249709 2336 2336 size_t wordBreakSearchStart = start + length; 2337 2337 while (wordBreakSearchStart > start) 2338 wordBreakSearchStart = findNextWordFromIndex(StringView(m_buffer.data(), m_buffer.size()), wordBreakSearchStart, false /* backwards */);2338 wordBreakSearchStart = findNextWordFromIndex(StringView(m_buffer.data(), m_buffer.size()), wordBreakSearchStart, NextWordDirection::Backward); 2339 2339 return wordBreakSearchStart == start; 2340 2340 } -
trunk/Source/WebCore/editing/VisibleUnits.cpp
r249701 r249709 762 762 } 763 763 764 template <NextWordModeInIOS nextWordModeInIOS> 764 765 static unsigned previousWordPositionBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext) 765 766 { … … 769 770 } 770 771 needMoreContext = false; 771 return findNextWordFromIndex(text, offset, false); 772 } 773 774 VisiblePosition previousWordPosition(const VisiblePosition& position) 775 { 776 return position.honorEditingBoundaryAtOrBefore(previousBoundary(position, previousWordPositionBoundary)); 777 } 778 772 return findNextWordFromIndex(text, offset, NextWordDirection::Backward, nextWordModeInIOS); 773 } 774 775 VisiblePosition previousWordPosition(const VisiblePosition& position, NextWordModeInIOS nextWordModeInIOS) 776 { 777 if (nextWordModeInIOS == NextWordModeInIOS::LegacyStopBeforeWord) // FIXME: Remove this code path. 778 return position.honorEditingBoundaryAtOrBefore(previousBoundary(position, previousWordPositionBoundary<NextWordModeInIOS::LegacyStopBeforeWord>)); 779 return position.honorEditingBoundaryAtOrBefore(previousBoundary(position, previousWordPositionBoundary<NextWordModeInIOS::StopAfterWord>)); 780 } 781 782 template <NextWordModeInIOS nextWordModeInIOS> 779 783 static unsigned nextWordPositionBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext) 780 784 { … … 784 788 } 785 789 needMoreContext = false; 786 return findNextWordFromIndex(text, offset, true); 787 } 788 789 VisiblePosition nextWordPosition(const VisiblePosition& position) 790 { 791 return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextWordPositionBoundary)); 790 return findNextWordFromIndex(text, offset, NextWordDirection::Forward, nextWordModeInIOS); 791 } 792 793 VisiblePosition nextWordPosition(const VisiblePosition& position, NextWordModeInIOS nextWordModeInIOS) 794 { 795 if (nextWordModeInIOS == NextWordModeInIOS::LegacyStopBeforeWord) // FIXME: Remove this code path. 796 return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextWordPositionBoundary<NextWordModeInIOS::LegacyStopBeforeWord>)); 797 return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextWordPositionBoundary<NextWordModeInIOS::StopAfterWord>)); 792 798 } 793 799 -
trunk/Source/WebCore/editing/VisibleUnits.h
r243296 r249709 27 27 28 28 #include "EditingBoundary.h" 29 #include "TextBoundaries.h" 29 30 #include "VisibleSelection.h" 30 31 … … 41 42 WEBCORE_EXPORT VisiblePosition startOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary); 42 43 WEBCORE_EXPORT VisiblePosition endOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary); 43 WEBCORE_EXPORT VisiblePosition previousWordPosition(const VisiblePosition &);44 WEBCORE_EXPORT VisiblePosition nextWordPosition(const VisiblePosition &);44 WEBCORE_EXPORT VisiblePosition previousWordPosition(const VisiblePosition&, NextWordModeInIOS = NextWordModeInIOS::LegacyStopBeforeWord); 45 WEBCORE_EXPORT VisiblePosition nextWordPosition(const VisiblePosition&, NextWordModeInIOS = NextWordModeInIOS::LegacyStopBeforeWord); 45 46 VisiblePosition rightWordPosition(const VisiblePosition&, bool skipsSpaceWhenMovingRight); 46 47 VisiblePosition leftWordPosition(const VisiblePosition&, bool skipsSpaceWhenMovingRight); -
trunk/Source/WebCore/platform/text/TextBoundaries.cpp
r209907 r249709 62 62 #if !PLATFORM(COCOA) 63 63 64 int findNextWordFromIndex(StringView text, int position, bool forward)64 int findNextWordFromIndex(StringView text, int position, NextWordDirection direction, NextWordModeInIOS) 65 65 { 66 66 UBreakIterator* it = wordBreakIterator(text); 67 67 68 if ( forward) {68 if (direction == NextWordDirection::Forward) { 69 69 position = ubrk_following(it, position); 70 70 while (position != UBRK_DONE) { -
trunk/Source/WebCore/platform/text/TextBoundaries.h
r165676 r249709 48 48 void findWordBoundary(StringView, int position, int* start, int* end); 49 49 void findEndWordBoundary(StringView, int position, int* end); 50 int findNextWordFromIndex(StringView, int position, bool forward); 50 51 enum class NextWordDirection : bool { Forward, Backward }; 52 enum class NextWordModeInIOS : bool { LegacyStopBeforeWord, StopAfterWord }; 53 int findNextWordFromIndex(StringView, int position, NextWordDirection, NextWordModeInIOS = NextWordModeInIOS::LegacyStopBeforeWord); 51 54 52 55 } -
trunk/Source/WebCore/platform/text/mac/TextBoundaries.mm
r227552 r249709 230 230 } 231 231 232 int findNextWordFromIndex(StringView text, int position, bool forward)232 int findNextWordFromIndex(StringView text, int position, NextWordDirection direction, NextWordModeInIOS whitespaceModeInIOS) 233 233 { 234 234 #if USE(APPKIT) 235 UNUSED_PARAM(whitespaceModeInIOS); 235 236 NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text.createNSStringWithoutCopying().get()]; 236 int result = [attributedString nextWordFromIndex:position forward: forward];237 int result = [attributedString nextWordFromIndex:position forward:direction == NextWordDirection::Forward]; 237 238 [attributedString release]; 238 239 return result; … … 244 245 UBreakIterator* boundary = wordBreakIterator(text); 245 246 if (boundary) { 246 if (forward) { 247 if (direction == NextWordDirection::Forward) { 248 if (whitespaceModeInIOS == NextWordModeInIOS::StopAfterWord) { 249 while (static_cast<unsigned>(pos) < text.length() && isWordDelimitingCharacter(text[pos])) { 250 pos = ubrk_following(boundary, pos); 251 if (pos == UBRK_DONE) 252 return text.length(); 253 } 254 } 247 255 do { 248 256 pos = ubrk_following(boundary, pos); 249 257 if (pos == UBRK_DONE) 250 pos =text.length();258 return text.length(); 251 259 } while (static_cast<unsigned>(pos) < text.length() && (pos == 0 || !isSkipCharacter(text[pos - 1])) && isSkipCharacter(text[pos])); 260 261 // ICU would skip the trailing whitespace. Go back. 262 if (whitespaceModeInIOS == NextWordModeInIOS::StopAfterWord && isWordDelimitingCharacter(text[pos - 1])) 263 pos = ubrk_preceding(boundary, pos); 252 264 } 253 265 else { 266 if (whitespaceModeInIOS == NextWordModeInIOS::StopAfterWord && pos && isWordDelimitingCharacter(text[pos - 1])) { 267 pos = ubrk_preceding(boundary, pos); 268 if (pos == UBRK_DONE) 269 return 0; 270 } 271 254 272 do { 255 273 pos = ubrk_preceding(boundary, pos);
Note:
See TracChangeset
for help on using the changeset viewer.