Tests: Import some CSS if() tests

This commit is contained in:
Callum Law
2026-03-01 23:43:53 +13:00
committed by Sam Atkins
parent 0c847e2560
commit c1add21be2
Notes: github-actions[bot] 2026-03-09 14:38:25 +00:00
10 changed files with 1497 additions and 0 deletions

View File

@@ -0,0 +1,770 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: CSS inline if() function</title>
<meta name="assert" content="Test inline if() function">
<link rel="help" href="https://drafts.csswg.org/css-values-5/#if-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<html>
<style>
@property --string {
syntax: "<string>";
inherits: true;
initial-value: "";
}
@property --color {
syntax: "<color>";
inherits: true;
initial-value: blue;
}
@property --length {
syntax: "<length>";
inherits: false;
initial-value: 3px;
}
@property --length-inherited {
syntax: "<length>";
inherits: true;
initial-value: 3px;
}
@property --percentage {
syntax: "<percentage>";
inherits: true;
initial-value: 30%;
}
@property --number {
syntax: "<number>";
inherits: true;
initial-value: 3;
}
@property --angle {
syntax: "<angle>";
inherits: true;
initial-value: 3deg;
}
@property --time {
syntax: "<time>";
inherits: true;
initial-value: 3s;
}
@property --resolution {
syntax: "<resolution>";
inherits: true;
initial-value: 3dpi;
}
div {
font-size: 30px;
}
.outer {
--inherited: outer_value;
--number: 30;
--x: 11;
--length: 30px;
--length-inherited: 30px;
}
.inner {
--inherited: inner_value;
}
</style>
<body>
<div class="outer">
<div id="if" class="inner" data-foo="30px" data-attr="attr"></div>
</div>
</body>
</html>
<script>
function set_custom_properties(customPropertiesData) {
customPropertiesData.forEach(entry => {
const [customPropertyName, customPropertyValue] = entry;
document.getElementById("if").style.setProperty(customPropertyName, customPropertyValue);
});
}
function clear_custom_properties(customPropertiesData) {
customPropertiesData.forEach(entry => {
const [customPropertyName, customPropertyValue] = entry;
document.getElementById("if").style.removeProperty(customPropertyName);
});
}
function test_if_with_custom_properties(ifValue, customPropertiesData, expectedValue) {
set_custom_properties(customPropertiesData);
var elem = document.getElementById("if");
var property = "--property";
elem.style.setProperty(property, ifValue);
test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property),
expectedValue,
'"' + ifValue + '" should be substituted to "' + expectedValue + '".');
});
clear_custom_properties(customPropertiesData);
elem.style.removeProperty(property);
}
function test_if(ifValue, expectedValue) {
test_if_with_custom_properties(ifValue, [], expectedValue);
}
// Valid if() with unregistered custom properties in conditions.
test_if_with_custom_properties('if(style(--x: 3): true_value)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if( style( --x : 3 ) : true_value )', [['--x', '3']], 'true_value ');
test_if_with_custom_properties('if(style(--x): true_value;)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if( style(--x) : true_value; )', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if(style(--x: 3): true_value;)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if(style(--x: 0): true_value;)', [['--x', '0']], 'true_value');
test_if_with_custom_properties('if(style(--x: 0): ;)', [['--x', '0']], '');
test_if_with_custom_properties('if(style(--x: 0): )', [['--x', '0']], '');
test_if_with_custom_properties('if(style(--x: blue): true_value;)', [['--x', 'blue']], 'true_value');
test_if_with_custom_properties('if(style(--x: 3): true_value; else: false_value)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if(style(--non-existent: var(--non-existent)): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(--x: initial): true_value; else: false_value)', [['--x', '']], 'false_value');
test_if_with_custom_properties('if(style(--x: initial): true_value; else: false_value)', [['--x', 'initial']], 'true_value');
test_if_with_custom_properties('if(style(--non-existent: initial): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(--x: initial): true_value; else: false_value)', [['--x', '3']], 'false_value');
test_if_with_custom_properties(`if(style(--inherited: inherit): true_value;
else: false_value)`,
[['--inherited', 'outer_value']],
'true_value');
test_if_with_custom_properties(`if(style(--inherited: inherit): true_value;
else: false_value)`,
[['--inherited', 'inherit']],
'true_value');
test_if_with_custom_properties(`if(style(--inherited: inherit): true_value;
else: false_value)`,
[['--inherited', 'unset']],
'true_value');
test_if_with_custom_properties(`if(style(--inherited: inherit): true_value;
else: false_value)`,
[['--inherited', 'inner_value']],
'false_value');
test_if_with_custom_properties(`if(style(--inherited: unset): true_value;
else: false_value)`,
[['--inherited', 'outer_value']],
'true_value');
test_if_with_custom_properties(`if(style(--inherited: unset): true_value;
else: false_value)`,
[['--inherited', 'unset']],
'true_value');
test_if_with_custom_properties(`if(style(--inherited: unset): true_value;
else: false_value)`,
[['--inherited', 'inner_value']],
'false_value');
test_if_with_custom_properties(`if(style(--inherited: unset): true_value;
else: false_value)`,
[['--inherited', 'inherit']],
'true_value');
test_if_with_custom_properties('if(style(--x: 3): true_value; else:false_value)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if(style(--x: 3): true_value; else: false_value;)', [['--x', '3']], 'true_value');
test_if_with_custom_properties('if(style(--x: 0): true_value; else: false_value)', [['--x', '3']], 'false_value');
test_if_with_custom_properties('if( style( --x: 0 ) : true_value ; else : false_value)', [['--x', '3']], 'false_value');
test_if_with_custom_properties('if(style(not (--unknown)): true_value;)', [['--x', '3']], 'true_value');
test_if_with_custom_properties(`if(style(--x: 0): true_value;
else: )`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(style(--x: 3): ;
else: false_value)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(style(--non-existent: 0): true_value;
else: false_value)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'calc(1 + 2)']],
'false_value');
test_if_with_custom_properties(`if(style(--x: calc(1 + 2)): true_value;
else: false_value)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--non-existent): true_value;
else: false_value;)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(style(--x)): true_value;
else: false_value;)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(var(--x)): true_value;
else: false_value;)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--x: revert): true_value;
else: false_value)`,
[['--x', '11']],
'false_value');
test_if_with_custom_properties(`if(style(--x: revert-layer): true_value;
else: false_value)`,
[['--x', '']],
'false_value');
test_if_with_custom_properties(`if(style(--x):a)if(style(--x):b)`,
[['--x', '3']],
'a/**/b');
test_if_with_custom_properties(`if(style(--x!): true_value;
else: false_value)`,
[['--x', '3']],
'false_value');
test_if_with_custom_properties(`if(style(color: green): true_value;
else: false_value)`,
[],
'false_value');
test_if_with_custom_properties(`if(not style(--non-existent): true_value;
else: false_value)`,
[],
'true_value');
test_if_with_custom_properties(`if(not style(--x: 0): true_value;
else: false_value)`,
[['--x', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--x: 0) and style(--y: 3): true_value;
else: false_value)`,
[['--x', '3'], ['--y', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--x: 3) and style(--y: 3): true_value;
else: false_value)`,
[['--x', '3'], ['--y', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--x: 0) or style(--y: 3): true_value;
else: false_value)`,
[['--x', '3'], ['--y', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--x: 0) or (style(--y: 3) and style(--z: 3)): true_value;
else: false_value)`,
[['--x', '3'], ['--y', '3'], ['--z', '3']],
'true_value');
// Valid if() with multiple conditions with unregistered custom properties
test_if_with_custom_properties(`if(style(--non-existent): value1;
style(--x): value2;
else: value3;)`,
[['--x', '3']],
'value2');
test_if_with_custom_properties(`if(style(--x: 1): value1;
style(--x: 2): value2;
style(--x: 3): value3;)`,
[['--x', '3']],
'value3');
test_if_with_custom_properties(`if(style(--x: 1): value1;
style(--y: green): value2;
style(--z: 3px): value3;
else: value4;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'value4');
test_if_with_custom_properties(`if(style(--x: 1): value1;
else: value2;
style(--y: green): value3;
style(--z: 3px): value4;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'value2');
test_if_with_custom_properties(`if(style(--x: 1): value1;
else: value2;
style(--y: green): value3;
style(--z: 3px): value4;
else: value5;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'value2');
test_if_with_custom_properties(`if(style(--x: 3): value1;
style(--y: green): value2;
style(--z: 3px): value3;
else: value4;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'value1');
test_if_with_custom_properties(`if(style((--x: 3) and (not (--y: red) or (--z: 10px))): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'green'], ['--z', '11px']],
'false_value');
test_if_with_custom_properties(`if(style(--x: 3): value1;
style((--x: 3) and (not (--y: red) or (--z: 10px))): value2;
else: value3;)`,
[['--x', '3'], ['--y', 'green'], ['--z', '11px']],
'value1');
// Valid if() with complicated style queries
test_if_with_custom_properties(`if(style((--x: 1) and (--y: green) and (--z: 3px)): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'false_value');
test_if_with_custom_properties(`if(style((--x: 3) and (--y: red) and (--z: 10px)): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'true_value');
test_if_with_custom_properties(`if(style((--x: 3) and ((not (--y: red)) or (--z: 10px))): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '11px']],
'false_value');
test_if_with_custom_properties(`if(style((--x: 3) and ((not (--y: red)) or (--z: 10px))): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'true_value');
test_if_with_custom_properties(`if(style((--x: 3) and ((not (--y: red)) or (--z: 10px))): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'green'], ['--z', '11px']],
'true_value');
test_if_with_custom_properties(`if(style((--x: 3) and (not (--y: red))): value1;
style(--z: 15px): value2;
else: value3;)`,
[['--x', '3'], ['--y', 'green'], ['--z', '11px']],
'value1');
test_if_with_custom_properties(`if(style((--x: 3) and (not (--y: red))): value1;
style(--z: 15px): value2;
else: value3;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '15px']],
'value2');
test_if_with_custom_properties(`if(style((--x: 3) and (not (--y: red))): value1;
style(--z: 15px): value2;
else: value3;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '11px']],
'value3');
// Valid if() with registered custom properties in conditions.
test_if_with_custom_properties(`if(style(--string: "success"): true_value;
else: false_value)`,
[['--string', '"success"']],
'true_value');
test_if_with_custom_properties(`if(style(--string: "success"): true_value;
else: false_value)`,
[['--string', '"fail"']],
'false_value');
test_if_with_custom_properties(`if(style(--number: 1): true_value;
else: false_value)`,
[['--number', '1']],
'true_value');
test_if_with_custom_properties(`if(style(--number: 3): true_value;
else: false_value)`,
[['--number', '1']],
'false_value');
test_if_with_custom_properties(`if(style(--number: calc(1 + 2)): true_value;
else: false_value)`,
[['--number', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--number: 3): true_value;
else: false_value)`,
[['--number', 'calc(1 + 2)']],
'true_value');
test_if_with_custom_properties(`if(style(--number: revert): true_value;
else: false_value)`,
[['--number', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--number: revert-layer): true_value;
else: false_value)`,
[['--number', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--length: 1px): true_value;
else: false_value)`,
[['--length', '1px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 3): true_value;
else: false_value)`,
[['--length', '3px']],
'false_value');
test_if_with_custom_properties(`if(style(--length: calc(1px + 2px)): true_value;
else: false_value)`,
[['--length', '3px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 3px): true_value;
else: false_value)`,
[['--length', 'calc(1px + 2px)']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 1em): true_value;
else: false_value)`,
[['--length', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 30px): true_value;
else: false_value)`,
[['--length', '1em']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 3): true_value;
else: false_value)`,
[],
'false_value');
test_if_with_custom_properties(`if(style(--length: initial): true_value;
else: false_value)`,
[['--length', '3px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: initial): true_value;
else: false_value)`,
[],
'true_value');
test_if_with_custom_properties(`if(style(--length: inherit): true_value;
else: false_value)`,
[],
'false_value');
test_if_with_custom_properties(`if(style(--length: inherit): true_value;
else: false_value)`,
[['--length', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: unset): true_value;
else: false_value)`,
[['--length', '3px']],
'true_value');
test_if_with_custom_properties(`if(style(--length-inherited: inherit): true_value;
else: false_value)`,
[],
'true_value');
test_if_with_custom_properties(`if(style(--length-inherited: inherit): true_value;
else: false_value)`,
[['--length-inherited', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--length-inherited: inherit): true_value;
else: false_value)`,
[['--length-inherited', 'unset']],
'true_value');
test_if_with_custom_properties(`if(style(--length-inherited: unset): true_value;
else: false_value)`,
[['--length-inherited', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--length-inherited: unset): true_value;
else: false_value)`,
[['--length-inherited', 'inherit']],
'true_value');
test_if_with_custom_properties(`if(style(--percentage: 30%): true_value;
else: false_value)`,
[['--percentage', '30%']],
'true_value');
test_if_with_custom_properties(`if(style(--percentage: 90px): true_value;
else: false_value)`,
[['--percentage', '30%']],
'false_value');
test_if_with_custom_properties(`if(style(--percentage: 30px): true_value;
else: false_value)`,
[['--percentage', '30%']],
'false_value');
test_if_with_custom_properties(`if(style(--percentage: 90%): true_value;
else: false_value)`,
[['--percentage', '3px']],
'false_value');
test_if_with_custom_properties(`if(style(--color: green): true_value;
else: false_value)`,
[['--color', 'green']],
'true_value');
test_if_with_custom_properties(`if(style(--color: rgb(0, 128, 0)): true_value;
else: false_value)`,
[['--color', 'green']],
'true_value');
test_if_with_custom_properties(`if(style(--color: green): true_value;
else: false_value)`,
[['--color', 'rgb(0, 128, 0)']],
'true_value');
test_if_with_custom_properties(`if(style(--color: #008000): true_value;
else: false_value)`,
[['--color', 'green']],
'true_value');
test_if_with_custom_properties(`if(style(--color: green): true_value;
else: false_value)`,
[['--color', '#008000']],
'true_value');
test_if_with_custom_properties(`if(style(--color: green): true_value;
else: false_value)`,
[['--color', 'blue']],
'false_value');
// Valid if() with substitution function in conditions.
test_if_with_custom_properties(`if(style(--x: var(--x)): true_value;
else: false_value)`,
[['--x', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--non-existent: var(--non-existent)): true_value;
else: false_value)`,
[],
'false_value');
test_if_with_custom_properties(`if(style(--x: var(--y)): true_value;
else: false_value)`,
[['--x', '3'], ['--y', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--x: var(--y)): true_value;
else: false_value)`,
[['--x', '1'], ['--y', '3']],
'false_value');
test_if_with_custom_properties(`if(style(--x: attr(data-foo type(<length>))): true_value;
else: false_value)`,
[['--x', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--x: attr(data-foo)): true_value;
else: false_value)`,
[['--x', '"30px"']],
'true_value');
test_if_with_custom_properties(`if(style(--length: attr(data-foo type(<length>))): true_value;
else: false_value)`,
[['--length', '30px']],
'true_value');
test_if_with_custom_properties(`if(style(--length: attr(data-foo type(<length>))): true_value;
else: false_value)`,
[['--length', '30']],
'false_value');
// Valid if() with substitution function in custom properties.
test_if_with_custom_properties(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'var(--y)'], ['--y', '3']],
'true_value');
test_if_with_custom_properties(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'var(--y)'], ['--y', '1']],
'false_value');
test_if_with_custom_properties(`if(style(--x: "30px"): true_value;
else: false_value)`,
[['--x', 'attr(data-foo)']],
'true_value');
test_if_with_custom_properties(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'attr(data-foo)']],
'false_value');
test_if_with_custom_properties(`if(style(--length: 30px): true_value;
else: false_value)`,
[['--length', 'attr(data-foo type(<length>))']],
'true_value');
test_if_with_custom_properties(`if(style(--length: 30): true_value;
else: false_value)`,
[['--length', 'attr(data-foo type(<length>))']],
'false_value');
// style() queries with range syntax in the condition, literals on both sides of equation
test_if_with_custom_properties('if(style(5 > 3): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(0 = 0): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(0 = 0px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(0 = 0%): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(0 < 3px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(5 > 3 !invalid): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(5 !invalid > 3): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(5 > 3 !): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(5.5 > 3): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(5.5 > 3.3): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(10em > 3px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(1em > 1px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(7px > 3px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(3px > 3px): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(3turn > 3deg): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(3turn <= 3deg): true_value; else: false_value)', [], 'false_value');
test_if_with_custom_properties('if(style(3% >= 3%): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(3s > 3ms): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(3dppx > 96dpi): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties(`if(style(--length > initial): true_value;
else: false_value)`,
[['--length', '5px']],
'false_value');
test_if_with_custom_properties('if(style(--x = initial): true_value; else: false_value)', [['--x', 'initial']], 'false_value');
// style() queries with range syntax in the condition, simple custom properties in the condition
test_if_with_custom_properties('if(style(--x <= 3): true_value; else: false_value)',
[['--x', '3']],
'true_value');
test_if_with_custom_properties('if(style(--x >= --y): true_value; else: false_value)',
[['--x', '3'], ['--y', '3']],
'true_value');
test_if_with_custom_properties('if(style(--length > 3px): true_value; else: false_value)',
[['--length', '11px']],
'true_value');
test_if_with_custom_properties('if(style(--x > 3px): true_value; else: false_value)',
[['--x', '11px']],
'true_value');
test_if_with_custom_properties('if(style(--number >= 3): true_value; else: false_value)',
[['--number', '3']],
'true_value');
test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)',
[['--x', '3']],
'true_value');
test_if_with_custom_properties('if(style(--percentage > 3%): true_value; else: false_value)',
[['--percentage', '5%']],
'true_value');
test_if_with_custom_properties('if(style(--x > 3%): true_value; else: false_value)',
[['--x', '5%']],
'true_value');
test_if_with_custom_properties('if(style(--angle < 1turn): true_value; else: false_value)',
[['--angle', '1deg']],
'true_value');
test_if_with_custom_properties('if(style(--x < 1turn): true_value; else: false_value)',
[['--x', '1deg']],
'true_value');
test_if_with_custom_properties('if(style(--time <= 1000ms): true_value; else: false_value)',
[['--time', '1s']],
'true_value');
test_if_with_custom_properties('if(style(var(--time) <= 1000ms): true_value; else: false_value)',
[['--time', '1s']],
'true_value');
test_if_with_custom_properties('if(style(--x <= 1000ms): true_value; else: false_value)',
[['--x', '1s']],
'true_value');
test_if_with_custom_properties('if(style(3dppx > --resolution): true_value; else: false_value)',
[['--resolution', '96dpi']],
'true_value');
test_if_with_custom_properties('if(style(3dppx > --x): true_value; else: false_value)',
[['--x', '96dpi']],
'true_value');
// style() queries with range syntax in the condition, invalid custom properties in the condition
test_if_with_custom_properties('if(style(--x + 1 >= --y): true_value; else: false_value)',
[['--x', '5'], ['--y', '3']],
'false_value');
test_if_with_custom_properties('if(style(--x >= --y + 1): true_value; else: false_value)',
[['--x', '5'], ['--y', '3']],
'false_value');
test_if_with_custom_properties('if(style(calc(--x + 1) >= --y): true_value; else: false_value)',
[['--x', '5'], ['--y', '3']],
'false_value');
test_if_with_custom_properties('if(style(--x >= calc(--y + 1)): true_value; else: false_value)',
[['--x', '5'], ['--y', '3']],
'false_value');
// style() queries with range syntax in the condition, custom properties with functions in the condition
test_if_with_custom_properties('if(style(--x >= calc(3px + 3px)): true_value; else: false_value)',
[['--x', '7px']],
'true_value');
test_if_with_custom_properties('if(style(calc(var(--x) + 1) >= var(--y)): true_value; else: false_value)',
[['--x', '5'], ['--y', '3']],
'true_value');
test_if_with_custom_properties('if(style(var(--x) >= --x): true_value; else: false_value)',
[['--x', '3']],
'true_value');
// style() queries with range syntax in the condition, incompatible types in the range.
test_if_with_custom_properties('if(style(3px > 3): true_value; else: false_value)',
[],
'false_value');
test_if_with_custom_properties('if(style(3em > 3deg): true_value; else: false_value)',
[],
'false_value');
test_if_with_custom_properties('if(style(1px >= 1%) or style(1px <= 1%): true_value; else: false_value)',
[],
'false_value');
test_if_with_custom_properties('if(style(--length > 3): true_value; else: false_value)',
[['--length', '11em']],
'false_value');
test_if_with_custom_properties('if(style(--number > 3px): true_value; else: false_value)',
[['--number', '11']],
'false_value');
test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)',
[['--x', '3px']],
'false_value');
test_if_with_custom_properties(`if(style(--length >= 30px): true_value;
else: false_value)`,
[['--length', 'attr(data-foo type(<length>))']],
'true_value');
// style() queries with range syntax in the condition, double range
test_if_with_custom_properties('if(style(10px <= 10px < 11px): true_value; else: false_value)', [], 'true_value');
test_if_with_custom_properties('if(style(3 < --x <= 5): true_value; else: false_value)',
[['--x', '5']],
'true_value');
test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)',
[['--x', '3'], ['--y', '3'], ['--z', '3']],
'false_value');
test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)',
[['--x', '3'], ['--y', '3'], ['--z', '1']],
'true_value');
// media() queries in the condition
test_if(`if(media(max-width: 1px): true_value;
else: false_value)`,
'false_value');
test_if(`if(media((max-width: 1px)): true_value;
else: false_value)`,
'false_value');
test_if(`if(media(height <= 999999px): true_value;
else: false_value)`,
'true_value');
test_if(`if(media(min-color: 1): true_value;
else: false_value)`,
'true_value');
test_if(`if(media((min-color: 1) and (height <= 999999px)): true_value;
else: false_value)`,
'true_value');
// supports() queries in the condition
test_if(`if(supports((display: table-cell)): true_value;
else: false_value)`,
'true_value');
test_if(`if(supports(display: table-cell): true_value;
else: false_value)`,
'true_value');
test_if(`if(supports(display): true_value;
else: false_value)`,
'false_value');
test_if(`if(supports(display: invalid): true_value;
else: false_value)`,
'false_value');
test_if(`if(supports(not (transform-origin: 10em 10em 10em)): true_value;
else: false_value)`,
'false_value')
test_if(`if(supports(selector(h2 > p)): true_value;
else: false_value)`,
'true_value');
test_if(`if(supports((selector(h2 > p))): true_value;
else: false_value)`,
'true_value');
test_if(`if(supports((display: table-cell) and (display: list-item) and (display: contents)): true_value;
else: false_value)`,
'true_value');
test_if(`if(supports((display: invalid) and (display: list-item) and (display: contents)): true_value;
else: false_value)`,
'false_value');
test_if(`if(supports((display: table-cell) and (invalid: list-item) and (display: contents)): true_value;
else: false_value)`,
'false_value');
// media(), style() and supports() queries in the condition
test_if(`if((media(min-width: 1px)) or (style(--x)): true_value;
else: false_value)`,
'true_value');
test_if(`if((media(height <= 999999px)) and style(--non-existent): true_value;
else: false_value)`,
'false_value');
test_if(`if((media((min-color: 1) and (height <= 999999px))) and (style(--x)): true_value;
else: false_value)`,
'true_value');
test_if(`if((media((min-color: 8) and (height <= 600px)) and style(--x: 3px)) or supports(display: table-cell): true_value;
else: false_value)`,
'true_value');
// Invalid if() syntax
test_if_with_custom_properties('if()', [['--x', '3']], '');
test_if_with_custom_properties('if(style())', [['--x', '3']], '');
test_if_with_custom_properties('if(style(--x: 3) !)', [['--x', '3']], '');
test_if_with_custom_properties(`if(style(--x: 3) true_value;
else: false_value)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(style(--x: 3): true_value;
else: false_value!)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(!style(--x: 3): true_value;
else: false_value)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(style(--x) and invalid: true_value;
else: false_value)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(invalid or style(--x): true_value;
else: false_value)`,
[['--x', '3']],
'');
test_if_with_custom_properties(`if(style(not (--x: 5) or (--z: 10px)): true_value;
else: false_value;)`,
[['--x', '3'], ['--y', 'green'], ['--z', '11px']],
'');
// IACVT
test_if_with_custom_properties('if(style(--x: 0): true_value;)', [['--x', '3']], '');
test_if_with_custom_properties('if(style(--non-existent): true_value;)', [['--x', '3']], '');
test_if_with_custom_properties('if(style(--non-existent: 3): true_value;)', [['--x', '3']], '');
test_if_with_custom_properties('if(style(--invalid): value)', [], '');
test_if_with_custom_properties('if(style(--invalid): var(--x))', [['--x', 'true_value']], '');
test_if_with_custom_properties(`if(style(--x: 1): value1;
style(--y: green): value2;
style(--z: 3px): value3;)`,
[['--x', '3'], ['--y', 'red'], ['--z', '10px']],
'');
// Equality of attr-tainted if()
test_if_with_custom_properties('if(style(--x: attr(data-attr type(*))): true_value; else: false_value)', [['--x', 'attr']], 'true_value');
test_if_with_custom_properties('if(style(--x: attr): true_value; else: false_value)', [['--x', 'attr(data-attr type(*))']], 'true_value');
</script>

View File

@@ -0,0 +1,261 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: CSS if() function cycles</title>
<meta name="assert" content="Test cycles in if() function">
<link rel="help" href="https://drafts.csswg.org/css-values-5/#if-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="attr"></div>
<div id="expected"></div>
<body>
<div id="if"></div>
</body>
<script>
function set_custom_properties(customPropertiesData) {
customPropertiesData.forEach(entry => {
const [customPropertyName, customPropertyValue] = entry;
document.getElementById("if").style.setProperty(customPropertyName, customPropertyValue);
});
}
function test_if(ifValue, customPropertiesData, expectedValue) {
set_custom_properties(customPropertiesData);
var elem = document.getElementById("if");
var property = "--prop";
elem.style.setProperty(property, ifValue);
test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property),
expectedValue,
'"' + ifValue + '" should be substituted to "' + expectedValue + '".');
});
elem.style.setProperty(property, '');
}
var ifElem = document.getElementById("if");
// var() cycle in declaration value
//
// Note: 'test_if()' places the 'if()' in a custom property '--prop'.
test_if(`if(style(--x: 3): var(--prop); else: value)`,
[['--x', '3']],
'');
test_if(`if(style(--x: 3): value; else: var(--prop))`,
[['--x', '0']],
'');
// attr() cycle in declaration value
ifElem.setAttribute('data-foo', 'var(--prop)');
test_if(`if(style(--x: 3): attr(data-foo type(*)); else: value)`,
[['--x', '3']],
'');
ifElem.setAttribute('data-foo', 'var(--prop)');
test_if(`if(style(--x: 3): value; else: attr(data-foo type(*)))`,
[['--x', '0']],
'');
// Cycle in the condition
//
// Note: 'test_if()' places the 'if()' in a custom property '--prop'.
test_if(`if(style(--prop): var(--prop); else: value)`,
[],
'');
test_if(`if(style(--x): var(--prop); else: value)`,
[['--x', 'var(--prop)']],
'');
test_if(`if(style(--prop: 3): true_value;
else: false_value)`,
[['--prop', '3']],
'');
test_if(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'var(--prop)']],
'');
test_if(`if(style(not (--prop)): true_value;
else: false_value)`,
[],
'');
test_if(`if(style(not (--x: var(--y))): true_value;
else: false_value)`,
[['--x', '11'], ['--y', 'var(--prop)']],
'');
test_if(`if(style((--prop) or (--y)): true_value;
else: false_value)`,
[['--y', '3']],
'');
test_if(`if(style((--prop) and (--y)): true_value;
else: false_value)`,
[['--y', '3']],
'');
test_if(`if(style(--x: var(--prop)): true_value;
else: false_value)`,
[['--x', '3']],
'');
test_if(`if(style(--x: var(--y)): true_value;
else: false_value)`,
[['--x', '3'], ['--y', 'var(--prop)']],
'');
ifElem.setAttribute('data-foo', 'var(--prop)');
test_if(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'attr(data-foo type(*))']],
'');
ifElem.setAttribute('data-foo', 'var(--prop)');
test_if(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'var(--y)'], ['--y', 'attr(data-foo type(*))']],
'');
ifElem.setAttribute('data-foo', 'var(--prop)');
test_if(`if(style(--x: attr(data-foo type(*))): true_value;
else: false_value)`,
[['--x', '30px']],
'');
// var() cycle in condition's custom property
test_if(`if(style(--y): true_value;
else: false_value)`,
[['--y', 'var(--x)'], ['--x', 'var(--y)']],
'false_value');
test_if(`if(style(not (--x: var(--y))): true_value;
else: false_value)`,
[['--x', '11'], ['--y', 'var(--y)']],
'true_value');
test_if(`if(style(not (--x: var(--y))): true_value;
else: false_value)`,
[['--x', '11'], ['--y', 'var(--y)']],
'true_value');
test_if(`if(style((--x) or (--y)): true_value;
else: false_value)`,
[['--x', 'var(--x)'], ['--y', '3']],
'true_value');
test_if(`if(style((--x) and (--y)): true_value;
else: false_value)`,
[['--x', 'var(--x)'], ['--y', '3']],
'false_value');
test_if(`if(style((not (--z)) or (--y)): true_value;
else: false_value)`,
[['--z', 'var(--x)'], ['--x', 'var(--z)'], ['--y', '3']],
'true_value');
test_if(`if(style((not (--z)) and (--y)): true_value;
else: false_value)`,
[['--z', 'var(--x)'], ['--x', 'var(--z)'], ['--y', '3']],
'true_value');
// cycle with var() and attr() in condition's custom property
ifElem.setAttribute('data-foo', 'var(--x)');
test_if(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'attr(data-foo type(*))']],
'false_value');
ifElem.setAttribute('data-foo', 'var(--y)');
test_if(`if(style(--x: 3): true_value;
else: false_value)`,
[['--x', 'var(--y)'], ['--y', 'attr(data-foo type(*))']],
'false_value');
// var() cycle in condition specified value
test_if(`if(style(--x: var(--y)): true_value;
else: false_value)`,
[['--x', '3'], ['--y', 'var(--z)'], ['--z', 'var(--y)']],
'false_value');
test_if(`if(style(--x: var(--y)): true_value;
else: false_value)`,
[['--x', '3'], ['--y', 'var(--y)']],
'false_value');
// attr() cycle in condition specified value
ifElem.setAttribute('data-foo', 'attr(data-foo type(*))');
test_if(`if(style(--x: attr(data-foo type(*))): true_value;
else: false_value)`,
[['--x', '30px']],
'false_value');
ifElem.setAttribute('data-foo', '30px');
test_if(`if(style(--x: attr(data-foo, var(--y))): true_value;
else: false_value)`,
[['--x', '"30px"'], ['--y', 'var(--y)']],
'true_value');
// self cycle in unused condition
test_if(`if(style(--x: 0): value1; style(--prop): value2)`,
[['--x', '0']],
'value1');
test_if(`if(style(--x: 3): value1;
style(--y: 3): value2;
else: value3)`,
[['--x', '3'], ['--y', 'var(--prop)']],
'value1');
// cycle in unused condition
test_if(`if(style(--x: 0): value1; style(--y): value2)`,
[['--x', '0'], ['--y', 'var(--y)']],
'value1');
test_if(`if(style(--x: 3): value1;
style(--y: 3): value2;
else: value3)`,
[['--x', '3'], ['--y', 'var(--y)']],
'value1');
// var() cycle in unused declaration value
test_if(`if(style(--x: 0): var(--prop); else: value)`,
[['--x', '3']],
'value');
test_if(`if(style(--x: 0): value; else: var(--prop))`,
[['--x', '0']],
'value');
test_if(`if(style(--x: 3): value1;
style(--y: 3): var(--prop);
else: value3)`,
[['--x', '3'], ['--y', '0']],
'value1');
test_if(`if(style(--x: 3): var(--prop);
style(--y: 3): var(--prop);
else: value3)`,
[['--x', '0'], ['--y', '0']],
'value3');
// no cycle
test_if(`if(style(--x: 3): var(--x);
else: value)`,
[['--x', '3']],
'3');
test_if(`if(style(--x: var(--y)): var(--y);
else: value)`,
[['--x', '3'], ['--y', '3']],
'3');
test_if(`if(style(--x: var(--x)): true_value;
else: false_value)`,
[['--x', '3']],
'true_value');
test_if(`if(style(--non-existent: var(--non-existent)): true_value;
else: false_value)`,
[],
'false_value');
test_if(`if(style(--x: 3): true_value;
else: var(--x))`,
[['--x', '1']],
'1');
test_if(`if(style(--x: var(--x)): value1;
style(--x: 3): value2;
else: value3;)`,
[['--x', '3']],
'value1');
test_if(`if(style(--x: var(--y)): value1;
style(--z: 3): value2;
else: value3;)`,
[['--x', 'var(--y)'], ['--y', 'var(--y)'], ['--z', '3']],
'value2');
test_if(`if(style(--z: var(--y)): value1;
style(--z: 3): value2;
else: value3;)`,
[['--x', 'var(--y)'], ['--y', 'var(--y)'], ['--z', '3']],
'value2');
</script>

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: if() media() condition invalidation</title>
<meta name="assert" content="Test if() media() condition invalidation">
<link rel="help" href="https://drafts.csswg.org/css-values-5/#if-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
iframe {
width: 50px;
height: 50px;
}
</style>
<iframe id="iframe" srcdoc="
<div id=target></div>
<style>
#target {
--actual: if(media((height < 100px) or ((height >= 200px) and (height < 300px))): true_value; else: false_value;);
}
</style>
"></iframe>
<script>
function waitForLoad(w) {
return new Promise(resolve => w.addEventListener('load', resolve));
}
promise_test(async () => {
await waitForLoad(window);
const target = iframe.contentDocument.querySelector('#target');
let actualValue = () => getComputedStyle(target).getPropertyValue('--actual');
assert_equals(actualValue(), 'true_value', '--actual before resize');
// [<height of frame>, <expected function result>]
let data = [
['100px', 'false_value'],
['200px', 'true_value'],
['300px', 'false_value']
];
for (let d of data) {
iframe.style.height = d[0];
let expected = d[1];
assert_equals(actualValue(), expected, `--actual after resize to ${d[0]}`);
}
});
</script>

View File

@@ -0,0 +1,20 @@
<!-- quirks mode -->
<title>CSS Values and Units Test: CSS inline if() function supports() in quirks mode</title>
<meta name="assert" content="Test inline if() function with supports() query in quirks mode">
<link rel="help" href="https://drafts.csswg.org/css-values-5/#if-notation">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
div {
color: red;
--x: if(supports(width: 30): true_value; else: false_value;)
}
</style>
<div id="if">test</div>
<script>
setup({ single_test: true });
var elem = document.getElementById("if");
let val = window.getComputedStyle(elem).getPropertyValue("--x");
assert_equals(val, "true_value");
done();
</script>

View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: random() in if()</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#random">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../css/support/computed-testcommon.js"></script>
<body>
</body>
<style id="style">
@property --number {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
@property --number2 {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
div {
--random1: random(1, 10);
--random2: random(11, 30);
}
</style>
<script>
// Since actual and expected values are generated randomly, `assert_equals()`
// does not generate deterministic test failure output. Chrome relies on test
// failure output to be deterministic and stable for failing test expectations.
function test_random_equals(actual, expected, message = "Random values should be equal") {
assert_true(actual == expected, message);
}
function test_random_not_equals(actual, expected, message = "Random values should be equal") {
assert_false(actual == expected, message);
}
function test_value_is_not_initial(value) {
assert_false(value == 0);
}
test(() => {
const holder = document.createElement('div');
document.body.appendChild(holder);
try {
const el = document.createElement('div');
el.style.setProperty('--unregistered', 'if(style(random(1, 10) < random(11, 30)): true; else: false;)');
holder.appendChild(el);
const elComputedValue = getComputedStyle(el).getPropertyValue('--unregistered');
assert_equals(elComputedValue, 'false');
} finally {
document.body.removeChild(holder);
}
}, `random() should not be allowed in if() style() condition`);
test(() => {
const holder = document.createElement('div');
document.body.appendChild(holder);
try {
const el = document.createElement('div');
el.style.setProperty('--unregistered', 'if(style(var(--random1) < var(--random2)): true; else: false;)');
holder.appendChild(el);
const elComputedValue = getComputedStyle(el).getPropertyValue('--unregistered');
assert_equals(elComputedValue, 'false');
} finally {
document.body.removeChild(holder);
}
}, `random() in var() should not be allowed in if() style() condition`);
test(() => {
const holder = document.createElement('div');
document.body.appendChild(holder);
try {
const el = document.createElement('div');
el.style.setProperty('--number', 'if(style(--unknown): ; else: random(1, 100000);)');
el.style.setProperty('--number2', 'if(style(--unknown): ; else: random(1, 100000);)');
holder.appendChild(el);
const elComputedValue1 = getComputedStyle(el).getPropertyValue('--number');
const elComputedValue2 = getComputedStyle(el).getPropertyValue('--number2');
test_value_is_not_initial(elComputedValue1);
test_value_is_not_initial(elComputedValue2);
test_random_not_equals(elComputedValue1, elComputedValue2);
} finally {
document.body.removeChild(holder);
}
}, `random() with different property names should not be shared in if() declaration value`);
test(() => {
const holder = document.createElement('div');
document.body.appendChild(holder);
try {
const el1 = document.createElement('div');
el1.style.setProperty('--number', 'if(style(--unknown): ; else: random(element-shared, 1, 100000);)');
holder.appendChild(el1);
const el2 = document.createElement('div');
el2.style.setProperty('--number', 'if(style(--unknown): ; else: random(element-shared, 1, 100000);)');
holder.appendChild(el2);
const elComputedValue1 = getComputedStyle(el1).getPropertyValue('--number');
const elComputedValue2 = getComputedStyle(el2).getPropertyValue('--number');
test_value_is_not_initial(elComputedValue1);
test_value_is_not_initial(elComputedValue2);
test_random_equals(elComputedValue1, elComputedValue2);
} finally {
document.body.removeChild(holder);
}
}, `element-shared random() with same property name on different elements in if() declaration value should be equal`);
</script>