diff options
author | Ben Murdoch <benm@google.com> | 2011-01-16 13:59:45 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-01-16 14:14:41 +0000 |
commit | 8a26975f9657a07318a10d481d7f332dad759325 (patch) | |
tree | 3d4270ff2d0aa27bdbb26e83c1de9d6ac18cb4fc /WebCore/dom/Range.cpp | |
parent | e137c43847f22807f1276afc87027711cc3f4e77 (diff) | |
download | external_webkit-8a26975f9657a07318a10d481d7f332dad759325.zip external_webkit-8a26975f9657a07318a10d481d7f332dad759325.tar.gz external_webkit-8a26975f9657a07318a10d481d7f332dad759325.tar.bz2 |
Merge WebKit at Chromium 9.0.597.69: Trivial merge by Git.
http://svn.webkit.org/repository/webkit/branches/chromium/597/WebCore@75681
Change-Id: Ibe552cf7af31f74b81e337eadf3d3b73a53daf60
Diffstat (limited to 'WebCore/dom/Range.cpp')
-rw-r--r-- | WebCore/dom/Range.cpp | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp index 5507b83..71bf08e 100644 --- a/WebCore/dom/Range.cpp +++ b/WebCore/dom/Range.cpp @@ -41,9 +41,12 @@ #include <stdio.h> #include <wtf/text/CString.h> #include <wtf/RefCountedLeakCounter.h> +#include <wtf/Vector.h> namespace WebCore { +typedef Vector<RefPtr<Node> > NodeVector; + using namespace std; #ifndef NDEBUG @@ -595,9 +598,6 @@ bool Range::intersectsNode(Node* refNode, ExceptionCode& ec) PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec) { - // FIXME: To work properly with mutation events, we will have to take into account - // situations where the tree is being transformed while we work on it - ugh! - RefPtr<DocumentFragment> fragment; if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) fragment = DocumentFragment::create(m_ownerDocument.get()); @@ -655,21 +655,20 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception pi->setData(data, ec); } } else { - Node* n = m_start.container()->firstChild(); + RefPtr<Node> n = m_start.container()->firstChild(); int i; for (i = 0; n && i < m_start.offset(); i++) // skip until start offset n = n->nextSibling(); int endOffset = m_end.offset(); - while (n && i < endOffset) { // delete until end offset - Node* next = n->nextSibling(); + RefPtr<Node> next; + for (; n && i < endOffset; n = next, i++) { // delete until end offset + next = n->nextSibling(); if (action == EXTRACT_CONTENTS) fragment->appendChild(n, ec); // will remove n from its parent else if (action == CLONE_CONTENTS) fragment->appendChild(n->cloneNode(true), ec); else - toContainerNode(m_start.container())->removeChild(n, ec); - n = next; - i++; + m_start.container()->removeChild(n.get(), ec); } } return fragment.release(); @@ -720,39 +719,47 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception } else { if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) leftContents = m_start.container()->cloneNode(false); + NodeVector nodes; Node* n = m_start.container()->firstChild(); - for (int i = 0; n && i < m_start.offset(); i++) // skip until start offset - n = n->nextSibling(); - while (n) { // process until end - Node* next = n->nextSibling(); + for (int i = 0; n; n = n->nextSibling(), i++) { + if (i < m_start.offset()) + continue; // Skip until start offset. + nodes.append(n); + } + for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) { + Node* n = it->get(); if (action == EXTRACT_CONTENTS) - leftContents->appendChild(n, ec); // will remove n from start container + leftContents->appendChild(n, ec); // Will remove n from start container. else if (action == CLONE_CONTENTS) leftContents->appendChild(n->cloneNode(true), ec); else toContainerNode(m_start.container())->removeChild(n, ec); - n = next; } } - ContainerNode* leftParent = m_start.container()->parentNode(); - Node* n = m_start.container()->nextSibling(); - for (; leftParent != commonRoot; leftParent = leftParent->parentNode()) { + NodeVector ancestorNodes; + for (ContainerNode* n = m_start.container()->parentNode(); n && n != commonRoot; n = n->parentNode()) + ancestorNodes.append(n); + RefPtr<Node> n = m_start.container()->nextSibling(); + for (NodeVector::const_iterator it = ancestorNodes.begin(); it != ancestorNodes.end(); it++) { + Node* leftParent = it->get(); if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) { RefPtr<Node> leftContentsParent = leftParent->cloneNode(false); - leftContentsParent->appendChild(leftContents, ec); - leftContents = leftContentsParent; + if (leftContentsParent) { // Might have been removed already during mutation event. + leftContentsParent->appendChild(leftContents, ec); + leftContents = leftContentsParent; + } } - Node* next; + RefPtr<Node> next; for (; n; n = next) { next = n->nextSibling(); if (action == EXTRACT_CONTENTS) - leftContents->appendChild(n, ec); // will remove n from leftParent + leftContents->appendChild(n.get(), ec); // will remove n from leftParent else if (action == CLONE_CONTENTS) leftContents->appendChild(n->cloneNode(true), ec); else - leftParent->removeChild(n, ec); + leftParent->removeChild(n.get(), ec); } n = leftParent->nextSibling(); } @@ -786,15 +793,16 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception rightContents = m_end.container()->cloneNode(false); Node* n = m_end.container()->firstChild(); if (n && m_end.offset()) { - for (int i = 0; i + 1 < m_end.offset(); i++) { // skip to end.offset() - Node* next = n->nextSibling(); - if (!next) + NodeVector nodes; + int i = 0; + do { + nodes.append(n); + if (!n->nextSibling()) break; - n = next; - } - Node* prev; - for (; n; n = prev) { - prev = n->previousSibling(); + n = n->nextSibling(); + } while (i + 1 < m_end.offset()); + for (int i = nodes.size() - 1; i >= 0; i--) { + n = nodes[i].get(); if (action == EXTRACT_CONTENTS) rightContents->insertBefore(n, rightContents->firstChild(), ec); // will remove n from its parent else if (action == CLONE_CONTENTS) @@ -868,11 +876,12 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception if ((action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) && leftContents) fragment->appendChild(leftContents, ec); - Node* next; - Node* n; if (processStart) { - for (n = processStart; n && n != processEnd; n = next) { - next = n->nextSibling(); + NodeVector nodes; + for (Node* n = processStart; n && n != processEnd; n = n->nextSibling()) + nodes.append(n); + for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) { + Node* n = it->get(); if (action == EXTRACT_CONTENTS) fragment->appendChild(n, ec); // will remove from commonRoot else if (action == CLONE_CONTENTS) |