18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2000 Gunnstein Lye (gunnstein@netcom.no)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2001 Peter Kelly (pmk@post.com)
6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Range.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RangeException.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ClientRect.h"
29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ClientRectList.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentFragment.h"
31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FrameView.h"
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLElement.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NodeWithIndex.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ProcessingInstruction.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextIterator.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "VisiblePosition.h"
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "htmlediting.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "markup.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "visible_units.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/RefCountedLeakCounter.h>
448a26975f9657a07318a10d481d7f332dad759325Ben Murdoch#include <wtf/Vector.h>
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic WTF::RefCountedLeakCounter rangeCounter("Range");
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5427621ca63c064d1a1d6af6373c2c9f7018e19861Steve Blocktypedef Vector<RefPtr<Node> > NodeVector;
5527621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline Range::Range(PassRefPtr<Document> ownerDocument)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_ownerDocument(ownerDocument)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_start(m_ownerDocument)
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_end(m_ownerDocument)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rangeCounter.increment();
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ownerDocument->attachRange(this);
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return adoptRef(new Range(ownerDocument));
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline Range::Range(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_ownerDocument(ownerDocument)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_start(m_ownerDocument)
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_end(m_ownerDocument)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rangeCounter.increment();
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ownerDocument->attachRange(this);
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Simply setting the containers and offsets directly would not do any of the checking
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that setStart and setEnd do, so we call those functions.
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setStart(startContainer, startOffset, ec);
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!ec);
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setEnd(endContainer, endOffset, ec);
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!ec);
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, PassRefPtr<Node> startContainer, int startOffset, PassRefPtr<Node> endContainer, int endOffset)
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return adoptRef(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, const Position& start, const Position& end)
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
100db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    return adoptRef(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRange::~Range()
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Always detach (even if we've already detached) to fix https://bugs.webkit.org/show_bug.cgi?id=26044
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_ownerDocument->detachRange(this);
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rangeCounter.decrement();
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11368513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid Range::setDocument(Document* document)
11468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
11568513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(m_ownerDocument != document);
11668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (m_ownerDocument)
11768513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_ownerDocument->detachRange(this);
11868513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_ownerDocument = document;
11968513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_start.setToStartOfNode(document);
12068513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_end.setToStartOfNode(document);
12168513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_ownerDocument->attachRange(this);
12268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
12368513a70bcd92384395513322f1b801e7bf9c729Steve Block
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::startContainer(ExceptionCode& ec) const
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_start.container();
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint Range::startOffset(ExceptionCode& ec) const
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_start.offset();
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::endContainer(ExceptionCode& ec) const
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_end.container();
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint Range::endOffset(ExceptionCode& ec) const
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_end.offset();
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::commonAncestorContainer(ExceptionCode& ec) const
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return commonAncestorContainer(m_start.container(), m_end.container());
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::commonAncestorContainer(Node* containerA, Node* containerB)
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* parentA = containerA; parentA; parentA = parentA->parentNode()) {
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Node* parentB = containerB; parentB; parentB = parentB->parentNode()) {
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (parentA == parentB)
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return parentA;
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Range::collapsed(ExceptionCode& ec) const
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_start == m_end;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* childNode = checkNodeWOffset(refNode.get(), offset, ec);
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_start.set(refNode, offset, childNode);
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // check if different root container
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* endRootContainer = m_end.container();
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (endRootContainer->parentNode())
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endRootContainer = endRootContainer->parentNode();
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* startRootContainer = m_start.container();
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (startRootContainer->parentNode())
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        startRootContainer = startRootContainer->parentNode();
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startRootContainer != endRootContainer)
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        collapse(true, ec);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // check if new start after end
2292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    else if (compareBoundaryPoints(m_start, m_end, ec) > 0) {
2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(!ec);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        collapse(true, ec);
2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* childNode = checkNodeWOffset(refNode.get(), offset, ec);
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_end.set(refNode, offset, childNode);
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // check if different root container
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* endRootContainer = m_end.container();
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (endRootContainer->parentNode())
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endRootContainer = endRootContainer->parentNode();
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* startRootContainer = m_start.container();
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (startRootContainer->parentNode())
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        startRootContainer = startRootContainer->parentNode();
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startRootContainer != endRootContainer)
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        collapse(false, ec);
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // check if new end before start
2692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (compareBoundaryPoints(m_start, m_end, ec) > 0) {
2702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(!ec);
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        collapse(false, ec);
2722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::collapse(bool toStart, ExceptionCode& ec)
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (toStart)
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_end = m_start;
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_start = m_end;
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec)
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_start.container()) {
2918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ec = INVALID_STATE_ERR;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!refNode) {
2968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ec = HIERARCHY_REQUEST_ERR;
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!refNode->attached()) {
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Firefox doesn't throw an exception for this case; it returns false.
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeWOffset(refNode, offset, ec);
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return compareBoundaryPoints(refNode, offset, m_start.container(), m_start.offset(), ec) >= 0 && !ec
3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        && compareBoundaryPoints(refNode, offset, m_end.container(), m_end.offset(), ec) <= 0 && !ec;
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochshort Range::comparePoint(Node* refNode, int offset, ExceptionCode& ec) const
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://developer.mozilla.org/en/docs/DOM:range.comparePoint
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This method returns -1, 0 or 1 depending on if the point described by the
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // refNode node and an offset within the node is before, same as, or after the range respectively.
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_start.container()) {
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!refNode) {
3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ec = HIERARCHY_REQUEST_ERR;
3328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 0;
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!refNode->attached() || refNode->document() != m_ownerDocument) {
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeWOffset(refNode, offset, ec);
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // compare to start, and point comes before
3462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (compareBoundaryPoints(refNode, offset, m_start.container(), m_start.offset(), ec) < 0)
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (ec)
3502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return 0;
3512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // compare to end, and point comes after
3532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (compareBoundaryPoints(refNode, offset, m_end.container(), m_end.offset(), ec) > 0 && !ec)
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1;
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // point is in the middle of this range, or on the boundary points
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRange::CompareResults Range::compareNode(Node* refNode, ExceptionCode& ec) const
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://developer.mozilla.org/en/docs/DOM:range.compareNode
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This method returns 0, 1, 2, or 3 based on if the node is before, after,
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // before and after(surrounds), or inside the range, respectively
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE;
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container() && refNode->attached()) {
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE;
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_start.container() && !refNode->attached()) {
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Firefox doesn't throw an exception for this case; it returns 0.
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Firefox doesn't throw an exception for this case; it returns 0.
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE;
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
386a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ContainerNode* parentNode = refNode->parentNode();
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int nodeIndex = refNode->nodeIndex();
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!parentNode) {
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if the node is the top document we should return NODE_BEFORE_AND_AFTER
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // but we throw to match firefox behavior
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE;
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (comparePoint(parentNode, nodeIndex, ec) < 0) { // starts before
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (comparePoint(parentNode, nodeIndex + 1, ec) > 0) // ends after the range
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return NODE_BEFORE_AND_AFTER;
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_BEFORE; // ends before or in the range
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else { // starts at or after the range start
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (comparePoint(parentNode, nodeIndex + 1, ec) > 0) // ends after the range
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return NODE_AFTER;
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NODE_INSIDE; // ends inside the range
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectshort Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionCode& ec) const
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!sourceRange) {
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* thisCont = commonAncestorContainer(ec);
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* sourceCont = sourceRange->commonAncestorContainer(ec);
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (thisCont->document() != sourceCont->document()) {
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* thisTop = thisCont;
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* sourceTop = sourceCont;
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (thisTop->parentNode())
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        thisTop = thisTop->parentNode();
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (sourceTop->parentNode())
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sourceTop = sourceTop->parentNode();
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (thisTop != sourceTop) { // in different DocumentFragments
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (how) {
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case START_TO_START:
4452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return compareBoundaryPoints(m_start, sourceRange->m_start, ec);
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case START_TO_END:
4472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return compareBoundaryPoints(m_end, sourceRange->m_start, ec);
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case END_TO_END:
4492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return compareBoundaryPoints(m_end, sourceRange->m_end, ec);
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case END_TO_START:
4512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return compareBoundaryPoints(m_start, sourceRange->m_end, ec);
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = SYNTAX_ERR;
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochshort Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB, ExceptionCode& ec)
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(containerA);
4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(containerB);
4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerA)
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!containerB)
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1;
4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // see DOM2 traversal & range section 2.5
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // case 1: both points have the same container
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containerA == containerB) {
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (offsetA == offsetB)
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;           // A is equal to B
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (offsetA < offsetB)
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;          // A is before B
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 1;           // A is after B
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // case 2: node C (container B or an ancestor) is a child node of A
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* c = containerB;
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (c && c->parentNode() != containerA)
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c = c->parentNode();
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (c) {
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int offsetC = 0;
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* n = containerA->firstChild();
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (n != c && offsetC < offsetA) {
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            offsetC++;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n = n->nextSibling();
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (offsetA <= offsetC)
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;              // A is before B
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 1;               // A is after B
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // case 3: node C (container A or an ancestor) is a child node of B
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    c = containerA;
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (c && c->parentNode() != containerB)
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c = c->parentNode();
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (c) {
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int offsetC = 0;
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* n = containerB->firstChild();
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (n != c && offsetC < offsetB) {
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            offsetC++;
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n = n->nextSibling();
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (offsetC < offsetB)
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1;              // A is before B
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 1;               // A is after B
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // case 4: containers A & B are siblings, or children of siblings
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // ### we need to do a traversal here instead
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* commonAncestor = commonAncestorContainer(containerA, containerB);
5192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!commonAncestor) {
5202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ec = WRONG_DOCUMENT_ERR;
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
5222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* childA = containerA;
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (childA && childA->parentNode() != commonAncestor)
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        childA = childA->parentNode();
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!childA)
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        childA = commonAncestor;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* childB = containerB;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (childB && childB->parentNode() != commonAncestor)
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        childB = childB->parentNode();
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!childB)
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        childB = commonAncestor;
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childA == childB)
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0; // A is equal to B
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* n = commonAncestor->firstChild();
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (n) {
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n == childA)
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return -1; // A is before B
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n == childB)
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 1; // A is after B
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n = n->nextSibling();
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Should never reach this point.
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochshort Range::compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const RangeBoundaryPoint& boundaryB, ExceptionCode& ec)
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return compareBoundaryPoints(boundaryA.container(), boundaryA.offset(), boundaryB.container(), boundaryB.offset(), ec);
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Range::boundaryPointsValid() const
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ExceptionCode ec = 0;
5592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_start.container() && compareBoundaryPoints(m_start, m_end, ec) <= 0 && !ec;
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::deleteContents(ExceptionCode& ec)
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkDeleteExtract(ec);
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    processContents(DELETE_CONTENTS, ec);
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Range::intersectsNode(Node* refNode, ExceptionCode& ec)
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Returns a bool if the node intersects the range.
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((!m_start.container() && refNode->attached())
5828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            || (m_start.container() && !refNode->attached())
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            || refNode->document() != m_ownerDocument) {
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Firefox doesn't throw an exception for these cases; it returns false.
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
588a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ContainerNode* parentNode = refNode->parentNode();
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int nodeIndex = refNode->nodeIndex();
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!parentNode) {
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if the node is the top document we should return NODE_BEFORE_AND_AFTER
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // but we throw to match firefox behavior
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (comparePoint(parentNode, nodeIndex, ec) < 0 && // starts before start
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        comparePoint(parentNode, nodeIndex + 1, ec) < 0) { // ends before start
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (comparePoint(parentNode, nodeIndex, ec) > 0 && // starts after end
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               comparePoint(parentNode, nodeIndex + 1, ec) > 0) { // ends after end
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true; // all other cases
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6092fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot)
6102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
6112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (node == commonRoot)
6122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
6132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(commonRoot->contains(node));
6152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (node->parentNode() != commonRoot)
6172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        node = node->parentNode();
6182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return node;
6202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
6212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
62281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offset, Node* commonRoot)
62381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
62481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(container);
62581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(commonRoot);
6261cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block
6271cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    if (!commonRoot->contains(container))
6281cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        return 0;
62981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
63081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (container == commonRoot) {
63181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        container = container->firstChild();
63281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (unsigned i = 0; container && i < offset; i++)
63381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            container = container->nextSibling();
63481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else {
63581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (container->parentNode() != commonRoot)
63681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            container = container->parentNode();
63781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
63881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
63981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return container;
64081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
64181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
64281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline unsigned lengthOfContentsInNode(Node* node)
64381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
64481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
64581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    switch (node->nodeType()) {
64681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::TEXT_NODE:
64781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::CDATA_SECTION_NODE:
64881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::COMMENT_NODE:
64981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return static_cast<CharacterData*>(node)->length();
65081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::PROCESSING_INSTRUCTION_NODE:
65181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return static_cast<ProcessingInstruction*>(node)->data().length();
65281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::ELEMENT_NODE:
65381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::ATTRIBUTE_NODE:
65481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::ENTITY_REFERENCE_NODE:
65581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::ENTITY_NODE:
65681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::DOCUMENT_NODE:
65781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::DOCUMENT_TYPE_NODE:
65881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::DOCUMENT_FRAGMENT_NODE:
65981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::NOTATION_NODE:
66081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case Node::XPATH_NAMESPACE_NODE:
66181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return node->childNodeCount();
66281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
66381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT_NOT_REACHED();
66481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return 0;
66581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
6662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<DocumentFragment> fragment;
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
671231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        fragment = DocumentFragment::create(m_ownerDocument.get());
6722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (collapsed(ec))
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return fragment.release();
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6791cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    RefPtr<Node> commonRoot = commonAncestorContainer(ec);
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(commonRoot);
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_start.container() == m_end.container()) {
6852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        processContentsBetweenOffsets(action, fragment, m_start.container(), m_start.offset(), m_end.offset(), ec);
6862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return fragment;
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // what is the highest node that partially selects the start / end of the range?
6901cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot.get());
6911cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot.get());
6922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Start and end containers are different.
694d0825bca7fe65beaee391d30da42e937db621564Steve Block    // There are three possibilities here:
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 1. Start container == commonRoot (End container must be a descendant)
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 2. End container == commonRoot (Start container must be a descendant)
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 3. Neither is commonRoot, they are both descendants
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In case 3, we grab everything after the start (up until a direct child
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // of commonRoot) into leftContents, and everything before the end (up until
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a direct child of commonRoot) into rightContents. Then we process all
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // commonRoot children between leftContents and rightContents
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In case 1 or 2, we skip either processing of leftContents or rightContents,
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // in which case the last lot of nodes either goes from the first or last
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // child of commonRoot.
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // These are deleted, cloned, or extracted (i.e. both) depending on action.
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7101cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    // Note that we are verifying that our common root hierarchy is still intact
7111cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    // after any DOM mutation event, at various stages below. See webkit bug 60350.
7121cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> leftContents;
7141cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    if (m_start.container() != commonRoot && commonRoot->contains(m_start.container())) {
71581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        leftContents = processContentsBetweenOffsets(action, 0, m_start.container(), m_start.offset(), lengthOfContentsInNode(m_start.container()), ec);
7161cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec);
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> rightContents;
7201cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    if (m_end.container() != commonRoot && commonRoot->contains(m_end.container())) {
7212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        rightContents = processContentsBetweenOffsets(action, 0, m_end.container(), 0, m_end.offset(), ec);
7221cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec);
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // delete all children of commonRoot between the start and end container
7261cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    RefPtr<Node> processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot.get());
7271cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    if (processStart && m_start.container() != commonRoot) // processStart contains nodes before m_start.
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        processStart = processStart->nextSibling();
7291cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot.get());
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Collapse the range, making sure that the result is not within a node that was partially selected.
7328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
7331cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        if (partialStart && commonRoot->contains(partialStart.get()))
7348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec);
7351cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        else if (partialEnd && commonRoot->contains(partialEnd.get()))
7368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec);
7378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (ec)
7388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return 0;
7398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_end = m_start;
7408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
7418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now add leftContents, stuff in between, and rightContents to the fragment
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (or just delete the stuff in between)
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents)
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fragment->appendChild(leftContents, ec);
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (processStart) {
7498a26975f9657a07318a10d481d7f332dad759325Ben Murdoch        NodeVector nodes;
7501cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block        for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling())
7518a26975f9657a07318a10d481d7f332dad759325Ben Murdoch            nodes.append(n);
75281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        processNodes(action, nodes, commonRoot, fragment, ec);
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && rightContents)
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fragment->appendChild(rightContents, ec);
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return fragment.release();
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
76181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
76281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
76381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (data->length() - endOffset)
76481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        data->deleteData(endOffset, data->length() - endOffset, ec);
76581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (startOffset)
76681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        data->deleteData(0, startOffset, ec);
76781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
76881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7692fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockPassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment,
7702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    Node* container, unsigned startOffset, unsigned endOffset, ExceptionCode& ec)
7712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(container);
7732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(startOffset <= endOffset);
77481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
77581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // This switch statement must be consistent with that of lengthOfContentsInNode.
77681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<Node> result;
7772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    switch (container->nodeType()) {
7782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::TEXT_NODE:
7792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::CDATA_SECTION_NODE:
7802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::COMMENT_NODE:
78181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(endOffset <= static_cast<CharacterData*>(container)->length());
7822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
7832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
78481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            deleteCharacterData(c, startOffset, endOffset, ec);
7852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (fragment) {
7862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = fragment;
7872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result->appendChild(c.release(), ec);
7882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else
7892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = c.release();
7902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
7912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS)
7922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            static_cast<CharacterData*>(container)->deleteData(startOffset, endOffset - startOffset, ec);
7932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
7942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::PROCESSING_INSTRUCTION_NODE:
79581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(endOffset <= static_cast<ProcessingInstruction*>(container)->data().length());
7962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
7972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
7982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            c->setData(c->data().substring(startOffset, endOffset - startOffset), ec);
7992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (fragment) {
8002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = fragment;
8012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result->appendChild(c.release(), ec);
8022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            } else
8032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = c.release();
8042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
8052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
8062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(container);
8072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            String data(pi->data());
8082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            data.remove(startOffset, endOffset - startOffset);
8092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            pi->setData(data, ec);
8102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
8112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
8122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::ELEMENT_NODE:
8132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::ATTRIBUTE_NODE:
8142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::ENTITY_REFERENCE_NODE:
8152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::ENTITY_NODE:
8162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::DOCUMENT_NODE:
8172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::DOCUMENT_TYPE_NODE:
8182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::DOCUMENT_FRAGMENT_NODE:
8192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::NOTATION_NODE:
8202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case Node::XPATH_NAMESPACE_NODE:
8212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // FIXME: Should we assert that some nodes never appear here?
8222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
8232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (fragment)
8242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = fragment;
8252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            else
8262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                result = container->cloneNode(false);
8272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
8282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Node* n = container->firstChild();
8302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        Vector<RefPtr<Node> > nodes;
8312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        for (unsigned i = startOffset; n && i; i--)
8322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            n = n->nextSibling();
8332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        for (unsigned i = startOffset; n && i < endOffset; i++, n = n->nextSibling())
8342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            nodes.append(n);
8352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
83681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        processNodes(action, nodes, container, result, ec);
83781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
83881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
83981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8401cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    return result.release();
84181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
84281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
84381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec)
84481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
84581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (unsigned i = 0; i < nodes.size(); i++) {
84681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        switch (action) {
84781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        case DELETE_CONTENTS:
84881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            oldContainer->removeChild(nodes[i].get(), ec);
84981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
85081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        case EXTRACT_CONTENTS:
85181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            newContainer->appendChild(nodes[i].release(), ec); // will remove n from its parent
85281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
85381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        case CLONE_CONTENTS:
85481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            newContainer->appendChild(nodes[i]->cloneNode(true), ec);
85581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
85681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
85781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
85881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
85981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
86081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochPassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionCode& ec)
86181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
86281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<Node> clonedContainer = passedClonedContainer;
86381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<RefPtr<Node> > ancestors;
86481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (ContainerNode* n = container->parentNode(); n && n != commonRoot; n = n->parentNode())
86581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ancestors.append(n);
86681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
86781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
86881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (Vector<RefPtr<Node> >::const_iterator it = ancestors.begin(); it != ancestors.end(); it++) {
86981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        RefPtr<Node> ancestor = *it;
87081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
87181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (RefPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
87281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                clonedAncestor->appendChild(clonedContainer, ec);
87381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                clonedContainer = clonedAncestor;
87481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
87581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
87681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
87781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Copy siblings of an ancestor of start/end containers
87881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // FIXME: This assertion may fail if DOM is modified during mutation event
87981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // FIXME: Share code with Range::processNodes
88081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->parentNode() == ancestor);
88127621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block
88227621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block        NodeVector nodes;
88327621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block        for (Node* child = firstChildInAncestorToProcess.get(); child;
88427621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block            child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling())
88527621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block            nodes.append(child);
88627621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block
88727621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block        for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
88827621ca63c064d1a1d6af6373c2c9f7018e19861Steve Block            Node* child = it->get();
8892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            switch (action) {
8902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            case DELETE_CONTENTS:
89181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ancestor->removeChild(child, ec);
8922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                break;
89381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            case EXTRACT_CONTENTS: // will remove child from ancestor
89481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (direction == ProcessContentsForward)
89581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    clonedContainer->appendChild(child, ec);
89681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else
89781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    clonedContainer->insertBefore(child, clonedContainer->firstChild(), ec);
8982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                break;
8992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            case CLONE_CONTENTS:
90081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (direction == ProcessContentsForward)
90181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    clonedContainer->appendChild(child->cloneNode(true), ec);
90281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else
90381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    clonedContainer->insertBefore(child->cloneNode(true), clonedContainer->firstChild(), ec);
9042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                break;
9052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
9062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
90781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling();
9082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
9092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9101cc46c0cf78d80f6cd0c8cd5093906c782be5691Steve Block    return clonedContainer.release();
9112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
9122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec)
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkDeleteExtract(ec);
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return processContents(EXTRACT_CONTENTS, ec);
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<DocumentFragment> Range::cloneContents(ExceptionCode& ec)
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return processContents(CLONE_CONTENTS, ec);
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionCode& ec)
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> newNode = prpNewNode;
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!newNode) {
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the Range is read-only.
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containedByReadOnly()) {
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NO_MODIFICATION_ALLOWED_ERR;
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // does not allow children of the type of newNode or if newNode is an ancestor of the container.
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // an extra one here - if a text node is going to split, it must have a parent to insert into
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool startIsText = m_start.container()->isTextNode();
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startIsText && !m_start.container()->parentNode()) {
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = HIERARCHY_REQUEST_ERR;
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In the case where the container is a text node, we check against the container's parent, because
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // text nodes get split up upon insertion.
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* checkAgainst;
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startIsText)
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        checkAgainst = m_start.container()->parentNode();
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        checkAgainst = m_start.container();
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node::NodeType newNodeType = newNode->nodeType();
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int numNewChildren;
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) {
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // check each child node, not the DocumentFragment itself
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        numNewChildren = 0;
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!checkAgainst->childTypeAllowed(c->nodeType())) {
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = HIERARCHY_REQUEST_ERR;
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ++numNewChildren;
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        numNewChildren = 1;
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!checkAgainst->childTypeAllowed(newNodeType)) {
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = HIERARCHY_REQUEST_ERR;
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = m_start.container(); n; n = n->parentNode()) {
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n == newNode) {
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = HIERARCHY_REQUEST_ERR;
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, Notation, or Document node.
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newNodeType == Node::ATTRIBUTE_NODE || newNodeType == Node::ENTITY_NODE
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            || newNodeType == Node::NOTATION_NODE || newNodeType == Node::DOCUMENT_NODE) {
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = RangeException::INVALID_NODE_TYPE_ERR;
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool collapsed = m_start == m_end;
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (startIsText) {
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Text> newText = static_cast<Text*>(m_start.container())->splitText(m_start.offset(), ec);
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_start.container()->parentNode()->insertBefore(newNode.release(), newText.get(), ec);
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This special case doesn't seem to match the DOM specification, but it's currently required
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to pass Acid3. We might later decide to remove this.
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (collapsed)
10195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_end.setToBeforeChild(newText.get());
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> lastChild;
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (collapsed)
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int startOffset = m_start.offset();
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_start.container()->insertBefore(newNode.release(), m_start.container()->childNode(startOffset), ec);
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This special case doesn't seem to match the DOM specification, but it's currently required
10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to pass Acid3. We might later decide to remove this.
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (collapsed)
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_end.set(m_start.container(), startOffset + numNewChildren, lastChild.get());
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString Range::toString(ExceptionCode& ec) const
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UChar> result;
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* pastLast = pastLastNode();
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = firstNode(); n != pastLast; n = n->traverseNextNode()) {
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String data = static_cast<CharacterData*>(n)->data();
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int length = data.length();
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int start = (n == m_start.container()) ? min(max(0, m_start.offset()), length) : 0;
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int end = (n == m_end.container()) ? min(max(start, m_end.offset()), length) : length;
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result.append(data.characters() + start, end - start);
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String::adopt(result);
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString Range::toHTML() const
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return createMarkup(this);
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString Range::text() const
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container())
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need to update layout, since plainText uses line boxes in the render tree.
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: As with innerText, we'd like this to work even if there are no render objects.
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_start.container()->document()->updateLayout();
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return plainText(this);
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionCode& ec) const
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!element || !element->isHTMLElement()) {
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_SUPPORTED_ERR;
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1090f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Logic from deprecatedCreateContextualFragment should just be moved into
1091f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // this function.  Range::createContextualFragment semantics do not make
1092f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // sense for the rest of the DOM implementation to use.
10932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RefPtr<DocumentFragment> fragment = toHTMLElement(element)->deprecatedCreateContextualFragment(markup);
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!fragment) {
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_SUPPORTED_ERR;
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return fragment.release();
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::detach(ExceptionCode& ec)
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Check first to see if we've already detached:
11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ownerDocument->detachRange(this);
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_start.clear();
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_end.clear();
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::checkNodeWOffset(Node* n, int offset, ExceptionCode& ec) const
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (n->nodeType()) {
11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
11218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = RangeException::INVALID_NODE_TYPE_ERR;
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (static_cast<unsigned>(offset) > static_cast<CharacterData*>(n)->length())
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = INDEX_SIZE_ERR;
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (static_cast<unsigned>(offset) > static_cast<ProcessingInstruction*>(n)->data().length())
11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = INDEX_SIZE_ERR;
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::XPATH_NAMESPACE_NODE: {
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!offset)
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return 0;
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Node* childBefore = n->childNode(offset - 1);
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!childBefore)
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = INDEX_SIZE_ERR;
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return childBefore;
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::checkNodeBA(Node* n, ExceptionCode& ec) const
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Attr, Document or DocumentFragment node or part of a shadow DOM tree
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or if refNode is a Document, DocumentFragment, Attr, Entity, or Notation node.
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (n->nodeType()) {
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = RangeException::INVALID_NODE_TYPE_ERR;
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::XPATH_NAMESPACE_NODE:
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* root = n;
1179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    while (ContainerNode* parent = root->parentNode())
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        root = parent;
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (root->nodeType()) {
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::XPATH_NAMESPACE_NODE:
1197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (root->isShadowRoot())
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = RangeException::INVALID_NODE_TYPE_ERR;
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> Range::cloneRange(ExceptionCode& ec) const
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Range::create(m_ownerDocument, m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setStartAfter(Node* refNode, ExceptionCode& ec)
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeBA(refNode, ec);
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setStart(refNode->parentNode(), refNode->nodeIndex() + 1, ec);
12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setEndBefore(Node* refNode, ExceptionCode& ec)
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
12438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeBA(refNode, ec);
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setEnd(refNode->parentNode(), refNode->nodeIndex(), ec);
12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setEndAfter(Node* refNode, ExceptionCode& ec)
12658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeBA(refNode, ec);
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, ec);
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::selectNode(Node* refNode, ExceptionCode& ec)
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an Entity, Notation or
13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // DocumentType node or if refNode is a Document, DocumentFragment, Attr, Entity, or Notation
13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // node.
1305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    for (ContainerNode* anc = refNode->parentNode(); anc; anc = anc->parentNode()) {
13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (anc->nodeType()) {
13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ATTRIBUTE_NODE:
13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::CDATA_SECTION_NODE:
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::COMMENT_NODE:
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_FRAGMENT_NODE:
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_NODE:
13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ELEMENT_NODE:
13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ENTITY_REFERENCE_NODE:
13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::PROCESSING_INSTRUCTION_NODE:
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::TEXT_NODE:
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::XPATH_NAMESPACE_NODE:
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_TYPE_NODE:
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ENTITY_NODE:
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::NOTATION_NODE:
13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = RangeException::INVALID_NODE_TYPE_ERR;
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (refNode->nodeType()) {
13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::XPATH_NAMESPACE_NODE:
13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = RangeException::INVALID_NODE_TYPE_ERR;
13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
134568513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (m_ownerDocument != refNode->document())
134668513a70bcd92384395513322f1b801e7bf9c729Steve Block        setDocument(refNode->document());
134768513a70bcd92384395513322f1b801e7bf9c729Steve Block
13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setStartBefore(refNode, ec);
13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setEndAfter(refNode, ec);
13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity, Notation
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or DocumentType node.
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = refNode; n; n = n->parentNode()) {
13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (n->nodeType()) {
13718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ATTRIBUTE_NODE:
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::CDATA_SECTION_NODE:
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::COMMENT_NODE:
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_FRAGMENT_NODE:
13758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_NODE:
13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ELEMENT_NODE:
13778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ENTITY_REFERENCE_NODE:
13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::PROCESSING_INSTRUCTION_NODE:
13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::TEXT_NODE:
13808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::XPATH_NAMESPACE_NODE:
13818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
13828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::DOCUMENT_TYPE_NODE:
13838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::ENTITY_NODE:
13848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Node::NOTATION_NODE:
13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ec = RangeException::INVALID_NODE_TYPE_ERR;
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
139068513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (m_ownerDocument != refNode->document())
139168513a70bcd92384395513322f1b801e7bf9c729Steve Block        setDocument(refNode->document());
139268513a70bcd92384395513322f1b801e7bf9c729Steve Block
13935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_start.setToStartOfNode(refNode);
13945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_end.setToEndOfNode(refNode);
13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionCode& ec)
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> newParent = passNewParent;
14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!newParent) {
14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType, Notation,
14128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Document, or DocumentFragment node.
14138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (newParent->nodeType()) {
14148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
14158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
14178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
14188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
14198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
14208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = RangeException::INVALID_NODE_TYPE_ERR;
14218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::XPATH_NAMESPACE_NODE:
14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of either boundary-point of
14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the Range is read-only.
14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containedByReadOnly()) {
14358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NO_MODIFICATION_ALLOWED_ERR;
14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Raise a HIERARCHY_REQUEST_ERR if m_start.container() doesn't accept children like newParent.
14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* parentOfNewParent = m_start.container();
14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If m_start.container() is a character data node, it will be split and it will be its parent that will
14438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // need to accept newParent (or in the case of a comment, it logically "would" be inserted into the parent,
14448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // although this will fail below for another reason).
14458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parentOfNewParent->isCharacterDataNode())
14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parentOfNewParent = parentOfNewParent->parentNode();
1447d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!parentOfNewParent || !parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = HIERARCHY_REQUEST_ERR;
14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_start.container() == newParent || m_start.container()->isDescendantOf(newParent.get())) {
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = HIERARCHY_REQUEST_ERR;
14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Do we need a check if the node would end up with a child node of a type not
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // allowed by the type of node?
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a non-Text node.
1461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Node* startNonTextContainer = m_start.container();
1462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (startNonTextContainer->nodeType() == Node::TEXT_NODE)
1463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        startNonTextContainer = startNonTextContainer->parentNode();
1464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Node* endNonTextContainer = m_end.container();
1465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (endNonTextContainer->nodeType() == Node::TEXT_NODE)
1466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        endNonTextContainer = endNonTextContainer->parentNode();
1467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (startNonTextContainer != endNonTextContainer) {
1468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ec = RangeException::BAD_BOUNDARYPOINTS_ERR;
1469635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
14738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (Node* n = newParent->firstChild()) {
1474a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        toContainerNode(newParent.get())->removeChild(n, ec);
14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<DocumentFragment> fragment = extractContents(ec);
14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    insertNode(newParent, ec);
14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    newParent->appendChild(fragment.release(), ec);
14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    selectNode(newParent.get(), ec);
14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::setStartBefore(Node* refNode, ExceptionCode& ec)
14918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
14948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refNode) {
14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refNode->document() != m_ownerDocument) {
15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = WRONG_DOCUMENT_ERR;
15048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkNodeBA(refNode, ec);
15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setStart(refNode->parentNode(), refNode->nodeIndex(), ec);
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::checkDeleteExtract(ExceptionCode& ec)
15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()) {
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!commonAncestorContainer(ec) || ec)
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* pastLast = pastLastNode();
15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = firstNode(); n != pastLast; n = n->traverseNextNode()) {
15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isReadOnlyNode()) {
15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = NO_MODIFICATION_ALLOWED_ERR;
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) {
15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ec = HIERARCHY_REQUEST_ERR;
15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (containedByReadOnly()) {
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NO_MODIFICATION_ALLOWED_ERR;
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Range::containedByReadOnly() const
15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = m_start.container(); n; n = n->parentNode()) {
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isReadOnlyNode())
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = m_end.container(); n; n = n->parentNode()) {
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isReadOnlyNode())
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
15558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::firstNode() const
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container())
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_start.container()->offsetInCharacters())
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_start.container();
15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (Node* child = m_start.container()->childNode(m_start.offset()))
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return child;
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.offset())
15668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_start.container();
15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_start.container()->traverseNextSibling();
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPosition Range::editingStartPosition() const
15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This function is used by range style computations to avoid bugs like:
15738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <rdar://problem/4017641> REGRESSION (Mail): you can only bold/unbold a selection starting from end of line once
15748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It is important to skip certain irrelevant content at the start of the selection, so we do not wind up
15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // with a spurious "mixed" style.
15768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
157781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    VisiblePosition visiblePosition = Position(m_start.container(), m_start.offset(), Position::PositionIsOffsetInAnchor);
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (visiblePosition.isNull())
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return Position();
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if the selection is a caret, just return the position, since the style
15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // behind us is relevant
15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (collapsed(ec))
15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return visiblePosition.deepEquivalent();
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if the selection starts just before a paragraph break, skip over it
15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isEndOfParagraph(visiblePosition))
15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return visiblePosition.next().deepEquivalent().downstream();
15908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // otherwise, make sure to be at the start of the first selected node,
15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // instead of possibly at the end of the last node before the selection
15938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return visiblePosition.deepEquivalent().downstream();
15948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::shadowTreeRootNode() const
15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return startContainer() ? startContainer()->shadowTreeRootNode() : 0;
15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* Range::pastLastNode() const
16028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container() || !m_end.container())
16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_end.container()->offsetInCharacters())
16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_end.container()->traverseNextSibling();
16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (Node* child = m_end.container()->childNode(m_end.offset()))
16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return child;
16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_end.container()->traverseNextSibling();
16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect Range::boundingBox()
16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect result;
16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<IntRect> rects;
16165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    textRects(rects);
16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const size_t n = rects.size();
16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < n; ++i)
16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.unite(rects[i]);
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight)
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1625643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Node* startContainer = m_start.container();
1626643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Node* endContainer = m_end.container();
1627643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1628643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!startContainer || !endContainer)
16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Node* stopNode = pastLastNode();
1632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
1633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        RenderObject* r = node->renderer();
1634643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!r || !r->isText())
1635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            continue;
1636643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        RenderText* renderText = toRenderText(r);
1637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int startOffset = node == startContainer ? m_start.offset() : 0;
1638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
1639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
1640643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
1641643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
1642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
16432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight) const
1644643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
16455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* startContainer = m_start.container();
16465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* endContainer = m_end.container();
16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!startContainer || !endContainer)
1649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
1650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
16515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* stopNode = pastLastNode();
16525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
16535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RenderObject* r = node->renderer();
16545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!r || !r->isText())
16555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            continue;
16565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RenderText* renderText = toRenderText(r);
16575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int startOffset = node == startContainer ? m_start.offset() : 0;
1658643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
1659643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        renderText->absoluteQuadsForRange(quads, startOffset, endOffset, useSelectionHeight);
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define FormatBufferSize 1024
16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::formatForDebugger(char* buffer, unsigned length) const
16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String result;
16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String s;
16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container() || !m_end.container())
16718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = "<empty>";
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char s[FormatBufferSize];
16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += "from offset ";
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += String::number(m_start.offset());
16768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += " of ";
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_start.container()->formatForDebugger(s, FormatBufferSize);
16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += s;
16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += " to offset ";
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += String::number(m_end.offset());
16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += " of ";
16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_end.container()->formatForDebugger(s, FormatBufferSize);
16838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += s;
16848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    strncpy(buffer, result.utf8().data(), length - 1);
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef FormatBufferSize
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1691dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool areRangesEqual(const Range* a, const Range* b)
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1693dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (a == b)
16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1695dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!a || !b)
16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1697dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return a->startPosition() == b->startPosition() && a->endPosition() == b->endPosition();
16988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Range> rangeOfContents(Node* node)
17018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node);
17038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Range> range = Range::create(node->document());
17048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int exception = 0;
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    range->selectNodeContents(node, exception);
17068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return range.release();
17078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint Range::maxStartOffset() const
17108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container())
17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_start.container()->offsetInCharacters())
17148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_start.container()->childNodeCount();
17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_start.container()->maxCharacterOffset();
17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint Range::maxEndOffset() const
17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_end.container())
17218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
17228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_end.container()->offsetInCharacters())
17238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_end.container()->childNodeCount();
17248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_end.container()->maxCharacterOffset();
17258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryNodeChildrenChanged(RangeBoundaryPoint& boundary, ContainerNode* container)
17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!boundary.childBefore())
17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.container() != container)
17328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundary.invalidateOffset();
17348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::nodeChildrenChanged(ContainerNode* container)
17378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(container);
17398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(container->document() == m_ownerDocument);
17408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryNodeChildrenChanged(m_start, container);
17418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryNodeChildrenChanged(m_end, container);
17428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
17456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
17466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
17476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (boundary.childBefore() == nodeToBeRemoved) {
17486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            boundary.setToStartOfNode(container);
17496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return;
17506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
17516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
17526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        for (Node* n = boundary.container(); n; n = n->parentNode()) {
17536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (n == nodeToBeRemoved) {
17546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                boundary.setToStartOfNode(container);
17556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                return;
17566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            }
17576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
17586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
17596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
17606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
17616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid Range::nodeChildrenWillBeRemoved(ContainerNode* container)
17626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
17636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ASSERT(container);
17646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ASSERT(container->document() == m_ownerDocument);
17656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    boundaryNodeChildrenWillBeRemoved(m_start, container);
17666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    boundaryNodeChildrenWillBeRemoved(m_end, container);
17676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
17686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node* nodeToBeRemoved)
17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.childBefore() == nodeToBeRemoved) {
17728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        boundary.childBeforeWillBeRemoved();
17738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
17748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = boundary.container(); n; n = n->parentNode()) {
17778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n == nodeToBeRemoved) {
17785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            boundary.setToBeforeChild(nodeToBeRemoved);
17798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
17818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::nodeWillBeRemoved(Node* node)
17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node);
17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node->document() == m_ownerDocument);
17888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node != m_ownerDocument);
17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node->parentNode());
17908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryNodeWillBeRemoved(m_start, node);
17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryNodeWillBeRemoved(m_end, node);
17928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryTextInserted(RangeBoundaryPoint& boundary, Node* text, unsigned offset, unsigned length)
17958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.container() != text)
17978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
17988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned boundaryOffset = boundary.offset();
17998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offset >= boundaryOffset)
18008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundary.setOffset(boundaryOffset + length);
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::textInserted(Node* text, unsigned offset, unsigned length)
18058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(text);
18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(text->document() == m_ownerDocument);
18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextInserted(m_start, text, offset, length);
18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextInserted(m_end, text, offset, length);
18108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryTextRemoved(RangeBoundaryPoint& boundary, Node* text, unsigned offset, unsigned length)
18138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.container() != text)
18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned boundaryOffset = boundary.offset();
18178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offset >= boundaryOffset)
18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (offset + length >= boundaryOffset)
18208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        boundary.setOffset(offset);
18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        boundary.setOffset(boundaryOffset - length);
18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::textRemoved(Node* text, unsigned offset, unsigned length)
18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(text);
18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(text->document() == m_ownerDocument);
18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextRemoved(m_start, text, offset, length);
18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextRemoved(m_end, text, offset, length);
18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.container() == oldNode.node())
18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        boundary.set(oldNode.node()->previousSibling(), boundary.offset() + offset, 0);
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (boundary.container() == oldNode.node()->parentNode() && boundary.offset() == oldNode.index())
18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        boundary.set(oldNode.node()->previousSibling(), offset, 0);
18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::textNodesMerged(NodeWithIndex& oldNode, unsigned offset)
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node());
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node()->document() == m_ownerDocument);
18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node()->parentNode());
18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node()->isTextNode());
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node()->previousSibling());
18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode.node()->previousSibling()->isTextNode());
18498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextNodesMerged(m_start, oldNode, offset);
18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextNodesMerged(m_end, oldNode, offset);
18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void boundaryTextNodesSplit(RangeBoundaryPoint& boundary, Text* oldNode)
18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundary.container() != oldNode)
18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned boundaryOffset = boundary.offset();
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (boundaryOffset <= oldNode->length())
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundary.set(oldNode->nextSibling(), boundaryOffset - oldNode->length(), 0);
18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Range::textNodeSplit(Text* oldNode)
18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode);
18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode->document() == m_ownerDocument);
18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode->parentNode());
18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode->isTextNode());
18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode->nextSibling());
18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(oldNode->nextSibling()->isTextNode());
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextNodesSplit(m_start, oldNode);
18728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    boundaryTextNodesSplit(m_end, oldNode);
18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1875231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Range::expand(const String& unit, ExceptionCode& ec)
1876231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    VisiblePosition start(startPosition());
1878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    VisiblePosition end(endPosition());
1879231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (unit == "word") {
1880231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        start = startOfWord(start);
1881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        end = endOfWord(end);
1882231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else if (unit == "sentence") {
1883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        start = startOfSentence(start);
1884231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        end = endOfSentence(end);
1885231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else if (unit == "block") {
1886231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        start = startOfParagraph(start);
1887231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        end = endOfParagraph(end);
1888231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else if (unit == "document") {
1889231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        start = startOfDocument(start);
1890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        end = endOfDocument(end);
1891231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else
1892231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
1893231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), ec);
1894231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), ec);
1895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1896231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1897231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<ClientRectList> Range::getClientRects() const
1898231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1899231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_start.container())
1900231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
1901231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1902231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_ownerDocument->updateLayoutIgnorePendingStylesheets();
1903231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1904231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Vector<FloatQuad> quads;
1905231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    getBorderAndTextQuads(quads);
1906231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return ClientRectList::create(quads);
1908231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<ClientRect> Range::getBoundingClientRect() const
1911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
191281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatRect rect = boundingRect();
191381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return rect.isEmpty() ? 0 : ClientRect::create(rect);
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1915231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
19162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void adjustFloatQuadsForScrollAndAbsoluteZoomAndPageScale(Vector<FloatQuad>& quads, Document* document, RenderObject* renderer)
1917231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1918231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    FrameView* view = document->view();
1919231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!view)
1920231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
1921231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
19222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float pageScale = 1;
19232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (Page* page = document->page()) {
19242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (Frame* frame = page->mainFrame())
19252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            pageScale = frame->pageScaleFactor();
19262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
19272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1928231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    IntRect visibleContentRect = view->visibleContentRect();
1929231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (size_t i = 0; i < quads.size(); ++i) {
1930231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
1931231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
19322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (pageScale != 1)
19332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            adjustFloatQuadForPageScale(quads[i], pageScale);
1934231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1935231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1936231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1937231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
1938231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1939231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Node* startContainer = m_start.container();
1940231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Node* endContainer = m_end.container();
1941231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Node* stopNode = pastLastNode();
1942231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1943231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HashSet<Node*> nodeSet;
1944231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
1945231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (node->isElementNode())
1946231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            nodeSet.add(node);
1947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (Node* node = firstNode(); node != stopNode; node = node->traverseNextNode()) {
1950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (node->isElementNode()) {
1951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!nodeSet.contains(node->parentNode())) {
1952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (RenderBoxModelObject* renderBoxModelObject = static_cast<Element*>(node)->renderBoxModelObject()) {
1953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    Vector<FloatQuad> elementQuads;
1954231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    renderBoxModelObject->absoluteQuads(elementQuads);
19552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    adjustFloatQuadsForScrollAndAbsoluteZoomAndPageScale(elementQuads, m_ownerDocument.get(), renderBoxModelObject);
1956231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1957231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    quads.append(elementQuads);
1958231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }
1959231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
1960231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (node->isTextNode()) {
1961231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (RenderObject* renderer = static_cast<Text*>(node)->renderer()) {
1962231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                RenderText* renderText = toRenderText(renderer);
1963231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                int startOffset = (node == startContainer) ? m_start.offset() : 0;
1964231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                int endOffset = (node == endContainer) ? m_end.offset() : INT_MAX;
1965231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1966231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                Vector<FloatQuad> textQuads;
1967231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                renderText->absoluteQuadsForRange(textQuads, startOffset, endOffset);
19682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                adjustFloatQuadsForScrollAndAbsoluteZoomAndPageScale(textQuads, m_ownerDocument.get(), renderText);
1969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1970231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                quads.append(textQuads);
1971231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
1972231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1973231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1974231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1975231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
197681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
197781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochFloatRect Range::boundingRect() const
197881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
197981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_start.container())
198081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return FloatRect();
198181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
198281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_ownerDocument->updateLayoutIgnorePendingStylesheets();
198381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
198481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<FloatQuad> quads;
198581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    getBorderAndTextQuads(quads);
198681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (quads.isEmpty())
198781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return FloatRect();
198881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
198981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatRect result;
199081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (size_t i = 0; i < quads.size(); ++i)
199181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        result.unite(quads[i].boundingBox());
199281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
199381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return result;
199481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
199581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1996231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore
1997d0825bca7fe65beaee391d30da42e937db621564Steve Block
1998d0825bca7fe65beaee391d30da42e937db621564Steve Block#ifndef NDEBUG
1999d0825bca7fe65beaee391d30da42e937db621564Steve Block
2000d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid showTree(const WebCore::Range* range)
2001d0825bca7fe65beaee391d30da42e937db621564Steve Block{
2002d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (range && range->boundaryPointsValid()) {
200381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        range->startContainer()->showTreeAndMark(range->startContainer(), "S", range->endContainer(), "E");
200481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset(), range->endOffset());
2005d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
2006d0825bca7fe65beaee391d30da42e937db621564Steve Block}
2007d0825bca7fe65beaee391d30da42e937db621564Steve Block
2008d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
2009