@angular/core 16.2.0-next.4 → 16.2.0
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/esm2022/src/application_tokens.mjs +2 -1
- package/esm2022/src/core.mjs +2 -1
- package/esm2022/src/core_private_export.mjs +3 -1
- package/esm2022/src/core_render3_private_export.mjs +3 -2
- package/esm2022/src/di/contextual.mjs +7 -1
- package/esm2022/src/di/create_injector.mjs +1 -3
- package/esm2022/src/di/injector.mjs +1 -1
- package/esm2022/src/di/injector_compatibility.mjs +5 -2
- package/esm2022/src/di/provider_collection.mjs +17 -16
- package/esm2022/src/di/r3_injector.mjs +37 -2
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/hydration/annotate.mjs +60 -15
- package/esm2022/src/hydration/api.mjs +40 -17
- package/esm2022/src/hydration/cleanup.mjs +15 -6
- package/esm2022/src/hydration/utils.mjs +58 -20
- package/esm2022/src/linker/template_ref.mjs +4 -19
- package/esm2022/src/linker/view_container_ref.mjs +5 -13
- package/esm2022/src/metadata/directives.mjs +1 -1
- package/esm2022/src/render3/after_render_hooks.mjs +210 -0
- package/esm2022/src/render3/component_ref.mjs +11 -11
- package/esm2022/src/render3/debug/framework_injector_profiler.mjs +212 -0
- package/esm2022/src/render3/debug/injector_profiler.mjs +103 -0
- package/esm2022/src/render3/di.mjs +32 -2
- package/esm2022/src/render3/di_setup.mjs +11 -4
- package/esm2022/src/render3/hooks.mjs +3 -3
- package/esm2022/src/render3/index.mjs +2 -2
- package/esm2022/src/render3/instructions/all.mjs +2 -1
- package/esm2022/src/render3/instructions/change_detection.mjs +16 -9
- package/esm2022/src/render3/instructions/defer.mjs +19 -0
- package/esm2022/src/render3/instructions/di.mjs +5 -2
- package/esm2022/src/render3/instructions/shared.mjs +1 -1
- package/esm2022/src/render3/interfaces/view.mjs +1 -1
- package/esm2022/src/render3/jit/environment.mjs +2 -1
- package/esm2022/src/render3/node_manipulation.mjs +5 -5
- package/esm2022/src/render3/pipe.mjs +12 -3
- package/esm2022/src/render3/util/global_utils.mjs +7 -1
- package/esm2022/src/render3/util/injector_discovery_utils.mjs +460 -0
- package/esm2022/src/render3/util/misc_utils.mjs +12 -1
- package/esm2022/src/render3/view_manipulation.mjs +65 -0
- package/esm2022/src/render3/view_ref.mjs +3 -3
- package/esm2022/src/util/coercion.mjs +11 -1
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +1854 -650
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +4023 -3540
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +214 -10
- package/package.json +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +13 -13
- package/schematics/migrations/remove-module-id/bundle.js +14 -14
- package/schematics/ng-generate/standalone-migration/bundle.js +3664 -2727
- package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
- package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v16.2.0
|
|
2
|
+
* @license Angular v16.2.0
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -604,6 +604,100 @@ function initNgDevMode() {
|
|
|
604
604
|
return false;
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
+
let _injectorProfilerContext;
|
|
608
|
+
function getInjectorProfilerContext() {
|
|
609
|
+
!ngDevMode && throwError('getInjectorProfilerContext should never be called in production mode');
|
|
610
|
+
return _injectorProfilerContext;
|
|
611
|
+
}
|
|
612
|
+
function setInjectorProfilerContext(context) {
|
|
613
|
+
!ngDevMode && throwError('setInjectorProfilerContext should never be called in production mode');
|
|
614
|
+
const previous = _injectorProfilerContext;
|
|
615
|
+
_injectorProfilerContext = context;
|
|
616
|
+
return previous;
|
|
617
|
+
}
|
|
618
|
+
let injectorProfilerCallback = null;
|
|
619
|
+
/**
|
|
620
|
+
* Sets the callback function which will be invoked during certain DI events within the
|
|
621
|
+
* runtime (for example: injecting services, creating injectable instances, configuring providers)
|
|
622
|
+
*
|
|
623
|
+
* Warning: this function is *INTERNAL* and should not be relied upon in application's code.
|
|
624
|
+
* The contract of the function might be changed in any release and/or the function can be removed
|
|
625
|
+
* completely.
|
|
626
|
+
*
|
|
627
|
+
* @param profiler function provided by the caller or null value to disable profiling.
|
|
628
|
+
*/
|
|
629
|
+
const setInjectorProfiler = (injectorProfiler) => {
|
|
630
|
+
!ngDevMode && throwError('setInjectorProfiler should never be called in production mode');
|
|
631
|
+
injectorProfilerCallback = injectorProfiler;
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* Injector profiler function which emits on DI events executed by the runtime.
|
|
635
|
+
*
|
|
636
|
+
* @param event InjectorProfilerEvent corresponding to the DI event being emitted
|
|
637
|
+
*/
|
|
638
|
+
function injectorProfiler(event) {
|
|
639
|
+
!ngDevMode && throwError('Injector profiler should never be called in production mode');
|
|
640
|
+
if (injectorProfilerCallback != null /* both `null` and `undefined` */) {
|
|
641
|
+
injectorProfilerCallback(event);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Emits an InjectorProfilerEventType.ProviderConfigured to the injector profiler. The data in the
|
|
646
|
+
* emitted event includes the raw provider, as well as the token that provider is providing.
|
|
647
|
+
*
|
|
648
|
+
* @param provider A provider object
|
|
649
|
+
*/
|
|
650
|
+
function emitProviderConfiguredEvent(provider, isViewProvider = false) {
|
|
651
|
+
!ngDevMode && throwError('Injector profiler should never be called in production mode');
|
|
652
|
+
injectorProfiler({
|
|
653
|
+
type: 2 /* InjectorProfilerEventType.ProviderConfigured */,
|
|
654
|
+
context: getInjectorProfilerContext(),
|
|
655
|
+
providerRecord: {
|
|
656
|
+
token: typeof provider === 'function' ? provider : resolveForwardRef(provider.provide),
|
|
657
|
+
provider,
|
|
658
|
+
isViewProvider
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Emits an event to the injector profiler with the instance that was created. Note that
|
|
664
|
+
* the injector associated with this emission can be accessed by using getDebugInjectContext()
|
|
665
|
+
*
|
|
666
|
+
* @param instance an object created by an injector
|
|
667
|
+
*/
|
|
668
|
+
function emitInstanceCreatedByInjectorEvent(instance) {
|
|
669
|
+
!ngDevMode && throwError('Injector profiler should never be called in production mode');
|
|
670
|
+
injectorProfiler({
|
|
671
|
+
type: 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */,
|
|
672
|
+
context: getInjectorProfilerContext(),
|
|
673
|
+
instance: { value: instance }
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* @param token DI token associated with injected service
|
|
678
|
+
* @param value the instance of the injected service (i.e the result of `inject(token)`)
|
|
679
|
+
* @param flags the flags that the token was injected with
|
|
680
|
+
*/
|
|
681
|
+
function emitInjectEvent(token, value, flags) {
|
|
682
|
+
!ngDevMode && throwError('Injector profiler should never be called in production mode');
|
|
683
|
+
injectorProfiler({
|
|
684
|
+
type: 0 /* InjectorProfilerEventType.Inject */,
|
|
685
|
+
context: getInjectorProfilerContext(),
|
|
686
|
+
service: { token, value, flags }
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
function runInInjectorProfilerContext(injector, token, callback) {
|
|
690
|
+
!ngDevMode &&
|
|
691
|
+
throwError('runInInjectorProfilerContext should never be called in production mode');
|
|
692
|
+
const prevInjectContext = setInjectorProfilerContext({ injector, token });
|
|
693
|
+
try {
|
|
694
|
+
callback();
|
|
695
|
+
}
|
|
696
|
+
finally {
|
|
697
|
+
setInjectorProfilerContext(prevInjectContext);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
607
701
|
const _THROW_IF_NOT_FOUND = {};
|
|
608
702
|
const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
|
609
703
|
/*
|
|
@@ -641,7 +735,9 @@ function injectInjectorOnly(token, flags = InjectFlags.Default) {
|
|
|
641
735
|
return injectRootLimpMode(token, undefined, flags);
|
|
642
736
|
}
|
|
643
737
|
else {
|
|
644
|
-
|
|
738
|
+
const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
|
|
739
|
+
ngDevMode && emitInjectEvent(token, value, flags);
|
|
740
|
+
return value;
|
|
645
741
|
}
|
|
646
742
|
}
|
|
647
743
|
function ɵɵinject(token, flags = InjectFlags.Default) {
|
|
@@ -3731,14 +3827,14 @@ function registerPostOrderHooks(tView, tNode) {
|
|
|
3731
3827
|
* This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
|
|
3732
3828
|
* and the index within that phase. They can be seen as a cursor in the following structure:
|
|
3733
3829
|
* [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
|
|
3734
|
-
* They are
|
|
3830
|
+
* They are stored as flags in LView[FLAGS].
|
|
3735
3831
|
*
|
|
3736
3832
|
* 2. Pre-order hooks can be executed in batches, because of the select instruction.
|
|
3737
3833
|
* To be able to pause and resume their execution, we also need some state about the hook's array
|
|
3738
3834
|
* that is being processed:
|
|
3739
3835
|
* - the index of the next hook to be executed
|
|
3740
3836
|
* - the number of init hooks already found in the processed part of the array
|
|
3741
|
-
* They are
|
|
3837
|
+
* They are stored as flags in LView[PREORDER_HOOK_FLAGS].
|
|
3742
3838
|
*/
|
|
3743
3839
|
/**
|
|
3744
3840
|
* Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
|
|
@@ -4498,7 +4594,18 @@ function lookupTokenUsingNodeInjector(tNode, lView, token, flags, notFoundValue)
|
|
|
4498
4594
|
lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
|
|
4499
4595
|
}
|
|
4500
4596
|
try {
|
|
4501
|
-
|
|
4597
|
+
let value;
|
|
4598
|
+
if (ngDevMode) {
|
|
4599
|
+
runInInjectorProfilerContext(new NodeInjector(getCurrentTNode(), getLView()), token, () => {
|
|
4600
|
+
value = bloomHash(flags);
|
|
4601
|
+
if (value != null) {
|
|
4602
|
+
emitInstanceCreatedByInjectorEvent(value);
|
|
4603
|
+
}
|
|
4604
|
+
});
|
|
4605
|
+
}
|
|
4606
|
+
else {
|
|
4607
|
+
value = bloomHash(flags);
|
|
4608
|
+
}
|
|
4502
4609
|
if (value == null && !(flags & InjectFlags.Optional)) {
|
|
4503
4610
|
throwProviderNotFoundError(token);
|
|
4504
4611
|
}
|
|
@@ -4653,12 +4760,23 @@ function getNodeInjectable(lView, tView, index, tNode) {
|
|
|
4653
4760
|
}
|
|
4654
4761
|
const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
|
|
4655
4762
|
factory.resolving = true;
|
|
4763
|
+
let prevInjectContext;
|
|
4764
|
+
if (ngDevMode) {
|
|
4765
|
+
// tData indexes mirror the concrete instances in its corresponding LView.
|
|
4766
|
+
// lView[index] here is either the injectable instace itself or a factory,
|
|
4767
|
+
// therefore tData[index] is the constructor of that injectable or a
|
|
4768
|
+
// definition object that contains the constructor in a `.type` field.
|
|
4769
|
+
const token = tData[index].type || tData[index];
|
|
4770
|
+
const injector = new NodeInjector(tNode, lView);
|
|
4771
|
+
prevInjectContext = setInjectorProfilerContext({ injector, token });
|
|
4772
|
+
}
|
|
4656
4773
|
const previousInjectImplementation = factory.injectImpl ? setInjectImplementation(factory.injectImpl) : null;
|
|
4657
4774
|
const success = enterDI(lView, tNode, InjectFlags.Default);
|
|
4658
4775
|
ngDevMode &&
|
|
4659
4776
|
assertEqual(success, true, 'Because flags do not contain \`SkipSelf\' we expect this to always succeed.');
|
|
4660
4777
|
try {
|
|
4661
4778
|
value = lView[index] = factory.factory(undefined, tData, lView, tNode);
|
|
4779
|
+
ngDevMode && emitInstanceCreatedByInjectorEvent(value);
|
|
4662
4780
|
// This code path is hit for both directives and providers.
|
|
4663
4781
|
// For perf reasons, we want to avoid searching for hooks on providers.
|
|
4664
4782
|
// It does no harm to try (the hooks just won't exist), but the extra
|
|
@@ -4671,6 +4789,7 @@ function getNodeInjectable(lView, tView, index, tNode) {
|
|
|
4671
4789
|
}
|
|
4672
4790
|
}
|
|
4673
4791
|
finally {
|
|
4792
|
+
ngDevMode && setInjectorProfilerContext(prevInjectContext);
|
|
4674
4793
|
previousInjectImplementation !== null &&
|
|
4675
4794
|
setInjectImplementation(previousInjectImplementation);
|
|
4676
4795
|
setIncludeViewProviders(previousIncludeViewProviders);
|
|
@@ -4732,6 +4851,12 @@ function bloomHasToken(bloomHash, injectorIndex, injectorView) {
|
|
|
4732
4851
|
function shouldSearchParent(flags, isFirstHostTNode) {
|
|
4733
4852
|
return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);
|
|
4734
4853
|
}
|
|
4854
|
+
function getNodeInjectorLView(nodeInjector) {
|
|
4855
|
+
return nodeInjector._lView;
|
|
4856
|
+
}
|
|
4857
|
+
function getNodeInjectorTNode(nodeInjector) {
|
|
4858
|
+
return nodeInjector._tNode;
|
|
4859
|
+
}
|
|
4735
4860
|
class NodeInjector {
|
|
4736
4861
|
constructor(_tNode, _lView) {
|
|
4737
4862
|
this._tNode = _tNode;
|
|
@@ -6812,7 +6937,7 @@ function createElementNode(renderer, name, namespace) {
|
|
|
6812
6937
|
* @param tView The `TView' of the `LView` from which elements should be added or removed
|
|
6813
6938
|
* @param lView The view from which elements should be added or removed
|
|
6814
6939
|
*/
|
|
6815
|
-
function
|
|
6940
|
+
function removeViewFromDOM(tView, lView) {
|
|
6816
6941
|
const renderer = lView[RENDERER];
|
|
6817
6942
|
applyView(tView, lView, renderer, 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
6818
6943
|
lView[HOST] = null;
|
|
@@ -6832,7 +6957,7 @@ function removeViewFromContainer(tView, lView) {
|
|
|
6832
6957
|
* @param parentNativeNode The parent `RElement` where it should be inserted into.
|
|
6833
6958
|
* @param beforeNode The node before which elements should be added, if insert mode
|
|
6834
6959
|
*/
|
|
6835
|
-
function
|
|
6960
|
+
function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
|
|
6836
6961
|
lView[HOST] = parentNativeNode;
|
|
6837
6962
|
lView[T_HOST] = parentTNode;
|
|
6838
6963
|
applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
|
|
@@ -6843,7 +6968,7 @@ function addViewToContainer(tView, parentTNode, renderer, lView, parentNativeNod
|
|
|
6843
6968
|
* @param tView The `TView' of the `LView` to be detached
|
|
6844
6969
|
* @param lView the `LView` to be detached.
|
|
6845
6970
|
*/
|
|
6846
|
-
function
|
|
6971
|
+
function detachViewFromDOM(tView, lView) {
|
|
6847
6972
|
applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
6848
6973
|
}
|
|
6849
6974
|
/**
|
|
@@ -7005,7 +7130,7 @@ function detachView(lContainer, removeIndex) {
|
|
|
7005
7130
|
lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
|
|
7006
7131
|
}
|
|
7007
7132
|
const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
|
|
7008
|
-
|
|
7133
|
+
removeViewFromDOM(viewToDetach[TVIEW], viewToDetach);
|
|
7009
7134
|
// notify query that a view has been removed
|
|
7010
7135
|
const lQueries = removedLView[QUERIES];
|
|
7011
7136
|
if (lQueries !== null) {
|
|
@@ -8827,6 +8952,9 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
8827
8952
|
const providersOut = [];
|
|
8828
8953
|
const dedup = new Set(); // already seen types
|
|
8829
8954
|
let injectorTypesWithProviders;
|
|
8955
|
+
const collectProviders = (provider) => {
|
|
8956
|
+
providersOut.push(provider);
|
|
8957
|
+
};
|
|
8830
8958
|
deepForEach(sources, source => {
|
|
8831
8959
|
if ((typeof ngDevMode === 'undefined' || ngDevMode) && checkForStandaloneCmp) {
|
|
8832
8960
|
const cmpDef = getComponentDef(source);
|
|
@@ -8836,14 +8964,14 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
8836
8964
|
}
|
|
8837
8965
|
// Narrow `source` to access the internal type analogue for `ModuleWithProviders`.
|
|
8838
8966
|
const internalSource = source;
|
|
8839
|
-
if (walkProviderTree(internalSource,
|
|
8967
|
+
if (walkProviderTree(internalSource, collectProviders, [], dedup)) {
|
|
8840
8968
|
injectorTypesWithProviders ||= [];
|
|
8841
8969
|
injectorTypesWithProviders.push(internalSource);
|
|
8842
8970
|
}
|
|
8843
8971
|
});
|
|
8844
8972
|
// Collect all providers from `ModuleWithProviders` types.
|
|
8845
8973
|
if (injectorTypesWithProviders !== undefined) {
|
|
8846
|
-
processInjectorTypesWithProviders(injectorTypesWithProviders,
|
|
8974
|
+
processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
|
|
8847
8975
|
}
|
|
8848
8976
|
return providersOut;
|
|
8849
8977
|
}
|
|
@@ -8851,12 +8979,12 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
8851
8979
|
* Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
|
|
8852
8980
|
* array.
|
|
8853
8981
|
*/
|
|
8854
|
-
function processInjectorTypesWithProviders(typesWithProviders,
|
|
8982
|
+
function processInjectorTypesWithProviders(typesWithProviders, visitor) {
|
|
8855
8983
|
for (let i = 0; i < typesWithProviders.length; i++) {
|
|
8856
8984
|
const { ngModule, providers } = typesWithProviders[i];
|
|
8857
8985
|
deepForEachProvider(providers, provider => {
|
|
8858
8986
|
ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);
|
|
8859
|
-
|
|
8987
|
+
visitor(provider, ngModule);
|
|
8860
8988
|
});
|
|
8861
8989
|
}
|
|
8862
8990
|
}
|
|
@@ -8869,7 +8997,7 @@ function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
|
|
|
8869
8997
|
* to be processed. This allows us to process providers of injector types after all imports of
|
|
8870
8998
|
* an injector definition are processed. (following View Engine semantics: see FW-1349)
|
|
8871
8999
|
*/
|
|
8872
|
-
function walkProviderTree(container,
|
|
9000
|
+
function walkProviderTree(container, visitor, parents, dedup) {
|
|
8873
9001
|
container = resolveForwardRef(container);
|
|
8874
9002
|
if (!container)
|
|
8875
9003
|
return false;
|
|
@@ -8917,7 +9045,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
8917
9045
|
if (cmpDef.dependencies) {
|
|
8918
9046
|
const deps = typeof cmpDef.dependencies === 'function' ? cmpDef.dependencies() : cmpDef.dependencies;
|
|
8919
9047
|
for (const dep of deps) {
|
|
8920
|
-
walkProviderTree(dep,
|
|
9048
|
+
walkProviderTree(dep, visitor, parents, dedup);
|
|
8921
9049
|
}
|
|
8922
9050
|
}
|
|
8923
9051
|
}
|
|
@@ -8932,7 +9060,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
8932
9060
|
let importTypesWithProviders;
|
|
8933
9061
|
try {
|
|
8934
9062
|
deepForEach(injDef.imports, imported => {
|
|
8935
|
-
if (walkProviderTree(imported,
|
|
9063
|
+
if (walkProviderTree(imported, visitor, parents, dedup)) {
|
|
8936
9064
|
importTypesWithProviders ||= [];
|
|
8937
9065
|
// If the processed import is an injector type with providers, we store it in the
|
|
8938
9066
|
// list of import types with providers, so that we can process those afterwards.
|
|
@@ -8948,7 +9076,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
8948
9076
|
// after all imported modules are processed. This is similar to how View Engine
|
|
8949
9077
|
// processes/merges module imports in the metadata resolver. See: FW-1349.
|
|
8950
9078
|
if (importTypesWithProviders !== undefined) {
|
|
8951
|
-
processInjectorTypesWithProviders(importTypesWithProviders,
|
|
9079
|
+
processInjectorTypesWithProviders(importTypesWithProviders, visitor);
|
|
8952
9080
|
}
|
|
8953
9081
|
}
|
|
8954
9082
|
if (!isDuplicate) {
|
|
@@ -8958,14 +9086,12 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
8958
9086
|
// Append extra providers to make more info available for consumers (to retrieve an injector
|
|
8959
9087
|
// type), as well as internally (to calculate an injection scope correctly and eagerly
|
|
8960
9088
|
// instantiate a `defType` when an injector is created).
|
|
8961
|
-
providersOut.push(
|
|
8962
9089
|
// Provider to create `defType` using its factory.
|
|
8963
|
-
{ provide: defType, useFactory: factory, deps: EMPTY_ARRAY },
|
|
9090
|
+
visitor({ provide: defType, useFactory: factory, deps: EMPTY_ARRAY }, defType);
|
|
8964
9091
|
// Make this `defType` available to an internal logic that calculates injector scope.
|
|
8965
|
-
{ provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true },
|
|
8966
|
-
// Provider to eagerly instantiate `defType` via `
|
|
8967
|
-
{ provide: ENVIRONMENT_INITIALIZER, useValue: () => ɵɵinject(defType), multi: true }
|
|
8968
|
-
);
|
|
9092
|
+
visitor({ provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true }, defType);
|
|
9093
|
+
// Provider to eagerly instantiate `defType` via `INJECTOR_INITIALIZER`.
|
|
9094
|
+
visitor({ provide: ENVIRONMENT_INITIALIZER, useValue: () => ɵɵinject(defType), multi: true }, defType);
|
|
8969
9095
|
}
|
|
8970
9096
|
// Next, include providers listed on the definition itself.
|
|
8971
9097
|
const defProviders = injDef.providers;
|
|
@@ -8973,7 +9099,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
8973
9099
|
const injectorType = container;
|
|
8974
9100
|
deepForEachProvider(defProviders, provider => {
|
|
8975
9101
|
ngDevMode && validateProvider(provider, defProviders, injectorType);
|
|
8976
|
-
|
|
9102
|
+
visitor(provider, injectorType);
|
|
8977
9103
|
});
|
|
8978
9104
|
}
|
|
8979
9105
|
}
|
|
@@ -9047,12 +9173,12 @@ const CIRCULAR = {};
|
|
|
9047
9173
|
/**
|
|
9048
9174
|
* A lazily initialized NullInjector.
|
|
9049
9175
|
*/
|
|
9050
|
-
let NULL_INJECTOR
|
|
9176
|
+
let NULL_INJECTOR = undefined;
|
|
9051
9177
|
function getNullInjector() {
|
|
9052
|
-
if (NULL_INJECTOR
|
|
9053
|
-
NULL_INJECTOR
|
|
9178
|
+
if (NULL_INJECTOR === undefined) {
|
|
9179
|
+
NULL_INJECTOR = new NullInjector();
|
|
9054
9180
|
}
|
|
9055
|
-
return NULL_INJECTOR
|
|
9181
|
+
return NULL_INJECTOR;
|
|
9056
9182
|
}
|
|
9057
9183
|
/**
|
|
9058
9184
|
* An `Injector` that's part of the environment injector hierarchy, which exists outside of the
|
|
@@ -9140,12 +9266,17 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9140
9266
|
this.assertNotDestroyed();
|
|
9141
9267
|
const previousInjector = setCurrentInjector(this);
|
|
9142
9268
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
9269
|
+
let prevInjectContext;
|
|
9270
|
+
if (ngDevMode) {
|
|
9271
|
+
prevInjectContext = setInjectorProfilerContext({ injector: this, token: null });
|
|
9272
|
+
}
|
|
9143
9273
|
try {
|
|
9144
9274
|
return fn();
|
|
9145
9275
|
}
|
|
9146
9276
|
finally {
|
|
9147
9277
|
setCurrentInjector(previousInjector);
|
|
9148
9278
|
setInjectImplementation(previousInjectImplementation);
|
|
9279
|
+
ngDevMode && setInjectorProfilerContext(prevInjectContext);
|
|
9149
9280
|
}
|
|
9150
9281
|
}
|
|
9151
9282
|
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
|
|
@@ -9155,6 +9286,10 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9155
9286
|
}
|
|
9156
9287
|
flags = convertToBitFlags(flags);
|
|
9157
9288
|
// Set the injection context.
|
|
9289
|
+
let prevInjectContext;
|
|
9290
|
+
if (ngDevMode) {
|
|
9291
|
+
prevInjectContext = setInjectorProfilerContext({ injector: this, token: token });
|
|
9292
|
+
}
|
|
9158
9293
|
const previousInjector = setCurrentInjector(this);
|
|
9159
9294
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
9160
9295
|
try {
|
|
@@ -9212,12 +9347,17 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9212
9347
|
// Lastly, restore the previous injection context.
|
|
9213
9348
|
setInjectImplementation(previousInjectImplementation);
|
|
9214
9349
|
setCurrentInjector(previousInjector);
|
|
9350
|
+
ngDevMode && setInjectorProfilerContext(prevInjectContext);
|
|
9215
9351
|
}
|
|
9216
9352
|
}
|
|
9217
9353
|
/** @internal */
|
|
9218
9354
|
resolveInjectorInitializers() {
|
|
9219
9355
|
const previousInjector = setCurrentInjector(this);
|
|
9220
9356
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
9357
|
+
let prevInjectContext;
|
|
9358
|
+
if (ngDevMode) {
|
|
9359
|
+
prevInjectContext = setInjectorProfilerContext({ injector: this, token: null });
|
|
9360
|
+
}
|
|
9221
9361
|
try {
|
|
9222
9362
|
const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
|
|
9223
9363
|
if (ngDevMode && !Array.isArray(initializers)) {
|
|
@@ -9233,6 +9373,7 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9233
9373
|
finally {
|
|
9234
9374
|
setCurrentInjector(previousInjector);
|
|
9235
9375
|
setInjectImplementation(previousInjectImplementation);
|
|
9376
|
+
ngDevMode && setInjectorProfilerContext(prevInjectContext);
|
|
9236
9377
|
}
|
|
9237
9378
|
}
|
|
9238
9379
|
toString() {
|
|
@@ -9258,6 +9399,17 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9258
9399
|
let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
|
|
9259
9400
|
// Construct a `Record` for the provider.
|
|
9260
9401
|
const record = providerToRecord(provider);
|
|
9402
|
+
if (ngDevMode) {
|
|
9403
|
+
runInInjectorProfilerContext(this, token, () => {
|
|
9404
|
+
// Emit InjectorProfilerEventType.Create if provider is a value provider because
|
|
9405
|
+
// these are the only providers that do not go through the value hydration logic
|
|
9406
|
+
// where this event would normally be emitted from.
|
|
9407
|
+
if (isValueProvider(provider)) {
|
|
9408
|
+
emitInstanceCreatedByInjectorEvent(provider.useValue);
|
|
9409
|
+
}
|
|
9410
|
+
emitProviderConfiguredEvent(provider);
|
|
9411
|
+
});
|
|
9412
|
+
}
|
|
9261
9413
|
if (!isTypeProvider(provider) && provider.multi === true) {
|
|
9262
9414
|
// If the provider indicates that it's a multi-provider, process it specially.
|
|
9263
9415
|
// First check whether it's been defined already.
|
|
@@ -9290,7 +9442,15 @@ class R3Injector extends EnvironmentInjector {
|
|
|
9290
9442
|
}
|
|
9291
9443
|
else if (record.value === NOT_YET) {
|
|
9292
9444
|
record.value = CIRCULAR;
|
|
9293
|
-
|
|
9445
|
+
if (ngDevMode) {
|
|
9446
|
+
runInInjectorProfilerContext(this, token, () => {
|
|
9447
|
+
record.value = record.factory();
|
|
9448
|
+
emitInstanceCreatedByInjectorEvent(record.value);
|
|
9449
|
+
});
|
|
9450
|
+
}
|
|
9451
|
+
else {
|
|
9452
|
+
record.value = record.factory();
|
|
9453
|
+
}
|
|
9294
9454
|
}
|
|
9295
9455
|
if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
|
|
9296
9456
|
this._ngOnDestroyHooks.add(record.value);
|
|
@@ -9489,6 +9649,7 @@ const PLATFORM_ID = new InjectionToken('Platform ID', {
|
|
|
9489
9649
|
* A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
|
|
9490
9650
|
* the application
|
|
9491
9651
|
* @publicApi
|
|
9652
|
+
* @deprecated
|
|
9492
9653
|
*/
|
|
9493
9654
|
const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
|
|
9494
9655
|
// We keep this token here, rather than the animations package, so that modules that only care
|
|
@@ -9709,6 +9870,10 @@ const NGH_DATA_KEY = makeStateKey(TRANSFER_STATE_TOKEN_ID);
|
|
|
9709
9870
|
* state that contains the necessary hydration info for this component.
|
|
9710
9871
|
*/
|
|
9711
9872
|
const NGH_ATTR_NAME = 'ngh';
|
|
9873
|
+
/**
|
|
9874
|
+
* Marker used in a comment node to ensure hydration content integrity
|
|
9875
|
+
*/
|
|
9876
|
+
const SSR_CONTENT_INTEGRITY_MARKER = 'nghm';
|
|
9712
9877
|
/**
|
|
9713
9878
|
* Reference to a function that reads `ngh` attribute value from a given RNode
|
|
9714
9879
|
* and retrieves hydration information from the TransferState using that value
|
|
@@ -9716,12 +9881,30 @@ const NGH_ATTR_NAME = 'ngh';
|
|
|
9716
9881
|
*
|
|
9717
9882
|
* @param rNode Component's host element.
|
|
9718
9883
|
* @param injector Injector that this component has access to.
|
|
9884
|
+
* @param isRootView Specifies whether we trying to read hydration info for the root view.
|
|
9719
9885
|
*/
|
|
9720
|
-
let _retrieveHydrationInfoImpl = (rNode, injector) => null;
|
|
9721
|
-
function retrieveHydrationInfoImpl(rNode, injector) {
|
|
9722
|
-
|
|
9886
|
+
let _retrieveHydrationInfoImpl = (rNode, injector, isRootView) => null;
|
|
9887
|
+
function retrieveHydrationInfoImpl(rNode, injector, isRootView = false) {
|
|
9888
|
+
let nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
|
|
9723
9889
|
if (nghAttrValue == null)
|
|
9724
9890
|
return null;
|
|
9891
|
+
// For cases when a root component also acts as an anchor node for a ViewContainerRef
|
|
9892
|
+
// (for example, when ViewContainerRef is injected in a root component), there is a need
|
|
9893
|
+
// to serialize information about the component itself, as well as an LContainer that
|
|
9894
|
+
// represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
|
|
9895
|
+
// (1) hydration info for the root component itself and (2) hydration info for the
|
|
9896
|
+
// ViewContainerRef instance (an LContainer). Each piece of information is included into
|
|
9897
|
+
// the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
|
|
9898
|
+
// Since we only have 1 root element, we encode both bits of info into a single string:
|
|
9899
|
+
// ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
|
|
9900
|
+
// and 25 is the `ngh` for a root view which holds LContainer).
|
|
9901
|
+
const [componentViewNgh, rootViewNgh] = nghAttrValue.split('|');
|
|
9902
|
+
nghAttrValue = isRootView ? rootViewNgh : componentViewNgh;
|
|
9903
|
+
if (!nghAttrValue)
|
|
9904
|
+
return null;
|
|
9905
|
+
// We've read one of the ngh ids, keep the remaining one, so that
|
|
9906
|
+
// we can set it back on the DOM element.
|
|
9907
|
+
const remainingNgh = isRootView ? componentViewNgh : (rootViewNgh ? `|${rootViewNgh}` : '');
|
|
9725
9908
|
let data = {};
|
|
9726
9909
|
// An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
|
|
9727
9910
|
// which means that no special annotations are required. Do not attempt to read
|
|
@@ -9743,9 +9926,29 @@ function retrieveHydrationInfoImpl(rNode, injector) {
|
|
|
9743
9926
|
data,
|
|
9744
9927
|
firstChild: rNode.firstChild ?? null,
|
|
9745
9928
|
};
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9929
|
+
if (isRootView) {
|
|
9930
|
+
// If there is hydration info present for the root view, it means that there was
|
|
9931
|
+
// a ViewContainerRef injected in the root component. The root component host element
|
|
9932
|
+
// acted as an anchor node in this scenario. As a result, the DOM nodes that represent
|
|
9933
|
+
// embedded views in this ViewContainerRef are located as siblings to the host node,
|
|
9934
|
+
// i.e. `<app-root /><#VIEW1><#VIEW2>...<!--container-->`. In this case, the current
|
|
9935
|
+
// node becomes the first child of this root view and the next sibling is the first
|
|
9936
|
+
// element in the DOM segment.
|
|
9937
|
+
dehydratedView.firstChild = rNode;
|
|
9938
|
+
// We use `0` here, since this is the slot (right after the HEADER_OFFSET)
|
|
9939
|
+
// where a component LView or an LContainer is located in a root LView.
|
|
9940
|
+
setSegmentHead(dehydratedView, 0, rNode.nextSibling);
|
|
9941
|
+
}
|
|
9942
|
+
if (remainingNgh) {
|
|
9943
|
+
// If we have only used one of the ngh ids, store the remaining one
|
|
9944
|
+
// back on this RNode.
|
|
9945
|
+
rNode.setAttribute(NGH_ATTR_NAME, remainingNgh);
|
|
9946
|
+
}
|
|
9947
|
+
else {
|
|
9948
|
+
// The `ngh` attribute is cleared from the DOM node now
|
|
9949
|
+
// that the data has been retrieved for all indices.
|
|
9950
|
+
rNode.removeAttribute(NGH_ATTR_NAME);
|
|
9951
|
+
}
|
|
9749
9952
|
// Note: don't check whether this node was claimed for hydration,
|
|
9750
9953
|
// because this node might've been previously claimed while processing
|
|
9751
9954
|
// template instructions.
|
|
@@ -9763,14 +9966,16 @@ function enableRetrieveHydrationInfoImpl() {
|
|
|
9763
9966
|
* Retrieves hydration info by reading the value from the `ngh` attribute
|
|
9764
9967
|
* and accessing a corresponding slot in TransferState storage.
|
|
9765
9968
|
*/
|
|
9766
|
-
function retrieveHydrationInfo(rNode, injector) {
|
|
9767
|
-
return _retrieveHydrationInfoImpl(rNode, injector);
|
|
9969
|
+
function retrieveHydrationInfo(rNode, injector, isRootView = false) {
|
|
9970
|
+
return _retrieveHydrationInfoImpl(rNode, injector, isRootView);
|
|
9768
9971
|
}
|
|
9769
9972
|
/**
|
|
9770
|
-
* Retrieves
|
|
9771
|
-
*
|
|
9973
|
+
* Retrieves the necessary object from a given ViewRef to serialize:
|
|
9974
|
+
* - an LView for component views
|
|
9975
|
+
* - an LContainer for cases when component acts as a ViewContainerRef anchor
|
|
9976
|
+
* - `null` in case of an embedded view
|
|
9772
9977
|
*/
|
|
9773
|
-
function
|
|
9978
|
+
function getLNodeForHydration(viewRef) {
|
|
9774
9979
|
// Reading an internal field from `ViewRef` instance.
|
|
9775
9980
|
let lView = viewRef._lView;
|
|
9776
9981
|
const tView = lView[TVIEW];
|
|
@@ -9784,12 +9989,6 @@ function getComponentLViewForHydration(viewRef) {
|
|
|
9784
9989
|
if (isRootView(lView)) {
|
|
9785
9990
|
lView = lView[HEADER_OFFSET];
|
|
9786
9991
|
}
|
|
9787
|
-
// If a `ViewContainerRef` was injected in a component class, this resulted
|
|
9788
|
-
// in an LContainer creation at that location. In this case, the component
|
|
9789
|
-
// LView is in the LContainer's `HOST` slot.
|
|
9790
|
-
if (isLContainer(lView)) {
|
|
9791
|
-
lView = lView[HOST];
|
|
9792
|
-
}
|
|
9793
9992
|
return lView;
|
|
9794
9993
|
}
|
|
9795
9994
|
function getTextNodeContent(node) {
|
|
@@ -10092,7 +10291,7 @@ class Version {
|
|
|
10092
10291
|
/**
|
|
10093
10292
|
* @publicApi
|
|
10094
10293
|
*/
|
|
10095
|
-
const VERSION = new Version('16.2.0
|
|
10294
|
+
const VERSION = new Version('16.2.0');
|
|
10096
10295
|
|
|
10097
10296
|
// This default value is when checking the hierarchy for a token.
|
|
10098
10297
|
//
|
|
@@ -10114,171 +10313,658 @@ const VERSION = new Version('16.2.0-next.4');
|
|
|
10114
10313
|
const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
|
|
10115
10314
|
|
|
10116
10315
|
/**
|
|
10117
|
-
*
|
|
10118
|
-
*
|
|
10119
|
-
* Returns the root view because it is found as a byproduct of marking the view tree
|
|
10120
|
-
* dirty, and can be used by methods that consume markViewDirty() to easily schedule
|
|
10121
|
-
* change detection. Otherwise, such methods would need to traverse up the view tree
|
|
10122
|
-
* an additional time to get the root view and schedule a tick on it.
|
|
10123
|
-
*
|
|
10124
|
-
* @param lView The starting LView to mark dirty
|
|
10125
|
-
* @returns the root LView
|
|
10126
|
-
*/
|
|
10127
|
-
function markViewDirty(lView) {
|
|
10128
|
-
while (lView) {
|
|
10129
|
-
lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
|
|
10130
|
-
const parent = getLViewParent(lView);
|
|
10131
|
-
// Stop traversing up as soon as you find a root view that wasn't attached to any container
|
|
10132
|
-
if (isRootView(lView) && !parent) {
|
|
10133
|
-
return lView;
|
|
10134
|
-
}
|
|
10135
|
-
// continue otherwise
|
|
10136
|
-
lView = parent;
|
|
10137
|
-
}
|
|
10138
|
-
return null;
|
|
10139
|
-
}
|
|
10140
|
-
|
|
10141
|
-
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
10142
|
-
function wrappedError(message, originalError) {
|
|
10143
|
-
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
10144
|
-
const error = Error(msg);
|
|
10145
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
10146
|
-
return error;
|
|
10147
|
-
}
|
|
10148
|
-
function getOriginalError(error) {
|
|
10149
|
-
return error[ERROR_ORIGINAL_ERROR];
|
|
10150
|
-
}
|
|
10151
|
-
|
|
10152
|
-
/**
|
|
10153
|
-
* Provides a hook for centralized exception handling.
|
|
10154
|
-
*
|
|
10155
|
-
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
10156
|
-
* intercept error handling, write a custom exception handler that replaces this default as
|
|
10157
|
-
* appropriate for your app.
|
|
10158
|
-
*
|
|
10159
|
-
* @usageNotes
|
|
10160
|
-
* ### Example
|
|
10161
|
-
*
|
|
10162
|
-
* ```
|
|
10163
|
-
* class MyErrorHandler implements ErrorHandler {
|
|
10164
|
-
* handleError(error) {
|
|
10165
|
-
* // do something with the exception
|
|
10166
|
-
* }
|
|
10167
|
-
* }
|
|
10316
|
+
* Runs the given function in the [context](guide/dependency-injection-context) of the given
|
|
10317
|
+
* `Injector`.
|
|
10168
10318
|
*
|
|
10169
|
-
*
|
|
10170
|
-
*
|
|
10171
|
-
*
|
|
10172
|
-
* class MyModule {}
|
|
10173
|
-
* ```
|
|
10319
|
+
* Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
|
|
10320
|
+
* from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
|
|
10321
|
+
* any asynchronous callbacks or after any `await` points.
|
|
10174
10322
|
*
|
|
10323
|
+
* @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
|
|
10324
|
+
* is executing
|
|
10325
|
+
* @param fn the closure to be run in the context of `injector`
|
|
10326
|
+
* @returns the return value of the function, if any
|
|
10175
10327
|
* @publicApi
|
|
10176
10328
|
*/
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
* @internal
|
|
10181
|
-
*/
|
|
10182
|
-
this._console = console;
|
|
10183
|
-
}
|
|
10184
|
-
handleError(error) {
|
|
10185
|
-
const originalError = this._findOriginalError(error);
|
|
10186
|
-
this._console.error('ERROR', error);
|
|
10187
|
-
if (originalError) {
|
|
10188
|
-
this._console.error('ORIGINAL ERROR', originalError);
|
|
10189
|
-
}
|
|
10329
|
+
function runInInjectionContext(injector, fn) {
|
|
10330
|
+
if (injector instanceof R3Injector) {
|
|
10331
|
+
injector.assertNotDestroyed();
|
|
10190
10332
|
}
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
while (e && getOriginalError(e)) {
|
|
10195
|
-
e = getOriginalError(e);
|
|
10196
|
-
}
|
|
10197
|
-
return e || null;
|
|
10333
|
+
let prevInjectorProfilerContext;
|
|
10334
|
+
if (ngDevMode) {
|
|
10335
|
+
prevInjectorProfilerContext = setInjectorProfilerContext({ injector, token: null });
|
|
10198
10336
|
}
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
/**
|
|
10202
|
-
* Internal token that specifies whether DOM reuse logic
|
|
10203
|
-
* during hydration is enabled.
|
|
10204
|
-
*/
|
|
10205
|
-
const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
|
|
10206
|
-
// By default (in client rendering mode), we remove all the contents
|
|
10207
|
-
// of the host element and render an application after that.
|
|
10208
|
-
const PRESERVE_HOST_CONTENT_DEFAULT = false;
|
|
10209
|
-
/**
|
|
10210
|
-
* Internal token that indicates whether host element content should be
|
|
10211
|
-
* retained during the bootstrap.
|
|
10212
|
-
*/
|
|
10213
|
-
const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
|
|
10214
|
-
providedIn: 'root',
|
|
10215
|
-
factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
|
|
10216
|
-
});
|
|
10217
|
-
|
|
10218
|
-
function normalizeDebugBindingName(name) {
|
|
10219
|
-
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
10220
|
-
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
10221
|
-
return `ng-reflect-${name}`;
|
|
10222
|
-
}
|
|
10223
|
-
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
|
10224
|
-
function camelCaseToDashCase(input) {
|
|
10225
|
-
return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
|
|
10226
|
-
}
|
|
10227
|
-
function normalizeDebugBindingValue(value) {
|
|
10337
|
+
const prevInjector = setCurrentInjector(injector);
|
|
10338
|
+
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
10228
10339
|
try {
|
|
10229
|
-
|
|
10230
|
-
return value != null ? value.toString().slice(0, 30) : value;
|
|
10340
|
+
return fn();
|
|
10231
10341
|
}
|
|
10232
|
-
|
|
10233
|
-
|
|
10342
|
+
finally {
|
|
10343
|
+
setCurrentInjector(prevInjector);
|
|
10344
|
+
ngDevMode && setInjectorProfilerContext(prevInjectorProfilerContext);
|
|
10345
|
+
setInjectImplementation(previousInjectImplementation);
|
|
10234
10346
|
}
|
|
10235
10347
|
}
|
|
10236
|
-
|
|
10237
|
-
/**
|
|
10238
|
-
*
|
|
10239
|
-
* @codeGenApi
|
|
10240
|
-
*/
|
|
10241
|
-
function ɵɵresolveWindow(element) {
|
|
10242
|
-
return element.ownerDocument.defaultView;
|
|
10243
|
-
}
|
|
10244
10348
|
/**
|
|
10349
|
+
* Asserts that the current stack frame is within an [injection
|
|
10350
|
+
* context](guide/dependency-injection-context) and has access to `inject`.
|
|
10245
10351
|
*
|
|
10246
|
-
* @
|
|
10247
|
-
*/
|
|
10248
|
-
function ɵɵresolveDocument(element) {
|
|
10249
|
-
return element.ownerDocument;
|
|
10250
|
-
}
|
|
10251
|
-
/**
|
|
10352
|
+
* @param debugFn a reference to the function making the assertion (used for the error message).
|
|
10252
10353
|
*
|
|
10253
|
-
* @
|
|
10354
|
+
* @publicApi
|
|
10254
10355
|
*/
|
|
10255
|
-
function
|
|
10256
|
-
|
|
10356
|
+
function assertInInjectionContext(debugFn) {
|
|
10357
|
+
// Taking a `Function` instead of a string name here prevents the unminified name of the function
|
|
10358
|
+
// from being retained in the bundle regardless of minification.
|
|
10359
|
+
if (!getInjectImplementation() && !getCurrentInjector()) {
|
|
10360
|
+
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
|
|
10361
|
+
(debugFn.name +
|
|
10362
|
+
'() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
|
|
10363
|
+
}
|
|
10257
10364
|
}
|
|
10365
|
+
|
|
10258
10366
|
/**
|
|
10259
|
-
*
|
|
10260
|
-
* in property binding metadata. See storeBindingMetadata().
|
|
10261
|
-
*
|
|
10262
|
-
* We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
|
|
10263
|
-
* because it is a very uncommon character that is unlikely to be part of a user's
|
|
10264
|
-
* property names or interpolation strings. If it is in fact used in a property
|
|
10265
|
-
* binding, DebugElement.properties will not return the correct value for that
|
|
10266
|
-
* binding. However, there should be no runtime effect for real applications.
|
|
10267
|
-
*
|
|
10268
|
-
* This character is typically rendered as a question mark inside of a diamond.
|
|
10269
|
-
* See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
|
|
10367
|
+
* A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
|
|
10270
10368
|
*
|
|
10369
|
+
* This should be kept up to date with the public exports of @angular/core.
|
|
10271
10370
|
*/
|
|
10272
|
-
const
|
|
10371
|
+
const angularCoreDiEnv = {
|
|
10372
|
+
'ɵɵdefineInjectable': ɵɵdefineInjectable,
|
|
10373
|
+
'ɵɵdefineInjector': ɵɵdefineInjector,
|
|
10374
|
+
'ɵɵinject': ɵɵinject,
|
|
10375
|
+
'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
|
|
10376
|
+
'resolveForwardRef': resolveForwardRef,
|
|
10377
|
+
};
|
|
10378
|
+
|
|
10273
10379
|
/**
|
|
10274
|
-
*
|
|
10380
|
+
* Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
|
|
10381
|
+
* injectable def (`ɵprov`) onto the injectable type.
|
|
10275
10382
|
*/
|
|
10276
|
-
function
|
|
10383
|
+
function compileInjectable(type, meta) {
|
|
10384
|
+
let ngInjectableDef = null;
|
|
10385
|
+
let ngFactoryDef = null;
|
|
10386
|
+
// if NG_PROV_DEF is already defined on this class then don't overwrite it
|
|
10387
|
+
if (!type.hasOwnProperty(NG_PROV_DEF)) {
|
|
10388
|
+
Object.defineProperty(type, NG_PROV_DEF, {
|
|
10389
|
+
get: () => {
|
|
10390
|
+
if (ngInjectableDef === null) {
|
|
10391
|
+
const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
|
|
10392
|
+
ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
|
|
10393
|
+
}
|
|
10394
|
+
return ngInjectableDef;
|
|
10395
|
+
},
|
|
10396
|
+
});
|
|
10397
|
+
}
|
|
10398
|
+
// if NG_FACTORY_DEF is already defined on this class then don't overwrite it
|
|
10399
|
+
if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
|
|
10400
|
+
Object.defineProperty(type, NG_FACTORY_DEF, {
|
|
10401
|
+
get: () => {
|
|
10402
|
+
if (ngFactoryDef === null) {
|
|
10403
|
+
const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
|
|
10404
|
+
ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
|
|
10405
|
+
name: type.name,
|
|
10406
|
+
type,
|
|
10407
|
+
typeArgumentCount: 0,
|
|
10408
|
+
deps: reflectDependencies(type),
|
|
10409
|
+
target: compiler.FactoryTarget.Injectable
|
|
10410
|
+
});
|
|
10411
|
+
}
|
|
10412
|
+
return ngFactoryDef;
|
|
10413
|
+
},
|
|
10414
|
+
// Leave this configurable so that the factories from directives or pipes can take precedence.
|
|
10415
|
+
configurable: true
|
|
10416
|
+
});
|
|
10417
|
+
}
|
|
10418
|
+
}
|
|
10419
|
+
const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
|
|
10420
|
+
function isUseClassProvider(meta) {
|
|
10421
|
+
return meta.useClass !== undefined;
|
|
10422
|
+
}
|
|
10423
|
+
function isUseValueProvider(meta) {
|
|
10424
|
+
return USE_VALUE in meta;
|
|
10425
|
+
}
|
|
10426
|
+
function isUseFactoryProvider(meta) {
|
|
10427
|
+
return meta.useFactory !== undefined;
|
|
10428
|
+
}
|
|
10429
|
+
function isUseExistingProvider(meta) {
|
|
10430
|
+
return meta.useExisting !== undefined;
|
|
10431
|
+
}
|
|
10432
|
+
function getInjectableMetadata(type, srcMeta) {
|
|
10433
|
+
// Allow the compilation of a class with a `@Injectable()` decorator without parameters
|
|
10434
|
+
const meta = srcMeta || { providedIn: null };
|
|
10435
|
+
const compilerMeta = {
|
|
10436
|
+
name: type.name,
|
|
10437
|
+
type: type,
|
|
10438
|
+
typeArgumentCount: 0,
|
|
10439
|
+
providedIn: meta.providedIn,
|
|
10440
|
+
};
|
|
10441
|
+
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
|
|
10442
|
+
compilerMeta.deps = convertDependencies(meta.deps);
|
|
10443
|
+
}
|
|
10444
|
+
// Check to see if the user explicitly provided a `useXxxx` property.
|
|
10445
|
+
if (isUseClassProvider(meta)) {
|
|
10446
|
+
compilerMeta.useClass = meta.useClass;
|
|
10447
|
+
}
|
|
10448
|
+
else if (isUseValueProvider(meta)) {
|
|
10449
|
+
compilerMeta.useValue = meta.useValue;
|
|
10450
|
+
}
|
|
10451
|
+
else if (isUseFactoryProvider(meta)) {
|
|
10452
|
+
compilerMeta.useFactory = meta.useFactory;
|
|
10453
|
+
}
|
|
10454
|
+
else if (isUseExistingProvider(meta)) {
|
|
10455
|
+
compilerMeta.useExisting = meta.useExisting;
|
|
10456
|
+
}
|
|
10457
|
+
return compilerMeta;
|
|
10458
|
+
}
|
|
10459
|
+
|
|
10460
|
+
/**
|
|
10461
|
+
* Injectable decorator and metadata.
|
|
10462
|
+
*
|
|
10463
|
+
* @Annotation
|
|
10464
|
+
* @publicApi
|
|
10465
|
+
*/
|
|
10466
|
+
const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
|
|
10467
|
+
|
|
10468
|
+
/**
|
|
10469
|
+
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
10470
|
+
*/
|
|
10471
|
+
function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
10472
|
+
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
10473
|
+
injector.resolveInjectorInitializers();
|
|
10474
|
+
return injector;
|
|
10475
|
+
}
|
|
10476
|
+
/**
|
|
10477
|
+
* Creates a new injector without eagerly resolving its injector types. Can be used in places
|
|
10478
|
+
* where resolving the injector types immediately can lead to an infinite loop. The injector types
|
|
10479
|
+
* should be resolved at a later point by calling `_resolveInjectorDefTypes`.
|
|
10480
|
+
*/
|
|
10481
|
+
function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
|
|
10482
|
+
const providers = [
|
|
10483
|
+
additionalProviders || EMPTY_ARRAY,
|
|
10484
|
+
importProvidersFrom(defType),
|
|
10485
|
+
];
|
|
10486
|
+
name = name || (typeof defType === 'object' ? undefined : stringify(defType));
|
|
10487
|
+
return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
|
|
10488
|
+
}
|
|
10489
|
+
|
|
10490
|
+
/**
|
|
10491
|
+
* Concrete injectors implement this interface. Injectors are configured
|
|
10492
|
+
* with [providers](guide/glossary#provider) that associate
|
|
10493
|
+
* dependencies of various types with [injection tokens](guide/glossary#di-token).
|
|
10494
|
+
*
|
|
10495
|
+
* @see ["DI Providers"](guide/dependency-injection-providers).
|
|
10496
|
+
* @see {@link StaticProvider}
|
|
10497
|
+
*
|
|
10498
|
+
* @usageNotes
|
|
10499
|
+
*
|
|
10500
|
+
* The following example creates a service injector instance.
|
|
10501
|
+
*
|
|
10502
|
+
* {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
|
|
10503
|
+
*
|
|
10504
|
+
* ### Usage example
|
|
10505
|
+
*
|
|
10506
|
+
* {@example core/di/ts/injector_spec.ts region='Injector'}
|
|
10507
|
+
*
|
|
10508
|
+
* `Injector` returns itself when given `Injector` as a token:
|
|
10509
|
+
*
|
|
10510
|
+
* {@example core/di/ts/injector_spec.ts region='injectInjector'}
|
|
10511
|
+
*
|
|
10512
|
+
* @publicApi
|
|
10513
|
+
*/
|
|
10514
|
+
class Injector {
|
|
10515
|
+
static { this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; }
|
|
10516
|
+
static { this.NULL = ( /* @__PURE__ */new NullInjector()); }
|
|
10517
|
+
static create(options, parent) {
|
|
10518
|
+
if (Array.isArray(options)) {
|
|
10519
|
+
return createInjector({ name: '' }, parent, options, '');
|
|
10520
|
+
}
|
|
10521
|
+
else {
|
|
10522
|
+
const name = options.name ?? '';
|
|
10523
|
+
return createInjector({ name }, options.parent, options.providers, name);
|
|
10524
|
+
}
|
|
10525
|
+
}
|
|
10526
|
+
/** @nocollapse */
|
|
10527
|
+
static { this.ɵprov = ɵɵdefineInjectable({
|
|
10528
|
+
token: Injector,
|
|
10529
|
+
providedIn: 'any',
|
|
10530
|
+
factory: () => ɵɵinject(INJECTOR),
|
|
10531
|
+
}); }
|
|
10532
|
+
/**
|
|
10533
|
+
* @internal
|
|
10534
|
+
* @nocollapse
|
|
10535
|
+
*/
|
|
10536
|
+
static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
|
|
10537
|
+
}
|
|
10538
|
+
|
|
10539
|
+
/**
|
|
10540
|
+
* @module
|
|
10541
|
+
* @description
|
|
10542
|
+
* The `di` module provides dependency injection container services.
|
|
10543
|
+
*/
|
|
10544
|
+
|
|
10545
|
+
/**
|
|
10546
|
+
* This file should not be necessary because node resolution should just default to `./di/index`!
|
|
10547
|
+
*
|
|
10548
|
+
* However it does not seem to work and it breaks:
|
|
10549
|
+
* - //packages/animations/browser/test:test_web_chromium-local
|
|
10550
|
+
* - //packages/compiler-cli/test:extract_i18n
|
|
10551
|
+
* - //packages/compiler-cli/test:ngc
|
|
10552
|
+
* - //packages/compiler-cli/test:perform_watch
|
|
10553
|
+
* - //packages/compiler-cli/test/diagnostics:check_types
|
|
10554
|
+
* - //packages/compiler-cli/test/transformers:test
|
|
10555
|
+
* - //packages/compiler/test:test
|
|
10556
|
+
* - //tools/public_api_guard:core_api
|
|
10557
|
+
*
|
|
10558
|
+
* Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
|
|
10559
|
+
* safe to delete this file.
|
|
10560
|
+
*/
|
|
10561
|
+
|
|
10562
|
+
/**
|
|
10563
|
+
* `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
|
|
10564
|
+
* The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
|
|
10565
|
+
* is injected in a component or directive, the callbacks run when that component or
|
|
10566
|
+
* directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
|
|
10567
|
+
*
|
|
10568
|
+
* @publicApi
|
|
10569
|
+
*/
|
|
10570
|
+
class DestroyRef {
|
|
10571
|
+
/**
|
|
10572
|
+
* @internal
|
|
10573
|
+
* @nocollapse
|
|
10574
|
+
*/
|
|
10575
|
+
static { this.__NG_ELEMENT_ID__ = injectDestroyRef; }
|
|
10576
|
+
/**
|
|
10577
|
+
* @internal
|
|
10578
|
+
* @nocollapse
|
|
10579
|
+
*/
|
|
10580
|
+
static { this.__NG_ENV_ID__ = (injector) => injector; }
|
|
10581
|
+
}
|
|
10582
|
+
class NodeInjectorDestroyRef extends DestroyRef {
|
|
10583
|
+
constructor(_lView) {
|
|
10584
|
+
super();
|
|
10585
|
+
this._lView = _lView;
|
|
10586
|
+
}
|
|
10587
|
+
onDestroy(callback) {
|
|
10588
|
+
storeLViewOnDestroy(this._lView, callback);
|
|
10589
|
+
return () => removeLViewOnDestroy(this._lView, callback);
|
|
10590
|
+
}
|
|
10591
|
+
}
|
|
10592
|
+
function injectDestroyRef() {
|
|
10593
|
+
return new NodeInjectorDestroyRef(getLView());
|
|
10594
|
+
}
|
|
10595
|
+
|
|
10596
|
+
/**
|
|
10597
|
+
*
|
|
10598
|
+
* @codeGenApi
|
|
10599
|
+
*/
|
|
10600
|
+
function ɵɵresolveWindow(element) {
|
|
10601
|
+
return element.ownerDocument.defaultView;
|
|
10602
|
+
}
|
|
10603
|
+
/**
|
|
10604
|
+
*
|
|
10605
|
+
* @codeGenApi
|
|
10606
|
+
*/
|
|
10607
|
+
function ɵɵresolveDocument(element) {
|
|
10608
|
+
return element.ownerDocument;
|
|
10609
|
+
}
|
|
10610
|
+
/**
|
|
10611
|
+
*
|
|
10612
|
+
* @codeGenApi
|
|
10613
|
+
*/
|
|
10614
|
+
function ɵɵresolveBody(element) {
|
|
10615
|
+
return element.ownerDocument.body;
|
|
10616
|
+
}
|
|
10617
|
+
/**
|
|
10618
|
+
* The special delimiter we use to separate property names, prefixes, and suffixes
|
|
10619
|
+
* in property binding metadata. See storeBindingMetadata().
|
|
10620
|
+
*
|
|
10621
|
+
* We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
|
|
10622
|
+
* because it is a very uncommon character that is unlikely to be part of a user's
|
|
10623
|
+
* property names or interpolation strings. If it is in fact used in a property
|
|
10624
|
+
* binding, DebugElement.properties will not return the correct value for that
|
|
10625
|
+
* binding. However, there should be no runtime effect for real applications.
|
|
10626
|
+
*
|
|
10627
|
+
* This character is typically rendered as a question mark inside of a diamond.
|
|
10628
|
+
* See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
|
|
10629
|
+
*
|
|
10630
|
+
*/
|
|
10631
|
+
const INTERPOLATION_DELIMITER = `�`;
|
|
10632
|
+
/**
|
|
10633
|
+
* Unwrap a value which might be behind a closure (for forward declaration reasons).
|
|
10634
|
+
*/
|
|
10635
|
+
function maybeUnwrapFn(value) {
|
|
10277
10636
|
if (value instanceof Function) {
|
|
10278
10637
|
return value();
|
|
10279
10638
|
}
|
|
10280
|
-
else {
|
|
10281
|
-
return value;
|
|
10639
|
+
else {
|
|
10640
|
+
return value;
|
|
10641
|
+
}
|
|
10642
|
+
}
|
|
10643
|
+
/**
|
|
10644
|
+
* Detects whether the code is invoked in a browser.
|
|
10645
|
+
* Later on, this check should be replaced with a tree-shakable
|
|
10646
|
+
* flag (e.g. `!isServer`).
|
|
10647
|
+
*/
|
|
10648
|
+
function isPlatformBrowser(injector) {
|
|
10649
|
+
return (injector ?? inject(Injector)).get(PLATFORM_ID) === 'browser';
|
|
10650
|
+
}
|
|
10651
|
+
|
|
10652
|
+
/**
|
|
10653
|
+
* Register a callback to be invoked each time the application
|
|
10654
|
+
* finishes rendering.
|
|
10655
|
+
*
|
|
10656
|
+
* Note that the callback will run
|
|
10657
|
+
* - in the order it was registered
|
|
10658
|
+
* - once per render
|
|
10659
|
+
* - on browser platforms only
|
|
10660
|
+
*
|
|
10661
|
+
* <div class="alert is-important">
|
|
10662
|
+
*
|
|
10663
|
+
* Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
|
|
10664
|
+
* You must use caution when directly reading or writing the DOM and layout.
|
|
10665
|
+
*
|
|
10666
|
+
* </div>
|
|
10667
|
+
*
|
|
10668
|
+
* @param callback A callback function to register
|
|
10669
|
+
*
|
|
10670
|
+
* @usageNotes
|
|
10671
|
+
*
|
|
10672
|
+
* Use `afterRender` to read or write the DOM after each render.
|
|
10673
|
+
*
|
|
10674
|
+
* ### Example
|
|
10675
|
+
* ```ts
|
|
10676
|
+
* @Component({
|
|
10677
|
+
* selector: 'my-cmp',
|
|
10678
|
+
* template: `<span #content>{{ ... }}</span>`,
|
|
10679
|
+
* })
|
|
10680
|
+
* export class MyComponent {
|
|
10681
|
+
* @ViewChild('content') contentRef: ElementRef;
|
|
10682
|
+
*
|
|
10683
|
+
* constructor() {
|
|
10684
|
+
* afterRender(() => {
|
|
10685
|
+
* console.log('content height: ' + this.contentRef.nativeElement.scrollHeight);
|
|
10686
|
+
* });
|
|
10687
|
+
* }
|
|
10688
|
+
* }
|
|
10689
|
+
* ```
|
|
10690
|
+
*
|
|
10691
|
+
* @developerPreview
|
|
10692
|
+
*/
|
|
10693
|
+
function afterRender(callback, options) {
|
|
10694
|
+
!options && assertInInjectionContext(afterRender);
|
|
10695
|
+
const injector = options?.injector ?? inject(Injector);
|
|
10696
|
+
if (!isPlatformBrowser(injector)) {
|
|
10697
|
+
return { destroy() { } };
|
|
10698
|
+
}
|
|
10699
|
+
let destroy;
|
|
10700
|
+
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
|
10701
|
+
const manager = injector.get(AfterRenderEventManager);
|
|
10702
|
+
const instance = new AfterRenderCallback(callback);
|
|
10703
|
+
destroy = () => {
|
|
10704
|
+
manager.unregister(instance);
|
|
10705
|
+
unregisterFn();
|
|
10706
|
+
};
|
|
10707
|
+
manager.register(instance);
|
|
10708
|
+
return { destroy };
|
|
10709
|
+
}
|
|
10710
|
+
/**
|
|
10711
|
+
* Register a callback to be invoked the next time the application
|
|
10712
|
+
* finishes rendering.
|
|
10713
|
+
*
|
|
10714
|
+
* Note that the callback will run
|
|
10715
|
+
* - in the order it was registered
|
|
10716
|
+
* - on browser platforms only
|
|
10717
|
+
*
|
|
10718
|
+
* <div class="alert is-important">
|
|
10719
|
+
*
|
|
10720
|
+
* Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
|
|
10721
|
+
* You must use caution when directly reading or writing the DOM and layout.
|
|
10722
|
+
*
|
|
10723
|
+
* </div>
|
|
10724
|
+
*
|
|
10725
|
+
* @param callback A callback function to register
|
|
10726
|
+
*
|
|
10727
|
+
* @usageNotes
|
|
10728
|
+
*
|
|
10729
|
+
* Use `afterNextRender` to read or write the DOM once,
|
|
10730
|
+
* for example to initialize a non-Angular library.
|
|
10731
|
+
*
|
|
10732
|
+
* ### Example
|
|
10733
|
+
* ```ts
|
|
10734
|
+
* @Component({
|
|
10735
|
+
* selector: 'my-chart-cmp',
|
|
10736
|
+
* template: `<div #chart>{{ ... }}</div>`,
|
|
10737
|
+
* })
|
|
10738
|
+
* export class MyChartCmp {
|
|
10739
|
+
* @ViewChild('chart') chartRef: ElementRef;
|
|
10740
|
+
* chart: MyChart|null;
|
|
10741
|
+
*
|
|
10742
|
+
* constructor() {
|
|
10743
|
+
* afterNextRender(() => {
|
|
10744
|
+
* this.chart = new MyChart(this.chartRef.nativeElement);
|
|
10745
|
+
* });
|
|
10746
|
+
* }
|
|
10747
|
+
* }
|
|
10748
|
+
* ```
|
|
10749
|
+
*
|
|
10750
|
+
* @developerPreview
|
|
10751
|
+
*/
|
|
10752
|
+
function afterNextRender(callback, options) {
|
|
10753
|
+
!options && assertInInjectionContext(afterNextRender);
|
|
10754
|
+
const injector = options?.injector ?? inject(Injector);
|
|
10755
|
+
if (!isPlatformBrowser(injector)) {
|
|
10756
|
+
return { destroy() { } };
|
|
10757
|
+
}
|
|
10758
|
+
let destroy;
|
|
10759
|
+
const unregisterFn = injector.get(DestroyRef).onDestroy(() => destroy?.());
|
|
10760
|
+
const manager = injector.get(AfterRenderEventManager);
|
|
10761
|
+
const instance = new AfterRenderCallback(() => {
|
|
10762
|
+
destroy?.();
|
|
10763
|
+
callback();
|
|
10764
|
+
});
|
|
10765
|
+
destroy = () => {
|
|
10766
|
+
manager.unregister(instance);
|
|
10767
|
+
unregisterFn();
|
|
10768
|
+
};
|
|
10769
|
+
manager.register(instance);
|
|
10770
|
+
return { destroy };
|
|
10771
|
+
}
|
|
10772
|
+
/**
|
|
10773
|
+
* A wrapper around a function to be used as an after render callback.
|
|
10774
|
+
* @private
|
|
10775
|
+
*/
|
|
10776
|
+
class AfterRenderCallback {
|
|
10777
|
+
constructor(callback) {
|
|
10778
|
+
this.callback = callback;
|
|
10779
|
+
}
|
|
10780
|
+
invoke() {
|
|
10781
|
+
this.callback();
|
|
10782
|
+
}
|
|
10783
|
+
}
|
|
10784
|
+
/**
|
|
10785
|
+
* Implements `afterRender` and `afterNextRender` callback manager logic.
|
|
10786
|
+
*/
|
|
10787
|
+
class AfterRenderEventManager {
|
|
10788
|
+
constructor() {
|
|
10789
|
+
this.callbacks = new Set();
|
|
10790
|
+
this.deferredCallbacks = new Set();
|
|
10791
|
+
this.renderDepth = 0;
|
|
10792
|
+
this.runningCallbacks = false;
|
|
10793
|
+
}
|
|
10794
|
+
/**
|
|
10795
|
+
* Mark the beginning of a render operation (i.e. CD cycle).
|
|
10796
|
+
* Throws if called from an `afterRender` callback.
|
|
10797
|
+
*/
|
|
10798
|
+
begin() {
|
|
10799
|
+
if (this.runningCallbacks) {
|
|
10800
|
+
throw new RuntimeError(102 /* RuntimeErrorCode.RECURSIVE_APPLICATION_RENDER */, ngDevMode &&
|
|
10801
|
+
'A new render operation began before the previous operation ended. ' +
|
|
10802
|
+
'Did you trigger change detection from afterRender or afterNextRender?');
|
|
10803
|
+
}
|
|
10804
|
+
this.renderDepth++;
|
|
10805
|
+
}
|
|
10806
|
+
/**
|
|
10807
|
+
* Mark the end of a render operation. Registered callbacks
|
|
10808
|
+
* are invoked if there are no more pending operations.
|
|
10809
|
+
*/
|
|
10810
|
+
end() {
|
|
10811
|
+
this.renderDepth--;
|
|
10812
|
+
if (this.renderDepth === 0) {
|
|
10813
|
+
try {
|
|
10814
|
+
this.runningCallbacks = true;
|
|
10815
|
+
for (const callback of this.callbacks) {
|
|
10816
|
+
callback.invoke();
|
|
10817
|
+
}
|
|
10818
|
+
}
|
|
10819
|
+
finally {
|
|
10820
|
+
this.runningCallbacks = false;
|
|
10821
|
+
for (const callback of this.deferredCallbacks) {
|
|
10822
|
+
this.callbacks.add(callback);
|
|
10823
|
+
}
|
|
10824
|
+
this.deferredCallbacks.clear();
|
|
10825
|
+
}
|
|
10826
|
+
}
|
|
10827
|
+
}
|
|
10828
|
+
register(callback) {
|
|
10829
|
+
// If we're currently running callbacks, new callbacks should be deferred
|
|
10830
|
+
// until the next render operation.
|
|
10831
|
+
const target = this.runningCallbacks ? this.deferredCallbacks : this.callbacks;
|
|
10832
|
+
target.add(callback);
|
|
10833
|
+
}
|
|
10834
|
+
unregister(callback) {
|
|
10835
|
+
this.callbacks.delete(callback);
|
|
10836
|
+
this.deferredCallbacks.delete(callback);
|
|
10837
|
+
}
|
|
10838
|
+
ngOnDestroy() {
|
|
10839
|
+
this.callbacks.clear();
|
|
10840
|
+
this.deferredCallbacks.clear();
|
|
10841
|
+
}
|
|
10842
|
+
/** @nocollapse */
|
|
10843
|
+
static { this.ɵprov = ɵɵdefineInjectable({
|
|
10844
|
+
token: AfterRenderEventManager,
|
|
10845
|
+
providedIn: 'root',
|
|
10846
|
+
factory: () => new AfterRenderEventManager(),
|
|
10847
|
+
}); }
|
|
10848
|
+
}
|
|
10849
|
+
|
|
10850
|
+
/**
|
|
10851
|
+
* Marks current view and all ancestors dirty.
|
|
10852
|
+
*
|
|
10853
|
+
* Returns the root view because it is found as a byproduct of marking the view tree
|
|
10854
|
+
* dirty, and can be used by methods that consume markViewDirty() to easily schedule
|
|
10855
|
+
* change detection. Otherwise, such methods would need to traverse up the view tree
|
|
10856
|
+
* an additional time to get the root view and schedule a tick on it.
|
|
10857
|
+
*
|
|
10858
|
+
* @param lView The starting LView to mark dirty
|
|
10859
|
+
* @returns the root LView
|
|
10860
|
+
*/
|
|
10861
|
+
function markViewDirty(lView) {
|
|
10862
|
+
while (lView) {
|
|
10863
|
+
lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
|
|
10864
|
+
const parent = getLViewParent(lView);
|
|
10865
|
+
// Stop traversing up as soon as you find a root view that wasn't attached to any container
|
|
10866
|
+
if (isRootView(lView) && !parent) {
|
|
10867
|
+
return lView;
|
|
10868
|
+
}
|
|
10869
|
+
// continue otherwise
|
|
10870
|
+
lView = parent;
|
|
10871
|
+
}
|
|
10872
|
+
return null;
|
|
10873
|
+
}
|
|
10874
|
+
|
|
10875
|
+
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
10876
|
+
function wrappedError(message, originalError) {
|
|
10877
|
+
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
10878
|
+
const error = Error(msg);
|
|
10879
|
+
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
10880
|
+
return error;
|
|
10881
|
+
}
|
|
10882
|
+
function getOriginalError(error) {
|
|
10883
|
+
return error[ERROR_ORIGINAL_ERROR];
|
|
10884
|
+
}
|
|
10885
|
+
|
|
10886
|
+
/**
|
|
10887
|
+
* Provides a hook for centralized exception handling.
|
|
10888
|
+
*
|
|
10889
|
+
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
10890
|
+
* intercept error handling, write a custom exception handler that replaces this default as
|
|
10891
|
+
* appropriate for your app.
|
|
10892
|
+
*
|
|
10893
|
+
* @usageNotes
|
|
10894
|
+
* ### Example
|
|
10895
|
+
*
|
|
10896
|
+
* ```
|
|
10897
|
+
* class MyErrorHandler implements ErrorHandler {
|
|
10898
|
+
* handleError(error) {
|
|
10899
|
+
* // do something with the exception
|
|
10900
|
+
* }
|
|
10901
|
+
* }
|
|
10902
|
+
*
|
|
10903
|
+
* @NgModule({
|
|
10904
|
+
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
10905
|
+
* })
|
|
10906
|
+
* class MyModule {}
|
|
10907
|
+
* ```
|
|
10908
|
+
*
|
|
10909
|
+
* @publicApi
|
|
10910
|
+
*/
|
|
10911
|
+
class ErrorHandler {
|
|
10912
|
+
constructor() {
|
|
10913
|
+
/**
|
|
10914
|
+
* @internal
|
|
10915
|
+
*/
|
|
10916
|
+
this._console = console;
|
|
10917
|
+
}
|
|
10918
|
+
handleError(error) {
|
|
10919
|
+
const originalError = this._findOriginalError(error);
|
|
10920
|
+
this._console.error('ERROR', error);
|
|
10921
|
+
if (originalError) {
|
|
10922
|
+
this._console.error('ORIGINAL ERROR', originalError);
|
|
10923
|
+
}
|
|
10924
|
+
}
|
|
10925
|
+
/** @internal */
|
|
10926
|
+
_findOriginalError(error) {
|
|
10927
|
+
let e = error && getOriginalError(error);
|
|
10928
|
+
while (e && getOriginalError(e)) {
|
|
10929
|
+
e = getOriginalError(e);
|
|
10930
|
+
}
|
|
10931
|
+
return e || null;
|
|
10932
|
+
}
|
|
10933
|
+
}
|
|
10934
|
+
|
|
10935
|
+
/**
|
|
10936
|
+
* Internal token that specifies whether DOM reuse logic
|
|
10937
|
+
* during hydration is enabled.
|
|
10938
|
+
*/
|
|
10939
|
+
const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
|
|
10940
|
+
// By default (in client rendering mode), we remove all the contents
|
|
10941
|
+
// of the host element and render an application after that.
|
|
10942
|
+
const PRESERVE_HOST_CONTENT_DEFAULT = false;
|
|
10943
|
+
/**
|
|
10944
|
+
* Internal token that indicates whether host element content should be
|
|
10945
|
+
* retained during the bootstrap.
|
|
10946
|
+
*/
|
|
10947
|
+
const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
|
|
10948
|
+
providedIn: 'root',
|
|
10949
|
+
factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
|
|
10950
|
+
});
|
|
10951
|
+
|
|
10952
|
+
function normalizeDebugBindingName(name) {
|
|
10953
|
+
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
10954
|
+
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
10955
|
+
return `ng-reflect-${name}`;
|
|
10956
|
+
}
|
|
10957
|
+
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
|
10958
|
+
function camelCaseToDashCase(input) {
|
|
10959
|
+
return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
|
|
10960
|
+
}
|
|
10961
|
+
function normalizeDebugBindingValue(value) {
|
|
10962
|
+
try {
|
|
10963
|
+
// Limit the size of the value as otherwise the DOM just gets polluted.
|
|
10964
|
+
return value != null ? value.toString().slice(0, 30) : value;
|
|
10965
|
+
}
|
|
10966
|
+
catch (e) {
|
|
10967
|
+
return '[ERROR] Exception while trying to serialize the value';
|
|
10282
10968
|
}
|
|
10283
10969
|
}
|
|
10284
10970
|
|
|
@@ -10381,384 +11067,140 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
|
|
|
10381
11067
|
// first interpolation delimiter separates property name from interpolation parts (in case of
|
|
10382
11068
|
// property interpolations), so we subtract one from total number of found delimiters
|
|
10383
11069
|
if (matches && (matches.length - 1) > bindingIndex - idx) {
|
|
10384
|
-
return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
|
|
10385
|
-
}
|
|
10386
|
-
}
|
|
10387
|
-
}
|
|
10388
|
-
return { propName: undefined, oldValue, newValue };
|
|
10389
|
-
}
|
|
10390
|
-
|
|
10391
|
-
class ReactiveLViewConsumer extends ReactiveNode {
|
|
10392
|
-
constructor() {
|
|
10393
|
-
super(...arguments);
|
|
10394
|
-
this.consumerAllowSignalWrites = false;
|
|
10395
|
-
this._lView = null;
|
|
10396
|
-
}
|
|
10397
|
-
set lView(lView) {
|
|
10398
|
-
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
10399
|
-
assertEqual(this._lView, null, 'Consumer already associated with a view.');
|
|
10400
|
-
this._lView = lView;
|
|
10401
|
-
}
|
|
10402
|
-
onConsumerDependencyMayHaveChanged() {
|
|
10403
|
-
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
10404
|
-
assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
|
|
10405
|
-
markViewDirty(this._lView);
|
|
10406
|
-
}
|
|
10407
|
-
onProducerUpdateValueVersion() {
|
|
10408
|
-
// This type doesn't implement the producer side of a `ReactiveNode`.
|
|
10409
|
-
}
|
|
10410
|
-
get hasReadASignal() {
|
|
10411
|
-
return this.hasProducers;
|
|
10412
|
-
}
|
|
10413
|
-
runInContext(fn, rf, ctx) {
|
|
10414
|
-
const prevConsumer = setActiveConsumer(this);
|
|
10415
|
-
this.trackingVersion++;
|
|
10416
|
-
try {
|
|
10417
|
-
fn(rf, ctx);
|
|
10418
|
-
}
|
|
10419
|
-
finally {
|
|
10420
|
-
setActiveConsumer(prevConsumer);
|
|
10421
|
-
}
|
|
10422
|
-
}
|
|
10423
|
-
destroy() {
|
|
10424
|
-
// Incrementing the version means that every producer which tries to update this consumer will
|
|
10425
|
-
// consider its record stale, and not notify.
|
|
10426
|
-
this.trackingVersion++;
|
|
10427
|
-
}
|
|
10428
|
-
}
|
|
10429
|
-
let currentConsumer = null;
|
|
10430
|
-
function getOrCreateCurrentLViewConsumer() {
|
|
10431
|
-
currentConsumer ??= new ReactiveLViewConsumer();
|
|
10432
|
-
return currentConsumer;
|
|
10433
|
-
}
|
|
10434
|
-
/**
|
|
10435
|
-
* Create a new template consumer pointing at the specified LView.
|
|
10436
|
-
* Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
|
|
10437
|
-
* case, the LView will be updated.
|
|
10438
|
-
*/
|
|
10439
|
-
function getReactiveLViewConsumer(lView, slot) {
|
|
10440
|
-
return lView[slot] ?? getOrCreateCurrentLViewConsumer();
|
|
10441
|
-
}
|
|
10442
|
-
/**
|
|
10443
|
-
* Assigns the `currentTemplateContext` to its LView's `REACTIVE_CONSUMER` slot if there are tracked
|
|
10444
|
-
* producers.
|
|
10445
|
-
*
|
|
10446
|
-
* The presence of producers means that a signal was read while the consumer was the active
|
|
10447
|
-
* consumer.
|
|
10448
|
-
*
|
|
10449
|
-
* If no producers are present, we do not assign the current template context. This also means we
|
|
10450
|
-
* can just reuse the template context for the next LView.
|
|
10451
|
-
*/
|
|
10452
|
-
function commitLViewConsumerIfHasProducers(lView, slot) {
|
|
10453
|
-
const consumer = getOrCreateCurrentLViewConsumer();
|
|
10454
|
-
if (!consumer.hasReadASignal) {
|
|
10455
|
-
return;
|
|
10456
|
-
}
|
|
10457
|
-
lView[slot] = currentConsumer;
|
|
10458
|
-
consumer.lView = lView;
|
|
10459
|
-
currentConsumer = new ReactiveLViewConsumer();
|
|
10460
|
-
}
|
|
10461
|
-
|
|
10462
|
-
/** A special value which designates that a value has not changed. */
|
|
10463
|
-
const NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
|
|
10464
|
-
|
|
10465
|
-
/**
|
|
10466
|
-
* Advances to an element for later binding instructions.
|
|
10467
|
-
*
|
|
10468
|
-
* Used in conjunction with instructions like {@link property} to act on elements with specified
|
|
10469
|
-
* indices, for example those created with {@link element} or {@link elementStart}.
|
|
10470
|
-
*
|
|
10471
|
-
* ```ts
|
|
10472
|
-
* (rf: RenderFlags, ctx: any) => {
|
|
10473
|
-
* if (rf & 1) {
|
|
10474
|
-
* text(0, 'Hello');
|
|
10475
|
-
* text(1, 'Goodbye')
|
|
10476
|
-
* element(2, 'div');
|
|
10477
|
-
* }
|
|
10478
|
-
* if (rf & 2) {
|
|
10479
|
-
* advance(2); // Advance twice to the <div>.
|
|
10480
|
-
* property('title', 'test');
|
|
10481
|
-
* }
|
|
10482
|
-
* }
|
|
10483
|
-
* ```
|
|
10484
|
-
* @param delta Number of elements to advance forwards by.
|
|
10485
|
-
*
|
|
10486
|
-
* @codeGenApi
|
|
10487
|
-
*/
|
|
10488
|
-
function ɵɵadvance(delta) {
|
|
10489
|
-
ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
|
|
10490
|
-
selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
|
|
10491
|
-
}
|
|
10492
|
-
function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
|
|
10493
|
-
ngDevMode && assertIndexInDeclRange(lView, index);
|
|
10494
|
-
// Flush the initial hooks for elements in the view that have been added up to this point.
|
|
10495
|
-
// PERF WARNING: do NOT extract this to a separate function without running benchmarks
|
|
10496
|
-
if (!checkNoChangesMode) {
|
|
10497
|
-
const hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
|
|
10498
|
-
if (hooksInitPhaseCompleted) {
|
|
10499
|
-
const preOrderCheckHooks = tView.preOrderCheckHooks;
|
|
10500
|
-
if (preOrderCheckHooks !== null) {
|
|
10501
|
-
executeCheckHooks(lView, preOrderCheckHooks, index);
|
|
10502
|
-
}
|
|
10503
|
-
}
|
|
10504
|
-
else {
|
|
10505
|
-
const preOrderHooks = tView.preOrderHooks;
|
|
10506
|
-
if (preOrderHooks !== null) {
|
|
10507
|
-
executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, index);
|
|
10508
|
-
}
|
|
10509
|
-
}
|
|
10510
|
-
}
|
|
10511
|
-
// We must set the selected index *after* running the hooks, because hooks may have side-effects
|
|
10512
|
-
// that cause other template functions to run, thus updating the selected index, which is global
|
|
10513
|
-
// state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
|
|
10514
|
-
// will be altered by the time we leave the `ɵɵadvance` instruction.
|
|
10515
|
-
setSelectedIndex(index);
|
|
10516
|
-
}
|
|
10517
|
-
|
|
10518
|
-
/**
|
|
10519
|
-
* Runs the given function in the [context](guide/dependency-injection-context) of the given
|
|
10520
|
-
* `Injector`.
|
|
10521
|
-
*
|
|
10522
|
-
* Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
|
|
10523
|
-
* from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
|
|
10524
|
-
* any asynchronous callbacks or after any `await` points.
|
|
10525
|
-
*
|
|
10526
|
-
* @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
|
|
10527
|
-
* is executing
|
|
10528
|
-
* @param fn the closure to be run in the context of `injector`
|
|
10529
|
-
* @returns the return value of the function, if any
|
|
10530
|
-
* @publicApi
|
|
10531
|
-
*/
|
|
10532
|
-
function runInInjectionContext(injector, fn) {
|
|
10533
|
-
if (injector instanceof R3Injector) {
|
|
10534
|
-
injector.assertNotDestroyed();
|
|
10535
|
-
}
|
|
10536
|
-
const prevInjector = setCurrentInjector(injector);
|
|
10537
|
-
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
10538
|
-
try {
|
|
10539
|
-
return fn();
|
|
10540
|
-
}
|
|
10541
|
-
finally {
|
|
10542
|
-
setCurrentInjector(prevInjector);
|
|
10543
|
-
setInjectImplementation(previousInjectImplementation);
|
|
10544
|
-
}
|
|
10545
|
-
}
|
|
10546
|
-
/**
|
|
10547
|
-
* Asserts that the current stack frame is within an [injection
|
|
10548
|
-
* context](guide/dependency-injection-context) and has access to `inject`.
|
|
10549
|
-
*
|
|
10550
|
-
* @param debugFn a reference to the function making the assertion (used for the error message).
|
|
10551
|
-
*
|
|
10552
|
-
* @publicApi
|
|
10553
|
-
*/
|
|
10554
|
-
function assertInInjectionContext(debugFn) {
|
|
10555
|
-
// Taking a `Function` instead of a string name here prevents the unminified name of the function
|
|
10556
|
-
// from being retained in the bundle regardless of minification.
|
|
10557
|
-
if (!getInjectImplementation() && !getCurrentInjector()) {
|
|
10558
|
-
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
|
|
10559
|
-
(debugFn.name +
|
|
10560
|
-
'() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
|
|
10561
|
-
}
|
|
10562
|
-
}
|
|
10563
|
-
|
|
10564
|
-
/**
|
|
10565
|
-
* A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
|
|
10566
|
-
*
|
|
10567
|
-
* This should be kept up to date with the public exports of @angular/core.
|
|
10568
|
-
*/
|
|
10569
|
-
const angularCoreDiEnv = {
|
|
10570
|
-
'ɵɵdefineInjectable': ɵɵdefineInjectable,
|
|
10571
|
-
'ɵɵdefineInjector': ɵɵdefineInjector,
|
|
10572
|
-
'ɵɵinject': ɵɵinject,
|
|
10573
|
-
'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
|
|
10574
|
-
'resolveForwardRef': resolveForwardRef,
|
|
10575
|
-
};
|
|
10576
|
-
|
|
10577
|
-
/**
|
|
10578
|
-
* Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
|
|
10579
|
-
* injectable def (`ɵprov`) onto the injectable type.
|
|
10580
|
-
*/
|
|
10581
|
-
function compileInjectable(type, meta) {
|
|
10582
|
-
let ngInjectableDef = null;
|
|
10583
|
-
let ngFactoryDef = null;
|
|
10584
|
-
// if NG_PROV_DEF is already defined on this class then don't overwrite it
|
|
10585
|
-
if (!type.hasOwnProperty(NG_PROV_DEF)) {
|
|
10586
|
-
Object.defineProperty(type, NG_PROV_DEF, {
|
|
10587
|
-
get: () => {
|
|
10588
|
-
if (ngInjectableDef === null) {
|
|
10589
|
-
const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
|
|
10590
|
-
ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
|
|
10591
|
-
}
|
|
10592
|
-
return ngInjectableDef;
|
|
10593
|
-
},
|
|
10594
|
-
});
|
|
10595
|
-
}
|
|
10596
|
-
// if NG_FACTORY_DEF is already defined on this class then don't overwrite it
|
|
10597
|
-
if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
|
|
10598
|
-
Object.defineProperty(type, NG_FACTORY_DEF, {
|
|
10599
|
-
get: () => {
|
|
10600
|
-
if (ngFactoryDef === null) {
|
|
10601
|
-
const compiler = getCompilerFacade({ usage: 0 /* JitCompilerUsage.Decorator */, kind: 'injectable', type });
|
|
10602
|
-
ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
|
|
10603
|
-
name: type.name,
|
|
10604
|
-
type,
|
|
10605
|
-
typeArgumentCount: 0,
|
|
10606
|
-
deps: reflectDependencies(type),
|
|
10607
|
-
target: compiler.FactoryTarget.Injectable
|
|
10608
|
-
});
|
|
10609
|
-
}
|
|
10610
|
-
return ngFactoryDef;
|
|
10611
|
-
},
|
|
10612
|
-
// Leave this configurable so that the factories from directives or pipes can take precedence.
|
|
10613
|
-
configurable: true
|
|
10614
|
-
});
|
|
10615
|
-
}
|
|
10616
|
-
}
|
|
10617
|
-
const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
|
|
10618
|
-
function isUseClassProvider(meta) {
|
|
10619
|
-
return meta.useClass !== undefined;
|
|
10620
|
-
}
|
|
10621
|
-
function isUseValueProvider(meta) {
|
|
10622
|
-
return USE_VALUE in meta;
|
|
10623
|
-
}
|
|
10624
|
-
function isUseFactoryProvider(meta) {
|
|
10625
|
-
return meta.useFactory !== undefined;
|
|
10626
|
-
}
|
|
10627
|
-
function isUseExistingProvider(meta) {
|
|
10628
|
-
return meta.useExisting !== undefined;
|
|
11070
|
+
return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
|
|
11071
|
+
}
|
|
11072
|
+
}
|
|
11073
|
+
}
|
|
11074
|
+
return { propName: undefined, oldValue, newValue };
|
|
10629
11075
|
}
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
typeArgumentCount: 0,
|
|
10637
|
-
providedIn: meta.providedIn,
|
|
10638
|
-
};
|
|
10639
|
-
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
|
|
10640
|
-
compilerMeta.deps = convertDependencies(meta.deps);
|
|
11076
|
+
|
|
11077
|
+
class ReactiveLViewConsumer extends ReactiveNode {
|
|
11078
|
+
constructor() {
|
|
11079
|
+
super(...arguments);
|
|
11080
|
+
this.consumerAllowSignalWrites = false;
|
|
11081
|
+
this._lView = null;
|
|
10641
11082
|
}
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
11083
|
+
set lView(lView) {
|
|
11084
|
+
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11085
|
+
assertEqual(this._lView, null, 'Consumer already associated with a view.');
|
|
11086
|
+
this._lView = lView;
|
|
10645
11087
|
}
|
|
10646
|
-
|
|
10647
|
-
|
|
11088
|
+
onConsumerDependencyMayHaveChanged() {
|
|
11089
|
+
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
11090
|
+
assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
|
|
11091
|
+
markViewDirty(this._lView);
|
|
10648
11092
|
}
|
|
10649
|
-
|
|
10650
|
-
|
|
11093
|
+
onProducerUpdateValueVersion() {
|
|
11094
|
+
// This type doesn't implement the producer side of a `ReactiveNode`.
|
|
10651
11095
|
}
|
|
10652
|
-
|
|
10653
|
-
|
|
11096
|
+
get hasReadASignal() {
|
|
11097
|
+
return this.hasProducers;
|
|
11098
|
+
}
|
|
11099
|
+
runInContext(fn, rf, ctx) {
|
|
11100
|
+
const prevConsumer = setActiveConsumer(this);
|
|
11101
|
+
this.trackingVersion++;
|
|
11102
|
+
try {
|
|
11103
|
+
fn(rf, ctx);
|
|
11104
|
+
}
|
|
11105
|
+
finally {
|
|
11106
|
+
setActiveConsumer(prevConsumer);
|
|
11107
|
+
}
|
|
11108
|
+
}
|
|
11109
|
+
destroy() {
|
|
11110
|
+
// Incrementing the version means that every producer which tries to update this consumer will
|
|
11111
|
+
// consider its record stale, and not notify.
|
|
11112
|
+
this.trackingVersion++;
|
|
10654
11113
|
}
|
|
10655
|
-
return compilerMeta;
|
|
10656
11114
|
}
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
* @publicApi
|
|
10663
|
-
*/
|
|
10664
|
-
const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));
|
|
10665
|
-
|
|
11115
|
+
let currentConsumer = null;
|
|
11116
|
+
function getOrCreateCurrentLViewConsumer() {
|
|
11117
|
+
currentConsumer ??= new ReactiveLViewConsumer();
|
|
11118
|
+
return currentConsumer;
|
|
11119
|
+
}
|
|
10666
11120
|
/**
|
|
10667
|
-
* Create a new
|
|
10668
|
-
*
|
|
10669
|
-
*
|
|
11121
|
+
* Create a new template consumer pointing at the specified LView.
|
|
11122
|
+
* Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
|
|
11123
|
+
* case, the LView will be updated.
|
|
10670
11124
|
*/
|
|
10671
|
-
function
|
|
10672
|
-
|
|
10673
|
-
injector.resolveInjectorInitializers();
|
|
10674
|
-
return injector;
|
|
11125
|
+
function getReactiveLViewConsumer(lView, slot) {
|
|
11126
|
+
return lView[slot] ?? getOrCreateCurrentLViewConsumer();
|
|
10675
11127
|
}
|
|
10676
11128
|
/**
|
|
10677
|
-
*
|
|
10678
|
-
*
|
|
10679
|
-
*
|
|
11129
|
+
* Assigns the `currentTemplateContext` to its LView's `REACTIVE_CONSUMER` slot if there are tracked
|
|
11130
|
+
* producers.
|
|
11131
|
+
*
|
|
11132
|
+
* The presence of producers means that a signal was read while the consumer was the active
|
|
11133
|
+
* consumer.
|
|
11134
|
+
*
|
|
11135
|
+
* If no producers are present, we do not assign the current template context. This also means we
|
|
11136
|
+
* can just reuse the template context for the next LView.
|
|
10680
11137
|
*/
|
|
10681
|
-
function
|
|
10682
|
-
const
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
11138
|
+
function commitLViewConsumerIfHasProducers(lView, slot) {
|
|
11139
|
+
const consumer = getOrCreateCurrentLViewConsumer();
|
|
11140
|
+
if (!consumer.hasReadASignal) {
|
|
11141
|
+
return;
|
|
11142
|
+
}
|
|
11143
|
+
lView[slot] = currentConsumer;
|
|
11144
|
+
consumer.lView = lView;
|
|
11145
|
+
currentConsumer = new ReactiveLViewConsumer();
|
|
10688
11146
|
}
|
|
10689
11147
|
|
|
11148
|
+
/** A special value which designates that a value has not changed. */
|
|
11149
|
+
const NO_CHANGE = (typeof ngDevMode === 'undefined' || ngDevMode) ? { __brand__: 'NO_CHANGE' } : {};
|
|
11150
|
+
|
|
10690
11151
|
/**
|
|
10691
|
-
*
|
|
10692
|
-
* with [providers](guide/glossary#provider) that associate
|
|
10693
|
-
* dependencies of various types with [injection tokens](guide/glossary#di-token).
|
|
10694
|
-
*
|
|
10695
|
-
* @see ["DI Providers"](guide/dependency-injection-providers).
|
|
10696
|
-
* @see {@link StaticProvider}
|
|
10697
|
-
*
|
|
10698
|
-
* @usageNotes
|
|
10699
|
-
*
|
|
10700
|
-
* The following example creates a service injector instance.
|
|
10701
|
-
*
|
|
10702
|
-
* {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
|
|
10703
|
-
*
|
|
10704
|
-
* ### Usage example
|
|
10705
|
-
*
|
|
10706
|
-
* {@example core/di/ts/injector_spec.ts region='Injector'}
|
|
11152
|
+
* Advances to an element for later binding instructions.
|
|
10707
11153
|
*
|
|
10708
|
-
*
|
|
11154
|
+
* Used in conjunction with instructions like {@link property} to act on elements with specified
|
|
11155
|
+
* indices, for example those created with {@link element} or {@link elementStart}.
|
|
10709
11156
|
*
|
|
10710
|
-
*
|
|
11157
|
+
* ```ts
|
|
11158
|
+
* (rf: RenderFlags, ctx: any) => {
|
|
11159
|
+
* if (rf & 1) {
|
|
11160
|
+
* text(0, 'Hello');
|
|
11161
|
+
* text(1, 'Goodbye')
|
|
11162
|
+
* element(2, 'div');
|
|
11163
|
+
* }
|
|
11164
|
+
* if (rf & 2) {
|
|
11165
|
+
* advance(2); // Advance twice to the <div>.
|
|
11166
|
+
* property('title', 'test');
|
|
11167
|
+
* }
|
|
11168
|
+
* }
|
|
11169
|
+
* ```
|
|
11170
|
+
* @param delta Number of elements to advance forwards by.
|
|
10711
11171
|
*
|
|
10712
|
-
* @
|
|
11172
|
+
* @codeGenApi
|
|
10713
11173
|
*/
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
11174
|
+
function ɵɵadvance(delta) {
|
|
11175
|
+
ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
|
|
11176
|
+
selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
|
|
11177
|
+
}
|
|
11178
|
+
function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
|
|
11179
|
+
ngDevMode && assertIndexInDeclRange(lView, index);
|
|
11180
|
+
// Flush the initial hooks for elements in the view that have been added up to this point.
|
|
11181
|
+
// PERF WARNING: do NOT extract this to a separate function without running benchmarks
|
|
11182
|
+
if (!checkNoChangesMode) {
|
|
11183
|
+
const hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
|
|
11184
|
+
if (hooksInitPhaseCompleted) {
|
|
11185
|
+
const preOrderCheckHooks = tView.preOrderCheckHooks;
|
|
11186
|
+
if (preOrderCheckHooks !== null) {
|
|
11187
|
+
executeCheckHooks(lView, preOrderCheckHooks, index);
|
|
11188
|
+
}
|
|
10720
11189
|
}
|
|
10721
11190
|
else {
|
|
10722
|
-
const
|
|
10723
|
-
|
|
11191
|
+
const preOrderHooks = tView.preOrderHooks;
|
|
11192
|
+
if (preOrderHooks !== null) {
|
|
11193
|
+
executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, index);
|
|
11194
|
+
}
|
|
10724
11195
|
}
|
|
10725
11196
|
}
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
}); }
|
|
10732
|
-
/**
|
|
10733
|
-
* @internal
|
|
10734
|
-
* @nocollapse
|
|
10735
|
-
*/
|
|
10736
|
-
static { this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */; }
|
|
11197
|
+
// We must set the selected index *after* running the hooks, because hooks may have side-effects
|
|
11198
|
+
// that cause other template functions to run, thus updating the selected index, which is global
|
|
11199
|
+
// state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
|
|
11200
|
+
// will be altered by the time we leave the `ɵɵadvance` instruction.
|
|
11201
|
+
setSelectedIndex(index);
|
|
10737
11202
|
}
|
|
10738
11203
|
|
|
10739
|
-
/**
|
|
10740
|
-
* @module
|
|
10741
|
-
* @description
|
|
10742
|
-
* The `di` module provides dependency injection container services.
|
|
10743
|
-
*/
|
|
10744
|
-
|
|
10745
|
-
/**
|
|
10746
|
-
* This file should not be necessary because node resolution should just default to `./di/index`!
|
|
10747
|
-
*
|
|
10748
|
-
* However it does not seem to work and it breaks:
|
|
10749
|
-
* - //packages/animations/browser/test:test_web_chromium-local
|
|
10750
|
-
* - //packages/compiler-cli/test:extract_i18n
|
|
10751
|
-
* - //packages/compiler-cli/test:ngc
|
|
10752
|
-
* - //packages/compiler-cli/test:perform_watch
|
|
10753
|
-
* - //packages/compiler-cli/test/diagnostics:check_types
|
|
10754
|
-
* - //packages/compiler-cli/test/transformers:test
|
|
10755
|
-
* - //packages/compiler/test:test
|
|
10756
|
-
* - //tools/public_api_guard:core_api
|
|
10757
|
-
*
|
|
10758
|
-
* Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
|
|
10759
|
-
* safe to delete this file.
|
|
10760
|
-
*/
|
|
10761
|
-
|
|
10762
11204
|
function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
|
|
10763
11205
|
const lView = getLView();
|
|
10764
11206
|
// Fall back to inject() if view hasn't been created. This situation can happen in tests
|
|
@@ -10769,7 +11211,9 @@ function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
|
|
|
10769
11211
|
return ɵɵinject(token, flags);
|
|
10770
11212
|
}
|
|
10771
11213
|
const tNode = getCurrentTNode();
|
|
10772
|
-
|
|
11214
|
+
const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
11215
|
+
ngDevMode && emitInjectEvent(token, value, flags);
|
|
11216
|
+
return value;
|
|
10773
11217
|
}
|
|
10774
11218
|
/**
|
|
10775
11219
|
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
@@ -12210,40 +12654,6 @@ function renderChildComponents(hostLView, components) {
|
|
|
12210
12654
|
}
|
|
12211
12655
|
}
|
|
12212
12656
|
|
|
12213
|
-
/**
|
|
12214
|
-
* `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
|
|
12215
|
-
* The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
|
|
12216
|
-
* is injected in a component or directive, the callbacks run when that component or
|
|
12217
|
-
* directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
|
|
12218
|
-
*
|
|
12219
|
-
* @publicApi
|
|
12220
|
-
*/
|
|
12221
|
-
class DestroyRef {
|
|
12222
|
-
/**
|
|
12223
|
-
* @internal
|
|
12224
|
-
* @nocollapse
|
|
12225
|
-
*/
|
|
12226
|
-
static { this.__NG_ELEMENT_ID__ = injectDestroyRef; }
|
|
12227
|
-
/**
|
|
12228
|
-
* @internal
|
|
12229
|
-
* @nocollapse
|
|
12230
|
-
*/
|
|
12231
|
-
static { this.__NG_ENV_ID__ = (injector) => injector; }
|
|
12232
|
-
}
|
|
12233
|
-
class NodeInjectorDestroyRef extends DestroyRef {
|
|
12234
|
-
constructor(_lView) {
|
|
12235
|
-
super();
|
|
12236
|
-
this._lView = _lView;
|
|
12237
|
-
}
|
|
12238
|
-
onDestroy(callback) {
|
|
12239
|
-
storeLViewOnDestroy(this._lView, callback);
|
|
12240
|
-
return () => removeLViewOnDestroy(this._lView, callback);
|
|
12241
|
-
}
|
|
12242
|
-
}
|
|
12243
|
-
function injectDestroyRef() {
|
|
12244
|
-
return new NodeInjectorDestroyRef(getLView());
|
|
12245
|
-
}
|
|
12246
|
-
|
|
12247
12657
|
/**
|
|
12248
12658
|
* Tracks all effects registered within a given application and runs them via `flush`.
|
|
12249
12659
|
*/
|
|
@@ -12412,13 +12822,17 @@ function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
|
|
|
12412
12822
|
}
|
|
12413
12823
|
|
|
12414
12824
|
function detectChangesInternal(tView, lView, context, notifyErrorHandler = true) {
|
|
12415
|
-
const
|
|
12825
|
+
const environment = lView[ENVIRONMENT];
|
|
12826
|
+
const rendererFactory = environment.rendererFactory;
|
|
12827
|
+
const afterRenderEventManager = environment.afterRenderEventManager;
|
|
12416
12828
|
// Check no changes mode is a dev only mode used to verify that bindings have not changed
|
|
12417
12829
|
// since they were assigned. We do not want to invoke renderer factory functions in that mode
|
|
12418
12830
|
// to avoid any possible side-effects.
|
|
12419
12831
|
const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
|
|
12420
|
-
if (!checkNoChangesMode
|
|
12421
|
-
rendererFactory.begin();
|
|
12832
|
+
if (!checkNoChangesMode) {
|
|
12833
|
+
rendererFactory.begin?.();
|
|
12834
|
+
afterRenderEventManager?.begin();
|
|
12835
|
+
}
|
|
12422
12836
|
try {
|
|
12423
12837
|
refreshView(tView, lView, tView.template, context);
|
|
12424
12838
|
}
|
|
@@ -12429,11 +12843,14 @@ function detectChangesInternal(tView, lView, context, notifyErrorHandler = true)
|
|
|
12429
12843
|
throw error;
|
|
12430
12844
|
}
|
|
12431
12845
|
finally {
|
|
12432
|
-
if (!checkNoChangesMode
|
|
12433
|
-
rendererFactory.end();
|
|
12434
|
-
|
|
12435
|
-
|
|
12436
|
-
|
|
12846
|
+
if (!checkNoChangesMode) {
|
|
12847
|
+
rendererFactory.end?.();
|
|
12848
|
+
// One final flush of the effects queue to catch any effects created in `ngAfterViewInit` or
|
|
12849
|
+
// other post-order hooks.
|
|
12850
|
+
environment.effectManager?.flush();
|
|
12851
|
+
// Invoke all callbacks registered via `after*Render`, if needed.
|
|
12852
|
+
afterRenderEventManager?.end();
|
|
12853
|
+
}
|
|
12437
12854
|
}
|
|
12438
12855
|
}
|
|
12439
12856
|
function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true) {
|
|
@@ -12915,7 +13332,7 @@ class ViewRef$1 {
|
|
|
12915
13332
|
}
|
|
12916
13333
|
detachFromAppRef() {
|
|
12917
13334
|
this._appRef = null;
|
|
12918
|
-
|
|
13335
|
+
detachViewFromDOM(this._lView[TVIEW], this._lView);
|
|
12919
13336
|
}
|
|
12920
13337
|
attachToAppRef(appRef) {
|
|
12921
13338
|
if (this._attachedToViewContainer) {
|
|
@@ -13054,10 +13471,12 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
13054
13471
|
}
|
|
13055
13472
|
const sanitizer = rootViewInjector.get(Sanitizer, null);
|
|
13056
13473
|
const effectManager = rootViewInjector.get(EffectManager, null);
|
|
13474
|
+
const afterRenderEventManager = rootViewInjector.get(AfterRenderEventManager, null);
|
|
13057
13475
|
const environment = {
|
|
13058
13476
|
rendererFactory,
|
|
13059
13477
|
sanitizer,
|
|
13060
13478
|
effectManager,
|
|
13479
|
+
afterRenderEventManager,
|
|
13061
13480
|
};
|
|
13062
13481
|
const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
|
|
13063
13482
|
// Determine a tag name used for creating host elements when this component is created
|
|
@@ -13072,9 +13491,13 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
13072
13491
|
const nonSignalFlags = this.componentDef.onPush ? 64 /* LViewFlags.Dirty */ | 512 /* LViewFlags.IsRoot */ :
|
|
13073
13492
|
16 /* LViewFlags.CheckAlways */ | 512 /* LViewFlags.IsRoot */;
|
|
13074
13493
|
const rootFlags = this.componentDef.signals ? signalFlags : nonSignalFlags;
|
|
13494
|
+
let hydrationInfo = null;
|
|
13495
|
+
if (hostRNode !== null) {
|
|
13496
|
+
hydrationInfo = retrieveHydrationInfo(hostRNode, rootViewInjector, true /* isRootView */);
|
|
13497
|
+
}
|
|
13075
13498
|
// Create the root view. Uses empty TView and ContentTemplate.
|
|
13076
13499
|
const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null, null);
|
|
13077
|
-
const rootLView = createLView(null, rootTView, null, rootFlags, null, null, environment, hostRenderer, rootViewInjector, null,
|
|
13500
|
+
const rootLView = createLView(null, rootTView, null, rootFlags, null, null, environment, hostRenderer, rootViewInjector, null, hydrationInfo);
|
|
13078
13501
|
// rootView is the parent when bootstrapping
|
|
13079
13502
|
// TODO(misko): it looks like we are entering view here but we don't really need to as
|
|
13080
13503
|
// `renderView` does that. However as the code is written it is needed because
|
|
@@ -13175,12 +13598,6 @@ class ComponentRef extends ComponentRef$1 {
|
|
|
13175
13598
|
this.hostView.onDestroy(callback);
|
|
13176
13599
|
}
|
|
13177
13600
|
}
|
|
13178
|
-
// TODO: A hack to not pull in the NullInjector from @angular/core.
|
|
13179
|
-
const NULL_INJECTOR = {
|
|
13180
|
-
get: (token, notFoundValue) => {
|
|
13181
|
-
throwProviderNotFoundError(token, 'NullInjector');
|
|
13182
|
-
}
|
|
13183
|
-
};
|
|
13184
13601
|
/** Creates a TNode that can be used to instantiate a root component. */
|
|
13185
13602
|
function createRootComponentTNode(lView, rNode) {
|
|
13186
13603
|
const tView = lView[TVIEW];
|
|
@@ -13207,7 +13624,7 @@ function createRootComponentTNode(lView, rNode) {
|
|
|
13207
13624
|
function createRootComponentView(tNode, hostRNode, rootComponentDef, rootDirectives, rootView, environment, hostRenderer) {
|
|
13208
13625
|
const tView = rootView[TVIEW];
|
|
13209
13626
|
applyRootComponentStyling(rootDirectives, tNode, hostRNode, hostRenderer);
|
|
13210
|
-
// Hydration info is on the host element and needs to be
|
|
13627
|
+
// Hydration info is on the host element and needs to be retrieved
|
|
13211
13628
|
// and passed to the component LView.
|
|
13212
13629
|
let hydrationInfo = null;
|
|
13213
13630
|
if (hostRNode !== null) {
|
|
@@ -21290,6 +21707,18 @@ function ɵɵi18nPostprocess(message, replacements = {}) {
|
|
|
21290
21707
|
return i18nPostprocess(message, replacements);
|
|
21291
21708
|
}
|
|
21292
21709
|
|
|
21710
|
+
/**
|
|
21711
|
+
* Creates runtime data structures for `{#defer}` blocks.
|
|
21712
|
+
*
|
|
21713
|
+
* @param index The index of the defer block in the data array
|
|
21714
|
+
* @param deferredDepsFn Function that contains dependencies for this defer block
|
|
21715
|
+
*
|
|
21716
|
+
* @codeGenApi
|
|
21717
|
+
*/
|
|
21718
|
+
function ɵɵdefer(index, deferredDepsFn) {
|
|
21719
|
+
// TODO: implement runtime logic.
|
|
21720
|
+
}
|
|
21721
|
+
|
|
21293
21722
|
/*
|
|
21294
21723
|
* This file re-exports all symbols contained in this directory.
|
|
21295
21724
|
*
|
|
@@ -21354,9 +21783,15 @@ function resolveProvider(provider, tInjectables, lInjectablesBlueprint, isCompon
|
|
|
21354
21783
|
else {
|
|
21355
21784
|
const tView = getTView();
|
|
21356
21785
|
const lView = getLView();
|
|
21357
|
-
let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
|
|
21358
|
-
let providerFactory = providerToFactory(provider);
|
|
21359
21786
|
const tNode = getCurrentTNode();
|
|
21787
|
+
let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
|
|
21788
|
+
const providerFactory = providerToFactory(provider);
|
|
21789
|
+
if (ngDevMode) {
|
|
21790
|
+
const injector = new NodeInjector(tNode, lView);
|
|
21791
|
+
runInInjectorProfilerContext(injector, token, () => {
|
|
21792
|
+
emitProviderConfiguredEvent(provider, isViewProvider);
|
|
21793
|
+
});
|
|
21794
|
+
}
|
|
21360
21795
|
const beginIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
|
|
21361
21796
|
const endIndex = tNode.directiveStart;
|
|
21362
21797
|
const cptViewProvidersCount = tNode.providerIndexes >> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */;
|
|
@@ -22576,6 +23011,13 @@ function ɵɵpipe(index, pipeName) {
|
|
|
22576
23011
|
pipeDef = tView.data[adjustedIndex];
|
|
22577
23012
|
}
|
|
22578
23013
|
const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
|
|
23014
|
+
let previousInjectorProfilerContext;
|
|
23015
|
+
if (ngDevMode) {
|
|
23016
|
+
previousInjectorProfilerContext = setInjectorProfilerContext({
|
|
23017
|
+
injector: new NodeInjector(getCurrentTNode(), getLView()),
|
|
23018
|
+
token: pipeDef.type
|
|
23019
|
+
});
|
|
23020
|
+
}
|
|
22579
23021
|
const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
|
|
22580
23022
|
try {
|
|
22581
23023
|
// DI for pipes is supposed to behave like directives when placed on a component
|
|
@@ -22590,6 +23032,7 @@ function ɵɵpipe(index, pipeName) {
|
|
|
22590
23032
|
// we have to restore the injector implementation in finally, just in case the creation of the
|
|
22591
23033
|
// pipe throws an error.
|
|
22592
23034
|
setInjectImplementation(previousInjectImplementation);
|
|
23035
|
+
ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
|
|
22593
23036
|
}
|
|
22594
23037
|
}
|
|
22595
23038
|
/**
|
|
@@ -22964,6 +23407,57 @@ class QueryList {
|
|
|
22964
23407
|
}
|
|
22965
23408
|
}
|
|
22966
23409
|
|
|
23410
|
+
function createAndRenderEmbeddedLView(declarationLView, templateTNode, context, options) {
|
|
23411
|
+
const embeddedTView = templateTNode.tView;
|
|
23412
|
+
ngDevMode && assertDefined(embeddedTView, 'TView must be defined for a template node.');
|
|
23413
|
+
ngDevMode && assertTNodeForLView(templateTNode, declarationLView);
|
|
23414
|
+
// Embedded views follow the change detection strategy of the view they're declared in.
|
|
23415
|
+
const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
23416
|
+
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
23417
|
+
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, null, options?.injector ?? null, options?.hydrationInfo ?? null);
|
|
23418
|
+
const declarationLContainer = declarationLView[templateTNode.index];
|
|
23419
|
+
ngDevMode && assertLContainer(declarationLContainer);
|
|
23420
|
+
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
23421
|
+
const declarationViewLQueries = declarationLView[QUERIES];
|
|
23422
|
+
if (declarationViewLQueries !== null) {
|
|
23423
|
+
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
|
|
23424
|
+
}
|
|
23425
|
+
// execute creation mode of a view
|
|
23426
|
+
renderView(embeddedTView, embeddedLView, context);
|
|
23427
|
+
return embeddedLView;
|
|
23428
|
+
}
|
|
23429
|
+
function getLViewFromLContainer(lContainer, index) {
|
|
23430
|
+
const adjustedIndex = CONTAINER_HEADER_OFFSET + index;
|
|
23431
|
+
// avoid reading past the array boundaries
|
|
23432
|
+
if (adjustedIndex < lContainer.length) {
|
|
23433
|
+
const lView = lContainer[adjustedIndex];
|
|
23434
|
+
ngDevMode && assertLView(lView);
|
|
23435
|
+
return lView;
|
|
23436
|
+
}
|
|
23437
|
+
return undefined;
|
|
23438
|
+
}
|
|
23439
|
+
function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
|
|
23440
|
+
const tView = lView[TVIEW];
|
|
23441
|
+
// insert to the view tree so the new view can be change-detected
|
|
23442
|
+
insertView(tView, lView, lContainer, index);
|
|
23443
|
+
// insert to the view to the DOM tree
|
|
23444
|
+
if (addToDOM) {
|
|
23445
|
+
const beforeNode = getBeforeNodeForView(index, lContainer);
|
|
23446
|
+
const renderer = lView[RENDERER];
|
|
23447
|
+
const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
|
|
23448
|
+
if (parentRNode !== null) {
|
|
23449
|
+
addViewToDOM(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
|
|
23450
|
+
}
|
|
23451
|
+
}
|
|
23452
|
+
}
|
|
23453
|
+
function removeLViewFromLContainer(lContainer, index) {
|
|
23454
|
+
const lView = detachView(lContainer, index);
|
|
23455
|
+
if (lView !== undefined) {
|
|
23456
|
+
destroyLView(lView[TVIEW], lView);
|
|
23457
|
+
}
|
|
23458
|
+
return lView;
|
|
23459
|
+
}
|
|
23460
|
+
|
|
22967
23461
|
/**
|
|
22968
23462
|
* Represents an embedded template that can be used to instantiate embedded views.
|
|
22969
23463
|
* To instantiate embedded views based on a template, use the `ViewContainerRef`
|
|
@@ -23009,25 +23503,13 @@ const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
|
|
|
23009
23503
|
return this._declarationTContainer.tView?.ssrId || null;
|
|
23010
23504
|
}
|
|
23011
23505
|
createEmbeddedView(context, injector) {
|
|
23012
|
-
return this.createEmbeddedViewImpl(context, injector
|
|
23506
|
+
return this.createEmbeddedViewImpl(context, injector);
|
|
23013
23507
|
}
|
|
23014
23508
|
/**
|
|
23015
23509
|
* @internal
|
|
23016
23510
|
*/
|
|
23017
23511
|
createEmbeddedViewImpl(context, injector, hydrationInfo) {
|
|
23018
|
-
|
|
23019
|
-
const isSignalView = this._declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
23020
|
-
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
23021
|
-
const embeddedTView = this._declarationTContainer.tView;
|
|
23022
|
-
const embeddedLView = createLView(this._declarationLView, embeddedTView, context, viewFlags, null, embeddedTView.declTNode, null, null, null, injector || null, hydrationInfo || null);
|
|
23023
|
-
const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
|
|
23024
|
-
ngDevMode && assertLContainer(declarationLContainer);
|
|
23025
|
-
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
23026
|
-
const declarationViewLQueries = this._declarationLView[QUERIES];
|
|
23027
|
-
if (declarationViewLQueries !== null) {
|
|
23028
|
-
embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
|
|
23029
|
-
}
|
|
23030
|
-
renderView(embeddedTView, embeddedLView, context);
|
|
23512
|
+
const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { injector, hydrationInfo });
|
|
23031
23513
|
return new ViewRef$1(embeddedLView);
|
|
23032
23514
|
}
|
|
23033
23515
|
};
|
|
@@ -23124,11 +23606,20 @@ function cleanupLView(lView) {
|
|
|
23124
23606
|
function cleanupDehydratedViews(appRef) {
|
|
23125
23607
|
const viewRefs = appRef._views;
|
|
23126
23608
|
for (const viewRef of viewRefs) {
|
|
23127
|
-
const
|
|
23609
|
+
const lNode = getLNodeForHydration(viewRef);
|
|
23128
23610
|
// An `lView` might be `null` if a `ViewRef` represents
|
|
23129
23611
|
// an embedded view (not a component view).
|
|
23130
|
-
if (
|
|
23131
|
-
|
|
23612
|
+
if (lNode !== null && lNode[HOST] !== null) {
|
|
23613
|
+
if (isLView(lNode)) {
|
|
23614
|
+
cleanupLView(lNode);
|
|
23615
|
+
}
|
|
23616
|
+
else {
|
|
23617
|
+
// Cleanup in the root component view
|
|
23618
|
+
const componentLView = lNode[HOST];
|
|
23619
|
+
cleanupLView(componentLView);
|
|
23620
|
+
// Cleanup in all views within this view container
|
|
23621
|
+
cleanupLContainer(lNode);
|
|
23622
|
+
}
|
|
23132
23623
|
ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
|
|
23133
23624
|
}
|
|
23134
23625
|
}
|
|
@@ -23305,7 +23796,7 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
|
23305
23796
|
let index;
|
|
23306
23797
|
// This function supports 2 signatures and we need to handle options correctly for both:
|
|
23307
23798
|
// 1. When first argument is a Component type. This signature also requires extra
|
|
23308
|
-
// options to be provided as
|
|
23799
|
+
// options to be provided as object (more ergonomic option).
|
|
23309
23800
|
// 2. First argument is a Component factory. In this case extra options are represented as
|
|
23310
23801
|
// positional arguments. This signature is less ergonomic and will be deprecated.
|
|
23311
23802
|
if (isComponentFactory) {
|
|
@@ -23410,16 +23901,7 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
|
23410
23901
|
// Logical operation of adding `LView` to `LContainer`
|
|
23411
23902
|
const adjustedIdx = this._adjustIndex(index);
|
|
23412
23903
|
const lContainer = this._lContainer;
|
|
23413
|
-
|
|
23414
|
-
// Physical operation of adding the DOM nodes.
|
|
23415
|
-
if (!skipDomInsertion) {
|
|
23416
|
-
const beforeNode = getBeforeNodeForView(adjustedIdx, lContainer);
|
|
23417
|
-
const renderer = lView[RENDERER];
|
|
23418
|
-
const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
|
|
23419
|
-
if (parentRNode !== null) {
|
|
23420
|
-
addViewToContainer(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
|
|
23421
|
-
}
|
|
23422
|
-
}
|
|
23904
|
+
addLViewToLContainer(lContainer, lView, adjustedIdx, !skipDomInsertion);
|
|
23423
23905
|
viewRef.attachToViewContainerRef();
|
|
23424
23906
|
addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
|
|
23425
23907
|
return viewRef;
|
|
@@ -24169,6 +24651,7 @@ const angularCoreEnv = (() => ({
|
|
|
24169
24651
|
'ɵɵclassProp': ɵɵclassProp,
|
|
24170
24652
|
'ɵɵadvance': ɵɵadvance,
|
|
24171
24653
|
'ɵɵtemplate': ɵɵtemplate,
|
|
24654
|
+
'ɵɵdefer': ɵɵdefer,
|
|
24172
24655
|
'ɵɵtext': ɵɵtext,
|
|
24173
24656
|
'ɵɵtextInterpolate': ɵɵtextInterpolate,
|
|
24174
24657
|
'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
|
|
@@ -25867,6 +26350,206 @@ const COMPILER_OPTIONS = new InjectionToken('compilerOptions');
|
|
|
25867
26350
|
class CompilerFactory {
|
|
25868
26351
|
}
|
|
25869
26352
|
|
|
26353
|
+
/**
|
|
26354
|
+
* These are the data structures that our framework injector profiler will fill with data in order
|
|
26355
|
+
* to support DI debugging APIs.
|
|
26356
|
+
*
|
|
26357
|
+
* resolverToTokenToDependencies: Maps an injector to a Map of tokens to an Array of
|
|
26358
|
+
* dependencies. Injector -> Token -> Dependencies This is used to support the
|
|
26359
|
+
* getDependenciesFromInjectable API, which takes in an injector and a token and returns it's
|
|
26360
|
+
* dependencies.
|
|
26361
|
+
*
|
|
26362
|
+
* resolverToProviders: Maps a DI resolver (an Injector or an LView) to the providers configured
|
|
26363
|
+
* within it This is used to support the getInjectorProviders API, which takes in an injector and
|
|
26364
|
+
* returns the providers that it was configured with.
|
|
26365
|
+
*
|
|
26366
|
+
* standaloneInjectorToComponent: Maps the injector of a standalone component to the standalone
|
|
26367
|
+
* component that it is associated with. Used in the getInjectorProviders API, specificially in the
|
|
26368
|
+
* discovery of import paths for each provider. This is necessary because the imports array of a
|
|
26369
|
+
* standalone component is processed and configured in its standalone injector, but exists within
|
|
26370
|
+
* the component's definition. Because getInjectorProviders takes in an injector, if that injector
|
|
26371
|
+
* is the injector of a standalone component, we need to be able to discover the place where the
|
|
26372
|
+
* imports array is located (the component) in order to flatten the imports array within it to
|
|
26373
|
+
* discover all of it's providers.
|
|
26374
|
+
*
|
|
26375
|
+
*
|
|
26376
|
+
* All of these data structures are instantiated with WeakMaps. This will ensure that the presence
|
|
26377
|
+
* of any object in the keys of these maps does not prevent the garbage collector from collecting
|
|
26378
|
+
* those objects. Because of this property of WeakMaps, these data structures will never be the
|
|
26379
|
+
* source of a memory leak.
|
|
26380
|
+
*
|
|
26381
|
+
* An example of this advantage: When components are destroyed, we don't need to do
|
|
26382
|
+
* any additional work to remove that component from our mappings.
|
|
26383
|
+
*
|
|
26384
|
+
*/
|
|
26385
|
+
class DIDebugData {
|
|
26386
|
+
constructor() {
|
|
26387
|
+
this.resolverToTokenToDependencies = new WeakMap();
|
|
26388
|
+
this.resolverToProviders = new WeakMap();
|
|
26389
|
+
this.standaloneInjectorToComponent = new WeakMap();
|
|
26390
|
+
}
|
|
26391
|
+
reset() {
|
|
26392
|
+
this.resolverToTokenToDependencies =
|
|
26393
|
+
new WeakMap();
|
|
26394
|
+
this.resolverToProviders = new WeakMap();
|
|
26395
|
+
this.standaloneInjectorToComponent = new WeakMap();
|
|
26396
|
+
}
|
|
26397
|
+
}
|
|
26398
|
+
let frameworkDIDebugData = new DIDebugData();
|
|
26399
|
+
function getFrameworkDIDebugData() {
|
|
26400
|
+
return frameworkDIDebugData;
|
|
26401
|
+
}
|
|
26402
|
+
/**
|
|
26403
|
+
* Initalize default handling of injector events. This handling parses events
|
|
26404
|
+
* as they are emitted and constructs the data structures necessary to support
|
|
26405
|
+
* some of debug APIs.
|
|
26406
|
+
*
|
|
26407
|
+
* See handleInjectEvent, handleCreateEvent and handleProviderConfiguredEvent
|
|
26408
|
+
* for descriptions of each handler
|
|
26409
|
+
*
|
|
26410
|
+
* Supported APIs:
|
|
26411
|
+
* - getDependenciesFromInjectable
|
|
26412
|
+
* - getInjectorProviders
|
|
26413
|
+
*/
|
|
26414
|
+
function setupFrameworkInjectorProfiler() {
|
|
26415
|
+
frameworkDIDebugData.reset();
|
|
26416
|
+
setInjectorProfiler((injectorProfilerEvent) => handleInjectorProfilerEvent(injectorProfilerEvent));
|
|
26417
|
+
}
|
|
26418
|
+
function handleInjectorProfilerEvent(injectorProfilerEvent) {
|
|
26419
|
+
const { context, type } = injectorProfilerEvent;
|
|
26420
|
+
if (type === 0 /* InjectorProfilerEventType.Inject */) {
|
|
26421
|
+
handleInjectEvent(context, injectorProfilerEvent.service);
|
|
26422
|
+
}
|
|
26423
|
+
else if (type === 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */) {
|
|
26424
|
+
handleInstanceCreatedByInjectorEvent(context, injectorProfilerEvent.instance);
|
|
26425
|
+
}
|
|
26426
|
+
else if (type === 2 /* InjectorProfilerEventType.ProviderConfigured */) {
|
|
26427
|
+
handleProviderConfiguredEvent(context, injectorProfilerEvent.providerRecord);
|
|
26428
|
+
}
|
|
26429
|
+
}
|
|
26430
|
+
/**
|
|
26431
|
+
*
|
|
26432
|
+
* Stores the injected service in frameworkDIDebugData.resolverToTokenToDependencies
|
|
26433
|
+
* based on it's injector and token.
|
|
26434
|
+
*
|
|
26435
|
+
* @param context InjectorProfilerContext the injection context that this event occurred in.
|
|
26436
|
+
* @param data InjectedService the service associated with this inject event.
|
|
26437
|
+
*
|
|
26438
|
+
*/
|
|
26439
|
+
function handleInjectEvent(context, data) {
|
|
26440
|
+
const diResolver = getDIResolver(context.injector);
|
|
26441
|
+
if (diResolver === null) {
|
|
26442
|
+
throwError('An Inject event must be run within an injection context.');
|
|
26443
|
+
}
|
|
26444
|
+
const diResolverToInstantiatedToken = frameworkDIDebugData.resolverToTokenToDependencies;
|
|
26445
|
+
if (!diResolverToInstantiatedToken.has(diResolver)) {
|
|
26446
|
+
diResolverToInstantiatedToken.set(diResolver, new WeakMap());
|
|
26447
|
+
}
|
|
26448
|
+
// if token is a primitive type, ignore this event. We do this because we cannot keep track of
|
|
26449
|
+
// non-primitive tokens in WeakMaps since they are not garbage collectable.
|
|
26450
|
+
if (!canBeHeldWeakly(context.token)) {
|
|
26451
|
+
return;
|
|
26452
|
+
}
|
|
26453
|
+
const instantiatedTokenToDependencies = diResolverToInstantiatedToken.get(diResolver);
|
|
26454
|
+
if (!instantiatedTokenToDependencies.has(context.token)) {
|
|
26455
|
+
instantiatedTokenToDependencies.set(context.token, []);
|
|
26456
|
+
}
|
|
26457
|
+
const { token, value, flags } = data;
|
|
26458
|
+
instantiatedTokenToDependencies.get(context.token).push({ token, value, flags });
|
|
26459
|
+
}
|
|
26460
|
+
/**
|
|
26461
|
+
*
|
|
26462
|
+
* If the created instance is an instance of a standalone component, maps the injector to that
|
|
26463
|
+
* standalone component in frameworkDIDebugData.standaloneInjectorToComponent
|
|
26464
|
+
*
|
|
26465
|
+
* @param context InjectorProfilerContext the injection context that this event occurred in.
|
|
26466
|
+
* @param data InjectorCreatedInstance an object containing the instance that was just created
|
|
26467
|
+
*
|
|
26468
|
+
*/
|
|
26469
|
+
function handleInstanceCreatedByInjectorEvent(context, data) {
|
|
26470
|
+
const { value } = data;
|
|
26471
|
+
if (getDIResolver(context.injector) === null) {
|
|
26472
|
+
throwError('An InjectorCreatedInstance event must be run within an injection context.');
|
|
26473
|
+
}
|
|
26474
|
+
// if our value is an instance of a standalone component, map the injector of that standalone
|
|
26475
|
+
// component to the component class. Otherwise, this event is a noop.
|
|
26476
|
+
let standaloneComponent = undefined;
|
|
26477
|
+
if (typeof value === 'object') {
|
|
26478
|
+
standaloneComponent = value?.constructor;
|
|
26479
|
+
}
|
|
26480
|
+
if (standaloneComponent === undefined || !isStandaloneComponent(standaloneComponent)) {
|
|
26481
|
+
return;
|
|
26482
|
+
}
|
|
26483
|
+
const environmentInjector = context.injector.get(EnvironmentInjector, null, { optional: true });
|
|
26484
|
+
// Standalone components should have an environment injector. If one cannot be
|
|
26485
|
+
// found we may be in a test case for low level functionality that did not explictly
|
|
26486
|
+
// setup this injector. In those cases, we simply ignore this event.
|
|
26487
|
+
if (environmentInjector === null) {
|
|
26488
|
+
return;
|
|
26489
|
+
}
|
|
26490
|
+
const { standaloneInjectorToComponent } = frameworkDIDebugData;
|
|
26491
|
+
// If our injector has already been mapped, as is the case
|
|
26492
|
+
// when a standalone component imports another standalone component,
|
|
26493
|
+
// we consider the original component (the component doing the importing)
|
|
26494
|
+
// as the component connected to our injector.
|
|
26495
|
+
if (standaloneInjectorToComponent.has(environmentInjector)) {
|
|
26496
|
+
return;
|
|
26497
|
+
}
|
|
26498
|
+
// If our injector hasn't been mapped, then we map it to the standalone component
|
|
26499
|
+
standaloneInjectorToComponent.set(environmentInjector, standaloneComponent);
|
|
26500
|
+
}
|
|
26501
|
+
function isStandaloneComponent(value) {
|
|
26502
|
+
const def = getComponentDef(value);
|
|
26503
|
+
return !!def?.standalone;
|
|
26504
|
+
}
|
|
26505
|
+
/**
|
|
26506
|
+
*
|
|
26507
|
+
* Stores the emitted ProviderRecords from the InjectorProfilerEventType.ProviderConfigured
|
|
26508
|
+
* event in frameworkDIDebugData.resolverToProviders
|
|
26509
|
+
*
|
|
26510
|
+
* @param context InjectorProfilerContext the injection context that this event occurred in.
|
|
26511
|
+
* @param data ProviderRecord an object containing the instance that was just created
|
|
26512
|
+
*
|
|
26513
|
+
*/
|
|
26514
|
+
function handleProviderConfiguredEvent(context, data) {
|
|
26515
|
+
const { resolverToProviders } = frameworkDIDebugData;
|
|
26516
|
+
const diResolver = getDIResolver(context?.injector);
|
|
26517
|
+
if (diResolver === null) {
|
|
26518
|
+
throwError('A ProviderConfigured event must be run within an injection context.');
|
|
26519
|
+
}
|
|
26520
|
+
if (!resolverToProviders.has(diResolver)) {
|
|
26521
|
+
resolverToProviders.set(diResolver, []);
|
|
26522
|
+
}
|
|
26523
|
+
resolverToProviders.get(diResolver).push(data);
|
|
26524
|
+
}
|
|
26525
|
+
function getDIResolver(injector) {
|
|
26526
|
+
let diResolver = null;
|
|
26527
|
+
if (injector === undefined) {
|
|
26528
|
+
return diResolver;
|
|
26529
|
+
}
|
|
26530
|
+
// We use the LView as the diResolver for NodeInjectors because they
|
|
26531
|
+
// do not persist anywhere in the framework. They are simply wrappers around an LView and a TNode
|
|
26532
|
+
// that do persist. Because of this, we rely on the LView of the NodeInjector in order to use
|
|
26533
|
+
// as a concrete key to represent this injector. If we get the same LView back later, we know
|
|
26534
|
+
// we're looking at the same injector.
|
|
26535
|
+
if (injector instanceof NodeInjector) {
|
|
26536
|
+
diResolver = getNodeInjectorLView(injector);
|
|
26537
|
+
}
|
|
26538
|
+
// Other injectors can be used a keys for a map because their instances
|
|
26539
|
+
// persist
|
|
26540
|
+
else {
|
|
26541
|
+
diResolver = injector;
|
|
26542
|
+
}
|
|
26543
|
+
return diResolver;
|
|
26544
|
+
}
|
|
26545
|
+
// inspired by
|
|
26546
|
+
// https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-canbeheldweakly
|
|
26547
|
+
function canBeHeldWeakly(value) {
|
|
26548
|
+
// we check for value !== null here because typeof null === 'object
|
|
26549
|
+
return value !== null &&
|
|
26550
|
+
(typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol');
|
|
26551
|
+
}
|
|
26552
|
+
|
|
25870
26553
|
/**
|
|
25871
26554
|
* Marks a component for check (in case of OnPush components) and synchronously
|
|
25872
26555
|
* performs change detection on the application this component belongs to.
|
|
@@ -25882,6 +26565,447 @@ function applyChanges(component) {
|
|
|
25882
26565
|
getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
|
|
25883
26566
|
}
|
|
25884
26567
|
|
|
26568
|
+
/**
|
|
26569
|
+
* Discovers the dependencies of an injectable instance. Provides DI information about each
|
|
26570
|
+
* dependency that the injectable was instantiated with, including where they were provided from.
|
|
26571
|
+
*
|
|
26572
|
+
* @param injector An injector instance
|
|
26573
|
+
* @param token a DI token that was constructed by the given injector instance
|
|
26574
|
+
* @returns an object that contains the created instance of token as well as all of the dependencies
|
|
26575
|
+
* that it was instantiated with OR undefined if the token was not created within the given
|
|
26576
|
+
* injector.
|
|
26577
|
+
*/
|
|
26578
|
+
function getDependenciesFromInjectable(injector, token) {
|
|
26579
|
+
// First we check to see if the token given maps to an actual instance in the injector given.
|
|
26580
|
+
// We use `self: true` because we only want to look at the injector we were given.
|
|
26581
|
+
// We use `optional: true` because it's possible that the token we were given was never
|
|
26582
|
+
// constructed by the injector we were given.
|
|
26583
|
+
const instance = injector.get(token, null, { self: true, optional: true });
|
|
26584
|
+
if (instance === null) {
|
|
26585
|
+
throw new Error(`Unable to determine instance of ${token} in given injector`);
|
|
26586
|
+
}
|
|
26587
|
+
let diResolver = injector;
|
|
26588
|
+
if (injector instanceof NodeInjector) {
|
|
26589
|
+
diResolver = getNodeInjectorLView(injector);
|
|
26590
|
+
}
|
|
26591
|
+
const { resolverToTokenToDependencies } = getFrameworkDIDebugData();
|
|
26592
|
+
let dependencies = resolverToTokenToDependencies.get(diResolver)?.get?.(token) ?? [];
|
|
26593
|
+
const resolutionPath = getInjectorResolutionPath(injector);
|
|
26594
|
+
dependencies = dependencies.map(dep => {
|
|
26595
|
+
const flags = dep.flags;
|
|
26596
|
+
dep.flags = {
|
|
26597
|
+
optional: (8 /* InternalInjectFlags.Optional */ & flags) === 8 /* InternalInjectFlags.Optional */,
|
|
26598
|
+
host: (1 /* InternalInjectFlags.Host */ & flags) === 1 /* InternalInjectFlags.Host */,
|
|
26599
|
+
self: (2 /* InternalInjectFlags.Self */ & flags) === 2 /* InternalInjectFlags.Self */,
|
|
26600
|
+
skipSelf: (4 /* InternalInjectFlags.SkipSelf */ & flags) === 4 /* InternalInjectFlags.SkipSelf */,
|
|
26601
|
+
};
|
|
26602
|
+
for (let i = 0; i < resolutionPath.length; i++) {
|
|
26603
|
+
const injectorToCheck = resolutionPath[i];
|
|
26604
|
+
// if skipSelf is true we skip the first injector
|
|
26605
|
+
if (i === 0 && dep.flags.skipSelf) {
|
|
26606
|
+
continue;
|
|
26607
|
+
}
|
|
26608
|
+
// host only applies to NodeInjectors
|
|
26609
|
+
if (dep.flags.host && injectorToCheck instanceof EnvironmentInjector) {
|
|
26610
|
+
break;
|
|
26611
|
+
}
|
|
26612
|
+
const instance = injectorToCheck.get(dep.token, null, { self: true, optional: true });
|
|
26613
|
+
if (instance !== null) {
|
|
26614
|
+
// if host flag is true we double check that we can get the service from the first element
|
|
26615
|
+
// in the resolution path by using the host flag. This is done to make sure that we've found
|
|
26616
|
+
// the correct providing injector, and not a node injector that is connected to our path via
|
|
26617
|
+
// a router outlet.
|
|
26618
|
+
if (dep.flags.host) {
|
|
26619
|
+
const firstInjector = resolutionPath[0];
|
|
26620
|
+
const lookupFromFirstInjector = firstInjector.get(dep.token, null, { ...dep.flags, optional: true });
|
|
26621
|
+
if (lookupFromFirstInjector !== null) {
|
|
26622
|
+
dep.providedIn = injectorToCheck;
|
|
26623
|
+
}
|
|
26624
|
+
break;
|
|
26625
|
+
}
|
|
26626
|
+
dep.providedIn = injectorToCheck;
|
|
26627
|
+
break;
|
|
26628
|
+
}
|
|
26629
|
+
// if self is true we stop after the first injector
|
|
26630
|
+
if (i === 0 && dep.flags.self) {
|
|
26631
|
+
break;
|
|
26632
|
+
}
|
|
26633
|
+
}
|
|
26634
|
+
return dep;
|
|
26635
|
+
});
|
|
26636
|
+
return { instance, dependencies };
|
|
26637
|
+
}
|
|
26638
|
+
/**
|
|
26639
|
+
* Gets the class associated with an injector that contains a provider `imports` array in it's
|
|
26640
|
+
* definition
|
|
26641
|
+
*
|
|
26642
|
+
* For Module Injectors this returns the NgModule constructor.
|
|
26643
|
+
*
|
|
26644
|
+
* For Standalone injectors this returns the standalone component constructor.
|
|
26645
|
+
*
|
|
26646
|
+
* @param injector Injector an injector instance
|
|
26647
|
+
* @returns the constructor where the `imports` array that configures this injector is located
|
|
26648
|
+
*/
|
|
26649
|
+
function getProviderImportsContainer(injector) {
|
|
26650
|
+
const { standaloneInjectorToComponent } = getFrameworkDIDebugData();
|
|
26651
|
+
// standalone components configure providers through a component def, so we have to
|
|
26652
|
+
// use the standalone component associated with this injector if Injector represents
|
|
26653
|
+
// a standalone components EnvironmentInjector
|
|
26654
|
+
if (standaloneInjectorToComponent.has(injector)) {
|
|
26655
|
+
return standaloneInjectorToComponent.get(injector);
|
|
26656
|
+
}
|
|
26657
|
+
// Module injectors configure providers through their NgModule def, so we use the
|
|
26658
|
+
// injector to lookup its NgModuleRef and through that grab its instance
|
|
26659
|
+
const defTypeRef = injector.get(NgModuleRef$1, null, { self: true, optional: true });
|
|
26660
|
+
// If we can't find an associated imports container, return null.
|
|
26661
|
+
// This could be the case if this function is called with an R3Injector that does not represent
|
|
26662
|
+
// a standalone component or NgModule.
|
|
26663
|
+
if (defTypeRef === null) {
|
|
26664
|
+
return null;
|
|
26665
|
+
}
|
|
26666
|
+
return defTypeRef.instance.constructor;
|
|
26667
|
+
}
|
|
26668
|
+
/**
|
|
26669
|
+
* Gets the providers configured on a NodeInjector
|
|
26670
|
+
*
|
|
26671
|
+
* @param injector A NodeInjector instance
|
|
26672
|
+
* @returns ProviderRecord[] an array of objects representing the providers configured on this
|
|
26673
|
+
* injector
|
|
26674
|
+
*/
|
|
26675
|
+
function getNodeInjectorProviders(injector) {
|
|
26676
|
+
const diResolver = getNodeInjectorLView(injector);
|
|
26677
|
+
const { resolverToProviders } = getFrameworkDIDebugData();
|
|
26678
|
+
return resolverToProviders.get(diResolver) ?? [];
|
|
26679
|
+
}
|
|
26680
|
+
/**
|
|
26681
|
+
* Gets a mapping of providers configured on an injector to their import paths
|
|
26682
|
+
*
|
|
26683
|
+
* ModuleA -> imports ModuleB
|
|
26684
|
+
* ModuleB -> imports ModuleC
|
|
26685
|
+
* ModuleB -> provides MyServiceA
|
|
26686
|
+
* ModuleC -> provides MyServiceB
|
|
26687
|
+
*
|
|
26688
|
+
* getProviderImportPaths(ModuleA)
|
|
26689
|
+
* > Map(2) {
|
|
26690
|
+
* MyServiceA => [ModuleA, ModuleB]
|
|
26691
|
+
* MyServiceB => [ModuleA, ModuleB, ModuleC]
|
|
26692
|
+
* }
|
|
26693
|
+
*
|
|
26694
|
+
* @param providerImportsContainer constructor of class that contains an `imports` array in it's
|
|
26695
|
+
* definition
|
|
26696
|
+
* @returns A Map object that maps providers to an array of constructors representing it's import
|
|
26697
|
+
* path
|
|
26698
|
+
*
|
|
26699
|
+
*/
|
|
26700
|
+
function getProviderImportPaths(providerImportsContainer) {
|
|
26701
|
+
const providerToPath = new Map();
|
|
26702
|
+
const visitedContainers = new Set();
|
|
26703
|
+
const visitor = walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers);
|
|
26704
|
+
walkProviderTree(providerImportsContainer, visitor, [], new Set());
|
|
26705
|
+
return providerToPath;
|
|
26706
|
+
}
|
|
26707
|
+
/**
|
|
26708
|
+
*
|
|
26709
|
+
* Higher order function that returns a visitor for WalkProviderTree
|
|
26710
|
+
*
|
|
26711
|
+
* Takes in a Map and Set to keep track of the providers and containers
|
|
26712
|
+
* visited, so that we can discover the import paths of these providers
|
|
26713
|
+
* during the traversal.
|
|
26714
|
+
*
|
|
26715
|
+
* This visitor takes advantage of the fact that walkProviderTree performs a
|
|
26716
|
+
* postorder traversal of the provider tree for the passed in container. Because postorder
|
|
26717
|
+
* traversal recursively processes subtrees from leaf nodes until the traversal reaches the root,
|
|
26718
|
+
* we write a visitor that constructs provider import paths in reverse.
|
|
26719
|
+
*
|
|
26720
|
+
*
|
|
26721
|
+
* We use the visitedContainers set defined outside this visitor
|
|
26722
|
+
* because we want to run some logic only once for
|
|
26723
|
+
* each container in the tree. That logic can be described as:
|
|
26724
|
+
*
|
|
26725
|
+
*
|
|
26726
|
+
* 1. for each discovered_provider and discovered_path in the incomplete provider paths we've
|
|
26727
|
+
* already discovered
|
|
26728
|
+
* 2. get the first container in discovered_path
|
|
26729
|
+
* 3. if that first container is in the imports array of the container we're visiting
|
|
26730
|
+
* Then the container we're visiting is also in the import path of discovered_provider, so we
|
|
26731
|
+
* unshift discovered_path with the container we're currently visiting
|
|
26732
|
+
*
|
|
26733
|
+
*
|
|
26734
|
+
* Example Run:
|
|
26735
|
+
* ```
|
|
26736
|
+
* ┌──────────┐
|
|
26737
|
+
* │containerA│
|
|
26738
|
+
* ┌─imports-─┤ ├──imports─┐
|
|
26739
|
+
* │ │ provA │ │
|
|
26740
|
+
* │ │ provB │ │
|
|
26741
|
+
* │ └──────────┘ │
|
|
26742
|
+
* │ │
|
|
26743
|
+
* ┌▼─────────┐ ┌────────▼─┐
|
|
26744
|
+
* │containerB│ │containerC│
|
|
26745
|
+
* │ │ │ │
|
|
26746
|
+
* │ provD │ │ provF │
|
|
26747
|
+
* │ provE │ │ provG │
|
|
26748
|
+
* └──────────┘ └──────────┘
|
|
26749
|
+
* ```
|
|
26750
|
+
*
|
|
26751
|
+
* Each step of the traversal,
|
|
26752
|
+
*
|
|
26753
|
+
* ```
|
|
26754
|
+
* visitor(provD, containerB)
|
|
26755
|
+
* providerToPath === Map { provD => [containerB] }
|
|
26756
|
+
* visitedContainers === Set { containerB }
|
|
26757
|
+
*
|
|
26758
|
+
* visitor(provE, containerB)
|
|
26759
|
+
* providerToPath === Map { provD => [containerB], provE => [containerB] }
|
|
26760
|
+
* visitedContainers === Set { containerB }
|
|
26761
|
+
*
|
|
26762
|
+
* visitor(provF, containerC)
|
|
26763
|
+
* providerToPath === Map { provD => [containerB], provE => [containerB], provF => [containerC] }
|
|
26764
|
+
* visitedContainers === Set { containerB, containerC }
|
|
26765
|
+
*
|
|
26766
|
+
* visitor(provG, containerC)
|
|
26767
|
+
* providerToPath === Map {
|
|
26768
|
+
* provD => [containerB], provE => [containerB], provF => [containerC], provG => [containerC]
|
|
26769
|
+
* }
|
|
26770
|
+
* visitedContainers === Set { containerB, containerC }
|
|
26771
|
+
*
|
|
26772
|
+
* visitor(provA, containerA)
|
|
26773
|
+
* providerToPath === Map {
|
|
26774
|
+
* provD => [containerA, containerB],
|
|
26775
|
+
* provE => [containerA, containerB],
|
|
26776
|
+
* provF => [containerA, containerC],
|
|
26777
|
+
* provG => [containerA, containerC],
|
|
26778
|
+
* provA => [containerA]
|
|
26779
|
+
* }
|
|
26780
|
+
* visitedContainers === Set { containerB, containerC, containerA }
|
|
26781
|
+
*
|
|
26782
|
+
* visitor(provB, containerA)
|
|
26783
|
+
* providerToPath === Map {
|
|
26784
|
+
* provD => [containerA, containerB],
|
|
26785
|
+
* provE => [containerA, containerB],
|
|
26786
|
+
* provF => [containerA, containerC],
|
|
26787
|
+
* provG => [containerA, containerC],
|
|
26788
|
+
* provA => [containerA]
|
|
26789
|
+
* provB => [containerA]
|
|
26790
|
+
* }
|
|
26791
|
+
* visitedContainers === Set { containerB, containerC, containerA }
|
|
26792
|
+
* ```
|
|
26793
|
+
*
|
|
26794
|
+
* @param providerToPath Map map of providers to paths that this function fills
|
|
26795
|
+
* @param visitedContainers Set a set to keep track of the containers we've already visited
|
|
26796
|
+
* @return function(provider SingleProvider, container: Type<unknown> | InjectorType<unknown>) =>
|
|
26797
|
+
* void
|
|
26798
|
+
*/
|
|
26799
|
+
function walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers) {
|
|
26800
|
+
return (provider, container) => {
|
|
26801
|
+
// If the provider is not already in the providerToPath map,
|
|
26802
|
+
// add an entry with the provider as the key and an array containing the current container as
|
|
26803
|
+
// the value
|
|
26804
|
+
if (!providerToPath.has(provider)) {
|
|
26805
|
+
providerToPath.set(provider, [container]);
|
|
26806
|
+
}
|
|
26807
|
+
// This block will run exactly once for each container in the import tree.
|
|
26808
|
+
// This is where we run the logic to check the imports array of the current
|
|
26809
|
+
// container to see if it's the next container in the path for our currently
|
|
26810
|
+
// discovered providers.
|
|
26811
|
+
if (!visitedContainers.has(container)) {
|
|
26812
|
+
// Iterate through the providers we've already seen
|
|
26813
|
+
for (const prov of providerToPath.keys()) {
|
|
26814
|
+
const existingImportPath = providerToPath.get(prov);
|
|
26815
|
+
let containerDef = getInjectorDef(container);
|
|
26816
|
+
if (!containerDef) {
|
|
26817
|
+
const ngModule = container.ngModule;
|
|
26818
|
+
containerDef = getInjectorDef(ngModule);
|
|
26819
|
+
}
|
|
26820
|
+
if (!containerDef) {
|
|
26821
|
+
return;
|
|
26822
|
+
}
|
|
26823
|
+
const lastContainerAddedToPath = existingImportPath[0];
|
|
26824
|
+
let isNextStepInPath = false;
|
|
26825
|
+
deepForEach(containerDef.imports, (moduleImport) => {
|
|
26826
|
+
if (isNextStepInPath) {
|
|
26827
|
+
return;
|
|
26828
|
+
}
|
|
26829
|
+
isNextStepInPath = moduleImport.ngModule === lastContainerAddedToPath ||
|
|
26830
|
+
moduleImport === lastContainerAddedToPath;
|
|
26831
|
+
if (isNextStepInPath) {
|
|
26832
|
+
providerToPath.get(prov)?.unshift(container);
|
|
26833
|
+
}
|
|
26834
|
+
});
|
|
26835
|
+
}
|
|
26836
|
+
}
|
|
26837
|
+
visitedContainers.add(container);
|
|
26838
|
+
};
|
|
26839
|
+
}
|
|
26840
|
+
/**
|
|
26841
|
+
* Gets the providers configured on an EnvironmentInjector
|
|
26842
|
+
*
|
|
26843
|
+
* @param injector EnvironmentInjector
|
|
26844
|
+
* @returns an array of objects representing the providers of the given injector
|
|
26845
|
+
*/
|
|
26846
|
+
function getEnvironmentInjectorProviders(injector) {
|
|
26847
|
+
const providerImportsContainer = getProviderImportsContainer(injector);
|
|
26848
|
+
if (providerImportsContainer === null) {
|
|
26849
|
+
throwError('Could not determine where injector providers were configured.');
|
|
26850
|
+
}
|
|
26851
|
+
const providerToPath = getProviderImportPaths(providerImportsContainer);
|
|
26852
|
+
const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
|
|
26853
|
+
return providerRecords.map(providerRecord => {
|
|
26854
|
+
let importPath = providerToPath.get(providerRecord.provider) ?? [providerImportsContainer];
|
|
26855
|
+
const def = getComponentDef(providerImportsContainer);
|
|
26856
|
+
const isStandaloneComponent = !!def?.standalone;
|
|
26857
|
+
// We prepend the component constructor in the standalone case
|
|
26858
|
+
// because walkProviderTree does not visit this constructor during it's traversal
|
|
26859
|
+
if (isStandaloneComponent) {
|
|
26860
|
+
importPath = [providerImportsContainer, ...providerToPath.get(providerRecord.provider) ?? []];
|
|
26861
|
+
}
|
|
26862
|
+
return { ...providerRecord, importPath };
|
|
26863
|
+
});
|
|
26864
|
+
}
|
|
26865
|
+
/**
|
|
26866
|
+
* Gets the providers configured on an injector.
|
|
26867
|
+
*
|
|
26868
|
+
* @param injector the injector to lookup the providers of
|
|
26869
|
+
* @returns ProviderRecord[] an array of objects representing the providers of the given injector
|
|
26870
|
+
*/
|
|
26871
|
+
function getInjectorProviders(injector) {
|
|
26872
|
+
if (injector instanceof NodeInjector) {
|
|
26873
|
+
return getNodeInjectorProviders(injector);
|
|
26874
|
+
}
|
|
26875
|
+
else if (injector instanceof EnvironmentInjector) {
|
|
26876
|
+
return getEnvironmentInjectorProviders(injector);
|
|
26877
|
+
}
|
|
26878
|
+
throwError('getInjectorProviders only supports NodeInjector and EnvironmentInjector');
|
|
26879
|
+
}
|
|
26880
|
+
function getInjectorResolutionPath(injector) {
|
|
26881
|
+
const resolutionPath = [injector];
|
|
26882
|
+
getInjectorResolutionPathHelper(injector, resolutionPath);
|
|
26883
|
+
return resolutionPath;
|
|
26884
|
+
}
|
|
26885
|
+
function getInjectorResolutionPathHelper(injector, resolutionPath) {
|
|
26886
|
+
const parent = getInjectorParent(injector);
|
|
26887
|
+
// if getInjectorParent can't find a parent, then we've either reached the end
|
|
26888
|
+
// of the path, or we need to move from the Element Injector tree to the
|
|
26889
|
+
// module injector tree using the first injector in our path as the connection point.
|
|
26890
|
+
if (parent === null) {
|
|
26891
|
+
if (injector instanceof NodeInjector) {
|
|
26892
|
+
const firstInjector = resolutionPath[0];
|
|
26893
|
+
if (firstInjector instanceof NodeInjector) {
|
|
26894
|
+
const moduleInjector = getModuleInjectorOfNodeInjector(firstInjector);
|
|
26895
|
+
if (moduleInjector === null) {
|
|
26896
|
+
throwError('NodeInjector must have some connection to the module injector tree');
|
|
26897
|
+
}
|
|
26898
|
+
resolutionPath.push(moduleInjector);
|
|
26899
|
+
getInjectorResolutionPathHelper(moduleInjector, resolutionPath);
|
|
26900
|
+
}
|
|
26901
|
+
return resolutionPath;
|
|
26902
|
+
}
|
|
26903
|
+
}
|
|
26904
|
+
else {
|
|
26905
|
+
resolutionPath.push(parent);
|
|
26906
|
+
getInjectorResolutionPathHelper(parent, resolutionPath);
|
|
26907
|
+
}
|
|
26908
|
+
return resolutionPath;
|
|
26909
|
+
}
|
|
26910
|
+
/**
|
|
26911
|
+
* Gets the parent of an injector.
|
|
26912
|
+
*
|
|
26913
|
+
* This function is not able to make the jump from the Element Injector Tree to the Module
|
|
26914
|
+
* injector tree. This is because the "parent" (the next step in the reoslution path)
|
|
26915
|
+
* of a root NodeInjector is dependent on which NodeInjector ancestor initiated
|
|
26916
|
+
* the DI lookup. See getInjectorResolutionPath for a function that can make this jump.
|
|
26917
|
+
*
|
|
26918
|
+
* In the below diagram:
|
|
26919
|
+
* ```ts
|
|
26920
|
+
* getInjectorParent(NodeInjectorB)
|
|
26921
|
+
* > NodeInjectorA
|
|
26922
|
+
* getInjectorParent(NodeInjectorA) // or getInjectorParent(getInjectorParent(NodeInjectorB))
|
|
26923
|
+
* > null // cannot jump to ModuleInjector tree
|
|
26924
|
+
* ```
|
|
26925
|
+
*
|
|
26926
|
+
* ```
|
|
26927
|
+
* ┌───────┐ ┌───────────────────┐
|
|
26928
|
+
* ┌───────────┤ModuleA├───Injector────►│EnvironmentInjector│
|
|
26929
|
+
* │ └───┬───┘ └───────────────────┘
|
|
26930
|
+
* │ │
|
|
26931
|
+
* │ bootstraps
|
|
26932
|
+
* │ │
|
|
26933
|
+
* │ │
|
|
26934
|
+
* │ ┌────▼─────┐ ┌─────────────┐
|
|
26935
|
+
* declares │ComponentA├────Injector────►│NodeInjectorA│
|
|
26936
|
+
* │ └────┬─────┘ └─────▲───────┘
|
|
26937
|
+
* │ │ │
|
|
26938
|
+
* │ renders parent
|
|
26939
|
+
* │ │ │
|
|
26940
|
+
* │ ┌────▼─────┐ ┌─────┴───────┐
|
|
26941
|
+
* └─────────►│ComponentB├────Injector────►│NodeInjectorB│
|
|
26942
|
+
* └──────────┘ └─────────────┘
|
|
26943
|
+
*```
|
|
26944
|
+
*
|
|
26945
|
+
* @param injector an Injector to get the parent of
|
|
26946
|
+
* @returns Injector the parent of the given injector
|
|
26947
|
+
*/
|
|
26948
|
+
function getInjectorParent(injector) {
|
|
26949
|
+
if (injector instanceof R3Injector) {
|
|
26950
|
+
return injector.parent;
|
|
26951
|
+
}
|
|
26952
|
+
let tNode;
|
|
26953
|
+
let lView;
|
|
26954
|
+
if (injector instanceof NodeInjector) {
|
|
26955
|
+
tNode = getNodeInjectorTNode(injector);
|
|
26956
|
+
lView = getNodeInjectorLView(injector);
|
|
26957
|
+
}
|
|
26958
|
+
else if (injector instanceof NullInjector) {
|
|
26959
|
+
return null;
|
|
26960
|
+
}
|
|
26961
|
+
else {
|
|
26962
|
+
throwError('getInjectorParent only support injectors of type R3Injector, NodeInjector, NullInjector');
|
|
26963
|
+
}
|
|
26964
|
+
const parentLocation = getParentInjectorLocation(tNode, lView);
|
|
26965
|
+
if (hasParentInjector(parentLocation)) {
|
|
26966
|
+
const parentInjectorIndex = getParentInjectorIndex(parentLocation);
|
|
26967
|
+
const parentLView = getParentInjectorView(parentLocation, lView);
|
|
26968
|
+
const parentTView = parentLView[TVIEW];
|
|
26969
|
+
const parentTNode = parentTView.data[parentInjectorIndex + 8 /* NodeInjectorOffset.TNODE */];
|
|
26970
|
+
return new NodeInjector(parentTNode, parentLView);
|
|
26971
|
+
}
|
|
26972
|
+
else {
|
|
26973
|
+
const chainedInjector = lView[INJECTOR$1];
|
|
26974
|
+
// Case where chainedInjector.injector is an OutletInjector and chainedInjector.injector.parent
|
|
26975
|
+
// is a NodeInjector.
|
|
26976
|
+
// todo(aleksanderbodurri): ideally nothing in packages/core should deal
|
|
26977
|
+
// directly with router concerns. Refactor this so that we can make the jump from
|
|
26978
|
+
// NodeInjector -> OutletInjector -> NodeInjector
|
|
26979
|
+
// without explictly relying on types contracts from packages/router
|
|
26980
|
+
const injectorParent = chainedInjector.injector?.parent;
|
|
26981
|
+
if (injectorParent instanceof NodeInjector) {
|
|
26982
|
+
return injectorParent;
|
|
26983
|
+
}
|
|
26984
|
+
}
|
|
26985
|
+
return null;
|
|
26986
|
+
}
|
|
26987
|
+
/**
|
|
26988
|
+
* Gets the module injector of a NodeInjector.
|
|
26989
|
+
*
|
|
26990
|
+
* @param injector NodeInjector to get module injector of
|
|
26991
|
+
* @returns Injector representing module injector of the given NodeInjector
|
|
26992
|
+
*/
|
|
26993
|
+
function getModuleInjectorOfNodeInjector(injector) {
|
|
26994
|
+
let lView;
|
|
26995
|
+
if (injector instanceof NodeInjector) {
|
|
26996
|
+
lView = getNodeInjectorLView(injector);
|
|
26997
|
+
}
|
|
26998
|
+
else {
|
|
26999
|
+
throwError('getModuleInjectorOfNodeInjector must be called with a NodeInjector');
|
|
27000
|
+
}
|
|
27001
|
+
const chainedInjector = lView[INJECTOR$1];
|
|
27002
|
+
const moduleInjector = chainedInjector.parentInjector;
|
|
27003
|
+
if (!moduleInjector) {
|
|
27004
|
+
throwError('NodeInjector must have some connection to the module injector tree');
|
|
27005
|
+
}
|
|
27006
|
+
return moduleInjector;
|
|
27007
|
+
}
|
|
27008
|
+
|
|
25885
27009
|
/**
|
|
25886
27010
|
* This file introduces series of globally accessible debug tools
|
|
25887
27011
|
* to allow for the Angular debugging story to function.
|
|
@@ -25907,6 +27031,10 @@ let _published = false;
|
|
|
25907
27031
|
function publishDefaultGlobalUtils$1() {
|
|
25908
27032
|
if (!_published) {
|
|
25909
27033
|
_published = true;
|
|
27034
|
+
setupFrameworkInjectorProfiler();
|
|
27035
|
+
publishGlobalUtil('ɵgetDependenciesFromInjectable', getDependenciesFromInjectable);
|
|
27036
|
+
publishGlobalUtil('ɵgetInjectorProviders', getInjectorProviders);
|
|
27037
|
+
publishGlobalUtil('ɵgetInjectorResolutionPath', getInjectorResolutionPath);
|
|
25910
27038
|
/**
|
|
25911
27039
|
* Warning: this function is *INTERNAL* and should not be relied upon in application's code.
|
|
25912
27040
|
* The contract of the function might be changed in any release and/or the function can be
|
|
@@ -29593,6 +30721,47 @@ function calcNumRootNodes(tView, lView, tNode) {
|
|
|
29593
30721
|
collectNativeNodes(tView, lView, tNode, rootNodes);
|
|
29594
30722
|
return rootNodes.length;
|
|
29595
30723
|
}
|
|
30724
|
+
/**
|
|
30725
|
+
* Annotates root level component's LView for hydration,
|
|
30726
|
+
* see `annotateHostElementForHydration` for additional information.
|
|
30727
|
+
*/
|
|
30728
|
+
function annotateComponentLViewForHydration(lView, context) {
|
|
30729
|
+
const hostElement = lView[HOST];
|
|
30730
|
+
// Root elements might also be annotated with the `ngSkipHydration` attribute,
|
|
30731
|
+
// check if it's present before starting the serialization process.
|
|
30732
|
+
if (hostElement && !hostElement.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
|
|
30733
|
+
return annotateHostElementForHydration(hostElement, lView, context);
|
|
30734
|
+
}
|
|
30735
|
+
return null;
|
|
30736
|
+
}
|
|
30737
|
+
/**
|
|
30738
|
+
* Annotates root level LContainer for hydration. This happens when a root component
|
|
30739
|
+
* injects ViewContainerRef, thus making the component an anchor for a view container.
|
|
30740
|
+
* This function serializes the component itself as well as all views from the view
|
|
30741
|
+
* container.
|
|
30742
|
+
*/
|
|
30743
|
+
function annotateLContainerForHydration(lContainer, context) {
|
|
30744
|
+
const componentLView = lContainer[HOST];
|
|
30745
|
+
// Serialize the root component itself.
|
|
30746
|
+
const componentLViewNghIndex = annotateComponentLViewForHydration(componentLView, context);
|
|
30747
|
+
const hostElement = unwrapRNode(componentLView[HOST]);
|
|
30748
|
+
// Serialize all views within this view container.
|
|
30749
|
+
const rootLView = lContainer[PARENT];
|
|
30750
|
+
const rootLViewNghIndex = annotateHostElementForHydration(hostElement, rootLView, context);
|
|
30751
|
+
const renderer = componentLView[RENDERER];
|
|
30752
|
+
// For cases when a root component also acts as an anchor node for a ViewContainerRef
|
|
30753
|
+
// (for example, when ViewContainerRef is injected in a root component), there is a need
|
|
30754
|
+
// to serialize information about the component itself, as well as an LContainer that
|
|
30755
|
+
// represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
|
|
30756
|
+
// (1) hydration info for the root component itself and (2) hydration info for the
|
|
30757
|
+
// ViewContainerRef instance (an LContainer). Each piece of information is included into
|
|
30758
|
+
// the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
|
|
30759
|
+
// Since we only have 1 root element, we encode both bits of info into a single string:
|
|
30760
|
+
// ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
|
|
30761
|
+
// and 25 is the `ngh` for a root view which holds LContainer).
|
|
30762
|
+
const finalIndex = `${componentLViewNghIndex}|${rootLViewNghIndex}`;
|
|
30763
|
+
renderer.setAttribute(hostElement, NGH_ATTR_NAME, finalIndex);
|
|
30764
|
+
}
|
|
29596
30765
|
/**
|
|
29597
30766
|
* Annotates all components bootstrapped in a given ApplicationRef
|
|
29598
30767
|
* with info needed for hydration.
|
|
@@ -29605,21 +30774,21 @@ function annotateForHydration(appRef, doc) {
|
|
|
29605
30774
|
const corruptedTextNodes = new Map();
|
|
29606
30775
|
const viewRefs = appRef._views;
|
|
29607
30776
|
for (const viewRef of viewRefs) {
|
|
29608
|
-
const
|
|
30777
|
+
const lNode = getLNodeForHydration(viewRef);
|
|
29609
30778
|
// An `lView` might be `null` if a `ViewRef` represents
|
|
29610
30779
|
// an embedded view (not a component view).
|
|
29611
|
-
if (
|
|
29612
|
-
const
|
|
29613
|
-
|
|
29614
|
-
|
|
29615
|
-
|
|
29616
|
-
|
|
29617
|
-
|
|
29618
|
-
|
|
29619
|
-
|
|
29620
|
-
|
|
29621
|
-
insertCorruptedTextNodeMarkers(corruptedTextNodes, doc);
|
|
30780
|
+
if (lNode !== null) {
|
|
30781
|
+
const context = {
|
|
30782
|
+
serializedViewCollection,
|
|
30783
|
+
corruptedTextNodes,
|
|
30784
|
+
};
|
|
30785
|
+
if (isLContainer(lNode)) {
|
|
30786
|
+
annotateLContainerForHydration(lNode, context);
|
|
30787
|
+
}
|
|
30788
|
+
else {
|
|
30789
|
+
annotateComponentLViewForHydration(lNode, context);
|
|
29622
30790
|
}
|
|
30791
|
+
insertCorruptedTextNodeMarkers(corruptedTextNodes, doc);
|
|
29623
30792
|
}
|
|
29624
30793
|
}
|
|
29625
30794
|
// Note: we *always* include hydration info key and a corresponding value
|
|
@@ -29900,6 +31069,8 @@ function componentUsesShadowDomEncapsulation(lView) {
|
|
|
29900
31069
|
* @param element The Host element to be annotated
|
|
29901
31070
|
* @param lView The associated LView
|
|
29902
31071
|
* @param context The hydration context
|
|
31072
|
+
* @returns An index of serialized view from the transfer state object
|
|
31073
|
+
* or `null` when a given component can not be serialized.
|
|
29903
31074
|
*/
|
|
29904
31075
|
function annotateHostElementForHydration(element, lView, context) {
|
|
29905
31076
|
const renderer = lView[RENDERER];
|
|
@@ -29910,11 +31081,13 @@ function annotateHostElementForHydration(element, lView, context) {
|
|
|
29910
31081
|
// shadow DOM, so we can not guarantee that client and server representations
|
|
29911
31082
|
// would exactly match
|
|
29912
31083
|
renderer.setAttribute(element, SKIP_HYDRATION_ATTR_NAME, '');
|
|
31084
|
+
return null;
|
|
29913
31085
|
}
|
|
29914
31086
|
else {
|
|
29915
31087
|
const ngh = serializeLView(lView, context);
|
|
29916
31088
|
const index = context.serializedViewCollection.add(ngh);
|
|
29917
31089
|
renderer.setAttribute(element, NGH_ATTR_NAME, index.toString());
|
|
31090
|
+
return index;
|
|
29918
31091
|
}
|
|
29919
31092
|
}
|
|
29920
31093
|
/**
|
|
@@ -29993,14 +31166,6 @@ function enableHydrationRuntimeSupport() {
|
|
|
29993
31166
|
enableApplyRootElementTransformImpl();
|
|
29994
31167
|
}
|
|
29995
31168
|
}
|
|
29996
|
-
/**
|
|
29997
|
-
* Detects whether the code is invoked in a browser.
|
|
29998
|
-
* Later on, this check should be replaced with a tree-shakable
|
|
29999
|
-
* flag (e.g. `!isServer`).
|
|
30000
|
-
*/
|
|
30001
|
-
function isBrowser() {
|
|
30002
|
-
return inject(PLATFORM_ID) === 'browser';
|
|
30003
|
-
}
|
|
30004
31169
|
/**
|
|
30005
31170
|
* Outputs a message with hydration stats into a console.
|
|
30006
31171
|
*/
|
|
@@ -30049,7 +31214,7 @@ function withDomHydration() {
|
|
|
30049
31214
|
provide: IS_HYDRATION_DOM_REUSE_ENABLED,
|
|
30050
31215
|
useFactory: () => {
|
|
30051
31216
|
let isEnabled = true;
|
|
30052
|
-
if (
|
|
31217
|
+
if (isPlatformBrowser()) {
|
|
30053
31218
|
// On the client, verify that the server response contains
|
|
30054
31219
|
// hydration annotations. Otherwise, keep hydration disabled.
|
|
30055
31220
|
const transferState = inject(TransferState, { optional: true });
|
|
@@ -30076,10 +31241,11 @@ function withDomHydration() {
|
|
|
30076
31241
|
useValue: () => {
|
|
30077
31242
|
// Since this function is used across both server and client,
|
|
30078
31243
|
// make sure that the runtime code is only added when invoked
|
|
30079
|
-
// on the client. Moving forward, the `
|
|
31244
|
+
// on the client. Moving forward, the `isPlatformBrowser` check should
|
|
30080
31245
|
// be replaced with a tree-shakable alternative (e.g. `isServer`
|
|
30081
31246
|
// flag).
|
|
30082
|
-
if (
|
|
31247
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
31248
|
+
verifySsrContentsIntegrity();
|
|
30083
31249
|
enableHydrationRuntimeSupport();
|
|
30084
31250
|
}
|
|
30085
31251
|
},
|
|
@@ -30092,13 +31258,13 @@ function withDomHydration() {
|
|
|
30092
31258
|
// environment and when hydration is configured properly.
|
|
30093
31259
|
// On a server, an application is rendered from scratch,
|
|
30094
31260
|
// so the host content needs to be empty.
|
|
30095
|
-
return
|
|
31261
|
+
return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
|
|
30096
31262
|
}
|
|
30097
31263
|
},
|
|
30098
31264
|
{
|
|
30099
31265
|
provide: APP_BOOTSTRAP_LISTENER,
|
|
30100
31266
|
useFactory: () => {
|
|
30101
|
-
if (
|
|
31267
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
30102
31268
|
const appRef = inject(ApplicationRef);
|
|
30103
31269
|
const injector = inject(Injector);
|
|
30104
31270
|
return () => {
|
|
@@ -30130,10 +31296,43 @@ function logWarningOnStableTimedout(time, console) {
|
|
|
30130
31296
|
`as a signal to complete hydration process.`;
|
|
30131
31297
|
console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
|
|
30132
31298
|
}
|
|
31299
|
+
/**
|
|
31300
|
+
* Verifies whether the DOM contains a special marker added during SSR time to make sure
|
|
31301
|
+
* there is no SSR'ed contents transformations happen after SSR is completed. Typically that
|
|
31302
|
+
* happens either by CDN or during the build process as an optimization to remove comment nodes.
|
|
31303
|
+
* Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
|
|
31304
|
+
* When this special marker is *not* present - throw an error and do not proceed with hydration,
|
|
31305
|
+
* since it will not be able to function correctly.
|
|
31306
|
+
*
|
|
31307
|
+
* Note: this function is invoked only on the client, so it's safe to use DOM APIs.
|
|
31308
|
+
*/
|
|
31309
|
+
function verifySsrContentsIntegrity() {
|
|
31310
|
+
const doc = getDocument();
|
|
31311
|
+
let hydrationMarker;
|
|
31312
|
+
for (const node of doc.body.childNodes) {
|
|
31313
|
+
if (node.nodeType === Node.COMMENT_NODE &&
|
|
31314
|
+
node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
|
|
31315
|
+
hydrationMarker = node;
|
|
31316
|
+
break;
|
|
31317
|
+
}
|
|
31318
|
+
}
|
|
31319
|
+
if (!hydrationMarker) {
|
|
31320
|
+
throw new RuntimeError(507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode &&
|
|
31321
|
+
'Angular hydration logic detected that HTML content of this page was modified after it ' +
|
|
31322
|
+
'was produced during server side rendering. Make sure that there are no optimizations ' +
|
|
31323
|
+
'that remove comment nodes from HTML are enabled on your CDN. Angular hydration ' +
|
|
31324
|
+
'relies on HTML produced by the server, including whitespaces and comment nodes.');
|
|
31325
|
+
}
|
|
31326
|
+
}
|
|
30133
31327
|
|
|
30134
31328
|
/**
|
|
30135
31329
|
* Transforms a value (typically a string) to a boolean.
|
|
30136
31330
|
* Intended to be used as a transform function of an input.
|
|
31331
|
+
*
|
|
31332
|
+
* @usageNotes
|
|
31333
|
+
* ```typescript
|
|
31334
|
+
* @Input({ transform: booleanAttribute }) status!: boolean;
|
|
31335
|
+
* ```
|
|
30137
31336
|
* @param value Value to be transformed.
|
|
30138
31337
|
*
|
|
30139
31338
|
* @publicApi
|
|
@@ -30147,6 +31346,11 @@ function booleanAttribute(value) {
|
|
|
30147
31346
|
* @param value Value to be transformed.
|
|
30148
31347
|
* @param fallbackValue Value to use if the provided value can't be parsed as a number.
|
|
30149
31348
|
*
|
|
31349
|
+
* @usageNotes
|
|
31350
|
+
* ```typescript
|
|
31351
|
+
* @Input({ transform: numberAttribute }) id!: number;
|
|
31352
|
+
* ```
|
|
31353
|
+
*
|
|
30150
31354
|
* @publicApi
|
|
30151
31355
|
*/
|
|
30152
31356
|
function numberAttribute(value, fallbackValue = NaN) {
|
|
@@ -30439,5 +31643,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
30439
31643
|
* Generated bundle index. Do not edit.
|
|
30440
31644
|
*/
|
|
30441
31645
|
|
|
30442
|
-
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
|
|
31646
|
+
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertPlatform, booleanAttribute, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, numberAttribute, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, ENABLED_SSR_FEATURES as ɵENABLED_SSR_FEATURES, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_ENABLED, InitialRenderPendingTasks as ɵInitialRenderPendingTasks, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefer, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
|
|
30443
31647
|
//# sourceMappingURL=core.mjs.map
|