Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / editing / VisiblePosition.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2011 Motorola Mobility, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "core/editing/VisiblePosition.h"
29
30 #include "bindings/core/v8/ExceptionState.h"
31 #include "core/HTMLNames.h"
32 #include "core/dom/Document.h"
33 #include "core/dom/Range.h"
34 #include "core/dom/Text.h"
35 #include "core/editing/VisibleUnits.h"
36 #include "core/editing/htmlediting.h"
37 #include "core/html/HTMLElement.h"
38 #include "core/rendering/RenderBlock.h"
39 #include "core/rendering/RootInlineBox.h"
40 #include "platform/geometry/FloatQuad.h"
41 #include "wtf/text/CString.h"
42
43 #ifndef NDEBUG
44 #include <stdio.h>
45 #endif
46
47 namespace blink {
48
49 using namespace HTMLNames;
50
51 VisiblePosition::VisiblePosition(const Position &pos, EAffinity affinity)
52 {
53     init(pos, affinity);
54 }
55
56 VisiblePosition::VisiblePosition(const PositionWithAffinity& positionWithAffinity)
57 {
58     init(positionWithAffinity.position(), positionWithAffinity.affinity());
59 }
60
61 void VisiblePosition::init(const Position& position, EAffinity affinity)
62 {
63     m_affinity = affinity;
64
65     m_deepPosition = canonicalPosition(position);
66
67     // When not at a line wrap, make sure to end up with DOWNSTREAM affinity.
68     if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(position, DOWNSTREAM), *this)))
69         m_affinity = DOWNSTREAM;
70 }
71
72 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const
73 {
74     VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affinity);
75
76     switch (rule) {
77     case CanCrossEditingBoundary:
78         return next;
79     case CannotCrossEditingBoundary:
80         return honorEditingBoundaryAtOrAfter(next);
81     case CanSkipOverEditingBoundary:
82         return skipToEndOfEditingBoundary(next);
83     }
84     ASSERT_NOT_REACHED();
85     return honorEditingBoundaryAtOrAfter(next);
86 }
87
88 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) const
89 {
90     Position pos = previousVisuallyDistinctCandidate(m_deepPosition);
91
92     // return null visible position if there is no previous visible position
93     if (pos.atStartOfTree())
94         return VisiblePosition();
95
96     VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM);
97     ASSERT(prev != *this);
98
99 #if ENABLE(ASSERT)
100     // we should always be able to make the affinity DOWNSTREAM, because going previous from an
101     // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!).
102     if (prev.isNotNull() && m_affinity == UPSTREAM) {
103         VisiblePosition temp = prev;
104         temp.setAffinity(UPSTREAM);
105         ASSERT(inSameLine(temp, prev));
106     }
107 #endif
108
109     switch (rule) {
110     case CanCrossEditingBoundary:
111         return prev;
112     case CannotCrossEditingBoundary:
113         return honorEditingBoundaryAtOrBefore(prev);
114     case CanSkipOverEditingBoundary:
115         return skipToStartOfEditingBoundary(prev);
116     }
117
118     ASSERT_NOT_REACHED();
119     return honorEditingBoundaryAtOrBefore(prev);
120 }
121
122 Position VisiblePosition::leftVisuallyDistinctCandidate() const
123 {
124     Position p = m_deepPosition;
125     if (p.isNull())
126         return Position();
127
128     Position downstreamStart = p.downstream();
129     TextDirection primaryDirection = p.primaryDirection();
130
131     while (true) {
132         InlineBox* box;
133         int offset;
134         p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset);
135         if (!box)
136             return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
137
138         RenderObject* renderer = &box->renderer();
139
140         while (true) {
141             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset())
142                 return box->isLeftToRightDirection() ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
143
144             if (!renderer->node()) {
145                 box = box->prevLeafChild();
146                 if (!box)
147                     return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
148                 renderer = &box->renderer();
149                 offset = box->caretRightmostOffset();
150                 continue;
151             }
152
153             offset = box->isLeftToRightDirection() ? renderer->previousOffset(offset) : renderer->nextOffset(offset);
154
155             int caretMinOffset = box->caretMinOffset();
156             int caretMaxOffset = box->caretMaxOffset();
157
158             if (offset > caretMinOffset && offset < caretMaxOffset)
159                 break;
160
161             if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset > caretMaxOffset) {
162                 // Overshot to the left.
163                 InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
164                 if (!prevBox) {
165                     Position positionOnLeft = primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
166                     if (positionOnLeft.isNull())
167                         return Position();
168
169                     InlineBox* boxOnLeft;
170                     int offsetOnLeft;
171                     positionOnLeft.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnLeft, offsetOnLeft);
172                     if (boxOnLeft && boxOnLeft->root() == box->root())
173                         return Position();
174                     return positionOnLeft;
175                 }
176
177                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
178                 box = prevBox;
179                 renderer = &box->renderer();
180                 offset = prevBox->caretRightmostOffset();
181                 continue;
182             }
183
184             ASSERT(offset == box->caretLeftmostOffset());
185
186             unsigned char level = box->bidiLevel();
187             InlineBox* prevBox = box->prevLeafChild();
188
189             if (box->direction() == primaryDirection) {
190                 if (!prevBox) {
191                     InlineBox* logicalStart = 0;
192                     if (primaryDirection == LTR ? box->root().getLogicalStartBoxWithNode(logicalStart) : box->root().getLogicalEndBoxWithNode(logicalStart)) {
193                         box = logicalStart;
194                         renderer = &box->renderer();
195                         offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
196                     }
197                     break;
198                 }
199                 if (prevBox->bidiLevel() >= level)
200                     break;
201
202                 level = prevBox->bidiLevel();
203
204                 InlineBox* nextBox = box;
205                 do {
206                     nextBox = nextBox->nextLeafChild();
207                 } while (nextBox && nextBox->bidiLevel() > level);
208
209                 if (nextBox && nextBox->bidiLevel() == level)
210                     break;
211
212                 box = prevBox;
213                 renderer = &box->renderer();
214                 offset = box->caretRightmostOffset();
215                 if (box->direction() == primaryDirection)
216                     break;
217                 continue;
218             }
219
220             while (prevBox && !prevBox->renderer().node())
221                 prevBox = prevBox->prevLeafChild();
222
223             if (prevBox) {
224                 box = prevBox;
225                 renderer = &box->renderer();
226                 offset = box->caretRightmostOffset();
227                 if (box->bidiLevel() > level) {
228                     do {
229                         prevBox = prevBox->prevLeafChild();
230                     } while (prevBox && prevBox->bidiLevel() > level);
231
232                     if (!prevBox || prevBox->bidiLevel() < level)
233                         continue;
234                 }
235             } else {
236                 // Trailing edge of a secondary run. Set to the leading edge of the entire run.
237                 while (true) {
238                     while (InlineBox* nextBox = box->nextLeafChild()) {
239                         if (nextBox->bidiLevel() < level)
240                             break;
241                         box = nextBox;
242                     }
243                     if (box->bidiLevel() == level)
244                         break;
245                     level = box->bidiLevel();
246                     while (InlineBox* prevBox = box->prevLeafChild()) {
247                         if (prevBox->bidiLevel() < level)
248                             break;
249                         box = prevBox;
250                     }
251                     if (box->bidiLevel() == level)
252                         break;
253                     level = box->bidiLevel();
254                 }
255                 renderer = &box->renderer();
256                 offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
257             }
258             break;
259         }
260
261         p = createLegacyEditingPosition(renderer->node(), offset);
262
263         if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
264             return p;
265
266         ASSERT(p != m_deepPosition);
267     }
268 }
269
270 VisiblePosition VisiblePosition::left(bool stayInEditableContent) const
271 {
272     Position pos = leftVisuallyDistinctCandidate();
273     // FIXME: Why can't we move left from the last position in a tree?
274     if (pos.atStartOfTree() || pos.atEndOfTree())
275         return VisiblePosition();
276
277     VisiblePosition left = VisiblePosition(pos, DOWNSTREAM);
278     ASSERT(left != *this);
279
280     if (!stayInEditableContent)
281         return left;
282
283     // FIXME: This may need to do something different from "before".
284     return honorEditingBoundaryAtOrBefore(left);
285 }
286
287 Position VisiblePosition::rightVisuallyDistinctCandidate() const
288 {
289     Position p = m_deepPosition;
290     if (p.isNull())
291         return Position();
292
293     Position downstreamStart = p.downstream();
294     TextDirection primaryDirection = p.primaryDirection();
295
296     while (true) {
297         InlineBox* box;
298         int offset;
299         p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset);
300         if (!box)
301             return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
302
303         RenderObject* renderer = &box->renderer();
304
305         while (true) {
306             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset())
307                 return box->isLeftToRightDirection() ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
308
309             if (!renderer->node()) {
310                 box = box->nextLeafChild();
311                 if (!box)
312                     return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
313                 renderer = &box->renderer();
314                 offset = box->caretLeftmostOffset();
315                 continue;
316             }
317
318             offset = box->isLeftToRightDirection() ? renderer->nextOffset(offset) : renderer->previousOffset(offset);
319
320             int caretMinOffset = box->caretMinOffset();
321             int caretMaxOffset = box->caretMaxOffset();
322
323             if (offset > caretMinOffset && offset < caretMaxOffset)
324                 break;
325
326             if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset < caretMinOffset) {
327                 // Overshot to the right.
328                 InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
329                 if (!nextBox) {
330                     Position positionOnRight = primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
331                     if (positionOnRight.isNull())
332                         return Position();
333
334                     InlineBox* boxOnRight;
335                     int offsetOnRight;
336                     positionOnRight.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnRight, offsetOnRight);
337                     if (boxOnRight && boxOnRight->root() == box->root())
338                         return Position();
339                     return positionOnRight;
340                 }
341
342                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
343                 box = nextBox;
344                 renderer = &box->renderer();
345                 offset = nextBox->caretLeftmostOffset();
346                 continue;
347             }
348
349             ASSERT(offset == box->caretRightmostOffset());
350
351             unsigned char level = box->bidiLevel();
352             InlineBox* nextBox = box->nextLeafChild();
353
354             if (box->direction() == primaryDirection) {
355                 if (!nextBox) {
356                     InlineBox* logicalEnd = 0;
357                     if (primaryDirection == LTR ? box->root().getLogicalEndBoxWithNode(logicalEnd) : box->root().getLogicalStartBoxWithNode(logicalEnd)) {
358                         box = logicalEnd;
359                         renderer = &box->renderer();
360                         offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
361                     }
362                     break;
363                 }
364
365                 if (nextBox->bidiLevel() >= level)
366                     break;
367
368                 level = nextBox->bidiLevel();
369
370                 InlineBox* prevBox = box;
371                 do {
372                     prevBox = prevBox->prevLeafChild();
373                 } while (prevBox && prevBox->bidiLevel() > level);
374
375                 if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
376                     break;
377
378                 // For example, abc 123 ^ CBA or 123 ^ CBA abc
379                 box = nextBox;
380                 renderer = &box->renderer();
381                 offset = box->caretLeftmostOffset();
382                 if (box->direction() == primaryDirection)
383                     break;
384                 continue;
385             }
386
387             while (nextBox && !nextBox->renderer().node())
388                 nextBox = nextBox->nextLeafChild();
389
390             if (nextBox) {
391                 box = nextBox;
392                 renderer = &box->renderer();
393                 offset = box->caretLeftmostOffset();
394
395                 if (box->bidiLevel() > level) {
396                     do {
397                         nextBox = nextBox->nextLeafChild();
398                     } while (nextBox && nextBox->bidiLevel() > level);
399
400                     if (!nextBox || nextBox->bidiLevel() < level)
401                         continue;
402                 }
403             } else {
404                 // Trailing edge of a secondary run. Set to the leading edge of the entire run.
405                 while (true) {
406                     while (InlineBox* prevBox = box->prevLeafChild()) {
407                         if (prevBox->bidiLevel() < level)
408                             break;
409                         box = prevBox;
410                     }
411                     if (box->bidiLevel() == level)
412                         break;
413                     level = box->bidiLevel();
414                     while (InlineBox* nextBox = box->nextLeafChild()) {
415                         if (nextBox->bidiLevel() < level)
416                             break;
417                         box = nextBox;
418                     }
419                     if (box->bidiLevel() == level)
420                         break;
421                     level = box->bidiLevel();
422                 }
423                 renderer = &box->renderer();
424                 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
425             }
426             break;
427         }
428
429         p = createLegacyEditingPosition(renderer->node(), offset);
430
431         if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
432             return p;
433
434         ASSERT(p != m_deepPosition);
435     }
436 }
437
438 VisiblePosition VisiblePosition::right(bool stayInEditableContent) const
439 {
440     Position pos = rightVisuallyDistinctCandidate();
441     // FIXME: Why can't we move left from the last position in a tree?
442     if (pos.atStartOfTree() || pos.atEndOfTree())
443         return VisiblePosition();
444
445     VisiblePosition right = VisiblePosition(pos, DOWNSTREAM);
446     ASSERT(right != *this);
447
448     if (!stayInEditableContent)
449         return right;
450
451     // FIXME: This may need to do something different from "after".
452     return honorEditingBoundaryAtOrAfter(right);
453 }
454
455 VisiblePosition VisiblePosition::honorEditingBoundaryAtOrBefore(const VisiblePosition &pos) const
456 {
457     if (pos.isNull())
458         return pos;
459
460     ContainerNode* highestRoot = highestEditableRoot(deepEquivalent());
461
462     // Return empty position if pos is not somewhere inside the editable region containing this position
463     if (highestRoot && !pos.deepEquivalent().deprecatedNode()->isDescendantOf(highestRoot))
464         return VisiblePosition();
465
466     // Return pos itself if the two are from the very same editable region, or both are non-editable
467     // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
468     // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
469     if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
470         return pos;
471
472     // Return empty position if this position is non-editable, but pos is editable
473     // FIXME: Move to the previous non-editable region.
474     if (!highestRoot)
475         return VisiblePosition();
476
477     // Return the last position before pos that is in the same editable region as this position
478     return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
479 }
480
481 VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosition &pos) const
482 {
483     if (pos.isNull())
484         return pos;
485
486     ContainerNode* highestRoot = highestEditableRoot(deepEquivalent());
487
488     // Return empty position if pos is not somewhere inside the editable region containing this position
489     if (highestRoot && !pos.deepEquivalent().deprecatedNode()->isDescendantOf(highestRoot))
490         return VisiblePosition();
491
492     // Return pos itself if the two are from the very same editable region, or both are non-editable
493     // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
494     // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
495     if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
496         return pos;
497
498     // Return empty position if this position is non-editable, but pos is editable
499     // FIXME: Move to the next non-editable region.
500     if (!highestRoot)
501         return VisiblePosition();
502
503     // Return the next position after pos that is in the same editable region as this position
504     return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
505 }
506
507 VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosition &pos) const
508 {
509     if (pos.isNull())
510         return pos;
511
512     ContainerNode* highestRoot = highestEditableRoot(deepEquivalent());
513     ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent());
514
515     // Return pos itself if the two are from the very same editable region, or both are non-editable.
516     if (highestRootOfPos == highestRoot)
517         return pos;
518
519     // If |pos| has an editable root, skip to the start
520     if (highestRootOfPos)
521         return VisiblePosition(previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent()));
522
523     // That must mean that |pos| is not editable. Return the last position before pos that is in the same editable region as this position
524     return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
525 }
526
527 VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePosition &pos) const
528 {
529     if (pos.isNull())
530         return pos;
531
532     ContainerNode* highestRoot = highestEditableRoot(deepEquivalent());
533     ContainerNode* highestRootOfPos = highestEditableRoot(pos.deepEquivalent());
534
535     // Return pos itself if the two are from the very same editable region, or both are non-editable.
536     if (highestRootOfPos == highestRoot)
537         return pos;
538
539     // If |pos| has an editable root, skip to the end
540     if (highestRootOfPos)
541         return VisiblePosition(Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent());
542
543     // That must mean that |pos| is not editable. Return the next position after pos that is in the same editable region as this position
544     return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
545 }
546
547 static Position canonicalizeCandidate(const Position& candidate)
548 {
549     if (candidate.isNull())
550         return Position();
551     ASSERT(candidate.isCandidate());
552     Position upstream = candidate.upstream();
553     if (upstream.isCandidate())
554         return upstream;
555     return candidate;
556 }
557
558 Position VisiblePosition::canonicalPosition(const Position& passedPosition)
559 {
560     // The updateLayout call below can do so much that even the position passed
561     // in to us might get changed as a side effect. Specifically, there are code
562     // paths that pass selection endpoints, and updateLayout can change the selection.
563     Position position = passedPosition;
564
565     // FIXME (9535):  Canonicalizing to the leftmost candidate means that if we're at a line wrap, we will
566     // ask renderers to paint downstream carets for other renderers.
567     // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to
568     // the appropriate renderer for VisiblePosition's like these, or b) canonicalize to the rightmost candidate
569     // unless the affinity is upstream.
570     if (position.isNull())
571         return Position();
572
573     ASSERT(position.document());
574     position.document()->updateLayoutIgnorePendingStylesheets();
575
576     Node* node = position.containerNode();
577
578     Position candidate = position.upstream();
579     if (candidate.isCandidate())
580         return candidate;
581     candidate = position.downstream();
582     if (candidate.isCandidate())
583         return candidate;
584
585     // When neither upstream or downstream gets us to a candidate (upstream/downstream won't leave
586     // blocks or enter new ones), we search forward and backward until we find one.
587     Position next = canonicalizeCandidate(nextCandidate(position));
588     Position prev = canonicalizeCandidate(previousCandidate(position));
589     Node* nextNode = next.deprecatedNode();
590     Node* prevNode = prev.deprecatedNode();
591
592     // The new position must be in the same editable element. Enforce that first.
593     // Unless the descent is from a non-editable html element to an editable body.
594     if (isHTMLHtmlElement(node) && !node->hasEditableStyle() && node->document().body() && node->document().body()->hasEditableStyle())
595         return next.isNotNull() ? next : prev;
596
597     Element* editingRoot = editableRootForPosition(position);
598
599     // If the html element is editable, descending into its body will look like a descent
600     // from non-editable to editable content since rootEditableElement() always stops at the body.
601     if (isHTMLHtmlElement(editingRoot) || position.deprecatedNode()->isDocumentNode())
602         return next.isNotNull() ? next : prev;
603
604     bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
605     bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;
606     if (prevIsInSameEditableElement && !nextIsInSameEditableElement)
607         return prev;
608
609     if (nextIsInSameEditableElement && !prevIsInSameEditableElement)
610         return next;
611
612     if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)
613         return Position();
614
615     // The new position should be in the same block flow element. Favor that.
616     Element* originalBlock = node ? enclosingBlockFlowElement(*node) : 0;
617     bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) && nextNode != originalBlock;
618     bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) && prevNode != originalBlock;
619     if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock)
620         return prev;
621
622     return next;
623 }
624
625 UChar32 VisiblePosition::characterAfter() const
626 {
627     // We canonicalize to the first of two equivalent candidates, but the second of the two candidates
628     // is the one that will be inside the text node containing the character after this visible position.
629     Position pos = m_deepPosition.downstream();
630     if (!pos.containerNode() || !pos.containerNode()->isTextNode())
631         return 0;
632     switch (pos.anchorType()) {
633     case Position::PositionIsAfterChildren:
634     case Position::PositionIsAfterAnchor:
635     case Position::PositionIsBeforeAnchor:
636     case Position::PositionIsBeforeChildren:
637         return 0;
638     case Position::PositionIsOffsetInAnchor:
639         break;
640     }
641     unsigned offset = static_cast<unsigned>(pos.offsetInContainerNode());
642     Text* textNode = pos.containerText();
643     unsigned length = textNode->length();
644     if (offset >= length)
645         return 0;
646
647     return textNode->data().characterStartingAt(offset);
648 }
649
650 LayoutRect VisiblePosition::localCaretRect(RenderObject*& renderer) const
651 {
652     PositionWithAffinity positionWithAffinity(m_deepPosition, m_affinity);
653     return localCaretRectOfPosition(positionWithAffinity, renderer);
654 }
655
656 IntRect VisiblePosition::absoluteCaretBounds() const
657 {
658     RenderObject* renderer;
659     LayoutRect localRect = localCaretRect(renderer);
660     if (localRect.isEmpty() || !renderer)
661         return IntRect();
662
663     return renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
664 }
665
666 int VisiblePosition::lineDirectionPointForBlockDirectionNavigation() const
667 {
668     RenderObject* renderer;
669     LayoutRect localRect = localCaretRect(renderer);
670     if (localRect.isEmpty() || !renderer)
671         return 0;
672
673     // This ignores transforms on purpose, for now. Vertical navigation is done
674     // without consulting transforms, so that 'up' in transformed text is 'up'
675     // relative to the text, not absolute 'up'.
676     FloatPoint caretPoint = renderer->localToAbsolute(localRect.location());
677     RenderObject* containingBlock = renderer->containingBlock();
678     if (!containingBlock)
679         containingBlock = renderer; // Just use ourselves to determine the writing mode if we have no containing block.
680     return containingBlock->isHorizontalWritingMode() ? caretPoint.x() : caretPoint.y();
681 }
682
683 #ifndef NDEBUG
684
685 void VisiblePosition::debugPosition(const char* msg) const
686 {
687     if (isNull())
688         fprintf(stderr, "Position [%s]: null\n", msg);
689     else {
690         fprintf(stderr, "Position [%s]: %s, ", msg, m_deepPosition.deprecatedNode()->nodeName().utf8().data());
691         m_deepPosition.showAnchorTypeAndOffset();
692     }
693 }
694
695 void VisiblePosition::formatForDebugger(char* buffer, unsigned length) const
696 {
697     m_deepPosition.formatForDebugger(buffer, length);
698 }
699
700 void VisiblePosition::showTreeForThis() const
701 {
702     m_deepPosition.showTreeForThis();
703 }
704
705 #endif
706
707 PassRefPtrWillBeRawPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
708 {
709     if (start.isNull() || end.isNull())
710         return nullptr;
711
712     Position s = start.deepEquivalent().parentAnchoredEquivalent();
713     Position e = end.deepEquivalent().parentAnchoredEquivalent();
714     if (s.isNull() || e.isNull())
715         return nullptr;
716
717     return Range::create(s.containerNode()->document(), s.containerNode(), s.offsetInContainerNode(), e.containerNode(), e.offsetInContainerNode());
718 }
719
720 VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
721 {
722     return VisiblePosition(r->startPosition(), affinity);
723 }
724
725 bool setStart(Range *r, const VisiblePosition &visiblePosition)
726 {
727     if (!r)
728         return false;
729     Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
730     TrackExceptionState exceptionState;
731     r->setStart(p.containerNode(), p.offsetInContainerNode(), exceptionState);
732     return !exceptionState.hadException();
733 }
734
735 bool setEnd(Range *r, const VisiblePosition &visiblePosition)
736 {
737     if (!r)
738         return false;
739     Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
740     TrackExceptionState exceptionState;
741     r->setEnd(p.containerNode(), p.offsetInContainerNode(), exceptionState);
742     return !exceptionState.hadException();
743 }
744
745 Element* enclosingBlockFlowElement(const VisiblePosition& visiblePosition)
746 {
747     if (visiblePosition.isNull())
748         return 0;
749
750     return enclosingBlockFlowElement(*visiblePosition.deepEquivalent().deprecatedNode());
751 }
752
753 bool isFirstVisiblePositionInNode(const VisiblePosition& visiblePosition, const ContainerNode* node)
754 {
755     if (visiblePosition.isNull())
756         return false;
757
758     if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
759         return false;
760
761     VisiblePosition previous = visiblePosition.previous();
762     return previous.isNull() || !previous.deepEquivalent().deprecatedNode()->isDescendantOf(node);
763 }
764
765 bool isLastVisiblePositionInNode(const VisiblePosition& visiblePosition, const ContainerNode* node)
766 {
767     if (visiblePosition.isNull())
768         return false;
769
770     if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
771         return false;
772
773     VisiblePosition next = visiblePosition.next();
774     return next.isNull() || !next.deepEquivalent().deprecatedNode()->isDescendantOf(node);
775 }
776
777 void VisiblePosition::trace(Visitor* visitor)
778 {
779     visitor->trace(m_deepPosition);
780 }
781
782 }  // namespace blink
783
784 #ifndef NDEBUG
785
786 void showTree(const blink::VisiblePosition* vpos)
787 {
788     if (vpos)
789         vpos->showTreeForThis();
790 }
791
792 void showTree(const blink::VisiblePosition& vpos)
793 {
794     vpos.showTreeForThis();
795 }
796
797 #endif