Changeset 43032 in webkit
- Timestamp:
- Apr 29, 2009, 5:48:43 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r43031 r43032 1 2009-04-29 Xiaomei Ji <xji@chromium.org> 2 3 Reviewed by Dan Bernstein. 4 5 Fix https://bugs.webkit.org/show_bug.cgi?id=24168 6 RTL: Home/End key does not behave correctly in mixed bidi text in RTL document 7 8 * editing/selection/extend-selection-expected.txt: Added result for extend in 9 lineBoundary. 10 * editing/selection/extend-selection.html: Added test cases and script for extend 11 in lineBoundary. 12 * editing/selection/home-end-expected.txt: Added. 13 * editing/selection/home-end.html: Added. 14 1 15 2009-04-29 Ojan Vafai <ojan@chromium.org> 2 16 -
trunk/LayoutTests/editing/selection/extend-selection-expected.txt
r43028 r43032 10 10 ipsum dolor sit 11 11 amett 12 Lorem ipsum dolor sit amet 13 Lorem ipsum dolor 14 just a test 15 sit amet 16 Lorem ipsum dolor sit amet 17 Lorem 18 ipsum dolor sit 19 amet 20 Just testing רק בודק 21 Just testing what ever 22 car means אבג. 23 car דהו אבג. 24 he said " car דהו אבג ." 25 זחט יךכ לםמ ' he said " car דהו אבג " '? 26 אבג abc דהו 27 edf זחט abrebg 28 abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg 29 abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg 12 30 13 31 … … 373 391 Extending left: " amett"[(0,6), (0,1)], "ipsum dolor sit"[(0,12), (0,6), (0,0)], "Lorem "[(0,0), (0,5)] 374 392 393 394 395 Extending by lineBoundary 396 Test 1, LTR: 397 Extending forward: "\nabc ABC xyz DEF def\n"[(1,1), (1,20)] 398 Extending backward: "\nabc ABC xyz DEF def\n"[(1,20), (1,1)] 399 Test 1, RTL: 400 Extending forward: "\nabc ABC xyz DEF def\n"[(1,1), (1,20)] 401 Extending backward: "\nabc ABC xyz DEF def\n"[(1,20), (1,1)] 402 Test 2, LTR: 403 Extending forward: "\nABC xyz DEF def GHI\n"[(1,1), (1,20)] 404 Extending backward: "\nABC xyz DEF def GHI\n"[(1,20), (1,1)] 405 Test 2, RTL: 406 Extending forward: "\nABC xyz DEF def GHI\n"[(1,1), (1,20)] 407 Extending backward: "\nABC xyz DEF def GHI\n"[(1,20), (1,1)] 408 Test 3, LTR: 409 Extending forward: "\nABC DEF ABC\n"[(1,1), (1,12)] 410 Extending backward: "\nABC DEF ABC\n"[(1,12), (1,1)] 411 Test 3, RTL: 412 Extending forward: "\nABC DEF ABC\n"[(1,1), (1,12)] 413 Extending backward: "\nABC DEF ABC\n"[(1,12), (1,1)] 414 Test 4, LTR: 415 Extending forward: "\nabc efd dabeb\n"[(1,1), (1,14)] 416 Extending backward: "\nabc efd dabeb\n"[(1,14), (1,1)] 417 Test 4, RTL: 418 Extending forward: "\nabc efd dabeb\n"[(1,1), (1,14)] 419 Extending backward: "\nabc efd dabeb\n"[(1,14), (1,1)] 420 Test 5, LTR: 421 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 422 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 423 Test 5, RTL: 424 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 425 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 426 Test 6, LTR: 427 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 428 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 429 Test 6, RTL: 430 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 431 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 432 Test 7, LTR: 433 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 434 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 435 Test 7, RTL: 436 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 437 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 438 Test 8, LTR: 439 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 440 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 441 Test 8, RTL: 442 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 443 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 444 Test 9, LTR: 445 Extending forward: "Lorem "[(0,0), (0,5)] 446 Extending backward: "Lorem "[(0,5), (0,0)] 447 Test 9, RTL: 448 Extending forward: "Lorem "[(0,0), (0,5)] 449 Extending backward: "Lorem "[(0,5), (0,0)] 450 Test 10, LTR: 451 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 452 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 453 Test 10, RTL: 454 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 455 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 456 Test 11, LTR: 457 Extending forward: "Lorem "[(0,0)], "ipsum dolor"[(0,11)] 458 Extending backward: "ipsum dolor"[(0,11)], "Lorem "[(0,0)] 459 Test 11, RTL: 460 Extending forward: "Lorem "[(0,0)], "ipsum dolor"[(0,11)] 461 Extending backward: "ipsum dolor"[(0,11)], "Lorem "[(0,0)] 462 Test 12, LTR: 463 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 464 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 465 Test 12, RTL: 466 Extending forward: "Lorem "[(0,0)], " amet"[(0,5)] 467 Extending backward: " amet"[(0,5)], "Lorem "[(0,0)] 468 Test 13, LTR: 469 Extending forward: "Lorem "[(0,0), (0,5)] 470 Extending backward: "Lorem "[(0,5), (0,0)] 471 Test 13, RTL: 472 Extending forward: "Lorem "[(0,0), (0,5)] 473 Extending backward: "Lorem "[(0,5), (0,0)] 474 Test 14, LTR: 475 Extending forward: "\n Just\n "[(2,2)], "\n BFDX\n"[(2,6)] 476 Extending backward: "\n BFDX\n"[(2,6)], "\n Just\n "[(2,2)] 477 Test 14, RTL: 478 Extending forward: "\n Just\n "[(2,2)], "\n BFDX\n"[(2,6)] 479 Extending backward: "\n BFDX\n"[(2,6)], "\n Just\n "[(2,2)] 480 Test 15, LTR: 481 Extending forward: "\n Just\n "[(2,2)], "\n ever\n"[(2,6)] 482 Extending backward: "\n ever\n"[(2,6)], "\n Just\n "[(2,2)] 483 Test 15, RTL: 484 Extending forward: "\n Just\n "[(2,2)], "\n ever\n"[(2,6)] 485 Extending backward: "\n ever\n"[(2,6)], "\n Just\n "[(2,2)] 486 Test 16, LTR: 487 Extending forward: "car means ABC."[(0,0), (0,14)] 488 Extending backward: "car means ABC."[(0,14), (0,0)] 489 Test 16, RTL: 490 Extending forward: "car means ABC."[(0,0), (0,14)] 491 Extending backward: "car means ABC."[(0,14), (0,0)] 492 Test 17, LTR: 493 Extending forward: "car DEF ABC."[(1,1), (1,13)] 494 Extending backward: "car DEF ABC."[(1,13), (1,1)] 495 Test 17, RTL: 496 Extending forward: "car DEF ABC."[(1,1), (1,13)] 497 Extending backward: "car DEF ABC."[(1,13), (1,1)] 498 Test 18, LTR: 499 Extending forward: "he said "car DEF ABC.""[(0,0), (0,24)] 500 Extending backward: "he said "car DEF ABC.""[(0,24), (0,0)] 501 Test 18, RTL: 502 Extending forward: "he said "car DEF ABC.""[(0,0), (0,24)] 503 Extending backward: "he said "car DEF ABC.""[(0,24), (0,0)] 504 Test 19, LTR: 505 Extending forward: "GHI JKL MNO 'he said "car DEF ABC"'?"[(0,0), (0,40)] 506 Extending backward: "GHI JKL MNO 'he said "car DEF ABC"'?"[(0,40), (0,0)] 507 Test 19, RTL: 508 Extending forward: "GHI JKL MNO 'he said "car DEF ABC"'?"[(0,0), (0,40)] 509 Extending backward: "GHI JKL MNO 'he said "car DEF ABC"'?"[(0,40), (0,0)] 510 Test 20, LTR: 511 Extending forward: "ABC abc DEF"[(0,0), (0,11)] 512 Extending backward: "ABC abc DEF"[(0,11), (0,0)] 513 Test 20, RTL: 514 Extending forward: "ABC abc DEF"[(0,0), (0,11)] 515 Extending backward: "ABC abc DEF"[(0,11), (0,0)] 516 Test 21, LTR: 517 Extending forward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,0), (0,8), (0,16), (0,26), (0,34), (0,42), (0,50), (0,58), (0,66), (0,74), (0,82), (0,90), (0,98), (0,105)] 518 Extending backward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,105), (0,0)] 519 Test 21, RTL: 520 Extending forward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,0), (0,7)] 521 Extending backward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,7), (0,0)] 522 Test 22, LTR: 523 Extending forward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,0), (0,8), (0,16), (0,26), (0,34), (0,42), (0,50), (0,58), (0,66), (0,74), (0,82), (0,90), (0,98), (0,105)] 524 Extending backward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,105), (0,0)] 525 Test 22, RTL: 526 Extending forward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,0), (0,7)] 527 Extending backward: "abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg "[(0,7), (0,0)] 528 -
trunk/LayoutTests/editing/selection/extend-selection.html
r43028 r43032 248 248 } 249 249 250 function testExtendingLineBoundary(tests, sel) 251 { 252 for (var i = 0; i < tests.length; ++i) { 253 tests[i].style.direction = "ltr"; 254 log("Test " + (i + 1) + ", LTR:\n Extending forward: "); 255 sel.setPosition(tests[i], 0); 256 var ltrRightPos = extendingSelection(sel, "forward", "lineBoundary", 0); 257 258 log(" Extending backward: "); 259 var ltrLeftPos = extendingSelection(sel, "backward", "lineBoundary", 0); 260 261 tests[i].style.direction = "rtl"; 262 log("Test " + (i + 1) + ", RTL:\n Extending forward: "); 263 sel.setPosition(tests[i], 0); 264 var ltrRightPos = extendingSelection(sel, "forward", "lineBoundary", 0); 265 266 log(" Extending backward: "); 267 var ltrLeftPos = extendingSelection(sel, "backward", "lineBoundary", 0); 268 } 269 } 270 250 271 onload = function() 251 272 { … … 270 291 log("\n\n\n\n\nExtending by word\n"); 271 292 testExtendingSelectionForEnclosingBlock(tests, sel, "word", 1); 293 294 tests = document.getElementsByClassName("home-end-test"); 295 var sel = getSelection(); 296 log("\n\n\nExtending by lineBoundary\n"); 297 testExtendingLineBoundary(tests, sel); 272 298 } 273 299 … … 275 301 </head> 276 302 <body> 277 <div contenteditable class="test ">303 <div contenteditable class="test home-end-test"> 278 304 abc אבג xyz דהו def 279 305 </div> 280 <div contenteditable class="test ">306 <div contenteditable class="test home-end-test"> 281 307 אבג xyz דהו def זחט 282 308 </div> 283 <div contenteditable class="test ">309 <div contenteditable class="test home-end-test"> 284 310 אבג דהו אבג 285 311 </div> 286 <div contenteditable class="test ">312 <div contenteditable class="test home-end-test"> 287 313 abc efd dabeb 288 314 </div> 289 315 290 316 291 <div contenteditable class="test">Lorem <span style="direction: rtl">ipsum dolor sit</span> amet</div> 292 <div contenteditable class="test">Lorem <span dir="rtl">ipsum dolor sit</span> amet</div> 293 <div contenteditable class="test">Lorem <span style="direction: ltr">ipsum dolor sit</span> amet</div> 294 <div contenteditable class="test">Lorem <span dir="ltr">ipsum dolor sit</span> amet</div> 295 296 <div contenteditable class="testEnclosingBlock">Lorem <div dir="rtl">ipsum dolor sit</div> amett</div> 317 <div contenteditable class="test home-end-test">Lorem <span style="direction: rtl">ipsum dolor sit</span> amet</div> 318 <div contenteditable class="test home-end-test">Lorem <span dir="rtl">ipsum dolor sit</span> amet</div> 319 <div contenteditable class="test home-end-test">Lorem <span style="direction: ltr">ipsum dolor sit</span> amet</div> 320 <div contenteditable class="test home-end-test">Lorem <span dir="ltr">ipsum dolor sit</span> amet</div> 321 322 <div contenteditable class="testEnclosingBlock home-end-test">Lorem <div dir="rtl">ipsum dolor sit</div> amett</div> 323 324 <div contenteditable class="home-end-test">Lorem <span style="direction: ltr">ipsum dolor sit</span> amet</div> 325 <div contenteditable class="home-end-test">Lorem <span style="direction: ltr">ipsum dolor<div > just a test</div> sit</span> amet</div> 326 <div contenteditable class="home-end-test">Lorem <span dir="ltr">ipsum dolor sit</span> amet</div> 327 <div contenteditable class="home-end-test">Lorem <div dir="ltr">ipsum dolor sit</div> amet</div> 328 329 <div class="home-end-test" contenteditable> 330 Just 331 <span>testing רק</span> 332 בודק 333 </div> 334 335 <div class="home-end-test" contenteditable> 336 Just 337 <span>testing what</span> 338 ever 339 </div> 340 341 342 <div class="home-end-test" contenteditable>car means אבג.</div> 343 <div class="home-end-test" contenteditable>‫car דהו אבג.‬</div> 344 <div class="home-end-test" contenteditable>he said "‫car דהו אבג‬."</div> 345 <div class="home-end-test" contenteditable>זחט יךכ לםמ '‪he said "‫car דהו אבג‬"‬'?</div> 346 347 348 <div class="home-end-test" contenteditable>אבג abc דהו<br />edf זחט abrebg</div> 349 <div class="home-end-test" contenteditable style="line-break:before-white-space; width:100px">abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg </div> 350 <div class="home-end-test" contenteditable style="line-break:after-white-space; width:100px">abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg </div> 297 351 298 352 <pre id="console"></pre> -
trunk/WebCore/ChangeLog
r43028 r43032 1 2009-04-29 Xiaomei Ji <xji@chromium.org> 2 3 Reviewed by Dan Bernstein. 4 5 Fix https://bugs.webkit.org/show_bug.cgi?id=24168 6 RTL: Home/End key does not behave correctly in mixed bidi text in RTL document 7 8 Test: editing/selection/home-end.html 9 10 * editing/SelectionController.cpp: 11 (WebCore::SelectionController::modifyExtendingForward): Change calling endOfLine() 12 to logicalEndOfLine() when granularity is LineBoundary. 13 (WebCore::SelectionController::modifyMovingForward): Change calling endOfLine() 14 to logicalEndOfLine() when granularity is LineBoundary 15 (WebCore::SelectionController::modifyExtendingBackward): Change calling 16 startOfLine() to logicalStartOfLine() when granularity is LineBoundary. 17 (WebCore::SelectionController::modifyMovingBackward): Change calling startOfLine() 18 to logicalStartOfLine() when granularity is LineBoundary. 19 * editing/visible_units.cpp: 20 (WebCore::getLeafBoxesInLogicalOrder): Added. Reconstruct leaf boxes in logical order. 21 (WebCore::getLogicalStartBoxAndNode): Added. 22 (WebCore::getLogicalEndBoxAndNode): Added. 23 (WebCore::logicalStartPositionForLine): Added. Similar to startPositionForLine. 24 (WebCore::logicalStartOfLine): Added. Similar to startOfLine. 25 (WebCore::logicalEndPositionForLine): Added. Similar to endPositionForLine. 26 (WebCore::inSameLogicalLine): Added. 27 (WebCore::logicalEndOfLine): Added. Similar to endOfLine. 28 * editing/visible_units.h: 29 1 30 2009-04-29 Eric Seidel <eric@webkit.org> 2 31 -
trunk/WebCore/editing/SelectionController.cpp
r43028 r43032 322 322 break; 323 323 case LineBoundary: 324 pos = endOfLine(VisiblePosition(m_sel.end(), m_sel.affinity()));324 pos = logicalEndOfLine(VisiblePosition(m_sel.end(), m_sel.affinity())); 325 325 break; 326 326 case ParagraphBoundary: … … 396 396 break; 397 397 case LineBoundary: 398 pos = endOfLine(VisiblePosition(m_sel.end(), m_sel.affinity()));398 pos = logicalEndOfLine(VisiblePosition(m_sel.end(), m_sel.affinity())); 399 399 break; 400 400 case ParagraphBoundary: … … 475 475 break; 476 476 case LineBoundary: 477 pos = startOfLine(VisiblePosition(m_sel.start(), m_sel.affinity()));477 pos = logicalStartOfLine(VisiblePosition(m_sel.start(), m_sel.affinity())); 478 478 break; 479 479 case ParagraphBoundary: … … 542 542 break; 543 543 case LineBoundary: 544 pos = startOfLine(VisiblePosition(m_sel.start(), m_sel.affinity()));544 pos = logicalStartOfLine(VisiblePosition(m_sel.start(), m_sel.affinity())); 545 545 break; 546 546 case ParagraphBoundary: -
trunk/WebCore/editing/visible_units.cpp
r43028 r43032 1056 1056 } 1057 1057 1058 } 1058 static void getLeafBoxesInLogicalOrder(RootInlineBox* rootBox, Vector<InlineBox*>& leafBoxesInLogicalOrder) { 1059 unsigned char minLevel = 128; 1060 unsigned char maxLevel = 0; 1061 unsigned count = 0; 1062 InlineBox* r = rootBox->firstLeafChild(); 1063 // First find highest and lowest levels, 1064 // and initialize leafBoxesInLogicalOrder with the leaf boxes in visual order. 1065 while (r) { 1066 if (r->bidiLevel() > maxLevel) 1067 maxLevel = r->bidiLevel(); 1068 if (r->bidiLevel() < minLevel) 1069 minLevel = r->bidiLevel(); 1070 leafBoxesInLogicalOrder.append(r); 1071 r = r->nextLeafChild(); 1072 ++count; 1073 } 1074 1075 if (rootBox->renderer()->style()->visuallyOrdered()) 1076 return; 1077 // Reverse of reordering of the line (L2 according to Bidi spec): 1078 // L2. From the highest level found in the text to the lowest odd level on each line, 1079 // reverse any contiguous sequence of characters that are at that level or higher. 1080 1081 // Reversing the reordering of the line is only done up to the lowest odd level. 1082 if (!(minLevel % 2)) 1083 minLevel++; 1084 1085 InlineBox** end = leafBoxesInLogicalOrder.end(); 1086 while (minLevel <= maxLevel) { 1087 InlineBox** iter = leafBoxesInLogicalOrder.begin(); 1088 while (iter != end) { 1089 while (iter != end) { 1090 if ((*iter)->bidiLevel() >= minLevel) 1091 break; 1092 ++iter; 1093 } 1094 InlineBox** first = iter; 1095 while (iter != end) { 1096 if ((*iter)->bidiLevel() < minLevel) 1097 break; 1098 ++iter; 1099 } 1100 InlineBox** last = iter; 1101 std::reverse(first, last); 1102 } 1103 ++minLevel; 1104 } 1105 } 1106 1107 static void getLogicalStartBoxAndNode(RootInlineBox* rootBox, InlineBox*& startBox, Node*& startNode) 1108 { 1109 Vector<InlineBox*> leafBoxesInLogicalOrder; 1110 getLeafBoxesInLogicalOrder(rootBox, leafBoxesInLogicalOrder); 1111 startBox = 0; 1112 startNode = 0; 1113 for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) { 1114 startBox = leafBoxesInLogicalOrder[i]; 1115 startNode = startBox->renderer()->node(); 1116 if (startNode) 1117 return; 1118 } 1119 } 1120 1121 static void getLogicalEndBoxAndNode(RootInlineBox* rootBox, InlineBox*& endBox, Node*& endNode) 1122 { 1123 Vector<InlineBox*> leafBoxesInLogicalOrder; 1124 getLeafBoxesInLogicalOrder(rootBox, leafBoxesInLogicalOrder); 1125 endBox = 0; 1126 endNode = 0; 1127 // Generated content (e.g. list markers and CSS :before and :after 1128 // pseudoelements) have no corresponding DOM element, and so cannot be 1129 // represented by a VisiblePosition. Use whatever precedes instead. 1130 for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) { 1131 endBox = leafBoxesInLogicalOrder[i - 1]; 1132 endNode = endBox->renderer()->node(); 1133 if (endNode) 1134 return; 1135 } 1136 } 1137 1138 static VisiblePosition logicalStartPositionForLine(const VisiblePosition& c) 1139 { 1140 if (c.isNull()) 1141 return VisiblePosition(); 1142 1143 RootInlineBox* rootBox = rootBoxForLine(c); 1144 if (!rootBox) { 1145 // There are VisiblePositions at offset 0 in blocks without 1146 // RootInlineBoxes, like empty editable blocks and bordered blocks. 1147 Position p = c.deepEquivalent(); 1148 if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && !p.m_offset) 1149 return positionAvoidingFirstPositionInTable(c); 1150 1151 return VisiblePosition(); 1152 } 1153 1154 InlineBox* logicalStartBox; 1155 Node* logicalStartNode; 1156 getLogicalStartBoxAndNode(rootBox, logicalStartBox, logicalStartNode); 1157 1158 if (!logicalStartNode) 1159 return VisiblePosition(); 1160 1161 int startOffset = logicalStartBox->caretMinOffset(); 1162 1163 VisiblePosition visPos = VisiblePosition(logicalStartNode, startOffset, DOWNSTREAM); 1164 return positionAvoidingFirstPositionInTable(visPos); 1165 } 1166 1167 VisiblePosition logicalStartOfLine(const VisiblePosition& c) 1168 { 1169 VisiblePosition visPos = logicalStartPositionForLine(c); 1170 1171 if (visPos.isNull()) 1172 return c.honorEditableBoundaryAtOrAfter(visPos); 1173 1174 return c.honorEditableBoundaryAtOrAfter(visPos); 1175 } 1176 1177 static VisiblePosition logicalEndPositionForLine(const VisiblePosition& c) 1178 { 1179 if (c.isNull()) 1180 return VisiblePosition(); 1181 1182 RootInlineBox* rootBox = rootBoxForLine(c); 1183 if (!rootBox) { 1184 // There are VisiblePositions at offset 0 in blocks without 1185 // RootInlineBoxes, like empty editable blocks and bordered blocks. 1186 Position p = c.deepEquivalent(); 1187 if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && !p.m_offset) 1188 return c; 1189 return VisiblePosition(); 1190 } 1191 1192 InlineBox* logicalEndBox; 1193 Node* logicalEndNode; 1194 getLogicalEndBoxAndNode(rootBox, logicalEndBox, logicalEndNode); 1195 if (!logicalEndNode) 1196 return VisiblePosition(); 1197 1198 int endOffset = 1; 1199 if (logicalEndNode->hasTagName(brTag)) 1200 endOffset = 0; 1201 else if (logicalEndBox->isInlineTextBox()) { 1202 InlineTextBox* endTextBox = static_cast<InlineTextBox*>(logicalEndBox); 1203 endOffset = endTextBox->start(); 1204 if (!endTextBox->isLineBreak()) 1205 endOffset += endTextBox->len(); 1206 } 1207 1208 return VisiblePosition(logicalEndNode, endOffset, VP_UPSTREAM_IF_POSSIBLE); 1209 } 1210 1211 bool inSameLogicalLine(const VisiblePosition& a, const VisiblePosition& b) 1212 { 1213 return a.isNotNull() && logicalStartOfLine(a) == logicalStartOfLine(b); 1214 } 1215 1216 VisiblePosition logicalEndOfLine(const VisiblePosition& c) 1217 { 1218 VisiblePosition visPos = logicalEndPositionForLine(c); 1219 1220 // Make sure the end of line is at the same line as the given input position. For a wrapping line, the logical end 1221 // position for the not-last-2-lines might incorrectly hand back the logical beginning of the next line. 1222 // For example, <div contenteditable dir="rtl" style="line-break:before-white-space">abcdefg abcdefg abcdefg 1223 // a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg </div> 1224 // In this case, use the previous position of the computed logical end position. 1225 if (!inSameLogicalLine(c, visPos)) 1226 visPos = visPos.previous(); 1227 1228 return c.honorEditableBoundaryAtOrBefore(visPos); 1229 } 1230 1231 } -
trunk/WebCore/editing/visible_units.h
r43028 r43032 54 54 VisiblePosition nextLinePosition(const VisiblePosition &, int x); 55 55 bool inSameLine(const VisiblePosition &, const VisiblePosition &); 56 bool inSameLogicalLine(const VisiblePosition &, const VisiblePosition &); 56 57 bool isStartOfLine(const VisiblePosition &); 57 58 bool isEndOfLine(const VisiblePosition &); 59 VisiblePosition logicalStartOfLine(const VisiblePosition &); 60 VisiblePosition logicalEndOfLine(const VisiblePosition &); 58 61 59 62 // paragraphs (perhaps a misnomer, can be divided by line break elements)
Note:
See TracChangeset
for help on using the changeset viewer.