mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(compiler): support one additional level of nesting in :host()
Previously we supported one level of nested parentheses inside of a
`:host()` selector, e.g. `:host(:not(p))`. This caused a breakage in g3
when I migrated a selector from `:host:not(:has(p))` to
`:host(:not(:has(p)))`. This change adds support for just one more level
of nesting.
It'd be nice to move everything to a real CSS parser (or even update it
to count parentheses like I did with :host-context()), but I wasn't able
to get that to work in ~20 minutes and I'm focusing on other things at
the moment.
This change punts the problem until somebody tries to use just one more
level of nesting in a selector.
Fixes #64830
(cherry picked from commit 444143758e)
This commit is contained in:
parent
3bbcae6ce8
commit
aad6ced0ef
2 changed files with 10 additions and 1 deletions
|
|
@ -1067,7 +1067,13 @@ const _cssContentUnscopedRuleRe =
|
|||
const _polyfillHost = '-shadowcsshost';
|
||||
// note: :host-context pre-processed to -shadowcsshostcontext.
|
||||
const _polyfillHostContext = '-shadowcsscontext';
|
||||
const _parenSuffix = '(?:\\((' + '(?:\\([^)(]*\\)|[^)(]*)+?' + ')\\))';
|
||||
// Matches text content with no parentheses, e.g., "foo"
|
||||
const _noParens = '[^)(]*';
|
||||
// Matches content with at most ONE level of nesting, e.g., "a(b)c"
|
||||
const _level1Parens = String.raw`(?:\(${_noParens}\)|${_noParens})+?`;
|
||||
// Matches content with at most TWO levels of nesting, e.g., "a(b(c)d)e"
|
||||
const _level2Parens = String.raw`(?:\(${_level1Parens}\)|${_noParens})+?`;
|
||||
const _parenSuffix = String.raw`(?:\((${_level2Parens})\))`;
|
||||
const _cssColonHostRe = new RegExp(_polyfillHost + _parenSuffix + '?([^,{]*)', 'gim');
|
||||
// note: :host-context patterns are terminated with `{`, as opposed to :host which
|
||||
// is both `{` and `,` because :host-context handles top-level commas differently.
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ describe('ShadowCss, :host and :host-context', () => {
|
|||
expect(shim(':host(:not(p)):before {}', 'contenta', 'a-host')).toEqualCss(
|
||||
'[a-host]:not(p):before {}',
|
||||
);
|
||||
expect(shim(':host(:not(:has(p))) {}', 'contenta', 'a-host')).toEqualCss(
|
||||
'[a-host]:not(:has(p)) {}',
|
||||
);
|
||||
expect(shim(':host:not(:host.foo) {}', 'contenta', 'a-host')).toEqualCss(
|
||||
'[a-host]:not([a-host].foo) {}',
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue