mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(compiler): scope animations declared in minified nested rules
The regular expressions in `_scopeAnimationRule` expect an `animation` or `animation-name` property to be preceded by whitespace or a semicolon, and its value to end at a semicolon. Minified CSS breaks both assumptions. Inside an at-rule the property follows a `{`, and the last declaration of a block has no trailing semicolon, so the closing `}` lands inside the captured value. The keyframe name is then left unscoped while the `@keyframes` rule itself is renamed, so the animation does nothing in a production build.
Accept `{` as a leading boundary and stop the value at `}`. The prefix is written back unchanged, and a declaration value cannot contain an unescaped `}`.
Fixes #70316
This commit is contained in:
committed by
Leon Senft
parent
1e35de536d
commit
58b0cb4735
@@ -362,7 +362,7 @@ export class ShadowCss {
|
||||
unscopedKeyframesSet: ReadonlySet<string>,
|
||||
): CssRule {
|
||||
let content = rule.content.replace(
|
||||
/((?:^|\s+|;)(?:-webkit-)?animation\s*:\s*)([^;]+)/g,
|
||||
/((?:^|[\s;{])(?:-webkit-)?animation\s*:\s*)([^;}]+)/g,
|
||||
(_, start, animationDeclarations) =>
|
||||
start +
|
||||
animationDeclarations.replace(
|
||||
@@ -393,7 +393,7 @@ export class ShadowCss {
|
||||
),
|
||||
);
|
||||
content = content.replace(
|
||||
/((?:^|\s+|;)(?:-webkit-)?animation-name(?:\s*):(?:\s*))([^;]+)/g,
|
||||
/((?:^|[\s;{])(?:-webkit-)?animation-name(?:\s*):(?:\s*))([^;}]+)/g,
|
||||
(_match, start, commaSeparatedKeyframes) =>
|
||||
`${start}${commaSeparatedKeyframes
|
||||
.split(',')
|
||||
|
||||
@@ -259,6 +259,17 @@ describe('ShadowCss, keyframes and animations', () => {
|
||||
expect(shim(css, 'host-a')).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly process animations defined in minified rules nested in an at-rule', () => {
|
||||
let css = '@keyframes foo {}@media screen{.test{animation:foo 1s forwards}}';
|
||||
let expected =
|
||||
'@keyframes host-a_foo {}@media screen{.test[host-a]{animation:host-a_foo 1s forwards}}';
|
||||
expect(shim(css, 'host-a')).toEqual(expected);
|
||||
css = '@keyframes foo {}@supports (display:grid){.test{animation-name:foo}}';
|
||||
expected =
|
||||
'@keyframes host-a_foo {}@supports (display:grid){.test[host-a]{animation-name:host-a_foo}}';
|
||||
expect(shim(css, 'host-a')).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should ignore keywords values when scoping local animations', () => {
|
||||
const css = `
|
||||
div {
|
||||
|
||||
Reference in New Issue
Block a user