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