- Revision
- 216431
- Author
- an...@apple.com
- Date
- 2017-05-08 10:20:54 -0700 (Mon, 08 May 2017)
Log Message
ComposedTreeIterator does not traverse all slotted children if the traversal root is a slot element.
https://bugs.webkit.org/show_bug.cgi?id=171375
<rdar://problem/31863184>
Reviewed by Zalan Bujtas.
Source/WebCore:
We were hitting an assert when using details element with a flow thread. The root cause for this turned
out to be that we only traversed the first slotted child if the traversal root was a slot element.
Test: fast/html/details-flow-thread.html
* dom/ComposedTreeIterator.cpp:
(WebCore::ComposedTreeIterator::traverseNextLeavingContext):
Try to traverse to the next slotted child before testing if we at the end of the current context.
LayoutTests:
* fast/html/details-flow-thread-expected.txt: Added.
* fast/html/details-flow-thread.html: Added.
* fast/shadow-dom/composed-tree-slots-expected.txt:
* fast/shadow-dom/composed-tree-slots.html:
Expand the test so it also prints out slot subtrees using slots as traversal roots.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (216430 => 216431)
--- trunk/LayoutTests/ChangeLog 2017-05-08 17:06:29 UTC (rev 216430)
+++ trunk/LayoutTests/ChangeLog 2017-05-08 17:20:54 UTC (rev 216431)
@@ -1,3 +1,18 @@
+2017-05-08 Antti Koivisto <an...@apple.com>
+
+ ComposedTreeIterator does not traverse all slotted children if the traversal root is a slot element.
+ https://bugs.webkit.org/show_bug.cgi?id=171375
+ <rdar://problem/31863184>
+
+ Reviewed by Zalan Bujtas.
+
+ * fast/html/details-flow-thread-expected.txt: Added.
+ * fast/html/details-flow-thread.html: Added.
+ * fast/shadow-dom/composed-tree-slots-expected.txt:
+ * fast/shadow-dom/composed-tree-slots.html:
+
+ Expand the test so it also prints out slot subtrees using slots as traversal roots.
+
2017-05-08 Chris Dumez <cdu...@apple.com>
Move 'style' from Element to HTMLElement / SVGElement and make it settable
Added: trunk/LayoutTests/fast/html/details-flow-thread-expected.txt (0 => 216431)
--- trunk/LayoutTests/fast/html/details-flow-thread-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/html/details-flow-thread-expected.txt 2017-05-08 17:20:54 UTC (rev 216431)
@@ -0,0 +1 @@
+This test passes if it doesn't assert
Added: trunk/LayoutTests/fast/html/details-flow-thread.html (0 => 216431)
--- trunk/LayoutTests/fast/html/details-flow-thread.html (rev 0)
+++ trunk/LayoutTests/fast/html/details-flow-thread.html 2017-05-08 17:20:54 UTC (rev 216431)
@@ -0,0 +1,26 @@
+<style>
+details div { -webkit-flow-into: bar; }
+</style>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+function gc() {
+ if (window.GCController)
+ return GCController.collect();
+ var a;
+ for (var i=0; i<100; i++)
+ a = new Uint8Array(1024*1024);
+}
+
+function go() {
+ details.offsetLeft;
+ details.open = false;
+ div.innerHTML = "This test passes if it doesn't assert";
+ gc();
+}
+</script>
+<body _onload_=go()>
+<div id="div">
+<details open id="details">
+<div>foo</div>
Modified: trunk/LayoutTests/fast/shadow-dom/composed-tree-slots-expected.txt (216430 => 216431)
--- trunk/LayoutTests/fast/shadow-dom/composed-tree-slots-expected.txt 2017-05-08 17:06:29 UTC (rev 216430)
+++ trunk/LayoutTests/fast/shadow-dom/composed-tree-slots-expected.txt 2017-05-08 17:20:54 UTC (rev 216431)
@@ -2,18 +2,27 @@
Test 1
div (shadow root)
slot
+Slot trees:
+
Test 2
div (shadow root)
slot
#text
+Slot trees:
+ #text
+
Test 3
div (shadow root)
slot
#text
div
+Slot trees:
+ #text
+ div
+
Test 4
div (shadow root)
slot
@@ -21,13 +30,21 @@
#text
div
#text
+Slot trees:
+ div
+ #text
+ div
+ #text
+
Test 5
div (shadow root)
div
slot
#text
+Slot trees:
+
Test 6
div (shadow root)
div
@@ -34,7 +51,10 @@
slot
#text
#text
+Slot trees:
+ #text
+
Test 7
div (shadow root)
div
@@ -42,7 +62,11 @@
#text
div
#text
+Slot trees:
+ #text
+ div
+
Test 8
div (shadow root)
div
@@ -52,24 +76,41 @@
div
#text
#text
+Slot trees:
+ div
+ #text
+ div
+ #text
+
Test 9
div (shadow root)
slot
slot-default
#text
+Slot trees:
+ slot-default
+ #text
+
Test 10
div (shadow root)
slot
#text
+Slot trees:
+ #text
+
Test 11
div (shadow root)
slot
#text
div
+Slot trees:
+ #text
+ div
+
Test 12
div (shadow root)
slot
@@ -77,7 +118,13 @@
#text
div
#text
+Slot trees:
+ div
+ #text
+ div
+ #text
+
Test 13
div (shadow root)
div (shadow root)
@@ -86,7 +133,13 @@
#text
slot
#text
+Slot trees:
+ #text
+ slot
+ #text
+
+
Test 14
div (shadow root)
div (shadow root)
@@ -96,7 +149,15 @@
slot
#text
#text
+Slot trees:
+ #text
+ #text
+ slot
+ #text
+ #text
+
+
Test 15
div (shadow root)
div (shadow root)
@@ -107,7 +168,17 @@
#text
div
#text
+Slot trees:
+ #text
+ div
+ #text
+ slot
+ #text
+ div
+ #text
+
+
Test 16
div (shadow root)
div (shadow root)
@@ -120,4 +191,18 @@
div
#text
#text
+Slot trees:
+ div
+ #text
+ div
+ #text
+ #text
+ slot
+ div
+ #text
+ div
+ #text
+ #text
+
+
Modified: trunk/LayoutTests/fast/shadow-dom/composed-tree-slots.html (216430 => 216431)
--- trunk/LayoutTests/fast/shadow-dom/composed-tree-slots.html 2017-05-08 17:06:29 UTC (rev 216430)
+++ trunk/LayoutTests/fast/shadow-dom/composed-tree-slots.html 2017-05-08 17:20:54 UTC (rev 216431)
@@ -34,26 +34,38 @@
<script>
function installShadows(tree)
{
- var shadowHosts = tree.querySelectorAll("[shadow]");
- for (var i = 0; i < shadowHosts.length; ++i) {
- var shadowId = shadowHosts[i].getAttribute("shadow");
+ for (const host of tree.querySelectorAll("[shadow]")) {
+ var shadowId = host.getAttribute("shadow");
var shadowContents = document.querySelector("#"+shadowId).content.cloneNode(true);
installShadows(shadowContents);
- var shadowRoot = shadowHosts[i].attachShadow({ mode: "open" });
+ var shadowRoot = host.attachShadow({ mode: "open" });
shadowRoot.appendChild(shadowContents);
}
}
+function findSlots(root)
+{
+ let slots = [];
+ for (const host of root.querySelectorAll("[shadow]")) {
+ for (const slot of host.shadowRoot.querySelectorAll("slot"))
+ slots.push(slot);
+ Array.prototype.push.apply(slots, findSlots(host.shadowRoot));
+ }
+ return slots;
+}
+
var console = document.querySelector("#console");
-var tests = document.querySelectorAll("[test]");
-for (var i = 0; i < tests.length; ++i) {
- var test = tests[i].content.cloneNode(true);
+for (const testTemplate of document.querySelectorAll("[test]")) {
+ var test = testTemplate.content.cloneNode(true);
installShadows(test);
- console.innerText += "\nTest " + tests[i].getAttribute("test") + "\n";
+ console.innerText += "\nTest " + testTemplate.getAttribute("test") + "\n";
console.innerText += internals.composedTreeAsText(test);
+ console.innerText += "Slot trees:\n";
+ for (const slot of findSlots(test))
+ console.innerText += internals.composedTreeAsText(slot) + "\n";
}
</script>
Modified: trunk/Source/WebCore/ChangeLog (216430 => 216431)
--- trunk/Source/WebCore/ChangeLog 2017-05-08 17:06:29 UTC (rev 216430)
+++ trunk/Source/WebCore/ChangeLog 2017-05-08 17:20:54 UTC (rev 216431)
@@ -1,3 +1,21 @@
+2017-05-08 Antti Koivisto <an...@apple.com>
+
+ ComposedTreeIterator does not traverse all slotted children if the traversal root is a slot element.
+ https://bugs.webkit.org/show_bug.cgi?id=171375
+ <rdar://problem/31863184>
+
+ Reviewed by Zalan Bujtas.
+
+ We were hitting an assert when using details element with a flow thread. The root cause for this turned
+ out to be that we only traversed the first slotted child if the traversal root was a slot element.
+
+ Test: fast/html/details-flow-thread.html
+
+ * dom/ComposedTreeIterator.cpp:
+ (WebCore::ComposedTreeIterator::traverseNextLeavingContext):
+
+ Try to traverse to the next slotted child before testing if we at the end of the current context.
+
2017-05-08 Mark Lam <mark....@apple.com>
Introduce ExceptionScope::assertNoException() and releaseAssertNoException().
Modified: trunk/Source/WebCore/dom/ComposedTreeIterator.cpp (216430 => 216431)
--- trunk/Source/WebCore/dom/ComposedTreeIterator.cpp 2017-05-08 17:06:29 UTC (rev 216430)
+++ trunk/Source/WebCore/dom/ComposedTreeIterator.cpp 2017-05-08 17:20:54 UTC (rev 216431)
@@ -179,10 +179,10 @@
{
while (context().iterator == context().end && m_contextStack.size() > 1) {
m_contextStack.removeLast();
+ if (is<HTMLSlotElement>(current()) && advanceInSlot(1))
+ return;
if (context().iterator == context().end)
return;
- if (is<HTMLSlotElement>(current()) && advanceInSlot(1))
- return;
context().iterator.traverseNextSkippingChildren();
}
}