Home | History | Annotate | Download | only in editing
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 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 "VisiblePosition.h"
     28 
     29 #include "Document.h"
     30 #include "FloatQuad.h"
     31 #include "HTMLElement.h"
     32 #include "HTMLNames.h"
     33 #include "InlineTextBox.h"
     34 #include "Logging.h"
     35 #include "Range.h"
     36 #include "RootInlineBox.h"
     37 #include "Text.h"
     38 #include "htmlediting.h"
     39 #include "visible_units.h"
     40 #include <stdio.h>
     41 #include <wtf/text/CString.h>
     42 
     43 namespace WebCore {
     44 
     45 using namespace HTMLNames;
     46 
     47 VisiblePosition::VisiblePosition(const Position &pos, EAffinity affinity)
     48 {
     49     init(pos, affinity);
     50 }
     51 
     52 void VisiblePosition::init(const Position& position, EAffinity affinity)
     53 {
     54     m_affinity = affinity;
     55 
     56     m_deepPosition = canonicalPosition(position);
     57 
     58     // When not at a line wrap, make sure to end up with DOWNSTREAM affinity.
     59     if (m_affinity == UPSTREAM && (isNull() || inSameLine(VisiblePosition(position, DOWNSTREAM), *this)))
     60         m_affinity = DOWNSTREAM;
     61 }
     62 
     63 VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const
     64 {
     65     // FIXME: Support CanSkipEditingBoundary
     66     ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
     67     VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affinity);
     68 
     69     if (rule == CanCrossEditingBoundary)
     70         return next;
     71 
     72     return honorEditableBoundaryAtOrAfter(next);
     73 }
     74 
     75 VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) const
     76 {
     77     // FIXME: Support CanSkipEditingBoundary
     78     ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary);
     79     // find first previous DOM position that is visible
     80     Position pos = previousVisuallyDistinctCandidate(m_deepPosition);
     81 
     82     // return null visible position if there is no previous visible position
     83     if (pos.atStartOfTree())
     84         return VisiblePosition();
     85 
     86     VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM);
     87     ASSERT(prev != *this);
     88 
     89 #ifndef NDEBUG
     90     // we should always be able to make the affinity DOWNSTREAM, because going previous from an
     91     // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!).
     92     if (prev.isNotNull() && m_affinity == UPSTREAM) {
     93         VisiblePosition temp = prev;
     94         temp.setAffinity(UPSTREAM);
     95         ASSERT(inSameLine(temp, prev));
     96     }
     97 #endif
     98 
     99     if (rule == CanCrossEditingBoundary)
    100         return prev;
    101 
    102     return honorEditableBoundaryAtOrBefore(prev);
    103 }
    104 
    105 Position VisiblePosition::leftVisuallyDistinctCandidate() const
    106 {
    107     Position p = m_deepPosition;
    108     if (p.isNull())
    109         return Position();
    110 
    111     Position downstreamStart = p.downstream();
    112     TextDirection primaryDirection = p.primaryDirection();
    113 
    114     while (true) {
    115         InlineBox* box;
    116         int offset;
    117         p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset);
    118         if (!box)
    119             return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
    120 
    121         RenderObject* renderer = box->renderer();
    122 
    123         while (true) {
    124             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset())
    125                 return box->isLeftToRightDirection() ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
    126 
    127             offset = box->isLeftToRightDirection() ? renderer->previousOffset(offset) : renderer->nextOffset(offset);
    128 
    129             int caretMinOffset = box->caretMinOffset();
    130             int caretMaxOffset = box->caretMaxOffset();
    131 
    132             if (offset > caretMinOffset && offset < caretMaxOffset)
    133                 break;
    134 
    135             if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset > caretMaxOffset) {
    136                 // Overshot to the left.
    137                 InlineBox* prevBox = box->prevLeafChild();
    138                 if (!prevBox) {
    139                     Position positionOnLeft = primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
    140                     if (positionOnLeft.isNull())
    141                         return Position();
    142 
    143                     InlineBox* boxOnLeft;
    144                     int offsetOnLeft;
    145                     positionOnLeft.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnLeft, offsetOnLeft);
    146                     if (boxOnLeft && boxOnLeft->root() == box->root())
    147                         return Position();
    148                     return positionOnLeft;
    149                 }
    150 
    151                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
    152                 box = prevBox;
    153                 renderer = box->renderer();
    154                 offset = prevBox->caretRightmostOffset();
    155                 continue;
    156             }
    157 
    158             ASSERT(offset == box->caretLeftmostOffset());
    159 
    160             unsigned char level = box->bidiLevel();
    161             InlineBox* prevBox = box->prevLeafChild();
    162 
    163             if (box->direction() == primaryDirection) {
    164                 if (!prevBox) {
    165                     InlineBox* logicalStart = 0;
    166                     if (primaryDirection == LTR ? box->root()->getLogicalStartBoxWithNode(logicalStart) : box->root()->getLogicalEndBoxWithNode(logicalStart)) {
    167                         box = logicalStart;
    168                         renderer = box->renderer();
    169                         offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
    170                     }
    171                     break;
    172                 }
    173                 if (prevBox->bidiLevel() >= level)
    174                     break;
    175 
    176                 level = prevBox->bidiLevel();
    177 
    178                 InlineBox* nextBox = box;
    179                 do {
    180                     nextBox = nextBox->nextLeafChild();
    181                 } while (nextBox && nextBox->bidiLevel() > level);
    182 
    183                 if (nextBox && nextBox->bidiLevel() == level)
    184                     break;
    185 
    186                 box = prevBox;
    187                 renderer = box->renderer();
    188                 offset = box->caretRightmostOffset();
    189                 if (box->direction() == primaryDirection)
    190                     break;
    191                 continue;
    192             }
    193 
    194             if (prevBox) {
    195                 box = prevBox;
    196                 renderer = box->renderer();
    197                 offset = box->caretRightmostOffset();
    198                 if (box->bidiLevel() > level) {
    199                     do {
    200                         prevBox = prevBox->prevLeafChild();
    201                     } while (prevBox && prevBox->bidiLevel() > level);
    202 
    203                     if (!prevBox || prevBox->bidiLevel() < level)
    204                         continue;
    205                 }
    206             } else {
    207                 // Trailing edge of a secondary run. Set to the leading edge of the entire run.
    208                 while (true) {
    209                     while (InlineBox* nextBox = box->nextLeafChild()) {
    210                         if (nextBox->bidiLevel() < level)
    211                             break;
    212                         box = nextBox;
    213                     }
    214                     if (box->bidiLevel() == level)
    215                         break;
    216                     level = box->bidiLevel();
    217                     while (InlineBox* prevBox = box->prevLeafChild()) {
    218                         if (prevBox->bidiLevel() < level)
    219                             break;
    220                         box = prevBox;
    221                     }
    222                     if (box->bidiLevel() == level)
    223                         break;
    224                     level = box->bidiLevel();
    225                 }
    226                 renderer = box->renderer();
    227                 offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
    228             }
    229             break;
    230         }
    231 
    232         p = Position(renderer->node(), offset);
    233 
    234         if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
    235             return p;
    236     }
    237 }
    238 
    239 VisiblePosition VisiblePosition::left(bool stayInEditableContent) const
    240 {
    241     Position pos = leftVisuallyDistinctCandidate();
    242     // FIXME: Why can't we move left from the last position in a tree?
    243     if (pos.atStartOfTree() || pos.atEndOfTree())
    244         return VisiblePosition();
    245 
    246     VisiblePosition left = VisiblePosition(pos, DOWNSTREAM);
    247     ASSERT(left != *this);
    248 
    249     if (!stayInEditableContent)
    250         return left;
    251 
    252     // FIXME: This may need to do something different from "before".
    253     return honorEditableBoundaryAtOrBefore(left);
    254 }
    255 
    256 Position VisiblePosition::rightVisuallyDistinctCandidate() const
    257 {
    258     Position p = m_deepPosition;
    259     if (p.isNull())
    260         return Position();
    261 
    262     Position downstreamStart = p.downstream();
    263     TextDirection primaryDirection = p.primaryDirection();
    264 
    265     while (true) {
    266         InlineBox* box;
    267         int offset;
    268         p.getInlineBoxAndOffset(m_affinity, primaryDirection, box, offset);
    269         if (!box)
    270             return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
    271 
    272         RenderObject* renderer = box->renderer();
    273 
    274         while (true) {
    275             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset())
    276                 return box->isLeftToRightDirection() ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
    277 
    278             offset = box->isLeftToRightDirection() ? renderer->nextOffset(offset) : renderer->previousOffset(offset);
    279 
    280             int caretMinOffset = box->caretMinOffset();
    281             int caretMaxOffset = box->caretMaxOffset();
    282 
    283             if (offset > caretMinOffset && offset < caretMaxOffset)
    284                 break;
    285 
    286             if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset < caretMinOffset) {
    287                 // Overshot to the right.
    288                 InlineBox* nextBox = box->nextLeafChild();
    289                 if (!nextBox) {
    290                     Position positionOnRight = primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
    291                     if (positionOnRight.isNull())
    292                         return Position();
    293 
    294                     InlineBox* boxOnRight;
    295                     int offsetOnRight;
    296                     positionOnRight.getInlineBoxAndOffset(m_affinity, primaryDirection, boxOnRight, offsetOnRight);
    297                     if (boxOnRight && boxOnRight->root() == box->root())
    298                         return Position();
    299                     return positionOnRight;
    300                 }
    301 
    302                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
    303                 box = nextBox;
    304                 renderer = box->renderer();
    305                 offset = nextBox->caretLeftmostOffset();
    306                 continue;
    307             }
    308 
    309             ASSERT(offset == box->caretRightmostOffset());
    310 
    311             unsigned char level = box->bidiLevel();
    312             InlineBox* nextBox = box->nextLeafChild();
    313 
    314             if (box->direction() == primaryDirection) {
    315                 if (!nextBox) {
    316                     InlineBox* logicalEnd = 0;
    317                     if (primaryDirection == LTR ? box->root()->getLogicalEndBoxWithNode(logicalEnd) : box->root()->getLogicalStartBoxWithNode(logicalEnd)) {
    318                         box = logicalEnd;
    319                         renderer = box->renderer();
    320                         offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
    321                     }
    322                     break;
    323                 }
    324                 if (nextBox->bidiLevel() >= level)
    325                     break;
    326 
    327                 level = nextBox->bidiLevel();
    328 
    329                 InlineBox* prevBox = box;
    330                 do {
    331                     prevBox = prevBox->prevLeafChild();
    332                 } while (prevBox && prevBox->bidiLevel() > level);
    333 
    334                 if (prevBox && prevBox->bidiLevel() == level)   // For example, abc FED 123 ^ CBA
    335                     break;
    336 
    337                 // For example, abc 123 ^ CBA or 123 ^ CBA abc
    338                 box = nextBox;
    339                 renderer = box->renderer();
    340                 offset = box->caretLeftmostOffset();
    341                 if (box->direction() == primaryDirection)
    342                     break;
    343                 continue;
    344             }
    345 
    346             if (nextBox) {
    347                 box = nextBox;
    348                 renderer = box->renderer();
    349                 offset = box->caretLeftmostOffset();
    350                 if (box->bidiLevel() > level) {
    351                     do {
    352                         nextBox = nextBox->nextLeafChild();
    353                     } while (nextBox && nextBox->bidiLevel() > level);
    354 
    355                     if (!nextBox || nextBox->bidiLevel() < level)
    356                         continue;
    357                 }
    358             } else {
    359                 // Trailing edge of a secondary run. Set to the leading edge of the entire run.
    360                 while (true) {
    361                     while (InlineBox* prevBox = box->prevLeafChild()) {
    362                         if (prevBox->bidiLevel() < level)
    363                             break;
    364                         box = prevBox;
    365                     }
    366                     if (box->bidiLevel() == level)
    367                         break;
    368                     level = box->bidiLevel();
    369                     while (InlineBox* nextBox = box->nextLeafChild()) {
    370                         if (nextBox->bidiLevel() < level)
    371                             break;
    372                         box = nextBox;
    373                     }
    374                     if (box->bidiLevel() == level)
    375                         break;
    376                     level = box->bidiLevel();
    377                 }
    378                 renderer = box->renderer();
    379                 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
    380             }
    381             break;
    382         }
    383 
    384         p = Position(renderer->node(), offset);
    385 
    386         if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
    387             return p;
    388     }
    389 }
    390 
    391 VisiblePosition VisiblePosition::right(bool stayInEditableContent) const
    392 {
    393     Position pos = rightVisuallyDistinctCandidate();
    394     // FIXME: Why can't we move left from the last position in a tree?
    395     if (pos.atStartOfTree() || pos.atEndOfTree())
    396         return VisiblePosition();
    397 
    398     VisiblePosition right = VisiblePosition(pos, DOWNSTREAM);
    399     ASSERT(right != *this);
    400 
    401     if (!stayInEditableContent)
    402         return right;
    403 
    404     // FIXME: This may need to do something different from "after".
    405     return honorEditableBoundaryAtOrAfter(right);
    406 }
    407 
    408 VisiblePosition VisiblePosition::honorEditableBoundaryAtOrBefore(const VisiblePosition &pos) const
    409 {
    410     if (pos.isNull())
    411         return pos;
    412 
    413     Node* highestRoot = highestEditableRoot(deepEquivalent());
    414 
    415     // Return empty position if pos is not somewhere inside the editable region containing this position
    416     if (highestRoot && !pos.deepEquivalent().deprecatedNode()->isDescendantOf(highestRoot))
    417         return VisiblePosition();
    418 
    419     // Return pos itself if the two are from the very same editable region, or both are non-editable
    420     // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
    421     // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
    422     if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
    423         return pos;
    424 
    425     // Return empty position if this position is non-editable, but pos is editable
    426     // FIXME: Move to the previous non-editable region.
    427     if (!highestRoot)
    428         return VisiblePosition();
    429 
    430     // Return the last position before pos that is in the same editable region as this position
    431     return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
    432 }
    433 
    434 VisiblePosition VisiblePosition::honorEditableBoundaryAtOrAfter(const VisiblePosition &pos) const
    435 {
    436     if (pos.isNull())
    437         return pos;
    438 
    439     Node* highestRoot = highestEditableRoot(deepEquivalent());
    440 
    441     // Return empty position if pos is not somewhere inside the editable region containing this position
    442     if (highestRoot && !pos.deepEquivalent().deprecatedNode()->isDescendantOf(highestRoot))
    443         return VisiblePosition();
    444 
    445     // Return pos itself if the two are from the very same editable region, or both are non-editable
    446     // FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
    447     // to it is allowed.  VisibleSelection::adjustForEditableContent has this problem too.
    448     if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
    449         return pos;
    450 
    451     // Return empty position if this position is non-editable, but pos is editable
    452     // FIXME: Move to the next non-editable region.
    453     if (!highestRoot)
    454         return VisiblePosition();
    455 
    456     // Return the next position after pos that is in the same editable region as this position
    457     return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
    458 }
    459 
    460 static Position canonicalizeCandidate(const Position& candidate)
    461 {
    462     if (candidate.isNull())
    463         return Position();
    464     ASSERT(candidate.isCandidate());
    465     Position upstream = candidate.upstream();
    466     if (upstream.isCandidate())
    467         return upstream;
    468     return candidate;
    469 }
    470 
    471 Position VisiblePosition::canonicalPosition(const Position& passedPosition)
    472 {
    473     // The updateLayout call below can do so much that even the position passed
    474     // in to us might get changed as a side effect. Specifically, there are code
    475     // paths that pass selection endpoints, and updateLayout can change the selection.
    476     Position position = passedPosition;
    477 
    478     // FIXME (9535):  Canonicalizing to the leftmost candidate means that if we're at a line wrap, we will
    479     // ask renderers to paint downstream carets for other renderers.
    480     // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to
    481     // the appropriate renderer for VisiblePosition's like these, or b) canonicalize to the rightmost candidate
    482     // unless the affinity is upstream.
    483     if (position.isNull())
    484         return Position();
    485 
    486     Node* node = position.containerNode();
    487 
    488     ASSERT(position.document());
    489     position.document()->updateLayoutIgnorePendingStylesheets();
    490 
    491     Position candidate = position.upstream();
    492     if (candidate.isCandidate())
    493         return candidate;
    494     candidate = position.downstream();
    495     if (candidate.isCandidate())
    496         return candidate;
    497 
    498     // When neither upstream or downstream gets us to a candidate (upstream/downstream won't leave
    499     // blocks or enter new ones), we search forward and backward until we find one.
    500     Position next = canonicalizeCandidate(nextCandidate(position));
    501     Position prev = canonicalizeCandidate(previousCandidate(position));
    502     Node* nextNode = next.deprecatedNode();
    503     Node* prevNode = prev.deprecatedNode();
    504 
    505     // The new position must be in the same editable element. Enforce that first.
    506     // Unless the descent is from a non-editable html element to an editable body.
    507     if (node && node->hasTagName(htmlTag) && !node->rendererIsEditable() && node->document()->body() && node->document()->body()->rendererIsEditable())
    508         return next.isNotNull() ? next : prev;
    509 
    510     Node* editingRoot = editableRootForPosition(position);
    511 
    512     // If the html element is editable, descending into its body will look like a descent
    513     // from non-editable to editable content since rootEditableElement() always stops at the body.
    514     if ((editingRoot && editingRoot->hasTagName(htmlTag)) || position.deprecatedNode()->isDocumentNode())
    515         return next.isNotNull() ? next : prev;
    516 
    517     bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
    518     bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;
    519     if (prevIsInSameEditableElement && !nextIsInSameEditableElement)
    520         return prev;
    521 
    522     if (nextIsInSameEditableElement && !prevIsInSameEditableElement)
    523         return next;
    524 
    525     if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)
    526         return Position();
    527 
    528     // The new position should be in the same block flow element. Favor that.
    529     Node* originalBlock = node ? node->enclosingBlockFlowElement() : 0;
    530     bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) && nextNode != originalBlock;
    531     bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) && prevNode != originalBlock;
    532     if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock)
    533         return prev;
    534 
    535     return next;
    536 }
    537 
    538 UChar32 VisiblePosition::characterAfter() const
    539 {
    540     // We canonicalize to the first of two equivalent candidates, but the second of the two candidates
    541     // is the one that will be inside the text node containing the character after this visible position.
    542     Position pos = m_deepPosition.downstream();
    543     Node* node = pos.containerNode();
    544     if (!node || !node->isTextNode() || pos.anchorType() == Position::PositionIsAfterAnchor)
    545         return 0;
    546     ASSERT(pos.anchorType() == Position::PositionIsBeforeAnchor || pos.anchorType() == Position::PositionIsOffsetInAnchor);
    547     Text* textNode = static_cast<Text*>(pos.containerNode());
    548     unsigned offset = pos.anchorType() == Position::PositionIsOffsetInAnchor ? pos.offsetInContainerNode() : 0;
    549     unsigned length = textNode->length();
    550     if (offset >= length)
    551         return 0;
    552 
    553     UChar32 ch;
    554     const UChar* characters = textNode->data().characters();
    555     U16_NEXT(characters, offset, length, ch);
    556     return ch;
    557 }
    558 
    559 IntRect VisiblePosition::localCaretRect(RenderObject*& renderer) const
    560 {
    561     if (m_deepPosition.isNull()) {
    562         renderer = 0;
    563         return IntRect();
    564     }
    565     Node* node = m_deepPosition.anchorNode();
    566 
    567     renderer = node->renderer();
    568     if (!renderer)
    569         return IntRect();
    570 
    571     InlineBox* inlineBox;
    572     int caretOffset;
    573     getInlineBoxAndOffset(inlineBox, caretOffset);
    574 
    575     if (inlineBox)
    576         renderer = inlineBox->renderer();
    577 
    578     return renderer->localCaretRect(inlineBox, caretOffset);
    579 }
    580 
    581 IntRect VisiblePosition::absoluteCaretBounds() const
    582 {
    583     RenderObject* renderer;
    584     IntRect localRect = localCaretRect(renderer);
    585     if (localRect.isEmpty() || !renderer)
    586         return IntRect();
    587 
    588     return renderer->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
    589 }
    590 
    591 int VisiblePosition::xOffsetForVerticalNavigation() const
    592 {
    593     RenderObject* renderer;
    594     IntRect localRect = localCaretRect(renderer);
    595     if (localRect.isEmpty() || !renderer)
    596         return 0;
    597 
    598     // This ignores transforms on purpose, for now. Vertical navigation is done
    599     // without consulting transforms, so that 'up' in transformed text is 'up'
    600     // relative to the text, not absolute 'up'.
    601     return renderer->localToAbsolute(localRect.location()).x();
    602 }
    603 
    604 #ifndef NDEBUG
    605 
    606 void VisiblePosition::debugPosition(const char* msg) const
    607 {
    608     if (isNull())
    609         fprintf(stderr, "Position [%s]: null\n", msg);
    610     else {
    611         fprintf(stderr, "Position [%s]: %s, ", msg, m_deepPosition.deprecatedNode()->nodeName().utf8().data());
    612         m_deepPosition.showAnchorTypeAndOffset();
    613     }
    614 }
    615 
    616 void VisiblePosition::formatForDebugger(char* buffer, unsigned length) const
    617 {
    618     m_deepPosition.formatForDebugger(buffer, length);
    619 }
    620 
    621 void VisiblePosition::showTreeForThis() const
    622 {
    623     m_deepPosition.showTreeForThis();
    624 }
    625 
    626 #endif
    627 
    628 PassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
    629 {
    630     if (start.isNull() || end.isNull())
    631         return 0;
    632 
    633     Position s = start.deepEquivalent().parentAnchoredEquivalent();
    634     Position e = end.deepEquivalent().parentAnchoredEquivalent();
    635     return Range::create(s.containerNode()->document(), s.containerNode(), s.offsetInContainerNode(), e.containerNode(), e.offsetInContainerNode());
    636 }
    637 
    638 VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
    639 {
    640     int exception = 0;
    641     return VisiblePosition(Position(r->startContainer(exception), r->startOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
    642 }
    643 
    644 VisiblePosition endVisiblePosition(const Range *r, EAffinity affinity)
    645 {
    646     int exception = 0;
    647     return VisiblePosition(Position(r->endContainer(exception), r->endOffset(exception), Position::PositionIsOffsetInAnchor), affinity);
    648 }
    649 
    650 bool setStart(Range *r, const VisiblePosition &visiblePosition)
    651 {
    652     if (!r)
    653         return false;
    654     Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
    655     int code = 0;
    656     r->setStart(p.containerNode(), p.offsetInContainerNode(), code);
    657     return code == 0;
    658 }
    659 
    660 bool setEnd(Range *r, const VisiblePosition &visiblePosition)
    661 {
    662     if (!r)
    663         return false;
    664     Position p = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
    665     int code = 0;
    666     r->setEnd(p.containerNode(), p.offsetInContainerNode(), code);
    667     return code == 0;
    668 }
    669 
    670 Element* enclosingBlockFlowElement(const VisiblePosition &visiblePosition)
    671 {
    672     if (visiblePosition.isNull())
    673         return NULL;
    674 
    675     return visiblePosition.deepEquivalent().deprecatedNode()->enclosingBlockFlowElement();
    676 }
    677 
    678 bool isFirstVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node)
    679 {
    680     if (visiblePosition.isNull())
    681         return false;
    682 
    683     if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
    684         return false;
    685 
    686     VisiblePosition previous = visiblePosition.previous();
    687     return previous.isNull() || !previous.deepEquivalent().deprecatedNode()->isDescendantOf(node);
    688 }
    689 
    690 bool isLastVisiblePositionInNode(const VisiblePosition &visiblePosition, const Node *node)
    691 {
    692     if (visiblePosition.isNull())
    693         return false;
    694 
    695     if (!visiblePosition.deepEquivalent().containerNode()->isDescendantOf(node))
    696         return false;
    697 
    698     VisiblePosition next = visiblePosition.next();
    699     return next.isNull() || !next.deepEquivalent().deprecatedNode()->isDescendantOf(node);
    700 }
    701 
    702 }  // namespace WebCore
    703 
    704 #ifndef NDEBUG
    705 
    706 void showTree(const WebCore::VisiblePosition* vpos)
    707 {
    708     if (vpos)
    709         vpos->showTreeForThis();
    710 }
    711 
    712 void showTree(const WebCore::VisiblePosition& vpos)
    713 {
    714     vpos.showTreeForThis();
    715 }
    716 
    717 #endif
    718