OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 return 0; | 81 return 0; |
82 } | 82 } |
83 | 83 |
84 // FIXME: consolidate with code in previousLinePosition. | 84 // FIXME: consolidate with code in previousLinePosition. |
85 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) | 85 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) |
86 { | 86 { |
87 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); | 87 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); |
88 Node* previousNode = previousLeafWithSameEditability(node, editableType); | 88 Node* previousNode = previousLeafWithSameEditability(node, editableType); |
89 | 89 |
90 while (previousNode && (!previousNode->renderer() || inSameLine(VisiblePosit
ion(firstPositionInOrBeforeNode(previousNode)), visiblePosition))) | 90 while (previousNode && (!previousNode->layoutObject() || inSameLine(VisibleP
osition(firstPositionInOrBeforeNode(previousNode)), visiblePosition))) |
91 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); | 91 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); |
92 | 92 |
93 while (previousNode && !previousNode->isShadowRoot()) { | 93 while (previousNode && !previousNode->isShadowRoot()) { |
94 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), edita
bleType) != highestRoot) | 94 if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), edita
bleType) != highestRoot) |
95 break; | 95 break; |
96 | 96 |
97 Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previ
ousNode) : | 97 Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previ
ousNode) : |
98 createLegacyEditingPosition(previousNode, caretMaxOffset(previousNod
e)); | 98 createLegacyEditingPosition(previousNode, caretMaxOffset(previousNod
e)); |
99 | 99 |
100 if (pos.isCandidate()) | 100 if (pos.isCandidate()) |
101 return pos; | 101 return pos; |
102 | 102 |
103 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); | 103 previousNode = previousLeafWithSameEditability(previousNode, editableTyp
e); |
104 } | 104 } |
105 return Position(); | 105 return Position(); |
106 } | 106 } |
107 | 107 |
108 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi
tion& visiblePosition, EditableType editableType) | 108 static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi
tion& visiblePosition, EditableType editableType) |
109 { | 109 { |
110 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); | 110 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); |
111 Node* nextNode = nextLeafWithSameEditability(node, editableType); | 111 Node* nextNode = nextLeafWithSameEditability(node, editableType); |
112 while (nextNode && (!nextNode->renderer() || inSameLine(VisiblePosition(firs
tPositionInOrBeforeNode(nextNode)), visiblePosition))) | 112 while (nextNode && (!nextNode->layoutObject() || inSameLine(VisiblePosition(
firstPositionInOrBeforeNode(nextNode)), visiblePosition))) |
113 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable); | 113 nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable); |
114 | 114 |
115 while (nextNode && !nextNode->isShadowRoot()) { | 115 while (nextNode && !nextNode->isShadowRoot()) { |
116 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode), editableT
ype) != highestRoot) | 116 if (highestEditableRoot(firstPositionInOrBeforeNode(nextNode), editableT
ype) != highestRoot) |
117 break; | 117 break; |
118 | 118 |
119 Position pos; | 119 Position pos; |
120 pos = createLegacyEditingPosition(nextNode, caretMinOffset(nextNode)); | 120 pos = createLegacyEditingPosition(nextNode, caretMinOffset(nextNode)); |
121 | 121 |
122 if (pos.isCandidate()) | 122 if (pos.isCandidate()) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 214 |
215 const InlineTextBox* previousBox = leafBoxes.previousTextBox(&startBox->root
(), textBox); | 215 const InlineTextBox* previousBox = leafBoxes.previousTextBox(&startBox->root
(), textBox); |
216 if (previousBox) | 216 if (previousBox) |
217 return previousBox; | 217 return previousBox; |
218 | 218 |
219 previousBox = leafBoxes.previousTextBox(startBox->root().prevRootBox(), 0); | 219 previousBox = leafBoxes.previousTextBox(startBox->root().prevRootBox(), 0); |
220 if (previousBox) | 220 if (previousBox) |
221 return previousBox; | 221 return previousBox; |
222 | 222 |
223 while (1) { | 223 while (1) { |
224 Node* startNode = startBox->renderer().nonPseudoNode(); | 224 Node* startNode = startBox->layoutObject().nonPseudoNode(); |
225 if (!startNode) | 225 if (!startNode) |
226 break; | 226 break; |
227 | 227 |
228 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); | 228 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); |
229 if (position.isNull()) | 229 if (position.isNull()) |
230 break; | 230 break; |
231 | 231 |
232 RenderedPosition renderedPosition(position, DOWNSTREAM); | 232 RenderedPosition renderedPosition(position, DOWNSTREAM); |
233 RootInlineBox* previousRoot = renderedPosition.rootBox(); | 233 RootInlineBox* previousRoot = renderedPosition.rootBox(); |
234 if (!previousRoot) | 234 if (!previousRoot) |
(...skipping 20 matching lines...) Expand all Loading... |
255 | 255 |
256 const InlineTextBox* nextBox = leafBoxes.nextTextBox(&startBox->root(), text
Box); | 256 const InlineTextBox* nextBox = leafBoxes.nextTextBox(&startBox->root(), text
Box); |
257 if (nextBox) | 257 if (nextBox) |
258 return nextBox; | 258 return nextBox; |
259 | 259 |
260 nextBox = leafBoxes.nextTextBox(startBox->root().nextRootBox(), 0); | 260 nextBox = leafBoxes.nextTextBox(startBox->root().nextRootBox(), 0); |
261 if (nextBox) | 261 if (nextBox) |
262 return nextBox; | 262 return nextBox; |
263 | 263 |
264 while (1) { | 264 while (1) { |
265 Node* startNode =startBox->renderer().nonPseudoNode(); | 265 Node* startNode =startBox->layoutObject().nonPseudoNode(); |
266 if (!startNode) | 266 if (!startNode) |
267 break; | 267 break; |
268 | 268 |
269 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); | 269 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); |
270 if (position.isNull()) | 270 if (position.isNull()) |
271 break; | 271 break; |
272 | 272 |
273 RenderedPosition renderedPosition(position, DOWNSTREAM); | 273 RenderedPosition renderedPosition(position, DOWNSTREAM); |
274 RootInlineBox* nextRoot = renderedPosition.rootBox(); | 274 RootInlineBox* nextRoot = renderedPosition.rootBox(); |
275 if (!nextRoot) | 275 if (!nextRoot) |
(...skipping 17 matching lines...) Expand all Loading... |
293 { | 293 { |
294 previousBoxInDifferentBlock = false; | 294 previousBoxInDifferentBlock = false; |
295 | 295 |
296 // FIXME: Handle the case when we don't have an inline text box. | 296 // FIXME: Handle the case when we don't have an inline text box. |
297 const InlineTextBox* previousBox = logicallyPreviousBox(visiblePosition, tex
tBox, previousBoxInDifferentBlock, leafBoxes); | 297 const InlineTextBox* previousBox = logicallyPreviousBox(visiblePosition, tex
tBox, previousBoxInDifferentBlock, leafBoxes); |
298 | 298 |
299 int len = 0; | 299 int len = 0; |
300 string.clear(); | 300 string.clear(); |
301 if (previousBox) { | 301 if (previousBox) { |
302 previousBoxLength = previousBox->len(); | 302 previousBoxLength = previousBox->len(); |
303 previousBox->renderer().text().appendTo(string, previousBox->start(), pr
eviousBoxLength); | 303 previousBox->layoutObject().text().appendTo(string, previousBox->start()
, previousBoxLength); |
304 len += previousBoxLength; | 304 len += previousBoxLength; |
305 } | 305 } |
306 textBox->renderer().text().appendTo(string, textBox->start(), textBox->len()
); | 306 textBox->layoutObject().text().appendTo(string, textBox->start(), textBox->l
en()); |
307 len += textBox->len(); | 307 len += textBox->len(); |
308 | 308 |
309 return wordBreakIterator(string.data(), len); | 309 return wordBreakIterator(string.data(), len); |
310 } | 310 } |
311 | 311 |
312 static TextBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePos
ition& visiblePosition, const InlineTextBox* textBox, | 312 static TextBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePos
ition& visiblePosition, const InlineTextBox* textBox, |
313 bool& nextBoxInDifferentBlock, Vector<UChar, 1024>& string, CachedLogicallyO
rderedLeafBoxes& leafBoxes) | 313 bool& nextBoxInDifferentBlock, Vector<UChar, 1024>& string, CachedLogicallyO
rderedLeafBoxes& leafBoxes) |
314 { | 314 { |
315 nextBoxInDifferentBlock = false; | 315 nextBoxInDifferentBlock = false; |
316 | 316 |
317 // FIXME: Handle the case when we don't have an inline text box. | 317 // FIXME: Handle the case when we don't have an inline text box. |
318 const InlineTextBox* nextBox = logicallyNextBox(visiblePosition, textBox, ne
xtBoxInDifferentBlock, leafBoxes); | 318 const InlineTextBox* nextBox = logicallyNextBox(visiblePosition, textBox, ne
xtBoxInDifferentBlock, leafBoxes); |
319 | 319 |
320 int len = 0; | 320 int len = 0; |
321 string.clear(); | 321 string.clear(); |
322 textBox->renderer().text().appendTo(string, textBox->start(), textBox->len()
); | 322 textBox->layoutObject().text().appendTo(string, textBox->start(), textBox->l
en()); |
323 len += textBox->len(); | 323 len += textBox->len(); |
324 if (nextBox) { | 324 if (nextBox) { |
325 nextBox->renderer().text().appendTo(string, nextBox->start(), nextBox->l
en()); | 325 nextBox->layoutObject().text().appendTo(string, nextBox->start(), nextBo
x->len()); |
326 len += nextBox->len(); | 326 len += nextBox->len(); |
327 } | 327 } |
328 | 328 |
329 return wordBreakIterator(string.data(), len); | 329 return wordBreakIterator(string.data(), len); |
330 } | 330 } |
331 | 331 |
332 static bool isLogicalStartOfWord(TextBreakIterator* iter, int position, bool har
dLineBreak) | 332 static bool isLogicalStartOfWord(TextBreakIterator* iter, int position, bool har
dLineBreak) |
333 { | 333 { |
334 bool boundary = hardLineBreak ? true : iter->isBoundary(position); | 334 bool boundary = hardLineBreak ? true : iter->isBoundary(position); |
335 if (!boundary) | 335 if (!boundary) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 int previousBoxLength = 0; | 382 int previousBoxLength = 0; |
383 bool previousBoxInDifferentBlock = false; | 383 bool previousBoxInDifferentBlock = false; |
384 bool nextBoxInDifferentBlock = false; | 384 bool nextBoxInDifferentBlock = false; |
385 bool movingIntoNewBox = previouslyVisitedBox != box; | 385 bool movingIntoNewBox = previouslyVisitedBox != box; |
386 | 386 |
387 if (offsetInBox == box->caretMinOffset()) | 387 if (offsetInBox == box->caretMinOffset()) |
388 iter = wordBreakIteratorForMinOffsetBoundary(visiblePosition, textBo
x, previousBoxLength, previousBoxInDifferentBlock, string, leafBoxes); | 388 iter = wordBreakIteratorForMinOffsetBoundary(visiblePosition, textBo
x, previousBoxLength, previousBoxInDifferentBlock, string, leafBoxes); |
389 else if (offsetInBox == box->caretMaxOffset()) | 389 else if (offsetInBox == box->caretMaxOffset()) |
390 iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBo
x, nextBoxInDifferentBlock, string, leafBoxes); | 390 iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBo
x, nextBoxInDifferentBlock, string, leafBoxes); |
391 else if (movingIntoNewBox) { | 391 else if (movingIntoNewBox) { |
392 iter = wordBreakIterator(textBox->renderer().text(), textBox->start(
), textBox->len()); | 392 iter = wordBreakIterator(textBox->layoutObject().text(), textBox->st
art(), textBox->len()); |
393 previouslyVisitedBox = box; | 393 previouslyVisitedBox = box; |
394 } | 394 } |
395 | 395 |
396 if (!iter) | 396 if (!iter) |
397 break; | 397 break; |
398 | 398 |
399 iter->first(); | 399 iter->first(); |
400 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; | 400 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; |
401 | 401 |
402 bool isWordBreak; | 402 bool isWordBreak; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 483 } |
484 | 484 |
485 ASSERT(!exceptionState.hadException()); | 485 ASSERT(!exceptionState.hadException()); |
486 if (exceptionState.hadException()) | 486 if (exceptionState.hadException()) |
487 return VisiblePosition(); | 487 return VisiblePosition(); |
488 | 488 |
489 SimplifiedBackwardsTextIterator it(start, end); | 489 SimplifiedBackwardsTextIterator it(start, end); |
490 unsigned next = 0; | 490 unsigned next = 0; |
491 bool needMoreContext = false; | 491 bool needMoreContext = false; |
492 while (!it.atEnd()) { | 492 while (!it.atEnd()) { |
493 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; | 493 bool inTextSecurityMode = it.node() && it.node()->layoutObject() && it.n
ode()->layoutObject()->style()->textSecurity() != TSNONE; |
494 // iterate to get chunks until the searchFunction returns a non-zero val
ue. | 494 // iterate to get chunks until the searchFunction returns a non-zero val
ue. |
495 if (!inTextSecurityMode) | 495 if (!inTextSecurityMode) |
496 it.prependTextTo(string); | 496 it.prependTextTo(string); |
497 else { | 497 else { |
498 // Treat bullets used in the text security mode as regular character
s when looking for boundaries | 498 // Treat bullets used in the text security mode as regular character
s when looking for boundaries |
499 Vector<UChar, 1024> iteratorString; | 499 Vector<UChar, 1024> iteratorString; |
500 iteratorString.fill('x', it.length()); | 500 iteratorString.fill('x', it.length()); |
501 string.prepend(iteratorString.data(), iteratorString.size()); | 501 string.prepend(iteratorString.data(), iteratorString.size()); |
502 } | 502 } |
503 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, MayHaveMoreContext, needMoreContext); | 503 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, MayHaveMoreContext, needMoreContext); |
504 if (next) | 504 if (next) |
505 break; | 505 break; |
506 it.advance(); | 506 it.advance(); |
507 } | 507 } |
508 if (needMoreContext) { | 508 if (needMoreContext) { |
509 // The last search returned the beginning of the buffer and asked for mo
re context, | 509 // The last search returned the beginning of the buffer and asked for mo
re context, |
510 // but there is no earlier text. Force a search with what's available. | 510 // but there is no earlier text. Force a search with what's available. |
511 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, DontHaveMoreContext, needMoreContext); | 511 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, DontHaveMoreContext, needMoreContext); |
512 ASSERT(!needMoreContext); | 512 ASSERT(!needMoreContext); |
513 } | 513 } |
514 | 514 |
515 if (!next) | 515 if (!next) |
516 return VisiblePosition(it.atEnd() ? it.startPosition() : pos, DOWNSTREAM
); | 516 return VisiblePosition(it.atEnd() ? it.startPosition() : pos, DOWNSTREAM
); |
517 | 517 |
518 Node* node = it.startContainer(); | 518 Node* node = it.startContainer(); |
519 if ((node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffse
t()) || (node->renderer() && node->renderer()->isBR() && !next)) | 519 if ((node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffse
t()) || (node->layoutObject() && node->layoutObject()->isBR() && !next)) |
520 // The next variable contains a usable index into a text node | 520 // The next variable contains a usable index into a text node |
521 return VisiblePosition(createLegacyEditingPosition(node, next), DOWNSTRE
AM); | 521 return VisiblePosition(createLegacyEditingPosition(node, next), DOWNSTRE
AM); |
522 | 522 |
523 // Use the character iterator to translate the next value into a DOM positio
n. | 523 // Use the character iterator to translate the next value into a DOM positio
n. |
524 BackwardsCharacterIterator charIt(start, end); | 524 BackwardsCharacterIterator charIt(start, end); |
525 charIt.advance(string.size() - suffixLength - next); | 525 charIt.advance(string.size() - suffixLength - next); |
526 // FIXME: charIt can get out of shadow host. | 526 // FIXME: charIt can get out of shadow host. |
527 return VisiblePosition(charIt.endPosition(), DOWNSTREAM); | 527 return VisiblePosition(charIt.endPosition(), DOWNSTREAM); |
528 } | 528 } |
529 | 529 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 RangeBoundaryPoint searchEndPoint(boundary); | 561 RangeBoundaryPoint searchEndPoint(boundary); |
562 searchEndPoint.setToEndOfNode(*boundary); | 562 searchEndPoint.setToEndOfNode(*boundary); |
563 Position searchEnd = searchEndPoint.toPosition(); | 563 Position searchEnd = searchEndPoint.toPosition(); |
564 TextIterator it(searchStart, searchEnd, TextIteratorEmitsCharactersBetweenAl
lVisiblePositions); | 564 TextIterator it(searchStart, searchEnd, TextIteratorEmitsCharactersBetweenAl
lVisiblePositions); |
565 const unsigned invalidOffset = static_cast<unsigned>(-1); | 565 const unsigned invalidOffset = static_cast<unsigned>(-1); |
566 unsigned next = invalidOffset; | 566 unsigned next = invalidOffset; |
567 bool needMoreContext = false; | 567 bool needMoreContext = false; |
568 while (!it.atEnd()) { | 568 while (!it.atEnd()) { |
569 // Keep asking the iterator for chunks until the search function | 569 // Keep asking the iterator for chunks until the search function |
570 // returns an end value not equal to the length of the string passed to
it. | 570 // returns an end value not equal to the length of the string passed to
it. |
571 bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node(
)->renderer()->style()->textSecurity() != TSNONE; | 571 bool inTextSecurityMode = it.node() && it.node()->layoutObject() && it.n
ode()->layoutObject()->style()->textSecurity() != TSNONE; |
572 if (!inTextSecurityMode) | 572 if (!inTextSecurityMode) |
573 it.appendTextTo(string); | 573 it.appendTextTo(string); |
574 else { | 574 else { |
575 // Treat bullets used in the text security mode as regular character
s when looking for boundaries | 575 // Treat bullets used in the text security mode as regular character
s when looking for boundaries |
576 Vector<UChar, 1024> iteratorString; | 576 Vector<UChar, 1024> iteratorString; |
577 iteratorString.fill('x', it.length()); | 577 iteratorString.fill('x', it.length()); |
578 string.append(iteratorString.data(), iteratorString.size()); | 578 string.append(iteratorString.data(), iteratorString.size()); |
579 } | 579 } |
580 next = searchFunction(string.data(), string.size(), prefixLength, MayHav
eMoreContext, needMoreContext); | 580 next = searchFunction(string.data(), string.size(), prefixLength, MayHav
eMoreContext, needMoreContext); |
581 if (next != string.size()) | 581 if (next != string.size()) |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 static VisiblePosition startPositionForLine(const VisiblePosition& c, LineEndpoi
ntComputationMode mode) | 709 static VisiblePosition startPositionForLine(const VisiblePosition& c, LineEndpoi
ntComputationMode mode) |
710 { | 710 { |
711 if (c.isNull()) | 711 if (c.isNull()) |
712 return VisiblePosition(); | 712 return VisiblePosition(); |
713 | 713 |
714 RootInlineBox* rootBox = RenderedPosition(c).rootBox(); | 714 RootInlineBox* rootBox = RenderedPosition(c).rootBox(); |
715 if (!rootBox) { | 715 if (!rootBox) { |
716 // There are VisiblePositions at offset 0 in blocks without | 716 // There are VisiblePositions at offset 0 in blocks without |
717 // RootInlineBoxes, like empty editable blocks and bordered blocks. | 717 // RootInlineBoxes, like empty editable blocks and bordered blocks. |
718 Position p = c.deepEquivalent(); | 718 Position p = c.deepEquivalent(); |
719 if (p.deprecatedNode()->renderer() && p.deprecatedNode()->renderer()->is
LayoutBlock() && !p.deprecatedEditingOffset()) | 719 if (p.deprecatedNode()->layoutObject() && p.deprecatedNode()->layoutObje
ct()->isLayoutBlock() && !p.deprecatedEditingOffset()) |
720 return c; | 720 return c; |
721 | 721 |
722 return VisiblePosition(); | 722 return VisiblePosition(); |
723 } | 723 } |
724 | 724 |
725 Node* startNode; | 725 Node* startNode; |
726 InlineBox* startBox; | 726 InlineBox* startBox; |
727 if (mode == UseLogicalOrdering) { | 727 if (mode == UseLogicalOrdering) { |
728 startNode = rootBox->getLogicalStartBoxWithNode(startBox); | 728 startNode = rootBox->getLogicalStartBoxWithNode(startBox); |
729 if (!startNode) | 729 if (!startNode) |
730 return VisiblePosition(); | 730 return VisiblePosition(); |
731 } else { | 731 } else { |
732 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, | 732 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, |
733 // and so cannot be represented by a VisiblePosition. Use whatever follo
ws instead. | 733 // and so cannot be represented by a VisiblePosition. Use whatever follo
ws instead. |
734 startBox = rootBox->firstLeafChild(); | 734 startBox = rootBox->firstLeafChild(); |
735 while (true) { | 735 while (true) { |
736 if (!startBox) | 736 if (!startBox) |
737 return VisiblePosition(); | 737 return VisiblePosition(); |
738 | 738 |
739 startNode = startBox->renderer().nonPseudoNode(); | 739 startNode = startBox->layoutObject().nonPseudoNode(); |
740 if (startNode) | 740 if (startNode) |
741 break; | 741 break; |
742 | 742 |
743 startBox = startBox->nextLeafChild(); | 743 startBox = startBox->nextLeafChild(); |
744 } | 744 } |
745 } | 745 } |
746 | 746 |
747 return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode),
toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode)); | 747 return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode),
toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode)); |
748 } | 748 } |
749 | 749 |
(...skipping 27 matching lines...) Expand all Loading... |
777 static VisiblePosition endPositionForLine(const VisiblePosition& c, LineEndpoint
ComputationMode mode) | 777 static VisiblePosition endPositionForLine(const VisiblePosition& c, LineEndpoint
ComputationMode mode) |
778 { | 778 { |
779 if (c.isNull()) | 779 if (c.isNull()) |
780 return VisiblePosition(); | 780 return VisiblePosition(); |
781 | 781 |
782 RootInlineBox* rootBox = RenderedPosition(c).rootBox(); | 782 RootInlineBox* rootBox = RenderedPosition(c).rootBox(); |
783 if (!rootBox) { | 783 if (!rootBox) { |
784 // There are VisiblePositions at offset 0 in blocks without | 784 // There are VisiblePositions at offset 0 in blocks without |
785 // RootInlineBoxes, like empty editable blocks and bordered blocks. | 785 // RootInlineBoxes, like empty editable blocks and bordered blocks. |
786 Position p = c.deepEquivalent(); | 786 Position p = c.deepEquivalent(); |
787 if (p.deprecatedNode()->renderer() && p.deprecatedNode()->renderer()->is
LayoutBlock() && !p.deprecatedEditingOffset()) | 787 if (p.deprecatedNode()->layoutObject() && p.deprecatedNode()->layoutObje
ct()->isLayoutBlock() && !p.deprecatedEditingOffset()) |
788 return c; | 788 return c; |
789 return VisiblePosition(); | 789 return VisiblePosition(); |
790 } | 790 } |
791 | 791 |
792 Node* endNode; | 792 Node* endNode; |
793 InlineBox* endBox; | 793 InlineBox* endBox; |
794 if (mode == UseLogicalOrdering) { | 794 if (mode == UseLogicalOrdering) { |
795 endNode = rootBox->getLogicalEndBoxWithNode(endBox); | 795 endNode = rootBox->getLogicalEndBoxWithNode(endBox); |
796 if (!endNode) | 796 if (!endNode) |
797 return VisiblePosition(); | 797 return VisiblePosition(); |
798 } else { | 798 } else { |
799 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, | 799 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, |
800 // and so cannot be represented by a VisiblePosition. Use whatever prece
des instead. | 800 // and so cannot be represented by a VisiblePosition. Use whatever prece
des instead. |
801 endBox = rootBox->lastLeafChild(); | 801 endBox = rootBox->lastLeafChild(); |
802 while (true) { | 802 while (true) { |
803 if (!endBox) | 803 if (!endBox) |
804 return VisiblePosition(); | 804 return VisiblePosition(); |
805 | 805 |
806 endNode = endBox->renderer().nonPseudoNode(); | 806 endNode = endBox->layoutObject().nonPseudoNode(); |
807 if (endNode) | 807 if (endNode) |
808 break; | 808 break; |
809 | 809 |
810 endBox = endBox->prevLeafChild(); | 810 endBox = endBox->prevLeafChild(); |
811 } | 811 } |
812 } | 812 } |
813 | 813 |
814 Position pos; | 814 Position pos; |
815 if (isHTMLBRElement(*endNode)) | 815 if (isHTMLBRElement(*endNode)) |
816 pos = positionBeforeNode(endNode); | 816 pos = positionBeforeNode(endNode); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, Lay
outUnit lineDirectionPoint, EditableType editableType) | 917 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, Lay
outUnit lineDirectionPoint, EditableType editableType) |
918 { | 918 { |
919 Position p = visiblePosition.deepEquivalent(); | 919 Position p = visiblePosition.deepEquivalent(); |
920 Node* node = p.deprecatedNode(); | 920 Node* node = p.deprecatedNode(); |
921 | 921 |
922 if (!node) | 922 if (!node) |
923 return VisiblePosition(); | 923 return VisiblePosition(); |
924 | 924 |
925 node->document().updateLayoutIgnorePendingStylesheets(); | 925 node->document().updateLayoutIgnorePendingStylesheets(); |
926 | 926 |
927 LayoutObject* renderer = node->renderer(); | 927 LayoutObject* renderer = node->layoutObject(); |
928 if (!renderer) | 928 if (!renderer) |
929 return VisiblePosition(); | 929 return VisiblePosition(); |
930 | 930 |
931 RootInlineBox* root = 0; | 931 RootInlineBox* root = 0; |
932 InlineBox* box; | 932 InlineBox* box; |
933 int ignoredCaretOffset; | 933 int ignoredCaretOffset; |
934 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); | 934 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); |
935 if (box) { | 935 if (box) { |
936 root = box->root().prevRootBox(); | 936 root = box->root().prevRootBox(); |
937 // We want to skip zero height boxes. | 937 // We want to skip zero height boxes. |
938 // This could happen in case it is a TrailingFloatsRootInlineBox. | 938 // This could happen in case it is a TrailingFloatsRootInlineBox. |
939 if (!root || !root->logicalHeight() || !root->firstLeafChild()) | 939 if (!root || !root->logicalHeight() || !root->firstLeafChild()) |
940 root = 0; | 940 root = 0; |
941 } | 941 } |
942 | 942 |
943 if (!root) { | 943 if (!root) { |
944 Position position = previousRootInlineBoxCandidatePosition(node, visible
Position, editableType); | 944 Position position = previousRootInlineBoxCandidatePosition(node, visible
Position, editableType); |
945 if (position.isNotNull()) { | 945 if (position.isNotNull()) { |
946 RenderedPosition renderedPosition((VisiblePosition(position))); | 946 RenderedPosition renderedPosition((VisiblePosition(position))); |
947 root = renderedPosition.rootBox(); | 947 root = renderedPosition.rootBox(); |
948 if (!root) | 948 if (!root) |
949 return VisiblePosition(position); | 949 return VisiblePosition(position); |
950 } | 950 } |
951 } | 951 } |
952 | 952 |
953 if (root) { | 953 if (root) { |
954 // FIXME: Can be wrong for multi-column layout and with transforms. | 954 // FIXME: Can be wrong for multi-column layout and with transforms. |
955 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(
root, lineDirectionPoint); | 955 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(
root, lineDirectionPoint); |
956 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 956 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->layoutObject(); |
957 Node* node = renderer.node(); | 957 Node* node = renderer.node(); |
958 if (node && editingIgnoresContent(node)) | 958 if (node && editingIgnoresContent(node)) |
959 return VisiblePosition(positionInParentBeforeNode(*node)); | 959 return VisiblePosition(positionInParentBeforeNode(*node)); |
960 return VisiblePosition(renderer.positionForPoint(pointInLine)); | 960 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
961 } | 961 } |
962 | 962 |
963 // Could not find a previous line. This means we must already be on the firs
t line. | 963 // Could not find a previous line. This means we must already be on the firs
t line. |
964 // Move to the start of the content in this block, which effectively moves u
s | 964 // Move to the start of the content in this block, which effectively moves u
s |
965 // to the start of the line we're on. | 965 // to the start of the line we're on. |
966 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 966 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
967 if (!rootElement) | 967 if (!rootElement) |
968 return VisiblePosition(); | 968 return VisiblePosition(); |
969 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); | 969 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); |
970 } | 970 } |
971 | 971 |
972 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) | 972 VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) |
973 { | 973 { |
974 Position p = visiblePosition.deepEquivalent(); | 974 Position p = visiblePosition.deepEquivalent(); |
975 Node* node = p.deprecatedNode(); | 975 Node* node = p.deprecatedNode(); |
976 | 976 |
977 if (!node) | 977 if (!node) |
978 return VisiblePosition(); | 978 return VisiblePosition(); |
979 | 979 |
980 node->document().updateLayoutIgnorePendingStylesheets(); | 980 node->document().updateLayoutIgnorePendingStylesheets(); |
981 | 981 |
982 LayoutObject* renderer = node->renderer(); | 982 LayoutObject* renderer = node->layoutObject(); |
983 if (!renderer) | 983 if (!renderer) |
984 return VisiblePosition(); | 984 return VisiblePosition(); |
985 | 985 |
986 RootInlineBox* root = 0; | 986 RootInlineBox* root = 0; |
987 InlineBox* box; | 987 InlineBox* box; |
988 int ignoredCaretOffset; | 988 int ignoredCaretOffset; |
989 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); | 989 visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset); |
990 if (box) { | 990 if (box) { |
991 root = box->root().nextRootBox(); | 991 root = box->root().nextRootBox(); |
992 // We want to skip zero height boxes. | 992 // We want to skip zero height boxes. |
(...skipping 11 matching lines...) Expand all Loading... |
1004 RenderedPosition renderedPosition((VisiblePosition(position))); | 1004 RenderedPosition renderedPosition((VisiblePosition(position))); |
1005 root = renderedPosition.rootBox(); | 1005 root = renderedPosition.rootBox(); |
1006 if (!root) | 1006 if (!root) |
1007 return VisiblePosition(position); | 1007 return VisiblePosition(position); |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 if (root) { | 1011 if (root) { |
1012 // FIXME: Can be wrong for multi-column layout and with transforms. | 1012 // FIXME: Can be wrong for multi-column layout and with transforms. |
1013 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(
root, lineDirectionPoint); | 1013 LayoutPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(
root, lineDirectionPoint); |
1014 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 1014 LayoutObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->layoutObject(); |
1015 Node* node = renderer.node(); | 1015 Node* node = renderer.node(); |
1016 if (node && editingIgnoresContent(node)) | 1016 if (node && editingIgnoresContent(node)) |
1017 return VisiblePosition(positionInParentBeforeNode(*node)); | 1017 return VisiblePosition(positionInParentBeforeNode(*node)); |
1018 return VisiblePosition(renderer.positionForPoint(pointInLine)); | 1018 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
1019 } | 1019 } |
1020 | 1020 |
1021 // Could not find a next line. This means we must already be on the last lin
e. | 1021 // Could not find a next line. This means we must already be on the last lin
e. |
1022 // Move to the end of the content in this block, which effectively moves us | 1022 // Move to the end of the content in this block, which effectively moves us |
1023 // to the end of the line we're on. | 1023 // to the end of the line we're on. |
1024 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); | 1024 Element* rootElement = node->hasEditableStyle(editableType) ? node->rootEdit
ableElement(editableType) : node->document().documentElement(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 bool startNodeIsEditable = startNode->hasEditableStyle(); | 1103 bool startNodeIsEditable = startNode->hasEditableStyle(); |
1104 while (n) { | 1104 while (n) { |
1105 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1105 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) |
1106 break; | 1106 break; |
1107 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1107 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1108 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1108 while (n && n->hasEditableStyle() != startNodeIsEditable) |
1109 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1109 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1110 if (!n || !n->isDescendantOf(highestRoot)) | 1110 if (!n || !n->isDescendantOf(highestRoot)) |
1111 break; | 1111 break; |
1112 } | 1112 } |
1113 LayoutObject* r = n->renderer(); | 1113 LayoutObject* r = n->layoutObject(); |
1114 if (!r) { | 1114 if (!r) { |
1115 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1115 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1116 continue; | 1116 continue; |
1117 } | 1117 } |
1118 LayoutStyle* style = r->style(); | 1118 LayoutStyle* style = r->style(); |
1119 if (style->visibility() != VISIBLE) { | 1119 if (style->visibility() != VISIBLE) { |
1120 n = NodeTraversal::previousPostOrder(*n, startBlock); | 1120 n = NodeTraversal::previousPostOrder(*n, startBlock); |
1121 continue; | 1121 continue; |
1122 } | 1122 } |
1123 | 1123 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 while (n) { | 1182 while (n) { |
1183 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1183 if (boundaryCrossingRule == CannotCrossEditingBoundary && !Position::nod
eIsUserSelectAll(n) && n->hasEditableStyle() != startNodeIsEditable) |
1184 break; | 1184 break; |
1185 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1185 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1186 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1186 while (n && n->hasEditableStyle() != startNodeIsEditable) |
1187 n = NodeTraversal::next(*n, stayInsideBlock); | 1187 n = NodeTraversal::next(*n, stayInsideBlock); |
1188 if (!n || !n->isDescendantOf(highestRoot)) | 1188 if (!n || !n->isDescendantOf(highestRoot)) |
1189 break; | 1189 break; |
1190 } | 1190 } |
1191 | 1191 |
1192 LayoutObject* r = n->renderer(); | 1192 LayoutObject* r = n->layoutObject(); |
1193 if (!r) { | 1193 if (!r) { |
1194 n = NodeTraversal::next(*n, stayInsideBlock); | 1194 n = NodeTraversal::next(*n, stayInsideBlock); |
1195 continue; | 1195 continue; |
1196 } | 1196 } |
1197 LayoutStyle* style = r->style(); | 1197 LayoutStyle* style = r->style(); |
1198 if (style->visibility() != VISIBLE) { | 1198 if (style->visibility() != VISIBLE) { |
1199 n = NodeTraversal::next(*n, stayInsideBlock); | 1199 n = NodeTraversal::next(*n, stayInsideBlock); |
1200 continue; | 1200 continue; |
1201 } | 1201 } |
1202 | 1202 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 } | 1391 } |
1392 | 1392 |
1393 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Layout
Object*& renderer) | 1393 LayoutRect localCaretRectOfPosition(const PositionWithAffinity& position, Layout
Object*& renderer) |
1394 { | 1394 { |
1395 if (position.position().isNull()) { | 1395 if (position.position().isNull()) { |
1396 renderer = nullptr; | 1396 renderer = nullptr; |
1397 return LayoutRect(); | 1397 return LayoutRect(); |
1398 } | 1398 } |
1399 Node* node = position.position().anchorNode(); | 1399 Node* node = position.position().anchorNode(); |
1400 | 1400 |
1401 renderer = node->renderer(); | 1401 renderer = node->layoutObject(); |
1402 if (!renderer) | 1402 if (!renderer) |
1403 return LayoutRect(); | 1403 return LayoutRect(); |
1404 | 1404 |
1405 InlineBox* inlineBox; | 1405 InlineBox* inlineBox; |
1406 int caretOffset; | 1406 int caretOffset; |
1407 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); | 1407 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); |
1408 | 1408 |
1409 if (inlineBox) | 1409 if (inlineBox) |
1410 renderer = &inlineBox->renderer(); | 1410 renderer = &inlineBox->layoutObject(); |
1411 | 1411 |
1412 return renderer->localCaretRect(inlineBox, caretOffset); | 1412 return renderer->localCaretRect(inlineBox, caretOffset); |
1413 } | 1413 } |
1414 | 1414 |
1415 } | 1415 } |
OLD | NEW |