| 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 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. | 3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 case CannotCrossEditingBoundary: | 108 case CannotCrossEditingBoundary: |
| 109 return visiblePosition.honorEditingBoundaryAtOrBefore(prev); | 109 return visiblePosition.honorEditingBoundaryAtOrBefore(prev); |
| 110 case CanSkipOverEditingBoundary: | 110 case CanSkipOverEditingBoundary: |
| 111 return visiblePosition.skipToStartOfEditingBoundary(prev); | 111 return visiblePosition.skipToStartOfEditingBoundary(prev); |
| 112 } | 112 } |
| 113 | 113 |
| 114 ASSERT_NOT_REACHED(); | 114 ASSERT_NOT_REACHED(); |
| 115 return visiblePosition.honorEditingBoundaryAtOrBefore(prev); | 115 return visiblePosition.honorEditingBoundaryAtOrBefore(prev); |
| 116 } | 116 } |
| 117 | 117 |
| 118 Position VisiblePosition::leftVisuallyDistinctCandidate() const | 118 // TODO(yosin) We should move |rightVisuallyDistinctCandidate()| with |
| 119 // |rightPositionOf()| to "VisibleUnits.cpp". |
| 120 static Position leftVisuallyDistinctCandidate(const VisiblePosition& visiblePosi
tion) |
| 119 { | 121 { |
| 120 Position p = m_deepPosition; | 122 const Position deepPosition = visiblePosition.deepEquivalent(); |
| 123 Position p = deepPosition; |
| 121 if (p.isNull()) | 124 if (p.isNull()) |
| 122 return Position(); | 125 return Position(); |
| 123 | 126 |
| 124 Position downstreamStart = mostForwardCaretPosition(p); | 127 Position downstreamStart = mostForwardCaretPosition(p); |
| 125 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 128 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
| 129 const TextAffinity affinity = visiblePosition.affinity(); |
| 126 | 130 |
| 127 while (true) { | 131 while (true) { |
| 128 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); | 132 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); |
| 129 InlineBox* box = boxPosition.inlineBox; | 133 InlineBox* box = boxPosition.inlineBox; |
| 130 int offset = boxPosition.offsetInBox; | 134 int offset = boxPosition.offsetInBox; |
| 131 if (!box) | 135 if (!box) |
| 132 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m
_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); | 136 return primaryDirection == LTR ? previousVisuallyDistinctCandidate(d
eepPosition) : nextVisuallyDistinctCandidate(deepPosition); |
| 133 | 137 |
| 134 LayoutObject* layoutObject = &box->layoutObject(); | 138 LayoutObject* layoutObject = &box->layoutObject(); |
| 135 | 139 |
| 136 while (true) { | 140 while (true) { |
| 137 if ((layoutObject->isReplaced() || layoutObject->isBR()) && offset =
= box->caretRightmostOffset()) | 141 if ((layoutObject->isReplaced() || layoutObject->isBR()) && offset =
= box->caretRightmostOffset()) |
| 138 return box->isLeftToRightDirection() ? previousVisuallyDistinctC
andidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); | 142 return box->isLeftToRightDirection() ? previousVisuallyDistinctC
andidate(deepPosition) : nextVisuallyDistinctCandidate(deepPosition); |
| 139 | 143 |
| 140 if (!layoutObject->node()) { | 144 if (!layoutObject->node()) { |
| 141 box = box->prevLeafChild(); | 145 box = box->prevLeafChild(); |
| 142 if (!box) | 146 if (!box) |
| 143 return primaryDirection == LTR ? previousVisuallyDistinctCan
didate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); | 147 return primaryDirection == LTR ? previousVisuallyDistinctCan
didate(deepPosition) : nextVisuallyDistinctCandidate(deepPosition); |
| 144 layoutObject = &box->layoutObject(); | 148 layoutObject = &box->layoutObject(); |
| 145 offset = box->caretRightmostOffset(); | 149 offset = box->caretRightmostOffset(); |
| 146 continue; | 150 continue; |
| 147 } | 151 } |
| 148 | 152 |
| 149 offset = box->isLeftToRightDirection() ? layoutObject->previousOffse
t(offset) : layoutObject->nextOffset(offset); | 153 offset = box->isLeftToRightDirection() ? layoutObject->previousOffse
t(offset) : layoutObject->nextOffset(offset); |
| 150 | 154 |
| 151 int caretMinOffset = box->caretMinOffset(); | 155 int caretMinOffset = box->caretMinOffset(); |
| 152 int caretMaxOffset = box->caretMaxOffset(); | 156 int caretMaxOffset = box->caretMaxOffset(); |
| 153 | 157 |
| 154 if (offset > caretMinOffset && offset < caretMaxOffset) | 158 if (offset > caretMinOffset && offset < caretMaxOffset) |
| 155 break; | 159 break; |
| 156 | 160 |
| 157 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { | 161 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { |
| 158 // Overshot to the left. | 162 // Overshot to the left. |
| 159 InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); | 163 InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak(); |
| 160 if (!prevBox) { | 164 if (!prevBox) { |
| 161 Position positionOnLeft = primaryDirection == LTR ? previous
VisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deep
Position); | 165 Position positionOnLeft = primaryDirection == LTR ? previous
VisuallyDistinctCandidate(deepPosition) : nextVisuallyDistinctCandidate(deepPosi
tion); |
| 162 if (positionOnLeft.isNull()) | 166 if (positionOnLeft.isNull()) |
| 163 return Position(); | 167 return Position(); |
| 164 | 168 |
| 165 InlineBox* boxOnLeft = computeInlineBoxPosition(positionOnLe
ft, m_affinity, primaryDirection).inlineBox; | 169 InlineBox* boxOnLeft = computeInlineBoxPosition(positionOnLe
ft, affinity, primaryDirection).inlineBox; |
| 166 if (boxOnLeft && boxOnLeft->root() == box->root()) | 170 if (boxOnLeft && boxOnLeft->root() == box->root()) |
| 167 return Position(); | 171 return Position(); |
| 168 return positionOnLeft; | 172 return positionOnLeft; |
| 169 } | 173 } |
| 170 | 174 |
| 171 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. | 175 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. |
| 172 box = prevBox; | 176 box = prevBox; |
| 173 layoutObject = &box->layoutObject(); | 177 layoutObject = &box->layoutObject(); |
| 174 offset = prevBox->caretRightmostOffset(); | 178 offset = prevBox->caretRightmostOffset(); |
| 175 continue; | 179 continue; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); | 254 offset = primaryDirection == LTR ? box->caretMinOffset() : box->
caretMaxOffset(); |
| 251 } | 255 } |
| 252 break; | 256 break; |
| 253 } | 257 } |
| 254 | 258 |
| 255 p = Position::editingPositionOf(layoutObject->node(), offset); | 259 p = Position::editingPositionOf(layoutObject->node(), offset); |
| 256 | 260 |
| 257 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) | 261 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
| 258 return p; | 262 return p; |
| 259 | 263 |
| 260 ASSERT(p != m_deepPosition); | 264 ASSERT(p != deepPosition); |
| 261 } | 265 } |
| 262 } | 266 } |
| 263 | 267 |
| 264 VisiblePosition VisiblePosition::left() const | 268 // TODO(yosin) We should move |leftPositionOf()| to "VisibleUnits.cpp". |
| 269 VisiblePosition leftPositionOf(const VisiblePosition& visiblePosition) |
| 265 { | 270 { |
| 266 Position pos = leftVisuallyDistinctCandidate(); | 271 const Position pos = leftVisuallyDistinctCandidate(visiblePosition); |
| 267 // FIXME: Why can't we move left from the last position in a tree? | 272 // TODO(yosin) Why can't we move left from the last position in a tree? |
| 268 if (pos.atStartOfTree() || pos.atEndOfTree()) | 273 if (pos.atStartOfTree() || pos.atEndOfTree()) |
| 269 return VisiblePosition(); | 274 return VisiblePosition(); |
| 270 | 275 |
| 271 VisiblePosition left = VisiblePosition(pos); | 276 VisiblePosition left = VisiblePosition(pos); |
| 272 ASSERT(left.deepEquivalent() != m_deepPosition); | 277 ASSERT(left.deepEquivalent() != visiblePosition.deepEquivalent()); |
| 273 | 278 |
| 274 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? honorEditin
gBoundaryAtOrBefore(left) : honorEditingBoundaryAtOrAfter(left); | 279 return directionOfEnclosingBlock(left.deepEquivalent()) == LTR ? visiblePosi
tion.honorEditingBoundaryAtOrBefore(left) : visiblePosition.honorEditingBoundary
AtOrAfter(left); |
| 275 } | 280 } |
| 276 | 281 |
| 277 Position VisiblePosition::rightVisuallyDistinctCandidate() const | 282 // TODO(yosin) We should move |rightVisuallyDistinctCandidate()| with |
| 283 // |rightPositionOf()| to "VisibleUnits.cpp". |
| 284 static Position rightVisuallyDistinctCandidate(const VisiblePosition& visiblePos
ition) |
| 278 { | 285 { |
| 279 Position p = m_deepPosition; | 286 const Position deepPosition = visiblePosition.deepEquivalent(); |
| 287 Position p = deepPosition; |
| 280 if (p.isNull()) | 288 if (p.isNull()) |
| 281 return Position(); | 289 return Position(); |
| 282 | 290 |
| 283 Position downstreamStart = mostForwardCaretPosition(p); | 291 Position downstreamStart = mostForwardCaretPosition(p); |
| 284 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); | 292 TextDirection primaryDirection = primaryDirectionOf(*p.anchorNode()); |
| 293 const TextAffinity affinity = visiblePosition.affinity(); |
| 285 | 294 |
| 286 while (true) { | 295 while (true) { |
| 287 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, m_affinity,
primaryDirection); | 296 InlineBoxPosition boxPosition = computeInlineBoxPosition(p, affinity, pr
imaryDirection); |
| 288 InlineBox* box = boxPosition.inlineBox; | 297 InlineBox* box = boxPosition.inlineBox; |
| 289 int offset = boxPosition.offsetInBox; | 298 int offset = boxPosition.offsetInBox; |
| 290 if (!box) | 299 if (!box) |
| 291 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_dee
pPosition) : previousVisuallyDistinctCandidate(m_deepPosition); | 300 return primaryDirection == LTR ? nextVisuallyDistinctCandidate(deepP
osition) : previousVisuallyDistinctCandidate(deepPosition); |
| 292 | 301 |
| 293 LayoutObject* layoutObject = &box->layoutObject(); | 302 LayoutObject* layoutObject = &box->layoutObject(); |
| 294 | 303 |
| 295 while (true) { | 304 while (true) { |
| 296 if ((layoutObject->isReplaced() || layoutObject->isBR()) && offset =
= box->caretLeftmostOffset()) | 305 if ((layoutObject->isReplaced() || layoutObject->isBR()) && offset =
= box->caretLeftmostOffset()) |
| 297 return box->isLeftToRightDirection() ? nextVisuallyDistinctCandi
date(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); | 306 return box->isLeftToRightDirection() ? nextVisuallyDistinctCandi
date(deepPosition) : previousVisuallyDistinctCandidate(deepPosition); |
| 298 | 307 |
| 299 if (!layoutObject->node()) { | 308 if (!layoutObject->node()) { |
| 300 box = box->nextLeafChild(); | 309 box = box->nextLeafChild(); |
| 301 if (!box) | 310 if (!box) |
| 302 return primaryDirection == LTR ? nextVisuallyDistinctCandida
te(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); | 311 return primaryDirection == LTR ? nextVisuallyDistinctCandida
te(deepPosition) : previousVisuallyDistinctCandidate(deepPosition); |
| 303 layoutObject = &box->layoutObject(); | 312 layoutObject = &box->layoutObject(); |
| 304 offset = box->caretLeftmostOffset(); | 313 offset = box->caretLeftmostOffset(); |
| 305 continue; | 314 continue; |
| 306 } | 315 } |
| 307 | 316 |
| 308 offset = box->isLeftToRightDirection() ? layoutObject->nextOffset(of
fset) : layoutObject->previousOffset(offset); | 317 offset = box->isLeftToRightDirection() ? layoutObject->nextOffset(of
fset) : layoutObject->previousOffset(offset); |
| 309 | 318 |
| 310 int caretMinOffset = box->caretMinOffset(); | 319 int caretMinOffset = box->caretMinOffset(); |
| 311 int caretMaxOffset = box->caretMaxOffset(); | 320 int caretMaxOffset = box->caretMaxOffset(); |
| 312 | 321 |
| 313 if (offset > caretMinOffset && offset < caretMaxOffset) | 322 if (offset > caretMinOffset && offset < caretMaxOffset) |
| 314 break; | 323 break; |
| 315 | 324 |
| 316 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { | 325 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { |
| 317 // Overshot to the right. | 326 // Overshot to the right. |
| 318 InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); | 327 InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak(); |
| 319 if (!nextBox) { | 328 if (!nextBox) { |
| 320 Position positionOnRight = primaryDirection == LTR ? nextVis
uallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_dee
pPosition); | 329 Position positionOnRight = primaryDirection == LTR ? nextVis
uallyDistinctCandidate(deepPosition) : previousVisuallyDistinctCandidate(deepPos
ition); |
| 321 if (positionOnRight.isNull()) | 330 if (positionOnRight.isNull()) |
| 322 return Position(); | 331 return Position(); |
| 323 | 332 |
| 324 InlineBox* boxOnRight = computeInlineBoxPosition(positionOnR
ight, m_affinity, primaryDirection).inlineBox; | 333 InlineBox* boxOnRight = computeInlineBoxPosition(positionOnR
ight, affinity, primaryDirection).inlineBox; |
| 325 if (boxOnRight && boxOnRight->root() == box->root()) | 334 if (boxOnRight && boxOnRight->root() == box->root()) |
| 326 return Position(); | 335 return Position(); |
| 327 return positionOnRight; | 336 return positionOnRight; |
| 328 } | 337 } |
| 329 | 338 |
| 330 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. | 339 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. |
| 331 box = nextBox; | 340 box = nextBox; |
| 332 layoutObject = &box->layoutObject(); | 341 layoutObject = &box->layoutObject(); |
| 333 offset = nextBox->caretLeftmostOffset(); | 342 offset = nextBox->caretLeftmostOffset(); |
| 334 continue; | 343 continue; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); | 421 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->
caretMinOffset(); |
| 413 } | 422 } |
| 414 break; | 423 break; |
| 415 } | 424 } |
| 416 | 425 |
| 417 p = Position::editingPositionOf(layoutObject->node(), offset); | 426 p = Position::editingPositionOf(layoutObject->node(), offset); |
| 418 | 427 |
| 419 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) | 428 if ((isVisuallyEquivalentCandidate(p) && mostForwardCaretPosition(p) !=
downstreamStart) || p.atStartOfTree() || p.atEndOfTree()) |
| 420 return p; | 429 return p; |
| 421 | 430 |
| 422 ASSERT(p != m_deepPosition); | 431 ASSERT(p != deepPosition); |
| 423 } | 432 } |
| 424 } | 433 } |
| 425 | 434 |
| 426 VisiblePosition VisiblePosition::right() const | 435 // TODO(yosin) We should move |rightPositionOf()| to "VisibleUnits.cpp". |
| 436 VisiblePosition rightPositionOf(const VisiblePosition& visiblePosition) |
| 427 { | 437 { |
| 428 Position pos = rightVisuallyDistinctCandidate(); | 438 const Position pos = rightVisuallyDistinctCandidate(visiblePosition); |
| 429 // FIXME: Why can't we move left from the last position in a tree? | 439 // TODO(yosin) Why can't we move left from the last position in a tree? |
| 430 if (pos.atStartOfTree() || pos.atEndOfTree()) | 440 if (pos.atStartOfTree() || pos.atEndOfTree()) |
| 431 return VisiblePosition(); | 441 return VisiblePosition(); |
| 432 | 442 |
| 433 VisiblePosition right = VisiblePosition(pos); | 443 VisiblePosition right = VisiblePosition(pos); |
| 434 ASSERT(right.deepEquivalent() != m_deepPosition); | 444 ASSERT(right.deepEquivalent() != visiblePosition.deepEquivalent()); |
| 435 | 445 |
| 436 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? honorEditi
ngBoundaryAtOrAfter(right) : honorEditingBoundaryAtOrBefore(right); | 446 return directionOfEnclosingBlock(right.deepEquivalent()) == LTR ? visiblePos
ition.honorEditingBoundaryAtOrAfter(right) : visiblePosition.honorEditingBoundar
yAtOrBefore(right); |
| 437 } | 447 } |
| 438 | 448 |
| 439 template <typename Strategy> | 449 template <typename Strategy> |
| 440 PositionWithAffinityTemplate<Strategy> honorEditingBoundaryAtOrBeforeAlgorithm(c
onst PositionWithAffinityTemplate<Strategy>& pos, const PositionAlgorithm<Strate
gy>& anchor) | 450 PositionWithAffinityTemplate<Strategy> honorEditingBoundaryAtOrBeforeAlgorithm(c
onst PositionWithAffinityTemplate<Strategy>& pos, const PositionAlgorithm<Strate
gy>& anchor) |
| 441 { | 451 { |
| 442 if (pos.isNull()) | 452 if (pos.isNull()) |
| 443 return pos; | 453 return pos; |
| 444 | 454 |
| 445 ContainerNode* highestRoot = highestEditableRoot(anchor); | 455 ContainerNode* highestRoot = highestEditableRoot(anchor); |
| 446 | 456 |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 else | 788 else |
| 779 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); | 789 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); |
| 780 } | 790 } |
| 781 | 791 |
| 782 void showTree(const blink::VisiblePosition& vpos) | 792 void showTree(const blink::VisiblePosition& vpos) |
| 783 { | 793 { |
| 784 vpos.showTreeForThis(); | 794 vpos.showTreeForThis(); |
| 785 } | 795 } |
| 786 | 796 |
| 787 #endif | 797 #endif |
| OLD | NEW |