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