fix(ivy): ensure select(n) instructions are always generated around style/class bindings (#30311)

Prior to this patch, the `select(n)` instruction would only be generated
when property bindings are encountered which meant that styling-related
bindings were skipped. This patch ensures that all styling-related bindings
(i.e. class and style bindings) are always prepended with a `select()`
instruction prior to being generated in AOT.

PR Close #30311
This commit is contained in:
Matias Niemelä
2019-05-07 13:18:27 -07:00
committed by Kara Erickson
parent bd37622050
commit 345a3cd9aa
3 changed files with 78 additions and 9 deletions

View File

@ -666,7 +666,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
// (things like `elementStyleProp`, `elementClassProp`, etc..) are applied later on in this
// file
this.processStylingInstruction(
implicit,
elementIndex, implicit,
stylingBuilder.buildElementStylingInstruction(element.sourceSpan, this.constantPool),
true);
@ -688,10 +688,13 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
// update block of the template function AOT code. Instructions like `elementStyleProp`,
// `elementStyleMap`, `elementClassMap`, `elementClassProp` and `elementStylingApply`
// are all generated and assigned in the code below.
stylingBuilder.buildUpdateLevelInstructions(this._valueConverter).forEach(instruction => {
const stylingInstructions = stylingBuilder.buildUpdateLevelInstructions(this._valueConverter);
const limit = stylingInstructions.length - 1;
for (let i = 0; i <= limit; i++) {
const instruction = stylingInstructions[i];
this._bindingSlots += instruction.allocateBindingSlots;
this.processStylingInstruction(implicit, instruction, false);
});
this.processStylingInstruction(elementIndex, implicit, instruction, false);
}
// the reason why `undefined` is used is because the renderer understands this as a
// special value to symbolize that there is no RHS to this binding
@ -1007,14 +1010,15 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}
private processStylingInstruction(
implicit: any, instruction: Instruction|null, createMode: boolean) {
elementIndex: number, implicit: any, instruction: Instruction|null, createMode: boolean) {
if (instruction) {
const paramsFn = () =>
instruction.buildParams(value => this.convertPropertyBinding(implicit, value, true));
if (createMode) {
this.creationInstruction(instruction.sourceSpan, instruction.reference, paramsFn);
} else {
this.updateInstruction(-1, instruction.sourceSpan, instruction.reference, paramsFn);
this.updateInstruction(
elementIndex, instruction.sourceSpan, instruction.reference, paramsFn);
}
}
}