blob: 855d9f383b2affe75f26a28e5668db0b1ee3e7bc [file] [log] [blame]
<!DOCTYPE html>
<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/utils.js"></script>
<style>
#divWithFontSizeSet, #parentDiv {
font-size: 10px;
}
</style>
<div id=divWithFontSizeSet></div>
<div id=parentDiv>
<div id=divWithFontSizeInherited></div>
</div>
<div id="ref"></div>
<script>
for (let element of [divWithFontSizeSet, divWithFontSizeInherited]) {
let id = element.id;
// Generate a property and temporarily set its value. Then call 'fn' with
// the name of the generated property.
function with_custom_property(reg, value, fn) {
let name = generate_property(reg);
// Because we want to include the parsing step, insert a stylesheet
// node with textContent.
let node = document.createElement('style');
node.textContent = `#${id} { ${name}:${value}; }`;
document.body.append(node);
try {
fn(name);
} finally {
node.remove();
}
}
function assert_computed_value(syntax, value, expected) {
with_custom_property(syntax, value, (name) => {
let actual = getComputedStyle(element).getPropertyValue(name);
assert_equals(actual, expected);
});
}
// Computes an absolute reference value for some length.
//
// E.g. to figure out how many pixels '10vh' is, do length_ref('10vh').
function length_ref(value, refnode = ref) {
try {
// The reference property 'min-height' is chosen arbitrarily, but
// avoid properties with "resolved value is used value"-behavior
// [1], as it may affect rounding, and custom properties do not
// have this behavior.
//
// [1] https://drafts.csswg.org/cssom/#resolved-values
const ref_property = 'min-height';
refnode.style = `${ref_property}: ${value}`;
return getComputedStyle(refnode).getPropertyValue(ref_property);
} finally {
refnode.style = '';
}
}
test(function() {
assert_computed_value('<length>', '12px', '12px');
assert_computed_value('<length>', '13vw', length_ref('13vw'));
assert_computed_value('<length>', '14em', '140px');
assert_computed_value('<length>', '15vmin', length_ref('15vmin'));
assert_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)'));
with_custom_property('<length>', '14em', (name) => {
assert_computed_value('<length>', `var(${name})`, '140px');
});
}, "<length> values are computed correctly for " + id);
test(function() {
assert_computed_value('<length-percentage>', '17em', '170px');
assert_computed_value('<length-percentage>', '18%', '18%');
assert_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(190px + -2%)');
}, "<length-percentage> values are computed correctly for " + id);
test(function() {
assert_computed_value('<length>#', '10px, 3em', '10px, 30px');
assert_computed_value('<length>#', '10px, 3em', '10px, 30px');
assert_computed_value('<length>#', '4em ,9px', '40px, 9px');
assert_computed_value('<length>#', '8em', '80px');
}, "<length># values are computed correctly for " + id);
test(function() {
assert_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', '));
assert_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(10px + 50%), 4px');
assert_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(37px + 13%)');
}, "<length-percentage># values are computed correctly for " + id);
test(function() {
assert_computed_value('<length>+', '10px 3em', '10px 30px');
assert_computed_value('<length>+', '4em 9px', '40px 9px');
}, "<length>+ values are computed correctly for " + id);
test(function() {
assert_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' '));
assert_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(10px + 50%) 4px');
}, "<length-percentage>+ values are computed correctly for " + id);
test(function() {
assert_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)');
assert_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)');
assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))');
assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)');
}, "<transform-function> values are computed correctly for " + id);
test(function() {
assert_computed_value('<integer>', '15', '15');
assert_computed_value('<integer>', 'calc(15 + 15)', '30');
assert_computed_value('<integer>', 'calc(2.4)', '2');
assert_computed_value('<integer>', 'calc(2.6)', '3');
assert_computed_value('<integer>', 'calc(2.6 + 3.1)', '6');
}, "<integer> values are computed correctly for " + id);
test(function() {
assert_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3');
}, "<integer>+ values are computed correctly for " + id);
test(function() {
assert_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)');
assert_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)');
assert_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)');
assert_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)');
assert_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)');
assert_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)');
assert_computed_value('<color>', 'plum', 'rgb(221, 160, 221)');
assert_computed_value('<color>', 'currentcolor', 'currentcolor');
}, "<color> values are computed correctly for " + id);
test(function() {
assert_computed_value('*', 'tomato', 'tomato');
assert_computed_value('tomato | plum', 'plum', 'plum');
assert_computed_value('tomato | plum | <color>', 'plum', 'plum');
}, "ident values that look like color keywords are not converted to colors" + id);
test(function() {
assert_computed_value('*', '-50grad', '-50grad');
assert_computed_value('<angle>', '180deg', '180deg');
assert_computed_value('<angle>', '400grad', '360deg');
assert_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg');
}, "<angle> values computed correctly for " + id);
test(function() {
assert_computed_value('*', '50s', '50s');
assert_computed_value('<time>', '1s', '1s');
assert_computed_value('<time>', '1000ms', '1s');
assert_computed_value('<time>', 'calc(1000ms + 1s)', '2s');
}, "<time> values computed correctly for " + id);
}
</script>