Range constructors should take a Document&.
[WebKit-https.git] / Source / WebCore / editing / VisibleSelection.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 "VisibleSelection.h"
28
29 #include "Document.h"
30 #include "Element.h"
31 #include "Range.h"
32 #include "TextIterator.h"
33 #include "VisiblePosition.h"
34 #include "VisibleUnits.h"
35 #include "htmlediting.h"
36 #include <stdio.h>
37 #include <wtf/Assertions.h>
38 #include <wtf/text/CString.h>
39 #include <wtf/text/StringBuilder.h>
40 #include <wtf/unicode/CharacterNames.h>
41
42 namespace WebCore {
43
44 VisibleSelection::VisibleSelection()
45     : m_affinity(DOWNSTREAM)
46     , m_selectionType(NoSelection)
47     , m_baseIsFirst(true)
48     , m_isDirectional(false)
49 {
50 }
51
52 VisibleSelection::VisibleSelection(const Position& pos, EAffinity affinity, bool isDirectional)
53     : m_base(pos)
54     , m_extent(pos)
55     , m_affinity(affinity)
56     , m_isDirectional(isDirectional)
57 {
58     validate();
59 }
60
61 VisibleSelection::VisibleSelection(const Position& base, const Position& extent, EAffinity affinity, bool isDirectional)
62     : m_base(base)
63     , m_extent(extent)
64     , m_affinity(affinity)
65     , m_isDirectional(isDirectional)
66 {
67     validate();
68 }
69
70 VisibleSelection::VisibleSelection(const VisiblePosition& pos, bool isDirectional)
71     : m_base(pos.deepEquivalent())
72     , m_extent(pos.deepEquivalent())
73     , m_affinity(pos.affinity())
74     , m_isDirectional(isDirectional)
75 {
76     validate();
77 }
78
79 VisibleSelection::VisibleSelection(const VisiblePosition& base, const VisiblePosition& extent, bool isDirectional)
80     : m_base(base.deepEquivalent())
81     , m_extent(extent.deepEquivalent())
82     , m_affinity(base.affinity())
83     , m_isDirectional(isDirectional)
84 {
85     validate();
86 }
87
88 VisibleSelection::VisibleSelection(const Range* range, EAffinity affinity, bool isDirectional)
89     : m_base(range->startPosition())
90     , m_extent(range->endPosition())
91     , m_affinity(affinity)
92     , m_isDirectional(isDirectional)
93 {
94     validate();
95 }
96
97 VisibleSelection VisibleSelection::selectionFromContentsOfNode(Node* node)
98 {
99     ASSERT(!editingIgnoresContent(node));
100     return VisibleSelection(firstPositionInNode(node), lastPositionInNode(node), DOWNSTREAM);
101 }
102
103 void VisibleSelection::setBase(const Position& position)
104 {
105     m_base = position;
106     validate();
107 }
108
109 void VisibleSelection::setBase(const VisiblePosition& visiblePosition)
110 {
111     m_base = visiblePosition.deepEquivalent();
112     validate();
113 }
114
115 void VisibleSelection::setExtent(const Position& position)
116 {
117     m_extent = position;
118     validate();
119 }
120
121 void VisibleSelection::setExtent(const VisiblePosition& visiblePosition)
122 {
123     m_extent = visiblePosition.deepEquivalent();
124     validate();
125 }
126
127 PassRefPtr<Range> VisibleSelection::firstRange() const
128 {
129     if (isNone())
130         return 0;
131     Position start = m_start.parentAnchoredEquivalent();
132     Position end = m_end.parentAnchoredEquivalent();
133     return Range::create(start.anchorNode()->document(), start, end);
134 }
135
136 PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
137 {
138     if (isNone())
139         return 0;
140
141     // Make sure we have an updated layout since this function is called
142     // in the course of running edit commands which modify the DOM.
143     // Failing to call this can result in equivalentXXXPosition calls returning
144     // incorrect results.
145     m_start.anchorNode()->document().updateLayout();
146
147     // Check again, because updating layout can clear the selection.
148     if (isNone())
149         return 0;
150
151     Position s, e;
152     if (isCaret()) {
153         // If the selection is a caret, move the range start upstream. This helps us match
154         // the conventions of text editors tested, which make style determinations based
155         // on the character before the caret, if any. 
156         s = m_start.upstream().parentAnchoredEquivalent();
157         e = s;
158     } else {
159         // If the selection is a range, select the minimum range that encompasses the selection.
160         // Again, this is to match the conventions of text editors tested, which make style 
161         // determinations based on the first character of the selection. 
162         // For instance, this operation helps to make sure that the "X" selected below is the 
163         // only thing selected. The range should not be allowed to "leak" out to the end of the 
164         // previous text node, or to the beginning of the next text node, each of which has a 
165         // different style.
166         // 
167         // On a treasure map, <b>X</b> marks the spot.
168         //                       ^ selected
169         //
170         ASSERT(isRange());
171         s = m_start.downstream();
172         e = m_end.upstream();
173         if (comparePositions(s, e) > 0) {
174             // Make sure the start is before the end.
175             // The end can wind up before the start if collapsed whitespace is the only thing selected.
176             Position tmp = s;
177             s = e;
178             e = tmp;
179         }
180         s = s.parentAnchoredEquivalent();
181         e = e.parentAnchoredEquivalent();
182     }
183
184     if (!s.containerNode() || !e.containerNode())
185         return 0;
186
187     // VisibleSelections are supposed to always be valid.  This constructor will ASSERT
188     // if a valid range could not be created, which is fine for this callsite.
189     return Range::create(s.anchorNode()->document(), s, e);
190 }
191
192 bool VisibleSelection::expandUsingGranularity(TextGranularity granularity)
193 {
194     if (isNone())
195         return false;
196
197     validate(granularity);
198     return true;
199 }
200
201 static PassRefPtr<Range> makeSearchRange(const Position& pos)
202 {
203     Node* n = pos.deprecatedNode();
204     if (!n)
205         return 0;
206     Node* de = n->document().documentElement();
207     if (!de)
208         return 0;
209     Element* boundary = deprecatedEnclosingBlockFlowElement(n);
210     if (!boundary)
211         return 0;
212
213     RefPtr<Range> searchRange(Range::create(n->document()));
214     ExceptionCode ec = 0;
215
216     Position start(pos.parentAnchoredEquivalent());
217     searchRange->selectNodeContents(boundary, ec);
218     searchRange->setStart(start.containerNode(), start.offsetInContainerNode(), ec);
219
220     ASSERT(!ec);
221     if (ec)
222         return 0;
223
224     return searchRange.release();
225 }
226
227 bool VisibleSelection::isAll(EditingBoundaryCrossingRule rule) const
228 {
229     return !nonBoundaryShadowTreeRootNode() && visibleStart().previous(rule).isNull() && visibleEnd().next(rule).isNull();
230 }
231
232 void VisibleSelection::appendTrailingWhitespace()
233 {
234     RefPtr<Range> searchRange = makeSearchRange(m_end);
235     if (!searchRange)
236         return;
237
238     CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
239
240     for (; charIt.length(); charIt.advance(1)) {
241         UChar c = charIt.characters()[0];
242         if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n')
243             break;
244         m_end = charIt.range()->endPosition();
245     }
246 }
247
248 void VisibleSelection::setBaseAndExtentToDeepEquivalents()
249 {
250     // Move the selection to rendered positions, if possible.
251     bool baseAndExtentEqual = m_base == m_extent;
252     if (m_base.isNotNull()) {
253         m_base = VisiblePosition(m_base, m_affinity).deepEquivalent();
254         if (baseAndExtentEqual)
255             m_extent = m_base;
256     }
257     if (m_extent.isNotNull() && !baseAndExtentEqual)
258         m_extent = VisiblePosition(m_extent, m_affinity).deepEquivalent();
259
260     // Make sure we do not have a dangling base or extent.
261     if (m_base.isNull() && m_extent.isNull())
262         m_baseIsFirst = true;
263     else if (m_base.isNull()) {
264         m_base = m_extent;
265         m_baseIsFirst = true;
266     } else if (m_extent.isNull()) {
267         m_extent = m_base;
268         m_baseIsFirst = true;
269     } else
270         m_baseIsFirst = comparePositions(m_base, m_extent) <= 0;
271 }
272
273 void VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity(TextGranularity granularity)
274 {
275     if (m_baseIsFirst) {
276         m_start = m_base;
277         m_end = m_extent;
278     } else {
279         m_start = m_extent;
280         m_end = m_base;
281     }
282
283     switch (granularity) {
284         case CharacterGranularity:
285             // Don't do any expansion.
286             break;
287         case WordGranularity: {
288             // General case: Select the word the caret is positioned inside of, or at the start of (RightWordIfOnBoundary).
289             // Edge case: If the caret is after the last word in a soft-wrapped line or the last word in
290             // the document, select that last word (LeftWordIfOnBoundary).
291             // Edge case: If the caret is after the last word in a paragraph, select from the the end of the
292             // last word to the line break (also RightWordIfOnBoundary);
293             VisiblePosition start = VisiblePosition(m_start, m_affinity);
294             VisiblePosition originalEnd(m_end, m_affinity);
295             EWordSide side = RightWordIfOnBoundary;
296             if (isEndOfEditableOrNonEditableContent(start) || (isEndOfLine(start) && !isStartOfLine(start) && !isEndOfParagraph(start)))
297                 side = LeftWordIfOnBoundary;
298             m_start = startOfWord(start, side).deepEquivalent();
299             side = RightWordIfOnBoundary;
300             if (isEndOfEditableOrNonEditableContent(originalEnd) || (isEndOfLine(originalEnd) && !isStartOfLine(originalEnd) && !isEndOfParagraph(originalEnd)))
301                 side = LeftWordIfOnBoundary;
302                 
303             VisiblePosition wordEnd(endOfWord(originalEnd, side));
304             VisiblePosition end(wordEnd);
305             
306             if (isEndOfParagraph(originalEnd) && !isEmptyTableCell(m_start.deprecatedNode())) {
307                 // Select the paragraph break (the space from the end of a paragraph to the start of 
308                 // the next one) to match TextEdit.
309                 end = wordEnd.next();
310                 
311                 if (Node* table = isFirstPositionAfterTable(end)) {
312                     // The paragraph break after the last paragraph in the last cell of a block table ends
313                     // at the start of the paragraph after the table.
314                     if (isBlock(table))
315                         end = end.next(CannotCrossEditingBoundary);
316                     else
317                         end = wordEnd;
318                 }
319                 
320                 if (end.isNull())
321                     end = wordEnd;
322                     
323             }
324                 
325             m_end = end.deepEquivalent();
326             break;
327         }
328         case SentenceGranularity: {
329             m_start = startOfSentence(VisiblePosition(m_start, m_affinity)).deepEquivalent();
330             m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent();
331             break;
332         }
333         case LineGranularity: {
334             m_start = startOfLine(VisiblePosition(m_start, m_affinity)).deepEquivalent();
335             VisiblePosition end = endOfLine(VisiblePosition(m_end, m_affinity));
336             // If the end of this line is at the end of a paragraph, include the space 
337             // after the end of the line in the selection.
338             if (isEndOfParagraph(end)) {
339                 VisiblePosition next = end.next();
340                 if (next.isNotNull())
341                     end = next;
342             }
343             m_end = end.deepEquivalent();
344             break;
345         }
346         case LineBoundary:
347             m_start = startOfLine(VisiblePosition(m_start, m_affinity)).deepEquivalent();
348             m_end = endOfLine(VisiblePosition(m_end, m_affinity)).deepEquivalent();
349             break;
350         case ParagraphGranularity: {
351             VisiblePosition pos(m_start, m_affinity);
352             if (isStartOfLine(pos) && isEndOfEditableOrNonEditableContent(pos))
353                 pos = pos.previous();
354             m_start = startOfParagraph(pos).deepEquivalent();
355             VisiblePosition visibleParagraphEnd = endOfParagraph(VisiblePosition(m_end, m_affinity));
356             
357             // Include the "paragraph break" (the space from the end of this paragraph to the start
358             // of the next one) in the selection.
359             VisiblePosition end(visibleParagraphEnd.next());
360              
361             if (Node* table = isFirstPositionAfterTable(end)) {
362                 // The paragraph break after the last paragraph in the last cell of a block table ends
363                 // at the start of the paragraph after the table, not at the position just after the table.
364                 if (isBlock(table))
365                     end = end.next(CannotCrossEditingBoundary);
366                 // There is no parargraph break after the last paragraph in the last cell of an inline table.
367                 else
368                     end = visibleParagraphEnd;
369             }
370              
371             if (end.isNull())
372                 end = visibleParagraphEnd;
373                 
374             m_end = end.deepEquivalent();
375             break;
376         }
377         case DocumentBoundary:
378             m_start = startOfDocument(VisiblePosition(m_start, m_affinity)).deepEquivalent();
379             m_end = endOfDocument(VisiblePosition(m_end, m_affinity)).deepEquivalent();
380             break;
381         case ParagraphBoundary:
382             m_start = startOfParagraph(VisiblePosition(m_start, m_affinity)).deepEquivalent();
383             m_end = endOfParagraph(VisiblePosition(m_end, m_affinity)).deepEquivalent();
384             break;
385         case SentenceBoundary:
386             m_start = startOfSentence(VisiblePosition(m_start, m_affinity)).deepEquivalent();
387             m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent();
388             break;
389     }
390     
391     // Make sure we do not have a dangling start or end.
392     if (m_start.isNull())
393         m_start = m_end;
394     if (m_end.isNull())
395         m_end = m_start;
396 }
397
398 void VisibleSelection::updateSelectionType()
399 {
400     if (m_start.isNull()) {
401         ASSERT(m_end.isNull());
402         m_selectionType = NoSelection;
403     } else if (m_start == m_end || m_start.upstream() == m_end.upstream()) {
404         m_selectionType = CaretSelection;
405     } else
406         m_selectionType = RangeSelection;
407
408     // Affinity only makes sense for a caret
409     if (m_selectionType != CaretSelection)
410         m_affinity = DOWNSTREAM;
411 }
412
413 void VisibleSelection::validate(TextGranularity granularity)
414 {
415     setBaseAndExtentToDeepEquivalents();
416     setStartAndEndFromBaseAndExtentRespectingGranularity(granularity);
417     adjustSelectionToAvoidCrossingShadowBoundaries();
418     adjustSelectionToAvoidCrossingEditingBoundaries();
419     updateSelectionType();
420
421     if (selectionType() == RangeSelection) {
422         // "Constrain" the selection to be the smallest equivalent range of nodes.
423         // This is a somewhat arbitrary choice, but experience shows that it is
424         // useful to make to make the selection "canonical" (if only for
425         // purposes of comparing selections). This is an ideal point of the code
426         // to do this operation, since all selection changes that result in a RANGE 
427         // come through here before anyone uses it.
428         // FIXME: Canonicalizing is good, but haven't we already done it (when we
429         // set these two positions to VisiblePosition deepEquivalent()s above)?
430         m_start = m_start.downstream();
431         m_end = m_end.upstream();
432
433         // FIXME: Position::downstream() or Position::upStream() might violate editing boundaries
434         // if an anchor node has a Shadow DOM. So we adjust selection to avoid crossing editing
435         // boundaries again. See https://bugs.webkit.org/show_bug.cgi?id=87463
436         adjustSelectionToAvoidCrossingEditingBoundaries();
437     }
438 }
439
440 // FIXME: This function breaks the invariant of this class.
441 // But because we use VisibleSelection to store values in editing commands for use when
442 // undoing the command, we need to be able to create a selection that while currently
443 // invalid, will be valid once the changes are undone. This is a design problem.
444 // To fix it we either need to change the invariants of VisibleSelection or create a new
445 // class for editing to use that can manipulate selections that are not currently valid.
446 void VisibleSelection::setWithoutValidation(const Position& base, const Position& extent)
447 {
448     ASSERT(!base.isNull());
449     ASSERT(!extent.isNull());
450     ASSERT(m_affinity == DOWNSTREAM);
451     m_base = base;
452     m_extent = extent;
453     m_baseIsFirst = comparePositions(base, extent) <= 0;
454     if (m_baseIsFirst) {
455         m_start = base;
456         m_end = extent;
457     } else {
458         m_start = extent;
459         m_end = base;
460     }
461     m_selectionType = base == extent ? CaretSelection : RangeSelection;
462 }
463
464 static Position adjustPositionForEnd(const Position& currentPosition, Node* startContainerNode)
465 {
466     TreeScope& treeScope = startContainerNode->treeScope();
467
468     ASSERT(&currentPosition.containerNode()->treeScope() != &treeScope);
469
470     if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.containerNode())) {
471         if (ancestor->contains(startContainerNode))
472             return positionAfterNode(ancestor);
473         return positionBeforeNode(ancestor);
474     }
475
476     if (Node* lastChild = treeScope.rootNode()->lastChild())
477         return positionAfterNode(lastChild);
478
479     return Position();
480 }
481
482 static Position adjustPositionForStart(const Position& currentPosition, Node* endContainerNode)
483 {
484     TreeScope& treeScope = endContainerNode->treeScope();
485
486     ASSERT(&currentPosition.containerNode()->treeScope() != &treeScope);
487     
488     if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.containerNode())) {
489         if (ancestor->contains(endContainerNode))
490             return positionBeforeNode(ancestor);
491         return positionAfterNode(ancestor);
492     }
493
494     if (Node* firstChild = treeScope.rootNode()->firstChild())
495         return positionBeforeNode(firstChild);
496
497     return Position();
498 }
499
500 void VisibleSelection::adjustSelectionToAvoidCrossingShadowBoundaries()
501 {
502     if (m_base.isNull() || m_start.isNull() || m_end.isNull())
503         return;
504
505     if (&m_start.anchorNode()->treeScope() == &m_end.anchorNode()->treeScope())
506         return;
507
508     if (m_baseIsFirst) {
509         m_extent = adjustPositionForEnd(m_end, m_start.containerNode());
510         m_end = m_extent;
511     } else {
512         m_extent = adjustPositionForStart(m_start, m_end.containerNode());
513         m_start = m_extent;
514     }
515
516     ASSERT(&m_start.anchorNode()->treeScope() == &m_end.anchorNode()->treeScope());
517 }
518
519 void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
520 {
521     if (m_base.isNull() || m_start.isNull() || m_end.isNull())
522         return;
523
524     Node* baseRoot = highestEditableRoot(m_base);
525     Node* startRoot = highestEditableRoot(m_start);
526     Node* endRoot = highestEditableRoot(m_end);
527     
528     Node* baseEditableAncestor = lowestEditableAncestor(m_base.containerNode());
529     
530     // The base, start and end are all in the same region.  No adjustment necessary.
531     if (baseRoot == startRoot && baseRoot == endRoot)
532         return;
533     
534     // The selection is based in editable content.
535     if (baseRoot) {
536         // If the start is outside the base's editable root, cap it at the start of that root.
537         // If the start is in non-editable content that is inside the base's editable root, put it
538         // at the first editable position after start inside the base's editable root.
539         if (startRoot != baseRoot) {
540             VisiblePosition first = firstEditablePositionAfterPositionInRoot(m_start, baseRoot);
541             m_start = first.deepEquivalent();
542             if (m_start.isNull()) {
543                 ASSERT_NOT_REACHED();
544                 m_start = m_end;
545             }
546         }
547         // If the end is outside the base's editable root, cap it at the end of that root.
548         // If the end is in non-editable content that is inside the base's root, put it
549         // at the last editable position before the end inside the base's root.
550         if (endRoot != baseRoot) {
551             VisiblePosition last = lastEditablePositionBeforePositionInRoot(m_end, baseRoot);
552             m_end = last.deepEquivalent();
553             if (m_end.isNull())
554                 m_end = m_start;
555         }
556     // The selection is based in non-editable content.
557     } else {
558         // FIXME: Non-editable pieces inside editable content should be atomic, in the same way that editable
559         // pieces in non-editable content are atomic.
560     
561         // The selection ends in editable content or non-editable content inside a different editable ancestor, 
562         // move backward until non-editable content inside the same lowest editable ancestor is reached.
563         Node* endEditableAncestor = lowestEditableAncestor(m_end.containerNode());
564         if (endRoot || endEditableAncestor != baseEditableAncestor) {
565             
566             Position p = previousVisuallyDistinctCandidate(m_end);
567             Node* shadowAncestor = endRoot ? endRoot->shadowHost() : 0;
568             if (p.isNull() && shadowAncestor)
569                 p = positionAfterNode(shadowAncestor);
570             while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
571                 Node* root = editableRootForPosition(p);
572                 shadowAncestor = root ? root->shadowHost() : 0;
573                 p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(p.containerNode()) : previousVisuallyDistinctCandidate(p);
574                 if (p.isNull() && shadowAncestor)
575                     p = positionAfterNode(shadowAncestor);
576             }
577             VisiblePosition previous(p);
578
579             if (previous.isNull()) {
580                 // The selection crosses an Editing boundary.  This is a
581                 // programmer error in the editing code.  Happy debugging!
582                 ASSERT_NOT_REACHED();
583                 m_base = Position();
584                 m_extent = Position();
585                 validate();
586                 return;
587             }
588             m_end = previous.deepEquivalent();
589         }
590
591         // The selection starts in editable content or non-editable content inside a different editable ancestor, 
592         // move forward until non-editable content inside the same lowest editable ancestor is reached.
593         Node* startEditableAncestor = lowestEditableAncestor(m_start.containerNode());      
594         if (startRoot || startEditableAncestor != baseEditableAncestor) {
595             Position p = nextVisuallyDistinctCandidate(m_start);
596             Node* shadowAncestor = startRoot ? startRoot->shadowHost() : 0;
597             if (p.isNull() && shadowAncestor)
598                 p = positionBeforeNode(shadowAncestor);
599             while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
600                 Node* root = editableRootForPosition(p);
601                 shadowAncestor = root ? root->shadowHost() : 0;
602                 p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(p.containerNode()) : nextVisuallyDistinctCandidate(p);
603                 if (p.isNull() && shadowAncestor)
604                     p = positionBeforeNode(shadowAncestor);
605             }
606             VisiblePosition next(p);
607             
608             if (next.isNull()) {
609                 // The selection crosses an Editing boundary.  This is a
610                 // programmer error in the editing code.  Happy debugging!
611                 ASSERT_NOT_REACHED();
612                 m_base = Position();
613                 m_extent = Position();
614                 validate();
615                 return;
616             }
617             m_start = next.deepEquivalent();
618         }
619     }
620     
621     // Correct the extent if necessary.
622     if (baseEditableAncestor != lowestEditableAncestor(m_extent.containerNode()))
623         m_extent = m_baseIsFirst ? m_end : m_start;
624 }
625
626 bool VisibleSelection::isContentEditable() const
627 {
628     return isEditablePosition(start());
629 }
630
631 bool VisibleSelection::rendererIsEditable() const
632 {
633     return isEditablePosition(start(), ContentIsEditable, DoNotUpdateStyle);
634 }
635
636 bool VisibleSelection::isContentRichlyEditable() const
637 {
638     return isRichlyEditablePosition(start());
639 }
640
641 Element* VisibleSelection::rootEditableElement() const
642 {
643     return editableRootForPosition(start());
644 }
645
646 Node* VisibleSelection::nonBoundaryShadowTreeRootNode() const
647 {
648     return start().deprecatedNode() ? start().deprecatedNode()->nonBoundaryShadowTreeRootNode() : 0;
649 }
650
651 #ifndef NDEBUG
652
653 void VisibleSelection::debugPosition() const
654 {
655     fprintf(stderr, "VisibleSelection ===============\n");
656
657     if (!m_start.anchorNode())
658         fputs("pos:   null", stderr);
659     else if (m_start == m_end) {
660         fprintf(stderr, "pos:   %s ", m_start.anchorNode()->nodeName().utf8().data());
661         m_start.showAnchorTypeAndOffset();
662     } else {
663         fprintf(stderr, "start: %s ", m_start.anchorNode()->nodeName().utf8().data());
664         m_start.showAnchorTypeAndOffset();
665         fprintf(stderr, "end:   %s ", m_end.anchorNode()->nodeName().utf8().data());
666         m_end.showAnchorTypeAndOffset();
667     }
668
669     fprintf(stderr, "================================\n");
670 }
671
672 void VisibleSelection::formatForDebugger(char* buffer, unsigned length) const
673 {
674     StringBuilder result;
675     String s;
676
677     if (isNone()) {
678         result.appendLiteral("<none>");
679     } else {
680         const int FormatBufferSize = 1024;
681         char s[FormatBufferSize];
682         result.appendLiteral("from ");
683         start().formatForDebugger(s, FormatBufferSize);
684         result.append(s);
685         result.appendLiteral(" to ");
686         end().formatForDebugger(s, FormatBufferSize);
687         result.append(s);
688     }
689
690     strncpy(buffer, result.toString().utf8().data(), length - 1);
691 }
692
693 void VisibleSelection::showTreeForThis() const
694 {
695     if (start().anchorNode()) {
696         start().anchorNode()->showTreeAndMark(start().anchorNode(), "S", end().anchorNode(), "E");
697         fputs("start: ", stderr);
698         start().showAnchorTypeAndOffset();
699         fputs("end: ", stderr);
700         end().showAnchorTypeAndOffset();
701     }
702 }
703
704 #endif
705
706 } // namespace WebCore
707
708 #ifndef NDEBUG
709
710 void showTree(const WebCore::VisibleSelection& sel)
711 {
712     sel.showTreeForThis();
713 }
714
715 void showTree(const WebCore::VisibleSelection* sel)
716 {
717     if (sel)
718         sel->showTreeForThis();
719 }
720
721 #endif