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/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
47namespace WebCore {
48
49using namespace HTMLNames;
50
51VisiblePosition::VisiblePosition(const Position &pos, EAffinity affinity)
52{
53    init(pos, affinity);
54}
55
56VisiblePosition::VisiblePosition(const PositionWithAffinity& positionWithAffinity)
57{
58    init(positionWithAffinity.position(), positionWithAffinity.affinity());
59}
60
61void 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
72VisiblePosition 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
88VisiblePosition 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#ifndef NDEBUG
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
122Position 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
270VisiblePosition 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
287Position 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
438VisiblePosition 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
455VisiblePosition VisiblePosition::honorEditingBoundaryAtOrBefore(const VisiblePosition &pos) const
456{
457    if (pos.isNull())
458        return pos;
459
460    Node* 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
481VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosition &pos) const
482{
483    if (pos.isNull())
484        return pos;
485
486    Node* 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
507VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosition &pos) const
508{
509    if (pos.isNull())
510        return pos;
511
512    Node* highestRoot = highestEditableRoot(deepEquivalent());
513    Node* 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
527VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePosition &pos) const
528{
529    if (pos.isNull())
530        return pos;
531
532    Node* highestRoot = highestEditableRoot(deepEquivalent());
533    Node* 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
547static 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
558Position 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->rendererIsEditable() && node->document().body() && node->document().body()->rendererIsEditable())
595        return next.isNotNull() ? next : prev;
596
597    Node* 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    Node* originalBlock = node ? node->enclosingBlockFlowElement() : 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
625UChar32 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
650LayoutRect VisiblePosition::localCaretRect(RenderObject*& renderer) const
651{
652    if (m_deepPosition.isNull()) {
653        renderer = 0;
654        return IntRect();
655    }
656    Node* node = m_deepPosition.anchorNode();
657
658    renderer = node->renderer();
659    if (!renderer)
660        return LayoutRect();
661
662    InlineBox* inlineBox;
663    int caretOffset;
664    getInlineBoxAndOffset(inlineBox, caretOffset);
665
666    if (inlineBox)
667        renderer = &inlineBox->renderer();
668
669    return renderer->localCaretRect(inlineBox, caretOffset);
670}
671
672IntRect VisiblePosition::absoluteCaretBounds() const
673{
674    RenderObject* renderer;
675    LayoutRect localRect = localCaretRect(renderer);
676    if (localRect.isEmpty() || !renderer)
677        return IntRect();
678
679    return renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
680}
681
682int VisiblePosition::lineDirectionPointForBlockDirectionNavigation() const
683{
684    RenderObject* renderer;
685    LayoutRect localRect = localCaretRect(renderer);
686    if (localRect.isEmpty() || !renderer)
687        return 0;
688
689    // This ignores transforms on purpose, for now. Vertical navigation is done
690    // without consulting transforms, so that 'up' in transformed text is 'up'
691    // relative to the text, not absolute 'up'.
692    FloatPoint caretPoint = renderer->localToAbsolute(localRect.location());
693    RenderObject* containingBlock = renderer->containingBlock();
694    if (!containingBlock)
695        containingBlock = renderer; // Just use ourselves to determine the writing mode if we have no containing block.
696    return containingBlock->isHorizontalWritingMode() ? caretPoint.x() : caretPoint.y();
697}
698
699#ifndef NDEBUG
700
701void VisiblePosition::debugPosition(const char* msg) const
702{
703    if (isNull())
704        fprintf(stderr, "Position [%s]: null\n", msg);
705    else {
706        fprintf(stderr, "Position [%s]: %s, ", msg, m_deepPosition.deprecatedNode()->nodeName().utf8().data());
707        m_deepPosition.showAnchorTypeAndOffset();
708    }
709}
710
711void VisiblePosition::formatForDebugger(char* buffer, unsigned length) const
712{
713    m_deepPosition.formatForDebugger(buffer, length);
714}
715
716void VisiblePosition::showTreeForThis() const
717{
718    m_deepPosition.showTreeForThis();
719}
720
721#endif
722
723PassRefPtrWillBeRawPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
724{
725    if (start.isNull() || end.isNull())
726        return nullptr;
727
728    Position s = start.deepEquivalent().parentAnchoredEquivalent();
729    Position e = end.deepEquivalent().parentAnchoredEquivalent();
730    if (s.isNull() || e.isNull())
731        return nullptr;
732
733    return Range::create(s.containerNode()->document(), s.containerNode(), s.offsetInContainerNode(), e.containerNode(), e.offsetInContainerNode());
734}
735
736VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
737{
738    return VisiblePosition(r->startPosition(), affinity);
739}
740
741bool setStart(Range *r, const VisiblePosition &visiblePosition)
742{
743    if (!r)
744        return false;
745    Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
746    TrackExceptionState exceptionState;
747    r->setStart(p.containerNode(), p.offsetInContainerNode(), exceptionState);
748    return !exceptionState.hadException();
749}
750
751bool setEnd(Range *r, const VisiblePosition &visiblePosition)
752{
753    if (!r)
754        return false;
755    Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
756    TrackExceptionState exceptionState;
757    r->setEnd(p.containerNode(), p.offsetInContainerNode(), exceptionState);
758    return !exceptionState.hadException();
759}
760
761Element* enclosingBlockFlowElement(const VisiblePosition &visiblePosition)
762{
763    if (visiblePosition.isNull())
764        return NULL;
765
766    return visiblePosition.deepEquivalent().deprecatedNode()->enclosingBlockFlowElement();
767}
768
769bool isFirstVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node)
770{
771    if (visiblePosition.isNull())
772        return false;
773
774    if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
775        return false;
776
777    VisiblePosition previous = visiblePosition.previous();
778    return previous.isNull() || !previous.deepEquivalent().deprecatedNode()->isDescendantOf(node);
779}
780
781bool isLastVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node)
782{
783    if (visiblePosition.isNull())
784        return false;
785
786    if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
787        return false;
788
789    VisiblePosition next = visiblePosition.next();
790    return next.isNull() || !next.deepEquivalent().deprecatedNode()->isDescendantOf(node);
791}
792
793void VisiblePosition::trace(Visitor* visitor)
794{
795    visitor->trace(m_deepPosition);
796}
797
798}  // namespace WebCore
799
800#ifndef NDEBUG
801
802void showTree(const WebCore::VisiblePosition* vpos)
803{
804    if (vpos)
805        vpos->showTreeForThis();
806}
807
808void showTree(const WebCore::VisiblePosition& vpos)
809{
810    vpos.showTreeForThis();
811}
812
813#endif
814