Skip to content

Conversation

crisbeto
Copy link
Member

Both :host and :host-context work by looking for a specific character sequence that is terminated by , or { and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for :host, because each :host produces one scoped selector which doesn't affect any child selectors, however it breaks down with :host-context which replaces each instance with two selectors. For example, if we have a selector in the form of :host-context(.foo) a:not(.a, .b), the compiler ends up determining that .a, is the end selector and produces .foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}.

These changes resolve the issue by splitting the CSS alogn top-level commas, processing the :host-context in them individually, and stiching the CSS back together.

Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`. These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.
@crisbeto crisbeto added the target: patch This PR is targeted for the next patch release label Dec 21, 2024
@angular-robot angular-robot bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Dec 21, 2024
@ngbot ngbot bot added this to the Backlog milestone Dec 21, 2024
@crisbeto crisbeto added the action: global presubmit The PR is in need of a google3 global presubmit label Dec 21, 2024
@crisbeto
Copy link
Member Author

Passing TGP, aside from some unrelated broken targets.

@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer and removed action: global presubmit The PR is in need of a google3 global presubmit labels Dec 21, 2024
@crisbeto crisbeto marked this pull request as ready for review December 21, 2024 16:31
@AndrewKushnir
Copy link
Contributor

// cc @mattrberry

@mattrbeck
Copy link
Member

This makes me want to remove support for :host-context(.a, .b) to match the Shadow DOM spec, but LGTM since this PR just fixes a bug and doesn't change the behavior otherwise :)

const _parenSuffix = '(?:\\((' + '(?:\\([^)(]*\\)|[^)(]*)+?' + ')\\))';
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOC: do you have any information on this?

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Jan 21, 2025
@AndrewKushnir
Copy link
Contributor

This PR was merged into the repository by commit 98f8207.

The changes were merged into the following branches: main, 19.1.x

AndrewKushnir pushed a commit that referenced this pull request Jan 21, 2025
…or (#59276) Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`. These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together. PR Close #59276
PrajaktaB27 pushed a commit to PrajaktaB27/angular that referenced this pull request Feb 7, 2025
…or (angular#59276) Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`. These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together. PR Close angular#59276
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: compiler Issues related to `ngc`, Angular's template compiler target: patch This PR is targeted for the next patch release

4 participants