Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(728)

Side by Side Diff: Source/core/editing/VisiblePosition.cpp

Issue 1321033002: Introduce {left,right}PositionOf() for VisiblePosition (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-28T21:59:15 Rebase after merge failure Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/editing/VisiblePosition.h ('k') | Source/core/editing/VisibleUnits.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/editing/VisiblePosition.h ('k') | Source/core/editing/VisibleUnits.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698