| 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 |