mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(compiler): apply style on :host attributes in prod builds. (#49118)
In prod builds, selectors are optimized and spaces a removed. #48558 introduced a regression on selectors without spaces. This commit fixes tihs. Fixes #49100 PR Close #49118
This commit is contained in:
committed by
Andrew Scott
parent
926db6dd36
commit
073ebfe09e
@@ -713,7 +713,7 @@ export class ShadowCss {
|
||||
// (ie: ".\fc ber" for ".über") is not a separator between 2 selectors
|
||||
// also keep in mind that backslashes are replaced by a placeholder by SafeSelector
|
||||
// These escaped selectors happen for example when esbuild runs with optimization.minify.
|
||||
if (part.match(_placeholderRe) && selector[res.index + 1]?.match(/[a-fA-F\d]/)) {
|
||||
if (part.match(/__esc-ph-(\d+)__/) && selector[res.index + 1]?.match(/[a-fA-F\d]/)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -752,7 +752,13 @@ class SafeSelector {
|
||||
// pseudo-class, but writing `.foo\:blue` will match, because the colon was escaped.
|
||||
// Replace all escape sequences (`\` followed by a character) with a placeholder so
|
||||
// that our handling of pseudo-selectors doesn't mess with them.
|
||||
selector = this._escapeRegexMatches(selector, /(\\.)/g);
|
||||
// Escaped characters have a specific placeholder so they can be detected separately.
|
||||
selector = selector.replace(/(\\.)/g, (_, keep) => {
|
||||
const replaceBy = `__esc-ph-${this.index}__`;
|
||||
this.placeholders.push(keep);
|
||||
this.index++;
|
||||
return replaceBy;
|
||||
});
|
||||
|
||||
// Replaces the expression in `:nth-child(2n + 1)` with a placeholder.
|
||||
// WS and "+" would otherwise be interpreted as selector separators.
|
||||
@@ -765,7 +771,7 @@ class SafeSelector {
|
||||
}
|
||||
|
||||
restore(content: string): string {
|
||||
return content.replace(_placeholderRe, (_ph, index) => this.placeholders[+index]);
|
||||
return content.replace(/__(?:ph|esc-ph)-(\d+)__/g, (_ph, index) => this.placeholders[+index]);
|
||||
}
|
||||
|
||||
content(): string {
|
||||
@@ -825,8 +831,6 @@ const _commentWithHashRe = /\/\*\s*#\s*source(Mapping)?URL=/g;
|
||||
const COMMENT_PLACEHOLDER = '%COMMENT%';
|
||||
const _commentWithHashPlaceHolderRe = new RegExp(COMMENT_PLACEHOLDER, 'g');
|
||||
|
||||
const _placeholderRe = /__ph-(\d+)__/g;
|
||||
|
||||
const BLOCK_PLACEHOLDER = '%BLOCK%';
|
||||
const _ruleRe = new RegExp(
|
||||
`(\\s*(?:${COMMENT_PLACEHOLDER}\\s*)*)([^;\\{\\}]+?)(\\s*)((?:{%BLOCK%}?\\s*;?)|(?:\\s*;))`,
|
||||
|
||||
@@ -27,6 +27,19 @@ describe('ShadowCss, :host and :host-context', () => {
|
||||
expect(shim(':host([a=b]) {}', 'contenta', 'a-host')).toEqualCss('[a=b][a-host] {}');
|
||||
});
|
||||
|
||||
it('should handle attribute and next operator without spaces', () => {
|
||||
expect(shim(':host[foo]>div {}', 'contenta', 'a-host'))
|
||||
.toEqualCss(('[foo][a-host] > div[contenta] {}'));
|
||||
});
|
||||
|
||||
// we know that the following test doesn't pass
|
||||
// the host attribute is added before the space
|
||||
// We advise to a more simple class name that doesn't require escaping
|
||||
xit('should handle host with escaped class selector', () => {
|
||||
// here we're looking to shim :host.prüfung (an escaped ü is replaced by "\\fc ")
|
||||
expect(shim(':host.pr\\fc fung {}', 'contenta', 'a-host')).toEqual('.pr\\fc fung[a-host] {}');
|
||||
});
|
||||
|
||||
it('should handle multiple tag selectors', () => {
|
||||
expect(shim(':host(ul,li) {}', 'contenta', 'a-host')).toEqualCss('ul[a-host], li[a-host] {}');
|
||||
expect(shim(':host(ul,li) > .z {}', 'contenta', 'a-host'))
|
||||
|
||||
@@ -72,6 +72,7 @@ describe('ShadowCss', () => {
|
||||
expect(shim('one\\:two {}', 'contenta')).toEqualCss('one\\:two[contenta] {}');
|
||||
expect(shim('one\\\\:two {}', 'contenta')).toEqualCss('one\\\\[contenta]:two {}');
|
||||
expect(shim('.one\\:two {}', 'contenta')).toEqualCss('.one\\:two[contenta] {}');
|
||||
expect(shim('.one\\:\\fc ber {}', 'contenta')).toEqualCss('.one\\:\\fc ber[contenta] {}');
|
||||
expect(shim('.one\\:two .three\\:four {}', 'contenta'))
|
||||
.toEqualCss('.one\\:two[contenta] .three\\:four[contenta] {}');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user