@angular/core 16.0.0-next.0 → 16.0.0-next.2
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/esm2020/src/application_config.mjs +21 -0
- package/esm2020/src/application_init.mjs +23 -31
- package/esm2020/src/application_module.mjs +3 -2
- package/esm2020/src/application_ref.mjs +35 -33
- package/esm2020/src/application_tokens.mjs +2 -13
- package/esm2020/src/change_detection/change_detection.mjs +2 -2
- package/esm2020/src/change_detection/change_detector_ref.mjs +3 -2
- package/esm2020/src/change_detection/constants.mjs +1 -49
- package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -2
- package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +3 -2
- package/esm2020/src/console.mjs +3 -2
- package/esm2020/src/core.mjs +4 -3
- package/esm2020/src/core_private_export.mjs +6 -7
- package/esm2020/src/core_render3_private_export.mjs +3 -1
- package/esm2020/src/debug/debug_node.mjs +1 -5
- package/esm2020/src/di/injector.mjs +3 -2
- package/esm2020/src/di/r3_injector.mjs +5 -1
- package/esm2020/src/di/reflective_injector.mjs +3 -2
- package/esm2020/src/hydration/annotate.mjs +140 -0
- package/esm2020/src/hydration/api.mjs +120 -0
- package/esm2020/src/hydration/error_handling.mjs +29 -0
- package/esm2020/src/hydration/interfaces.mjs +10 -0
- package/esm2020/src/hydration/node_lookup_utils.mjs +75 -0
- package/esm2020/src/hydration/skip_hydration.mjs +34 -0
- package/esm2020/src/hydration/tokens.mjs +25 -0
- package/esm2020/src/hydration/utils.mjs +131 -0
- package/esm2020/src/linker/compiler.mjs +3 -2
- package/esm2020/src/linker/component_factory_resolver.mjs +3 -2
- package/esm2020/src/linker/destroy_ref.mjs +41 -0
- package/esm2020/src/linker/element_ref.mjs +3 -2
- package/esm2020/src/linker/query_list.mjs +6 -7
- package/esm2020/src/linker/template_ref.mjs +6 -5
- package/esm2020/src/linker/view_container_ref.mjs +3 -2
- package/esm2020/src/linker.mjs +2 -1
- package/esm2020/src/render/api.mjs +3 -2
- package/esm2020/src/render3/component_ref.mjs +16 -9
- package/esm2020/src/render3/features/standalone_feature.mjs +1 -1
- package/esm2020/src/render3/fields.mjs +10 -1
- package/esm2020/src/render3/hooks.mjs +3 -2
- package/esm2020/src/render3/i18n/i18n_util.mjs +3 -3
- package/esm2020/src/render3/instructions/element.mjs +56 -13
- package/esm2020/src/render3/instructions/element_container.mjs +54 -9
- package/esm2020/src/render3/instructions/listener.mjs +3 -3
- package/esm2020/src/render3/instructions/shared.mjs +40 -24
- package/esm2020/src/render3/instructions/template.mjs +2 -2
- package/esm2020/src/render3/instructions/text.mjs +36 -5
- package/esm2020/src/render3/interfaces/definition.mjs +1 -1
- package/esm2020/src/render3/interfaces/node.mjs +1 -1
- package/esm2020/src/render3/interfaces/renderer_dom.mjs +1 -1
- package/esm2020/src/render3/interfaces/view.mjs +4 -2
- package/esm2020/src/render3/jit/directive.mjs +1 -2
- package/esm2020/src/render3/node_manipulation.mjs +25 -14
- package/esm2020/src/render3/state.mjs +45 -1
- package/esm2020/src/render3/util/view_utils.mjs +11 -2
- package/esm2020/src/render3/view_ref.mjs +4 -3
- package/esm2020/src/sanitization/sanitizer.mjs +3 -2
- package/esm2020/src/testability/testability.mjs +5 -3
- package/esm2020/src/transfer_state.mjs +153 -0
- package/esm2020/src/util/iterable.mjs +6 -7
- package/esm2020/src/util/lang.mjs +1 -11
- package/esm2020/src/util/ng_dev_mode.mjs +3 -1
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/logger.mjs +6 -5
- package/esm2020/testing/src/ng_zone_mock.mjs +6 -5
- package/esm2020/testing/src/test_bed.mjs +3 -2
- package/fesm2015/core.mjs +1076 -297
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +747 -159
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +1066 -295
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +741 -159
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +290 -87
- package/package.json +3 -3
- package/schematics/migrations/router-link-with-href/bundle.js.map +2 -2
- package/schematics/ng-generate/standalone-migration/bundle.js +1044 -1024
- package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
- package/testing/index.d.ts +1 -1
- package/esm2020/src/util/symbol.mjs +0 -30
package/fesm2020/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v16.0.0-next.
|
|
2
|
+
* @license Angular v16.0.0-next.2
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -555,6 +555,8 @@ function ngDevModeResetPerfCounters() {
|
|
|
555
555
|
rendererAppendChild: 0,
|
|
556
556
|
rendererInsertBefore: 0,
|
|
557
557
|
rendererCreateComment: 0,
|
|
558
|
+
hydratedNodes: 0,
|
|
559
|
+
hydratedComponents: 0,
|
|
558
560
|
};
|
|
559
561
|
// Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
|
|
560
562
|
const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
|
|
@@ -855,54 +857,6 @@ var ChangeDetectionStrategy;
|
|
|
855
857
|
*/
|
|
856
858
|
ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
|
|
857
859
|
})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
|
|
858
|
-
/**
|
|
859
|
-
* Defines the possible states of the default change detector.
|
|
860
|
-
* @see `ChangeDetectorRef`
|
|
861
|
-
*/
|
|
862
|
-
var ChangeDetectorStatus;
|
|
863
|
-
(function (ChangeDetectorStatus) {
|
|
864
|
-
/**
|
|
865
|
-
* A state in which, after calling `detectChanges()`, the change detector
|
|
866
|
-
* state becomes `Checked`, and must be explicitly invoked or reactivated.
|
|
867
|
-
*/
|
|
868
|
-
ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
|
|
869
|
-
/**
|
|
870
|
-
* A state in which change detection is skipped until the change detector mode
|
|
871
|
-
* becomes `CheckOnce`.
|
|
872
|
-
*/
|
|
873
|
-
ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
|
|
874
|
-
/**
|
|
875
|
-
* A state in which change detection continues automatically until explicitly
|
|
876
|
-
* deactivated.
|
|
877
|
-
*/
|
|
878
|
-
ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
|
|
879
|
-
/**
|
|
880
|
-
* A state in which a change detector sub tree is not a part of the main tree and
|
|
881
|
-
* should be skipped.
|
|
882
|
-
*/
|
|
883
|
-
ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
|
|
884
|
-
/**
|
|
885
|
-
* Indicates that the change detector encountered an error checking a binding
|
|
886
|
-
* or calling a directive lifecycle method and is now in an inconsistent state. Change
|
|
887
|
-
* detectors in this state do not detect changes.
|
|
888
|
-
*/
|
|
889
|
-
ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
|
|
890
|
-
/**
|
|
891
|
-
* Indicates that the change detector has been destroyed.
|
|
892
|
-
*/
|
|
893
|
-
ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
|
|
894
|
-
})(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
|
|
895
|
-
/**
|
|
896
|
-
* Reports whether a given strategy is currently the default for change detection.
|
|
897
|
-
* @param changeDetectionStrategy The strategy to check.
|
|
898
|
-
* @returns True if the given strategy is the current default, false otherwise.
|
|
899
|
-
* @see `ChangeDetectorStatus`
|
|
900
|
-
* @see `ChangeDetectorRef`
|
|
901
|
-
*/
|
|
902
|
-
function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
|
|
903
|
-
return changeDetectionStrategy == null ||
|
|
904
|
-
changeDetectionStrategy === ChangeDetectionStrategy.Default;
|
|
905
|
-
}
|
|
906
860
|
|
|
907
861
|
/**
|
|
908
862
|
* Defines the CSS styles encapsulation policies for the {@link Component} decorator's
|
|
@@ -974,6 +928,15 @@ const NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty })
|
|
|
974
928
|
*/
|
|
975
929
|
// TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
|
|
976
930
|
const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
|
|
931
|
+
/**
|
|
932
|
+
* The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
|
|
933
|
+
* getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
|
|
934
|
+
* strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
|
|
935
|
+
*
|
|
936
|
+
* This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
|
|
937
|
+
* improve tree-shaking.
|
|
938
|
+
*/
|
|
939
|
+
const NG_ENV_ID = getClosureSafeProperty({ __NG_ENV_ID__: getClosureSafeProperty });
|
|
977
940
|
|
|
978
941
|
/** Counter used to generate unique IDs for component definitions. */
|
|
979
942
|
let componentDefCount = 0;
|
|
@@ -1290,6 +1253,8 @@ const PREORDER_HOOK_FLAGS = 18;
|
|
|
1290
1253
|
const QUERIES = 19;
|
|
1291
1254
|
const ID = 20;
|
|
1292
1255
|
const EMBEDDED_VIEW_INJECTOR = 21;
|
|
1256
|
+
const ON_DESTROY_HOOKS = 22;
|
|
1257
|
+
const HYDRATION = 23;
|
|
1293
1258
|
/**
|
|
1294
1259
|
* Size of LView's header. Necessary to adjust for it when setting slots.
|
|
1295
1260
|
*
|
|
@@ -1297,7 +1262,7 @@ const EMBEDDED_VIEW_INJECTOR = 21;
|
|
|
1297
1262
|
* instruction index into `LView` index. All other indexes should be in the `LView` index space and
|
|
1298
1263
|
* there should be no need to refer to `HEADER_OFFSET` anywhere else.
|
|
1299
1264
|
*/
|
|
1300
|
-
const HEADER_OFFSET =
|
|
1265
|
+
const HEADER_OFFSET = 24;
|
|
1301
1266
|
// Note: This hack is necessary so we don't erroneously get a circular dependency
|
|
1302
1267
|
// failure based on types.
|
|
1303
1268
|
const unusedValueExportToPlacateAjd$4 = 1;
|
|
@@ -1773,10 +1738,20 @@ function updateTransplantedViewCount(lContainer, amount) {
|
|
|
1773
1738
|
parent = parent[PARENT];
|
|
1774
1739
|
}
|
|
1775
1740
|
}
|
|
1741
|
+
/**
|
|
1742
|
+
* Stores a LView-specific destroy callback.
|
|
1743
|
+
*/
|
|
1744
|
+
function storeLViewOnDestroy(lView, onDestroyCallback) {
|
|
1745
|
+
if (lView[ON_DESTROY_HOOKS] === null) {
|
|
1746
|
+
lView[ON_DESTROY_HOOKS] = [];
|
|
1747
|
+
}
|
|
1748
|
+
lView[ON_DESTROY_HOOKS].push(onDestroyCallback);
|
|
1749
|
+
}
|
|
1776
1750
|
|
|
1777
1751
|
const instructionState = {
|
|
1778
1752
|
lFrame: createLFrame(null),
|
|
1779
1753
|
bindingsEnabled: true,
|
|
1754
|
+
skipHydrationRootTNode: null,
|
|
1780
1755
|
};
|
|
1781
1756
|
/**
|
|
1782
1757
|
* In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
|
|
@@ -1807,6 +1782,21 @@ function decreaseElementDepthCount() {
|
|
|
1807
1782
|
function getBindingsEnabled() {
|
|
1808
1783
|
return instructionState.bindingsEnabled;
|
|
1809
1784
|
}
|
|
1785
|
+
/**
|
|
1786
|
+
* Returns true if currently inside a skip hydration block.
|
|
1787
|
+
* @returns boolean
|
|
1788
|
+
*/
|
|
1789
|
+
function isInSkipHydrationBlock() {
|
|
1790
|
+
return instructionState.skipHydrationRootTNode !== null;
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Returns true if this is the root TNode of the skip hydration block.
|
|
1794
|
+
* @param tNode the current TNode
|
|
1795
|
+
* @returns boolean
|
|
1796
|
+
*/
|
|
1797
|
+
function isSkipHydrationRootTNode(tNode) {
|
|
1798
|
+
return instructionState.skipHydrationRootTNode === tNode;
|
|
1799
|
+
}
|
|
1810
1800
|
/**
|
|
1811
1801
|
* Enables directive matching on elements.
|
|
1812
1802
|
*
|
|
@@ -1829,6 +1819,13 @@ function getBindingsEnabled() {
|
|
|
1829
1819
|
function ɵɵenableBindings() {
|
|
1830
1820
|
instructionState.bindingsEnabled = true;
|
|
1831
1821
|
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Sets a flag to specify that the TNode is in a skip hydration block.
|
|
1824
|
+
* @param tNode the current TNode
|
|
1825
|
+
*/
|
|
1826
|
+
function enterSkipHydrationBlock(tNode) {
|
|
1827
|
+
instructionState.skipHydrationRootTNode = tNode;
|
|
1828
|
+
}
|
|
1832
1829
|
/**
|
|
1833
1830
|
* Disables directive matching on element.
|
|
1834
1831
|
*
|
|
@@ -1851,6 +1848,12 @@ function ɵɵenableBindings() {
|
|
|
1851
1848
|
function ɵɵdisableBindings() {
|
|
1852
1849
|
instructionState.bindingsEnabled = false;
|
|
1853
1850
|
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Clears the root skip hydration node when leaving a skip hydration block.
|
|
1853
|
+
*/
|
|
1854
|
+
function leaveSkipHydrationBlock() {
|
|
1855
|
+
instructionState.skipHydrationRootTNode = null;
|
|
1856
|
+
}
|
|
1854
1857
|
/**
|
|
1855
1858
|
* Return the current `LView`.
|
|
1856
1859
|
*/
|
|
@@ -2275,6 +2278,21 @@ function namespaceHTMLInternal() {
|
|
|
2275
2278
|
function getNamespace$1() {
|
|
2276
2279
|
return instructionState.lFrame.currentNamespace;
|
|
2277
2280
|
}
|
|
2281
|
+
let _wasLastNodeCreated = true;
|
|
2282
|
+
/**
|
|
2283
|
+
* Retrieves a global flag that indicates whether the most recent DOM node
|
|
2284
|
+
* was created or hydrated.
|
|
2285
|
+
*/
|
|
2286
|
+
function wasLastNodeCreated() {
|
|
2287
|
+
return _wasLastNodeCreated;
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2290
|
+
* Sets a global flag to indicate whether the most recent DOM node
|
|
2291
|
+
* was created or hydrated.
|
|
2292
|
+
*/
|
|
2293
|
+
function lastNodeWasCreated(flag) {
|
|
2294
|
+
_wasLastNodeCreated = flag;
|
|
2295
|
+
}
|
|
2278
2296
|
|
|
2279
2297
|
/**
|
|
2280
2298
|
* Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
|
|
@@ -2450,8 +2468,9 @@ function callHooks(currentView, arr, initPhase, currentNodeIndex) {
|
|
|
2450
2468
|
}
|
|
2451
2469
|
else {
|
|
2452
2470
|
const isInitHook = arr[i] < 0;
|
|
2453
|
-
if (isInitHook)
|
|
2471
|
+
if (isInitHook) {
|
|
2454
2472
|
currentView[PREORDER_HOOK_FLAGS] += 65536 /* PreOrderHookFlags.NumberOfInitHooksCalledIncrementer */;
|
|
2473
|
+
}
|
|
2455
2474
|
if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
|
|
2456
2475
|
callHook(currentView, initPhase, arr, i);
|
|
2457
2476
|
currentView[PREORDER_HOOK_FLAGS] =
|
|
@@ -5965,10 +5984,6 @@ function cleanUpView(tView, lView) {
|
|
|
5965
5984
|
function processCleanups(tView, lView) {
|
|
5966
5985
|
const tCleanup = tView.cleanup;
|
|
5967
5986
|
const lCleanup = lView[CLEANUP];
|
|
5968
|
-
// `LCleanup` contains both share information with `TCleanup` as well as instance specific
|
|
5969
|
-
// information appended at the end. We need to know where the end of the `TCleanup` information
|
|
5970
|
-
// is, and we track this with `lastLCleanupIndex`.
|
|
5971
|
-
let lastLCleanupIndex = -1;
|
|
5972
5987
|
if (tCleanup !== null) {
|
|
5973
5988
|
for (let i = 0; i < tCleanup.length - 1; i += 2) {
|
|
5974
5989
|
if (typeof tCleanup[i] === 'string') {
|
|
@@ -5978,29 +5993,33 @@ function processCleanups(tView, lView) {
|
|
|
5978
5993
|
ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
|
|
5979
5994
|
if (targetIdx >= 0) {
|
|
5980
5995
|
// unregister
|
|
5981
|
-
lCleanup[
|
|
5996
|
+
lCleanup[targetIdx]();
|
|
5982
5997
|
}
|
|
5983
5998
|
else {
|
|
5984
5999
|
// Subscription
|
|
5985
|
-
lCleanup[
|
|
6000
|
+
lCleanup[-targetIdx].unsubscribe();
|
|
5986
6001
|
}
|
|
5987
6002
|
i += 2;
|
|
5988
6003
|
}
|
|
5989
6004
|
else {
|
|
5990
6005
|
// This is a cleanup function that is grouped with the index of its context
|
|
5991
|
-
const context = lCleanup[
|
|
6006
|
+
const context = lCleanup[tCleanup[i + 1]];
|
|
5992
6007
|
tCleanup[i].call(context);
|
|
5993
6008
|
}
|
|
5994
6009
|
}
|
|
5995
6010
|
}
|
|
5996
6011
|
if (lCleanup !== null) {
|
|
5997
|
-
for (let i = lastLCleanupIndex + 1; i < lCleanup.length; i++) {
|
|
5998
|
-
const instanceCleanupFn = lCleanup[i];
|
|
5999
|
-
ngDevMode && assertFunction(instanceCleanupFn, 'Expecting instance cleanup function.');
|
|
6000
|
-
instanceCleanupFn();
|
|
6001
|
-
}
|
|
6002
6012
|
lView[CLEANUP] = null;
|
|
6003
6013
|
}
|
|
6014
|
+
const destroyHooks = lView[ON_DESTROY_HOOKS];
|
|
6015
|
+
if (destroyHooks !== null) {
|
|
6016
|
+
for (let i = 0; i < destroyHooks.length; i++) {
|
|
6017
|
+
const destroyHooksFn = destroyHooks[i];
|
|
6018
|
+
ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
|
|
6019
|
+
destroyHooksFn();
|
|
6020
|
+
}
|
|
6021
|
+
lView[ON_DESTROY_HOOKS] = null;
|
|
6022
|
+
}
|
|
6004
6023
|
}
|
|
6005
6024
|
/** Calls onDestroy hooks for this view */
|
|
6006
6025
|
function executeOnDestroys(tView, lView) {
|
|
@@ -6311,6 +6330,17 @@ function nativeRemoveNode(renderer, rNode, isHostElement) {
|
|
|
6311
6330
|
nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
|
|
6312
6331
|
}
|
|
6313
6332
|
}
|
|
6333
|
+
/**
|
|
6334
|
+
* Removes the contents of a given RElement using a given renderer.
|
|
6335
|
+
*
|
|
6336
|
+
* @param renderer A renderer to be used
|
|
6337
|
+
* @param rElement the native RElement to be cleared
|
|
6338
|
+
*/
|
|
6339
|
+
function clearElementContents(renderer, rElement) {
|
|
6340
|
+
while (rElement.firstChild) {
|
|
6341
|
+
nativeRemoveChild(renderer, rElement, rElement.firstChild, false);
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6314
6344
|
/**
|
|
6315
6345
|
* Performs the operation of `action` on the node. Typically this involves inserting or removing
|
|
6316
6346
|
* nodes on the LView or projection boundary.
|
|
@@ -7928,6 +7958,9 @@ class R3Injector extends EnvironmentInjector {
|
|
|
7928
7958
|
}
|
|
7929
7959
|
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
|
|
7930
7960
|
this.assertNotDestroyed();
|
|
7961
|
+
if (token.hasOwnProperty(NG_ENV_ID)) {
|
|
7962
|
+
return token[NG_ENV_ID](this);
|
|
7963
|
+
}
|
|
7931
7964
|
flags = convertToBitFlags(flags);
|
|
7932
7965
|
// Set the injection context.
|
|
7933
7966
|
const previousInjector = setCurrentInjector(this);
|
|
@@ -8205,6 +8238,328 @@ function forEachSingleProvider(providers, fn) {
|
|
|
8205
8238
|
}
|
|
8206
8239
|
}
|
|
8207
8240
|
|
|
8241
|
+
/**
|
|
8242
|
+
* A [DI token](guide/glossary#di-token "DI token definition") representing a unique string ID, used
|
|
8243
|
+
* primarily for prefixing application attributes and CSS styles when
|
|
8244
|
+
* {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
|
|
8245
|
+
*
|
|
8246
|
+
* BY default, the value is randomly generated and assigned to the application by Angular.
|
|
8247
|
+
* To provide a custom ID value, use a DI provider <!-- TODO: provider --> to configure
|
|
8248
|
+
* the root {@link Injector} that uses this token.
|
|
8249
|
+
*
|
|
8250
|
+
* @publicApi
|
|
8251
|
+
*/
|
|
8252
|
+
const APP_ID = new InjectionToken('AppId', {
|
|
8253
|
+
providedIn: 'root',
|
|
8254
|
+
factory: _appIdRandomProviderFactory,
|
|
8255
|
+
});
|
|
8256
|
+
function _appIdRandomProviderFactory() {
|
|
8257
|
+
return `${_randomChar()}${_randomChar()}${_randomChar()}`;
|
|
8258
|
+
}
|
|
8259
|
+
/**
|
|
8260
|
+
* Providers that generate a random `APP_ID_TOKEN`.
|
|
8261
|
+
* @publicApi
|
|
8262
|
+
*/
|
|
8263
|
+
const APP_ID_RANDOM_PROVIDER = {
|
|
8264
|
+
provide: APP_ID,
|
|
8265
|
+
useFactory: _appIdRandomProviderFactory,
|
|
8266
|
+
deps: [],
|
|
8267
|
+
};
|
|
8268
|
+
function _randomChar() {
|
|
8269
|
+
return String.fromCharCode(97 + Math.floor(Math.random() * 25));
|
|
8270
|
+
}
|
|
8271
|
+
/**
|
|
8272
|
+
* A function that is executed when a platform is initialized.
|
|
8273
|
+
* @publicApi
|
|
8274
|
+
*/
|
|
8275
|
+
const PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
|
|
8276
|
+
/**
|
|
8277
|
+
* A token that indicates an opaque platform ID.
|
|
8278
|
+
* @publicApi
|
|
8279
|
+
*/
|
|
8280
|
+
const PLATFORM_ID = new InjectionToken('Platform ID', {
|
|
8281
|
+
providedIn: 'platform',
|
|
8282
|
+
factory: () => 'unknown', // set a default platform name, when none set explicitly
|
|
8283
|
+
});
|
|
8284
|
+
/**
|
|
8285
|
+
* A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
|
|
8286
|
+
* the application
|
|
8287
|
+
* @publicApi
|
|
8288
|
+
*/
|
|
8289
|
+
const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
|
|
8290
|
+
// We keep this token here, rather than the animations package, so that modules that only care
|
|
8291
|
+
// about which animations module is loaded (e.g. the CDK) can retrieve it without having to
|
|
8292
|
+
// include extra dependencies. See #44970 for more context.
|
|
8293
|
+
/**
|
|
8294
|
+
* A [DI token](guide/glossary#di-token "DI token definition") that indicates which animations
|
|
8295
|
+
* module has been loaded.
|
|
8296
|
+
* @publicApi
|
|
8297
|
+
*/
|
|
8298
|
+
const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
|
|
8299
|
+
|
|
8300
|
+
function escapeTransferStateContent(text) {
|
|
8301
|
+
const escapedText = {
|
|
8302
|
+
'&': '&a;',
|
|
8303
|
+
'"': '&q;',
|
|
8304
|
+
'\'': '&s;',
|
|
8305
|
+
'<': '&l;',
|
|
8306
|
+
'>': '&g;',
|
|
8307
|
+
};
|
|
8308
|
+
return text.replace(/[&"'<>]/g, s => escapedText[s]);
|
|
8309
|
+
}
|
|
8310
|
+
function unescapeTransferStateContent(text) {
|
|
8311
|
+
const unescapedText = {
|
|
8312
|
+
'&a;': '&',
|
|
8313
|
+
'&q;': '"',
|
|
8314
|
+
'&s;': '\'',
|
|
8315
|
+
'&l;': '<',
|
|
8316
|
+
'&g;': '>',
|
|
8317
|
+
};
|
|
8318
|
+
return text.replace(/&[^;]+;/g, s => unescapedText[s]);
|
|
8319
|
+
}
|
|
8320
|
+
/**
|
|
8321
|
+
* Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
|
|
8322
|
+
*
|
|
8323
|
+
* Example:
|
|
8324
|
+
*
|
|
8325
|
+
* ```
|
|
8326
|
+
* const COUNTER_KEY = makeStateKey<number>('counter');
|
|
8327
|
+
* let value = 10;
|
|
8328
|
+
*
|
|
8329
|
+
* transferState.set(COUNTER_KEY, value);
|
|
8330
|
+
* ```
|
|
8331
|
+
*
|
|
8332
|
+
* @publicApi
|
|
8333
|
+
*/
|
|
8334
|
+
function makeStateKey(key) {
|
|
8335
|
+
return key;
|
|
8336
|
+
}
|
|
8337
|
+
function initTransferState() {
|
|
8338
|
+
const transferState = new TransferState();
|
|
8339
|
+
transferState.store = retrieveTransferredState(getDocument(), inject(APP_ID));
|
|
8340
|
+
return transferState;
|
|
8341
|
+
}
|
|
8342
|
+
/**
|
|
8343
|
+
* A key value store that is transferred from the application on the server side to the application
|
|
8344
|
+
* on the client side.
|
|
8345
|
+
*
|
|
8346
|
+
* The `TransferState` is available as an injectable token.
|
|
8347
|
+
* On the client, just inject this token using DI and use it, it will be lazily initialized.
|
|
8348
|
+
* On the server it's already included if `renderApplication` function is used. Otherwise, import
|
|
8349
|
+
* the `ServerTransferStateModule` module to make the `TransferState` available.
|
|
8350
|
+
*
|
|
8351
|
+
* The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only
|
|
8352
|
+
* boolean, number, string, null and non-class objects will be serialized and deserialized in a
|
|
8353
|
+
* non-lossy manner.
|
|
8354
|
+
*
|
|
8355
|
+
* @publicApi
|
|
8356
|
+
*/
|
|
8357
|
+
class TransferState {
|
|
8358
|
+
constructor() {
|
|
8359
|
+
/** @internal */
|
|
8360
|
+
this.store = {};
|
|
8361
|
+
this.onSerializeCallbacks = {};
|
|
8362
|
+
}
|
|
8363
|
+
/**
|
|
8364
|
+
* Get the value corresponding to a key. Return `defaultValue` if key is not found.
|
|
8365
|
+
*/
|
|
8366
|
+
get(key, defaultValue) {
|
|
8367
|
+
return this.store[key] !== undefined ? this.store[key] : defaultValue;
|
|
8368
|
+
}
|
|
8369
|
+
/**
|
|
8370
|
+
* Set the value corresponding to a key.
|
|
8371
|
+
*/
|
|
8372
|
+
set(key, value) {
|
|
8373
|
+
this.store[key] = value;
|
|
8374
|
+
}
|
|
8375
|
+
/**
|
|
8376
|
+
* Remove a key from the store.
|
|
8377
|
+
*/
|
|
8378
|
+
remove(key) {
|
|
8379
|
+
delete this.store[key];
|
|
8380
|
+
}
|
|
8381
|
+
/**
|
|
8382
|
+
* Test whether a key exists in the store.
|
|
8383
|
+
*/
|
|
8384
|
+
hasKey(key) {
|
|
8385
|
+
return this.store.hasOwnProperty(key);
|
|
8386
|
+
}
|
|
8387
|
+
/**
|
|
8388
|
+
* Indicates whether the state is empty.
|
|
8389
|
+
*/
|
|
8390
|
+
get isEmpty() {
|
|
8391
|
+
return Object.keys(this.store).length === 0;
|
|
8392
|
+
}
|
|
8393
|
+
/**
|
|
8394
|
+
* Register a callback to provide the value for a key when `toJson` is called.
|
|
8395
|
+
*/
|
|
8396
|
+
onSerialize(key, callback) {
|
|
8397
|
+
this.onSerializeCallbacks[key] = callback;
|
|
8398
|
+
}
|
|
8399
|
+
/**
|
|
8400
|
+
* Serialize the current state of the store to JSON.
|
|
8401
|
+
*/
|
|
8402
|
+
toJson() {
|
|
8403
|
+
// Call the onSerialize callbacks and put those values into the store.
|
|
8404
|
+
for (const key in this.onSerializeCallbacks) {
|
|
8405
|
+
if (this.onSerializeCallbacks.hasOwnProperty(key)) {
|
|
8406
|
+
try {
|
|
8407
|
+
this.store[key] = this.onSerializeCallbacks[key]();
|
|
8408
|
+
}
|
|
8409
|
+
catch (e) {
|
|
8410
|
+
console.warn('Exception in onSerialize callback: ', e);
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
}
|
|
8414
|
+
return JSON.stringify(this.store);
|
|
8415
|
+
}
|
|
8416
|
+
}
|
|
8417
|
+
/** @nocollapse */
|
|
8418
|
+
TransferState.ɵprov =
|
|
8419
|
+
/** @pureOrBreakMyCode */ ɵɵdefineInjectable({
|
|
8420
|
+
token: TransferState,
|
|
8421
|
+
providedIn: 'root',
|
|
8422
|
+
factory: initTransferState,
|
|
8423
|
+
});
|
|
8424
|
+
function retrieveTransferredState(doc, appId) {
|
|
8425
|
+
// Locate the script tag with the JSON data transferred from the server.
|
|
8426
|
+
// The id of the script tag is set to the Angular appId + 'state'.
|
|
8427
|
+
const script = doc.getElementById(appId + '-state');
|
|
8428
|
+
let initialState = {};
|
|
8429
|
+
if (script && script.textContent) {
|
|
8430
|
+
try {
|
|
8431
|
+
// Avoid using any here as it triggers lint errors in google3 (any is not allowed).
|
|
8432
|
+
initialState = JSON.parse(unescapeTransferStateContent(script.textContent));
|
|
8433
|
+
}
|
|
8434
|
+
catch (e) {
|
|
8435
|
+
console.warn('Exception while restoring TransferState for app ' + appId, e);
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8438
|
+
return initialState;
|
|
8439
|
+
}
|
|
8440
|
+
|
|
8441
|
+
/* Represents a key in NghDom that holds information about <ng-container>s. */
|
|
8442
|
+
const ELEMENT_CONTAINERS = 'e';
|
|
8443
|
+
|
|
8444
|
+
/**
|
|
8445
|
+
* The name of the key used in the TransferState collection,
|
|
8446
|
+
* where hydration information is located.
|
|
8447
|
+
*/
|
|
8448
|
+
const TRANSFER_STATE_TOKEN_ID = '__ɵnghData__';
|
|
8449
|
+
/**
|
|
8450
|
+
* Lookup key used to reference DOM hydration data (ngh) in `TransferState`.
|
|
8451
|
+
*/
|
|
8452
|
+
const NGH_DATA_KEY = makeStateKey(TRANSFER_STATE_TOKEN_ID);
|
|
8453
|
+
/**
|
|
8454
|
+
* The name of the attribute that would be added to host component
|
|
8455
|
+
* nodes and contain a reference to a particular slot in transferred
|
|
8456
|
+
* state that contains the necessary hydration info for this component.
|
|
8457
|
+
*/
|
|
8458
|
+
const NGH_ATTR_NAME = 'ngh';
|
|
8459
|
+
/**
|
|
8460
|
+
* Reference to a function that reads `ngh` attribute value from a given RNode
|
|
8461
|
+
* and retrieves hydration information from the TransferState using that value
|
|
8462
|
+
* as an index. Returns `null` by default, when hydration is not enabled.
|
|
8463
|
+
*
|
|
8464
|
+
* @param rNode Component's host element.
|
|
8465
|
+
* @param injector Injector that this component has access to.
|
|
8466
|
+
*/
|
|
8467
|
+
let _retrieveHydrationInfoImpl = (rNode, injector) => null;
|
|
8468
|
+
function retrieveHydrationInfoImpl(rNode, injector) {
|
|
8469
|
+
const nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
|
|
8470
|
+
if (nghAttrValue == null)
|
|
8471
|
+
return null;
|
|
8472
|
+
let data = {};
|
|
8473
|
+
// An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
|
|
8474
|
+
// which means that no special annotations are required. Do not attempt to read
|
|
8475
|
+
// from the TransferState in this case.
|
|
8476
|
+
if (nghAttrValue !== '') {
|
|
8477
|
+
const transferState = injector.get(TransferState, null, { optional: true });
|
|
8478
|
+
if (transferState !== null) {
|
|
8479
|
+
const nghData = transferState.get(NGH_DATA_KEY, []);
|
|
8480
|
+
// The nghAttrValue is always a number referencing an index
|
|
8481
|
+
// in the hydration TransferState data.
|
|
8482
|
+
data = nghData[Number(nghAttrValue)];
|
|
8483
|
+
// If the `ngh` attribute exists and has a non-empty value,
|
|
8484
|
+
// the hydration info *must* be present in the TransferState.
|
|
8485
|
+
// If there is no data for some reasons, this is an error.
|
|
8486
|
+
ngDevMode && assertDefined(data, 'Unable to retrieve hydration info from the TransferState.');
|
|
8487
|
+
}
|
|
8488
|
+
}
|
|
8489
|
+
const dehydratedView = {
|
|
8490
|
+
data,
|
|
8491
|
+
firstChild: rNode.firstChild ?? null,
|
|
8492
|
+
};
|
|
8493
|
+
// The `ngh` attribute is cleared from the DOM node now
|
|
8494
|
+
// that the data has been retrieved.
|
|
8495
|
+
rNode.removeAttribute(NGH_ATTR_NAME);
|
|
8496
|
+
// Note: don't check whether this node was claimed for hydration,
|
|
8497
|
+
// because this node might've been previously claimed while processing
|
|
8498
|
+
// template instructions.
|
|
8499
|
+
ngDevMode && markRNodeAsClaimedByHydration(rNode, /* checkIfAlreadyClaimed */ false);
|
|
8500
|
+
ngDevMode && ngDevMode.hydratedComponents++;
|
|
8501
|
+
return dehydratedView;
|
|
8502
|
+
}
|
|
8503
|
+
/**
|
|
8504
|
+
* Sets the implementation for the `retrieveNghInfo` function.
|
|
8505
|
+
*/
|
|
8506
|
+
function enableRetrieveHydrationInfoImpl() {
|
|
8507
|
+
_retrieveHydrationInfoImpl = retrieveHydrationInfoImpl;
|
|
8508
|
+
}
|
|
8509
|
+
/**
|
|
8510
|
+
* Retrieves hydration info by reading the value from the `ngh` attribute
|
|
8511
|
+
* and accessing a corresponding slot in TransferState storage.
|
|
8512
|
+
*/
|
|
8513
|
+
function retrieveHydrationInfo(rNode, injector) {
|
|
8514
|
+
return _retrieveHydrationInfoImpl(rNode, injector);
|
|
8515
|
+
}
|
|
8516
|
+
/**
|
|
8517
|
+
* Retrieves an instance of a component LView from a given ViewRef.
|
|
8518
|
+
* Returns an instance of a component LView or `null` in case of an embedded view.
|
|
8519
|
+
*/
|
|
8520
|
+
function getComponentLViewForHydration(viewRef) {
|
|
8521
|
+
// Reading an internal field from `ViewRef` instance.
|
|
8522
|
+
let lView = viewRef._lView;
|
|
8523
|
+
const tView = lView[TVIEW];
|
|
8524
|
+
// A registered ViewRef might represent an instance of an
|
|
8525
|
+
// embedded view, in which case we do not need to annotate it.
|
|
8526
|
+
if (tView.type === 2 /* TViewType.Embedded */) {
|
|
8527
|
+
return null;
|
|
8528
|
+
}
|
|
8529
|
+
// Check if it's a root view and if so, retrieve component's
|
|
8530
|
+
// LView from the first slot after the header.
|
|
8531
|
+
if (isRootView(lView)) {
|
|
8532
|
+
lView = lView[HEADER_OFFSET];
|
|
8533
|
+
}
|
|
8534
|
+
return lView;
|
|
8535
|
+
}
|
|
8536
|
+
/**
|
|
8537
|
+
* Marks a node as "claimed" by hydration process.
|
|
8538
|
+
* This is needed to make assessments in tests whether
|
|
8539
|
+
* the hydration process handled all nodes.
|
|
8540
|
+
*/
|
|
8541
|
+
function markRNodeAsClaimedByHydration(node, checkIfAlreadyClaimed = true) {
|
|
8542
|
+
if (!ngDevMode) {
|
|
8543
|
+
throw new Error('Calling `markRNodeAsClaimedByHydration` in prod mode ' +
|
|
8544
|
+
'is not supported and likely a mistake.');
|
|
8545
|
+
}
|
|
8546
|
+
if (checkIfAlreadyClaimed && isRNodeClaimedForHydration(node)) {
|
|
8547
|
+
throw new Error('Trying to claim a node, which was claimed already.');
|
|
8548
|
+
}
|
|
8549
|
+
node.__claimed = true;
|
|
8550
|
+
ngDevMode.hydratedNodes++;
|
|
8551
|
+
}
|
|
8552
|
+
function isRNodeClaimedForHydration(node) {
|
|
8553
|
+
return !!node.__claimed;
|
|
8554
|
+
}
|
|
8555
|
+
function storeNgContainerInfo(hydrationInfo, index, firstChild) {
|
|
8556
|
+
hydrationInfo.ngContainers ?? (hydrationInfo.ngContainers = {});
|
|
8557
|
+
hydrationInfo.ngContainers[index] = { firstChild };
|
|
8558
|
+
}
|
|
8559
|
+
function getNgContainerSize(hydrationInfo, index) {
|
|
8560
|
+
return hydrationInfo.data[ELEMENT_CONTAINERS]?.[index] ?? null;
|
|
8561
|
+
}
|
|
8562
|
+
|
|
8208
8563
|
/**
|
|
8209
8564
|
* Represents a component created by a `ComponentFactory`.
|
|
8210
8565
|
* Provides access to the component instance and related objects,
|
|
@@ -8384,7 +8739,7 @@ class Version {
|
|
|
8384
8739
|
/**
|
|
8385
8740
|
* @publicApi
|
|
8386
8741
|
*/
|
|
8387
|
-
const VERSION = new Version('16.0.0-next.
|
|
8742
|
+
const VERSION = new Version('16.0.0-next.2');
|
|
8388
8743
|
|
|
8389
8744
|
// This default value is when checking the hierarchy for a token.
|
|
8390
8745
|
//
|
|
@@ -8465,6 +8820,23 @@ class ErrorHandler {
|
|
|
8465
8820
|
}
|
|
8466
8821
|
}
|
|
8467
8822
|
|
|
8823
|
+
const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
8824
|
+
/**
|
|
8825
|
+
* Internal token that specifies whether hydration is enabled.
|
|
8826
|
+
*/
|
|
8827
|
+
const IS_HYDRATION_FEATURE_ENABLED = new InjectionToken(NG_DEV_MODE$1 ? 'IS_HYDRATION_FEATURE_ENABLED' : '');
|
|
8828
|
+
// By default (in client rendering mode), we remove all the contents
|
|
8829
|
+
// of the host element and render an application after that.
|
|
8830
|
+
const PRESERVE_HOST_CONTENT_DEFAULT = false;
|
|
8831
|
+
/**
|
|
8832
|
+
* Internal token that indicates whether host element content should be
|
|
8833
|
+
* retained during the bootstrap.
|
|
8834
|
+
*/
|
|
8835
|
+
const PRESERVE_HOST_CONTENT = new InjectionToken(NG_DEV_MODE$1 ? 'PRESERVE_HOST_CONTENT' : '', {
|
|
8836
|
+
providedIn: 'root',
|
|
8837
|
+
factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
|
|
8838
|
+
});
|
|
8839
|
+
|
|
8468
8840
|
function normalizeDebugBindingName(name) {
|
|
8469
8841
|
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
8470
8842
|
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
@@ -10163,7 +10535,7 @@ function renderChildComponents(hostLView, components) {
|
|
|
10163
10535
|
renderComponent(hostLView, components[i]);
|
|
10164
10536
|
}
|
|
10165
10537
|
}
|
|
10166
|
-
function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
|
|
10538
|
+
function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector, hydrationInfo) {
|
|
10167
10539
|
const lView = tView.blueprint.slice();
|
|
10168
10540
|
lView[HOST] = host;
|
|
10169
10541
|
lView[FLAGS] = flags | 4 /* LViewFlags.CreationMode */ | 64 /* LViewFlags.Attached */ | 8 /* LViewFlags.FirstLViewPass */;
|
|
@@ -10183,6 +10555,7 @@ function createLView(parentLView, tView, context, flags, host, tHostNode, render
|
|
|
10183
10555
|
lView[INJECTOR$1] = injector || parentLView && parentLView[INJECTOR$1] || null;
|
|
10184
10556
|
lView[T_HOST] = tHostNode;
|
|
10185
10557
|
lView[ID] = getUniqueLViewId();
|
|
10558
|
+
lView[HYDRATION] = hydrationInfo;
|
|
10186
10559
|
lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
|
|
10187
10560
|
ngDevMode &&
|
|
10188
10561
|
assertEqual(tView.type == 2 /* TViewType.Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
|
|
@@ -10245,6 +10618,7 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
|
|
|
10245
10618
|
// In the case of i18n the `currentTNode` may already be linked, in which case we don't want
|
|
10246
10619
|
// to break the links which i18n created.
|
|
10247
10620
|
currentTNode.next = tNode;
|
|
10621
|
+
tNode.prev = currentTNode;
|
|
10248
10622
|
}
|
|
10249
10623
|
}
|
|
10250
10624
|
}
|
|
@@ -10623,10 +10997,19 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
|
|
|
10623
10997
|
* @param rendererFactory Factory function to create renderer instance.
|
|
10624
10998
|
* @param elementOrSelector Render element or CSS selector to locate the element.
|
|
10625
10999
|
* @param encapsulation View Encapsulation defined for component that requests host element.
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
11000
|
+
* @param injector Root view injector instance.
|
|
11001
|
+
*/
|
|
11002
|
+
function locateHostElement(renderer, elementOrSelector, encapsulation, injector) {
|
|
11003
|
+
// Note: we use default value for the `PRESERVE_HOST_CONTENT` here even though it's a
|
|
11004
|
+
// tree-shakable one (providedIn:'root'). This code path can be triggered during dynamic component
|
|
11005
|
+
// creation (after calling ViewContainerRef.createComponent) when an injector instance can be
|
|
11006
|
+
// provided. The injector instance might be disconnected from the main DI tree, thus the
|
|
11007
|
+
// `PRESERVE_HOST_CONTENT` woild not be able to instantiate. In this case, the default value will
|
|
11008
|
+
// be used.
|
|
11009
|
+
const preserveHostContent = injector.get(PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT);
|
|
11010
|
+
// When using native Shadow DOM, do not clear host element to allow native slot
|
|
11011
|
+
// projection.
|
|
11012
|
+
const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation$1.ShadowDom;
|
|
10630
11013
|
return renderer.selectRootElement(elementOrSelector, preserveContent);
|
|
10631
11014
|
}
|
|
10632
11015
|
/**
|
|
@@ -10635,24 +11018,24 @@ function locateHostElement(renderer, elementOrSelector, encapsulation) {
|
|
|
10635
11018
|
* On the first template pass, saves in TView:
|
|
10636
11019
|
* - Cleanup function
|
|
10637
11020
|
* - Index of context we just saved in LView.cleanupInstances
|
|
10638
|
-
*
|
|
10639
|
-
* This function can also be used to store instance specific cleanup fns. In that case the `context`
|
|
10640
|
-
* is `null` and the function is store in `LView` (rather than it `TView`).
|
|
10641
11021
|
*/
|
|
10642
11022
|
function storeCleanupWithContext(tView, lView, context, cleanupFn) {
|
|
10643
11023
|
const lCleanup = getOrCreateLViewCleanup(lView);
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
11024
|
+
// Historically the `storeCleanupWithContext` was used to register both framework-level and
|
|
11025
|
+
// user-defined cleanup callbacks, but over time those two types of cleanups were separated. This
|
|
11026
|
+
// dev mode checks assures that user-level cleanup callbacks are _not_ stored in data structures
|
|
11027
|
+
// reserved for framework-specific hooks.
|
|
11028
|
+
ngDevMode &&
|
|
11029
|
+
assertDefined(context, 'Cleanup context is mandatory when registering framework-level destroy hooks');
|
|
11030
|
+
lCleanup.push(context);
|
|
11031
|
+
if (tView.firstCreatePass) {
|
|
11032
|
+
getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
|
|
10651
11033
|
}
|
|
10652
11034
|
else {
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
11035
|
+
// Make sure that no new framework-level cleanup functions are registered after the first
|
|
11036
|
+
// template pass is done (and TView data structures are meant to fully constructed).
|
|
11037
|
+
if (ngDevMode) {
|
|
11038
|
+
Object.freeze(getOrCreateTViewCleanup(tView));
|
|
10656
11039
|
}
|
|
10657
11040
|
}
|
|
10658
11041
|
}
|
|
@@ -10683,8 +11066,9 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
10683
11066
|
initialInputs: undefined,
|
|
10684
11067
|
inputs: null,
|
|
10685
11068
|
outputs: null,
|
|
10686
|
-
|
|
11069
|
+
tView: null,
|
|
10687
11070
|
next: null,
|
|
11071
|
+
prev: null,
|
|
10688
11072
|
projectionNext: null,
|
|
10689
11073
|
child: null,
|
|
10690
11074
|
parent: tParent,
|
|
@@ -10894,7 +11278,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
10894
11278
|
// Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
|
|
10895
11279
|
// tsickle.
|
|
10896
11280
|
ngDevMode && assertFirstCreatePass(tView);
|
|
10897
|
-
let hasDirectives = false;
|
|
10898
11281
|
if (getBindingsEnabled()) {
|
|
10899
11282
|
const exportsMap = localRefs === null ? null : { '': -1 };
|
|
10900
11283
|
const matchResult = findDirectiveDefMatches(tView, tNode);
|
|
@@ -10907,7 +11290,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
10907
11290
|
[directiveDefs, hostDirectiveDefs] = matchResult;
|
|
10908
11291
|
}
|
|
10909
11292
|
if (directiveDefs !== null) {
|
|
10910
|
-
hasDirectives = true;
|
|
10911
11293
|
initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
|
|
10912
11294
|
}
|
|
10913
11295
|
if (exportsMap)
|
|
@@ -10915,7 +11297,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
10915
11297
|
}
|
|
10916
11298
|
// Merge the template attrs last so that they have the highest priority.
|
|
10917
11299
|
tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
|
|
10918
|
-
return hasDirectives;
|
|
10919
11300
|
}
|
|
10920
11301
|
/** Initializes the data structures necessary for a list of directives to be instantiated. */
|
|
10921
11302
|
function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
|
|
@@ -11228,7 +11609,7 @@ function addComponentLogic(lView, hostTNode, def) {
|
|
|
11228
11609
|
// Only component views should be added to the view tree directly. Embedded views are
|
|
11229
11610
|
// accessed through their containers because they may be removed / re-added later.
|
|
11230
11611
|
const rendererFactory = lView[RENDERER_FACTORY];
|
|
11231
|
-
const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null, null));
|
|
11612
|
+
const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null, null, null));
|
|
11232
11613
|
// Component view will always be created before any injected LContainers,
|
|
11233
11614
|
// so this is a regular element, wrap it with the component view
|
|
11234
11615
|
lView[hostTNode.index] = componentView;
|
|
@@ -11473,6 +11854,11 @@ function renderComponent(hostLView, componentHostIdx) {
|
|
|
11473
11854
|
const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
|
|
11474
11855
|
const componentTView = componentView[TVIEW];
|
|
11475
11856
|
syncViewWithBlueprint(componentTView, componentView);
|
|
11857
|
+
const hostRNode = componentView[HOST];
|
|
11858
|
+
// Populate an LView with hydration info retrieved from the DOM via TransferState.
|
|
11859
|
+
if (hostRNode !== null && componentView[HYDRATION] === null) {
|
|
11860
|
+
componentView[HYDRATION] = retrieveHydrationInfo(hostRNode, componentView[INJECTOR$1]);
|
|
11861
|
+
}
|
|
11476
11862
|
renderView(componentTView, componentView, componentView[CONTEXT]);
|
|
11477
11863
|
}
|
|
11478
11864
|
/**
|
|
@@ -11846,7 +12232,7 @@ class ViewRef$1 {
|
|
|
11846
12232
|
destroyLView(this._lView[TVIEW], this._lView);
|
|
11847
12233
|
}
|
|
11848
12234
|
onDestroy(callback) {
|
|
11849
|
-
|
|
12235
|
+
storeLViewOnDestroy(this._lView, callback);
|
|
11850
12236
|
}
|
|
11851
12237
|
/**
|
|
11852
12238
|
* Marks a view and all of its ancestors dirty.
|
|
@@ -12173,13 +12559,13 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
12173
12559
|
// dynamically. Default to 'div' if this component did not specify any tag name in its selector.
|
|
12174
12560
|
const elementName = this.componentDef.selectors[0][0] || 'div';
|
|
12175
12561
|
const hostRNode = rootSelectorOrNode ?
|
|
12176
|
-
locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
|
|
12562
|
+
locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation, rootViewInjector) :
|
|
12177
12563
|
createElementNode(hostRenderer, elementName, getNamespace(elementName));
|
|
12178
12564
|
const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
|
|
12179
12565
|
16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
|
|
12180
12566
|
// Create the root view. Uses empty TView and ContentTemplate.
|
|
12181
12567
|
const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
|
|
12182
|
-
const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
|
|
12568
|
+
const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null, null);
|
|
12183
12569
|
// rootView is the parent when bootstrapping
|
|
12184
12570
|
// TODO(misko): it looks like we are entering view here but we don't really need to as
|
|
12185
12571
|
// `renderView` does that. However as the code is written it is needed because
|
|
@@ -12290,7 +12676,7 @@ function createRootComponentTNode(lView, rNode) {
|
|
|
12290
12676
|
/**
|
|
12291
12677
|
* Creates the root component view and the root component node.
|
|
12292
12678
|
*
|
|
12293
|
-
* @param
|
|
12679
|
+
* @param hostRNode Render host element.
|
|
12294
12680
|
* @param rootComponentDef ComponentDef
|
|
12295
12681
|
* @param rootView The parent view where the host node is stored
|
|
12296
12682
|
* @param rendererFactory Factory to be used for creating child renderers.
|
|
@@ -12299,11 +12685,17 @@ function createRootComponentTNode(lView, rNode) {
|
|
|
12299
12685
|
*
|
|
12300
12686
|
* @returns Component view created
|
|
12301
12687
|
*/
|
|
12302
|
-
function createRootComponentView(tNode,
|
|
12688
|
+
function createRootComponentView(tNode, hostRNode, rootComponentDef, rootDirectives, rootView, rendererFactory, hostRenderer, sanitizer) {
|
|
12303
12689
|
const tView = rootView[TVIEW];
|
|
12304
|
-
applyRootComponentStyling(rootDirectives, tNode,
|
|
12305
|
-
|
|
12306
|
-
|
|
12690
|
+
applyRootComponentStyling(rootDirectives, tNode, hostRNode, hostRenderer);
|
|
12691
|
+
// Hydration info is on the host element and needs to be retreived
|
|
12692
|
+
// and passed to the component LView.
|
|
12693
|
+
let hydrationInfo = null;
|
|
12694
|
+
if (hostRNode !== null) {
|
|
12695
|
+
hydrationInfo = retrieveHydrationInfo(hostRNode, rootView[INJECTOR$1]);
|
|
12696
|
+
}
|
|
12697
|
+
const viewRenderer = rendererFactory.createRenderer(hostRNode, rootComponentDef);
|
|
12698
|
+
const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, rootComponentDef.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[tNode.index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null, hydrationInfo);
|
|
12307
12699
|
if (tView.firstCreatePass) {
|
|
12308
12700
|
markAsComponentHost(tView, tNode, rootDirectives.length - 1);
|
|
12309
12701
|
}
|
|
@@ -12781,41 +13173,19 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
|
|
|
12781
13173
|
}
|
|
12782
13174
|
}
|
|
12783
13175
|
|
|
12784
|
-
let _symbolIterator = null;
|
|
12785
|
-
function getSymbolIterator() {
|
|
12786
|
-
if (!_symbolIterator) {
|
|
12787
|
-
const Symbol = _global['Symbol'];
|
|
12788
|
-
if (Symbol && Symbol.iterator) {
|
|
12789
|
-
_symbolIterator = Symbol.iterator;
|
|
12790
|
-
}
|
|
12791
|
-
else {
|
|
12792
|
-
// es6-shim specific logic
|
|
12793
|
-
const keys = Object.getOwnPropertyNames(Map.prototype);
|
|
12794
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
12795
|
-
const key = keys[i];
|
|
12796
|
-
if (key !== 'entries' && key !== 'size' &&
|
|
12797
|
-
Map.prototype[key] === Map.prototype['entries']) {
|
|
12798
|
-
_symbolIterator = key;
|
|
12799
|
-
}
|
|
12800
|
-
}
|
|
12801
|
-
}
|
|
12802
|
-
}
|
|
12803
|
-
return _symbolIterator;
|
|
12804
|
-
}
|
|
12805
|
-
|
|
12806
13176
|
function isIterable(obj) {
|
|
12807
|
-
return obj !== null && typeof obj === 'object' && obj[
|
|
13177
|
+
return obj !== null && typeof obj === 'object' && obj[Symbol.iterator] !== undefined;
|
|
12808
13178
|
}
|
|
12809
13179
|
function isListLikeIterable(obj) {
|
|
12810
13180
|
if (!isJsObject(obj))
|
|
12811
13181
|
return false;
|
|
12812
13182
|
return Array.isArray(obj) ||
|
|
12813
13183
|
(!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
|
|
12814
|
-
|
|
13184
|
+
Symbol.iterator in obj); // JS Iterable have a Symbol.iterator prop
|
|
12815
13185
|
}
|
|
12816
13186
|
function areIterablesEqual(a, b, comparator) {
|
|
12817
|
-
const iterator1 = a[
|
|
12818
|
-
const iterator2 = b[
|
|
13187
|
+
const iterator1 = a[Symbol.iterator]();
|
|
13188
|
+
const iterator2 = b[Symbol.iterator]();
|
|
12819
13189
|
while (true) {
|
|
12820
13190
|
const item1 = iterator1.next();
|
|
12821
13191
|
const item2 = iterator2.next();
|
|
@@ -12834,7 +13204,7 @@ function iterateListLike(obj, fn) {
|
|
|
12834
13204
|
}
|
|
12835
13205
|
}
|
|
12836
13206
|
else {
|
|
12837
|
-
const iterator = obj[
|
|
13207
|
+
const iterator = obj[Symbol.iterator]();
|
|
12838
13208
|
let item;
|
|
12839
13209
|
while (!((item = iterator.next()).done)) {
|
|
12840
13210
|
fn(item.value);
|
|
@@ -13487,7 +13857,7 @@ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, t
|
|
|
13487
13857
|
const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
|
|
13488
13858
|
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
|
|
13489
13859
|
registerPostOrderHooks(tView, tNode);
|
|
13490
|
-
const embeddedTView = tNode.
|
|
13860
|
+
const embeddedTView = tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
|
|
13491
13861
|
if (tView.queries !== null) {
|
|
13492
13862
|
tView.queries.template(tView, tNode);
|
|
13493
13863
|
embeddedTView.queries = tView.queries.embeddedTView(tNode);
|
|
@@ -13557,6 +13927,119 @@ function ɵɵreference(index) {
|
|
|
13557
13927
|
return load(contextLView, HEADER_OFFSET + index);
|
|
13558
13928
|
}
|
|
13559
13929
|
|
|
13930
|
+
/**
|
|
13931
|
+
* Verifies whether a given node matches an expected criteria,
|
|
13932
|
+
* based on internal data structure state.
|
|
13933
|
+
*/
|
|
13934
|
+
function validateMatchingNode(node, nodeType, tagName, lView, tNode) {
|
|
13935
|
+
if (node.nodeType !== nodeType ||
|
|
13936
|
+
(node.nodeType === Node.ELEMENT_NODE &&
|
|
13937
|
+
node.tagName.toLowerCase() !== tagName?.toLowerCase())) {
|
|
13938
|
+
// TODO: improve error message and use RuntimeError instead.
|
|
13939
|
+
throw new Error(`Unexpected node found during hydration.`);
|
|
13940
|
+
}
|
|
13941
|
+
}
|
|
13942
|
+
/**
|
|
13943
|
+
* Verifies whether next sibling node exists.
|
|
13944
|
+
*/
|
|
13945
|
+
function validateSiblingNodeExists(node) {
|
|
13946
|
+
if (!node.nextSibling) {
|
|
13947
|
+
// TODO: improve error message and use RuntimeError instead.
|
|
13948
|
+
throw new Error(`Unexpected state: insufficient number of sibling nodes.`);
|
|
13949
|
+
}
|
|
13950
|
+
}
|
|
13951
|
+
|
|
13952
|
+
/** Whether current TNode is a first node in an <ng-container>. */
|
|
13953
|
+
function isFirstElementInNgContainer(tNode) {
|
|
13954
|
+
return !tNode.prev && tNode.parent?.type === 8 /* TNodeType.ElementContainer */;
|
|
13955
|
+
}
|
|
13956
|
+
/** Returns first element from a DOM segment that corresponds to this <ng-container>. */
|
|
13957
|
+
function getDehydratedNgContainer(hydrationInfo, tContainerNode) {
|
|
13958
|
+
const noOffsetIndex = tContainerNode.index - HEADER_OFFSET;
|
|
13959
|
+
const ngContainer = hydrationInfo.ngContainers?.[noOffsetIndex];
|
|
13960
|
+
ngDevMode &&
|
|
13961
|
+
assertDefined(ngContainer, 'Unexpected state: no hydration info available for a given TNode, ' +
|
|
13962
|
+
'which represents an element container.');
|
|
13963
|
+
return ngContainer;
|
|
13964
|
+
}
|
|
13965
|
+
/**
|
|
13966
|
+
* Locate a node in DOM tree that corresponds to a given TNode.
|
|
13967
|
+
*
|
|
13968
|
+
* @param hydrationInfo The hydration annotation data
|
|
13969
|
+
* @param tView the current tView
|
|
13970
|
+
* @param lView the current lView
|
|
13971
|
+
* @param tNode the current tNode
|
|
13972
|
+
* @returns an RNode that represents a given tNode
|
|
13973
|
+
*/
|
|
13974
|
+
function locateNextRNode(hydrationInfo, tView, lView, tNode) {
|
|
13975
|
+
let native = null;
|
|
13976
|
+
if (tView.firstChild === tNode) {
|
|
13977
|
+
// We create a first node in this view, so we use a reference
|
|
13978
|
+
// to the first child in this DOM segment.
|
|
13979
|
+
native = hydrationInfo.firstChild;
|
|
13980
|
+
}
|
|
13981
|
+
else {
|
|
13982
|
+
// Locate a node based on a previous sibling or a parent node.
|
|
13983
|
+
const previousTNodeParent = tNode.prev === null;
|
|
13984
|
+
const previousTNode = (tNode.prev ?? tNode.parent);
|
|
13985
|
+
ngDevMode &&
|
|
13986
|
+
assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
|
|
13987
|
+
'to the previous node or a parent node.');
|
|
13988
|
+
const previousRElement = getNativeByTNode(previousTNode, lView);
|
|
13989
|
+
if (isFirstElementInNgContainer(tNode)) {
|
|
13990
|
+
const ngContainer = getDehydratedNgContainer(hydrationInfo, tNode.parent);
|
|
13991
|
+
native = ngContainer.firstChild ?? null;
|
|
13992
|
+
}
|
|
13993
|
+
else {
|
|
13994
|
+
if (previousTNodeParent) {
|
|
13995
|
+
native = previousRElement.firstChild;
|
|
13996
|
+
}
|
|
13997
|
+
else {
|
|
13998
|
+
native = previousRElement.nextSibling;
|
|
13999
|
+
}
|
|
14000
|
+
}
|
|
14001
|
+
}
|
|
14002
|
+
return native;
|
|
14003
|
+
}
|
|
14004
|
+
/**
|
|
14005
|
+
* Skips over a specified number of nodes and returns the next sibling node after that.
|
|
14006
|
+
*/
|
|
14007
|
+
function siblingAfter(skip, from) {
|
|
14008
|
+
let currentNode = from;
|
|
14009
|
+
for (let i = 0; i < skip; i++) {
|
|
14010
|
+
ngDevMode && validateSiblingNodeExists(currentNode);
|
|
14011
|
+
currentNode = currentNode.nextSibling;
|
|
14012
|
+
}
|
|
14013
|
+
return currentNode;
|
|
14014
|
+
}
|
|
14015
|
+
|
|
14016
|
+
/**
|
|
14017
|
+
* The name of an attribute that can be added to the hydration boundary node
|
|
14018
|
+
* (component host node) to disable hydration for the content within that boundary.
|
|
14019
|
+
*/
|
|
14020
|
+
const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';
|
|
14021
|
+
/**
|
|
14022
|
+
* Helper function to check if a given node has the 'ngSkipHydration' attribute
|
|
14023
|
+
*/
|
|
14024
|
+
function hasNgSkipHydrationAttr(tNode) {
|
|
14025
|
+
const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = SKIP_HYDRATION_ATTR_NAME.toLowerCase();
|
|
14026
|
+
const attrs = tNode.mergedAttrs;
|
|
14027
|
+
if (attrs === null)
|
|
14028
|
+
return false;
|
|
14029
|
+
// only ever look at the attribute name and skip the values
|
|
14030
|
+
for (let i = 0; i < attrs.length; i += 2) {
|
|
14031
|
+
const value = attrs[i];
|
|
14032
|
+
// This is a marker, which means that the static attributes section is over,
|
|
14033
|
+
// so we can exit early.
|
|
14034
|
+
if (typeof value === 'number')
|
|
14035
|
+
return false;
|
|
14036
|
+
if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {
|
|
14037
|
+
return true;
|
|
14038
|
+
}
|
|
14039
|
+
}
|
|
14040
|
+
return false;
|
|
14041
|
+
}
|
|
14042
|
+
|
|
13560
14043
|
/**
|
|
13561
14044
|
* Update a property on a selected element.
|
|
13562
14045
|
*
|
|
@@ -13597,16 +14080,13 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
|
|
|
13597
14080
|
setInputsForProperty(tView, lView, inputs[property], property, value);
|
|
13598
14081
|
}
|
|
13599
14082
|
|
|
13600
|
-
function elementStartFirstCreatePass(index, tView, lView,
|
|
14083
|
+
function elementStartFirstCreatePass(index, tView, lView, name, attrsIndex, localRefsIndex) {
|
|
13601
14084
|
ngDevMode && assertFirstCreatePass(tView);
|
|
13602
14085
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
13603
14086
|
const tViewConsts = tView.consts;
|
|
13604
14087
|
const attrs = getConstant(tViewConsts, attrsIndex);
|
|
13605
14088
|
const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
|
|
13606
|
-
|
|
13607
|
-
if (ngDevMode) {
|
|
13608
|
-
validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
|
|
13609
|
-
}
|
|
14089
|
+
resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
|
|
13610
14090
|
if (tNode.attrs !== null) {
|
|
13611
14091
|
computeStaticStyling(tNode, tNode.attrs, false);
|
|
13612
14092
|
}
|
|
@@ -13641,13 +14121,18 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
13641
14121
|
assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
|
|
13642
14122
|
ngDevMode && assertIndexInRange(lView, adjustedIndex);
|
|
13643
14123
|
const renderer = lView[RENDERER];
|
|
13644
|
-
const native = lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1());
|
|
13645
14124
|
const tNode = tView.firstCreatePass ?
|
|
13646
|
-
elementStartFirstCreatePass(adjustedIndex, tView, lView,
|
|
14125
|
+
elementStartFirstCreatePass(adjustedIndex, tView, lView, name, attrsIndex, localRefsIndex) :
|
|
13647
14126
|
tView.data[adjustedIndex];
|
|
14127
|
+
const native = _locateOrCreateElementNode(tView, lView, tNode, renderer, name);
|
|
14128
|
+
lView[adjustedIndex] = native;
|
|
14129
|
+
const hasDirectives = isDirectiveHost(tNode);
|
|
14130
|
+
if (ngDevMode && tView.firstCreatePass) {
|
|
14131
|
+
validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
|
|
14132
|
+
}
|
|
13648
14133
|
setCurrentTNode(tNode, true);
|
|
13649
14134
|
setupStaticAttributes(renderer, native, tNode);
|
|
13650
|
-
if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
|
|
14135
|
+
if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */ && wasLastNodeCreated()) {
|
|
13651
14136
|
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
13652
14137
|
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
13653
14138
|
appendChild(tView, lView, native, tNode);
|
|
@@ -13659,7 +14144,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
13659
14144
|
attachPatchData(native, lView);
|
|
13660
14145
|
}
|
|
13661
14146
|
increaseElementDepthCount();
|
|
13662
|
-
if (
|
|
14147
|
+
if (hasDirectives) {
|
|
13663
14148
|
createDirectivesInstances(tView, lView, tNode);
|
|
13664
14149
|
executeContentQueries(tView, tNode, lView);
|
|
13665
14150
|
}
|
|
@@ -13687,6 +14172,9 @@ function ɵɵelementEnd() {
|
|
|
13687
14172
|
}
|
|
13688
14173
|
const tNode = currentTNode;
|
|
13689
14174
|
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
|
|
14175
|
+
if (isSkipHydrationRootTNode(tNode)) {
|
|
14176
|
+
leaveSkipHydrationBlock();
|
|
14177
|
+
}
|
|
13690
14178
|
decreaseElementDepthCount();
|
|
13691
14179
|
const tView = getTView();
|
|
13692
14180
|
if (tView.firstCreatePass) {
|
|
@@ -13719,6 +14207,40 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
|
|
|
13719
14207
|
ɵɵelementEnd();
|
|
13720
14208
|
return ɵɵelement;
|
|
13721
14209
|
}
|
|
14210
|
+
let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name) => {
|
|
14211
|
+
lastNodeWasCreated(true);
|
|
14212
|
+
return createElementNode(renderer, name, getNamespace$1());
|
|
14213
|
+
};
|
|
14214
|
+
/**
|
|
14215
|
+
* Enables hydration code path (to lookup existing elements in DOM)
|
|
14216
|
+
* in addition to the regular creation mode of element nodes.
|
|
14217
|
+
*/
|
|
14218
|
+
function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name) {
|
|
14219
|
+
const hydrationInfo = lView[HYDRATION];
|
|
14220
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
|
|
14221
|
+
lastNodeWasCreated(isNodeCreationMode);
|
|
14222
|
+
// Regular creation mode.
|
|
14223
|
+
if (isNodeCreationMode) {
|
|
14224
|
+
return createElementNode(renderer, name, getNamespace$1());
|
|
14225
|
+
}
|
|
14226
|
+
// Hydration mode, looking up an existing element in DOM.
|
|
14227
|
+
const native = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
14228
|
+
ngDevMode &&
|
|
14229
|
+
validateMatchingNode(native, Node.ELEMENT_NODE, name, lView, tNode);
|
|
14230
|
+
ngDevMode && markRNodeAsClaimedByHydration(native);
|
|
14231
|
+
// Checks if the skip hydration attribute is present during hydration so we know to
|
|
14232
|
+
// skip attempting to hydrate this block.
|
|
14233
|
+
if (hydrationInfo && hasNgSkipHydrationAttr(tNode)) {
|
|
14234
|
+
enterSkipHydrationBlock(tNode);
|
|
14235
|
+
// Since this isn't hydratable, we need to empty the node
|
|
14236
|
+
// so there's no duplicate content after render
|
|
14237
|
+
clearElementContents(renderer, native);
|
|
14238
|
+
}
|
|
14239
|
+
return native;
|
|
14240
|
+
}
|
|
14241
|
+
function enableLocateOrCreateElementNodeImpl() {
|
|
14242
|
+
_locateOrCreateElementNode = locateOrCreateElementNodeImpl;
|
|
14243
|
+
}
|
|
13722
14244
|
|
|
13723
14245
|
function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
|
|
13724
14246
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
@@ -13764,10 +14286,12 @@ function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
|
|
|
13764
14286
|
tView.data[adjustedIndex];
|
|
13765
14287
|
setCurrentTNode(tNode, true);
|
|
13766
14288
|
ngDevMode && ngDevMode.rendererCreateComment++;
|
|
13767
|
-
const
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
14289
|
+
const comment = _locateOrCreateElementContainerNode(tView, lView, tNode, index);
|
|
14290
|
+
lView[adjustedIndex] = comment;
|
|
14291
|
+
if (wasLastNodeCreated()) {
|
|
14292
|
+
appendChild(tView, lView, comment, tNode);
|
|
14293
|
+
}
|
|
14294
|
+
attachPatchData(comment, lView);
|
|
13771
14295
|
if (isDirectiveHost(tNode)) {
|
|
13772
14296
|
createDirectivesInstances(tView, lView, tNode);
|
|
13773
14297
|
executeContentQueries(tView, tNode, lView);
|
|
@@ -13819,6 +14343,46 @@ function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
|
|
|
13819
14343
|
ɵɵelementContainerEnd();
|
|
13820
14344
|
return ɵɵelementContainer;
|
|
13821
14345
|
}
|
|
14346
|
+
let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
|
|
14347
|
+
lastNodeWasCreated(true);
|
|
14348
|
+
return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
|
|
14349
|
+
};
|
|
14350
|
+
/**
|
|
14351
|
+
* Enables hydration code path (to lookup existing elements in DOM)
|
|
14352
|
+
* in addition to the regular creation mode of comment nodes that
|
|
14353
|
+
* represent <ng-container>'s anchor.
|
|
14354
|
+
*/
|
|
14355
|
+
function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
|
|
14356
|
+
let comment;
|
|
14357
|
+
const hydrationInfo = lView[HYDRATION];
|
|
14358
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
|
|
14359
|
+
lastNodeWasCreated(isNodeCreationMode);
|
|
14360
|
+
// Regular creation mode.
|
|
14361
|
+
if (isNodeCreationMode) {
|
|
14362
|
+
return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
|
|
14363
|
+
}
|
|
14364
|
+
// Hydration mode, looking up existing elements in DOM.
|
|
14365
|
+
const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
14366
|
+
const ngContainerSize = getNgContainerSize(hydrationInfo, index);
|
|
14367
|
+
ngDevMode &&
|
|
14368
|
+
assertNumber(ngContainerSize, 'Unexpected state: hydrating an <ng-container>, ' +
|
|
14369
|
+
'but no hydration info is available.');
|
|
14370
|
+
if (ngContainerSize > 0) {
|
|
14371
|
+
storeNgContainerInfo(hydrationInfo, index, currentRNode);
|
|
14372
|
+
comment = siblingAfter(ngContainerSize, currentRNode);
|
|
14373
|
+
}
|
|
14374
|
+
else {
|
|
14375
|
+
// If <ng-container> has no nodes,
|
|
14376
|
+
// the current node is an anchor (comment) node.
|
|
14377
|
+
comment = currentRNode;
|
|
14378
|
+
}
|
|
14379
|
+
ngDevMode && validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
|
|
14380
|
+
ngDevMode && markRNodeAsClaimedByHydration(comment);
|
|
14381
|
+
return comment;
|
|
14382
|
+
}
|
|
14383
|
+
function enableLocateOrCreateElementContainerNodeImpl() {
|
|
14384
|
+
_locateOrCreateElementContainerNode = locateOrCreateElementContainerNode;
|
|
14385
|
+
}
|
|
13822
14386
|
|
|
13823
14387
|
/**
|
|
13824
14388
|
* Returns the current OpaqueViewState instance.
|
|
@@ -13847,16 +14411,6 @@ function isPromise(obj) {
|
|
|
13847
14411
|
function isSubscribable(obj) {
|
|
13848
14412
|
return !!obj && typeof obj.subscribe === 'function';
|
|
13849
14413
|
}
|
|
13850
|
-
/**
|
|
13851
|
-
* Determine if the argument is an Observable
|
|
13852
|
-
*
|
|
13853
|
-
* Strictly this tests that the `obj` is `Subscribable`, since `Observable`
|
|
13854
|
-
* types need additional methods, such as `lift()`. But it is adequate for our
|
|
13855
|
-
* needs since within the Angular framework code we only ever need to use the
|
|
13856
|
-
* `subscribe()` method, and RxJS has mechanisms to wrap `Subscribable` objects
|
|
13857
|
-
* into `Observable` as needed.
|
|
13858
|
-
*/
|
|
13859
|
-
const isObservable = isSubscribable;
|
|
13860
14414
|
|
|
13861
14415
|
/**
|
|
13862
14416
|
* Adds an event listener to the current node.
|
|
@@ -14019,7 +14573,7 @@ function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn,
|
|
|
14019
14573
|
const minifiedName = props[i + 1];
|
|
14020
14574
|
const directiveInstance = lView[index];
|
|
14021
14575
|
const output = directiveInstance[minifiedName];
|
|
14022
|
-
if (ngDevMode && !
|
|
14576
|
+
if (ngDevMode && !isSubscribable(output)) {
|
|
14023
14577
|
throw new Error(`@Output ${minifiedName} not initialized in '${directiveInstance.constructor.name}'.`);
|
|
14024
14578
|
}
|
|
14025
14579
|
const subscription = output.subscribe(listenerFn);
|
|
@@ -16163,11 +16717,39 @@ function ɵɵtext(index, value = '') {
|
|
|
16163
16717
|
const tNode = tView.firstCreatePass ?
|
|
16164
16718
|
getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null) :
|
|
16165
16719
|
tView.data[adjustedIndex];
|
|
16166
|
-
const textNative =
|
|
16167
|
-
|
|
16720
|
+
const textNative = _locateOrCreateTextNode(tView, lView, tNode, value);
|
|
16721
|
+
lView[adjustedIndex] = textNative;
|
|
16722
|
+
if (wasLastNodeCreated()) {
|
|
16723
|
+
appendChild(tView, lView, textNative, tNode);
|
|
16724
|
+
}
|
|
16168
16725
|
// Text nodes are self closing.
|
|
16169
16726
|
setCurrentTNode(tNode, false);
|
|
16170
16727
|
}
|
|
16728
|
+
let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
|
|
16729
|
+
lastNodeWasCreated(true);
|
|
16730
|
+
return createTextNode(lView[RENDERER], value);
|
|
16731
|
+
};
|
|
16732
|
+
/**
|
|
16733
|
+
* Enables hydration code path (to lookup existing elements in DOM)
|
|
16734
|
+
* in addition to the regular creation mode of text nodes.
|
|
16735
|
+
*/
|
|
16736
|
+
function locateOrCreateTextNodeImpl(tView, lView, tNode, value) {
|
|
16737
|
+
const hydrationInfo = lView[HYDRATION];
|
|
16738
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
|
|
16739
|
+
lastNodeWasCreated(isNodeCreationMode);
|
|
16740
|
+
// Regular creation mode.
|
|
16741
|
+
if (isNodeCreationMode) {
|
|
16742
|
+
return createTextNode(lView[RENDERER], value);
|
|
16743
|
+
}
|
|
16744
|
+
// Hydration mode, looking up an existing element in DOM.
|
|
16745
|
+
const textNative = locateNextRNode(hydrationInfo, tView, lView, tNode);
|
|
16746
|
+
ngDevMode && validateMatchingNode(textNative, Node.TEXT_NODE, null, lView, tNode);
|
|
16747
|
+
ngDevMode && markRNodeAsClaimedByHydration(textNative);
|
|
16748
|
+
return textNative;
|
|
16749
|
+
}
|
|
16750
|
+
function enableLocateOrCreateTextNodeImpl() {
|
|
16751
|
+
_locateOrCreateTextNode = locateOrCreateTextNodeImpl;
|
|
16752
|
+
}
|
|
16171
16753
|
|
|
16172
16754
|
/**
|
|
16173
16755
|
*
|
|
@@ -17845,7 +18427,7 @@ function getTIcu(tView, index) {
|
|
|
17845
18427
|
if (value === null || typeof value === 'string')
|
|
17846
18428
|
return null;
|
|
17847
18429
|
if (ngDevMode &&
|
|
17848
|
-
!(value.hasOwnProperty('
|
|
18430
|
+
!(value.hasOwnProperty('tView') || value.hasOwnProperty('currentCaseLViewIndex'))) {
|
|
17849
18431
|
throwError('We expect to get \'null\'|\'TIcu\'|\'TIcuContainer\', but got: ' + value);
|
|
17850
18432
|
}
|
|
17851
18433
|
// Here the `value.hasOwnProperty('currentCaseLViewIndex')` is a polymorphic read as it can be
|
|
@@ -17874,7 +18456,7 @@ function getTIcu(tView, index) {
|
|
|
17874
18456
|
function setTIcu(tView, index, tIcu) {
|
|
17875
18457
|
const tNode = tView.data[index];
|
|
17876
18458
|
ngDevMode &&
|
|
17877
|
-
assertEqual(tNode === null || tNode.hasOwnProperty('
|
|
18459
|
+
assertEqual(tNode === null || tNode.hasOwnProperty('tView'), true, 'We expect to get \'null\'|\'TIcuContainer\'');
|
|
17878
18460
|
if (tNode === null) {
|
|
17879
18461
|
tView.data[index] = tIcu;
|
|
17880
18462
|
}
|
|
@@ -20974,7 +21556,8 @@ function _wrapInTimeout(fn) {
|
|
|
20974
21556
|
const EventEmitter = EventEmitter_;
|
|
20975
21557
|
|
|
20976
21558
|
function symbolIterator() {
|
|
20977
|
-
|
|
21559
|
+
// @ts-expect-error accessing a private member
|
|
21560
|
+
return this._results[Symbol.iterator]();
|
|
20978
21561
|
}
|
|
20979
21562
|
/**
|
|
20980
21563
|
* An unmodifiable list of items that Angular keeps up to date when the state
|
|
@@ -21026,11 +21609,10 @@ class QueryList {
|
|
|
21026
21609
|
// This function should be declared on the prototype, but doing so there will cause the class
|
|
21027
21610
|
// declaration to have side-effects and become not tree-shakable. For this reason we do it in
|
|
21028
21611
|
// the constructor.
|
|
21029
|
-
// [
|
|
21030
|
-
const symbol = getSymbolIterator();
|
|
21612
|
+
// [Symbol.iterator](): Iterator<T> { ... }
|
|
21031
21613
|
const proto = QueryList.prototype;
|
|
21032
|
-
if (!proto[
|
|
21033
|
-
proto[
|
|
21614
|
+
if (!proto[Symbol.iterator])
|
|
21615
|
+
proto[Symbol.iterator] = symbolIterator;
|
|
21034
21616
|
}
|
|
21035
21617
|
/**
|
|
21036
21618
|
* Returns the QueryList entry at `index`.
|
|
@@ -21169,8 +21751,8 @@ const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
|
|
|
21169
21751
|
this.elementRef = elementRef;
|
|
21170
21752
|
}
|
|
21171
21753
|
createEmbeddedView(context, injector) {
|
|
21172
|
-
const embeddedTView = this._declarationTContainer.
|
|
21173
|
-
const embeddedLView = createLView(this._declarationLView, embeddedTView, context, 16 /* LViewFlags.CheckAlways */, null, embeddedTView.declTNode, null, null, null, null, injector || null);
|
|
21754
|
+
const embeddedTView = this._declarationTContainer.tView;
|
|
21755
|
+
const embeddedLView = createLView(this._declarationLView, embeddedTView, context, 16 /* LViewFlags.CheckAlways */, null, embeddedTView.declTNode, null, null, null, null, injector || null, null);
|
|
21174
21756
|
const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
|
|
21175
21757
|
ngDevMode && assertLContainer(declarationLContainer);
|
|
21176
21758
|
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
@@ -21199,7 +21781,7 @@ function injectTemplateRef() {
|
|
|
21199
21781
|
*/
|
|
21200
21782
|
function createTemplateRef(hostTNode, hostLView) {
|
|
21201
21783
|
if (hostTNode.type & 4 /* TNodeType.Container */) {
|
|
21202
|
-
ngDevMode && assertDefined(hostTNode.
|
|
21784
|
+
ngDevMode && assertDefined(hostTNode.tView, 'TView must be allocated');
|
|
21203
21785
|
return new R3TemplateRef(hostLView, hostTNode, createElementRef(hostTNode, hostLView));
|
|
21204
21786
|
}
|
|
21205
21787
|
return null;
|
|
@@ -22767,7 +23349,6 @@ function compileComponent(type, metadata) {
|
|
|
22767
23349
|
encapsulation,
|
|
22768
23350
|
interpolation: metadata.interpolation,
|
|
22769
23351
|
viewProviders: metadata.viewProviders || null,
|
|
22770
|
-
isStandalone: !!metadata.standalone,
|
|
22771
23352
|
};
|
|
22772
23353
|
compilationDepth++;
|
|
22773
23354
|
try {
|
|
@@ -23292,10 +23873,6 @@ const NgModule = makeDecorator('NgModule', (ngModule) => ngModule, undefined, un
|
|
|
23292
23873
|
* to be used by the decorator versions of these annotations.
|
|
23293
23874
|
*/
|
|
23294
23875
|
|
|
23295
|
-
function noop(...args) {
|
|
23296
|
-
// Do nothing.
|
|
23297
|
-
}
|
|
23298
|
-
|
|
23299
23876
|
/*
|
|
23300
23877
|
* This file exists to support compilation of @angular/core in Ivy mode.
|
|
23301
23878
|
*
|
|
@@ -23393,17 +23970,15 @@ const APP_INITIALIZER = new InjectionToken('Application Initializer');
|
|
|
23393
23970
|
* @publicApi
|
|
23394
23971
|
*/
|
|
23395
23972
|
class ApplicationInitStatus {
|
|
23396
|
-
constructor(
|
|
23397
|
-
this.appInits = appInits;
|
|
23398
|
-
this.resolve = noop;
|
|
23399
|
-
this.reject = noop;
|
|
23973
|
+
constructor() {
|
|
23400
23974
|
this.initialized = false;
|
|
23401
23975
|
this.done = false;
|
|
23402
|
-
// TODO: Throw RuntimeErrorCode.INVALID_MULTI_PROVIDER if appInits is not an array
|
|
23403
23976
|
this.donePromise = new Promise((res, rej) => {
|
|
23404
23977
|
this.resolve = res;
|
|
23405
23978
|
this.reject = rej;
|
|
23406
23979
|
});
|
|
23980
|
+
// TODO: Throw RuntimeErrorCode.INVALID_MULTI_PROVIDER if appInits is not an array
|
|
23981
|
+
this.appInits = inject(APP_INITIALIZER, { optional: true }) ?? [];
|
|
23407
23982
|
}
|
|
23408
23983
|
/** @internal */
|
|
23409
23984
|
runInitializers() {
|
|
@@ -23411,24 +23986,23 @@ class ApplicationInitStatus {
|
|
|
23411
23986
|
return;
|
|
23412
23987
|
}
|
|
23413
23988
|
const asyncInitPromises = [];
|
|
23989
|
+
for (const appInits of this.appInits) {
|
|
23990
|
+
const initResult = appInits();
|
|
23991
|
+
if (isPromise(initResult)) {
|
|
23992
|
+
asyncInitPromises.push(initResult);
|
|
23993
|
+
}
|
|
23994
|
+
else if (isSubscribable(initResult)) {
|
|
23995
|
+
const observableAsPromise = new Promise((resolve, reject) => {
|
|
23996
|
+
initResult.subscribe({ complete: resolve, error: reject });
|
|
23997
|
+
});
|
|
23998
|
+
asyncInitPromises.push(observableAsPromise);
|
|
23999
|
+
}
|
|
24000
|
+
}
|
|
23414
24001
|
const complete = () => {
|
|
24002
|
+
// @ts-expect-error overwriting a readonly
|
|
23415
24003
|
this.done = true;
|
|
23416
24004
|
this.resolve();
|
|
23417
24005
|
};
|
|
23418
|
-
if (this.appInits) {
|
|
23419
|
-
for (let i = 0; i < this.appInits.length; i++) {
|
|
23420
|
-
const initResult = this.appInits[i]();
|
|
23421
|
-
if (isPromise(initResult)) {
|
|
23422
|
-
asyncInitPromises.push(initResult);
|
|
23423
|
-
}
|
|
23424
|
-
else if (isObservable(initResult)) {
|
|
23425
|
-
const observableAsPromise = new Promise((resolve, reject) => {
|
|
23426
|
-
initResult.subscribe({ complete: resolve, error: reject });
|
|
23427
|
-
});
|
|
23428
|
-
asyncInitPromises.push(observableAsPromise);
|
|
23429
|
-
}
|
|
23430
|
-
}
|
|
23431
|
-
}
|
|
23432
24006
|
Promise.all(asyncInitPromises)
|
|
23433
24007
|
.then(() => {
|
|
23434
24008
|
complete();
|
|
@@ -23442,87 +24016,12 @@ class ApplicationInitStatus {
|
|
|
23442
24016
|
this.initialized = true;
|
|
23443
24017
|
}
|
|
23444
24018
|
}
|
|
23445
|
-
ApplicationInitStatus.ɵfac = function ApplicationInitStatus_Factory(t) { return new (t || ApplicationInitStatus)(
|
|
24019
|
+
ApplicationInitStatus.ɵfac = function ApplicationInitStatus_Factory(t) { return new (t || ApplicationInitStatus)(); };
|
|
23446
24020
|
ApplicationInitStatus.ɵprov = /*@__PURE__*/ ɵɵdefineInjectable({ token: ApplicationInitStatus, factory: ApplicationInitStatus.ɵfac, providedIn: 'root' });
|
|
23447
24021
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationInitStatus, [{
|
|
23448
24022
|
type: Injectable,
|
|
23449
24023
|
args: [{ providedIn: 'root' }]
|
|
23450
|
-
}],
|
|
23451
|
-
type: Inject,
|
|
23452
|
-
args: [APP_INITIALIZER]
|
|
23453
|
-
}, {
|
|
23454
|
-
type: Optional
|
|
23455
|
-
}] }]; }, null); })();
|
|
23456
|
-
|
|
23457
|
-
/**
|
|
23458
|
-
* A [DI token](guide/glossary#di-token "DI token definition") representing a unique string ID, used
|
|
23459
|
-
* primarily for prefixing application attributes and CSS styles when
|
|
23460
|
-
* {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
|
|
23461
|
-
*
|
|
23462
|
-
* BY default, the value is randomly generated and assigned to the application by Angular.
|
|
23463
|
-
* To provide a custom ID value, use a DI provider <!-- TODO: provider --> to configure
|
|
23464
|
-
* the root {@link Injector} that uses this token.
|
|
23465
|
-
*
|
|
23466
|
-
* @publicApi
|
|
23467
|
-
*/
|
|
23468
|
-
const APP_ID = new InjectionToken('AppId', {
|
|
23469
|
-
providedIn: 'root',
|
|
23470
|
-
factory: _appIdRandomProviderFactory,
|
|
23471
|
-
});
|
|
23472
|
-
function _appIdRandomProviderFactory() {
|
|
23473
|
-
return `${_randomChar()}${_randomChar()}${_randomChar()}`;
|
|
23474
|
-
}
|
|
23475
|
-
/**
|
|
23476
|
-
* Providers that generate a random `APP_ID_TOKEN`.
|
|
23477
|
-
* @publicApi
|
|
23478
|
-
*/
|
|
23479
|
-
const APP_ID_RANDOM_PROVIDER = {
|
|
23480
|
-
provide: APP_ID,
|
|
23481
|
-
useFactory: _appIdRandomProviderFactory,
|
|
23482
|
-
deps: [],
|
|
23483
|
-
};
|
|
23484
|
-
function _randomChar() {
|
|
23485
|
-
return String.fromCharCode(97 + Math.floor(Math.random() * 25));
|
|
23486
|
-
}
|
|
23487
|
-
/**
|
|
23488
|
-
* A function that is executed when a platform is initialized.
|
|
23489
|
-
* @publicApi
|
|
23490
|
-
*/
|
|
23491
|
-
const PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
|
|
23492
|
-
/**
|
|
23493
|
-
* A token that indicates an opaque platform ID.
|
|
23494
|
-
* @publicApi
|
|
23495
|
-
*/
|
|
23496
|
-
const PLATFORM_ID = new InjectionToken('Platform ID', {
|
|
23497
|
-
providedIn: 'platform',
|
|
23498
|
-
factory: () => 'unknown', // set a default platform name, when none set explicitly
|
|
23499
|
-
});
|
|
23500
|
-
/**
|
|
23501
|
-
* A [DI token](guide/glossary#di-token "DI token definition") that provides a set of callbacks to
|
|
23502
|
-
* be called for every component that is bootstrapped.
|
|
23503
|
-
*
|
|
23504
|
-
* Each callback must take a `ComponentRef` instance and return nothing.
|
|
23505
|
-
*
|
|
23506
|
-
* `(componentRef: ComponentRef) => void`
|
|
23507
|
-
*
|
|
23508
|
-
* @publicApi
|
|
23509
|
-
*/
|
|
23510
|
-
const APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
|
|
23511
|
-
/**
|
|
23512
|
-
* A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
|
|
23513
|
-
* the application
|
|
23514
|
-
* @publicApi
|
|
23515
|
-
*/
|
|
23516
|
-
const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
|
|
23517
|
-
// We keep this token here, rather than the animations package, so that modules that only care
|
|
23518
|
-
// about which animations module is loaded (e.g. the CDK) can retrieve it without having to
|
|
23519
|
-
// include extra dependencies. See #44970 for more context.
|
|
23520
|
-
/**
|
|
23521
|
-
* A [DI token](guide/glossary#di-token "DI token definition") that indicates which animations
|
|
23522
|
-
* module has been loaded.
|
|
23523
|
-
* @publicApi
|
|
23524
|
-
*/
|
|
23525
|
-
const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
|
|
24024
|
+
}], null, null); })();
|
|
23526
24025
|
|
|
23527
24026
|
class Console {
|
|
23528
24027
|
log(message) {
|
|
@@ -23913,6 +24412,10 @@ function scheduleMicroTask(fn) {
|
|
|
23913
24412
|
}
|
|
23914
24413
|
}
|
|
23915
24414
|
|
|
24415
|
+
function noop(...args) {
|
|
24416
|
+
// Do nothing.
|
|
24417
|
+
}
|
|
24418
|
+
|
|
23916
24419
|
function getNativeRequestAnimationFrame() {
|
|
23917
24420
|
let nativeRequestAnimationFrame = _global['requestAnimationFrame'];
|
|
23918
24421
|
let nativeCancelAnimationFrame = _global['cancelAnimationFrame'];
|
|
@@ -24633,6 +25136,7 @@ function setTestabilityGetter(getter) {
|
|
|
24633
25136
|
}
|
|
24634
25137
|
let _testabilityGetter;
|
|
24635
25138
|
|
|
25139
|
+
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
|
|
24636
25140
|
let _platformInjector = null;
|
|
24637
25141
|
/**
|
|
24638
25142
|
* Internal token to indicate whether having multiple bootstrapped platform should be allowed (only
|
|
@@ -24646,7 +25150,17 @@ const ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
|
|
|
24646
25150
|
* entire class tree-shakeable.
|
|
24647
25151
|
*/
|
|
24648
25152
|
const PLATFORM_DESTROY_LISTENERS = new InjectionToken('PlatformDestroyListeners');
|
|
24649
|
-
|
|
25153
|
+
/**
|
|
25154
|
+
* A [DI token](guide/glossary#di-token "DI token definition") that provides a set of callbacks to
|
|
25155
|
+
* be called for every component that is bootstrapped.
|
|
25156
|
+
*
|
|
25157
|
+
* Each callback must take a `ComponentRef` instance and return nothing.
|
|
25158
|
+
*
|
|
25159
|
+
* `(componentRef: ComponentRef) => void`
|
|
25160
|
+
*
|
|
25161
|
+
* @publicApi
|
|
25162
|
+
*/
|
|
25163
|
+
const APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
|
|
24650
25164
|
function compileNgModuleFactory(injector, options, moduleType) {
|
|
24651
25165
|
ngDevMode && assertNgModuleType(moduleType);
|
|
24652
25166
|
const moduleFactory = new NgModuleFactory(moduleType);
|
|
@@ -24665,7 +25179,7 @@ function compileNgModuleFactory(injector, options, moduleType) {
|
|
|
24665
25179
|
if (isComponentResourceResolutionQueueEmpty()) {
|
|
24666
25180
|
return Promise.resolve(moduleFactory);
|
|
24667
25181
|
}
|
|
24668
|
-
const compilerProviders =
|
|
25182
|
+
const compilerProviders = compilerOptions.flatMap((option) => option.providers ?? []);
|
|
24669
25183
|
// In case there are no compiler providers, we just return the module factory as
|
|
24670
25184
|
// there won't be any resource loader. This can happen with Ivy, because AOT compiled
|
|
24671
25185
|
// modules can be still passed through "bootstrapModule". In that case we shouldn't
|
|
@@ -24738,9 +25252,7 @@ function createOrReusePlatformInjector(providers = []) {
|
|
|
24738
25252
|
}
|
|
24739
25253
|
function runPlatformInitializers(injector) {
|
|
24740
25254
|
const inits = injector.get(PLATFORM_INITIALIZER, null);
|
|
24741
|
-
|
|
24742
|
-
inits.forEach((init) => init());
|
|
24743
|
-
}
|
|
25255
|
+
inits?.forEach((init) => init());
|
|
24744
25256
|
}
|
|
24745
25257
|
/**
|
|
24746
25258
|
* Internal create application API that implements the core application creation logic and optional
|
|
@@ -24765,7 +25277,7 @@ function internalCreateApplication(config) {
|
|
|
24765
25277
|
// bootstrap level as well as providers passed to the bootstrap call by a user.
|
|
24766
25278
|
const allAppProviders = [
|
|
24767
25279
|
{ provide: NgZone, useValue: ngZone },
|
|
24768
|
-
...(appProviders || []),
|
|
25280
|
+
...(appProviders || []),
|
|
24769
25281
|
];
|
|
24770
25282
|
const envInjector = createEnvironmentInjector(allAppProviders, platformInjector, 'Environment Injector');
|
|
24771
25283
|
const exceptionHandler = envInjector.get(ErrorHandler, null);
|
|
@@ -25034,19 +25546,18 @@ PlatformRef.ɵprov = /*@__PURE__*/ ɵɵdefineInjectable({ token: PlatformRef, fa
|
|
|
25034
25546
|
function getNgZoneOptions(options) {
|
|
25035
25547
|
return {
|
|
25036
25548
|
enableLongStackTrace: typeof ngDevMode === 'undefined' ? false : !!ngDevMode,
|
|
25037
|
-
shouldCoalesceEventChangeDetection:
|
|
25038
|
-
shouldCoalesceRunChangeDetection:
|
|
25549
|
+
shouldCoalesceEventChangeDetection: options?.ngZoneEventCoalescing ?? false,
|
|
25550
|
+
shouldCoalesceRunChangeDetection: options?.ngZoneRunCoalescing ?? false,
|
|
25039
25551
|
};
|
|
25040
25552
|
}
|
|
25041
|
-
function getNgZone(ngZoneToUse, options) {
|
|
25042
|
-
let ngZone;
|
|
25553
|
+
function getNgZone(ngZoneToUse = 'zone.js', options) {
|
|
25043
25554
|
if (ngZoneToUse === 'noop') {
|
|
25044
|
-
|
|
25555
|
+
return new NoopNgZone();
|
|
25045
25556
|
}
|
|
25046
|
-
|
|
25047
|
-
|
|
25557
|
+
if (ngZoneToUse === 'zone.js') {
|
|
25558
|
+
return new NgZone(options);
|
|
25048
25559
|
}
|
|
25049
|
-
return
|
|
25560
|
+
return ngZoneToUse;
|
|
25050
25561
|
}
|
|
25051
25562
|
function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
|
|
25052
25563
|
try {
|
|
@@ -25068,12 +25579,9 @@ function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
|
|
|
25068
25579
|
}
|
|
25069
25580
|
function optionsReducer(dst, objs) {
|
|
25070
25581
|
if (Array.isArray(objs)) {
|
|
25071
|
-
|
|
25582
|
+
return objs.reduce(optionsReducer, dst);
|
|
25072
25583
|
}
|
|
25073
|
-
|
|
25074
|
-
dst = { ...dst, ...objs };
|
|
25075
|
-
}
|
|
25076
|
-
return dst;
|
|
25584
|
+
return { ...dst, ...objs };
|
|
25077
25585
|
}
|
|
25078
25586
|
/**
|
|
25079
25587
|
* A reference to an Angular application running on a page.
|
|
@@ -25188,11 +25696,12 @@ class ApplicationRef {
|
|
|
25188
25696
|
this._exceptionHandler = _exceptionHandler;
|
|
25189
25697
|
/** @internal */
|
|
25190
25698
|
this._bootstrapListeners = [];
|
|
25191
|
-
this._views = [];
|
|
25192
25699
|
this._runningTick = false;
|
|
25193
25700
|
this._stable = true;
|
|
25194
25701
|
this._destroyed = false;
|
|
25195
25702
|
this._destroyListeners = [];
|
|
25703
|
+
/** @internal */
|
|
25704
|
+
this._views = [];
|
|
25196
25705
|
/**
|
|
25197
25706
|
* Get a list of component types registered to this application.
|
|
25198
25707
|
* This list is populated even before the component is created.
|
|
@@ -25249,8 +25758,7 @@ class ApplicationRef {
|
|
|
25249
25758
|
unstableSub.unsubscribe();
|
|
25250
25759
|
};
|
|
25251
25760
|
});
|
|
25252
|
-
this.isStable =
|
|
25253
|
-
merge$1(isCurrentlyStable, isStable.pipe(share()));
|
|
25761
|
+
this.isStable = merge$1(isCurrentlyStable, isStable.pipe(share()));
|
|
25254
25762
|
}
|
|
25255
25763
|
/**
|
|
25256
25764
|
* Bootstrap a component onto the element identified by its selector or, optionally, to a
|
|
@@ -25479,11 +25987,6 @@ function _lastDefined(args) {
|
|
|
25479
25987
|
}
|
|
25480
25988
|
return undefined;
|
|
25481
25989
|
}
|
|
25482
|
-
function _mergeArrays(parts) {
|
|
25483
|
-
const result = [];
|
|
25484
|
-
parts.forEach((part) => part && result.push(...part));
|
|
25485
|
-
return result;
|
|
25486
|
-
}
|
|
25487
25990
|
|
|
25488
25991
|
/**
|
|
25489
25992
|
* Returns whether Angular is in development mode.
|
|
@@ -25523,6 +26026,37 @@ function enableProdMode() {
|
|
|
25523
26026
|
|
|
25524
26027
|
// Public API for render
|
|
25525
26028
|
|
|
26029
|
+
/**
|
|
26030
|
+
* `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
|
|
26031
|
+
* The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
|
|
26032
|
+
* is injected in a component or directive, the callbacks run when that component or
|
|
26033
|
+
* directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
|
|
26034
|
+
*/
|
|
26035
|
+
class DestroyRef {
|
|
26036
|
+
}
|
|
26037
|
+
/**
|
|
26038
|
+
* @internal
|
|
26039
|
+
* @nocollapse
|
|
26040
|
+
*/
|
|
26041
|
+
DestroyRef.__NG_ELEMENT_ID__ = injectDestroyRef;
|
|
26042
|
+
/**
|
|
26043
|
+
* @internal
|
|
26044
|
+
* @nocollapse
|
|
26045
|
+
*/
|
|
26046
|
+
DestroyRef.__NG_ENV_ID__ = (injector) => injector;
|
|
26047
|
+
class NodeInjectorDestroyRef extends DestroyRef {
|
|
26048
|
+
constructor(_lView) {
|
|
26049
|
+
super();
|
|
26050
|
+
this._lView = _lView;
|
|
26051
|
+
}
|
|
26052
|
+
onDestroy(callback) {
|
|
26053
|
+
storeLViewOnDestroy(this._lView, callback);
|
|
26054
|
+
}
|
|
26055
|
+
}
|
|
26056
|
+
function injectDestroyRef() {
|
|
26057
|
+
return new NodeInjectorDestroyRef(getLView());
|
|
26058
|
+
}
|
|
26059
|
+
|
|
25526
26060
|
/**
|
|
25527
26061
|
* Returns the NgModuleFactory with the given id (specified using [@NgModule.id
|
|
25528
26062
|
* field](api/core/NgModule#id)), if it exists and has been loaded. Factories for NgModules that do
|
|
@@ -26259,10 +26793,6 @@ function getDebugNode(nativeNode) {
|
|
|
26259
26793
|
}
|
|
26260
26794
|
return null;
|
|
26261
26795
|
}
|
|
26262
|
-
// TODO: cleanup all references to this function and remove it.
|
|
26263
|
-
function getDebugNodeR2(_nativeNode) {
|
|
26264
|
-
return null;
|
|
26265
|
-
}
|
|
26266
26796
|
function getAllDebugNodes() {
|
|
26267
26797
|
return Array.from(_nativeNodeToDebugNode.values());
|
|
26268
26798
|
}
|
|
@@ -27350,14 +27880,241 @@ ApplicationModule.ɵinj = /*@__PURE__*/ ɵɵdefineInjector({});
|
|
|
27350
27880
|
type: NgModule
|
|
27351
27881
|
}], function () { return [{ type: ApplicationRef }]; }, null); })();
|
|
27352
27882
|
|
|
27883
|
+
/**
|
|
27884
|
+
* A collection that tracks all serialized views (`ngh` DOM annotations)
|
|
27885
|
+
* to avoid duplication. An attempt to add a duplicate view results in the
|
|
27886
|
+
* collection returning the index of the previously collected serialized view.
|
|
27887
|
+
* This reduces the number of annotations needed for a given page.
|
|
27888
|
+
*/
|
|
27889
|
+
class SerializedViewCollection {
|
|
27890
|
+
constructor() {
|
|
27891
|
+
this.views = [];
|
|
27892
|
+
this.indexByContent = new Map();
|
|
27893
|
+
}
|
|
27894
|
+
add(serializedView) {
|
|
27895
|
+
const viewAsString = JSON.stringify(serializedView);
|
|
27896
|
+
if (!this.indexByContent.has(viewAsString)) {
|
|
27897
|
+
const index = this.views.length;
|
|
27898
|
+
this.views.push(serializedView);
|
|
27899
|
+
this.indexByContent.set(viewAsString, index);
|
|
27900
|
+
return index;
|
|
27901
|
+
}
|
|
27902
|
+
return this.indexByContent.get(viewAsString);
|
|
27903
|
+
}
|
|
27904
|
+
getAll() {
|
|
27905
|
+
return this.views;
|
|
27906
|
+
}
|
|
27907
|
+
}
|
|
27908
|
+
/**
|
|
27909
|
+
* Computes the number of root nodes in a given view
|
|
27910
|
+
* (or child nodes in a given container if a tNode is provided).
|
|
27911
|
+
*/
|
|
27912
|
+
function calcNumRootNodes(tView, lView, tNode) {
|
|
27913
|
+
const rootNodes = [];
|
|
27914
|
+
collectNativeNodes(tView, lView, tNode, rootNodes);
|
|
27915
|
+
return rootNodes.length;
|
|
27916
|
+
}
|
|
27917
|
+
/**
|
|
27918
|
+
* Annotates all components bootstrapped in a given ApplicationRef
|
|
27919
|
+
* with info needed for hydration.
|
|
27920
|
+
*
|
|
27921
|
+
* @param appRef An instance of an ApplicationRef.
|
|
27922
|
+
* @param doc A reference to the current Document instance.
|
|
27923
|
+
*/
|
|
27924
|
+
function annotateForHydration(appRef, doc) {
|
|
27925
|
+
const serializedViewCollection = new SerializedViewCollection();
|
|
27926
|
+
const viewRefs = appRef._views;
|
|
27927
|
+
for (const viewRef of viewRefs) {
|
|
27928
|
+
const lView = getComponentLViewForHydration(viewRef);
|
|
27929
|
+
// An `lView` might be `null` if a `ViewRef` represents
|
|
27930
|
+
// an embedded view (not a component view).
|
|
27931
|
+
if (lView !== null) {
|
|
27932
|
+
const hostElement = lView[HOST];
|
|
27933
|
+
if (hostElement) {
|
|
27934
|
+
const context = {
|
|
27935
|
+
serializedViewCollection,
|
|
27936
|
+
};
|
|
27937
|
+
annotateHostElementForHydration(hostElement, lView, context);
|
|
27938
|
+
}
|
|
27939
|
+
}
|
|
27940
|
+
}
|
|
27941
|
+
const allSerializedViews = serializedViewCollection.getAll();
|
|
27942
|
+
if (allSerializedViews.length > 0) {
|
|
27943
|
+
const transferState = appRef.injector.get(TransferState);
|
|
27944
|
+
transferState.set(NGH_DATA_KEY, allSerializedViews);
|
|
27945
|
+
}
|
|
27946
|
+
}
|
|
27947
|
+
/**
|
|
27948
|
+
* Serializes the lView data into a SerializedView object that will later be added
|
|
27949
|
+
* to the TransferState storage and referenced using the `ngh` attribute on a host
|
|
27950
|
+
* element.
|
|
27951
|
+
*
|
|
27952
|
+
* @param lView the lView we are serializing
|
|
27953
|
+
* @param context the hydration context
|
|
27954
|
+
* @returns the `SerializedView` object containing the data to be added to the host node
|
|
27955
|
+
*/
|
|
27956
|
+
function serializeLView(lView, context) {
|
|
27957
|
+
const ngh = {};
|
|
27958
|
+
const tView = lView[TVIEW];
|
|
27959
|
+
// Iterate over DOM element references in an LView.
|
|
27960
|
+
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
27961
|
+
const tNode = tView.data[i];
|
|
27962
|
+
const noOffsetIndex = i - HEADER_OFFSET;
|
|
27963
|
+
// Local refs (e.g. <div #localRef>) take up an extra slot in LViews
|
|
27964
|
+
// to store the same element. In this case, there is no information in
|
|
27965
|
+
// a corresponding slot in TNode data structure. If that's the case, just
|
|
27966
|
+
// skip this slot and move to the next one.
|
|
27967
|
+
if (!tNode) {
|
|
27968
|
+
continue;
|
|
27969
|
+
}
|
|
27970
|
+
if (isLContainer(lView[i])) {
|
|
27971
|
+
// TODO: serialization of LContainers will be added
|
|
27972
|
+
// in followup PRs.
|
|
27973
|
+
}
|
|
27974
|
+
else if (Array.isArray(lView[i])) {
|
|
27975
|
+
// This is a component, annotate the host node with an `ngh` attribute.
|
|
27976
|
+
const targetNode = unwrapRNode(lView[i][HOST]);
|
|
27977
|
+
if (!targetNode.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
|
|
27978
|
+
annotateHostElementForHydration(targetNode, lView[i], context);
|
|
27979
|
+
}
|
|
27980
|
+
}
|
|
27981
|
+
else {
|
|
27982
|
+
// <ng-container> case
|
|
27983
|
+
if (tNode.type & 8 /* TNodeType.ElementContainer */) {
|
|
27984
|
+
// An <ng-container> is represented by the number of
|
|
27985
|
+
// top-level nodes. This information is needed to skip over
|
|
27986
|
+
// those nodes to reach a corresponding anchor node (comment node).
|
|
27987
|
+
ngh[ELEMENT_CONTAINERS] ?? (ngh[ELEMENT_CONTAINERS] = {});
|
|
27988
|
+
ngh[ELEMENT_CONTAINERS][noOffsetIndex] = calcNumRootNodes(tView, lView, tNode.child);
|
|
27989
|
+
}
|
|
27990
|
+
}
|
|
27991
|
+
}
|
|
27992
|
+
return ngh;
|
|
27993
|
+
}
|
|
27994
|
+
/**
|
|
27995
|
+
* Physically adds the `ngh` attribute and serialized data to the host element.
|
|
27996
|
+
*
|
|
27997
|
+
* @param element The Host element to be annotated
|
|
27998
|
+
* @param lView The associated LView
|
|
27999
|
+
* @param context The hydration context
|
|
28000
|
+
*/
|
|
28001
|
+
function annotateHostElementForHydration(element, lView, context) {
|
|
28002
|
+
const ngh = serializeLView(lView, context);
|
|
28003
|
+
const index = context.serializedViewCollection.add(ngh);
|
|
28004
|
+
const renderer = lView[RENDERER];
|
|
28005
|
+
renderer.setAttribute(element, NGH_ATTR_NAME, index.toString());
|
|
28006
|
+
}
|
|
28007
|
+
|
|
28008
|
+
/**
|
|
28009
|
+
* Indicates whether the hydration-related code was added,
|
|
28010
|
+
* prevents adding it multiple times.
|
|
28011
|
+
*/
|
|
28012
|
+
let isHydrationSupportEnabled = false;
|
|
28013
|
+
/**
|
|
28014
|
+
* Brings the necessary hydration code in tree-shakable manner.
|
|
28015
|
+
* The code is only present when the `provideHydrationSupport` is
|
|
28016
|
+
* invoked. Otherwise, this code is tree-shaken away during the
|
|
28017
|
+
* build optimization step.
|
|
28018
|
+
*
|
|
28019
|
+
* This technique allows us to swap implementations of methods so
|
|
28020
|
+
* tree shaking works appropriately when hydration is disabled or
|
|
28021
|
+
* enabled. It brings in the appropriate version of the method that
|
|
28022
|
+
* supports hydration only when enabled.
|
|
28023
|
+
*/
|
|
28024
|
+
function enableHydrationRuntimeSupport() {
|
|
28025
|
+
if (!isHydrationSupportEnabled) {
|
|
28026
|
+
isHydrationSupportEnabled = true;
|
|
28027
|
+
enableRetrieveHydrationInfoImpl();
|
|
28028
|
+
enableLocateOrCreateElementNodeImpl();
|
|
28029
|
+
enableLocateOrCreateTextNodeImpl();
|
|
28030
|
+
enableLocateOrCreateElementContainerNodeImpl();
|
|
28031
|
+
}
|
|
28032
|
+
}
|
|
28033
|
+
/**
|
|
28034
|
+
* Detects whether the code is invoked in a browser.
|
|
28035
|
+
* Later on, this check should be replaced with a tree-shakable
|
|
28036
|
+
* flag (e.g. `!isServer`).
|
|
28037
|
+
*/
|
|
28038
|
+
function isBrowser() {
|
|
28039
|
+
return inject(PLATFORM_ID) === 'browser';
|
|
28040
|
+
}
|
|
28041
|
+
/**
|
|
28042
|
+
* Returns a set of providers required to setup hydration support
|
|
28043
|
+
* for an application that is server side rendered.
|
|
28044
|
+
*
|
|
28045
|
+
* ## NgModule-based bootstrap
|
|
28046
|
+
*
|
|
28047
|
+
* You can add the function call to the root AppModule of an application:
|
|
28048
|
+
* ```
|
|
28049
|
+
* import {provideHydrationSupport} from '@angular/core';
|
|
28050
|
+
*
|
|
28051
|
+
* @NgModule({
|
|
28052
|
+
* providers: [
|
|
28053
|
+
* // ... other providers ...
|
|
28054
|
+
* provideHydrationSupport()
|
|
28055
|
+
* ],
|
|
28056
|
+
* declarations: [AppComponent],
|
|
28057
|
+
* bootstrap: [AppComponent]
|
|
28058
|
+
* })
|
|
28059
|
+
* class AppModule {}
|
|
28060
|
+
* ```
|
|
28061
|
+
*
|
|
28062
|
+
* ## Standalone-based bootstrap
|
|
28063
|
+
*
|
|
28064
|
+
* Add the function to the `bootstrapApplication` call:
|
|
28065
|
+
* ```
|
|
28066
|
+
* import {provideHydrationSupport} from '@angular/core';
|
|
28067
|
+
*
|
|
28068
|
+
* bootstrapApplication(RootComponent, {
|
|
28069
|
+
* providers: [
|
|
28070
|
+
* // ... other providers ...
|
|
28071
|
+
* provideHydrationSupport()
|
|
28072
|
+
* ]
|
|
28073
|
+
* });
|
|
28074
|
+
* ```
|
|
28075
|
+
*
|
|
28076
|
+
* The function sets up an internal flag that would be recognized during
|
|
28077
|
+
* the server side rendering time as well, so there is no need to
|
|
28078
|
+
* configure or change anything in NgUniversal to enable the feature.
|
|
28079
|
+
*
|
|
28080
|
+
* @publicApi
|
|
28081
|
+
* @developerPreview
|
|
28082
|
+
*/
|
|
28083
|
+
function provideHydrationSupport() {
|
|
28084
|
+
return makeEnvironmentProviders([
|
|
28085
|
+
{
|
|
28086
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
28087
|
+
useValue: () => {
|
|
28088
|
+
// Since this function is used across both server and client,
|
|
28089
|
+
// make sure that the runtime code is only added when invoked
|
|
28090
|
+
// on the client. Moving forward, the `isBrowser` check should
|
|
28091
|
+
// be replaced with a tree-shakable alternative (e.g. `isServer`
|
|
28092
|
+
// flag).
|
|
28093
|
+
if (isBrowser()) {
|
|
28094
|
+
enableHydrationRuntimeSupport();
|
|
28095
|
+
}
|
|
28096
|
+
},
|
|
28097
|
+
multi: true,
|
|
28098
|
+
},
|
|
28099
|
+
{
|
|
28100
|
+
provide: IS_HYDRATION_FEATURE_ENABLED,
|
|
28101
|
+
useValue: true,
|
|
28102
|
+
},
|
|
28103
|
+
{
|
|
28104
|
+
provide: PRESERVE_HOST_CONTENT,
|
|
28105
|
+
// Preserve host element content only in a browser
|
|
28106
|
+
// environment. On a server, an application is rendered
|
|
28107
|
+
// from scratch, so the host content needs to be empty.
|
|
28108
|
+
useFactory: () => isBrowser(),
|
|
28109
|
+
}
|
|
28110
|
+
]);
|
|
28111
|
+
}
|
|
28112
|
+
|
|
27353
28113
|
/** Coerces a value (typically a string) to a boolean. */
|
|
27354
28114
|
function coerceToBoolean(value) {
|
|
27355
28115
|
return typeof value === 'boolean' ? value : (value != null && value !== 'false');
|
|
27356
28116
|
}
|
|
27357
28117
|
|
|
27358
|
-
// TODO(alxhub): allows tests to compile, can be removed when tests have been updated.
|
|
27359
|
-
const ɵivyEnabled = true;
|
|
27360
|
-
|
|
27361
28118
|
/**
|
|
27362
28119
|
* Compiles a partial directive declaration object into a full directive definition object.
|
|
27363
28120
|
*
|
|
@@ -28058,6 +28815,20 @@ function reflectComponentType(component) {
|
|
|
28058
28815
|
};
|
|
28059
28816
|
}
|
|
28060
28817
|
|
|
28818
|
+
/**
|
|
28819
|
+
* Merge multiple application configurations from left to right.
|
|
28820
|
+
*
|
|
28821
|
+
* @param configs Two or more configurations to be merged.
|
|
28822
|
+
* @returns A merged [ApplicationConfig](api/core/ApplicationConfig).
|
|
28823
|
+
*
|
|
28824
|
+
* @publicApi
|
|
28825
|
+
*/
|
|
28826
|
+
function mergeApplicationConfig(...configs) {
|
|
28827
|
+
return configs.reduce((prev, curr) => {
|
|
28828
|
+
return Object.assign(prev, curr, { providers: [...prev.providers, ...curr.providers] });
|
|
28829
|
+
}, { providers: [] });
|
|
28830
|
+
}
|
|
28831
|
+
|
|
28061
28832
|
/**
|
|
28062
28833
|
* @module
|
|
28063
28834
|
* @description
|
|
@@ -28093,5 +28864,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
28093
28864
|
* Generated bundle index. Do not edit.
|
|
28094
28865
|
*/
|
|
28095
28866
|
|
|
28096
|
-
export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, 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, 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, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, platformCore, reflectComponentType, resolveForwardRef, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, APP_ID_RANDOM_PROVIDER as ɵAPP_ID_RANDOM_PROVIDER,
|
|
28867
|
+
export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, 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, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, mergeApplicationConfig, platformCore, reflectComponentType, resolveForwardRef, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, APP_ID_RANDOM_PROVIDER as ɵAPP_ID_RANDOM_PROVIDER, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_FEATURE_ENABLED as ɵIS_HYDRATION_FEATURE_ENABLED, 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, TransferState as ɵTransferState, 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, coerceToBoolean as ɵcoerceToBoolean, 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, escapeTransferStateContent as ɵescapeTransferStateContent, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getComponentDef as ɵgetComponentDef, 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, makeDecorator as ɵmakeDecorator, makeStateKey as ɵmakeStateKey, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, provideHydrationSupport as ɵprovideHydrationSupport, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unescapeTransferStateContent as ɵunescapeTransferStateContent, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵ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 };
|
|
28097
28868
|
//# sourceMappingURL=core.mjs.map
|