refactor(ivy): remove ɵɵelementAttribute instruction (#30640)
PR Close #30640
This commit is contained in:
@ -126,7 +126,6 @@ export {
|
||||
ɵɵenableBindings,
|
||||
ɵɵdisableBindings,
|
||||
ɵɵallocHostVars,
|
||||
ɵɵelementAttribute,
|
||||
ɵɵelementContainerStart,
|
||||
ɵɵelementContainerEnd,
|
||||
ɵɵstyling,
|
||||
|
@ -7,16 +7,18 @@
|
||||
*/
|
||||
|
||||
import '../util/ng_i18n_closure_mode';
|
||||
|
||||
import {getPluralCase} from '../i18n/localization';
|
||||
import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent} from '../sanitization/html_sanitizer';
|
||||
import {InertBodyHelper} from '../sanitization/inert_body';
|
||||
import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer';
|
||||
import {addAllToArray} from '../util/array_utils';
|
||||
import {assertDataInRange, assertDefined, assertEqual, assertGreaterThan} from '../util/assert';
|
||||
|
||||
import {attachPatchData} from './context_discovery';
|
||||
import {elementAttributeInternal, setDelayProjection, ɵɵload, ɵɵtextBinding} from './instructions/all';
|
||||
import {setDelayProjection, ɵɵload, ɵɵtextBinding} from './instructions/all';
|
||||
import {attachI18nOpCodesDebug} from './instructions/lview_debug';
|
||||
import {allocExpando, elementPropertyInternal, getOrCreateTNode, setInputsForProperty} from './instructions/shared';
|
||||
import {allocExpando, elementAttributeInternal, elementPropertyInternal, getOrCreateTNode, setInputsForProperty} from './instructions/shared';
|
||||
import {LContainer, NATIVE} from './interfaces/container';
|
||||
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n, TIcu} from './interfaces/i18n';
|
||||
import {TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeType, TProjectionNode} from './interfaces/node';
|
||||
@ -755,10 +757,9 @@ function readCreateOpCodes(
|
||||
const elementNodeIndex = opCode >>> I18nMutateOpCode.SHIFT_REF;
|
||||
const attrName = createOpCodes[++i] as string;
|
||||
const attrValue = createOpCodes[++i] as string;
|
||||
const renderer = viewData[RENDERER];
|
||||
// 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, viewData, renderer);
|
||||
elementAttributeInternal(elementNodeIndex, attrName, attrValue, viewData);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unable to determine the type of mutate operation for "${opCode}"`);
|
||||
@ -988,8 +989,7 @@ function i18nAttributesFirstPass(tView: TView, index: number, values: string[])
|
||||
generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes);
|
||||
} else {
|
||||
const lView = getLView();
|
||||
const renderer = lView[RENDERER];
|
||||
elementAttributeInternal(previousElementIndex, attrName, value, lView, renderer);
|
||||
elementAttributeInternal(previousElementIndex, attrName, value, lView);
|
||||
// Check if that attribute is a directive input
|
||||
const tNode = getTNode(previousElementIndex, lView);
|
||||
const dataValue = tNode.inputs && tNode.inputs[attrName];
|
||||
|
@ -47,7 +47,6 @@ export {
|
||||
ɵɵdirectiveInject,
|
||||
|
||||
ɵɵelement,
|
||||
ɵɵelementAttribute,
|
||||
ɵɵelementContainerEnd,
|
||||
|
||||
ɵɵelementContainerStart,
|
||||
|
@ -6,10 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {SanitizerFn} from '../interfaces/sanitization';
|
||||
import {getSelectedIndex} from '../state';
|
||||
import {getLView, getSelectedIndex} from '../state';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
|
||||
import {ɵɵelementAttribute} from './element';
|
||||
import {ɵɵbind} from './property';
|
||||
import {elementAttributeInternal} from './shared';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Updates the value of or removes a bound attribute on an Element.
|
||||
@ -27,6 +30,10 @@ import {ɵɵbind} from './property';
|
||||
export function ɵɵattribute(
|
||||
name: string, value: any, sanitizer?: SanitizerFn | null, namespace?: string) {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
return ɵɵelementAttribute(index, name, ɵɵbind(value), sanitizer, namespace);
|
||||
const bound = ɵɵbind(value);
|
||||
if (bound !== NO_CHANGE) {
|
||||
return elementAttributeInternal(index, name, bound, lView, sanitizer, namespace);
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {SanitizerFn} from '../interfaces/sanitization';
|
||||
import {getSelectedIndex} from '../state';
|
||||
import {ɵɵelementAttribute} from './element';
|
||||
import {getLView, getSelectedIndex} from '../state';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
|
||||
import {ɵɵinterpolation1, ɵɵinterpolation2, ɵɵinterpolation3, ɵɵinterpolation4, ɵɵinterpolation5, ɵɵinterpolation6, ɵɵinterpolation7, ɵɵinterpolation8, ɵɵinterpolationV} from './interpolation';
|
||||
import {TsickleIssue1009} from './shared';
|
||||
import {TsickleIssue1009, elementAttributeInternal} from './shared';
|
||||
|
||||
|
||||
|
||||
@ -41,12 +42,13 @@ export function ɵɵattributeInterpolate1(
|
||||
attrName: string, prefix: string, v0: any, suffix: string, sanitizer?: SanitizerFn,
|
||||
namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue = ɵɵinterpolation1(prefix, v0, suffix);
|
||||
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate1;
|
||||
}
|
||||
|
||||
@ -80,10 +82,13 @@ export function ɵɵattributeInterpolate2(
|
||||
attrName: string, prefix: string, v0: any, i0: string, v1: any, suffix: string,
|
||||
sanitizer?: SanitizerFn, namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue = ɵɵinterpolation2(prefix, v0, i0, v1, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate2;
|
||||
}
|
||||
|
||||
@ -120,10 +125,13 @@ export function ɵɵattributeInterpolate3(
|
||||
attrName: string, prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any,
|
||||
suffix: string, sanitizer?: SanitizerFn, namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue = ɵɵinterpolation3(prefix, v0, i0, v1, i1, v2, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate3;
|
||||
}
|
||||
|
||||
@ -162,10 +170,13 @@ export function ɵɵattributeInterpolate4(
|
||||
attrName: string, prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string,
|
||||
v3: any, suffix: string, sanitizer?: SanitizerFn, namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue = ɵɵinterpolation4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate4;
|
||||
}
|
||||
|
||||
@ -207,10 +218,13 @@ export function ɵɵattributeInterpolate5(
|
||||
v3: any, i3: string, v4: any, suffix: string, sanitizer?: SanitizerFn,
|
||||
namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue = ɵɵinterpolation5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate5;
|
||||
}
|
||||
|
||||
@ -254,10 +268,13 @@ export function ɵɵattributeInterpolate6(
|
||||
v3: any, i3: string, v4: any, i4: string, v5: any, suffix: string, sanitizer?: SanitizerFn,
|
||||
namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue =
|
||||
ɵɵinterpolation6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate6;
|
||||
}
|
||||
|
||||
@ -303,10 +320,13 @@ export function ɵɵattributeInterpolate7(
|
||||
v3: any, i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, suffix: string,
|
||||
sanitizer?: SanitizerFn, namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue =
|
||||
ɵɵinterpolation7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate7;
|
||||
}
|
||||
|
||||
@ -354,10 +374,13 @@ export function ɵɵattributeInterpolate8(
|
||||
v3: any, i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, i6: string, v7: any,
|
||||
suffix: string, sanitizer?: SanitizerFn, namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
const interpolatedValue =
|
||||
ɵɵinterpolation8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
|
||||
ɵɵelementAttribute(index, attrName, interpolatedValue, sanitizer, namespace);
|
||||
if (interpolatedValue !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolate8;
|
||||
}
|
||||
|
||||
@ -391,7 +414,11 @@ export function ɵɵattributeInterpolateV(
|
||||
attrName: string, values: any[], sanitizer?: SanitizerFn,
|
||||
namespace?: string): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(FW-1340): Refactor to remove the use of other instructions here.
|
||||
ɵɵelementAttribute(index, attrName, ɵɵinterpolationV(values), sanitizer, namespace);
|
||||
const interpolated = ɵɵinterpolationV(values);
|
||||
if (interpolated !== NO_CHANGE) {
|
||||
elementAttributeInternal(index, attrName, interpolated, lView, sanitizer, namespace);
|
||||
}
|
||||
return ɵɵattributeInterpolateV;
|
||||
}
|
||||
|
@ -5,16 +5,14 @@
|
||||
* 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
|
||||
*/
|
||||
import {validateAgainstEventAttributes} from '../../sanitization/sanitization';
|
||||
import {assertDataInRange, assertDefined, assertEqual} from '../../util/assert';
|
||||
import {assertHasParent} from '../assert';
|
||||
import {attachPatchData} from '../context_discovery';
|
||||
import {registerPostOrderHooks} from '../hooks';
|
||||
import {TAttributes, TNodeFlags, TNodeType} from '../interfaces/node';
|
||||
import {RElement, Renderer3, isProceduralRenderer} from '../interfaces/renderer';
|
||||
import {SanitizerFn} from '../interfaces/sanitization';
|
||||
import {RElement} from '../interfaces/renderer';
|
||||
import {StylingContext} from '../interfaces/styling';
|
||||
import {BINDING_INDEX, HEADER_OFFSET, LView, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view';
|
||||
import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view';
|
||||
import {assertNodeType} from '../node_assert';
|
||||
import {appendChild} from '../node_manipulation';
|
||||
import {applyOnCreateInstructions} from '../node_util';
|
||||
@ -23,14 +21,14 @@ import {getInitialClassNameValue, getInitialStyleStringValue, initializeStaticCo
|
||||
import {getStylingContextFromLView, hasClassInput, hasStyleInput} from '../styling/util';
|
||||
import {registerInitialStylingIntoContext} from '../styling_next/instructions';
|
||||
import {runtimeIsNewStylingInUse} from '../styling_next/state';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
import {attrsStylingIndexOf, setUpAttributes} from '../util/attrs_utils';
|
||||
import {renderStringify} from '../util/misc_utils';
|
||||
import {getNativeByIndex, getNativeByTNode, getTNode} from '../util/view_utils';
|
||||
import {getNativeByTNode, getTNode} from '../util/view_utils';
|
||||
|
||||
import {createDirectivesAndLocals, elementCreate, executeContentQueries, getOrCreateTNode, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate} from './shared';
|
||||
import {getActiveDirectiveStylingIndex} from './styling';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
|
||||
*
|
||||
@ -197,54 +195,6 @@ export function ɵɵelement(
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the value or removes an attribute on an Element.
|
||||
*
|
||||
* @param index The index of the element in the data array
|
||||
* @param name name The name of the attribute.
|
||||
* @param value value The attribute is removed when value is `null` or `undefined`.
|
||||
* Otherwise the attribute value is set to the stringified value.
|
||||
* @param sanitizer An optional function used to sanitize the value.
|
||||
* @param namespace Optional namespace to use when setting the attribute.
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵelementAttribute(
|
||||
index: number, name: string, value: any, sanitizer?: SanitizerFn | null,
|
||||
namespace?: string): void {
|
||||
if (value !== NO_CHANGE) {
|
||||
const lView = getLView();
|
||||
const renderer = lView[RENDERER];
|
||||
elementAttributeInternal(index, name, value, lView, renderer, sanitizer, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
export function elementAttributeInternal(
|
||||
index: number, name: string, value: any, lView: LView, renderer: Renderer3,
|
||||
sanitizer?: SanitizerFn | null, namespace?: string) {
|
||||
ngDevMode && validateAgainstEventAttributes(name);
|
||||
const element = getNativeByIndex(index, lView) as RElement;
|
||||
if (value == null) {
|
||||
ngDevMode && ngDevMode.rendererRemoveAttribute++;
|
||||
isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
|
||||
element.removeAttribute(name);
|
||||
} else {
|
||||
ngDevMode && ngDevMode.rendererSetAttribute++;
|
||||
const tNode = getTNode(index, lView);
|
||||
const strValue =
|
||||
sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name);
|
||||
|
||||
|
||||
if (isProceduralRenderer(renderer)) {
|
||||
renderer.setAttribute(element, name, strValue, namespace);
|
||||
} else {
|
||||
namespace ? element.setAttributeNS(namespace, name, strValue) :
|
||||
element.setAttribute(name, strValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign static attribute values to a host element.
|
||||
*
|
||||
|
@ -9,7 +9,7 @@ import {Injector} from '../../di';
|
||||
import {ErrorHandler} from '../../error_handler';
|
||||
import {Type} from '../../interface/type';
|
||||
import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, SchemaMetadata} from '../../metadata/schema';
|
||||
import {validateAgainstEventProperties} from '../../sanitization/sanitization';
|
||||
import {validateAgainstEventAttributes, validateAgainstEventProperties} from '../../sanitization/sanitization';
|
||||
import {Sanitizer} from '../../sanitization/security';
|
||||
import {assertDataInRange, assertDefined, assertDomNode, assertEqual, assertLessThan, assertNotEqual, assertNotSame} from '../../util/assert';
|
||||
import {createNamedArrayType} from '../../util/named_array_type';
|
||||
@ -35,7 +35,7 @@ import {initializeStaticContext as initializeStaticStylingContext} from '../styl
|
||||
import {ANIMATION_PROP_PREFIX, isAnimationProp} from '../styling/util';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
import {attrsStylingIndexOf} from '../util/attrs_utils';
|
||||
import {INTERPOLATION_DELIMITER, stringifyForError} from '../util/misc_utils';
|
||||
import {INTERPOLATION_DELIMITER, renderStringify, stringifyForError} from '../util/misc_utils';
|
||||
import {getLViewParent, getRootContext} from '../util/view_traversal_utils';
|
||||
import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, isComponent, isComponentDef, isContentQueryHost, isLContainer, isRootView, readPatchedLView, resetPreOrderHookFlags, unwrapRNode, viewAttachedToChangeDetector} from '../util/view_utils';
|
||||
|
||||
@ -1303,6 +1303,33 @@ function addComponentLogic<T>(
|
||||
}
|
||||
}
|
||||
|
||||
export function elementAttributeInternal(
|
||||
index: number, name: string, value: any, lView: LView, sanitizer?: SanitizerFn | null,
|
||||
namespace?: string) {
|
||||
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 renderer = lView[RENDERER];
|
||||
if (value == null) {
|
||||
ngDevMode && ngDevMode.rendererRemoveAttribute++;
|
||||
isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
|
||||
element.removeAttribute(name);
|
||||
} else {
|
||||
ngDevMode && ngDevMode.rendererSetAttribute++;
|
||||
const tNode = getTNode(index, lView);
|
||||
const strValue =
|
||||
sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name);
|
||||
|
||||
|
||||
if (isProceduralRenderer(renderer)) {
|
||||
renderer.setAttribute(element, name, strValue, namespace);
|
||||
} else {
|
||||
namespace ? element.setAttributeNS(namespace, name, strValue) :
|
||||
element.setAttribute(name, strValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets initial input properties on directive instances from attribute data
|
||||
*
|
||||
|
@ -46,7 +46,6 @@ export const angularCoreEnv: {[name: string]: Function} =
|
||||
'ɵɵNgOnChangesFeature': r3.ɵɵNgOnChangesFeature,
|
||||
'ɵɵProvidersFeature': r3.ɵɵProvidersFeature,
|
||||
'ɵɵInheritDefinitionFeature': r3.ɵɵInheritDefinitionFeature,
|
||||
'ɵɵelementAttribute': r3.ɵɵelementAttribute,
|
||||
'ɵɵbind': r3.ɵɵbind,
|
||||
'ɵɵcontainer': r3.ɵɵcontainer,
|
||||
'ɵɵnextContext': r3.ɵɵnextContext,
|
||||
|
Reference in New Issue
Block a user