refactor(ivy): remove TStylingContext locking in favor of firstUpdatePass flag (#33521)

This patch removes the need to lock the style and class context
instances to track when bindings can be added. What happens now is
that the `tNode.firstUpdatePass` is used to track when bindings are
registered on the context instances.

PR Close #33521
This commit is contained in:
Matias Niemelä
2019-10-29 15:35:00 -07:00
committed by atscott
parent 5453c4cd96
commit 3297a76195
7 changed files with 156 additions and 181 deletions

View File

@ -74,15 +74,16 @@ export function hasConfig(context: TStylingContext, flag: TStylingConfig) {
* Determines whether or not to apply styles/classes directly or via context resolution.
*
* There are three cases that are matched here:
* 1. there are no directives present AND ngDevMode is falsy
* 2. context is locked for template or host bindings (depending on `hostBindingsMode`)
* 1. there are no directives present AND `ngDevMode` is falsy
* 2. the `firstUpdatePass` has not already run (which means that
* there are more bindings to register and, therefore, direct
* style/class application is not yet possible)
* 3. There are no collisions (i.e. properties with more than one binding) across multiple
* sources (i.e. template + directive, directive + directive, directive + component)
*/
export function allowDirectStyling(context: TStylingContext, hostBindingsMode: boolean): boolean {
export function allowDirectStyling(context: TStylingContext, firstUpdatePass: boolean): boolean {
let allow = false;
const config = getConfig(context);
const contextIsLocked = (config & getLockedConfig(hostBindingsMode)) !== 0;
const hasNoDirectives = (config & TStylingConfig.HasDirectives) === 0;
// if no directives are present then we do not need populate a context at all. This
@ -93,8 +94,8 @@ export function allowDirectStyling(context: TStylingContext, hostBindingsMode: b
// `ngDevMode` is required to be checked here because tests/debugging rely on the context being
// populated. If things are in production mode then there is no need to build a context
// therefore the direct apply can be allowed (even on the first update).
allow = ngDevMode ? contextIsLocked : true;
} else if (contextIsLocked) {
allow = ngDevMode ? !firstUpdatePass : true;
} else if (!firstUpdatePass) {
const hasNoCollisions = (config & TStylingConfig.HasCollisions) === 0;
const hasOnlyMapsOrOnlyProps =
(config & TStylingConfig.HasPropAndMapBindings) !== TStylingConfig.HasPropAndMapBindings;
@ -172,19 +173,6 @@ export function getValue<T = any>(data: LStylingData, bindingIndex: number): T|n
return bindingIndex !== 0 ? data[bindingIndex] as T : null;
}
export function lockContext(context: TStylingContext, hostBindingsMode: boolean): void {
patchConfig(context, getLockedConfig(hostBindingsMode));
}
export function isContextLocked(context: TStylingContext, hostBindingsMode: boolean): boolean {
return hasConfig(context, getLockedConfig(hostBindingsMode));
}
export function getLockedConfig(hostBindingsMode: boolean) {
return hostBindingsMode ? TStylingConfig.HostBindingsLocked :
TStylingConfig.TemplateBindingsLocked;
}
export function getPropValuesStartPosition(context: TStylingContext) {
let startPosition = TStylingContextIndex.ValuesStartPosition;
if (hasConfig(context, TStylingConfig.HasMapBindings)) {