1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/*
2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
38cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com *
4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Redistribution and use in source and binary forms, with or without
5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * modification, are permitted provided that the following conditions
6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * are met:
78cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 1. Redistributions of source code must retain the above copyright
8cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com *    notice, this list of conditions and the following disclaimer.
98cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 2. Redistributions in binary form must reproduce the above copyright
10cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com *    notice, this list of conditions and the following disclaimer in the
118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com *    documentation and/or other materials provided with the distribution.
128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com *
138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */
258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "config.h"
278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/dom/Position.h"
288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/HTMLNames.h"
308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/css/CSSComputedStyleDeclaration.h"
318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/dom/PositionIterator.h"
328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/dom/Text.h"
338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/editing/TextIterator.h"
348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/editing/VisiblePosition.h"
358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/editing/VisibleUnits.h"
368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/editing/htmlediting.h"
378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/frame/LocalFrame.h"
388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/frame/Settings.h"
398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/html/HTMLTableElement.h"
408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/rendering/InlineIterator.h"
418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/rendering/InlineTextBox.h"
428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/rendering/RenderBlock.h"
438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/rendering/RenderInline.h"
448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "core/rendering/RenderText.h"
458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "platform/Logging.h"
468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "wtf/text/CString.h"
478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "wtf/unicode/CharacterNames.h"
488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include <stdio.h>
498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comnamespace blink {
518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comusing namespace HTMLNames;
538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comstatic Node* nextRenderedEditable(Node* node)
558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com{
568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    for (node = node->nextLeafNode(); node; node = node->nextLeafNode()) {
578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        RenderObject* renderer = node->renderer();
588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        if (!renderer)
598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            continue;
608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        if (!node->hasEditableStyle())
618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            continue;
628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com        if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com            return node;
648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    }
658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com    return 0;
668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com}
678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com
688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comstatic Node* previousRenderedEditable(Node* node)
698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com{
70    for (node = node->previousLeafNode(); node; node = node->previousLeafNode()) {
71        RenderObject* renderer = node->renderer();
72        if (!renderer)
73            continue;
74        if (!node->hasEditableStyle())
75            continue;
76        if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
77            return node;
78    }
79    return 0;
80}
81
82Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset offset)
83    : m_anchorNode(anchorNode)
84    , m_offset(offset.value())
85    , m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
86    , m_isLegacyEditingPosition(true)
87{
88    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
89}
90
91Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType anchorType)
92    : m_anchorNode(anchorNode)
93    , m_offset(0)
94    , m_anchorType(anchorType)
95    , m_isLegacyEditingPosition(false)
96{
97    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
98
99    ASSERT(anchorType != PositionIsOffsetInAnchor);
100    ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
101        && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
102}
103
104Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType anchorType)
105    : m_anchorNode(anchorNode)
106    , m_offset(offset)
107    , m_anchorType(anchorType)
108    , m_isLegacyEditingPosition(false)
109{
110    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
111
112    ASSERT(anchorType == PositionIsOffsetInAnchor);
113}
114
115Position::Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset)
116    : m_anchorNode(textNode)
117    , m_offset(static_cast<int>(offset))
118    , m_anchorType(PositionIsOffsetInAnchor)
119    , m_isLegacyEditingPosition(false)
120{
121    ASSERT(m_anchorNode);
122}
123
124void Position::moveToPosition(PassRefPtrWillBeRawPtr<Node> node, int offset)
125{
126    ASSERT(!editingIgnoresContent(node.get()));
127    ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
128    m_anchorNode = node;
129    m_offset = offset;
130    if (m_isLegacyEditingPosition)
131        m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
132}
133void Position::moveToOffset(int offset)
134{
135    ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
136    m_offset = offset;
137    if (m_isLegacyEditingPosition)
138        m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
139}
140
141Node* Position::containerNode() const
142{
143    if (!m_anchorNode)
144        return 0;
145
146    switch (anchorType()) {
147    case PositionIsBeforeChildren:
148    case PositionIsAfterChildren:
149    case PositionIsOffsetInAnchor:
150        return m_anchorNode.get();
151    case PositionIsBeforeAnchor:
152    case PositionIsAfterAnchor:
153        return m_anchorNode->parentNode();
154    }
155    ASSERT_NOT_REACHED();
156    return 0;
157}
158
159Text* Position::containerText() const
160{
161    switch (anchorType()) {
162    case PositionIsOffsetInAnchor:
163        return m_anchorNode && m_anchorNode->isTextNode() ? toText(m_anchorNode) : 0;
164    case PositionIsBeforeAnchor:
165    case PositionIsAfterAnchor:
166        return 0;
167    case PositionIsBeforeChildren:
168    case PositionIsAfterChildren:
169        ASSERT(!m_anchorNode || !m_anchorNode->isTextNode());
170        return 0;
171    }
172    ASSERT_NOT_REACHED();
173    return 0;
174}
175
176int Position::computeOffsetInContainerNode() const
177{
178    if (!m_anchorNode)
179        return 0;
180
181    switch (anchorType()) {
182    case PositionIsBeforeChildren:
183        return 0;
184    case PositionIsAfterChildren:
185        return lastOffsetInNode(m_anchorNode.get());
186    case PositionIsOffsetInAnchor:
187        return minOffsetForNode(m_anchorNode.get(), m_offset);
188    case PositionIsBeforeAnchor:
189        return m_anchorNode->nodeIndex();
190    case PositionIsAfterAnchor:
191        return m_anchorNode->nodeIndex() + 1;
192    }
193    ASSERT_NOT_REACHED();
194    return 0;
195}
196
197int Position::offsetForPositionAfterAnchor() const
198{
199    ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren);
200    ASSERT(!m_isLegacyEditingPosition);
201    return lastOffsetForEditing(m_anchorNode.get());
202}
203
204// Neighbor-anchored positions are invalid DOM positions, so they need to be
205// fixed up before handing them off to the Range object.
206Position Position::parentAnchoredEquivalent() const
207{
208    if (!m_anchorNode)
209        return Position();
210
211    // FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
212    if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
213        if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get())))
214            return positionInParentBeforeNode(*m_anchorNode);
215        return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
216    }
217    if (!m_anchorNode->offsetInCharacters()
218        && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren())
219        && (editingIgnoresContent(m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get()))
220        && containerNode()) {
221        return positionInParentAfterNode(*m_anchorNode);
222    }
223
224    return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
225}
226
227Node* Position::computeNodeBeforePosition() const
228{
229    if (!m_anchorNode)
230        return 0;
231    switch (anchorType()) {
232    case PositionIsBeforeChildren:
233        return 0;
234    case PositionIsAfterChildren:
235        return m_anchorNode->lastChild();
236    case PositionIsOffsetInAnchor:
237        return m_offset ? NodeTraversal::childAt(*m_anchorNode, m_offset - 1) : 0;
238    case PositionIsBeforeAnchor:
239        return m_anchorNode->previousSibling();
240    case PositionIsAfterAnchor:
241        return m_anchorNode.get();
242    }
243    ASSERT_NOT_REACHED();
244    return 0;
245}
246
247Node* Position::computeNodeAfterPosition() const
248{
249    if (!m_anchorNode)
250        return 0;
251
252    switch (anchorType()) {
253    case PositionIsBeforeChildren:
254        return m_anchorNode->firstChild();
255    case PositionIsAfterChildren:
256        return 0;
257    case PositionIsOffsetInAnchor:
258        return NodeTraversal::childAt(*m_anchorNode, m_offset);
259    case PositionIsBeforeAnchor:
260        return m_anchorNode.get();
261    case PositionIsAfterAnchor:
262        return m_anchorNode->nextSibling();
263    }
264    ASSERT_NOT_REACHED();
265    return 0;
266}
267
268Position::AnchorType Position::anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset)
269{
270    if (anchorNode && editingIgnoresContent(anchorNode)) {
271        if (offset == 0)
272            return Position::PositionIsBeforeAnchor;
273        return Position::PositionIsAfterAnchor;
274    }
275    return Position::PositionIsOffsetInAnchor;
276}
277
278// FIXME: This method is confusing (does it return anchorNode() or containerNode()?) and should be renamed or removed
279Element* Position::element() const
280{
281    Node* node = anchorNode();
282    if (!node || node->isElementNode())
283        return toElement(node);
284    return node->parentElement();
285}
286
287PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
288{
289    Element* elem = element();
290    if (!elem)
291        return nullptr;
292    return CSSComputedStyleDeclaration::create(elem);
293}
294
295Position Position::previous(PositionMoveType moveType) const
296{
297    Node* node = deprecatedNode();
298    if (!node)
299        return *this;
300
301    int offset = deprecatedEditingOffset();
302    // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
303    ASSERT(offset >= 0);
304
305    if (offset > 0) {
306        if (Node* child = NodeTraversal::childAt(*node, offset - 1))
307            return lastPositionInOrAfterNode(child);
308
309        // There are two reasons child might be 0:
310        //   1) The node is node like a text node that is not an element, and therefore has no children.
311        //      Going backward one character at a time is correct.
312        //   2) The old offset was a bogus offset like (<br>, 1), and there is no child.
313        //      Going from 1 to 0 is correct.
314        switch (moveType) {
315        case CodePoint:
316            return createLegacyEditingPosition(node, offset - 1);
317        case Character:
318            return createLegacyEditingPosition(node, uncheckedPreviousOffset(node, offset));
319        case BackwardDeletion:
320            return createLegacyEditingPosition(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
321        }
322    }
323
324    if (ContainerNode* parent = node->parentNode())
325        return createLegacyEditingPosition(parent, node->nodeIndex());
326    return *this;
327}
328
329Position Position::next(PositionMoveType moveType) const
330{
331    ASSERT(moveType != BackwardDeletion);
332
333    Node* node = deprecatedNode();
334    if (!node)
335        return *this;
336
337    int offset = deprecatedEditingOffset();
338    // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
339    ASSERT(offset >= 0);
340
341    if (Node* child = NodeTraversal::childAt(*node, offset))
342        return firstPositionInOrBeforeNode(child);
343
344    if (!node->hasChildren() && offset < lastOffsetForEditing(node)) {
345        // There are two reasons child might be 0:
346        //   1) The node is node like a text node that is not an element, and therefore has no children.
347        //      Going forward one character at a time is correct.
348        //   2) The new offset is a bogus offset like (<br>, 1), and there is no child.
349        //      Going from 0 to 1 is correct.
350        return createLegacyEditingPosition(node, (moveType == Character) ? uncheckedNextOffset(node, offset) : offset + 1);
351    }
352
353    if (ContainerNode* parent = node->parentNode())
354        return createLegacyEditingPosition(parent, node->nodeIndex() + 1);
355    return *this;
356}
357
358int Position::uncheckedPreviousOffset(const Node* n, int current)
359{
360    return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
361}
362
363int Position::uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
364{
365    return n->renderer() ? n->renderer()->previousOffsetForBackwardDeletion(current) : current - 1;
366}
367
368int Position::uncheckedNextOffset(const Node* n, int current)
369{
370    return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
371}
372
373bool Position::atFirstEditingPositionForNode() const
374{
375    if (isNull())
376        return true;
377    // FIXME: Position before anchor shouldn't be considered as at the first editing position for node
378    // since that position resides outside of the node.
379    switch (m_anchorType) {
380    case PositionIsOffsetInAnchor:
381        return m_offset <= 0;
382    case PositionIsBeforeChildren:
383    case PositionIsBeforeAnchor:
384        return true;
385    case PositionIsAfterChildren:
386    case PositionIsAfterAnchor:
387        return !lastOffsetForEditing(deprecatedNode());
388    }
389    ASSERT_NOT_REACHED();
390    return false;
391}
392
393bool Position::atLastEditingPositionForNode() const
394{
395    if (isNull())
396        return true;
397    // FIXME: Position after anchor shouldn't be considered as at the first editing position for node
398    // since that position resides outside of the node.
399    return m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || m_offset >= lastOffsetForEditing(deprecatedNode());
400}
401
402// A position is considered at editing boundary if one of the following is true:
403// 1. It is the first position in the node and the next visually equivalent position
404//    is non editable.
405// 2. It is the last position in the node and the previous visually equivalent position
406//    is non editable.
407// 3. It is an editable position and both the next and previous visually equivalent
408//    positions are both non editable.
409bool Position::atEditingBoundary() const
410{
411    Position nextPosition = downstream(CanCrossEditingBoundary);
412    if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditableStyle())
413        return true;
414
415    Position prevPosition = upstream(CanCrossEditingBoundary);
416    if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditableStyle())
417        return true;
418
419    return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditableStyle()
420        && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditableStyle();
421}
422
423Node* Position::parentEditingBoundary() const
424{
425    if (!m_anchorNode)
426        return 0;
427
428    Node* documentElement = m_anchorNode->document().documentElement();
429    if (!documentElement)
430        return 0;
431
432    Node* boundary = m_anchorNode.get();
433    while (boundary != documentElement && boundary->nonShadowBoundaryParentNode() && m_anchorNode->hasEditableStyle() == boundary->parentNode()->hasEditableStyle())
434        boundary = boundary->nonShadowBoundaryParentNode();
435
436    return boundary;
437}
438
439
440bool Position::atStartOfTree() const
441{
442    if (isNull())
443        return true;
444    return !deprecatedNode()->parentNode() && m_offset <= 0;
445}
446
447bool Position::atEndOfTree() const
448{
449    if (isNull())
450        return true;
451    return !deprecatedNode()->parentNode() && m_offset >= lastOffsetForEditing(deprecatedNode());
452}
453
454int Position::renderedOffset() const
455{
456    if (!deprecatedNode()->isTextNode())
457        return m_offset;
458
459    if (!deprecatedNode()->renderer())
460        return m_offset;
461
462    int result = 0;
463    RenderText* textRenderer = toRenderText(deprecatedNode()->renderer());
464    for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
465        int start = box->start();
466        int end = box->start() + box->len();
467        if (m_offset < start)
468            return result;
469        if (m_offset <= end) {
470            result += m_offset - start;
471            return result;
472        }
473        result += box->len();
474    }
475    return result;
476}
477
478// Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
479// If true, adjacent candidates are visually distinct.
480// FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
481// FIXME: Share code with isCandidate, if possible.
482static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
483{
484    if (!node || !node->renderer())
485        return false;
486
487    if (!node->renderer()->isInline())
488        return true;
489
490    // Don't include inline tables.
491    if (isHTMLTableElement(*node))
492        return false;
493
494    // A Marquee elements are moving so we should assume their ends are always
495    // visibily distinct.
496    if (isHTMLMarqueeElement(*node))
497        return true;
498
499    // There is a VisiblePosition inside an empty inline-block container.
500    return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->hasChildren();
501}
502
503static Node* enclosingVisualBoundary(Node* node)
504{
505    while (node && !endsOfNodeAreVisuallyDistinctPositions(node))
506        node = node->parentNode();
507
508    return node;
509}
510
511// upstream() and downstream() want to return positions that are either in a
512// text node or at just before a non-text node.  This method checks for that.
513static bool isStreamer(const PositionIterator& pos)
514{
515    if (!pos.node())
516        return true;
517
518    if (isAtomicNode(pos.node()))
519        return true;
520
521    return pos.atStartOfNode();
522}
523
524// This function and downstream() are used for moving back and forth between visually equivalent candidates.
525// For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates
526// that map to the VisiblePosition between 'b' and the space.  This function will return the left candidate
527// and downstream() will return the right one.
528// Also, upstream() will return [boundary, 0] for any of the positions from [boundary, 0] to the first candidate
529// in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
530Position Position::upstream(EditingBoundaryCrossingRule rule) const
531{
532    Node* startNode = deprecatedNode();
533    if (!startNode)
534        return Position();
535
536    // iterate backward from there, looking for a qualified position
537    Node* boundary = enclosingVisualBoundary(startNode);
538    // FIXME: PositionIterator should respect Before and After positions.
539    PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
540    PositionIterator currentPos = lastVisible;
541    bool startEditable = startNode->hasEditableStyle();
542    Node* lastNode = startNode;
543    bool boundaryCrossed = false;
544    for (; !currentPos.atStart(); currentPos.decrement()) {
545        Node* currentNode = currentPos.node();
546
547        // Don't check for an editability change if we haven't moved to a different node,
548        // to avoid the expense of computing hasEditableStyle().
549        if (currentNode != lastNode) {
550            // Don't change editability.
551            bool currentEditable = currentNode->hasEditableStyle();
552            if (startEditable != currentEditable) {
553                if (rule == CannotCrossEditingBoundary)
554                    break;
555                boundaryCrossed = true;
556            }
557            lastNode = currentNode;
558        }
559
560        // If we've moved to a position that is visually distinct, return the last saved position. There
561        // is code below that terminates early if we're *about* to move to a visually distinct position.
562        if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
563            return lastVisible;
564
565        // skip position in unrendered or invisible node
566        RenderObject* renderer = currentNode->renderer();
567        if (!renderer || renderer->style()->visibility() != VISIBLE)
568            continue;
569
570        if (rule == CanCrossEditingBoundary && boundaryCrossed) {
571            lastVisible = currentPos;
572            break;
573        }
574
575        // track last visible streamer position
576        if (isStreamer(currentPos))
577            lastVisible = currentPos;
578
579        // Don't move past a position that is visually distinct.  We could rely on code above to terminate and
580        // return lastVisible on the next iteration, but we terminate early to avoid doing a nodeIndex() call.
581        if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.atStartOfNode())
582            return lastVisible;
583
584        // Return position after tables and nodes which have content that can be ignored.
585        if (editingIgnoresContent(currentNode) || isRenderedHTMLTableElement(currentNode)) {
586            if (currentPos.atEndOfNode())
587                return positionAfterNode(currentNode);
588            continue;
589        }
590
591        // return current position if it is in rendered text
592        if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
593            if (currentNode != startNode) {
594                // This assertion fires in layout tests in the case-transform.html test because
595                // of a mix-up between offsets in the text in the DOM tree with text in the
596                // render tree which can have a different length due to case transformation.
597                // Until we resolve that, disable this so we can run the layout tests!
598                //ASSERT(currentOffset >= renderer->caretMaxOffset());
599                return createLegacyEditingPosition(currentNode, renderer->caretMaxOffset());
600            }
601
602            unsigned textOffset = currentPos.offsetInLeafNode();
603            RenderText* textRenderer = toRenderText(renderer);
604            InlineTextBox* lastTextBox = textRenderer->lastTextBox();
605            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
606                if (textOffset <= box->start() + box->len()) {
607                    if (textOffset > box->start())
608                        return currentPos;
609                    continue;
610                }
611
612                if (box == lastTextBox || textOffset != box->start() + box->len() + 1)
613                    continue;
614
615                // The text continues on the next line only if the last text box is not on this line and
616                // none of the boxes on this line have a larger start offset.
617
618                bool continuesOnNextLine = true;
619                InlineBox* otherBox = box;
620                while (continuesOnNextLine) {
621                    otherBox = otherBox->nextLeafChild();
622                    if (!otherBox)
623                        break;
624                    if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && toInlineTextBox(otherBox)->start() > textOffset))
625                        continuesOnNextLine = false;
626                }
627
628                otherBox = box;
629                while (continuesOnNextLine) {
630                    otherBox = otherBox->prevLeafChild();
631                    if (!otherBox)
632                        break;
633                    if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && toInlineTextBox(otherBox)->start() > textOffset))
634                        continuesOnNextLine = false;
635                }
636
637                if (continuesOnNextLine)
638                    return currentPos;
639            }
640        }
641    }
642
643    return lastVisible;
644}
645
646// This function and upstream() are used for moving back and forth between visually equivalent candidates.
647// For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates
648// that map to the VisiblePosition between 'b' and the space.  This function will return the right candidate
649// and upstream() will return the left one.
650// Also, downstream() will return the last position in the last atomic node in boundary for all of the positions
651// in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPositions(boundary).
652// FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264
653Position Position::downstream(EditingBoundaryCrossingRule rule) const
654{
655    Node* startNode = deprecatedNode();
656    if (!startNode)
657        return Position();
658
659    // iterate forward from there, looking for a qualified position
660    Node* boundary = enclosingVisualBoundary(startNode);
661    // FIXME: PositionIterator should respect Before and After positions.
662    PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
663    PositionIterator currentPos = lastVisible;
664    bool startEditable = startNode->hasEditableStyle();
665    Node* lastNode = startNode;
666    bool boundaryCrossed = false;
667    for (; !currentPos.atEnd(); currentPos.increment()) {
668        Node* currentNode = currentPos.node();
669
670        // Don't check for an editability change if we haven't moved to a different node,
671        // to avoid the expense of computing hasEditableStyle().
672        if (currentNode != lastNode) {
673            // Don't change editability.
674            bool currentEditable = currentNode->hasEditableStyle();
675            if (startEditable != currentEditable) {
676                if (rule == CannotCrossEditingBoundary)
677                    break;
678                boundaryCrossed = true;
679            }
680
681            lastNode = currentNode;
682        }
683
684        // stop before going above the body, up into the head
685        // return the last visible streamer position
686        if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode())
687            break;
688
689        // Do not move to a visually distinct position.
690        if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
691            return lastVisible;
692        // Do not move past a visually disinct position.
693        // Note: The first position after the last in a node whose ends are visually distinct
694        // positions will be [boundary->parentNode(), originalBlock->nodeIndex() + 1].
695        if (boundary && boundary->parentNode() == currentNode)
696            return lastVisible;
697
698        // skip position in unrendered or invisible node
699        RenderObject* renderer = currentNode->renderer();
700        if (!renderer || renderer->style()->visibility() != VISIBLE)
701            continue;
702
703        if (rule == CanCrossEditingBoundary && boundaryCrossed) {
704            lastVisible = currentPos;
705            break;
706        }
707
708        // track last visible streamer position
709        if (isStreamer(currentPos))
710            lastVisible = currentPos;
711
712        // Return position before tables and nodes which have content that can be ignored.
713        if (editingIgnoresContent(currentNode) || isRenderedHTMLTableElement(currentNode)) {
714            if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
715                return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
716            continue;
717        }
718
719        // return current position if it is in rendered text
720        if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
721            if (currentNode != startNode) {
722                ASSERT(currentPos.atStartOfNode());
723                return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
724            }
725
726            unsigned textOffset = currentPos.offsetInLeafNode();
727            RenderText* textRenderer = toRenderText(renderer);
728            InlineTextBox* lastTextBox = textRenderer->lastTextBox();
729            for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
730                if (textOffset <= box->end()) {
731                    if (textOffset >= box->start())
732                        return currentPos;
733                    continue;
734                }
735
736                if (box == lastTextBox || textOffset != box->start() + box->len())
737                    continue;
738
739                // The text continues on the next line only if the last text box is not on this line and
740                // none of the boxes on this line have a larger start offset.
741
742                bool continuesOnNextLine = true;
743                InlineBox* otherBox = box;
744                while (continuesOnNextLine) {
745                    otherBox = otherBox->nextLeafChild();
746                    if (!otherBox)
747                        break;
748                    if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && toInlineTextBox(otherBox)->start() >= textOffset))
749                        continuesOnNextLine = false;
750                }
751
752                otherBox = box;
753                while (continuesOnNextLine) {
754                    otherBox = otherBox->prevLeafChild();
755                    if (!otherBox)
756                        break;
757                    if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && toInlineTextBox(otherBox)->start() >= textOffset))
758                        continuesOnNextLine = false;
759                }
760
761                if (continuesOnNextLine)
762                    return currentPos;
763            }
764        }
765    }
766
767    return lastVisible;
768}
769
770static int boundingBoxLogicalHeight(RenderObject *o, const IntRect &rect)
771{
772    return o->style()->isHorizontalWritingMode() ? rect.height() : rect.width();
773}
774
775bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* renderer)
776{
777    RenderObject* stop = renderer->nextInPreOrderAfterChildren();
778    for (RenderObject *o = renderer->slowFirstChild(); o && o != stop; o = o->nextInPreOrder())
779        if (o->nonPseudoNode()) {
780            if ((o->isText() && boundingBoxLogicalHeight(o, toRenderText(o)->linesBoundingBox()))
781                || (o->isBox() && toRenderBox(o)->pixelSnappedLogicalHeight())
782                || (o->isRenderInline() && isEmptyInline(o) && boundingBoxLogicalHeight(o, toRenderInline(o)->linesBoundingBox())))
783                return true;
784        }
785    return false;
786}
787
788bool Position::nodeIsUserSelectNone(Node* node)
789{
790    return node && node->renderer() && !node->renderer()->isSelectable();
791}
792
793bool Position::nodeIsUserSelectAll(const Node* node)
794{
795    return RuntimeEnabledFeatures::userSelectAllEnabled() && node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
796}
797
798Node* Position::rootUserSelectAllForNode(Node* node)
799{
800    if (!node || !nodeIsUserSelectAll(node))
801        return 0;
802    Node* parent = node->parentNode();
803    if (!parent)
804        return node;
805
806    Node* candidateRoot = node;
807    while (parent) {
808        if (!parent->renderer()) {
809            parent = parent->parentNode();
810            continue;
811        }
812        if (!nodeIsUserSelectAll(parent))
813            break;
814        candidateRoot = parent;
815        parent = candidateRoot->parentNode();
816    }
817    return candidateRoot;
818}
819
820bool Position::isCandidate() const
821{
822    if (isNull())
823        return false;
824
825    RenderObject* renderer = deprecatedNode()->renderer();
826    if (!renderer)
827        return false;
828
829    if (renderer->style()->visibility() != VISIBLE)
830        return false;
831
832    if (renderer->isBR())
833        // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor, but for now we still need to support legacy positions.
834        return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
835
836    if (renderer->isText())
837        return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
838
839    if (renderer->isSVG()) {
840        // We don't consider SVG elements are contenteditable except for
841        // associated renderer returns isText() true, e.g. RenderSVGInlineText.
842        return false;
843    }
844
845    if (isRenderedHTMLTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
846        return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
847
848    if (isHTMLHtmlElement(*m_anchorNode))
849        return false;
850
851    if (renderer->isRenderBlockFlow()) {
852        if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
853            if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
854                return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
855            return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
856        }
857    } else {
858        LocalFrame* frame = m_anchorNode->document().frame();
859        bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
860        return (caretBrowsing || m_anchorNode->hasEditableStyle()) && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
861    }
862
863    return false;
864}
865
866bool Position::inRenderedText() const
867{
868    if (isNull() || !deprecatedNode()->isTextNode())
869        return false;
870
871    RenderObject* renderer = deprecatedNode()->renderer();
872    if (!renderer)
873        return false;
874
875    RenderText *textRenderer = toRenderText(renderer);
876    for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
877        if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
878            // The offset we're looking for is before this node
879            // this means the offset must be in content that is
880            // not rendered. Return false.
881            return false;
882        }
883        if (box->containsCaretOffset(m_offset))
884            // Return false for offsets inside composed characters.
885            return m_offset == 0 || m_offset == textRenderer->nextOffset(textRenderer->previousOffset(m_offset));
886    }
887
888    return false;
889}
890
891bool Position::isRenderedCharacter() const
892{
893    if (isNull() || !deprecatedNode()->isTextNode())
894        return false;
895
896    RenderObject* renderer = deprecatedNode()->renderer();
897    if (!renderer)
898        return false;
899
900    RenderText* textRenderer = toRenderText(renderer);
901    for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
902        if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
903            // The offset we're looking for is before this node
904            // this means the offset must be in content that is
905            // not rendered. Return false.
906            return false;
907        }
908        if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
909            return true;
910    }
911
912    return false;
913}
914
915bool Position::rendersInDifferentPosition(const Position &pos) const
916{
917    if (isNull() || pos.isNull())
918        return false;
919
920    RenderObject* renderer = deprecatedNode()->renderer();
921    if (!renderer)
922        return false;
923
924    RenderObject* posRenderer = pos.deprecatedNode()->renderer();
925    if (!posRenderer)
926        return false;
927
928    if (renderer->style()->visibility() != VISIBLE ||
929        posRenderer->style()->visibility() != VISIBLE)
930        return false;
931
932    if (deprecatedNode() == pos.deprecatedNode()) {
933        if (isHTMLBRElement(*deprecatedNode()))
934            return false;
935
936        if (m_offset == pos.deprecatedEditingOffset())
937            return false;
938
939        if (!deprecatedNode()->isTextNode() && !pos.deprecatedNode()->isTextNode()) {
940            if (m_offset != pos.deprecatedEditingOffset())
941                return true;
942        }
943    }
944
945    if (isHTMLBRElement(*deprecatedNode()) && pos.isCandidate())
946        return true;
947
948    if (isHTMLBRElement(*pos.deprecatedNode()) && isCandidate())
949        return true;
950
951    if (!inSameContainingBlockFlowElement(deprecatedNode(), pos.deprecatedNode()))
952        return true;
953
954    if (deprecatedNode()->isTextNode() && !inRenderedText())
955        return false;
956
957    if (pos.deprecatedNode()->isTextNode() && !pos.inRenderedText())
958        return false;
959
960    int thisRenderedOffset = renderedOffset();
961    int posRenderedOffset = pos.renderedOffset();
962
963    if (renderer == posRenderer && thisRenderedOffset == posRenderedOffset)
964        return false;
965
966    int ignoredCaretOffset;
967    InlineBox* b1;
968    getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset);
969    InlineBox* b2;
970    pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset);
971
972    WTF_LOG(Editing, "renderer:               %p [%p]\n", renderer, b1);
973    WTF_LOG(Editing, "thisRenderedOffset:         %d\n", thisRenderedOffset);
974    WTF_LOG(Editing, "posRenderer:            %p [%p]\n", posRenderer, b2);
975    WTF_LOG(Editing, "posRenderedOffset:      %d\n", posRenderedOffset);
976    WTF_LOG(Editing, "node min/max:           %d:%d\n", caretMinOffset(deprecatedNode()), caretMaxOffset(deprecatedNode()));
977    WTF_LOG(Editing, "pos node min/max:       %d:%d\n", caretMinOffset(pos.deprecatedNode()), caretMaxOffset(pos.deprecatedNode()));
978    WTF_LOG(Editing, "----------------------------------------------------------------------\n");
979
980    if (!b1 || !b2) {
981        return false;
982    }
983
984    if (b1->root() != b2->root()) {
985        return true;
986    }
987
988    if (nextRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
989        && thisRenderedOffset == caretMaxOffset(deprecatedNode()) && !posRenderedOffset) {
990        return false;
991    }
992
993    if (previousRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
994        && !thisRenderedOffset && posRenderedOffset == caretMaxOffset(pos.deprecatedNode())) {
995        return false;
996    }
997
998    return true;
999}
1000
1001void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox, int& caretOffset) const
1002{
1003    getInlineBoxAndOffset(affinity, primaryDirection(), inlineBox, caretOffset);
1004}
1005
1006static bool isNonTextLeafChild(RenderObject* object)
1007{
1008    if (object->slowFirstChild())
1009        return false;
1010    if (object->isText())
1011        return false;
1012    return true;
1013}
1014
1015static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
1016{
1017    RenderBlock* container = renderer->containingBlock();
1018    for (RenderObject* next = renderer->nextInPreOrder(container); next; next = next->nextInPreOrder(container)) {
1019        if (next->isRenderBlock())
1020            return 0;
1021        if (next->isBR())
1022            return 0;
1023        if (isNonTextLeafChild(next))
1024            return 0;
1025        if (next->isText()) {
1026            InlineTextBox* match = 0;
1027            int minOffset = INT_MAX;
1028            for (InlineTextBox* box = toRenderText(next)->firstTextBox(); box; box = box->nextTextBox()) {
1029                int caretMinOffset = box->caretMinOffset();
1030                if (caretMinOffset < minOffset) {
1031                    match = box;
1032                    minOffset = caretMinOffset;
1033                }
1034            }
1035            if (match)
1036                return match;
1037        }
1038    }
1039    return 0;
1040}
1041
1042static Position downstreamIgnoringEditingBoundaries(Position position)
1043{
1044    Position lastPosition;
1045    while (position != lastPosition) {
1046        lastPosition = position;
1047        position = position.downstream(CanCrossEditingBoundary);
1048    }
1049    return position;
1050}
1051
1052static Position upstreamIgnoringEditingBoundaries(Position position)
1053{
1054    Position lastPosition;
1055    while (position != lastPosition) {
1056        lastPosition = position;
1057        position = position.upstream(CanCrossEditingBoundary);
1058    }
1059    return position;
1060}
1061
1062void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
1063{
1064    caretOffset = deprecatedEditingOffset();
1065    RenderObject* renderer = deprecatedNode()->renderer();
1066
1067    if (!renderer->isText()) {
1068        inlineBox = 0;
1069        if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isRenderBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
1070            // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
1071            // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
1072            // of RenderObject::createVisiblePosition().
1073            Position equivalent = downstreamIgnoringEditingBoundaries(*this);
1074            if (equivalent == *this) {
1075                equivalent = upstreamIgnoringEditingBoundaries(*this);
1076                if (equivalent == *this || downstreamIgnoringEditingBoundaries(equivalent) == *this)
1077                    return;
1078            }
1079
1080            equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
1081            return;
1082        }
1083        if (renderer->isBox()) {
1084            inlineBox = toRenderBox(renderer)->inlineBoxWrapper();
1085            if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
1086                return;
1087        }
1088    } else {
1089        RenderText* textRenderer = toRenderText(renderer);
1090
1091        InlineTextBox* box;
1092        InlineTextBox* candidate = 0;
1093
1094        for (box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
1095            int caretMinOffset = box->caretMinOffset();
1096            int caretMaxOffset = box->caretMaxOffset();
1097
1098            if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
1099                continue;
1100
1101            if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) {
1102                inlineBox = box;
1103                return;
1104            }
1105
1106            if (((caretOffset == caretMaxOffset) ^ (affinity == DOWNSTREAM))
1107                || ((caretOffset == caretMinOffset) ^ (affinity == UPSTREAM))
1108                || (caretOffset == caretMaxOffset && box->nextLeafChild() && box->nextLeafChild()->isLineBreak()))
1109                break;
1110
1111            candidate = box;
1112        }
1113        if (candidate && candidate == textRenderer->lastTextBox() && affinity == DOWNSTREAM) {
1114            box = searchAheadForBetterMatch(textRenderer);
1115            if (box)
1116                caretOffset = box->caretMinOffset();
1117        }
1118        inlineBox = box ? box : candidate;
1119    }
1120
1121    if (!inlineBox)
1122        return;
1123
1124    unsigned char level = inlineBox->bidiLevel();
1125
1126    if (inlineBox->direction() == primaryDirection) {
1127        if (caretOffset == inlineBox->caretRightmostOffset()) {
1128            InlineBox* nextBox = inlineBox->nextLeafChild();
1129            if (!nextBox || nextBox->bidiLevel() >= level)
1130                return;
1131
1132            level = nextBox->bidiLevel();
1133            InlineBox* prevBox = inlineBox;
1134            do {
1135                prevBox = prevBox->prevLeafChild();
1136            } while (prevBox && prevBox->bidiLevel() > level);
1137
1138            if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
1139                return;
1140
1141            // For example, abc 123 ^ CBA
1142            while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
1143                if (nextBox->bidiLevel() < level)
1144                    break;
1145                inlineBox = nextBox;
1146            }
1147            caretOffset = inlineBox->caretRightmostOffset();
1148        } else {
1149            InlineBox* prevBox = inlineBox->prevLeafChild();
1150            if (!prevBox || prevBox->bidiLevel() >= level)
1151                return;
1152
1153            level = prevBox->bidiLevel();
1154            InlineBox* nextBox = inlineBox;
1155            do {
1156                nextBox = nextBox->nextLeafChild();
1157            } while (nextBox && nextBox->bidiLevel() > level);
1158
1159            if (nextBox && nextBox->bidiLevel() == level)
1160                return;
1161
1162            while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
1163                if (prevBox->bidiLevel() < level)
1164                    break;
1165                inlineBox = prevBox;
1166            }
1167            caretOffset = inlineBox->caretLeftmostOffset();
1168        }
1169        return;
1170    }
1171
1172    if (caretOffset == inlineBox->caretLeftmostOffset()) {
1173        InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak();
1174        if (!prevBox || prevBox->bidiLevel() < level) {
1175            // Left edge of a secondary run. Set to the right edge of the entire run.
1176            while (InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1177                if (nextBox->bidiLevel() < level)
1178                    break;
1179                inlineBox = nextBox;
1180            }
1181            caretOffset = inlineBox->caretRightmostOffset();
1182        } else if (prevBox->bidiLevel() > level) {
1183            // Right edge of a "tertiary" run. Set to the left edge of that run.
1184            while (InlineBox* tertiaryBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1185                if (tertiaryBox->bidiLevel() <= level)
1186                    break;
1187                inlineBox = tertiaryBox;
1188            }
1189            caretOffset = inlineBox->caretLeftmostOffset();
1190        }
1191    } else if (m_anchorNode->selfOrAncestorHasDirAutoAttribute()) {
1192        if (inlineBox->bidiLevel() < level)
1193            caretOffset = inlineBox->caretLeftmostOffset();
1194        else
1195            caretOffset = inlineBox->caretRightmostOffset();
1196    } else {
1197        InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak();
1198        if (!nextBox || nextBox->bidiLevel() < level) {
1199            // Right edge of a secondary run. Set to the left edge of the entire run.
1200            while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1201                if (prevBox->bidiLevel() < level)
1202                    break;
1203                inlineBox = prevBox;
1204            }
1205            caretOffset = inlineBox->caretLeftmostOffset();
1206        } else if (nextBox->bidiLevel() > level) {
1207            // Left edge of a "tertiary" run. Set to the right edge of that run.
1208            while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1209                if (tertiaryBox->bidiLevel() <= level)
1210                    break;
1211                inlineBox = tertiaryBox;
1212            }
1213            caretOffset = inlineBox->caretRightmostOffset();
1214        }
1215    }
1216}
1217
1218TextDirection Position::primaryDirection() const
1219{
1220    TextDirection primaryDirection = LTR;
1221    for (const RenderObject* r = m_anchorNode->renderer(); r; r = r->parent()) {
1222        if (r->isRenderBlockFlow()) {
1223            primaryDirection = r->style()->direction();
1224            break;
1225        }
1226    }
1227
1228    return primaryDirection;
1229}
1230
1231void Position::trace(Visitor* visitor)
1232{
1233    visitor->trace(m_anchorNode);
1234}
1235
1236void Position::debugPosition(const char* msg) const
1237{
1238    if (isNull())
1239        fprintf(stderr, "Position [%s]: null\n", msg);
1240    else
1241        fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, deprecatedNode()->nodeName().utf8().data(), deprecatedNode(), m_offset);
1242}
1243
1244#ifndef NDEBUG
1245
1246void Position::formatForDebugger(char* buffer, unsigned length) const
1247{
1248    StringBuilder result;
1249
1250    if (isNull())
1251        result.appendLiteral("<null>");
1252    else {
1253        char s[1024];
1254        result.appendLiteral("offset ");
1255        result.appendNumber(m_offset);
1256        result.appendLiteral(" of ");
1257        deprecatedNode()->formatForDebugger(s, sizeof(s));
1258        result.append(s);
1259    }
1260
1261    strncpy(buffer, result.toString().utf8().data(), length - 1);
1262}
1263
1264void Position::showAnchorTypeAndOffset() const
1265{
1266    if (m_isLegacyEditingPosition)
1267        fputs("legacy, ", stderr);
1268    switch (anchorType()) {
1269    case PositionIsOffsetInAnchor:
1270        fputs("offset", stderr);
1271        break;
1272    case PositionIsBeforeChildren:
1273        fputs("beforeChildren", stderr);
1274        break;
1275    case PositionIsAfterChildren:
1276        fputs("afterChildren", stderr);
1277        break;
1278    case PositionIsBeforeAnchor:
1279        fputs("before", stderr);
1280        break;
1281    case PositionIsAfterAnchor:
1282        fputs("after", stderr);
1283        break;
1284    }
1285    fprintf(stderr, ", offset:%d\n", m_offset);
1286}
1287
1288void Position::showTreeForThis() const
1289{
1290    if (anchorNode()) {
1291        anchorNode()->showTreeForThis();
1292        showAnchorTypeAndOffset();
1293    }
1294}
1295
1296#endif
1297
1298
1299
1300} // namespace blink
1301
1302#ifndef NDEBUG
1303
1304void showTree(const blink::Position& pos)
1305{
1306    pos.showTreeForThis();
1307}
1308
1309void showTree(const blink::Position* pos)
1310{
1311    if (pos)
1312        pos->showTreeForThis();
1313}
1314
1315#endif
1316