Range API is throwing wrong exception type
[WebKit-https.git] / Source / WebCore / dom / Range.cpp
1 /*
2  * (C) 1999 Lars Knoll (knoll@kde.org)
3  * (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
4  * (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
5  * (C) 2001 Peter Kelly (pmk@post.com)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
7  * Copyright (C) 2011 Motorola Mobility. All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #include "config.h"
26 #include "Range.h"
27
28 #include "ClientRect.h"
29 #include "ClientRectList.h"
30 #include "DocumentFragment.h"
31 #include "Event.h"
32 #include "Frame.h"
33 #include "FrameView.h"
34 #include "HTMLElement.h"
35 #include "HTMLNames.h"
36 #include "NodeTraversal.h"
37 #include "NodeWithIndex.h"
38 #include "Page.h"
39 #include "ProcessingInstruction.h"
40 #include "RenderBoxModelObject.h"
41 #include "RenderText.h"
42 #include "ScopedEventQueue.h"
43 #include "TextIterator.h"
44 #include "VisiblePosition.h"
45 #include "VisibleUnits.h"
46 #include "htmlediting.h"
47 #include "markup.h"
48 #include <stdio.h>
49 #include <wtf/RefCountedLeakCounter.h>
50 #include <wtf/text/CString.h>
51 #include <wtf/text/StringBuilder.h>
52
53 #if PLATFORM(IOS)
54 #include "SelectionRect.h"
55 #endif
56
57 namespace WebCore {
58
59 using namespace HTMLNames;
60
61 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range"));
62
63 inline Range::Range(Document& ownerDocument)
64     : m_ownerDocument(ownerDocument)
65     , m_start(&ownerDocument)
66     , m_end(&ownerDocument)
67 {
68 #ifndef NDEBUG
69     rangeCounter.increment();
70 #endif
71
72     m_ownerDocument->attachRange(this);
73 }
74
75 Ref<Range> Range::create(Document& ownerDocument)
76 {
77     return adoptRef(*new Range(ownerDocument));
78 }
79
80 inline Range::Range(Document& ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
81     : m_ownerDocument(ownerDocument)
82     , m_start(&ownerDocument)
83     , m_end(&ownerDocument)
84 {
85 #ifndef NDEBUG
86     rangeCounter.increment();
87 #endif
88
89     m_ownerDocument->attachRange(this);
90
91     // Simply setting the containers and offsets directly would not do any of the checking
92     // that setStart and setEnd do, so we call those functions.
93     setStart(startContainer, startOffset);
94     setEnd(endContainer, endOffset);
95 }
96
97 Ref<Range> Range::create(Document& ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
98 {
99     return adoptRef(*new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
100 }
101
102 Ref<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
103 {
104     return adoptRef(*new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
105 }
106
107 Ref<Range> Range::create(Document& ownerDocument, const VisiblePosition& visibleStart, const VisiblePosition& visibleEnd)
108 {
109     Position start = visibleStart.deepEquivalent().parentAnchoredEquivalent();
110     Position end = visibleEnd.deepEquivalent().parentAnchoredEquivalent();
111     return adoptRef(*new Range(ownerDocument, start.anchorNode(), start.deprecatedEditingOffset(), end.anchorNode(), end.deprecatedEditingOffset()));
112 }
113
114 Range::~Range()
115 {
116     // Always detach (even if we've already detached) to fix https://bugs.webkit.org/show_bug.cgi?id=26044
117     m_ownerDocument->detachRange(this);
118
119 #ifndef NDEBUG
120     rangeCounter.decrement();
121 #endif
122 }
123
124 void Range::setDocument(Document& document)
125 {
126     ASSERT(m_ownerDocument.ptr() != &document);
127     m_ownerDocument->detachRange(this);
128     m_ownerDocument = document;
129     m_start.setToStartOfNode(&document);
130     m_end.setToStartOfNode(&document);
131     m_ownerDocument->attachRange(this);
132 }
133
134 Node* Range::commonAncestorContainer(Node* containerA, Node* containerB)
135 {
136     for (Node* parentA = containerA; parentA; parentA = parentA->parentNode()) {
137         for (Node* parentB = containerB; parentB; parentB = parentB->parentNode()) {
138             if (parentA == parentB)
139                 return parentA;
140         }
141     }
142     return nullptr;
143 }
144
145 static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& start, const RangeBoundaryPoint& end)
146 {
147     Node* endRootContainer = end.container();
148     while (endRootContainer->parentNode())
149         endRootContainer = endRootContainer->parentNode();
150     Node* startRootContainer = start.container();
151     while (startRootContainer->parentNode())
152         startRootContainer = startRootContainer->parentNode();
153
154     return startRootContainer != endRootContainer || (Range::compareBoundaryPoints(start, end, ASSERT_NO_EXCEPTION) > 0);
155 }
156
157 void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
158 {
159     if (!refNode) {
160         ec = NOT_FOUND_ERR;
161         return;
162     }
163
164     bool didMoveDocument = false;
165     if (&refNode->document() != &ownerDocument()) {
166         setDocument(refNode->document());
167         didMoveDocument = true;
168     }
169
170     ec = 0;
171     Node* childNode = checkNodeWOffset(refNode.get(), offset, ec);
172     if (ec)
173         return;
174
175     m_start.set(refNode, offset, childNode);
176
177     if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
178         collapse(true);
179 }
180
181 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
182 {
183     if (!refNode) {
184         ec = NOT_FOUND_ERR;
185         return;
186     }
187
188     bool didMoveDocument = false;
189     if (&refNode->document() != &ownerDocument()) {
190         setDocument(refNode->document());
191         didMoveDocument = true;
192     }
193
194     ec = 0;
195     Node* childNode = checkNodeWOffset(refNode.get(), offset, ec);
196     if (ec)
197         return;
198
199     m_end.set(refNode, offset, childNode);
200
201     if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
202         collapse(false);
203 }
204
205 void Range::setStart(const Position& start, ExceptionCode& ec)
206 {
207     Position parentAnchored = start.parentAnchoredEquivalent();
208     setStart(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(), ec);
209 }
210
211 void Range::setEnd(const Position& end, ExceptionCode& ec)
212 {
213     Position parentAnchored = end.parentAnchoredEquivalent();
214     setEnd(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(), ec);
215 }
216
217 void Range::collapse(bool toStart)
218 {
219     if (toStart)
220         m_end = m_start;
221     else
222         m_start = m_end;
223 }
224
225 bool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec)
226 {
227     if (!refNode) {
228         ec = HIERARCHY_REQUEST_ERR;
229         return false;
230     }
231
232     if (!refNode->inDocument() || &refNode->document() != &ownerDocument()) {
233         return false;
234     }
235
236     ec = 0;
237     checkNodeWOffset(refNode, offset, ec);
238     if (ec)
239         return false;
240
241     return compareBoundaryPoints(refNode, offset, &startContainer(), m_start.offset(), ec) >= 0 && !ec
242         && compareBoundaryPoints(refNode, offset, &endContainer(), m_end.offset(), ec) <= 0 && !ec;
243 }
244
245 short Range::comparePoint(Node* refNode, int offset, ExceptionCode& ec) const
246 {
247     // http://developer.mozilla.org/en/docs/DOM:range.comparePoint
248     // This method returns -1, 0 or 1 depending on if the point described by the 
249     // refNode node and an offset within the node is before, same as, or after the range respectively.
250
251     if (!refNode) {
252         ec = HIERARCHY_REQUEST_ERR;
253         return 0;
254     }
255
256     if (!refNode->inDocument() || &refNode->document() != &ownerDocument()) {
257         ec = WRONG_DOCUMENT_ERR;
258         return 0;
259     }
260
261     ec = 0;
262     checkNodeWOffset(refNode, offset, ec);
263     if (ec)
264         return 0;
265
266     // compare to start, and point comes before
267     if (compareBoundaryPoints(refNode, offset, &startContainer(), m_start.offset(), ec) < 0)
268         return -1;
269
270     if (ec)
271         return 0;
272
273     // compare to end, and point comes after
274     if (compareBoundaryPoints(refNode, offset, &endContainer(), m_end.offset(), ec) > 0 && !ec)
275         return 1;
276
277     // point is in the middle of this range, or on the boundary points
278     return 0;
279 }
280
281 Range::CompareResults Range::compareNode(Node* refNode, ExceptionCode& ec) const
282 {
283     // http://developer.mozilla.org/en/docs/DOM:range.compareNode
284     // This method returns 0, 1, 2, or 3 based on if the node is before, after,
285     // before and after(surrounds), or inside the range, respectively
286
287     if (!refNode) {
288         ec = NOT_FOUND_ERR;
289         return NODE_BEFORE;
290     }
291
292     if (!refNode->inDocument()) {
293         // Firefox doesn't throw an exception for this case; it returns 0.
294         return NODE_BEFORE;
295     }
296
297     if (&refNode->document() != &ownerDocument()) {
298         // Firefox doesn't throw an exception for this case; it returns 0.
299         return NODE_BEFORE;
300     }
301
302     ContainerNode* parentNode = refNode->parentNode();
303     unsigned nodeIndex = refNode->computeNodeIndex();
304     
305     if (!parentNode) {
306         // if the node is the top document we should return NODE_BEFORE_AND_AFTER
307         // but we throw to match firefox behavior
308         ec = NOT_FOUND_ERR;
309         return NODE_BEFORE;
310     }
311
312     if (comparePoint(parentNode, nodeIndex, ec) < 0) { // starts before
313         if (comparePoint(parentNode, nodeIndex + 1, ec) > 0) // ends after the range
314             return NODE_BEFORE_AND_AFTER;
315         return NODE_BEFORE; // ends before or in the range
316     } else { // starts at or after the range start
317         if (comparePoint(parentNode, nodeIndex + 1, ec) > 0) // ends after the range
318             return NODE_AFTER;
319         return NODE_INSIDE; // ends inside the range
320     }
321 }
322
323 short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionCode& ec) const
324 {
325     if (!sourceRange) {
326         ec = NOT_FOUND_ERR;
327         return 0;
328     }
329
330     Node* thisCont = commonAncestorContainer();
331     Node* sourceCont = sourceRange->commonAncestorContainer();
332
333     if (&thisCont->document() != &sourceCont->document()) {
334         ec = WRONG_DOCUMENT_ERR;
335         return 0;
336     }
337
338     Node* thisTop = thisCont;
339     Node* sourceTop = sourceCont;
340     while (thisTop->parentNode())
341         thisTop = thisTop->parentNode();
342     while (sourceTop->parentNode())
343         sourceTop = sourceTop->parentNode();
344     if (thisTop != sourceTop) { // in different DocumentFragments
345         ec = WRONG_DOCUMENT_ERR;
346         return 0;
347     }
348
349     switch (how) {
350         case START_TO_START:
351             return compareBoundaryPoints(m_start, sourceRange->m_start, ec);
352         case START_TO_END:
353             return compareBoundaryPoints(m_end, sourceRange->m_start, ec);
354         case END_TO_END:
355             return compareBoundaryPoints(m_end, sourceRange->m_end, ec);
356         case END_TO_START:
357             return compareBoundaryPoints(m_start, sourceRange->m_end, ec);
358     }
359
360     ec = SYNTAX_ERR;
361     return 0;
362 }
363
364 short Range::compareBoundaryPointsForBindings(unsigned short compareHow, const Range* sourceRange, ExceptionCode& ec) const
365 {
366     if (compareHow > END_TO_START) {
367         ec = NOT_SUPPORTED_ERR;
368         return 0;
369     }
370     return compareBoundaryPoints(static_cast<CompareHow>(compareHow), sourceRange, ec);
371 }
372
373 short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB, ExceptionCode& ec)
374 {
375     ASSERT(containerA);
376     ASSERT(containerB);
377
378     if (!containerA)
379         return -1;
380     if (!containerB)
381         return 1;
382
383     // see DOM2 traversal & range section 2.5
384
385     // case 1: both points have the same container
386     if (containerA == containerB) {
387         if (offsetA == offsetB)
388             return 0;           // A is equal to B
389         if (offsetA < offsetB)
390             return -1;          // A is before B
391         else
392             return 1;           // A is after B
393     }
394
395     // case 2: node C (container B or an ancestor) is a child node of A
396     Node* c = containerB;
397     while (c && c->parentNode() != containerA)
398         c = c->parentNode();
399     if (c) {
400         int offsetC = 0;
401         Node* n = containerA->firstChild();
402         while (n != c && offsetC < offsetA) {
403             offsetC++;
404             n = n->nextSibling();
405         }
406
407         if (offsetA <= offsetC)
408             return -1;              // A is before B
409         else
410             return 1;               // A is after B
411     }
412
413     // case 3: node C (container A or an ancestor) is a child node of B
414     c = containerA;
415     while (c && c->parentNode() != containerB)
416         c = c->parentNode();
417     if (c) {
418         int offsetC = 0;
419         Node* n = containerB->firstChild();
420         while (n != c && offsetC < offsetB) {
421             offsetC++;
422             n = n->nextSibling();
423         }
424
425         if (offsetC < offsetB)
426             return -1;              // A is before B
427         else
428             return 1;               // A is after B
429     }
430
431     // case 4: containers A & B are siblings, or children of siblings
432     // ### we need to do a traversal here instead
433     Node* commonAncestor = commonAncestorContainer(containerA, containerB);
434     if (!commonAncestor) {
435         ec = WRONG_DOCUMENT_ERR;
436         return 0;
437     }
438     Node* childA = containerA;
439     while (childA && childA->parentNode() != commonAncestor)
440         childA = childA->parentNode();
441     if (!childA)
442         childA = commonAncestor;
443     Node* childB = containerB;
444     while (childB && childB->parentNode() != commonAncestor)
445         childB = childB->parentNode();
446     if (!childB)
447         childB = commonAncestor;
448
449     if (childA == childB)
450         return 0; // A is equal to B
451
452     Node* n = commonAncestor->firstChild();
453     while (n) {
454         if (n == childA)
455             return -1; // A is before B
456         if (n == childB)
457             return 1; // A is after B
458         n = n->nextSibling();
459     }
460
461     // Should never reach this point.
462     ASSERT_NOT_REACHED();
463     return 0;
464 }
465
466 short Range::compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const RangeBoundaryPoint& boundaryB, ExceptionCode& ec)
467 {
468     return compareBoundaryPoints(boundaryA.container(), boundaryA.offset(), boundaryB.container(), boundaryB.offset(), ec);
469 }
470
471 bool Range::boundaryPointsValid() const
472 {
473     ExceptionCode ec = 0;
474     return compareBoundaryPoints(m_start, m_end, ec) <= 0 && !ec;
475 }
476
477 void Range::deleteContents(ExceptionCode& ec)
478 {
479     checkDeleteExtract(ec);
480     if (ec)
481         return;
482
483     processContents(Delete, ec);
484 }
485
486 bool Range::intersectsNode(Node* refNode, ExceptionCode& ec) const
487 {
488     // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode
489     // Returns a bool if the node intersects the range.
490
491     if (!refNode) {
492         ec = NOT_FOUND_ERR;
493         return false;
494     }
495
496     if (!refNode->inDocument() || &refNode->document() != &ownerDocument()) {
497         // Firefox doesn't throw an exception for these cases; it returns false.
498         return false;
499     }
500
501     ContainerNode* parentNode = refNode->parentNode();
502     unsigned nodeIndex = refNode->computeNodeIndex();
503     
504     if (!parentNode) {
505         // if the node is the top document we should return NODE_BEFORE_AND_AFTER
506         // but we throw to match firefox behavior
507         ec = NOT_FOUND_ERR;
508         return false;
509     }
510
511     if (comparePoint(parentNode, nodeIndex, ec) < 0 && // starts before start
512         comparePoint(parentNode, nodeIndex + 1, ec) < 0) { // ends before start
513         return false;
514     } else if (comparePoint(parentNode, nodeIndex, ec) > 0 && // starts after end
515                comparePoint(parentNode, nodeIndex + 1, ec) > 0) { // ends after end
516         return false;
517     }
518     
519     return true; // all other cases
520 }
521
522 static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot)
523 {
524     if (node == commonRoot)
525         return 0;
526
527     ASSERT(commonRoot->contains(node));
528
529     while (node->parentNode() != commonRoot)
530         node = node->parentNode();
531
532     return node;
533 }
534
535 static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offset, Node* commonRoot)
536 {
537     ASSERT(container);
538     ASSERT(commonRoot);
539     
540     if (!commonRoot->contains(container))
541         return 0;
542
543     if (container == commonRoot) {
544         container = container->firstChild();
545         for (unsigned i = 0; container && i < offset; i++)
546             container = container->nextSibling();
547     } else {
548         while (container->parentNode() != commonRoot)
549             container = container->parentNode();
550     }
551
552     return container;
553 }
554
555 static inline unsigned lengthOfContentsInNode(Node* node)
556 {
557     // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
558     switch (node->nodeType()) {
559     case Node::TEXT_NODE:
560     case Node::CDATA_SECTION_NODE:
561     case Node::COMMENT_NODE:
562     case Node::PROCESSING_INSTRUCTION_NODE:
563         return downcast<CharacterData>(*node).length();
564     case Node::ELEMENT_NODE:
565     case Node::ATTRIBUTE_NODE:
566     case Node::ENTITY_REFERENCE_NODE:
567     case Node::ENTITY_NODE:
568     case Node::DOCUMENT_NODE:
569     case Node::DOCUMENT_TYPE_NODE:
570     case Node::DOCUMENT_FRAGMENT_NODE:
571     case Node::XPATH_NAMESPACE_NODE:
572         return node->countChildNodes();
573     }
574     ASSERT_NOT_REACHED();
575     return 0;
576 }
577
578 RefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
579 {
580     typedef Vector<RefPtr<Node>> NodeVector;
581
582     RefPtr<DocumentFragment> fragment;
583     if (action == Extract || action == Clone)
584         fragment = DocumentFragment::create(ownerDocument());
585
586     if (collapsed())
587         return fragment;
588
589     RefPtr<Node> commonRoot = commonAncestorContainer();
590     ASSERT(commonRoot);
591
592     if (&startContainer() == &endContainer()) {
593         processContentsBetweenOffsets(action, fragment, &startContainer(), m_start.offset(), m_end.offset(), ec);
594         return fragment;
595     }
596
597     // Since mutation events can modify the range during the process, the boundary points need to be saved.
598     RangeBoundaryPoint originalStart(m_start);
599     RangeBoundaryPoint originalEnd(m_end);
600
601     // what is the highest node that partially selects the start / end of the range?
602     RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(originalStart.container(), commonRoot.get());
603     RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(originalEnd.container(), commonRoot.get());
604
605     // Start and end containers are different.
606     // There are three possibilities here:
607     // 1. Start container == commonRoot (End container must be a descendant)
608     // 2. End container == commonRoot (Start container must be a descendant)
609     // 3. Neither is commonRoot, they are both descendants
610     //
611     // In case 3, we grab everything after the start (up until a direct child
612     // of commonRoot) into leftContents, and everything before the end (up until
613     // a direct child of commonRoot) into rightContents. Then we process all
614     // commonRoot children between leftContents and rightContents
615     //
616     // In case 1 or 2, we skip either processing of leftContents or rightContents,
617     // in which case the last lot of nodes either goes from the first or last
618     // child of commonRoot.
619     //
620     // These are deleted, cloned, or extracted (i.e. both) depending on action.
621
622     // Note that we are verifying that our common root hierarchy is still intact
623     // after any DOM mutation event, at various stages below. See webkit bug 60350.
624
625     RefPtr<Node> leftContents;
626     if (originalStart.container() != commonRoot && commonRoot->contains(originalStart.container())) {
627         leftContents = processContentsBetweenOffsets(action, 0, originalStart.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.container()), ec);
628         leftContents = processAncestorsAndTheirSiblings(action, originalStart.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec);
629     }
630
631     RefPtr<Node> rightContents;
632     if (&endContainer() != commonRoot && commonRoot->contains(originalEnd.container())) {
633         rightContents = processContentsBetweenOffsets(action, 0, originalEnd.container(), 0, originalEnd.offset(), ec);
634         rightContents = processAncestorsAndTheirSiblings(action, originalEnd.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec);
635     }
636
637     // delete all children of commonRoot between the start and end container
638     RefPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.container(), originalStart.offset(), commonRoot.get());
639     if (processStart && originalStart.container() != commonRoot) // processStart contains nodes before m_start.
640         processStart = processStart->nextSibling();
641     RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.container(), originalEnd.offset(), commonRoot.get());
642
643     // Collapse the range, making sure that the result is not within a node that was partially selected.
644     ec = 0;
645     if (action == Extract || action == Delete) {
646         if (partialStart && commonRoot->contains(partialStart.get()))
647             setStart(partialStart->parentNode(), partialStart->computeNodeIndex() + 1, ec);
648         else if (partialEnd && commonRoot->contains(partialEnd.get()))
649             setStart(partialEnd->parentNode(), partialEnd->computeNodeIndex(), ec);
650         if (ec)
651             return nullptr;
652         m_end = m_start;
653     }
654
655     // Now add leftContents, stuff in between, and rightContents to the fragment
656     // (or just delete the stuff in between)
657
658     if ((action == Extract || action == Clone) && leftContents)
659         fragment->appendChild(leftContents, ec);
660
661     if (processStart) {
662         NodeVector nodes;
663         for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling())
664             nodes.append(n);
665         processNodes(action, nodes, commonRoot, fragment, ec);
666     }
667
668     if ((action == Extract || action == Clone) && rightContents)
669         fragment->appendChild(rightContents, ec);
670
671     return fragment;
672 }
673
674 static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
675 {
676     if (data->length() - endOffset)
677         data->deleteData(endOffset, data->length() - endOffset, ec);
678     if (startOffset)
679         data->deleteData(0, startOffset, ec);
680 }
681
682 RefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment, Node* container, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
683 {
684     ASSERT(container);
685     ASSERT(startOffset <= endOffset);
686
687     // This switch statement must be consistent with that of lengthOfContentsInNode.
688     RefPtr<Node> result;   
689     switch (container->nodeType()) {
690     case Node::TEXT_NODE:
691     case Node::CDATA_SECTION_NODE:
692     case Node::COMMENT_NODE:
693         endOffset = std::min(endOffset, static_cast<CharacterData*>(container)->length());
694         startOffset = std::min(startOffset, endOffset);
695         if (action == Extract || action == Clone) {
696             RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
697             deleteCharacterData(c, startOffset, endOffset, ec);
698             if (fragment) {
699                 result = fragment;
700                 result->appendChild(c.release(), ec);
701             } else
702                 result = c.release();
703         }
704         if (action == Extract || action == Delete)
705             downcast<CharacterData>(*container).deleteData(startOffset, endOffset - startOffset, ec);
706         break;
707     case Node::PROCESSING_INSTRUCTION_NODE:
708         endOffset = std::min(endOffset, static_cast<ProcessingInstruction*>(container)->data().length());
709         startOffset = std::min(startOffset, endOffset);
710         if (action == Extract || action == Clone) {
711             RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
712             c->setData(c->data().substring(startOffset, endOffset - startOffset), ec);
713             if (fragment) {
714                 result = fragment;
715                 result->appendChild(c.release(), ec);
716             } else
717                 result = c.release();
718         }
719         if (action == Extract || action == Delete) {
720             ProcessingInstruction& pi = downcast<ProcessingInstruction>(*container);
721             String data(pi.data());
722             data.remove(startOffset, endOffset - startOffset);
723             pi.setData(data, ec);
724         }
725         break;
726     case Node::ELEMENT_NODE:
727     case Node::ATTRIBUTE_NODE:
728     case Node::ENTITY_REFERENCE_NODE:
729     case Node::ENTITY_NODE:
730     case Node::DOCUMENT_NODE:
731     case Node::DOCUMENT_TYPE_NODE:
732     case Node::DOCUMENT_FRAGMENT_NODE:
733     case Node::XPATH_NAMESPACE_NODE:
734         // FIXME: Should we assert that some nodes never appear here?
735         if (action == Extract || action == Clone) {
736             if (fragment)
737                 result = fragment;
738             else
739                 result = container->cloneNode(false);
740         }
741
742         Node* n = container->firstChild();
743         Vector<RefPtr<Node>> nodes;
744         for (unsigned i = startOffset; n && i; i--)
745             n = n->nextSibling();
746         for (unsigned i = startOffset; n && i < endOffset; i++, n = n->nextSibling())
747             nodes.append(n);
748
749         processNodes(action, nodes, container, result, ec);
750         break;
751     }
752
753     return result;
754 }
755
756 void Range::processNodes(ActionType action, Vector<RefPtr<Node>>& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec)
757 {
758     for (unsigned i = 0; i < nodes.size(); i++) {
759         switch (action) {
760         case Delete:
761             oldContainer->removeChild(nodes[i].get(), ec);
762             break;
763         case Extract:
764             newContainer->appendChild(nodes[i].release(), ec); // will remove n from its parent
765             break;
766         case Clone:
767             newContainer->appendChild(nodes[i]->cloneNode(true), ec);
768             break;
769         }
770     }
771 }
772
773 RefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionCode& ec)
774 {
775     typedef Vector<RefPtr<Node>> NodeVector;
776
777     RefPtr<Node> clonedContainer = passedClonedContainer;
778     Vector<RefPtr<Node>> ancestors;
779     for (ContainerNode* n = container->parentNode(); n && n != commonRoot; n = n->parentNode())
780         ancestors.append(n);
781
782     RefPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
783     for (Vector<RefPtr<Node>>::const_iterator it = ancestors.begin(); it != ancestors.end(); ++it) {
784         RefPtr<Node> ancestor = *it;
785         if (action == Extract || action == Clone) {
786             if (RefPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
787                 clonedAncestor->appendChild(clonedContainer, ec);
788                 clonedContainer = clonedAncestor;
789             }
790         }
791
792         // Copy siblings of an ancestor of start/end containers
793         // FIXME: This assertion may fail if DOM is modified during mutation event
794         // FIXME: Share code with Range::processNodes
795         ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->parentNode() == ancestor);
796         
797         NodeVector nodes;
798         for (Node* child = firstChildInAncestorToProcess.get(); child;
799             child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling())
800             nodes.append(child);
801
802         for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
803             Node* child = it->get();
804             switch (action) {
805             case Delete:
806                 ancestor->removeChild(child, ec);
807                 break;
808             case Extract: // will remove child from ancestor
809                 if (direction == ProcessContentsForward)
810                     clonedContainer->appendChild(child, ec);
811                 else
812                     clonedContainer->insertBefore(child, clonedContainer->firstChild(), ec);
813                 break;
814             case Clone:
815                 if (direction == ProcessContentsForward)
816                     clonedContainer->appendChild(child->cloneNode(true), ec);
817                 else
818                     clonedContainer->insertBefore(child->cloneNode(true), clonedContainer->firstChild(), ec);
819                 break;
820             }
821         }
822         firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling();
823     }
824
825     return clonedContainer;
826 }
827
828 RefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec)
829 {
830     checkDeleteExtract(ec);
831     if (ec)
832         return nullptr;
833
834     return processContents(Extract, ec);
835 }
836
837 RefPtr<DocumentFragment> Range::cloneContents(ExceptionCode& ec)
838 {
839     return processContents(Clone, ec);
840 }
841
842 void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec)
843 {
844     RefPtr<Node> newNode = prpNewNode;
845
846     ec = 0;
847     if (!newNode) {
848         ec = NOT_FOUND_ERR;
849         return;
850     }
851
852     // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
853     // the Range is read-only.
854     if (containedByReadOnly()) {
855         ec = NO_MODIFICATION_ALLOWED_ERR;
856         return;
857     }
858
859     // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that
860     // does not allow children of the type of newNode or if newNode is an ancestor of the container.
861
862     // an extra one here - if a text node is going to split, it must have a parent to insert into
863     bool startIsText = is<Text>(startContainer());
864     if (startIsText && !startContainer().parentNode()) {
865         ec = HIERARCHY_REQUEST_ERR;
866         return;
867     }
868
869     // In the case where the container is a text node, we check against the container's parent, because
870     // text nodes get split up upon insertion.
871     Node* checkAgainst;
872     if (startIsText)
873         checkAgainst = startContainer().parentNode();
874     else
875         checkAgainst = &startContainer();
876
877     Node::NodeType newNodeType = newNode->nodeType();
878     int numNewChildren;
879     if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE && !newNode->isShadowRoot()) {
880         // check each child node, not the DocumentFragment itself
881         numNewChildren = 0;
882         for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {
883             if (!checkAgainst->childTypeAllowed(c->nodeType())) {
884                 ec = HIERARCHY_REQUEST_ERR;
885                 return;
886             }
887             ++numNewChildren;
888         }
889     } else {
890         numNewChildren = 1;
891         if (!checkAgainst->childTypeAllowed(newNodeType)) {
892             ec = HIERARCHY_REQUEST_ERR;
893             return;
894         }
895     }
896
897     for (Node* n = &startContainer(); n; n = n->parentNode()) {
898         if (n == newNode) {
899             ec = HIERARCHY_REQUEST_ERR;
900             return;
901         }
902     }
903
904     // INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, ShadowRoot or Document node.
905     switch (newNodeType) {
906     case Node::ATTRIBUTE_NODE:
907     case Node::ENTITY_NODE:
908     case Node::DOCUMENT_NODE:
909         ec = INVALID_NODE_TYPE_ERR;
910         return;
911     default:
912         if (newNode->isShadowRoot()) {
913             ec = INVALID_NODE_TYPE_ERR;
914             return;
915         }
916         break;
917     }
918
919     EventQueueScope scope;
920     bool collapsed = m_start == m_end;
921     RefPtr<Node> container;
922     if (startIsText) {
923         container = &startContainer();
924         RefPtr<Text> newText = downcast<Text>(*container).splitText(m_start.offset(), ec);
925         if (ec)
926             return;
927         
928         container = &startContainer();
929         container->parentNode()->insertBefore(newNode.release(), newText.get(), ec);
930         if (ec)
931             return;
932
933         if (collapsed && newText->parentNode() == container && &container->document() == &ownerDocument())
934             m_end.setToBeforeChild(*newText);
935     } else {
936         container = &startContainer();
937         RefPtr<Node> firstInsertedChild = newNodeType == Node::DOCUMENT_FRAGMENT_NODE ? newNode->firstChild() : newNode;
938         RefPtr<Node> lastInsertedChild = newNodeType == Node::DOCUMENT_FRAGMENT_NODE ? newNode->lastChild() : newNode;
939         RefPtr<Node> childAfterInsertedContent = container->traverseToChildAt(m_start.offset());
940         container->insertBefore(newNode.release(), childAfterInsertedContent.get(), ec);
941         if (ec)
942             return;
943
944         if (collapsed && numNewChildren && &container->document() == &ownerDocument()) {
945             if (firstInsertedChild->parentNode() == container)
946                 m_start.setToBeforeChild(*firstInsertedChild);
947             if (lastInsertedChild->parentNode() == container)
948                 m_end.set(container, lastInsertedChild->computeNodeIndex() + 1, lastInsertedChild.get());
949         }
950     }
951 }
952
953 String Range::toString() const
954 {
955     StringBuilder builder;
956
957     Node* pastLast = pastLastNode();
958     for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
959         if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
960             const String& data = static_cast<CharacterData*>(n)->data();
961             int length = data.length();
962             int start = n == &startContainer() ? std::min(std::max(0, m_start.offset()), length) : 0;
963             int end = n == &endContainer() ? std::min(std::max(start, m_end.offset()), length) : length;
964             builder.append(data, start, end - start);
965         }
966     }
967
968     return builder.toString();
969 }
970
971 String Range::toHTML() const
972 {
973     return createMarkup(*this);
974 }
975
976 String Range::text() const
977 {
978     // We need to update layout, since plainText uses line boxes in the render tree.
979     // FIXME: As with innerText, we'd like this to work even if there are no render objects.
980     startContainer().document().updateLayout();
981
982     return plainText(this);
983 }
984
985 RefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionCode& ec)
986 {
987     Node* element = startContainer().isElementNode() ? &startContainer() : startContainer().parentNode();
988     if (!element || !element->isHTMLElement()) {
989         ec = NOT_SUPPORTED_ERR;
990         return nullptr;
991     }
992
993     return WebCore::createContextualFragment(markup, downcast<HTMLElement>(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, ec);
994 }
995
996
997 void Range::detach()
998 {
999     // This is now a no-op as per the DOM specification.
1000 }
1001
1002 Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionCode& ec) const
1003 {
1004     switch (n->nodeType()) {
1005         case Node::DOCUMENT_TYPE_NODE:
1006         case Node::ENTITY_NODE:
1007             ec = INVALID_NODE_TYPE_ERR;
1008             return nullptr;
1009         case Node::CDATA_SECTION_NODE:
1010         case Node::COMMENT_NODE:
1011         case Node::TEXT_NODE:
1012         case Node::PROCESSING_INSTRUCTION_NODE:
1013             if (static_cast<unsigned>(offset) > downcast<CharacterData>(*n).length())
1014                 ec = INDEX_SIZE_ERR;
1015             return nullptr;
1016         case Node::ATTRIBUTE_NODE:
1017         case Node::DOCUMENT_FRAGMENT_NODE:
1018         case Node::DOCUMENT_NODE:
1019         case Node::ELEMENT_NODE:
1020         case Node::ENTITY_REFERENCE_NODE:
1021         case Node::XPATH_NAMESPACE_NODE: {
1022             if (!offset)
1023                 return nullptr;
1024             Node* childBefore = n->traverseToChildAt(offset - 1);
1025             if (!childBefore)
1026                 ec = INDEX_SIZE_ERR;
1027             return childBefore;
1028         }
1029     }
1030     ASSERT_NOT_REACHED();
1031     return nullptr;
1032 }
1033
1034 void Range::checkNodeBA(Node* n, ExceptionCode& ec) const
1035 {
1036     // INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an
1037     // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG shadow DOM tree,
1038     // or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, or Entity node.
1039
1040     switch (n->nodeType()) {
1041         case Node::ATTRIBUTE_NODE:
1042         case Node::DOCUMENT_FRAGMENT_NODE:
1043         case Node::DOCUMENT_NODE:
1044         case Node::ENTITY_NODE:
1045             ec = INVALID_NODE_TYPE_ERR;
1046             return;
1047         case Node::CDATA_SECTION_NODE:
1048         case Node::COMMENT_NODE:
1049         case Node::DOCUMENT_TYPE_NODE:
1050         case Node::ELEMENT_NODE:
1051         case Node::ENTITY_REFERENCE_NODE:
1052         case Node::PROCESSING_INSTRUCTION_NODE:
1053         case Node::TEXT_NODE:
1054         case Node::XPATH_NAMESPACE_NODE:
1055             break;
1056     }
1057
1058     Node* root = n;
1059     while (ContainerNode* parent = root->parentNode())
1060         root = parent;
1061
1062     switch (root->nodeType()) {
1063         case Node::ATTRIBUTE_NODE:
1064         case Node::DOCUMENT_NODE:
1065         case Node::DOCUMENT_FRAGMENT_NODE:
1066             break;
1067         case Node::CDATA_SECTION_NODE:
1068         case Node::COMMENT_NODE:
1069         case Node::DOCUMENT_TYPE_NODE:
1070         case Node::ELEMENT_NODE:
1071         case Node::ENTITY_NODE:
1072         case Node::ENTITY_REFERENCE_NODE:
1073         case Node::PROCESSING_INSTRUCTION_NODE:
1074         case Node::TEXT_NODE:
1075         case Node::XPATH_NAMESPACE_NODE:
1076             ec = INVALID_NODE_TYPE_ERR;
1077             return;
1078     }
1079 }
1080
1081 Ref<Range> Range::cloneRange() const
1082 {
1083     return Range::create(ownerDocument(), &startContainer(), m_start.offset(), &endContainer(), m_end.offset());
1084 }
1085
1086 void Range::setStartAfter(Node* refNode, ExceptionCode& ec)
1087 {
1088     if (!refNode) {
1089         ec = NOT_FOUND_ERR;
1090         return;
1091     }
1092
1093     ec = 0;
1094     checkNodeBA(refNode, ec);
1095     if (ec)
1096         return;
1097
1098     setStart(refNode->parentNode(), refNode->computeNodeIndex() + 1, ec);
1099 }
1100
1101 void Range::setEndBefore(Node* refNode, ExceptionCode& ec)
1102 {
1103     if (!refNode) {
1104         ec = NOT_FOUND_ERR;
1105         return;
1106     }
1107
1108     ec = 0;
1109     checkNodeBA(refNode, ec);
1110     if (ec)
1111         return;
1112
1113     setEnd(refNode->parentNode(), refNode->computeNodeIndex(), ec);
1114 }
1115
1116 void Range::setEndAfter(Node* refNode, ExceptionCode& ec)
1117 {
1118     if (!refNode) {
1119         ec = NOT_FOUND_ERR;
1120         return;
1121     }
1122
1123     ec = 0;
1124     checkNodeBA(refNode, ec);
1125     if (ec)
1126         return;
1127
1128     setEnd(refNode->parentNode(), refNode->computeNodeIndex() + 1, ec);
1129 }
1130
1131 void Range::selectNode(Node* refNode, ExceptionCode& ec)
1132 {
1133     if (!refNode) {
1134         ec = NOT_FOUND_ERR;
1135         return;
1136     }
1137
1138     // INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an Entity, or
1139     // DocumentType node or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, or Entity
1140     // node.
1141     for (ContainerNode* anc = refNode->parentNode(); anc; anc = anc->parentNode()) {
1142         switch (anc->nodeType()) {
1143             case Node::ATTRIBUTE_NODE:
1144             case Node::CDATA_SECTION_NODE:
1145             case Node::COMMENT_NODE:
1146             case Node::DOCUMENT_FRAGMENT_NODE:
1147             case Node::DOCUMENT_NODE:
1148             case Node::ELEMENT_NODE:
1149             case Node::ENTITY_REFERENCE_NODE:
1150             case Node::PROCESSING_INSTRUCTION_NODE:
1151             case Node::TEXT_NODE:
1152             case Node::XPATH_NAMESPACE_NODE:
1153                 break;
1154             case Node::DOCUMENT_TYPE_NODE:
1155             case Node::ENTITY_NODE:
1156                 ec = INVALID_NODE_TYPE_ERR;
1157                 return;
1158         }
1159     }
1160
1161     switch (refNode->nodeType()) {
1162         case Node::CDATA_SECTION_NODE:
1163         case Node::COMMENT_NODE:
1164         case Node::DOCUMENT_TYPE_NODE:
1165         case Node::ELEMENT_NODE:
1166         case Node::ENTITY_REFERENCE_NODE:
1167         case Node::PROCESSING_INSTRUCTION_NODE:
1168         case Node::TEXT_NODE:
1169         case Node::XPATH_NAMESPACE_NODE:
1170             break;
1171         case Node::ATTRIBUTE_NODE:
1172         case Node::DOCUMENT_FRAGMENT_NODE:
1173         case Node::DOCUMENT_NODE:
1174         case Node::ENTITY_NODE:
1175             ec = INVALID_NODE_TYPE_ERR;
1176             return;
1177     }
1178
1179     if (&ownerDocument() != &refNode->document())
1180         setDocument(refNode->document());
1181
1182     ec = 0;
1183     setStartBefore(refNode, ec);
1184     if (ec)
1185         return;
1186     setEndAfter(refNode, ec);
1187 }
1188
1189 void Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
1190 {
1191     if (!refNode) {
1192         ec = NOT_FOUND_ERR;
1193         return;
1194     }
1195
1196     // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity,
1197     // or DocumentType node.
1198     for (Node* n = refNode; n; n = n->parentNode()) {
1199         switch (n->nodeType()) {
1200             case Node::ATTRIBUTE_NODE:
1201             case Node::CDATA_SECTION_NODE:
1202             case Node::COMMENT_NODE:
1203             case Node::DOCUMENT_FRAGMENT_NODE:
1204             case Node::DOCUMENT_NODE:
1205             case Node::ELEMENT_NODE:
1206             case Node::ENTITY_REFERENCE_NODE:
1207             case Node::PROCESSING_INSTRUCTION_NODE:
1208             case Node::TEXT_NODE:
1209             case Node::XPATH_NAMESPACE_NODE:
1210                 break;
1211             case Node::DOCUMENT_TYPE_NODE:
1212             case Node::ENTITY_NODE:
1213                 ec = INVALID_NODE_TYPE_ERR;
1214                 return;
1215         }
1216     }
1217
1218     if (&ownerDocument() != &refNode->document())
1219         setDocument(refNode->document());
1220
1221     m_start.setToStartOfNode(refNode);
1222     m_end.setToEndOfNode(refNode);
1223 }
1224
1225 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
1226 {
1227     RefPtr<Node> newParent = passNewParent;
1228
1229     if (!newParent) {
1230         ec = NOT_FOUND_ERR;
1231         return;
1232     }
1233
1234     // INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType,
1235     // Document, or DocumentFragment node.
1236     switch (newParent->nodeType()) {
1237         case Node::ATTRIBUTE_NODE:
1238         case Node::DOCUMENT_FRAGMENT_NODE:
1239         case Node::DOCUMENT_NODE:
1240         case Node::DOCUMENT_TYPE_NODE:
1241         case Node::ENTITY_NODE:
1242             ec = INVALID_NODE_TYPE_ERR;
1243             return;
1244         case Node::CDATA_SECTION_NODE:
1245         case Node::COMMENT_NODE:
1246         case Node::ELEMENT_NODE:
1247         case Node::ENTITY_REFERENCE_NODE:
1248         case Node::PROCESSING_INSTRUCTION_NODE:
1249         case Node::TEXT_NODE:
1250         case Node::XPATH_NAMESPACE_NODE:
1251             break;
1252     }
1253
1254     // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
1255     // the Range is read-only.
1256     if (containedByReadOnly()) {
1257         ec = NO_MODIFICATION_ALLOWED_ERR;
1258         return;
1259     }
1260
1261     // Raise a HIERARCHY_REQUEST_ERR if startContainer() doesn't accept children like newParent.
1262     Node* parentOfNewParent = &startContainer();
1263
1264     // If startContainer() is a character data node, it will be split and it will be its parent that will
1265     // need to accept newParent (or in the case of a comment, it logically "would" be inserted into the parent,
1266     // although this will fail below for another reason).
1267     if (parentOfNewParent->isCharacterDataNode())
1268         parentOfNewParent = parentOfNewParent->parentNode();
1269     if (!parentOfNewParent || !parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
1270         ec = HIERARCHY_REQUEST_ERR;
1271         return;
1272     }
1273     
1274     if (newParent->contains(&startContainer())) {
1275         ec = HIERARCHY_REQUEST_ERR;
1276         return;
1277     }
1278
1279     // FIXME: Do we need a check if the node would end up with a child node of a type not
1280     // allowed by the type of node?
1281
1282     // INVALID_STATE_ERR: Raised if the Range partially selects a non-Text node.
1283     // https://dom.spec.whatwg.org/#dom-range-surroundcontents (step 1).
1284     Node* startNonTextContainer = &startContainer();
1285     if (startNonTextContainer->nodeType() == Node::TEXT_NODE)
1286         startNonTextContainer = startNonTextContainer->parentNode();
1287     Node* endNonTextContainer = &endContainer();
1288     if (endNonTextContainer->nodeType() == Node::TEXT_NODE)
1289         endNonTextContainer = endNonTextContainer->parentNode();
1290     if (startNonTextContainer != endNonTextContainer) {
1291         ec = INVALID_STATE_ERR;
1292         return;
1293     }
1294
1295     ec = 0;
1296     while (Node* n = newParent->firstChild()) {
1297         downcast<ContainerNode>(*newParent).removeChild(n, ec);
1298         if (ec)
1299             return;
1300     }
1301     RefPtr<DocumentFragment> fragment = extractContents(ec);
1302     if (ec)
1303         return;
1304     insertNode(newParent, ec);
1305     if (ec)
1306         return;
1307     newParent->appendChild(fragment.release(), ec);
1308     if (ec)
1309         return;
1310     selectNode(newParent.get(), ec);
1311 }
1312
1313 void Range::setStartBefore(Node* refNode, ExceptionCode& ec)
1314 {
1315     if (!refNode) {
1316         ec = NOT_FOUND_ERR;
1317         return;
1318     }
1319
1320     ec = 0;
1321     checkNodeBA(refNode, ec);
1322     if (ec)
1323         return;
1324
1325     setStart(refNode->parentNode(), refNode->computeNodeIndex(), ec);
1326 }
1327
1328 void Range::checkDeleteExtract(ExceptionCode& ec)
1329 {
1330     ec = 0;
1331     if (!commonAncestorContainer())
1332         return;
1333
1334     Node* pastLast = pastLastNode();
1335     for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
1336         if (n->isReadOnlyNode()) {
1337             ec = NO_MODIFICATION_ALLOWED_ERR;
1338             return;
1339         }
1340         if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) {
1341             ec = HIERARCHY_REQUEST_ERR;
1342             return;
1343         }
1344     }
1345
1346     if (containedByReadOnly()) {
1347         ec = NO_MODIFICATION_ALLOWED_ERR;
1348         return;
1349     }
1350 }
1351
1352 bool Range::containedByReadOnly() const
1353 {
1354     for (Node* n = &startContainer(); n; n = n->parentNode()) {
1355         if (n->isReadOnlyNode())
1356             return true;
1357     }
1358     for (Node* n = &endContainer(); n; n = n->parentNode()) {
1359         if (n->isReadOnlyNode())
1360             return true;
1361     }
1362     return false;
1363 }
1364
1365 Node* Range::firstNode() const
1366 {
1367     if (startContainer().offsetInCharacters())
1368         return &startContainer();
1369     if (Node* child = startContainer().traverseToChildAt(m_start.offset()))
1370         return child;
1371     if (!m_start.offset())
1372         return &startContainer();
1373     return NodeTraversal::nextSkippingChildren(startContainer());
1374 }
1375
1376 ShadowRoot* Range::shadowRoot() const
1377 {
1378     return startContainer().containingShadowRoot();
1379 }
1380
1381 Node* Range::pastLastNode() const
1382 {
1383     if (endContainer().offsetInCharacters())
1384         return NodeTraversal::nextSkippingChildren(endContainer());
1385     if (Node* child = endContainer().traverseToChildAt(m_end.offset()))
1386         return child;
1387     return NodeTraversal::nextSkippingChildren(endContainer());
1388 }
1389
1390 IntRect Range::absoluteBoundingBox() const
1391 {
1392     IntRect result;
1393     Vector<IntRect> rects;
1394     absoluteTextRects(rects);
1395     const size_t n = rects.size();
1396     for (size_t i = 0; i < n; ++i)
1397         result.unite(rects[i]);
1398     return result;
1399 }
1400
1401 void Range::absoluteTextRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
1402 {
1403     bool allFixed = true;
1404     bool someFixed = false;
1405
1406     Node* stopNode = pastLastNode();
1407     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
1408         RenderObject* renderer = node->renderer();
1409         if (!renderer)
1410             continue;
1411         bool isFixed = false;
1412         if (renderer->isBR())
1413             renderer->absoluteRects(rects, flooredLayoutPoint(renderer->localToAbsolute()));
1414         else if (is<RenderText>(*renderer)) {
1415             int startOffset = node == &startContainer() ? m_start.offset() : 0;
1416             int endOffset = node == &endContainer() ? m_end.offset() : std::numeric_limits<int>::max();
1417             rects.appendVector(downcast<RenderText>(*renderer).absoluteRectsForRange(startOffset, endOffset, useSelectionHeight, &isFixed));
1418         } else
1419             continue;
1420         allFixed &= isFixed;
1421         someFixed |= isFixed;
1422     }
1423     
1424     if (inFixed)
1425         *inFixed = allFixed ? EntirelyFixedPosition : (someFixed ? PartiallyFixedPosition : NotFixedPosition);
1426 }
1427
1428 void Range::absoluteTextQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
1429 {
1430     bool allFixed = true;
1431     bool someFixed = false;
1432
1433     Node* stopNode = pastLastNode();
1434     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
1435         RenderObject* renderer = node->renderer();
1436         if (!renderer)
1437             continue;
1438         bool isFixed = false;
1439         if (renderer->isBR())
1440             renderer->absoluteQuads(quads, &isFixed);
1441         else if (is<RenderText>(*renderer)) {
1442             int startOffset = node == &startContainer() ? m_start.offset() : 0;
1443             int endOffset = node == &endContainer() ? m_end.offset() : std::numeric_limits<int>::max();
1444             quads.appendVector(downcast<RenderText>(*renderer).absoluteQuadsForRange(startOffset, endOffset, useSelectionHeight, &isFixed));
1445         } else
1446             continue;
1447         allFixed &= isFixed;
1448         someFixed |= isFixed;
1449     }
1450
1451     if (inFixed)
1452         *inFixed = allFixed ? EntirelyFixedPosition : (someFixed ? PartiallyFixedPosition : NotFixedPosition);
1453 }
1454
1455 #if PLATFORM(IOS)
1456 static bool intervalsSufficientlyOverlap(int startA, int endA, int startB, int endB)
1457 {
1458     if (endA <= startA || endB <= startB)
1459         return false;
1460
1461     const float sufficientOverlap = .75;
1462
1463     int lengthA = endA - startA;
1464     int lengthB = endB - startB;
1465
1466     int maxStart = std::max(startA, startB);
1467     int minEnd = std::min(endA, endB);
1468
1469     if (maxStart > minEnd)
1470         return false;
1471
1472     return minEnd - maxStart >= sufficientOverlap * std::min(lengthA, lengthB);
1473 }
1474
1475 static inline void adjustLineHeightOfSelectionRects(Vector<SelectionRect>& rects, size_t numberOfRects, int lineNumber, int lineTop, int lineHeight)
1476 {
1477     ASSERT(rects.size() >= numberOfRects);
1478     for (size_t i = numberOfRects; i; ) {
1479         --i;
1480         if (rects[i].lineNumber())
1481             break;
1482         rects[i].setLineNumber(lineNumber);
1483         rects[i].setLogicalTop(lineTop);
1484         rects[i].setLogicalHeight(lineHeight);
1485     }
1486 }
1487
1488 static SelectionRect coalesceSelectionRects(const SelectionRect& original, const SelectionRect& previous)
1489 {
1490     SelectionRect result(unionRect(previous.rect(), original.rect()), original.isHorizontal(), original.pageNumber());
1491     result.setDirection(original.containsStart() || original.containsEnd() ? original.direction() : previous.direction());
1492     result.setContainsStart(previous.containsStart() || original.containsStart());
1493     result.setContainsEnd(previous.containsEnd() || original.containsEnd());
1494     result.setIsFirstOnLine(previous.isFirstOnLine() || original.isFirstOnLine());
1495     result.setIsLastOnLine(previous.isLastOnLine() || original.isLastOnLine());
1496     return result;
1497 }
1498
1499 // This function is similar in spirit to addLineBoxRects, but annotates the returned rectangles
1500 // with additional state which helps iOS draw selections in its unique way.
1501 void Range::collectSelectionRects(Vector<SelectionRect>& rects)
1502 {
1503     auto& startContainer = this->startContainer();
1504     auto& endContainer = this->endContainer();
1505     int startOffset = m_start.offset();
1506     int endOffset = m_end.offset();
1507
1508     Vector<SelectionRect> newRects;
1509     Node* stopNode = pastLastNode();
1510     bool hasFlippedWritingMode = startContainer.renderer() && startContainer.renderer()->style().isFlippedBlocksWritingMode();
1511     bool containsDifferentWritingModes = false;
1512     for (Node* node = firstNode(); node && node != stopNode; node = NodeTraversal::next(*node)) {
1513         RenderObject* renderer = node->renderer();
1514         // Only ask leaf render objects for their line box rects.
1515         if (renderer && !renderer->firstChildSlow() && renderer->style().userSelect() != SELECT_NONE) {
1516             bool isStartNode = renderer->node() == &startContainer;
1517             bool isEndNode = renderer->node() == &endContainer;
1518             if (hasFlippedWritingMode != renderer->style().isFlippedBlocksWritingMode())
1519                 containsDifferentWritingModes = true;
1520             // FIXME: Sending 0 for the startOffset is a weird way of telling the renderer that the selection
1521             // doesn't start inside it, since we'll also send 0 if the selection *does* start in it, at offset 0.
1522             //
1523             // FIXME: Selection endpoints aren't always inside leaves, and we only build SelectionRects for leaves,
1524             // so we can't accurately determine which SelectionRects contain the selection start and end using
1525             // only the offsets of the start and end. We need to pass the whole Range.
1526             int beginSelectionOffset = isStartNode ? startOffset : 0;
1527             int endSelectionOffset = isEndNode ? endOffset : std::numeric_limits<int>::max();
1528             renderer->collectSelectionRects(newRects, beginSelectionOffset, endSelectionOffset);
1529             size_t numberOfNewRects = newRects.size();
1530             for (size_t i = 0; i < numberOfNewRects; ++i) {
1531                 SelectionRect& selectionRect = newRects[i];
1532                 if (selectionRect.containsStart() && !isStartNode)
1533                     selectionRect.setContainsStart(false);
1534                 if (selectionRect.containsEnd() && !isEndNode)
1535                     selectionRect.setContainsEnd(false);
1536                 if (selectionRect.logicalWidth() || selectionRect.logicalHeight())
1537                     rects.append(newRects[i]);
1538             }
1539             newRects.shrink(0);
1540         }
1541     }
1542
1543     // The range could span over nodes with different writing modes.
1544     // If this is the case, we use the writing mode of the common ancestor.
1545     if (containsDifferentWritingModes) {
1546         if (Node* ancestor = commonAncestorContainer(&startContainer, &endContainer))
1547             hasFlippedWritingMode = ancestor->renderer()->style().isFlippedBlocksWritingMode();
1548     }
1549
1550     const size_t numberOfRects = rects.size();
1551
1552     // If the selection ends in a BR, then add the line break bit to the last
1553     // rect we have. This will cause its selection rect to extend to the
1554     // end of the line.
1555     if (stopNode && stopNode->hasTagName(HTMLNames::brTag) && numberOfRects) {
1556         // Only set the line break bit if the end of the range actually
1557         // extends all the way to include the <br>. VisiblePosition helps to
1558         // figure this out.
1559         VisiblePosition endPosition(createLegacyEditingPosition(&endContainer, endOffset), VP_DEFAULT_AFFINITY);
1560         VisiblePosition brPosition(createLegacyEditingPosition(stopNode, 0), VP_DEFAULT_AFFINITY);
1561         if (endPosition == brPosition)
1562             rects.last().setIsLineBreak(true);    
1563     }
1564
1565     int lineTop = std::numeric_limits<int>::max();
1566     int lineBottom = std::numeric_limits<int>::min();
1567     int lastLineTop = lineTop;
1568     int lastLineBottom = lineBottom;
1569     int lineNumber = 0;
1570
1571     for (size_t i = 0; i < numberOfRects; ++i) {
1572         int currentRectTop = rects[i].logicalTop();
1573         int currentRectBottom = currentRectTop + rects[i].logicalHeight();
1574
1575         // We don't want to count the ruby text as a separate line.
1576         if (intervalsSufficientlyOverlap(currentRectTop, currentRectBottom, lineTop, lineBottom) || (i && rects[i].isRubyText())) {
1577             // Grow the current line bounds.
1578             lineTop = std::min(lineTop, currentRectTop);
1579             lineBottom = std::max(lineBottom, currentRectBottom);
1580             // Avoid overlap with the previous line.
1581             if (!hasFlippedWritingMode)
1582                 lineTop = std::max(lastLineBottom, lineTop);
1583             else
1584                 lineBottom = std::min(lastLineTop, lineBottom);
1585         } else {
1586             adjustLineHeightOfSelectionRects(rects, i, lineNumber, lineTop, lineBottom - lineTop);
1587             if (!hasFlippedWritingMode) {
1588                 lastLineTop = lineTop;
1589                 if (currentRectBottom >= lastLineTop) {
1590                     lastLineBottom = lineBottom;
1591                     lineTop = lastLineBottom;
1592                 } else {
1593                     lineTop = currentRectTop;
1594                     lastLineBottom = std::numeric_limits<int>::min();
1595                 }
1596                 lineBottom = currentRectBottom;
1597             } else {
1598                 lastLineBottom = lineBottom;
1599                 if (currentRectTop <= lastLineBottom && i && rects[i].pageNumber() == rects[i - 1].pageNumber()) {
1600                     lastLineTop = lineTop;
1601                     lineBottom = lastLineTop;
1602                 } else {
1603                     lastLineTop = std::numeric_limits<int>::max();
1604                     lineBottom = currentRectBottom;
1605                 }
1606                 lineTop = currentRectTop;
1607             }
1608             ++lineNumber;
1609         }
1610     }
1611
1612     // Adjust line height.
1613     adjustLineHeightOfSelectionRects(rects, numberOfRects, lineNumber, lineTop, lineBottom - lineTop);
1614
1615     // Sort the rectangles and make sure there are no gaps. The rectangles could be unsorted when
1616     // there is ruby text and we could have gaps on the line when adjacent elements on the line
1617     // have a different orientation.
1618     size_t firstRectWithCurrentLineNumber = 0;
1619     for (size_t currentRect = 1; currentRect < numberOfRects; ++currentRect) {
1620         if (rects[currentRect].lineNumber() != rects[currentRect - 1].lineNumber()) {
1621             firstRectWithCurrentLineNumber = currentRect;
1622             continue;
1623         }
1624         if (rects[currentRect].logicalLeft() >= rects[currentRect - 1].logicalLeft())
1625             continue;
1626
1627         SelectionRect selectionRect = rects[currentRect];
1628         size_t i;
1629         for (i = currentRect; i > firstRectWithCurrentLineNumber && selectionRect.logicalLeft() < rects[i - 1].logicalLeft(); --i)
1630             rects[i] = rects[i - 1];
1631         rects[i] = selectionRect;
1632     }
1633
1634     for (size_t j = 1; j < numberOfRects; ++j) {
1635         if (rects[j].lineNumber() != rects[j - 1].lineNumber())
1636             continue;
1637         SelectionRect& previousRect = rects[j - 1];
1638         bool previousRectMayNotReachRightEdge = (previousRect.direction() == LTR && previousRect.containsEnd()) || (previousRect.direction() == RTL && previousRect.containsStart());
1639         if (previousRectMayNotReachRightEdge)
1640             continue;
1641         int adjustedWidth = rects[j].logicalLeft() - previousRect.logicalLeft();
1642         if (adjustedWidth > previousRect.logicalWidth())
1643             previousRect.setLogicalWidth(adjustedWidth);
1644     }
1645
1646     int maxLineNumber = lineNumber;
1647
1648     // Extend rects out to edges as needed.
1649     for (size_t i = 0; i < numberOfRects; ++i) {
1650         SelectionRect& selectionRect = rects[i];
1651         if (!selectionRect.isLineBreak() && selectionRect.lineNumber() >= maxLineNumber)
1652             continue;
1653         if (selectionRect.direction() == RTL && selectionRect.isFirstOnLine()) {
1654             selectionRect.setLogicalWidth(selectionRect.logicalWidth() + selectionRect.logicalLeft() - selectionRect.minX());
1655             selectionRect.setLogicalLeft(selectionRect.minX());
1656         } else if (selectionRect.direction() == LTR && selectionRect.isLastOnLine())
1657             selectionRect.setLogicalWidth(selectionRect.maxX() - selectionRect.logicalLeft());
1658     }
1659
1660     // Union all the rectangles on interior lines (i.e. not first or last).
1661     // On first and last lines, just avoid having overlaps by merging intersecting rectangles.
1662     Vector<SelectionRect> unionedRects;
1663     IntRect interiorUnionRect;
1664     for (size_t i = 0; i < numberOfRects; ++i) {
1665         SelectionRect& currentRect = rects[i];
1666         if (currentRect.lineNumber() == 1) {
1667             ASSERT(interiorUnionRect.isEmpty());
1668             if (!unionedRects.isEmpty()) {
1669                 SelectionRect& previousRect = unionedRects.last();
1670                 if (previousRect.rect().intersects(currentRect.rect())) {
1671                     previousRect = coalesceSelectionRects(currentRect, previousRect);
1672                     continue;
1673                 }
1674             }
1675             // Couldn't merge with previous rect, so just appending.
1676             unionedRects.append(currentRect);
1677         } else if (currentRect.lineNumber() < maxLineNumber) {
1678             if (interiorUnionRect.isEmpty()) {
1679                 // Start collecting interior rects.
1680                 interiorUnionRect = currentRect.rect();         
1681             } else if (interiorUnionRect.intersects(currentRect.rect())
1682                 || interiorUnionRect.maxX() == currentRect.rect().x()
1683                 || interiorUnionRect.maxY() == currentRect.rect().y()
1684                 || interiorUnionRect.x() == currentRect.rect().maxX()
1685                 || interiorUnionRect.y() == currentRect.rect().maxY()) {
1686                 // Only union the lines that are attached.
1687                 // For iBooks, the interior lines may cross multiple horizontal pages.
1688                 interiorUnionRect.unite(currentRect.rect());
1689             } else {
1690                 unionedRects.append(SelectionRect(interiorUnionRect, currentRect.isHorizontal(), currentRect.pageNumber()));
1691                 interiorUnionRect = currentRect.rect();
1692             }
1693         } else {
1694             // Processing last line.
1695             if (!interiorUnionRect.isEmpty()) {
1696                 unionedRects.append(SelectionRect(interiorUnionRect, currentRect.isHorizontal(), currentRect.pageNumber()));
1697                 interiorUnionRect = IntRect();
1698             }
1699
1700             ASSERT(!unionedRects.isEmpty());
1701             SelectionRect& previousRect = unionedRects.last();
1702             if (previousRect.logicalTop() == currentRect.logicalTop() && previousRect.rect().intersects(currentRect.rect())) {
1703                 // previousRect is also on the last line, and intersects the current one.
1704                 previousRect = coalesceSelectionRects(currentRect, previousRect);
1705                 continue;
1706             }
1707             // Couldn't merge with previous rect, so just appending.
1708             unionedRects.append(currentRect);
1709         }
1710     }
1711
1712     rects.swap(unionedRects);
1713 }
1714 #endif
1715
1716 #if ENABLE(TREE_DEBUGGING)
1717 void Range::formatForDebugger(char* buffer, unsigned length) const
1718 {
1719     StringBuilder result;
1720
1721     const int FormatBufferSize = 1024;
1722     char s[FormatBufferSize];
1723     result.appendLiteral("from offset ");
1724     result.appendNumber(m_start.offset());
1725     result.appendLiteral(" of ");
1726     startContainer().formatForDebugger(s, FormatBufferSize);
1727     result.append(s);
1728     result.appendLiteral(" to offset ");
1729     result.appendNumber(m_end.offset());
1730     result.appendLiteral(" of ");
1731     endContainer().formatForDebugger(s, FormatBufferSize);
1732     result.append(s);
1733
1734     strncpy(buffer, result.toString().utf8().data(), length - 1);
1735 }
1736 #endif
1737
1738 bool Range::contains(const Range& other) const
1739 {
1740     if (commonAncestorContainer()->ownerDocument() != other.commonAncestorContainer()->ownerDocument())
1741         return false;
1742
1743     short startToStart = compareBoundaryPoints(Range::START_TO_START, &other, ASSERT_NO_EXCEPTION);
1744     if (startToStart > 0)
1745         return false;
1746
1747     short endToEnd = compareBoundaryPoints(Range::END_TO_END, &other, ASSERT_NO_EXCEPTION);
1748     return endToEnd >= 0;
1749 }
1750
1751 bool Range::contains(const VisiblePosition& position) const
1752 {
1753     RefPtr<Range> positionRange = makeRange(position, position);
1754     if (!positionRange)
1755         return false;
1756     return contains(*positionRange);
1757 }
1758
1759 bool areRangesEqual(const Range* a, const Range* b)
1760 {
1761     if (a == b)
1762         return true;
1763     if (!a || !b)
1764         return false;
1765     return a->startPosition() == b->startPosition() && a->endPosition() == b->endPosition();
1766 }
1767
1768 bool rangesOverlap(const Range* a, const Range* b)
1769 {
1770     if (!a || !b)
1771         return false;
1772
1773     if (a == b)
1774         return true;
1775
1776     if (a->commonAncestorContainer()->ownerDocument() != b->commonAncestorContainer()->ownerDocument())
1777         return false;
1778
1779     short startToStart = a->compareBoundaryPoints(Range::START_TO_START, b, ASSERT_NO_EXCEPTION);
1780     short endToEnd = a->compareBoundaryPoints(Range::END_TO_END, b, ASSERT_NO_EXCEPTION);
1781
1782     // First range contains the second range.
1783     if (startToStart <= 0 && endToEnd >= 0)
1784         return true;
1785
1786     // End of first range is inside second range.
1787     if (a->compareBoundaryPoints(Range::START_TO_END, b, ASSERT_NO_EXCEPTION) >= 0 && endToEnd <= 0)
1788         return true;
1789
1790     // Start of first range is inside second range.
1791     if (startToStart >= 0 && a->compareBoundaryPoints(Range::END_TO_START, b, ASSERT_NO_EXCEPTION) <= 0)
1792         return true;
1793
1794     return false;
1795 }
1796
1797 Ref<Range> rangeOfContents(Node& node)
1798 {
1799     Ref<Range> range = Range::create(node.document());
1800     int exception = 0;
1801     range->selectNodeContents(&node, exception);
1802     return range;
1803 }
1804
1805 static inline void boundaryNodeChildrenChanged(RangeBoundaryPoint& boundary, ContainerNode& container)
1806 {
1807     if (!boundary.childBefore())
1808         return;
1809     if (boundary.container() != &container)
1810         return;
1811     boundary.invalidateOffset();
1812 }
1813
1814 void Range::nodeChildrenChanged(ContainerNode& container)
1815 {
1816     ASSERT(&container.document() == &ownerDocument());
1817     boundaryNodeChildrenChanged(m_start, container);
1818     boundaryNodeChildrenChanged(m_end, container);
1819 }
1820
1821 static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode& container)
1822 {
1823     for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
1824         if (boundary.childBefore() == nodeToBeRemoved) {
1825             boundary.setToStartOfNode(&container);
1826             return;
1827         }
1828
1829         for (Node* n = boundary.container(); n; n = n->parentNode()) {
1830             if (n == nodeToBeRemoved) {
1831                 boundary.setToStartOfNode(&container);
1832                 return;
1833             }
1834         }
1835     }
1836 }
1837
1838 void Range::nodeChildrenWillBeRemoved(ContainerNode& container)
1839 {
1840     ASSERT(&container.document() == &ownerDocument());
1841     boundaryNodeChildrenWillBeRemoved(m_start, container);
1842     boundaryNodeChildrenWillBeRemoved(m_end, container);
1843 }
1844
1845 static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node& nodeToBeRemoved)
1846 {
1847     if (boundary.childBefore() == &nodeToBeRemoved) {
1848         boundary.childBeforeWillBeRemoved();
1849         return;
1850     }
1851
1852     for (Node* n = boundary.container(); n; n = n->parentNode()) {
1853         if (n == &nodeToBeRemoved) {
1854             boundary.setToBeforeChild(nodeToBeRemoved);
1855             return;
1856         }
1857     }
1858 }
1859
1860 void Range::nodeWillBeRemoved(Node& node)
1861 {
1862     ASSERT(&node.document() == &ownerDocument());
1863     ASSERT(&node != &ownerDocument());
1864     ASSERT(node.parentNode());
1865     boundaryNodeWillBeRemoved(m_start, node);
1866     boundaryNodeWillBeRemoved(m_end, node);
1867 }
1868
1869 static inline void boundaryTextInserted(RangeBoundaryPoint& boundary, Node* text, unsigned offset, unsigned length)
1870 {
1871     if (boundary.container() != text)
1872         return;
1873     unsigned boundaryOffset = boundary.offset();
1874     if (offset >= boundaryOffset)
1875         return;
1876     boundary.setOffset(boundaryOffset + length);
1877 }
1878
1879 void Range::textInserted(Node* text, unsigned offset, unsigned length)
1880 {
1881     ASSERT(text);
1882     ASSERT(&text->document() == &ownerDocument());
1883     boundaryTextInserted(m_start, text, offset, length);
1884     boundaryTextInserted(m_end, text, offset, length);
1885 }
1886
1887 static inline void boundaryTextRemoved(RangeBoundaryPoint& boundary, Node* text, unsigned offset, unsigned length)
1888 {
1889     if (boundary.container() != text)
1890         return;
1891     unsigned boundaryOffset = boundary.offset();
1892     if (offset >= boundaryOffset)
1893         return;
1894     if (offset + length >= boundaryOffset)
1895         boundary.setOffset(offset);
1896     else
1897         boundary.setOffset(boundaryOffset - length);
1898 }
1899
1900 void Range::textRemoved(Node* text, unsigned offset, unsigned length)
1901 {
1902     ASSERT(text);
1903     ASSERT(&text->document() == &ownerDocument());
1904     boundaryTextRemoved(m_start, text, offset, length);
1905     boundaryTextRemoved(m_end, text, offset, length);
1906 }
1907
1908 static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
1909 {
1910     if (boundary.container() == oldNode.node())
1911         boundary.set(oldNode.node()->previousSibling(), boundary.offset() + offset, 0);
1912     else if (boundary.container() == oldNode.node()->parentNode() && boundary.offset() == oldNode.index())
1913         boundary.set(oldNode.node()->previousSibling(), offset, 0);
1914 }
1915
1916 void Range::textNodesMerged(NodeWithIndex& oldNode, unsigned offset)
1917 {
1918     ASSERT(oldNode.node());
1919     ASSERT(&oldNode.node()->document() == &ownerDocument());
1920     ASSERT(oldNode.node()->parentNode());
1921     ASSERT(oldNode.node()->isTextNode());
1922     ASSERT(oldNode.node()->previousSibling());
1923     ASSERT(oldNode.node()->previousSibling()->isTextNode());
1924     boundaryTextNodesMerged(m_start, oldNode, offset);
1925     boundaryTextNodesMerged(m_end, oldNode, offset);
1926 }
1927
1928 static inline void boundaryTextNodesSplit(RangeBoundaryPoint& boundary, Text* oldNode)
1929 {
1930     if (boundary.container() != oldNode)
1931         return;
1932     unsigned boundaryOffset = boundary.offset();
1933     if (boundaryOffset <= oldNode->length())
1934         return;
1935     boundary.set(oldNode->nextSibling(), boundaryOffset - oldNode->length(), 0);
1936 }
1937
1938 void Range::textNodeSplit(Text* oldNode)
1939 {
1940     ASSERT(oldNode);
1941     ASSERT(&oldNode->document() == &ownerDocument());
1942     ASSERT(oldNode->parentNode());
1943     ASSERT(oldNode->isTextNode());
1944     ASSERT(oldNode->nextSibling());
1945     ASSERT(oldNode->nextSibling()->isTextNode());
1946     boundaryTextNodesSplit(m_start, oldNode);
1947     boundaryTextNodesSplit(m_end, oldNode);
1948 }
1949
1950 void Range::expand(const String& unit, ExceptionCode& ec)
1951 {
1952     VisiblePosition start(startPosition());
1953     VisiblePosition end(endPosition());
1954     if (unit == "word") {
1955         start = startOfWord(start);
1956         end = endOfWord(end);
1957     } else if (unit == "sentence") {
1958         start = startOfSentence(start);
1959         end = endOfSentence(end);
1960     } else if (unit == "block") {
1961         start = startOfParagraph(start);
1962         end = endOfParagraph(end);
1963     } else if (unit == "document") {
1964         start = startOfDocument(start);
1965         end = endOfDocument(end);
1966     } else
1967         return;
1968     setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), ec);
1969     setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), ec);
1970 }
1971
1972 Ref<ClientRectList> Range::getClientRects() const
1973 {
1974     ownerDocument().updateLayoutIgnorePendingStylesheets();
1975
1976     Vector<FloatQuad> quads;
1977     getBorderAndTextQuads(quads, CoordinateSpace::Client);
1978
1979     return ClientRectList::create(quads);
1980 }
1981
1982 Ref<ClientRect> Range::getBoundingClientRect() const
1983 {
1984     return ClientRect::create(boundingRectInternal(CoordinateSpace::Client));
1985 }
1986
1987 void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads, CoordinateSpace space) const
1988 {
1989     Node* stopNode = pastLastNode();
1990
1991     HashSet<Node*> selectedElementsSet;
1992     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
1993         if (node->isElementNode())
1994             selectedElementsSet.add(node);
1995     }
1996
1997     // Don't include elements that are only partially selected.
1998     Node* lastNode = m_end.childBefore() ? m_end.childBefore() : &endContainer();
1999     for (Node* parent = lastNode->parentNode(); parent; parent = parent->parentNode())
2000         selectedElementsSet.remove(parent);
2001
2002     for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
2003         if (is<Element>(*node) && selectedElementsSet.contains(node) && !selectedElementsSet.contains(node->parentNode())) {
2004             if (RenderBoxModelObject* renderBoxModelObject = downcast<Element>(*node).renderBoxModelObject()) {
2005                 Vector<FloatQuad> elementQuads;
2006                 renderBoxModelObject->absoluteQuads(elementQuads);
2007
2008                 if (space == CoordinateSpace::Client)
2009                     ownerDocument().adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(elementQuads, renderBoxModelObject->style());
2010
2011                 quads.appendVector(elementQuads);
2012             }
2013         } else if (is<Text>(*node)) {
2014             if (RenderText* renderText = downcast<Text>(*node).renderer()) {
2015                 int startOffset = node == &startContainer() ? m_start.offset() : 0;
2016                 int endOffset = node == &endContainer() ? m_end.offset() : INT_MAX;
2017                 
2018                 auto textQuads = renderText->absoluteQuadsForRange(startOffset, endOffset);
2019
2020                 if (space == CoordinateSpace::Client)
2021                     ownerDocument().adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(textQuads, renderText->style());
2022
2023                 quads.appendVector(textQuads);
2024             }
2025         }
2026     }
2027 }
2028
2029 FloatRect Range::boundingRectInternal(CoordinateSpace space) const
2030 {
2031     ownerDocument().updateLayoutIgnorePendingStylesheets();
2032
2033     Vector<FloatQuad> quads;
2034     getBorderAndTextQuads(quads, space);
2035
2036     FloatRect result;
2037     for (auto& quad : quads)
2038         result.unite(quad.boundingBox());
2039
2040     return result;
2041 }
2042
2043 FloatRect Range::absoluteBoundingRect() const
2044 {
2045     return boundingRectInternal(CoordinateSpace::Absolute);
2046 }
2047
2048 } // namespace WebCore
2049
2050 #if ENABLE(TREE_DEBUGGING)
2051
2052 void showTree(const WebCore::Range* range)
2053 {
2054     if (range && range->boundaryPointsValid()) {
2055         range->startContainer().showTreeAndMark(&range->startContainer(), "S", &range->endContainer(), "E");
2056         fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset(), range->endOffset());
2057     }
2058 }
2059
2060 #endif