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