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