has-with-not.html (3229B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>CSS Selector Invalidation: :has() with :not()</title> 4 <link rel="author" title="Antti Koivisto" href="mailto:antti@apple.com"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <link rel="help" href="https://drafts.csswg.org/selectors/#relational"> 8 <style> 9 div, main { color: grey } 10 #subject:has(:not(.test)) { color: green } 11 #subject:has(.test :not(.test)) { color: red } 12 </style> 13 14 <main id=main> 15 <div id=subject> 16 <div id=subject_child class=test> 17 <div id=subject_descendant class=test></div> 18 </div> 19 </div> 20 </main> 21 22 <script> 23 const grey = 'rgb(128, 128, 128)'; 24 const red = 'rgb(255, 0, 0)'; 25 const green = 'rgb(0, 128, 0)'; 26 const blue = 'rgb(0, 0, 255)'; 27 28 function testColor(test_name, color) { 29 test(function() { 30 assert_equals(getComputedStyle(subject).color, color); 31 }, test_name); 32 } 33 34 function testClassChange(element, expectedColor) 35 { 36 element.classList.remove('test'); 37 testColor(`remove .test to ${element.id}`, expectedColor); 38 element.classList.add('test'); 39 testColor(`add .test from ${element.id}`, grey); 40 } 41 42 function testElementInsertionBefore(beforeElement, expectedColor) 43 { 44 const newElement = document.createElement('div'); 45 46 beforeElement.before(newElement); 47 testColor(`insert element div before ${beforeElement.id}`, expectedColor); 48 49 newElement.remove(); 50 testColor(`remove element div before ${beforeElement.id}`, grey); 51 } 52 53 function testElementInsertionAfter(afterElement, expectedColor) 54 { 55 const newElement = document.createElement('div'); 56 57 afterElement.after(newElement); 58 testColor(`insert element div after ${afterElement.id}`, expectedColor); 59 60 newElement.remove(); 61 testColor(`remove element div after ${afterElement.id}`, grey); 62 } 63 64 function testTreeInsertionBefore(beforeElement, expectedColor) 65 { 66 const newElement = document.createElement('div'); 67 const newChild = document.createElement('div'); 68 newElement.appendChild(newChild); 69 70 beforeElement.before(newElement); 71 testColor(`insert tree div>div before ${beforeElement.id}`, expectedColor); 72 73 newElement.remove(); 74 testColor(`remove tree div>div before ${beforeElement.id}`, grey); 75 } 76 77 function testTreeInsertionAfter(afterElement, expectedColor) 78 { 79 const newElement = document.createElement('div'); 80 const newChild = document.createElement('div'); 81 newElement.appendChild(newChild); 82 83 afterElement.after(newElement); 84 testColor(`insert tree div.test after ${afterElement.id}`, expectedColor); 85 86 newElement.remove(); 87 testColor(`remove tree div.test after ${afterElement.id}`, grey); 88 } 89 90 testColor('Initial color', grey); 91 92 testClassChange(subject_child, green); 93 testClassChange(subject_descendant, red); 94 95 testElementInsertionBefore(subject_child, green); 96 testElementInsertionBefore(subject_descendant, red); 97 98 testElementInsertionAfter(subject_child, green); 99 testElementInsertionAfter(subject_descendant, red); 100 101 testTreeInsertionBefore(subject_child, green); 102 testTreeInsertionBefore(subject_descendant, red); 103 104 testTreeInsertionAfter(subject_child, green); 105 testTreeInsertionAfter(subject_descendant, red); 106 107 </script>