mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
refactor(compiler): Adds a new phase for parsing extracted styles (#51258)
Adds a new phase that converts previously extracted ExtractedAttributeOps representing a style attribute into individual ExtractedAttributeOps representing each of the style properties set in the style attribute. PR Close #51258
This commit is contained in:
parent
82009a529a
commit
d792db8652
4 changed files with 48 additions and 10 deletions
|
|
@ -902,3 +902,10 @@ export function transformExpressionsInStatement(
|
|||
throw new Error(`Unhandled statement kind: ${stmt.constructor.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given expression is a string literal.
|
||||
*/
|
||||
export function isStringLiteral(expr: o.Expression): expr is o.LiteralExpr&{value: string} {
|
||||
return expr instanceof o.LiteralExpr && typeof expr.value === 'string';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import {phaseNgContainer} from './phases/ng_container';
|
|||
import {phaseNoListenersOnTemplates} from './phases/no_listeners_on_templates';
|
||||
import {phaseNonbindable} from './phases/nonbindable';
|
||||
import {phaseNullishCoalescing} from './phases/nullish_coalescing';
|
||||
import {phaseParseExtractedStyles} from './phases/parse_extracted_styles';
|
||||
import {phasePipeCreation} from './phases/pipe_creation';
|
||||
import {phasePipeVariadic} from './phases/pipe_variadic';
|
||||
import {phasePropertyOrdering} from './phases/property_ordering';
|
||||
|
|
@ -58,6 +59,7 @@ export function transformTemplate(job: ComponentCompilationJob): void {
|
|||
phaseStyleBindingSpecialization(job);
|
||||
phaseBindingSpecialization(job);
|
||||
phaseAttributeExtraction(job);
|
||||
phaseParseExtractedStyles(job);
|
||||
phaseRemoveEmptyBindings(job);
|
||||
phaseNoListenersOnTemplates(job);
|
||||
phasePipeCreation(job);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
|
||||
import {SecurityContext} from '../../../../core';
|
||||
import * as o from '../../../../output/output_ast';
|
||||
import * as ir from '../../ir';
|
||||
import {ComponentCompilationJob, ViewCompilationUnit} from '../compilation';
|
||||
import {getElementsByXrefId} from '../util/elements';
|
||||
|
|
@ -70,13 +69,6 @@ function lookupElement(
|
|||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given expression is a string literal.
|
||||
*/
|
||||
function isStringLiteral(expr: o.Expression): expr is o.LiteralExpr&{value: string} {
|
||||
return expr instanceof o.LiteralExpr && typeof expr.value === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an attribute binding.
|
||||
*/
|
||||
|
|
@ -94,13 +86,13 @@ function extractAttributeOp(
|
|||
// context, so we emulate that behavior in compaitiblity mode, otherwise we optimize more
|
||||
// aggressively.
|
||||
extractable = view.compatibility === ir.CompatibilityMode.TemplateDefinitionBuilder ?
|
||||
isStringLiteral(op.expression) && op.securityContext === SecurityContext.NONE :
|
||||
ir.isStringLiteral(op.expression) && op.securityContext === SecurityContext.NONE :
|
||||
op.expression.isConstant();
|
||||
} else {
|
||||
// TemplateDefinitionBuilder only extracted string constants, so we emulate that behavior in
|
||||
// compaitiblity mode, otherwise we optimize more aggressively.
|
||||
extractable = view.compatibility === ir.CompatibilityMode.TemplateDefinitionBuilder ?
|
||||
isStringLiteral(op.expression) :
|
||||
ir.isStringLiteral(op.expression) :
|
||||
op.expression.isConstant();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as o from '../../../../output/output_ast';
|
||||
import {parse as parseStyle} from '../../../../render3/view/style_parser';
|
||||
import * as ir from '../../ir';
|
||||
import {ComponentCompilationJob} from '../compilation';
|
||||
|
||||
/**
|
||||
* Parses extracted style attributes into separate ExtractedAttributeOps per style property.
|
||||
*/
|
||||
export function phaseParseExtractedStyles(cpl: ComponentCompilationJob) {
|
||||
for (const [_, view] of cpl.views) {
|
||||
for (const op of view.create) {
|
||||
if (op.kind === ir.OpKind.ExtractedAttribute && op.bindingKind === ir.BindingKind.Attribute) {
|
||||
if (op.name === 'style') {
|
||||
if (ir.isStringLiteral(op.expression!)) {
|
||||
const parsedStyles = parseStyle(op.expression.value);
|
||||
for (let i = 0; i < parsedStyles.length - 1; i += 2) {
|
||||
ir.OpList.insertBefore<ir.CreateOp>(
|
||||
ir.createExtractedAttributeOp(
|
||||
op.target, ir.BindingKind.StyleProperty, parsedStyles[i],
|
||||
o.literal(parsedStyles[i + 1])),
|
||||
op);
|
||||
}
|
||||
ir.OpList.remove<ir.CreateOp>(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue