@angular/core 19.1.4 → 19.1.6
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/fesm2022/core.mjs +635 -597
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +4 -4
- package/index.d.ts +13 -2
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{apply_import_manager-3ba5d1bb.js → apply_import_manager-61eb7e4a.js} +3 -3
- package/schematics/bundles/{checker-ca858016.js → checker-58684f3f.js} +90 -52
- package/schematics/bundles/cleanup-unused-imports.js +5 -5
- package/schematics/bundles/{compiler_host-c26ed2d0.js → compiler_host-dff4346e.js} +2 -2
- package/schematics/bundles/control-flow-migration.js +10 -3
- package/schematics/bundles/explicit-standalone-flag.js +3 -3
- package/schematics/bundles/imports-31a38653.js +1 -1
- package/schematics/bundles/{index-aa0e0065.js → index-027c9191.js} +4 -4
- package/schematics/bundles/{index-761b9f6f.js → index-4bb9c755.js} +4 -4
- package/schematics/bundles/inject-migration.js +3 -3
- package/schematics/bundles/leading_space-6e7a8ec6.js +1 -1
- package/schematics/bundles/{migrate_ts_type_references-c6d4443c.js → migrate_ts_type_references-f48f6ec0.js} +5 -5
- package/schematics/bundles/nodes-88c2157f.js +1 -1
- package/schematics/bundles/output-migration.js +5 -5
- package/schematics/bundles/pending-tasks.js +3 -3
- package/schematics/bundles/{program-8e222816.js → program-721d697e.js} +123 -35
- package/schematics/bundles/project_tsconfig_paths-6c9cde78.js +1 -1
- package/schematics/bundles/provide-initializer.js +3 -3
- package/schematics/bundles/route-lazy-loading.js +3 -3
- package/schematics/bundles/signal-input-migration.js +6 -6
- package/schematics/bundles/signal-queries-migration.js +6 -6
- package/schematics/bundles/signals.js +6 -6
- package/schematics/bundles/standalone-migration.js +5 -5
- package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v19.1.
|
|
2
|
+
* @license Angular v19.1.6
|
|
3
3
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -3067,7 +3067,7 @@ function assertProjectionSlots(lView, errMessage) {
|
|
|
3067
3067
|
function assertParentView(lView, errMessage) {
|
|
3068
3068
|
assertDefined(lView, errMessage || "Component views should always have a parent view (component's host view)");
|
|
3069
3069
|
}
|
|
3070
|
-
function assertNoDuplicateDirectives(directives) {
|
|
3070
|
+
function assertNoDuplicateDirectives$1(directives) {
|
|
3071
3071
|
// The array needs at least two elements in order to have duplicates.
|
|
3072
3072
|
if (directives.length < 2) {
|
|
3073
3073
|
return;
|
|
@@ -4060,7 +4060,7 @@ function ɵɵnamespaceHTML() {
|
|
|
4060
4060
|
function namespaceHTMLInternal() {
|
|
4061
4061
|
instructionState.lFrame.currentNamespace = null;
|
|
4062
4062
|
}
|
|
4063
|
-
function getNamespace
|
|
4063
|
+
function getNamespace() {
|
|
4064
4064
|
return instructionState.lFrame.currentNamespace;
|
|
4065
4065
|
}
|
|
4066
4066
|
let _wasLastNodeCreated = true;
|
|
@@ -11637,14 +11637,6 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
|
|
|
11637
11637
|
return { propName: undefined, oldValue, newValue };
|
|
11638
11638
|
}
|
|
11639
11639
|
|
|
11640
|
-
/** Flags describing an input for a directive. */
|
|
11641
|
-
var InputFlags;
|
|
11642
|
-
(function (InputFlags) {
|
|
11643
|
-
InputFlags[InputFlags["None"] = 0] = "None";
|
|
11644
|
-
InputFlags[InputFlags["SignalBased"] = 1] = "SignalBased";
|
|
11645
|
-
InputFlags[InputFlags["HasDecoratorInputTransform"] = 2] = "HasDecoratorInputTransform";
|
|
11646
|
-
})(InputFlags || (InputFlags = {}));
|
|
11647
|
-
|
|
11648
11640
|
/**
|
|
11649
11641
|
* Returns an index of `classToSearch` in `className` taking token boundaries into account.
|
|
11650
11642
|
*
|
|
@@ -12254,38 +12246,13 @@ function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
|
|
|
12254
12246
|
setSelectedIndex(index);
|
|
12255
12247
|
}
|
|
12256
12248
|
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
return ɵɵinject(token, flags);
|
|
12265
|
-
}
|
|
12266
|
-
const tNode = getCurrentTNode();
|
|
12267
|
-
const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
12268
|
-
ngDevMode && emitInjectEvent(token, value, flags);
|
|
12269
|
-
return value;
|
|
12270
|
-
}
|
|
12271
|
-
/**
|
|
12272
|
-
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
12273
|
-
* particular class.
|
|
12274
|
-
*
|
|
12275
|
-
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
12276
|
-
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
12277
|
-
*
|
|
12278
|
-
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
12279
|
-
* and thus in the stack trace.
|
|
12280
|
-
*
|
|
12281
|
-
* @codeGenApi
|
|
12282
|
-
*/
|
|
12283
|
-
function ɵɵinvalidFactory() {
|
|
12284
|
-
const msg = ngDevMode
|
|
12285
|
-
? `This constructor was not compatible with Dependency Injection.`
|
|
12286
|
-
: 'invalid';
|
|
12287
|
-
throw new Error(msg);
|
|
12288
|
-
}
|
|
12249
|
+
/** Flags describing an input for a directive. */
|
|
12250
|
+
var InputFlags;
|
|
12251
|
+
(function (InputFlags) {
|
|
12252
|
+
InputFlags[InputFlags["None"] = 0] = "None";
|
|
12253
|
+
InputFlags[InputFlags["SignalBased"] = 1] = "SignalBased";
|
|
12254
|
+
InputFlags[InputFlags["HasDecoratorInputTransform"] = 2] = "HasDecoratorInputTransform";
|
|
12255
|
+
})(InputFlags || (InputFlags = {}));
|
|
12289
12256
|
|
|
12290
12257
|
function writeToDirectiveInput(def, instance, publicName, privateName, flags, value) {
|
|
12291
12258
|
const prevConsumer = setActiveConsumer$1(null);
|
|
@@ -12353,34 +12320,6 @@ function createLView(parentLView, tView, context, flags, host, tHostNode, enviro
|
|
|
12353
12320
|
tView.type == 2 /* TViewType.Embedded */ ? parentLView[DECLARATION_COMPONENT_VIEW] : lView;
|
|
12354
12321
|
return lView;
|
|
12355
12322
|
}
|
|
12356
|
-
/**
|
|
12357
|
-
* When elements are created dynamically after a view blueprint is created (e.g. through
|
|
12358
|
-
* i18nApply()), we need to adjust the blueprint for future
|
|
12359
|
-
* template passes.
|
|
12360
|
-
*
|
|
12361
|
-
* @param tView `TView` associated with `LView`
|
|
12362
|
-
* @param lView The `LView` containing the blueprint to adjust
|
|
12363
|
-
* @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
|
|
12364
|
-
* @param initialValue Initial value to store in blueprint
|
|
12365
|
-
*/
|
|
12366
|
-
function allocExpando(tView, lView, numSlotsToAlloc, initialValue) {
|
|
12367
|
-
if (numSlotsToAlloc === 0)
|
|
12368
|
-
return -1;
|
|
12369
|
-
if (ngDevMode) {
|
|
12370
|
-
assertFirstCreatePass(tView);
|
|
12371
|
-
assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
|
|
12372
|
-
assertEqual(tView.data.length, lView.length, 'Expecting LView to be same size as TView');
|
|
12373
|
-
assertEqual(tView.data.length, tView.blueprint.length, 'Expecting Blueprint to be same size as TView');
|
|
12374
|
-
assertFirstUpdatePass(tView);
|
|
12375
|
-
}
|
|
12376
|
-
const allocIdx = lView.length;
|
|
12377
|
-
for (let i = 0; i < numSlotsToAlloc; i++) {
|
|
12378
|
-
lView.push(initialValue);
|
|
12379
|
-
tView.blueprint.push(initialValue);
|
|
12380
|
-
tView.data.push(null);
|
|
12381
|
-
}
|
|
12382
|
-
return allocIdx;
|
|
12383
|
-
}
|
|
12384
12323
|
function executeTemplate(tView, lView, templateFn, rf, context) {
|
|
12385
12324
|
const prevSelectedIndex = getSelectedIndex();
|
|
12386
12325
|
const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
|
|
@@ -12593,106 +12532,6 @@ function applyRootElementTransformImpl(rootElement) {
|
|
|
12593
12532
|
function enableApplyRootElementTransformImpl() {
|
|
12594
12533
|
_applyRootElementTransformImpl = applyRootElementTransformImpl;
|
|
12595
12534
|
}
|
|
12596
|
-
function captureNodeBindings(mode, aliasMap, directiveIndex, bindingsResult, hostDirectiveAliasMap) {
|
|
12597
|
-
for (let publicName in aliasMap) {
|
|
12598
|
-
if (!aliasMap.hasOwnProperty(publicName)) {
|
|
12599
|
-
continue;
|
|
12600
|
-
}
|
|
12601
|
-
const value = aliasMap[publicName];
|
|
12602
|
-
if (value === undefined) {
|
|
12603
|
-
continue;
|
|
12604
|
-
}
|
|
12605
|
-
bindingsResult ??= {};
|
|
12606
|
-
let internalName;
|
|
12607
|
-
let inputFlags = InputFlags.None;
|
|
12608
|
-
// For inputs, the value might be an array capturing additional
|
|
12609
|
-
// input flags.
|
|
12610
|
-
if (Array.isArray(value)) {
|
|
12611
|
-
internalName = value[0];
|
|
12612
|
-
inputFlags = value[1];
|
|
12613
|
-
}
|
|
12614
|
-
else {
|
|
12615
|
-
internalName = value;
|
|
12616
|
-
}
|
|
12617
|
-
// If there are no host directive mappings, we want to remap using the alias map from the
|
|
12618
|
-
// definition itself. If there is an alias map, it has two functions:
|
|
12619
|
-
// 1. It serves as an allowlist of bindings that are exposed by the host directives. Only the
|
|
12620
|
-
// ones inside the host directive map will be exposed on the host.
|
|
12621
|
-
// 2. The public name of the property is aliased using the host directive alias map, rather
|
|
12622
|
-
// than the alias map from the definition.
|
|
12623
|
-
let finalPublicName = publicName;
|
|
12624
|
-
if (hostDirectiveAliasMap !== null) {
|
|
12625
|
-
// If there is no mapping, it's not part of the allowlist and this input/output
|
|
12626
|
-
// is not captured and should be ignored.
|
|
12627
|
-
if (!hostDirectiveAliasMap.hasOwnProperty(publicName)) {
|
|
12628
|
-
continue;
|
|
12629
|
-
}
|
|
12630
|
-
finalPublicName = hostDirectiveAliasMap[publicName];
|
|
12631
|
-
}
|
|
12632
|
-
if (mode === 0 /* CaptureNodeBindingMode.Inputs */) {
|
|
12633
|
-
addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName, inputFlags);
|
|
12634
|
-
}
|
|
12635
|
-
else {
|
|
12636
|
-
addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName);
|
|
12637
|
-
}
|
|
12638
|
-
}
|
|
12639
|
-
return bindingsResult;
|
|
12640
|
-
}
|
|
12641
|
-
function addPropertyBinding(bindings, directiveIndex, publicName, internalName, inputFlags) {
|
|
12642
|
-
let values;
|
|
12643
|
-
if (bindings.hasOwnProperty(publicName)) {
|
|
12644
|
-
(values = bindings[publicName]).push(directiveIndex, internalName);
|
|
12645
|
-
}
|
|
12646
|
-
else {
|
|
12647
|
-
values = bindings[publicName] = [directiveIndex, internalName];
|
|
12648
|
-
}
|
|
12649
|
-
if (inputFlags !== undefined) {
|
|
12650
|
-
values.push(inputFlags);
|
|
12651
|
-
}
|
|
12652
|
-
}
|
|
12653
|
-
/**
|
|
12654
|
-
* Initializes data structures required to work with directive inputs and outputs.
|
|
12655
|
-
* Initialization is done for all directives matched on a given TNode.
|
|
12656
|
-
*/
|
|
12657
|
-
function initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefinitionMap) {
|
|
12658
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
12659
|
-
const start = tNode.directiveStart;
|
|
12660
|
-
const end = tNode.directiveEnd;
|
|
12661
|
-
const tViewData = tView.data;
|
|
12662
|
-
const tNodeAttrs = tNode.attrs;
|
|
12663
|
-
const inputsFromAttrs = [];
|
|
12664
|
-
let inputsStore = null;
|
|
12665
|
-
let outputsStore = null;
|
|
12666
|
-
for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
|
|
12667
|
-
const directiveDef = tViewData[directiveIndex];
|
|
12668
|
-
const aliasData = hostDirectiveDefinitionMap
|
|
12669
|
-
? hostDirectiveDefinitionMap.get(directiveDef)
|
|
12670
|
-
: null;
|
|
12671
|
-
const aliasedInputs = aliasData ? aliasData.inputs : null;
|
|
12672
|
-
const aliasedOutputs = aliasData ? aliasData.outputs : null;
|
|
12673
|
-
inputsStore = captureNodeBindings(0 /* CaptureNodeBindingMode.Inputs */, directiveDef.inputs, directiveIndex, inputsStore, aliasedInputs);
|
|
12674
|
-
outputsStore = captureNodeBindings(1 /* CaptureNodeBindingMode.Outputs */, directiveDef.outputs, directiveIndex, outputsStore, aliasedOutputs);
|
|
12675
|
-
// Do not use unbound attributes as inputs to structural directives, since structural
|
|
12676
|
-
// directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
|
|
12677
|
-
// TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
|
|
12678
|
-
// should be set for inline templates.
|
|
12679
|
-
const initialInputs = inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)
|
|
12680
|
-
? generateInitialInputs(inputsStore, directiveIndex, tNodeAttrs)
|
|
12681
|
-
: null;
|
|
12682
|
-
inputsFromAttrs.push(initialInputs);
|
|
12683
|
-
}
|
|
12684
|
-
if (inputsStore !== null) {
|
|
12685
|
-
if (inputsStore.hasOwnProperty('class')) {
|
|
12686
|
-
tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
|
|
12687
|
-
}
|
|
12688
|
-
if (inputsStore.hasOwnProperty('style')) {
|
|
12689
|
-
tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
|
|
12690
|
-
}
|
|
12691
|
-
}
|
|
12692
|
-
tNode.initialInputs = inputsFromAttrs;
|
|
12693
|
-
tNode.inputs = inputsStore;
|
|
12694
|
-
tNode.outputs = outputsStore;
|
|
12695
|
-
}
|
|
12696
12535
|
/**
|
|
12697
12536
|
* Mapping between attributes names that don't correspond to their element property names.
|
|
12698
12537
|
*
|
|
@@ -12793,126 +12632,6 @@ function setNgReflectProperties(lView, element, type, dataValue, value) {
|
|
|
12793
12632
|
}
|
|
12794
12633
|
}
|
|
12795
12634
|
}
|
|
12796
|
-
/**
|
|
12797
|
-
* Resolve the matched directives on a node.
|
|
12798
|
-
*/
|
|
12799
|
-
function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
12800
|
-
// Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
|
|
12801
|
-
// tsickle.
|
|
12802
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
12803
|
-
if (getBindingsEnabled()) {
|
|
12804
|
-
const exportsMap = localRefs === null ? null : { '': -1 };
|
|
12805
|
-
const matchedDirectiveDefs = findDirectiveDefMatches(tView, tNode);
|
|
12806
|
-
if (matchedDirectiveDefs !== null) {
|
|
12807
|
-
const [directiveDefs, hostDirectiveDefs] = resolveHostDirectives(tView, tNode, matchedDirectiveDefs);
|
|
12808
|
-
initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
|
|
12809
|
-
}
|
|
12810
|
-
if (exportsMap)
|
|
12811
|
-
cacheMatchingLocalNames(tNode, localRefs, exportsMap);
|
|
12812
|
-
}
|
|
12813
|
-
// Merge the template attrs last so that they have the highest priority.
|
|
12814
|
-
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
12815
|
-
}
|
|
12816
|
-
/** Initializes the data structures necessary for a list of directives to be instantiated. */
|
|
12817
|
-
function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
|
|
12818
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
12819
|
-
// Publishes the directive types to DI so they can be injected. Needs to
|
|
12820
|
-
// happen in a separate pass before the TNode flags have been initialized.
|
|
12821
|
-
for (let i = 0; i < directives.length; i++) {
|
|
12822
|
-
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directives[i].type);
|
|
12823
|
-
}
|
|
12824
|
-
initTNodeFlags(tNode, tView.data.length, directives.length);
|
|
12825
|
-
// When the same token is provided by several directives on the same node, some rules apply in
|
|
12826
|
-
// the viewEngine:
|
|
12827
|
-
// - viewProviders have priority over providers
|
|
12828
|
-
// - the last directive in NgModule.declarations has priority over the previous one
|
|
12829
|
-
// So to match these rules, the order in which providers are added in the arrays is very
|
|
12830
|
-
// important.
|
|
12831
|
-
for (let i = 0; i < directives.length; i++) {
|
|
12832
|
-
const def = directives[i];
|
|
12833
|
-
if (def.providersResolver)
|
|
12834
|
-
def.providersResolver(def);
|
|
12835
|
-
}
|
|
12836
|
-
let preOrderHooksFound = false;
|
|
12837
|
-
let preOrderCheckHooksFound = false;
|
|
12838
|
-
let directiveIdx = allocExpando(tView, lView, directives.length, null);
|
|
12839
|
-
ngDevMode &&
|
|
12840
|
-
assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
|
|
12841
|
-
for (let i = 0; i < directives.length; i++) {
|
|
12842
|
-
const def = directives[i];
|
|
12843
|
-
// Merge the attrs in the order of matches. This assumes that the first directive is the
|
|
12844
|
-
// component itself, so that the component has the least priority.
|
|
12845
|
-
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
|
|
12846
|
-
configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
|
|
12847
|
-
saveNameToExportMap(directiveIdx, def, exportsMap);
|
|
12848
|
-
if (def.contentQueries !== null)
|
|
12849
|
-
tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
|
|
12850
|
-
if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
|
|
12851
|
-
tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
|
|
12852
|
-
const lifeCycleHooks = def.type.prototype;
|
|
12853
|
-
// Only push a node index into the preOrderHooks array if this is the first
|
|
12854
|
-
// pre-order hook found on this node.
|
|
12855
|
-
if (!preOrderHooksFound &&
|
|
12856
|
-
(lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
|
|
12857
|
-
// We will push the actual hook function into this array later during dir instantiation.
|
|
12858
|
-
// We cannot do it now because we must ensure hooks are registered in the same
|
|
12859
|
-
// order that directives are created (i.e. injection order).
|
|
12860
|
-
(tView.preOrderHooks ??= []).push(tNode.index);
|
|
12861
|
-
preOrderHooksFound = true;
|
|
12862
|
-
}
|
|
12863
|
-
if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
|
|
12864
|
-
(tView.preOrderCheckHooks ??= []).push(tNode.index);
|
|
12865
|
-
preOrderCheckHooksFound = true;
|
|
12866
|
-
}
|
|
12867
|
-
directiveIdx++;
|
|
12868
|
-
}
|
|
12869
|
-
initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefs);
|
|
12870
|
-
}
|
|
12871
|
-
/**
|
|
12872
|
-
* Add `hostBindings` to the `TView.hostBindingOpCodes`.
|
|
12873
|
-
*
|
|
12874
|
-
* @param tView `TView` to which the `hostBindings` should be added.
|
|
12875
|
-
* @param tNode `TNode` the element which contains the directive
|
|
12876
|
-
* @param directiveIdx Directive index in view.
|
|
12877
|
-
* @param directiveVarsIdx Where will the directive's vars be stored
|
|
12878
|
-
* @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
|
|
12879
|
-
*/
|
|
12880
|
-
function registerHostBindingOpCodes(tView, tNode, directiveIdx, directiveVarsIdx, def) {
|
|
12881
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
12882
|
-
const hostBindings = def.hostBindings;
|
|
12883
|
-
if (hostBindings) {
|
|
12884
|
-
let hostBindingOpCodes = tView.hostBindingOpCodes;
|
|
12885
|
-
if (hostBindingOpCodes === null) {
|
|
12886
|
-
hostBindingOpCodes = tView.hostBindingOpCodes = [];
|
|
12887
|
-
}
|
|
12888
|
-
const elementIndx = ~tNode.index;
|
|
12889
|
-
if (lastSelectedElementIdx(hostBindingOpCodes) != elementIndx) {
|
|
12890
|
-
// Conditionally add select element so that we are more efficient in execution.
|
|
12891
|
-
// NOTE: this is strictly not necessary and it trades code size for runtime perf.
|
|
12892
|
-
// (We could just always add it.)
|
|
12893
|
-
hostBindingOpCodes.push(elementIndx);
|
|
12894
|
-
}
|
|
12895
|
-
hostBindingOpCodes.push(directiveIdx, directiveVarsIdx, hostBindings);
|
|
12896
|
-
}
|
|
12897
|
-
}
|
|
12898
|
-
/**
|
|
12899
|
-
* Returns the last selected element index in the `HostBindingOpCodes`
|
|
12900
|
-
*
|
|
12901
|
-
* For perf reasons we don't need to update the selected element index in `HostBindingOpCodes` only
|
|
12902
|
-
* if it changes. This method returns the last index (or '0' if not found.)
|
|
12903
|
-
*
|
|
12904
|
-
* Selected element index are only the ones which are negative.
|
|
12905
|
-
*/
|
|
12906
|
-
function lastSelectedElementIdx(hostBindingOpCodes) {
|
|
12907
|
-
let i = hostBindingOpCodes.length;
|
|
12908
|
-
while (i > 0) {
|
|
12909
|
-
const value = hostBindingOpCodes[--i];
|
|
12910
|
-
if (typeof value === 'number' && value < 0) {
|
|
12911
|
-
return value;
|
|
12912
|
-
}
|
|
12913
|
-
}
|
|
12914
|
-
return 0;
|
|
12915
|
-
}
|
|
12916
12635
|
/**
|
|
12917
12636
|
* Instantiate all the directives that were previously resolved on the current node.
|
|
12918
12637
|
*/
|
|
@@ -13006,121 +12725,6 @@ function findDirectiveDefMatches(tView, tNode) {
|
|
|
13006
12725
|
}
|
|
13007
12726
|
return matches;
|
|
13008
12727
|
}
|
|
13009
|
-
function resolveHostDirectives(tView, tNode, matches) {
|
|
13010
|
-
const allDirectiveDefs = [];
|
|
13011
|
-
let hostDirectiveDefs = null;
|
|
13012
|
-
for (const def of matches) {
|
|
13013
|
-
if (def.findHostDirectiveDefs !== null) {
|
|
13014
|
-
// TODO(pk): probably could return matches instead of taking in an array to fill in?
|
|
13015
|
-
hostDirectiveDefs ??= new Map();
|
|
13016
|
-
// Components are inserted at the front of the matches array so that their lifecycle
|
|
13017
|
-
// hooks run before any directive lifecycle hooks. This appears to be for ViewEngine
|
|
13018
|
-
// compatibility. This logic doesn't make sense with host directives, because it
|
|
13019
|
-
// would allow the host directives to undo any overrides the host may have made.
|
|
13020
|
-
// To handle this case, the host directives of components are inserted at the beginning
|
|
13021
|
-
// of the array, followed by the component. As such, the insertion order is as follows:
|
|
13022
|
-
// 1. Host directives belonging to the selector-matched component.
|
|
13023
|
-
// 2. Selector-matched component.
|
|
13024
|
-
// 3. Host directives belonging to selector-matched directives.
|
|
13025
|
-
// 4. Selector-matched directives.
|
|
13026
|
-
def.findHostDirectiveDefs(def, allDirectiveDefs, hostDirectiveDefs);
|
|
13027
|
-
}
|
|
13028
|
-
if (isComponentDef(def)) {
|
|
13029
|
-
allDirectiveDefs.push(def);
|
|
13030
|
-
markAsComponentHost(tView, tNode, allDirectiveDefs.length - 1);
|
|
13031
|
-
}
|
|
13032
|
-
}
|
|
13033
|
-
if (isComponentHost(tNode)) {
|
|
13034
|
-
allDirectiveDefs.push(...matches.slice(1));
|
|
13035
|
-
}
|
|
13036
|
-
else {
|
|
13037
|
-
allDirectiveDefs.push(...matches);
|
|
13038
|
-
}
|
|
13039
|
-
if (ngDevMode) {
|
|
13040
|
-
assertNoDuplicateDirectives(allDirectiveDefs);
|
|
13041
|
-
}
|
|
13042
|
-
return [allDirectiveDefs, hostDirectiveDefs];
|
|
13043
|
-
}
|
|
13044
|
-
/**
|
|
13045
|
-
* Marks a given TNode as a component's host. This consists of:
|
|
13046
|
-
* - setting the component offset on the TNode.
|
|
13047
|
-
* - storing index of component's host element so it will be queued for view refresh during CD.
|
|
13048
|
-
*/
|
|
13049
|
-
function markAsComponentHost(tView, hostTNode, componentOffset) {
|
|
13050
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
13051
|
-
ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
|
|
13052
|
-
hostTNode.componentOffset = componentOffset;
|
|
13053
|
-
(tView.components ??= []).push(hostTNode.index);
|
|
13054
|
-
}
|
|
13055
|
-
/** Caches local names and their matching directive indices for query and template lookups. */
|
|
13056
|
-
function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
|
|
13057
|
-
if (localRefs) {
|
|
13058
|
-
const localNames = (tNode.localNames = []);
|
|
13059
|
-
// Local names must be stored in tNode in the same order that localRefs are defined
|
|
13060
|
-
// in the template to ensure the data is loaded in the same slots as their refs
|
|
13061
|
-
// in the template (for template queries).
|
|
13062
|
-
for (let i = 0; i < localRefs.length; i += 2) {
|
|
13063
|
-
const index = exportsMap[localRefs[i + 1]];
|
|
13064
|
-
if (index == null)
|
|
13065
|
-
throw new RuntimeError(-301 /* RuntimeErrorCode.EXPORT_NOT_FOUND */, ngDevMode && `Export of name '${localRefs[i + 1]}' not found!`);
|
|
13066
|
-
localNames.push(localRefs[i], index);
|
|
13067
|
-
}
|
|
13068
|
-
}
|
|
13069
|
-
}
|
|
13070
|
-
/**
|
|
13071
|
-
* Builds up an export map as directives are created, so local refs can be quickly mapped
|
|
13072
|
-
* to their directive instances.
|
|
13073
|
-
*/
|
|
13074
|
-
function saveNameToExportMap(directiveIdx, def, exportsMap) {
|
|
13075
|
-
if (exportsMap) {
|
|
13076
|
-
if (def.exportAs) {
|
|
13077
|
-
for (let i = 0; i < def.exportAs.length; i++) {
|
|
13078
|
-
exportsMap[def.exportAs[i]] = directiveIdx;
|
|
13079
|
-
}
|
|
13080
|
-
}
|
|
13081
|
-
if (isComponentDef(def))
|
|
13082
|
-
exportsMap[''] = directiveIdx;
|
|
13083
|
-
}
|
|
13084
|
-
}
|
|
13085
|
-
/**
|
|
13086
|
-
* Initializes the flags on the current node, setting all indices to the initial index,
|
|
13087
|
-
* the directive count to 0, and adding the isComponent flag.
|
|
13088
|
-
* @param index the initial index
|
|
13089
|
-
*/
|
|
13090
|
-
function initTNodeFlags(tNode, index, numberOfDirectives) {
|
|
13091
|
-
ngDevMode &&
|
|
13092
|
-
assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
|
|
13093
|
-
tNode.flags |= 1 /* TNodeFlags.isDirectiveHost */;
|
|
13094
|
-
// When the first directive is created on a node, save the index
|
|
13095
|
-
tNode.directiveStart = index;
|
|
13096
|
-
tNode.directiveEnd = index + numberOfDirectives;
|
|
13097
|
-
tNode.providerIndexes = index;
|
|
13098
|
-
}
|
|
13099
|
-
/**
|
|
13100
|
-
* Setup directive for instantiation.
|
|
13101
|
-
*
|
|
13102
|
-
* We need to create a `NodeInjectorFactory` which is then inserted in both the `Blueprint` as well
|
|
13103
|
-
* as `LView`. `TView` gets the `DirectiveDef`.
|
|
13104
|
-
*
|
|
13105
|
-
* @param tView `TView`
|
|
13106
|
-
* @param tNode `TNode`
|
|
13107
|
-
* @param lView `LView`
|
|
13108
|
-
* @param directiveIndex Index where the directive will be stored in the Expando.
|
|
13109
|
-
* @param def `DirectiveDef`
|
|
13110
|
-
*/
|
|
13111
|
-
function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
|
|
13112
|
-
ngDevMode &&
|
|
13113
|
-
assertGreaterThanOrEqual(directiveIndex, HEADER_OFFSET, 'Must be in Expando section');
|
|
13114
|
-
tView.data[directiveIndex] = def;
|
|
13115
|
-
const directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true));
|
|
13116
|
-
// Even though `directiveFactory` will already be using `ɵɵdirectiveInject` in its generated code,
|
|
13117
|
-
// we also want to support `inject()` directly from the directive constructor context so we set
|
|
13118
|
-
// `ɵɵdirectiveInject` as the inject implementation here too.
|
|
13119
|
-
const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), ɵɵdirectiveInject);
|
|
13120
|
-
tView.blueprint[directiveIndex] = nodeInjectorFactory;
|
|
13121
|
-
lView[directiveIndex] = nodeInjectorFactory;
|
|
13122
|
-
registerHostBindingOpCodes(tView, tNode, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
|
|
13123
|
-
}
|
|
13124
12728
|
/**
|
|
13125
12729
|
* Gets the initial set of LView flags based on the component definition that the LView represents.
|
|
13126
12730
|
* @param def Component definition from which to determine the flags.
|
|
@@ -13192,58 +12796,6 @@ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initial
|
|
|
13192
12796
|
}
|
|
13193
12797
|
}
|
|
13194
12798
|
}
|
|
13195
|
-
/**
|
|
13196
|
-
* Generates initialInputData for a node and stores it in the template's static storage
|
|
13197
|
-
* so subsequent template invocations don't have to recalculate it.
|
|
13198
|
-
*
|
|
13199
|
-
* initialInputData is an array containing values that need to be set as input properties
|
|
13200
|
-
* for directives on this node, but only once on creation. We need this array to support
|
|
13201
|
-
* the case where you set an @Input property of a directive using attribute-like syntax.
|
|
13202
|
-
* e.g. if you have a `name` @Input, you can set it once like this:
|
|
13203
|
-
*
|
|
13204
|
-
* <my-component name="Bess"></my-component>
|
|
13205
|
-
*
|
|
13206
|
-
* @param inputs Input alias map that was generated from the directive def inputs.
|
|
13207
|
-
* @param directiveIndex Index of the directive that is currently being processed.
|
|
13208
|
-
* @param attrs Static attrs on this node.
|
|
13209
|
-
*/
|
|
13210
|
-
function generateInitialInputs(inputs, directiveIndex, attrs) {
|
|
13211
|
-
let inputsToStore = null;
|
|
13212
|
-
let i = 0;
|
|
13213
|
-
while (i < attrs.length) {
|
|
13214
|
-
const attrName = attrs[i];
|
|
13215
|
-
if (attrName === 0 /* AttributeMarker.NamespaceURI */) {
|
|
13216
|
-
// We do not allow inputs on namespaced attributes.
|
|
13217
|
-
i += 4;
|
|
13218
|
-
continue;
|
|
13219
|
-
}
|
|
13220
|
-
else if (attrName === 5 /* AttributeMarker.ProjectAs */) {
|
|
13221
|
-
// Skip over the `ngProjectAs` value.
|
|
13222
|
-
i += 2;
|
|
13223
|
-
continue;
|
|
13224
|
-
}
|
|
13225
|
-
// If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
|
|
13226
|
-
if (typeof attrName === 'number')
|
|
13227
|
-
break;
|
|
13228
|
-
if (inputs.hasOwnProperty(attrName)) {
|
|
13229
|
-
if (inputsToStore === null)
|
|
13230
|
-
inputsToStore = [];
|
|
13231
|
-
// Find the input's public name from the input store. Note that we can be found easier
|
|
13232
|
-
// through the directive def, but we want to do it using the inputs store so that it can
|
|
13233
|
-
// account for host directive aliases.
|
|
13234
|
-
const inputConfig = inputs[attrName];
|
|
13235
|
-
for (let j = 0; j < inputConfig.length; j += 3) {
|
|
13236
|
-
if (inputConfig[j] === directiveIndex) {
|
|
13237
|
-
inputsToStore.push(attrName, inputConfig[j + 1], inputConfig[j + 2], attrs[i + 1]);
|
|
13238
|
-
// A directive can't have multiple inputs with the same name so we can break here.
|
|
13239
|
-
break;
|
|
13240
|
-
}
|
|
13241
|
-
}
|
|
13242
|
-
}
|
|
13243
|
-
i += 2;
|
|
13244
|
-
}
|
|
13245
|
-
return inputsToStore;
|
|
13246
|
-
}
|
|
13247
12799
|
//////////////////////////
|
|
13248
12800
|
//// ViewContainer & View
|
|
13249
12801
|
//////////////////////////
|
|
@@ -17778,6 +17330,492 @@ function computeStaticStyling(tNode, attrs, writeToHost) {
|
|
|
17778
17330
|
writeToHost ? (tNode.classes = classes) : (tNode.classesWithoutHost = classes);
|
|
17779
17331
|
}
|
|
17780
17332
|
|
|
17333
|
+
function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
|
|
17334
|
+
const lView = getLView();
|
|
17335
|
+
// Fall back to inject() if view hasn't been created. This situation can happen in tests
|
|
17336
|
+
// if inject utilities are used before bootstrapping.
|
|
17337
|
+
if (lView === null) {
|
|
17338
|
+
// Verify that we will not get into infinite loop.
|
|
17339
|
+
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
|
17340
|
+
return ɵɵinject(token, flags);
|
|
17341
|
+
}
|
|
17342
|
+
const tNode = getCurrentTNode();
|
|
17343
|
+
const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
17344
|
+
ngDevMode && emitInjectEvent(token, value, flags);
|
|
17345
|
+
return value;
|
|
17346
|
+
}
|
|
17347
|
+
/**
|
|
17348
|
+
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
17349
|
+
* particular class.
|
|
17350
|
+
*
|
|
17351
|
+
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
17352
|
+
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
17353
|
+
*
|
|
17354
|
+
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
17355
|
+
* and thus in the stack trace.
|
|
17356
|
+
*
|
|
17357
|
+
* @codeGenApi
|
|
17358
|
+
*/
|
|
17359
|
+
function ɵɵinvalidFactory() {
|
|
17360
|
+
const msg = ngDevMode
|
|
17361
|
+
? `This constructor was not compatible with Dependency Injection.`
|
|
17362
|
+
: 'invalid';
|
|
17363
|
+
throw new Error(msg);
|
|
17364
|
+
}
|
|
17365
|
+
|
|
17366
|
+
/**
|
|
17367
|
+
* When elements are created dynamically after a view blueprint is created (e.g. through
|
|
17368
|
+
* i18nApply()), we need to adjust the blueprint for future template passes.
|
|
17369
|
+
*
|
|
17370
|
+
* @param tView `TView` associated with `LView`
|
|
17371
|
+
* @param lView The `LView` containing the blueprint to adjust
|
|
17372
|
+
* @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
|
|
17373
|
+
* @param initialValue Initial value to store in blueprint
|
|
17374
|
+
*/
|
|
17375
|
+
function allocExpando(tView, lView, numSlotsToAlloc, initialValue) {
|
|
17376
|
+
if (numSlotsToAlloc === 0)
|
|
17377
|
+
return -1;
|
|
17378
|
+
if (ngDevMode) {
|
|
17379
|
+
assertFirstCreatePass(tView);
|
|
17380
|
+
assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
|
|
17381
|
+
assertEqual(tView.data.length, lView.length, 'Expecting LView to be same size as TView');
|
|
17382
|
+
assertEqual(tView.data.length, tView.blueprint.length, 'Expecting Blueprint to be same size as TView');
|
|
17383
|
+
assertFirstUpdatePass(tView);
|
|
17384
|
+
}
|
|
17385
|
+
const allocIdx = lView.length;
|
|
17386
|
+
for (let i = 0; i < numSlotsToAlloc; i++) {
|
|
17387
|
+
lView.push(initialValue);
|
|
17388
|
+
tView.blueprint.push(initialValue);
|
|
17389
|
+
tView.data.push(null);
|
|
17390
|
+
}
|
|
17391
|
+
return allocIdx;
|
|
17392
|
+
}
|
|
17393
|
+
|
|
17394
|
+
/**
|
|
17395
|
+
* Resolve the matched directives on a node.
|
|
17396
|
+
*/
|
|
17397
|
+
function resolveDirectives(tView, lView, tNode, localRefs, directiveMatcher) {
|
|
17398
|
+
// Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
|
|
17399
|
+
// tsickle.
|
|
17400
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17401
|
+
const exportsMap = localRefs === null ? null : { '': -1 };
|
|
17402
|
+
const matchedDirectiveDefs = directiveMatcher(tView, tNode);
|
|
17403
|
+
if (matchedDirectiveDefs !== null) {
|
|
17404
|
+
const [directiveDefs, hostDirectiveDefs] = resolveHostDirectives(tView, tNode, matchedDirectiveDefs);
|
|
17405
|
+
initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
|
|
17406
|
+
}
|
|
17407
|
+
if (exportsMap !== null && localRefs !== null) {
|
|
17408
|
+
cacheMatchingLocalNames(tNode, localRefs, exportsMap);
|
|
17409
|
+
}
|
|
17410
|
+
}
|
|
17411
|
+
/** Caches local names and their matching directive indices for query and template lookups. */
|
|
17412
|
+
function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
|
|
17413
|
+
const localNames = (tNode.localNames = []);
|
|
17414
|
+
// Local names must be stored in tNode in the same order that localRefs are defined
|
|
17415
|
+
// in the template to ensure the data is loaded in the same slots as their refs
|
|
17416
|
+
// in the template (for template queries).
|
|
17417
|
+
for (let i = 0; i < localRefs.length; i += 2) {
|
|
17418
|
+
const index = exportsMap[localRefs[i + 1]];
|
|
17419
|
+
if (index == null)
|
|
17420
|
+
throw new RuntimeError(-301 /* RuntimeErrorCode.EXPORT_NOT_FOUND */, ngDevMode && `Export of name '${localRefs[i + 1]}' not found!`);
|
|
17421
|
+
localNames.push(localRefs[i], index);
|
|
17422
|
+
}
|
|
17423
|
+
}
|
|
17424
|
+
function resolveHostDirectives(tView, tNode, matches) {
|
|
17425
|
+
const allDirectiveDefs = [];
|
|
17426
|
+
let hostDirectiveDefs = null;
|
|
17427
|
+
for (const def of matches) {
|
|
17428
|
+
if (def.findHostDirectiveDefs !== null) {
|
|
17429
|
+
// TODO(pk): probably could return matches instead of taking in an array to fill in?
|
|
17430
|
+
hostDirectiveDefs ??= new Map();
|
|
17431
|
+
// Components are inserted at the front of the matches array so that their lifecycle
|
|
17432
|
+
// hooks run before any directive lifecycle hooks. This appears to be for ViewEngine
|
|
17433
|
+
// compatibility. This logic doesn't make sense with host directives, because it
|
|
17434
|
+
// would allow the host directives to undo any overrides the host may have made.
|
|
17435
|
+
// To handle this case, the host directives of components are inserted at the beginning
|
|
17436
|
+
// of the array, followed by the component. As such, the insertion order is as follows:
|
|
17437
|
+
// 1. Host directives belonging to the selector-matched component.
|
|
17438
|
+
// 2. Selector-matched component.
|
|
17439
|
+
// 3. Host directives belonging to selector-matched directives.
|
|
17440
|
+
// 4. Selector-matched directives.
|
|
17441
|
+
def.findHostDirectiveDefs(def, allDirectiveDefs, hostDirectiveDefs);
|
|
17442
|
+
}
|
|
17443
|
+
if (isComponentDef(def)) {
|
|
17444
|
+
allDirectiveDefs.push(def);
|
|
17445
|
+
markAsComponentHost(tView, tNode, allDirectiveDefs.length - 1);
|
|
17446
|
+
}
|
|
17447
|
+
}
|
|
17448
|
+
if (isComponentHost(tNode)) {
|
|
17449
|
+
allDirectiveDefs.push(...matches.slice(1));
|
|
17450
|
+
}
|
|
17451
|
+
else {
|
|
17452
|
+
allDirectiveDefs.push(...matches);
|
|
17453
|
+
}
|
|
17454
|
+
if (ngDevMode) {
|
|
17455
|
+
assertNoDuplicateDirectives(allDirectiveDefs);
|
|
17456
|
+
}
|
|
17457
|
+
return [allDirectiveDefs, hostDirectiveDefs];
|
|
17458
|
+
}
|
|
17459
|
+
/**
|
|
17460
|
+
* Marks a given TNode as a component's host. This consists of:
|
|
17461
|
+
* - setting the component offset on the TNode.
|
|
17462
|
+
* - storing index of component's host element so it will be queued for view refresh during CD.
|
|
17463
|
+
*/
|
|
17464
|
+
function markAsComponentHost(tView, hostTNode, componentOffset) {
|
|
17465
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17466
|
+
ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
|
|
17467
|
+
hostTNode.componentOffset = componentOffset;
|
|
17468
|
+
(tView.components ??= []).push(hostTNode.index);
|
|
17469
|
+
}
|
|
17470
|
+
/** Initializes the data structures necessary for a list of directives to be instantiated. */
|
|
17471
|
+
function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
|
|
17472
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17473
|
+
// Publishes the directive types to DI so they can be injected. Needs to
|
|
17474
|
+
// happen in a separate pass before the TNode flags have been initialized.
|
|
17475
|
+
for (let i = 0; i < directives.length; i++) {
|
|
17476
|
+
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directives[i].type);
|
|
17477
|
+
}
|
|
17478
|
+
initTNodeFlags(tNode, tView.data.length, directives.length);
|
|
17479
|
+
// When the same token is provided by several directives on the same node, some rules apply in
|
|
17480
|
+
// the viewEngine:
|
|
17481
|
+
// - viewProviders have priority over providers
|
|
17482
|
+
// - the last directive in NgModule.declarations has priority over the previous one
|
|
17483
|
+
// So to match these rules, the order in which providers are added in the arrays is very
|
|
17484
|
+
// important.
|
|
17485
|
+
for (let i = 0; i < directives.length; i++) {
|
|
17486
|
+
const def = directives[i];
|
|
17487
|
+
if (def.providersResolver)
|
|
17488
|
+
def.providersResolver(def);
|
|
17489
|
+
}
|
|
17490
|
+
let preOrderHooksFound = false;
|
|
17491
|
+
let preOrderCheckHooksFound = false;
|
|
17492
|
+
let directiveIdx = allocExpando(tView, lView, directives.length, null);
|
|
17493
|
+
ngDevMode &&
|
|
17494
|
+
assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
|
|
17495
|
+
for (let i = 0; i < directives.length; i++) {
|
|
17496
|
+
const def = directives[i];
|
|
17497
|
+
// Merge the attrs in the order of matches. This assumes that the first directive is the
|
|
17498
|
+
// component itself, so that the component has the least priority.
|
|
17499
|
+
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
|
|
17500
|
+
configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
|
|
17501
|
+
saveNameToExportMap(directiveIdx, def, exportsMap);
|
|
17502
|
+
if (def.contentQueries !== null)
|
|
17503
|
+
tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
|
|
17504
|
+
if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
|
|
17505
|
+
tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
|
|
17506
|
+
const lifeCycleHooks = def.type.prototype;
|
|
17507
|
+
// Only push a node index into the preOrderHooks array if this is the first
|
|
17508
|
+
// pre-order hook found on this node.
|
|
17509
|
+
if (!preOrderHooksFound &&
|
|
17510
|
+
(lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
|
|
17511
|
+
// We will push the actual hook function into this array later during dir instantiation.
|
|
17512
|
+
// We cannot do it now because we must ensure hooks are registered in the same
|
|
17513
|
+
// order that directives are created (i.e. injection order).
|
|
17514
|
+
(tView.preOrderHooks ??= []).push(tNode.index);
|
|
17515
|
+
preOrderHooksFound = true;
|
|
17516
|
+
}
|
|
17517
|
+
if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
|
|
17518
|
+
(tView.preOrderCheckHooks ??= []).push(tNode.index);
|
|
17519
|
+
preOrderCheckHooksFound = true;
|
|
17520
|
+
}
|
|
17521
|
+
directiveIdx++;
|
|
17522
|
+
}
|
|
17523
|
+
initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefs);
|
|
17524
|
+
}
|
|
17525
|
+
/**
|
|
17526
|
+
* Initializes data structures required to work with directive inputs and outputs.
|
|
17527
|
+
* Initialization is done for all directives matched on a given TNode.
|
|
17528
|
+
*/
|
|
17529
|
+
function initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefinitionMap) {
|
|
17530
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17531
|
+
const start = tNode.directiveStart;
|
|
17532
|
+
const end = tNode.directiveEnd;
|
|
17533
|
+
const tViewData = tView.data;
|
|
17534
|
+
const tNodeAttrs = tNode.attrs;
|
|
17535
|
+
const inputsFromAttrs = [];
|
|
17536
|
+
let inputsStore = null;
|
|
17537
|
+
let outputsStore = null;
|
|
17538
|
+
for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
|
|
17539
|
+
const directiveDef = tViewData[directiveIndex];
|
|
17540
|
+
const aliasData = hostDirectiveDefinitionMap
|
|
17541
|
+
? hostDirectiveDefinitionMap.get(directiveDef)
|
|
17542
|
+
: null;
|
|
17543
|
+
const aliasedInputs = aliasData ? aliasData.inputs : null;
|
|
17544
|
+
const aliasedOutputs = aliasData ? aliasData.outputs : null;
|
|
17545
|
+
inputsStore = captureNodeBindings(0 /* CaptureNodeBindingMode.Inputs */, directiveDef.inputs, directiveIndex, inputsStore, aliasedInputs);
|
|
17546
|
+
outputsStore = captureNodeBindings(1 /* CaptureNodeBindingMode.Outputs */, directiveDef.outputs, directiveIndex, outputsStore, aliasedOutputs);
|
|
17547
|
+
// Do not use unbound attributes as inputs to structural directives, since structural
|
|
17548
|
+
// directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
|
|
17549
|
+
const initialInputs = inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)
|
|
17550
|
+
? generateInitialInputs(inputsStore, directiveIndex, tNodeAttrs)
|
|
17551
|
+
: null;
|
|
17552
|
+
inputsFromAttrs.push(initialInputs);
|
|
17553
|
+
}
|
|
17554
|
+
if (inputsStore !== null) {
|
|
17555
|
+
if (inputsStore.hasOwnProperty('class')) {
|
|
17556
|
+
tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
|
|
17557
|
+
}
|
|
17558
|
+
if (inputsStore.hasOwnProperty('style')) {
|
|
17559
|
+
tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
|
|
17560
|
+
}
|
|
17561
|
+
}
|
|
17562
|
+
tNode.initialInputs = inputsFromAttrs;
|
|
17563
|
+
tNode.inputs = inputsStore;
|
|
17564
|
+
tNode.outputs = outputsStore;
|
|
17565
|
+
}
|
|
17566
|
+
function captureNodeBindings(mode, aliasMap, directiveIndex, bindingsResult, hostDirectiveAliasMap) {
|
|
17567
|
+
for (let publicName in aliasMap) {
|
|
17568
|
+
if (!aliasMap.hasOwnProperty(publicName)) {
|
|
17569
|
+
continue;
|
|
17570
|
+
}
|
|
17571
|
+
const value = aliasMap[publicName];
|
|
17572
|
+
if (value === undefined) {
|
|
17573
|
+
continue;
|
|
17574
|
+
}
|
|
17575
|
+
bindingsResult ??= {};
|
|
17576
|
+
let internalName;
|
|
17577
|
+
let inputFlags = InputFlags.None;
|
|
17578
|
+
// For inputs, the value might be an array capturing additional
|
|
17579
|
+
// input flags.
|
|
17580
|
+
if (Array.isArray(value)) {
|
|
17581
|
+
internalName = value[0];
|
|
17582
|
+
inputFlags = value[1];
|
|
17583
|
+
}
|
|
17584
|
+
else {
|
|
17585
|
+
internalName = value;
|
|
17586
|
+
}
|
|
17587
|
+
// If there are no host directive mappings, we want to remap using the alias map from the
|
|
17588
|
+
// definition itself. If there is an alias map, it has two functions:
|
|
17589
|
+
// 1. It serves as an allowlist of bindings that are exposed by the host directives. Only the
|
|
17590
|
+
// ones inside the host directive map will be exposed on the host.
|
|
17591
|
+
// 2. The public name of the property is aliased using the host directive alias map, rather
|
|
17592
|
+
// than the alias map from the definition.
|
|
17593
|
+
let finalPublicName = publicName;
|
|
17594
|
+
if (hostDirectiveAliasMap !== null) {
|
|
17595
|
+
// If there is no mapping, it's not part of the allowlist and this input/output
|
|
17596
|
+
// is not captured and should be ignored.
|
|
17597
|
+
if (!hostDirectiveAliasMap.hasOwnProperty(publicName)) {
|
|
17598
|
+
continue;
|
|
17599
|
+
}
|
|
17600
|
+
finalPublicName = hostDirectiveAliasMap[publicName];
|
|
17601
|
+
}
|
|
17602
|
+
if (mode === 0 /* CaptureNodeBindingMode.Inputs */) {
|
|
17603
|
+
addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName, inputFlags);
|
|
17604
|
+
}
|
|
17605
|
+
else {
|
|
17606
|
+
addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName);
|
|
17607
|
+
}
|
|
17608
|
+
}
|
|
17609
|
+
return bindingsResult;
|
|
17610
|
+
}
|
|
17611
|
+
function addPropertyBinding(bindings, directiveIndex, publicName, internalName, inputFlags) {
|
|
17612
|
+
let values;
|
|
17613
|
+
if (bindings.hasOwnProperty(publicName)) {
|
|
17614
|
+
(values = bindings[publicName]).push(directiveIndex, internalName);
|
|
17615
|
+
}
|
|
17616
|
+
else {
|
|
17617
|
+
values = bindings[publicName] = [directiveIndex, internalName];
|
|
17618
|
+
}
|
|
17619
|
+
if (inputFlags !== undefined) {
|
|
17620
|
+
values.push(inputFlags);
|
|
17621
|
+
}
|
|
17622
|
+
}
|
|
17623
|
+
/**
|
|
17624
|
+
* Generates initialInputData for a node and stores it in the template's static storage
|
|
17625
|
+
* so subsequent template invocations don't have to recalculate it.
|
|
17626
|
+
*
|
|
17627
|
+
* initialInputData is an array containing values that need to be set as input properties
|
|
17628
|
+
* for directives on this node, but only once on creation. We need this array to support
|
|
17629
|
+
* the case where you set an @Input property of a directive using attribute-like syntax.
|
|
17630
|
+
* e.g. if you have a `name` @Input, you can set it once like this:
|
|
17631
|
+
*
|
|
17632
|
+
* <my-component name="Bess"></my-component>
|
|
17633
|
+
*
|
|
17634
|
+
* @param inputs Input alias map that was generated from the directive def inputs.
|
|
17635
|
+
* @param directiveIndex Index of the directive that is currently being processed.
|
|
17636
|
+
* @param attrs Static attrs on this node.
|
|
17637
|
+
*/
|
|
17638
|
+
function generateInitialInputs(inputs, directiveIndex, attrs) {
|
|
17639
|
+
let inputsToStore = null;
|
|
17640
|
+
let i = 0;
|
|
17641
|
+
while (i < attrs.length) {
|
|
17642
|
+
const attrName = attrs[i];
|
|
17643
|
+
if (attrName === 0 /* AttributeMarker.NamespaceURI */) {
|
|
17644
|
+
// We do not allow inputs on namespaced attributes.
|
|
17645
|
+
i += 4;
|
|
17646
|
+
continue;
|
|
17647
|
+
}
|
|
17648
|
+
else if (attrName === 5 /* AttributeMarker.ProjectAs */) {
|
|
17649
|
+
// Skip over the `ngProjectAs` value.
|
|
17650
|
+
i += 2;
|
|
17651
|
+
continue;
|
|
17652
|
+
}
|
|
17653
|
+
// If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
|
|
17654
|
+
if (typeof attrName === 'number')
|
|
17655
|
+
break;
|
|
17656
|
+
if (inputs.hasOwnProperty(attrName)) {
|
|
17657
|
+
if (inputsToStore === null)
|
|
17658
|
+
inputsToStore = [];
|
|
17659
|
+
// Find the input's public name from the input store. Note that we can be found easier
|
|
17660
|
+
// through the directive def, but we want to do it using the inputs store so that it can
|
|
17661
|
+
// account for host directive aliases.
|
|
17662
|
+
const inputConfig = inputs[attrName];
|
|
17663
|
+
for (let j = 0; j < inputConfig.length; j += 3) {
|
|
17664
|
+
if (inputConfig[j] === directiveIndex) {
|
|
17665
|
+
inputsToStore.push(attrName, inputConfig[j + 1], inputConfig[j + 2], attrs[i + 1]);
|
|
17666
|
+
// A directive can't have multiple inputs with the same name so we can break here.
|
|
17667
|
+
break;
|
|
17668
|
+
}
|
|
17669
|
+
}
|
|
17670
|
+
}
|
|
17671
|
+
i += 2;
|
|
17672
|
+
}
|
|
17673
|
+
return inputsToStore;
|
|
17674
|
+
}
|
|
17675
|
+
/**
|
|
17676
|
+
* Setup directive for instantiation.
|
|
17677
|
+
*
|
|
17678
|
+
* We need to create a `NodeInjectorFactory` which is then inserted in both the `Blueprint` as well
|
|
17679
|
+
* as `LView`. `TView` gets the `DirectiveDef`.
|
|
17680
|
+
*
|
|
17681
|
+
* @param tView `TView`
|
|
17682
|
+
* @param tNode `TNode`
|
|
17683
|
+
* @param lView `LView`
|
|
17684
|
+
* @param directiveIndex Index where the directive will be stored in the Expando.
|
|
17685
|
+
* @param def `DirectiveDef`
|
|
17686
|
+
*/
|
|
17687
|
+
function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
|
|
17688
|
+
ngDevMode &&
|
|
17689
|
+
assertGreaterThanOrEqual(directiveIndex, HEADER_OFFSET, 'Must be in Expando section');
|
|
17690
|
+
tView.data[directiveIndex] = def;
|
|
17691
|
+
const directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true));
|
|
17692
|
+
// Even though `directiveFactory` will already be using `ɵɵdirectiveInject` in its generated code,
|
|
17693
|
+
// we also want to support `inject()` directly from the directive constructor context so we set
|
|
17694
|
+
// `ɵɵdirectiveInject` as the inject implementation here too.
|
|
17695
|
+
const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), ɵɵdirectiveInject);
|
|
17696
|
+
tView.blueprint[directiveIndex] = nodeInjectorFactory;
|
|
17697
|
+
lView[directiveIndex] = nodeInjectorFactory;
|
|
17698
|
+
registerHostBindingOpCodes(tView, tNode, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
|
|
17699
|
+
}
|
|
17700
|
+
/**
|
|
17701
|
+
* Add `hostBindings` to the `TView.hostBindingOpCodes`.
|
|
17702
|
+
*
|
|
17703
|
+
* @param tView `TView` to which the `hostBindings` should be added.
|
|
17704
|
+
* @param tNode `TNode` the element which contains the directive
|
|
17705
|
+
* @param directiveIdx Directive index in view.
|
|
17706
|
+
* @param directiveVarsIdx Where will the directive's vars be stored
|
|
17707
|
+
* @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
|
|
17708
|
+
*/
|
|
17709
|
+
function registerHostBindingOpCodes(tView, tNode, directiveIdx, directiveVarsIdx, def) {
|
|
17710
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17711
|
+
const hostBindings = def.hostBindings;
|
|
17712
|
+
if (hostBindings) {
|
|
17713
|
+
let hostBindingOpCodes = tView.hostBindingOpCodes;
|
|
17714
|
+
if (hostBindingOpCodes === null) {
|
|
17715
|
+
hostBindingOpCodes = tView.hostBindingOpCodes = [];
|
|
17716
|
+
}
|
|
17717
|
+
const elementIndx = ~tNode.index;
|
|
17718
|
+
if (lastSelectedElementIdx(hostBindingOpCodes) != elementIndx) {
|
|
17719
|
+
// Conditionally add select element so that we are more efficient in execution.
|
|
17720
|
+
// NOTE: this is strictly not necessary and it trades code size for runtime perf.
|
|
17721
|
+
// (We could just always add it.)
|
|
17722
|
+
hostBindingOpCodes.push(elementIndx);
|
|
17723
|
+
}
|
|
17724
|
+
hostBindingOpCodes.push(directiveIdx, directiveVarsIdx, hostBindings);
|
|
17725
|
+
}
|
|
17726
|
+
}
|
|
17727
|
+
/**
|
|
17728
|
+
* Returns the last selected element index in the `HostBindingOpCodes`
|
|
17729
|
+
*
|
|
17730
|
+
* For perf reasons we don't need to update the selected element index in `HostBindingOpCodes` only
|
|
17731
|
+
* if it changes. This method returns the last index (or '0' if not found.)
|
|
17732
|
+
*
|
|
17733
|
+
* Selected element index are only the ones which are negative.
|
|
17734
|
+
*/
|
|
17735
|
+
function lastSelectedElementIdx(hostBindingOpCodes) {
|
|
17736
|
+
let i = hostBindingOpCodes.length;
|
|
17737
|
+
while (i > 0) {
|
|
17738
|
+
const value = hostBindingOpCodes[--i];
|
|
17739
|
+
if (typeof value === 'number' && value < 0) {
|
|
17740
|
+
return value;
|
|
17741
|
+
}
|
|
17742
|
+
}
|
|
17743
|
+
return 0;
|
|
17744
|
+
}
|
|
17745
|
+
/**
|
|
17746
|
+
* Builds up an export map as directives are created, so local refs can be quickly mapped
|
|
17747
|
+
* to their directive instances.
|
|
17748
|
+
*/
|
|
17749
|
+
function saveNameToExportMap(directiveIdx, def, exportsMap) {
|
|
17750
|
+
if (exportsMap) {
|
|
17751
|
+
if (def.exportAs) {
|
|
17752
|
+
for (let i = 0; i < def.exportAs.length; i++) {
|
|
17753
|
+
exportsMap[def.exportAs[i]] = directiveIdx;
|
|
17754
|
+
}
|
|
17755
|
+
}
|
|
17756
|
+
if (isComponentDef(def))
|
|
17757
|
+
exportsMap[''] = directiveIdx;
|
|
17758
|
+
}
|
|
17759
|
+
}
|
|
17760
|
+
/**
|
|
17761
|
+
* Initializes the flags on the current node, setting all indices to the initial index,
|
|
17762
|
+
* the directive count to 0, and adding the isComponent flag.
|
|
17763
|
+
* @param index the initial index
|
|
17764
|
+
*/
|
|
17765
|
+
function initTNodeFlags(tNode, index, numberOfDirectives) {
|
|
17766
|
+
ngDevMode &&
|
|
17767
|
+
assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
|
|
17768
|
+
tNode.flags |= 1 /* TNodeFlags.isDirectiveHost */;
|
|
17769
|
+
// When the first directive is created on a node, save the index
|
|
17770
|
+
tNode.directiveStart = index;
|
|
17771
|
+
tNode.directiveEnd = index + numberOfDirectives;
|
|
17772
|
+
tNode.providerIndexes = index;
|
|
17773
|
+
}
|
|
17774
|
+
function assertNoDuplicateDirectives(directives) {
|
|
17775
|
+
// The array needs at least two elements in order to have duplicates.
|
|
17776
|
+
if (directives.length < 2) {
|
|
17777
|
+
return;
|
|
17778
|
+
}
|
|
17779
|
+
const seenDirectives = new Set();
|
|
17780
|
+
for (const current of directives) {
|
|
17781
|
+
if (seenDirectives.has(current)) {
|
|
17782
|
+
throw new RuntimeError(309 /* RuntimeErrorCode.DUPLICATE_DIRECTIVE */, `Directive ${current.type.name} matches multiple times on the same element. ` +
|
|
17783
|
+
`Directives can only match an element once.`);
|
|
17784
|
+
}
|
|
17785
|
+
seenDirectives.add(current);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
|
|
17789
|
+
function elementStartFirstCreatePass(index, tView, lView, name, directiveMatcher, bindingsEnabled, attrsIndex, localRefsIndex) {
|
|
17790
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17791
|
+
ngDevMode && ngDevMode.firstCreatePass++;
|
|
17792
|
+
const tViewConsts = tView.consts;
|
|
17793
|
+
const attrs = getConstant(tViewConsts, attrsIndex);
|
|
17794
|
+
const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
|
|
17795
|
+
if (bindingsEnabled) {
|
|
17796
|
+
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex), directiveMatcher);
|
|
17797
|
+
}
|
|
17798
|
+
// Merge the template attrs last so that they have the highest priority.
|
|
17799
|
+
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
17800
|
+
if (tNode.attrs !== null) {
|
|
17801
|
+
computeStaticStyling(tNode, tNode.attrs, false);
|
|
17802
|
+
}
|
|
17803
|
+
if (tNode.mergedAttrs !== null) {
|
|
17804
|
+
computeStaticStyling(tNode, tNode.mergedAttrs, true);
|
|
17805
|
+
}
|
|
17806
|
+
if (tView.queries !== null) {
|
|
17807
|
+
tView.queries.elementStart(tView, tNode);
|
|
17808
|
+
}
|
|
17809
|
+
return tNode;
|
|
17810
|
+
}
|
|
17811
|
+
function elementEndFirstCreatePass(tView, tNode) {
|
|
17812
|
+
ngDevMode && assertFirstCreatePass(tView);
|
|
17813
|
+
registerPostOrderHooks(tView, tNode);
|
|
17814
|
+
if (isContentQueryHost(tNode)) {
|
|
17815
|
+
tView.queries.elementEnd(tNode);
|
|
17816
|
+
}
|
|
17817
|
+
}
|
|
17818
|
+
|
|
17781
17819
|
class ComponentFactoryResolver extends ComponentFactoryResolver$1 {
|
|
17782
17820
|
ngModule;
|
|
17783
17821
|
/**
|
|
@@ -17822,9 +17860,51 @@ function toRefArray(map, isInputMap) {
|
|
|
17822
17860
|
}
|
|
17823
17861
|
return array;
|
|
17824
17862
|
}
|
|
17825
|
-
function
|
|
17826
|
-
|
|
17827
|
-
|
|
17863
|
+
function verifyNotAnOrphanComponent(componentDef) {
|
|
17864
|
+
// TODO(pk): create assert that verifies ngDevMode
|
|
17865
|
+
if ((typeof ngJitMode === 'undefined' || ngJitMode) &&
|
|
17866
|
+
componentDef.debugInfo?.forbidOrphanRendering) {
|
|
17867
|
+
if (depsTracker.isOrphanComponent(componentDef.type)) {
|
|
17868
|
+
throw new RuntimeError(981 /* RuntimeErrorCode.RUNTIME_DEPS_ORPHAN_COMPONENT */, `Orphan component found! Trying to render the component ${debugStringifyTypeForError(componentDef.type)} without first loading the NgModule that declares it. It is recommended to make this component standalone in order to avoid this error. If this is not possible now, import the component's NgModule in the appropriate NgModule, or the standalone component in which you are trying to render this component. If this is a lazy import, load the NgModule lazily as well and use its module injector.`);
|
|
17869
|
+
}
|
|
17870
|
+
}
|
|
17871
|
+
}
|
|
17872
|
+
function createRootViewInjector(componentDef, environmentInjector, injector) {
|
|
17873
|
+
let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector
|
|
17874
|
+
? environmentInjector
|
|
17875
|
+
: environmentInjector?.injector;
|
|
17876
|
+
if (realEnvironmentInjector && componentDef.getStandaloneInjector !== null) {
|
|
17877
|
+
realEnvironmentInjector =
|
|
17878
|
+
componentDef.getStandaloneInjector(realEnvironmentInjector) || realEnvironmentInjector;
|
|
17879
|
+
}
|
|
17880
|
+
const rootViewInjector = realEnvironmentInjector
|
|
17881
|
+
? new ChainedInjector(injector, realEnvironmentInjector)
|
|
17882
|
+
: injector;
|
|
17883
|
+
return rootViewInjector;
|
|
17884
|
+
}
|
|
17885
|
+
function createRootLViewEnvironment(rootLViewInjector) {
|
|
17886
|
+
const rendererFactory = rootLViewInjector.get(RendererFactory2, null);
|
|
17887
|
+
if (rendererFactory === null) {
|
|
17888
|
+
throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode &&
|
|
17889
|
+
'Angular was not able to inject a renderer (RendererFactory2). ' +
|
|
17890
|
+
'Likely this is due to a broken DI hierarchy. ' +
|
|
17891
|
+
'Make sure that any injector used to create this component has a correct parent.');
|
|
17892
|
+
}
|
|
17893
|
+
const sanitizer = rootLViewInjector.get(Sanitizer, null);
|
|
17894
|
+
const changeDetectionScheduler = rootLViewInjector.get(ChangeDetectionScheduler, null);
|
|
17895
|
+
return {
|
|
17896
|
+
rendererFactory,
|
|
17897
|
+
sanitizer,
|
|
17898
|
+
changeDetectionScheduler,
|
|
17899
|
+
};
|
|
17900
|
+
}
|
|
17901
|
+
function createHostElement(componentDef, render) {
|
|
17902
|
+
// Determine a tag name used for creating host elements when this component is created
|
|
17903
|
+
// dynamically. Default to 'div' if this component did not specify any tag name in its
|
|
17904
|
+
// selector.
|
|
17905
|
+
const tagName = (componentDef.selectors[0][0] || 'div').toLowerCase();
|
|
17906
|
+
const namespace = tagName === 'svg' ? SVG_NAMESPACE : tagName === 'math' ? MATH_ML_NAMESPACE : null;
|
|
17907
|
+
return createElementNode(render, tagName, namespace);
|
|
17828
17908
|
}
|
|
17829
17909
|
/**
|
|
17830
17910
|
* ComponentFactory interface implementation.
|
|
@@ -17868,63 +17948,22 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
17868
17948
|
create(injector, projectableNodes, rootSelectorOrNode, environmentInjector) {
|
|
17869
17949
|
const prevConsumer = setActiveConsumer$1(null);
|
|
17870
17950
|
try {
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
}
|
|
17878
|
-
}
|
|
17879
|
-
environmentInjector = environmentInjector || this.ngModule;
|
|
17880
|
-
let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector
|
|
17881
|
-
? environmentInjector
|
|
17882
|
-
: environmentInjector?.injector;
|
|
17883
|
-
if (realEnvironmentInjector && this.componentDef.getStandaloneInjector !== null) {
|
|
17884
|
-
realEnvironmentInjector =
|
|
17885
|
-
this.componentDef.getStandaloneInjector(realEnvironmentInjector) ||
|
|
17886
|
-
realEnvironmentInjector;
|
|
17887
|
-
}
|
|
17888
|
-
const rootViewInjector = realEnvironmentInjector
|
|
17889
|
-
? new ChainedInjector(injector, realEnvironmentInjector)
|
|
17890
|
-
: injector;
|
|
17891
|
-
const rendererFactory = rootViewInjector.get(RendererFactory2, null);
|
|
17892
|
-
if (rendererFactory === null) {
|
|
17893
|
-
throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode &&
|
|
17894
|
-
'Angular was not able to inject a renderer (RendererFactory2). ' +
|
|
17895
|
-
'Likely this is due to a broken DI hierarchy. ' +
|
|
17896
|
-
'Make sure that any injector used to create this component has a correct parent.');
|
|
17897
|
-
}
|
|
17898
|
-
const sanitizer = rootViewInjector.get(Sanitizer, null);
|
|
17899
|
-
const changeDetectionScheduler = rootViewInjector.get(ChangeDetectionScheduler, null);
|
|
17900
|
-
const environment = {
|
|
17901
|
-
rendererFactory,
|
|
17902
|
-
sanitizer,
|
|
17903
|
-
changeDetectionScheduler,
|
|
17904
|
-
};
|
|
17905
|
-
const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
|
|
17906
|
-
// Determine a tag name used for creating host elements when this component is created
|
|
17907
|
-
// dynamically. Default to 'div' if this component did not specify any tag name in its
|
|
17908
|
-
// selector.
|
|
17909
|
-
const elementName = this.componentDef.selectors[0][0] || 'div';
|
|
17910
|
-
const hostRNode = rootSelectorOrNode
|
|
17911
|
-
? locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation, rootViewInjector)
|
|
17912
|
-
: createElementNode(hostRenderer, elementName, getNamespace(elementName));
|
|
17913
|
-
let rootFlags = 512 /* LViewFlags.IsRoot */;
|
|
17914
|
-
if (this.componentDef.signals) {
|
|
17915
|
-
rootFlags |= 4096 /* LViewFlags.SignalView */;
|
|
17916
|
-
}
|
|
17917
|
-
else if (!this.componentDef.onPush) {
|
|
17918
|
-
rootFlags |= 16 /* LViewFlags.CheckAlways */;
|
|
17919
|
-
}
|
|
17920
|
-
let hydrationInfo = null;
|
|
17921
|
-
if (hostRNode !== null) {
|
|
17922
|
-
hydrationInfo = retrieveHydrationInfo(hostRNode, rootViewInjector, true /* isRootView */);
|
|
17923
|
-
}
|
|
17951
|
+
const cmpDef = this.componentDef;
|
|
17952
|
+
ngDevMode && verifyNotAnOrphanComponent(cmpDef);
|
|
17953
|
+
const tAttributes = rootSelectorOrNode
|
|
17954
|
+
? ['ng-version', '19.1.6']
|
|
17955
|
+
: // Extract attributes and classes from the first selector only to match VE behavior.
|
|
17956
|
+
extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
|
|
17924
17957
|
// Create the root view. Uses empty TView and ContentTemplate.
|
|
17925
|
-
const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null,
|
|
17926
|
-
const
|
|
17927
|
-
|
|
17958
|
+
const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, [tAttributes], null);
|
|
17959
|
+
const rootViewInjector = createRootViewInjector(cmpDef, environmentInjector || this.ngModule, injector);
|
|
17960
|
+
const environment = createRootLViewEnvironment(rootViewInjector);
|
|
17961
|
+
const hostRenderer = environment.rendererFactory.createRenderer(null, cmpDef);
|
|
17962
|
+
const hostElement = rootSelectorOrNode
|
|
17963
|
+
? locateHostElement(hostRenderer, rootSelectorOrNode, cmpDef.encapsulation, rootViewInjector)
|
|
17964
|
+
: createHostElement(cmpDef, hostRenderer);
|
|
17965
|
+
const rootLView = createLView(null, rootTView, null, 512 /* LViewFlags.IsRoot */ | getInitialLViewFlagsFromDef(cmpDef), null, null, environment, hostRenderer, rootViewInjector, null, retrieveHydrationInfo(hostElement, rootViewInjector, true /* isRootView */));
|
|
17966
|
+
rootLView[HEADER_OFFSET] = hostElement;
|
|
17928
17967
|
// rootView is the parent when bootstrapping
|
|
17929
17968
|
// TODO(misko): it looks like we are entering view here but we don't really need to as
|
|
17930
17969
|
// `renderView` does that. However as the code is written it is needed because
|
|
@@ -17933,37 +17972,22 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
17933
17972
|
enterView(rootLView);
|
|
17934
17973
|
let componentView = null;
|
|
17935
17974
|
try {
|
|
17936
|
-
|
|
17937
|
-
|
|
17938
|
-
? ['ng-version', '19.1.4']
|
|
17939
|
-
: // Extract attributes and classes from the first selector only to match VE behavior.
|
|
17940
|
-
extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
|
|
17941
|
-
// TODO: this logic is shared with the element instruction first create pass
|
|
17942
|
-
const hostTNode = getOrCreateTNode(rootTView, HEADER_OFFSET, 2 /* TNodeType.Element */, '#host', tAttributes);
|
|
17943
|
-
const [directiveDefs, hostDirectiveDefs] = resolveHostDirectives(rootTView, hostTNode, [
|
|
17944
|
-
this.componentDef,
|
|
17945
|
-
]);
|
|
17946
|
-
initializeDirectives(rootTView, rootLView, hostTNode, directiveDefs, {}, hostDirectiveDefs);
|
|
17947
|
-
for (const def of directiveDefs) {
|
|
17948
|
-
hostTNode.mergedAttrs = mergeHostAttrs(hostTNode.mergedAttrs, def.hostAttrs);
|
|
17949
|
-
}
|
|
17950
|
-
hostTNode.mergedAttrs = mergeHostAttrs(hostTNode.mergedAttrs, tAttributes);
|
|
17951
|
-
computeStaticStyling(hostTNode, hostTNode.mergedAttrs, true);
|
|
17975
|
+
const hostTNode = elementStartFirstCreatePass(HEADER_OFFSET, rootTView, rootLView, '#host', () => [this.componentDef], true, 0);
|
|
17976
|
+
// ---- element instruction
|
|
17952
17977
|
// TODO(crisbeto): in practice `hostRNode` should always be defined, but there are some
|
|
17953
17978
|
// tests where the renderer is mocked out and `undefined` is returned. We should update the
|
|
17954
17979
|
// tests so that this check can be removed.
|
|
17955
|
-
if (
|
|
17956
|
-
setupStaticAttributes(hostRenderer,
|
|
17957
|
-
attachPatchData(
|
|
17958
|
-
}
|
|
17959
|
-
if (projectableNodes !== undefined) {
|
|
17960
|
-
projectNodes(hostTNode, this.ngContentSelectors, projectableNodes);
|
|
17980
|
+
if (hostElement) {
|
|
17981
|
+
setupStaticAttributes(hostRenderer, hostElement, hostTNode);
|
|
17982
|
+
attachPatchData(hostElement, rootLView);
|
|
17961
17983
|
}
|
|
17962
17984
|
// TODO(pk): this logic is similar to the instruction code where a node can have directives
|
|
17963
17985
|
createDirectivesInstances(rootTView, rootLView, hostTNode);
|
|
17964
17986
|
executeContentQueries(rootTView, hostTNode, rootLView);
|
|
17965
|
-
|
|
17966
|
-
|
|
17987
|
+
elementEndFirstCreatePass(rootTView, hostTNode);
|
|
17988
|
+
if (projectableNodes !== undefined) {
|
|
17989
|
+
projectNodes(hostTNode, this.ngContentSelectors, projectableNodes);
|
|
17990
|
+
}
|
|
17967
17991
|
componentView = getComponentLViewByIndex(hostTNode.index, rootLView);
|
|
17968
17992
|
// TODO(pk): why do we need this logic?
|
|
17969
17993
|
rootLView[CONTEXT] = componentView[CONTEXT];
|
|
@@ -20578,7 +20602,11 @@ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, t
|
|
|
20578
20602
|
const tViewConsts = tView.consts;
|
|
20579
20603
|
// TODO(pk): refactor getOrCreateTNode to have the "create" only version
|
|
20580
20604
|
const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, attrs || null);
|
|
20581
|
-
|
|
20605
|
+
if (getBindingsEnabled()) {
|
|
20606
|
+
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex), findDirectiveDefMatches);
|
|
20607
|
+
}
|
|
20608
|
+
// Merge the template attrs last so that they have the highest priority.
|
|
20609
|
+
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
20582
20610
|
registerPostOrderHooks(tView, tNode);
|
|
20583
20611
|
const embeddedTView = (tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts, null /* ssrId */));
|
|
20584
20612
|
if (tView.queries !== null) {
|
|
@@ -23250,24 +23278,6 @@ class NgProbeToken {
|
|
|
23250
23278
|
}
|
|
23251
23279
|
/** Maximum number of times ApplicationRef will refresh all attached views in a single tick. */
|
|
23252
23280
|
const MAXIMUM_REFRESH_RERUNS = 10;
|
|
23253
|
-
function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
|
|
23254
|
-
try {
|
|
23255
|
-
const result = callback();
|
|
23256
|
-
if (isPromise(result)) {
|
|
23257
|
-
return result.catch((e) => {
|
|
23258
|
-
ngZone.runOutsideAngular(() => errorHandler.handleError(e));
|
|
23259
|
-
// rethrow as the exception handler might not do it
|
|
23260
|
-
throw e;
|
|
23261
|
-
});
|
|
23262
|
-
}
|
|
23263
|
-
return result;
|
|
23264
|
-
}
|
|
23265
|
-
catch (e) {
|
|
23266
|
-
ngZone.runOutsideAngular(() => errorHandler.handleError(e));
|
|
23267
|
-
// rethrow as the exception handler might not do it
|
|
23268
|
-
throw e;
|
|
23269
|
-
}
|
|
23270
|
-
}
|
|
23271
23281
|
function optionsReducer(dst, objs) {
|
|
23272
23282
|
if (Array.isArray(objs)) {
|
|
23273
23283
|
return objs.reduce(optionsReducer, dst);
|
|
@@ -27954,24 +27964,6 @@ function getExistingTNode(tView, index) {
|
|
|
27954
27964
|
return tNode;
|
|
27955
27965
|
}
|
|
27956
27966
|
|
|
27957
|
-
function elementStartFirstCreatePass(index, tView, lView, name, attrsIndex, localRefsIndex) {
|
|
27958
|
-
ngDevMode && assertFirstCreatePass(tView);
|
|
27959
|
-
ngDevMode && ngDevMode.firstCreatePass++;
|
|
27960
|
-
const tViewConsts = tView.consts;
|
|
27961
|
-
const attrs = getConstant(tViewConsts, attrsIndex);
|
|
27962
|
-
const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
|
|
27963
|
-
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
|
|
27964
|
-
if (tNode.attrs !== null) {
|
|
27965
|
-
computeStaticStyling(tNode, tNode.attrs, false);
|
|
27966
|
-
}
|
|
27967
|
-
if (tNode.mergedAttrs !== null) {
|
|
27968
|
-
computeStaticStyling(tNode, tNode.mergedAttrs, true);
|
|
27969
|
-
}
|
|
27970
|
-
if (tView.queries !== null) {
|
|
27971
|
-
tView.queries.elementStart(tView, tNode);
|
|
27972
|
-
}
|
|
27973
|
-
return tNode;
|
|
27974
|
-
}
|
|
27975
27967
|
/**
|
|
27976
27968
|
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
|
|
27977
27969
|
*
|
|
@@ -27996,7 +27988,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
27996
27988
|
ngDevMode && assertIndexInRange(lView, adjustedIndex);
|
|
27997
27989
|
const renderer = lView[RENDERER];
|
|
27998
27990
|
const tNode = tView.firstCreatePass
|
|
27999
|
-
? elementStartFirstCreatePass(adjustedIndex, tView, lView, name, attrsIndex, localRefsIndex)
|
|
27991
|
+
? elementStartFirstCreatePass(adjustedIndex, tView, lView, name, findDirectiveDefMatches, getBindingsEnabled(), attrsIndex, localRefsIndex)
|
|
28000
27992
|
: tView.data[adjustedIndex];
|
|
28001
27993
|
const native = _locateOrCreateElementNode(tView, lView, tNode, renderer, name, index);
|
|
28002
27994
|
lView[adjustedIndex] = native;
|
|
@@ -28052,10 +28044,7 @@ function ɵɵelementEnd() {
|
|
|
28052
28044
|
decreaseElementDepthCount();
|
|
28053
28045
|
const tView = getTView();
|
|
28054
28046
|
if (tView.firstCreatePass) {
|
|
28055
|
-
|
|
28056
|
-
if (isContentQueryHost(currentTNode)) {
|
|
28057
|
-
tView.queries.elementEnd(currentTNode);
|
|
28058
|
-
}
|
|
28047
|
+
elementEndFirstCreatePass(tView, tNode);
|
|
28059
28048
|
}
|
|
28060
28049
|
if (tNode.classesWithoutHost != null && hasClassInput(tNode)) {
|
|
28061
28050
|
setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.classesWithoutHost, true);
|
|
@@ -28083,7 +28072,7 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
|
|
|
28083
28072
|
}
|
|
28084
28073
|
let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) => {
|
|
28085
28074
|
lastNodeWasCreated(true);
|
|
28086
|
-
return createElementNode(renderer, name, getNamespace
|
|
28075
|
+
return createElementNode(renderer, name, getNamespace());
|
|
28087
28076
|
};
|
|
28088
28077
|
/**
|
|
28089
28078
|
* Enables hydration code path (to lookup existing elements in DOM)
|
|
@@ -28098,7 +28087,7 @@ function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, inde
|
|
|
28098
28087
|
lastNodeWasCreated(isNodeCreationMode);
|
|
28099
28088
|
// Regular creation mode.
|
|
28100
28089
|
if (isNodeCreationMode) {
|
|
28101
|
-
return createElementNode(renderer, name, getNamespace
|
|
28090
|
+
return createElementNode(renderer, name, getNamespace());
|
|
28102
28091
|
}
|
|
28103
28092
|
// Hydration mode, looking up an existing element in DOM.
|
|
28104
28093
|
const native = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
@@ -28151,7 +28140,11 @@ function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, l
|
|
|
28151
28140
|
computeStaticStyling(tNode, attrs, true);
|
|
28152
28141
|
}
|
|
28153
28142
|
const localRefs = getConstant(tViewConsts, localRefsIndex);
|
|
28154
|
-
|
|
28143
|
+
if (getBindingsEnabled()) {
|
|
28144
|
+
resolveDirectives(tView, lView, tNode, localRefs, findDirectiveDefMatches);
|
|
28145
|
+
}
|
|
28146
|
+
// Merge the template attrs last so that they have the highest priority.
|
|
28147
|
+
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
28155
28148
|
if (tView.queries !== null) {
|
|
28156
28149
|
tView.queries.elementStart(tView, tNode);
|
|
28157
28150
|
}
|
|
@@ -33312,9 +33305,13 @@ function ɵsetClassDebugInfo(type, debugInfo) {
|
|
|
33312
33305
|
* @param applyMetadata Callback that will apply a new set of metadata on the `type` when invoked.
|
|
33313
33306
|
* @param environment Syntehtic namespace imports that need to be passed along to the callback.
|
|
33314
33307
|
* @param locals Local symbols from the source location that have to be exposed to the callback.
|
|
33308
|
+
* @param importMeta `import.meta` from the call site of the replacement function. Optional since
|
|
33309
|
+
* it isn't used internally.
|
|
33310
|
+
* @param id ID to the class being replaced. **Not** the same as the component definition ID.
|
|
33311
|
+
* Optional since the ID might not be available internally.
|
|
33315
33312
|
* @codeGenApi
|
|
33316
33313
|
*/
|
|
33317
|
-
function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals) {
|
|
33314
|
+
function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals, importMeta = null, id = null) {
|
|
33318
33315
|
ngDevMode && assertComponentDef(type);
|
|
33319
33316
|
const currentDef = getComponentDef(type);
|
|
33320
33317
|
// The reason `applyMetadata` is a callback that is invoked (almost) immediately is because
|
|
@@ -33336,7 +33333,7 @@ function ɵɵreplaceMetadata(type, applyMetadata, namespaces, locals) {
|
|
|
33336
33333
|
// Note: we have the additional check, because `IsRoot` can also indicate
|
|
33337
33334
|
// a component created through something like `createComponent`.
|
|
33338
33335
|
if (isRootView(root) && root[PARENT] === null) {
|
|
33339
|
-
recreateMatchingLViews(newDef, oldDef, root);
|
|
33336
|
+
recreateMatchingLViews(importMeta, id, newDef, oldDef, root);
|
|
33340
33337
|
}
|
|
33341
33338
|
}
|
|
33342
33339
|
}
|
|
@@ -33372,10 +33369,12 @@ function mergeWithExistingDefinition(currentDef, newDef) {
|
|
|
33372
33369
|
}
|
|
33373
33370
|
/**
|
|
33374
33371
|
* Finds all LViews matching a specific component definition and recreates them.
|
|
33372
|
+
* @param importMeta `import.meta` information.
|
|
33373
|
+
* @param id HMR ID of the component.
|
|
33375
33374
|
* @param oldDef Component definition to search for.
|
|
33376
33375
|
* @param rootLView View from which to start the search.
|
|
33377
33376
|
*/
|
|
33378
|
-
function recreateMatchingLViews(newDef, oldDef, rootLView) {
|
|
33377
|
+
function recreateMatchingLViews(importMeta, id, newDef, oldDef, rootLView) {
|
|
33379
33378
|
ngDevMode &&
|
|
33380
33379
|
assertDefined(oldDef.tView, 'Expected a component definition that has been instantiated at least once');
|
|
33381
33380
|
const tView = rootLView[TVIEW];
|
|
@@ -33383,7 +33382,7 @@ function recreateMatchingLViews(newDef, oldDef, rootLView) {
|
|
|
33383
33382
|
// produce false positives when using inheritance.
|
|
33384
33383
|
if (tView === oldDef.tView) {
|
|
33385
33384
|
ngDevMode && assertComponentDef(oldDef.type);
|
|
33386
|
-
recreateLView(newDef, oldDef, rootLView);
|
|
33385
|
+
recreateLView(importMeta, id, newDef, oldDef, rootLView);
|
|
33387
33386
|
return;
|
|
33388
33387
|
}
|
|
33389
33388
|
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
@@ -33391,14 +33390,14 @@ function recreateMatchingLViews(newDef, oldDef, rootLView) {
|
|
|
33391
33390
|
if (isLContainer(current)) {
|
|
33392
33391
|
// The host can be an LView if a component is injecting `ViewContainerRef`.
|
|
33393
33392
|
if (isLView(current[HOST])) {
|
|
33394
|
-
recreateMatchingLViews(newDef, oldDef, current[HOST]);
|
|
33393
|
+
recreateMatchingLViews(importMeta, id, newDef, oldDef, current[HOST]);
|
|
33395
33394
|
}
|
|
33396
33395
|
for (let j = CONTAINER_HEADER_OFFSET; j < current.length; j++) {
|
|
33397
|
-
recreateMatchingLViews(newDef, oldDef, current[j]);
|
|
33396
|
+
recreateMatchingLViews(importMeta, id, newDef, oldDef, current[j]);
|
|
33398
33397
|
}
|
|
33399
33398
|
}
|
|
33400
33399
|
else if (isLView(current)) {
|
|
33401
|
-
recreateMatchingLViews(newDef, oldDef, current);
|
|
33400
|
+
recreateMatchingLViews(importMeta, id, newDef, oldDef, current);
|
|
33402
33401
|
}
|
|
33403
33402
|
}
|
|
33404
33403
|
}
|
|
@@ -33417,11 +33416,13 @@ function clearRendererCache(factory, def) {
|
|
|
33417
33416
|
}
|
|
33418
33417
|
/**
|
|
33419
33418
|
* Recreates an LView in-place from a new component definition.
|
|
33419
|
+
* @param importMeta `import.meta` information.
|
|
33420
|
+
* @param id HMR ID for the component.
|
|
33420
33421
|
* @param newDef Definition from which to recreate the view.
|
|
33421
33422
|
* @param oldDef Previous component definition being swapped out.
|
|
33422
33423
|
* @param lView View to be recreated.
|
|
33423
33424
|
*/
|
|
33424
|
-
function recreateLView(newDef, oldDef, lView) {
|
|
33425
|
+
function recreateLView(importMeta, id, newDef, oldDef, lView) {
|
|
33425
33426
|
const instance = lView[CONTEXT];
|
|
33426
33427
|
let host = lView[HOST];
|
|
33427
33428
|
// In theory the parent can also be an LContainer, but it appears like that's
|
|
@@ -33473,10 +33474,29 @@ function recreateLView(newDef, oldDef, lView) {
|
|
|
33473
33474
|
};
|
|
33474
33475
|
// The callback isn't guaranteed to be inside the Zone so we need to bring it in ourselves.
|
|
33475
33476
|
if (zone === null) {
|
|
33476
|
-
recreate
|
|
33477
|
+
executeWithInvalidateFallback(importMeta, id, recreate);
|
|
33477
33478
|
}
|
|
33478
33479
|
else {
|
|
33479
|
-
zone.run(recreate);
|
|
33480
|
+
zone.run(() => executeWithInvalidateFallback(importMeta, id, recreate));
|
|
33481
|
+
}
|
|
33482
|
+
}
|
|
33483
|
+
/**
|
|
33484
|
+
* Runs an HMR-related function and falls back to
|
|
33485
|
+
* invalidating the HMR data if it throws an error.
|
|
33486
|
+
*/
|
|
33487
|
+
function executeWithInvalidateFallback(importMeta, id, callback) {
|
|
33488
|
+
try {
|
|
33489
|
+
callback();
|
|
33490
|
+
}
|
|
33491
|
+
catch (e) {
|
|
33492
|
+
const errorMessage = e.message;
|
|
33493
|
+
// If we have all the necessary information and APIs to send off the invalidation
|
|
33494
|
+
// request, send it before rethrowing so the dev server can decide what to do.
|
|
33495
|
+
if (id !== null && errorMessage) {
|
|
33496
|
+
importMeta?.hot?.send?.('angular:invalidate', { id, message: errorMessage, error: true });
|
|
33497
|
+
}
|
|
33498
|
+
// Throw the error in case the page doesn't get refreshed.
|
|
33499
|
+
throw e;
|
|
33480
33500
|
}
|
|
33481
33501
|
}
|
|
33482
33502
|
/**
|
|
@@ -34904,7 +34924,7 @@ class Version {
|
|
|
34904
34924
|
/**
|
|
34905
34925
|
* @publicApi
|
|
34906
34926
|
*/
|
|
34907
|
-
const VERSION = new Version('19.1.
|
|
34927
|
+
const VERSION = new Version('19.1.6');
|
|
34908
34928
|
|
|
34909
34929
|
/**
|
|
34910
34930
|
* Combination of NgModuleFactory and ComponentFactories.
|
|
@@ -36053,6 +36073,24 @@ function moduleDoBootstrap(moduleRef, allPlatformModules) {
|
|
|
36053
36073
|
}
|
|
36054
36074
|
allPlatformModules.push(moduleRef);
|
|
36055
36075
|
}
|
|
36076
|
+
function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
|
|
36077
|
+
try {
|
|
36078
|
+
const result = callback();
|
|
36079
|
+
if (isPromise(result)) {
|
|
36080
|
+
return result.catch((e) => {
|
|
36081
|
+
ngZone.runOutsideAngular(() => errorHandler.handleError(e));
|
|
36082
|
+
// rethrow as the exception handler might not do it
|
|
36083
|
+
throw e;
|
|
36084
|
+
});
|
|
36085
|
+
}
|
|
36086
|
+
return result;
|
|
36087
|
+
}
|
|
36088
|
+
catch (e) {
|
|
36089
|
+
ngZone.runOutsideAngular(() => errorHandler.handleError(e));
|
|
36090
|
+
// rethrow as the exception handler might not do it
|
|
36091
|
+
throw e;
|
|
36092
|
+
}
|
|
36093
|
+
}
|
|
36056
36094
|
|
|
36057
36095
|
/**
|
|
36058
36096
|
* The Angular platform is the entry point for Angular on a web page.
|