@angular/core 17.3.0-rc.0 → 17.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/src/application/application_ref.mjs +14 -11
- package/esm2022/src/authoring/input/input.mjs +4 -1
- package/esm2022/src/authoring/output/output.mjs +2 -2
- package/esm2022/src/authoring/output/output_emitter_ref.mjs +14 -3
- package/esm2022/src/authoring/queries.mjs +7 -1
- package/esm2022/src/change_detection/scheduling/zoneless_scheduling.mjs +1 -1
- package/esm2022/src/change_detection/scheduling/zoneless_scheduling_impl.mjs +10 -4
- package/esm2022/src/core_private_export.mjs +2 -3
- package/esm2022/src/di/contextual.mjs +9 -3
- package/esm2022/src/event_emitter.mjs +6 -7
- package/esm2022/src/hydration/annotate.mjs +4 -2
- package/esm2022/src/hydration/api.mjs +27 -2
- package/esm2022/src/hydration/cleanup.mjs +18 -2
- package/esm2022/src/hydration/interfaces.mjs +1 -1
- package/esm2022/src/hydration/node_lookup_utils.mjs +59 -39
- package/esm2022/src/hydration/tokens.mjs +6 -1
- package/esm2022/src/i18n/utils.mjs +16 -0
- package/esm2022/src/render3/after_render_hooks.mjs +11 -8
- package/esm2022/src/render3/component_ref.mjs +1 -1
- package/esm2022/src/render3/i18n/i18n_apply.mjs +32 -7
- package/esm2022/src/render3/i18n/i18n_parse.mjs +50 -16
- package/esm2022/src/render3/instructions/control_flow.mjs +4 -2
- package/esm2022/src/render3/instructions/element.mjs +5 -3
- package/esm2022/src/render3/instructions/element_container.mjs +3 -2
- package/esm2022/src/render3/instructions/template.mjs +4 -2
- package/esm2022/src/render3/instructions/text.mjs +4 -2
- package/esm2022/src/render3/interfaces/i18n.mjs +1 -1
- package/esm2022/src/render3/node_manipulation.mjs +6 -2
- package/esm2022/src/render3/node_selector_matcher.mjs +37 -51
- package/esm2022/src/render3/queue_state_update.mjs +2 -4
- package/esm2022/src/render3/util/view_utils.mjs +2 -1
- package/esm2022/src/sanitization/html_sanitizer.mjs +54 -14
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/component_fixture.mjs +11 -66
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +629 -436
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +11 -66
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +96 -12
- package/package.json +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/block-template-entities/bundle.js +8 -2
- package/schematics/migrations/block-template-entities/bundle.js.map +2 -2
- package/schematics/migrations/invalid-two-way-bindings/bundle.js +8 -2
- package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
- package/schematics/ng-generate/control-flow-migration/bundle.js +8 -2
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
- package/schematics/ng-generate/standalone-migration/bundle.js +356 -294
- package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
- package/testing/index.d.ts +1 -1
- package/esm2022/src/is_internal.mjs +0 -15
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.3.0
|
|
2
|
+
* @license Angular v17.3.0
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -1966,47 +1966,40 @@ const NG_TEMPLATE_SELECTOR = 'ng-template';
|
|
|
1966
1966
|
/**
|
|
1967
1967
|
* Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
|
|
1968
1968
|
*
|
|
1969
|
+
* @param tNode static data of the node to match
|
|
1969
1970
|
* @param attrs `TAttributes` to search through.
|
|
1970
1971
|
* @param cssClassToMatch class to match (lowercase)
|
|
1971
1972
|
* @param isProjectionMode Whether or not class matching should look into the attribute `class` in
|
|
1972
1973
|
* addition to the `AttributeMarker.Classes`.
|
|
1973
1974
|
*/
|
|
1974
|
-
function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
|
|
1975
|
-
// TODO(misko): The fact that this function needs to know about `isProjectionMode` seems suspect.
|
|
1976
|
-
// It is strange to me that sometimes the class information comes in form of `class` attribute
|
|
1977
|
-
// and sometimes in form of `AttributeMarker.Classes`. Some investigation is needed to determine
|
|
1978
|
-
// if that is the right behavior.
|
|
1975
|
+
function isCssClassMatching(tNode, attrs, cssClassToMatch, isProjectionMode) {
|
|
1979
1976
|
ngDevMode &&
|
|
1980
1977
|
assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
|
|
1981
1978
|
let i = 0;
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
const value = attrs[i++];
|
|
1989
|
-
if (isProjectionMode && item === 'class') {
|
|
1990
|
-
// We found a `class` attribute in the implicit attribute section,
|
|
1991
|
-
// check if it matches the value of the `cssClassToMatch` argument.
|
|
1992
|
-
if (classIndexOf(value.toLowerCase(), cssClassToMatch, 0) !== -1) {
|
|
1993
|
-
return true;
|
|
1994
|
-
}
|
|
1979
|
+
if (isProjectionMode) {
|
|
1980
|
+
for (; i < attrs.length && typeof attrs[i] === 'string'; i += 2) {
|
|
1981
|
+
// Search for an implicit `class` attribute and check if its value matches `cssClassToMatch`.
|
|
1982
|
+
if (attrs[i] === 'class' &&
|
|
1983
|
+
classIndexOf(attrs[i + 1].toLowerCase(), cssClassToMatch, 0) !== -1) {
|
|
1984
|
+
return true;
|
|
1995
1985
|
}
|
|
1996
1986
|
}
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
1987
|
+
}
|
|
1988
|
+
else if (isInlineTemplate(tNode)) {
|
|
1989
|
+
// Matching directives (i.e. when not matching for projection mode) should not consider the
|
|
1990
|
+
// class bindings that are present on inline templates, as those class bindings only target
|
|
1991
|
+
// the root node of the template, not the template itself.
|
|
1992
|
+
return false;
|
|
1993
|
+
}
|
|
1994
|
+
// Resume the search for classes after the `Classes` marker.
|
|
1995
|
+
i = attrs.indexOf(1 /* AttributeMarker.Classes */, i);
|
|
1996
|
+
if (i > -1) {
|
|
1997
|
+
// We found the classes section. Start searching for the class.
|
|
1998
|
+
let item;
|
|
1999
|
+
while (++i < attrs.length && typeof (item = attrs[i]) === 'string') {
|
|
2000
|
+
if (item.toLowerCase() === cssClassToMatch) {
|
|
2001
|
+
return true;
|
|
2003
2002
|
}
|
|
2004
|
-
return false;
|
|
2005
|
-
}
|
|
2006
|
-
else if (typeof item === 'number') {
|
|
2007
|
-
// We've came across a first marker, which indicates
|
|
2008
|
-
// that the implicit attribute section is over.
|
|
2009
|
-
isImplicitAttrsSection = false;
|
|
2010
2003
|
}
|
|
2011
2004
|
}
|
|
2012
2005
|
return false;
|
|
@@ -2037,7 +2030,7 @@ function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
|
|
|
2037
2030
|
/**
|
|
2038
2031
|
* A utility function to match an Ivy node static data against a simple CSS selector
|
|
2039
2032
|
*
|
|
2040
|
-
* @param
|
|
2033
|
+
* @param tNode static data of the node to match
|
|
2041
2034
|
* @param selector The selector to try matching against the node.
|
|
2042
2035
|
* @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing
|
|
2043
2036
|
* directive matching.
|
|
@@ -2046,9 +2039,9 @@ function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
|
|
|
2046
2039
|
function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
|
|
2047
2040
|
ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
|
|
2048
2041
|
let mode = 4 /* SelectorFlags.ELEMENT */;
|
|
2049
|
-
const nodeAttrs = tNode.attrs
|
|
2042
|
+
const nodeAttrs = tNode.attrs;
|
|
2050
2043
|
// Find the index of first attribute that has no value, only a name.
|
|
2051
|
-
const nameOnlyMarkerIdx = getNameOnlyMarkerIndex(nodeAttrs);
|
|
2044
|
+
const nameOnlyMarkerIdx = nodeAttrs !== null ? getNameOnlyMarkerIndex(nodeAttrs) : 0;
|
|
2052
2045
|
// When processing ":not" selectors, we skip to the next ":not" if the
|
|
2053
2046
|
// current one doesn't match
|
|
2054
2047
|
let skipToNextSelector = false;
|
|
@@ -2078,20 +2071,16 @@ function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
|
|
|
2078
2071
|
skipToNextSelector = true;
|
|
2079
2072
|
}
|
|
2080
2073
|
}
|
|
2081
|
-
else {
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
if (!isCssClassMatching(tNode.attrs, selectorAttrValue, isProjectionMode)) {
|
|
2087
|
-
if (isPositive(mode))
|
|
2088
|
-
return false;
|
|
2089
|
-
skipToNextSelector = true;
|
|
2090
|
-
}
|
|
2091
|
-
continue;
|
|
2074
|
+
else if (mode & 8 /* SelectorFlags.CLASS */) {
|
|
2075
|
+
if (nodeAttrs === null || !isCssClassMatching(tNode, nodeAttrs, current, isProjectionMode)) {
|
|
2076
|
+
if (isPositive(mode))
|
|
2077
|
+
return false;
|
|
2078
|
+
skipToNextSelector = true;
|
|
2092
2079
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2080
|
+
}
|
|
2081
|
+
else {
|
|
2082
|
+
const selectorAttrValue = selector[++i];
|
|
2083
|
+
const attrIndexInNode = findAttrIndexInNode(current, nodeAttrs, isInlineTemplate(tNode), isProjectionMode);
|
|
2095
2084
|
if (attrIndexInNode === -1) {
|
|
2096
2085
|
if (isPositive(mode))
|
|
2097
2086
|
return false;
|
|
@@ -2111,10 +2100,7 @@ function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
|
|
|
2111
2100
|
// (selectors are already in lowercase when generated)
|
|
2112
2101
|
nodeAttrValue = nodeAttrs[attrIndexInNode + 1].toLowerCase();
|
|
2113
2102
|
}
|
|
2114
|
-
|
|
2115
|
-
if (compareAgainstClassName &&
|
|
2116
|
-
classIndexOf(compareAgainstClassName, selectorAttrValue, 0) !== -1 ||
|
|
2117
|
-
mode & 2 /* SelectorFlags.ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
|
|
2103
|
+
if (mode & 2 /* SelectorFlags.ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
|
|
2118
2104
|
if (isPositive(mode))
|
|
2119
2105
|
return false;
|
|
2120
2106
|
skipToNextSelector = true;
|
|
@@ -3419,6 +3405,12 @@ function runInInjectionContext(injector, fn) {
|
|
|
3419
3405
|
setInjectImplementation(previousInjectImplementation);
|
|
3420
3406
|
}
|
|
3421
3407
|
}
|
|
3408
|
+
/**
|
|
3409
|
+
* Whether the current stack frame is inside an injection context.
|
|
3410
|
+
*/
|
|
3411
|
+
function isInInjectionContext() {
|
|
3412
|
+
return getInjectImplementation() !== undefined || getCurrentInjector() != null;
|
|
3413
|
+
}
|
|
3422
3414
|
/**
|
|
3423
3415
|
* Asserts that the current stack frame is within an [injection
|
|
3424
3416
|
* context](guide/dependency-injection-context) and has access to `inject`.
|
|
@@ -3430,7 +3422,7 @@ function runInInjectionContext(injector, fn) {
|
|
|
3430
3422
|
function assertInInjectionContext(debugFn) {
|
|
3431
3423
|
// Taking a `Function` instead of a string name here prevents the unminified name of the function
|
|
3432
3424
|
// from being retained in the bundle regardless of minification.
|
|
3433
|
-
if (!
|
|
3425
|
+
if (!isInInjectionContext()) {
|
|
3434
3426
|
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
|
|
3435
3427
|
(debugFn.name +
|
|
3436
3428
|
'() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
|
|
@@ -4335,6 +4327,7 @@ function requiresRefreshOrTraversal(lView) {
|
|
|
4335
4327
|
* parents above.
|
|
4336
4328
|
*/
|
|
4337
4329
|
function updateAncestorTraversalFlagsOnAttach(lView) {
|
|
4330
|
+
lView[ENVIRONMENT].changeDetectionScheduler?.notify(1 /* NotificationType.AfterRenderHooks */);
|
|
4338
4331
|
// TODO(atscott): Simplify if...else cases once getEnsureDirtyViewsAreAlwaysReachable is always
|
|
4339
4332
|
// `true`. When we attach a view that's marked `Dirty`, we should ensure that it is reached during
|
|
4340
4333
|
// the next CD traversal so we add the `RefreshView` flag and mark ancestors accordingly.
|
|
@@ -6490,6 +6483,79 @@ class HostAttributeToken {
|
|
|
6490
6483
|
* safe to delete this file.
|
|
6491
6484
|
*/
|
|
6492
6485
|
|
|
6486
|
+
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
6487
|
+
function wrappedError(message, originalError) {
|
|
6488
|
+
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
6489
|
+
const error = Error(msg);
|
|
6490
|
+
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
6491
|
+
return error;
|
|
6492
|
+
}
|
|
6493
|
+
function getOriginalError(error) {
|
|
6494
|
+
return error[ERROR_ORIGINAL_ERROR];
|
|
6495
|
+
}
|
|
6496
|
+
|
|
6497
|
+
/**
|
|
6498
|
+
* Provides a hook for centralized exception handling.
|
|
6499
|
+
*
|
|
6500
|
+
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
6501
|
+
* intercept error handling, write a custom exception handler that replaces this default as
|
|
6502
|
+
* appropriate for your app.
|
|
6503
|
+
*
|
|
6504
|
+
* @usageNotes
|
|
6505
|
+
* ### Example
|
|
6506
|
+
*
|
|
6507
|
+
* ```
|
|
6508
|
+
* class MyErrorHandler implements ErrorHandler {
|
|
6509
|
+
* handleError(error) {
|
|
6510
|
+
* // do something with the exception
|
|
6511
|
+
* }
|
|
6512
|
+
* }
|
|
6513
|
+
*
|
|
6514
|
+
* @NgModule({
|
|
6515
|
+
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
6516
|
+
* })
|
|
6517
|
+
* class MyModule {}
|
|
6518
|
+
* ```
|
|
6519
|
+
*
|
|
6520
|
+
* @publicApi
|
|
6521
|
+
*/
|
|
6522
|
+
class ErrorHandler {
|
|
6523
|
+
constructor() {
|
|
6524
|
+
/**
|
|
6525
|
+
* @internal
|
|
6526
|
+
*/
|
|
6527
|
+
this._console = console;
|
|
6528
|
+
}
|
|
6529
|
+
handleError(error) {
|
|
6530
|
+
const originalError = this._findOriginalError(error);
|
|
6531
|
+
this._console.error('ERROR', error);
|
|
6532
|
+
if (originalError) {
|
|
6533
|
+
this._console.error('ORIGINAL ERROR', originalError);
|
|
6534
|
+
}
|
|
6535
|
+
}
|
|
6536
|
+
/** @internal */
|
|
6537
|
+
_findOriginalError(error) {
|
|
6538
|
+
let e = error && getOriginalError(error);
|
|
6539
|
+
while (e && getOriginalError(e)) {
|
|
6540
|
+
e = getOriginalError(e);
|
|
6541
|
+
}
|
|
6542
|
+
return e || null;
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6545
|
+
/**
|
|
6546
|
+
* `InjectionToken` used to configure how to call the `ErrorHandler`.
|
|
6547
|
+
*
|
|
6548
|
+
* `NgZone` is provided by default today so the default (and only) implementation for this
|
|
6549
|
+
* is calling `ErrorHandler.handleError` outside of the Angular zone.
|
|
6550
|
+
*/
|
|
6551
|
+
const INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'internal error handler' : '', {
|
|
6552
|
+
providedIn: 'root',
|
|
6553
|
+
factory: () => {
|
|
6554
|
+
const userErrorHandler = inject(ErrorHandler);
|
|
6555
|
+
return userErrorHandler.handleError.bind(undefined);
|
|
6556
|
+
}
|
|
6557
|
+
});
|
|
6558
|
+
|
|
6493
6559
|
/**
|
|
6494
6560
|
* `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
|
|
6495
6561
|
* The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
|
|
@@ -6541,6 +6607,7 @@ class OutputEmitterRef {
|
|
|
6541
6607
|
constructor() {
|
|
6542
6608
|
this.destroyed = false;
|
|
6543
6609
|
this.listeners = null;
|
|
6610
|
+
this.errorHandler = inject(ErrorHandler, { optional: true });
|
|
6544
6611
|
/** @internal */
|
|
6545
6612
|
this.destroyRef = inject(DestroyRef);
|
|
6546
6613
|
// Clean-up all listeners and mark as destroyed upon destroy.
|
|
@@ -6572,10 +6639,19 @@ class OutputEmitterRef {
|
|
|
6572
6639
|
'Unexpected emit for destroyed `OutputRef`. ' +
|
|
6573
6640
|
'The owning directive/component is destroyed.');
|
|
6574
6641
|
}
|
|
6642
|
+
if (this.listeners === null) {
|
|
6643
|
+
return;
|
|
6644
|
+
}
|
|
6575
6645
|
const previousConsumer = setActiveConsumer$1(null);
|
|
6576
6646
|
try {
|
|
6577
|
-
|
|
6578
|
-
|
|
6647
|
+
for (const listenerFn of this.listeners) {
|
|
6648
|
+
try {
|
|
6649
|
+
listenerFn(value);
|
|
6650
|
+
}
|
|
6651
|
+
catch (err) {
|
|
6652
|
+
this.errorHandler?.handleError(err);
|
|
6653
|
+
}
|
|
6654
|
+
}
|
|
6579
6655
|
}
|
|
6580
6656
|
finally {
|
|
6581
6657
|
setActiveConsumer$1(previousConsumer);
|
|
@@ -6588,7 +6664,7 @@ function getOutputDestroyRef(ref) {
|
|
|
6588
6664
|
}
|
|
6589
6665
|
|
|
6590
6666
|
/**
|
|
6591
|
-
* The `
|
|
6667
|
+
* The `output` function allows declaration of outputs in directives and
|
|
6592
6668
|
* components.
|
|
6593
6669
|
*
|
|
6594
6670
|
* Initializes an output that can emit values to consumers of your
|
|
@@ -6614,9 +6690,11 @@ function output(opts) {
|
|
|
6614
6690
|
}
|
|
6615
6691
|
|
|
6616
6692
|
function inputFunction(initialValue, opts) {
|
|
6693
|
+
ngDevMode && assertInInjectionContext(input);
|
|
6617
6694
|
return createInputSignal(initialValue, opts);
|
|
6618
6695
|
}
|
|
6619
6696
|
function inputRequiredFunction(opts) {
|
|
6697
|
+
ngDevMode && assertInInjectionContext(input);
|
|
6620
6698
|
return createInputSignal(REQUIRED_UNSET_VALUE, opts);
|
|
6621
6699
|
}
|
|
6622
6700
|
/**
|
|
@@ -6708,14 +6786,12 @@ function unwrapElementRef(value) {
|
|
|
6708
6786
|
class EventEmitter_ extends Subject {
|
|
6709
6787
|
constructor(isAsync = false) {
|
|
6710
6788
|
super();
|
|
6789
|
+
this.destroyRef = undefined;
|
|
6711
6790
|
this.__isAsync = isAsync;
|
|
6712
6791
|
// Attempt to retrieve a `DestroyRef` optionally.
|
|
6713
|
-
// For backwards compatibility reasons, this cannot be required
|
|
6714
|
-
|
|
6715
|
-
this.destroyRef = inject(DestroyRef);
|
|
6716
|
-
}
|
|
6717
|
-
catch {
|
|
6718
|
-
this.destroyRef = undefined;
|
|
6792
|
+
// For backwards compatibility reasons, this cannot be required
|
|
6793
|
+
if (isInInjectionContext()) {
|
|
6794
|
+
this.destroyRef = inject(DestroyRef, { optional: true }) ?? undefined;
|
|
6719
6795
|
}
|
|
6720
6796
|
}
|
|
6721
6797
|
emit(value) {
|
|
@@ -7593,79 +7669,6 @@ function isDisconnectedNode$1(hydrationInfo, index) {
|
|
|
7593
7669
|
return !!hydrationInfo.disconnectedNodes?.has(index);
|
|
7594
7670
|
}
|
|
7595
7671
|
|
|
7596
|
-
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
7597
|
-
function wrappedError(message, originalError) {
|
|
7598
|
-
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
7599
|
-
const error = Error(msg);
|
|
7600
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
7601
|
-
return error;
|
|
7602
|
-
}
|
|
7603
|
-
function getOriginalError(error) {
|
|
7604
|
-
return error[ERROR_ORIGINAL_ERROR];
|
|
7605
|
-
}
|
|
7606
|
-
|
|
7607
|
-
/**
|
|
7608
|
-
* Provides a hook for centralized exception handling.
|
|
7609
|
-
*
|
|
7610
|
-
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
7611
|
-
* intercept error handling, write a custom exception handler that replaces this default as
|
|
7612
|
-
* appropriate for your app.
|
|
7613
|
-
*
|
|
7614
|
-
* @usageNotes
|
|
7615
|
-
* ### Example
|
|
7616
|
-
*
|
|
7617
|
-
* ```
|
|
7618
|
-
* class MyErrorHandler implements ErrorHandler {
|
|
7619
|
-
* handleError(error) {
|
|
7620
|
-
* // do something with the exception
|
|
7621
|
-
* }
|
|
7622
|
-
* }
|
|
7623
|
-
*
|
|
7624
|
-
* @NgModule({
|
|
7625
|
-
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
7626
|
-
* })
|
|
7627
|
-
* class MyModule {}
|
|
7628
|
-
* ```
|
|
7629
|
-
*
|
|
7630
|
-
* @publicApi
|
|
7631
|
-
*/
|
|
7632
|
-
class ErrorHandler {
|
|
7633
|
-
constructor() {
|
|
7634
|
-
/**
|
|
7635
|
-
* @internal
|
|
7636
|
-
*/
|
|
7637
|
-
this._console = console;
|
|
7638
|
-
}
|
|
7639
|
-
handleError(error) {
|
|
7640
|
-
const originalError = this._findOriginalError(error);
|
|
7641
|
-
this._console.error('ERROR', error);
|
|
7642
|
-
if (originalError) {
|
|
7643
|
-
this._console.error('ORIGINAL ERROR', originalError);
|
|
7644
|
-
}
|
|
7645
|
-
}
|
|
7646
|
-
/** @internal */
|
|
7647
|
-
_findOriginalError(error) {
|
|
7648
|
-
let e = error && getOriginalError(error);
|
|
7649
|
-
while (e && getOriginalError(e)) {
|
|
7650
|
-
e = getOriginalError(e);
|
|
7651
|
-
}
|
|
7652
|
-
return e || null;
|
|
7653
|
-
}
|
|
7654
|
-
}
|
|
7655
|
-
/**
|
|
7656
|
-
* `InjectionToken` used to configure how to call the `ErrorHandler`.
|
|
7657
|
-
*
|
|
7658
|
-
* `NgZone` is provided by default today so the default (and only) implementation for this
|
|
7659
|
-
* is calling `ErrorHandler.handleError` outside of the Angular zone.
|
|
7660
|
-
*/
|
|
7661
|
-
const INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'internal error handler' : '', {
|
|
7662
|
-
providedIn: 'root',
|
|
7663
|
-
factory: () => {
|
|
7664
|
-
const userErrorHandler = inject(ErrorHandler);
|
|
7665
|
-
return userErrorHandler.handleError.bind(undefined);
|
|
7666
|
-
}
|
|
7667
|
-
});
|
|
7668
|
-
|
|
7669
7672
|
/**
|
|
7670
7673
|
* Internal token that specifies whether DOM reuse logic
|
|
7671
7674
|
* during hydration is enabled.
|
|
@@ -7682,6 +7685,11 @@ const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefine
|
|
|
7682
7685
|
providedIn: 'root',
|
|
7683
7686
|
factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
|
|
7684
7687
|
});
|
|
7688
|
+
/**
|
|
7689
|
+
* Internal token that indicates whether hydration support for i18n
|
|
7690
|
+
* is enabled.
|
|
7691
|
+
*/
|
|
7692
|
+
const IS_I18N_HYDRATION_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode ? 'IS_I18N_HYDRATION_ENABLED' : ''));
|
|
7685
7693
|
|
|
7686
7694
|
/**
|
|
7687
7695
|
* @fileoverview
|
|
@@ -8185,6 +8193,7 @@ class SanitizingHtmlSerializer {
|
|
|
8185
8193
|
// again, so it shouldn't be vulnerable to DOM clobbering.
|
|
8186
8194
|
let current = el.firstChild;
|
|
8187
8195
|
let traverseContent = true;
|
|
8196
|
+
let parentNodes = [];
|
|
8188
8197
|
while (current) {
|
|
8189
8198
|
if (current.nodeType === Node.ELEMENT_NODE) {
|
|
8190
8199
|
traverseContent = this.startElement(current);
|
|
@@ -8197,20 +8206,24 @@ class SanitizingHtmlSerializer {
|
|
|
8197
8206
|
this.sanitizedSomething = true;
|
|
8198
8207
|
}
|
|
8199
8208
|
if (traverseContent && current.firstChild) {
|
|
8200
|
-
current
|
|
8209
|
+
// Push current node to the parent stack before entering its content.
|
|
8210
|
+
parentNodes.push(current);
|
|
8211
|
+
current = getFirstChild(current);
|
|
8201
8212
|
continue;
|
|
8202
8213
|
}
|
|
8203
8214
|
while (current) {
|
|
8204
|
-
// Leaving the element.
|
|
8215
|
+
// Leaving the element.
|
|
8216
|
+
// Walk up and to the right, closing tags as we go.
|
|
8205
8217
|
if (current.nodeType === Node.ELEMENT_NODE) {
|
|
8206
8218
|
this.endElement(current);
|
|
8207
8219
|
}
|
|
8208
|
-
let next =
|
|
8220
|
+
let next = getNextSibling(current);
|
|
8209
8221
|
if (next) {
|
|
8210
8222
|
current = next;
|
|
8211
8223
|
break;
|
|
8212
8224
|
}
|
|
8213
|
-
|
|
8225
|
+
// There was no next sibling, walk up to the parent node (extract it from the stack).
|
|
8226
|
+
current = parentNodes.pop();
|
|
8214
8227
|
}
|
|
8215
8228
|
}
|
|
8216
8229
|
return this.buf.join('');
|
|
@@ -8224,7 +8237,7 @@ class SanitizingHtmlSerializer {
|
|
|
8224
8237
|
* @return True if the element's contents should be traversed.
|
|
8225
8238
|
*/
|
|
8226
8239
|
startElement(element) {
|
|
8227
|
-
const tagName = element.
|
|
8240
|
+
const tagName = getNodeName(element).toLowerCase();
|
|
8228
8241
|
if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
|
|
8229
8242
|
this.sanitizedSomething = true;
|
|
8230
8243
|
return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
|
|
@@ -8250,7 +8263,7 @@ class SanitizingHtmlSerializer {
|
|
|
8250
8263
|
return true;
|
|
8251
8264
|
}
|
|
8252
8265
|
endElement(current) {
|
|
8253
|
-
const tagName = current.
|
|
8266
|
+
const tagName = getNodeName(current).toLowerCase();
|
|
8254
8267
|
if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
|
|
8255
8268
|
this.buf.push('</');
|
|
8256
8269
|
this.buf.push(tagName);
|
|
@@ -8260,14 +8273,49 @@ class SanitizingHtmlSerializer {
|
|
|
8260
8273
|
chars(chars) {
|
|
8261
8274
|
this.buf.push(encodeEntities(chars));
|
|
8262
8275
|
}
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8276
|
+
}
|
|
8277
|
+
/**
|
|
8278
|
+
* Verifies whether a given child node is a descendant of a given parent node.
|
|
8279
|
+
* It may not be the case when properties like `.firstChild` are clobbered and
|
|
8280
|
+
* accessing `.firstChild` results in an unexpected node returned.
|
|
8281
|
+
*/
|
|
8282
|
+
function isClobberedElement(parentNode, childNode) {
|
|
8283
|
+
return (parentNode.compareDocumentPosition(childNode) & Node.DOCUMENT_POSITION_CONTAINED_BY) !==
|
|
8284
|
+
Node.DOCUMENT_POSITION_CONTAINED_BY;
|
|
8285
|
+
}
|
|
8286
|
+
/**
|
|
8287
|
+
* Retrieves next sibling node and makes sure that there is no
|
|
8288
|
+
* clobbering of the `nextSibling` property happening.
|
|
8289
|
+
*/
|
|
8290
|
+
function getNextSibling(node) {
|
|
8291
|
+
const nextSibling = node.nextSibling;
|
|
8292
|
+
// Make sure there is no `nextSibling` clobbering: navigating to
|
|
8293
|
+
// the next sibling and going back to the previous one should result
|
|
8294
|
+
// in the original node.
|
|
8295
|
+
if (nextSibling && node !== nextSibling.previousSibling) {
|
|
8296
|
+
throw clobberedElementError(nextSibling);
|
|
8297
|
+
}
|
|
8298
|
+
return nextSibling;
|
|
8299
|
+
}
|
|
8300
|
+
/**
|
|
8301
|
+
* Retrieves first child node and makes sure that there is no
|
|
8302
|
+
* clobbering of the `firstChild` property happening.
|
|
8303
|
+
*/
|
|
8304
|
+
function getFirstChild(node) {
|
|
8305
|
+
const firstChild = node.firstChild;
|
|
8306
|
+
if (firstChild && isClobberedElement(node, firstChild)) {
|
|
8307
|
+
throw clobberedElementError(firstChild);
|
|
8270
8308
|
}
|
|
8309
|
+
return firstChild;
|
|
8310
|
+
}
|
|
8311
|
+
/** Gets a reasonable nodeName, even for clobbered nodes. */
|
|
8312
|
+
function getNodeName(node) {
|
|
8313
|
+
const nodeName = node.nodeName;
|
|
8314
|
+
// If the property is clobbered, assume it is an `HTMLFormElement`.
|
|
8315
|
+
return (typeof nodeName === 'string') ? nodeName : 'FORM';
|
|
8316
|
+
}
|
|
8317
|
+
function clobberedElementError(node) {
|
|
8318
|
+
return new Error(`Failed to sanitize html because the element is clobbered: ${node.outerHTML}`);
|
|
8271
8319
|
}
|
|
8272
8320
|
// Regular Expressions for parsing tags and attributes
|
|
8273
8321
|
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
@@ -9597,6 +9645,10 @@ function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, bef
|
|
|
9597
9645
|
* @param lView the `LView` to be detached.
|
|
9598
9646
|
*/
|
|
9599
9647
|
function detachViewFromDOM(tView, lView) {
|
|
9648
|
+
// When we remove a view from the DOM, we need to rerun afterRender hooks
|
|
9649
|
+
// We don't necessarily needs to run change detection. DOM removal only requires
|
|
9650
|
+
// change detection if animations are enabled (this notification is handled by animations).
|
|
9651
|
+
lView[ENVIRONMENT].changeDetectionScheduler?.notify(1 /* NotificationType.AfterRenderHooks */);
|
|
9600
9652
|
applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
9601
9653
|
}
|
|
9602
9654
|
/**
|
|
@@ -13325,11 +13377,27 @@ function cleanupLContainer(lContainer) {
|
|
|
13325
13377
|
cleanupLView(lContainer[i]);
|
|
13326
13378
|
}
|
|
13327
13379
|
}
|
|
13380
|
+
/**
|
|
13381
|
+
* Removes any remaining dehydrated i18n nodes from a given LView,
|
|
13382
|
+
* both in internal data structure, as well as removing the
|
|
13383
|
+
* corresponding DOM nodes.
|
|
13384
|
+
*/
|
|
13385
|
+
function cleanupDehydratedI18nNodes(lView) {
|
|
13386
|
+
const i18nNodes = lView[HYDRATION]?.i18nNodes;
|
|
13387
|
+
if (i18nNodes) {
|
|
13388
|
+
const renderer = lView[RENDERER];
|
|
13389
|
+
for (const node of i18nNodes.values()) {
|
|
13390
|
+
nativeRemoveNode(renderer, node, false);
|
|
13391
|
+
}
|
|
13392
|
+
lView[HYDRATION].i18nNodes = undefined;
|
|
13393
|
+
}
|
|
13394
|
+
}
|
|
13328
13395
|
/**
|
|
13329
13396
|
* Walks over `LContainer`s and components registered within
|
|
13330
13397
|
* this LView and invokes dehydrated views cleanup function for each one.
|
|
13331
13398
|
*/
|
|
13332
13399
|
function cleanupLView(lView) {
|
|
13400
|
+
cleanupDehydratedI18nNodes(lView);
|
|
13333
13401
|
const tView = lView[TVIEW];
|
|
13334
13402
|
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
13335
13403
|
if (isLContainer(lView[i])) {
|
|
@@ -13448,6 +13516,24 @@ function isDisconnectedNode(tNode, lView) {
|
|
|
13448
13516
|
return !(tNode.type & 16 /* TNodeType.Projection */) && !!lView[tNode.index] &&
|
|
13449
13517
|
!unwrapRNode(lView[tNode.index])?.isConnected;
|
|
13450
13518
|
}
|
|
13519
|
+
/**
|
|
13520
|
+
* Locate a node in an i18n tree that corresponds to a given instruction index.
|
|
13521
|
+
*
|
|
13522
|
+
* @param hydrationInfo The hydration annotation data
|
|
13523
|
+
* @param noOffsetIndex the instruction index
|
|
13524
|
+
* @returns an RNode that corresponds to the instruction index
|
|
13525
|
+
*/
|
|
13526
|
+
function locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex) {
|
|
13527
|
+
const i18nNodes = hydrationInfo.i18nNodes;
|
|
13528
|
+
if (i18nNodes) {
|
|
13529
|
+
const native = i18nNodes.get(noOffsetIndex);
|
|
13530
|
+
if (native) {
|
|
13531
|
+
i18nNodes.delete(noOffsetIndex);
|
|
13532
|
+
}
|
|
13533
|
+
return native;
|
|
13534
|
+
}
|
|
13535
|
+
return null;
|
|
13536
|
+
}
|
|
13451
13537
|
/**
|
|
13452
13538
|
* Locate a node in DOM tree that corresponds to a given TNode.
|
|
13453
13539
|
*
|
|
@@ -13458,51 +13544,53 @@ function isDisconnectedNode(tNode, lView) {
|
|
|
13458
13544
|
* @returns an RNode that represents a given tNode
|
|
13459
13545
|
*/
|
|
13460
13546
|
function locateNextRNode(hydrationInfo, tView, lView, tNode) {
|
|
13461
|
-
let native = null;
|
|
13462
13547
|
const noOffsetIndex = getNoOffsetIndex(tNode);
|
|
13463
|
-
|
|
13464
|
-
if (
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
// Locate a node based on a previous sibling or a parent node.
|
|
13475
|
-
const previousTNodeParent = tNode.prev === null;
|
|
13476
|
-
const previousTNode = (tNode.prev ?? tNode.parent);
|
|
13477
|
-
ngDevMode &&
|
|
13478
|
-
assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
|
|
13479
|
-
'to the previous node or a parent node.');
|
|
13480
|
-
if (isFirstElementInNgContainer(tNode)) {
|
|
13481
|
-
const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
|
|
13482
|
-
native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
|
|
13548
|
+
let native = locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex);
|
|
13549
|
+
if (!native) {
|
|
13550
|
+
const nodes = hydrationInfo.data[NODES];
|
|
13551
|
+
if (nodes?.[noOffsetIndex]) {
|
|
13552
|
+
// We know the exact location of the node.
|
|
13553
|
+
native = locateRNodeByPath(nodes[noOffsetIndex], lView);
|
|
13554
|
+
}
|
|
13555
|
+
else if (tView.firstChild === tNode) {
|
|
13556
|
+
// We create a first node in this view, so we use a reference
|
|
13557
|
+
// to the first child in this DOM segment.
|
|
13558
|
+
native = hydrationInfo.firstChild;
|
|
13483
13559
|
}
|
|
13484
13560
|
else {
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13561
|
+
// Locate a node based on a previous sibling or a parent node.
|
|
13562
|
+
const previousTNodeParent = tNode.prev === null;
|
|
13563
|
+
const previousTNode = (tNode.prev ?? tNode.parent);
|
|
13564
|
+
ngDevMode &&
|
|
13565
|
+
assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
|
|
13566
|
+
'to the previous node or a parent node.');
|
|
13567
|
+
if (isFirstElementInNgContainer(tNode)) {
|
|
13568
|
+
const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
|
|
13569
|
+
native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
|
|
13488
13570
|
}
|
|
13489
13571
|
else {
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
// In this case, there are nodes *after* this element and we need to skip
|
|
13494
|
-
// all of them to reach an element that we are looking for.
|
|
13495
|
-
const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
|
|
13496
|
-
const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13497
|
-
if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
|
|
13498
|
-
const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13499
|
-
// `+1` stands for an anchor comment node after all the views in this container.
|
|
13500
|
-
const nodesToSkip = numRootNodesToSkip + 1;
|
|
13501
|
-
// First node after this segment.
|
|
13502
|
-
native = siblingAfter(nodesToSkip, segmentHead);
|
|
13572
|
+
let previousRElement = getNativeByTNode(previousTNode, lView);
|
|
13573
|
+
if (previousTNodeParent) {
|
|
13574
|
+
native = previousRElement.firstChild;
|
|
13503
13575
|
}
|
|
13504
13576
|
else {
|
|
13505
|
-
|
|
13577
|
+
// If the previous node is an element, but it also has container info,
|
|
13578
|
+
// this means that we are processing a node like `<div #vcrTarget>`, which is
|
|
13579
|
+
// represented in the DOM as `<div></div>...<!--container-->`.
|
|
13580
|
+
// In this case, there are nodes *after* this element and we need to skip
|
|
13581
|
+
// all of them to reach an element that we are looking for.
|
|
13582
|
+
const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
|
|
13583
|
+
const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13584
|
+
if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
|
|
13585
|
+
const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13586
|
+
// `+1` stands for an anchor comment node after all the views in this container.
|
|
13587
|
+
const nodesToSkip = numRootNodesToSkip + 1;
|
|
13588
|
+
// First node after this segment.
|
|
13589
|
+
native = siblingAfter(nodesToSkip, segmentHead);
|
|
13590
|
+
}
|
|
13591
|
+
else {
|
|
13592
|
+
native = previousRElement.nextSibling;
|
|
13593
|
+
}
|
|
13506
13594
|
}
|
|
13507
13595
|
}
|
|
13508
13596
|
}
|
|
@@ -14590,7 +14678,7 @@ function afterRender(callback, options) {
|
|
|
14590
14678
|
unregisterFn();
|
|
14591
14679
|
};
|
|
14592
14680
|
const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
|
|
14593
|
-
const instance = new AfterRenderCallback(
|
|
14681
|
+
const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, callback));
|
|
14594
14682
|
callbackHandler.register(instance);
|
|
14595
14683
|
return { destroy };
|
|
14596
14684
|
}
|
|
@@ -14660,10 +14748,10 @@ function afterNextRender(callback, options) {
|
|
|
14660
14748
|
unregisterFn();
|
|
14661
14749
|
};
|
|
14662
14750
|
const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
|
|
14663
|
-
const instance = new AfterRenderCallback(
|
|
14751
|
+
const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, () => {
|
|
14664
14752
|
destroy();
|
|
14665
14753
|
callback();
|
|
14666
|
-
});
|
|
14754
|
+
}));
|
|
14667
14755
|
callbackHandler.register(instance);
|
|
14668
14756
|
return { destroy };
|
|
14669
14757
|
}
|
|
@@ -14671,11 +14759,13 @@ function afterNextRender(callback, options) {
|
|
|
14671
14759
|
* A wrapper around a function to be used as an after render callback.
|
|
14672
14760
|
*/
|
|
14673
14761
|
class AfterRenderCallback {
|
|
14674
|
-
constructor(
|
|
14762
|
+
constructor(phase, callbackFn) {
|
|
14675
14763
|
this.phase = phase;
|
|
14676
14764
|
this.callbackFn = callbackFn;
|
|
14677
|
-
this.zone =
|
|
14678
|
-
this.errorHandler =
|
|
14765
|
+
this.zone = inject(NgZone);
|
|
14766
|
+
this.errorHandler = inject(ErrorHandler, { optional: true });
|
|
14767
|
+
// Registering a callback will notify the scheduler.
|
|
14768
|
+
inject(ChangeDetectionScheduler, { optional: true })?.notify(1 /* NotificationType.AfterRenderHooks */);
|
|
14679
14769
|
}
|
|
14680
14770
|
invoke() {
|
|
14681
14771
|
try {
|
|
@@ -15474,7 +15564,7 @@ function createRootComponent(componentView, rootComponentDef, rootDirectives, ho
|
|
|
15474
15564
|
function setRootNodeAttributes(hostRenderer, componentDef, hostRNode, rootSelectorOrNode) {
|
|
15475
15565
|
if (rootSelectorOrNode) {
|
|
15476
15566
|
// The placeholder will be replaced with the actual version at build time.
|
|
15477
|
-
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '17.3.0
|
|
15567
|
+
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '17.3.0']);
|
|
15478
15568
|
}
|
|
15479
15569
|
else {
|
|
15480
15570
|
// If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
|
|
@@ -16500,9 +16590,11 @@ function refreshSignalQuery(node, firstOnly) {
|
|
|
16500
16590
|
}
|
|
16501
16591
|
|
|
16502
16592
|
function viewChildFn(locator, opts) {
|
|
16593
|
+
ngDevMode && assertInInjectionContext(viewChild);
|
|
16503
16594
|
return createSingleResultOptionalQuerySignalFn();
|
|
16504
16595
|
}
|
|
16505
16596
|
function viewChildRequiredFn(locator, opts) {
|
|
16597
|
+
ngDevMode && assertInInjectionContext(viewChild);
|
|
16506
16598
|
return createSingleResultRequiredQuerySignalFn();
|
|
16507
16599
|
}
|
|
16508
16600
|
/**
|
|
@@ -16551,12 +16643,15 @@ const viewChild = (() => {
|
|
|
16551
16643
|
* ```
|
|
16552
16644
|
*/
|
|
16553
16645
|
function viewChildren(locator, opts) {
|
|
16646
|
+
ngDevMode && assertInInjectionContext(viewChildren);
|
|
16554
16647
|
return createMultiResultQuerySignalFn();
|
|
16555
16648
|
}
|
|
16556
16649
|
function contentChildFn(locator, opts) {
|
|
16650
|
+
ngDevMode && assertInInjectionContext(contentChild);
|
|
16557
16651
|
return createSingleResultOptionalQuerySignalFn();
|
|
16558
16652
|
}
|
|
16559
16653
|
function contentChildRequiredFn(locator, opts) {
|
|
16654
|
+
ngDevMode && assertInInjectionContext(contentChildren);
|
|
16560
16655
|
return createSingleResultRequiredQuerySignalFn();
|
|
16561
16656
|
}
|
|
16562
16657
|
/**
|
|
@@ -17831,6 +17926,15 @@ function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
|
|
|
17831
17926
|
return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
|
|
17832
17927
|
}
|
|
17833
17928
|
|
|
17929
|
+
/**
|
|
17930
|
+
* Checks whether a TNode is considered detached, i.e. not present in the
|
|
17931
|
+
* translated i18n template. We should not attempt hydration for such nodes
|
|
17932
|
+
* and instead, use a regular "creation mode".
|
|
17933
|
+
*/
|
|
17934
|
+
function isDetachedByI18n(tNode) {
|
|
17935
|
+
return (tNode.flags & 32 /* TNodeFlags.isDetached */) === 32 /* TNodeFlags.isDetached */;
|
|
17936
|
+
}
|
|
17937
|
+
|
|
17834
17938
|
function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
|
|
17835
17939
|
ngDevMode && assertFirstCreatePass(tView);
|
|
17836
17940
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
@@ -17907,7 +18011,8 @@ function createContainerAnchorImpl(tView, lView, tNode, index) {
|
|
|
17907
18011
|
*/
|
|
17908
18012
|
function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
|
|
17909
18013
|
const hydrationInfo = lView[HYDRATION];
|
|
17910
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
18014
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
18015
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
17911
18016
|
lastNodeWasCreated(isNodeCreationMode);
|
|
17912
18017
|
// Regular creation mode.
|
|
17913
18018
|
if (isNodeCreationMode) {
|
|
@@ -22194,6 +22299,8 @@ class RepeaterMetadata {
|
|
|
22194
22299
|
*/
|
|
22195
22300
|
function ɵɵrepeaterCreate(index, templateFn, decls, vars, tagName, attrsIndex, trackByFn, trackByUsesComponentInstance, emptyTemplateFn, emptyDecls, emptyVars, emptyTagName, emptyAttrsIndex) {
|
|
22196
22301
|
performanceMarkFeature('NgControlFlow');
|
|
22302
|
+
ngDevMode &&
|
|
22303
|
+
assertFunction(trackByFn, `A track expression must be a function, was ${typeof trackByFn} instead.`);
|
|
22197
22304
|
const hasEmptyBlock = emptyTemplateFn !== undefined;
|
|
22198
22305
|
const hostLView = getLView();
|
|
22199
22306
|
const boundTrackBy = trackByUsesComponentInstance ?
|
|
@@ -22389,7 +22496,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
22389
22496
|
}
|
|
22390
22497
|
setCurrentTNode(tNode, true);
|
|
22391
22498
|
setupStaticAttributes(renderer, native, tNode);
|
|
22392
|
-
if ((tNode
|
|
22499
|
+
if (!isDetachedByI18n(tNode) && wasLastNodeCreated()) {
|
|
22393
22500
|
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
22394
22501
|
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
22395
22502
|
appendChild(tView, lView, native, tNode);
|
|
@@ -22474,7 +22581,8 @@ let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) =>
|
|
|
22474
22581
|
*/
|
|
22475
22582
|
function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, index) {
|
|
22476
22583
|
const hydrationInfo = lView[HYDRATION];
|
|
22477
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
22584
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
22585
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
22478
22586
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22479
22587
|
// Regular creation mode.
|
|
22480
22588
|
if (isNodeCreationMode) {
|
|
@@ -22632,7 +22740,7 @@ let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
|
|
|
22632
22740
|
function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
|
|
22633
22741
|
let comment;
|
|
22634
22742
|
const hydrationInfo = lView[HYDRATION];
|
|
22635
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
|
|
22743
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode);
|
|
22636
22744
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22637
22745
|
// Regular creation mode.
|
|
22638
22746
|
if (isNodeCreationMode) {
|
|
@@ -23245,6 +23353,29 @@ function applyI18n(tView, lView, index) {
|
|
|
23245
23353
|
changeMask = 0b0;
|
|
23246
23354
|
changeMaskCounter = 0;
|
|
23247
23355
|
}
|
|
23356
|
+
function createNodeWithoutHydration(lView, textOrName, nodeType) {
|
|
23357
|
+
const renderer = lView[RENDERER];
|
|
23358
|
+
switch (nodeType) {
|
|
23359
|
+
case Node.COMMENT_NODE:
|
|
23360
|
+
return createCommentNode(renderer, textOrName);
|
|
23361
|
+
case Node.TEXT_NODE:
|
|
23362
|
+
return createTextNode(renderer, textOrName);
|
|
23363
|
+
case Node.ELEMENT_NODE:
|
|
23364
|
+
return createElementNode(renderer, textOrName, null);
|
|
23365
|
+
}
|
|
23366
|
+
}
|
|
23367
|
+
let _locateOrCreateNode = (lView, index, textOrName, nodeType) => {
|
|
23368
|
+
lastNodeWasCreated(true);
|
|
23369
|
+
return createNodeWithoutHydration(lView, textOrName, nodeType);
|
|
23370
|
+
};
|
|
23371
|
+
function locateOrCreateNodeImpl(lView, index, textOrName, nodeType) {
|
|
23372
|
+
// TODO: Add support for hydration
|
|
23373
|
+
lastNodeWasCreated(true);
|
|
23374
|
+
return createNodeWithoutHydration(lView, textOrName, nodeType);
|
|
23375
|
+
}
|
|
23376
|
+
function enableLocateOrCreateI18nNodeImpl() {
|
|
23377
|
+
_locateOrCreateNode = locateOrCreateNodeImpl;
|
|
23378
|
+
}
|
|
23248
23379
|
/**
|
|
23249
23380
|
* Apply `I18nCreateOpCodes` op-codes as stored in `TI18n.create`.
|
|
23250
23381
|
*
|
|
@@ -23265,13 +23396,15 @@ function applyCreateOpCodes(lView, createOpCodes, parentRNode, insertInFrontOf)
|
|
|
23265
23396
|
const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
|
|
23266
23397
|
const index = opCode >>> I18nCreateOpCode.SHIFT;
|
|
23267
23398
|
let rNode = lView[index];
|
|
23399
|
+
let lastNodeWasCreated = false;
|
|
23268
23400
|
if (rNode === null) {
|
|
23269
23401
|
// We only create new DOM nodes if they don't already exist: If ICU switches case back to a
|
|
23270
23402
|
// case which was already instantiated, no need to create new DOM nodes.
|
|
23271
23403
|
rNode = lView[index] =
|
|
23272
|
-
isComment ?
|
|
23404
|
+
_locateOrCreateNode(lView, index, text, isComment ? Node.COMMENT_NODE : Node.TEXT_NODE);
|
|
23405
|
+
lastNodeWasCreated = wasLastNodeCreated();
|
|
23273
23406
|
}
|
|
23274
|
-
if (appendNow && parentRNode !== null) {
|
|
23407
|
+
if (appendNow && parentRNode !== null && lastNodeWasCreated) {
|
|
23275
23408
|
nativeInsertBefore(renderer, parentRNode, rNode, insertInFrontOf, false);
|
|
23276
23409
|
}
|
|
23277
23410
|
}
|
|
@@ -23302,7 +23435,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23302
23435
|
if (lView[textNodeIndex] === null) {
|
|
23303
23436
|
ngDevMode && ngDevMode.rendererCreateTextNode++;
|
|
23304
23437
|
ngDevMode && assertIndexInRange(lView, textNodeIndex);
|
|
23305
|
-
lView[textNodeIndex] =
|
|
23438
|
+
lView[textNodeIndex] = _locateOrCreateNode(lView, textNodeIndex, opCode, Node.TEXT_NODE);
|
|
23306
23439
|
}
|
|
23307
23440
|
}
|
|
23308
23441
|
else if (typeof opCode == 'number') {
|
|
@@ -23377,7 +23510,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23377
23510
|
ngDevMode && ngDevMode.rendererCreateComment++;
|
|
23378
23511
|
ngDevMode && assertIndexInExpandoRange(lView, commentNodeIndex);
|
|
23379
23512
|
const commentRNode = lView[commentNodeIndex] =
|
|
23380
|
-
|
|
23513
|
+
_locateOrCreateNode(lView, commentNodeIndex, commentValue, Node.COMMENT_NODE);
|
|
23381
23514
|
// FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
|
|
23382
23515
|
attachPatchData(commentRNode, lView);
|
|
23383
23516
|
}
|
|
@@ -23391,7 +23524,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23391
23524
|
ngDevMode && ngDevMode.rendererCreateElement++;
|
|
23392
23525
|
ngDevMode && assertIndexInExpandoRange(lView, elementNodeIndex);
|
|
23393
23526
|
const elementRNode = lView[elementNodeIndex] =
|
|
23394
|
-
|
|
23527
|
+
_locateOrCreateNode(lView, elementNodeIndex, tagName, Node.ELEMENT_NODE);
|
|
23395
23528
|
// FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
|
|
23396
23529
|
attachPatchData(elementRNode, lView);
|
|
23397
23530
|
}
|
|
@@ -23918,6 +24051,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23918
24051
|
const createOpCodes = [];
|
|
23919
24052
|
const updateOpCodes = [];
|
|
23920
24053
|
const existingTNodeStack = [[]];
|
|
24054
|
+
const astStack = [[]];
|
|
23921
24055
|
if (ngDevMode) {
|
|
23922
24056
|
attachDebugGetter(createOpCodes, i18nCreateOpCodesToString);
|
|
23923
24057
|
attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
|
|
@@ -23936,7 +24070,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23936
24070
|
const text = part;
|
|
23937
24071
|
ngDevMode && assertString(text, 'Parsed ICU part should be string');
|
|
23938
24072
|
if (text !== '') {
|
|
23939
|
-
i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
|
|
24073
|
+
i18nStartFirstCreatePassProcessTextNode(astStack[0], tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
|
|
23940
24074
|
}
|
|
23941
24075
|
}
|
|
23942
24076
|
else {
|
|
@@ -23955,7 +24089,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23955
24089
|
const icuNodeIndex = icuContainerTNode.index;
|
|
23956
24090
|
ngDevMode &&
|
|
23957
24091
|
assertGreaterThanOrEqual(icuNodeIndex, HEADER_OFFSET, 'Index must be in absolute LView offset');
|
|
23958
|
-
icuStart(tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
|
|
24092
|
+
icuStart(astStack[0], tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
|
|
23959
24093
|
}
|
|
23960
24094
|
}
|
|
23961
24095
|
}
|
|
@@ -23968,18 +24102,29 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23968
24102
|
const index = HEADER_OFFSET + Number.parseInt(value.substring((isClosing ? 2 : 1)));
|
|
23969
24103
|
if (isClosing) {
|
|
23970
24104
|
existingTNodeStack.shift();
|
|
24105
|
+
astStack.shift();
|
|
23971
24106
|
setCurrentTNode(getCurrentParentTNode(), false);
|
|
23972
24107
|
}
|
|
23973
24108
|
else {
|
|
23974
24109
|
const tNode = createTNodePlaceholder(tView, existingTNodeStack[0], index);
|
|
23975
24110
|
existingTNodeStack.unshift([]);
|
|
23976
24111
|
setCurrentTNode(tNode, true);
|
|
24112
|
+
const placeholderNode = {
|
|
24113
|
+
kind: 2 /* I18nNodeKind.PLACEHOLDER */,
|
|
24114
|
+
index,
|
|
24115
|
+
children: [],
|
|
24116
|
+
type: type === 35 /* CharCode.HASH */ ? 0 /* I18nPlaceholderType.ELEMENT */ :
|
|
24117
|
+
1 /* I18nPlaceholderType.SUBTEMPLATE */,
|
|
24118
|
+
};
|
|
24119
|
+
astStack[0].push(placeholderNode);
|
|
24120
|
+
astStack.unshift(placeholderNode.children);
|
|
23977
24121
|
}
|
|
23978
24122
|
}
|
|
23979
24123
|
}
|
|
23980
24124
|
tView.data[index] = {
|
|
23981
24125
|
create: createOpCodes,
|
|
23982
24126
|
update: updateOpCodes,
|
|
24127
|
+
ast: astStack[0],
|
|
23983
24128
|
};
|
|
23984
24129
|
}
|
|
23985
24130
|
/**
|
|
@@ -24048,12 +24193,14 @@ function createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, create
|
|
|
24048
24193
|
* @param lView Current `LView`
|
|
24049
24194
|
* @param text The translated text (which may contain binding)
|
|
24050
24195
|
*/
|
|
24051
|
-
function i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
|
|
24196
|
+
function i18nStartFirstCreatePassProcessTextNode(ast, tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
|
|
24052
24197
|
const hasBinding = text.match(BINDING_REGEXP);
|
|
24053
24198
|
const tNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, hasBinding ? null : text, false);
|
|
24199
|
+
const index = tNode.index;
|
|
24054
24200
|
if (hasBinding) {
|
|
24055
|
-
generateBindingUpdateOpCodes(updateOpCodes, text,
|
|
24201
|
+
generateBindingUpdateOpCodes(updateOpCodes, text, index, null, 0, null);
|
|
24056
24202
|
}
|
|
24203
|
+
ast.push({ kind: 0 /* I18nNodeKind.TEXT */, index });
|
|
24057
24204
|
}
|
|
24058
24205
|
/**
|
|
24059
24206
|
* See `i18nAttributes` above.
|
|
@@ -24231,7 +24378,7 @@ function getTranslationForTemplate(message, subTemplateIndex) {
|
|
|
24231
24378
|
* - `lView[anchorIdx]` points to a `Comment` node representing the anchor for the ICU.
|
|
24232
24379
|
* - `tView.data[anchorIdx]` points to the `TIcuContainerNode` if ICU is root (`null` otherwise)
|
|
24233
24380
|
*/
|
|
24234
|
-
function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
|
|
24381
|
+
function icuStart(ast, tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
|
|
24235
24382
|
ngDevMode && assertDefined(icuExpression, 'ICU expression must be defined');
|
|
24236
24383
|
let bindingMask = 0;
|
|
24237
24384
|
const tIcu = {
|
|
@@ -24246,6 +24393,7 @@ function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorI
|
|
|
24246
24393
|
addUpdateIcuSwitch(updateOpCodes, icuExpression, anchorIdx);
|
|
24247
24394
|
setTIcu(tView, anchorIdx, tIcu);
|
|
24248
24395
|
const values = icuExpression.values;
|
|
24396
|
+
const cases = [];
|
|
24249
24397
|
for (let i = 0; i < values.length; i++) {
|
|
24250
24398
|
// Each value is an array of strings & other ICU expressions
|
|
24251
24399
|
const valueArr = values[i];
|
|
@@ -24259,12 +24407,20 @@ function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorI
|
|
|
24259
24407
|
valueArr[j] = `<!--�${icuIndex}�-->`;
|
|
24260
24408
|
}
|
|
24261
24409
|
}
|
|
24262
|
-
|
|
24410
|
+
const caseAst = [];
|
|
24411
|
+
cases.push(caseAst);
|
|
24412
|
+
bindingMask = parseIcuCase(caseAst, tView, tIcu, lView, updateOpCodes, parentIdx, icuExpression.cases[i], valueArr.join(''), nestedIcus) |
|
|
24263
24413
|
bindingMask;
|
|
24264
24414
|
}
|
|
24265
24415
|
if (bindingMask) {
|
|
24266
24416
|
addUpdateIcuUpdate(updateOpCodes, bindingMask, anchorIdx);
|
|
24267
24417
|
}
|
|
24418
|
+
ast.push({
|
|
24419
|
+
kind: 3 /* I18nNodeKind.ICU */,
|
|
24420
|
+
index: anchorIdx,
|
|
24421
|
+
cases,
|
|
24422
|
+
currentCaseLViewIndex: tIcu.currentCaseLViewIndex
|
|
24423
|
+
});
|
|
24268
24424
|
}
|
|
24269
24425
|
/**
|
|
24270
24426
|
* Parses text containing an ICU expression and produces a JSON object for it.
|
|
@@ -24361,7 +24517,7 @@ function i18nParseTextIntoPartsAndICU(pattern) {
|
|
|
24361
24517
|
* Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
|
|
24362
24518
|
*
|
|
24363
24519
|
*/
|
|
24364
|
-
function parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
|
|
24520
|
+
function parseIcuCase(ast, tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
|
|
24365
24521
|
const create = [];
|
|
24366
24522
|
const remove = [];
|
|
24367
24523
|
const update = [];
|
|
@@ -24379,13 +24535,13 @@ function parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, caseName, un
|
|
|
24379
24535
|
ngDevMode && assertDefined(inertBodyElement, 'Unable to generate inert body element');
|
|
24380
24536
|
const inertRootNode = getTemplateContent(inertBodyElement) || inertBodyElement;
|
|
24381
24537
|
if (inertRootNode) {
|
|
24382
|
-
return walkIcuTree(tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
|
|
24538
|
+
return walkIcuTree(ast, tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
|
|
24383
24539
|
}
|
|
24384
24540
|
else {
|
|
24385
24541
|
return 0;
|
|
24386
24542
|
}
|
|
24387
24543
|
}
|
|
24388
|
-
function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
|
|
24544
|
+
function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
|
|
24389
24545
|
let bindingMask = 0;
|
|
24390
24546
|
let currentNode = parentNode.firstChild;
|
|
24391
24547
|
while (currentNode) {
|
|
@@ -24423,9 +24579,16 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24423
24579
|
addCreateAttribute(create, newIndex, attr);
|
|
24424
24580
|
}
|
|
24425
24581
|
}
|
|
24582
|
+
const elementNode = {
|
|
24583
|
+
kind: 1 /* I18nNodeKind.ELEMENT */,
|
|
24584
|
+
index: newIndex,
|
|
24585
|
+
children: [],
|
|
24586
|
+
};
|
|
24587
|
+
ast.push(elementNode);
|
|
24426
24588
|
// Parse the children of this node (if any)
|
|
24427
|
-
bindingMask =
|
|
24428
|
-
|
|
24589
|
+
bindingMask =
|
|
24590
|
+
walkIcuTree(elementNode.children, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, currentNode, newIndex, nestedIcus, depth + 1) |
|
|
24591
|
+
bindingMask;
|
|
24429
24592
|
addRemoveNode(remove, newIndex, depth);
|
|
24430
24593
|
}
|
|
24431
24594
|
break;
|
|
@@ -24438,6 +24601,10 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24438
24601
|
bindingMask =
|
|
24439
24602
|
generateBindingUpdateOpCodes(update, value, newIndex, null, 0, null) | bindingMask;
|
|
24440
24603
|
}
|
|
24604
|
+
ast.push({
|
|
24605
|
+
kind: 0 /* I18nNodeKind.TEXT */,
|
|
24606
|
+
index: newIndex,
|
|
24607
|
+
});
|
|
24441
24608
|
break;
|
|
24442
24609
|
case Node.COMMENT_NODE:
|
|
24443
24610
|
// Check if the comment node is a placeholder for a nested ICU
|
|
@@ -24447,7 +24614,7 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24447
24614
|
const icuExpression = nestedIcus[nestedIcuIndex];
|
|
24448
24615
|
// Create the comment node that will anchor the ICU expression
|
|
24449
24616
|
addCreateNodeAndAppend(create, ICU_MARKER, ngDevMode ? `nested ICU ${nestedIcuIndex}` : '', parentIdx, newIndex);
|
|
24450
|
-
icuStart(tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
|
|
24617
|
+
icuStart(ast, tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
|
|
24451
24618
|
addRemoveNestedIcu(remove, newIndex, depth);
|
|
24452
24619
|
}
|
|
24453
24620
|
break;
|
|
@@ -26410,7 +26577,8 @@ let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
|
|
|
26410
26577
|
*/
|
|
26411
26578
|
function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
|
|
26412
26579
|
const hydrationInfo = lView[HYDRATION];
|
|
26413
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
26580
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
26581
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
26414
26582
|
lastNodeWasCreated(isNodeCreationMode);
|
|
26415
26583
|
// Regular creation mode.
|
|
26416
26584
|
if (isNodeCreationMode) {
|
|
@@ -29570,7 +29738,7 @@ class Version {
|
|
|
29570
29738
|
/**
|
|
29571
29739
|
* @publicApi
|
|
29572
29740
|
*/
|
|
29573
|
-
const VERSION = new Version('17.3.0
|
|
29741
|
+
const VERSION = new Version('17.3.0');
|
|
29574
29742
|
|
|
29575
29743
|
class Console {
|
|
29576
29744
|
log(message) {
|
|
@@ -29590,14 +29758,6 @@ class Console {
|
|
|
29590
29758
|
args: [{ providedIn: 'platform' }]
|
|
29591
29759
|
}], null, null); })();
|
|
29592
29760
|
|
|
29593
|
-
/**
|
|
29594
|
-
* Used to patch behavior that needs to _temporarily_ be different between g3 and external.
|
|
29595
|
-
*
|
|
29596
|
-
* For example, make breaking changes ahead of the main branch targeting a major version.
|
|
29597
|
-
* Permanent differences between g3 and external should be configured by individual patches.
|
|
29598
|
-
*/
|
|
29599
|
-
const isG3 = false;
|
|
29600
|
-
|
|
29601
29761
|
/**
|
|
29602
29762
|
* These are the data structures that our framework injector profiler will fill with data in order
|
|
29603
29763
|
* to support DI debugging APIs.
|
|
@@ -31229,6 +31389,10 @@ class ApplicationRef {
|
|
|
31229
31389
|
* detection pass during which all change detection must complete.
|
|
31230
31390
|
*/
|
|
31231
31391
|
tick() {
|
|
31392
|
+
this._tick(true);
|
|
31393
|
+
}
|
|
31394
|
+
/** @internal */
|
|
31395
|
+
_tick(refreshViews) {
|
|
31232
31396
|
(typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
|
|
31233
31397
|
if (this._runningTick) {
|
|
31234
31398
|
throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, ngDevMode && 'ApplicationRef.tick is called recursively');
|
|
@@ -31236,7 +31400,7 @@ class ApplicationRef {
|
|
|
31236
31400
|
const prevConsumer = setActiveConsumer$1(null);
|
|
31237
31401
|
try {
|
|
31238
31402
|
this._runningTick = true;
|
|
31239
|
-
this.detectChangesInAttachedViews();
|
|
31403
|
+
this.detectChangesInAttachedViews(refreshViews);
|
|
31240
31404
|
if ((typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
31241
31405
|
for (let view of this._views) {
|
|
31242
31406
|
view.checkNoChanges();
|
|
@@ -31253,7 +31417,7 @@ class ApplicationRef {
|
|
|
31253
31417
|
setActiveConsumer$1(prevConsumer);
|
|
31254
31418
|
}
|
|
31255
31419
|
}
|
|
31256
|
-
detectChangesInAttachedViews() {
|
|
31420
|
+
detectChangesInAttachedViews(refreshViews) {
|
|
31257
31421
|
let runs = 0;
|
|
31258
31422
|
const afterRenderEffectManager = this.afterRenderEffectManager;
|
|
31259
31423
|
while (true) {
|
|
@@ -31262,10 +31426,12 @@ class ApplicationRef {
|
|
|
31262
31426
|
'Infinite change detection while refreshing application views. ' +
|
|
31263
31427
|
'Ensure afterRender or queueStateUpdate hooks are not continuously causing updates.');
|
|
31264
31428
|
}
|
|
31265
|
-
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31429
|
+
if (refreshViews) {
|
|
31430
|
+
const isFirstPass = runs === 0;
|
|
31431
|
+
this.beforeRender.next(isFirstPass);
|
|
31432
|
+
for (let { _lView, notifyErrorHandler } of this._views) {
|
|
31433
|
+
detectChangesInViewIfRequired(_lView, isFirstPass, notifyErrorHandler);
|
|
31434
|
+
}
|
|
31269
31435
|
}
|
|
31270
31436
|
runs++;
|
|
31271
31437
|
afterRenderEffectManager.executeInternalCallbacks();
|
|
@@ -31412,9 +31578,7 @@ function detectChangesInViewIfRequired(lView, isFirstPass, notifyErrorHandler) {
|
|
|
31412
31578
|
detectChangesInView(lView, notifyErrorHandler, isFirstPass);
|
|
31413
31579
|
}
|
|
31414
31580
|
function shouldRecheckView(view) {
|
|
31415
|
-
return requiresRefreshOrTraversal(view)
|
|
31416
|
-
// TODO(atscott): Remove isG3 check and make this a breaking change for v18
|
|
31417
|
-
(isG3 && !!(view[FLAGS] & 64 /* LViewFlags.Dirty */));
|
|
31581
|
+
return requiresRefreshOrTraversal(view);
|
|
31418
31582
|
}
|
|
31419
31583
|
function detectChangesInView(lView, notifyErrorHandler, isFirstPass) {
|
|
31420
31584
|
let mode;
|
|
@@ -34833,10 +34997,15 @@ class ChangeDetectionSchedulerImpl {
|
|
|
34833
34997
|
this.appRef = inject(ApplicationRef);
|
|
34834
34998
|
this.taskService = inject(PendingTasks);
|
|
34835
34999
|
this.pendingRenderTaskId = null;
|
|
35000
|
+
this.shouldRefreshViews = false;
|
|
34836
35001
|
}
|
|
34837
|
-
notify() {
|
|
34838
|
-
|
|
35002
|
+
notify(type = 0 /* NotificationType.RefreshViews */) {
|
|
35003
|
+
// When the only source of notification is an afterRender hook will skip straight to the hooks
|
|
35004
|
+
// rather than refreshing views in ApplicationRef.tick
|
|
35005
|
+
this.shouldRefreshViews ||= type === 0 /* NotificationType.RefreshViews */;
|
|
35006
|
+
if (this.pendingRenderTaskId !== null) {
|
|
34839
35007
|
return;
|
|
35008
|
+
}
|
|
34840
35009
|
this.pendingRenderTaskId = this.taskService.add();
|
|
34841
35010
|
this.raceTimeoutAndRequestAnimationFrame();
|
|
34842
35011
|
}
|
|
@@ -34874,10 +35043,11 @@ class ChangeDetectionSchedulerImpl {
|
|
|
34874
35043
|
tick() {
|
|
34875
35044
|
try {
|
|
34876
35045
|
if (!this.appRef.destroyed) {
|
|
34877
|
-
this.appRef.
|
|
35046
|
+
this.appRef._tick(this.shouldRefreshViews);
|
|
34878
35047
|
}
|
|
34879
35048
|
}
|
|
34880
35049
|
finally {
|
|
35050
|
+
this.shouldRefreshViews = false;
|
|
34881
35051
|
// If this is the last task, the service will synchronously emit a stable notification. If
|
|
34882
35052
|
// there is a subscriber that then acts in a way that tries to notify the scheduler again,
|
|
34883
35053
|
// we need to be able to respond to schedule a new change detection. Therefore, we should
|
|
@@ -34939,6 +35109,226 @@ function getDeferBlocks(lView, deferBlocks) {
|
|
|
34939
35109
|
}
|
|
34940
35110
|
}
|
|
34941
35111
|
|
|
35112
|
+
/**
|
|
35113
|
+
* Indicates whether the hydration-related code was added,
|
|
35114
|
+
* prevents adding it multiple times.
|
|
35115
|
+
*/
|
|
35116
|
+
let isHydrationSupportEnabled = false;
|
|
35117
|
+
/**
|
|
35118
|
+
* Indicates whether support for hydrating i18n blocks is enabled.
|
|
35119
|
+
*/
|
|
35120
|
+
let _isI18nHydrationSupportEnabled = false;
|
|
35121
|
+
/**
|
|
35122
|
+
* Defines a period of time that Angular waits for the `ApplicationRef.isStable` to emit `true`.
|
|
35123
|
+
* If there was no event with the `true` value during this time, Angular reports a warning.
|
|
35124
|
+
*/
|
|
35125
|
+
const APPLICATION_IS_STABLE_TIMEOUT = 10_000;
|
|
35126
|
+
/**
|
|
35127
|
+
* Brings the necessary hydration code in tree-shakable manner.
|
|
35128
|
+
* The code is only present when the `provideClientHydration` is
|
|
35129
|
+
* invoked. Otherwise, this code is tree-shaken away during the
|
|
35130
|
+
* build optimization step.
|
|
35131
|
+
*
|
|
35132
|
+
* This technique allows us to swap implementations of methods so
|
|
35133
|
+
* tree shaking works appropriately when hydration is disabled or
|
|
35134
|
+
* enabled. It brings in the appropriate version of the method that
|
|
35135
|
+
* supports hydration only when enabled.
|
|
35136
|
+
*/
|
|
35137
|
+
function enableHydrationRuntimeSupport() {
|
|
35138
|
+
if (!isHydrationSupportEnabled) {
|
|
35139
|
+
isHydrationSupportEnabled = true;
|
|
35140
|
+
enableRetrieveHydrationInfoImpl();
|
|
35141
|
+
enableLocateOrCreateElementNodeImpl();
|
|
35142
|
+
enableLocateOrCreateTextNodeImpl();
|
|
35143
|
+
enableLocateOrCreateElementContainerNodeImpl();
|
|
35144
|
+
enableLocateOrCreateContainerAnchorImpl();
|
|
35145
|
+
enableLocateOrCreateContainerRefImpl();
|
|
35146
|
+
enableFindMatchingDehydratedViewImpl();
|
|
35147
|
+
enableApplyRootElementTransformImpl();
|
|
35148
|
+
enableLocateOrCreateI18nNodeImpl();
|
|
35149
|
+
}
|
|
35150
|
+
}
|
|
35151
|
+
/**
|
|
35152
|
+
* Outputs a message with hydration stats into a console.
|
|
35153
|
+
*/
|
|
35154
|
+
function printHydrationStats(injector) {
|
|
35155
|
+
const console = injector.get(Console);
|
|
35156
|
+
const message = `Angular hydrated ${ngDevMode.hydratedComponents} component(s) ` +
|
|
35157
|
+
`and ${ngDevMode.hydratedNodes} node(s), ` +
|
|
35158
|
+
`${ngDevMode.componentsSkippedHydration} component(s) were skipped. ` +
|
|
35159
|
+
`Learn more at https://angular.io/guide/hydration.`;
|
|
35160
|
+
// tslint:disable-next-line:no-console
|
|
35161
|
+
console.log(message);
|
|
35162
|
+
}
|
|
35163
|
+
/**
|
|
35164
|
+
* Returns a Promise that is resolved when an application becomes stable.
|
|
35165
|
+
*/
|
|
35166
|
+
function whenStableWithTimeout(appRef, injector) {
|
|
35167
|
+
const whenStablePromise = whenStable(appRef);
|
|
35168
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35169
|
+
const timeoutTime = APPLICATION_IS_STABLE_TIMEOUT;
|
|
35170
|
+
const console = injector.get(Console);
|
|
35171
|
+
const ngZone = injector.get(NgZone);
|
|
35172
|
+
// The following call should not and does not prevent the app to become stable
|
|
35173
|
+
// We cannot use RxJS timer here because the app would remain unstable.
|
|
35174
|
+
// This also avoids an extra change detection cycle.
|
|
35175
|
+
const timeoutId = ngZone.runOutsideAngular(() => {
|
|
35176
|
+
return setTimeout(() => logWarningOnStableTimedout(timeoutTime, console), timeoutTime);
|
|
35177
|
+
});
|
|
35178
|
+
whenStablePromise.finally(() => clearTimeout(timeoutId));
|
|
35179
|
+
}
|
|
35180
|
+
return whenStablePromise;
|
|
35181
|
+
}
|
|
35182
|
+
/**
|
|
35183
|
+
* Returns a set of providers required to setup hydration support
|
|
35184
|
+
* for an application that is server side rendered. This function is
|
|
35185
|
+
* included into the `provideClientHydration` public API function from
|
|
35186
|
+
* the `platform-browser` package.
|
|
35187
|
+
*
|
|
35188
|
+
* The function sets up an internal flag that would be recognized during
|
|
35189
|
+
* the server side rendering time as well, so there is no need to
|
|
35190
|
+
* configure or change anything in NgUniversal to enable the feature.
|
|
35191
|
+
*/
|
|
35192
|
+
function withDomHydration() {
|
|
35193
|
+
return makeEnvironmentProviders([
|
|
35194
|
+
{
|
|
35195
|
+
provide: IS_HYDRATION_DOM_REUSE_ENABLED,
|
|
35196
|
+
useFactory: () => {
|
|
35197
|
+
let isEnabled = true;
|
|
35198
|
+
if (isPlatformBrowser()) {
|
|
35199
|
+
// On the client, verify that the server response contains
|
|
35200
|
+
// hydration annotations. Otherwise, keep hydration disabled.
|
|
35201
|
+
const transferState = inject(TransferState, { optional: true });
|
|
35202
|
+
isEnabled = !!transferState?.get(NGH_DATA_KEY, null);
|
|
35203
|
+
if (!isEnabled && (typeof ngDevMode !== 'undefined' && ngDevMode)) {
|
|
35204
|
+
const console = inject(Console);
|
|
35205
|
+
const message = formatRuntimeError(-505 /* RuntimeErrorCode.MISSING_HYDRATION_ANNOTATIONS */, 'Angular hydration was requested on the client, but there was no ' +
|
|
35206
|
+
'serialized information present in the server response, ' +
|
|
35207
|
+
'thus hydration was not enabled. ' +
|
|
35208
|
+
'Make sure the `provideClientHydration()` is included into the list ' +
|
|
35209
|
+
'of providers in the server part of the application configuration.');
|
|
35210
|
+
// tslint:disable-next-line:no-console
|
|
35211
|
+
console.warn(message);
|
|
35212
|
+
}
|
|
35213
|
+
}
|
|
35214
|
+
if (isEnabled) {
|
|
35215
|
+
performanceMarkFeature('NgHydration');
|
|
35216
|
+
}
|
|
35217
|
+
return isEnabled;
|
|
35218
|
+
},
|
|
35219
|
+
},
|
|
35220
|
+
{
|
|
35221
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
35222
|
+
useValue: () => {
|
|
35223
|
+
_isI18nHydrationSupportEnabled = !!inject(IS_I18N_HYDRATION_ENABLED, { optional: true });
|
|
35224
|
+
// Since this function is used across both server and client,
|
|
35225
|
+
// make sure that the runtime code is only added when invoked
|
|
35226
|
+
// on the client. Moving forward, the `isPlatformBrowser` check should
|
|
35227
|
+
// be replaced with a tree-shakable alternative (e.g. `isServer`
|
|
35228
|
+
// flag).
|
|
35229
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35230
|
+
verifySsrContentsIntegrity();
|
|
35231
|
+
enableHydrationRuntimeSupport();
|
|
35232
|
+
}
|
|
35233
|
+
},
|
|
35234
|
+
multi: true,
|
|
35235
|
+
},
|
|
35236
|
+
{
|
|
35237
|
+
provide: PRESERVE_HOST_CONTENT,
|
|
35238
|
+
useFactory: () => {
|
|
35239
|
+
// Preserve host element content only in a browser
|
|
35240
|
+
// environment and when hydration is configured properly.
|
|
35241
|
+
// On a server, an application is rendered from scratch,
|
|
35242
|
+
// so the host content needs to be empty.
|
|
35243
|
+
return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
|
|
35244
|
+
}
|
|
35245
|
+
},
|
|
35246
|
+
{
|
|
35247
|
+
provide: APP_BOOTSTRAP_LISTENER,
|
|
35248
|
+
useFactory: () => {
|
|
35249
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35250
|
+
const appRef = inject(ApplicationRef);
|
|
35251
|
+
const injector = inject(Injector);
|
|
35252
|
+
return () => {
|
|
35253
|
+
// Wait until an app becomes stable and cleanup all views that
|
|
35254
|
+
// were not claimed during the application bootstrap process.
|
|
35255
|
+
// The timing is similar to when we start the serialization process
|
|
35256
|
+
// on the server.
|
|
35257
|
+
//
|
|
35258
|
+
// Note: the cleanup task *MUST* be scheduled within the Angular zone
|
|
35259
|
+
// to ensure that change detection is properly run afterward.
|
|
35260
|
+
whenStableWithTimeout(appRef, injector).then(() => {
|
|
35261
|
+
NgZone.assertInAngularZone();
|
|
35262
|
+
cleanupDehydratedViews(appRef);
|
|
35263
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35264
|
+
printHydrationStats(injector);
|
|
35265
|
+
}
|
|
35266
|
+
});
|
|
35267
|
+
};
|
|
35268
|
+
}
|
|
35269
|
+
return () => { }; // noop
|
|
35270
|
+
},
|
|
35271
|
+
multi: true,
|
|
35272
|
+
}
|
|
35273
|
+
]);
|
|
35274
|
+
}
|
|
35275
|
+
/**
|
|
35276
|
+
* Returns a set of providers required to setup support for i18n hydration.
|
|
35277
|
+
* Requires hydration to be enabled separately.
|
|
35278
|
+
*/
|
|
35279
|
+
function withI18nHydration() {
|
|
35280
|
+
return makeEnvironmentProviders([
|
|
35281
|
+
{
|
|
35282
|
+
provide: IS_I18N_HYDRATION_ENABLED,
|
|
35283
|
+
useValue: true,
|
|
35284
|
+
},
|
|
35285
|
+
]);
|
|
35286
|
+
}
|
|
35287
|
+
/**
|
|
35288
|
+
* Returns whether i18n hydration support is enabled.
|
|
35289
|
+
*/
|
|
35290
|
+
function isI18nHydrationSupportEnabled() {
|
|
35291
|
+
return _isI18nHydrationSupportEnabled;
|
|
35292
|
+
}
|
|
35293
|
+
/**
|
|
35294
|
+
*
|
|
35295
|
+
* @param time The time in ms until the stable timedout warning message is logged
|
|
35296
|
+
*/
|
|
35297
|
+
function logWarningOnStableTimedout(time, console) {
|
|
35298
|
+
const message = `Angular hydration expected the ApplicationRef.isStable() to emit \`true\`, but it ` +
|
|
35299
|
+
`didn't happen within ${time}ms. Angular hydration logic depends on the application becoming stable ` +
|
|
35300
|
+
`as a signal to complete hydration process.`;
|
|
35301
|
+
console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
|
|
35302
|
+
}
|
|
35303
|
+
/**
|
|
35304
|
+
* Verifies whether the DOM contains a special marker added during SSR time to make sure
|
|
35305
|
+
* there is no SSR'ed contents transformations happen after SSR is completed. Typically that
|
|
35306
|
+
* happens either by CDN or during the build process as an optimization to remove comment nodes.
|
|
35307
|
+
* Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
|
|
35308
|
+
* When this special marker is *not* present - throw an error and do not proceed with hydration,
|
|
35309
|
+
* since it will not be able to function correctly.
|
|
35310
|
+
*
|
|
35311
|
+
* Note: this function is invoked only on the client, so it's safe to use DOM APIs.
|
|
35312
|
+
*/
|
|
35313
|
+
function verifySsrContentsIntegrity() {
|
|
35314
|
+
const doc = getDocument();
|
|
35315
|
+
let hydrationMarker;
|
|
35316
|
+
for (const node of doc.body.childNodes) {
|
|
35317
|
+
if (node.nodeType === Node.COMMENT_NODE &&
|
|
35318
|
+
node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
|
|
35319
|
+
hydrationMarker = node;
|
|
35320
|
+
break;
|
|
35321
|
+
}
|
|
35322
|
+
}
|
|
35323
|
+
if (!hydrationMarker) {
|
|
35324
|
+
throw new RuntimeError(-507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode &&
|
|
35325
|
+
'Angular hydration logic detected that HTML content of this page was modified after it ' +
|
|
35326
|
+
'was produced during server side rendering. Make sure that there are no optimizations ' +
|
|
35327
|
+
'that remove comment nodes from HTML enabled on your CDN. Angular hydration ' +
|
|
35328
|
+
'relies on HTML produced by the server, including whitespaces and comment nodes.');
|
|
35329
|
+
}
|
|
35330
|
+
}
|
|
35331
|
+
|
|
34942
35332
|
/**
|
|
34943
35333
|
* A collection that tracks all serialized views (`ngh` DOM annotations)
|
|
34944
35334
|
* to avoid duplication. An attempt to add a duplicate view results in the
|
|
@@ -35396,7 +35786,8 @@ function componentUsesShadowDomEncapsulation(lView) {
|
|
|
35396
35786
|
*/
|
|
35397
35787
|
function annotateHostElementForHydration(element, lView, context) {
|
|
35398
35788
|
const renderer = lView[RENDERER];
|
|
35399
|
-
if (hasI18n(lView)
|
|
35789
|
+
if ((hasI18n(lView) && !isI18nHydrationSupportEnabled()) ||
|
|
35790
|
+
componentUsesShadowDomEncapsulation(lView)) {
|
|
35400
35791
|
// Attach the skip hydration attribute if this component:
|
|
35401
35792
|
// - either has i18n blocks, since hydrating such blocks is not yet supported
|
|
35402
35793
|
// - or uses ShadowDom view encapsulation, since Domino doesn't support
|
|
@@ -35443,202 +35834,6 @@ function isContentProjectedNode(tNode) {
|
|
|
35443
35834
|
return false;
|
|
35444
35835
|
}
|
|
35445
35836
|
|
|
35446
|
-
/**
|
|
35447
|
-
* Indicates whether the hydration-related code was added,
|
|
35448
|
-
* prevents adding it multiple times.
|
|
35449
|
-
*/
|
|
35450
|
-
let isHydrationSupportEnabled = false;
|
|
35451
|
-
/**
|
|
35452
|
-
* Defines a period of time that Angular waits for the `ApplicationRef.isStable` to emit `true`.
|
|
35453
|
-
* If there was no event with the `true` value during this time, Angular reports a warning.
|
|
35454
|
-
*/
|
|
35455
|
-
const APPLICATION_IS_STABLE_TIMEOUT = 10_000;
|
|
35456
|
-
/**
|
|
35457
|
-
* Brings the necessary hydration code in tree-shakable manner.
|
|
35458
|
-
* The code is only present when the `provideClientHydration` is
|
|
35459
|
-
* invoked. Otherwise, this code is tree-shaken away during the
|
|
35460
|
-
* build optimization step.
|
|
35461
|
-
*
|
|
35462
|
-
* This technique allows us to swap implementations of methods so
|
|
35463
|
-
* tree shaking works appropriately when hydration is disabled or
|
|
35464
|
-
* enabled. It brings in the appropriate version of the method that
|
|
35465
|
-
* supports hydration only when enabled.
|
|
35466
|
-
*/
|
|
35467
|
-
function enableHydrationRuntimeSupport() {
|
|
35468
|
-
if (!isHydrationSupportEnabled) {
|
|
35469
|
-
isHydrationSupportEnabled = true;
|
|
35470
|
-
enableRetrieveHydrationInfoImpl();
|
|
35471
|
-
enableLocateOrCreateElementNodeImpl();
|
|
35472
|
-
enableLocateOrCreateTextNodeImpl();
|
|
35473
|
-
enableLocateOrCreateElementContainerNodeImpl();
|
|
35474
|
-
enableLocateOrCreateContainerAnchorImpl();
|
|
35475
|
-
enableLocateOrCreateContainerRefImpl();
|
|
35476
|
-
enableFindMatchingDehydratedViewImpl();
|
|
35477
|
-
enableApplyRootElementTransformImpl();
|
|
35478
|
-
}
|
|
35479
|
-
}
|
|
35480
|
-
/**
|
|
35481
|
-
* Outputs a message with hydration stats into a console.
|
|
35482
|
-
*/
|
|
35483
|
-
function printHydrationStats(injector) {
|
|
35484
|
-
const console = injector.get(Console);
|
|
35485
|
-
const message = `Angular hydrated ${ngDevMode.hydratedComponents} component(s) ` +
|
|
35486
|
-
`and ${ngDevMode.hydratedNodes} node(s), ` +
|
|
35487
|
-
`${ngDevMode.componentsSkippedHydration} component(s) were skipped. ` +
|
|
35488
|
-
`Learn more at https://angular.io/guide/hydration.`;
|
|
35489
|
-
// tslint:disable-next-line:no-console
|
|
35490
|
-
console.log(message);
|
|
35491
|
-
}
|
|
35492
|
-
/**
|
|
35493
|
-
* Returns a Promise that is resolved when an application becomes stable.
|
|
35494
|
-
*/
|
|
35495
|
-
function whenStableWithTimeout(appRef, injector) {
|
|
35496
|
-
const whenStablePromise = whenStable(appRef);
|
|
35497
|
-
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35498
|
-
const timeoutTime = APPLICATION_IS_STABLE_TIMEOUT;
|
|
35499
|
-
const console = injector.get(Console);
|
|
35500
|
-
const ngZone = injector.get(NgZone);
|
|
35501
|
-
// The following call should not and does not prevent the app to become stable
|
|
35502
|
-
// We cannot use RxJS timer here because the app would remain unstable.
|
|
35503
|
-
// This also avoids an extra change detection cycle.
|
|
35504
|
-
const timeoutId = ngZone.runOutsideAngular(() => {
|
|
35505
|
-
return setTimeout(() => logWarningOnStableTimedout(timeoutTime, console), timeoutTime);
|
|
35506
|
-
});
|
|
35507
|
-
whenStablePromise.finally(() => clearTimeout(timeoutId));
|
|
35508
|
-
}
|
|
35509
|
-
return whenStablePromise;
|
|
35510
|
-
}
|
|
35511
|
-
/**
|
|
35512
|
-
* Returns a set of providers required to setup hydration support
|
|
35513
|
-
* for an application that is server side rendered. This function is
|
|
35514
|
-
* included into the `provideClientHydration` public API function from
|
|
35515
|
-
* the `platform-browser` package.
|
|
35516
|
-
*
|
|
35517
|
-
* The function sets up an internal flag that would be recognized during
|
|
35518
|
-
* the server side rendering time as well, so there is no need to
|
|
35519
|
-
* configure or change anything in NgUniversal to enable the feature.
|
|
35520
|
-
*/
|
|
35521
|
-
function withDomHydration() {
|
|
35522
|
-
return makeEnvironmentProviders([
|
|
35523
|
-
{
|
|
35524
|
-
provide: IS_HYDRATION_DOM_REUSE_ENABLED,
|
|
35525
|
-
useFactory: () => {
|
|
35526
|
-
let isEnabled = true;
|
|
35527
|
-
if (isPlatformBrowser()) {
|
|
35528
|
-
// On the client, verify that the server response contains
|
|
35529
|
-
// hydration annotations. Otherwise, keep hydration disabled.
|
|
35530
|
-
const transferState = inject(TransferState, { optional: true });
|
|
35531
|
-
isEnabled = !!transferState?.get(NGH_DATA_KEY, null);
|
|
35532
|
-
if (!isEnabled && (typeof ngDevMode !== 'undefined' && ngDevMode)) {
|
|
35533
|
-
const console = inject(Console);
|
|
35534
|
-
const message = formatRuntimeError(-505 /* RuntimeErrorCode.MISSING_HYDRATION_ANNOTATIONS */, 'Angular hydration was requested on the client, but there was no ' +
|
|
35535
|
-
'serialized information present in the server response, ' +
|
|
35536
|
-
'thus hydration was not enabled. ' +
|
|
35537
|
-
'Make sure the `provideClientHydration()` is included into the list ' +
|
|
35538
|
-
'of providers in the server part of the application configuration.');
|
|
35539
|
-
// tslint:disable-next-line:no-console
|
|
35540
|
-
console.warn(message);
|
|
35541
|
-
}
|
|
35542
|
-
}
|
|
35543
|
-
if (isEnabled) {
|
|
35544
|
-
performanceMarkFeature('NgHydration');
|
|
35545
|
-
}
|
|
35546
|
-
return isEnabled;
|
|
35547
|
-
},
|
|
35548
|
-
},
|
|
35549
|
-
{
|
|
35550
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
35551
|
-
useValue: () => {
|
|
35552
|
-
// Since this function is used across both server and client,
|
|
35553
|
-
// make sure that the runtime code is only added when invoked
|
|
35554
|
-
// on the client. Moving forward, the `isPlatformBrowser` check should
|
|
35555
|
-
// be replaced with a tree-shakable alternative (e.g. `isServer`
|
|
35556
|
-
// flag).
|
|
35557
|
-
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35558
|
-
verifySsrContentsIntegrity();
|
|
35559
|
-
enableHydrationRuntimeSupport();
|
|
35560
|
-
}
|
|
35561
|
-
},
|
|
35562
|
-
multi: true,
|
|
35563
|
-
},
|
|
35564
|
-
{
|
|
35565
|
-
provide: PRESERVE_HOST_CONTENT,
|
|
35566
|
-
useFactory: () => {
|
|
35567
|
-
// Preserve host element content only in a browser
|
|
35568
|
-
// environment and when hydration is configured properly.
|
|
35569
|
-
// On a server, an application is rendered from scratch,
|
|
35570
|
-
// so the host content needs to be empty.
|
|
35571
|
-
return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
|
|
35572
|
-
}
|
|
35573
|
-
},
|
|
35574
|
-
{
|
|
35575
|
-
provide: APP_BOOTSTRAP_LISTENER,
|
|
35576
|
-
useFactory: () => {
|
|
35577
|
-
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35578
|
-
const appRef = inject(ApplicationRef);
|
|
35579
|
-
const injector = inject(Injector);
|
|
35580
|
-
return () => {
|
|
35581
|
-
// Wait until an app becomes stable and cleanup all views that
|
|
35582
|
-
// were not claimed during the application bootstrap process.
|
|
35583
|
-
// The timing is similar to when we start the serialization process
|
|
35584
|
-
// on the server.
|
|
35585
|
-
//
|
|
35586
|
-
// Note: the cleanup task *MUST* be scheduled within the Angular zone
|
|
35587
|
-
// to ensure that change detection is properly run afterward.
|
|
35588
|
-
whenStableWithTimeout(appRef, injector).then(() => {
|
|
35589
|
-
NgZone.assertInAngularZone();
|
|
35590
|
-
cleanupDehydratedViews(appRef);
|
|
35591
|
-
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35592
|
-
printHydrationStats(injector);
|
|
35593
|
-
}
|
|
35594
|
-
});
|
|
35595
|
-
};
|
|
35596
|
-
}
|
|
35597
|
-
return () => { }; // noop
|
|
35598
|
-
},
|
|
35599
|
-
multi: true,
|
|
35600
|
-
}
|
|
35601
|
-
]);
|
|
35602
|
-
}
|
|
35603
|
-
/**
|
|
35604
|
-
*
|
|
35605
|
-
* @param time The time in ms until the stable timedout warning message is logged
|
|
35606
|
-
*/
|
|
35607
|
-
function logWarningOnStableTimedout(time, console) {
|
|
35608
|
-
const message = `Angular hydration expected the ApplicationRef.isStable() to emit \`true\`, but it ` +
|
|
35609
|
-
`didn't happen within ${time}ms. Angular hydration logic depends on the application becoming stable ` +
|
|
35610
|
-
`as a signal to complete hydration process.`;
|
|
35611
|
-
console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
|
|
35612
|
-
}
|
|
35613
|
-
/**
|
|
35614
|
-
* Verifies whether the DOM contains a special marker added during SSR time to make sure
|
|
35615
|
-
* there is no SSR'ed contents transformations happen after SSR is completed. Typically that
|
|
35616
|
-
* happens either by CDN or during the build process as an optimization to remove comment nodes.
|
|
35617
|
-
* Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
|
|
35618
|
-
* When this special marker is *not* present - throw an error and do not proceed with hydration,
|
|
35619
|
-
* since it will not be able to function correctly.
|
|
35620
|
-
*
|
|
35621
|
-
* Note: this function is invoked only on the client, so it's safe to use DOM APIs.
|
|
35622
|
-
*/
|
|
35623
|
-
function verifySsrContentsIntegrity() {
|
|
35624
|
-
const doc = getDocument();
|
|
35625
|
-
let hydrationMarker;
|
|
35626
|
-
for (const node of doc.body.childNodes) {
|
|
35627
|
-
if (node.nodeType === Node.COMMENT_NODE &&
|
|
35628
|
-
node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
|
|
35629
|
-
hydrationMarker = node;
|
|
35630
|
-
break;
|
|
35631
|
-
}
|
|
35632
|
-
}
|
|
35633
|
-
if (!hydrationMarker) {
|
|
35634
|
-
throw new RuntimeError(-507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode &&
|
|
35635
|
-
'Angular hydration logic detected that HTML content of this page was modified after it ' +
|
|
35636
|
-
'was produced during server side rendering. Make sure that there are no optimizations ' +
|
|
35637
|
-
'that remove comment nodes from HTML enabled on your CDN. Angular hydration ' +
|
|
35638
|
-
'relies on HTML produced by the server, including whitespaces and comment nodes.');
|
|
35639
|
-
}
|
|
35640
|
-
}
|
|
35641
|
-
|
|
35642
35837
|
/**
|
|
35643
35838
|
* Queue a state update to be performed asynchronously.
|
|
35644
35839
|
*
|
|
@@ -35664,9 +35859,7 @@ function queueStateUpdate(callback, options) {
|
|
|
35664
35859
|
callback();
|
|
35665
35860
|
};
|
|
35666
35861
|
internalAfterNextRender(runCallbackOnce, { injector, runOnServer: true });
|
|
35667
|
-
queueMicrotask(
|
|
35668
|
-
runCallbackOnce();
|
|
35669
|
-
});
|
|
35862
|
+
queueMicrotask(runCallbackOnce);
|
|
35670
35863
|
}
|
|
35671
35864
|
|
|
35672
35865
|
/**
|
|
@@ -36176,5 +36369,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
36176
36369
|
* Generated bundle index. Do not edit.
|
|
36177
36370
|
*/
|
|
36178
36371
|
|
|
36179
|
-
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AfterRenderPhase, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostAttributeToken, HostBinding, HostListener, INJECTOR$1 as 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, OutputEmitterRef, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertNotInReactiveContext, assertPlatform, booleanAttribute, computed, contentChild, contentChildren, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, input, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, model, numberAttribute, output, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, viewChild, viewChildren, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, CONTAINER_HEADER_OFFSET as ɵCONTAINER_HEADER_OFFSET, ChangeDetectionScheduler as ɵChangeDetectionScheduler, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG as ɵDEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DeferBlockBehavior as ɵDeferBlockBehavior, DeferBlockState as ɵDeferBlockState, EffectScheduler as ɵEffectScheduler, IMAGE_CONFIG as ɵIMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS as ɵIMAGE_CONFIG_DEFAULTS, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_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, PendingTasks as ɵPendingTasks, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, USE_RUNTIME_DEPS_TRACKER_FOR_JIT as ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, depsTracker as ɵdepsTracker, detectChangesInViewIfRequired as ɵdetectChangesInViewIfRequired, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, getAsyncClassMetadataFn as ɵgetAsyncClassMetadataFn, getDebugNode as ɵgetDebugNode, getDeferBlocks as ɵgetDeferBlocks, getDirectives as ɵgetDirectives, getEnsureDirtyViewsAreAlwaysReachable as ɵgetEnsureDirtyViewsAreAlwaysReachable, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getOutputDestroyRef as ɵgetOutputDestroyRef, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalAfterNextRender as ɵinternalAfterNextRender, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isComponentDefPendingResolution as ɵisComponentDefPendingResolution, isEnvironmentProviders as ɵisEnvironmentProviders, isG3 as ɵisG3, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, performanceMarkFeature as ɵperformanceMarkFeature, provideZonelessChangeDetection as ɵprovideZonelessChangeDetection, queueStateUpdate as ɵqueueStateUpdate, readHydrationInfo as ɵreadHydrationInfo, registerLocaleData as ɵregisterLocaleData, renderDeferBlockState as ɵrenderDeferBlockState, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, ɵsetClassDebugInfo, setClassMetadata as ɵsetClassMetadata, setClassMetadataAsync as ɵsetClassMetadataAsync, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setEnsureDirtyViewsAreAlwaysReachable as ɵsetEnsureDirtyViewsAreAlwaysReachable, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, triggerResourceLoading as ɵtriggerResourceLoading, truncateMiddle as ɵtruncateMiddle, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵunwrapWritableSignal, whenStable as ɵwhenStable, withDomHydration as ɵwithDomHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, InputFlags as ɵɵInputFlags, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetComponentDepsFactory, ɵɵ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, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵ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, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
|
|
36372
|
+
export { ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AfterRenderPhase, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostAttributeToken, HostBinding, HostListener, INJECTOR$1 as 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, OutputEmitterRef, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TransferState, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, afterNextRender, afterRender, asNativeElements, assertInInjectionContext, assertNotInReactiveContext, assertPlatform, booleanAttribute, computed, contentChild, contentChildren, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, input, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, makeStateKey, mergeApplicationConfig, model, numberAttribute, output, platformCore, provideZoneChangeDetection, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, viewChild, viewChildren, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, AfterRenderEventManager as ɵAfterRenderEventManager, CONTAINER_HEADER_OFFSET as ɵCONTAINER_HEADER_OFFSET, ChangeDetectionScheduler as ɵChangeDetectionScheduler, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG as ɵDEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DeferBlockBehavior as ɵDeferBlockBehavior, DeferBlockState as ɵDeferBlockState, EffectScheduler as ɵEffectScheduler, IMAGE_CONFIG as ɵIMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS as ɵIMAGE_CONFIG_DEFAULTS, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE, IS_HYDRATION_DOM_REUSE_ENABLED as ɵIS_HYDRATION_DOM_REUSE_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, PendingTasks as ɵPendingTasks, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, USE_RUNTIME_DEPS_TRACKER_FOR_JIT as ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, depsTracker as ɵdepsTracker, detectChangesInViewIfRequired as ɵdetectChangesInViewIfRequired, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, getAsyncClassMetadataFn as ɵgetAsyncClassMetadataFn, getDebugNode as ɵgetDebugNode, getDeferBlocks as ɵgetDeferBlocks, getDirectives as ɵgetDirectives, getEnsureDirtyViewsAreAlwaysReachable as ɵgetEnsureDirtyViewsAreAlwaysReachable, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getOutputDestroyRef as ɵgetOutputDestroyRef, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalAfterNextRender as ɵinternalAfterNextRender, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isComponentDefPendingResolution as ɵisComponentDefPendingResolution, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, performanceMarkFeature as ɵperformanceMarkFeature, provideZonelessChangeDetection as ɵprovideZonelessChangeDetection, queueStateUpdate as ɵqueueStateUpdate, readHydrationInfo as ɵreadHydrationInfo, registerLocaleData as ɵregisterLocaleData, renderDeferBlockState as ɵrenderDeferBlockState, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, ɵsetClassDebugInfo, setClassMetadata as ɵsetClassMetadata, setClassMetadataAsync as ɵsetClassMetadataAsync, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setEnsureDirtyViewsAreAlwaysReachable as ɵsetEnsureDirtyViewsAreAlwaysReachable, setInjectorProfilerContext as ɵsetInjectorProfilerContext, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, triggerResourceLoading as ɵtriggerResourceLoading, truncateMiddle as ɵtruncateMiddle, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵunwrapWritableSignal, whenStable as ɵwhenStable, withDomHydration as ɵwithDomHydration, withI18nHydration as ɵwithI18nHydration, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, InputFlags as ɵɵInputFlags, ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetComponentDepsFactory, ɵɵ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, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵ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, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
|
|
36180
36373
|
//# sourceMappingURL=core.mjs.map
|