browser_rules_pseudo-element_02.js (12041B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test that pseudo elements rules are displayed correctly in Rules view. 7 8 const TEST_URI = URL_ROOT + "doc_pseudoelement.html"; 9 10 add_task(async function () { 11 await addTab(TEST_URI); 12 const { inspector, view } = await openRuleView(); 13 14 const node = await getNodeFront("#topleft", inspector); 15 const children = await inspector.markup.walker.children(node); 16 17 is(children.nodes.length, 3, "Element has correct number of children"); 18 19 info("Check rules on #topleft::before node"); 20 const beforeElement = children.nodes[0]; 21 is(beforeElement.displayName, "::before", "display name is correct"); 22 await selectNode(beforeElement, inspector); 23 checkRuleViewContent(view, [ 24 { 25 selector: `.topleft::before`, 26 ancestorRulesData: null, 27 declarations: [ 28 { name: "top", value: "0" }, 29 { name: "left", value: "0" }, 30 ], 31 }, 32 { 33 selector: `.box::before`, 34 ancestorRulesData: null, 35 declarations: [ 36 { name: "background", value: "green" }, 37 { name: "content", value: `" "` }, 38 { name: "position", value: `absolute` }, 39 { name: "height", value: `32px` }, 40 { name: "width", value: `32px` }, 41 ], 42 }, 43 { 44 header: "Inherited from div#topleft", 45 }, 46 { 47 selector: `*`, 48 ancestorRulesData: null, 49 inherited: true, 50 declarations: [{ name: "cursor", value: "default" }], 51 }, 52 { 53 header: "Inherited from body", 54 }, 55 { 56 selector: `body`, 57 ancestorRulesData: null, 58 inherited: true, 59 declarations: [{ name: "color", value: "#333" }], 60 }, 61 ]); 62 63 info("Check rules on #topleft::after node"); 64 const afterElement = children.nodes.at(-1); 65 is(afterElement.displayName, "::after", "display name is correct"); 66 await selectNode(afterElement, inspector); 67 checkRuleViewContent(view, [ 68 { 69 selector: `.box::after`, 70 ancestorRulesData: null, 71 declarations: [ 72 { name: "background", value: `red` }, 73 { name: "content", value: `" "` }, 74 { name: "position", value: `absolute` }, 75 { name: "border-radius", value: `50%` }, 76 { name: "height", value: `32px` }, 77 { name: "width", value: `32px` }, 78 { name: "top", value: `50%` }, 79 { name: "left", value: `50%` }, 80 { name: "margin-top", value: `-16px` }, 81 { name: "margin-left", value: `-16px` }, 82 ], 83 }, 84 { 85 header: "Inherited from div#topleft", 86 }, 87 { 88 selector: `*`, 89 ancestorRulesData: null, 90 inherited: true, 91 declarations: [{ name: "cursor", value: "default" }], 92 }, 93 { 94 header: "Inherited from body", 95 }, 96 { 97 selector: `body`, 98 ancestorRulesData: null, 99 inherited: true, 100 declarations: [{ name: "color", value: "#333" }], 101 }, 102 ]); 103 104 info("Check #list children"); 105 const listNode = await getNodeFront("#list", inspector); 106 const listChildren = await inspector.markup.walker.children(listNode); 107 const listAfterNode = listChildren.nodes.at(-1); 108 is( 109 listAfterNode.displayName, 110 "::after", 111 "display name is correct for #list::after" 112 ); 113 const listAfterChildren = 114 await inspector.markup.walker.children(listAfterNode); 115 is( 116 listAfterChildren.nodes.length, 117 1, 118 "ol::after has the expected number of children" 119 ); 120 const listAfterMarkerNode = listAfterChildren.nodes[0]; 121 is( 122 listAfterMarkerNode.displayName, 123 "::marker", 124 "display name is correct for #list::after::marker" 125 ); 126 info("Check rules on #list-item::marker node"); 127 await selectNode(listAfterMarkerNode, inspector); 128 checkRuleViewContent(view, [ 129 { 130 selector: `#list::after::marker`, 131 ancestorRulesData: null, 132 declarations: [ 133 { name: "content", value: `"+"` }, 134 { name: "color", value: `tomato` }, 135 ], 136 }, 137 { 138 header: "Inherited from ol#list", 139 }, 140 { 141 selector: `*`, 142 ancestorRulesData: null, 143 inherited: true, 144 declarations: [{ name: "cursor", value: "default" }], 145 }, 146 { 147 header: "Inherited from body", 148 }, 149 { 150 selector: `body`, 151 ancestorRulesData: null, 152 inherited: true, 153 declarations: [{ name: "color", value: "#333", overridden: true }], 154 }, 155 ]); 156 157 info("Check #list-item children"); 158 const listItemNode = await getNodeFront("#list-item", inspector); 159 const listItemChildren = await inspector.markup.walker.children(listItemNode); 160 161 is(listItemChildren.nodes.length, 4, "<li> has correct number of children"); 162 163 info("Check rules on #list-item::marker node"); 164 const markerElement = listItemChildren.nodes[0]; 165 is(markerElement.displayName, "::marker", "display name is correct"); 166 await selectNode(markerElement, inspector); 167 checkRuleViewContent(view, [ 168 { 169 selector: `#list-item::marker`, 170 ancestorRulesData: null, 171 declarations: [{ name: "color", value: `purple` }], 172 }, 173 { 174 header: "Inherited from li#list-item", 175 }, 176 { 177 selector: `*`, 178 ancestorRulesData: null, 179 inherited: true, 180 declarations: [{ name: "cursor", value: "default" }], 181 }, 182 { 183 header: "Inherited from body", 184 }, 185 { 186 selector: `body`, 187 ancestorRulesData: null, 188 inherited: true, 189 declarations: [{ name: "color", value: "#333", overridden: true }], 190 }, 191 ]); 192 193 info("Check rules on #list-item::before node"); 194 const listBeforeElement = listItemChildren.nodes[1]; 195 is(listBeforeElement.displayName, "::before", "display name is correct"); 196 await selectNode(listBeforeElement, inspector); 197 checkRuleViewContent(view, [ 198 { 199 selector: `.box::before`, 200 ancestorRulesData: null, 201 declarations: [ 202 { name: "background", value: "green" }, 203 { name: "content", value: `" "` }, 204 { name: "position", value: `absolute` }, 205 { name: "height", value: `32px` }, 206 { name: "width", value: `32px` }, 207 ], 208 }, 209 { 210 header: "Inherited from li#list-item", 211 }, 212 { 213 selector: `*`, 214 ancestorRulesData: null, 215 inherited: true, 216 declarations: [{ name: "cursor", value: "default" }], 217 }, 218 { 219 header: "Inherited from body", 220 }, 221 { 222 selector: `body`, 223 ancestorRulesData: null, 224 inherited: true, 225 declarations: [{ name: "color", value: "#333" }], 226 }, 227 ]); 228 229 info("Check unmatched selector parts in Pseudo element section"); 230 await selectNode("#with-unmatched-selector", inspector); 231 checkRuleViewContent(view, [ 232 { 233 header: `Pseudo-elements`, 234 }, 235 { 236 selector: `#with-unmatched-selector::before, ~~unknown::before~~, #with-unmatched-selector::after, ~~anotherunknown~~`, 237 declarations: [{ name: "content", value: `"unmatched pseudo"` }], 238 }, 239 { 240 header: `This Element`, 241 }, 242 { 243 selector: `element`, 244 declarations: [], 245 selectorEditable: false, 246 }, 247 { 248 selector: `*`, 249 declarations: [{ name: "cursor", value: "default" }], 250 }, 251 { 252 header: "Inherited from body", 253 }, 254 { 255 selector: `body`, 256 inherited: true, 257 declarations: [{ name: "color", value: "#333" }], 258 }, 259 ]); 260 261 info("Check rules on ::view-transition"); 262 const htmlNodeFront = await getNodeFront("html", inspector); 263 264 const onMarkupMutation = inspector.once("markupmutation"); 265 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { 266 const document = content.document; 267 const transition = document.startViewTransition(() => { 268 document.querySelector(".transition").append("updated"); 269 }); 270 await transition.ready; 271 await transition.updateCallbackDone; 272 }); 273 await onMarkupMutation; 274 275 const htmlChildren = await inspector.markup.walker.children(htmlNodeFront); 276 const viewTransitionNodeFront = htmlChildren.nodes[2]; 277 278 is( 279 viewTransitionNodeFront.getAttribute("type"), 280 ":view-transition", 281 "Got expected ::view-transition node front" 282 ); 283 284 await selectNode(viewTransitionNodeFront, inspector); 285 286 checkRuleViewContent(view, [ 287 { 288 selector: `::view-transition`, 289 declarations: [{ name: "color", value: `lime` }], 290 }, 291 { 292 header: "Inherited from html", 293 }, 294 { 295 selector: `html:active-view-transition`, 296 inherited: true, 297 declarations: [{ name: "color", value: "peachpuff", overridden: true }], 298 }, 299 { 300 selector: `*`, 301 inherited: true, 302 declarations: [{ name: "cursor", value: "default" }], 303 }, 304 ]); 305 306 const viewTransitionChildren = await inspector.markup.walker.children( 307 viewTransitionNodeFront 308 ); 309 const viewTransitionGroupNodeFront = viewTransitionChildren.nodes[0]; 310 is( 311 viewTransitionGroupNodeFront.getAttribute("type"), 312 ":view-transition-group", 313 "Got expected ::view-transition-group node front" 314 ); 315 316 const viewTransitionGroupChildren = await inspector.markup.walker.children( 317 viewTransitionGroupNodeFront 318 ); 319 const viewTransitionImagePairNodeFront = viewTransitionGroupChildren.nodes[0]; 320 is( 321 viewTransitionImagePairNodeFront.getAttribute("type"), 322 ":view-transition-image-pair", 323 "Got expected ::view-transition-image-pair node front" 324 ); 325 326 const viewTransitionImagePairChildren = 327 await inspector.markup.walker.children(viewTransitionImagePairNodeFront); 328 const [viewTransitionOldNodeFront, viewTransitionNewNodeFront] = 329 viewTransitionImagePairChildren.nodes; 330 is( 331 viewTransitionOldNodeFront.getAttribute("type"), 332 ":view-transition-old", 333 "Got expected ::view-transition-old node front" 334 ); 335 is( 336 viewTransitionNewNodeFront.getAttribute("type"), 337 ":view-transition-new", 338 "Got expected ::view-transition-new node front" 339 ); 340 341 info("Check rules on ::view-transition-old"); 342 await selectNode(viewTransitionOldNodeFront, inspector); 343 checkRuleViewContent(view, [ 344 { 345 selector: `::view-transition-old(root), ~~::view-transition-new(root)~~`, 346 declarations: [ 347 { name: "animation-duration", value: `1000s` }, 348 { name: "top", value: `1em` }, 349 { name: "gap", value: `10px`, inactiveCSS: true }, 350 ], 351 }, 352 { 353 header: "Inherited from ::view-transition", 354 }, 355 { 356 selector: `::view-transition`, 357 inherited: true, 358 declarations: [{ name: "color", value: `lime` }], 359 }, 360 { 361 header: "Inherited from html", 362 }, 363 { 364 selector: `html:active-view-transition`, 365 inherited: true, 366 declarations: [{ name: "color", value: "peachpuff", overridden: true }], 367 }, 368 { 369 selector: `*`, 370 inherited: true, 371 declarations: [{ name: "cursor", value: "default" }], 372 }, 373 ]); 374 375 info("Check rules on ::view-transition-new"); 376 await selectNode(viewTransitionNewNodeFront, inspector); 377 checkRuleViewContent(view, [ 378 { 379 selector: `::view-transition-new(root)`, 380 declarations: [ 381 { name: "animation-duration", value: `3600s` }, 382 { name: "color", value: `thistle` }, 383 ], 384 }, 385 { 386 selector: `~~::view-transition-old(root)~~, ::view-transition-new(root)`, 387 declarations: [ 388 { name: "animation-duration", value: `1000s`, overridden: true }, 389 { 390 name: "top", 391 value: `1em`, 392 // This shouldn't be inactive. See Bug 1998357 393 inactiveCSS: true, 394 }, 395 { name: "gap", value: `10px`, inactiveCSS: true }, 396 ], 397 }, 398 { 399 header: "Inherited from ::view-transition", 400 }, 401 { 402 selector: `::view-transition`, 403 inherited: true, 404 declarations: [{ name: "color", value: `lime`, overridden: true }], 405 }, 406 { 407 header: "Inherited from html", 408 }, 409 { 410 selector: `html:active-view-transition`, 411 inherited: true, 412 declarations: [{ name: "color", value: "peachpuff", overridden: true }], 413 }, 414 { 415 selector: `*`, 416 inherited: true, 417 declarations: [{ name: "cursor", value: "default" }], 418 }, 419 ]); 420 });