Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3702)

Unified Diff: WebCore/dom/Range.cpp

Issue 6129003: Merge 73799 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/597/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/fast/dom/Range/range-extractContents-expected.txt ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: WebCore/dom/Range.cpp
===================================================================
--- WebCore/dom/Range.cpp (revision 75431)
+++ WebCore/dom/Range.cpp (working copy)
@@ -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 @@
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 @@
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++;
+ toContainerNode(m_start.container())->removeChild(n.get(), ec);
}
}
return fragment.release();
@@ -720,39 +719,47 @@
} 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,12 @@
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)
- break;
- n = next;
+ NodeVector nodes;
+ for (int i = 0; i + 1 < m_end.offset() && n; i++, n = n->nextSibling()) {
+ nodes.append(n);
}
- Node* prev;
- for (; n; n = prev) {
- prev = n->previousSibling();
+ for (int i = nodes.size() - 1; i >= 0; i--) {
+ Node* 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 +872,12 @@
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)
« no previous file with comments | « LayoutTests/fast/dom/Range/range-extractContents-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698