has-argument-with-explicit-scope.html (2723B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>:has pseudo class behavior with explicit ':scope' in its argument</title> 4 <link rel="author" title="Byungwoo Lee" href="mailto:blee@igalia.com"> 5 <link rel="help" href="https://drafts.csswg.org/selectors/#relational"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 9 <main> 10 <div id=d01 class="a"> 11 <div id=scope1 class="b"> 12 <div id=d02 class="c"> 13 <div id=d03 class="c"> 14 <div id=d04 class="d"></div> 15 </div> 16 </div> 17 <div id=d05 class="e"></div> 18 </div> 19 </div> 20 <div id=d06> 21 <div id=scope2 class="b"> 22 <div id=d07 class="c"> 23 <div id=d08 class="c"> 24 <div id=d09></div> 25 </div> 26 </div> 27 </div> 28 </div> 29 </div> 30 31 <script> 32 function formatElements(elements) { 33 return elements.map(e => e.id).sort().join(); 34 } 35 36 // Test that |selector| returns the given elements in the given scope element 37 function test_selector_all(scope, selector, expected) { 38 test(function() { 39 let actual = Array.from(scope.querySelectorAll(selector)); 40 assert_equals(formatElements(actual), formatElements(expected)); 41 }, `${selector} matches expected elements on ${scope.id}`); 42 } 43 44 // Test that |selector1| and |selector2| returns same elements in the given scope element 45 function compare_selector_all(scope, selector1, selector2) { 46 test(function() { 47 let result1 = Array.from(scope.querySelectorAll(selector1)); 48 let result2 = Array.from(scope.querySelectorAll(selector2)); 49 assert_equals(formatElements(result1), formatElements(result2)); 50 }, `${selector1} and ${selector2} returns same elements on ${scope.id}`); 51 } 52 53 // descendants of a scope element cannot have the scope element as its descendant 54 test_selector_all(scope1, ':has(:scope)', []); 55 test_selector_all(scope1, ':has(:scope .c)', []); 56 test_selector_all(scope1, ':has(.a :scope)', []); 57 58 // there can be more simple and efficient alternative for a ':scope' in ':has' 59 test_selector_all(scope1, '.a:has(:scope) .c', [d02, d03]); 60 compare_selector_all(scope1, '.a:has(:scope) .c', ':is(.a :scope .c)'); 61 test_selector_all(scope2, '.a:has(:scope) .c', []); 62 compare_selector_all(scope2, '.a:has(:scope) .c', ':is(.a :scope .c)'); 63 test_selector_all(scope1, '.c:has(:is(:scope .d))', [d02, d03]); 64 compare_selector_all(scope1, '.c:has(:is(:scope .d))', ':scope .c:has(.d)'); 65 compare_selector_all(scope1, '.c:has(:is(:scope .d))', '.c:has(.d)'); 66 test_selector_all(scope2, '.c:has(:is(:scope .d))', []); 67 compare_selector_all(scope2, '.c:has(:is(:scope .d))', ':scope .c:has(.d)'); 68 compare_selector_all(scope2, '.c:has(:is(:scope .d))', '.c:has(.d)'); 69 </script>