tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

select-base-appearance-computed-style.html (6985B)


      1 <!DOCTYPE html>
      2 <link rel=author href="mailto:jarhar@chromium.org">
      3 <link rel=help href="https://github.com/w3c/csswg-drafts/issues/10857">
      4 <link rel=help href="https://github.com/w3c/csswg-drafts/issues/11486">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 
      8 <style>
      9 select, ::picker(select) {
     10  appearance: base-select;
     11 }
     12 #sibling {
     13  color: CanvasText;
     14  background-color: Canvas;
     15 }
     16 #parent {
     17  text-transform: uppercase;
     18  text-align: end;
     19 }
     20 </style>
     21 
     22 <div id=parent>
     23  <select>
     24    <button>button</button>
     25    <div id=parent-in-picker>
     26      <option>option</option>
     27      <optgroup>
     28        <legend>legend</legend>
     29        <option>option in optgroup</option>
     30      </optgroup>
     31    </div>
     32  </select>
     33  <div id=sibling>sibling</div>
     34 </div>
     35 <div id=initial></div>
     36 
     37 <script>
     38 const select = document.querySelector('select');
     39 const parent = document.getElementById('parent');
     40 const parentInPicker = document.getElementById('parent-in-picker');
     41 const sibling = document.getElementById('sibling');
     42 const intial = document.getElementById('initial');
     43 const button = document.querySelector('button');
     44 const option = document.querySelector('option');
     45 const optgroup = document.querySelector('optgroup');
     46 const legend = document.querySelector('legend');
     47 const optgroupOption = document.querySelector('optgroup > option');
     48 
     49 const canvas = getComputedStyle(sibling).backgroundColor;
     50 const canvasText = getComputedStyle(sibling).color;
     51 
     52 // All of the elements should inherit these properties.
     53 const expectedInheritedProperties = {
     54  'font-size': '24px',
     55  'font-family': 'monospace',
     56  'font-stretch': '150%',
     57  'font-style': 'italic',
     58  'font-variant': 'small-caps',
     59  'font-weight': '500',
     60  'line-height': '13px',
     61  'text-shadow': 'rgb(1, 1, 1) 1px 1px 1px',
     62  'text-rendering': 'optimizelegibility',
     63  'letter-spacing': '1px',
     64  'word-spacing': '2px',
     65  'color': 'rgb(255, 0, 0)',
     66 };
     67 for (const [property, value] of Object.entries(expectedInheritedProperties)) {
     68  parent.style[property] = value;
     69  parentInPicker.style[property] = value;
     70 }
     71 
     72 function testProperties(style, expectedProperties) {
     73  const parentStyle = getComputedStyle(parent);
     74  const initialStyle = getComputedStyle(initial);
     75 
     76  for (let [property, value] of Object.entries(expectedProperties)) {
     77    if (value == 'initial') {
     78      value = initialStyle[property];
     79    } else if (value.endsWith('em')) {
     80      // Properties with em units get serialized into px. In order to calculate
     81      // the expected value of an em unit, we can set another element to the
     82      // expected amount of ems and then serialize that one.
     83      sibling.style[property] = value;
     84      value = getComputedStyle(sibling)[property];
     85    }
     86    assert_equals(style[property], value, property);
     87  }
     88 
     89  for (const [property, value] of Object.entries(expectedInheritedProperties)) {
     90    // Don't test whether a property was inherited if expectedProperties
     91    // already has an expected value for it.
     92    if (!Object.keys(expectedProperties).includes(property)) {
     93      assert_equals(style[property], value, property);
     94    }
     95  }
     96 }
     97 
     98 test(() => {
     99  const expectedProperties = {
    100    'background-color': 'rgba(0, 0, 0, 0)',
    101    'border': '1px solid rgb(255, 0, 0)', /* color is currentColor */
    102    'min-inline-size': 'calc-size(auto, max(size, 24px))',
    103    'display': 'inline-flex',
    104    'user-select': 'none',
    105    'min-block-size': `calc-size(auto, max(size, 24px, ${expectedInheritedProperties['line-height']}))`,
    106    'padding-block-start': '0.25em',
    107    'padding-block-end': '0.25em',
    108    'padding-inline-start': '0.5em',
    109    'padding-inline-end': '0.5em',
    110    'gap': '0.5em',
    111    'border-radius': '0.5em',
    112    'text-indent': 'initial',
    113    'cursor': 'initial',
    114    'white-space': 'initial',
    115    'align-items': 'initial',
    116    'text-transform': 'initial',
    117    'text-align': 'initial'
    118  };
    119  testProperties(getComputedStyle(select), expectedProperties);
    120 }, 'UA styles of base appearance <select>.');
    121 
    122 test(() => {
    123  // margin-inline-start:auto is not tested here because the value 'auto' gets
    124  // serialized to '0px'.
    125  const expectedProperties = {
    126    'content': 'counter(fake-counter-name, disclosure-open)',
    127    'display': 'block'
    128  };
    129  testProperties(getComputedStyle(select, '::picker-icon'), expectedProperties);
    130 }, 'UA styles of base appearance select::picker-icon.');
    131 
    132 test(() => {
    133  // Properties not tested here:
    134  // min-inline-size: anchor-size(self-inline)
    135  // min-block-size: stretch
    136  const expectedProperties = {
    137    'box-sizing': 'border-box',
    138    'padding': '0px',
    139    'margin': '0px',
    140    'inset': 'auto',
    141    'overflow': 'auto',
    142    // position-area is actually 'block-end span-inline-end' but gets
    143    // serialized this way. position-try-fallbacks also gets serialized
    144    // differently.
    145    // https://drafts.csswg.org/css-anchor-position/#position-area-computed
    146    'position-area': 'end span-end',
    147    'position-try-order': 'most-block-size',
    148    'position-try-fallbacks': 'start span-end, end span-start, start span-start',
    149    'border': `1px solid ${canvasText}`,
    150    'background-color': canvas,
    151    'color': canvasText
    152  };
    153  testProperties(getComputedStyle(select, '::picker(select)'), expectedProperties);
    154 }, 'UA styles of base appearance ::picker(select)');
    155 
    156 test(() => {
    157  const expectedProperties = {
    158    'min-inline-size': '24px',
    159    'min-block-size': '24px',
    160    'padding-block-start': '0px',
    161    'padding-block-end': '0px',
    162    'padding-inline-start': '0.5em',
    163    'padding-inline-end': '0.5em',
    164    'display': 'flex',
    165    'gap': '0.5em',
    166    'align-items': 'center',
    167    'white-space': 'nowrap'
    168  };
    169  testProperties(getComputedStyle(option), expectedProperties);
    170 }, 'UA styles of base appearance <option>.');
    171 
    172 test(() => {
    173  const expectedProperties = {
    174    'content': `"${String.fromCodePoint(10003)}"`
    175  }
    176  testProperties(getComputedStyle(option, '::checkmark'), expectedProperties);
    177 }, 'UA styles of base appearance option::checkmark.');
    178 
    179 test(() => {
    180  const expectedProperties = {
    181    'font-weight': '700',
    182    'display': 'block'
    183  };
    184  testProperties(getComputedStyle(optgroup), expectedProperties);
    185 }, 'UA styles of base appearance <optgroup>.');
    186 
    187 test(() => {
    188  const expectedProperties = {
    189    'min-block-size': expectedInheritedProperties['line-height'],
    190    'padding-inline': '0.5em',
    191    'display': 'block',
    192    'unicode-bidi': 'isolate',
    193    'font-weight': '700'
    194  };
    195  testProperties(getComputedStyle(legend), expectedProperties);
    196 }, 'UA styles of base appearance <legend>.');
    197 
    198 test(() => {
    199  // Properties not tested here:
    200  // all: unset
    201  const expectedProperties = {
    202    'display': 'contents'
    203  };
    204  testProperties(getComputedStyle(button), expectedProperties);
    205 }, 'UA styles of base appearance select <button>.');
    206 
    207 test(() => {
    208  const expectedProperties = {
    209    'font-weight': '400',
    210  };
    211  testProperties(getComputedStyle(optgroupOption), expectedProperties);
    212 }, 'UA styles of base appearance <option> in <optgroup>.');
    213 </script>