diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json index c1124a924e2..d577608c6cf 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json @@ -84,8 +84,7 @@ "host_attributes_with_classes_and_styles.js" ] } - ], - "skipForTemplatePipeline": true + ] }, { "description": "should chain multiple host property bindings into a single instruction", diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json index 429ac636a41..4601c866413 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_styling/host_bindings/TEST_CASES.json @@ -13,8 +13,7 @@ "static_and_dynamic.js" ] } - ], - "skipForTemplatePipeline": true + ] }, { "description": "should generate style/class instructions for multiple host binding definitions", diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts index a30fe6d1c39..88f860a1cf9 100644 --- a/packages/compiler/src/render3/view/compiler.ts +++ b/packages/compiler/src/render3/view/compiler.ts @@ -566,15 +566,24 @@ function createHostBindingsFunction( const bindings = bindingParser.createBoundHostProperties(hostBindingsMetadata.properties, typeSourceSpan); - // Calculate host event bindings const eventBindings = bindingParser.createDirectiveHostEventAsts(hostBindingsMetadata.listeners, typeSourceSpan); if (USE_TEMPLATE_PIPELINE) { - // TODO: host binding metadata is not yet parsed in the template pipeline, so we need to extract - // that code from below. Then, we will ingest a `HostBindingJob`, and run the template pipeline - // phases. + // The parser for host bindings treats class and style attributes specially -- they are + // extracted into these separate fields. This is not the case for templates, so the compiler can + // actually already handle these special attributes internally. Therefore, we just drop them + // into the attributes map. + if (hostBindingsMetadata.specialAttributes.styleAttr) { + hostBindingsMetadata.attributes.style = + o.literal(hostBindingsMetadata.specialAttributes.styleAttr); + } + if (hostBindingsMetadata.specialAttributes.classAttr) { + hostBindingsMetadata.attributes.class = + o.literal(hostBindingsMetadata.specialAttributes.classAttr); + } + const hostJob = ingestHostBinding( { componentName: name, @@ -585,11 +594,12 @@ function createHostBindingsFunction( bindingParser, constantPool); transformHostBinding(hostJob); + definitionMap.set('hostAttrs', hostJob.root.attributes); + const varCount = hostJob.root.vars; if (varCount !== null && varCount > 0) { definitionMap.set('hostVars', o.literal(varCount)); } - definitionMap.set('hostAttrs', hostJob.root.attributes); return emitHostBindingFunction(hostJob); } diff --git a/packages/compiler/src/template/pipeline/src/emit.ts b/packages/compiler/src/template/pipeline/src/emit.ts index 368298d259f..03ea4580ba7 100644 --- a/packages/compiler/src/template/pipeline/src/emit.ts +++ b/packages/compiler/src/template/pipeline/src/emit.ts @@ -110,6 +110,7 @@ export function transformHostBinding(job: HostBindingCompilationJob): void { phaseStyleBindingSpecialization(job); phaseBindingSpecialization(job); phaseAttributeExtraction(job); + phaseParseExtractedStyles(job); phasePureLiteralStructures(job); phaseConstCollection(job); phaseNullishCoalescing(job); diff --git a/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts b/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts index 2428deb5729..ef834d31ef5 100644 --- a/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts +++ b/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts @@ -9,13 +9,13 @@ 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'; +import type {CompilationJob} from '../compilation'; /** * Parses extracted style and class attributes into separate ExtractedAttributeOps per style or * class property. */ -export function phaseParseExtractedStyles(cpl: ComponentCompilationJob) { +export function phaseParseExtractedStyles(cpl: CompilationJob) { for (const unit of cpl.units) { for (const op of unit.create) { if (op.kind === ir.OpKind.ExtractedAttribute && op.bindingKind === ir.BindingKind.Attribute &&