Changeset 82588 in webkit
- Timestamp:
- Mar 31, 2011 9:17:25 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r82579 r82588 1 2011-03-30 Xiaomei Ji <xji@chromium.org> 2 3 Reviewed by Ryosuke Niwa. 4 5 Experiment with moving caret by word in visual order. 6 https://bugs.webkit.org/show_bug.cgi?id=57336 7 8 * editing/selection/move-by-word-visually-expected.txt: Added. 9 * editing/selection/move-by-word-visually.html: Added. 10 1 11 2011-03-31 Pavel Podivilov <podivilov@chromium.org> 2 12 -
trunk/Source/WebCore/ChangeLog
r82584 r82588 1 2011-03-30 Xiaomei Ji <xji@chromium.org> 2 3 Reviewed by Ryosuke Niwa. 4 5 Experiment with moving caret by word in visual order. 6 https://bugs.webkit.org/show_bug.cgi?id=57336 7 8 Follow Firefox's convention in Windows, 9 In LTR block, word break visually moves cursor to the left boundary of words, 10 In RTL block, word break visually moves cursor to the right boundary of words. 11 12 This is the 1st version of implementing "move caret by word in visual order". 13 It only works in the following situation: 14 1. For a LTR box in a LTR block or a RTL box in RTL block, 15 when caret is at the left boundary of the box and we are looking for 16 the word boundary in right. 17 2. For a LTR or RTL box in a LTR block, when caret is at the left boundary 18 of the box and we are looking for the word boundary in left and 19 previous box is a LTR box. 20 3. For a LTR or RTL box in a RTL block, when the caret is at the right 21 boundary of the box and we are looking for the word boundary in right and next box is RTL box. 22 23 An experimental granularity is introduced, as a side effect, functions having switch statements 24 to handle those granularities have to add more one case to handle this new granularity. 25 The experimental granularity is exposed though JS by '-webkit-visual-word". 26 27 The overall algorithm is looping through inline boxes visually and looking 28 for the visually nearest word break position. 29 30 Test: editing/selection/move-by-word-visually.html 31 32 * editing/SelectionController.cpp: 33 (WebCore::SelectionController::modifyExtendingRight): 34 (WebCore::SelectionController::modifyExtendingForward): 35 (WebCore::SelectionController::modifyMovingRight): 36 (WebCore::SelectionController::modifyMovingForward): 37 (WebCore::SelectionController::modifyExtendingLeft): 38 (WebCore::SelectionController::modifyExtendingBackward): 39 (WebCore::SelectionController::modifyMovingLeft): 40 (WebCore::SelectionController::modifyMovingBackward): 41 * editing/TextGranularity.h: 42 * editing/VisibleSelection.cpp: 43 (WebCore::VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity): 44 * editing/visible_units.cpp: 45 (WebCore::previousWordBreakInBoxInsideBlockWithSameDirectionality): 46 (WebCore::wordBoundaryInBox): 47 (WebCore::wordBoundaryInAdjacentBoxes): 48 (WebCore::leftWordBoundary): 49 (WebCore::rightWordBoundary): 50 (WebCore::leftWordPosition): 51 (WebCore::rightWordPosition): 52 * editing/visible_units.h: 53 * page/DOMSelection.cpp: 54 (WebCore::DOMSelection::modify): 55 1 56 2011-03-31 Dimitri Glazkov <dglazkov@chromium.org> 2 57 -
trunk/Source/WebCore/editing/SelectionController.cpp
r82121 r82588 448 448 // FIXME: implement all of the above? 449 449 pos = modifyExtendingForward(granularity); 450 break; 451 case WebKitVisualWordGranularity: 452 break; 450 453 } 451 454 return pos; … … 486 489 else 487 490 pos = endOfDocument(pos); 491 break; 492 case WebKitVisualWordGranularity: 488 493 break; 489 494 } … … 518 523 pos = rightBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock()); 519 524 break; 525 case WebKitVisualWordGranularity: 526 pos = rightWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity())); 527 break; 520 528 } 521 529 return pos; … … 565 573 else 566 574 pos = endOfDocument(pos); 575 break; 576 case WebKitVisualWordGranularity: 567 577 break; 568 578 } … … 605 615 case DocumentBoundary: 606 616 pos = modifyExtendingBackward(granularity); 617 break; 618 case WebKitVisualWordGranularity: 619 break; 607 620 } 608 621 return pos; … … 648 661 else 649 662 pos = startOfDocument(pos); 663 break; 664 case WebKitVisualWordGranularity: 650 665 break; 651 666 } … … 667 682 break; 668 683 case WordGranularity: 684 pos = leftWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity())); 685 break; 669 686 case SentenceGranularity: 670 687 case LineGranularity: … … 679 696 pos = leftBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock()); 680 697 break; 698 case WebKitVisualWordGranularity: 699 pos = leftWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity())); 700 break; 681 701 } 682 702 return pos; … … 720 740 else 721 741 pos = startOfDocument(pos); 742 break; 743 case WebKitVisualWordGranularity: 722 744 break; 723 745 } -
trunk/Source/WebCore/editing/TextGranularity.h
r18874 r82588 40 40 LineBoundary, 41 41 ParagraphBoundary, 42 DocumentBoundary 42 DocumentBoundary, 43 // FIXME: this is added temporarily for experiment with visually move 44 // caret by wordGranularity. Once all patches are landed, it should be removed. 45 WebKitVisualWordGranularity 43 46 }; 44 47 -
trunk/Source/WebCore/editing/VisibleSelection.cpp
r81518 r82588 381 381 m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent(); 382 382 break; 383 case WebKitVisualWordGranularity: 384 break; 383 385 } 384 386 -
trunk/Source/WebCore/editing/visible_units.cpp
r82447 r82588 38 38 #include "TextIterator.h" 39 39 #include "VisiblePosition.h" 40 #include "VisibleSelection.h" 40 41 #include "htmlediting.h" 41 42 #include <wtf/unicode/Unicode.h> … … 1147 1148 } 1148 1149 1149 } 1150 static const int invalidOffset = -1; 1151 1152 static VisiblePosition previousWordBreakInBoxInsideBlockWithSameDirectionality(const InlineBox* box, const VisiblePosition& previousWordBreak, int& offsetOfWordBreak) 1153 { 1154 bool hasSeenWordBreakInThisBox = previousWordBreak.isNotNull(); 1155 // In a LTR block, the word break should be on the left boundary of a word. 1156 // In a RTL block, the word break should be on the right boundary of a word. 1157 // Because nextWordPosition() returns the word break on the right boundary of the word for LTR text, 1158 // we need to use previousWordPosition() to traverse words within the inline boxes from right to left 1159 // to find the previous word break (i.e. the first word break on the left). The same applies to RTL text. 1160 1161 VisiblePosition wordBreak = hasSeenWordBreakInThisBox ? previousWordBreak : Position(box->renderer()->node(), box->caretMaxOffset(), Position::PositionIsOffsetInAnchor); 1162 1163 // FIXME: handle multi-spaces (http://webkit.org/b/57543). 1164 1165 wordBreak = previousWordPosition(wordBreak); 1166 if (previousWordBreak == wordBreak) 1167 return VisiblePosition(); 1168 1169 InlineBox* boxContainingPreviousWordBreak; 1170 wordBreak.getInlineBoxAndOffset(boxContainingPreviousWordBreak, offsetOfWordBreak); 1171 if (boxContainingPreviousWordBreak != box) 1172 return VisiblePosition(); 1173 return wordBreak; 1174 } 1175 1176 static VisiblePosition previousWordBreakInBox(const InlineBox* box, int offset, TextDirection blockDirection) 1177 { 1178 int offsetOfWordBreak = 0; 1179 VisiblePosition wordBreak; 1180 while (true) { 1181 if (box->direction() == blockDirection) 1182 wordBreak = previousWordBreakInBoxInsideBlockWithSameDirectionality(box, wordBreak, offsetOfWordBreak); 1183 // FIXME: Implement the 'else' case when the box direction is not equal to the block direction. 1184 if (wordBreak.isNull()) 1185 break; 1186 if (offset == invalidOffset || offsetOfWordBreak != offset) 1187 return wordBreak; 1188 } 1189 return VisiblePosition(); 1190 } 1191 1192 static VisiblePosition leftWordBoundary(const InlineBox* box, int offset, TextDirection blockDirection) 1193 { 1194 VisiblePosition wordBreak; 1195 for (const InlineBox* adjacentBox = box; adjacentBox; adjacentBox = adjacentBox->prevLeafChild()) { 1196 if (blockDirection == LTR) 1197 wordBreak = previousWordBreakInBox(adjacentBox, adjacentBox == box ? offset : invalidOffset, blockDirection); 1198 // FIXME: Implement the "else" case. 1199 if (wordBreak.isNotNull()) 1200 return wordBreak; 1201 } 1202 return VisiblePosition(); 1203 } 1204 1205 static VisiblePosition rightWordBoundary(const InlineBox* box, int offset, TextDirection blockDirection) 1206 { 1207 1208 VisiblePosition wordBreak; 1209 for (const InlineBox* adjacentBox = box; adjacentBox; adjacentBox = adjacentBox->nextLeafChild()) { 1210 if (blockDirection == RTL) 1211 wordBreak = previousWordBreakInBox(adjacentBox, adjacentBox == box ? offset : invalidOffset, blockDirection); 1212 // FIXME: Implement the "else" case. 1213 if (!wordBreak.isNull()) 1214 return wordBreak; 1215 } 1216 return VisiblePosition(); 1217 } 1218 1219 VisiblePosition leftWordPosition(const VisiblePosition& visiblePosition) 1220 { 1221 InlineBox* box; 1222 int offset; 1223 visiblePosition.getInlineBoxAndOffset(box, offset); 1224 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition.deepEquivalent()); 1225 1226 // FIXME: If the box's directionality is the same as that of the enclosing block, when the offset is at the box boundary 1227 // and the direction is towards inside the box, do I still need to make it a special case? For example, a LTR box inside a LTR block, 1228 // when offset is at box's caretMinOffset and the direction is DirectionRight, should it be taken care as a general case? 1229 if (offset == box->caretLeftmostOffset()) 1230 return leftWordBoundary(box->prevLeafChild(), invalidOffset, blockDirection); 1231 if (offset == box->caretRightmostOffset()) 1232 return leftWordBoundary(box, offset, blockDirection); 1233 1234 // FIXME: Not implemented. 1235 return VisiblePosition(); 1236 } 1237 1238 VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition) 1239 { 1240 InlineBox* box; 1241 int offset; 1242 visiblePosition.getInlineBoxAndOffset(box, offset); 1243 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition.deepEquivalent()); 1244 1245 if (offset == box->caretLeftmostOffset()) 1246 return rightWordBoundary(box, offset, blockDirection); 1247 if (offset == box->caretRightmostOffset()) 1248 return rightWordBoundary(box->nextLeafChild(), -1, blockDirection); 1249 1250 // FIXME: Not implemented. 1251 return VisiblePosition(); 1252 } 1253 1254 } -
trunk/Source/WebCore/editing/visible_units.h
r82447 r82588 43 43 VisiblePosition previousWordPosition(const VisiblePosition &); 44 44 VisiblePosition nextWordPosition(const VisiblePosition &); 45 VisiblePosition rightWordPosition(const VisiblePosition&); 46 VisiblePosition leftWordPosition(const VisiblePosition&); 45 47 46 48 // sentences -
trunk/Source/WebCore/page/DOMSelection.cpp
r80604 r82588 333 333 else if (equalIgnoringCase(granularityString, "documentboundary")) 334 334 granularity = DocumentBoundary; 335 else if (equalIgnoringCase(granularityString, "-webkit-visual-word")) 336 granularity = WebKitVisualWordGranularity; 335 337 else 336 338 return;
Note: See TracChangeset
for help on using the changeset viewer.