summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-fonts/parsing/font-computed.html
diff options
context:
space:
mode:
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.html251
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>