test_selectormatcheselement.html (3890B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1037519 5 --> 6 <head> 7 <title>Test for CSSStyleRule::selectorMatchesElement</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 <style type="text/css"> 11 #foo, 12 #bar, 13 #foo::before { 14 color: red; 15 } 16 17 #foo { 18 div& { 19 outline: 1px solid gold; 20 } 21 } 22 23 #foo::before, 24 #bar::before { 25 content: 'foo-before'; 26 color: green; 27 } 28 #foo::after, 29 #bar::after { 30 content: 'foo-after'; 31 color: blue; 32 } 33 #foo::first-line, 34 #bar::first-line { 35 text-decoration: underline; 36 } 37 #foo::first-letter, 38 #bar::first-letter { 39 font-variant: small-caps; 40 } 41 42 ::view-transition-group(root), #bar, ::view-transition-group(*) { 43 animation-duration: 3600s; 44 } 45 </style> 46 </head> 47 <body> 48 <div id="foo">foo content</div> 49 50 <script> 51 52 const InspectorUtils = SpecialPowers.InspectorUtils; 53 54 add_task(async () => { 55 const element = document.querySelector("#foo"); 56 const elementRules = InspectorUtils.getMatchingCSSRules(element); 57 58 const multiSelectorRule = elementRules[2]; 59 is( 60 multiSelectorRule.selectorText, 61 `#foo, #bar, #foo::before`, 62 "Got expected multi-selector rule" 63 ); 64 ok( 65 multiSelectorRule.selectorMatchesElement(0, element), 66 "Matches #foo" 67 ); 68 ok( 69 !multiSelectorRule.selectorMatchesElement(1, element), 70 "Doesn't match #bar" 71 ); 72 ok( 73 !multiSelectorRule.selectorMatchesElement(0, element, ":bogus"), 74 "Doesn't match #foo with a bogus pseudo" 75 ); 76 ok( 77 !multiSelectorRule.selectorMatchesElement(2, element, ":bogus"), 78 "Doesn't match #foo::before with bogus pseudo" 79 ); 80 ok( 81 !multiSelectorRule.selectorMatchesElement(0, element, ":after"), 82 "Does match #foo::before with the :after pseudo" 83 ); 84 85 const nestedRule = elementRules[4]; 86 is(nestedRule.selectorText, `div&`, "Got expected nested rule"); 87 ok(nestedRule.selectorMatchesElement(0, element), "Matches div&"); 88 89 checkPseudo(":before"); 90 checkPseudo(":after"); 91 checkPseudo(":first-letter"); 92 checkPseudo(":first-line"); 93 94 function checkPseudo(pseudo) { 95 const rule = InspectorUtils.getMatchingCSSRules(element, pseudo).at(-1); 96 ok( 97 !rule.selectorMatchesElement(0, element), 98 "Doesn't match without " + pseudo 99 ); 100 ok( 101 !rule.selectorMatchesElement(1, element), 102 "Doesn't match without " + pseudo 103 ); 104 ok( 105 rule.selectorMatchesElement(0, element, pseudo), 106 "Matches on #foo" + pseudo 107 ); 108 ok( 109 !rule.selectorMatchesElement(1, element, pseudo), 110 "Doesn't match on #bar" + pseudo 111 ); 112 } 113 114 info("Create a view transition"); 115 const transition = document.startViewTransition(() => { 116 element.replaceChildren("updated foo content"); 117 }); 118 await transition.ready; 119 await transition.updateCallbackDone; 120 121 const viewTransitionGroupRule = InspectorUtils.getMatchingCSSRules( 122 document.documentElement, 123 "::view-transition-group(root)" 124 ).find(rule => { 125 try { 126 return rule.selectorText === "::view-transition-group(root), #bar, ::view-transition-group(*)"; 127 } catch {} 128 return false; 129 }); 130 131 ok( 132 !!viewTransitionGroupRule, 133 "Got the expected ::view-transition-group rule" 134 ); 135 ok( 136 viewTransitionGroupRule.selectorMatchesElement( 137 0, 138 document.documentElement, 139 "::view-transition-group(root)" 140 ), 141 "Matches ::view-transition-group(root)" 142 ); 143 ok( 144 !viewTransitionGroupRule.selectorMatchesElement(1, document.documentElement), 145 "Doesn't match #bar" 146 ); 147 ok( 148 viewTransitionGroupRule.selectorMatchesElement( 149 2, 150 document.documentElement, 151 "::view-transition-group(root)" 152 ), 153 "Matches ::view-transition-group(*)" 154 ); 155 }); 156 157 </script> 158 </body> 159 </html>