has-basic.html (3079B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Basic matching behavior of :has pseudo class</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 9 <main id=main> 10 <div id=a class="ancestor"> 11 <div id=b class="parent ancestor"> 12 <div id=c class="sibling descendant"> 13 <div id=d class="descendant"></div> 14 </div> 15 <div id=e class="target descendant"></div> 16 </div> 17 <div id=f class="parent ancestor"> 18 <div id=g class="target descendant"></div> 19 </div> 20 <div id=h class="parent ancestor"> 21 <div id=i class="target descendant"></div> 22 <div id=j class="sibling descendant"> 23 <div id=k class="descendant"></div> 24 </div> 25 </div> 26 </div> 27 </main> 28 29 <script> 30 function formatElements(elements) { 31 return elements.map(e => e.id).sort().join(); 32 } 33 34 // Test that |selector| returns the given elements in #main. 35 function test_selector_all(selector, expected) { 36 test(function() { 37 let actual = Array.from(main.querySelectorAll(selector)); 38 assert_equals(formatElements(actual), formatElements(expected)); 39 }, `${selector} matches expected elements`); 40 } 41 42 // Test that |selector| returns the given element in #main. 43 function test_selector(selector, expected) { 44 test(function() { 45 assert_equals(main.querySelector(selector), expected); 46 }, `${selector} matches expected element`); 47 } 48 49 // Test that |selector| returns the given closest element. 50 function test_closest(node, selector, expected) { 51 test(function() { 52 assert_equals(node.closest(selector), expected); 53 }, `closest(${selector}) returns expected element`); 54 } 55 56 // Test that |selector| returns matching status. 57 function test_matches(node, selector, expected) { 58 test(function() { 59 assert_equals(node.matches(selector), expected); 60 }, `${selector} matches expectedly`); 61 } 62 63 test_selector_all(':has(#a)', []); 64 test_selector_all(':has(.ancestor)', [a]); 65 test_selector_all(':has(.target)', [a, b, f, h]); 66 test_selector_all(':has(.descendant)', [a, b, c, f, h, j]); 67 test_selector_all('.parent:has(.target)', [b, f, h]); 68 test_selector_all(':has(.sibling ~ .target)', [a, b]); 69 test_selector_all('.parent:has(.sibling ~ .target)', [b]); 70 test_selector_all(':has(:is(.target ~ .sibling .descendant))', [a, h, j]); 71 test_selector_all('.parent:has(:is(.target ~ .sibling .descendant))', [h]); 72 test_selector_all('.sibling:has(.descendant) ~ .target', [e]); 73 test_selector_all(':has(> .parent)', [a]); 74 test_selector_all(':has(> .target)', [b, f, h]); 75 test_selector_all(':has(> .parent, > .target)', [a, b, f, h]); 76 test_selector_all(':has(+ #h)', [f]); 77 test_selector_all('.parent:has(~ #h)', [b, f]); 78 test_selector('.sibling:has(.descendant)', c); 79 test_closest(k, '.ancestor:has(.descendant)', h); 80 test_matches(h, ':has(.target ~ .sibling .descendant)', true); 81 </script>