| <!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> |