Modified: trunk/LayoutTests/ChangeLog (159619 => 159620)
--- trunk/LayoutTests/ChangeLog 2013-11-21 13:46:39 UTC (rev 159619)
+++ trunk/LayoutTests/ChangeLog 2013-11-21 13:52:09 UTC (rev 159620)
@@ -1,5 +1,20 @@
2013-11-21 Ryosuke Niwa <[email protected]>
+ Fix Range.insertNode when the inserted node is in the same container as the Range
+ https://bugs.webkit.org/show_bug.cgi?id=123957
+
+ Reviewed by Antti Koivisto.
+
+ Merge https://chromium.googlesource.com/chromium/blink/+/fb6ca1f488703e8d4f20ce6449cc8ea210be6edb
+
+ Used better labels between divs, and added more evalAndLog and shouldBe so that
+ the expected result is self-explanatory.
+
+ * fast/dom/Range/range-insertNode-same-container-expected.txt: Added.
+ * fast/dom/Range/range-insertNode-same-container.html: Added.
+
+2013-11-21 Ryosuke Niwa <[email protected]>
+
nextBoundary and previousBoundary are very slow when there is a password field
https://bugs.webkit.org/show_bug.cgi?id=123973
Added: trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container-expected.txt (0 => 159620)
--- trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container-expected.txt 2013-11-21 13:52:09 UTC (rev 159620)
@@ -0,0 +1,49 @@
+insertedElement = document.getElementById("div1");
+range.setStart(containerElement, 3); range.setEnd(containerElement, 3); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 2
+PASS range.endOffset is 3
+PASS range.toString() is "1"
+range.setStart(containerElement, 3); range.setEnd(containerElement, 3); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 2
+PASS range.endOffset is 3
+PASS range.toString() is "1"
+insertedElement = document.getElementById("div3");
+range.setStart(containerElement, 5); range.setEnd(containerElement, 5); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 4
+PASS range.endOffset is 5
+PASS range.toString() is "3-begin 45 3-end"
+range.setStart(containerElement, 5); range.setEnd(containerElement, 5); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 4
+PASS range.endOffset is 5
+PASS range.toString() is "3-begin 45 3-end"
+insertedElement = document.getElementById("div6");
+range.setStart(containerElement, 1); range.setEnd(containerElement, 1); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 1
+PASS range.endOffset is 2
+PASS range.toString() is "6"
+insertedElement = document.getElementById("div3");
+range.setStart(containerElement, 4); range.setEnd(containerElement, 4); range.insertNode(insertedElement);
+PASS range.startContainer is containerElement
+PASS range.endContainer is containerElement
+PASS range.startOffset is 4
+PASS range.endOffset is 5
+PASS range.toString() is "3-begin 45 3-end"
+PASS documentFragment = range.extractContents(); range.startContainer is containerElement
+PASS range.startOffset is 4
+PASS range.endContainer is containerElement
+PASS range.endOffset is 4
+PASS range.insertNode(documentFragment); range.toString() is "3-begin 45 3-end"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container.html (0 => 159620)
--- trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container.html (rev 0)
+++ trunk/LayoutTests/fast/dom/Range/range-insertNode-same-container.html 2013-11-21 13:52:09 UTC (rev 159620)
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<div id="rootDiv">
+<div id="div1">1</div><div id="div2">2</div><div id="div3">3-begin <div id="div4">4</div><div id="div5">5</div> 3-end</div><div id="div6">6</div><div id="div7">7</div>
+<div id="description">Test various cases of Range.insertNode with nodes in the same container as the Range.</div>
+</div>
+<script>
+var range = document.createRange();
+
+var containerElement = document.getElementById("rootDiv");
+
+evalAndLog('insertedElement = document.getElementById("div1");');
+evalAndLog('range.setStart(containerElement, 3); range.setEnd(containerElement, 3); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '2');
+shouldBe('range.endOffset', '3');
+shouldBe('range.toString()', '"1"');
+
+evalAndLog('range.setStart(containerElement, 3); range.setEnd(containerElement, 3); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '2');
+shouldBe('range.endOffset', '3');
+shouldBe('range.toString()', '"1"');
+
+evalAndLog('insertedElement = document.getElementById("div3");');
+evalAndLog('range.setStart(containerElement, 5); range.setEnd(containerElement, 5); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '4');
+shouldBe('range.endOffset', '5');
+shouldBe('range.toString()', '"3-begin 45 3-end"');
+
+evalAndLog('range.setStart(containerElement, 5); range.setEnd(containerElement, 5); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '4');
+shouldBe('range.endOffset', '5');
+shouldBe('range.toString()', '"3-begin 45 3-end"');
+
+evalAndLog('insertedElement = document.getElementById("div6");');
+evalAndLog('range.setStart(containerElement, 1); range.setEnd(containerElement, 1); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '1');
+shouldBe('range.endOffset', '2');
+shouldBe('range.toString()', '"6"');
+
+evalAndLog('insertedElement = document.getElementById("div3");');
+evalAndLog('range.setStart(containerElement, 4); range.setEnd(containerElement, 4); range.insertNode(insertedElement);');
+shouldBe('range.startContainer', 'containerElement');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.startOffset', '4');
+shouldBe('range.endOffset', '5');
+shouldBe('range.toString()', '"3-begin 45 3-end"');
+
+shouldBe('documentFragment = range.extractContents(); range.startContainer', 'containerElement');
+shouldBe('range.startOffset', '4');
+shouldBe('range.endContainer', 'containerElement');
+shouldBe('range.endOffset', '4');
+shouldBe('range.insertNode(documentFragment); range.toString()', '"3-begin 45 3-end"');
+
+containerElement.style.display = 'none';
+
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (159619 => 159620)
--- trunk/Source/WebCore/ChangeLog 2013-11-21 13:46:39 UTC (rev 159619)
+++ trunk/Source/WebCore/ChangeLog 2013-11-21 13:52:09 UTC (rev 159620)
@@ -1,5 +1,25 @@
2013-11-21 Ryosuke Niwa <[email protected]>
+ Fix Range.insertNode when the inserted node is in the same container as the Range
+ https://bugs.webkit.org/show_bug.cgi?id=123957
+
+ Reviewed by Antti Koivisto.
+
+ Inspired by https://chromium.googlesource.com/chromium/blink/+/fb6ca1f488703e8d4f20ce6449cc8ea210be6edb
+
+ When a node from the same container is inserted, we can't simply adjust m_end with the offset.
+ Compute m_start and m_end from the inserted nodes instead.
+
+ Also, don't adjust m_start and m_end to nodes outside of the document if the inserted nodes had been
+ removed by mutation events.
+
+ Test: fast/dom/Range/range-insertNode-same-container.html
+
+ * dom/Range.cpp:
+ (WebCore::Range::insertNode):
+
+2013-11-21 Ryosuke Niwa <[email protected]>
+
nextBoundary and previousBoundary are very slow when there is a password field
https://bugs.webkit.org/show_bug.cgi?id=123973
Modified: trunk/Source/WebCore/dom/Range.cpp (159619 => 159620)
--- trunk/Source/WebCore/dom/Range.cpp 2013-11-21 13:46:39 UTC (rev 159619)
+++ trunk/Source/WebCore/dom/Range.cpp 2013-11-21 13:52:09 UTC (rev 159620)
@@ -1034,20 +1034,23 @@
if (ec)
return;
- if (collapsed)
+ if (collapsed && newText->parentNode() == container && &container->document() == &ownerDocument())
m_end.setToBeforeChild(newText.get());
} else {
- RefPtr<Node> lastChild;
- if (collapsed)
- lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
-
container = m_start.container();
- container->insertBefore(newNode.release(), container->childNode(m_start.offset()), ec);
+ RefPtr<Node> firstInsertedChild = newNodeType == Node::DOCUMENT_FRAGMENT_NODE ? newNode->firstChild() : newNode;
+ RefPtr<Node> lastInsertedChild = newNodeType == Node::DOCUMENT_FRAGMENT_NODE ? newNode->lastChild() : newNode;
+ RefPtr<Node> childAfterInsertedContent = container->childNode(m_start.offset());
+ container->insertBefore(newNode.release(), childAfterInsertedContent.get(), ec);
if (ec)
return;
- if (collapsed && numNewChildren)
- m_end.set(m_start.container(), m_start.offset() + numNewChildren, lastChild.get());
+ if (collapsed && numNewChildren && &container->document() == &ownerDocument()) {
+ if (firstInsertedChild->parentNode() == container)
+ m_start.setToBeforeChild(firstInsertedChild.get());
+ if (lastInsertedChild->parentNode() == container)
+ m_end.set(container, lastInsertedChild->nodeIndex() + 1, lastInsertedChild.get());
+ }
}
}