refactor(ivy): evaluate prop-based styling bindings with a new algorithm (#30469)
This is the first refactor PR designed to change how styling bindings (i.e. `[style]` and `[class]`) behave in Ivy. Instead of having a heavy element-by-element context be generated for each element, this new refactor aims to use a single context for each `tNode` element that is examined and iterated over when styling values are to be applied to the element. This patch brings this new functionality to prop-based bindings such as `[style.prop]` and `[class.name]`. PR Close #30469
This commit is contained in:

committed by
Jason Aden

parent
848e53efd0
commit
f03475cac8
@ -13,7 +13,6 @@ import {BindingForm, convertPropertyBinding} from '../../compiler_util/expressio
|
||||
import {ConstantPool, DefinitionKind} from '../../constant_pool';
|
||||
import * as core from '../../core';
|
||||
import {AST, ParsedEvent, ParsedEventType, ParsedProperty} from '../../expression_parser/ast';
|
||||
import {LifecycleHooks} from '../../lifecycle_reflector';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG} from '../../ml_parser/interpolation_config';
|
||||
import * as o from '../../output/output_ast';
|
||||
import {ParseError, ParseSourceSpan, typeSourceSpan} from '../../parse_util';
|
||||
@ -725,6 +724,7 @@ function createHostBindingsFunction(
|
||||
// the update block of a component/directive templateFn/hostBindingsFn so that the bindings
|
||||
// are evaluated and updated for the element.
|
||||
styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEach(instruction => {
|
||||
totalHostVarsCount += instruction.allocateBindingSlots;
|
||||
updateStatements.push(createStylingStmt(instruction, bindingContext, bindingFn));
|
||||
});
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import * as t from '../r3_ast';
|
||||
import {Identifiers as R3} from '../r3_identifiers';
|
||||
|
||||
import {parse as parseStyle} from './style_parser';
|
||||
import {compilerIsNewStylingInUse} from './styling_state';
|
||||
import {ValueConverter} from './template';
|
||||
|
||||
const IMPORTANT_FLAG = '!important';
|
||||
@ -389,6 +390,11 @@ export class StylingBuilder {
|
||||
const bindingIndex: number = mapIndex.get(input.name !) !;
|
||||
const value = input.value.visit(valueConverter);
|
||||
totalBindingSlotsRequired += (value instanceof Interpolation) ? value.expressions.length : 0;
|
||||
if (compilerIsNewStylingInUse()) {
|
||||
// the old implementation does not reserve slot values for
|
||||
// binding entries. The new one does.
|
||||
totalBindingSlotsRequired++;
|
||||
}
|
||||
return {
|
||||
sourceSpan: input.sourceSpan,
|
||||
allocateBindingSlots: totalBindingSlotsRequired, reference,
|
||||
|
37
packages/compiler/src/render3/view/styling_state.ts
Normal file
37
packages/compiler/src/render3/view/styling_state.ts
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* A temporary enum of states that inform the core whether or not
|
||||
* to defer all styling instruction calls to the old or new
|
||||
* styling implementation.
|
||||
*/
|
||||
export const enum CompilerStylingMode {
|
||||
UseOld = 0,
|
||||
UseBothOldAndNew = 1,
|
||||
UseNew = 2,
|
||||
}
|
||||
|
||||
let _stylingMode = 0;
|
||||
|
||||
/**
|
||||
* Temporary function used to inform the existing styling algorithm
|
||||
* code to delegate all styling instruction calls to the new refactored
|
||||
* styling code.
|
||||
*/
|
||||
export function compilerSetStylingMode(mode: CompilerStylingMode) {
|
||||
_stylingMode = mode;
|
||||
}
|
||||
|
||||
export function compilerIsNewStylingInUse() {
|
||||
return _stylingMode > CompilerStylingMode.UseOld;
|
||||
}
|
||||
|
||||
export function compilerAllowOldStyling() {
|
||||
return _stylingMode < CompilerStylingMode.UseNew;
|
||||
}
|
Reference in New Issue
Block a user