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