| Index: Source/WebCore/dom/Range.cpp
|
| ===================================================================
|
| --- Source/WebCore/dom/Range.cpp (revision 90844)
|
| +++ Source/WebCore/dom/Range.cpp (working copy)
|
| @@ -628,7 +628,9 @@
|
| {
|
| ASSERT(container);
|
| ASSERT(commonRoot);
|
| - ASSERT(commonRoot->contains(container));
|
| +
|
| + if (!commonRoot->contains(container))
|
| + return 0;
|
|
|
| if (container == commonRoot) {
|
| container = container->firstChild();
|
| @@ -682,7 +684,7 @@
|
| if (ec)
|
| return 0;
|
|
|
| - Node* commonRoot = commonAncestorContainer(ec);
|
| + RefPtr<Node> commonRoot = commonAncestorContainer(ec);
|
| if (ec)
|
| return 0;
|
| ASSERT(commonRoot);
|
| @@ -693,8 +695,8 @@
|
| }
|
|
|
| // what is the highest node that partially selects the start / end of the range?
|
| - Node* partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot);
|
| - Node* partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot);
|
| + RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot.get());
|
| + RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot.get());
|
|
|
| // Start and end containers are different.
|
| // There are three possibilities here:
|
| @@ -713,29 +715,32 @@
|
| //
|
| // These are deleted, cloned, or extracted (i.e. both) depending on action.
|
|
|
| + // Note that we are verifying that our common root hierarchy is still intact
|
| + // after any DOM mutation event, at various stages below. See webkit bug 60350.
|
| +
|
| RefPtr<Node> leftContents;
|
| - if (m_start.container() != commonRoot) {
|
| + if (m_start.container() != commonRoot && commonRoot->contains(m_start.container())) {
|
| leftContents = processContentsBetweenOffsets(action, 0, m_start.container(), m_start.offset(), lengthOfContentsInNode(m_start.container()), ec);
|
| - leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot, ec);
|
| + leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec);
|
| }
|
|
|
| RefPtr<Node> rightContents;
|
| - if (m_end.container() != commonRoot) {
|
| + if (m_end.container() != commonRoot && commonRoot->contains(m_end.container())) {
|
| rightContents = processContentsBetweenOffsets(action, 0, m_end.container(), 0, m_end.offset(), ec);
|
| - rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot, ec);
|
| + rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec);
|
| }
|
|
|
| // delete all children of commonRoot between the start and end container
|
| - Node* processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot);
|
| - if (m_start.container() != commonRoot) // processStart contains nodes before m_start.
|
| + RefPtr<Node> processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot.get());
|
| + if (processStart && m_start.container() != commonRoot) // processStart contains nodes before m_start.
|
| processStart = processStart->nextSibling();
|
| - Node* processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot);
|
| + RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot.get());
|
|
|
| // Collapse the range, making sure that the result is not within a node that was partially selected.
|
| if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
|
| - if (partialStart)
|
| + if (partialStart && commonRoot->contains(partialStart.get()))
|
| setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec);
|
| - else if (partialEnd)
|
| + else if (partialEnd && commonRoot->contains(partialEnd.get()))
|
| setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec);
|
| if (ec)
|
| return 0;
|
| @@ -750,7 +755,7 @@
|
|
|
| if (processStart) {
|
| NodeVector nodes;
|
| - for (Node* n = processStart; n && n != processEnd; n = n->nextSibling())
|
| + for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling())
|
| nodes.append(n);
|
| processNodes(action, nodes, commonRoot, fragment, ec);
|
| }
|
| @@ -841,7 +846,7 @@
|
| break;
|
| }
|
|
|
| - return result;
|
| + return result.release();
|
| }
|
|
|
| void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec)
|
| @@ -906,7 +911,7 @@
|
| firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling();
|
| }
|
|
|
| - return clonedContainer;
|
| + return clonedContainer.release();
|
| }
|
|
|
| PassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec)
|
|
|