summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-scoping
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/css/css-scoping')
-rw-r--r--testing/web-platform/tests/css/css-scoping/META.yml6
-rw-r--r--testing/web-platform/tests/css/css-scoping/chrome-1492368-crash.html17
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-before-after.html58
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-rules.html48
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-dynamic-remove-style-detached.html29
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-functional-rule.html67
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-namespace.html82
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-rule.html67
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-with-before-after.html48
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-invisible-slot.html40
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-nested-slot-display-override.html23
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-root-hides-children.html36
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-display-override.html39
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-fallback.html47
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-style.html47
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot.html40
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-nested.html66
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-rule.html55
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-outside-rules.html43
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules-no-style-leak.html37
-rw-r--r--testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules.html36
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-context-parsing.html16
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-context-specificity-001.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-context-specificity-002.html23
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-context-specificity-003.html22
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-descendant-001.html16
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-descendant-002.html15
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-descendant-invalidation.html22
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-dom-001.html16
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-functional-descendant-invalidation.html22
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-is-001.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-is-002.html20
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-is-003.html24
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-is-004.html23
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-is-005.html22
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-multiple-001.html15
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-nested-001.html29
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-parsing.html16
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-slotted-001.html17
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-specificity-002.html26
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-specificity-003.html26
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-specificity.html25
-rw-r--r--testing/web-platform/tests/css/css-scoping/host-with-default-namespace-001.html18
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-001.html42
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-002.html34
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-003.html26
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-004.html27
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-005.html28
-rw-r--r--testing/web-platform/tests/css/css-scoping/keyframes-006.html29
-rw-r--r--testing/web-platform/tests/css/css-scoping/reference/green-box.html11
-rw-r--r--testing/web-platform/tests/css/css-scoping/reference/green-text.html3
-rw-r--r--testing/web-platform/tests/css/css-scoping/reslot-text-inheritance.html17
-rw-r--r--testing/web-platform/tests/css/css-scoping/resources/host-green-box.css5
-rw-r--r--testing/web-platform/tests/css/css-scoping/scoped-reference-animation-001.html42
-rw-r--r--testing/web-platform/tests/css/css-scoping/scoped-reference-animation-002.html55
-rw-r--r--testing/web-platform/tests/css/css-scoping/scoped-reference-animation-ref.html30
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-assign-dynamic-001.html29
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-at-import.html13
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-cascade-order-001.html403
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-directionality-001.tentative.html34
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-directionality-002.tentative.html19
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-disabled-sheet-001.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-001.html19
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-002.html19
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-003.html18
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html20
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-005.html20
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-host-removal-invalidation.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-host-with-before-after.html83
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet.html11
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-multiple-links.html15
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-001.html22
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-002.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-003.html19
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-004.html26
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-root-insert-into-document.html18
-rw-r--r--testing/web-platform/tests/css/css-scoping/shadow-shared-style-cache-001.html27
-rw-r--r--testing/web-platform/tests/css/css-scoping/slot-non-html-display-value.html18
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-invalidation.html35
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-link.html21
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-matches.html16
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-nested.html49
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-parsing.html49
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-placeholder-ref.html6
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-placeholder.html19
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-slot.html17
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-specificity-002.html24
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-specificity.html25
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element-ref.html8
-rw-r--r--testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element.html31
-rw-r--r--testing/web-platform/tests/css/css-scoping/stylesheet-title-001.html24
-rw-r--r--testing/web-platform/tests/css/css-scoping/stylesheet-title-002.html36
-rw-r--r--testing/web-platform/tests/css/css-scoping/whitespace-crash-001.html32
94 files changed, 3044 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-scoping/META.yml b/testing/web-platform/tests/css/css-scoping/META.yml
new file mode 100644
index 0000000000..8263416521
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/META.yml
@@ -0,0 +1,6 @@
+spec: https://drafts.csswg.org/css-scoping/
+suggested_reviewers:
+ - kojiishi
+ - rniwa
+ - tabatkins
+ - fantasai
diff --git a/testing/web-platform/tests/css/css-scoping/chrome-1492368-crash.html b/testing/web-platform/tests/css/css-scoping/chrome-1492368-crash.html
new file mode 100644
index 0000000000..04d48ef215
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/chrome-1492368-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Chrome crash re-assigning to slots with display:none slot</title>
+<link rel="help" href="https://crbug.com/1492368">
+<div id="host">
+ <span id="slotted" style="display:none"></span>
+</div>
+<script>
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ <slot name="s1" style="display:none"></slot>
+ `;
+ host.offsetTop;
+ slotted.setAttribute("slot", "s1");
+ slotted.style.color = "green";
+ host.offsetTop;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-before-after.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-before-after.html
new file mode 100644
index 0000000000..b926540ae9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-before-after.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - ::before and ::after pseudo class' contents on a node assigned to a slot element must be rendered</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ div {
+ display: block;
+ background: red;
+ line-height: 0px;
+ width: 100%;
+ height: 50px;
+ }
+ [slot=foo]::before,
+ [slot=foo]::after {
+ display: block;
+ content: "";
+ width: 100%;
+ height: 25px;
+ }
+ [slot=foo]::before,
+ [slot=foo]::after {
+ background: green;
+ }
+ [slot=bar]::before,
+ [slot=bar]::after {
+ background: yellow;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div slot="foo"></div>
+ <div slot="bar"></div>
+ <div slot="foo"></div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot name="foo"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-rules.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-rules.html
new file mode 100644
index 0000000000..e981eae055
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-assigned-node-with-rules.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - Only rules outside a shadow tree must apply to nodes assigned to a slot in the shadow tree.</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ overflow: hidden;
+ background: green;
+ }
+ div {
+ width: 100%;
+ height: 50%;
+ }
+ .green {
+ color: green;
+ }
+ .red {
+ color: red;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div class="red">FAIL</div>
+ <div class="green" slot="green">FAIL</div>
+ <div class="red" slot="invalid">FAIL</div>
+ <div class="green" slot="green">FAIL</div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> div { color: yellow; } </style><slot name="green"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-dynamic-remove-style-detached.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-dynamic-remove-style-detached.html
new file mode 100644
index 0000000000..c8c9eadc87
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-dynamic-remove-style-detached.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>CSS Scoping: Invalidation of style data while ShadowRoot is disconnected.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1612114">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host"></div>
+<script>
+let t = async_test("Invalidation of style data while ShadowRoot is disconnected.");
+
+let host = document.getElementById("host");
+host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ div { color: red }
+ </style>
+ <div></div>
+`;
+assert_equals(getComputedStyle(host.shadowRoot.querySelector("div")).color, "rgb(255, 0, 0)");
+host.remove();
+host.shadowRoot.querySelector("style").remove();
+requestAnimationFrame(t.step_func(function() {
+ requestAnimationFrame(t.step_func_done(function() {
+ document.body.appendChild(host);
+ assert_not_equals(getComputedStyle(host.shadowRoot.querySelector("div")).color, "rgb(255, 0, 0)");
+ }));
+}));
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-functional-rule.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-functional-rule.html
new file mode 100644
index 0000000000..13f9a67ed8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-functional-rule.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - :host() rules must apply to the shadow host.</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#host-selector">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ host-1, host-2, host-3, host-4, host-5 {
+ display: block;
+ width: 100px;
+ height: 20px;
+ background: red;
+ }
+ host-3, host-4, host-5 {
+ background: green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <host-1>
+ <div>FAIL1</div>
+ </host-1>
+ <host-2 id="bar" class="foo" name="baz">
+ <div>FAIL2</div>
+ </host-2>
+ <div>
+ <host-3>
+ FAIL3
+ </host-3>
+ </div>
+ <host-4>
+ <div class="child">FAIL4</div>
+ </host-4>
+ <host-5>
+ <div>FAIL5</div>
+ </host-5>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('host-1');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host(host-1) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('host-2');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host(host-2.foo#bar[name=baz]) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('host-3');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host(div host-3) { background: red !important; } </style>';
+
+ shadowHost = document.querySelector('host-4');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host(.child) { background: red !important; } </style>';
+
+ shadowHost = document.querySelector('host-5');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host(host-1) { background: red !important; } </style>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-namespace.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-namespace.html
new file mode 100644
index 0000000000..46dffc8de3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-namespace.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - :host, :host-context, and default @namespace</title>
+ <link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"/>
+ <link rel="help" href="https://www.w3.org/TR/css-scoping-1/#host-selector">
+ <link rel="help" href="https://www.w3.org/TR/css3-selectors/#typenmsp">
+ <link rel="help" href="https://www.w3.org/TR/css3-selectors/#univnmsp">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ .host {
+ display: block;
+ width: 100px;
+ height: 10px;
+ background: red;
+ }
+ #host-3, #host-5, #host-10 {
+ background: green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div id="host-1" class="host">FAIL</div>
+ <div id="host-2" class="host">FAIL</div>
+ <div id="host-3" class="host">FAIL</div>
+ <div id="host-4" class="host">FAIL</div>
+ <div id="host-5" class="host">FAIL</div>
+ <div id="host-6" class="host">FAIL</div>
+ <div id="host-7" class="host">FAIL</div>
+ <div id="host-8" class="host">FAIL</div>
+ <div id="host-9" class="host">FAIL</div>
+ <div id="host-10" class="host">FAIL</div>
+ <script>
+ try {
+ var shadowHost = document.querySelector('#host-1');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://www.w3.org/1999/xhtml); :host { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-2');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-3');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host(*) { background: red !important; } </style>';
+
+ shadowHost = document.querySelector('#host-4');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host(*|*) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-5');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host-context(*) { background: red !important; } </style>';
+
+ shadowHost = document.querySelector('#host-6');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host-context(*|*) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-7');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://www.w3.org/1999/xhtml); :host(*) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-8');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://www.w3.org/1999/xhtml); :host-context(*) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-9');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://www.w3.org/1999/xhtml); :host(div) { background: green !important; } </style>';
+
+ shadowHost = document.querySelector('#host-10');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style>@namespace url(http://dummy); :host-context(html) { background: red !important; } </style>';
+
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-rule.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-rule.html
new file mode 100644
index 0000000000..ef70b9017c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-rule.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - :host rules must apply to the shadow host.</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#host-selector">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host, my-host2, my-host3, my-host4 {
+ display: block;
+ width: 100px;
+ height: 25px;
+ }
+ my-host2 {
+ background: green;
+ }
+ my-host3 {
+ background: red;
+ color: green;
+ }
+ my-host4 {
+ background: green;
+ color: green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div>FAIL</div>
+ </my-host>
+ <my-host2>
+ <div>FAIL</div>
+ </my-host2>
+ <my-host3>
+ <div>FAIL</div>
+ </my-host3>
+ <div class="container">
+ <my-host4>
+ <div>FAIL</div>
+ </my-host4>
+ </div>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host { color: green; background: green; } </style><div>FAIL</div>';
+
+ shadowHost = document.querySelector('my-host2');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host { color: red; background: red; } div { color: green }</style><div>FAIL</div>';
+
+ shadowHost = document.querySelector('my-host3');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> :host { background: green !important; color: green !important; } </style><div>FAIL</div>';
+
+ shadowHost = document.querySelector('my-host4');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> .container :host { background: red !important; } </style><div>FAIL</div>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-with-before-after.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-with-before-after.html
new file mode 100644
index 0000000000..c32d8a9e87
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-host-with-before-after.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - ::before and ::after pseudo elements' contents on a shadow host must be rendered</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ my-host::before {
+ display: block;
+ content: "";
+ width: 100px;
+ height: 25px;
+ background: green;
+ }
+ my-host::after {
+ display: block;
+ content: "";
+ width: 100px;
+ height: 25px;
+ background: green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div>FAIL</div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<div style="width: 100px; height: 50px; background: green"></div>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-invisible-slot.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-invisible-slot.html
new file mode 100644
index 0000000000..be9f308fc4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-invisible-slot.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - elements with a distribution list should generate boxes in the formatting tree.</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ overflow: hidden;
+ }
+ div {
+ width: 100%;
+ height: 50%;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div slot="green" style="background: green;"></div>
+ <div style="background: red;">FAIL</div>
+ <div slot="green" style="background: green;"></div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot name="green" style="border: solid 50px red;"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-nested-slot-display-override.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-nested-slot-display-override.html
new file mode 100644
index 0000000000..f194e469f0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-nested-slot-display-override.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>CSS Scoping: Dynamically overriding nested slot display value</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slots-in-shadow-tree">
+<link rel="match" href="reference/green-box.html"/>
+<style>
+ #outerHost {
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+</style>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="outerHost"> </div>
+<script>
+ let outerRoot = outerHost.attachShadow({mode:"open"});
+ outerRoot.innerHTML = '<div id="innerHost"><slot></slot></div>';
+ let innerHost = outerRoot.querySelector("#innerHost");
+ let innerRoot = innerHost.attachShadow({mode:"open"});
+ innerRoot.innerHTML = '<slot style="display:none; border:solid 50px green"></slot>';
+ document.body.offsetTop;
+ innerRoot.querySelector("slot").style.display = "block";
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-root-hides-children.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-root-hides-children.html
new file mode 100644
index 0000000000..bc526059dc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-root-hides-children.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - a shadow tree hides non-distributed children of the host</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ }
+ div {
+ width: 100%; height: 100%; background: red;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div>FAIL</div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<div style="width: 100px; height: 100px; background: green; color:green">FAIL</div>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-display-override.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-display-override.html
new file mode 100644
index 0000000000..9338a25be6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-display-override.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - overriding slot element's display value should generate boxes</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ my-host > div {
+ width: 50px;
+ height: 50px;
+ background: green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div></div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot style="display:block; border: solid 25px green;"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-fallback.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-fallback.html
new file mode 100644
index 0000000000..6cf1b5bafc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-fallback.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - slot element without distributed nodes must render its fallback content</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ background-color: red;
+ width: 100px;
+ height: 50px;
+ }
+ .red {
+ background-color: red;
+ }
+ .green {
+ background-color: green;
+ }
+ div {
+ width: 100px;
+ height: 50px;
+ }
+ slot {
+ border: solid 10px red;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host></my-host>
+ <div class="red"><slot><div class="green"></div></slot></div>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot style="border: solid 10px red;">'
+ + '<div style="width: 100%; height: 100%; background-color: green;"></div></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-style.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-style.html
new file mode 100644
index 0000000000..e3f37c33c8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot-style.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - Ensure that slot's style is inherited by slotted children</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host, my-non-host {
+ display: block;
+ width: 100px;
+ height: 50px;
+ overflow: hidden;
+ background: red;
+ color: red;
+ }
+ div {
+ width: 100%;
+ height: 50%;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div slot="green" style="background: green;">FAIL</div>
+ <div slot="green" style="background: inherit;">FAIL</div>
+ </my-host>
+ <my-non-host>
+ <slot name="green" style="color: green; background: green">
+ <div slot="green" style="background: green;">FAIL</div>
+ <div slot="green" style="background: inherit;">FAIL</div>
+ </slot>
+ </my-non-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot name="green" style="color: green; background: green"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot.html
new file mode 100644
index 0000000000..2b588d622e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slot.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - elements with a distribution list should generate boxes in the formatting tree.</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ overflow: hidden;
+ }
+ div {
+ width: 100%;
+ height: 50%;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div slot="green" style="background: green;"></div>
+ <div style="background: red;">FAIL</div>
+ <div slot="green" style="background: green;"></div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot name="green"></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-nested.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-nested.html
new file mode 100644
index 0000000000..5f930e2e87
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-nested.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - ::slotted pseudo element rule must apply to an element that got slotted via another slot</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#slotted-pseudo">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ outer-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ outer-host > * {
+ display: block;
+ width: 100px;
+ height: 25px;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <outer-host>
+ <span slot="outer">FAIL1</span>
+ <span slot="inner">FAIL2</span>
+ <span slot="both">FAIL3</span>
+ </outer-host>
+ <template id="outer-host-template">
+ <inner-host>
+ <style>
+ ::slotted([slot=outer]) { background: green; color: green; }
+ ::slotted([slot=both]) { background: green; }
+ span { display: block; width: 100px; height: 25px; }
+ </style>
+ <slot name="outer"></slot>
+ <slot name="inner"></slot>
+ <slot name="both"></slot>
+ <span slot="inner">FAIL4</span>
+ </inner-host>
+ </template>
+ <template id="inner-host-template">
+ <style>
+ ::slotted([slot=inner]) { background: green; color: green; }
+ ::slotted([slot=both]) { color: green; }
+ </style>
+ <slot></slot>
+ <slot name="inner"></slot>
+ </template>
+ <script>
+
+ try {
+ var outerHost = document.querySelector('outer-host');
+ outerShadow = outerHost.attachShadow({mode: 'closed'});
+ outerShadow.appendChild(document.getElementById('outer-host-template').content.cloneNode(true));
+
+ var innerHost = outerShadow.querySelector('inner-host');
+ innerShadow = innerHost.attachShadow({mode: 'closed'});
+ innerShadow.appendChild(document.getElementById('inner-host-template').content.cloneNode(true));
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-rule.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-rule.html
new file mode 100644
index 0000000000..9771c5d1df
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-slotted-rule.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - :slotted pseudo element must allow selecting elements assigned to a slot element</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#slotted-pseudo">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ color: red;
+ background: green;
+ }
+ my-host > div, nested-host {
+ display: block;
+ width: 100px;
+ height: 25px;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div class="green">FAIL1</div>
+ <myelem><span>FAIL2</span></myelem>
+ <nested-host>
+ <span>FAIL3</span>
+ </nested-host>
+ <another-host>
+ <b>FAIL4</b>
+ </another-host>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<slot></slot><style> ::slotted(.green), ::slotted(myelem) { color:green; } </style>';
+
+ shadowHost = document.querySelector('nested-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> .mydiv ::slotted(*) { color:green; } </style><div class=mydiv><slot></slot></div>';
+
+ shadowHost = document.querySelector('another-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> ::slotted(*) { color:green; } </style><slot></slot>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-outside-rules.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-outside-rules.html
new file mode 100644
index 0000000000..c725752cba
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-outside-rules.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - a selector outside a shadow tree should not match nodes inside the shadow tree</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+
+ div {
+ width: 100%;
+ height: 100%;
+ background: red;
+ content: "FAIL";
+ }
+
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div>FAIL</div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<div></div>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules-no-style-leak.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules-no-style-leak.html
new file mode 100644
index 0000000000..e4d1d15b7b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules-no-style-leak.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - a style rule inside a shadow tree doesn't affect the normal dom</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ }
+ div {
+ width: 100px;
+ height: 100px;
+ background: green;
+ color:green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ </my-host>
+ <div>FAIL</div>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> div { background: red; } </style>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules.html b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules.html
new file mode 100644
index 0000000000..3338ecbf72
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/css-scoping-shadow-with-rules.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - a selector inside a shadow tree is matched against nodes in the shadow tree</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+ <link rel="help" href="http://www.w3.org/TR/css-scoping-1/#selectors-data-model">
+ <link rel="match" href="reference/green-box.html"/>
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ }
+ div {
+ width: 100%; height: 100%; background: red;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ <div>FAIL</div>
+ </my-host>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<div>FAIL</div><style> div {width: 100px; height: 100px; background: green; color:green; } </style>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/host-context-parsing.html b/testing/web-platform/tests/css/css-scoping/host-context-parsing.html
new file mode 100644
index 0000000000..56055ece63
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-context-parsing.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Test parsing of the host-context() pseudo-classes</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectordef-host-context">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+ test_valid_selector(':host-context(.a)');
+ test_valid_selector(':host-context(div.a)');
+
+ test_invalid_selector(':host-context');
+ test_invalid_selector(':host-context()');
+ test_invalid_selector(':host-context(.a, .b)');
+ test_invalid_selector(':host-context(.a + .b)');
+ test_invalid_selector(':host-context(.a + .b, #c > #d)');
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-context-specificity-001.html b/testing/web-platform/tests/css/css-scoping/host-context-specificity-001.html
new file mode 100644
index 0000000000..694087f56b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-context-specificity-001.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: the selector inside :host-context() affects specificity</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ :host-context(#host) {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ :host {
+ background: red;
+ }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-context-specificity-002.html b/testing/web-platform/tests/css/css-scoping/host-context-specificity-002.html
new file mode 100644
index 0000000000..3d4d3e5b24
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-context-specificity-002.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: :host-context() is accounted for during specificity computation</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ .foo span {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ :host-context(*) span {
+ background: green;
+ }
+ </style>
+ <div class="foo"><span></span></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-context-specificity-003.html b/testing/web-platform/tests/css/css-scoping/host-context-specificity-003.html
new file mode 100644
index 0000000000..7abf8847c9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-context-specificity-003.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: the :host-context() selector affects specificity</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ :host-context(*) div {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ div {
+ background: red;
+ }
+ </style>
+ <div></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-descendant-001.html b/testing/web-platform/tests/css/css-scoping/host-descendant-001.html
new file mode 100644
index 0000000000..423beaf055
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-descendant-001.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"><div></div></div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ :host ::slotted(div) { width: 100px; height: 100px; background: green; }
+ * :host ::slotted(div) { background: red; }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-descendant-002.html b/testing/web-platform/tests/css/css-scoping/host-descendant-002.html
new file mode 100644
index 0000000000..6660d4a40c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-descendant-002.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ :host { width: 100px; height: 100px; background: green; }
+ * :host { background: red; }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-descendant-invalidation.html b/testing/web-platform/tests/css/css-scoping/host-descendant-invalidation.html
new file mode 100644
index 0000000000..61ed4bbfc7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-descendant-invalidation.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>CSS Test: element style is correctly updated for rule with :host</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<div id="host"><div id="slotted"></div></div>
+<script>
+test(function() {
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ :host ::slotted(div) { width: 100px; height: 100px; background: red; }
+ :host ::slotted(.foo) { background: green; }
+ </style>
+ <slot></slot>
+ `;
+ assert_equals(getComputedStyle(slotted).backgroundColor, "rgb(255, 0, 0)");
+ host.firstElementChild.classList.add('foo');
+ assert_equals(getComputedStyle(slotted).backgroundColor, "rgb(0, 128, 0)");
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-dom-001.html b/testing/web-platform/tests/css/css-scoping/host-dom-001.html
new file mode 100644
index 0000000000..fff0112b1e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-dom-001.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>CSS Test: :host in DOM APIs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<div id="host"></div>
+<script>
+test(function() {
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `<div></div>`;
+ assert_false(host.matches(":host"), ":host shouldn't match from CSSOM from outside the shadow tree");
+ assert_true(root.firstElementChild.matches(":host div"), ":host should match from within the shadow tree");
+ assert_equals(root.querySelector(":host div"), root.firstElementChild, ":host should match from within the shadow tree");
+})
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-functional-descendant-invalidation.html b/testing/web-platform/tests/css/css-scoping/host-functional-descendant-invalidation.html
new file mode 100644
index 0000000000..b9f1329a95
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-functional-descendant-invalidation.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>CSS Test: element style is correctly updated for rule with :host(..)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<div id="host"><div id="slotted"></div></div>
+<script>
+test(function() {
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ :host ::slotted(div) { width: 100px; height: 100px; background: red; }
+ :host(.foo) ::slotted(div) { background: green; }
+ </style>
+ <slot></slot>
+ `;
+ assert_equals(getComputedStyle(slotted).backgroundColor, "rgb(255, 0, 0)");
+ host.classList.add('foo');
+ assert_equals(getComputedStyle(slotted).backgroundColor, "rgb(0, 128, 0)");
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-is-001.html b/testing/web-platform/tests/css/css-scoping/host-is-001.html
new file mode 100644
index 0000000000..16d0dd7669
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-is-001.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>:host and :is (basic) </title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/selectors/#featureless">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({mode: "open"}).innerHTML = `
+ <style>
+ :is(:host) .nested {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+ </style>
+ <div class="nested"></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-is-002.html b/testing/web-platform/tests/css/css-scoping/host-is-002.html
new file mode 100644
index 0000000000..408dde2987
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-is-002.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>:host and :is (basic)</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/selectors/#featureless">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({mode: "open"}).innerHTML = `
+ <style>
+ :is(:host) {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-is-003.html b/testing/web-platform/tests/css/css-scoping/host-is-003.html
new file mode 100644
index 0000000000..b1958c00ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-is-003.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>:host and :is() (combined with something else)</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/selectors/#featureless">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({mode: "open"}).innerHTML = `
+ <style>
+ .nested {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+ :is(:host(#not-host), #host) .nested {
+ background-color: red;
+ }
+ </style>
+ <div class="nested"></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-is-004.html b/testing/web-platform/tests/css/css-scoping/host-is-004.html
new file mode 100644
index 0000000000..5d12a5b5a7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-is-004.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>:host and :is (combined with something else)</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/selectors/#featureless">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({mode: "open"}).innerHTML = `
+ <style>
+ :host {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+ :is(:host(#not-host), #host) {
+ background-color: red;
+ }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-is-005.html b/testing/web-platform/tests/css/css-scoping/host-is-005.html
new file mode 100644
index 0000000000..1e2209abda
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-is-005.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>:host and :is() (with pseudos)</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/selectors/#featureless">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({mode: "open"}).innerHTML = `
+ <style>
+ :is(:host)::before {
+ display: block;
+ content: "";
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-multiple-001.html b/testing/web-platform/tests/css/css-scoping/host-multiple-001.html
new file mode 100644
index 0000000000..c8833c4b5b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-multiple-001.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>CSS Test: :host multiple times in the same compound selector.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ :host:host { width: 100px; height: 100px; background: green }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-nested-001.html b/testing/web-platform/tests/css/css-scoping/host-nested-001.html
new file mode 100644
index 0000000000..f8e412cc00
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-nested-001.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>CSS Test: :host doesn't match nested shadow hosts.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<style>
+ #host {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">FAIL</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ div {
+ background: green;
+ width: 100px;
+ height: 100px;
+ }
+ :host { background: red !important }
+ div:host { background: red !important }
+ </style>
+ <div id="nested-host">FAIL - nested shadow host</div>
+ `;
+ root.getElementById("nested-host").attachShadow({ mode: "open" });
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-parsing.html b/testing/web-platform/tests/css/css-scoping/host-parsing.html
new file mode 100644
index 0000000000..139433af48
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-parsing.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Test parsing of the :host/host() pseudo-classes</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectordef-host-function">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+ test_valid_selector(':host');
+ test_valid_selector(':host(.a)');
+ test_valid_selector(':host(div.a)');
+
+ test_invalid_selector(':host()');
+ test_invalid_selector(':host(.a, .b)');
+ test_invalid_selector(':host(.a + .b)');
+ test_invalid_selector(':host(.a + .b, #c > #d)');
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-slotted-001.html b/testing/web-platform/tests/css/css-scoping/host-slotted-001.html
new file mode 100644
index 0000000000..f05b7c729f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-slotted-001.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>CSS Test: :host matches while collecting ::slotted rules</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"><div></div></div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>
+ ::slotted(div) { width: 100px; height: 100px; background: red; }
+ :host ::slotted(div) { background: green; }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-specificity-002.html b/testing/web-platform/tests/css/css-scoping/host-specificity-002.html
new file mode 100644
index 0000000000..3132d3a345
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-specificity-002.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: :host is accounted for during specificity computation</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="help" href="https://drafts.csswg.org/selectors/#specificity-rules">
+<link rel="help" href="https://bugzil.la/1454165">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ .foo span {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+ :host span {
+ background: green;
+ }
+ </style>
+ <div class="foo"><span></span></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-specificity-003.html b/testing/web-platform/tests/css/css-scoping/host-specificity-003.html
new file mode 100644
index 0000000000..54a22599d8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-specificity-003.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: the :host() selector affects specificity</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1915">
+<link rel="help" href="https://bugzil.la/1454165">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ :host(*) div {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ div {
+ background: red;
+ }
+ </style>
+ <div></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-specificity.html b/testing/web-platform/tests/css/css-scoping/host-specificity.html
new file mode 100644
index 0000000000..3ef61d4135
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-specificity.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: the selector inside :host() affects specificity</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1915">
+<link rel="help" href="https://bugzil.la/1454165">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ :host(#host) {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ :host {
+ background: red;
+ }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/host-with-default-namespace-001.html b/testing/web-platform/tests/css/css-scoping/host-with-default-namespace-001.html
new file mode 100644
index 0000000000..dcd51f8119
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/host-with-default-namespace-001.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: :host ignores default namespace</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-element-in-tree">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#featureless">
+<link rel="help" href="https://bugzil.la/1546375">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @namespace url(http://www.w3.org/2000/svg);
+ :host { background-color: green; width: 100px; height: 100px; }
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-001.html b/testing/web-platform/tests/css/css-scoping/keyframes-001.html
new file mode 100644
index 0000000000..b0a95ac686
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-001.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<title>CSS Test: @keyframes applies in the shadow tree.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<!--
+ Beware of https://github.com/w3c/csswg-drafts/issues/1995 potentially, but
+ unlikely, changing the expected result of this test.
+-->
+<style>
+#in-document {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+}
+</style>
+<div id="host"><div id="in-document"></div></div>
+<script>
+test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @keyframes myanim {
+ from { background: red; }
+ to { background: green; }
+ }
+ #in-shadow {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+ }
+ </style>
+ <slot></slot>
+ <div id="in-shadow"></div>
+ `;
+
+ assert_equals(document.getElementById('in-document').getAnimations().length, 0);
+ assert_equals(host.shadowRoot.getElementById('in-shadow').getAnimations().length, 1);
+}, "@keyframes applies in the shadow tree")
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-002.html b/testing/web-platform/tests/css/css-scoping/keyframes-002.html
new file mode 100644
index 0000000000..b80b250460
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-002.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>CSS Test: @keyframes from the document don't apply in the shadow tree.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<!--
+ Beware of https://github.com/w3c/csswg-drafts/issues/1995 potentially, but
+ unlikely, changing the expected result of this test.
+-->
+<style>
+@keyframes myanim {
+ from { background: red; }
+ to { background: red; }
+}
+</style>
+<div id="host"></div>
+<script>
+test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ #in-shadow {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+ }
+ </style>
+ <div id="in-shadow"></div>
+ `;
+
+ assert_equals(host.shadowRoot.getElementById('in-shadow').getAnimations().length, 0);
+}, "@keyframes from the document don't apply in the shadow tree");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-003.html b/testing/web-platform/tests/css/css-scoping/keyframes-003.html
new file mode 100644
index 0000000000..2e1d799bd0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-003.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>CSS Test: @keyframes applies to :host.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<div id="host"></div>
+<script>
+ test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @keyframes myanim {
+ from { background: red; }
+ to { background: green; }
+ }
+ :host {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+ }
+ </style>
+ `;
+
+ assert_equals(document.getElementById('host').getAnimations().length, 1);
+ }, "@keyframes applies to the shadow host");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-004.html b/testing/web-platform/tests/css/css-scoping/keyframes-004.html
new file mode 100644
index 0000000000..2dee8c2e64
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-004.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>CSS Test: @keyframes applies to ::slotted.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<div id="host"><div id="in-document"></div></div>
+<script>
+ test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @keyframes myanim {
+ from { background: red; }
+ to { background: green; }
+ }
+ ::slotted(#in-document) {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+ }
+ </style>
+ <slot></slot>
+ `;
+
+ assert_equals(document.getElementById('in-document').getAnimations().length, 1);
+ }, "@keyframes in shadow tree applies to the slotted element");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-005.html b/testing/web-platform/tests/css/css-scoping/keyframes-005.html
new file mode 100644
index 0000000000..d9026d2f6a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-005.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>CSS Test: @keyframes should not leak out of shadow tree.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<style>
+ #host {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite;
+ }
+</style>
+<div id="host"></div>
+<script>
+ test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @keyframes myanim {
+ from { background: red; }
+ to { background: green; }
+ }
+ </style>
+ `;
+
+ assert_equals(document.getElementById('host').getAnimations().length, 0);
+ }, "@keyframes should not leak out of the shadow tree.");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/keyframes-006.html b/testing/web-platform/tests/css/css-scoping/keyframes-006.html
new file mode 100644
index 0000000000..79c39a14ac
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/keyframes-006.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>CSS Test: @keyframes applies to :host::before/::after.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<div id="host"></div>
+<script>
+ test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @keyframes myanim {
+ from { background: red; }
+ to { background: green; }
+ }
+ :host::before, :host::after {
+ content: "";
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: blue;
+ animation: myanim 10s infinite step-end;
+ }
+ </style>
+ `;
+
+ assert_equals(getComputedStyle(document.getElementById('host'), "::before").backgroundColor, "rgb(255, 0, 0)");
+ assert_equals(getComputedStyle(document.getElementById('host'), "::after").backgroundColor, "rgb(255, 0, 0)");
+ }, "@keyframes applies to the shadow host");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/reference/green-box.html b/testing/web-platform/tests/css/css-scoping/reference/green-box.html
new file mode 100644
index 0000000000..24b5e0d5f5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/reference/green-box.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping Module Level 1 - A green box reference</title>
+ <link rel="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
+</head>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/reference/green-text.html b/testing/web-platform/tests/css/css-scoping/reference/green-text.html
new file mode 100644
index 0000000000..95736b4484
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/reference/green-text.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>CSS Test: Reference</title>
+<p style="color:green">This text should be green.</p>
diff --git a/testing/web-platform/tests/css/css-scoping/reslot-text-inheritance.html b/testing/web-platform/tests/css/css-scoping/reslot-text-inheritance.html
new file mode 100644
index 0000000000..43711c83bd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/reslot-text-inheritance.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>CSS Test: Re-slotted text node inheritance</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="match" href="reference/green-text.html">
+<script src="/common/reftest-wait.js"></script>
+<p id="host">This text should be green.</p>
+<script>
+ const root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot style="color:green" name="no-match"></slot>
+ <slot style="color:red"></slot>
+ `;
+ host.offsetTop;
+ root.querySelector("slot").removeAttribute("name");
+ takeScreenshot();
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/resources/host-green-box.css b/testing/web-platform/tests/css/css-scoping/resources/host-green-box.css
new file mode 100644
index 0000000000..a77b3fdc64
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/resources/host-green-box.css
@@ -0,0 +1,5 @@
+:host {
+ background: green;
+ width: 100px;
+ height: 100px;
+}
diff --git a/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-001.html b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-001.html
new file mode 100644
index 0000000000..891bda52a3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-001.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Tests animation with tree-scoped names and references</title>
+<meta name="assert" content="Custom counter style references should work in keyframes">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<link rel="match" href="scoped-reference-animation-ref.html">
+
+<style>
+/* Overrides predefined lower-roman counter-style */
+@counter-style lower-roman {
+ system: cyclic;
+ symbols: 'X';
+}
+
+/* Overrides predefined upper-roman counter-style */
+@counter-style upper-roman {
+ system: cyclic;
+ symbols: 'O';
+}
+
+/* Should resolve to the custom counter styles, not the predefined ones */
+@keyframes list-style-type-anim {
+ from { list-style-type: lower-roman; }
+ to { list-style-type: upper-roman; }
+}
+
+#target1 {
+ animation: list-style-type-anim 2s -0.9s linear paused;
+}
+
+#target2 {
+ animation: list-style-type-anim 2s -1s linear paused;
+}
+</style>
+
+<ul id="target1">
+ <li>List marker should be X
+</ul>
+
+<ul id="target2">
+ <li>List marker should be O
+</ul>
diff --git a/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-002.html b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-002.html
new file mode 100644
index 0000000000..d5c25f06c0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-002.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Tests animation with tree-scoped names and references</title>
+<meta name="assert" content="Custom counter style references should work in shadow DOM keyframes">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<link rel="match" href="scoped-reference-animation-ref.html">
+
+<style>
+@counter-style lower-roman { system: extends disc; }
+@counter-style upper-roman { system: extends disc; }
+</style>
+
+<div id="host">
+</div>
+
+<script>
+host.attachShadow({mode: 'open'}).innerHTML = `
+<style>
+/* Overrides predefined and outer tree scope's custom lower-roman counter-style */
+@counter-style lower-roman {
+ system: cyclic;
+ symbols: 'X';
+}
+
+/* Overrides predefined and outer tree scope's upper-roman counter-style */
+@counter-style upper-roman {
+ system: cyclic;
+ symbols: 'O';
+}
+
+/* Should resolve to the custom counter styles, not the predefined or the outer
+ tree scope's ones */
+@keyframes list-style-type-anim {
+ from { list-style-type: lower-roman; }
+ to { list-style-type: upper-roman; }
+}
+
+#target1 {
+ animation: list-style-type-anim 2s -0.9s linear paused;
+}
+
+#target2 {
+ animation: list-style-type-anim 2s -1s linear paused;
+}
+</style>
+
+<ul id="target1">
+ <li>List marker should be X
+</ul>
+
+<ul id="target2">
+ <li>List marker should be O
+</ul>
+`;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-ref.html b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-ref.html
new file mode 100644
index 0000000000..9f407eb690
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/scoped-reference-animation-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Tests animation with tree-scoped names and references</title>
+
+<style>
+@counter-style from-counter-style {
+ system: cyclic;
+ symbols: 'X';
+}
+
+@counter-style to-counter-style {
+ system: cyclic;
+ symbols: 'O';
+}
+
+#target1 {
+ list-style-type: from-counter-style;
+}
+
+#target2 {
+ list-style-type: to-counter-style;
+}
+</style>
+
+<ul id="target1">
+ <li>List marker should be X
+</ul>
+
+<ul id="target2">
+ <li>List marker should be O
+</ul>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-assign-dynamic-001.html b/testing/web-platform/tests/css/css-scoping/shadow-assign-dynamic-001.html
new file mode 100644
index 0000000000..b9a0d1a299
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-assign-dynamic-001.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Scoping Module Level 1 - Dynamic mutations to both shadow root and shadow host subtrees</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="help" href="https://bugzil.la/1303605">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<style>
+ #host {
+ width: 100px;
+ height: 100px;
+ background: red;
+ }
+
+ #host > div {
+ width: 100px;
+ height: 50px;
+ background: green;
+ }
+</style>
+<div id="host"></div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ document.body.offsetTop;
+
+ root.innerHTML = `<slot name="slot1"></slot><slot name="slot2"></slot>`;
+ host.innerHTML = `<div slot="slot1"></div><div slot="slot2"></div>`;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-at-import.html b/testing/web-platform/tests/css/css-scoping/shadow-at-import.html
new file mode 100644
index 0000000000..1adf516311
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-at-import.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>CSS Test: @import in Shadow DOM</title>
+<link rel="help" href="https://drafts.csswg.org/css-cascade/#at-import">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">FAIL</div>
+<script>
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ @import url("resources/host-green-box.css");
+ </style>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-cascade-order-001.html b/testing/web-platform/tests/css/css-scoping/shadow-cascade-order-001.html
new file mode 100644
index 0000000000..59b71b0ee1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-cascade-order-001.html
@@ -0,0 +1,403 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Shadow DOM: CSS Style Rule cascading</title>
+<meta name="assert" content="Cascading order test for style rules from various shadow trees.">
+<link rel="author" title="Takayoshi Kochi" href="mailto:kochi@google.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping-1/#shadow-cascading">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+// Taken from the example in
+// https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Shadow-DOM-Cascade-Order.md
+// https://github.com/w3c/webcomponents/issues/316
+// https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Shadow-DOM-Cascade-Order-in-v1.md
+// with element renamed and style rule location changed.
+//
+// <style>my-item { color: red; }</style>
+// <my-list>
+// <:shadow>
+// <style>::slotted(my-item) { color: blue; }</style>
+// <slot></slot>
+// </:shadow>
+// <my-item style="color: green;">
+// <:shadow>
+// <style>:host { color: yellow; }</style>
+// <slot></slot>
+// </:shadow>
+// ITEM
+// </my-item>
+// </my-list>
+//
+// There are 4 possible style rules that applies to <my-item> above:
+// 1. document-wide style
+// 2. ::slotted style in the shadow in <my-list>
+// 3. :host style in the shadow in <my-item>
+// 4. inline style within <my-item> itself.
+//
+// It could be possible to nest many more shadow trees in <my-list>,
+// but to prevent the number of combination explosion, such case is covered
+// in another test file.
+//
+// So testing cases where 2 style rules are competing,
+// 4C2 = 6 combinations exist, multiplied by 4, which is the possible
+// combination of applying "!important" for the 2 style rules.
+
+function createMyList(mode, slottedStyle, hostStyle, inlineStyle) {
+ var myList = document.createElement('my-list');
+ var root = myList.attachShadow({'mode': mode});
+ root.innerHTML = '<style>' + slottedStyle + '</style><slot></slot>';
+ var myItem = document.createElement('my-item');
+ if (inlineStyle !== '')
+ myItem.setAttribute('style', inlineStyle);
+ myList.appendChild(myItem);
+ var root2 = myItem.attachShadow({'mode': mode});
+ root2.innerHTML = '<style>' + hostStyle + '</style><slot></slot>';
+ myItem.appendChild(document.createTextNode('ITEM'));
+ return myList;
+}
+
+function testCascadingOrder(mode) {
+ // In all test cases, the rule specified as "color: green" should win.
+ var testCases = [
+ // [A] Cases between document, ::slotteed, :host, and inline
+ {
+ title: 'A1. document vs ::slotted, document rule should win',
+ documentStyle: 'my-item { color: green; }',
+ slottedStyle: '::slotted(my-item) { color: red; }',
+ hostStyle: '',
+ inlineStyle: ''
+ },
+ {
+ title: 'A2. document vs :host, document rule should win',
+ documentStyle: 'my-item { color: green; }',
+ slottedStyle: '',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'A3. document vs inline, inline rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle: '',
+ hostStyle: '',
+ inlineStyle: 'color: green;'
+ },
+ {
+ title: 'A4. ::slotted vs :host, earlier in tree-of-trees rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green; }',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'A5. ::slotted vs inline, inline rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: red; }',
+ hostStyle: '',
+ inlineStyle: 'color: green;'
+ },
+ {
+ title: 'A6. :host vs inline, inline rule should win',
+ documentStyle: '',
+ slottedStyle: '',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: 'color: green;'
+ },
+
+ // [B] Stronger rule is still stronger with !important
+ {
+ title: 'B1. document with !important vs ::slotted, document rule should win',
+ documentStyle: 'my-item { color: green !important; }',
+ slottedStyle: '::slotted(my-item) { color: red; }',
+ hostStyle: '',
+ inlineStyle: ''
+ },
+ {
+ title: 'B2. document with !important vs :host, document rule should win',
+ documentStyle: 'my-item { color: green !important; }',
+ slottedStyle: '',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'B3. document vs inline with !important, inline rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle: '',
+ hostStyle: '',
+ inlineStyle: 'color: green !important;'
+ },
+ {
+ title: 'B4. ::slotted with !important vs :host, earlier in tree-of-trees rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'B5. ::slotted vs inline with !important, inline rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: '',
+ inlineStyle: 'color: red;'
+ },
+ {
+ title: 'B6. :host vs inline with !important, inline rule should win',
+ documentStyle: '',
+ slottedStyle: '',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: 'color: green !important;'
+ },
+
+ // [C] Weaker rule gets stronger with !important
+ {
+ title: 'C1. document vs ::slotted with !important, ::slotted rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: '',
+ inlineStyle: ''
+ },
+ {
+ title: 'C2. document vs :host with !important, :host rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle: '',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'C3. document with !important vs inline, document rule should win',
+ documentStyle: 'my-item { color: green !important; }',
+ slottedStyle: '',
+ hostStyle: '',
+ inlineStyle: 'color: red;'
+ },
+ {
+ title: 'C4. ::slotted vs :host with !important, later in tree-of-trees rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: ':host { color: red; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'C5. ::slotted with !important vs inline, ::slotted rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: '',
+ inlineStyle: 'color: red;'
+ },
+ {
+ title: 'C6. :host with !important vs inline, :host rule should win',
+ documentStyle: '',
+ slottedStyle: '',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: 'color: red;'
+ },
+
+ // [D] Cases between document, ::slotteed, :host, and inline, both with !important
+ {
+ title: 'D1. document vs ::slotted both with !important, ::slotted rule should win',
+ documentStyle: 'my-item { color: red !important; }',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: '',
+ inlineStyle: ''
+ },
+ {
+ title: 'D2. document vs :host both with !important, :host rule should win',
+ documentStyle: 'my-item { color: red !important; }',
+ slottedStyle: '',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'D3. document vs inline both with !important, inline rule should win',
+ documentStyle: 'my-item { color: red !important; }',
+ slottedStyle: '',
+ hostStyle: '',
+ inlineStyle: 'color: green !important;'
+ },
+ {
+ title: 'D4. ::slotted vs :host both with !important, later in tree-of-trees rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: red !important; }',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: ''
+ },
+ {
+ title: 'D5. ::slotted vs inline both with !important, ::slotted rule should win',
+ documentStyle: '',
+ slottedStyle: '::slotted(my-item) { color: green !important; }',
+ hostStyle: '',
+ inlineStyle: 'color: red !important;'
+ },
+ {
+ title: 'D6. :host vs inline both with !important, :host rule should win',
+ documentStyle: '',
+ slottedStyle: '',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: 'color: red !important;'
+ },
+ // [E] Putting all together
+ {
+ title: 'E1. all style applied, inline rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle: '::slotted(my-item) { color: blue; }',
+ hostStyle: ':host { color: yellow; }',
+ inlineStyle: 'color: green;'
+ },
+ {
+ title: 'E2. all styles with !important applied, rule in the last tree-of-trees should win',
+ documentStyle: 'my-item { color: red !important; }',
+ slottedStyle: '::slotted(my-item) { color: blue !important; }',
+ hostStyle: ':host { color: green !important; }',
+ inlineStyle: 'color: yellow !important;'
+ },
+ ];
+
+ for (var i = 0; i < testCases.length; ++i) {
+ var testCase = testCases[i];
+ var documentStyle = document.createElement('style');
+ documentStyle.appendChild(document.createTextNode(testCase['documentStyle']));
+ document.head.appendChild(documentStyle);
+
+ var myList = createMyList(mode,
+ testCase['slottedStyle'], testCase['hostStyle'], testCase['inlineStyle']);
+ document.body.appendChild(myList);
+
+ test(function () {
+ var myItem = myList.querySelector('my-item');
+ assert_equals(window.getComputedStyle(myItem).color, 'rgb(0, 128, 0)',
+ testCase['title']);
+ }, testCase['title'] + ' for ' + mode + ' mode.');
+
+ myList.parentNode.removeChild(myList);
+ document.head.removeChild(documentStyle)
+ }
+}
+
+// Open or Closed should not make any difference in style application.
+testCascadingOrder('open');
+testCascadingOrder('closed');
+
+
+// Taken from the example in
+// https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Shadow-DOM-Cascade-Order.md
+// https://github.com/w3c/webcomponents/issues/316
+// https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Shadow-DOM-Cascade-Order-in-v1.md
+// with element renamed and style rule location changed.
+//
+// <style>my-item { color: red; }</style>
+// <my-list>
+// <:shadow>
+// <style>::slotted(my-item) { color: blue; }</style>
+// <div>
+// <:shadow>
+// <slot/>
+// </:shadow>
+// <slot/>
+// </div>
+// </:shadow>
+// <my-item style="color: green;">
+// <:shadow>
+// <style>:host { color: yellow; }</style>
+// <slot/>
+// </:shadow>
+// ITEM
+// </my-item>
+// </my-list>
+//
+// The difference from the example tree above is that <my-list> has 2 levels of
+// shadow trees, each with ::slotted(my-list) style rules.
+
+function createMyListWith2LevelShadow(mode, slottedStyle1, slottedStyle2, hostStyle) {
+ var myList = document.createElement('my-list');
+ var root = myList.attachShadow({'mode': mode});
+ root.innerHTML = '<style>' + slottedStyle1 + '</style><div><slot></slot></div>';
+ var div = root.querySelector('div');
+ var root2 = div.attachShadow({'mode': mode});
+ root2.innerHTML = '<style>' + slottedStyle2 + '</style><slot></slot>';
+ var myItem = document.createElement('my-item');
+ myList.appendChild(myItem);
+ var root3 = myItem.attachShadow({'mode': mode});
+ root3.innerHTML = '<style>' + hostStyle + '</style><slot></slot>';
+ myItem.appendChild(document.createTextNode('ITEM'));
+ return myList;
+}
+
+function testCascadingOrderWith2LevelShadow(mode) {
+ // In all test cases, the rule specified as "color: green" should win.
+ var testCases = [
+ {
+ title: 'F1. document vs others, document (the first rule in tree-of-trees order) rule should win',
+ documentStyle: 'my-item { color: green; }',
+ slottedStyle1: '::slotted(my-item) { color: red; }',
+ slottedStyle2: '::slotted(my-item) { color: red; }',
+ hostStyle: ':host { color: red; }',
+ },
+ {
+ title: 'F2. document with !important vs others, document rule should win',
+ documentStyle: 'my-item { color: green !important; }',
+ slottedStyle1: '::slotted(my-item) { color: red; }',
+ slottedStyle2: '::slotted(my-item) { color: red; }',
+ hostStyle: ':host { color: red; }',
+ },
+ {
+ title: 'F3. document vs ::slotted with !important, important rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle1: '::slotted(my-item) { color: green !important; }',
+ slottedStyle2: '::slotted(my-item) { color: red; }',
+ hostStyle: ':host { color: red; }',
+ },
+ {
+ title: 'F4. document vs ::slotted with !important, important rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle1: '::slotted(my-item) { color: red; }',
+ slottedStyle2: '::slotted(my-item) { color: green !important; }',
+ hostStyle: ':host { color: red; }',
+ },
+ {
+ title: 'F5. document vs :host with !important, important rule should win',
+ documentStyle: 'my-item { color: red; }',
+ slottedStyle1: '::slotted(my-item) { color: red; }',
+ slottedStyle2: '::slotted(my-item) { color: red; }',
+ hostStyle: ':host { color: green !important; }',
+ },
+ {
+ title: 'F6. all rules with !important, the last rule in tree-of-trees should win',
+ documentStyle: 'my-item { color: red !important; }',
+ slottedStyle1: '::slotted(my-item) { color: red !important; }',
+ slottedStyle2: '::slotted(my-item) { color: red !important; }',
+ hostStyle: ':host { color: green !important ; }',
+ }
+ ];
+
+ for (var i = 0; i < testCases.length; ++i) {
+ var testCase = testCases[i];
+ var documentStyle = document.createElement('style');
+ documentStyle.appendChild(document.createTextNode(testCase['documentStyle']));
+ document.head.appendChild(documentStyle);
+
+ var myList = createMyListWith2LevelShadow(mode,
+ testCase['slottedStyle1'], testCase['slottedStyle2'], testCase['hostStyle']);
+ document.body.appendChild(myList);
+
+ test(function () {
+ var myItem = myList.querySelector('my-item');
+ assert_equals(window.getComputedStyle(myItem).color, 'rgb(0, 128, 0)',
+ testCase['title']);
+ }, testCase['title'] + ' for ' + mode + ' mode.');
+
+ myList.parentNode.removeChild(myList);
+ document.head.removeChild(documentStyle)
+ }
+}
+
+// Open or Closed should not make any difference in style application.
+testCascadingOrderWith2LevelShadow('open');
+testCascadingOrderWith2LevelShadow('closed');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-directionality-001.tentative.html b/testing/web-platform/tests/css/css-scoping/shadow-directionality-001.tentative.html
new file mode 100644
index 0000000000..7070d2a1d9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-directionality-001.tentative.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>CSS Test: directionality propagation in Shadow DOM.</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="match" href="reference/green-box.html">
+<style>
+ div { width: 100px; }
+</style>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host1"></div>
+<div id="host2" dir="rtl"></div>
+<div id="host3"></div>
+<div id="host4" dir="rtl"></div>
+<script>
+ host1.attachShadow({ mode: "open" }).innerHTML = `
+ <style>:dir(ltr) { background: green; height: 25px; }</style>
+ <div></div>
+ `;
+ host2.attachShadow({ mode: "open" }).innerHTML = `
+ <style>:dir(rtl) { background: green; height: 25px; }</style>
+ <div></div>
+ `;
+ host3.attachShadow({ mode: "open" }).innerHTML = `
+ <style>:dir(rtl) { background: green; height: 25px; }</style>
+ <div></div>
+ `;
+ host4.attachShadow({ mode: "open" }).innerHTML = `
+ <style>span:dir(ltr) { display: block; background: green; height: 25px; }</style>
+ <div dir="ltr"><span></span></div>
+ `;
+ document.body.offsetTop;
+ host3.setAttribute("dir", "rtl");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-directionality-002.tentative.html b/testing/web-platform/tests/css/css-scoping/shadow-directionality-002.tentative.html
new file mode 100644
index 0000000000..6aba12436a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-directionality-002.tentative.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>CSS Test: directionality propagation in Shadow DOM, appending a shadow host.</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<style>
+ div { width: 100px; }
+</style>
+<div id="host-parent" dir="rtl"></div>
+<script>
+ let host = document.createElement("div");
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>:dir(rtl) { background: green; height: 100px; width: 100px; }</style>
+ <div></div>
+ `;
+ document.getElementById("host-parent").appendChild(host);
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-disabled-sheet-001.html b/testing/web-platform/tests/css/css-scoping/shadow-disabled-sheet-001.html
new file mode 100644
index 0000000000..275ac47a61
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-disabled-sheet-001.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Disabled stylesheet dynamically</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ let root = host.attachShadow({ mode: 'open' });
+ root.innerHTML = `
+ <style>
+ div { background: green; width: 100px; height: 100px; }
+ </style>
+ <style>
+ div { background: red; }
+ </style>
+ <div></div>
+ `;
+ document.body.offsetTop;
+ root.styleSheets[1].disabled = true;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-001.html b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-001.html
new file mode 100644
index 0000000000..9a5672eb63
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-001.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic fallback content</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">
+ <span slot="myslot">FAIL</span>
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <slot name="myslot">
+ <div style="width: 100px; height: 100px; background: green"></div>
+ </slot>
+ `;
+ document.body.offsetTop;
+ host.firstElementChild.remove();
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-002.html b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-002.html
new file mode 100644
index 0000000000..f65d0c7a21
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-002.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic fallback content</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">
+ <span slot="myslot">FAIL</span>
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <slot name="myslot">
+ <div style="width: 100px; height: 100px; background: green"></div>
+ </slot>
+ `;
+ document.body.offsetTop;
+ host.firstElementChild.removeAttribute("slot");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-003.html b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-003.html
new file mode 100644
index 0000000000..a30e8fed7d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-003.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic fallback content</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <slot name="myslot">FAIL</slot>
+ `;
+ document.body.offsetTop;
+ host.innerHTML = `
+ <div slot="myslot" style="width: 100px; height: 100px; background: green"></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html
new file mode 100644
index 0000000000..29e407573a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic fallback content</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">
+ <div slot="myslot" style="width: 100px; height: 100px; background: green"></div>
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <slot name="myslot"></slot>
+ `;
+ document.body.offsetTop;
+ let newSlot = document.createElement('slot');
+ newSlot.appendChild(document.createTextNode("FAIL"));
+ newSlot.setAttribute("name", "myslot");
+ root.insertBefore(newSlot, root.firstChild);
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-005.html b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-005.html
new file mode 100644
index 0000000000..1d84907e5f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-005.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic fallback content</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">
+ <div slot="myslot" style="width: 100px; height: 100px; background: green"></div>
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <slot name="myslot"></slot>
+ <slot name="myotherslot">
+ FAIL
+ </slot>
+ `;
+ document.body.offsetTop;
+ host.firstElementChild.setAttribute("slot", "myotherslot");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-host-removal-invalidation.html b/testing/web-platform/tests/css/css-scoping/shadow-host-removal-invalidation.html
new file mode 100644
index 0000000000..6daa635fa6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-host-removal-invalidation.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>CSS Test: Invalidation of :host selectors</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#host-selector">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499603">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host" style="color: green"></div>
+<script>
+host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ :host { color: red !important }
+ </style>
+`;
+test(function() {
+ assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)");
+ host.shadowRoot.querySelector("style").remove();
+ assert_equals(getComputedStyle(host).color, "rgb(0, 128, 0)");
+}, ":host rules are properly invalidated when stylesheets are removed");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-host-with-before-after.html b/testing/web-platform/tests/css/css-scoping/shadow-host-with-before-after.html
new file mode 100644
index 0000000000..87e1554f15
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-host-with-before-after.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<title>CSS Test: Pseudo-elements and :host selector.</title>
+<link rel="author" title="Antti Koivisto" href="mailto:koivisto@iki.fi"/>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"/>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<style>
+.test {
+ width: 100px;
+ height: 25px;
+ background: red;
+ color: red;
+}
+#host1, #host2 {
+ color: green;
+}
+#host3 div, #host4 div {
+ width: 50%;
+ height: 100%;
+ background: green;
+ display: inline-block;
+}
+</style>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host1" class="test"></div>
+<div id="host2" class="test"></div>
+<div id="host3" class="test"><div>text</div></div>
+<div id="host4" class="test"><div>text</div></div>
+<script>
+
+host1.attachShadow({mode: 'closed'}).innerHTML = `<style>
+ :host::before, :host::after {
+ width: 50%;
+ height: 100%;
+ background: green;
+ display: inline-block;
+ content: "test";
+ }
+ </style>`;
+
+host2.attachShadow({mode: 'closed'}).innerHTML = `<style>
+ :host(.green)::before, :host(.green)::after {
+ width: 50%;
+ height: 100%;
+ background: green;
+ display: inline-block;
+ content: "test";
+ }
+ </style>`;
+
+getComputedStyle(host2).backgroundColor;
+host2.classList.add('green');
+
+host3.attachShadow({mode: 'closed'}).innerHTML = `<style>
+ :host {
+ color: green !important;
+ }
+ :host::before {
+ width: 50%;
+ height: 100%;
+ background: green;
+ display: inline-block;
+ content: "test";
+ }
+ </style><slot></slot>`;
+
+host4.attachShadow({mode: 'closed'}).innerHTML = `<style>
+ :host(.green) {
+ color: green !important;
+ }
+ :host(.green)::after {
+ width: 50%;
+ height: 100%;
+ background: green;
+ display: inline-block;
+ content: "test";
+ }
+ </style><slot></slot>`;
+
+getComputedStyle(host4).backgroundColor;
+host4.classList.add('green');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html b/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html
new file mode 100644
index 0000000000..8ca69ccd1b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM doesn't affect the normal DOM</title>
+<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<style>
+ #light-dom {
+ width: 100px;
+ height: 100px;
+ background: green;
+ color: green;
+ }
+</style>
+<div id="host">FAIL</div>
+<div id="light-dom"></div>
+<script>
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <link rel="stylesheet" href="data:text/css,div { background: red !important }">
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet.html b/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet.html
new file mode 100644
index 0000000000..d67929a1ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-link-rel-stylesheet.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test: &lt;link rel="stylesheet"&gt; in Shadow DOM</title>
+<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host">FAIL</div>
+<script>
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <link rel="stylesheet" href="resources/host-green-box.css">
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-multiple-links.html b/testing/web-platform/tests/css/css-scoping/shadow-multiple-links.html
new file mode 100644
index 0000000000..d1c4fd9eb7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-multiple-links.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>CSS Test: ShadowRoot with multiple sheet links with the same href shouldn't crash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<div id="host"></div>
+<script>
+test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <link rel="stylesheet" href="data:text/css,">
+ <link rel="stylesheet" href="data:text/css,">
+ `;
+}, "Multiple stylesheets with the same href in a ShadowRoot should not assert or crash");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-001.html b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-001.html
new file mode 100644
index 0000000000..e8fe49ac96
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: Dynamic reassignment of a slot.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435632">
+<link rel="match" href="reference/green-box.html"/>
+<div id="host">
+ <div id="green" style="background: green"></div>
+ <div id="red" style="background: red" slot="myslot"></div>
+</div>
+<script>
+ let root = host.attachShadow({ mode: "open" });
+ root.innerHTML = `
+ <style>::slotted(div) { width: 100px; height: 100px }</style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <slot name="myslot">FAIL</slot>
+ `;
+ document.body.offsetTop;
+ green.setAttribute("slot", "myslot");
+ red.removeAttribute("slot");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-002.html b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-002.html
new file mode 100644
index 0000000000..7874e2e139
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-002.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: Dynamic reassignment of a slot.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1465572">
+<link rel="match" href="reference/green-box.html"/>
+<div id="host">
+ FAIL
+ <div style="background: green" slot="the-slot"></div>
+</div>
+<script>
+ document.body.offsetTop;
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>::slotted(div) { width: 100px; height: 100px }</style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <slot>FAIL</slot>
+ `;
+ document.body.offsetTop;
+ host.shadowRoot.querySelector("slot").setAttribute("name", "the-slot");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-003.html b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-003.html
new file mode 100644
index 0000000000..bc6392176e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-003.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slots-in-shadow-tree">
+<div id="host"><span id="slotted">This text should be green.</span></div>
+<script>
+ const root = host.attachShadow({mode:"open"});
+ root.innerHTML = '<slot name="nomatch" style="color:green"></slot><slot style="color:red"></slot>';
+
+ test(() => {
+ assert_equals(getComputedStyle(slotted).color, "rgb(255, 0, 0)");
+ }, "Initial computed color.");
+
+ test(() => {
+ root.querySelector("slot").removeAttribute("name");
+ assert_equals(getComputedStyle(slotted).color, "rgb(0, 128, 0)");
+
+ }, "Computed color after re-slotting.");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-004.html b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-004.html
new file mode 100644
index 0000000000..6c2beadc36
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-004.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: Dynamic reassignment of a slot.</title>
+<link rel="author" title="Edgar Chen" href="mailto:echen@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1548848">
+<link rel="match" href="reference/green-box.html"/>
+<div id="host">
+ <div id="green" style="background: green"></div>
+<div>
+<script>
+ let root = host.attachShadow({mode: 'open'});
+ root.innerHTML = `
+ <style>::slotted(div),div { width: 100px; height: 100px }</style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <slot id="slot"></slot>
+ <slot>
+ <div style="background: red"></div>
+ </slot>
+ `;
+
+ onload = function () {
+ root.offsetTop; // Update layout
+ root.getElementById('slot').remove();
+ };
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-root-insert-into-document.html b/testing/web-platform/tests/css/css-scoping/shadow-root-insert-into-document.html
new file mode 100644
index 0000000000..a3b89be389
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-root-insert-into-document.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Scoping Module Level 1 - Dynamic insertion of shadow host</title>
+<link rel="author" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<script>
+ let host = document.createElement('div');
+ let root = host.attachShadow({ mode: 'open' });
+ root.innerHTML = `
+ <style>
+ div { background: green; width: 100px; height: 100px; }
+ </style>
+ <div></div>
+ `;
+ document.body.offsetTop;
+ document.body.appendChild(host);
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/shadow-shared-style-cache-001.html b/testing/web-platform/tests/css/css-scoping/shadow-shared-style-cache-001.html
new file mode 100644
index 0000000000..e80b4d1c42
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-shared-style-cache-001.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Shared style invalidation with removals</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1707116">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host-1"></div>
+<div id="host-2"></div>
+<script>
+const INITIALLY_COMMON_STYLE = `<style>:host { background-color: red !important }</style>`;
+let helper = document.querySelector("#host-1");
+let host = document.querySelector("#host-2");
+
+test(function() {
+ helper.attachShadow({ mode: "open" }).innerHTML = INITIALLY_COMMON_STYLE;
+ assert_equals(getComputedStyle(helper).backgroundColor, "rgb(255, 0, 0)", "Common style should apply to helper");
+
+ host.attachShadow({ mode: "open" }).innerHTML = INITIALLY_COMMON_STYLE;
+ assert_equals(getComputedStyle(host).backgroundColor, "rgb(255, 0, 0)", "Common style should apply to host");
+
+ host.shadowRoot.innerHTML = `<style>:host { background-color: lime; width: 100px; height: 100px; }</style>`;
+ assert_equals(getComputedStyle(host).backgroundColor, "rgb(0, 255, 0)", "Common style should no longer apply to host");
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slot-non-html-display-value.html b/testing/web-platform/tests/css/css-scoping/slot-non-html-display-value.html
new file mode 100644
index 0000000000..2f56254a7d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slot-non-html-display-value.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>CSS Test: non-HTML slot elements don't get display: contents by default.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slots-in-shadow-tree">
+<link rel="help" href="https://bugzil.la/1468127">
+<body>
+<script>
+test(function() {
+ const non_html_slot = document.createElementNS("http://www.w3.org/2000/svg", "slot");
+ document.body.appendChild(non_html_slot);
+ const display = getComputedStyle(non_html_slot).display;
+ // contents would get turned to "none" due to https://drafts.csswg.org/css-display/#unbox-svg
+ assert_true(display != "contents" && display != "none");
+}, "Non-HTML slot elements shouldn't be display: contents by default.");
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-invalidation.html b/testing/web-platform/tests/css/css-scoping/slotted-invalidation.html
new file mode 100644
index 0000000000..f8471062e1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-invalidation.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<title>CSS Test: Style invalidation for ::slotted()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<div id="host">
+ <div>
+ <span></span>
+ <span></span>
+ </div>
+ <div id="slotted">
+ <span></span>
+ <span></span>
+ </div>
+ <div>
+ <span></span>
+ <span></span>
+ </div>
+</div>
+<script>
+test(function() {
+ var root = host.attachShadow({"mode":"open"});
+ root.innerHTML = '<style>.outer ::slotted(#slotted) { background-color: red } .outer .inner::slotted(#slotted) { background-color: green }</style><div id="outer"><slot id="inner"></slot></div>';
+
+ assert_equals(window.getComputedStyle(slotted).backgroundColor, "rgba(0, 0, 0, 0)");
+
+ root.querySelector("#outer").className = "outer";
+ assert_equals(window.getComputedStyle(slotted).backgroundColor, "rgb(255, 0, 0)");
+
+ root.querySelector("#inner").className = "inner";
+ assert_equals(window.getComputedStyle(slotted).backgroundColor, "rgb(0, 128, 0)");
+})
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-link.html b/testing/web-platform/tests/css/css-scoping/slotted-link.html
new file mode 100644
index 0000000000..c06c96143b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-link.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: ::slotted :link</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host"><a id="a" href="#notvisited">This link should be green.</a></div>
+<script>
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <style>
+ ::slotted(:link) { color:green }
+ ::slotted(:visited) { color:red }
+ </style>
+ <slot></slot>`;
+
+ test(() => {
+ assert_equals(getComputedStyle(a).color, "rgb(0, 128, 0)", "Unvisited link should be green.");
+ }, "Check that we match :link and not :visited for slotted anchor.");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-matches.html b/testing/web-platform/tests/css/css-scoping/slotted-matches.html
new file mode 100644
index 0000000000..1a582fe98d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-matches.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>CSS Test: ::slotted() should not match via the matches() API, since it's in the wrong scope</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-element-matches">
+<link rel="help" href="https://bugzil.la/1544242">
+<div id="host"><div id="slotted"></div></div>
+<script>
+test(function() {
+ let slotted = document.getElementById("slotted");
+ host.attachShadow({ mode: "open" }).innerHTML = `<slot></slot>`;
+ assert_false(slotted.matches("::slotted(div)"), "Shouldn't match ::slotted from the outer tree")
+}, "::slotted() doesn't reveal the presence of shadow DOM via matches()");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-nested.html b/testing/web-platform/tests/css/css-scoping/slotted-nested.html
new file mode 100644
index 0000000000..c7139fea4c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-nested.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<link rel="href" href="https://mozilla.org" title="Mozilla">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host"><p>This text should be green</p></div>
+<script>
+ let shadow = host.attachShadow({ mode: "open" });
+ shadow.innerHTML = `
+ <style>
+ /* This is not expected to match */
+ .container ::slotted(p) {
+ color: red !important;
+ }
+
+ /* This _is_ expected to match */
+ #nested ::slotted(p) {
+ background-color: green;
+ }
+ </style>
+ <div id="nested"><slot></slot></div>
+ `;
+
+ let nested = shadow.querySelector("#nested").attachShadow({ mode: "open" });
+ nested.innerHTML = `
+ <style>
+ .container ::slotted(p) {
+ color: green;
+ }
+ </style>
+ <div class="container">
+ <slot></slot>
+ </div>
+ `;
+
+ let p = document.querySelector("p");
+ test(function() {
+ assert_equals(getComputedStyle(p).color, "rgb(0, 128, 0)");
+ assert_equals(getComputedStyle(p).backgroundColor, "rgb(0, 128, 0)");
+ }, "Slotted matches rules against the slot in the right tree");
+ test(function() {
+ nested.querySelector(".container").classList.remove("container");
+ assert_not_equals(getComputedStyle(p).color, "rgb(0, 128, 0)");
+
+ nested.host.removeAttribute("id");
+ assert_not_equals(getComputedStyle(p).backgroundColor, "rgb(0, 128, 0)");
+ }, "Style invalidation works correctly for nested slots");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-parsing.html b/testing/web-platform/tests/css/css-scoping/slotted-parsing.html
new file mode 100644
index 0000000000..e4657b588a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-parsing.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: ::slotted pseudo parsing</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<style id="styleElm">
+</style>
+<script>
+ test_invalid_selector("::slotted");
+ test_invalid_selector("::slotted()");
+ test_invalid_selector("::slotted(*).class");
+ test_invalid_selector("::slotted(*)#id {}");
+ test_invalid_selector("::slotted(*)[attr]");
+ test_invalid_selector("::slotted(*):host");
+ test_invalid_selector("::slotted(*):host(div)");
+ test_invalid_selector("::slotted(*):hover");
+ test_invalid_selector("::slotted(*):read-only");
+ test_invalid_selector("::slotted(*)::slotted(*)");
+ test_invalid_selector("::slotted(*)::before::slotted(*)");
+ test_invalid_selector("::slotted(*) span");
+
+ test_valid_selector("::slotted(*)");
+ test_valid_selector("::slotted(div)");
+ test_valid_selector("::slotted([attr]:hover)");
+ test_valid_selector("::slotted(:not(.a))");
+
+ test_valid_forgiving_selector("::slotted(*):is()");
+ test_valid_forgiving_selector("::slotted(*):is(:hover)");
+ test_valid_forgiving_selector("::slotted(*):is(#id)");
+
+ test_valid_forgiving_selector("::slotted(*):where()");
+ test_valid_forgiving_selector("::slotted(*):where(:hover)");
+ test_valid_forgiving_selector("::slotted(*):where(#id)");
+ test_valid_forgiving_selector("::slotted(*):where(::before)");
+
+ // Allow tree-abiding pseudo elements after ::slotted
+ test_valid_selector("::slotted(*)::before");
+ test_valid_selector("::slotted(*)::after");
+ test_valid_selector("::slotted(*)::placeholder");
+ test_valid_selector("::slotted(*)::marker");
+
+ // Other pseudo elements not valid after ::slotted
+ test_invalid_selector("::slotted(*)::first-line");
+ test_invalid_selector("::slotted(*)::first-letter");
+ test_invalid_selector("::slotted(*)::selection");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-placeholder-ref.html b/testing/web-platform/tests/css/css-scoping/slotted-placeholder-ref.html
new file mode 100644
index 0000000000..f99c0385d0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-placeholder-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<style>
+ ::placeholder { color: green }
+</style>
+<input placeholder="I should be green">
+<textarea placeholder="I should be green"></textarea>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-placeholder.html b/testing/web-platform/tests/css/css-scoping/slotted-placeholder.html
new file mode 100644
index 0000000000..a3d607afb8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-placeholder.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Scoping Test: ::slotted() allows ::placeholder</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="match" href="slotted-placeholder-ref.html">
+<div id="host">
+ <input placeholder="I should be green">
+ <textarea placeholder="I should be green"></textarea>
+</div>
+<script>
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ ::slotted(*)::placeholder { color: green }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-slot.html b/testing/web-platform/tests/css/css-scoping/slotted-slot.html
new file mode 100644
index 0000000000..1f4aa75ae6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-slot.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>CSS Test: ::slotted() not matching slot elements</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host" style="color:green">This text should be green.</div>
+<script>
+ test(() => {
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = '<div><slot id="slot"></slot><div>';
+ let innerHost = root.firstChild;
+ let innerRoot = innerHost.attachShadow({mode:"open"});
+ innerRoot.innerHTML = "<style>::slotted(#slot){color:red}</style><slot></slot>";
+ assert_equals(getComputedStyle(root.querySelector("#slot")).color, "rgb(0, 128, 0)");
+ }, "Check that ::slotted does not match slot elements");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-specificity-002.html b/testing/web-platform/tests/css/css-scoping/slotted-specificity-002.html
new file mode 100644
index 0000000000..ca2b9ab14c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-specificity-002.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: slotted selectors are compared correctly for specificity</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=229438">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"><div></div></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ :host ::slotted(*) {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ ::slotted(*) {
+ background: red;
+ }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-specificity.html b/testing/web-platform/tests/css/css-scoping/slotted-specificity.html
new file mode 100644
index 0000000000..d049182db6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-specificity.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: the selector inside ::slotted() affects specificity</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1915">
+<link rel="help" href="https://bugzil.la/1454165">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"><div id="slotted"></div></div>
+<script>
+ host.attachShadow({ mode: 'open' }).innerHTML = `
+ <style>
+ ::slotted(#slotted) {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ ::slotted(*) {
+ background: red;
+ }
+ </style>
+ <slot></slot>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element-ref.html b/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element-ref.html
new file mode 100644
index 0000000000..d452d489a4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: pseudo element after ::slotted - reference</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<div>PASS</div>
+<div>PASS</div>
+<div style="color:green">PASS</div>
+<div style="color:green">PASS</div>
diff --git a/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element.html b/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element.html
new file mode 100644
index 0000000000..f2b33ae494
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/slotted-with-pseudo-element.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: pseudo element after ::slotted</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="match" href="slotted-with-pseudo-element-ref.html">
+<div id="host1"><span></span></div>
+<div id="host2"><span></span></div>
+<div id="host3"><span></span></div>
+<div id="host4"><span></span></div>
+<style>
+ #host3 > span::before { content: "PASS" }
+</style>
+<script>
+ function attachShadowWithSlottedStyle(host, styleString) {
+ var root = host.attachShadow({mode:"open"});
+ root.innerHTML = "<style>"+styleString+"</style><slot></slot>";
+ }
+
+ attachShadowWithSlottedStyle(host1, "::slotted(span)::before { content: 'PASS' }");
+ attachShadowWithSlottedStyle(host2, "::slotted(span)::after { content: 'PASS' }");
+ attachShadowWithSlottedStyle(host3, "::slotted(span)::before { content: 'FAIL'; color: green }");
+ attachShadowWithSlottedStyle(host4, `
+ ::slotted(span)::before { content: 'PASS'; color: red }
+ ::slotted(.foo)::before { color: green }
+ `);
+ onload = function() {
+ host4.offsetTop;
+ host4.firstElementChild.classList.add("foo");
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/stylesheet-title-001.html b/testing/web-platform/tests/css/css-scoping/stylesheet-title-001.html
new file mode 100644
index 0000000000..a91fca8ce1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/stylesheet-title-001.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: title attribute in stylesheets not in the document tree is ignored</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/cssom/#preferred-css-style-sheet-set-name">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-style-title">
+<link rel="help" href="https://github.com/w3c/webcomponents/issues/535">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host"></div>
+<script>
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ div { width: 100px; height: 100px; }
+ </style>
+ <style title="Foo">
+ div { background: purple }
+ </style>
+ <style title="Bar">
+ div { background: green }
+ </style>
+ <div></div>
+ `;
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/stylesheet-title-002.html b/testing/web-platform/tests/css/css-scoping/stylesheet-title-002.html
new file mode 100644
index 0000000000..2843ada3ee
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/stylesheet-title-002.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: title attribute in stylesheets not in the document tree is ignored</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/cssom/#preferred-css-style-sheet-set-name">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-style-title">
+<link rel="help" href="https://github.com/w3c/webcomponents/issues/535">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host"></div>
+<script>
+test(function() {
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ div { width: 100px; height: 100px; }
+ </style>
+ <style title="Foo">
+ div { background: purple }
+ </style>
+ <style title="Bar">
+ div { background: green }
+ </style>
+ <div></div>
+ `;
+ assert_equals(host.shadowRoot.styleSheets.length, 3);
+ for (let sheet of host.shadowRoot.styleSheets) {
+ assert_equals(sheet.title, null, "Sheet outside of the document generates no setter");
+ sheet.title = "Foo";
+ assert_equals(sheet.title, null, "Mutation doesn't change the sheet title");
+ }
+ for (let element of host.shadowRoot.querySelectorAll("style")) {
+ element.setAttribute("title", "Foo");
+ assert_equals(element.sheet.title, null, "Attribute mutation doesn't change the sheet title");
+ }
+}, "Title attribute in stylesheets not in the document tree is ignored");
+</script>
diff --git a/testing/web-platform/tests/css/css-scoping/whitespace-crash-001.html b/testing/web-platform/tests/css/css-scoping/whitespace-crash-001.html
new file mode 100644
index 0000000000..d3b4a8a4ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/whitespace-crash-001.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Scoping: Dynamic shadow root creation and whitespace optimization crash.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1465572">
+<link rel="match" href="reference/green-box.html"/>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<!--
+ It's important for the test-case that there's whitespace inside the host,
+ and that it's not assigned to any slot.
+-->
+<div id="host">
+ <div style="display: inline" slot="the-slot"></div>
+</div>
+<script>
+ // Flush layout before creating a ShadowRoot, so that the whitespace ends up
+ // suppressed.
+ document.body.offsetTop;
+ host.attachShadow({ mode: "open" }).innerHTML = `
+ <style>
+ ::slotted(div) {
+ width: 100px;
+ height: 100px;
+ background: green;
+ }
+ </style>
+ <slot name="the-slot"></slot>
+ `;
+ document.body.offsetTop;
+ host.firstElementChild.style.display = "block"; // or anything else that reframes the <div>.
+</script>