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