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