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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 | 209 |
210 const InlineTextBox* previousBox = leafBoxes.previousTextBox(startBox->root(
), textBox); | 210 const InlineTextBox* previousBox = leafBoxes.previousTextBox(startBox->root(
), textBox); |
211 if (previousBox) | 211 if (previousBox) |
212 return previousBox; | 212 return previousBox; |
213 | 213 |
214 previousBox = leafBoxes.previousTextBox(startBox->root()->prevRootBox(), 0); | 214 previousBox = leafBoxes.previousTextBox(startBox->root()->prevRootBox(), 0); |
215 if (previousBox) | 215 if (previousBox) |
216 return previousBox; | 216 return previousBox; |
217 | 217 |
218 while (1) { | 218 while (1) { |
219 Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudo
Node() : 0; | 219 Node* startNode = startBox->renderer().nonPseudoNode(); |
220 if (!startNode) | 220 if (!startNode) |
221 break; | 221 break; |
222 | 222 |
223 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); | 223 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); |
224 if (position.isNull()) | 224 if (position.isNull()) |
225 break; | 225 break; |
226 | 226 |
227 RenderedPosition renderedPosition(position, DOWNSTREAM); | 227 RenderedPosition renderedPosition(position, DOWNSTREAM); |
228 RootInlineBox* previousRoot = renderedPosition.rootBox(); | 228 RootInlineBox* previousRoot = renderedPosition.rootBox(); |
229 if (!previousRoot) | 229 if (!previousRoot) |
(...skipping 20 matching lines...) Expand all Loading... |
250 | 250 |
251 const InlineTextBox* nextBox = leafBoxes.nextTextBox(startBox->root(), textB
ox); | 251 const InlineTextBox* nextBox = leafBoxes.nextTextBox(startBox->root(), textB
ox); |
252 if (nextBox) | 252 if (nextBox) |
253 return nextBox; | 253 return nextBox; |
254 | 254 |
255 nextBox = leafBoxes.nextTextBox(startBox->root()->nextRootBox(), 0); | 255 nextBox = leafBoxes.nextTextBox(startBox->root()->nextRootBox(), 0); |
256 if (nextBox) | 256 if (nextBox) |
257 return nextBox; | 257 return nextBox; |
258 | 258 |
259 while (1) { | 259 while (1) { |
260 Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudo
Node() : 0; | 260 Node* startNode =startBox->renderer().nonPseudoNode(); |
261 if (!startNode) | 261 if (!startNode) |
262 break; | 262 break; |
263 | 263 |
264 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); | 264 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); |
265 if (position.isNull()) | 265 if (position.isNull()) |
266 break; | 266 break; |
267 | 267 |
268 RenderedPosition renderedPosition(position, DOWNSTREAM); | 268 RenderedPosition renderedPosition(position, DOWNSTREAM); |
269 RootInlineBox* nextRoot = renderedPosition.rootBox(); | 269 RootInlineBox* nextRoot = renderedPosition.rootBox(); |
270 if (!nextRoot) | 270 if (!nextRoot) |
(...skipping 17 matching lines...) Expand all Loading... |
288 { | 288 { |
289 previousBoxInDifferentBlock = false; | 289 previousBoxInDifferentBlock = false; |
290 | 290 |
291 // FIXME: Handle the case when we don't have an inline text box. | 291 // FIXME: Handle the case when we don't have an inline text box. |
292 const InlineTextBox* previousBox = logicallyPreviousBox(visiblePosition, tex
tBox, previousBoxInDifferentBlock, leafBoxes); | 292 const InlineTextBox* previousBox = logicallyPreviousBox(visiblePosition, tex
tBox, previousBoxInDifferentBlock, leafBoxes); |
293 | 293 |
294 int len = 0; | 294 int len = 0; |
295 string.clear(); | 295 string.clear(); |
296 if (previousBox) { | 296 if (previousBox) { |
297 previousBoxLength = previousBox->len(); | 297 previousBoxLength = previousBox->len(); |
298 previousBox->textRenderer()->text().appendTo(string, previousBox->start(
), previousBoxLength); | 298 previousBox->textRenderer().text().appendTo(string, previousBox->start()
, previousBoxLength); |
299 len += previousBoxLength; | 299 len += previousBoxLength; |
300 } | 300 } |
301 textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->
len()); | 301 textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->l
en()); |
302 len += textBox->len(); | 302 len += textBox->len(); |
303 | 303 |
304 return wordBreakIterator(string.data(), len); | 304 return wordBreakIterator(string.data(), len); |
305 } | 305 } |
306 | 306 |
307 static TextBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePos
ition& visiblePosition, const InlineTextBox* textBox, | 307 static TextBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePos
ition& visiblePosition, const InlineTextBox* textBox, |
308 bool& nextBoxInDifferentBlock, Vector<UChar, 1024>& string, CachedLogicallyO
rderedLeafBoxes& leafBoxes) | 308 bool& nextBoxInDifferentBlock, Vector<UChar, 1024>& string, CachedLogicallyO
rderedLeafBoxes& leafBoxes) |
309 { | 309 { |
310 nextBoxInDifferentBlock = false; | 310 nextBoxInDifferentBlock = false; |
311 | 311 |
312 // FIXME: Handle the case when we don't have an inline text box. | 312 // FIXME: Handle the case when we don't have an inline text box. |
313 const InlineTextBox* nextBox = logicallyNextBox(visiblePosition, textBox, ne
xtBoxInDifferentBlock, leafBoxes); | 313 const InlineTextBox* nextBox = logicallyNextBox(visiblePosition, textBox, ne
xtBoxInDifferentBlock, leafBoxes); |
314 | 314 |
315 int len = 0; | 315 int len = 0; |
316 string.clear(); | 316 string.clear(); |
317 textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->
len()); | 317 textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->l
en()); |
318 len += textBox->len(); | 318 len += textBox->len(); |
319 if (nextBox) { | 319 if (nextBox) { |
320 nextBox->textRenderer()->text().appendTo(string, nextBox->start(), nextB
ox->len()); | 320 nextBox->textRenderer().text().appendTo(string, nextBox->start(), nextBo
x->len()); |
321 len += nextBox->len(); | 321 len += nextBox->len(); |
322 } | 322 } |
323 | 323 |
324 return wordBreakIterator(string.data(), len); | 324 return wordBreakIterator(string.data(), len); |
325 } | 325 } |
326 | 326 |
327 static bool isLogicalStartOfWord(TextBreakIterator* iter, int position, bool har
dLineBreak) | 327 static bool isLogicalStartOfWord(TextBreakIterator* iter, int position, bool har
dLineBreak) |
328 { | 328 { |
329 bool boundary = hardLineBreak ? true : iter->isBoundary(position); | 329 bool boundary = hardLineBreak ? true : iter->isBoundary(position); |
330 if (!boundary) | 330 if (!boundary) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 int previousBoxLength = 0; | 377 int previousBoxLength = 0; |
378 bool previousBoxInDifferentBlock = false; | 378 bool previousBoxInDifferentBlock = false; |
379 bool nextBoxInDifferentBlock = false; | 379 bool nextBoxInDifferentBlock = false; |
380 bool movingIntoNewBox = previouslyVisitedBox != box; | 380 bool movingIntoNewBox = previouslyVisitedBox != box; |
381 | 381 |
382 if (offsetInBox == box->caretMinOffset()) | 382 if (offsetInBox == box->caretMinOffset()) |
383 iter = wordBreakIteratorForMinOffsetBoundary(visiblePosition, textBo
x, previousBoxLength, previousBoxInDifferentBlock, string, leafBoxes); | 383 iter = wordBreakIteratorForMinOffsetBoundary(visiblePosition, textBo
x, previousBoxLength, previousBoxInDifferentBlock, string, leafBoxes); |
384 else if (offsetInBox == box->caretMaxOffset()) | 384 else if (offsetInBox == box->caretMaxOffset()) |
385 iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBo
x, nextBoxInDifferentBlock, string, leafBoxes); | 385 iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBo
x, nextBoxInDifferentBlock, string, leafBoxes); |
386 else if (movingIntoNewBox) { | 386 else if (movingIntoNewBox) { |
387 iter = wordBreakIterator(textBox->textRenderer()->text(), textBox->s
tart(), textBox->len()); | 387 iter = wordBreakIterator(textBox->textRenderer().text(), textBox->st
art(), textBox->len()); |
388 previouslyVisitedBox = box; | 388 previouslyVisitedBox = box; |
389 } | 389 } |
390 | 390 |
391 if (!iter) | 391 if (!iter) |
392 break; | 392 break; |
393 | 393 |
394 iter->first(); | 394 iter->first(); |
395 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; | 395 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; |
396 | 396 |
397 bool isWordBreak; | 397 bool isWordBreak; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 if (!startNode) | 730 if (!startNode) |
731 return VisiblePosition(); | 731 return VisiblePosition(); |
732 } else { | 732 } else { |
733 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, | 733 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, |
734 // and so cannot be represented by a VisiblePosition. Use whatever follo
ws instead. | 734 // and so cannot be represented by a VisiblePosition. Use whatever follo
ws instead. |
735 startBox = rootBox->firstLeafChild(); | 735 startBox = rootBox->firstLeafChild(); |
736 while (true) { | 736 while (true) { |
737 if (!startBox) | 737 if (!startBox) |
738 return VisiblePosition(); | 738 return VisiblePosition(); |
739 | 739 |
740 RenderObject* startRenderer = startBox->renderer(); | 740 startNode = startBox->renderer().nonPseudoNode(); |
741 if (!startRenderer) | |
742 return VisiblePosition(); | |
743 | |
744 startNode = startRenderer->nonPseudoNode(); | |
745 if (startNode) | 741 if (startNode) |
746 break; | 742 break; |
747 | 743 |
748 startBox = startBox->nextLeafChild(); | 744 startBox = startBox->nextLeafChild(); |
749 } | 745 } |
750 } | 746 } |
751 | 747 |
752 return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode),
toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode)); | 748 return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode),
toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode)); |
753 } | 749 } |
754 | 750 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 if (!endNode) | 797 if (!endNode) |
802 return VisiblePosition(); | 798 return VisiblePosition(); |
803 } else { | 799 } else { |
804 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, | 800 // Generated content (e.g. list markers and CSS :before and :after pseud
oelements) have no corresponding DOM element, |
805 // and so cannot be represented by a VisiblePosition. Use whatever prece
des instead. | 801 // and so cannot be represented by a VisiblePosition. Use whatever prece
des instead. |
806 endBox = rootBox->lastLeafChild(); | 802 endBox = rootBox->lastLeafChild(); |
807 while (true) { | 803 while (true) { |
808 if (!endBox) | 804 if (!endBox) |
809 return VisiblePosition(); | 805 return VisiblePosition(); |
810 | 806 |
811 RenderObject* endRenderer = endBox->renderer(); | 807 endNode = endBox->renderer().nonPseudoNode(); |
812 if (!endRenderer) | |
813 return VisiblePosition(); | |
814 | |
815 endNode = endRenderer->nonPseudoNode(); | |
816 if (endNode) | 808 if (endNode) |
817 break; | 809 break; |
818 | 810 |
819 endBox = endBox->prevLeafChild(); | 811 endBox = endBox->prevLeafChild(); |
820 } | 812 } |
821 } | 813 } |
822 | 814 |
823 Position pos; | 815 Position pos; |
824 if (endNode->hasTagName(brTag)) | 816 if (endNode->hasTagName(brTag)) |
825 pos = positionBeforeNode(endNode); | 817 pos = positionBeforeNode(endNode); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 } | 892 } |
901 | 893 |
902 bool isEndOfLine(const VisiblePosition &p) | 894 bool isEndOfLine(const VisiblePosition &p) |
903 { | 895 { |
904 return p.isNotNull() && p == endOfLine(p); | 896 return p.isNotNull() && p == endOfLine(p); |
905 } | 897 } |
906 | 898 |
907 static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineB
ox* root, int lineDirectionPoint) | 899 static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineB
ox* root, int lineDirectionPoint) |
908 { | 900 { |
909 ASSERT(root); | 901 ASSERT(root); |
910 RenderBlockFlow* containingBlock = root->block(); | 902 RenderBlockFlow& containingBlock = root->block(); |
911 FloatPoint absoluteBlockPoint = containingBlock->localToAbsolute(FloatPoint(
)); | 903 FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint()
); |
912 if (containingBlock->hasOverflowClip()) | 904 if (containingBlock.hasOverflowClip()) |
913 absoluteBlockPoint -= containingBlock->scrolledContentOffset(); | 905 absoluteBlockPoint -= containingBlock.scrolledContentOffset(); |
914 | 906 |
915 if (root->block()->isHorizontalWritingMode()) | 907 if (root->block().isHorizontalWritingMode()) |
916 return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->block
DirectionPointInLine()); | 908 return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->block
DirectionPointInLine()); |
917 | 909 |
918 return IntPoint(root->blockDirectionPointInLine(), lineDirectionPoint - abso
luteBlockPoint.y()); | 910 return IntPoint(root->blockDirectionPointInLine(), lineDirectionPoint - abso
luteBlockPoint.y()); |
919 } | 911 } |
920 | 912 |
921 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
lineDirectionPoint, EditableType editableType) | 913 VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
lineDirectionPoint, EditableType editableType) |
922 { | 914 { |
923 Position p = visiblePosition.deepEquivalent(); | 915 Position p = visiblePosition.deepEquivalent(); |
924 Node* node = p.deprecatedNode(); | 916 Node* node = p.deprecatedNode(); |
925 | 917 |
(...skipping 24 matching lines...) Expand all Loading... |
950 RenderedPosition renderedPosition((VisiblePosition(position))); | 942 RenderedPosition renderedPosition((VisiblePosition(position))); |
951 root = renderedPosition.rootBox(); | 943 root = renderedPosition.rootBox(); |
952 if (!root) | 944 if (!root) |
953 return VisiblePosition(position); | 945 return VisiblePosition(position); |
954 } | 946 } |
955 } | 947 } |
956 | 948 |
957 if (root) { | 949 if (root) { |
958 // FIXME: Can be wrong for multi-column layout and with transforms. | 950 // FIXME: Can be wrong for multi-column layout and with transforms. |
959 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 951 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
960 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 952 RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
961 Node* node = renderer->node(); | 953 Node* node = renderer.node(); |
962 if (node && editingIgnoresContent(node)) | 954 if (node && editingIgnoresContent(node)) |
963 return VisiblePosition(positionInParentBeforeNode(node)); | 955 return VisiblePosition(positionInParentBeforeNode(node)); |
964 return VisiblePosition(renderer->positionForPoint(pointInLine)); | 956 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
965 } | 957 } |
966 | 958 |
967 // Could not find a previous line. This means we must already be on the firs
t line. | 959 // Could not find a previous line. This means we must already be on the firs
t line. |
968 // Move to the start of the content in this block, which effectively moves u
s | 960 // Move to the start of the content in this block, which effectively moves u
s |
969 // to the start of the line we're on. | 961 // to the start of the line we're on. |
970 Element* rootElement = node->rendererIsEditable(editableType) ? node->rootEd
itableElement(editableType) : node->document().documentElement(); | 962 Element* rootElement = node->rendererIsEditable(editableType) ? node->rootEd
itableElement(editableType) : node->document().documentElement(); |
971 if (!rootElement) | 963 if (!rootElement) |
972 return VisiblePosition(); | 964 return VisiblePosition(); |
973 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); | 965 return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM); |
974 } | 966 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 RenderedPosition renderedPosition((VisiblePosition(position))); | 1000 RenderedPosition renderedPosition((VisiblePosition(position))); |
1009 root = renderedPosition.rootBox(); | 1001 root = renderedPosition.rootBox(); |
1010 if (!root) | 1002 if (!root) |
1011 return VisiblePosition(position); | 1003 return VisiblePosition(position); |
1012 } | 1004 } |
1013 } | 1005 } |
1014 | 1006 |
1015 if (root) { | 1007 if (root) { |
1016 // FIXME: Can be wrong for multi-column layout and with transforms. | 1008 // FIXME: Can be wrong for multi-column layout and with transforms. |
1017 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); | 1009 IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(roo
t, lineDirectionPoint); |
1018 RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); | 1010 RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isE
ditablePosition(p))->renderer(); |
1019 Node* node = renderer->node(); | 1011 Node* node = renderer.node(); |
1020 if (node && editingIgnoresContent(node)) | 1012 if (node && editingIgnoresContent(node)) |
1021 return VisiblePosition(positionInParentBeforeNode(node)); | 1013 return VisiblePosition(positionInParentBeforeNode(node)); |
1022 return VisiblePosition(renderer->positionForPoint(pointInLine)); | 1014 return VisiblePosition(renderer.positionForPoint(pointInLine)); |
1023 } | 1015 } |
1024 | 1016 |
1025 // Could not find a next line. This means we must already be on the last lin
e. | 1017 // Could not find a next line. This means we must already be on the last lin
e. |
1026 // Move to the end of the content in this block, which effectively moves us | 1018 // Move to the end of the content in this block, which effectively moves us |
1027 // to the end of the line we're on. | 1019 // to the end of the line we're on. |
1028 Element* rootElement = node->rendererIsEditable(editableType) ? node->rootEd
itableElement(editableType) : node->document().documentElement(); | 1020 Element* rootElement = node->rendererIsEditable(editableType) ? node->rootEd
itableElement(editableType) : node->document().documentElement(); |
1029 if (!rootElement) | 1021 if (!rootElement) |
1030 return VisiblePosition(); | 1022 return VisiblePosition(); |
1031 return VisiblePosition(lastPositionInNode(rootElement), DOWNSTREAM); | 1023 return VisiblePosition(lastPositionInNode(rootElement), DOWNSTREAM); |
1032 } | 1024 } |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 { | 1384 { |
1393 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); | 1385 return direction == LTR ? logicalStartOfLine(c) : logicalEndOfLine(c); |
1394 } | 1386 } |
1395 | 1387 |
1396 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) | 1388 VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
ction) |
1397 { | 1389 { |
1398 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); | 1390 return direction == LTR ? logicalEndOfLine(c) : logicalStartOfLine(c); |
1399 } | 1391 } |
1400 | 1392 |
1401 } | 1393 } |
OLD | NEW |