From 168a393589f80bd2fa6fb3fb6235754c5e75a384 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 5 Mar 2020 14:14:59 -0800 Subject: [PATCH] refactor(core): misc refactoring to support upcoming changes to improve synthetic host bindings (#35884) This commit performs a few updates to internal functions that would be required in upcoming changes to support synthetic host bindings in Directives. * the `elementPropertyInternal` function was refactored to accept renderer as an argument (prior to that, there was a function that loads the renderer in some specific way for animation bindings) * `elementPropertyInternal`, `elementAttributeInternal` and `listenerInternal` functions were updated to have a fixed set of arguments (for better performance) * `elementPropertyInternal` and `elementAttributeInternal` functions were updated to take `tNode` as an argument instead of passing node index (that was used to retrieve `tNode` internally), in some cases we already have `tNode` available or we can retrieve it from the state The refactoring was triggered by the need to pass different renderers to the `elementPropertyInternal` to support synthetic host bindings in Directives (see this comment for additional context: https://github.com/angular/angular/pull/35568/files#r388034584). PR Close #35884 --- packages/core/src/render3/i18n.ts | 9 ++- .../src/render3/instructions/attribute.ts | 8 +- .../instructions/attribute_interpolation.ts | 73 +++++++---------- .../src/render3/instructions/host_property.ts | 18 +++-- .../core/src/render3/instructions/property.ts | 12 +-- .../instructions/property_interpolation.ts | 78 +++++++++++-------- .../core/src/render3/instructions/shared.ts | 23 +++--- packages/core/src/render3/state.ts | 8 ++ .../injection/bundle.golden_symbols.json | 8 +- .../bundling/todo/bundle.golden_symbols.json | 3 + 10 files changed, 123 insertions(+), 117 deletions(-) diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts index 5bcda795a8..640c3eefd9 100644 --- a/packages/core/src/render3/i18n.ts +++ b/packages/core/src/render3/i18n.ts @@ -800,7 +800,8 @@ function readCreateOpCodes( const attrValue = createOpCodes[++i] as string; // This code is used for ICU expressions only, since we don't support // directives/components in ICUs, we don't need to worry about inputs here - elementAttributeInternal(elementNodeIndex, attrName, attrValue, tView, lView); + elementAttributeInternal( + getTNode(tView, elementNodeIndex), lView, attrName, attrValue, null, null); break; default: throw new Error(`Unable to determine the type of mutate operation for "${opCode}"`); @@ -877,7 +878,9 @@ function readUpdateOpCodes( case I18nUpdateOpCode.Attr: const propName = updateOpCodes[++j] as string; const sanitizeFn = updateOpCodes[++j] as SanitizerFn | null; - elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizeFn); + elementPropertyInternal( + tView, getTNode(tView, nodeIndex), lView, propName, value, lView[RENDERER], + sanitizeFn, false); break; case I18nUpdateOpCode.Text: textBindingInternal(lView, nodeIndex, value); @@ -1042,7 +1045,7 @@ function i18nAttributesFirstPass(lView: LView, tView: TView, index: number, valu // Set attributes for Elements only, for other types (like ElementContainer), // only set inputs below if (tNode.type === TNodeType.Element) { - elementAttributeInternal(previousElementIndex, attrName, value, tView, lView); + elementAttributeInternal(tNode, lView, attrName, value, null, null); } // Check if that attribute is a directive input const dataValue = tNode.inputs !== null && tNode.inputs[attrName]; diff --git a/packages/core/src/render3/instructions/attribute.ts b/packages/core/src/render3/instructions/attribute.ts index 13641efd82..a3a2bfab8f 100644 --- a/packages/core/src/render3/instructions/attribute.ts +++ b/packages/core/src/render3/instructions/attribute.ts @@ -7,7 +7,7 @@ */ import {bindingUpdated} from '../bindings'; import {SanitizerFn} from '../interfaces/sanitization'; -import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; +import {getLView, getSelectedIndex, getSelectedTNode, getTView, nextBindingIndex} from '../state'; import {elementAttributeInternal, storePropertyBindingMetadata} from './shared'; @@ -31,10 +31,10 @@ export function ɵɵattribute( const lView = getLView(); const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementAttributeInternal(nodeIndex, name, value, tView, lView, sanitizer, namespace); - ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, 'attr.' + name, bindingIndex); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace); + ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex); } return ɵɵattribute; } diff --git a/packages/core/src/render3/instructions/attribute_interpolation.ts b/packages/core/src/render3/instructions/attribute_interpolation.ts index 1d6c6833af..96f7e8b01e 100644 --- a/packages/core/src/render3/instructions/attribute_interpolation.ts +++ b/packages/core/src/render3/instructions/attribute_interpolation.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {SanitizerFn} from '../interfaces/sanitization'; -import {getBindingIndex, getLView, getSelectedIndex, getTView} from '../state'; +import {getBindingIndex, getLView, getSelectedTNode, getTView} from '../state'; import {NO_CHANGE} from '../tokens'; import {interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV} from './interpolation'; import {elementAttributeInternal, storePropertyBindingMetadata} from './shared'; @@ -43,13 +43,11 @@ export function ɵɵattributeInterpolate1( const lView = getLView(); const interpolatedValue = interpolation1(lView, prefix, v0, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix); + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix); } return ɵɵattributeInterpolate1; } @@ -86,13 +84,11 @@ export function ɵɵattributeInterpolate2( const lView = getLView(); const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix); + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix); } return ɵɵattributeInterpolate2; } @@ -132,12 +128,10 @@ export function ɵɵattributeInterpolate3( const lView = getLView(); const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix); } return ɵɵattributeInterpolate3; @@ -181,12 +175,10 @@ export function ɵɵattributeInterpolate4( const lView = getLView(); const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix); } return ɵɵattributeInterpolate4; @@ -233,12 +225,10 @@ export function ɵɵattributeInterpolate5( const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix); } return ɵɵattributeInterpolate5; @@ -287,12 +277,10 @@ export function ɵɵattributeInterpolate6( const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix); } return ɵɵattributeInterpolate6; @@ -343,12 +331,10 @@ export function ɵɵattributeInterpolate7( const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix); } return ɵɵattributeInterpolate7; @@ -401,12 +387,10 @@ export function ɵɵattributeInterpolate8( const interpolatedValue = interpolation8( lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); - const tView = getTView(); - elementAttributeInternal( - nodeIndex, attrName, interpolatedValue, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix); } return ɵɵattributeInterpolate8; @@ -444,16 +428,15 @@ export function ɵɵattributeInterpolateV( const lView = getLView(); const interpolated = interpolationV(lView, values); if (interpolated !== NO_CHANGE) { - const tView = getTView(); - const nodeIndex = getSelectedIndex(); - elementAttributeInternal(nodeIndex, attrName, interpolated, tView, lView, sanitizer, namespace); + const tNode = getSelectedTNode(); + elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace); if (ngDevMode) { const interpolationInBetween = [values[0]]; // prefix for (let i = 2; i < values.length; i += 2) { interpolationInBetween.push(values[i]); } storePropertyBindingMetadata( - tView.data, nodeIndex, 'attr.' + attrName, + getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween); } } diff --git a/packages/core/src/render3/instructions/host_property.ts b/packages/core/src/render3/instructions/host_property.ts index 3201c3ab0c..cc662152dc 100644 --- a/packages/core/src/render3/instructions/host_property.ts +++ b/packages/core/src/render3/instructions/host_property.ts @@ -7,8 +7,10 @@ */ import {bindingUpdated} from '../bindings'; import {SanitizerFn} from '../interfaces/sanitization'; -import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; +import {RENDERER} from '../interfaces/view'; +import {getLView, getSelectedTNode, getTView, nextBindingIndex} from '../state'; import {NO_CHANGE} from '../tokens'; + import {elementPropertyInternal, loadComponentRenderer, storePropertyBindingMetadata} from './shared'; /** @@ -30,10 +32,10 @@ export function ɵɵhostProperty( const lView = getLView(); const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizer, true); - ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); + const tNode = getSelectedTNode(); + elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, true); + ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex); } return ɵɵhostProperty; } @@ -66,11 +68,11 @@ export function ɵɵupdateSyntheticHostBinding( const lView = getLView(); const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal( - tView, lView, nodeIndex, propName, value, sanitizer, true, loadComponentRenderer); - ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); + const tNode = getSelectedTNode(); + const renderer = loadComponentRenderer(tNode, lView); + elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, true); + ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex); } return ɵɵupdateSyntheticHostBinding; } diff --git a/packages/core/src/render3/instructions/property.ts b/packages/core/src/render3/instructions/property.ts index e02a8808a4..5867fc9eca 100644 --- a/packages/core/src/render3/instructions/property.ts +++ b/packages/core/src/render3/instructions/property.ts @@ -8,8 +8,9 @@ import {bindingUpdated} from '../bindings'; import {TNode} from '../interfaces/node'; import {SanitizerFn} from '../interfaces/sanitization'; -import {LView, TView} from '../interfaces/view'; -import {getLView, getSelectedIndex, getTView, nextBindingIndex} from '../state'; +import {LView, RENDERER, TView} from '../interfaces/view'; +import {getLView, getSelectedTNode, getTView, nextBindingIndex} from '../state'; + import {elementPropertyInternal, setInputsForProperty, storePropertyBindingMetadata} from './shared'; @@ -36,10 +37,11 @@ export function ɵɵproperty( const lView = getLView(); const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, value, sanitizer); - ngDevMode && storePropertyBindingMetadata(tView.data, nodeIndex, propName, bindingIndex); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false); + ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex); } return ɵɵproperty; } diff --git a/packages/core/src/render3/instructions/property_interpolation.ts b/packages/core/src/render3/instructions/property_interpolation.ts index 7779f05133..373f591211 100644 --- a/packages/core/src/render3/instructions/property_interpolation.ts +++ b/packages/core/src/render3/instructions/property_interpolation.ts @@ -6,8 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ import {SanitizerFn} from '../interfaces/sanitization'; -import {getBindingIndex, getLView, getSelectedIndex, getTView} from '../state'; +import {RENDERER} from '../interfaces/view'; +import {getBindingIndex, getLView, getSelectedTNode, getTView} from '../state'; import {NO_CHANGE} from '../tokens'; + import {interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV} from './interpolation'; import {elementPropertyInternal, storePropertyBindingMetadata} from './shared'; @@ -82,11 +84,12 @@ export function ɵɵpropertyInterpolate1( const lView = getLView(); const interpolatedValue = interpolation1(lView, prefix, v0, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 1, prefix, suffix); + tView.data, tNode, propName, getBindingIndex() - 1, prefix, suffix); } return ɵɵpropertyInterpolate1; } @@ -127,11 +130,12 @@ export function ɵɵpropertyInterpolate2( const lView = getLView(); const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 2, prefix, i0, suffix); + tView.data, tNode, propName, getBindingIndex() - 2, prefix, i0, suffix); } return ɵɵpropertyInterpolate2; } @@ -175,12 +179,12 @@ export function ɵɵpropertyInterpolate3( const lView = getLView(); const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); - ngDevMode && - storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 3, prefix, i0, i1, suffix); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); + ngDevMode && storePropertyBindingMetadata( + tView.data, tNode, propName, getBindingIndex() - 3, prefix, i0, i1, suffix); } return ɵɵpropertyInterpolate3; } @@ -226,12 +230,13 @@ export function ɵɵpropertyInterpolate4( const lView = getLView(); const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix); + tView.data, tNode, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix); } return ɵɵpropertyInterpolate4; } @@ -281,12 +286,13 @@ export function ɵɵpropertyInterpolate5( const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix); + tView.data, tNode, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix); } return ɵɵpropertyInterpolate5; } @@ -338,12 +344,13 @@ export function ɵɵpropertyInterpolate6( const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); - ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, - i4, suffix); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); + ngDevMode && + storePropertyBindingMetadata( + tView.data, tNode, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix); } return ɵɵpropertyInterpolate6; } @@ -397,12 +404,13 @@ export function ɵɵpropertyInterpolate7( const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, - i4, i5, suffix); + tView.data, tNode, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, + i5, suffix); } return ɵɵpropertyInterpolate7; } @@ -458,12 +466,13 @@ export function ɵɵpropertyInterpolate8( const interpolatedValue = interpolation8( lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, - i4, i5, i6, suffix); + tView.data, tNode, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, + i5, i6, suffix); } return ɵɵpropertyInterpolate8; } @@ -503,16 +512,17 @@ export function ɵɵpropertyInterpolateV( const lView = getLView(); const interpolatedValue = interpolationV(lView, values); if (interpolatedValue !== NO_CHANGE) { - const nodeIndex = getSelectedIndex(); const tView = getTView(); - elementPropertyInternal(tView, lView, nodeIndex, propName, interpolatedValue, sanitizer); + const tNode = getSelectedTNode(); + elementPropertyInternal( + tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false); if (ngDevMode) { const interpolationInBetween = [values[0]]; // prefix for (let i = 2; i < values.length; i += 2) { interpolationInBetween.push(values[i]); } storePropertyBindingMetadata( - tView.data, nodeIndex, propName, getBindingIndex() - interpolationInBetween.length + 1, + tView.data, tNode, propName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween); } } diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 8c0fa14d48..5c07128a56 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -941,17 +941,15 @@ function mapPropName(name: string): string { } export function elementPropertyInternal( - tView: TView, lView: LView, index: number, propName: string, value: T, - sanitizer?: SanitizerFn | null, nativeOnly?: boolean, - loadRendererFn?: ((tNode: TNode, lView: LView) => Renderer3) | null): void { + tView: TView, tNode: TNode, lView: LView, propName: string, value: T, renderer: Renderer3, + sanitizer: SanitizerFn | null | undefined, nativeOnly: boolean): void { ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.'); - const element = getNativeByIndex(index, lView) as RElement | RComment; - const tNode = getTNode(tView, index); + const element = getNativeByTNode(tNode, lView) as RElement | RComment; let inputData = tNode.inputs; let dataValue: PropertyAliasValue|undefined; if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) { setInputsForProperty(tView, lView, dataValue, propName, value); - if (isComponentHost(tNode)) markDirtyIfOnPush(lView, index + HEADER_OFFSET); + if (isComponentHost(tNode)) markDirtyIfOnPush(lView, tNode.index); if (ngDevMode) { setNgReflectProperties(lView, element, tNode.type, dataValue, value); } @@ -968,7 +966,6 @@ export function elementPropertyInternal( ngDevMode.rendererSetProperty++; } - const renderer = loadRendererFn ? loadRendererFn(tNode, lView) : lView[RENDERER]; // It is assumed that the sanitizer is only added when the compiler determines that the // property is risky, so sanitization can be done without further checks. value = sanitizer != null ? (sanitizer(value, tNode.tagName || '', propName) as any) : value; @@ -1438,11 +1435,11 @@ function addComponentLogic(lView: LView, hostTNode: TElementNode, def: Compon } export function elementAttributeInternal( - index: number, name: string, value: any, tView: TView, lView: LView, - sanitizer?: SanitizerFn | null, namespace?: string) { + tNode: TNode, lView: LView, name: string, value: any, sanitizer: SanitizerFn | null | undefined, + namespace: string | null | undefined) { ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.'); ngDevMode && validateAgainstEventAttributes(name); - const element = getNativeByIndex(index, lView) as RElement; + const element = getNativeByTNode(tNode, lView) as RElement; const renderer = lView[RENDERER]; if (value == null) { ngDevMode && ngDevMode.rendererRemoveAttribute++; @@ -1450,7 +1447,6 @@ export function elementAttributeInternal( element.removeAttribute(name); } else { ngDevMode && ngDevMode.rendererSetAttribute++; - const tNode = getTNode(tView, index); const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name); @@ -1892,19 +1888,18 @@ function executeViewQueryFn( * interpolated properties. * * @param tData `TData` where meta-data will be saved; - * @param nodeIndex index of a `TNode` that is a target of the binding; + * @param tNode `TNode` that is a target of the binding; * @param propertyName bound property name; * @param bindingIndex binding index in `LView` * @param interpolationParts static interpolation parts (for property interpolations) */ export function storePropertyBindingMetadata( - tData: TData, nodeIndex: number, propertyName: string, bindingIndex: number, + tData: TData, tNode: TNode, propertyName: string, bindingIndex: number, ...interpolationParts: string[]) { // Binding meta-data are stored only the first time a given property instruction is processed. // Since we don't have a concept of the "first update pass" we need to check for presence of the // binding meta-data to decide if one should be stored (or if was stored already). if (tData[bindingIndex] === null) { - const tNode = tData[nodeIndex + HEADER_OFFSET] as TNode; if (tNode.inputs == null || !tNode.inputs[propertyName]) { const propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []); propBindingIdxs.push(bindingIndex); diff --git a/packages/core/src/render3/state.ts b/packages/core/src/render3/state.ts index 432f355173..2a45f8c601 100644 --- a/packages/core/src/render3/state.ts +++ b/packages/core/src/render3/state.ts @@ -12,6 +12,7 @@ import {assertLViewOrUndefined} from './assert'; import {TNode} from './interfaces/node'; import {CONTEXT, DECLARATION_VIEW, LView, OpaqueViewState, TVIEW, TView} from './interfaces/view'; import {MATH_ML_NAMESPACE, SVG_NAMESPACE} from './namespaces'; +import {getTNode} from './util/view_utils'; /** @@ -532,6 +533,13 @@ export function setSelectedIndex(index: number) { instructionState.lFrame.selectedIndex = index; } +/** + * Gets the `tNode` that represents currently selected element. + */ +export function getSelectedTNode() { + const lFrame = instructionState.lFrame; + return getTNode(lFrame.tView, lFrame.selectedIndex); +} /** * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state. diff --git a/packages/core/test/bundling/injection/bundle.golden_symbols.json b/packages/core/test/bundling/injection/bundle.golden_symbols.json index 125db87f31..316eac6869 100644 --- a/packages/core/test/bundling/injection/bundle.golden_symbols.json +++ b/packages/core/test/bundling/injection/bundle.golden_symbols.json @@ -191,6 +191,9 @@ { "name": "newArray" }, + { + "name": "noSideEffects" + }, { "name": "providerToFactory" }, @@ -223,8 +226,5 @@ }, { "name": "ɵɵinject" - }, - { - "name": "noSideEffects" } -] +] \ No newline at end of file diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 7297319d19..b68bdac5a8 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -707,6 +707,9 @@ { "name": "getSelectedIndex" }, + { + "name": "getSelectedTNode" + }, { "name": "getSymbolIterator" },