tor-browser

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

semantics.html (13655B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>Selectors: semantics of case-sensitivity attribute selector</title>
      4 <link rel="help" href="https://drafts.csswg.org/selectors/#attribute-case">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <style></style>
      8 <div id=log></div>
      9 <iframe id="quirks" src="resources/semantics-quirks.html"></iframe>
     10 <iframe id="xml" src="resources/semantics-xml.xhtml"></iframe>
     11 <script>
     12 setup({explicit_done:true});
     13 var match = [
     14  // [selector, attrs...] (each attr is [ns, name, value])
     15  ["[foo='BAR'] /* sanity check (match) */", ["", "foo", "BAR"]],
     16  ["[foo='bar'] /* sanity check (match) */", ["", "foo", "bar"]],
     17  ["[align='left'] /* sanity check (match) */", ["", "align", "left"]],
     18  ["[class~='a'] /* sanity check (match) */", ["", "class", "X a b"]],
     19  ["[class~='A'] /* sanity check (match) */", ["", "class", "x A B"]],
     20  ["[id^='a'] /* sanity check (match) */", ["", "id", "ab"]],
     21  ["[id$='A'] /* sanity check (match) */", ["", "id", "XA"]],
     22  ["[lang|='a'] /* sanity check (match) */", ["", "lang", "a-b"]],
     23  ["[lang*='A'] /* sanity check (match) */", ["", "lang", "XAB"]],
     24  ["@namespace x 'http://www.w3.org/XML/1998/namespace'; [x|lang='A'] /* sanity check (match) */",
     25   ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
     26  // Case-insensitive matching.
     27  ["[foo='bar' i]", ["", "foo", "BAR"]],
     28  ["[foo='' i]", ["", "foo", ""]],
     29  ["[foo='a\u0308' i] /* COMBINING in both */", ["", "foo", "A\u0308"]],
     30  ["[foo='A\u0308' i] /* COMBINING in both */", ["", "foo", "a\u0308"]],
     31  ["[*|foo='bar' i]", ["", "foo", "x"], ["a", "foo", "x"], ["b", "foo", "BAR"], ["c", "foo", "x"]],
     32  ["[*|foo='bar' i]", ["", "foo", "BAR"], ["a", "foo", "x"], ["b", "foo", "x"], ["c", "foo", "x"]],
     33  ["[align='left' i]", ["", "align", "LEFT"]],
     34  ["[align='LEFT' i]", ["", "align", "left"]],
     35  ["[class~='a' i]", ["", "class", "X A B"]],
     36  ["[class~='A' i]", ["", "class", "x a b"]],
     37  ["[id^='a' i]", ["", "id", "AB"]],
     38  ["[id$='A' i]", ["", "id", "xa"]],
     39  ["[lang|='a' i]", ["", "lang", "A-B"]],
     40  ["[lang*='A' i]", ["", "lang", "xab"]],
     41  ["[*|lang='a' i]", ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
     42  ["[*|lang='A' i]", ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
     43  ["@namespace x 'http://www.w3.org/XML/1998/namespace'; [x|lang='A' i]", ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
     44  ["[foo='bar' i][foo='bar' i]", ["", "foo", "BAR"]],
     45  ["[foo='BAR'][foo='bar' i]", ["", "foo", "BAR"]],
     46  ["[foo='bar' i][foo='BAR']", ["", "foo", "BAR"]],
     47  // Case-sensitive matching.
     48  ["[foo='bar' s]", ["", "foo", "bar"]],
     49  ["[foo='' s]", ["", "foo", ""]],
     50  ["[foo='a\u0308' s] /* COMBINING in both */", ["", "foo", "a\u0308"]],
     51  ["[*|foo='bar' s]", ["", "foo", "x"], ["a", "foo", "x"], ["b", "foo", "bar"], ["c", "foo", "x"]],
     52  ["[*|foo='bar' s]", ["", "foo", "bar"], ["a", "foo", "x"], ["b", "foo", "x"], ["c", "foo", "x"]],
     53  ["[align='left' s]", ["", "align", "left"]],
     54  ["[align='LEFT' s]", ["", "align", "LEFT"]],
     55  ["[class~='a' s]", ["", "class", "x a b"]],
     56  ["[class~='A' s]", ["", "class", "X A B"]],
     57  ["[id^='a' s]", ["", "id", "ab"]],
     58  ["[id$='A' s]", ["", "id", "XA"]],
     59  ["[lang|='a' s]", ["", "lang", "a-b"]],
     60  ["[lang*='A' s]", ["", "lang", "XAB"]],
     61  ["[*|lang='a' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
     62  ["[*|lang='A' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
     63  ["@namespace x 'http://www.w3.org/XML/1998/namespace'; [x|lang='A' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
     64  ["[foo='BAR' s][foo='BAR' s]", ["", "foo", "BAR"]],
     65 ];
     66 
     67 var matchHTMLOnly = [
     68  ["[align='left'] /* sanity check (match HTML) */", ["", "align", "LEFT"]],
     69  ["[align='LEFT'] /* sanity check (match HTML) */", ["", "align", "left"]],
     70  ["[lang|='a'] /* sanity check (match HTML) */", ["", "lang", "A-B"]],
     71  ["[lang*='A'] /* sanity check (match HTML) */", ["", "lang", "xab"]],
     72 ];
     73 
     74 var nomatch = [
     75  ["[missingattr] /* sanity check (no match) */", ["", "foo", "BAR"]],
     76  ["[foo='bar'] /* sanity check (no match) */", ["", "foo", "BAR"]],
     77  ["[class~='a'] /* sanity check (no match) */", ["", "class", "X A B"]],
     78  ["[class~='A'] /* sanity check (no match) */", ["", "class", "x a b"]],
     79  ["[id^='a'] /* sanity check (no match) */", ["", "id", "AB"]],
     80  ["[id$='A']", ["", "id", "xa"]],
     81  ["[*|lang='a'] /* sanity check (no match) */",
     82   ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
     83  ["[*|lang='A'] /* sanity check (no match) */",
     84   ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
     85  ["@namespace x 'http://www.w3.org/XML/1998/namespace'; [x|lang='A'] /* sanity check (no match) */",
     86   ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
     87  // Case-insensitive matching.
     88  ["[foo='' i]", ["", "foo", "BAR"]],
     89  ["[foo='\u0000' i] /* \\0 in selector */", ["", "foo", ""]],
     90  ["[foo='' i] /* \\0 in attribute */", ["", "foo", "\u0000"]],
     91  ["[foo='\u00E4' i]", ["", "foo", "\u00C4"]],
     92  ["[foo='\u00C4' i]", ["", "foo", "\u00E4"]],
     93  ["[foo='a\u0308' i] /* COMBINING in selector */", ["", "foo", "\u00C4"]],
     94  ["[foo~='a\u0308' i] /* COMBINING in selector */", ["", "foo", "\u00E4"]],
     95  ["[foo^='A\u0308' i] /* COMBINING in selector */", ["", "foo", "\u00C4"]],
     96  ["[foo$='A\u0308' i] /* COMBINING in selector */", ["", "foo", "\u00E4"]],
     97  ["[foo*='\u00E4' i] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
     98  ["[foo|='\u00E4' i] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
     99  ["[foo='\u00C4' i] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    100  ["[foo='\u00C4' i] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    101  ["[foo='a\u0308' i] /* COMBINING in selector */", ["", "foo", "a"]],
    102  ["[foo='a\u0308' i] /* COMBINING in selector */", ["", "foo", "A"]],
    103  ["[foo='A\u0308' i] /* COMBINING in selector */", ["", "foo", "a"]],
    104  ["[foo='A\u0308' i] /* COMBINING in selector */", ["", "foo", "A"]],
    105  ["[foo='a' i] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    106  ["[foo='A' i] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    107  ["[foo='a' i] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    108  ["[foo='A' i] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    109  ["[foo='i' i]", ["", "foo", "\u0130"]],
    110  ["[foo='i' i]", ["", "foo", "\u0131"]],
    111  ["[foo='I' i]", ["", "foo", "\u0130"]],
    112  ["[foo='I' i]", ["", "foo", "\u0131"]],
    113  ["[foo='\u0130' i]", ["", "foo", "i"]],
    114  ["[foo='\u0131' i]", ["", "foo", "i"]],
    115  ["[foo='\u0130' i]", ["", "foo", "I"]],
    116  ["[foo='\u0131' i]", ["", "foo", "I"]],
    117  ["[foo='bar' i]", ["", "foo", "x"], ["a", "foo", "BAR"]],
    118  ["[|foo='bar' i]", ["", "foo", "x"], ["a", "foo", "BAR"]],
    119  ["[foo='bar' i]", ["", "FOO", "bar"]],
    120  ["[foo='\t' i] /* tab in selector */", ["", "foo", " "]],
    121  ["[foo=' ' i] /* tab in attribute */", ["", "foo", "\t"]],
    122  ["@namespace x 'a'; [x|foo='' i]", ["A", "foo", ""]],
    123  ["@namespace x 'A'; [x|foo='' i]", ["a", "foo", ""]],
    124  ["[foo='bar' i][foo='bar']", ["", "foo", "BAR"]],
    125  ["[foo='bar' i]", ["", "baz", "BAR"]],
    126  ["[foo^='é' i]", ["", "foo", "É"]],
    127  ["[foo$='é' i]", ["", "foo", "É"]],
    128  ["[foo*='é' i]", ["", "foo", "É"]],
    129  ["[foo|='é' i]", ["", "foo", "É"]],
    130  ["[foo^='É' i]", ["", "foo", "é"]],
    131  ["[foo$='É' i]", ["", "foo", "é"]],
    132  ["[foo*='É' i]", ["", "foo", "é"]],
    133  ["[foo|='É' i]", ["", "foo", "é"]],
    134  // Case-sensitive matching
    135  ["[foo='' s]", ["", "foo", "BAR"]],
    136  ["[foo='\u0000' s] /* \\0 in selector */", ["", "foo", ""]],
    137  ["[foo='' s] /* \\0 in attribute */", ["", "foo", "\u0000"]],
    138  ["[foo='\u00E4' s]", ["", "foo", "\u00C4"]],
    139  ["[foo='\u00C4' s]", ["", "foo", "\u00E4"]],
    140  ["[foo='a\u0308' s] /* COMBINING in selector */", ["", "foo", "\u00C4"]],
    141  ["[foo~='a\u0308' s] /* COMBINING in selector */", ["", "foo", "\u00E4"]],
    142  ["[foo^='A\u0308' s] /* COMBINING in selector */", ["", "foo", "\u00C4"]],
    143  ["[foo$='A\u0308' s] /* COMBINING in selector */", ["", "foo", "\u00E4"]],
    144  ["[foo*='\u00E4' s] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    145  ["[foo|='\u00E4' s] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    146  ["[foo='\u00C4' s] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    147  ["[foo='\u00C4' s] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    148  ["[foo='a\u0308' s] /* COMBINING in selector */", ["", "foo", "a"]],
    149  ["[foo='a\u0308' s] /* COMBINING in selector */", ["", "foo", "A"]],
    150  ["[foo='A\u0308' s] /* COMBINING in selector */", ["", "foo", "a"]],
    151  ["[foo='A\u0308' s] /* COMBINING in selector */", ["", "foo", "A"]],
    152  ["[foo='a' s] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    153  ["[foo='A' s] /* COMBINING in attribute */", ["", "foo", "a\u0308"]],
    154  ["[foo='a' s] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    155  ["[foo='A' s] /* COMBINING in attribute */", ["", "foo", "A\u0308"]],
    156  ["[foo='i' s]", ["", "foo", "\u0130"]],
    157  ["[foo='i' s]", ["", "foo", "\u0131"]],
    158  ["[foo='I' s]", ["", "foo", "\u0130"]],
    159  ["[foo='I' s]", ["", "foo", "\u0131"]],
    160  ["[foo='\u0130' s]", ["", "foo", "i"]],
    161  ["[foo='\u0131' s]", ["", "foo", "i"]],
    162  ["[foo='\u0130' s]", ["", "foo", "I"]],
    163  ["[foo='\u0131' s]", ["", "foo", "I"]],
    164  ["[foo='bar' s]", ["", "foo", "x"], ["a", "foo", "BAR"]],
    165  ["[|foo='bar' s]", ["", "foo", "x"], ["a", "foo", "BAR"]],
    166  ["[foo='bar' s]", ["", "FOO", "bar"]],
    167  ["[foo='\t' s] /* tab in selector */", ["", "foo", " "]],
    168  ["[foo=' ' s] /* tab in attribute */", ["", "foo", "\t"]],
    169  ["@namespace x 'a'; [x|foo='' s]", ["A", "foo", ""]],
    170  ["@namespace x 'A'; [x|foo='' s]", ["a", "foo", ""]],
    171  ["[foo='bar' s][foo='bar']", ["", "foo", "BAR"]],
    172  ["[foo='bar' s]", ["", "baz", "BAR"]],
    173  ["[foo='bar' s]", ["", "foo", "BAR"]],
    174  ["[foo='a\u0308' s] /* COMBINING in both */", ["", "foo", "A\u0308"]],
    175  ["[foo='A\u0308' s] /* COMBINING in both */", ["", "foo", "a\u0308"]],
    176  ["[*|foo='bar' s]", ["", "foo", "x"], ["a", "foo", "x"], ["b", "foo", "BAR"], ["c", "foo", "x"]],
    177  ["[*|foo='bar' s]", ["", "foo", "BAR"], ["a", "foo", "x"], ["b", "foo", "x"], ["c", "foo", "x"]],
    178  ["[align='left' s]", ["", "align", "LEFT"]],
    179  ["[align='LEFT' s]", ["", "align", "left"]],
    180  ["[class~='a' s]", ["", "class", "X A B"]],
    181  ["[class~='A' s]", ["", "class", "x a b"]],
    182  ["[id^='a' s]", ["", "id", "AB"]],
    183  ["[id$='A' s]", ["", "id", "xa"]],
    184  ["[lang|='a' s]", ["", "lang", "A-B"]],
    185  ["[lang*='A' s]", ["", "lang", "xab"]],
    186  ["[*|lang='a' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "A"]],
    187  ["[*|lang='A' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
    188  ["@namespace x 'http://www.w3.org/XML/1998/namespace'; [x|lang='A' s]", ["http://www.w3.org/XML/1998/namespace", "lang", "a"]],
    189  ["[foo='bar' s][foo='bar' s]", ["", "foo", "BAR"]],
    190  ["[foo='BAR' s][foo='bar']", ["", "foo", "BAR"]],
    191  ["[foo='bar'][foo='BAR' s]", ["", "foo", "BAR"]],
    192  ["[foo='BAR'][foo='bar' s]", ["", "foo", "BAR"]],
    193  ["[foo='bar' s][foo='BAR']", ["", "foo", "bar"]],
    194 ];
    195 var mode = "standards mode";
    196 function format_attrs(attrs) {
    197  var rv = [];
    198  attrs.forEach(function(attr) {
    199    var str = "";
    200    var ns = attr[0];
    201    var name = attr[1];
    202    var value = attr[2];
    203    if (ns)
    204      str += "{" + ns + "}";
    205    str += name + "=\"" + value + "\"";
    206    rv.push(str);
    207  });
    208  return rv.join(" ");
    209 }
    210 onload = function() {
    211  var quirks = document.getElementById('quirks').contentWindow;
    212  var xml = document.getElementById('xml').contentWindow;
    213  [window, quirks, xml].forEach(function(global) {
    214    var style = global.document.getElementsByTagName('style')[0];
    215    var elm;
    216    function clean_slate() {
    217      style.textContent = '';
    218      if (elm)
    219        elm.parentNode.removeChild(elm);
    220      elm = global.document.createElement('div');
    221      global.document.body.appendChild(elm);
    222    }
    223    function set_attrs(attrs) {
    224      attrs.forEach(function(attr) {
    225        elm.setAttributeNS(attr[0], attr[1], attr[2]);
    226      });
    227    }
    228    var localMatch = match.slice();
    229    if (global != xml) {
    230      localMatch.push(...matchHTMLOnly);
    231    }
    232    localMatch.forEach(function(arr) {
    233      var s = arr[0];
    234      var attrs = arr.slice(1);
    235      var ns_decl = s.substr(0, "@namespace".length) == "@namespace";
    236      test(function() {
    237        clean_slate();
    238        set_attrs(attrs);
    239        style.textContent = s + ' { visibility:hidden }';
    240        assert_equals(style.sheet.cssRules.length, (ns_decl ? 2 : 1), 'rule didn\'t parse into CSSOM');
    241        assert_equals(global.getComputedStyle(elm).visibility, 'hidden', 'selector didn\'t match');
    242      }, s + ' <div ' + format_attrs(attrs) + '> in ' + global.mode);
    243      if (!ns_decl) {
    244        test(function() {
    245          assert_equals(global.document.querySelector(s), elm, 'selector didn\'t match');
    246        }, s + ' <div ' + format_attrs(attrs) + '> with querySelector in ' + global.mode);
    247      }
    248    });
    249    nomatch.forEach(function(arr) {
    250      var s = arr[0];
    251      var attrs = arr.slice(1);
    252      var ns_decl = s.substr(0, "@namespace".length) == "@namespace";
    253      test(function() {
    254        clean_slate();
    255        set_attrs(attrs);
    256        style.textContent = s + ' { visibility:hidden }';
    257        assert_equals(style.sheet.cssRules.length, (ns_decl ? 2 : 1), 'rule didn\'t parse into CSSOM');
    258        assert_equals(global.getComputedStyle(elm).visibility, 'visible', 'selector matched');
    259      }, s + ' <div ' + format_attrs(attrs) + '> in ' + global.mode);
    260      if (!ns_decl) {
    261        test(function() {
    262          assert_equals(global.document.querySelector(s), null, 'selector matched');
    263        }, s + ' <div ' + format_attrs(attrs) + '> with querySelector in ' + global.mode);
    264      }
    265    });
    266  });
    267  done();
    268 };
    269 </script>