-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathrevert-rule-shadow.html
More file actions
266 lines (254 loc) · 7.6 KB
/
revert-rule-shadow.html
File metadata and controls
266 lines (254 loc) · 7.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
<!DOCTYPE html>
<title>The revert-rule keyword: interaction with shadow DOM scopes</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#revert-rule-keyword">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- Test 1: revert-rule in document rule falls back to :host rule -->
<div id="host1"></div>
<script>
host1.attachShadow({mode: 'open'}).innerHTML = `
<style>
:host { color: green; }
</style>
`;
</script>
<style>
#host1 {
color: red;
color: revert-rule;
}
</style>
<script>
test(() => {
assert_true(CSS.supports('color:revert-rule'));
assert_equals(getComputedStyle(host1).color, 'rgb(0, 128, 0)');
}, 'revert-rule in document rule falls back to :host rule');
</script>
<!-- Test 2: revert-rule in document rule falls back to ::slotted rule -->
<div id="host2"><div id="slotted2"></div></div>
<script>
host2.attachShadow({mode: 'open'}).innerHTML = `
<style>
::slotted(*) { color: green; }
</style>
<slot></slot>
`;
</script>
<style>
#slotted2 {
color: red;
color: revert-rule;
}
</style>
<script>
test(() => {
assert_equals(getComputedStyle(slotted2).color, 'rgb(0, 128, 0)');
}, 'revert-rule in document rule falls back to ::slotted rule');
</script>
<!-- Test 3: revert-rule in :host rule has no effect when a document rule wins -->
<div id="host3"></div>
<script>
host3.attachShadow({mode: 'open'}).innerHTML = `
<style>
:host { color: revert-rule; }
</style>
`;
</script>
<style>
#host3 { color: green; }
</style>
<script>
test(() => {
assert_equals(getComputedStyle(host3).color, 'rgb(0, 128, 0)');
}, 'revert-rule in :host rule has no effect when a document rule already wins');
</script>
<!-- Test 4: revert-rule in document rule with no fallback falls through to unset -->
<div id="host4"></div>
<script>
host4.attachShadow({mode: 'open'}).innerHTML = `<slot></slot>`;
</script>
<style>
#host4 {
color: red;
color: revert-rule;
}
</style>
<script>
test(() => {
// No :host rule exists; color is inherited from the document body (rgb(0,0,0)).
assert_equals(getComputedStyle(host4).color, 'rgb(0, 0, 0)');
}, 'revert-rule with no shadow fallback falls through to unset (inherited)');
</script>
<!-- Test 5: revert-rule in document rule, multiple competing :host rules -->
<div id="host5"></div>
<script>
host5.attachShadow({mode: 'open'}).innerHTML = `
<style>
:host { color: green; }
:host { color: red; }
</style>
`;
</script>
<style>
#host5 {
color: blue;
color: revert-rule;
}
</style>
<script>
test(() => {
assert_equals(getComputedStyle(host5).color, 'rgb(255, 0, 0)');
}, 'revert-rule in document rule falls back to the winning :host rule');
</script>
<!-- Test 6: revert-rule in document rule, :host rule also reverts -->
<div id="host6"></div>
<script>
host6.attachShadow({mode: 'open'}).innerHTML = `
<style>
:host { color: green; }
:host { color: revert-rule; }
</style>
`;
</script>
<style>
#host6 {
color: blue;
color: revert-rule;
}
</style>
<script>
test(() => {
// The document revert-rule falls back to the :host block. Within the :host
// block, the second :host rule says revert-rule, which falls back to the
// first :host rule's green.
assert_equals(getComputedStyle(host6).color, 'rgb(0, 128, 0)');
}, 'revert-rule chain across document rule and :host rule');
</script>
<!-- Test 7: revert-rule in ::part() rule falls back to earlier ::part() rule -->
<div id="host7"></div>
<script>
{
const shadow = host7.attachShadow({mode: 'open'});
shadow.innerHTML = `<span id="p7" part="mypart">text</span>`;
}
</script>
<style>
#host7::part(mypart) { color: green; }
#host7::part(mypart) { color: revert-rule; }
</style>
<script>
test(() => {
const part = host7.shadowRoot.getElementById('p7');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule in ::part() rule falls back to earlier ::part() rule');
</script>
<!-- Test 8: revert-rule in ::part() rule falls back to shadow-internal rule -->
<div id="host8"></div>
<script>
{
const shadow = host8.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>span { color: green; }</style>
<span id="p8" part="mypart">text</span>
`;
}
</script>
<style>
#host8::part(mypart) { color: revert-rule; }
</style>
<script>
test(() => {
// The ::part() rule reverts, falling back to the shadow-internal span rule (green).
const part = host8.shadowRoot.getElementById('p8');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule in ::part() rule falls back to shadow-internal rule');
</script>
<!-- Test 9: revert-rule in shadow-internal rule, ::part() rule wins -->
<div id="host9"></div>
<script>
{
const shadow = host9.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>
span { color: blue; }
span { color: revert-rule; }
</style>
<span id="p9" part="mypart">text</span>
`;
}
</script>
<style>
#host9::part(mypart) { color: green; }
</style>
<script>
test(() => {
// The ::part() rule in the document wins. revert-rule inside the shadow
// does not affect the winning ::part() declaration.
const part = host9.shadowRoot.getElementById('p9');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule in shadow-internal rule has no effect when ::part() rule wins');
</script>
<!-- Test 10: revert-rule chain across two ::part() rules -->
<div id="host10"></div>
<script>
{
const shadow = host10.attachShadow({mode: 'open'});
shadow.innerHTML = `<span id="p10" part="mypart">text</span>`;
}
</script>
<style>
#host10::part(mypart) { color: red; }
#host10::part(mypart) { color: green; }
#host10::part(mypart) { color: revert-rule; }
</style>
<script>
test(() => {
// Third rule reverts to what would exist without it → second rule (green).
const part = host10.shadowRoot.getElementById('p10');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule in third ::part() rule falls back to second ::part() rule');
</script>
<!-- Test 11: revert-rule in ::part() and :host on same host element -->
<div id="host11"></div>
<script>
{
const shadow = host11.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>:host { color: blue; }</style>
<span id="p11" part="mypart">text</span>
`;
}
</script>
<style>
#host11 { color: red; color: revert-rule; }
#host11::part(mypart) { color: green; }
</style>
<script>
test(() => {
// Host color reverts to :host rule (blue).
assert_equals(getComputedStyle(host11).color, 'rgb(0, 0, 255)');
// Part color is set by ::part() rule (green), independent of host revert.
const part = host11.shadowRoot.getElementById('p11');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule on host and ::part() rule on part are independent');
</script>
<!-- Test 12: revert-rule in ::part() rule falls back across selector specificity -->
<div id="host12" class="host12cls"></div>
<script>
{
const shadow = host12.attachShadow({mode: 'open'});
shadow.innerHTML = `<span id="p12" part="mypart">text</span>`;
}
</script>
<style>
#host12::part(mypart) { color: green; }
#host12.host12cls::part(mypart) { color: revert-rule; }
</style>
<script>
test(() => {
// Higher specificity rule reverts, so falls back to the lower-specificity green.
const part = host12.shadowRoot.getElementById('p12');
assert_equals(getComputedStyle(part).color, 'rgb(0, 128, 0)');
}, 'revert-rule in higher-specificity ::part() rule falls back to lower-specificity ::part() rule');
</script>