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