host-has-shadow-tree-element-at-subject-position.html (5397B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>:host:has(...) to check whether a shadow host has a shadow tree element (subject position)</title> 4 <link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.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 <div class="ancestor host_context"> 9 <div id="host" class="ancestor"> 10 <template shadowrootmode="open"> 11 <style> 12 :host:has(.descendant) { color: green; } 13 :host:has(> .child) { color: blue; } 14 :host:has(~ .sibling) { color: yellow; } 15 :host:has(:is(.ancestor .descendant)) { color: purple; } 16 :host:has(.descendant):has(> .child) { color: pink; } 17 :host-context(.host_context):has(> .child > .grand_child) { color: ivory; } 18 :host(.host_context):has(> .child > .grand_child) { color: skyblue; } 19 :host:has(> .child > .grand_child):host(.host_context):has(> .child > .descendant) { color: lightgreen; } 20 </style> 21 <div id="shadow_child"> 22 <div id="shadow_descendant"></div> 23 </div> 24 </template> 25 <div class="child"> 26 <div class="descendant"></div> 27 </div> 28 </div> 29 <div class="sibling"></div> 30 </div> 31 32 <script> 33 const black = 'rgb(0, 0, 0)'; 34 const green = 'rgb(0, 128, 0)'; 35 const blue = 'rgb(0, 0, 255)'; 36 const yellow = 'rgb(255, 255, 0)'; 37 const purple = 'rgb(128, 0, 128)'; 38 const pink = 'rgb(255, 192, 203)'; 39 const ivory = 'rgb(255, 255, 240)'; 40 const skyblue = 'rgb(135, 206, 235)'; 41 const lightgreen = 'rgb(144, 238, 144)'; 42 43 var shadow_root = host.shadowRoot; 44 45 function element(id) { 46 return document.getElementById(id); 47 } 48 49 function shadow_element(id) { 50 return shadow_root.getElementById(id); 51 } 52 53 function test_color(test_name, color) { 54 test(function() { 55 assert_equals(getComputedStyle(host).color, color); 56 }, test_name); 57 } 58 59 function create_div(id, class_name) { 60 let div = document.createElement('div'); 61 div.id = id; 62 div.classList.add(class_name); 63 return div 64 } 65 66 test_color('Initial color', black); 67 68 shadow_element('shadow_child').classList.add('descendant'); 69 test_color(`Add .descendant to #shadow_child`, green); 70 71 shadow_element('shadow_child').classList.remove('descendant'); 72 test_color(`Remove .descendant from #shadow_child`, black); 73 74 shadow_element('shadow_descendant').classList.add('descendant'); 75 test_color(`Add .descendant to #shadow_descendant`, green); 76 77 shadow_element('shadow_child').classList.add('ancestor'); 78 test_color(`Add .ancestor to #shadow_child:has(.descendant)`, purple); 79 80 shadow_element('shadow_child').classList.remove('ancestor'); 81 test_color(`Remove .ancestor from #shadow_child:has(.descendant)`, green); 82 83 shadow_element('shadow_child').classList.add('child'); 84 test_color(`Add .child to #shadow_child:has(.descendant)`, pink); 85 86 shadow_element('shadow_child').classList.remove('child'); 87 test_color(`Remove .child from #shadow_child:has(.descendant)`, green); 88 89 shadow_element('shadow_descendant').classList.remove('descendant'); 90 test_color(`Remove .descendant from #shadow_descendant`, black); 91 92 shadow_element('shadow_child').classList.add('child'); 93 test_color(`Add .child to #shadow_child`, blue); 94 95 shadow_element('shadow_descendant').classList.add('grand_child'); 96 test_color(`Add .grand_child to #shadow_descendant`, ivory); 97 98 element('host').classList.add('host_context'); 99 test_color(`Add .host_context to #host`, skyblue); 100 101 shadow_element('shadow_descendant').classList.add('descendant'); 102 test_color(`Add .descendant to #shadow_descendant.grand_child`, lightgreen); 103 104 shadow_element('shadow_descendant').classList.remove('descendant'); 105 test_color(`Remove .descendant from #shadow_descendant.grand_child`, skyblue); 106 107 shadow_element('shadow_descendant').classList.remove('grand_child'); 108 test_color(`Remove .grand_child from #shadow_descendant`, blue); 109 110 shadow_element('shadow_child').classList.remove('child'); 111 test_color(`Remove .child from #shadow_child`, black); 112 113 shadow_element('shadow_descendant').classList.add('child'); 114 test_color(`Add .child to #shadow_descendant`, black); 115 116 shadow_element('shadow_descendant').classList.remove('child'); 117 test_color(`Remove .child from #shadow_descendant`, black); 118 119 div = shadow_root.insertBefore(create_div('first_child', 'descendant'), 120 shadow_root.firstChild); 121 test_color(`Insert #first_child.descendant to shadow root`, green); 122 div.remove(); 123 test_color(`Remove #first_child.descendant from shadow root`, black); 124 125 div = shadow_root.insertBefore(create_div('last_child', 'descendant'), null); 126 test_color(`Insert #last_child.descendant to shadow root`, green); 127 div.remove(); 128 test_color(`Remove #last_child.descendant from shadow root`, black); 129 130 div = shadow_root.insertBefore(create_div('child_in_middle','descendant'), 131 shadow_element('shadow_child')); 132 test_color(`Insert #child_in_middle.descendant before #shadow_child`, green); 133 div.remove(); 134 test_color(`Remove #child_in_middle.descendant from shadow root`, black); 135 136 div = shadow_element('shadow_child') 137 .insertBefore(create_div('grand_child','descendant'), 138 shadow_element('shadow_descendant')); 139 test_color(`Insert #grand_child.descendant before #shadow_descendant`, green); 140 div.remove(); 141 test_color(`Remove #grand_child.descendant from shadow tree`, black); 142 143 </script>