@angular/core 16.0.0-rc.4 → 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/src/application_ref.mjs +60 -55
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/hydration/annotate.mjs +1 -1
- package/esm2022/src/hydration/api.mjs +2 -2
- package/esm2022/src/hydration/skip_hydration.mjs +12 -1
- package/esm2022/src/hydration/utils.mjs +9 -3
- package/esm2022/src/linker/element_ref.mjs +1 -1
- package/esm2022/src/linker/view_container_ref.mjs +16 -6
- package/esm2022/src/render/api.mjs +1 -1
- package/esm2022/src/render3/definition.mjs +6 -3
- package/esm2022/src/render3/instructions/element_validation.mjs +2 -2
- package/esm2022/src/render3/instructions/shared.mjs +7 -3
- package/esm2022/src/render3/interfaces/document.mjs +6 -4
- package/esm2022/src/render3/interfaces/node.mjs +1 -1
- package/esm2022/src/render3/node_manipulation.mjs +7 -1
- package/esm2022/src/transfer_state.mjs +8 -7
- package/esm2022/src/util/assert.mjs +2 -5
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/logger.mjs +3 -3
- package/esm2022/testing/src/test_bed.mjs +4 -4
- package/fesm2022/core.mjs +163 -120
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +105 -67
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +9 -17
- package/package.json +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +13 -13
- package/schematics/migrations/remove-module-id/bundle.js +14 -14
- package/schematics/ng-generate/standalone-migration/bundle.js +415 -361
- package/schematics/ng-generate/standalone-migration/bundle.js.map +3 -3
- package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v16.0.
|
|
2
|
+
* @license Angular v16.0.1
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -302,10 +302,7 @@ function throwError(msg, actual, expected, comparison) {
|
|
|
302
302
|
(comparison == null ? '' : ` [Expected=> ${expected} ${comparison} ${actual} <=Actual]`));
|
|
303
303
|
}
|
|
304
304
|
function assertDomNode(node) {
|
|
305
|
-
|
|
306
|
-
if (!(typeof Node !== 'undefined' && node instanceof Node) &&
|
|
307
|
-
!(typeof node === 'object' && node != null &&
|
|
308
|
-
node.constructor.name === 'WebWorkerRenderNode')) {
|
|
305
|
+
if (!(node instanceof Node)) {
|
|
309
306
|
throwError(`The provided value must be an instance of a DOM Node but got ${stringify(node)}`);
|
|
310
307
|
}
|
|
311
308
|
}
|
|
@@ -1893,7 +1890,7 @@ function getComponentId(componentDef) {
|
|
|
1893
1890
|
// Example:
|
|
1894
1891
|
// https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248
|
|
1895
1892
|
// https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32
|
|
1896
|
-
const hashSelectors = [
|
|
1893
|
+
const hashSelectors = JSON.stringify([
|
|
1897
1894
|
componentDef.selectors,
|
|
1898
1895
|
componentDef.ngContentSelectors,
|
|
1899
1896
|
componentDef.hostVars,
|
|
@@ -1903,12 +1900,15 @@ function getComponentId(componentDef) {
|
|
|
1903
1900
|
componentDef.decls,
|
|
1904
1901
|
componentDef.encapsulation,
|
|
1905
1902
|
componentDef.standalone,
|
|
1903
|
+
componentDef.exportAs,
|
|
1904
|
+
componentDef.inputs,
|
|
1905
|
+
componentDef.outputs,
|
|
1906
1906
|
// We cannot use 'componentDef.type.name' as the name of the symbol will change and will not
|
|
1907
1907
|
// match in the server and browser bundles.
|
|
1908
1908
|
Object.getOwnPropertyNames(componentDef.type.prototype),
|
|
1909
1909
|
!!componentDef.contentQueries,
|
|
1910
1910
|
!!componentDef.viewQuery,
|
|
1911
|
-
]
|
|
1911
|
+
]);
|
|
1912
1912
|
for (const char of hashSelectors) {
|
|
1913
1913
|
hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;
|
|
1914
1914
|
}
|
|
@@ -5989,7 +5989,7 @@ function isPropertyValid(element, propName, tagName, schemas) {
|
|
|
5989
5989
|
if (schemas === null)
|
|
5990
5990
|
return true;
|
|
5991
5991
|
// The property is considered valid if the element matches the schema, it exists on the element,
|
|
5992
|
-
// or it is synthetic
|
|
5992
|
+
// or it is synthetic.
|
|
5993
5993
|
if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
|
|
5994
5994
|
return true;
|
|
5995
5995
|
}
|
|
@@ -6131,6 +6131,59 @@ function matchingSchemas(schemas, tagName) {
|
|
|
6131
6131
|
return false;
|
|
6132
6132
|
}
|
|
6133
6133
|
|
|
6134
|
+
/**
|
|
6135
|
+
* The name of an attribute that can be added to the hydration boundary node
|
|
6136
|
+
* (component host node) to disable hydration for the content within that boundary.
|
|
6137
|
+
*/
|
|
6138
|
+
const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';
|
|
6139
|
+
/**
|
|
6140
|
+
* Helper function to check if a given node has the 'ngSkipHydration' attribute
|
|
6141
|
+
*/
|
|
6142
|
+
function hasNgSkipHydrationAttr(tNode) {
|
|
6143
|
+
const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = SKIP_HYDRATION_ATTR_NAME.toLowerCase();
|
|
6144
|
+
const attrs = tNode.mergedAttrs;
|
|
6145
|
+
if (attrs === null)
|
|
6146
|
+
return false;
|
|
6147
|
+
// only ever look at the attribute name and skip the values
|
|
6148
|
+
for (let i = 0; i < attrs.length; i += 2) {
|
|
6149
|
+
const value = attrs[i];
|
|
6150
|
+
// This is a marker, which means that the static attributes section is over,
|
|
6151
|
+
// so we can exit early.
|
|
6152
|
+
if (typeof value === 'number')
|
|
6153
|
+
return false;
|
|
6154
|
+
if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {
|
|
6155
|
+
return true;
|
|
6156
|
+
}
|
|
6157
|
+
}
|
|
6158
|
+
return false;
|
|
6159
|
+
}
|
|
6160
|
+
/**
|
|
6161
|
+
* Checks whether a TNode has a flag to indicate that it's a part of
|
|
6162
|
+
* a skip hydration block.
|
|
6163
|
+
*/
|
|
6164
|
+
function hasInSkipHydrationBlockFlag(tNode) {
|
|
6165
|
+
return (tNode.flags & 128 /* TNodeFlags.inSkipHydrationBlock */) === 128 /* TNodeFlags.inSkipHydrationBlock */;
|
|
6166
|
+
}
|
|
6167
|
+
/**
|
|
6168
|
+
* Helper function that determines if a given node is within a skip hydration block
|
|
6169
|
+
* by navigating up the TNode tree to see if any parent nodes have skip hydration
|
|
6170
|
+
* attribute.
|
|
6171
|
+
*
|
|
6172
|
+
* TODO(akushnir): this function should contain the logic of `hasInSkipHydrationBlockFlag`,
|
|
6173
|
+
* there is no need to traverse parent nodes when we have a TNode flag (which would also
|
|
6174
|
+
* make this lookup O(1)).
|
|
6175
|
+
*/
|
|
6176
|
+
function isInSkipHydrationBlock(tNode) {
|
|
6177
|
+
let currentTNode = tNode.parent;
|
|
6178
|
+
while (currentTNode) {
|
|
6179
|
+
if (hasNgSkipHydrationAttr(currentTNode)) {
|
|
6180
|
+
return true;
|
|
6181
|
+
}
|
|
6182
|
+
currentTNode = currentTNode.parent;
|
|
6183
|
+
}
|
|
6184
|
+
return false;
|
|
6185
|
+
}
|
|
6186
|
+
|
|
6134
6187
|
/**
|
|
6135
6188
|
* Flags for renderer-specific style modifiers.
|
|
6136
6189
|
* @publicApi
|
|
@@ -7430,6 +7483,11 @@ function applyProjectionRecursive(renderer, action, lView, tProjectionNode, pare
|
|
|
7430
7483
|
else {
|
|
7431
7484
|
let nodeToProject = nodeToProjectOrRNodes;
|
|
7432
7485
|
const projectedComponentLView = componentLView[PARENT];
|
|
7486
|
+
// If a parent <ng-content> is located within a skip hydration block,
|
|
7487
|
+
// annotate an actual node that is being projected with the same flag too.
|
|
7488
|
+
if (hasInSkipHydrationBlockFlag(tProjectionNode)) {
|
|
7489
|
+
nodeToProject.flags |= 128 /* TNodeFlags.inSkipHydrationBlock */;
|
|
7490
|
+
}
|
|
7433
7491
|
applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
|
|
7434
7492
|
}
|
|
7435
7493
|
}
|
|
@@ -7730,7 +7788,7 @@ function ɵɵvalidateIframeAttribute(attrValue, tagName, attrName) {
|
|
|
7730
7788
|
* When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
|
|
7731
7789
|
* tell ivy what the global `document` is.
|
|
7732
7790
|
*
|
|
7733
|
-
* Angular does this for us in each of the standard platforms (`Browser
|
|
7791
|
+
* Angular does this for us in each of the standard platforms (`Browser` and `Server`)
|
|
7734
7792
|
* by calling `setDocument()` when providing the `DOCUMENT` token.
|
|
7735
7793
|
*/
|
|
7736
7794
|
let DOCUMENT = undefined;
|
|
@@ -7757,12 +7815,13 @@ function getDocument() {
|
|
|
7757
7815
|
else if (typeof document !== 'undefined') {
|
|
7758
7816
|
return document;
|
|
7759
7817
|
}
|
|
7818
|
+
throw new RuntimeError(210 /* RuntimeErrorCode.MISSING_DOCUMENT */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
7819
|
+
`The document object is not available in this context. Make sure the DOCUMENT injection token is provided.`);
|
|
7760
7820
|
// No "document" can be found. This should only happen if we are running ivy outside Angular and
|
|
7761
7821
|
// the current platform is not a browser. Since this is not a supported scenario at the moment
|
|
7762
7822
|
// this should not happen in Angular apps.
|
|
7763
7823
|
// Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
|
|
7764
|
-
// public API.
|
|
7765
|
-
return undefined;
|
|
7824
|
+
// public API.
|
|
7766
7825
|
}
|
|
7767
7826
|
|
|
7768
7827
|
/**
|
|
@@ -9468,7 +9527,9 @@ function makeStateKey(key) {
|
|
|
9468
9527
|
}
|
|
9469
9528
|
function initTransferState() {
|
|
9470
9529
|
const transferState = new TransferState();
|
|
9471
|
-
|
|
9530
|
+
if (inject(PLATFORM_ID) === 'browser') {
|
|
9531
|
+
transferState.store = retrieveTransferredState(getDocument(), inject(APP_ID));
|
|
9532
|
+
}
|
|
9472
9533
|
return transferState;
|
|
9473
9534
|
}
|
|
9474
9535
|
/**
|
|
@@ -9557,17 +9618,16 @@ function retrieveTransferredState(doc, appId) {
|
|
|
9557
9618
|
// Locate the script tag with the JSON data transferred from the server.
|
|
9558
9619
|
// The id of the script tag is set to the Angular appId + 'state'.
|
|
9559
9620
|
const script = doc.getElementById(appId + '-state');
|
|
9560
|
-
|
|
9561
|
-
if (script && script.textContent) {
|
|
9621
|
+
if (script?.textContent) {
|
|
9562
9622
|
try {
|
|
9563
9623
|
// Avoid using any here as it triggers lint errors in google3 (any is not allowed).
|
|
9564
|
-
|
|
9624
|
+
return JSON.parse(unescapeTransferStateContent(script.textContent));
|
|
9565
9625
|
}
|
|
9566
9626
|
catch (e) {
|
|
9567
9627
|
console.warn('Exception while restoring TransferState for app ' + appId, e);
|
|
9568
9628
|
}
|
|
9569
9629
|
}
|
|
9570
|
-
return
|
|
9630
|
+
return {};
|
|
9571
9631
|
}
|
|
9572
9632
|
|
|
9573
9633
|
/** Encodes that the node lookup should start from the host node of this component. */
|
|
@@ -9686,6 +9746,12 @@ function getComponentLViewForHydration(viewRef) {
|
|
|
9686
9746
|
if (isRootView(lView)) {
|
|
9687
9747
|
lView = lView[HEADER_OFFSET];
|
|
9688
9748
|
}
|
|
9749
|
+
// If a `ViewContainerRef` was injected in a component class, this resulted
|
|
9750
|
+
// in an LContainer creation at that location. In this case, the component
|
|
9751
|
+
// LView is in the LContainer's `HOST` slot.
|
|
9752
|
+
if (isLContainer(lView)) {
|
|
9753
|
+
lView = lView[HOST];
|
|
9754
|
+
}
|
|
9689
9755
|
return lView;
|
|
9690
9756
|
}
|
|
9691
9757
|
function getTextNodeContent(node) {
|
|
@@ -9981,7 +10047,7 @@ class Version {
|
|
|
9981
10047
|
/**
|
|
9982
10048
|
* @publicApi
|
|
9983
10049
|
*/
|
|
9984
|
-
const VERSION = new Version('16.0.
|
|
10050
|
+
const VERSION = new Version('16.0.1');
|
|
9985
10051
|
|
|
9986
10052
|
// This default value is when checking the hierarchy for a token.
|
|
9987
10053
|
//
|
|
@@ -10087,48 +10153,6 @@ class ErrorHandler {
|
|
|
10087
10153
|
}
|
|
10088
10154
|
}
|
|
10089
10155
|
|
|
10090
|
-
/**
|
|
10091
|
-
* The name of an attribute that can be added to the hydration boundary node
|
|
10092
|
-
* (component host node) to disable hydration for the content within that boundary.
|
|
10093
|
-
*/
|
|
10094
|
-
const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';
|
|
10095
|
-
/**
|
|
10096
|
-
* Helper function to check if a given node has the 'ngSkipHydration' attribute
|
|
10097
|
-
*/
|
|
10098
|
-
function hasNgSkipHydrationAttr(tNode) {
|
|
10099
|
-
const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = SKIP_HYDRATION_ATTR_NAME.toLowerCase();
|
|
10100
|
-
const attrs = tNode.mergedAttrs;
|
|
10101
|
-
if (attrs === null)
|
|
10102
|
-
return false;
|
|
10103
|
-
// only ever look at the attribute name and skip the values
|
|
10104
|
-
for (let i = 0; i < attrs.length; i += 2) {
|
|
10105
|
-
const value = attrs[i];
|
|
10106
|
-
// This is a marker, which means that the static attributes section is over,
|
|
10107
|
-
// so we can exit early.
|
|
10108
|
-
if (typeof value === 'number')
|
|
10109
|
-
return false;
|
|
10110
|
-
if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {
|
|
10111
|
-
return true;
|
|
10112
|
-
}
|
|
10113
|
-
}
|
|
10114
|
-
return false;
|
|
10115
|
-
}
|
|
10116
|
-
/**
|
|
10117
|
-
* Helper function that determines if a given node is within a skip hydration block
|
|
10118
|
-
* by navigating up the TNode tree to see if any parent nodes have skip hydration
|
|
10119
|
-
* attribute.
|
|
10120
|
-
*/
|
|
10121
|
-
function isInSkipHydrationBlock(tNode) {
|
|
10122
|
-
let currentTNode = tNode.parent;
|
|
10123
|
-
while (currentTNode) {
|
|
10124
|
-
if (hasNgSkipHydrationAttr(currentTNode)) {
|
|
10125
|
-
return true;
|
|
10126
|
-
}
|
|
10127
|
-
currentTNode = currentTNode.parent;
|
|
10128
|
-
}
|
|
10129
|
-
return false;
|
|
10130
|
-
}
|
|
10131
|
-
|
|
10132
10156
|
/**
|
|
10133
10157
|
* Internal token that specifies whether DOM reuse logic
|
|
10134
10158
|
* during hydration is enabled.
|
|
@@ -11123,6 +11147,10 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
11123
11147
|
ngDevMode && ngDevMode.tNode++;
|
|
11124
11148
|
ngDevMode && tParent && assertTNodeForTView(tParent, tView);
|
|
11125
11149
|
let injectorIndex = tParent ? tParent.injectorIndex : -1;
|
|
11150
|
+
let flags = 0;
|
|
11151
|
+
if (isInSkipHydrationBlock$1()) {
|
|
11152
|
+
flags |= 128 /* TNodeFlags.inSkipHydrationBlock */;
|
|
11153
|
+
}
|
|
11126
11154
|
const tNode = {
|
|
11127
11155
|
type,
|
|
11128
11156
|
index,
|
|
@@ -11133,7 +11161,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
11133
11161
|
directiveStylingLast: -1,
|
|
11134
11162
|
componentOffset: -1,
|
|
11135
11163
|
propertyBindings: null,
|
|
11136
|
-
flags
|
|
11164
|
+
flags,
|
|
11137
11165
|
providerIndexes: 0,
|
|
11138
11166
|
value: value,
|
|
11139
11167
|
attrs: attrs,
|
|
@@ -23121,7 +23149,11 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
|
23121
23149
|
}
|
|
23122
23150
|
const hydrationInfo = findMatchingDehydratedView(this._lContainer, templateRef.ssrId);
|
|
23123
23151
|
const viewRef = templateRef.createEmbeddedViewImpl(context || {}, injector, hydrationInfo);
|
|
23124
|
-
|
|
23152
|
+
// If there is a matching dehydrated view, but the host TNode is located in the skip
|
|
23153
|
+
// hydration block, this means that the content was detached (as a part of the skip
|
|
23154
|
+
// hydration logic) and it needs to be appended into the DOM.
|
|
23155
|
+
const skipDomInsertion = !!hydrationInfo && !hasInSkipHydrationBlockFlag(this._hostTNode);
|
|
23156
|
+
this.insertImpl(viewRef, index, skipDomInsertion);
|
|
23125
23157
|
return viewRef;
|
|
23126
23158
|
}
|
|
23127
23159
|
createComponent(componentFactoryOrType, indexOrOptions, injector, projectableNodes, environmentInjector) {
|
|
@@ -23195,7 +23227,11 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
|
|
|
23195
23227
|
const dehydratedView = findMatchingDehydratedView(this._lContainer, componentDef?.id ?? null);
|
|
23196
23228
|
const rNode = dehydratedView?.firstChild ?? null;
|
|
23197
23229
|
const componentRef = componentFactory.create(contextInjector, projectableNodes, rNode, environmentInjector);
|
|
23198
|
-
|
|
23230
|
+
// If there is a matching dehydrated view, but the host TNode is located in the skip
|
|
23231
|
+
// hydration block, this means that the content was detached (as a part of the skip
|
|
23232
|
+
// hydration logic) and it needs to be appended into the DOM.
|
|
23233
|
+
const skipDomInsertion = !!dehydratedView && !hasInSkipHydrationBlockFlag(this._hostTNode);
|
|
23234
|
+
this.insertImpl(componentRef.hostView, index, skipDomInsertion);
|
|
23199
23235
|
return componentRef;
|
|
23200
23236
|
}
|
|
23201
23237
|
insert(viewRef, index) {
|
|
@@ -23369,8 +23405,10 @@ function locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
|
|
|
23369
23405
|
return;
|
|
23370
23406
|
const hydrationInfo = hostLView[HYDRATION];
|
|
23371
23407
|
const noOffsetIndex = hostTNode.index - HEADER_OFFSET;
|
|
23372
|
-
|
|
23373
|
-
|
|
23408
|
+
// TODO(akushnir): this should really be a single condition, refactor the code
|
|
23409
|
+
// to use `hasInSkipHydrationBlockFlag` logic inside `isInSkipHydrationBlock`.
|
|
23410
|
+
const skipHydration = isInSkipHydrationBlock(hostTNode) || hasInSkipHydrationBlockFlag(hostTNode);
|
|
23411
|
+
const isNodeCreationMode = !hydrationInfo || skipHydration || isDisconnectedNode$1(hydrationInfo, noOffsetIndex);
|
|
23374
23412
|
// Regular creation mode.
|
|
23375
23413
|
if (isNodeCreationMode) {
|
|
23376
23414
|
return createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
|
|
@@ -26650,64 +26688,69 @@ function runPlatformInitializers(injector) {
|
|
|
26650
26688
|
* @returns A promise that returns an `ApplicationRef` instance once resolved.
|
|
26651
26689
|
*/
|
|
26652
26690
|
function internalCreateApplication(config) {
|
|
26653
|
-
|
|
26654
|
-
|
|
26655
|
-
|
|
26656
|
-
|
|
26657
|
-
|
|
26658
|
-
|
|
26659
|
-
|
|
26660
|
-
|
|
26661
|
-
|
|
26662
|
-
|
|
26663
|
-
|
|
26664
|
-
|
|
26665
|
-
|
|
26666
|
-
|
|
26667
|
-
|
|
26668
|
-
|
|
26669
|
-
|
|
26670
|
-
|
|
26671
|
-
|
|
26672
|
-
const envInjector = adapter.injector;
|
|
26673
|
-
const ngZone = envInjector.get(NgZone);
|
|
26674
|
-
return ngZone.run(() => {
|
|
26675
|
-
envInjector.resolveInjectorInitializers();
|
|
26676
|
-
const exceptionHandler = envInjector.get(ErrorHandler, null);
|
|
26677
|
-
if ((typeof ngDevMode === 'undefined' || ngDevMode) && !exceptionHandler) {
|
|
26678
|
-
throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, 'No `ErrorHandler` found in the Dependency Injection tree.');
|
|
26679
|
-
}
|
|
26680
|
-
let onErrorSubscription;
|
|
26681
|
-
ngZone.runOutsideAngular(() => {
|
|
26682
|
-
onErrorSubscription = ngZone.onError.subscribe({
|
|
26683
|
-
next: (error) => {
|
|
26684
|
-
exceptionHandler.handleError(error);
|
|
26685
|
-
}
|
|
26686
|
-
});
|
|
26687
|
-
});
|
|
26688
|
-
// If the whole platform is destroyed, invoke the `destroy` method
|
|
26689
|
-
// for all bootstrapped applications as well.
|
|
26690
|
-
const destroyListener = () => envInjector.destroy();
|
|
26691
|
-
const onPlatformDestroyListeners = platformInjector.get(PLATFORM_DESTROY_LISTENERS);
|
|
26692
|
-
onPlatformDestroyListeners.add(destroyListener);
|
|
26693
|
-
envInjector.onDestroy(() => {
|
|
26694
|
-
onErrorSubscription.unsubscribe();
|
|
26695
|
-
onPlatformDestroyListeners.delete(destroyListener);
|
|
26691
|
+
try {
|
|
26692
|
+
const { rootComponent, appProviders, platformProviders } = config;
|
|
26693
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) && rootComponent !== undefined) {
|
|
26694
|
+
assertStandaloneComponentType(rootComponent);
|
|
26695
|
+
}
|
|
26696
|
+
const platformInjector = createOrReusePlatformInjector(platformProviders);
|
|
26697
|
+
// Create root application injector based on a set of providers configured at the platform
|
|
26698
|
+
// bootstrap level as well as providers passed to the bootstrap call by a user.
|
|
26699
|
+
const allAppProviders = [
|
|
26700
|
+
provideZoneChangeDetection(),
|
|
26701
|
+
...(appProviders || []),
|
|
26702
|
+
];
|
|
26703
|
+
const adapter = new EnvironmentNgModuleRefAdapter({
|
|
26704
|
+
providers: allAppProviders,
|
|
26705
|
+
parent: platformInjector,
|
|
26706
|
+
debugName: (typeof ngDevMode === 'undefined' || ngDevMode) ? 'Environment Injector' : '',
|
|
26707
|
+
// We skip environment initializers because we need to run them inside the NgZone, which
|
|
26708
|
+
// happens after we get the NgZone instance from the Injector.
|
|
26709
|
+
runEnvironmentInitializers: false,
|
|
26696
26710
|
});
|
|
26697
|
-
|
|
26698
|
-
|
|
26699
|
-
|
|
26700
|
-
|
|
26701
|
-
|
|
26702
|
-
|
|
26703
|
-
|
|
26704
|
-
|
|
26705
|
-
|
|
26706
|
-
|
|
26707
|
-
|
|
26711
|
+
const envInjector = adapter.injector;
|
|
26712
|
+
const ngZone = envInjector.get(NgZone);
|
|
26713
|
+
return ngZone.run(() => {
|
|
26714
|
+
envInjector.resolveInjectorInitializers();
|
|
26715
|
+
const exceptionHandler = envInjector.get(ErrorHandler, null);
|
|
26716
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) && !exceptionHandler) {
|
|
26717
|
+
throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, 'No `ErrorHandler` found in the Dependency Injection tree.');
|
|
26718
|
+
}
|
|
26719
|
+
let onErrorSubscription;
|
|
26720
|
+
ngZone.runOutsideAngular(() => {
|
|
26721
|
+
onErrorSubscription = ngZone.onError.subscribe({
|
|
26722
|
+
next: (error) => {
|
|
26723
|
+
exceptionHandler.handleError(error);
|
|
26724
|
+
}
|
|
26725
|
+
});
|
|
26726
|
+
});
|
|
26727
|
+
// If the whole platform is destroyed, invoke the `destroy` method
|
|
26728
|
+
// for all bootstrapped applications as well.
|
|
26729
|
+
const destroyListener = () => envInjector.destroy();
|
|
26730
|
+
const onPlatformDestroyListeners = platformInjector.get(PLATFORM_DESTROY_LISTENERS);
|
|
26731
|
+
onPlatformDestroyListeners.add(destroyListener);
|
|
26732
|
+
envInjector.onDestroy(() => {
|
|
26733
|
+
onErrorSubscription.unsubscribe();
|
|
26734
|
+
onPlatformDestroyListeners.delete(destroyListener);
|
|
26735
|
+
});
|
|
26736
|
+
return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
|
|
26737
|
+
const initStatus = envInjector.get(ApplicationInitStatus);
|
|
26738
|
+
initStatus.runInitializers();
|
|
26739
|
+
return initStatus.donePromise.then(() => {
|
|
26740
|
+
const localeId = envInjector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
|
|
26741
|
+
setLocaleId(localeId || DEFAULT_LOCALE_ID);
|
|
26742
|
+
const appRef = envInjector.get(ApplicationRef);
|
|
26743
|
+
if (rootComponent !== undefined) {
|
|
26744
|
+
appRef.bootstrap(rootComponent);
|
|
26745
|
+
}
|
|
26746
|
+
return appRef;
|
|
26747
|
+
});
|
|
26708
26748
|
});
|
|
26709
26749
|
});
|
|
26710
|
-
}
|
|
26750
|
+
}
|
|
26751
|
+
catch (e) {
|
|
26752
|
+
return Promise.reject(e);
|
|
26753
|
+
}
|
|
26711
26754
|
}
|
|
26712
26755
|
/**
|
|
26713
26756
|
* Creates a factory for a platform. Can be used to provide or override `Providers` specific to
|
|
@@ -29818,7 +29861,7 @@ function printHydrationStats(injector) {
|
|
|
29818
29861
|
`and ${ngDevMode.hydratedNodes} node(s), ` +
|
|
29819
29862
|
`${ngDevMode.componentsSkippedHydration} component(s) were skipped. ` +
|
|
29820
29863
|
`Note: this feature is in Developer Preview mode. ` +
|
|
29821
|
-
`Learn more at https://
|
|
29864
|
+
`Learn more at https://angular.io/guide/hydration.`;
|
|
29822
29865
|
// tslint:disable-next-line:no-console
|
|
29823
29866
|
console.log(message);
|
|
29824
29867
|
}
|