has-with-pseudo-class.html (3947B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>CSS Selector Invalidation: :has() with pseudo-classes</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 main:has(input) div { color: grey } 10 main:has(#checkbox:checked) > #subject { color: red } 11 main:has(#option:checked) > #subject { color: red } 12 main:has(#checkbox:disabled) > #subject { color: green } 13 main:has(#option:disabled) > :is(#subject, #subject2) { color: green } 14 main:has(#optgroup:disabled) > #subject { color: blue } 15 main:not(:has(#checkbox:enabled)) > #subject3 { color: green } 16 main:not(:has(#option:enabled)) :is(#subject3, #subject4) { color: green } 17 main:not(:has(#optgroup:enabled)) > #subject3 { color: blue } 18 main:has(#text_input:valid) > #subject { color: yellow } 19 main:not(:has(#text_input:invalid)) > #subject2 { color: yellow } 20 main:has(#form:valid) > #subject3 { color: yellow } 21 main:not(:has(#form:invalid)) > #subject4 { color: yellow } 22 </style> 23 24 <main id=main> 25 <form id=form> 26 <input type=checkbox id=checkbox></input> 27 <select id=select><optgroup id=optgroup><option>a</option><option id=option>b</option></optgroup></select> 28 <input id=text_input type=text required></input> 29 </form> 30 <div id=subject></div> 31 <div id=subject2></div> 32 <div id=subject3></div> 33 <div id=subject4></div> 34 </main> 35 36 <script> 37 const grey = 'rgb(128, 128, 128)'; 38 const red = 'rgb(255, 0, 0)'; 39 const green = 'rgb(0, 128, 0)'; 40 const blue = 'rgb(0, 0, 255)'; 41 const yellow = 'rgb(255, 255, 0)'; 42 const purple = 'rgb(128, 0, 128)'; 43 const pink = 'rgb(255, 192, 203)'; 44 45 function testColor(test_name, subject_element, color) { 46 test(function() { 47 assert_equals(getComputedStyle(subject_element).color, color); 48 }, test_name); 49 } 50 51 function testPseudoClassChange(element, property, subject_element, expectedColor) 52 { 53 testColor(`Before set ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, grey); 54 55 element[property] = true; 56 testColor(`Set ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, expectedColor); 57 58 element[property] = false; 59 testColor(`Unset ${property} on ${element.id}, testing ${subject_element.id}`, subject_element, grey); 60 } 61 62 function testSelectedChange(option, subject_element, expectedColor) 63 { 64 const oldOption = select.selectedOptions[0]; 65 option.selected = true; 66 testColor(`Set select on ${option.id}`, subject_element, expectedColor); 67 oldOption.selected = true; 68 testColor(`Reset select`, subject, grey); 69 } 70 71 function testValueChange(input, subject_element, expectedColor) 72 { 73 testColor(`Before setting value of ${input.id}, testing ${subject_element.id}`, subject_element, grey); 74 75 input.value = "value"; 76 testColor(`Set value of ${input.id}, testing ${subject_element.id}`, subject_element, expectedColor); 77 78 input.value = ""; 79 testColor(`Clear value of ${input.id}, testing ${subject_element.id}`, subject_element, grey); 80 } 81 82 testPseudoClassChange(checkbox, "checked", subject, red); 83 testSelectedChange(option, subject, red); 84 85 testPseudoClassChange(checkbox, "disabled", subject, green); 86 testPseudoClassChange(checkbox, "disabled", subject3, green); 87 testPseudoClassChange(option, "disabled", subject, green); 88 testPseudoClassChange(option, "disabled", subject3, green); 89 90 testPseudoClassChange(optgroup, "disabled", subject, blue); 91 testPseudoClassChange(optgroup, "disabled", subject2, green); 92 testPseudoClassChange(optgroup, "disabled", subject3, blue); 93 testPseudoClassChange(optgroup, "disabled", subject4, green); 94 95 testValueChange(text_input, subject, yellow); 96 testValueChange(text_input, subject2, yellow); 97 testValueChange(text_input, subject3, yellow); 98 testValueChange(text_input, subject4, yellow); 99 </script>