tor-browser

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

has-pseudoclass-only.html (2800B)


      1 <!DOCTYPE html>
      2 <title>CSS Selectors Invalidation: :has() containing :empty, :first-child, :last-child, pseudoclasses only</title>
      3 <link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
      4 <link rel="help" href="https://drafts.csswg.org/selectors/#relational">
      5 <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931432">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <style>
      9 #subject {
     10  color: grey;
     11 }
     12 
     13 #subject.empty:has(:empty) {
     14  color: red;
     15 }
     16 
     17 #subject.first:has(:first-child) {
     18  color: orange;
     19 }
     20 
     21 #subject.last:has(:last-child) {
     22  color: yellow;
     23 }
     24 
     25 /* :empty :empty never matches, so use something else. */
     26 #subject.empty-subtree:has(:first-child :empty) {
     27  color: green;
     28 }
     29 
     30 #subject.first-subtree:has(:first-child :first-child) {
     31  color: blue;
     32 }
     33 
     34 #subject.last-subtree:has(:last-child :last-child) {
     35  color: purple;
     36 }
     37 </style>
     38 <div id="subject"></div>
     39 <script>
     40 const grey = "rgb(128, 128, 128)";
     41 const red = "rgb(255, 0, 0)";
     42 const orange = "rgb(255, 165, 0)";
     43 const yellow = "rgb(255, 255, 0)";
     44 const green = "rgb(0, 128, 0)";
     45 const blue = 'rgb(0, 0, 255)';
     46 const purple = 'rgb(128, 0, 128)';
     47 
     48 function testColor(test_name, color) {
     49  test(function() {
     50    assert_equals(getComputedStyle(subject).color, color);
     51  }, test_name);
     52 }
     53 
     54 function runTest(test_class, child, insert, color_after_add, desc) {
     55  subject.classList.add(test_class);
     56  testColor(desc + ' color initial', grey);
     57  insert(child);
     58  testColor(desc + ' color after adding', color_after_add);
     59  subject.replaceChildren();
     60  testColor(desc + ' color after removing', grey);
     61  subject.classList.remove(test_class);
     62 }
     63 
     64 function createSimpleTree() {
     65  const root = document.createElement('div');
     66  root.replaceChildren(document.createElement('div'), document.createElement('div'));
     67  return root;
     68 }
     69 
     70 const tests = {
     71  ':empty': {cls: 'empty', child: document.createElement('div'), color_after_add: red},
     72  ':first-child': {cls: 'first', child: document.createElement('div'), color_after_add: orange},
     73  ':last-child': {cls: 'last', child: document.createElement('div'), color_after_add: yellow},
     74  ':empty subtree': {cls: 'empty-subtree', child: createSimpleTree(), color_after_add: green},
     75  ':first-child subtree': {cls: 'first-subtree', child: createSimpleTree(), color_after_add: blue},
     76  ':last-child subtree': {cls: 'last-subtree', child: createSimpleTree(), color_after_add: purple},
     77 };
     78 
     79 const element = document.createElement('div');
     80 for (const [t, options] of Object.entries(tests)) {
     81  runTest(options.cls, options.child, (e) => subject.appendChild(e), options.color_after_add, t + ' append');
     82  runTest(options.cls, options.child, (e) => subject.insertBefore(e, null), options.color_after_add, t + ' insert');
     83 }
     84 </script>