browser_rules_inherited-element-backed-pseudo-elements.js (15089B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Tests that inherited element-backed pseudo element rules are properly displayed in 7 // the Rules view and that declarations are properly overridden. 8 9 const TEST_URI = ` 10 <style> 11 details { 12 --x: blue; 13 color: gold; 14 15 summary { color: violet; } 16 17 &::details-content { 18 --x: tomato; 19 color: dodgerblue; 20 background-color: rgb(200 0 0 / 0.1); 21 } 22 } 23 24 /* use :where() to have a lower specificity than the details rule above */ 25 :where(body > details)::details-content { 26 color: forestgreen; 27 } 28 29 p { 30 outline-color: var(--x); 31 32 &::after { 33 content: " meow"; 34 color: green; 35 } 36 } 37 38 details#in-summary { 39 color: cyan; 40 41 & summary { 42 color: hotpink; 43 } 44 45 &::details-content { 46 --x: rebeccapurple; 47 color: brown; 48 } 49 } 50 51 details#vip::details-content { 52 color: blue !important; 53 } 54 55 details#vip::details-content { 56 color: red; 57 } 58 </style> 59 <details open> 60 <summary> 61 Top-level summary 62 <details id=in-summary open> 63 <summary>nested summary</summary> 64 details in summary 65 <p>child of details in summary</p> 66 </details> 67 </summary> 68 top-level details 69 <summary id=non-functional-summary>not a real summary</summary> 70 <p>in top-level details</p> 71 /* don't use an id so the "inherited from" section would have the same text as the 72 section for the parent details. This will assert that we do get separate inhertied 73 section for those different "levels" */ 74 <details class=in-details open> 75 <summary>nested details summary</summary> 76 nested details 77 <p>child of nested details</p> 78 </details> 79 </details> 80 <details id=vip open> 81 <summary>s</summary> 82 <article>hello</hello> 83 </details> 84 `; 85 86 add_task(async function () { 87 await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); 88 const { inspector, view } = await openRuleView(); 89 90 info( 91 "Check that there's no inherited ::details-content header when top-level <summary> is selected" 92 ); 93 await selectNode("summary", inspector); 94 await checkRuleViewContent(view, [ 95 { 96 selector: `element`, 97 ancestorRulesData: null, 98 selectorEditable: false, 99 declarations: [], 100 }, 101 { 102 selector: `& summary`, 103 ancestorRulesData: ["details {"], 104 declarations: [{ name: "color", value: "violet" }], 105 }, 106 { 107 header: "Inherited from details", 108 }, 109 { 110 selector: `details`, 111 inherited: true, 112 declarations: [ 113 { name: "--x", value: "blue" }, 114 { name: "color", value: "gold", overridden: true }, 115 ], 116 }, 117 ]); 118 119 info( 120 "Check that there are expected inherited headers when children of top-level <details> is selected" 121 ); 122 await selectNode("body > details > p", inspector); 123 await checkRuleViewContent(view, [ 124 { 125 header: "Pseudo-elements", 126 }, 127 { 128 selector: `&::after`, 129 ancestorRulesData: [`p {`], 130 declarations: [ 131 { name: "content", value: `" meow"` }, 132 { name: "color", value: "green" }, 133 ], 134 }, 135 { 136 header: "This Element", 137 }, 138 { 139 selector: `element`, 140 ancestorRulesData: null, 141 selectorEditable: false, 142 declarations: [], 143 }, 144 { 145 selector: `p`, 146 declarations: [{ name: "outline-color", value: "var(--x)" }], 147 }, 148 { 149 header: "Inherited from details::details-content", 150 }, 151 { 152 selector: `&::details-content`, 153 ancestorRulesData: [`details {`], 154 inherited: true, 155 declarations: [ 156 { name: "--x", value: "tomato" }, 157 { name: "color", value: "dodgerblue" }, 158 ], 159 }, 160 { 161 selector: `:where(body > details)::details-content`, 162 inherited: true, 163 declarations: [ 164 { 165 name: "color", 166 value: "forestgreen", 167 // overridden because lower specificity than ::details-content 168 overridden: true, 169 }, 170 ], 171 }, 172 { 173 header: "Inherited from details", 174 }, 175 { 176 selector: `details`, 177 inherited: true, 178 declarations: [ 179 { 180 name: "--x", 181 value: "blue", 182 overridden: true, 183 }, 184 { 185 name: "color", 186 value: "gold", 187 // overridden by color: dodgerblue on ::details-content 188 overridden: true, 189 }, 190 ], 191 }, 192 ]); 193 194 checkCSSVariableOutput( 195 view, 196 "p", 197 "outline-color", 198 "inspector-variable", 199 "tomato" 200 ); 201 202 info("Check rules and declarations for details in summary"); 203 await selectNode("details#in-summary", inspector); 204 await checkRuleViewContent(view, [ 205 { 206 header: "Pseudo-elements", 207 }, 208 { 209 selector: `&::details-content`, 210 ancestorRulesData: ["details#in-summary {"], 211 declarations: [ 212 { name: "--x", value: "rebeccapurple" }, 213 { name: "color", value: "brown" }, 214 ], 215 }, 216 { 217 selector: `&::details-content`, 218 ancestorRulesData: ["details {"], 219 declarations: [ 220 { name: "--x", value: "tomato", overridden: true }, 221 { name: "color", value: "dodgerblue", overridden: true }, 222 { name: "background-color", value: "rgb(200 0 0 / 0.1)" }, 223 ], 224 }, 225 { 226 header: "This Element", 227 }, 228 { 229 selector: `element`, 230 ancestorRulesData: null, 231 selectorEditable: false, 232 declarations: [], 233 }, 234 { 235 selector: `details#in-summary`, 236 declarations: [{ name: "color", value: "cyan" }], 237 }, 238 { 239 selector: `details`, 240 declarations: [ 241 { name: "--x", value: "blue" }, 242 { name: "color", value: "gold", overridden: true }, 243 ], 244 }, 245 { 246 header: "Inherited from summary", 247 }, 248 { 249 selector: `& summary`, 250 ancestorRulesData: ["details {"], 251 inherited: true, 252 declarations: [{ name: "color", value: "violet", overridden: true }], 253 }, 254 ]); 255 256 info("Check rules and declarations for nested summary"); 257 await selectNode("details#in-summary summary", inspector); 258 259 await checkRuleViewContent(view, [ 260 { 261 selector: `element`, 262 ancestorRulesData: null, 263 selectorEditable: false, 264 declarations: [], 265 }, 266 { 267 selector: `& summary`, 268 ancestorRulesData: ["details#in-summary {"], 269 declarations: [{ name: "color", value: "hotpink" }], 270 }, 271 { 272 selector: `& summary`, 273 ancestorRulesData: ["details {"], 274 declarations: [{ name: "color", value: "violet", overridden: true }], 275 }, 276 { 277 header: "Inherited from details#in-summary", 278 }, 279 { 280 selector: `details#in-summary`, 281 inherited: true, 282 declarations: [{ name: "color", value: "cyan", overridden: true }], 283 }, 284 { 285 selector: `details`, 286 inherited: true, 287 declarations: [ 288 { name: "--x", value: "blue" }, 289 { name: "color", value: "gold", overridden: true }, 290 ], 291 }, 292 ]); 293 294 info("Check rules and declarations for nested <details> child"); 295 await selectNode("details#in-summary p", inspector); 296 await checkRuleViewContent(view, [ 297 { 298 header: "Pseudo-elements", 299 }, 300 { 301 selector: `&::after`, 302 ancestorRulesData: [`p {`], 303 declarations: [ 304 { name: "content", value: `" meow"` }, 305 { name: "color", value: "green" }, 306 ], 307 }, 308 { 309 header: "This Element", 310 }, 311 { 312 selector: `element`, 313 ancestorRulesData: null, 314 selectorEditable: false, 315 declarations: [], 316 }, 317 { 318 selector: `p`, 319 declarations: [{ name: "outline-color", value: "var(--x)" }], 320 }, 321 { 322 header: "Inherited from details#in-summary::details-content", 323 }, 324 { 325 selector: `&::details-content`, 326 ancestorRulesData: [`details#in-summary {`], 327 inherited: true, 328 declarations: [ 329 { name: "--x", value: "rebeccapurple" }, 330 { 331 name: "color", 332 value: "brown", 333 }, 334 ], 335 }, 336 { 337 selector: `&::details-content`, 338 ancestorRulesData: [`details {`], 339 inherited: true, 340 declarations: [ 341 { name: "--x", value: "tomato", overridden: true }, 342 { 343 name: "color", 344 value: "dodgerblue", 345 overridden: true, 346 }, 347 ], 348 }, 349 { 350 header: "Inherited from details#in-summary", 351 }, 352 { 353 selector: `details#in-summary`, 354 inherited: true, 355 declarations: [{ name: "color", value: "cyan", overridden: true }], 356 }, 357 { 358 selector: `details`, 359 inherited: true, 360 declarations: [ 361 { name: "--x", value: "blue", overridden: true }, 362 { name: "color", value: "gold", overridden: true }, 363 ], 364 }, 365 { 366 header: "Inherited from summary", 367 }, 368 { 369 selector: `& summary`, 370 ancestorRulesData: [`details {`], 371 inherited: true, 372 declarations: [ 373 { 374 name: "color", 375 value: "violet", 376 overridden: true, 377 }, 378 ], 379 }, 380 ]); 381 382 checkCSSVariableOutput( 383 view, 384 "p", 385 "outline-color", 386 "inspector-variable", 387 "rebeccapurple" 388 ); 389 390 info("Check rules and declarations for second summary inside details"); 391 // when a <details> element has multiple <summary> children, only the first one is 392 // actually interactive. The other ones are placed inside the ::details-content 393 await selectNode("summary#non-functional-summary", inspector); 394 await checkRuleViewContent(view, [ 395 { selector: `element`, selectorEditable: false, declarations: [] }, 396 { 397 selector: `& summary`, 398 ancestorRulesData: [`details {`], 399 declarations: [{ name: "color", value: "violet" }], 400 }, 401 { 402 header: "Inherited from details::details-content", 403 }, 404 { 405 selector: `&::details-content`, 406 ancestorRulesData: [`details {`], 407 inherited: true, 408 declarations: [ 409 { name: "--x", value: "tomato" }, 410 { name: "color", value: "dodgerblue", overridden: true }, 411 ], 412 }, 413 { 414 selector: `:where(body > details)::details-content`, 415 inherited: true, 416 declarations: [ 417 { 418 name: "color", 419 value: "forestgreen", 420 overridden: true, 421 }, 422 ], 423 }, 424 { 425 header: "Inherited from details", 426 }, 427 { 428 selector: `details`, 429 inherited: true, 430 declarations: [ 431 { 432 name: "--x", 433 value: "blue", 434 overridden: true, 435 }, 436 { 437 name: "color", 438 value: "gold", 439 overridden: true, 440 }, 441 ], 442 }, 443 ]); 444 445 info("Check rules and declarations for details in details"); 446 await selectNode("details.in-details", inspector); 447 await checkRuleViewContent(view, [ 448 { 449 header: "Pseudo-elements", 450 }, 451 { 452 selector: `&::details-content`, 453 ancestorRulesData: ["details {"], 454 declarations: [ 455 { name: "--x", value: "tomato" }, 456 { name: "color", value: "dodgerblue" }, 457 { name: "background-color", value: "rgb(200 0 0 / 0.1)" }, 458 ], 459 }, 460 { 461 header: "This Element", 462 }, 463 { 464 selector: `element`, 465 selectorEditable: false, 466 ancestorRulesData: null, 467 declarations: [], 468 }, 469 { 470 selector: `details`, 471 declarations: [ 472 { name: "--x", value: "blue" }, 473 { name: "color", value: "gold" }, 474 ], 475 }, 476 { 477 header: "Inherited from details::details-content", 478 }, 479 { 480 selector: `:where(body > details)::details-content`, 481 inherited: true, 482 declarations: [{ name: "color", value: "forestgreen", overridden: true }], 483 }, 484 ]); 485 486 info("Check rules and declarations for children of details in details"); 487 await selectNode("details.in-details p", inspector); 488 await checkRuleViewContent(view, [ 489 { 490 header: "Pseudo-elements", 491 }, 492 { 493 selector: `&::after`, 494 ancestorRulesData: [`p {`], 495 declarations: [ 496 { name: "content", value: `" meow"` }, 497 { name: "color", value: "green" }, 498 ], 499 }, 500 { 501 header: "This Element", 502 }, 503 { 504 selector: `element`, 505 selectorEditable: false, 506 ancestorRulesData: null, 507 declarations: [], 508 }, 509 { 510 selector: `p`, 511 declarations: [{ name: "outline-color", value: "var(--x)" }], 512 }, 513 { 514 // this is for the body > details > details::details-content pseudo 515 header: "Inherited from details::details-content", 516 }, 517 { 518 selector: `&::details-content`, 519 ancestorRulesData: [`details {`], 520 inherited: true, 521 declarations: [ 522 { name: "--x", value: "tomato" }, 523 { 524 name: "color", 525 value: "dodgerblue", 526 }, 527 ], 528 }, 529 { 530 // this is for the body > details::details-content pseudo 531 header: "Inherited from details::details-content", 532 }, 533 { 534 selector: `:where(body > details)::details-content`, 535 inherited: true, 536 declarations: [{ name: "color", value: "forestgreen", overridden: true }], 537 }, 538 { 539 header: "Inherited from details", 540 }, 541 { 542 selector: `details`, 543 inherited: true, 544 declarations: [ 545 { 546 name: "--x", 547 value: "blue", 548 overridden: true, 549 }, 550 { 551 name: "color", 552 value: "gold", 553 overridden: true, 554 }, 555 ], 556 }, 557 ]); 558 559 info( 560 "Check that properties in inherited element-backed pseudo element rules are properly picked when using !important" 561 ); 562 await selectNode("#vip article", inspector); 563 await checkRuleViewContent(view, [ 564 { 565 selector: `element`, 566 selectorEditable: false, 567 ancestorRulesData: null, 568 declarations: [], 569 }, 570 { 571 header: "Inherited from details#vip::details-content", 572 }, 573 { 574 selector: `details#vip::details-content`, 575 inherited: true, 576 declarations: [{ name: "color", value: "red", overridden: true }], 577 }, 578 { 579 selector: `details#vip::details-content`, 580 inherited: true, 581 declarations: [{ name: "color", value: "blue !important" }], 582 }, 583 { 584 selector: `&::details-content`, 585 ancestorRulesData: [`details {`], 586 inherited: true, 587 declarations: [ 588 { name: "--x", value: "tomato" }, 589 { name: "color", value: "dodgerblue", overridden: true }, 590 ], 591 }, 592 { 593 selector: `:where(body > details)::details-content`, 594 inherited: true, 595 declarations: [{ name: "color", value: "forestgreen", overridden: true }], 596 }, 597 { 598 header: "Inherited from details#vip", 599 }, 600 { 601 selector: `details`, 602 inherited: true, 603 declarations: [ 604 { 605 name: "--x", 606 value: "blue", 607 overridden: true, 608 }, 609 { 610 name: "color", 611 value: "gold", 612 overridden: true, 613 }, 614 ], 615 }, 616 ]); 617 });