Tests: Import tree-counting function WPT tests

This commit is contained in:
Callum Law 2025-09-27 13:38:18 +12:00 committed by Tim Ledbetter
parent 8284a99f0a
commit 85239fb1da
38 changed files with 1228 additions and 0 deletions

View File

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Fail
Fail Host children have sibling-index() and sibling-count() based on the DOM tree order

View File

@ -0,0 +1,16 @@
Harness status: OK
Found 10 tests
4 Pass
6 Fail
Fail e.style['left'] = "calc(1px * sibling-index())" should set the property value
Fail e.style['left'] = "calc(1px * sibling-index( ))" should set the property value
Fail e.style['z-index'] = "sibling-index()" should set the property value
Pass e.style['left'] = "calc(1px * sibling-index(100px))" should not set the property value
Pass e.style['left'] = "calc(1px * sibling-index(1))" should not set the property value
Fail e.style['left'] = "calc(1px * sibling-count())" should set the property value
Fail e.style['left'] = "calc(1px * sibling-count( ))" should set the property value
Fail e.style['z-index'] = "sibling-count()" should set the property value
Pass e.style['left'] = "calc(1px * sibling-count(100px))" should not set the property value
Pass e.style['left'] = "calc(1px * sibling-count(1))" should not set the property value

View File

@ -0,0 +1,12 @@
Harness status: OK
Found 6 tests
1 Pass
5 Fail
Fail basic sibling-index() test
Fail basic sibling-count() test
Fail sibling-index() in calc() with percentage
Fail sibling-count() on pseudo-element
Fail sibling-index() on root
Pass sibling-count() on root

View File

@ -0,0 +1,14 @@
Harness status: OK
Found 8 tests
4 Pass
4 Fail
Pass sibling-index() in @container width query initially not matching
Pass sibling-count() in @container width query initially not matching
Pass sibling-index() in @container style() query initially not matching
Pass sibling-count() in @container style() query initially not matching
Fail sibling-index() in @container width query matching after removal
Fail sibling-count() in @container width query matching after removal
Fail sibling-index() in @container style() query matching after removal
Fail sibling-count() in @container style() query matching after removal

View File

@ -0,0 +1,9 @@
Harness status: OK
Found 4 tests
4 Fail
Fail sibling-index() in @container width query
Fail sibling-count() in @container width query
Fail sibling-index() in @container style() query
Fail sibling-count() in @container style() query

View File

@ -0,0 +1,16 @@
Harness status: OK
Found 10 tests
2 Pass
8 Fail
Fail sibling-index() should not be allowed in @page properties
Fail sibling-count() should not be allowed in @page properties
Pass sibling-index() should not be allowed in @font-face descriptors
Pass sibling-count() should not be allowed in @font-face descriptors
Fail sibling-index() should not be allowed in @font-palette-values descriptors
Fail sibling-count() should not be allowed in @font-palette-values descriptors
Fail sibling-index() should not be allowed in @counter-style descriptors
Fail sibling-count() should not be allowed in @counter-style descriptors
Fail sibling-index() should not be allowed in @font-feature-values descriptors
Fail sibling-count() should not be allowed in @font-feature-values descriptors

View File

@ -0,0 +1,9 @@
Harness status: OK
Found 4 tests
4 Fail
Fail Initially 6th sibling
Fail 5th sibling after removal
Fail Initially 6 siblings
Fail 5 siblings after removal

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass sibling-index() and sibling-count() are not valid in @media queries
Pass @media queries with sibling-index() and sibling-count() as general-enclosed

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 2 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 4 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,25 @@
Harness status: OK
Found 20 tests
20 Fail
Fail Initially, the sibling-index() is 3 for --time
Fail Initially, the sibling-index() is 3 for --angle
Fail Initially, the sibling-index() is 3 for --resolution
Fail Initially, the sibling-index() is 3 for --percentage
Fail Initially, the sibling-index() is 3 for --number
Fail Initially, the sibling-index() is 3 for --integer
Fail Initially, the sibling-index() is 3 for --length
Fail Initially, the sibling-index() is 3 for --length-percentage
Fail Initially, the sibling-index() is 3 for --color
Fail Initially, the sibling-index() is 3 for --list
Fail Removing a preceding sibling of #target reduces the sibling-index() for --time
Fail Removing a preceding sibling of #target reduces the sibling-index() for --angle
Fail Removing a preceding sibling of #target reduces the sibling-index() for --resolution
Fail Removing a preceding sibling of #target reduces the sibling-index() for --percentage
Fail Removing a preceding sibling of #target reduces the sibling-index() for --number
Fail Removing a preceding sibling of #target reduces the sibling-index() for --integer
Fail Removing a preceding sibling of #target reduces the sibling-index() for --length
Fail Removing a preceding sibling of #target reduces the sibling-index() for --length-percentage
Fail Removing a preceding sibling of #target reduces the sibling-index() for --color
Fail Removing a preceding sibling of #target reduces the sibling-index() for --list

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail Initially, the sibling-index() is 3 for #target
Fail Removing a preceding sibling of #target reduces the sibling-index()

View File

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Fail
Fail sibling-index() and sibling-count() evaluates to 0 from outer tree with ::part
Fail sibling-index() and sibling-count() evaluate as normal from inner tree

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Values Test: sibling-index() and sibling-count() in flat tree</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting" />
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
</head>
<body>
<style>
#host > * {
orphans: sibling-index();
widows: sibling-count();
}
</style>
<div id="host">
<div>Some element.</div>
<div>Some other element.</div>
<div slot="unknown">This should be ignored.</div>
<div id="target">Some third element.</div>
</div>
<script>
test(() => {
host.attachShadow({mode: 'open'}).innerHTML = `
<style>
slot::slotted(*) {
z-index: sibling-index();
order: sibling-count();
}
</style>
<div>
<div>Some text before the slot.</div>
<slot></slot>
</div>
`;
assert_equals(getComputedStyle(target).zIndex, '4');
assert_equals(getComputedStyle(target).order, '4');
assert_equals(getComputedStyle(target).orphans, '4');
assert_equals(getComputedStyle(target).widows, '4');
}, 'Host children have sibling-index() and sibling-count() based on the DOM tree order');
</script>

View File

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CSS sibling-index() and sibling-count()</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting" />
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_valid_value('left', 'calc(1px * sibling-index())');
test_valid_value('left', 'calc(1px * sibling-index( ))', 'calc(1px * sibling-index())');
test_valid_value('z-index', 'sibling-index()');
test_invalid_value('left', 'calc(1px * sibling-index(100px))');
test_invalid_value('left', 'calc(1px * sibling-index(1))');
test_valid_value('left', 'calc(1px * sibling-count())');
test_valid_value('left', 'calc(1px * sibling-count( ))', 'calc(1px * sibling-count())');
test_valid_value('z-index', 'sibling-count()');
test_invalid_value('left', 'calc(1px * sibling-count(100px))');
test_invalid_value('left', 'calc(1px * sibling-count(1))');
</script>
</body>
</html>

View File

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CSS sibling-index() and sibling-count()</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting" />
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
html {
z-index: calc(sibling-index() * 2);
widows: calc(sibling-count() * 2);
}
#test {
z-index: calc(sibling-index());
counter-increment: foo calc(sibling-count());
left: calc(10% + 100px * sibling-index());
}
#test::before {
content: "";
z-index: calc(sibling-index() * 2);
widows: calc(sibling-count() * 2);
}
</style>
</head>
<body>
<div>
<div></div>
<div id="test"></div>
<div></div>
<div></div>
<ul></ul>
</div>
<script>
test(() => {
let style = getComputedStyle(document.getElementById('test'));
assert_equals(style.zIndex, '2');
}, 'basic sibling-index() test');
test(() => {
let style = getComputedStyle(document.getElementById('test'));
assert_equals(style.counterIncrement, 'foo 5');
}, 'basic sibling-count() test');
test(() => {
let style = getComputedStyle(document.getElementById('test'));
assert_equals(style.left, 'calc(10% + 200px)');
}, 'sibling-index() in calc() with percentage');
test(() => {
let style = getComputedStyle(document.getElementById('test'), '::before');
assert_equals(style.zIndex, '4');
assert_equals(style.widows, '10');
}, 'sibling-count() on pseudo-element');
test(() => {
let style = getComputedStyle(document.documentElement);
assert_equals(style.zIndex, '2');
}, 'sibling-index() on root');
test(() => {
let style = getComputedStyle(document.documentElement);
assert_equals(style.widows, '2');
}, 'sibling-count() on root');
</script>
</body>
</html>

View File

@ -0,0 +1,92 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() and sibling-count() changes in container queries</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-features">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@property --length {
syntax: "<length>";
initial-value: 0px;
inherits: false;
}
.container { container-type: inline-size; }
#c1 {
width: 100px;
--length: 100px;
}
#c2 {
width: 400px;
--length: 600px;
}
span {
--match-100: no;
--match-600: no;
}
@container (width = calc(100px * sibling-index())) {
span { background-color: green; }
}
@container (width = calc(200px * sibling-count())) {
span { color: lime; }
}
@container style(--length: calc(100px * sibling-index())) {
span { --match-100: yes; }
}
@container style(--length: calc(300px * sibling-count())) {
span { --match-600: yes; }
}
</style>
<div style="color:black">
<div id="rm1"></div>
<div id="rm2"></div>
<div id="c1" class="container">
<span id="t1"></span>
</div>
<div id="c2" class="container">
<span id="t2"></span>
</div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)");
assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
}, "sibling-index() in @container width query initially not matching");
test(() => {
assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)");
assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
}, "sibling-count() in @container width query initially not matching");
test(() => {
assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "no");
assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no");
}, "sibling-index() in @container style() query initially not matching");
test(() => {
assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no");
assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "no");
}, "sibling-count() in @container style() query initially not matching");
rm1.remove();
rm2.remove();
test(() => {
assert_equals(getComputedStyle(t1).backgroundColor, "rgb(0, 128, 0)");
assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
}, "sibling-index() in @container width query matching after removal");
test(() => {
assert_equals(getComputedStyle(t2).backgroundColor, "rgba(0, 0, 0, 0)");
assert_equals(getComputedStyle(t2).color, "rgb(0, 255, 0)");
}, "sibling-count() in @container width query matching after removal");
test(() => {
assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "yes");
assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no");
}, "sibling-index() in @container style() query matching after removal");
test(() => {
assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no");
assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "yes");
}, "sibling-count() in @container style() query matching after removal");
</script>

View File

@ -0,0 +1,67 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() and sibling-count() in container queries</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-features">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@property --length {
syntax: "<length>";
initial-value: 0px;
inherits: false;
}
.container { container-type: inline-size; }
#c1 {
width: 100px;
--length: 100px;
}
#c2 {
width: 400px;
--length: 400px;
}
span {
--match-100: no;
--match-400: no;
}
@container (width = calc(100px * sibling-index())) {
span { background-color: green; }
}
@container (width = calc(200px * sibling-count())) {
span { color: lime; }
}
@container style(--length: calc(100px * sibling-index())) {
span { --match-100: yes; }
}
@container style(--length: calc(200px * sibling-count())) {
span { --match-400: yes; }
}
</style>
<div style="color:black">
<div id="c1" class="container">
<span id="t1"></span>
</div>
<div id="c2" class="container">
<span id="t2"></span>
</div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(t1).backgroundColor, "rgb(0, 128, 0)");
assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
}, "sibling-index() in @container width query");
test(() => {
assert_equals(getComputedStyle(t2).backgroundColor, "rgba(0, 0, 0, 0)");
assert_equals(getComputedStyle(t2).color, "rgb(0, 255, 0)");
}, "sibling-count() in @container width query");
test(() => {
assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "yes");
assert_equals(getComputedStyle(t1).getPropertyValue("--match-400"), "no");
}, "sibling-index() in @container style() query");
test(() => {
assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no");
assert_equals(getComputedStyle(t2).getPropertyValue("--match-400"), "yes");
}, "sibling-count() in @container style() query");
</script>

View File

@ -0,0 +1,166 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() and sibling-count() invalid in descriptors</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10982">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style id="page_sheet">
@page {
margin: 100px;
margin: calc(0px * sibling-index());
}
@page {
margin: 100px;
margin: calc(0px * sibling-count());
}
</style>
<style id="font_face_sheet">
@font-face {
font-family: my-font;
font-weight: 300;
font-weight: calc(max(0 * sibling-index(), 400));
font-feature-settings: "vert" 2;
font-feature-settings: "vert" calc(max(sibling-index(), 1));
}
@font-face {
font-family: my-font;
font-weight: 300;
font-weight: calc(max(0 * sibling-count(), 400));
font-feature-settings: "vert" 2;
font-feature-settings: "vert" calc(max(sibling-count(), 1));
}
</style>
<style id="font_palette_sheet">
@font-palette-values --foo {
font-family: my-font;
base-palette: 1;
base-palette: calc(max(sibling-index(), 2));
override-colors: 1 green;
override-colors: sibling-index() red;
}
@font-palette-values --foo {
font-family: my-font;
base-palette: 1;
base-palette: calc(max(sibling-count(), 2));
override-colors: 1 green;
override-colors: sibling-count() red;
}
</style>
<style id="counter_style_sheet">
@counter-style --foo {
system: fixed 1;
system: fixed calc(max(sibling-index(), 2));
negative: --pass;
negative: linear-gradient(red calc(20px * sibling-index()), pink);
prefix: --pass;
prefix: linear-gradient(red calc(20px * sibling-index()), pink);
suffix: --pass;
suffix: linear-gradient(red calc(20px * sibling-index()), pink);
range: 1 infinite;
range: calc(max(sibling-index(), 2)) infinite;
pad: 1 --pass;
pad: 1 linear-gradient(red calc(20px * sibling-index()), pink);
pad: calc(max(sibling-index(), 2)) --fail;
symbols: --pass;
symbols: linear-gradient(red calc(20px * sibling-index()), pink);
}
@counter-style --foo {
system: fixed 1;
system: fixed calc(max(sibling-count(), 2));
negative: --pass;
negative: linear-gradient(green, green);
negative: linear-gradient(red calc(20px * sibling-count()), pink);
prefix: --pass;
prefix: linear-gradient(red calc(20px * sibling-count()), pink);
suffix: --pass;
suffix: linear-gradient(red calc(20px * sibling-count()), pink);
range: 1 infinite;
range: calc(max(sibling-count(), 2)) infinite;
pad: 1 --pass;
pad: 1 linear-gradient(red calc(20px * sibling-count()), pink);
pad: calc(max(sibling-count(), 2)) --fail;
symbols: --pass;
symbols: linear-gradient(red calc(20px * sibling-count()), pink);
}
</style>
<style id="font_features_sheet">
@font-feature-values foo {
@swash { pretty: 1; }
@swash { pretty: calc(max(sibling-index(), 2)); }
}
@font-feature-values bar {
@swash { pretty: 1; }
@swash { pretty: calc(max(sibling-count(), 2)); }
}
</style>
<script>
const page_rules = page_sheet.sheet.cssRules;
test(() => {
assert_equals(page_rules[0].style.margin, "100px");
}, "sibling-index() should not be allowed in @page properties");
test(() => {
assert_equals(page_rules[1].style.margin, "100px");
}, "sibling-count() should not be allowed in @page properties");
const font_face_rules = font_face_sheet.sheet.cssRules;
test(() => {
assert_equals(font_face_rules[0].style.fontWeight, "300");
assert_equals(font_face_rules[0].style.fontFeatureSettings, "\"vert\" 2");
}, "sibling-index() should not be allowed in @font-face descriptors");
test(() => {
assert_equals(font_face_rules[1].style.fontWeight, "300");
assert_equals(font_face_rules[1].style.fontFeatureSettings, "\"vert\" 2");
}, "sibling-count() should not be allowed in @font-face descriptors");
const font_palette_rules = font_palette_sheet.sheet.cssRules;
test(() => {
assert_equals(font_palette_rules[0].basePalette, "1");
assert_equals(font_palette_rules[0].overrideColors, "1 green");
}, "sibling-index() should not be allowed in @font-palette-values descriptors");
test(() => {
assert_equals(font_palette_rules[1].basePalette, "1");
assert_equals(font_palette_rules[1].overrideColors, "1 green");
}, "sibling-count() should not be allowed in @font-palette-values descriptors");
const counter_style_rules = counter_style_sheet.sheet.cssRules;
test(() => {
assert_equals(counter_style_rules[0].system, "fixed 1");
assert_equals(counter_style_rules[0].negative, "--pass");
assert_equals(counter_style_rules[0].prefix, "--pass");
assert_equals(counter_style_rules[0].suffix, "--pass");
assert_equals(counter_style_rules[0].range, "1 infinite");
assert_equals(counter_style_rules[0].pad, "1 --pass");
assert_equals(counter_style_rules[0].symbols, "--pass");
}, "sibling-index() should not be allowed in @counter-style descriptors");
test(() => {
assert_equals(counter_style_rules[1].system, "fixed 1");
assert_equals(counter_style_rules[1].negative, "--pass");
assert_equals(counter_style_rules[1].prefix, "--pass");
assert_equals(counter_style_rules[1].suffix, "--pass");
assert_equals(counter_style_rules[1].range, "1 infinite");
assert_equals(counter_style_rules[1].pad, "1 --pass");
assert_equals(counter_style_rules[1].symbols, "--pass");
}, "sibling-count() should not be allowed in @counter-style descriptors");
const font_features_rules = font_features_sheet.sheet.cssRules;
test(() => {
const swash = font_features_rules[0].swash;
assert_equals(swash.get("pretty")[0], 1);
}, "sibling-index() should not be allowed in @font-feature-values descriptors");
test(() => {
const swash = font_features_rules[1].swash;
assert_equals(swash.get("pretty")[0], 1);
}, "sibling-count() should not be allowed in @font-feature-values descriptors");
</script>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: Invalidation for sibling-index() and sibling-count()</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
#t1 {
width: calc(10px * sibling-index());
height: 50px;
background: teal;
}
</style>
<div>
<div id="rm1"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div id="t1"></div>
</div>
<script>
test(() => assert_equals(t1.offsetWidth, 60), "Initially 6th sibling");
test(() => {
rm1.remove();
assert_equals(t1.offsetWidth, 50);
}, "5th sibling after removal");
</script>
<style>
#t2 {
width: 50px;
height: calc(10px * sibling-count());
background: teal;
}
</style>
<div>
<div id="t2"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div id="rm2"></div>
</div>
<script>
test(() => assert_equals(t2.offsetHeight, 60), "Initially 6 siblings");
test(() => {
rm2.remove();
assert_equals(t2.offsetHeight, 50);
}, "5 siblings after removal");
</script>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() and sibling-count() invalid in media queries</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<link rel="help" href="https://drafts.csswg.org/mediaqueries-5/#width">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10982">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style id="test_sheet">
#target {
background-color: green;
}
@media (width > CALC(0px * sibling-index())) {
#target { background-color: red; }
}
@media (width > CALC(0px * sibling-count())) {
#target { background-color: red; }
}
</style>
<div id="target"></div>
<script>
test(() => {
assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 128, 0)");
}, "sibling-index() and sibling-count() are not valid in @media queries");
test(() => {
let rules = test_sheet.sheet.cssRules;
assert_equals(rules.length, 3);
assert_equals(rules[1].media.mediaText, "(width > CALC(0px * sibling-index()))");
assert_equals(rules[2].media.mediaText, "(width > CALC(0px * sibling-count()))");
}, "@media queries with sibling-index() and sibling-count() as general-enclosed");
</script>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing font-style during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
font-style: oblique calc(5deg * sibling-index());
}
to {
font-style: oblique 9deg;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).fontStyle, "oblique 15deg");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).fontStyle, "oblique 10deg");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing font-variation-settings during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
font-variation-settings: "wght" sibling-index();
}
to {
font-variation-settings: "wght" 10;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).fontVariationSettings, '"wght" 3');
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).fontVariationSettings, '"wght" 2');
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing length value during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
top: calc(100px * sibling-index());
}
to {
top: 0px;
}
}
#target {
animation: --anim 1000s step-end;
position: absolute;
top: 13px;
width: 100px;
height: 100px;
}
</style>
<div>
<div id="rm"></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).top, "200px");
}, "Initially, the sibling-index() is 2 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).top, "100px");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing font-palette during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@font-face {
font-family: "COLR-test-font";
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}
@font-palette-values --MyFirstPalette {
font-family: "COLR-test-font";
base-palette: 1;
}
@font-palette-values --MySecondPalette {
font-family: "COLR-test-font";
base-palette: 2;
}
@keyframes --anim {
from {
font-palette: palette-mix(in lch, --MyFirstPalette calc(5% * sibling-index()), --MySecondPalette 80%);
}
to {
font-palette: palette-mix(in lch, --MyFirstPalette 90%, --MySecondPalette 10%);
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).fontPalette, "palette-mix(in lch, --MyFirstPalette 20%, --MySecondPalette)");
}, "Initially, the sibling-index() is 4 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).fontPalette, "palette-mix(in lch, --MyFirstPalette 15%, --MySecondPalette 80%)");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing percentage during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
text-size-adjust: calc(50% * sibling-index());
}
to {
text-size-adjust: 90%;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).textSizeAdjust, "150%");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).textSizeAdjust, "100%");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,118 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing registered custom property values during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@property --time { syntax: "<time>"; initial-value: 0s; inherits: false; }
@property --angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
@property --resolution { syntax: "<resolution>"; initial-value: 1dppx; inherits: false; }
@property --percentage { syntax: "<percentage>"; initial-value: 0%; inherits: false; }
@property --number { syntax: "<number>"; initial-value: 0; inherits: false; }
@property --integer { syntax: "<integer>"; initial-value: 0; inherits: false; }
@property --length { syntax: "<length>"; initial-value: 0px; inherits: false; }
@property --length-percentage { syntax: "<length-percentage>"; initial-value: 0px; inherits: false; }
@property --color { syntax: "<color>"; initial-value: black; inherits: false; }
@property --list { syntax: "<integer>+"; initial-value: 0; inherits: false; }
@keyframes --anim {
from {
--time: calc(2s * sibling-index());
--angle: calc(30deg * sibling-index());
--resolution: calc(1dppx * sibling-index());
--percentage: calc(50% * sibling-index());
--number: sibling-index();
--integer: sibling-index();
--length: calc(sibling-index() * 7px);
--length-percentage: calc((sibling-index() * 8px) + (sibling-count() * 5%));
--color: color(srgb 0 calc(0.2 * sibling-index()) 0);
--list: 13 sibling-index();
}
to {
--time: 13s;
--angle: 13deg;
--resolution: 1dppx;
--percentage: 13%;
--number: 13;
--integer: 13;
--length: 13px;
--length-percentage: calc(13px + 7%);
--color: red;
--list: 29 sibling-index();
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--time"), "6s");
}, "Initially, the sibling-index() is 3 for --time");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--angle"), "90deg");
}, "Initially, the sibling-index() is 3 for --angle");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--resolution"), "3dppx");
}, "Initially, the sibling-index() is 3 for --resolution");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--percentage"), "150%");
}, "Initially, the sibling-index() is 3 for --percentage");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--number"), "3");
}, "Initially, the sibling-index() is 3 for --number");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--integer"), "3");
}, "Initially, the sibling-index() is 3 for --integer");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--length"), "21px");
}, "Initially, the sibling-index() is 3 for --length");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--length-percentage"), "calc(15% + 24px)");
}, "Initially, the sibling-index() is 3 for --length-percentage");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.6 0)");
}, "Initially, the sibling-index() is 3 for --color");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 3");
}, "Initially, the sibling-index() is 3 for --list");
rm.remove();
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--time"), "4s");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --time");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--angle"), "60deg");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --angle");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--resolution"), "2dppx");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --resolution");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--percentage"), "100%");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --percentage");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--number"), "2");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --number");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--integer"), "2");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --integer");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--length"), "14px");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --length");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--length-percentage"), "calc(10% + 16px)");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --length-percentage");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.4 0)");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --color");
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 2");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --list");
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing rotate during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
rotate: x calc(10deg * sibling-index());
}
to {
rotate: x 90deg;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).rotate, "x 30deg");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).rotate, "x 20deg");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing scale during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
scale: 0.7 calc(0.2 * sibling-index());
}
to {
scale: 0.3 2;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).scale, "0.7 0.6");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).scale, "0.7 0.4");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing transform during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
transform: translateX(calc(10px * sibling-index()));
}
to {
transform: none;
}
}
#target {
animation: --anim 1000s step-end;
}
</style>
<div>
<div id="rm"></div>
<div></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).transform, "matrix(1, 0, 0, 1, 30, 0)");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).transform, "matrix(1, 0, 0, 1, 20, 0)");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: sibling-index() changing value during @keyframes animation</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
@keyframes --anim {
from {
z-index: sibling-index();
}
to {
z-index: 1;
}
}
#target {
animation: --anim 1000s step-end;
position: relative;
width: 100px;
height: 100px;
background: red;
}
#abs {
position: absolute;
width: 100px;
height: 100px;
z-index: 3;
background: green;
}
</style>
<p>You should see a green square below.</p>
<div>
<div id="rm"></div>
<div id="abs"></div>
<div id="target"></div>
</div>
<script>
test(() => {
assert_equals(getComputedStyle(target).zIndex, "3");
}, "Initially, the sibling-index() is 3 for #target");
test(() => {
rm.remove();
assert_equals(getComputedStyle(target).zIndex, "2");
}, "Removing a preceding sibling of #target reduces the sibling-index()");
</script>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: Tree-scoped sibling-index()</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
#host1::part(--p) {
z-index: sibling-index();
/* Add 1 since widows does not accept 0 */
widows: calc(1 + sibling-count());
}
</style>
<div id="host1">
<template shadowrootmode="open">
<div></div>
<div></div>
<div id="t1" part="--p"></div>
</template>
</div>
<script>
test(() => {
const style = getComputedStyle(host1.shadowRoot.querySelector("#t1"));
assert_equals(style.zIndex, "0", "z-index should be 0");
assert_equals(style.widows, "1", "widows should be 1");
}, "sibling-index() and sibling-count() evaluates to 0 from outer tree with ::part");
</script>
<div>
<div></div>
<div></div>
<div id="t2">
<template shadowrootmode="open">
<style>
:host {
z-index: sibling-index();
widows: sibling-count();
}
</style>
</template>
</div>
<div></div>
<div></div>
</div>
<script>
test(() => {
const style = getComputedStyle(t2);
assert_equals(style.zIndex, "3", ":host is the third sibling");
assert_equals(style.widows, "5", ":host total sibling count is 5");
}, "sibling-index() and sibling-count() evaluate as normal from inner tree");
</script>