From 95993e1dd523cff96ebc2b42beb1e75dc95ca049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Mon, 22 Oct 2018 15:16:03 -0700 Subject: [PATCH] fix(ivy): ensure pipes indices are referenced in styling bindings (#26755) PR Close #26755 --- .../r3_view_compiler_styling_spec.ts | 57 +++++++++++++++++++ .../compiler/src/render3/view/template.ts | 23 ++++---- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts index aa7fe1b0d0..b9a8603001 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts @@ -660,5 +660,62 @@ describe('compiler compliance: styling', () => { const result = compile(files, angularFiles); expectEmit(result.source, template, 'Incorrect template'); }); + + it('should properly offset multiple style pipe references for styling bindings', () => { + const files = { + app: { + 'spec.ts': ` + import {Component, NgModule} from '@angular/core'; + + @Component({ + selector: 'my-component', + template: \` +
+ {{ item }}
\` + }) + export class MyComponent { + myStyleExp = {}; + fooExp = 'foo'; + barExp = 'bar'; + bazExp = 'baz'; + items = [1,2,3]; + } + + @NgModule({declarations: [MyComponent]}) + export class MyModule {} + ` + } + }; + + const template = ` + template: function MyComponent_Template(rf, $ctx$) { + if (rf & 1) { + $r3$.ɵelementStart(0, "div"); + $r3$.ɵelementStyling($e0_styling$, $e1_styling$, $r3$.ɵdefaultStyleSanitizer); + $r3$.ɵpipe(1, "pipe"); + $r3$.ɵpipe(2, "pipe"); + $r3$.ɵpipe(3, "pipe"); + $r3$.ɵpipe(4, "pipe"); + $r3$.ɵtext(5); + $r3$.ɵelementEnd(); + } + if (rf & 2) { + $r3$.ɵelementStylingMap(0, $e2_styling$, $r3$.ɵpipeBind2(1, 1, $ctx$.myStyleExp, 1000)); + $r3$.ɵelementStyleProp(0, 0, $r3$.ɵpipeBind2(2, 4, $ctx$.barExp, 3000)); + $r3$.ɵelementStyleProp(0, 1, $r3$.ɵpipeBind2(3, 7, $ctx$.bazExp, 4000)); + $r3$.ɵelementClassProp(0, 0, $r3$.ɵpipeBind2(4, 10, $ctx$.fooExp, 2000)); + $r3$.ɵelementStylingApply(0); + $r3$.ɵtextBinding(5, $r3$.ɵinterpolation1(" ", $ctx$.item, "")); + } + } + `; + + const result = compile(files, angularFiles); + expectEmit(result.source, template, 'Incorrect template'); + }); }); }); diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index d5f278bcd9..6e7ec2d7a3 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -675,15 +675,18 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver const key = input.name; const styleIndex: number = stylesIndexMap[key] !; const value = input.value.visit(this._valueConverter); - const params: o.Expression[] = [ - indexLiteral, o.literal(styleIndex), this.convertPropertyBinding(implicit, value, true) - ]; + this.updateInstruction(input.sourceSpan, R3.elementStyleProp, () => { + const params: o.Expression[] = [ + indexLiteral, o.literal(styleIndex), + this.convertPropertyBinding(implicit, value, true) + ]; - if (input.unit != null) { - params.push(o.literal(input.unit)); - } + if (input.unit != null) { + params.push(o.literal(input.unit)); + } - this.updateInstruction(input.sourceSpan, R3.elementStyleProp, params); + return params; + }); } lastInputCommand = styleInputs[styleInputs.length - 1]; @@ -701,10 +704,8 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver const classIndex: number = classesIndexMap[key] !; const value = input.value.visit(this._valueConverter); this.updateInstruction(input.sourceSpan, R3.elementClassProp, () => { - return [ - indexLiteral, o.literal(classIndex), - this.convertPropertyBinding(implicit, value, true), ...params - ]; + const valueLiteral = this.convertPropertyBinding(implicit, value, true); + return [indexLiteral, o.literal(classIndex), valueLiteral]; }); }