Skip to content
Permalink
Browse files
Element should be able to have multiple shadow roots.
https://bugs.webkit.org/show_bug.cgi?id=77931

Reviewed by Hajime Morita.

.:

* Source/autotools/symbols.filter:

Source/WebCore:

This patch enables us to add multiple shadow subtrees into elements.
Note that multiple shadow subtrees are enabled
only if RuntimeEnabledFeatures::multipleShadowSubtrees is enabled.

Since we don't have <shadow> element yet, only the youngest shadow tree
will be rendered. This patch includes tests to confirm adding a new shadow
tree dynamically to confirm only the youngest shadow tree is renderered.

Tests: fast/dom/shadow/multiple-shadowroot-rendering.html
       fast/dom/shadow/multiple-shadowroot.html

* WebCore.exp.in:
* dom/Element.cpp:
  Uses ShadowRootList interfaces directly instead of ShadowRootList emulation methods.
(WebCore::Element::~Element):
(WebCore::Element::attach):
(WebCore::Element::addShadowRoot):
(WebCore::Element::removeShadowRootList):
* dom/Element.h:
(Element):
* dom/NodeRenderingContext.cpp:
  Makes non-youngest shadow subtrees hidden.
(WebCore::NodeRenderingContext::NodeRenderingContext):
(WebCore::NodeRenderingContext::hostChildrenChanged):
  Since non-youngest children may be changed, make sure host children are changed.
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::create):
* dom/ShadowRoot.h:
  Utility methods to make code intention clear are added.
(WebCore::ShadowRoot::youngerShadowRoot):
(WebCore::ShadowRoot::olderShadowRoot):
(ShadowRoot):
(WebCore::ShadowRoot::isYoungest):
(WebCore::ShadowRoot::isOldest):
* dom/ShadowRootList.cpp:
(WebCore::ShadowRootList::popShadowRoot):
(WebCore::ShadowRootList::attach):
(WebCore::ShadowRootList::detach):
  Detaches shadow subtrees.
* testing/Internals.cpp:
(WebCore::Internals::address):
(WebCore):
(WebCore::Internals::youngerShadowRoot):
(WebCore::Internals::olderShadowRoot):
(WebCore::Internals::removeShadowRoot):
* testing/Internals.h:
(Internals):
* testing/Internals.idl:

Source/WebKit2:

* win/WebKit2.def:
* win/WebKit2CFLite.def:

LayoutTests:

* fast/dom/resources/shadow-test-driver.js:
(createSpanWithText):
(doneTest):
(doTest):
* fast/dom/shadow/multiple-shadowroot-expected.txt: Added.
* fast/dom/shadow/multiple-shadowroot-rendering-expected.txt: Added.
* fast/dom/shadow/multiple-shadowroot-rendering.html: Added.
* fast/dom/shadow/multiple-shadowroot.html: Added.
* platform/efl/Skipped:
* platform/gtk/Skipped:
* platform/mac/Skipped:
* platform/qt/Skipped:
* platform/win/Skipped:
* platform/wincairo/Skipped:
* platform/wk2/Skipped:


Canonical link: https://commits.webkit.org/96857@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@109096 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Shinya Kawanaka committed Feb 28, 2012
1 parent ce0753a commit bca961bbc743aa870d1d530a4e1ead8d2cbbd8a9
Showing 26 changed files with 428 additions and 30 deletions.
@@ -1,3 +1,12 @@
2012-02-28 Shinya Kawanaka <shinyak@chromium.org>

Element should be able to have multiple shadow roots.
https://bugs.webkit.org/show_bug.cgi?id=77931

Reviewed by Hajime Morita.

* Source/autotools/symbols.filter:

2012-02-27 Shinya Kawanaka <shinyak@chromium.org>

Element::removeShadowRoot() and setShadowRoot() should be moved into ShadowTree.
@@ -1,3 +1,26 @@
2012-02-28 Shinya Kawanaka <shinyak@chromium.org>

Element should be able to have multiple shadow roots.
https://bugs.webkit.org/show_bug.cgi?id=77931

Reviewed by Hajime Morita.

* fast/dom/resources/shadow-test-driver.js:
(createSpanWithText):
(doneTest):
(doTest):
* fast/dom/shadow/multiple-shadowroot-expected.txt: Added.
* fast/dom/shadow/multiple-shadowroot-rendering-expected.txt: Added.
* fast/dom/shadow/multiple-shadowroot-rendering.html: Added.
* fast/dom/shadow/multiple-shadowroot.html: Added.
* platform/efl/Skipped:
* platform/gtk/Skipped:
* platform/mac/Skipped:
* platform/qt/Skipped:
* platform/win/Skipped:
* platform/wincairo/Skipped:
* platform/wk2/Skipped:

2012-02-28 Yoshifumi Inoue <yosin@chromium.org>

[Chromium] We should reset mouse position before calling eventSender.mouseMove in LayoutTest
@@ -53,9 +53,11 @@ function check() {
}
}

function createSpanWithText(text) {
function createSpanWithText(text, className) {
var span = document.createElement('span');
span.appendChild(document.createTextNode(text));
if (className)
span.className = className;
return span;
}

@@ -118,11 +120,16 @@ function doTestIfLeft(restTests) {

function doneTest() {
log("TEST COMPLETED");
if (window.tearDownOnce)
window.tearDownOnce();
layoutTestController.notifyDone();
}

// A test driver. Call this body.onload.
function doTest(tests) {
if (window.setUpOnce)
window.setUpOnce();

if (window.layoutTestController) {
layoutTestController.waitUntilDone();
layoutTestController.dumpAsText();
@@ -0,0 +1,17 @@
This test ensure that the multiple shadow root is available.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS internals.shadowRoot(div) is null
PASS internals.shadowRoot(div) is shadowRoot1
PASS internals.olderShadowRoot(shadowRoot1) is null
PASS internals.shadowRoot(div) is shadowRoot2
PASS internals.olderShadowRoot(shadowRoot2) is shadowRoot1
PASS internals.shadowRoot(div) is shadowRoot3
PASS internals.olderShadowRoot(shadowRoot3) is shadowRoot2
PASS internals.shadowRoot(div) is null
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,14 @@
testDoubleShadowSubtrees
PASS
testTripleShadowSubtrees
PASS
testShadowSubtreesWithContent
PASS
testShadowSubtreesWithContentInOlderSubtree
PASS
testShadowSubtreesWithDynamicCreation
PASS
testShadowSubtreesWithDynamicCreationOutOfTree
PASS
TEST COMPLETED

@@ -0,0 +1,174 @@
<!DOCTYPE html>
<html>
<head>
<style>
/* relative positioning ensures underlying RenderLayer */
.container {
position: relative;
}

.span {
display: boxed-inline;
margin: 2px;
border: solid;
}
</style>
<script src="../resources/shadow-test-driver.js"></script>
<script>
function setUpOnce() {
internals.setMultipleShadowSubtreesEnabled(true);
}

function teatDownOnce() {
internals.setMultipleShadowSubtreesEnabled(false);
}

var testFuncs = [];

testFuncs.push(function testDoubleShadowSubtrees(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>MID</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('MID: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE'));
sr2.appendChild(createSpanWithText('MID'));
sr2.appendChild(createSpanWithText('AFTER'));

document.getElementById('actual-container').appendChild(root);

callIfDone();
});

testFuncs.push(function testTripleShadowSubtrees(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>MID</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('MID: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr2.appendChild(createSpanWithText('MID: SHOULD NOT BE RENDERED'));
sr2.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

var sr3 = new WebKitShadowRoot(root);
sr3.appendChild(createSpanWithText('BEFORE'));
sr3.appendChild(createSpanWithText('MID'));
sr3.appendChild(createSpanWithText('AFTER'));

document.getElementById('actual-container').appendChild(root);

callIfDone();
});

testFuncs.push(function testShadowSubtreesWithContent(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>LIGHT</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('MID: SHOULD NOT BE RENDERED'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE'));
sr2.appendChild(createContentWithSelect('span', 'FALLBACK'));
sr2.appendChild(createSpanWithText('AFTER'));

document.getElementById('actual-container').appendChild(root);

callIfDone();
});

testFuncs.push(function testShadowSubtreesWithContentInOlderSubtree(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>LIGHT 1</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT 1', 'c1'));
root.appendChild(createSpanWithText('LIGHT 2', 'c2'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createContentWithSelect('.c2', 'FALLBACK'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE'));
sr2.appendChild(createContentWithSelect('.c1', 'FALLBACK'));
sr2.appendChild(createSpanWithText('AFTER'));

document.getElementById('actual-container').appendChild(root);

callIfDone();
});

testFuncs.push(function testShadowSubtreesWithDynamicCreation(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>LIGHT 1</span><span>LIGHT 2</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT 1', 'c1'));
root.appendChild(createSpanWithText('LIGHT 2', 'c2'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createContentWithSelect('span', 'FALLBACK'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

document.getElementById('actual-container').appendChild(root);

setTimeout((function(callIfDone, root) { return function() {
var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE'));
sr2.appendChild(createContentWithSelect('span', 'FALLBACK'));
sr2.appendChild(createSpanWithText('AFTER'));

callIfDone();
};})(callIfDone, root), 0);
});

testFuncs.push(function testShadowSubtreesWithDynamicCreationOutOfTree(callIfDone) {
document.getElementById('expect-container').innerHTML = "<div><span>BEFORE</span><span>LIGHT 1</span><span>LIGHT 2</span><span>AFTER</span></div>";

var root = document.createElement('div');
root.appendChild(createSpanWithText('LIGHT 1', 'c1'));
root.appendChild(createSpanWithText('LIGHT 2', 'c2'));

var sr1 = new WebKitShadowRoot(root);
sr1.appendChild(createSpanWithText('BEFORE: SHOULD NOT BE RENDERED'));
sr1.appendChild(createContentWithSelect('span', 'FALLBACK'));
sr1.appendChild(createSpanWithText('AFTER: SHOULD NOT BE RENDERED'));

setTimeout((function(callIfDone, root) { return function() {
var sr2 = new WebKitShadowRoot(root);
sr2.appendChild(createSpanWithText('BEFORE'));
sr2.appendChild(createContentWithSelect('span', 'FALLBACK'));
sr2.appendChild(createSpanWithText('AFTER'));

document.getElementById('actual-container').appendChild(root);

callIfDone();
};})(callIfDone, root), 0);
});
</script>
</head>
<body onload="doTest(testFuncs)">

<div id="actual-container" class="container"></div>
<div id="expect-container" class="container"></div>
<pre id="console"></pre>

</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../js/resources/js-test-pre.js"></script>
</head>
<body>
<script>
description("This test ensure that the multiple shadow root is available.");

internals.setMultipleShadowSubtreesEnabled(true);

var div = document.createElement('div');
shouldBe("internals.shadowRoot(div)", "null");
var shadowRoot1 = new WebKitShadowRoot(div);
shouldBe("internals.shadowRoot(div)", "shadowRoot1");
shouldBe("internals.olderShadowRoot(shadowRoot1)", "null");

var shadowRoot2 = new WebKitShadowRoot(div)
shouldBe("internals.shadowRoot(div)", "shadowRoot2");
shouldBe("internals.olderShadowRoot(shadowRoot2)", "shadowRoot1");

var shadowRoot3 = new WebKitShadowRoot(div);
shouldBe("internals.shadowRoot(div)", "shadowRoot3");
shouldBe("internals.olderShadowRoot(shadowRoot3)", "shadowRoot2");

internals.removeShadowRoot(div);
shouldBe("internals.shadowRoot(div)", "null");

internals.setMultipleShadowSubtreesEnabled(false);

var successfullyParsed = true;
</script>
<script src="../../js/resources/js-test-post.js"></script>
</body>
</html>
@@ -2091,6 +2091,8 @@ fast/dom/shadow/shadow-root-js-api.html
fast/dom/shadow/shadow-disable.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# CSS Filters support not yet enabled (needs ENABLE_CSS_FILTERS).
# https://bugs.webkit.org/show_bug.cgi?id=68469
@@ -430,6 +430,8 @@ fast/dom/shadow/shadow-disable.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/shadow-ul-li.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# JSC does not support setIsolatedWorldSecurityOrigin (http://webkit.org/b/61540)
http/tests/security/isolatedWorld/cross-origin-xhr.html
@@ -168,6 +168,8 @@ fast/dom/shadow/shadow-on-image.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/shadow-ul-li.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# CSS Regions support not yet enabled. http://webkit.org/b/57312
fast/regions
@@ -1459,6 +1459,8 @@ fast/dom/shadow/shadow-disable.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/shadow-ul-li.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# CSS Regions support not yet enabled. http://webkit.org/b/57312
fast/regions
@@ -1969,6 +1969,8 @@ fast/dom/shadow/shadow-root-js-api.html
fast/dom/shadow/shadow-disable.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# CSS Regions support not yet enabled. http://webkit.org/b/57312
fast/regions
@@ -1070,6 +1070,8 @@ fast/dom/shadow/shadow-disable.html
fast/dom/shadow/shadow-root-attached.html
fast/dom/shadow/shadow-root-new.html
fast/dom/shadow/shadow-ul-li.html
fast/dom/shadow/multiple-shadowroot.html
fast/dom/shadow/multiple-shadowroot-rendering.html

# WTR needs an implementation for eventSender.continuousMouseScrollBy
# https://bugs.webkit.org/show_bug.cgi?id=69417

0 comments on commit bca961b

Please sign in to comment.