diff options
Diffstat (limited to 'testing/web-platform/tests/css/css-fonts/parsing/font-computed.html')
-rw-r--r-- | testing/web-platform/tests/css/css-fonts/parsing/font-computed.html | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html b/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html new file mode 100644 index 0000000000..ab2694d211 --- /dev/null +++ b/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html @@ -0,0 +1,251 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Fonts Module Level 4: getComputedStyle().font</title> +<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop"> +<meta name="assert" content="font computed value round-trips."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +<style> + #container { + font-weight: 800; + font-size: 40px; + } +</style> +</head> +<body> +<div id="container"> + <div id="target"></div> +</div> +<script> +'use strict'; + +// Firefox and Edge 18 serialize these as supplied. +// Blink and Safari have implementation-dependent or platform-dependent serializations. +function test_system_font(keyword) { + test(() => { + const target = document.getElementById('target'); + const previousValue = 'italic xx-large/0px fantasy'; + target.style.font = previousValue; + target.style.font = keyword; + const readValue = getComputedStyle(target).font; + assert_not_equals(readValue, '', 'font should be set'); + assert_not_equals(readValue, previousValue, 'font should be updated'); + target.style.font = previousValue; + target.style.font = readValue; + assert_equals(getComputedStyle(target).font, readValue, "serialization should round-trip"); + }, keyword + ' should be a supported system font.'); +} + +test_system_font('caption'); +test_system_font('icon'); +test_system_font('menu'); +test_system_font('message-box'); +test_system_font('small-caption'); +test_system_font('status-bar'); + +// a value other than normal +const generate_style = () => 'italic'; + +// value other than normal +const generate_variant = () => 'small-caps'; + +// values other than normal +const generate_weight = (() => { + const alternatives = [ + 'bold', + 'bolder', + 'lighter', + '100', + '900' + ]; + let counter = 0; + return () => alternatives[counter++ % alternatives.length]; +})(); + +const compute_weight = (() => { + const cache = {} + return (weight) => { + if (!(weight in cache)) { + const weight_reference = document.createElement('div'); + document.getElementById('container').appendChild(weight_reference); + weight_reference.style.fontWeight = weight; + cache[weight] = getComputedStyle(weight_reference).fontWeight; + weight_reference.remove(); + } + return cache[weight]; + } +})(); + +// values other than normal +const generate_stretch = (() => { + const alternatives = [ + 'ultra-condensed', + 'extra-condensed', + 'condensed', + 'semi-condensed', + 'semi-expanded', + 'expanded', + 'extra-expanded', + 'ultra-expanded' + ]; + let counter = 0; + return () => alternatives[counter++ % alternatives.length]; +})(); + +const generate_size = (() => { + const alternatives = [ + // <absolute-size> + 'xx-small', + 'medium', + 'xx-large', + + // <relative-size> + 'larger', + 'smaller', + + // <length-percentage> + '10px', + '20%', + 'calc(30% - 40px)', + ]; + let counter = 0; + return () => alternatives[counter++ % alternatives.length]; +})(); + +const generate_line_height = (() => { + const alternatives = [ + null, + 'normal', + '1.2', + 'calc(120% + 1.2em)' + ]; + let counter = 0; + return () => alternatives[counter++ % alternatives.length]; +})(); + +const generate_family = (() => { + const alternatives = [ + 'serif', + 'sans-serif', + 'cursive', + 'fantasy', + 'monospace', + 'Menu', + '"Non-Generic Example Family Name"' + ]; + let counter = 0; + return () => alternatives[counter++ % alternatives.length]; +})(); + +function test_specific(prefix) { + const reference = document.createElement('div'); + document.getElementById('container').appendChild(reference); + + let parts = []; + let canonical = []; + let style = null; + let variant = null; + let weight = null; + let stretch = null; + for (let entry of prefix) { + if (entry === 'style') { + style = generate_style(); + parts.push(style); + } else if (entry === 'variant') { + variant = generate_variant(); + parts.push(variant); + } else if (entry === 'weight') { + weight = generate_weight(); + parts.push(weight); + } else if (entry === 'stretch') { + stretch = generate_stretch(); + parts.push(stretch); + } else { + // normal + parts.push('normal'); + } + } + + if (style) { + canonical.push(style); + reference.style.fontStyle = style; + } + + if (variant) { + canonical.push(variant); + reference.style.fontVariant = style; + } + if (weight) { + canonical.push(compute_weight(weight)); + reference.style.fontWeight = style; + } + if (stretch) { + canonical.push(stretch); + reference.style.fontStretch = style; + } + + const size = generate_size(); + reference.style.fontSize = size; + const line_height = generate_line_height(); + if (line_height) { + parts.push(size + '/' + line_height); + reference.style.lineHeight = line_height; + } else { + parts.push(size); + } + + const family = generate_family(); + parts.push(family); + reference.style.fontFamily = family; + + if (!line_height || line_height === 'normal') { + canonical.push(getComputedStyle(reference).fontSize); + } else { + // Implementations differ on adjacent space when serializing '/' + // https://github.com/w3c/csswg-drafts/issues/4282 + canonical.push(getComputedStyle(reference).fontSize + ' / ' + getComputedStyle(reference).lineHeight); + } + + canonical.push(family); + + reference.remove(); + + test_computed_value('font', parts.join(' '), canonical.join(' ')); +} + +// Font style, variant, weight and stretch may appear in any order. +// Any or all may be omitted. Each accepts the keyword 'normal'. +// We generate every permutation of these four properties, treating +// the cases of a property value being omitted or being explicitly +// 'normal' as being distinct permutations from when the property +// has a value other than 'normal'. +function test_various(prefix) { + test_specific(prefix); + if (prefix.length === 4) { + // Font style, variant, weight and stretch may not appear + // more than once. + return; + } + + const alternatives = [ + 'normal', + 'style', + 'variant', + 'weight', + 'stretch' + ]; + for (let alternative of alternatives) { + // Since this is called recursively, check prefix for existing + // alternatives, otherwise we may have two styles or two variants, etc. + if (alternative === 'normal' || !prefix.includes(alternative)) + test_various(prefix.concat(alternative)); + } +} + +test_various([]); +</script> +</body> +</html> |