Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / dom / Position.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "core/dom/Position.h"
28
29 #include "core/HTMLNames.h"
30 #include "core/css/CSSComputedStyleDeclaration.h"
31 #include "core/dom/PositionIterator.h"
32 #include "core/dom/Text.h"
33 #include "core/editing/TextIterator.h"
34 #include "core/editing/VisiblePosition.h"
35 #include "core/editing/VisibleUnits.h"
36 #include "core/editing/htmlediting.h"
37 #include "core/frame/LocalFrame.h"
38 #include "core/frame/Settings.h"
39 #include "core/html/HTMLTableElement.h"
40 #include "core/rendering/InlineIterator.h"
41 #include "core/rendering/InlineTextBox.h"
42 #include "core/rendering/RenderBlock.h"
43 #include "core/rendering/RenderInline.h"
44 #include "core/rendering/RenderText.h"
45 #include "platform/Logging.h"
46 #include "wtf/text/CString.h"
47 #include "wtf/unicode/CharacterNames.h"
48 #include <stdio.h>
49
50 namespace blink {
51
52 using namespace HTMLNames;
53
54 static Node* nextRenderedEditable(Node* node)
55 {
56     for (node = node->nextLeafNode(); node; node = node->nextLeafNode()) {
57         RenderObject* renderer = node->renderer();
58         if (!renderer)
59             continue;
60         if (!node->hasEditableStyle())
61             continue;
62         if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
63             return node;
64     }
65     return 0;
66 }
67
68 static Node* previousRenderedEditable(Node* node)
69 {
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
82 Position::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
91 Position::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
104 Position::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
115 Position::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
124 void 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 }
133 void 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
141 Node* 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
159 Text* 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
176 int 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
197 int 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.
206 Position 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
227 Node* 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
247 Node* 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
268 Position::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
279 Element* Position::element() const
280 {
281     Node* n = anchorNode();
282     while (n && !n->isElementNode())
283         n = n->parentNode();
284     return toElement(n);
285 }
286
287 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
288 {
289     Element* elem = element();
290     if (!elem)
291         return nullptr;
292     return CSSComputedStyleDeclaration::create(elem);
293 }
294
295 Position 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
329 Position 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
358 int Position::uncheckedPreviousOffset(const Node* n, int current)
359 {
360     return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
361 }
362
363 int Position::uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
364 {
365     return n->renderer() ? n->renderer()->previousOffsetForBackwardDeletion(current) : current - 1;
366 }
367
368 int Position::uncheckedNextOffset(const Node* n, int current)
369 {
370     return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
371 }
372
373 bool 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
393 bool 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.
409 bool 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
423 Node* 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
440 bool Position::atStartOfTree() const
441 {
442     if (isNull())
443         return true;
444     return !deprecatedNode()->parentNode() && m_offset <= 0;
445 }
446
447 bool Position::atEndOfTree() const
448 {
449     if (isNull())
450         return true;
451     return !deprecatedNode()->parentNode() && m_offset >= lastOffsetForEditing(deprecatedNode());
452 }
453
454 int 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.
482 static 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
503 static 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.
513 static 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.
530 Position 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
653 Position 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
770 static int boundingBoxLogicalHeight(RenderObject *o, const IntRect &rect)
771 {
772     return o->style()->isHorizontalWritingMode() ? rect.height() : rect.width();
773 }
774
775 bool 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
788 bool Position::nodeIsUserSelectNone(Node* node)
789 {
790     return node && node->renderer() && !node->renderer()->isSelectable();
791 }
792
793 bool Position::nodeIsUserSelectAll(const Node* node)
794 {
795     return RuntimeEnabledFeatures::userSelectAllEnabled() && node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
796 }
797
798 Node* 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
820 bool 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
866 bool 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
891 bool 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
915 bool 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
1001 void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox, int& caretOffset) const
1002 {
1003     getInlineBoxAndOffset(affinity, primaryDirection(), inlineBox, caretOffset);
1004 }
1005
1006 static bool isNonTextLeafChild(RenderObject* object)
1007 {
1008     if (object->slowFirstChild())
1009         return false;
1010     if (object->isText())
1011         return false;
1012     return true;
1013 }
1014
1015 static 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
1042 static 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
1052 static 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
1062 void 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 {
1192         InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak();
1193         if (!nextBox || nextBox->bidiLevel() < level) {
1194             // Right edge of a secondary run. Set to the left edge of the entire run.
1195             while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
1196                 if (prevBox->bidiLevel() < level)
1197                     break;
1198                 inlineBox = prevBox;
1199             }
1200             if (m_anchorNode->selfOrAncestorHasDirAutoAttribute())
1201                 caretOffset = inlineBox->bidiLevel() < level ? inlineBox->caretLeftmostOffset() : inlineBox->caretRightmostOffset();
1202             else
1203                 caretOffset = inlineBox->caretLeftmostOffset();
1204         } else if (nextBox->bidiLevel() > level) {
1205             // Left edge of a "tertiary" run. Set to the right edge of that run.
1206             while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
1207                 if (tertiaryBox->bidiLevel() <= level)
1208                     break;
1209                 inlineBox = tertiaryBox;
1210             }
1211             caretOffset = inlineBox->caretRightmostOffset();
1212         }
1213     }
1214 }
1215
1216 TextDirection Position::primaryDirection() const
1217 {
1218     TextDirection primaryDirection = LTR;
1219     for (const RenderObject* r = m_anchorNode->renderer(); r; r = r->parent()) {
1220         if (r->isRenderBlockFlow()) {
1221             primaryDirection = r->style()->direction();
1222             break;
1223         }
1224     }
1225
1226     return primaryDirection;
1227 }
1228
1229 void Position::trace(Visitor* visitor)
1230 {
1231     visitor->trace(m_anchorNode);
1232 }
1233
1234 void Position::debugPosition(const char* msg) const
1235 {
1236     if (isNull())
1237         fprintf(stderr, "Position [%s]: null\n", msg);
1238     else
1239         fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, deprecatedNode()->nodeName().utf8().data(), deprecatedNode(), m_offset);
1240 }
1241
1242 #ifndef NDEBUG
1243
1244 void Position::formatForDebugger(char* buffer, unsigned length) const
1245 {
1246     StringBuilder result;
1247
1248     if (isNull())
1249         result.appendLiteral("<null>");
1250     else {
1251         char s[1024];
1252         result.appendLiteral("offset ");
1253         result.appendNumber(m_offset);
1254         result.appendLiteral(" of ");
1255         deprecatedNode()->formatForDebugger(s, sizeof(s));
1256         result.append(s);
1257     }
1258
1259     strncpy(buffer, result.toString().utf8().data(), length - 1);
1260 }
1261
1262 void Position::showAnchorTypeAndOffset() const
1263 {
1264     if (m_isLegacyEditingPosition)
1265         fputs("legacy, ", stderr);
1266     switch (anchorType()) {
1267     case PositionIsOffsetInAnchor:
1268         fputs("offset", stderr);
1269         break;
1270     case PositionIsBeforeChildren:
1271         fputs("beforeChildren", stderr);
1272         break;
1273     case PositionIsAfterChildren:
1274         fputs("afterChildren", stderr);
1275         break;
1276     case PositionIsBeforeAnchor:
1277         fputs("before", stderr);
1278         break;
1279     case PositionIsAfterAnchor:
1280         fputs("after", stderr);
1281         break;
1282     }
1283     fprintf(stderr, ", offset:%d\n", m_offset);
1284 }
1285
1286 void Position::showTreeForThis() const
1287 {
1288     if (anchorNode()) {
1289         anchorNode()->showTreeForThis();
1290         showAnchorTypeAndOffset();
1291     }
1292 }
1293
1294 #endif
1295
1296
1297
1298 } // namespace blink
1299
1300 #ifndef NDEBUG
1301
1302 void showTree(const blink::Position& pos)
1303 {
1304     pos.showTreeForThis();
1305 }
1306
1307 void showTree(const blink::Position* pos)
1308 {
1309     if (pos)
1310         pos->showTreeForThis();
1311 }
1312
1313 #endif