| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>CSS Fonts Module Level 4: parsing font with valid values</title> | |
| <link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop"> | |
| <meta name="assert" content="font supports the full grammar '[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-stretch-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar'."> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="/css/support/parsing-testcommon.js"></script> | |
| </head> | |
| <body> | |
| <div id="target"></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 = target.style.getPropertyValue('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(target.style.getPropertyValue('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'); | |
| // values other than normal | |
| const generate_style = (() => { | |
| const alternatives = [ | |
| 'italic', | |
| 'oblique' | |
| ]; | |
| let counter = 0; | |
| return () => alternatives[counter++ % alternatives.length]; | |
| })(); | |
| // 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]; | |
| })(); | |
| // 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', | |
| '"FB Armada"' | |
| ]; | |
| let counter = 0; | |
| return () => alternatives[counter++ % alternatives.length]; | |
| })(); | |
| function test_specific(prefix) { | |
| 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); | |
| if (variant) | |
| canonical.push(variant); | |
| if (weight) | |
| canonical.push(weight); | |
| if (stretch) | |
| canonical.push(stretch); | |
| const size = generate_size(); | |
| const lineHeight = generate_line_height(); | |
| if (lineHeight) { | |
| parts.push(size + '/' + lineHeight); | |
| if (lineHeight === 'normal') | |
| canonical.push(size); | |
| else | |
| canonical.push(size + ' / ' + lineHeight); | |
| } else { | |
| parts.push(size); | |
| canonical.push(size); | |
| } | |
| const family = generate_family(); | |
| parts.push(family); | |
| canonical.push(family); | |
| test_valid_value('font', parts.join(' '), canonical.join(' ')); | |
| } | |
| function test_various(prefix) { | |
| test_specific(prefix); | |
| if (prefix.length === 4) | |
| return; | |
| const alternatives = [ | |
| 'normal', | |
| 'style', | |
| 'variant', | |
| 'weight', | |
| 'stretch' | |
| ]; | |
| for (let alternative of alternatives) { | |
| if (alternative === 'normal' || !prefix.includes(alternative)) | |
| test_various(prefix.concat(alternative)); | |
| // else we would have two styles or two variants, etc. | |
| } | |
| } | |
| test_various([]); | |
| </script> | |
| </body> | |
| </html> |