Skip to content

Commit

Permalink
[@scope] Use CalculateNestingContext in setSelectorText
Browse files Browse the repository at this point in the history
This fixes an issue where relative selectors in @scope rules
would get an implied '&' instead of an implied ':scope'.

Fixed: 363189649
Change-Id: Ie53414cb122d08665d93877185ca51c91263b693
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6040164
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Steinar H Gunderson <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1389225}
  • Loading branch information
andruud authored and chromium-wpt-export-bot committed Nov 28, 2024
1 parent 5c711b5 commit 54647f8
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions css/css-cascade/scope-invalidation.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
function assert_green(element) {
assert_equals(getComputedStyle(element).backgroundColor, 'rgb(0, 128, 0)');
}
function assert_red(element) {
assert_equals(getComputedStyle(element).backgroundColor, 'rgb(255, 0, 0)');
}
function assert_not_green(element) {
assert_equals(getComputedStyle(element).backgroundColor, 'rgb(0, 0, 0)');
}
Expand Down Expand Up @@ -780,3 +783,90 @@
}, ':nth-child() in scope limit');

</script>

<template>
<style>
@scope (.a) {
.nomatch { background-color: green; }
}
</style>
<div id=wrapper>
<div class=a>
<div class=b></div>
</div>
</div>
</template>
<script>
test_scope_invalidation(document.currentScript, () => {
let b = main.querySelector('.b');
assert_not_green(b);
let scope_rule = main.querySelector('style').sheet.cssRules[0];
assert_true(scope_rule instanceof CSSScopeRule);
scope_rule.cssRules[0].selectorText = '.b';
assert_green(b);
}, 'Modifying selectorText invalidates affected elements');
</script>

<template>
<style>
@scope (.a) {
.nomatch { background-color: green; }
}
</style>
<div id=wrapper>
<div class=a>
<div class=b></div>
</div>
</div>
</template>
<script>
test_scope_invalidation(document.currentScript, () => {
let b = main.querySelector('.b');
assert_not_green(b);
let scope_rule = main.querySelector('style').sheet.cssRules[0];
assert_true(scope_rule instanceof CSSScopeRule);
scope_rule.cssRules[0].selectorText = '> .b';
assert_green(b);
}, 'Modifying selectorText invalidates affected elements (>)');
</script>

<template>
<style>
.a {
> .b, > .c {
background-color: green; /* Specificity: (0, 2, 0) */
}
}
@scope (.a.a) {
.nomatch1 {
background-color: red; /* Specificity: (0, 1, 0) */
}
.nomatch2 {
background-color: red; /* Specificity: (0, 1, 0) */
}
}
</style>
<div id=wrapper>
<div class=a>
<div class=b></div>
<div class=c></div>
</div>
</div>
</template>
<script>
test_scope_invalidation(document.currentScript, () => {
let b = main.querySelector('.b');
let c = main.querySelector('.c');
assert_green(b);
assert_green(c);
let scope_rule = main.querySelector('style').sheet.cssRules[1];
assert_true(scope_rule instanceof CSSScopeRule);
// Note: relative selectors imply a :where(:scope) selector to the left,
// which is observably different from an implicit '&' selector through
// specificity.
scope_rule.cssRules[0].selectorText = '> .b'; /* Still (0, 1, 0) */
scope_rule.cssRules[1].selectorText = '& > .c'; /* (0, 3, 0) */
assert_green(b);
assert_red(c);
}, 'Relative selectors set with selectorText are relative to :scope, not &');
</script>

0 comments on commit 54647f8

Please sign in to comment.