Commit c20f4ed8 authored by Eric Willigers's avatar Eric Willigers Committed by Commit Bot

CSS WPT: Attribute and sibling selectors

Test that attribute selectors are effective when attributes, ids and
class lists change.

https://drafts.csswg.org/selectors-4/#attribute-selectors

Test adjacent and universal sibling selectors when classes change.

https://drafts.csswg.org/selectors-4/#adjacent-sibling-combinators
https://drafts.csswg.org/selectors-4/#general-sibling-combinators

Based on
fast/css/invalidation/class-sibling-universal.html
(which Blink still needs as it uses internals to count style recalcs).

Change-Id: Ia62516e4ab596ef095d4c26a08f90f8f19e5069b
Reviewed-on: https://chromium-review.googlesource.com/c/1345371Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Commit-Queue: Eric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609894}
parent 16e6b253
<!DOCTYPE html>
<html>
<head>
<title>CSS Selectors Invalidation: attribute</title>
<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-selectors">
<meta name="assert" content="This tests that the attribute selectors are effective">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
div {
color: gray;
}
#a1[style] {
color: blue;
}
#a1[style] > #b1 {
color: green;
}
#a1[style] #c1 {
color: red;
}
#a1[style] + #d1 {
color: yellow;
}
[id=a2] {
color: blue;
}
[id=a2] > #b2 {
color: green;
}
[id=a2] #c2 {
color: red;
}
[id=a2] + #d2 {
color: yellow;
}
#a3[class~=q] {
color: blue;
}
#a3[class~=q] > #b3 {
color: green;
}
#a3[class~=q] #c3 {
color: red;
}
#a3[class~=q] + #d3 {
color: yellow;
}
#a4[run|=one] {
color: blue;
}
#a4[run|=one] > #b4 {
color: green;
}
#a4[run|=one] #c4 {
color: red;
}
#a4[run|=one] + #d4 {
color: yellow;
}
#a5 {
color: blue;
}
#a5 > #b5 {
color: green;
}
#a5 #c5 {
color: red;
}
#a5 + #d5 {
color: yellow;
}
#a6.q {
color: blue;
}
#a6.q > #b6 {
color: green;
}
#a6.q #c6 {
color: red;
}
#a6.q + #d6 {
color: yellow;
}
</style>
</head>
<body>
<div id="a1">
<div id="b1">
<div id="c1">
</div>
</div>
</div>
<div id="d1">
</div>
<div>
<div id="b2">
<div id="c2">
</div>
</div>
</div>
<div id="d2">
</div>
<div id="a3">
<div id="b3">
<div id="c3">
</div>
</div>
</div>
<div id="d3">
</div>
<div id="a4">
<div id="b4">
<div id="c4">
</div>
</div>
</div>
<div id="d4">
</div>
<div>
<div id="b5">
<div id="c5">
</div>
</div>
</div>
<div id="d5">
</div>
<div id="a6">
<div id="b6">
<div id="c6">
</div>
</div>
</div>
<div id="d6">
</div>
<script>
const gray = "rgb(128, 128, 128)";
const blue = "rgb(0, 0, 255)";
const green = "rgb(0, 128, 0)";
const red = "rgb(255, 0, 0)";
const yellow = "rgb(255, 255, 0)";
function assertGray(a, b, c, d) {
assert_equals(getComputedStyle(a).color, gray);
assert_equals(getComputedStyle(b).color, gray);
assert_equals(getComputedStyle(c).color, gray);
assert_equals(getComputedStyle(d).color, gray);
}
function assertColorful(a, b, c, d) {
assert_equals(getComputedStyle(a).color, blue);
assert_equals(getComputedStyle(b).color, green);
assert_equals(getComputedStyle(c).color, red);
assert_equals(getComputedStyle(d).color, yellow);
}
test(() => {
assertGray(a1, b1, c1, d1);
a1.style.visibility = "visible";
assertColorful(a1, b1, c1, d1);
a1.removeAttribute('style');
assertGray(a1, b1, c1, d1);
}, "[att] selector is effective");
test(() => {
const a2 = b2.parentElement;
assertGray(a2, b2, c2, d2);
a2.id = 'x-a2';
assertGray(a2, b2, c2, d2);
a2.id = 'a2';
assertColorful(a2, b2, c2, d2);
a2.id = 'a2-y';
assertGray(a2, b2, c2, d2);
}, "[att=val] selector is effective");
test(() => {
assertGray(a3, b3, c3, d3);
a3.setAttribute('class', 'p q r');
assertColorful(a3, b3, c3, d3);
a3.setAttribute('class', 'q-r');
assertGray(a3, b3, c3, d3);
}, "[att~=val] selector is effective");
test(() => {
assertGray(a4, b4, c4, d4);
a4.setAttribute('run', 'one');
assertColorful(a4, b4, c4, d4);
a4.setAttribute('run', 'one two three');
assertGray(a4, b4, c4, d4);
a4.setAttribute('run', 'one-two-three');
assertColorful(a4, b4, c4, d4);
a4.setAttribute('run', 'zero-one');
assertGray(a4, b4, c4, d4);
}, "[att|=val] selector is effective");
test(() => {
const a5 = b5.parentElement;
assertGray(a5, b5, c5, d5);
a5.setAttribute('id', 'x-a5');
assertGray(a5, b5, c5, d5);
a5.setAttribute('id', 'a5');
assertColorful(a5, b5, c5, d5);
a5.setAttribute('id', 'a5-y');
assertGray(a5, b5, c5, d5);
}, "#id selector is effective");
test(() => {
assertGray(a6, b6, c6, d6);
a6.classList.add('p');
a6.classList.add('q');
a6.classList.add('r');
assertColorful(a6, b6, c6, d6);
a6.classList.remove('q');
a6.classList.add('q-r');
assertGray(a6, b6, c6, d6);
}, ".class selector is effective");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>CSS Selectors Invalidation: sibling</title>
<link rel="help" href="https://drafts.csswg.org/selectors-4/#adjacent-sibling-combinators">
<link rel="help" href="https://drafts.csswg.org/selectors-4/#general-sibling-combinators">
<meta name="assert" content="This tests that the + next-sibling selector is effective">
<meta name="assert" content="This tests that the ~ subsequent-sibling selector is effective">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
* { background-color: inherit; }
body { background-color: rgba(0, 0, 0, 0); }
.t1 .sibling + *,
.t2 .sibling ~ *,
.t3 + .sibling + *,
.t4 + .sibling,
.t5 + *,
.t6 ~ .sibling,
.t7 + * + * .child { background-color: rgb(0, 128, 0); }
</style>
</head>
<body>
<div>
<div id="t1">
<div class="sibling"></div>
<div id="r1"></div>
<div id="u1"></div>
</div>
</div>
<div>
<div id="t2">
<div class="sibling"></div>
<div></div>
<div id="r2"></div>
</div>
</div>
<div>
<div id="t3"></div>
<div class="sibling"></div>
<div id="r3"></div>
</div>
<div>
<div id="t4"></div>
<div id="r4" class="sibling"></div>
<div id="u4" class="sibling"></div>
</div>
<div>
<div id="t5"></div>
<div id="r5"></div>
<div id="u5"></div>
</div>
<div>
<div id="t6"></div>
<div></div>
<div id="r6" class="sibling">
<div id="r6b"></div>
</div>
<div id="u6"></div>
</div>
<div>
<div id="t7">
<div class="child"></div>
</div>
<div></div>
<div>
<div id="r7" class="child"></div>
</div>
<div>
<div id="u7" class="child"></div>
</div>
</div>
<script>
test(function() {
assert_equals(getComputedStyle(r1).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t1.className = "t1";
assert_equals(getComputedStyle(r1).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
assert_equals(getComputedStyle(u1).backgroundColor, "rgba(0, 0, 0, 0)", "Background color remains transparent");
}, "Adjacent with universal selector");
test(function() {
assert_equals(getComputedStyle(r2).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t2.className = "t2";
assert_equals(getComputedStyle(r2).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
}, "Indirect adjacent with universal selector");
test(function() {
assert_equals(getComputedStyle(r3).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t3.className = "t3";
assert_equals(getComputedStyle(r3).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
}, "Indirect adjacent with two adjacent selectors");
test(function() {
assert_equals(getComputedStyle(r4).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t4.className = "t4";
assert_equals(getComputedStyle(r4).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
assert_equals(getComputedStyle(u4).backgroundColor, "rgba(0, 0, 0, 0)", "Background color remains transparent");
}, "Adjacent class");
test(function() {
assert_equals(getComputedStyle(r5).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t5.className = "t5";
assert_equals(getComputedStyle(r5).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
assert_equals(getComputedStyle(u5).backgroundColor, "rgba(0, 0, 0, 0)", "Background color remains transparent");
}, "Adjacent universal");
test(function() {
assert_equals(getComputedStyle(r6).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
assert_equals(getComputedStyle(r6b).backgroundColor, "rgba(0, 0, 0, 0)", "Child's background color should initially be transparent");
t6.className = "t6";
assert_equals(getComputedStyle(r6).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
assert_equals(getComputedStyle(r6b).backgroundColor, "rgb(0, 128, 0)", "Child's background color is green after class change");
assert_equals(getComputedStyle(u6).backgroundColor, "rgba(0, 0, 0, 0)", "Background color remains transparent");
}, "Sibling subtree through an indirect adjacent combinator");
test(function() {
assert_equals(getComputedStyle(r7).backgroundColor, "rgba(0, 0, 0, 0)", "Background color should initially be transparent");
t7.className = "t7";
assert_equals(getComputedStyle(r7).backgroundColor, "rgb(0, 128, 0)", "Background color is green after class change");
assert_equals(getComputedStyle(u7).backgroundColor, "rgba(0, 0, 0, 0)", "Background color remains transparent");
}, "Sibling descendant through a universal selector");
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment