initial import
[vuplus_webkit] / Source / WebCore / 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 "Position.h"
28
29 #include "CSSComputedStyleDeclaration.h"
30 #include "HTMLNames.h"
31 #include "InlineTextBox.h"
32 #include "Logging.h"
33 #include "PositionIterator.h"
34 #include "RenderBlock.h"
35 #include "RenderText.h"
36 #include "Text.h"
37 #include "TextIterator.h"
38 #include "VisiblePosition.h"
39 #include "htmlediting.h"
40 #include "visible_units.h"
41 #include <stdio.h>
42 #include <wtf/text/CString.h>
43 #include <wtf/unicode/CharacterNames.h>
44   
45 namespace WebCore {
46
47 using namespace HTMLNames;
48
49 static Node* nextRenderedEditable(Node* node)
50 {
51     while ((node = node->nextLeafNode())) {
52         if (!node->rendererIsEditable())
53             continue;
54         RenderObject* renderer = node->renderer();
55         if (!renderer)
56             continue;
57         if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
58             return node;
59     }
60     return 0;
61 }
62
63 static Node* previousRenderedEditable(Node* node)
64 {
65     while ((node = node->previousLeafNode())) {
66         if (!node->rendererIsEditable())
67             continue;
68         RenderObject* renderer = node->renderer();
69         if (!renderer)
70             continue;
71         if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
72             return node;
73     }
74     return 0;
75 }
76
77 Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
78     : m_anchorNode(anchorNode)
79     , m_offset(offset.value())
80     , m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
81     , m_isLegacyEditingPosition(true)
82 {
83     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
84 }
85
86 Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
87     : m_anchorNode(anchorNode)
88     , m_offset(0)
89     , m_anchorType(anchorType)
90     , m_isLegacyEditingPosition(false)
91 {
92     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
93     ASSERT(anchorType != PositionIsOffsetInAnchor);
94     ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
95         && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
96 }
97
98 Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
99     : m_anchorNode(anchorNode)
100     , m_offset(offset)
101     , m_anchorType(anchorType)
102     , m_isLegacyEditingPosition(false)
103 {
104     ASSERT(!m_anchorNode || !editingIgnoresContent(m_anchorNode.get()) || !m_anchorNode->isShadowRoot());
105     ASSERT(anchorType == PositionIsOffsetInAnchor);
106 }
107
108 Position::Position(PassRefPtr<Text> textNode, unsigned offset)
109     : m_anchorNode(textNode)
110     , m_offset(static_cast<int>(offset))
111     , m_anchorType(PositionIsOffsetInAnchor)
112     , m_isLegacyEditingPosition(false)
113 {
114     ASSERT(m_anchorNode);
115 }
116
117 void Position::moveToPosition(PassRefPtr<Node> node, int offset)
118 {
119     ASSERT(!editingIgnoresContent(node.get()));
120     ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
121     m_anchorNode = node;
122     m_offset = offset;
123     if (m_isLegacyEditingPosition)
124         m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
125 }
126 void Position::moveToOffset(int offset)
127 {
128     ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
129     m_offset = offset;
130     if (m_isLegacyEditingPosition)
131         m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset);
132 }
133
134 Node* Position::containerNode() const
135 {
136     if (!m_anchorNode)
137         return 0;
138
139     switch (anchorType()) {
140     case PositionIsBeforeChildren:
141     case PositionIsAfterChildren:
142     case PositionIsOffsetInAnchor:
143         return m_anchorNode.get();
144     case PositionIsBeforeAnchor:
145     case PositionIsAfterAnchor:
146         return m_anchorNode->nonShadowBoundaryParentNode();
147     }
148     ASSERT_NOT_REACHED();
149     return 0;
150 }
151
152 Text* Position::containerText() const
153 {
154     switch (anchorType()) {
155     case PositionIsOffsetInAnchor:
156         return m_anchorNode && m_anchorNode->isTextNode() ? static_cast<Text*>(m_anchorNode.get()) : 0;
157     case PositionIsBeforeAnchor:
158     case PositionIsAfterAnchor:
159         return 0;
160     case PositionIsBeforeChildren:
161     case PositionIsAfterChildren:
162         ASSERT(!m_anchorNode || !m_anchorNode->isTextNode());
163         return 0;
164     }
165     ASSERT_NOT_REACHED();
166     return 0;
167 }
168
169 int Position::computeOffsetInContainerNode() const
170 {
171     if (!m_anchorNode)
172         return 0;
173
174     switch (anchorType()) {
175     case PositionIsBeforeChildren:
176         return 0;
177     case PositionIsAfterChildren:
178         return lastOffsetInNode(m_anchorNode.get());
179     case PositionIsOffsetInAnchor:
180         return std::min(lastOffsetInNode(m_anchorNode.get()), m_offset);
181     case PositionIsBeforeAnchor:
182         return m_anchorNode->nodeIndex();
183     case PositionIsAfterAnchor:
184         return m_anchorNode->nodeIndex() + 1;
185     }
186     ASSERT_NOT_REACHED();
187     return 0;
188 }
189
190 int Position::offsetForPositionAfterAnchor() const
191 {
192     ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren);
193     ASSERT(!m_isLegacyEditingPosition);
194     return lastOffsetForEditing(m_anchorNode.get());
195 }
196
197 // Neighbor-anchored positions are invalid DOM positions, so they need to be
198 // fixed up before handing them off to the Range object.
199 Position Position::parentAnchoredEquivalent() const
200 {
201     if (!m_anchorNode)
202         return Position();
203     
204     // FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
205     if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
206         if (m_anchorNode->nonShadowBoundaryParentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
207             return positionInParentBeforeNode(m_anchorNode.get());
208         return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
209     }
210     if (!m_anchorNode->offsetInCharacters()
211         && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount())
212         && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get()))
213         && containerNode()) {
214         return positionInParentAfterNode(m_anchorNode.get());
215     }
216
217     return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
218 }
219
220 Node* Position::computeNodeBeforePosition() const
221 {
222     if (!m_anchorNode)
223         return 0;
224
225     switch (anchorType()) {
226     case PositionIsBeforeChildren:
227         return 0;
228     case PositionIsAfterChildren:
229         return m_anchorNode->lastChild();
230     case PositionIsOffsetInAnchor:
231         return m_anchorNode->childNode(m_offset - 1); // -1 converts to childNode((unsigned)-1) and returns null.
232     case PositionIsBeforeAnchor:
233         return m_anchorNode->previousSibling();
234     case PositionIsAfterAnchor:
235         return m_anchorNode.get();
236     }
237     ASSERT_NOT_REACHED();
238     return 0;
239 }
240
241 Node* Position::computeNodeAfterPosition() const
242 {
243     if (!m_anchorNode)
244         return 0;
245
246     switch (anchorType()) {
247     case PositionIsBeforeChildren:
248         return m_anchorNode->firstChild();
249     case PositionIsAfterChildren:
250         return 0;
251     case PositionIsOffsetInAnchor:
252         return m_anchorNode->childNode(m_offset);
253     case PositionIsBeforeAnchor:
254         return m_anchorNode.get();
255     case PositionIsAfterAnchor:
256         return m_anchorNode->nextSibling();
257     }
258     ASSERT_NOT_REACHED();
259     return 0;
260 }
261
262 Position::AnchorType Position::anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset)
263 {
264     if (anchorNode && editingIgnoresContent(anchorNode)) {
265         if (offset == 0)
266             return Position::PositionIsBeforeAnchor;
267         return Position::PositionIsAfterAnchor;
268     }
269     return Position::PositionIsOffsetInAnchor;
270 }
271
272 // FIXME: This method is confusing (does it return anchorNode() or containerNode()?) and should be renamed or removed
273 Element* Position::element() const
274 {
275     Node* n = anchorNode();
276     while (n && !n->isElementNode())
277         n = n->parentNode();
278     return static_cast<Element*>(n);
279 }
280
281 PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
282 {
283     Element* elem = element();
284     if (!elem)
285         return 0;
286     return WebCore::computedStyle(elem);
287 }
288
289 Position Position::previous(PositionMoveType moveType) const
290 {
291     Node* n = deprecatedNode();
292     if (!n)
293         return *this;
294
295     int o = deprecatedEditingOffset();
296     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
297     ASSERT(o >= 0);
298
299     if (o > 0) {
300         Node* child = n->childNode(o - 1);
301         if (child)
302             return lastPositionInOrAfterNode(child);
303
304         // There are two reasons child might be 0:
305         //   1) The node is node like a text node that is not an element, and therefore has no children.
306         //      Going backward one character at a time is correct.
307         //   2) The old offset was a bogus offset like (<br>, 1), and there is no child.
308         //      Going from 1 to 0 is correct.
309         switch (moveType) {
310         case CodePoint:
311             return createLegacyEditingPosition(n, o - 1);
312         case Character:
313             return createLegacyEditingPosition(n, uncheckedPreviousOffset(n, o));
314         case BackwardDeletion:
315             return createLegacyEditingPosition(n, uncheckedPreviousOffsetForBackwardDeletion(n, o));
316         }
317     }
318
319     ContainerNode* parent = n->nonShadowBoundaryParentNode();
320     if (!parent)
321         return *this;
322
323     return createLegacyEditingPosition(parent, n->nodeIndex());
324 }
325
326 Position Position::next(PositionMoveType moveType) const
327 {
328     ASSERT(moveType != BackwardDeletion);
329
330     Node* n = deprecatedNode();
331     if (!n)
332         return *this;
333
334     int o = deprecatedEditingOffset();
335     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
336     ASSERT(o >= 0);
337
338     Node* child = n->childNode(o);
339     if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
340         if (child)
341             return firstPositionInOrBeforeNode(child);
342
343         // There are two reasons child might be 0:
344         //   1) The node is node like a text node that is not an element, and therefore has no children.
345         //      Going forward one character at a time is correct.
346         //   2) The new offset is a bogus offset like (<br>, 1), and there is no child.
347         //      Going from 0 to 1 is correct.
348         return createLegacyEditingPosition(n, (moveType == Character) ? uncheckedNextOffset(n, o) : o + 1);
349     }
350
351     ContainerNode* parent = n->nonShadowBoundaryParentNode();
352     if (!parent)
353         return *this;
354
355     return createLegacyEditingPosition(parent, n->nodeIndex() + 1);
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()->rendererIsEditable())
413         return true;
414         
415     Position prevPosition = upstream(CanCrossEditingBoundary);
416     if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->rendererIsEditable())
417         return true;
418         
419     return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->rendererIsEditable()
420         && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->rendererIsEditable();
421 }
422
423 Node* Position::parentEditingBoundary() const
424 {
425     if (!m_anchorNode || !m_anchorNode->document())
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->rendererIsEditable() == boundary->parentNode()->rendererIsEditable())
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()->nonShadowBoundaryParentNode() && m_offset <= 0;
445 }
446
447 bool Position::atEndOfTree() const
448 {
449     if (isNull())
450         return true;
451     return !deprecatedNode()->nonShadowBoundaryParentNode() && 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 // return first preceding DOM position rendered at a different location, or "this"
479 Position Position::previousCharacterPosition(EAffinity affinity) const
480 {
481     if (isNull())
482         return Position();
483
484     Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
485
486     bool atStartOfLine = isStartOfLine(VisiblePosition(*this, affinity));
487     bool rendered = isCandidate();
488     
489     Position currentPos = *this;
490     while (!currentPos.atStartOfTree()) {
491         currentPos = currentPos.previous();
492
493         if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
494             return *this;
495
496         if (atStartOfLine || !rendered) {
497             if (currentPos.isCandidate())
498                 return currentPos;
499         } else if (rendersInDifferentPosition(currentPos))
500             return currentPos;
501     }
502     
503     return *this;
504 }
505
506 // return first following position rendered at a different location, or "this"
507 Position Position::nextCharacterPosition(EAffinity affinity) const
508 {
509     if (isNull())
510         return Position();
511
512     Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
513
514     bool atEndOfLine = isEndOfLine(VisiblePosition(*this, affinity));
515     bool rendered = isCandidate();
516     
517     Position currentPos = *this;
518     while (!currentPos.atEndOfTree()) {
519         currentPos = currentPos.next();
520
521         if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
522             return *this;
523
524         if (atEndOfLine || !rendered) {
525             if (currentPos.isCandidate())
526                 return currentPos;
527         } else if (rendersInDifferentPosition(currentPos))
528             return currentPos;
529     }
530     
531     return *this;
532 }
533
534 // Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
535 // If true, adjacent candidates are visually distinct.
536 // FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
537 // FIXME: Share code with isCandidate, if possible.
538 static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
539 {
540     if (!node || !node->renderer())
541         return false;
542         
543     if (!node->renderer()->isInline())
544         return true;
545         
546     // Don't include inline tables.
547     if (node->hasTagName(tableTag))
548         return false;
549     
550     // There is a VisiblePosition inside an empty inline-block container.
551     return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
552 }
553
554 static Node* enclosingVisualBoundary(Node* node)
555 {
556     while (node && !endsOfNodeAreVisuallyDistinctPositions(node))
557         node = node->parentNode();
558         
559     return node;
560 }
561
562 // upstream() and downstream() want to return positions that are either in a
563 // text node or at just before a non-text node.  This method checks for that.
564 static bool isStreamer(const PositionIterator& pos)
565 {
566     if (!pos.node())
567         return true;
568         
569     if (isAtomicNode(pos.node()))
570         return true;
571         
572     return pos.atStartOfNode();
573 }
574
575 // This function and downstream() are used for moving back and forth between visually equivalent candidates.
576 // For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates 
577 // that map to the VisiblePosition between 'b' and the space.  This function will return the left candidate 
578 // and downstream() will return the right one.
579 // Also, upstream() will return [boundary, 0] for any of the positions from [boundary, 0] to the first candidate
580 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
581 Position Position::upstream(EditingBoundaryCrossingRule rule) const
582 {
583     Node* startNode = deprecatedNode();
584     if (!startNode)
585         return Position();
586     
587     // iterate backward from there, looking for a qualified position
588     Node* boundary = enclosingVisualBoundary(startNode);
589     // FIXME: PositionIterator should respect Before and After positions.
590     PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
591     PositionIterator currentPos = lastVisible;
592     bool startEditable = startNode->rendererIsEditable();
593     Node* lastNode = startNode;
594     bool boundaryCrossed = false;
595     for (; !currentPos.atStart(); currentPos.decrement()) {
596         Node* currentNode = currentPos.node();
597         
598         // Don't check for an editability change if we haven't moved to a different node,
599         // to avoid the expense of computing rendererIsEditable().
600         if (currentNode != lastNode) {
601             // Don't change editability.
602             bool currentEditable = currentNode->rendererIsEditable();
603             if (startEditable != currentEditable) {
604                 if (rule == CannotCrossEditingBoundary)
605                     break;
606                 boundaryCrossed = true;
607             }
608             lastNode = currentNode;
609         }
610
611         // If we've moved to a position that is visually distinct, return the last saved position. There 
612         // is code below that terminates early if we're *about* to move to a visually distinct position.
613         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
614             return lastVisible;
615
616         // skip position in unrendered or invisible node
617         RenderObject* renderer = currentNode->renderer();
618         if (!renderer || renderer->style()->visibility() != VISIBLE)
619             continue;
620                  
621         if (rule == CanCrossEditingBoundary && boundaryCrossed) {
622             lastVisible = currentPos;
623             break;
624         }
625         
626         // track last visible streamer position
627         if (isStreamer(currentPos))
628             lastVisible = currentPos;
629         
630         // Don't move past a position that is visually distinct.  We could rely on code above to terminate and 
631         // return lastVisible on the next iteration, but we terminate early to avoid doing a nodeIndex() call.
632         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.atStartOfNode())
633             return lastVisible;
634
635         // Return position after tables and nodes which have content that can be ignored.
636         if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
637             if (currentPos.atEndOfNode())
638                 return positionAfterNode(currentNode);
639             continue;
640         }
641
642         // return current position if it is in rendered text
643         if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
644             if (currentNode != startNode) {
645                 // This assertion fires in layout tests in the case-transform.html test because
646                 // of a mix-up between offsets in the text in the DOM tree with text in the
647                 // render tree which can have a different length due to case transformation.
648                 // Until we resolve that, disable this so we can run the layout tests!
649                 //ASSERT(currentOffset >= renderer->caretMaxOffset());
650                 return createLegacyEditingPosition(currentNode, renderer->caretMaxOffset());
651             }
652
653             unsigned textOffset = currentPos.offsetInLeafNode();
654             RenderText* textRenderer = toRenderText(renderer);
655             InlineTextBox* lastTextBox = textRenderer->lastTextBox();
656             for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
657                 if (textOffset <= box->start() + box->len()) {
658                     if (textOffset > box->start())
659                         return currentPos;
660                     continue;
661                 }
662
663                 if (box == lastTextBox || textOffset != box->start() + box->len() + 1)
664                     continue;
665
666                 // The text continues on the next line only if the last text box is not on this line and
667                 // none of the boxes on this line have a larger start offset.
668
669                 bool continuesOnNextLine = true;
670                 InlineBox* otherBox = box;
671                 while (continuesOnNextLine) {
672                     otherBox = otherBox->nextLeafChild();
673                     if (!otherBox)
674                         break;
675                     if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
676                         continuesOnNextLine = false;
677                 }
678
679                 otherBox = box;
680                 while (continuesOnNextLine) {
681                     otherBox = otherBox->prevLeafChild();
682                     if (!otherBox)
683                         break;
684                     if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
685                         continuesOnNextLine = false;
686                 }
687
688                 if (continuesOnNextLine)
689                     return currentPos;
690             }
691         }
692     }
693
694     return lastVisible;
695 }
696
697 // This function and upstream() are used for moving back and forth between visually equivalent candidates.
698 // For example, for the text node "foo     bar" where whitespace is collapsible, there are two candidates 
699 // that map to the VisiblePosition between 'b' and the space.  This function will return the right candidate 
700 // and upstream() will return the left one.
701 // Also, downstream() will return the last position in the last atomic node in boundary for all of the positions
702 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPositions(boundary).
703 Position Position::downstream(EditingBoundaryCrossingRule rule) const
704 {
705     Node* startNode = deprecatedNode();
706     if (!startNode)
707         return Position();
708
709     // iterate forward from there, looking for a qualified position
710     Node* boundary = enclosingVisualBoundary(startNode);
711     // FIXME: PositionIterator should respect Before and After positions.
712     PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m_anchorNode.get())) : *this;
713     PositionIterator currentPos = lastVisible;
714     bool startEditable = startNode->rendererIsEditable();
715     Node* lastNode = startNode;
716     bool boundaryCrossed = false;
717     for (; !currentPos.atEnd(); currentPos.increment()) {   
718         Node* currentNode = currentPos.node();
719         
720         // Don't check for an editability change if we haven't moved to a different node,
721         // to avoid the expense of computing rendererIsEditable().
722         if (currentNode != lastNode) {
723             // Don't change editability.
724             bool currentEditable = currentNode->rendererIsEditable();
725             if (startEditable != currentEditable) {
726                 if (rule == CannotCrossEditingBoundary)
727                     break;
728                 boundaryCrossed = true;
729             }
730                 
731             lastNode = currentNode;
732         }
733
734         // stop before going above the body, up into the head
735         // return the last visible streamer position
736         if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
737             break;
738             
739         // Do not move to a visually distinct position.
740         if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode != boundary)
741             return lastVisible;
742         // Do not move past a visually disinct position.
743         // Note: The first position after the last in a node whose ends are visually distinct
744         // positions will be [boundary->parentNode(), originalBlock->nodeIndex() + 1].
745         if (boundary && boundary->parentNode() == currentNode)
746             return lastVisible;
747
748         // skip position in unrendered or invisible node
749         RenderObject* renderer = currentNode->renderer();
750         if (!renderer || renderer->style()->visibility() != VISIBLE)
751             continue;
752             
753         if (rule == CanCrossEditingBoundary && boundaryCrossed) {
754             lastVisible = currentPos;
755             break;
756         }
757         
758         // track last visible streamer position
759         if (isStreamer(currentPos))
760             lastVisible = currentPos;
761
762         // Return position before tables and nodes which have content that can be ignored.
763         if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
764             if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
765                 return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
766             continue;
767         }
768
769         // return current position if it is in rendered text
770         if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
771             if (currentNode != startNode) {
772                 ASSERT(currentPos.atStartOfNode());
773                 return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
774             }
775
776             unsigned textOffset = currentPos.offsetInLeafNode();
777             RenderText* textRenderer = toRenderText(renderer);
778             InlineTextBox* lastTextBox = textRenderer->lastTextBox();
779             for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
780                 if (textOffset <= box->end()) {
781                     if (textOffset >= box->start())
782                         return currentPos;
783                     continue;
784                 }
785
786                 if (box == lastTextBox || textOffset != box->start() + box->len())
787                     continue;
788
789                 // The text continues on the next line only if the last text box is not on this line and
790                 // none of the boxes on this line have a larger start offset.
791
792                 bool continuesOnNextLine = true;
793                 InlineBox* otherBox = box;
794                 while (continuesOnNextLine) {
795                     otherBox = otherBox->nextLeafChild();
796                     if (!otherBox)
797                         break;
798                     if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
799                         continuesOnNextLine = false;
800                 }
801
802                 otherBox = box;
803                 while (continuesOnNextLine) {
804                     otherBox = otherBox->prevLeafChild();
805                     if (!otherBox)
806                         break;
807                     if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
808                         continuesOnNextLine = false;
809                 }
810
811                 if (continuesOnNextLine)
812                     return currentPos;
813             }
814         }
815     }
816     
817     return lastVisible;
818 }
819
820 bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* renderer)
821 {
822     RenderObject* stop = renderer->nextInPreOrderAfterChildren();
823     for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
824         if (o->node()) {
825             if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
826                 (o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
827                 return true;
828         }
829     return false;
830 }
831
832 bool Position::nodeIsUserSelectNone(Node* node)
833 {
834     return node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_NONE;
835 }
836
837 bool Position::isCandidate() const
838 {
839     if (isNull())
840         return false;
841         
842     RenderObject* renderer = deprecatedNode()->renderer();
843     if (!renderer)
844         return false;
845     
846     if (renderer->style()->visibility() != VISIBLE)
847         return false;
848
849     if (renderer->isBR())
850         // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor, but for now we still need to support legacy positions.
851         return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
852
853     if (renderer->isText())
854         return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
855
856     if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
857         return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
858
859     if (m_anchorNode->hasTagName(htmlTag))
860         return false;
861         
862     if (renderer->isBlockFlow()) {
863         if (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)) {
864             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
865                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
866             return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
867         }
868     } else
869         return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
870
871     return false;
872 }
873
874 bool Position::inRenderedText() const
875 {
876     if (isNull() || !deprecatedNode()->isTextNode())
877         return false;
878         
879     RenderObject* renderer = deprecatedNode()->renderer();
880     if (!renderer)
881         return false;
882     
883     RenderText *textRenderer = toRenderText(renderer);
884     for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
885         if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
886             // The offset we're looking for is before this node
887             // this means the offset must be in content that is
888             // not rendered. Return false.
889             return false;
890         }
891         if (box->containsCaretOffset(m_offset))
892             // Return false for offsets inside composed characters.
893             return m_offset == 0 || m_offset == textRenderer->nextOffset(textRenderer->previousOffset(m_offset));
894     }
895     
896     return false;
897 }
898
899 static unsigned caretMaxRenderedOffset(const Node* n)
900 {
901     RenderObject* r = n->renderer();
902     if (r)
903         return r->caretMaxRenderedOffset();
904     
905     if (n->isCharacterDataNode())
906         return static_cast<const CharacterData*>(n)->length();
907     return 1;
908 }
909
910 bool Position::isRenderedCharacter() const
911 {
912     if (isNull() || !deprecatedNode()->isTextNode())
913         return false;
914         
915     RenderObject* renderer = deprecatedNode()->renderer();
916     if (!renderer)
917         return false;
918     
919     RenderText* textRenderer = toRenderText(renderer);
920     for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
921         if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
922             // The offset we're looking for is before this node
923             // this means the offset must be in content that is
924             // not rendered. Return false.
925             return false;
926         }
927         if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
928             return true;
929     }
930     
931     return false;
932 }
933
934 bool Position::rendersInDifferentPosition(const Position &pos) const
935 {
936     if (isNull() || pos.isNull())
937         return false;
938
939     RenderObject* renderer = deprecatedNode()->renderer();
940     if (!renderer)
941         return false;
942     
943     RenderObject* posRenderer = pos.deprecatedNode()->renderer();
944     if (!posRenderer)
945         return false;
946
947     if (renderer->style()->visibility() != VISIBLE ||
948         posRenderer->style()->visibility() != VISIBLE)
949         return false;
950     
951     if (deprecatedNode() == pos.deprecatedNode()) {
952         if (deprecatedNode()->hasTagName(brTag))
953             return false;
954
955         if (m_offset == pos.deprecatedEditingOffset())
956             return false;
957             
958         if (!deprecatedNode()->isTextNode() && !pos.deprecatedNode()->isTextNode()) {
959             if (m_offset != pos.deprecatedEditingOffset())
960                 return true;
961         }
962     }
963     
964     if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate())
965         return true;
966                 
967     if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate())
968         return true;
969                 
970     if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->enclosingBlockFlowElement())
971         return true;
972
973     if (deprecatedNode()->isTextNode() && !inRenderedText())
974         return false;
975
976     if (pos.deprecatedNode()->isTextNode() && !pos.inRenderedText())
977         return false;
978
979     int thisRenderedOffset = renderedOffset();
980     int posRenderedOffset = pos.renderedOffset();
981
982     if (renderer == posRenderer && thisRenderedOffset == posRenderedOffset)
983         return false;
984
985     int ignoredCaretOffset;
986     InlineBox* b1;
987     getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset);
988     InlineBox* b2;
989     pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset);
990
991     LOG(Editing, "renderer:               %p [%p]\n", renderer, b1);
992     LOG(Editing, "thisRenderedOffset:         %d\n", thisRenderedOffset);
993     LOG(Editing, "posRenderer:            %p [%p]\n", posRenderer, b2);
994     LOG(Editing, "posRenderedOffset:      %d\n", posRenderedOffset);
995     LOG(Editing, "node min/max:           %d:%d\n", caretMinOffset(deprecatedNode()), caretMaxRenderedOffset(deprecatedNode()));
996     LOG(Editing, "pos node min/max:       %d:%d\n", caretMinOffset(pos.deprecatedNode()), caretMaxRenderedOffset(pos.deprecatedNode()));
997     LOG(Editing, "----------------------------------------------------------------------\n");
998
999     if (!b1 || !b2) {
1000         return false;
1001     }
1002
1003     if (b1->root() != b2->root()) {
1004         return true;
1005     }
1006
1007     if (nextRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1008         && thisRenderedOffset == (int)caretMaxRenderedOffset(deprecatedNode()) && !posRenderedOffset) {
1009         return false;
1010     }
1011     
1012     if (previousRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1013         && !thisRenderedOffset && posRenderedOffset == (int)caretMaxRenderedOffset(pos.deprecatedNode())) {
1014         return false;
1015     }
1016
1017     return true;
1018 }
1019
1020 // This assumes that it starts in editable content.
1021 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
1022 {
1023     ASSERT(isEditablePosition(*this));
1024     if (isNull())
1025         return Position();
1026     
1027     if (upstream().deprecatedNode()->hasTagName(brTag))
1028         return Position();
1029
1030     Position prev = previousCharacterPosition(affinity);
1031     if (prev != *this && prev.deprecatedNode()->inSameContainingBlockFlowElement(deprecatedNode()) && prev.deprecatedNode()->isTextNode()) {
1032         String string = static_cast<Text *>(prev.deprecatedNode())->data();
1033         UChar c = string[prev.deprecatedEditingOffset()];
1034         if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
1035             if (isEditablePosition(prev))
1036                 return prev;
1037     }
1038
1039     return Position();
1040 }
1041
1042 // This assumes that it starts in editable content.
1043 Position Position::trailingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace) const
1044 {
1045     ASSERT(isEditablePosition(*this));
1046     if (isNull())
1047         return Position();
1048     
1049     VisiblePosition v(*this);
1050     UChar c = v.characterAfter();
1051     // The space must not be in another paragraph and it must be editable.
1052     if (!isEndOfParagraph(v) && v.next(CannotCrossEditingBoundary).isNotNull())
1053         if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
1054             return *this;
1055     
1056     return Position();
1057 }
1058
1059 void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox, int& caretOffset) const
1060 {
1061     getInlineBoxAndOffset(affinity, primaryDirection(), inlineBox, caretOffset);
1062 }
1063
1064 static bool isNonTextLeafChild(RenderObject* object)
1065 {
1066     if (object->firstChild())
1067         return false;
1068     if (object->isText())
1069         return false;
1070     return true;
1071 }
1072
1073 static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
1074 {
1075     RenderBlock* container = renderer->containingBlock();
1076     RenderObject* next = renderer;
1077     while ((next = next->nextInPreOrder(container))) {
1078         if (next->isRenderBlock())
1079             return 0;
1080         if (next->isBR())
1081             return 0;
1082         if (isNonTextLeafChild(next))
1083             return 0;
1084         if (next->isText()) {
1085             InlineTextBox* match = 0;
1086             int minOffset = INT_MAX;
1087             for (InlineTextBox* box = toRenderText(next)->firstTextBox(); box; box = box->nextTextBox()) {
1088                 int caretMinOffset = box->caretMinOffset();
1089                 if (caretMinOffset < minOffset) {
1090                     match = box;
1091                     minOffset = caretMinOffset;
1092                 }
1093             }
1094             if (match)
1095                 return match;
1096         }
1097     }
1098     return 0;
1099 }
1100
1101 static Position downstreamIgnoringEditingBoundaries(Position position)
1102 {
1103     Position lastPosition;
1104     while (position != lastPosition) {
1105         lastPosition = position;
1106         position = position.downstream(CanCrossEditingBoundary);
1107     }
1108     return position;
1109 }
1110
1111 static Position upstreamIgnoringEditingBoundaries(Position position)
1112 {
1113     Position lastPosition;
1114     while (position != lastPosition) {
1115         lastPosition = position;
1116         position = position.upstream(CanCrossEditingBoundary);
1117     }
1118     return position;
1119 }
1120
1121 void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
1122 {
1123     caretOffset = deprecatedEditingOffset();
1124     RenderObject* renderer = deprecatedNode()->renderer();
1125
1126     if (!renderer->isText()) {
1127         inlineBox = 0;
1128         if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
1129             // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
1130             // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
1131             // of RenderObject::createVisiblePosition().
1132             Position equivalent = downstreamIgnoringEditingBoundaries(*this);
1133             if (equivalent == *this) {
1134                 equivalent = upstreamIgnoringEditingBoundaries(*this);
1135                 if (equivalent == *this || downstreamIgnoringEditingBoundaries(equivalent) == *this)
1136                     return;
1137             }
1138
1139             equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
1140             return;
1141         }
1142         if (renderer->isBox()) {
1143             inlineBox = toRenderBox(renderer)->inlineBoxWrapper();
1144             if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
1145                 return;
1146         }
1147     } else {
1148         RenderText* textRenderer = toRenderText(renderer);
1149
1150         InlineTextBox* box;
1151         InlineTextBox* candidate = 0;
1152
1153         for (box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
1154             int caretMinOffset = box->caretMinOffset();
1155             int caretMaxOffset = box->caretMaxOffset();
1156
1157             if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
1158                 continue;
1159
1160             if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) {
1161                 inlineBox = box;
1162                 return;
1163             }
1164
1165             if (((caretOffset == caretMaxOffset) ^ (affinity == DOWNSTREAM))
1166                 || ((caretOffset == caretMinOffset) ^ (affinity == UPSTREAM)))
1167                 break;
1168
1169             candidate = box;
1170         }
1171         if (candidate && candidate == textRenderer->lastTextBox() && affinity == DOWNSTREAM) {
1172             box = searchAheadForBetterMatch(textRenderer);
1173             if (box)
1174                 caretOffset = box->caretMinOffset();
1175         }
1176         inlineBox = box ? box : candidate;
1177     }
1178
1179     if (!inlineBox)
1180         return;
1181
1182     unsigned char level = inlineBox->bidiLevel();
1183
1184     if (inlineBox->direction() == primaryDirection) {
1185         if (caretOffset == inlineBox->caretRightmostOffset()) {
1186             InlineBox* nextBox = inlineBox->nextLeafChild();
1187             if (!nextBox || nextBox->bidiLevel() >= level)
1188                 return;
1189
1190             level = nextBox->bidiLevel();
1191             InlineBox* prevBox = inlineBox;
1192             do {
1193                 prevBox = prevBox->prevLeafChild();
1194             } while (prevBox && prevBox->bidiLevel() > level);
1195
1196             if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
1197                 return;
1198
1199             // For example, abc 123 ^ CBA
1200             while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
1201                 if (nextBox->bidiLevel() < level)
1202                     break;
1203                 inlineBox = nextBox;
1204             }
1205             caretOffset = inlineBox->caretRightmostOffset();
1206         } else {
1207             InlineBox* prevBox = inlineBox->prevLeafChild();
1208             if (!prevBox || prevBox->bidiLevel() >= level)
1209                 return;
1210
1211             level = prevBox->bidiLevel();
1212             InlineBox* nextBox = inlineBox;
1213             do {
1214                 nextBox = nextBox->nextLeafChild();
1215             } while (nextBox && nextBox->bidiLevel() > level);
1216
1217             if (nextBox && nextBox->bidiLevel() == level)
1218                 return;
1219
1220             while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
1221                 if (prevBox->bidiLevel() < level)
1222                     break;
1223                 inlineBox = prevBox;
1224             }
1225             caretOffset = inlineBox->caretLeftmostOffset();
1226         }
1227         return;
1228     }
1229
1230     if (caretOffset == inlineBox->caretLeftmostOffset()) {
1231         InlineBox* prevBox = inlineBox->prevLeafChild();
1232         if (!prevBox || prevBox->bidiLevel() < level) {
1233             // Left edge of a secondary run. Set to the right edge of the entire run.
1234             while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
1235                 if (nextBox->bidiLevel() < level)
1236                     break;
1237                 inlineBox = nextBox;
1238             }
1239             caretOffset = inlineBox->caretRightmostOffset();
1240         } else if (prevBox->bidiLevel() > level) {
1241             // Right edge of a "tertiary" run. Set to the left edge of that run.
1242             while (InlineBox* tertiaryBox = inlineBox->prevLeafChild()) {
1243                 if (tertiaryBox->bidiLevel() <= level)
1244                     break;
1245                 inlineBox = tertiaryBox;
1246             }
1247             caretOffset = inlineBox->caretLeftmostOffset();
1248         }
1249     } else {
1250         InlineBox* nextBox = inlineBox->nextLeafChild();
1251         if (!nextBox || nextBox->bidiLevel() < level) {
1252             // Right edge of a secondary run. Set to the left edge of the entire run.
1253             while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
1254                 if (prevBox->bidiLevel() < level)
1255                     break;
1256                 inlineBox = prevBox;
1257             }
1258             caretOffset = inlineBox->caretLeftmostOffset();
1259         } else if (nextBox->bidiLevel() > level) {
1260             // Left edge of a "tertiary" run. Set to the right edge of that run.
1261             while (InlineBox* tertiaryBox = inlineBox->nextLeafChild()) {
1262                 if (tertiaryBox->bidiLevel() <= level)
1263                     break;
1264                 inlineBox = tertiaryBox;
1265             }
1266             caretOffset = inlineBox->caretRightmostOffset();
1267         }
1268     }
1269 }
1270
1271 TextDirection Position::primaryDirection() const
1272 {
1273     TextDirection primaryDirection = LTR;
1274     for (const RenderObject* r = m_anchorNode->renderer(); r; r = r->parent()) {
1275         if (r->isBlockFlow()) {
1276             primaryDirection = r->style()->direction();
1277             break;
1278         }
1279     }
1280
1281     return primaryDirection;
1282 }
1283
1284
1285 void Position::debugPosition(const char* msg) const
1286 {
1287     if (isNull())
1288         fprintf(stderr, "Position [%s]: null\n", msg);
1289     else
1290         fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, deprecatedNode()->nodeName().utf8().data(), deprecatedNode(), m_offset);
1291 }
1292
1293 #ifndef NDEBUG
1294
1295 void Position::formatForDebugger(char* buffer, unsigned length) const
1296 {
1297     String result;
1298     
1299     if (isNull())
1300         result = "<null>";
1301     else {
1302         char s[1024];
1303         result += "offset ";
1304         result += String::number(m_offset);
1305         result += " of ";
1306         deprecatedNode()->formatForDebugger(s, sizeof(s));
1307         result += s;
1308     }
1309           
1310     strncpy(buffer, result.utf8().data(), length - 1);
1311 }
1312
1313 void Position::showAnchorTypeAndOffset() const
1314 {
1315     if (m_isLegacyEditingPosition)
1316         fputs("legacy, ", stderr);
1317     switch (anchorType()) {
1318     case PositionIsOffsetInAnchor:
1319         fputs("offset", stderr);
1320         break;
1321     case PositionIsBeforeChildren:
1322         fputs("beforeChildren", stderr);
1323         break;
1324     case PositionIsAfterChildren:
1325         fputs("afterChildren", stderr);
1326         break;
1327     case PositionIsBeforeAnchor:
1328         fputs("before", stderr);
1329         break;
1330     case PositionIsAfterAnchor:
1331         fputs("after", stderr);
1332         break;
1333     }
1334     fprintf(stderr, ", offset:%d\n", m_offset);
1335 }
1336
1337 void Position::showTreeForThis() const
1338 {
1339     if (anchorNode()) {
1340         anchorNode()->showTreeForThis();
1341         showAnchorTypeAndOffset();
1342     }
1343 }
1344
1345 #endif
1346
1347
1348
1349 } // namespace WebCore
1350
1351 #ifndef NDEBUG
1352
1353 void showTree(const WebCore::Position& pos)
1354 {
1355     pos.showTreeForThis();
1356 }
1357
1358 void showTree(const WebCore::Position* pos)
1359 {
1360     if (pos)
1361         pos->showTreeForThis();
1362 }
1363
1364 #endif