Skip to content

Commit 66dcc69

Browse files
GeorgySergadevversion
authored andcommitted
fix(compiler): allow combinators inside pseudo selectors (#57796)
allow css combinators within pseudo selector functions, parsing those correctly. Similarly to previous version, don't break selectors into part if combinators are within parenthesis, for example `:where(.one > .two)` PR Close #57796
1 parent 7a6fd42 commit 66dcc69

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

packages/compiler/src/shadow_css.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,9 @@ export class ShadowCss {
808808
let scopedSelector = '';
809809
let startIndex = 0;
810810
let res: RegExpExecArray | null;
811-
// Spaces aren't used as a delimeter if they are within parenthesis, for example
811+
// Combinators aren't used as a delimeter if they are within parenthesis, for example
812812
// `:where(.one .two)` stays intact.
813-
const sep = /( (?![^\(]*\))|>|\+|~(?!=))\s*/g;
813+
const sep = /( |>|\+|~(?!=))(?![^\(]*\))\s*/g;
814814

815815
// If a selector appears before :host it should not be shimmed as it
816816
// matches on ancestor elements and not on elements in the host's shadow

packages/compiler/test/shadow_css/shadow_css_spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ describe('ShadowCss', () => {
104104
expect(shim(':where(.one, .two) {}', 'contenta', 'hosta')).toEqualCss(
105105
':where(.one[contenta], .two[contenta]) {}',
106106
);
107+
expect(shim(':where(.one > .two) {}', 'contenta', 'hosta')).toEqualCss(
108+
':where(.one[contenta] > .two[contenta]) {}',
109+
);
110+
expect(shim(':where(> .one) {}', 'contenta', 'hosta')).toEqualCss(
111+
':where( > .one[contenta]) {}',
112+
);
113+
expect(shim(':where(:not(.one) ~ .two) {}', 'contenta', 'hosta')).toEqualCss(
114+
':where([contenta]:not(.one) ~ .two[contenta]) {}',
115+
);
107116

108117
// :is()
109118
expect(shim('div:is(.foo) {}', 'contenta', 'a-host')).toEqualCss('div[contenta]:is(.foo) {}');
@@ -148,6 +157,9 @@ describe('ShadowCss', () => {
148157
expect(shim(':has(a) :host :has(b) {}', 'contenta', 'hosta')).toEqualCss(
149158
':has(a) [hosta] [contenta]:has(b) {}',
150159
);
160+
expect(shim('div:has(~ .one) {}', 'contenta', 'hosta')).toEqualCss(
161+
'div[contenta]:has(~ .one) {}',
162+
);
151163
// Unlike `:is()` or `:where()` the attribute selector isn't placed inside
152164
// of `:has()`. That is deliberate, `[contenta]:has(a)` would select all
153165
// `[contenta]` with `a` inside, while `:has(a[contenta])` would select

0 commit comments

Comments
 (0)