@angular/core 20.0.6 → 20.1.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{api.d.d.ts → api.d-Dwpmmn5j.d.ts} +2 -2
- package/{chrome_dev_tools_performance.d.d.ts → chrome_dev_tools_performance.d-Dk_7kdX9.d.ts} +7 -3
- package/{discovery.d.d.ts → discovery.d-AiW64LSq.d.ts} +5 -6
- package/{event_dispatcher.d.d.ts → event_dispatcher.d-BReQpZfC.d.ts} +1 -1
- package/fesm2022/{attribute.mjs → attribute-BWp59EjE.mjs} +2 -2
- package/fesm2022/attribute-BWp59EjE.mjs.map +1 -0
- package/fesm2022/core.mjs +22 -28
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/{debug_node.mjs → debug_node-CGQXW8qF.mjs} +1479 -1466
- package/fesm2022/debug_node-CGQXW8qF.mjs.map +1 -0
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/di.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -2
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +5 -5
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/{resource.mjs → resource-CIODajJI.mjs} +8 -12
- package/fesm2022/resource-CIODajJI.mjs.map +1 -0
- package/fesm2022/{root_effect_scheduler.mjs → root_effect_scheduler-BvK6bnZD.mjs} +20 -27
- package/fesm2022/root_effect_scheduler-BvK6bnZD.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +5 -5
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/{signal.mjs → signal-nCiHhWf6.mjs} +2 -2
- package/fesm2022/signal-nCiHhWf6.mjs.map +1 -0
- package/fesm2022/testing.mjs +72 -171
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/{untracked.mjs → untracked-DmD_2MlC.mjs} +3 -3
- package/fesm2022/untracked-DmD_2MlC.mjs.map +1 -0
- package/fesm2022/{weak_ref.mjs → weak_ref-BaIq-pgY.mjs} +2 -2
- package/fesm2022/weak_ref-BaIq-pgY.mjs.map +1 -0
- package/{graph.d.d.ts → graph.d-BcIOep_B.d.ts} +1 -1
- package/index.d.ts +23 -16
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +3 -3
- package/primitives/signals/index.d.ts +6 -6
- package/rxjs-interop/index.d.ts +5 -5
- package/schematics/bundles/{apply_import_manager-mlmcgZ0v.cjs → apply_import_manager-BsIRDO9W.cjs} +3 -3
- package/schematics/bundles/{checker-a0VNmSrQ.cjs → checker-CY7a8ko8.cjs} +771 -642
- package/schematics/bundles/cleanup-unused-imports.cjs +21 -35
- package/schematics/bundles/{compiler_host-CwrMDc6k.cjs → compiler_host-DNYQkH4l.cjs} +2 -2
- package/schematics/bundles/control-flow-migration.cjs +3 -3
- package/schematics/bundles/document-core.cjs +5 -5
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-DAP9ZmeX.cjs → index-BJ3PYYwQ.cjs} +17 -16
- package/schematics/bundles/{index-jMQgXbRg.cjs → index-BUgQDm-J.cjs} +1018 -589
- package/schematics/bundles/inject-flags.cjs +5 -5
- package/schematics/bundles/inject-migration.cjs +4 -9
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-CX0snBqz.cjs → migrate_ts_type_references-MBd4NBjn.cjs} +26 -77
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +6 -6
- package/schematics/bundles/{project_paths-C4WM31v5.cjs → project_paths-C5Df24y1.cjs} +3 -3
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +3 -3
- package/schematics/bundles/self-closing-tags-migration.cjs +7 -19
- package/schematics/bundles/signal-input-migration.cjs +28 -12
- package/schematics/bundles/signal-queries-migration.cjs +7 -7
- package/schematics/bundles/signals.cjs +7 -7
- package/schematics/bundles/standalone-migration.cjs +4 -4
- package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
- package/schematics/bundles/test-bed-get.cjs +4 -4
- package/{signal.d.d.ts → signal.d-BcmOdASA.d.ts} +2 -2
- package/testing/index.d.ts +6 -73
- package/{weak_ref.d.d.ts → weak_ref.d-eGOEP9S1.d.ts} +1 -1
- package/fesm2022/attribute.mjs.map +0 -1
- package/fesm2022/debug_node.mjs.map +0 -1
- package/fesm2022/resource.mjs.map +0 -1
- package/fesm2022/root_effect_scheduler.mjs.map +0 -1
- package/fesm2022/signal.mjs.map +0 -1
- package/fesm2022/untracked.mjs.map +0 -1
- package/fesm2022/weak_ref.mjs.map +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.0.
|
|
2
|
+
* @license Angular v20.1.0-next.1
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString,
|
|
8
|
-
import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './signal.mjs';
|
|
7
|
+
import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, throwCyclicDependencyError, stringifyForError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, isInInjectionContext, DestroyRef, PendingTasksInternal, noop, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, ZONELESS_SCHEDULER_DISABLED, SCHEDULE_IN_ROOT_ZONE, PROVIDED_ZONELESS, getNativeByTNodeOrNull } from './root_effect_scheduler-BvK6bnZD.mjs';
|
|
8
|
+
import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './signal-nCiHhWf6.mjs';
|
|
9
9
|
import { Subject, Subscription } from 'rxjs';
|
|
10
10
|
import { setActiveConsumer as setActiveConsumer$1 } from '@angular/core/primitives/signals';
|
|
11
11
|
import { map } from 'rxjs/operators';
|
|
12
|
-
import { Attribute as Attribute$1 } from './attribute.mjs';
|
|
12
|
+
import { Attribute as Attribute$1 } from './attribute-BWp59EjE.mjs';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Convince closure compiler that the wrapped function has no side-effects.
|
|
@@ -1893,7 +1893,7 @@ function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flag
|
|
|
1893
1893
|
const isHostSpecialCase = flags & 1 /* InternalInjectFlags.Host */ && hostTElementNode === tNode;
|
|
1894
1894
|
const injectableIdx = locateDirectiveOrProvider(tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);
|
|
1895
1895
|
if (injectableIdx !== null) {
|
|
1896
|
-
return getNodeInjectable(lView, currentTView, injectableIdx, tNode);
|
|
1896
|
+
return getNodeInjectable(lView, currentTView, injectableIdx, tNode, flags);
|
|
1897
1897
|
}
|
|
1898
1898
|
else {
|
|
1899
1899
|
return NOT_FOUND;
|
|
@@ -1943,7 +1943,7 @@ function locateDirectiveOrProvider(tNode, tView, token, canAccessViewProviders,
|
|
|
1943
1943
|
* cached `injectable`. Otherwise if it detects that the value is still a factory it
|
|
1944
1944
|
* instantiates the `injectable` and caches the value.
|
|
1945
1945
|
*/
|
|
1946
|
-
function getNodeInjectable(lView, tView, index, tNode) {
|
|
1946
|
+
function getNodeInjectable(lView, tView, index, tNode, flags) {
|
|
1947
1947
|
let value = lView[index];
|
|
1948
1948
|
const tData = tView.data;
|
|
1949
1949
|
if (value instanceof NodeInjectorFactory) {
|
|
@@ -1971,7 +1971,7 @@ function getNodeInjectable(lView, tView, index, tNode) {
|
|
|
1971
1971
|
assertEqual(success, true, "Because flags do not contain `SkipSelf' we expect this to always succeed.");
|
|
1972
1972
|
try {
|
|
1973
1973
|
ngDevMode && emitInjectorToCreateInstanceEvent(token);
|
|
1974
|
-
value = lView[index] = factory.factory(undefined, tData, lView, tNode);
|
|
1974
|
+
value = lView[index] = factory.factory(undefined, flags, tData, lView, tNode);
|
|
1975
1975
|
ngDevMode && emitInstanceCreatedByInjectorEvent(value);
|
|
1976
1976
|
// This code path is hit for both directives and providers.
|
|
1977
1977
|
// For perf reasons, we want to avoid searching for hooks on providers.
|
|
@@ -4189,6 +4189,15 @@ class DehydratedBlockRegistry {
|
|
|
4189
4189
|
});
|
|
4190
4190
|
}
|
|
4191
4191
|
|
|
4192
|
+
/**
|
|
4193
|
+
* Checks whether a TNode is considered detached, i.e. not present in the
|
|
4194
|
+
* translated i18n template. We should not attempt hydration for such nodes
|
|
4195
|
+
* and instead, use a regular "creation mode".
|
|
4196
|
+
*/
|
|
4197
|
+
function isDetachedByI18n(tNode) {
|
|
4198
|
+
return (tNode.flags & 32 /* TNodeFlags.isDetached */) === 32 /* TNodeFlags.isDetached */;
|
|
4199
|
+
}
|
|
4200
|
+
|
|
4192
4201
|
/**
|
|
4193
4202
|
* The name of the key used in the TransferState collection,
|
|
4194
4203
|
* where hydration information is located.
|
|
@@ -4532,6 +4541,18 @@ function isDisconnectedNode$1(hydrationInfo, index) {
|
|
|
4532
4541
|
}
|
|
4533
4542
|
return !!initDisconnectedNodes(hydrationInfo)?.has(index);
|
|
4534
4543
|
}
|
|
4544
|
+
/**
|
|
4545
|
+
* Checks whether a node can be hydrated.
|
|
4546
|
+
* @param lView View in which the node instance is placed.
|
|
4547
|
+
* @param tNode Node to be checked.
|
|
4548
|
+
*/
|
|
4549
|
+
function canHydrateNode(lView, tNode) {
|
|
4550
|
+
const hydrationInfo = lView[HYDRATION];
|
|
4551
|
+
return (hydrationInfo !== null &&
|
|
4552
|
+
!isInSkipHydrationBlock$1() &&
|
|
4553
|
+
!isDetachedByI18n(tNode) &&
|
|
4554
|
+
!isDisconnectedNode$1(hydrationInfo, tNode.index - HEADER_OFFSET));
|
|
4555
|
+
}
|
|
4535
4556
|
/**
|
|
4536
4557
|
* Helper function to prepare text nodes for serialization by ensuring
|
|
4537
4558
|
* that seperate logical text blocks in the DOM remain separate after
|
|
@@ -5896,21 +5917,20 @@ function ɵgetUnknownPropertyStrictMode() {
|
|
|
5896
5917
|
* - the element matches any directive
|
|
5897
5918
|
* - the element is allowed by one of the schemas
|
|
5898
5919
|
*
|
|
5899
|
-
* @param
|
|
5900
|
-
* @param
|
|
5901
|
-
* @param tagName Name of the tag to check
|
|
5902
|
-
* @param schemas Array of schemas
|
|
5903
|
-
* @param hasDirectives Boolean indicating that the element matches any directive
|
|
5920
|
+
* @param lView An `LView` associated with a template is being rendered
|
|
5921
|
+
* @param tNode TNode representing an element to be validated
|
|
5904
5922
|
*/
|
|
5905
|
-
function validateElementIsKnown(
|
|
5923
|
+
function validateElementIsKnown(lView, tNode) {
|
|
5924
|
+
const tView = lView[TVIEW];
|
|
5906
5925
|
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
5907
5926
|
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
5908
5927
|
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
5909
5928
|
// execute the check below.
|
|
5910
|
-
if (schemas === null)
|
|
5929
|
+
if (tView.schemas === null)
|
|
5911
5930
|
return;
|
|
5931
|
+
const tagName = tNode.value;
|
|
5912
5932
|
// If the element matches any directive, it's considered as valid.
|
|
5913
|
-
if (!
|
|
5933
|
+
if (!isDirectiveHost(tNode) && tagName !== null) {
|
|
5914
5934
|
// The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
|
|
5915
5935
|
// as a custom element. Note that unknown elements with a dash in their name won't be instances
|
|
5916
5936
|
// of HTMLUnknownElement in browsers that support web components.
|
|
@@ -5919,11 +5939,11 @@ function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives)
|
|
|
5919
5939
|
// Domino doesn't expose HTMLUnknownElement globally.
|
|
5920
5940
|
(typeof HTMLUnknownElement !== 'undefined' &&
|
|
5921
5941
|
HTMLUnknownElement &&
|
|
5922
|
-
|
|
5942
|
+
getNativeByTNode(tNode, lView) instanceof HTMLUnknownElement) ||
|
|
5923
5943
|
(typeof customElements !== 'undefined' &&
|
|
5924
5944
|
tagName.indexOf('-') > -1 &&
|
|
5925
5945
|
!customElements.get(tagName));
|
|
5926
|
-
if (isUnknown && !matchingSchemas(schemas, tagName)) {
|
|
5946
|
+
if (isUnknown && !matchingSchemas(tView.schemas, tagName)) {
|
|
5927
5947
|
const isHostStandalone = isHostComponentStandalone(lView);
|
|
5928
5948
|
const templateLocation = getTemplateLocationDetails(lView);
|
|
5929
5949
|
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
@@ -7123,1444 +7143,1477 @@ function writeToDirectiveInput(def, instance, publicName, value) {
|
|
|
7123
7143
|
}
|
|
7124
7144
|
}
|
|
7125
7145
|
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7146
|
+
/**
|
|
7147
|
+
* Flags for renderer-specific style modifiers.
|
|
7148
|
+
* @publicApi
|
|
7149
|
+
*/
|
|
7150
|
+
var RendererStyleFlags2;
|
|
7151
|
+
(function (RendererStyleFlags2) {
|
|
7152
|
+
// TODO(misko): This needs to be refactored into a separate file so that it can be imported from
|
|
7153
|
+
// `node_manipulation.ts` Currently doing the import cause resolution order to change and fails
|
|
7154
|
+
// the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.
|
|
7155
|
+
/**
|
|
7156
|
+
* Marks a style as important.
|
|
7157
|
+
*/
|
|
7158
|
+
RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
|
|
7159
|
+
/**
|
|
7160
|
+
* Marks a style as using dash case naming (this-is-dash-case).
|
|
7161
|
+
*/
|
|
7162
|
+
RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
|
|
7163
|
+
})(RendererStyleFlags2 || (RendererStyleFlags2 = {}));
|
|
7164
|
+
|
|
7165
|
+
let _icuContainerIterate;
|
|
7166
|
+
/**
|
|
7167
|
+
* Iterator which provides ability to visit all of the `TIcuContainerNode` root `RNode`s.
|
|
7168
|
+
*/
|
|
7169
|
+
function icuContainerIterate(tIcuContainerNode, lView) {
|
|
7170
|
+
return _icuContainerIterate(tIcuContainerNode, lView);
|
|
7149
7171
|
}
|
|
7150
7172
|
/**
|
|
7151
|
-
*
|
|
7173
|
+
* Ensures that `IcuContainerVisitor`'s implementation is present.
|
|
7174
|
+
*
|
|
7175
|
+
* This function is invoked when i18n instruction comes across an ICU. The purpose is to allow the
|
|
7176
|
+
* bundler to tree shake ICU logic and only load it if ICU instruction is executed.
|
|
7152
7177
|
*/
|
|
7153
|
-
function
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7178
|
+
function ensureIcuContainerVisitorLoaded(loader) {
|
|
7179
|
+
if (_icuContainerIterate === undefined) {
|
|
7180
|
+
// Do not inline this function. We want to keep `ensureIcuContainerVisitorLoaded` light, so it
|
|
7181
|
+
// can be inlined into call-site.
|
|
7182
|
+
_icuContainerIterate = loader();
|
|
7157
7183
|
}
|
|
7158
7184
|
}
|
|
7185
|
+
|
|
7159
7186
|
/**
|
|
7160
|
-
*
|
|
7161
|
-
*
|
|
7187
|
+
* NOTE: for performance reasons, the possible actions are inlined within the function instead of
|
|
7188
|
+
* being passed as an argument.
|
|
7162
7189
|
*/
|
|
7163
|
-
function
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7190
|
+
function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
|
|
7191
|
+
// If this slot was allocated for a text node dynamically created by i18n, the text node itself
|
|
7192
|
+
// won't be created until i18nApply() in the update block, so this node should be skipped.
|
|
7193
|
+
// For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
|
|
7194
|
+
// in `i18n_spec.ts`.
|
|
7195
|
+
if (lNodeToHandle != null) {
|
|
7196
|
+
let lContainer;
|
|
7197
|
+
let isComponent = false;
|
|
7198
|
+
// We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
|
|
7199
|
+
// wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
|
|
7200
|
+
// it has LContainer so that we can process all of those cases appropriately.
|
|
7201
|
+
if (isLContainer(lNodeToHandle)) {
|
|
7202
|
+
lContainer = lNodeToHandle;
|
|
7203
|
+
}
|
|
7204
|
+
else if (isLView(lNodeToHandle)) {
|
|
7205
|
+
isComponent = true;
|
|
7206
|
+
ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
|
|
7207
|
+
lNodeToHandle = lNodeToHandle[HOST];
|
|
7208
|
+
}
|
|
7209
|
+
const rNode = unwrapRNode(lNodeToHandle);
|
|
7210
|
+
if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
|
|
7211
|
+
if (beforeNode == null) {
|
|
7212
|
+
nativeAppendChild(renderer, parent, rNode);
|
|
7213
|
+
}
|
|
7214
|
+
else {
|
|
7215
|
+
nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
|
|
7216
|
+
}
|
|
7217
|
+
}
|
|
7218
|
+
else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
|
|
7219
|
+
nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
|
|
7220
|
+
}
|
|
7221
|
+
else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
|
|
7222
|
+
nativeRemoveNode(renderer, rNode, isComponent);
|
|
7223
|
+
}
|
|
7224
|
+
else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
|
|
7225
|
+
renderer.destroyNode(rNode);
|
|
7226
|
+
}
|
|
7227
|
+
if (lContainer != null) {
|
|
7228
|
+
applyContainer(renderer, action, lContainer, parent, beforeNode);
|
|
7173
7229
|
}
|
|
7174
7230
|
}
|
|
7175
7231
|
}
|
|
7176
7232
|
/**
|
|
7177
|
-
*
|
|
7233
|
+
* Removes all DOM elements associated with a view.
|
|
7178
7234
|
*
|
|
7179
|
-
*
|
|
7180
|
-
*
|
|
7181
|
-
*
|
|
7182
|
-
* @param injector Root view injector instance.
|
|
7183
|
-
*/
|
|
7184
|
-
function locateHostElement(renderer, elementOrSelector, encapsulation, injector) {
|
|
7185
|
-
// Note: we use default value for the `PRESERVE_HOST_CONTENT` here even though it's a
|
|
7186
|
-
// tree-shakable one (providedIn:'root'). This code path can be triggered during dynamic
|
|
7187
|
-
// component creation (after calling ViewContainerRef.createComponent) when an injector
|
|
7188
|
-
// instance can be provided. The injector instance might be disconnected from the main DI
|
|
7189
|
-
// tree, thus the `PRESERVE_HOST_CONTENT` would not be able to instantiate. In this case, the
|
|
7190
|
-
// default value will be used.
|
|
7191
|
-
const preserveHostContent = injector.get(PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT);
|
|
7192
|
-
// When using native Shadow DOM, do not clear host element to allow native slot
|
|
7193
|
-
// projection.
|
|
7194
|
-
const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation.ShadowDom;
|
|
7195
|
-
const rootElement = renderer.selectRootElement(elementOrSelector, preserveContent);
|
|
7196
|
-
applyRootElementTransform(rootElement);
|
|
7197
|
-
return rootElement;
|
|
7198
|
-
}
|
|
7199
|
-
/**
|
|
7200
|
-
* Applies any root element transformations that are needed. If hydration is enabled,
|
|
7201
|
-
* this will process corrupted text nodes.
|
|
7235
|
+
* Because some root nodes of the view may be containers, we sometimes need
|
|
7236
|
+
* to propagate deeply into the nested containers to remove all elements in the
|
|
7237
|
+
* views beneath it.
|
|
7202
7238
|
*
|
|
7203
|
-
* @param
|
|
7239
|
+
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
7240
|
+
* @param lView The view from which elements should be added or removed
|
|
7204
7241
|
*/
|
|
7205
|
-
function
|
|
7206
|
-
|
|
7242
|
+
function removeViewFromDOM(tView, lView) {
|
|
7243
|
+
detachViewFromDOM(tView, lView);
|
|
7244
|
+
lView[HOST] = null;
|
|
7245
|
+
lView[T_HOST] = null;
|
|
7207
7246
|
}
|
|
7208
7247
|
/**
|
|
7209
|
-
*
|
|
7210
|
-
* of an app. When hydration is enabled, this processes any corrupt text nodes
|
|
7211
|
-
* so they are properly hydratable on the client.
|
|
7248
|
+
* Adds all DOM elements associated with a view.
|
|
7212
7249
|
*
|
|
7213
|
-
*
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
/**
|
|
7217
|
-
* Processes text node markers before hydration begins. This replaces any special comment
|
|
7218
|
-
* nodes that were added prior to serialization are swapped out to restore proper text
|
|
7219
|
-
* nodes before hydration.
|
|
7250
|
+
* Because some root nodes of the view may be containers, we sometimes need
|
|
7251
|
+
* to propagate deeply into the nested containers to add all elements in the
|
|
7252
|
+
* views beneath it.
|
|
7220
7253
|
*
|
|
7221
|
-
* @param
|
|
7254
|
+
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
7255
|
+
* @param parentTNode The `TNode` where the `LView` should be attached to.
|
|
7256
|
+
* @param renderer Current renderer to use for DOM manipulations.
|
|
7257
|
+
* @param lView The view from which elements should be added or removed
|
|
7258
|
+
* @param parentNativeNode The parent `RElement` where it should be inserted into.
|
|
7259
|
+
* @param beforeNode The node before which elements should be added, if insert mode
|
|
7222
7260
|
*/
|
|
7223
|
-
function
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
// the contents and render everything from scratch.
|
|
7228
|
-
clearElementContents(rootElement);
|
|
7229
|
-
}
|
|
7230
|
-
else {
|
|
7231
|
-
processTextNodeMarkersBeforeHydration(rootElement);
|
|
7232
|
-
}
|
|
7261
|
+
function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
|
|
7262
|
+
lView[HOST] = parentNativeNode;
|
|
7263
|
+
lView[T_HOST] = parentTNode;
|
|
7264
|
+
applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
|
|
7233
7265
|
}
|
|
7234
7266
|
/**
|
|
7235
|
-
*
|
|
7267
|
+
* Detach a `LView` from the DOM by detaching its nodes.
|
|
7268
|
+
*
|
|
7269
|
+
* @param tView The `TView' of the `LView` to be detached
|
|
7270
|
+
* @param lView the `LView` to be detached.
|
|
7236
7271
|
*/
|
|
7237
|
-
function
|
|
7238
|
-
|
|
7272
|
+
function detachViewFromDOM(tView, lView) {
|
|
7273
|
+
// When we remove a view from the DOM, we need to rerun afterRender hooks
|
|
7274
|
+
// We don't necessarily needs to run change detection. DOM removal only requires
|
|
7275
|
+
// change detection if animations are enabled (this notification is handled by animations).
|
|
7276
|
+
lView[ENVIRONMENT].changeDetectionScheduler?.notify(9 /* NotificationSource.ViewDetachedFromDOM */);
|
|
7277
|
+
applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
7239
7278
|
}
|
|
7240
7279
|
/**
|
|
7241
|
-
*
|
|
7280
|
+
* Traverses down and up the tree of views and containers to remove listeners and
|
|
7281
|
+
* call onDestroy callbacks.
|
|
7242
7282
|
*
|
|
7243
|
-
*
|
|
7244
|
-
*
|
|
7245
|
-
*
|
|
7283
|
+
* Notes:
|
|
7284
|
+
* - Because it's used for onDestroy calls, it needs to be bottom-up.
|
|
7285
|
+
* - Must process containers instead of their views to avoid splicing
|
|
7286
|
+
* when views are destroyed and re-added.
|
|
7287
|
+
* - Using a while loop because it's faster than recursion
|
|
7288
|
+
* - Destroy only called on movement to sibling or movement to parent (laterally or up)
|
|
7246
7289
|
*
|
|
7247
|
-
*
|
|
7248
|
-
* type-checking machinery of ngtsc.
|
|
7290
|
+
* @param rootView The view to destroy
|
|
7249
7291
|
*/
|
|
7250
|
-
function
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
if (
|
|
7254
|
-
return
|
|
7255
|
-
if (name === 'formaction')
|
|
7256
|
-
return 'formAction';
|
|
7257
|
-
if (name === 'innerHtml')
|
|
7258
|
-
return 'innerHTML';
|
|
7259
|
-
if (name === 'readonly')
|
|
7260
|
-
return 'readOnly';
|
|
7261
|
-
if (name === 'tabindex')
|
|
7262
|
-
return 'tabIndex';
|
|
7263
|
-
return name;
|
|
7264
|
-
}
|
|
7265
|
-
function setPropertyAndInputs(tNode, lView, propName, value, renderer, sanitizer) {
|
|
7266
|
-
ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
|
7267
|
-
const tView = lView[TVIEW];
|
|
7268
|
-
const hasSetInput = setAllInputsForProperty(tNode, tView, lView, propName, value);
|
|
7269
|
-
if (hasSetInput) {
|
|
7270
|
-
isComponentHost(tNode) && markDirtyIfOnPush(lView, tNode.index);
|
|
7271
|
-
ngDevMode && setNgReflectProperties(lView, tView, tNode, propName, value);
|
|
7272
|
-
return; // Stop propcessing if we've matched at least one input.
|
|
7292
|
+
function destroyViewTree(rootView) {
|
|
7293
|
+
// If the view has no children, we can clean it up and return early.
|
|
7294
|
+
let lViewOrLContainer = rootView[CHILD_HEAD];
|
|
7295
|
+
if (!lViewOrLContainer) {
|
|
7296
|
+
return cleanUpView(rootView[TVIEW], rootView);
|
|
7273
7297
|
}
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
* @param lView View in which the node is located.
|
|
7280
|
-
* @param propName Name of the property.
|
|
7281
|
-
* @param value Value to set on the property.
|
|
7282
|
-
* @param renderer Renderer to use when setting the property.
|
|
7283
|
-
* @param sanitizer Function used to sanitize the value before setting it.
|
|
7284
|
-
*/
|
|
7285
|
-
function setDomProperty(tNode, lView, propName, value, renderer, sanitizer) {
|
|
7286
|
-
if (tNode.type & 3 /* TNodeType.AnyRNode */) {
|
|
7287
|
-
const element = getNativeByTNode(tNode, lView);
|
|
7288
|
-
propName = mapPropName(propName);
|
|
7289
|
-
if (ngDevMode) {
|
|
7290
|
-
validateAgainstEventProperties(propName);
|
|
7291
|
-
if (!isPropertyValid(element, propName, tNode.value, lView[TVIEW].schemas)) {
|
|
7292
|
-
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
7293
|
-
}
|
|
7298
|
+
while (lViewOrLContainer) {
|
|
7299
|
+
let next = null;
|
|
7300
|
+
if (isLView(lViewOrLContainer)) {
|
|
7301
|
+
// If LView, traverse down to child.
|
|
7302
|
+
next = lViewOrLContainer[CHILD_HEAD];
|
|
7294
7303
|
}
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7304
|
+
else {
|
|
7305
|
+
ngDevMode && assertLContainer(lViewOrLContainer);
|
|
7306
|
+
// If container, traverse down to its first LView.
|
|
7307
|
+
const firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
|
|
7308
|
+
if (firstView)
|
|
7309
|
+
next = firstView;
|
|
7310
|
+
}
|
|
7311
|
+
if (!next) {
|
|
7312
|
+
// Only clean up view when moving to the side or up, as destroy hooks
|
|
7313
|
+
// should be called in order from the bottom up.
|
|
7314
|
+
while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
|
|
7315
|
+
if (isLView(lViewOrLContainer)) {
|
|
7316
|
+
cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
|
|
7317
|
+
}
|
|
7318
|
+
lViewOrLContainer = lViewOrLContainer[PARENT];
|
|
7319
|
+
}
|
|
7320
|
+
if (lViewOrLContainer === null)
|
|
7321
|
+
lViewOrLContainer = rootView;
|
|
7322
|
+
if (isLView(lViewOrLContainer)) {
|
|
7323
|
+
cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
|
|
7324
|
+
}
|
|
7325
|
+
next = lViewOrLContainer && lViewOrLContainer[NEXT];
|
|
7305
7326
|
}
|
|
7327
|
+
lViewOrLContainer = next;
|
|
7306
7328
|
}
|
|
7307
7329
|
}
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
ngDevMode &&
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7330
|
+
function detachMovedView(declarationContainer, lView) {
|
|
7331
|
+
ngDevMode && assertLContainer(declarationContainer);
|
|
7332
|
+
ngDevMode &&
|
|
7333
|
+
assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
|
|
7334
|
+
const movedViews = declarationContainer[MOVED_VIEWS];
|
|
7335
|
+
const declarationViewIndex = movedViews.indexOf(lView);
|
|
7336
|
+
movedViews.splice(declarationViewIndex, 1);
|
|
7315
7337
|
}
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7338
|
+
/**
|
|
7339
|
+
* A standalone function which destroys an LView,
|
|
7340
|
+
* conducting clean up (e.g. removing listeners, calling onDestroys).
|
|
7341
|
+
*
|
|
7342
|
+
* @param tView The `TView' of the `LView` to be destroyed
|
|
7343
|
+
* @param lView The view to be destroyed.
|
|
7344
|
+
*/
|
|
7345
|
+
function destroyLView(tView, lView) {
|
|
7346
|
+
if (isDestroyed(lView)) {
|
|
7319
7347
|
return;
|
|
7320
7348
|
}
|
|
7321
|
-
const element = getNativeByTNode(tNode, lView);
|
|
7322
7349
|
const renderer = lView[RENDERER];
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
if (tNode.type & 3 /* TNodeType.AnyRNode */) {
|
|
7326
|
-
if (value == null) {
|
|
7327
|
-
renderer.removeAttribute(element, attrName);
|
|
7328
|
-
}
|
|
7329
|
-
else {
|
|
7330
|
-
renderer.setAttribute(element, attrName, debugValue);
|
|
7331
|
-
}
|
|
7332
|
-
}
|
|
7333
|
-
else {
|
|
7334
|
-
const textContent = escapeCommentText(`bindings=${JSON.stringify({ [attrName]: debugValue }, null, 2)}`);
|
|
7335
|
-
renderer.setValue(element, textContent);
|
|
7350
|
+
if (renderer.destroyNode) {
|
|
7351
|
+
applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
|
|
7336
7352
|
}
|
|
7353
|
+
destroyViewTree(lView);
|
|
7337
7354
|
}
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7355
|
+
/**
|
|
7356
|
+
* Calls onDestroys hooks for all directives and pipes in a given view and then removes all
|
|
7357
|
+
* listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
|
|
7358
|
+
* can be propagated to @Output listeners.
|
|
7359
|
+
*
|
|
7360
|
+
* @param tView `TView` for the `LView` to clean up.
|
|
7361
|
+
* @param lView The LView to clean up
|
|
7362
|
+
*/
|
|
7363
|
+
function cleanUpView(tView, lView) {
|
|
7364
|
+
if (isDestroyed(lView)) {
|
|
7341
7365
|
return;
|
|
7342
7366
|
}
|
|
7343
|
-
const
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7367
|
+
const prevConsumer = setActiveConsumer(null);
|
|
7368
|
+
try {
|
|
7369
|
+
// Usually the Attached flag is removed when the view is detached from its parent, however
|
|
7370
|
+
// if it's a root view, the flag won't be unset hence why we're also removing on destroy.
|
|
7371
|
+
lView[FLAGS] &= ~128 /* LViewFlags.Attached */;
|
|
7372
|
+
// Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
|
|
7373
|
+
// runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
|
|
7374
|
+
// We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
|
|
7375
|
+
// This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
|
|
7376
|
+
// really more of an "afterDestroy" hook if you think about it.
|
|
7377
|
+
lView[FLAGS] |= 256 /* LViewFlags.Destroyed */;
|
|
7378
|
+
lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy(lView[REACTIVE_TEMPLATE_CONSUMER]);
|
|
7379
|
+
executeOnDestroys(tView, lView);
|
|
7380
|
+
processCleanups(tView, lView);
|
|
7381
|
+
// For component views only, the local renderer is destroyed at clean up time.
|
|
7382
|
+
if (lView[TVIEW].type === 1 /* TViewType.Component */) {
|
|
7383
|
+
lView[RENDERER].destroy();
|
|
7351
7384
|
}
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7385
|
+
const declarationContainer = lView[DECLARATION_LCONTAINER];
|
|
7386
|
+
// we are dealing with an embedded view that is still inserted into a container
|
|
7387
|
+
if (declarationContainer !== null && isLContainer(lView[PARENT])) {
|
|
7388
|
+
// and this is a projected view
|
|
7389
|
+
if (declarationContainer !== lView[PARENT]) {
|
|
7390
|
+
detachMovedView(declarationContainer, lView);
|
|
7391
|
+
}
|
|
7392
|
+
// For embedded views still attached to a container: remove query result from this view.
|
|
7393
|
+
const lQueries = lView[QUERIES];
|
|
7394
|
+
if (lQueries !== null) {
|
|
7395
|
+
lQueries.detachView(tView);
|
|
7396
|
+
}
|
|
7358
7397
|
}
|
|
7398
|
+
// Unregister the view once everything else has been cleaned up.
|
|
7399
|
+
unregisterLView(lView);
|
|
7400
|
+
}
|
|
7401
|
+
finally {
|
|
7402
|
+
setActiveConsumer(prevConsumer);
|
|
7359
7403
|
}
|
|
7360
7404
|
}
|
|
7361
|
-
/**
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
const
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7405
|
+
/** Removes listeners and unsubscribes from output subscriptions */
|
|
7406
|
+
function processCleanups(tView, lView) {
|
|
7407
|
+
ngDevMode && assertNotReactive(processCleanups.name);
|
|
7408
|
+
const tCleanup = tView.cleanup;
|
|
7409
|
+
const lCleanup = lView[CLEANUP];
|
|
7410
|
+
if (tCleanup !== null) {
|
|
7411
|
+
for (let i = 0; i < tCleanup.length - 1; i += 2) {
|
|
7412
|
+
if (typeof tCleanup[i] === 'string') {
|
|
7413
|
+
// This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i +=
|
|
7414
|
+
// 2 at the end of this block).
|
|
7415
|
+
const targetIdx = tCleanup[i + 3];
|
|
7416
|
+
ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
|
|
7417
|
+
if (targetIdx >= 0) {
|
|
7418
|
+
// Destroy anything whose teardown is a function call (e.g. QueryList, ModelSignal).
|
|
7419
|
+
lCleanup[targetIdx]();
|
|
7420
|
+
}
|
|
7421
|
+
else {
|
|
7422
|
+
// Subscription
|
|
7423
|
+
lCleanup[-targetIdx].unsubscribe();
|
|
7424
|
+
}
|
|
7425
|
+
i += 2;
|
|
7426
|
+
}
|
|
7427
|
+
else {
|
|
7428
|
+
// This is a cleanup function that is grouped with the index of its context
|
|
7429
|
+
const context = lCleanup[tCleanup[i + 1]];
|
|
7430
|
+
tCleanup[i].call(context);
|
|
7431
|
+
}
|
|
7432
|
+
}
|
|
7372
7433
|
}
|
|
7373
|
-
if (
|
|
7374
|
-
|
|
7434
|
+
if (lCleanup !== null) {
|
|
7435
|
+
lView[CLEANUP] = null;
|
|
7375
7436
|
}
|
|
7376
|
-
const
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
const componentView = getComponentLViewByIndex(tNode.index, lView);
|
|
7386
|
-
componentView[CONTEXT] = getNodeInjectable(lView, tView, i, tNode);
|
|
7437
|
+
const destroyHooks = lView[ON_DESTROY_HOOKS];
|
|
7438
|
+
if (destroyHooks !== null) {
|
|
7439
|
+
// Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister
|
|
7440
|
+
// themselves from mutating the array during iteration.
|
|
7441
|
+
lView[ON_DESTROY_HOOKS] = null;
|
|
7442
|
+
for (let i = 0; i < destroyHooks.length; i++) {
|
|
7443
|
+
const destroyHooksFn = destroyHooks[i];
|
|
7444
|
+
ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
|
|
7445
|
+
destroyHooksFn();
|
|
7387
7446
|
}
|
|
7388
7447
|
}
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
try {
|
|
7396
|
-
setSelectedIndex(elementIndex);
|
|
7397
|
-
for (let dirIndex = start; dirIndex < end; dirIndex++) {
|
|
7398
|
-
const def = tView.data[dirIndex];
|
|
7399
|
-
const directive = lView[dirIndex];
|
|
7400
|
-
setCurrentDirectiveIndex(dirIndex);
|
|
7401
|
-
if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
|
|
7402
|
-
invokeHostBindingsInCreationMode(def, directive);
|
|
7403
|
-
}
|
|
7448
|
+
// Destroy effects registered to the view. Many of these will have been processed above.
|
|
7449
|
+
const effects = lView[EFFECTS];
|
|
7450
|
+
if (effects !== null) {
|
|
7451
|
+
lView[EFFECTS] = null;
|
|
7452
|
+
for (const effect of effects) {
|
|
7453
|
+
effect.destroy();
|
|
7404
7454
|
}
|
|
7405
7455
|
}
|
|
7406
|
-
finally {
|
|
7407
|
-
setSelectedIndex(-1);
|
|
7408
|
-
setCurrentDirectiveIndex(currentDirectiveIndex);
|
|
7409
|
-
}
|
|
7410
7456
|
}
|
|
7411
|
-
/**
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
if (registry) {
|
|
7432
|
-
for (let i = 0; i < registry.length; i++) {
|
|
7433
|
-
const def = registry[i];
|
|
7434
|
-
if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
|
|
7435
|
-
matches ??= [];
|
|
7436
|
-
if (isComponentDef(def)) {
|
|
7437
|
-
if (ngDevMode) {
|
|
7438
|
-
assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
|
|
7439
|
-
`Please use a different tag to activate the ${stringify(def.type)} component.`);
|
|
7440
|
-
if (matches.length && isComponentDef(matches[0])) {
|
|
7441
|
-
throwMultipleComponentError(tNode, matches.find(isComponentDef).type, def.type);
|
|
7457
|
+
/** Calls onDestroy hooks for this view */
|
|
7458
|
+
function executeOnDestroys(tView, lView) {
|
|
7459
|
+
ngDevMode && assertNotReactive(executeOnDestroys.name);
|
|
7460
|
+
let destroyHooks;
|
|
7461
|
+
if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
|
|
7462
|
+
for (let i = 0; i < destroyHooks.length; i += 2) {
|
|
7463
|
+
const context = lView[destroyHooks[i]];
|
|
7464
|
+
// Only call the destroy hook if the context has been requested.
|
|
7465
|
+
if (!(context instanceof NodeInjectorFactory)) {
|
|
7466
|
+
const toCall = destroyHooks[i + 1];
|
|
7467
|
+
if (Array.isArray(toCall)) {
|
|
7468
|
+
for (let j = 0; j < toCall.length; j += 2) {
|
|
7469
|
+
const callContext = context[toCall[j]];
|
|
7470
|
+
const hook = toCall[j + 1];
|
|
7471
|
+
profiler(4 /* ProfilerEvent.LifecycleHookStart */, callContext, hook);
|
|
7472
|
+
try {
|
|
7473
|
+
hook.call(callContext);
|
|
7474
|
+
}
|
|
7475
|
+
finally {
|
|
7476
|
+
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, callContext, hook);
|
|
7442
7477
|
}
|
|
7443
7478
|
}
|
|
7444
|
-
matches.unshift(def);
|
|
7445
7479
|
}
|
|
7446
7480
|
else {
|
|
7447
|
-
|
|
7481
|
+
profiler(4 /* ProfilerEvent.LifecycleHookStart */, context, toCall);
|
|
7482
|
+
try {
|
|
7483
|
+
toCall.call(context);
|
|
7484
|
+
}
|
|
7485
|
+
finally {
|
|
7486
|
+
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, context, toCall);
|
|
7487
|
+
}
|
|
7448
7488
|
}
|
|
7449
7489
|
}
|
|
7450
7490
|
}
|
|
7451
7491
|
}
|
|
7452
|
-
return matches;
|
|
7453
7492
|
}
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7493
|
+
/**
|
|
7494
|
+
* Returns a native element if a node can be inserted into the given parent.
|
|
7495
|
+
*
|
|
7496
|
+
* There are two reasons why we may not be able to insert a element immediately.
|
|
7497
|
+
* - Projection: When creating a child content element of a component, we have to skip the
|
|
7498
|
+
* insertion because the content of a component will be projected.
|
|
7499
|
+
* `<component><content>delayed due to projection</content></component>`
|
|
7500
|
+
* - Parent container is disconnected: This can happen when we are inserting a view into
|
|
7501
|
+
* parent container, which itself is disconnected. For example the parent container is part
|
|
7502
|
+
* of a View which has not be inserted or is made for projection but has not been inserted
|
|
7503
|
+
* into destination.
|
|
7504
|
+
*
|
|
7505
|
+
* @param tView: Current `TView`.
|
|
7506
|
+
* @param tNode: `TNode` for which we wish to retrieve render parent.
|
|
7507
|
+
* @param lView: Current `LView`.
|
|
7508
|
+
*/
|
|
7509
|
+
function getParentRElement(tView, tNode, lView) {
|
|
7510
|
+
return getClosestRElement(tView, tNode.parent, lView);
|
|
7463
7511
|
}
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7512
|
+
/**
|
|
7513
|
+
* Get closest `RElement` or `null` if it can't be found.
|
|
7514
|
+
*
|
|
7515
|
+
* If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.
|
|
7516
|
+
* If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).
|
|
7517
|
+
* If `TNode` is `null` then return host `RElement`:
|
|
7518
|
+
* - return `null` if projection
|
|
7519
|
+
* - return `null` if parent container is disconnected (we have no parent.)
|
|
7520
|
+
*
|
|
7521
|
+
* @param tView: Current `TView`.
|
|
7522
|
+
* @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is
|
|
7523
|
+
* needed).
|
|
7524
|
+
* @param lView: Current `LView`.
|
|
7525
|
+
* @returns `null` if the `RElement` can't be determined at this time (no parent / projection)
|
|
7526
|
+
*/
|
|
7527
|
+
function getClosestRElement(tView, tNode, lView) {
|
|
7528
|
+
let parentTNode = tNode;
|
|
7529
|
+
// Skip over element and ICU containers as those are represented by a comment node and
|
|
7530
|
+
// can't be used as a render parent. Also skip let declarations since they don't have a
|
|
7531
|
+
// corresponding DOM node at all.
|
|
7532
|
+
while (parentTNode !== null &&
|
|
7533
|
+
parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */ | 128 /* TNodeType.LetDeclaration */)) {
|
|
7534
|
+
tNode = parentTNode;
|
|
7535
|
+
parentTNode = tNode.parent;
|
|
7536
|
+
}
|
|
7537
|
+
// If the parent tNode is null, then we are inserting across views: either into an embedded view
|
|
7538
|
+
// or a component view.
|
|
7539
|
+
if (parentTNode === null) {
|
|
7540
|
+
// We are inserting a root element of the component view into the component host element and
|
|
7541
|
+
// it should always be eager.
|
|
7542
|
+
return lView[HOST];
|
|
7467
7543
|
}
|
|
7468
7544
|
else {
|
|
7469
|
-
|
|
7470
|
-
|
|
7545
|
+
ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
7546
|
+
if (isComponentHost(parentTNode)) {
|
|
7547
|
+
ngDevMode && assertTNodeForLView(parentTNode, lView);
|
|
7548
|
+
const { encapsulation } = tView.data[parentTNode.directiveStart + parentTNode.componentOffset];
|
|
7549
|
+
// We've got a parent which is an element in the current view. We just need to verify if the
|
|
7550
|
+
// parent element is not a component. Component's content nodes are not inserted immediately
|
|
7551
|
+
// because they will be projected, and so doing insert at this point would be wasteful.
|
|
7552
|
+
// Since the projection would then move it to its final destination. Note that we can't
|
|
7553
|
+
// make this assumption when using the Shadow DOM, because the native projection placeholders
|
|
7554
|
+
// (<content> or <slot>) have to be in place as elements are being inserted.
|
|
7555
|
+
if (encapsulation === ViewEncapsulation.None ||
|
|
7556
|
+
encapsulation === ViewEncapsulation.Emulated) {
|
|
7557
|
+
return null;
|
|
7558
|
+
}
|
|
7559
|
+
}
|
|
7560
|
+
return getNativeByTNode(parentTNode, lView);
|
|
7471
7561
|
}
|
|
7472
7562
|
}
|
|
7473
7563
|
/**
|
|
7474
|
-
*
|
|
7564
|
+
* Find a node in front of which `currentTNode` should be inserted.
|
|
7475
7565
|
*
|
|
7476
|
-
*
|
|
7477
|
-
*
|
|
7478
|
-
*
|
|
7479
|
-
* @param
|
|
7480
|
-
* @param
|
|
7566
|
+
* This method determines the `RNode` in front of which we should insert the `currentRNode`. This
|
|
7567
|
+
* takes `TNode.insertBeforeIndex` into account if i18n code has been invoked.
|
|
7568
|
+
*
|
|
7569
|
+
* @param parentTNode parent `TNode`
|
|
7570
|
+
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
7571
|
+
* @param lView current `LView`
|
|
7481
7572
|
*/
|
|
7482
|
-
function
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7573
|
+
function getInsertInFrontOfRNode(parentTNode, currentTNode, lView) {
|
|
7574
|
+
return _getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView);
|
|
7575
|
+
}
|
|
7576
|
+
/**
|
|
7577
|
+
* Find a node in front of which `currentTNode` should be inserted. (Does not take i18n into
|
|
7578
|
+
* account)
|
|
7579
|
+
*
|
|
7580
|
+
* This method determines the `RNode` in front of which we should insert the `currentRNode`. This
|
|
7581
|
+
* does not take `TNode.insertBeforeIndex` into account.
|
|
7582
|
+
*
|
|
7583
|
+
* @param parentTNode parent `TNode`
|
|
7584
|
+
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
7585
|
+
* @param lView current `LView`
|
|
7586
|
+
*/
|
|
7587
|
+
function getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView) {
|
|
7588
|
+
if (parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */)) {
|
|
7589
|
+
return getNativeByTNode(parentTNode, lView);
|
|
7493
7590
|
}
|
|
7591
|
+
return null;
|
|
7494
7592
|
}
|
|
7495
|
-
///////////////////////////////
|
|
7496
|
-
//// Bindings & interpolations
|
|
7497
|
-
///////////////////////////////
|
|
7498
7593
|
/**
|
|
7499
|
-
*
|
|
7594
|
+
* Tree shakable boundary for `getInsertInFrontOfRNodeWithI18n` function.
|
|
7500
7595
|
*
|
|
7501
|
-
*
|
|
7502
|
-
|
|
7503
|
-
|
|
7596
|
+
* This function will only be set if i18n code runs.
|
|
7597
|
+
*/
|
|
7598
|
+
let _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithNoI18n;
|
|
7599
|
+
/**
|
|
7600
|
+
* Tree shakable boundary for `processI18nInsertBefore` function.
|
|
7504
7601
|
*
|
|
7505
|
-
*
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7602
|
+
* This function will only be set if i18n code runs.
|
|
7603
|
+
*/
|
|
7604
|
+
let _processI18nInsertBefore;
|
|
7605
|
+
function setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore) {
|
|
7606
|
+
_getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithI18n;
|
|
7607
|
+
_processI18nInsertBefore = processI18nInsertBefore;
|
|
7608
|
+
}
|
|
7609
|
+
/**
|
|
7610
|
+
* Appends the `child` native node (or a collection of nodes) to the `parent`.
|
|
7512
7611
|
*
|
|
7513
|
-
* @param
|
|
7514
|
-
* @param
|
|
7515
|
-
* @param
|
|
7516
|
-
* @param
|
|
7517
|
-
* @param interpolationParts static interpolation parts (for property interpolations)
|
|
7612
|
+
* @param tView The `TView' to be appended
|
|
7613
|
+
* @param lView The current LView
|
|
7614
|
+
* @param childRNode The native child (or children) that should be appended
|
|
7615
|
+
* @param childTNode The TNode of the child element
|
|
7518
7616
|
*/
|
|
7519
|
-
function
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
if (interpolationParts.length > 0) {
|
|
7529
|
-
bindingMetadata +=
|
|
7530
|
-
INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
|
|
7617
|
+
function appendChild(tView, lView, childRNode, childTNode) {
|
|
7618
|
+
const parentRNode = getParentRElement(tView, childTNode, lView);
|
|
7619
|
+
const renderer = lView[RENDERER];
|
|
7620
|
+
const parentTNode = childTNode.parent || lView[T_HOST];
|
|
7621
|
+
const anchorNode = getInsertInFrontOfRNode(parentTNode, childTNode, lView);
|
|
7622
|
+
if (parentRNode != null) {
|
|
7623
|
+
if (Array.isArray(childRNode)) {
|
|
7624
|
+
for (let i = 0; i < childRNode.length; i++) {
|
|
7625
|
+
nativeAppendOrInsertBefore(renderer, parentRNode, childRNode[i], anchorNode, false);
|
|
7531
7626
|
}
|
|
7532
|
-
|
|
7627
|
+
}
|
|
7628
|
+
else {
|
|
7629
|
+
nativeAppendOrInsertBefore(renderer, parentRNode, childRNode, anchorNode, false);
|
|
7533
7630
|
}
|
|
7534
7631
|
}
|
|
7632
|
+
_processI18nInsertBefore !== undefined &&
|
|
7633
|
+
_processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRNode);
|
|
7535
7634
|
}
|
|
7536
7635
|
/**
|
|
7537
|
-
*
|
|
7538
|
-
*
|
|
7636
|
+
* Returns the first native node for a given LView, starting from the provided TNode.
|
|
7637
|
+
*
|
|
7638
|
+
* Native nodes are returned in the order in which those appear in the native tree (DOM).
|
|
7539
7639
|
*/
|
|
7540
|
-
function
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
}
|
|
7552
|
-
/** Handles an error thrown in an LView. */
|
|
7553
|
-
function handleUncaughtError(lView, error) {
|
|
7554
|
-
const injector = lView[INJECTOR];
|
|
7555
|
-
if (!injector) {
|
|
7556
|
-
return;
|
|
7557
|
-
}
|
|
7558
|
-
const errorHandler = injector.get(INTERNAL_APPLICATION_ERROR_HANDLER, null);
|
|
7559
|
-
errorHandler?.(error);
|
|
7560
|
-
}
|
|
7561
|
-
/**
|
|
7562
|
-
* Set all directive inputs with the specific public name on the node.
|
|
7563
|
-
*
|
|
7564
|
-
* @param tNode TNode on which the input is being set.
|
|
7565
|
-
* @param tView Current TView
|
|
7566
|
-
* @param lView `LView` which contains the directives.
|
|
7567
|
-
* @param publicName Public name of the input being set.
|
|
7568
|
-
* @param value Value to set.
|
|
7569
|
-
*/
|
|
7570
|
-
function setAllInputsForProperty(tNode, tView, lView, publicName, value) {
|
|
7571
|
-
const inputs = tNode.inputs?.[publicName];
|
|
7572
|
-
const hostDirectiveInputs = tNode.hostDirectiveInputs?.[publicName];
|
|
7573
|
-
let hasMatch = false;
|
|
7574
|
-
if (hostDirectiveInputs) {
|
|
7575
|
-
for (let i = 0; i < hostDirectiveInputs.length; i += 2) {
|
|
7576
|
-
const index = hostDirectiveInputs[i];
|
|
7577
|
-
ngDevMode && assertIndexInRange(lView, index);
|
|
7578
|
-
const publicName = hostDirectiveInputs[i + 1];
|
|
7579
|
-
const def = tView.data[index];
|
|
7580
|
-
writeToDirectiveInput(def, lView[index], publicName, value);
|
|
7581
|
-
hasMatch = true;
|
|
7640
|
+
function getFirstNativeNode(lView, tNode) {
|
|
7641
|
+
if (tNode !== null) {
|
|
7642
|
+
ngDevMode &&
|
|
7643
|
+
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ |
|
|
7644
|
+
12 /* TNodeType.AnyContainer */ |
|
|
7645
|
+
32 /* TNodeType.Icu */ |
|
|
7646
|
+
16 /* TNodeType.Projection */ |
|
|
7647
|
+
128 /* TNodeType.LetDeclaration */);
|
|
7648
|
+
const tNodeType = tNode.type;
|
|
7649
|
+
if (tNodeType & 3 /* TNodeType.AnyRNode */) {
|
|
7650
|
+
return getNativeByTNode(tNode, lView);
|
|
7582
7651
|
}
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
for (const index of inputs) {
|
|
7586
|
-
ngDevMode && assertIndexInRange(lView, index);
|
|
7587
|
-
const instance = lView[index];
|
|
7588
|
-
const def = tView.data[index];
|
|
7589
|
-
writeToDirectiveInput(def, instance, publicName, value);
|
|
7590
|
-
hasMatch = true;
|
|
7652
|
+
else if (tNodeType & 4 /* TNodeType.Container */) {
|
|
7653
|
+
return getBeforeNodeForView(-1, lView[tNode.index]);
|
|
7591
7654
|
}
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
* Sets an input value only on a specific directive and its host directives.
|
|
7597
|
-
* @param tNode TNode on which the input is being set.
|
|
7598
|
-
* @param tView Current TView
|
|
7599
|
-
* @param lView `LView` which contains the directives.
|
|
7600
|
-
* @param target Directive on which to set the input.
|
|
7601
|
-
* @param publicName Public name of the input being set.
|
|
7602
|
-
* @param value Value to set.
|
|
7603
|
-
*/
|
|
7604
|
-
function setDirectiveInput(tNode, tView, lView, target, publicName, value) {
|
|
7605
|
-
let hostIndex = null;
|
|
7606
|
-
let hostDirectivesStart = null;
|
|
7607
|
-
let hostDirectivesEnd = null;
|
|
7608
|
-
let hasSet = false;
|
|
7609
|
-
if (ngDevMode && !tNode.directiveToIndex?.has(target.type)) {
|
|
7610
|
-
throw new Error(`Node does not have a directive with type ${target.type.name}`);
|
|
7611
|
-
}
|
|
7612
|
-
const data = tNode.directiveToIndex.get(target.type);
|
|
7613
|
-
if (typeof data === 'number') {
|
|
7614
|
-
hostIndex = data;
|
|
7615
|
-
}
|
|
7616
|
-
else {
|
|
7617
|
-
[hostIndex, hostDirectivesStart, hostDirectivesEnd] = data;
|
|
7618
|
-
}
|
|
7619
|
-
if (hostDirectivesStart !== null &&
|
|
7620
|
-
hostDirectivesEnd !== null &&
|
|
7621
|
-
tNode.hostDirectiveInputs?.hasOwnProperty(publicName)) {
|
|
7622
|
-
const hostDirectiveInputs = tNode.hostDirectiveInputs[publicName];
|
|
7623
|
-
for (let i = 0; i < hostDirectiveInputs.length; i += 2) {
|
|
7624
|
-
const index = hostDirectiveInputs[i];
|
|
7625
|
-
if (index >= hostDirectivesStart && index <= hostDirectivesEnd) {
|
|
7626
|
-
ngDevMode && assertIndexInRange(lView, index);
|
|
7627
|
-
const def = tView.data[index];
|
|
7628
|
-
const hostDirectivePublicName = hostDirectiveInputs[i + 1];
|
|
7629
|
-
writeToDirectiveInput(def, lView[index], hostDirectivePublicName, value);
|
|
7630
|
-
hasSet = true;
|
|
7655
|
+
else if (tNodeType & 8 /* TNodeType.ElementContainer */) {
|
|
7656
|
+
const elIcuContainerChild = tNode.child;
|
|
7657
|
+
if (elIcuContainerChild !== null) {
|
|
7658
|
+
return getFirstNativeNode(lView, elIcuContainerChild);
|
|
7631
7659
|
}
|
|
7632
|
-
else
|
|
7633
|
-
|
|
7634
|
-
|
|
7660
|
+
else {
|
|
7661
|
+
const rNodeOrLContainer = lView[tNode.index];
|
|
7662
|
+
if (isLContainer(rNodeOrLContainer)) {
|
|
7663
|
+
return getBeforeNodeForView(-1, rNodeOrLContainer);
|
|
7664
|
+
}
|
|
7665
|
+
else {
|
|
7666
|
+
return unwrapRNode(rNodeOrLContainer);
|
|
7667
|
+
}
|
|
7635
7668
|
}
|
|
7636
7669
|
}
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
ngDevMode && assertIndexInRange(lView, hostIndex);
|
|
7640
|
-
writeToDirectiveInput(target, lView[hostIndex], publicName, value);
|
|
7641
|
-
hasSet = true;
|
|
7642
|
-
}
|
|
7643
|
-
return hasSet;
|
|
7644
|
-
}
|
|
7645
|
-
|
|
7646
|
-
function renderComponent(hostLView, componentHostIdx) {
|
|
7647
|
-
ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
|
|
7648
|
-
const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
|
|
7649
|
-
const componentTView = componentView[TVIEW];
|
|
7650
|
-
syncViewWithBlueprint(componentTView, componentView);
|
|
7651
|
-
const hostRNode = componentView[HOST];
|
|
7652
|
-
// Populate an LView with hydration info retrieved from the DOM via TransferState.
|
|
7653
|
-
if (hostRNode !== null && componentView[HYDRATION] === null) {
|
|
7654
|
-
componentView[HYDRATION] = retrieveHydrationInfo(hostRNode, componentView[INJECTOR]);
|
|
7655
|
-
}
|
|
7656
|
-
profiler(18 /* ProfilerEvent.ComponentStart */);
|
|
7657
|
-
renderView(componentTView, componentView, componentView[CONTEXT]);
|
|
7658
|
-
profiler(19 /* ProfilerEvent.ComponentEnd */, componentView[CONTEXT]);
|
|
7659
|
-
}
|
|
7660
|
-
/**
|
|
7661
|
-
* Syncs an LView instance with its blueprint if they have gotten out of sync.
|
|
7662
|
-
*
|
|
7663
|
-
* Typically, blueprints and their view instances should always be in sync, so the loop here
|
|
7664
|
-
* will be skipped. However, consider this case of two components side-by-side:
|
|
7665
|
-
*
|
|
7666
|
-
* App template:
|
|
7667
|
-
* ```html
|
|
7668
|
-
* <comp></comp>
|
|
7669
|
-
* <comp></comp>
|
|
7670
|
-
* ```
|
|
7671
|
-
*
|
|
7672
|
-
* The following will happen:
|
|
7673
|
-
* 1. App template begins processing.
|
|
7674
|
-
* 2. First <comp> is matched as a component and its LView is created.
|
|
7675
|
-
* 3. Second <comp> is matched as a component and its LView is created.
|
|
7676
|
-
* 4. App template completes processing, so it's time to check child templates.
|
|
7677
|
-
* 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
|
|
7678
|
-
* 6. Second <comp> template is checked. Its blueprint has been updated by the first
|
|
7679
|
-
* <comp> template, but its LView was created before this update, so it is out of sync.
|
|
7680
|
-
*
|
|
7681
|
-
* Note that embedded views inside ngFor loops will never be out of sync because these views
|
|
7682
|
-
* are processed as soon as they are created.
|
|
7683
|
-
*
|
|
7684
|
-
* @param tView The `TView` that contains the blueprint for syncing
|
|
7685
|
-
* @param lView The view to sync
|
|
7686
|
-
*/
|
|
7687
|
-
function syncViewWithBlueprint(tView, lView) {
|
|
7688
|
-
for (let i = lView.length; i < tView.blueprint.length; i++) {
|
|
7689
|
-
lView.push(tView.blueprint[i]);
|
|
7690
|
-
}
|
|
7691
|
-
}
|
|
7692
|
-
/**
|
|
7693
|
-
* Processes a view in the creation mode. This includes a number of steps in a specific order:
|
|
7694
|
-
* - creating view query functions (if any);
|
|
7695
|
-
* - executing a template function in the creation mode;
|
|
7696
|
-
* - updating static queries (if any);
|
|
7697
|
-
* - creating child components defined in a given view.
|
|
7698
|
-
*/
|
|
7699
|
-
function renderView(tView, lView, context) {
|
|
7700
|
-
ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
|
|
7701
|
-
ngDevMode && assertNotReactive(renderView.name);
|
|
7702
|
-
enterView(lView);
|
|
7703
|
-
try {
|
|
7704
|
-
const viewQuery = tView.viewQuery;
|
|
7705
|
-
if (viewQuery !== null) {
|
|
7706
|
-
executeViewQueryFn(1 /* RenderFlags.Create */, viewQuery, context);
|
|
7707
|
-
}
|
|
7708
|
-
// Execute a template associated with this view, if it exists. A template function might not be
|
|
7709
|
-
// defined for the root component views.
|
|
7710
|
-
const templateFn = tView.template;
|
|
7711
|
-
if (templateFn !== null) {
|
|
7712
|
-
executeTemplate(tView, lView, templateFn, 1 /* RenderFlags.Create */, context);
|
|
7713
|
-
}
|
|
7714
|
-
// This needs to be set before children are processed to support recursive components.
|
|
7715
|
-
// This must be set to false immediately after the first creation run because in an
|
|
7716
|
-
// ngFor loop, all the views will be created together before update mode runs and turns
|
|
7717
|
-
// off firstCreatePass. If we don't set it here, instances will perform directive
|
|
7718
|
-
// matching, etc again and again.
|
|
7719
|
-
if (tView.firstCreatePass) {
|
|
7720
|
-
tView.firstCreatePass = false;
|
|
7721
|
-
}
|
|
7722
|
-
// Mark all queries active in this view as dirty. This is necessary for signal-based queries to
|
|
7723
|
-
// have a clear marking point where we can read query results atomically (for a given view).
|
|
7724
|
-
lView[QUERIES]?.finishViewCreation(tView);
|
|
7725
|
-
// We resolve content queries specifically marked as `static` in creation mode. Dynamic
|
|
7726
|
-
// content queries are resolved during change detection (i.e. update mode), after embedded
|
|
7727
|
-
// views are refreshed (see block above).
|
|
7728
|
-
if (tView.staticContentQueries) {
|
|
7729
|
-
refreshContentQueries(tView, lView);
|
|
7730
|
-
}
|
|
7731
|
-
// We must materialize query results before child components are processed
|
|
7732
|
-
// in case a child component has projected a container. The LContainer needs
|
|
7733
|
-
// to exist so the embedded views are properly attached by the container.
|
|
7734
|
-
if (tView.staticViewQueries) {
|
|
7735
|
-
executeViewQueryFn(2 /* RenderFlags.Update */, tView.viewQuery, context);
|
|
7736
|
-
}
|
|
7737
|
-
// Render child component views.
|
|
7738
|
-
const components = tView.components;
|
|
7739
|
-
if (components !== null) {
|
|
7740
|
-
renderChildComponents(lView, components);
|
|
7741
|
-
}
|
|
7742
|
-
}
|
|
7743
|
-
catch (error) {
|
|
7744
|
-
// If we didn't manage to get past the first template pass due to
|
|
7745
|
-
// an error, mark the view as corrupted so we can try to recover.
|
|
7746
|
-
if (tView.firstCreatePass) {
|
|
7747
|
-
tView.incompleteFirstPass = true;
|
|
7748
|
-
tView.firstCreatePass = false;
|
|
7749
|
-
}
|
|
7750
|
-
throw error;
|
|
7751
|
-
}
|
|
7752
|
-
finally {
|
|
7753
|
-
lView[FLAGS] &= ~4 /* LViewFlags.CreationMode */;
|
|
7754
|
-
leaveView();
|
|
7755
|
-
}
|
|
7756
|
-
}
|
|
7757
|
-
/** Renders child components in the current view (creation mode). */
|
|
7758
|
-
function renderChildComponents(hostLView, components) {
|
|
7759
|
-
for (let i = 0; i < components.length; i++) {
|
|
7760
|
-
renderComponent(hostLView, components[i]);
|
|
7761
|
-
}
|
|
7762
|
-
}
|
|
7763
|
-
|
|
7764
|
-
function createAndRenderEmbeddedLView(declarationLView, templateTNode, context, options) {
|
|
7765
|
-
const prevConsumer = setActiveConsumer(null);
|
|
7766
|
-
try {
|
|
7767
|
-
const embeddedTView = templateTNode.tView;
|
|
7768
|
-
ngDevMode && assertDefined(embeddedTView, 'TView must be defined for a template node.');
|
|
7769
|
-
ngDevMode && assertTNodeForLView(templateTNode, declarationLView);
|
|
7770
|
-
// Embedded views follow the change detection strategy of the view they're declared in.
|
|
7771
|
-
const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
7772
|
-
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
7773
|
-
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, options?.injector ?? null, options?.embeddedViewInjector ?? null, options?.dehydratedView ?? null);
|
|
7774
|
-
const declarationLContainer = declarationLView[templateTNode.index];
|
|
7775
|
-
ngDevMode && assertLContainer(declarationLContainer);
|
|
7776
|
-
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
7777
|
-
const declarationViewLQueries = declarationLView[QUERIES];
|
|
7778
|
-
if (declarationViewLQueries !== null) {
|
|
7779
|
-
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
|
|
7780
|
-
}
|
|
7781
|
-
// execute creation mode of a view
|
|
7782
|
-
renderView(embeddedTView, embeddedLView, context);
|
|
7783
|
-
return embeddedLView;
|
|
7784
|
-
}
|
|
7785
|
-
finally {
|
|
7786
|
-
setActiveConsumer(prevConsumer);
|
|
7787
|
-
}
|
|
7788
|
-
}
|
|
7789
|
-
/**
|
|
7790
|
-
* Returns whether an elements that belong to a view should be
|
|
7791
|
-
* inserted into the DOM. For client-only cases, DOM elements are
|
|
7792
|
-
* always inserted. For hydration cases, we check whether serialized
|
|
7793
|
-
* info is available for a view and the view is not in a "skip hydration"
|
|
7794
|
-
* block (in which case view contents was re-created, thus needing insertion).
|
|
7795
|
-
*/
|
|
7796
|
-
function shouldAddViewToDom(tNode, dehydratedView) {
|
|
7797
|
-
return (!dehydratedView || dehydratedView.firstChild === null || hasInSkipHydrationBlockFlag(tNode));
|
|
7798
|
-
}
|
|
7799
|
-
|
|
7800
|
-
const USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT = false;
|
|
7801
|
-
const UseExhaustiveCheckNoChanges = new InjectionToken(ngDevMode ? 'exhaustive checkNoChanges' : '');
|
|
7802
|
-
|
|
7803
|
-
let _icuContainerIterate;
|
|
7804
|
-
/**
|
|
7805
|
-
* Iterator which provides ability to visit all of the `TIcuContainerNode` root `RNode`s.
|
|
7806
|
-
*/
|
|
7807
|
-
function icuContainerIterate(tIcuContainerNode, lView) {
|
|
7808
|
-
return _icuContainerIterate(tIcuContainerNode, lView);
|
|
7809
|
-
}
|
|
7810
|
-
/**
|
|
7811
|
-
* Ensures that `IcuContainerVisitor`'s implementation is present.
|
|
7812
|
-
*
|
|
7813
|
-
* This function is invoked when i18n instruction comes across an ICU. The purpose is to allow the
|
|
7814
|
-
* bundler to tree shake ICU logic and only load it if ICU instruction is executed.
|
|
7815
|
-
*/
|
|
7816
|
-
function ensureIcuContainerVisitorLoaded(loader) {
|
|
7817
|
-
if (_icuContainerIterate === undefined) {
|
|
7818
|
-
// Do not inline this function. We want to keep `ensureIcuContainerVisitorLoaded` light, so it
|
|
7819
|
-
// can be inlined into call-site.
|
|
7820
|
-
_icuContainerIterate = loader();
|
|
7821
|
-
}
|
|
7822
|
-
}
|
|
7823
|
-
|
|
7824
|
-
/**
|
|
7825
|
-
* Flags for renderer-specific style modifiers.
|
|
7826
|
-
* @publicApi
|
|
7827
|
-
*/
|
|
7828
|
-
var RendererStyleFlags2;
|
|
7829
|
-
(function (RendererStyleFlags2) {
|
|
7830
|
-
// TODO(misko): This needs to be refactored into a separate file so that it can be imported from
|
|
7831
|
-
// `node_manipulation.ts` Currently doing the import cause resolution order to change and fails
|
|
7832
|
-
// the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.
|
|
7833
|
-
/**
|
|
7834
|
-
* Marks a style as important.
|
|
7835
|
-
*/
|
|
7836
|
-
RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
|
|
7837
|
-
/**
|
|
7838
|
-
* Marks a style as using dash case naming (this-is-dash-case).
|
|
7839
|
-
*/
|
|
7840
|
-
RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
|
|
7841
|
-
})(RendererStyleFlags2 || (RendererStyleFlags2 = {}));
|
|
7842
|
-
|
|
7843
|
-
/**
|
|
7844
|
-
* Checks whether a TNode is considered detached, i.e. not present in the
|
|
7845
|
-
* translated i18n template. We should not attempt hydration for such nodes
|
|
7846
|
-
* and instead, use a regular "creation mode".
|
|
7847
|
-
*/
|
|
7848
|
-
function isDetachedByI18n(tNode) {
|
|
7849
|
-
return (tNode.flags & 32 /* TNodeFlags.isDetached */) === 32 /* TNodeFlags.isDetached */;
|
|
7850
|
-
}
|
|
7851
|
-
|
|
7852
|
-
/**
|
|
7853
|
-
* NOTE: for performance reasons, the possible actions are inlined within the function instead of
|
|
7854
|
-
* being passed as an argument.
|
|
7855
|
-
*/
|
|
7856
|
-
function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
|
|
7857
|
-
// If this slot was allocated for a text node dynamically created by i18n, the text node itself
|
|
7858
|
-
// won't be created until i18nApply() in the update block, so this node should be skipped.
|
|
7859
|
-
// For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
|
|
7860
|
-
// in `i18n_spec.ts`.
|
|
7861
|
-
if (lNodeToHandle != null) {
|
|
7862
|
-
let lContainer;
|
|
7863
|
-
let isComponent = false;
|
|
7864
|
-
// We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
|
|
7865
|
-
// wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
|
|
7866
|
-
// it has LContainer so that we can process all of those cases appropriately.
|
|
7867
|
-
if (isLContainer(lNodeToHandle)) {
|
|
7868
|
-
lContainer = lNodeToHandle;
|
|
7670
|
+
else if (tNodeType & 128 /* TNodeType.LetDeclaration */) {
|
|
7671
|
+
return getFirstNativeNode(lView, tNode.next);
|
|
7869
7672
|
}
|
|
7870
|
-
else if (
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7673
|
+
else if (tNodeType & 32 /* TNodeType.Icu */) {
|
|
7674
|
+
let nextRNode = icuContainerIterate(tNode, lView);
|
|
7675
|
+
let rNode = nextRNode();
|
|
7676
|
+
// If the ICU container has no nodes, than we use the ICU anchor as the node.
|
|
7677
|
+
return rNode || unwrapRNode(lView[tNode.index]);
|
|
7874
7678
|
}
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
if (
|
|
7878
|
-
|
|
7679
|
+
else {
|
|
7680
|
+
const projectionNodes = getProjectionNodes(lView, tNode);
|
|
7681
|
+
if (projectionNodes !== null) {
|
|
7682
|
+
if (Array.isArray(projectionNodes)) {
|
|
7683
|
+
return projectionNodes[0];
|
|
7684
|
+
}
|
|
7685
|
+
const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
|
|
7686
|
+
ngDevMode && assertParentView(parentView);
|
|
7687
|
+
return getFirstNativeNode(parentView, projectionNodes);
|
|
7879
7688
|
}
|
|
7880
7689
|
else {
|
|
7881
|
-
|
|
7690
|
+
return getFirstNativeNode(lView, tNode.next);
|
|
7882
7691
|
}
|
|
7883
7692
|
}
|
|
7884
|
-
|
|
7885
|
-
|
|
7693
|
+
}
|
|
7694
|
+
return null;
|
|
7695
|
+
}
|
|
7696
|
+
function getProjectionNodes(lView, tNode) {
|
|
7697
|
+
if (tNode !== null) {
|
|
7698
|
+
const componentView = lView[DECLARATION_COMPONENT_VIEW];
|
|
7699
|
+
const componentHost = componentView[T_HOST];
|
|
7700
|
+
const slotIdx = tNode.projection;
|
|
7701
|
+
ngDevMode && assertProjectionSlots(lView);
|
|
7702
|
+
return componentHost.projection[slotIdx];
|
|
7703
|
+
}
|
|
7704
|
+
return null;
|
|
7705
|
+
}
|
|
7706
|
+
function getBeforeNodeForView(viewIndexInContainer, lContainer) {
|
|
7707
|
+
const nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
|
|
7708
|
+
if (nextViewIndex < lContainer.length) {
|
|
7709
|
+
const lView = lContainer[nextViewIndex];
|
|
7710
|
+
const firstTNodeOfView = lView[TVIEW].firstChild;
|
|
7711
|
+
if (firstTNodeOfView !== null) {
|
|
7712
|
+
return getFirstNativeNode(lView, firstTNodeOfView);
|
|
7886
7713
|
}
|
|
7887
|
-
|
|
7888
|
-
|
|
7714
|
+
}
|
|
7715
|
+
return lContainer[NATIVE];
|
|
7716
|
+
}
|
|
7717
|
+
/**
|
|
7718
|
+
* Performs the operation of `action` on the node. Typically this involves inserting or removing
|
|
7719
|
+
* nodes on the LView or projection boundary.
|
|
7720
|
+
*/
|
|
7721
|
+
function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
|
|
7722
|
+
while (tNode != null) {
|
|
7723
|
+
ngDevMode && assertTNodeForLView(tNode, lView);
|
|
7724
|
+
// Let declarations don't have corresponding DOM nodes so we skip over them.
|
|
7725
|
+
if (tNode.type === 128 /* TNodeType.LetDeclaration */) {
|
|
7726
|
+
tNode = tNode.next;
|
|
7727
|
+
continue;
|
|
7889
7728
|
}
|
|
7890
|
-
|
|
7891
|
-
|
|
7729
|
+
ngDevMode &&
|
|
7730
|
+
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
|
|
7731
|
+
const rawSlotValue = lView[tNode.index];
|
|
7732
|
+
const tNodeType = tNode.type;
|
|
7733
|
+
if (isProjection) {
|
|
7734
|
+
if (action === 0 /* WalkTNodeTreeAction.Create */) {
|
|
7735
|
+
rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
|
|
7736
|
+
tNode.flags |= 2 /* TNodeFlags.isProjected */;
|
|
7737
|
+
}
|
|
7892
7738
|
}
|
|
7893
|
-
if (
|
|
7894
|
-
|
|
7739
|
+
if (!isDetachedByI18n(tNode)) {
|
|
7740
|
+
if (tNodeType & 8 /* TNodeType.ElementContainer */) {
|
|
7741
|
+
applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
|
|
7742
|
+
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
7743
|
+
}
|
|
7744
|
+
else if (tNodeType & 32 /* TNodeType.Icu */) {
|
|
7745
|
+
const nextRNode = icuContainerIterate(tNode, lView);
|
|
7746
|
+
let rNode;
|
|
7747
|
+
while ((rNode = nextRNode())) {
|
|
7748
|
+
applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
|
|
7749
|
+
}
|
|
7750
|
+
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
7751
|
+
}
|
|
7752
|
+
else if (tNodeType & 16 /* TNodeType.Projection */) {
|
|
7753
|
+
applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
|
|
7754
|
+
}
|
|
7755
|
+
else {
|
|
7756
|
+
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
7757
|
+
applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
|
|
7758
|
+
}
|
|
7895
7759
|
}
|
|
7760
|
+
tNode = isProjection ? tNode.projectionNext : tNode.next;
|
|
7896
7761
|
}
|
|
7897
7762
|
}
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
*
|
|
7901
|
-
* Because some root nodes of the view may be containers, we sometimes need
|
|
7902
|
-
* to propagate deeply into the nested containers to remove all elements in the
|
|
7903
|
-
* views beneath it.
|
|
7904
|
-
*
|
|
7905
|
-
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
7906
|
-
* @param lView The view from which elements should be added or removed
|
|
7907
|
-
*/
|
|
7908
|
-
function removeViewFromDOM(tView, lView) {
|
|
7909
|
-
detachViewFromDOM(tView, lView);
|
|
7910
|
-
lView[HOST] = null;
|
|
7911
|
-
lView[T_HOST] = null;
|
|
7763
|
+
function applyView(tView, lView, renderer, action, parentRElement, beforeNode) {
|
|
7764
|
+
applyNodes(renderer, action, tView.firstChild, lView, parentRElement, beforeNode, false);
|
|
7912
7765
|
}
|
|
7913
7766
|
/**
|
|
7914
|
-
*
|
|
7915
|
-
*
|
|
7916
|
-
* Because some root nodes of the view may be containers, we sometimes need
|
|
7917
|
-
* to propagate deeply into the nested containers to add all elements in the
|
|
7918
|
-
* views beneath it.
|
|
7767
|
+
* `applyProjection` performs operation on the projection.
|
|
7919
7768
|
*
|
|
7920
|
-
*
|
|
7921
|
-
*
|
|
7922
|
-
* @param renderer Current renderer to use for DOM manipulations.
|
|
7923
|
-
* @param lView The view from which elements should be added or removed
|
|
7924
|
-
* @param parentNativeNode The parent `RElement` where it should be inserted into.
|
|
7925
|
-
* @param beforeNode The node before which elements should be added, if insert mode
|
|
7926
|
-
*/
|
|
7927
|
-
function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
|
|
7928
|
-
lView[HOST] = parentNativeNode;
|
|
7929
|
-
lView[T_HOST] = parentTNode;
|
|
7930
|
-
applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
|
|
7931
|
-
}
|
|
7932
|
-
/**
|
|
7933
|
-
* Detach a `LView` from the DOM by detaching its nodes.
|
|
7769
|
+
* Inserting a projection requires us to locate the projected nodes from the parent component. The
|
|
7770
|
+
* complication is that those nodes themselves could be re-projected from their parent component.
|
|
7934
7771
|
*
|
|
7935
|
-
* @param tView The `TView
|
|
7936
|
-
* @param lView
|
|
7772
|
+
* @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed
|
|
7773
|
+
* @param lView The `LView` which needs to be inserted, detached, destroyed.
|
|
7774
|
+
* @param tProjectionNode node to project
|
|
7937
7775
|
*/
|
|
7938
|
-
function
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7776
|
+
function applyProjection(tView, lView, tProjectionNode) {
|
|
7777
|
+
const renderer = lView[RENDERER];
|
|
7778
|
+
const parentRNode = getParentRElement(tView, tProjectionNode, lView);
|
|
7779
|
+
const parentTNode = tProjectionNode.parent || lView[T_HOST];
|
|
7780
|
+
let beforeNode = getInsertInFrontOfRNode(parentTNode, tProjectionNode, lView);
|
|
7781
|
+
applyProjectionRecursive(renderer, 0 /* WalkTNodeTreeAction.Create */, lView, tProjectionNode, parentRNode, beforeNode);
|
|
7944
7782
|
}
|
|
7945
7783
|
/**
|
|
7946
|
-
*
|
|
7947
|
-
*
|
|
7784
|
+
* `applyProjectionRecursive` performs operation on the projection specified by `action` (insert,
|
|
7785
|
+
* detach, destroy)
|
|
7948
7786
|
*
|
|
7949
|
-
*
|
|
7950
|
-
*
|
|
7951
|
-
* - Must process containers instead of their views to avoid splicing
|
|
7952
|
-
* when views are destroyed and re-added.
|
|
7953
|
-
* - Using a while loop because it's faster than recursion
|
|
7954
|
-
* - Destroy only called on movement to sibling or movement to parent (laterally or up)
|
|
7787
|
+
* Inserting a projection requires us to locate the projected nodes from the parent component. The
|
|
7788
|
+
* complication is that those nodes themselves could be re-projected from their parent component.
|
|
7955
7789
|
*
|
|
7956
|
-
*
|
|
7790
|
+
* @param renderer Render to use
|
|
7791
|
+
* @param action action to perform (insert, detach, destroy)
|
|
7792
|
+
* @param lView The LView which needs to be inserted, detached, destroyed.
|
|
7793
|
+
* @param tProjectionNode node to project
|
|
7794
|
+
* @param parentRElement parent DOM element for insertion/removal.
|
|
7795
|
+
* @param beforeNode Before which node the insertions should happen.
|
|
7957
7796
|
*/
|
|
7958
|
-
function
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
const firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
|
|
7974
|
-
if (firstView)
|
|
7975
|
-
next = firstView;
|
|
7797
|
+
function applyProjectionRecursive(renderer, action, lView, tProjectionNode, parentRElement, beforeNode) {
|
|
7798
|
+
const componentLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
7799
|
+
const componentNode = componentLView[T_HOST];
|
|
7800
|
+
ngDevMode &&
|
|
7801
|
+
assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index');
|
|
7802
|
+
const nodeToProjectOrRNodes = componentNode.projection[tProjectionNode.projection];
|
|
7803
|
+
if (Array.isArray(nodeToProjectOrRNodes)) {
|
|
7804
|
+
// This should not exist, it is a bit of a hack. When we bootstrap a top level node and we
|
|
7805
|
+
// need to support passing projectable nodes, so we cheat and put them in the TNode
|
|
7806
|
+
// of the Host TView. (Yes we put instance info at the T Level). We can get away with it
|
|
7807
|
+
// because we know that TView is not shared and therefore it will not be a problem.
|
|
7808
|
+
// This should be refactored and cleaned up.
|
|
7809
|
+
for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
|
|
7810
|
+
const rNode = nodeToProjectOrRNodes[i];
|
|
7811
|
+
applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
|
|
7976
7812
|
}
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
}
|
|
7986
|
-
if (lViewOrLContainer === null)
|
|
7987
|
-
lViewOrLContainer = rootView;
|
|
7988
|
-
if (isLView(lViewOrLContainer)) {
|
|
7989
|
-
cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
|
|
7990
|
-
}
|
|
7991
|
-
next = lViewOrLContainer && lViewOrLContainer[NEXT];
|
|
7813
|
+
}
|
|
7814
|
+
else {
|
|
7815
|
+
let nodeToProject = nodeToProjectOrRNodes;
|
|
7816
|
+
const projectedComponentLView = componentLView[PARENT];
|
|
7817
|
+
// If a parent <ng-content> is located within a skip hydration block,
|
|
7818
|
+
// annotate an actual node that is being projected with the same flag too.
|
|
7819
|
+
if (hasInSkipHydrationBlockFlag(tProjectionNode)) {
|
|
7820
|
+
nodeToProject.flags |= 128 /* TNodeFlags.inSkipHydrationBlock */;
|
|
7992
7821
|
}
|
|
7993
|
-
|
|
7822
|
+
applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
|
|
7994
7823
|
}
|
|
7995
7824
|
}
|
|
7996
|
-
function detachMovedView(declarationContainer, lView) {
|
|
7997
|
-
ngDevMode && assertLContainer(declarationContainer);
|
|
7998
|
-
ngDevMode &&
|
|
7999
|
-
assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
|
|
8000
|
-
const movedViews = declarationContainer[MOVED_VIEWS];
|
|
8001
|
-
const declarationViewIndex = movedViews.indexOf(lView);
|
|
8002
|
-
movedViews.splice(declarationViewIndex, 1);
|
|
8003
|
-
}
|
|
8004
7825
|
/**
|
|
8005
|
-
*
|
|
8006
|
-
*
|
|
7826
|
+
* `applyContainer` performs an operation on the container and its views as specified by
|
|
7827
|
+
* `action` (insert, detach, destroy)
|
|
8007
7828
|
*
|
|
8008
|
-
*
|
|
8009
|
-
*
|
|
7829
|
+
* Inserting a Container is complicated by the fact that the container may have Views which
|
|
7830
|
+
* themselves have containers or projections.
|
|
7831
|
+
*
|
|
7832
|
+
* @param renderer Renderer to use
|
|
7833
|
+
* @param action action to perform (insert, detach, destroy)
|
|
7834
|
+
* @param lContainer The LContainer which needs to be inserted, detached, destroyed.
|
|
7835
|
+
* @param parentRElement parent DOM element for insertion/removal.
|
|
7836
|
+
* @param beforeNode Before which node the insertions should happen.
|
|
8010
7837
|
*/
|
|
8011
|
-
function
|
|
8012
|
-
|
|
8013
|
-
|
|
7838
|
+
function applyContainer(renderer, action, lContainer, parentRElement, beforeNode) {
|
|
7839
|
+
ngDevMode && assertLContainer(lContainer);
|
|
7840
|
+
const anchor = lContainer[NATIVE]; // LContainer has its own before node.
|
|
7841
|
+
const native = unwrapRNode(lContainer);
|
|
7842
|
+
// An LContainer can be created dynamically on any node by injecting ViewContainerRef.
|
|
7843
|
+
// Asking for a ViewContainerRef on an element will result in a creation of a separate anchor
|
|
7844
|
+
// node (comment in the DOM) that will be different from the LContainer's host node. In this
|
|
7845
|
+
// particular case we need to execute action on 2 nodes:
|
|
7846
|
+
// - container's host node (this is done in the executeActionOnElementOrContainer)
|
|
7847
|
+
// - container's host node (this is done here)
|
|
7848
|
+
if (anchor !== native) {
|
|
7849
|
+
// This is very strange to me (Misko). I would expect that the native is same as anchor. I
|
|
7850
|
+
// don't see a reason why they should be different, but they are.
|
|
7851
|
+
//
|
|
7852
|
+
// If they are we need to process the second anchor as well.
|
|
7853
|
+
applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
|
|
8014
7854
|
}
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
applyView(
|
|
7855
|
+
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
7856
|
+
const lView = lContainer[i];
|
|
7857
|
+
applyView(lView[TVIEW], lView, renderer, action, parentRElement, anchor);
|
|
8018
7858
|
}
|
|
8019
|
-
destroyViewTree(lView);
|
|
8020
7859
|
}
|
|
8021
7860
|
/**
|
|
8022
|
-
*
|
|
8023
|
-
* listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
|
|
8024
|
-
* can be propagated to @Output listeners.
|
|
7861
|
+
* Writes class/style to element.
|
|
8025
7862
|
*
|
|
8026
|
-
* @param
|
|
8027
|
-
* @param
|
|
7863
|
+
* @param renderer Renderer to use.
|
|
7864
|
+
* @param isClassBased `true` if it should be written to `class` (`false` to write to `style`)
|
|
7865
|
+
* @param rNode The Node to write to.
|
|
7866
|
+
* @param prop Property to write to. This would be the class/style name.
|
|
7867
|
+
* @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
|
|
7868
|
+
* otherwise).
|
|
8028
7869
|
*/
|
|
8029
|
-
function
|
|
8030
|
-
if (
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
try {
|
|
8035
|
-
// Usually the Attached flag is removed when the view is detached from its parent, however
|
|
8036
|
-
// if it's a root view, the flag won't be unset hence why we're also removing on destroy.
|
|
8037
|
-
lView[FLAGS] &= ~128 /* LViewFlags.Attached */;
|
|
8038
|
-
// Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
|
|
8039
|
-
// runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
|
|
8040
|
-
// We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
|
|
8041
|
-
// This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
|
|
8042
|
-
// really more of an "afterDestroy" hook if you think about it.
|
|
8043
|
-
lView[FLAGS] |= 256 /* LViewFlags.Destroyed */;
|
|
8044
|
-
lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy(lView[REACTIVE_TEMPLATE_CONSUMER]);
|
|
8045
|
-
executeOnDestroys(tView, lView);
|
|
8046
|
-
processCleanups(tView, lView);
|
|
8047
|
-
// For component views only, the local renderer is destroyed at clean up time.
|
|
8048
|
-
if (lView[TVIEW].type === 1 /* TViewType.Component */) {
|
|
8049
|
-
lView[RENDERER].destroy();
|
|
8050
|
-
}
|
|
8051
|
-
const declarationContainer = lView[DECLARATION_LCONTAINER];
|
|
8052
|
-
// we are dealing with an embedded view that is still inserted into a container
|
|
8053
|
-
if (declarationContainer !== null && isLContainer(lView[PARENT])) {
|
|
8054
|
-
// and this is a projected view
|
|
8055
|
-
if (declarationContainer !== lView[PARENT]) {
|
|
8056
|
-
detachMovedView(declarationContainer, lView);
|
|
8057
|
-
}
|
|
8058
|
-
// For embedded views still attached to a container: remove query result from this view.
|
|
8059
|
-
const lQueries = lView[QUERIES];
|
|
8060
|
-
if (lQueries !== null) {
|
|
8061
|
-
lQueries.detachView(tView);
|
|
8062
|
-
}
|
|
7870
|
+
function applyStyling(renderer, isClassBased, rNode, prop, value) {
|
|
7871
|
+
if (isClassBased) {
|
|
7872
|
+
// We actually want JS true/false here because any truthy value should add the class
|
|
7873
|
+
if (!value) {
|
|
7874
|
+
renderer.removeClass(rNode, prop);
|
|
8063
7875
|
}
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
}
|
|
8067
|
-
finally {
|
|
8068
|
-
setActiveConsumer(prevConsumer);
|
|
8069
|
-
}
|
|
8070
|
-
}
|
|
8071
|
-
/** Removes listeners and unsubscribes from output subscriptions */
|
|
8072
|
-
function processCleanups(tView, lView) {
|
|
8073
|
-
ngDevMode && assertNotReactive(processCleanups.name);
|
|
8074
|
-
const tCleanup = tView.cleanup;
|
|
8075
|
-
const lCleanup = lView[CLEANUP];
|
|
8076
|
-
if (tCleanup !== null) {
|
|
8077
|
-
for (let i = 0; i < tCleanup.length - 1; i += 2) {
|
|
8078
|
-
if (typeof tCleanup[i] === 'string') {
|
|
8079
|
-
// This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i +=
|
|
8080
|
-
// 2 at the end of this block).
|
|
8081
|
-
const targetIdx = tCleanup[i + 3];
|
|
8082
|
-
ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
|
|
8083
|
-
if (targetIdx >= 0) {
|
|
8084
|
-
// Destroy anything whose teardown is a function call (e.g. QueryList, ModelSignal).
|
|
8085
|
-
lCleanup[targetIdx]();
|
|
8086
|
-
}
|
|
8087
|
-
else {
|
|
8088
|
-
// Subscription
|
|
8089
|
-
lCleanup[-targetIdx].unsubscribe();
|
|
8090
|
-
}
|
|
8091
|
-
i += 2;
|
|
8092
|
-
}
|
|
8093
|
-
else {
|
|
8094
|
-
// This is a cleanup function that is grouped with the index of its context
|
|
8095
|
-
const context = lCleanup[tCleanup[i + 1]];
|
|
8096
|
-
tCleanup[i].call(context);
|
|
8097
|
-
}
|
|
7876
|
+
else {
|
|
7877
|
+
renderer.addClass(rNode, prop);
|
|
8098
7878
|
}
|
|
8099
7879
|
}
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
if (destroyHooks !== null) {
|
|
8105
|
-
// Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister
|
|
8106
|
-
// themselves from mutating the array during iteration.
|
|
8107
|
-
lView[ON_DESTROY_HOOKS] = null;
|
|
8108
|
-
for (let i = 0; i < destroyHooks.length; i++) {
|
|
8109
|
-
const destroyHooksFn = destroyHooks[i];
|
|
8110
|
-
ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
|
|
8111
|
-
destroyHooksFn();
|
|
7880
|
+
else {
|
|
7881
|
+
let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
|
|
7882
|
+
if (value == null /** || value === undefined */) {
|
|
7883
|
+
renderer.removeStyle(rNode, prop, flags);
|
|
8112
7884
|
}
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
7885
|
+
else {
|
|
7886
|
+
// A value is important if it ends with `!important`. The style
|
|
7887
|
+
// parser strips any semicolons at the end of the value.
|
|
7888
|
+
const isImportant = typeof value === 'string' ? value.endsWith('!important') : false;
|
|
7889
|
+
if (isImportant) {
|
|
7890
|
+
// !important has to be stripped from the value for it to be valid.
|
|
7891
|
+
value = value.slice(0, -10);
|
|
7892
|
+
flags |= RendererStyleFlags2.Important;
|
|
7893
|
+
}
|
|
7894
|
+
renderer.setStyle(rNode, prop, value, flags);
|
|
8120
7895
|
}
|
|
8121
7896
|
}
|
|
8122
7897
|
}
|
|
8123
|
-
|
|
8124
|
-
function
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
//
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
if (Array.isArray(toCall)) {
|
|
8134
|
-
for (let j = 0; j < toCall.length; j += 2) {
|
|
8135
|
-
const callContext = context[toCall[j]];
|
|
8136
|
-
const hook = toCall[j + 1];
|
|
8137
|
-
profiler(4 /* ProfilerEvent.LifecycleHookStart */, callContext, hook);
|
|
8138
|
-
try {
|
|
8139
|
-
hook.call(callContext);
|
|
8140
|
-
}
|
|
8141
|
-
finally {
|
|
8142
|
-
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, callContext, hook);
|
|
8143
|
-
}
|
|
8144
|
-
}
|
|
8145
|
-
}
|
|
8146
|
-
else {
|
|
8147
|
-
profiler(4 /* ProfilerEvent.LifecycleHookStart */, context, toCall);
|
|
8148
|
-
try {
|
|
8149
|
-
toCall.call(context);
|
|
8150
|
-
}
|
|
8151
|
-
finally {
|
|
8152
|
-
profiler(5 /* ProfilerEvent.LifecycleHookEnd */, context, toCall);
|
|
8153
|
-
}
|
|
8154
|
-
}
|
|
8155
|
-
}
|
|
7898
|
+
|
|
7899
|
+
function executeTemplate(tView, lView, templateFn, rf, context) {
|
|
7900
|
+
const prevSelectedIndex = getSelectedIndex();
|
|
7901
|
+
const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
|
|
7902
|
+
try {
|
|
7903
|
+
setSelectedIndex(-1);
|
|
7904
|
+
if (isUpdatePhase && lView.length > HEADER_OFFSET) {
|
|
7905
|
+
// When we're updating, inherently select 0 so we don't
|
|
7906
|
+
// have to generate that instruction for most update blocks.
|
|
7907
|
+
selectIndexInternal(tView, lView, HEADER_OFFSET, !!ngDevMode && isInCheckNoChangesMode());
|
|
8156
7908
|
}
|
|
7909
|
+
const preHookType = isUpdatePhase
|
|
7910
|
+
? 2 /* ProfilerEvent.TemplateUpdateStart */
|
|
7911
|
+
: 0 /* ProfilerEvent.TemplateCreateStart */;
|
|
7912
|
+
profiler(preHookType, context, templateFn);
|
|
7913
|
+
templateFn(rf, context);
|
|
7914
|
+
}
|
|
7915
|
+
finally {
|
|
7916
|
+
setSelectedIndex(prevSelectedIndex);
|
|
7917
|
+
const postHookType = isUpdatePhase
|
|
7918
|
+
? 3 /* ProfilerEvent.TemplateUpdateEnd */
|
|
7919
|
+
: 1 /* ProfilerEvent.TemplateCreateEnd */;
|
|
7920
|
+
profiler(postHookType, context, templateFn);
|
|
8157
7921
|
}
|
|
8158
7922
|
}
|
|
8159
7923
|
/**
|
|
8160
|
-
*
|
|
8161
|
-
*
|
|
8162
|
-
* There are two reasons why we may not be able to insert a element immediately.
|
|
8163
|
-
* - Projection: When creating a child content element of a component, we have to skip the
|
|
8164
|
-
* insertion because the content of a component will be projected.
|
|
8165
|
-
* `<component><content>delayed due to projection</content></component>`
|
|
8166
|
-
* - Parent container is disconnected: This can happen when we are inserting a view into
|
|
8167
|
-
* parent container, which itself is disconnected. For example the parent container is part
|
|
8168
|
-
* of a View which has not be inserted or is made for projection but has not been inserted
|
|
8169
|
-
* into destination.
|
|
8170
|
-
*
|
|
8171
|
-
* @param tView: Current `TView`.
|
|
8172
|
-
* @param tNode: `TNode` for which we wish to retrieve render parent.
|
|
8173
|
-
* @param lView: Current `LView`.
|
|
7924
|
+
* Creates directive instances.
|
|
8174
7925
|
*/
|
|
8175
|
-
function
|
|
8176
|
-
|
|
7926
|
+
function createDirectivesInstances(tView, lView, tNode) {
|
|
7927
|
+
instantiateAllDirectives(tView, lView, tNode);
|
|
7928
|
+
if ((tNode.flags & 64 /* TNodeFlags.hasHostBindings */) === 64 /* TNodeFlags.hasHostBindings */) {
|
|
7929
|
+
invokeDirectivesHostBindings(tView, lView, tNode);
|
|
7930
|
+
}
|
|
8177
7931
|
}
|
|
8178
7932
|
/**
|
|
8179
|
-
*
|
|
8180
|
-
*
|
|
8181
|
-
* If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.
|
|
8182
|
-
* If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).
|
|
8183
|
-
* If `TNode` is `null` then return host `RElement`:
|
|
8184
|
-
* - return `null` if projection
|
|
8185
|
-
* - return `null` if parent container is disconnected (we have no parent.)
|
|
8186
|
-
*
|
|
8187
|
-
* @param tView: Current `TView`.
|
|
8188
|
-
* @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is
|
|
8189
|
-
* needed).
|
|
8190
|
-
* @param lView: Current `LView`.
|
|
8191
|
-
* @returns `null` if the `RElement` can't be determined at this time (no parent / projection)
|
|
7933
|
+
* Takes a list of local names and indices and pushes the resolved local variable values
|
|
7934
|
+
* to LView in the same order as they are loaded in the template with load().
|
|
8192
7935
|
*/
|
|
8193
|
-
function
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
// If the parent tNode is null, then we are inserting across views: either into an embedded view
|
|
8204
|
-
// or a component view.
|
|
8205
|
-
if (parentTNode === null) {
|
|
8206
|
-
// We are inserting a root element of the component view into the component host element and
|
|
8207
|
-
// it should always be eager.
|
|
8208
|
-
return lView[HOST];
|
|
8209
|
-
}
|
|
8210
|
-
else {
|
|
8211
|
-
ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
|
|
8212
|
-
if (isComponentHost(parentTNode)) {
|
|
8213
|
-
ngDevMode && assertTNodeForLView(parentTNode, lView);
|
|
8214
|
-
const { encapsulation } = tView.data[parentTNode.directiveStart + parentTNode.componentOffset];
|
|
8215
|
-
// We've got a parent which is an element in the current view. We just need to verify if the
|
|
8216
|
-
// parent element is not a component. Component's content nodes are not inserted immediately
|
|
8217
|
-
// because they will be projected, and so doing insert at this point would be wasteful.
|
|
8218
|
-
// Since the projection would then move it to its final destination. Note that we can't
|
|
8219
|
-
// make this assumption when using the Shadow DOM, because the native projection placeholders
|
|
8220
|
-
// (<content> or <slot>) have to be in place as elements are being inserted.
|
|
8221
|
-
if (encapsulation === ViewEncapsulation.None ||
|
|
8222
|
-
encapsulation === ViewEncapsulation.Emulated) {
|
|
8223
|
-
return null;
|
|
8224
|
-
}
|
|
7936
|
+
function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNativeByTNode) {
|
|
7937
|
+
const localNames = tNode.localNames;
|
|
7938
|
+
if (localNames !== null) {
|
|
7939
|
+
let localIndex = tNode.index + 1;
|
|
7940
|
+
for (let i = 0; i < localNames.length; i += 2) {
|
|
7941
|
+
const index = localNames[i + 1];
|
|
7942
|
+
const value = index === -1
|
|
7943
|
+
? localRefExtractor(tNode, viewData)
|
|
7944
|
+
: viewData[index];
|
|
7945
|
+
viewData[localIndex++] = value;
|
|
8225
7946
|
}
|
|
8226
|
-
return getNativeByTNode(parentTNode, lView);
|
|
8227
7947
|
}
|
|
8228
7948
|
}
|
|
8229
7949
|
/**
|
|
8230
|
-
*
|
|
7950
|
+
* Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
|
|
8231
7951
|
*
|
|
8232
|
-
*
|
|
8233
|
-
*
|
|
7952
|
+
* @param renderer the renderer used to locate the element.
|
|
7953
|
+
* @param elementOrSelector Render element or CSS selector to locate the element.
|
|
7954
|
+
* @param encapsulation View Encapsulation defined for component that requests host element.
|
|
7955
|
+
* @param injector Root view injector instance.
|
|
7956
|
+
*/
|
|
7957
|
+
function locateHostElement(renderer, elementOrSelector, encapsulation, injector) {
|
|
7958
|
+
// Note: we use default value for the `PRESERVE_HOST_CONTENT` here even though it's a
|
|
7959
|
+
// tree-shakable one (providedIn:'root'). This code path can be triggered during dynamic
|
|
7960
|
+
// component creation (after calling ViewContainerRef.createComponent) when an injector
|
|
7961
|
+
// instance can be provided. The injector instance might be disconnected from the main DI
|
|
7962
|
+
// tree, thus the `PRESERVE_HOST_CONTENT` would not be able to instantiate. In this case, the
|
|
7963
|
+
// default value will be used.
|
|
7964
|
+
const preserveHostContent = injector.get(PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT);
|
|
7965
|
+
// When using native Shadow DOM, do not clear host element to allow native slot
|
|
7966
|
+
// projection.
|
|
7967
|
+
const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation.ShadowDom;
|
|
7968
|
+
const rootElement = renderer.selectRootElement(elementOrSelector, preserveContent);
|
|
7969
|
+
applyRootElementTransform(rootElement);
|
|
7970
|
+
return rootElement;
|
|
7971
|
+
}
|
|
7972
|
+
/**
|
|
7973
|
+
* Applies any root element transformations that are needed. If hydration is enabled,
|
|
7974
|
+
* this will process corrupted text nodes.
|
|
8234
7975
|
*
|
|
8235
|
-
* @param
|
|
8236
|
-
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
8237
|
-
* @param lView current `LView`
|
|
7976
|
+
* @param rootElement the app root HTML Element
|
|
8238
7977
|
*/
|
|
8239
|
-
function
|
|
8240
|
-
|
|
7978
|
+
function applyRootElementTransform(rootElement) {
|
|
7979
|
+
_applyRootElementTransformImpl(rootElement);
|
|
8241
7980
|
}
|
|
8242
7981
|
/**
|
|
8243
|
-
*
|
|
8244
|
-
*
|
|
7982
|
+
* Reference to a function that applies transformations to the root HTML element
|
|
7983
|
+
* of an app. When hydration is enabled, this processes any corrupt text nodes
|
|
7984
|
+
* so they are properly hydratable on the client.
|
|
8245
7985
|
*
|
|
8246
|
-
*
|
|
8247
|
-
|
|
7986
|
+
* @param rootElement the app root HTML Element
|
|
7987
|
+
*/
|
|
7988
|
+
let _applyRootElementTransformImpl = () => null;
|
|
7989
|
+
/**
|
|
7990
|
+
* Processes text node markers before hydration begins. This replaces any special comment
|
|
7991
|
+
* nodes that were added prior to serialization are swapped out to restore proper text
|
|
7992
|
+
* nodes before hydration.
|
|
8248
7993
|
*
|
|
8249
|
-
* @param
|
|
8250
|
-
* @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
|
|
8251
|
-
* @param lView current `LView`
|
|
7994
|
+
* @param rootElement the app root HTML Element
|
|
8252
7995
|
*/
|
|
8253
|
-
function
|
|
8254
|
-
if (
|
|
8255
|
-
|
|
7996
|
+
function applyRootElementTransformImpl(rootElement) {
|
|
7997
|
+
if (hasSkipHydrationAttrOnRElement(rootElement)) {
|
|
7998
|
+
// Handle a situation when the `ngSkipHydration` attribute is applied
|
|
7999
|
+
// to the root node of an application. In this case, we should clear
|
|
8000
|
+
// the contents and render everything from scratch.
|
|
8001
|
+
clearElementContents(rootElement);
|
|
8002
|
+
}
|
|
8003
|
+
else {
|
|
8004
|
+
processTextNodeMarkersBeforeHydration(rootElement);
|
|
8256
8005
|
}
|
|
8257
|
-
return null;
|
|
8258
8006
|
}
|
|
8259
8007
|
/**
|
|
8260
|
-
*
|
|
8261
|
-
*
|
|
8262
|
-
* This function will only be set if i18n code runs.
|
|
8008
|
+
* Sets the implementation for the `applyRootElementTransform` function.
|
|
8263
8009
|
*/
|
|
8264
|
-
|
|
8010
|
+
function enableApplyRootElementTransformImpl() {
|
|
8011
|
+
_applyRootElementTransformImpl = applyRootElementTransformImpl;
|
|
8012
|
+
}
|
|
8265
8013
|
/**
|
|
8266
|
-
*
|
|
8014
|
+
* Mapping between attributes names that don't correspond to their element property names.
|
|
8267
8015
|
*
|
|
8268
|
-
*
|
|
8016
|
+
* Performance note: this function is written as a series of if checks (instead of, say, a property
|
|
8017
|
+
* object lookup) for performance reasons - the series of `if` checks seems to be the fastest way of
|
|
8018
|
+
* mapping property names. Do NOT change without benchmarking.
|
|
8019
|
+
*
|
|
8020
|
+
* Note: this mapping has to be kept in sync with the equally named mapping in the template
|
|
8021
|
+
* type-checking machinery of ngtsc.
|
|
8269
8022
|
*/
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8023
|
+
function mapPropName(name) {
|
|
8024
|
+
if (name === 'class')
|
|
8025
|
+
return 'className';
|
|
8026
|
+
if (name === 'for')
|
|
8027
|
+
return 'htmlFor';
|
|
8028
|
+
if (name === 'formaction')
|
|
8029
|
+
return 'formAction';
|
|
8030
|
+
if (name === 'innerHtml')
|
|
8031
|
+
return 'innerHTML';
|
|
8032
|
+
if (name === 'readonly')
|
|
8033
|
+
return 'readOnly';
|
|
8034
|
+
if (name === 'tabindex')
|
|
8035
|
+
return 'tabIndex';
|
|
8036
|
+
return name;
|
|
8037
|
+
}
|
|
8038
|
+
function setPropertyAndInputs(tNode, lView, propName, value, renderer, sanitizer) {
|
|
8039
|
+
ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
|
8040
|
+
const tView = lView[TVIEW];
|
|
8041
|
+
const hasSetInput = setAllInputsForProperty(tNode, tView, lView, propName, value);
|
|
8042
|
+
if (hasSetInput) {
|
|
8043
|
+
isComponentHost(tNode) && markDirtyIfOnPush(lView, tNode.index);
|
|
8044
|
+
ngDevMode && setNgReflectProperties(lView, tView, tNode, propName, value);
|
|
8045
|
+
return; // Stop propcessing if we've matched at least one input.
|
|
8046
|
+
}
|
|
8047
|
+
setDomProperty(tNode, lView, propName, value, renderer, sanitizer);
|
|
8274
8048
|
}
|
|
8275
8049
|
/**
|
|
8276
|
-
*
|
|
8277
|
-
*
|
|
8278
|
-
* @param
|
|
8279
|
-
* @param
|
|
8280
|
-
* @param
|
|
8281
|
-
* @param
|
|
8050
|
+
* Sets a DOM property on a specific node.
|
|
8051
|
+
* @param tNode TNode on which to set the value.
|
|
8052
|
+
* @param lView View in which the node is located.
|
|
8053
|
+
* @param propName Name of the property.
|
|
8054
|
+
* @param value Value to set on the property.
|
|
8055
|
+
* @param renderer Renderer to use when setting the property.
|
|
8056
|
+
* @param sanitizer Function used to sanitize the value before setting it.
|
|
8282
8057
|
*/
|
|
8283
|
-
function
|
|
8284
|
-
|
|
8058
|
+
function setDomProperty(tNode, lView, propName, value, renderer, sanitizer) {
|
|
8059
|
+
if (tNode.type & 3 /* TNodeType.AnyRNode */) {
|
|
8060
|
+
const element = getNativeByTNode(tNode, lView);
|
|
8061
|
+
propName = mapPropName(propName);
|
|
8062
|
+
if (ngDevMode) {
|
|
8063
|
+
validateAgainstEventProperties(propName);
|
|
8064
|
+
if (!isPropertyValid(element, propName, tNode.value, lView[TVIEW].schemas)) {
|
|
8065
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
8066
|
+
}
|
|
8067
|
+
}
|
|
8068
|
+
// It is assumed that the sanitizer is only added when the compiler determines that the
|
|
8069
|
+
// property is risky, so sanitization can be done without further checks.
|
|
8070
|
+
value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
|
|
8071
|
+
renderer.setProperty(element, propName, value);
|
|
8072
|
+
}
|
|
8073
|
+
else if (tNode.type & 12 /* TNodeType.AnyContainer */) {
|
|
8074
|
+
// If the node is a container and the property didn't
|
|
8075
|
+
// match any of the inputs or schemas we should throw.
|
|
8076
|
+
if (ngDevMode && !matchingSchemas(lView[TVIEW].schemas, tNode.value)) {
|
|
8077
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
8080
|
+
}
|
|
8081
|
+
/** If node is an OnPush component, marks its LView dirty. */
|
|
8082
|
+
function markDirtyIfOnPush(lView, viewIndex) {
|
|
8083
|
+
ngDevMode && assertLView(lView);
|
|
8084
|
+
const childComponentLView = getComponentLViewByIndex(viewIndex, lView);
|
|
8085
|
+
if (!(childComponentLView[FLAGS] & 16 /* LViewFlags.CheckAlways */)) {
|
|
8086
|
+
childComponentLView[FLAGS] |= 64 /* LViewFlags.Dirty */;
|
|
8087
|
+
}
|
|
8088
|
+
}
|
|
8089
|
+
function setNgReflectProperty(lView, tNode, attrName, value) {
|
|
8090
|
+
const environment = lView[ENVIRONMENT];
|
|
8091
|
+
if (!environment.ngReflect) {
|
|
8092
|
+
return;
|
|
8093
|
+
}
|
|
8094
|
+
const element = getNativeByTNode(tNode, lView);
|
|
8285
8095
|
const renderer = lView[RENDERER];
|
|
8286
|
-
|
|
8287
|
-
const
|
|
8288
|
-
if (
|
|
8289
|
-
if (
|
|
8290
|
-
|
|
8291
|
-
|
|
8096
|
+
attrName = normalizeDebugBindingName(attrName);
|
|
8097
|
+
const debugValue = normalizeDebugBindingValue(value);
|
|
8098
|
+
if (tNode.type & 3 /* TNodeType.AnyRNode */) {
|
|
8099
|
+
if (value == null) {
|
|
8100
|
+
renderer.removeAttribute(element, attrName);
|
|
8101
|
+
}
|
|
8102
|
+
else {
|
|
8103
|
+
renderer.setAttribute(element, attrName, debugValue);
|
|
8104
|
+
}
|
|
8105
|
+
}
|
|
8106
|
+
else {
|
|
8107
|
+
const textContent = escapeCommentText(`bindings=${JSON.stringify({ [attrName]: debugValue }, null, 2)}`);
|
|
8108
|
+
renderer.setValue(element, textContent);
|
|
8109
|
+
}
|
|
8110
|
+
}
|
|
8111
|
+
function setNgReflectProperties(lView, tView, tNode, publicName, value) {
|
|
8112
|
+
const environment = lView[ENVIRONMENT];
|
|
8113
|
+
if (!environment.ngReflect || !(tNode.type & (3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */))) {
|
|
8114
|
+
return;
|
|
8115
|
+
}
|
|
8116
|
+
const inputConfig = tNode.inputs?.[publicName];
|
|
8117
|
+
const hostInputConfig = tNode.hostDirectiveInputs?.[publicName];
|
|
8118
|
+
if (hostInputConfig) {
|
|
8119
|
+
for (let i = 0; i < hostInputConfig.length; i += 2) {
|
|
8120
|
+
const index = hostInputConfig[i];
|
|
8121
|
+
const publicName = hostInputConfig[i + 1];
|
|
8122
|
+
const def = tView.data[index];
|
|
8123
|
+
setNgReflectProperty(lView, tNode, def.inputs[publicName][0], value);
|
|
8124
|
+
}
|
|
8125
|
+
}
|
|
8126
|
+
// Note: we set the private name of the input as the reflected property, not the public one.
|
|
8127
|
+
if (inputConfig) {
|
|
8128
|
+
for (const index of inputConfig) {
|
|
8129
|
+
const def = tView.data[index];
|
|
8130
|
+
setNgReflectProperty(lView, tNode, def.inputs[publicName][0], value);
|
|
8131
|
+
}
|
|
8132
|
+
}
|
|
8133
|
+
}
|
|
8134
|
+
/**
|
|
8135
|
+
* Instantiate all the directives that were previously resolved on the current node.
|
|
8136
|
+
*/
|
|
8137
|
+
function instantiateAllDirectives(tView, lView, tNode) {
|
|
8138
|
+
const start = tNode.directiveStart;
|
|
8139
|
+
const end = tNode.directiveEnd;
|
|
8140
|
+
// The component view needs to be created before creating the node injector
|
|
8141
|
+
// since it is used to inject some special symbols like `ChangeDetectorRef`.
|
|
8142
|
+
if (isComponentHost(tNode)) {
|
|
8143
|
+
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
|
|
8144
|
+
createComponentLView(lView, tNode, tView.data[start + tNode.componentOffset]);
|
|
8145
|
+
}
|
|
8146
|
+
if (!tView.firstCreatePass) {
|
|
8147
|
+
getOrCreateNodeInjectorForNode(tNode, lView);
|
|
8148
|
+
}
|
|
8149
|
+
const initialInputs = tNode.initialInputs;
|
|
8150
|
+
for (let i = start; i < end; i++) {
|
|
8151
|
+
const def = tView.data[i];
|
|
8152
|
+
const directive = getNodeInjectable(lView, tView, i, tNode);
|
|
8153
|
+
attachPatchData(directive, lView);
|
|
8154
|
+
if (initialInputs !== null) {
|
|
8155
|
+
setInputsFromAttrs(lView, i - start, directive, def, tNode, initialInputs);
|
|
8156
|
+
}
|
|
8157
|
+
if (isComponentDef(def)) {
|
|
8158
|
+
const componentView = getComponentLViewByIndex(tNode.index, lView);
|
|
8159
|
+
componentView[CONTEXT] = getNodeInjectable(lView, tView, i, tNode);
|
|
8160
|
+
}
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
function invokeDirectivesHostBindings(tView, lView, tNode) {
|
|
8164
|
+
const start = tNode.directiveStart;
|
|
8165
|
+
const end = tNode.directiveEnd;
|
|
8166
|
+
const elementIndex = tNode.index;
|
|
8167
|
+
const currentDirectiveIndex = getCurrentDirectiveIndex();
|
|
8168
|
+
try {
|
|
8169
|
+
setSelectedIndex(elementIndex);
|
|
8170
|
+
for (let dirIndex = start; dirIndex < end; dirIndex++) {
|
|
8171
|
+
const def = tView.data[dirIndex];
|
|
8172
|
+
const directive = lView[dirIndex];
|
|
8173
|
+
setCurrentDirectiveIndex(dirIndex);
|
|
8174
|
+
if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
|
|
8175
|
+
invokeHostBindingsInCreationMode(def, directive);
|
|
8292
8176
|
}
|
|
8293
8177
|
}
|
|
8294
|
-
else {
|
|
8295
|
-
nativeAppendOrInsertBefore(renderer, parentRNode, childRNode, anchorNode, false);
|
|
8296
|
-
}
|
|
8297
8178
|
}
|
|
8298
|
-
|
|
8299
|
-
|
|
8179
|
+
finally {
|
|
8180
|
+
setSelectedIndex(-1);
|
|
8181
|
+
setCurrentDirectiveIndex(currentDirectiveIndex);
|
|
8182
|
+
}
|
|
8300
8183
|
}
|
|
8301
8184
|
/**
|
|
8302
|
-
*
|
|
8185
|
+
* Invoke the host bindings in creation mode.
|
|
8303
8186
|
*
|
|
8304
|
-
*
|
|
8187
|
+
* @param def `DirectiveDef` which may contain the `hostBindings` function.
|
|
8188
|
+
* @param directive Instance of directive.
|
|
8305
8189
|
*/
|
|
8306
|
-
function
|
|
8307
|
-
if (
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
const
|
|
8323
|
-
if (
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
8190
|
+
function invokeHostBindingsInCreationMode(def, directive) {
|
|
8191
|
+
if (def.hostBindings !== null) {
|
|
8192
|
+
def.hostBindings(1 /* RenderFlags.Create */, directive);
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
/**
|
|
8196
|
+
* Matches the current node against all available selectors.
|
|
8197
|
+
* If a component is matched (at most one), it is returned in first position in the array.
|
|
8198
|
+
*/
|
|
8199
|
+
function findDirectiveDefMatches(tView, tNode) {
|
|
8200
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
8201
|
+
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
|
|
8202
|
+
const registry = tView.directiveRegistry;
|
|
8203
|
+
let matches = null;
|
|
8204
|
+
if (registry) {
|
|
8205
|
+
for (let i = 0; i < registry.length; i++) {
|
|
8206
|
+
const def = registry[i];
|
|
8207
|
+
if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
|
|
8208
|
+
matches ??= [];
|
|
8209
|
+
if (isComponentDef(def)) {
|
|
8210
|
+
if (ngDevMode) {
|
|
8211
|
+
assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
|
|
8212
|
+
`Please use a different tag to activate the ${stringify(def.type)} component.`);
|
|
8213
|
+
if (matches.length && isComponentDef(matches[0])) {
|
|
8214
|
+
throwMultipleComponentError(tNode, matches.find(isComponentDef).type, def.type);
|
|
8215
|
+
}
|
|
8216
|
+
}
|
|
8217
|
+
matches.unshift(def);
|
|
8330
8218
|
}
|
|
8331
8219
|
else {
|
|
8332
|
-
|
|
8333
|
-
}
|
|
8334
|
-
}
|
|
8335
|
-
}
|
|
8336
|
-
else if (tNodeType & 128 /* TNodeType.LetDeclaration */) {
|
|
8337
|
-
return getFirstNativeNode(lView, tNode.next);
|
|
8338
|
-
}
|
|
8339
|
-
else if (tNodeType & 32 /* TNodeType.Icu */) {
|
|
8340
|
-
let nextRNode = icuContainerIterate(tNode, lView);
|
|
8341
|
-
let rNode = nextRNode();
|
|
8342
|
-
// If the ICU container has no nodes, than we use the ICU anchor as the node.
|
|
8343
|
-
return rNode || unwrapRNode(lView[tNode.index]);
|
|
8344
|
-
}
|
|
8345
|
-
else {
|
|
8346
|
-
const projectionNodes = getProjectionNodes(lView, tNode);
|
|
8347
|
-
if (projectionNodes !== null) {
|
|
8348
|
-
if (Array.isArray(projectionNodes)) {
|
|
8349
|
-
return projectionNodes[0];
|
|
8220
|
+
matches.push(def);
|
|
8350
8221
|
}
|
|
8351
|
-
const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
|
|
8352
|
-
ngDevMode && assertParentView(parentView);
|
|
8353
|
-
return getFirstNativeNode(parentView, projectionNodes);
|
|
8354
|
-
}
|
|
8355
|
-
else {
|
|
8356
|
-
return getFirstNativeNode(lView, tNode.next);
|
|
8357
8222
|
}
|
|
8358
8223
|
}
|
|
8359
8224
|
}
|
|
8360
|
-
return
|
|
8225
|
+
return matches;
|
|
8361
8226
|
}
|
|
8362
|
-
function
|
|
8363
|
-
if (
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
return componentHost.projection[slotIdx];
|
|
8227
|
+
function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
|
|
8228
|
+
if (ngDevMode) {
|
|
8229
|
+
assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
|
8230
|
+
validateAgainstEventAttributes(name);
|
|
8231
|
+
assertTNodeType(tNode, 2 /* TNodeType.Element */, `Attempted to set attribute \`${name}\` on a container node. ` +
|
|
8232
|
+
`Host bindings are not valid on ng-container or ng-template.`);
|
|
8369
8233
|
}
|
|
8370
|
-
|
|
8234
|
+
const element = getNativeByTNode(tNode, lView);
|
|
8235
|
+
setElementAttribute(lView[RENDERER], element, namespace, tNode.value, name, value, sanitizer);
|
|
8371
8236
|
}
|
|
8372
|
-
function
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
}
|
|
8237
|
+
function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
|
|
8238
|
+
if (value == null) {
|
|
8239
|
+
renderer.removeAttribute(element, name, namespace);
|
|
8240
|
+
}
|
|
8241
|
+
else {
|
|
8242
|
+
const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
|
|
8243
|
+
renderer.setAttribute(element, name, strValue, namespace);
|
|
8380
8244
|
}
|
|
8381
|
-
return lContainer[NATIVE];
|
|
8382
8245
|
}
|
|
8383
8246
|
/**
|
|
8384
|
-
*
|
|
8385
|
-
*
|
|
8247
|
+
* Sets initial input properties on directive instances from attribute data
|
|
8248
|
+
*
|
|
8249
|
+
* @param lView Current LView that is being processed.
|
|
8250
|
+
* @param directiveIndex Index of the directive in directives array
|
|
8251
|
+
* @param instance Instance of the directive on which to set the initial inputs
|
|
8252
|
+
* @param def The directive def that contains the list of inputs
|
|
8253
|
+
* @param tNode The static data for this node
|
|
8386
8254
|
*/
|
|
8387
|
-
function
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
|
|
8397
|
-
const rawSlotValue = lView[tNode.index];
|
|
8398
|
-
const tNodeType = tNode.type;
|
|
8399
|
-
if (isProjection) {
|
|
8400
|
-
if (action === 0 /* WalkTNodeTreeAction.Create */) {
|
|
8401
|
-
rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
|
|
8402
|
-
tNode.flags |= 2 /* TNodeFlags.isProjected */;
|
|
8255
|
+
function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
|
|
8256
|
+
const initialInputs = initialInputData[directiveIndex];
|
|
8257
|
+
if (initialInputs !== null) {
|
|
8258
|
+
for (let i = 0; i < initialInputs.length; i += 2) {
|
|
8259
|
+
const lookupName = initialInputs[i];
|
|
8260
|
+
const value = initialInputs[i + 1];
|
|
8261
|
+
writeToDirectiveInput(def, instance, lookupName, value);
|
|
8262
|
+
if (ngDevMode) {
|
|
8263
|
+
setNgReflectProperty(lView, tNode, def.inputs[lookupName][0], value);
|
|
8403
8264
|
}
|
|
8404
8265
|
}
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8266
|
+
}
|
|
8267
|
+
}
|
|
8268
|
+
/** Shared code between instructions that indicate the start of an element. */
|
|
8269
|
+
function elementLikeStartShared(tNode, lView, index, name, locateOrCreateNativeNode) {
|
|
8270
|
+
const adjustedIndex = HEADER_OFFSET + index;
|
|
8271
|
+
const tView = lView[TVIEW];
|
|
8272
|
+
const native = locateOrCreateNativeNode(tView, lView, tNode, name, index);
|
|
8273
|
+
lView[adjustedIndex] = native;
|
|
8274
|
+
setCurrentTNode(tNode, true);
|
|
8275
|
+
// It's important that this runs before we've instantiated the directives.
|
|
8276
|
+
const isElement = tNode.type === 2 /* TNodeType.Element */;
|
|
8277
|
+
if (isElement) {
|
|
8278
|
+
setupStaticAttributes(lView[RENDERER], native, tNode);
|
|
8279
|
+
// any immediate children of a component or template container must be pre-emptively
|
|
8280
|
+
// monkey-patched with the component view data so that the element can be inspected
|
|
8281
|
+
// later on using any element discovery utility methods (see `element_discovery.ts`)
|
|
8282
|
+
if (getElementDepthCount() === 0 || isDirectiveHost(tNode)) {
|
|
8283
|
+
attachPatchData(native, lView);
|
|
8284
|
+
}
|
|
8285
|
+
increaseElementDepthCount();
|
|
8286
|
+
}
|
|
8287
|
+
else {
|
|
8288
|
+
attachPatchData(native, lView);
|
|
8289
|
+
}
|
|
8290
|
+
if (wasLastNodeCreated() && (!isElement || !isDetachedByI18n(tNode))) {
|
|
8291
|
+
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
8292
|
+
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
8293
|
+
appendChild(tView, lView, native, tNode);
|
|
8294
|
+
}
|
|
8295
|
+
return tNode;
|
|
8296
|
+
}
|
|
8297
|
+
/** Shared code between instructions that indicate the end of an element. */
|
|
8298
|
+
function elementLikeEndShared(tNode) {
|
|
8299
|
+
let currentTNode = tNode;
|
|
8300
|
+
if (isCurrentTNodeParent()) {
|
|
8301
|
+
setCurrentTNodeAsNotParent();
|
|
8302
|
+
}
|
|
8303
|
+
else {
|
|
8304
|
+
ngDevMode && assertHasParent(getCurrentTNode());
|
|
8305
|
+
currentTNode = currentTNode.parent;
|
|
8306
|
+
setCurrentTNode(currentTNode, false);
|
|
8307
|
+
}
|
|
8308
|
+
return currentTNode;
|
|
8309
|
+
}
|
|
8310
|
+
///////////////////////////////
|
|
8311
|
+
//// Bindings & interpolations
|
|
8312
|
+
///////////////////////////////
|
|
8313
|
+
/**
|
|
8314
|
+
* Stores meta-data for a property binding to be used by TestBed's `DebugElement.properties`.
|
|
8315
|
+
*
|
|
8316
|
+
* In order to support TestBed's `DebugElement.properties` we need to save, for each binding:
|
|
8317
|
+
* - a bound property name;
|
|
8318
|
+
* - a static parts of interpolated strings;
|
|
8319
|
+
*
|
|
8320
|
+
* A given property metadata is saved at the binding's index in the `TView.data` (in other words, a
|
|
8321
|
+
* property binding metadata will be stored in `TView.data` at the same index as a bound value in
|
|
8322
|
+
* `LView`). Metadata are represented as `INTERPOLATION_DELIMITER`-delimited string with the
|
|
8323
|
+
* following format:
|
|
8324
|
+
* - `propertyName` for bound properties;
|
|
8325
|
+
* - `propertyName�prefix�interpolation_static_part1�..interpolation_static_partN�suffix` for
|
|
8326
|
+
* interpolated properties.
|
|
8327
|
+
*
|
|
8328
|
+
* @param tData `TData` where meta-data will be saved;
|
|
8329
|
+
* @param tNode `TNode` that is a target of the binding;
|
|
8330
|
+
* @param propertyName bound property name;
|
|
8331
|
+
* @param bindingIndex binding index in `LView`
|
|
8332
|
+
* @param interpolationParts static interpolation parts (for property interpolations)
|
|
8333
|
+
*/
|
|
8334
|
+
function storePropertyBindingMetadata(tData, tNode, propertyName, bindingIndex, ...interpolationParts) {
|
|
8335
|
+
// Binding meta-data are stored only the first time a given property instruction is processed.
|
|
8336
|
+
// Since we don't have a concept of the "first update pass" we need to check for presence of the
|
|
8337
|
+
// binding meta-data to decide if one should be stored (or if was stored already).
|
|
8338
|
+
if (tData[bindingIndex] === null) {
|
|
8339
|
+
if (!tNode.inputs?.[propertyName] && !tNode.hostDirectiveInputs?.[propertyName]) {
|
|
8340
|
+
const propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []);
|
|
8341
|
+
propBindingIdxs.push(bindingIndex);
|
|
8342
|
+
let bindingMetadata = propertyName;
|
|
8343
|
+
if (interpolationParts.length > 0) {
|
|
8344
|
+
bindingMetadata +=
|
|
8345
|
+
INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
|
|
8424
8346
|
}
|
|
8347
|
+
tData[bindingIndex] = bindingMetadata;
|
|
8425
8348
|
}
|
|
8426
|
-
tNode = isProjection ? tNode.projectionNext : tNode.next;
|
|
8427
8349
|
}
|
|
8428
8350
|
}
|
|
8429
|
-
|
|
8430
|
-
|
|
8351
|
+
/**
|
|
8352
|
+
* There are cases where the sub component's renderer needs to be included
|
|
8353
|
+
* instead of the current renderer (see the componentSyntheticHost* instructions).
|
|
8354
|
+
*/
|
|
8355
|
+
function loadComponentRenderer(currentDef, tNode, lView) {
|
|
8356
|
+
// TODO(FW-2043): the `currentDef` is null when host bindings are invoked while creating root
|
|
8357
|
+
// component (see packages/core/src/render3/component.ts). This is not consistent with the process
|
|
8358
|
+
// of creating inner components, when current directive index is available in the state. In order
|
|
8359
|
+
// to avoid relying on current def being `null` (thus special-casing root component creation), the
|
|
8360
|
+
// process of creating root component should be unified with the process of creating inner
|
|
8361
|
+
// components.
|
|
8362
|
+
if (currentDef === null || isComponentDef(currentDef)) {
|
|
8363
|
+
lView = unwrapLView(lView[tNode.index]);
|
|
8364
|
+
}
|
|
8365
|
+
return lView[RENDERER];
|
|
8366
|
+
}
|
|
8367
|
+
/** Handles an error thrown in an LView. */
|
|
8368
|
+
function handleUncaughtError(lView, error) {
|
|
8369
|
+
const injector = lView[INJECTOR];
|
|
8370
|
+
if (!injector) {
|
|
8371
|
+
return;
|
|
8372
|
+
}
|
|
8373
|
+
const errorHandler = injector.get(INTERNAL_APPLICATION_ERROR_HANDLER, null);
|
|
8374
|
+
errorHandler?.(error);
|
|
8431
8375
|
}
|
|
8432
8376
|
/**
|
|
8433
|
-
*
|
|
8434
|
-
*
|
|
8435
|
-
* Inserting a projection requires us to locate the projected nodes from the parent component. The
|
|
8436
|
-
* complication is that those nodes themselves could be re-projected from their parent component.
|
|
8377
|
+
* Set all directive inputs with the specific public name on the node.
|
|
8437
8378
|
*
|
|
8438
|
-
* @param
|
|
8439
|
-
* @param
|
|
8440
|
-
* @param
|
|
8379
|
+
* @param tNode TNode on which the input is being set.
|
|
8380
|
+
* @param tView Current TView
|
|
8381
|
+
* @param lView `LView` which contains the directives.
|
|
8382
|
+
* @param publicName Public name of the input being set.
|
|
8383
|
+
* @param value Value to set.
|
|
8441
8384
|
*/
|
|
8442
|
-
function
|
|
8443
|
-
const
|
|
8444
|
-
const
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8385
|
+
function setAllInputsForProperty(tNode, tView, lView, publicName, value) {
|
|
8386
|
+
const inputs = tNode.inputs?.[publicName];
|
|
8387
|
+
const hostDirectiveInputs = tNode.hostDirectiveInputs?.[publicName];
|
|
8388
|
+
let hasMatch = false;
|
|
8389
|
+
if (hostDirectiveInputs) {
|
|
8390
|
+
for (let i = 0; i < hostDirectiveInputs.length; i += 2) {
|
|
8391
|
+
const index = hostDirectiveInputs[i];
|
|
8392
|
+
ngDevMode && assertIndexInRange(lView, index);
|
|
8393
|
+
const publicName = hostDirectiveInputs[i + 1];
|
|
8394
|
+
const def = tView.data[index];
|
|
8395
|
+
writeToDirectiveInput(def, lView[index], publicName, value);
|
|
8396
|
+
hasMatch = true;
|
|
8397
|
+
}
|
|
8398
|
+
}
|
|
8399
|
+
if (inputs) {
|
|
8400
|
+
for (const index of inputs) {
|
|
8401
|
+
ngDevMode && assertIndexInRange(lView, index);
|
|
8402
|
+
const instance = lView[index];
|
|
8403
|
+
const def = tView.data[index];
|
|
8404
|
+
writeToDirectiveInput(def, instance, publicName, value);
|
|
8405
|
+
hasMatch = true;
|
|
8406
|
+
}
|
|
8407
|
+
}
|
|
8408
|
+
return hasMatch;
|
|
8448
8409
|
}
|
|
8449
8410
|
/**
|
|
8450
|
-
*
|
|
8451
|
-
*
|
|
8452
|
-
*
|
|
8453
|
-
*
|
|
8454
|
-
*
|
|
8455
|
-
*
|
|
8456
|
-
* @param
|
|
8457
|
-
* @param action action to perform (insert, detach, destroy)
|
|
8458
|
-
* @param lView The LView which needs to be inserted, detached, destroyed.
|
|
8459
|
-
* @param tProjectionNode node to project
|
|
8460
|
-
* @param parentRElement parent DOM element for insertion/removal.
|
|
8461
|
-
* @param beforeNode Before which node the insertions should happen.
|
|
8411
|
+
* Sets an input value only on a specific directive and its host directives.
|
|
8412
|
+
* @param tNode TNode on which the input is being set.
|
|
8413
|
+
* @param tView Current TView
|
|
8414
|
+
* @param lView `LView` which contains the directives.
|
|
8415
|
+
* @param target Directive on which to set the input.
|
|
8416
|
+
* @param publicName Public name of the input being set.
|
|
8417
|
+
* @param value Value to set.
|
|
8462
8418
|
*/
|
|
8463
|
-
function
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
// This should be refactored and cleaned up.
|
|
8475
|
-
for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
|
|
8476
|
-
const rNode = nodeToProjectOrRNodes[i];
|
|
8477
|
-
applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
|
|
8478
|
-
}
|
|
8419
|
+
function setDirectiveInput(tNode, tView, lView, target, publicName, value) {
|
|
8420
|
+
let hostIndex = null;
|
|
8421
|
+
let hostDirectivesStart = null;
|
|
8422
|
+
let hostDirectivesEnd = null;
|
|
8423
|
+
let hasSet = false;
|
|
8424
|
+
if (ngDevMode && !tNode.directiveToIndex?.has(target.type)) {
|
|
8425
|
+
throw new Error(`Node does not have a directive with type ${target.type.name}`);
|
|
8426
|
+
}
|
|
8427
|
+
const data = tNode.directiveToIndex.get(target.type);
|
|
8428
|
+
if (typeof data === 'number') {
|
|
8429
|
+
hostIndex = data;
|
|
8479
8430
|
}
|
|
8480
8431
|
else {
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8432
|
+
[hostIndex, hostDirectivesStart, hostDirectivesEnd] = data;
|
|
8433
|
+
}
|
|
8434
|
+
if (hostDirectivesStart !== null &&
|
|
8435
|
+
hostDirectivesEnd !== null &&
|
|
8436
|
+
tNode.hostDirectiveInputs?.hasOwnProperty(publicName)) {
|
|
8437
|
+
const hostDirectiveInputs = tNode.hostDirectiveInputs[publicName];
|
|
8438
|
+
for (let i = 0; i < hostDirectiveInputs.length; i += 2) {
|
|
8439
|
+
const index = hostDirectiveInputs[i];
|
|
8440
|
+
if (index >= hostDirectivesStart && index <= hostDirectivesEnd) {
|
|
8441
|
+
ngDevMode && assertIndexInRange(lView, index);
|
|
8442
|
+
const def = tView.data[index];
|
|
8443
|
+
const hostDirectivePublicName = hostDirectiveInputs[i + 1];
|
|
8444
|
+
writeToDirectiveInput(def, lView[index], hostDirectivePublicName, value);
|
|
8445
|
+
hasSet = true;
|
|
8446
|
+
}
|
|
8447
|
+
else if (index > hostDirectivesEnd) {
|
|
8448
|
+
// Directives here are in ascending order so we can stop looking once we're past the range.
|
|
8449
|
+
break;
|
|
8450
|
+
}
|
|
8487
8451
|
}
|
|
8488
|
-
applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
|
|
8489
8452
|
}
|
|
8453
|
+
if (hostIndex !== null && target.inputs.hasOwnProperty(publicName)) {
|
|
8454
|
+
ngDevMode && assertIndexInRange(lView, hostIndex);
|
|
8455
|
+
writeToDirectiveInput(target, lView[hostIndex], publicName, value);
|
|
8456
|
+
hasSet = true;
|
|
8457
|
+
}
|
|
8458
|
+
return hasSet;
|
|
8459
|
+
}
|
|
8460
|
+
|
|
8461
|
+
function renderComponent(hostLView, componentHostIdx) {
|
|
8462
|
+
ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
|
|
8463
|
+
const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
|
|
8464
|
+
const componentTView = componentView[TVIEW];
|
|
8465
|
+
syncViewWithBlueprint(componentTView, componentView);
|
|
8466
|
+
const hostRNode = componentView[HOST];
|
|
8467
|
+
// Populate an LView with hydration info retrieved from the DOM via TransferState.
|
|
8468
|
+
if (hostRNode !== null && componentView[HYDRATION] === null) {
|
|
8469
|
+
componentView[HYDRATION] = retrieveHydrationInfo(hostRNode, componentView[INJECTOR]);
|
|
8470
|
+
}
|
|
8471
|
+
profiler(18 /* ProfilerEvent.ComponentStart */);
|
|
8472
|
+
renderView(componentTView, componentView, componentView[CONTEXT]);
|
|
8473
|
+
profiler(19 /* ProfilerEvent.ComponentEnd */, componentView[CONTEXT]);
|
|
8490
8474
|
}
|
|
8491
8475
|
/**
|
|
8492
|
-
*
|
|
8493
|
-
* `action` (insert, detach, destroy)
|
|
8476
|
+
* Syncs an LView instance with its blueprint if they have gotten out of sync.
|
|
8494
8477
|
*
|
|
8495
|
-
*
|
|
8496
|
-
*
|
|
8478
|
+
* Typically, blueprints and their view instances should always be in sync, so the loop here
|
|
8479
|
+
* will be skipped. However, consider this case of two components side-by-side:
|
|
8497
8480
|
*
|
|
8498
|
-
*
|
|
8499
|
-
*
|
|
8500
|
-
*
|
|
8501
|
-
*
|
|
8502
|
-
*
|
|
8481
|
+
* App template:
|
|
8482
|
+
* ```html
|
|
8483
|
+
* <comp></comp>
|
|
8484
|
+
* <comp></comp>
|
|
8485
|
+
* ```
|
|
8486
|
+
*
|
|
8487
|
+
* The following will happen:
|
|
8488
|
+
* 1. App template begins processing.
|
|
8489
|
+
* 2. First <comp> is matched as a component and its LView is created.
|
|
8490
|
+
* 3. Second <comp> is matched as a component and its LView is created.
|
|
8491
|
+
* 4. App template completes processing, so it's time to check child templates.
|
|
8492
|
+
* 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
|
|
8493
|
+
* 6. Second <comp> template is checked. Its blueprint has been updated by the first
|
|
8494
|
+
* <comp> template, but its LView was created before this update, so it is out of sync.
|
|
8495
|
+
*
|
|
8496
|
+
* Note that embedded views inside ngFor loops will never be out of sync because these views
|
|
8497
|
+
* are processed as soon as they are created.
|
|
8498
|
+
*
|
|
8499
|
+
* @param tView The `TView` that contains the blueprint for syncing
|
|
8500
|
+
* @param lView The view to sync
|
|
8503
8501
|
*/
|
|
8504
|
-
function
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
const native = unwrapRNode(lContainer);
|
|
8508
|
-
// An LContainer can be created dynamically on any node by injecting ViewContainerRef.
|
|
8509
|
-
// Asking for a ViewContainerRef on an element will result in a creation of a separate anchor
|
|
8510
|
-
// node (comment in the DOM) that will be different from the LContainer's host node. In this
|
|
8511
|
-
// particular case we need to execute action on 2 nodes:
|
|
8512
|
-
// - container's host node (this is done in the executeActionOnElementOrContainer)
|
|
8513
|
-
// - container's host node (this is done here)
|
|
8514
|
-
if (anchor !== native) {
|
|
8515
|
-
// This is very strange to me (Misko). I would expect that the native is same as anchor. I
|
|
8516
|
-
// don't see a reason why they should be different, but they are.
|
|
8517
|
-
//
|
|
8518
|
-
// If they are we need to process the second anchor as well.
|
|
8519
|
-
applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
|
|
8520
|
-
}
|
|
8521
|
-
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
8522
|
-
const lView = lContainer[i];
|
|
8523
|
-
applyView(lView[TVIEW], lView, renderer, action, parentRElement, anchor);
|
|
8502
|
+
function syncViewWithBlueprint(tView, lView) {
|
|
8503
|
+
for (let i = lView.length; i < tView.blueprint.length; i++) {
|
|
8504
|
+
lView.push(tView.blueprint[i]);
|
|
8524
8505
|
}
|
|
8525
8506
|
}
|
|
8526
8507
|
/**
|
|
8527
|
-
*
|
|
8528
|
-
*
|
|
8529
|
-
*
|
|
8530
|
-
*
|
|
8531
|
-
*
|
|
8532
|
-
* @param prop Property to write to. This would be the class/style name.
|
|
8533
|
-
* @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
|
|
8534
|
-
* otherwise).
|
|
8508
|
+
* Processes a view in the creation mode. This includes a number of steps in a specific order:
|
|
8509
|
+
* - creating view query functions (if any);
|
|
8510
|
+
* - executing a template function in the creation mode;
|
|
8511
|
+
* - updating static queries (if any);
|
|
8512
|
+
* - creating child components defined in a given view.
|
|
8535
8513
|
*/
|
|
8536
|
-
function
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8514
|
+
function renderView(tView, lView, context) {
|
|
8515
|
+
ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
|
|
8516
|
+
ngDevMode && assertNotReactive(renderView.name);
|
|
8517
|
+
enterView(lView);
|
|
8518
|
+
try {
|
|
8519
|
+
const viewQuery = tView.viewQuery;
|
|
8520
|
+
if (viewQuery !== null) {
|
|
8521
|
+
executeViewQueryFn(1 /* RenderFlags.Create */, viewQuery, context);
|
|
8522
|
+
}
|
|
8523
|
+
// Execute a template associated with this view, if it exists. A template function might not be
|
|
8524
|
+
// defined for the root component views.
|
|
8525
|
+
const templateFn = tView.template;
|
|
8526
|
+
if (templateFn !== null) {
|
|
8527
|
+
executeTemplate(tView, lView, templateFn, 1 /* RenderFlags.Create */, context);
|
|
8528
|
+
}
|
|
8529
|
+
// This needs to be set before children are processed to support recursive components.
|
|
8530
|
+
// This must be set to false immediately after the first creation run because in an
|
|
8531
|
+
// ngFor loop, all the views will be created together before update mode runs and turns
|
|
8532
|
+
// off firstCreatePass. If we don't set it here, instances will perform directive
|
|
8533
|
+
// matching, etc again and again.
|
|
8534
|
+
if (tView.firstCreatePass) {
|
|
8535
|
+
tView.firstCreatePass = false;
|
|
8536
|
+
}
|
|
8537
|
+
// Mark all queries active in this view as dirty. This is necessary for signal-based queries to
|
|
8538
|
+
// have a clear marking point where we can read query results atomically (for a given view).
|
|
8539
|
+
lView[QUERIES]?.finishViewCreation(tView);
|
|
8540
|
+
// We resolve content queries specifically marked as `static` in creation mode. Dynamic
|
|
8541
|
+
// content queries are resolved during change detection (i.e. update mode), after embedded
|
|
8542
|
+
// views are refreshed (see block above).
|
|
8543
|
+
if (tView.staticContentQueries) {
|
|
8544
|
+
refreshContentQueries(tView, lView);
|
|
8541
8545
|
}
|
|
8542
|
-
|
|
8543
|
-
|
|
8546
|
+
// We must materialize query results before child components are processed
|
|
8547
|
+
// in case a child component has projected a container. The LContainer needs
|
|
8548
|
+
// to exist so the embedded views are properly attached by the container.
|
|
8549
|
+
if (tView.staticViewQueries) {
|
|
8550
|
+
executeViewQueryFn(2 /* RenderFlags.Update */, tView.viewQuery, context);
|
|
8551
|
+
}
|
|
8552
|
+
// Render child component views.
|
|
8553
|
+
const components = tView.components;
|
|
8554
|
+
if (components !== null) {
|
|
8555
|
+
renderChildComponents(lView, components);
|
|
8544
8556
|
}
|
|
8545
8557
|
}
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8558
|
+
catch (error) {
|
|
8559
|
+
// If we didn't manage to get past the first template pass due to
|
|
8560
|
+
// an error, mark the view as corrupted so we can try to recover.
|
|
8561
|
+
if (tView.firstCreatePass) {
|
|
8562
|
+
tView.incompleteFirstPass = true;
|
|
8563
|
+
tView.firstCreatePass = false;
|
|
8550
8564
|
}
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8565
|
+
throw error;
|
|
8566
|
+
}
|
|
8567
|
+
finally {
|
|
8568
|
+
lView[FLAGS] &= ~4 /* LViewFlags.CreationMode */;
|
|
8569
|
+
leaveView();
|
|
8570
|
+
}
|
|
8571
|
+
}
|
|
8572
|
+
/** Renders child components in the current view (creation mode). */
|
|
8573
|
+
function renderChildComponents(hostLView, components) {
|
|
8574
|
+
for (let i = 0; i < components.length; i++) {
|
|
8575
|
+
renderComponent(hostLView, components[i]);
|
|
8576
|
+
}
|
|
8577
|
+
}
|
|
8578
|
+
|
|
8579
|
+
function createAndRenderEmbeddedLView(declarationLView, templateTNode, context, options) {
|
|
8580
|
+
const prevConsumer = setActiveConsumer(null);
|
|
8581
|
+
try {
|
|
8582
|
+
const embeddedTView = templateTNode.tView;
|
|
8583
|
+
ngDevMode && assertDefined(embeddedTView, 'TView must be defined for a template node.');
|
|
8584
|
+
ngDevMode && assertTNodeForLView(templateTNode, declarationLView);
|
|
8585
|
+
// Embedded views follow the change detection strategy of the view they're declared in.
|
|
8586
|
+
const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
8587
|
+
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
8588
|
+
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, options?.injector ?? null, options?.embeddedViewInjector ?? null, options?.dehydratedView ?? null);
|
|
8589
|
+
const declarationLContainer = declarationLView[templateTNode.index];
|
|
8590
|
+
ngDevMode && assertLContainer(declarationLContainer);
|
|
8591
|
+
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
8592
|
+
const declarationViewLQueries = declarationLView[QUERIES];
|
|
8593
|
+
if (declarationViewLQueries !== null) {
|
|
8594
|
+
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
|
|
8561
8595
|
}
|
|
8596
|
+
// execute creation mode of a view
|
|
8597
|
+
renderView(embeddedTView, embeddedLView, context);
|
|
8598
|
+
return embeddedLView;
|
|
8599
|
+
}
|
|
8600
|
+
finally {
|
|
8601
|
+
setActiveConsumer(prevConsumer);
|
|
8562
8602
|
}
|
|
8563
8603
|
}
|
|
8604
|
+
/**
|
|
8605
|
+
* Returns whether an elements that belong to a view should be
|
|
8606
|
+
* inserted into the DOM. For client-only cases, DOM elements are
|
|
8607
|
+
* always inserted. For hydration cases, we check whether serialized
|
|
8608
|
+
* info is available for a view and the view is not in a "skip hydration"
|
|
8609
|
+
* block (in which case view contents was re-created, thus needing insertion).
|
|
8610
|
+
*/
|
|
8611
|
+
function shouldAddViewToDom(tNode, dehydratedView) {
|
|
8612
|
+
return (!dehydratedView || dehydratedView.firstChild === null || hasInSkipHydrationBlockFlag(tNode));
|
|
8613
|
+
}
|
|
8614
|
+
|
|
8615
|
+
const USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT = false;
|
|
8616
|
+
const UseExhaustiveCheckNoChanges = new InjectionToken(ngDevMode ? 'exhaustive checkNoChanges' : '');
|
|
8564
8617
|
|
|
8565
8618
|
function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
|
|
8566
8619
|
while (tNode !== null) {
|
|
@@ -12679,11 +12732,12 @@ function assertNoDuplicateDirectives(directives) {
|
|
|
12679
12732
|
}
|
|
12680
12733
|
}
|
|
12681
12734
|
|
|
12682
|
-
function
|
|
12735
|
+
function directiveHostFirstCreatePass(index, lView, type, name, directiveMatcher, bindingsEnabled, attrsIndex, localRefsIndex) {
|
|
12736
|
+
const tView = lView[TVIEW];
|
|
12683
12737
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12684
12738
|
const tViewConsts = tView.consts;
|
|
12685
12739
|
const attrs = getConstant(tViewConsts, attrsIndex);
|
|
12686
|
-
const tNode = getOrCreateTNode(tView, index,
|
|
12740
|
+
const tNode = getOrCreateTNode(tView, index, type, name, attrs);
|
|
12687
12741
|
if (bindingsEnabled) {
|
|
12688
12742
|
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex), directiveMatcher);
|
|
12689
12743
|
}
|
|
@@ -12700,7 +12754,7 @@ function elementStartFirstCreatePass(index, tView, lView, name, directiveMatcher
|
|
|
12700
12754
|
}
|
|
12701
12755
|
return tNode;
|
|
12702
12756
|
}
|
|
12703
|
-
function
|
|
12757
|
+
function directiveHostEndFirstCreatePass(tView, tNode) {
|
|
12704
12758
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12705
12759
|
registerPostOrderHooks(tView, tNode);
|
|
12706
12760
|
if (isContentQueryHost(tNode)) {
|
|
@@ -13353,7 +13407,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
13353
13407
|
enterView(rootLView);
|
|
13354
13408
|
let componentView = null;
|
|
13355
13409
|
try {
|
|
13356
|
-
const hostTNode =
|
|
13410
|
+
const hostTNode = directiveHostFirstCreatePass(HEADER_OFFSET, rootLView, 2 /* TNodeType.Element */, '#host', () => rootTView.directiveRegistry, true, 0);
|
|
13357
13411
|
// ---- element instruction
|
|
13358
13412
|
// TODO(crisbeto): in practice `hostElement` should always be defined, but there are some
|
|
13359
13413
|
// tests where the renderer is mocked out and `undefined` is returned. We should update the
|
|
@@ -13365,7 +13419,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
13365
13419
|
// TODO(pk): this logic is similar to the instruction code where a node can have directives
|
|
13366
13420
|
createDirectivesInstances(rootTView, rootLView, hostTNode);
|
|
13367
13421
|
executeContentQueries(rootTView, hostTNode, rootLView);
|
|
13368
|
-
|
|
13422
|
+
directiveHostEndFirstCreatePass(rootTView, hostTNode);
|
|
13369
13423
|
if (projectableNodes !== undefined) {
|
|
13370
13424
|
projectNodes(hostTNode, this.ngContentSelectors, projectableNodes);
|
|
13371
13425
|
}
|
|
@@ -13396,7 +13450,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
13396
13450
|
}
|
|
13397
13451
|
function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
|
|
13398
13452
|
const tAttributes = rootSelectorOrNode
|
|
13399
|
-
? ['ng-version', '20.0.
|
|
13453
|
+
? ['ng-version', '20.1.0-next.1']
|
|
13400
13454
|
: // Extract attributes and classes from the first selector only to match VE behavior.
|
|
13401
13455
|
extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
|
|
13402
13456
|
let creationBindings = null;
|
|
@@ -13520,7 +13574,7 @@ class ComponentRef extends ComponentRef$1 {
|
|
|
13520
13574
|
if (ngDevMode && !hasSetInput) {
|
|
13521
13575
|
const cmpNameForError = stringifyForError(this.componentType);
|
|
13522
13576
|
let message = `Can't set value of the '${name}' input on the '${cmpNameForError}' component. `;
|
|
13523
|
-
message += `Make sure that the '${name}' property is
|
|
13577
|
+
message += `Make sure that the '${name}' property is annotated with @Input() or a mapped @Input('${name}') exists.`;
|
|
13524
13578
|
reportUnknownPropertyError(message);
|
|
13525
13579
|
}
|
|
13526
13580
|
}
|
|
@@ -14967,8 +15021,8 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
14967
15021
|
}
|
|
14968
15022
|
initFeatures(def);
|
|
14969
15023
|
const dependencies = componentDefinition.dependencies;
|
|
14970
|
-
def.directiveDefs = extractDefListOrFactory(dependencies,
|
|
14971
|
-
def.pipeDefs = extractDefListOrFactory(dependencies,
|
|
15024
|
+
def.directiveDefs = extractDefListOrFactory(dependencies, extractDirectiveDef);
|
|
15025
|
+
def.pipeDefs = extractDefListOrFactory(dependencies, getPipeDef$1);
|
|
14972
15026
|
def.id = getComponentId(def);
|
|
14973
15027
|
return def;
|
|
14974
15028
|
});
|
|
@@ -14976,9 +15030,6 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
14976
15030
|
function extractDirectiveDef(type) {
|
|
14977
15031
|
return getComponentDef(type) || getDirectiveDef(type);
|
|
14978
15032
|
}
|
|
14979
|
-
function nonNull(value) {
|
|
14980
|
-
return value !== null;
|
|
14981
|
-
}
|
|
14982
15033
|
/**
|
|
14983
15034
|
* @codeGenApi
|
|
14984
15035
|
*/
|
|
@@ -15182,14 +15233,21 @@ function getNgDirectiveDef(directiveDefinition) {
|
|
|
15182
15233
|
function initFeatures(definition) {
|
|
15183
15234
|
definition.features?.forEach((fn) => fn(definition));
|
|
15184
15235
|
}
|
|
15185
|
-
function extractDefListOrFactory(dependencies,
|
|
15236
|
+
function extractDefListOrFactory(dependencies, defExtractor) {
|
|
15186
15237
|
if (!dependencies) {
|
|
15187
15238
|
return null;
|
|
15188
15239
|
}
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
|
|
15192
|
-
|
|
15240
|
+
return () => {
|
|
15241
|
+
const resolvedDependencies = typeof dependencies === 'function' ? dependencies() : dependencies;
|
|
15242
|
+
const result = [];
|
|
15243
|
+
for (const dep of resolvedDependencies) {
|
|
15244
|
+
const definition = defExtractor(dep);
|
|
15245
|
+
if (definition !== null) {
|
|
15246
|
+
result.push(definition);
|
|
15247
|
+
}
|
|
15248
|
+
}
|
|
15249
|
+
return result;
|
|
15250
|
+
};
|
|
15193
15251
|
}
|
|
15194
15252
|
/**
|
|
15195
15253
|
* A map that contains the generated component IDs and type.
|
|
@@ -15720,26 +15778,35 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
|
|
|
15720
15778
|
}
|
|
15721
15779
|
}
|
|
15722
15780
|
|
|
15723
|
-
function
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
|
|
15728
|
-
|
|
15729
|
-
|
|
15781
|
+
function templateCreate(tNode, declarationLView, declarationTView, index, templateFn, decls, vars, flags) {
|
|
15782
|
+
if (declarationTView.firstCreatePass) {
|
|
15783
|
+
// Merge the template attrs last so that they have the highest priority.
|
|
15784
|
+
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
15785
|
+
const embeddedTView = (tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, declarationTView.directiveRegistry, declarationTView.pipeRegistry, null, declarationTView.schemas, declarationTView.consts, null /* ssrId */));
|
|
15786
|
+
if (declarationTView.queries !== null) {
|
|
15787
|
+
declarationTView.queries.template(declarationTView, tNode);
|
|
15788
|
+
embeddedTView.queries = declarationTView.queries.embeddedTView(tNode);
|
|
15789
|
+
}
|
|
15730
15790
|
}
|
|
15731
|
-
|
|
15732
|
-
|
|
15733
|
-
registerPostOrderHooks(tView, tNode);
|
|
15734
|
-
const embeddedTView = (tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts, null /* ssrId */));
|
|
15735
|
-
if (tView.queries !== null) {
|
|
15736
|
-
tView.queries.template(tView, tNode);
|
|
15737
|
-
embeddedTView.queries = tView.queries.embeddedTView(tNode);
|
|
15791
|
+
if (flags) {
|
|
15792
|
+
tNode.flags |= flags;
|
|
15738
15793
|
}
|
|
15739
|
-
|
|
15794
|
+
setCurrentTNode(tNode, false);
|
|
15795
|
+
const comment = _locateOrCreateContainerAnchor(declarationTView, declarationLView, tNode, index);
|
|
15796
|
+
if (wasLastNodeCreated()) {
|
|
15797
|
+
appendChild(declarationTView, declarationLView, comment, tNode);
|
|
15798
|
+
}
|
|
15799
|
+
attachPatchData(comment, declarationLView);
|
|
15800
|
+
const lContainer = createLContainer(comment, declarationLView, comment, tNode);
|
|
15801
|
+
declarationLView[index + HEADER_OFFSET] = lContainer;
|
|
15802
|
+
addToEndOfViewTree(declarationLView, lContainer);
|
|
15803
|
+
// If hydration is enabled, looks up dehydrated views in the DOM
|
|
15804
|
+
// using hydration annotation info and stores those views on LContainer.
|
|
15805
|
+
// In client-only mode, this function is a noop.
|
|
15806
|
+
populateDehydratedViewsInLContainer(lContainer, tNode, declarationLView);
|
|
15740
15807
|
}
|
|
15741
15808
|
/**
|
|
15742
|
-
*
|
|
15809
|
+
* Declares a new template that can have directives on its host node.
|
|
15743
15810
|
*
|
|
15744
15811
|
* @param declarationLView LView in which the template was declared.
|
|
15745
15812
|
* @param declarationTView TView in which the template wa declared.
|
|
@@ -15753,27 +15820,21 @@ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, t
|
|
|
15753
15820
|
* @param localRefExtractor A function which extracts local-refs values from the template.
|
|
15754
15821
|
* Defaults to the current element associated with the local-ref.
|
|
15755
15822
|
*/
|
|
15756
|
-
function
|
|
15823
|
+
function declareDirectiveHostTemplate(declarationLView, declarationTView, index, templateFn, decls, vars, tagName, attrs, flags, localRefsIndex, localRefExtractor) {
|
|
15757
15824
|
const adjustedIndex = index + HEADER_OFFSET;
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
:
|
|
15761
|
-
|
|
15762
|
-
|
|
15825
|
+
let tNode;
|
|
15826
|
+
if (declarationTView.firstCreatePass) {
|
|
15827
|
+
// TODO(pk): refactor getOrCreateTNode to have the "create" only version
|
|
15828
|
+
tNode = getOrCreateTNode(declarationTView, adjustedIndex, 4 /* TNodeType.Container */, tagName || null, attrs || null);
|
|
15829
|
+
if (getBindingsEnabled()) {
|
|
15830
|
+
resolveDirectives(declarationTView, declarationLView, tNode, getConstant(declarationTView.consts, localRefsIndex), findDirectiveDefMatches);
|
|
15831
|
+
}
|
|
15832
|
+
registerPostOrderHooks(declarationTView, tNode);
|
|
15763
15833
|
}
|
|
15764
|
-
|
|
15765
|
-
|
|
15766
|
-
if (wasLastNodeCreated()) {
|
|
15767
|
-
appendChild(declarationTView, declarationLView, comment, tNode);
|
|
15834
|
+
else {
|
|
15835
|
+
tNode = declarationTView.data[adjustedIndex];
|
|
15768
15836
|
}
|
|
15769
|
-
|
|
15770
|
-
const lContainer = createLContainer(comment, declarationLView, comment, tNode);
|
|
15771
|
-
declarationLView[adjustedIndex] = lContainer;
|
|
15772
|
-
addToEndOfViewTree(declarationLView, lContainer);
|
|
15773
|
-
// If hydration is enabled, looks up dehydrated views in the DOM
|
|
15774
|
-
// using hydration annotation info and stores those views on LContainer.
|
|
15775
|
-
// In client-only mode, this function is a noop.
|
|
15776
|
-
populateDehydratedViewsInLContainer(lContainer, tNode, declarationLView);
|
|
15837
|
+
templateCreate(tNode, declarationLView, declarationTView, index, templateFn, decls, vars, flags);
|
|
15777
15838
|
if (isDirectiveHost(tNode)) {
|
|
15778
15839
|
createDirectivesInstances(declarationTView, declarationLView, tNode);
|
|
15779
15840
|
}
|
|
@@ -15782,6 +15843,32 @@ function declareTemplate(declarationLView, declarationTView, index, templateFn,
|
|
|
15782
15843
|
}
|
|
15783
15844
|
return tNode;
|
|
15784
15845
|
}
|
|
15846
|
+
/**
|
|
15847
|
+
* Declares a new template that *cannot& have directives on its host node.
|
|
15848
|
+
*
|
|
15849
|
+
* @param declarationLView LView in which the template was declared.
|
|
15850
|
+
* @param declarationTView TView in which the template wa declared.
|
|
15851
|
+
* @param index The index of the container in the data array
|
|
15852
|
+
* @param templateFn Inline template
|
|
15853
|
+
* @param decls The number of nodes, local refs, and pipes for this template
|
|
15854
|
+
* @param vars The number of bindings for this template
|
|
15855
|
+
* @param tagName The name of the container element, if applicable
|
|
15856
|
+
* @param attrsIndex Index of template attributes in the `consts` array.
|
|
15857
|
+
* @param localRefs Index of the local references in the `consts` array.
|
|
15858
|
+
* @param localRefExtractor A function which extracts local-refs values from the template.
|
|
15859
|
+
* Defaults to the current element associated with the local-ref.
|
|
15860
|
+
*/
|
|
15861
|
+
function declareNoDirectiveHostTemplate(declarationLView, declarationTView, index, templateFn, decls, vars, tagName, attrs, flags, localRefsIndex, localRefExtractor) {
|
|
15862
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
15863
|
+
const tNode = declarationTView.firstCreatePass
|
|
15864
|
+
? getOrCreateTNode(declarationTView, adjustedIndex, 4 /* TNodeType.Container */, tagName || null, attrs || null)
|
|
15865
|
+
: declarationTView.data[adjustedIndex];
|
|
15866
|
+
templateCreate(tNode, declarationLView, declarationTView, index, templateFn, decls, vars, flags);
|
|
15867
|
+
if (localRefsIndex != null) {
|
|
15868
|
+
saveResolvedLocalsInData(declarationLView, tNode, localRefExtractor);
|
|
15869
|
+
}
|
|
15870
|
+
return tNode;
|
|
15871
|
+
}
|
|
15785
15872
|
/**
|
|
15786
15873
|
* Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
|
|
15787
15874
|
*
|
|
@@ -15805,7 +15892,7 @@ function ɵɵtemplate(index, templateFn, decls, vars, tagName, attrsIndex, local
|
|
|
15805
15892
|
const lView = getLView();
|
|
15806
15893
|
const tView = getTView();
|
|
15807
15894
|
const attrs = getConstant(tView.consts, attrsIndex);
|
|
15808
|
-
|
|
15895
|
+
declareDirectiveHostTemplate(lView, tView, index, templateFn, decls, vars, tagName, attrs, undefined, localRefsIndex, localRefExtractor);
|
|
15809
15896
|
return ɵɵtemplate;
|
|
15810
15897
|
}
|
|
15811
15898
|
let _locateOrCreateContainerAnchor = createContainerAnchorImpl;
|
|
@@ -15822,13 +15909,14 @@ function createContainerAnchorImpl(tView, lView, tNode, index) {
|
|
|
15822
15909
|
* anchor (comment) nodes.
|
|
15823
15910
|
*/
|
|
15824
15911
|
function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
|
|
15825
|
-
const
|
|
15826
|
-
const isNodeCreationMode = !hydrationInfo ||
|
|
15827
|
-
isInSkipHydrationBlock$1() ||
|
|
15828
|
-
isDetachedByI18n(tNode) ||
|
|
15829
|
-
isDisconnectedNode$1(hydrationInfo, index);
|
|
15912
|
+
const isNodeCreationMode = !canHydrateNode(lView, tNode);
|
|
15830
15913
|
lastNodeWasCreated(isNodeCreationMode);
|
|
15831
|
-
|
|
15914
|
+
// Regular creation mode.
|
|
15915
|
+
if (isNodeCreationMode) {
|
|
15916
|
+
return createContainerAnchorImpl(tView, lView);
|
|
15917
|
+
}
|
|
15918
|
+
const hydrationInfo = lView[HYDRATION];
|
|
15919
|
+
const ssrId = hydrationInfo.data[TEMPLATES]?.[index] ?? null;
|
|
15832
15920
|
// Apply `ssrId` value to the underlying TView if it was not previously set.
|
|
15833
15921
|
//
|
|
15834
15922
|
// There might be situations when the same component is present in a template
|
|
@@ -15846,10 +15934,6 @@ function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
|
|
|
15846
15934
|
assertEqual(tNode.tView.ssrId, ssrId, 'Unexpected value of the `ssrId` for this TView');
|
|
15847
15935
|
}
|
|
15848
15936
|
}
|
|
15849
|
-
// Regular creation mode.
|
|
15850
|
-
if (isNodeCreationMode) {
|
|
15851
|
-
return createContainerAnchorImpl(tView, lView);
|
|
15852
|
-
}
|
|
15853
15937
|
// Hydration mode, looking up existing elements in DOM.
|
|
15854
15938
|
const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
15855
15939
|
ngDevMode && validateNodeExists(currentRNode, lView, tNode);
|
|
@@ -16798,9 +16882,7 @@ function afterEveryRender(callbackOrSpec, options) {
|
|
|
16798
16882
|
return afterEveryRenderImpl(callbackOrSpec, injector, options, /* once */ false);
|
|
16799
16883
|
}
|
|
16800
16884
|
function afterNextRender(callbackOrSpec, options) {
|
|
16801
|
-
|
|
16802
|
-
assertInInjectionContext(afterNextRender);
|
|
16803
|
-
}
|
|
16885
|
+
!options?.injector && assertInInjectionContext(afterNextRender);
|
|
16804
16886
|
const injector = options?.injector ?? inject(Injector);
|
|
16805
16887
|
if (typeof ngServerMode !== 'undefined' && ngServerMode) {
|
|
16806
16888
|
return NOOP_AFTER_RENDER_REF;
|
|
@@ -18131,13 +18213,8 @@ function getDeferBlocks$1(lView, deferBlocks) {
|
|
|
18131
18213
|
continue;
|
|
18132
18214
|
}
|
|
18133
18215
|
}
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
if (isLView(lContainer[HOST])) {
|
|
18137
|
-
getDeferBlocks$1(lContainer[HOST], deferBlocks);
|
|
18138
|
-
}
|
|
18139
|
-
for (let j = CONTAINER_HEADER_OFFSET; j < lContainer.length; j++) {
|
|
18140
|
-
getDeferBlocks$1(lContainer[j], deferBlocks);
|
|
18216
|
+
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
18217
|
+
getDeferBlocks$1(lContainer[i], deferBlocks);
|
|
18141
18218
|
}
|
|
18142
18219
|
}
|
|
18143
18220
|
else if (isLView(lView[i])) {
|
|
@@ -18828,9 +18905,6 @@ function isComputedNode(node) {
|
|
|
18828
18905
|
function isTemplateEffectNode(node) {
|
|
18829
18906
|
return node.kind === 'template';
|
|
18830
18907
|
}
|
|
18831
|
-
function isEffectNode(node) {
|
|
18832
|
-
return node.kind === 'effect';
|
|
18833
|
-
}
|
|
18834
18908
|
function isSignalNode(node) {
|
|
18835
18909
|
return node.kind === 'signal';
|
|
18836
18910
|
}
|
|
@@ -18850,36 +18924,54 @@ function getTemplateConsumer(injector) {
|
|
|
18850
18924
|
}
|
|
18851
18925
|
return null;
|
|
18852
18926
|
}
|
|
18927
|
+
const signalDebugMap = new WeakMap();
|
|
18928
|
+
let counter$1 = 0;
|
|
18853
18929
|
function getNodesAndEdgesFromSignalMap(signalMap) {
|
|
18854
18930
|
const nodes = Array.from(signalMap.keys());
|
|
18855
18931
|
const debugSignalGraphNodes = [];
|
|
18856
18932
|
const edges = [];
|
|
18857
18933
|
for (const [consumer, producers] of signalMap.entries()) {
|
|
18858
18934
|
const consumerIndex = nodes.indexOf(consumer);
|
|
18935
|
+
let id = signalDebugMap.get(consumer);
|
|
18936
|
+
if (!id) {
|
|
18937
|
+
counter$1++;
|
|
18938
|
+
id = counter$1.toString();
|
|
18939
|
+
signalDebugMap.set(consumer, id);
|
|
18940
|
+
}
|
|
18859
18941
|
// collect node
|
|
18860
|
-
if (isComputedNode(consumer)
|
|
18942
|
+
if (isComputedNode(consumer)) {
|
|
18861
18943
|
debugSignalGraphNodes.push({
|
|
18862
18944
|
label: consumer.debugName,
|
|
18863
18945
|
value: consumer.value,
|
|
18864
18946
|
kind: consumer.kind,
|
|
18947
|
+
epoch: consumer.version,
|
|
18948
|
+
debuggableFn: consumer.computation,
|
|
18949
|
+
id,
|
|
18865
18950
|
});
|
|
18866
18951
|
}
|
|
18867
|
-
else if (
|
|
18952
|
+
else if (isSignalNode(consumer)) {
|
|
18868
18953
|
debugSignalGraphNodes.push({
|
|
18869
|
-
label: consumer.debugName
|
|
18954
|
+
label: consumer.debugName,
|
|
18955
|
+
value: consumer.value,
|
|
18870
18956
|
kind: consumer.kind,
|
|
18957
|
+
epoch: consumer.version,
|
|
18958
|
+
id,
|
|
18871
18959
|
});
|
|
18872
18960
|
}
|
|
18873
|
-
else if (
|
|
18961
|
+
else if (isTemplateEffectNode(consumer)) {
|
|
18874
18962
|
debugSignalGraphNodes.push({
|
|
18875
|
-
label: consumer.debugName,
|
|
18963
|
+
label: consumer.debugName ?? consumer.lView?.[HOST]?.tagName?.toLowerCase?.(),
|
|
18876
18964
|
kind: consumer.kind,
|
|
18965
|
+
epoch: consumer.version,
|
|
18966
|
+
id,
|
|
18877
18967
|
});
|
|
18878
18968
|
}
|
|
18879
18969
|
else {
|
|
18880
18970
|
debugSignalGraphNodes.push({
|
|
18881
18971
|
label: consumer.debugName,
|
|
18882
18972
|
kind: consumer.kind,
|
|
18973
|
+
epoch: consumer.version,
|
|
18974
|
+
id,
|
|
18883
18975
|
});
|
|
18884
18976
|
}
|
|
18885
18977
|
// collect edges for node
|
|
@@ -20853,7 +20945,7 @@ function ɵɵdefer(index, primaryTmplIndex, dependencyResolverFn, loadingTmplInd
|
|
|
20853
20945
|
const lView = getLView();
|
|
20854
20946
|
const tView = getTView();
|
|
20855
20947
|
const adjustedIndex = index + HEADER_OFFSET;
|
|
20856
|
-
const tNode =
|
|
20948
|
+
const tNode = declareNoDirectiveHostTemplate(lView, tView, index, null, 0, 0);
|
|
20857
20949
|
const injector = lView[INJECTOR];
|
|
20858
20950
|
if (tView.firstCreatePass) {
|
|
20859
20951
|
performanceMarkFeature('NgDefer');
|
|
@@ -21818,7 +21910,7 @@ function ɵɵconditionalCreate(index, templateFn, decls, vars, tagName, attrsInd
|
|
|
21818
21910
|
const lView = getLView();
|
|
21819
21911
|
const tView = getTView();
|
|
21820
21912
|
const attrs = getConstant(tView.consts, attrsIndex);
|
|
21821
|
-
|
|
21913
|
+
declareNoDirectiveHostTemplate(lView, tView, index, templateFn, decls, vars, tagName, attrs, 256 /* TNodeFlags.isControlFlowStart */, localRefsIndex, localRefExtractor);
|
|
21822
21914
|
return ɵɵconditionalBranchCreate;
|
|
21823
21915
|
}
|
|
21824
21916
|
/**
|
|
@@ -21844,7 +21936,7 @@ function ɵɵconditionalBranchCreate(index, templateFn, decls, vars, tagName, at
|
|
|
21844
21936
|
const lView = getLView();
|
|
21845
21937
|
const tView = getTView();
|
|
21846
21938
|
const attrs = getConstant(tView.consts, attrsIndex);
|
|
21847
|
-
|
|
21939
|
+
declareNoDirectiveHostTemplate(lView, tView, index, templateFn, decls, vars, tagName, attrs, 512 /* TNodeFlags.isInControlFlow */, localRefsIndex, localRefExtractor);
|
|
21848
21940
|
return ɵɵconditionalBranchCreate;
|
|
21849
21941
|
}
|
|
21850
21942
|
/**
|
|
@@ -21985,13 +22077,13 @@ function ɵɵrepeaterCreate(index, templateFn, decls, vars, tagName, attrsIndex,
|
|
|
21985
22077
|
: trackByFn;
|
|
21986
22078
|
const metadata = new RepeaterMetadata(hasEmptyBlock, boundTrackBy);
|
|
21987
22079
|
hostLView[HEADER_OFFSET + index] = metadata;
|
|
21988
|
-
|
|
22080
|
+
declareNoDirectiveHostTemplate(lView, tView, index + 1, templateFn, decls, vars, tagName, getConstant(tView.consts, attrsIndex), 256 /* TNodeFlags.isControlFlowStart */);
|
|
21989
22081
|
if (hasEmptyBlock) {
|
|
21990
22082
|
ngDevMode &&
|
|
21991
22083
|
assertDefined(emptyDecls, 'Missing number of declarations for the empty repeater block.');
|
|
21992
22084
|
ngDevMode &&
|
|
21993
22085
|
assertDefined(emptyVars, 'Missing number of bindings for the empty repeater block.');
|
|
21994
|
-
|
|
22086
|
+
declareNoDirectiveHostTemplate(lView, tView, index + 2, emptyTemplateFn, emptyDecls, emptyVars, emptyTagName, getConstant(tView.consts, emptyAttrsIndex), 512 /* TNodeFlags.isInControlFlow */);
|
|
21995
22087
|
}
|
|
21996
22088
|
}
|
|
21997
22089
|
function isViewExpensiveToRecreate(lView) {
|
|
@@ -22228,42 +22320,24 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
|
|
|
22228
22320
|
*/
|
|
22229
22321
|
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
22230
22322
|
const lView = getLView();
|
|
22231
|
-
|
|
22232
|
-
const
|
|
22233
|
-
|
|
22234
|
-
assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
|
|
22235
|
-
ngDevMode && assertIndexInRange(lView, adjustedIndex);
|
|
22236
|
-
const renderer = lView[RENDERER];
|
|
22323
|
+
ngDevMode && assertTNodeCreationIndex(lView, index);
|
|
22324
|
+
const tView = lView[TVIEW];
|
|
22325
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
22237
22326
|
const tNode = tView.firstCreatePass
|
|
22238
|
-
?
|
|
22327
|
+
? directiveHostFirstCreatePass(adjustedIndex, lView, 2 /* TNodeType.Element */, name, findDirectiveDefMatches, getBindingsEnabled(), attrsIndex, localRefsIndex)
|
|
22239
22328
|
: tView.data[adjustedIndex];
|
|
22240
|
-
|
|
22241
|
-
|
|
22242
|
-
|
|
22243
|
-
if (ngDevMode && tView.firstCreatePass) {
|
|
22244
|
-
validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
|
|
22245
|
-
}
|
|
22246
|
-
setCurrentTNode(tNode, true);
|
|
22247
|
-
setupStaticAttributes(renderer, native, tNode);
|
|
22248
|
-
if (!isDetachedByI18n(tNode) && wasLastNodeCreated()) {
|
|
22249
|
-
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
22250
|
-
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
22251
|
-
appendChild(tView, lView, native, tNode);
|
|
22252
|
-
}
|
|
22253
|
-
// any immediate children of a component or template container must be pre-emptively
|
|
22254
|
-
// monkey-patched with the component view data so that the element can be inspected
|
|
22255
|
-
// later on using any element discovery utility methods (see `element_discovery.ts`)
|
|
22256
|
-
if (getElementDepthCount() === 0 || hasDirectives) {
|
|
22257
|
-
attachPatchData(native, lView);
|
|
22258
|
-
}
|
|
22259
|
-
increaseElementDepthCount();
|
|
22260
|
-
if (hasDirectives) {
|
|
22329
|
+
elementLikeStartShared(tNode, lView, index, name, _locateOrCreateElementNode);
|
|
22330
|
+
if (isDirectiveHost(tNode)) {
|
|
22331
|
+
const tView = lView[TVIEW];
|
|
22261
22332
|
createDirectivesInstances(tView, lView, tNode);
|
|
22262
22333
|
executeContentQueries(tView, tNode, lView);
|
|
22263
22334
|
}
|
|
22264
|
-
if (localRefsIndex
|
|
22335
|
+
if (localRefsIndex != null) {
|
|
22265
22336
|
saveResolvedLocalsInData(lView, tNode);
|
|
22266
22337
|
}
|
|
22338
|
+
if (ngDevMode && lView[TVIEW].firstCreatePass) {
|
|
22339
|
+
validateElementIsKnown(lView, tNode);
|
|
22340
|
+
}
|
|
22267
22341
|
return ɵɵelementStart;
|
|
22268
22342
|
}
|
|
22269
22343
|
/**
|
|
@@ -22273,31 +22347,23 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
22273
22347
|
* @codeGenApi
|
|
22274
22348
|
*/
|
|
22275
22349
|
function ɵɵelementEnd() {
|
|
22276
|
-
|
|
22277
|
-
|
|
22278
|
-
|
|
22279
|
-
|
|
22280
|
-
|
|
22281
|
-
|
|
22282
|
-
|
|
22283
|
-
currentTNode = currentTNode.parent;
|
|
22284
|
-
setCurrentTNode(currentTNode, false);
|
|
22350
|
+
const tView = getTView();
|
|
22351
|
+
const initialTNode = getCurrentTNode();
|
|
22352
|
+
ngDevMode && assertDefined(initialTNode, 'No parent node to close.');
|
|
22353
|
+
const currentTNode = elementLikeEndShared(initialTNode);
|
|
22354
|
+
ngDevMode && assertTNodeType(currentTNode, 3 /* TNodeType.AnyRNode */);
|
|
22355
|
+
if (tView.firstCreatePass) {
|
|
22356
|
+
directiveHostEndFirstCreatePass(tView, currentTNode);
|
|
22285
22357
|
}
|
|
22286
|
-
|
|
22287
|
-
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
|
|
22288
|
-
if (isSkipHydrationRootTNode(tNode)) {
|
|
22358
|
+
if (isSkipHydrationRootTNode(currentTNode)) {
|
|
22289
22359
|
leaveSkipHydrationBlock();
|
|
22290
22360
|
}
|
|
22291
22361
|
decreaseElementDepthCount();
|
|
22292
|
-
|
|
22293
|
-
|
|
22294
|
-
elementEndFirstCreatePass(tView, tNode);
|
|
22362
|
+
if (currentTNode.classesWithoutHost != null && hasClassInput(currentTNode)) {
|
|
22363
|
+
setDirectiveInputsWhichShadowsStyling(tView, currentTNode, getLView(), currentTNode.classesWithoutHost, true);
|
|
22295
22364
|
}
|
|
22296
|
-
if (
|
|
22297
|
-
setDirectiveInputsWhichShadowsStyling(tView,
|
|
22298
|
-
}
|
|
22299
|
-
if (tNode.stylesWithoutHost != null && hasStyleInput(tNode)) {
|
|
22300
|
-
setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.stylesWithoutHost, false);
|
|
22365
|
+
if (currentTNode.stylesWithoutHost != null && hasStyleInput(currentTNode)) {
|
|
22366
|
+
setDirectiveInputsWhichShadowsStyling(tView, currentTNode, getLView(), currentTNode.stylesWithoutHost, false);
|
|
22301
22367
|
}
|
|
22302
22368
|
return ɵɵelementEnd;
|
|
22303
22369
|
}
|
|
@@ -22317,26 +22383,23 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
|
|
|
22317
22383
|
ɵɵelementEnd();
|
|
22318
22384
|
return ɵɵelement;
|
|
22319
22385
|
}
|
|
22320
|
-
let _locateOrCreateElementNode = (tView, lView, tNode,
|
|
22386
|
+
let _locateOrCreateElementNode = (tView, lView, tNode, name, index) => {
|
|
22321
22387
|
lastNodeWasCreated(true);
|
|
22322
|
-
return createElementNode(
|
|
22388
|
+
return createElementNode(lView[RENDERER], name, getNamespace());
|
|
22323
22389
|
};
|
|
22324
22390
|
/**
|
|
22325
22391
|
* Enables hydration code path (to lookup existing elements in DOM)
|
|
22326
22392
|
* in addition to the regular creation mode of element nodes.
|
|
22327
22393
|
*/
|
|
22328
|
-
function locateOrCreateElementNodeImpl(tView, lView, tNode,
|
|
22329
|
-
const
|
|
22330
|
-
const isNodeCreationMode = !hydrationInfo ||
|
|
22331
|
-
isInSkipHydrationBlock$1() ||
|
|
22332
|
-
isDetachedByI18n(tNode) ||
|
|
22333
|
-
isDisconnectedNode$1(hydrationInfo, index);
|
|
22394
|
+
function locateOrCreateElementNodeImpl(tView, lView, tNode, name, index) {
|
|
22395
|
+
const isNodeCreationMode = !canHydrateNode(lView, tNode);
|
|
22334
22396
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22335
22397
|
// Regular creation mode.
|
|
22336
22398
|
if (isNodeCreationMode) {
|
|
22337
|
-
return createElementNode(
|
|
22399
|
+
return createElementNode(lView[RENDERER], name, getNamespace());
|
|
22338
22400
|
}
|
|
22339
22401
|
// Hydration mode, looking up an existing element in DOM.
|
|
22402
|
+
const hydrationInfo = lView[HYDRATION];
|
|
22340
22403
|
const native = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
22341
22404
|
ngDevMode && validateMatchingNode(native, Node.ELEMENT_NODE, name, lView, tNode);
|
|
22342
22405
|
ngDevMode && markRNodeAsClaimedByHydration(native);
|
|
@@ -22376,26 +22439,6 @@ function enableLocateOrCreateElementNodeImpl() {
|
|
|
22376
22439
|
_locateOrCreateElementNode = locateOrCreateElementNodeImpl;
|
|
22377
22440
|
}
|
|
22378
22441
|
|
|
22379
|
-
function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
|
|
22380
|
-
const tViewConsts = tView.consts;
|
|
22381
|
-
const attrs = getConstant(tViewConsts, attrsIndex);
|
|
22382
|
-
const tNode = getOrCreateTNode(tView, index, 8 /* TNodeType.ElementContainer */, 'ng-container', attrs);
|
|
22383
|
-
// While ng-container doesn't necessarily support styling, we use the style context to identify
|
|
22384
|
-
// and execute directives on the ng-container.
|
|
22385
|
-
if (attrs !== null) {
|
|
22386
|
-
computeStaticStyling(tNode, attrs, true);
|
|
22387
|
-
}
|
|
22388
|
-
const localRefs = getConstant(tViewConsts, localRefsIndex);
|
|
22389
|
-
if (getBindingsEnabled()) {
|
|
22390
|
-
resolveDirectives(tView, lView, tNode, localRefs, findDirectiveDefMatches);
|
|
22391
|
-
}
|
|
22392
|
-
// Merge the template attrs last so that they have the highest priority.
|
|
22393
|
-
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
22394
|
-
if (tView.queries !== null) {
|
|
22395
|
-
tView.queries.elementStart(tView, tNode);
|
|
22396
|
-
}
|
|
22397
|
-
return tNode;
|
|
22398
|
-
}
|
|
22399
22442
|
/**
|
|
22400
22443
|
* Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
|
|
22401
22444
|
* The instruction must later be followed by `elementContainerEnd()` call.
|
|
@@ -22413,22 +22456,15 @@ function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, l
|
|
|
22413
22456
|
*/
|
|
22414
22457
|
function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
|
|
22415
22458
|
const lView = getLView();
|
|
22416
|
-
|
|
22459
|
+
ngDevMode && assertTNodeCreationIndex(lView, index);
|
|
22460
|
+
const tView = lView[TVIEW];
|
|
22417
22461
|
const adjustedIndex = index + HEADER_OFFSET;
|
|
22418
|
-
ngDevMode && assertIndexInRange(lView, adjustedIndex);
|
|
22419
|
-
ngDevMode &&
|
|
22420
|
-
assertEqual(getBindingIndex(), tView.bindingStartIndex, 'element containers should be created before any bindings');
|
|
22421
22462
|
const tNode = tView.firstCreatePass
|
|
22422
|
-
?
|
|
22463
|
+
? directiveHostFirstCreatePass(adjustedIndex, lView, 8 /* TNodeType.ElementContainer */, 'ng-container', findDirectiveDefMatches, getBindingsEnabled(), attrsIndex, localRefsIndex)
|
|
22423
22464
|
: tView.data[adjustedIndex];
|
|
22424
|
-
|
|
22425
|
-
const comment = _locateOrCreateElementContainerNode(tView, lView, tNode, index);
|
|
22426
|
-
lView[adjustedIndex] = comment;
|
|
22427
|
-
if (wasLastNodeCreated()) {
|
|
22428
|
-
appendChild(tView, lView, comment, tNode);
|
|
22429
|
-
}
|
|
22430
|
-
attachPatchData(comment, lView);
|
|
22465
|
+
elementLikeStartShared(tNode, lView, index, 'ng-container', _locateOrCreateElementContainerNode);
|
|
22431
22466
|
if (isDirectiveHost(tNode)) {
|
|
22467
|
+
const tView = lView[TVIEW];
|
|
22432
22468
|
createDirectivesInstances(tView, lView, tNode);
|
|
22433
22469
|
executeContentQueries(tView, tNode, lView);
|
|
22434
22470
|
}
|
|
@@ -22444,23 +22480,14 @@ function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
|
|
|
22444
22480
|
* @codeGenApi
|
|
22445
22481
|
*/
|
|
22446
22482
|
function ɵɵelementContainerEnd() {
|
|
22447
|
-
let currentTNode = getCurrentTNode();
|
|
22448
22483
|
const tView = getTView();
|
|
22449
|
-
|
|
22450
|
-
|
|
22451
|
-
|
|
22452
|
-
else {
|
|
22453
|
-
ngDevMode && assertHasParent(currentTNode);
|
|
22454
|
-
currentTNode = currentTNode.parent;
|
|
22455
|
-
setCurrentTNode(currentTNode, false);
|
|
22456
|
-
}
|
|
22457
|
-
ngDevMode && assertTNodeType(currentTNode, 8 /* TNodeType.ElementContainer */);
|
|
22484
|
+
const initialTNode = getCurrentTNode();
|
|
22485
|
+
ngDevMode && assertDefined(initialTNode, 'No parent node to close.');
|
|
22486
|
+
const currentTNode = elementLikeEndShared(initialTNode);
|
|
22458
22487
|
if (tView.firstCreatePass) {
|
|
22459
|
-
|
|
22460
|
-
if (isContentQueryHost(currentTNode)) {
|
|
22461
|
-
tView.queries.elementEnd(currentTNode);
|
|
22462
|
-
}
|
|
22488
|
+
directiveHostEndFirstCreatePass(tView, currentTNode);
|
|
22463
22489
|
}
|
|
22490
|
+
ngDevMode && assertTNodeType(currentTNode, 8 /* TNodeType.ElementContainer */);
|
|
22464
22491
|
return ɵɵelementContainerEnd;
|
|
22465
22492
|
}
|
|
22466
22493
|
/**
|
|
@@ -22479,28 +22506,25 @@ function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
|
|
|
22479
22506
|
ɵɵelementContainerEnd();
|
|
22480
22507
|
return ɵɵelementContainer;
|
|
22481
22508
|
}
|
|
22482
|
-
let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
|
|
22509
|
+
let _locateOrCreateElementContainerNode = (tView, lView, tNode, commentText, index) => {
|
|
22483
22510
|
lastNodeWasCreated(true);
|
|
22484
|
-
return createCommentNode(lView[RENDERER], ngDevMode ?
|
|
22511
|
+
return createCommentNode(lView[RENDERER], ngDevMode ? commentText : '');
|
|
22485
22512
|
};
|
|
22486
22513
|
/**
|
|
22487
22514
|
* Enables hydration code path (to lookup existing elements in DOM)
|
|
22488
22515
|
* in addition to the regular creation mode of comment nodes that
|
|
22489
22516
|
* represent <ng-container>'s anchor.
|
|
22490
22517
|
*/
|
|
22491
|
-
function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
|
|
22518
|
+
function locateOrCreateElementContainerNode(tView, lView, tNode, commentText, index) {
|
|
22492
22519
|
let comment;
|
|
22493
|
-
const
|
|
22494
|
-
const isNodeCreationMode = !hydrationInfo ||
|
|
22495
|
-
isInSkipHydrationBlock$1() ||
|
|
22496
|
-
isDisconnectedNode$1(hydrationInfo, index) ||
|
|
22497
|
-
isDetachedByI18n(tNode);
|
|
22520
|
+
const isNodeCreationMode = !canHydrateNode(lView, tNode);
|
|
22498
22521
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22499
22522
|
// Regular creation mode.
|
|
22500
22523
|
if (isNodeCreationMode) {
|
|
22501
|
-
return createCommentNode(lView[RENDERER], ngDevMode ?
|
|
22524
|
+
return createCommentNode(lView[RENDERER], ngDevMode ? commentText : '');
|
|
22502
22525
|
}
|
|
22503
22526
|
// Hydration mode, looking up existing elements in DOM.
|
|
22527
|
+
const hydrationInfo = lView[HYDRATION];
|
|
22504
22528
|
const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
22505
22529
|
ngDevMode && validateNodeExists(currentRNode, lView, tNode);
|
|
22506
22530
|
const ngContainerSize = getNgContainerSize(hydrationInfo, index);
|
|
@@ -24578,7 +24602,7 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs, fallbackTemplateFn,
|
|
|
24578
24602
|
// instances of the component may or may not insert it. Also it needs to be declare *before*
|
|
24579
24603
|
// the projection node in order to work correctly with hydration.
|
|
24580
24604
|
if (fallbackIndex !== null) {
|
|
24581
|
-
|
|
24605
|
+
declareNoDirectiveHostTemplate(lView, tView, fallbackIndex, fallbackTemplateFn, fallbackDecls, fallbackVars, null, attrs);
|
|
24582
24606
|
}
|
|
24583
24607
|
const tProjectionNode = getOrCreateTNode(tView, HEADER_OFFSET + nodeIndex, 16 /* TNodeType.Projection */, null, attrs || null);
|
|
24584
24608
|
// We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
|
|
@@ -26097,9 +26121,7 @@ function ɵɵtext(index, value = '') {
|
|
|
26097
26121
|
const lView = getLView();
|
|
26098
26122
|
const tView = getTView();
|
|
26099
26123
|
const adjustedIndex = index + HEADER_OFFSET;
|
|
26100
|
-
ngDevMode &&
|
|
26101
|
-
assertEqual(getBindingIndex(), tView.bindingStartIndex, 'text nodes should be created before any bindings');
|
|
26102
|
-
ngDevMode && assertIndexInRange(lView, adjustedIndex);
|
|
26124
|
+
ngDevMode && assertTNodeCreationIndex(lView, index);
|
|
26103
26125
|
const tNode = tView.firstCreatePass
|
|
26104
26126
|
? getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null)
|
|
26105
26127
|
: tView.data[adjustedIndex];
|
|
@@ -26120,17 +26142,14 @@ let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
|
|
|
26120
26142
|
* in addition to the regular creation mode of text nodes.
|
|
26121
26143
|
*/
|
|
26122
26144
|
function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
|
|
26123
|
-
const
|
|
26124
|
-
const isNodeCreationMode = !hydrationInfo ||
|
|
26125
|
-
isInSkipHydrationBlock$1() ||
|
|
26126
|
-
isDetachedByI18n(tNode) ||
|
|
26127
|
-
isDisconnectedNode$1(hydrationInfo, index);
|
|
26145
|
+
const isNodeCreationMode = !canHydrateNode(lView, tNode);
|
|
26128
26146
|
lastNodeWasCreated(isNodeCreationMode);
|
|
26129
26147
|
// Regular creation mode.
|
|
26130
26148
|
if (isNodeCreationMode) {
|
|
26131
26149
|
return createTextNode(lView[RENDERER], value);
|
|
26132
26150
|
}
|
|
26133
26151
|
// Hydration mode, looking up an existing element in DOM.
|
|
26152
|
+
const hydrationInfo = lView[HYDRATION];
|
|
26134
26153
|
const textNative = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
26135
26154
|
ngDevMode && validateMatchingNode(textNative, Node.TEXT_NODE, null, lView, tNode);
|
|
26136
26155
|
ngDevMode && markRNodeAsClaimedByHydration(textNative);
|
|
@@ -27145,7 +27164,7 @@ function indexOf(item, arr, begin, end) {
|
|
|
27145
27164
|
/**
|
|
27146
27165
|
* Use this with `multi` `providers`.
|
|
27147
27166
|
*/
|
|
27148
|
-
function multiProvidersFactoryResolver(_, tData, lData, tNode) {
|
|
27167
|
+
function multiProvidersFactoryResolver(_, flags, tData, lData, tNode) {
|
|
27149
27168
|
return multiResolve(this.multi, []);
|
|
27150
27169
|
}
|
|
27151
27170
|
/**
|
|
@@ -27153,7 +27172,7 @@ function multiProvidersFactoryResolver(_, tData, lData, tNode) {
|
|
|
27153
27172
|
*
|
|
27154
27173
|
* This factory knows how to concatenate itself with the existing `multi` `providers`.
|
|
27155
27174
|
*/
|
|
27156
|
-
function multiViewProvidersFactoryResolver(_,
|
|
27175
|
+
function multiViewProvidersFactoryResolver(_, _flags, _tData, lView, tNode) {
|
|
27157
27176
|
const factories = this.multi;
|
|
27158
27177
|
let result;
|
|
27159
27178
|
if (this.providerFactory) {
|
|
@@ -27278,8 +27297,8 @@ function ɵɵExternalStylesFeature(styleUrls) {
|
|
|
27278
27297
|
*/
|
|
27279
27298
|
function ɵɵsetComponentScope(type, directives, pipes) {
|
|
27280
27299
|
const def = type.ɵcmp;
|
|
27281
|
-
def.directiveDefs = extractDefListOrFactory(directives,
|
|
27282
|
-
def.pipeDefs = extractDefListOrFactory(pipes,
|
|
27300
|
+
def.directiveDefs = extractDefListOrFactory(directives, extractDirectiveDef);
|
|
27301
|
+
def.pipeDefs = extractDefListOrFactory(pipes, getPipeDef$1);
|
|
27283
27302
|
}
|
|
27284
27303
|
/**
|
|
27285
27304
|
* Adds the module metadata that is necessary to compute the module's transitive scope to an
|
|
@@ -29547,17 +29566,8 @@ function internalProvideZoneChangeDetection({ ngZoneFactory, ignoreChangesOutsid
|
|
|
29547
29566
|
const injector = inject(EnvironmentInjector);
|
|
29548
29567
|
let userErrorHandler;
|
|
29549
29568
|
return (e) => {
|
|
29550
|
-
|
|
29551
|
-
|
|
29552
|
-
setTimeout(() => {
|
|
29553
|
-
throw e;
|
|
29554
|
-
});
|
|
29555
|
-
}
|
|
29556
|
-
else {
|
|
29557
|
-
userErrorHandler ??= injector.get(ErrorHandler);
|
|
29558
|
-
userErrorHandler.handleError(e);
|
|
29559
|
-
}
|
|
29560
|
-
});
|
|
29569
|
+
userErrorHandler ??= injector.get(ErrorHandler);
|
|
29570
|
+
zone.runOutsideAngular(() => userErrorHandler.handleError(e));
|
|
29561
29571
|
};
|
|
29562
29572
|
},
|
|
29563
29573
|
},
|
|
@@ -30078,6 +30088,7 @@ const LOCALE_ID = new InjectionToken(ngDevMode ? 'LocaleId' : '', {
|
|
|
30078
30088
|
* In standalone apps:
|
|
30079
30089
|
* ```ts
|
|
30080
30090
|
* import { LOCALE_ID, ApplicationConfig } from '@angular/core';
|
|
30091
|
+
* import { AppModule } from './app/app.module';
|
|
30081
30092
|
*
|
|
30082
30093
|
* const appConfig: ApplicationConfig = {
|
|
30083
30094
|
* providers: [{provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }]
|
|
@@ -30111,6 +30122,7 @@ const DEFAULT_CURRENCY_CODE = new InjectionToken(ngDevMode ? 'DefaultCurrencyCod
|
|
|
30111
30122
|
* In standalone apps:
|
|
30112
30123
|
* ```ts
|
|
30113
30124
|
* import { LOCALE_ID, ApplicationConfig } from '@angular/core';
|
|
30125
|
+
* import { AppModule } from './app/app.module';
|
|
30114
30126
|
*
|
|
30115
30127
|
* const appConfig: ApplicationConfig = {
|
|
30116
30128
|
* providers: [{provide: TRANSLATIONS, useValue: translations }]
|
|
@@ -30145,6 +30157,7 @@ const TRANSLATIONS = new InjectionToken(ngDevMode ? 'Translations' : '');
|
|
|
30145
30157
|
* In standalone apps:
|
|
30146
30158
|
* ```ts
|
|
30147
30159
|
* import { LOCALE_ID, ApplicationConfig } from '@angular/core';
|
|
30160
|
+
* import { AppModule } from './app/app.module';
|
|
30148
30161
|
*
|
|
30149
30162
|
* const appConfig: ApplicationConfig = {
|
|
30150
30163
|
* providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
|
|
@@ -30757,4 +30770,4 @@ function getDebugNode(nativeNode) {
|
|
|
30757
30770
|
}
|
|
30758
30771
|
|
|
30759
30772
|
export { AFTER_RENDER_PHASES, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, EnvironmentNgModuleRefAdapter, EventEmitter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, NgProbeToken, NgZone, NoopNgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, PROVIDED_NG_ZONE, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getNgZone, getNgZoneOptions, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, inputBinding, internalProvideZoneChangeDetection, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZoneChangeDetection, provideZonelessChangeDetection, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomProperty, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
|
|
30760
|
-
//# sourceMappingURL=debug_node.mjs.map
|
|
30773
|
+
//# sourceMappingURL=debug_node-CGQXW8qF.mjs.map
|