@angular/core 17.3.0-rc.0 → 17.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/src/application/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/defer/instructions.mjs +2 -2
- 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/error_handling.mjs +6 -3
- 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/hydration/utils.mjs +5 -4
- package/esm2022/src/i18n/utils.mjs +16 -0
- package/esm2022/src/linker/template_ref.mjs +2 -2
- 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/render3/view_manipulation.mjs +2 -2
- 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 +1460 -1264
- 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 +14 -2
- package/schematics/migrations/block-template-entities/bundle.js.map +2 -2
- package/schematics/migrations/invalid-two-way-bindings/bundle.js +14 -2
- package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
- package/schematics/ng-generate/control-flow-migration/bundle.js +14 -2
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
- package/schematics/ng-generate/standalone-migration/bundle.js +386 -299
- 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.
|
|
2
|
+
* @license Angular v17.3.1
|
|
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) {
|
|
@@ -6983,6 +7059,822 @@ function isInSkipHydrationBlock(tNode) {
|
|
|
6983
7059
|
return false;
|
|
6984
7060
|
}
|
|
6985
7061
|
|
|
7062
|
+
// Keeps track of the currently-active LViews.
|
|
7063
|
+
const TRACKED_LVIEWS = new Map();
|
|
7064
|
+
// Used for generating unique IDs for LViews.
|
|
7065
|
+
let uniqueIdCounter = 0;
|
|
7066
|
+
/** Gets a unique ID that can be assigned to an LView. */
|
|
7067
|
+
function getUniqueLViewId() {
|
|
7068
|
+
return uniqueIdCounter++;
|
|
7069
|
+
}
|
|
7070
|
+
/** Starts tracking an LView. */
|
|
7071
|
+
function registerLView(lView) {
|
|
7072
|
+
ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
|
|
7073
|
+
TRACKED_LVIEWS.set(lView[ID], lView);
|
|
7074
|
+
}
|
|
7075
|
+
/** Gets an LView by its unique ID. */
|
|
7076
|
+
function getLViewById(id) {
|
|
7077
|
+
ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
|
|
7078
|
+
return TRACKED_LVIEWS.get(id) || null;
|
|
7079
|
+
}
|
|
7080
|
+
/** Stops tracking an LView. */
|
|
7081
|
+
function unregisterLView(lView) {
|
|
7082
|
+
ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
|
|
7083
|
+
TRACKED_LVIEWS.delete(lView[ID]);
|
|
7084
|
+
}
|
|
7085
|
+
|
|
7086
|
+
/**
|
|
7087
|
+
* The internal view context which is specific to a given DOM element, directive or
|
|
7088
|
+
* component instance. Each value in here (besides the LView and element node details)
|
|
7089
|
+
* can be present, null or undefined. If undefined then it implies the value has not been
|
|
7090
|
+
* looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
|
|
7091
|
+
*
|
|
7092
|
+
* Each value will get filled when the respective value is examined within the getContext
|
|
7093
|
+
* function. The component, element and each directive instance will share the same instance
|
|
7094
|
+
* of the context.
|
|
7095
|
+
*/
|
|
7096
|
+
class LContext {
|
|
7097
|
+
/** Component's parent view data. */
|
|
7098
|
+
get lView() {
|
|
7099
|
+
return getLViewById(this.lViewId);
|
|
7100
|
+
}
|
|
7101
|
+
constructor(
|
|
7102
|
+
/**
|
|
7103
|
+
* ID of the component's parent view data.
|
|
7104
|
+
*/
|
|
7105
|
+
lViewId,
|
|
7106
|
+
/**
|
|
7107
|
+
* The index instance of the node.
|
|
7108
|
+
*/
|
|
7109
|
+
nodeIndex,
|
|
7110
|
+
/**
|
|
7111
|
+
* The instance of the DOM node that is attached to the lNode.
|
|
7112
|
+
*/
|
|
7113
|
+
native) {
|
|
7114
|
+
this.lViewId = lViewId;
|
|
7115
|
+
this.nodeIndex = nodeIndex;
|
|
7116
|
+
this.native = native;
|
|
7117
|
+
}
|
|
7118
|
+
}
|
|
7119
|
+
|
|
7120
|
+
/**
|
|
7121
|
+
* Returns the matching `LContext` data for a given DOM node, directive or component instance.
|
|
7122
|
+
*
|
|
7123
|
+
* This function will examine the provided DOM element, component, or directive instance\'s
|
|
7124
|
+
* monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
|
|
7125
|
+
* value will be that of the newly created `LContext`.
|
|
7126
|
+
*
|
|
7127
|
+
* If the monkey-patched value is the `LView` instance then the context value for that
|
|
7128
|
+
* target will be created and the monkey-patch reference will be updated. Therefore when this
|
|
7129
|
+
* function is called it may mutate the provided element\'s, component\'s or any of the associated
|
|
7130
|
+
* directive\'s monkey-patch values.
|
|
7131
|
+
*
|
|
7132
|
+
* If the monkey-patch value is not detected then the code will walk up the DOM until an element
|
|
7133
|
+
* is found which contains a monkey-patch reference. When that occurs then the provided element
|
|
7134
|
+
* will be updated with a new context (which is then returned). If the monkey-patch value is not
|
|
7135
|
+
* detected for a component/directive instance then it will throw an error (all components and
|
|
7136
|
+
* directives should be automatically monkey-patched by ivy).
|
|
7137
|
+
*
|
|
7138
|
+
* @param target Component, Directive or DOM Node.
|
|
7139
|
+
*/
|
|
7140
|
+
function getLContext(target) {
|
|
7141
|
+
let mpValue = readPatchedData(target);
|
|
7142
|
+
if (mpValue) {
|
|
7143
|
+
// only when it's an array is it considered an LView instance
|
|
7144
|
+
// ... otherwise it's an already constructed LContext instance
|
|
7145
|
+
if (isLView(mpValue)) {
|
|
7146
|
+
const lView = mpValue;
|
|
7147
|
+
let nodeIndex;
|
|
7148
|
+
let component = undefined;
|
|
7149
|
+
let directives = undefined;
|
|
7150
|
+
if (isComponentInstance(target)) {
|
|
7151
|
+
nodeIndex = findViaComponent(lView, target);
|
|
7152
|
+
if (nodeIndex == -1) {
|
|
7153
|
+
throw new Error('The provided component was not found in the application');
|
|
7154
|
+
}
|
|
7155
|
+
component = target;
|
|
7156
|
+
}
|
|
7157
|
+
else if (isDirectiveInstance(target)) {
|
|
7158
|
+
nodeIndex = findViaDirective(lView, target);
|
|
7159
|
+
if (nodeIndex == -1) {
|
|
7160
|
+
throw new Error('The provided directive was not found in the application');
|
|
7161
|
+
}
|
|
7162
|
+
directives = getDirectivesAtNodeIndex(nodeIndex, lView);
|
|
7163
|
+
}
|
|
7164
|
+
else {
|
|
7165
|
+
nodeIndex = findViaNativeElement(lView, target);
|
|
7166
|
+
if (nodeIndex == -1) {
|
|
7167
|
+
return null;
|
|
7168
|
+
}
|
|
7169
|
+
}
|
|
7170
|
+
// the goal is not to fill the entire context full of data because the lookups
|
|
7171
|
+
// are expensive. Instead, only the target data (the element, component, container, ICU
|
|
7172
|
+
// expression or directive details) are filled into the context. If called multiple times
|
|
7173
|
+
// with different target values then the missing target data will be filled in.
|
|
7174
|
+
const native = unwrapRNode(lView[nodeIndex]);
|
|
7175
|
+
const existingCtx = readPatchedData(native);
|
|
7176
|
+
const context = (existingCtx && !Array.isArray(existingCtx)) ?
|
|
7177
|
+
existingCtx :
|
|
7178
|
+
createLContext(lView, nodeIndex, native);
|
|
7179
|
+
// only when the component has been discovered then update the monkey-patch
|
|
7180
|
+
if (component && context.component === undefined) {
|
|
7181
|
+
context.component = component;
|
|
7182
|
+
attachPatchData(context.component, context);
|
|
7183
|
+
}
|
|
7184
|
+
// only when the directives have been discovered then update the monkey-patch
|
|
7185
|
+
if (directives && context.directives === undefined) {
|
|
7186
|
+
context.directives = directives;
|
|
7187
|
+
for (let i = 0; i < directives.length; i++) {
|
|
7188
|
+
attachPatchData(directives[i], context);
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
attachPatchData(context.native, context);
|
|
7192
|
+
mpValue = context;
|
|
7193
|
+
}
|
|
7194
|
+
}
|
|
7195
|
+
else {
|
|
7196
|
+
const rElement = target;
|
|
7197
|
+
ngDevMode && assertDomNode(rElement);
|
|
7198
|
+
// if the context is not found then we need to traverse upwards up the DOM
|
|
7199
|
+
// to find the nearest element that has already been monkey patched with data
|
|
7200
|
+
let parent = rElement;
|
|
7201
|
+
while (parent = parent.parentNode) {
|
|
7202
|
+
const parentContext = readPatchedData(parent);
|
|
7203
|
+
if (parentContext) {
|
|
7204
|
+
const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView;
|
|
7205
|
+
// the edge of the app was also reached here through another means
|
|
7206
|
+
// (maybe because the DOM was changed manually).
|
|
7207
|
+
if (!lView) {
|
|
7208
|
+
return null;
|
|
7209
|
+
}
|
|
7210
|
+
const index = findViaNativeElement(lView, rElement);
|
|
7211
|
+
if (index >= 0) {
|
|
7212
|
+
const native = unwrapRNode(lView[index]);
|
|
7213
|
+
const context = createLContext(lView, index, native);
|
|
7214
|
+
attachPatchData(native, context);
|
|
7215
|
+
mpValue = context;
|
|
7216
|
+
break;
|
|
7217
|
+
}
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7220
|
+
}
|
|
7221
|
+
return mpValue || null;
|
|
7222
|
+
}
|
|
7223
|
+
/**
|
|
7224
|
+
* Creates an empty instance of a `LContext` context
|
|
7225
|
+
*/
|
|
7226
|
+
function createLContext(lView, nodeIndex, native) {
|
|
7227
|
+
return new LContext(lView[ID], nodeIndex, native);
|
|
7228
|
+
}
|
|
7229
|
+
/**
|
|
7230
|
+
* Takes a component instance and returns the view for that component.
|
|
7231
|
+
*
|
|
7232
|
+
* @param componentInstance
|
|
7233
|
+
* @returns The component's view
|
|
7234
|
+
*/
|
|
7235
|
+
function getComponentViewByInstance(componentInstance) {
|
|
7236
|
+
let patchedData = readPatchedData(componentInstance);
|
|
7237
|
+
let lView;
|
|
7238
|
+
if (isLView(patchedData)) {
|
|
7239
|
+
const contextLView = patchedData;
|
|
7240
|
+
const nodeIndex = findViaComponent(contextLView, componentInstance);
|
|
7241
|
+
lView = getComponentLViewByIndex(nodeIndex, contextLView);
|
|
7242
|
+
const context = createLContext(contextLView, nodeIndex, lView[HOST]);
|
|
7243
|
+
context.component = componentInstance;
|
|
7244
|
+
attachPatchData(componentInstance, context);
|
|
7245
|
+
attachPatchData(context.native, context);
|
|
7246
|
+
}
|
|
7247
|
+
else {
|
|
7248
|
+
const context = patchedData;
|
|
7249
|
+
const contextLView = context.lView;
|
|
7250
|
+
ngDevMode && assertLView(contextLView);
|
|
7251
|
+
lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
|
|
7252
|
+
}
|
|
7253
|
+
return lView;
|
|
7254
|
+
}
|
|
7255
|
+
/**
|
|
7256
|
+
* This property will be monkey-patched on elements, components and directives.
|
|
7257
|
+
*/
|
|
7258
|
+
const MONKEY_PATCH_KEY_NAME = '__ngContext__';
|
|
7259
|
+
/**
|
|
7260
|
+
* Assigns the given data to the given target (which could be a component,
|
|
7261
|
+
* directive or DOM node instance) using monkey-patching.
|
|
7262
|
+
*/
|
|
7263
|
+
function attachPatchData(target, data) {
|
|
7264
|
+
ngDevMode && assertDefined(target, 'Target expected');
|
|
7265
|
+
// Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
|
|
7266
|
+
// for `LView`, because we have control over when an `LView` is created and destroyed, whereas
|
|
7267
|
+
// we can't know when to remove an `LContext`.
|
|
7268
|
+
if (isLView(data)) {
|
|
7269
|
+
target[MONKEY_PATCH_KEY_NAME] = data[ID];
|
|
7270
|
+
registerLView(data);
|
|
7271
|
+
}
|
|
7272
|
+
else {
|
|
7273
|
+
target[MONKEY_PATCH_KEY_NAME] = data;
|
|
7274
|
+
}
|
|
7275
|
+
}
|
|
7276
|
+
/**
|
|
7277
|
+
* Returns the monkey-patch value data present on the target (which could be
|
|
7278
|
+
* a component, directive or a DOM node).
|
|
7279
|
+
*/
|
|
7280
|
+
function readPatchedData(target) {
|
|
7281
|
+
ngDevMode && assertDefined(target, 'Target expected');
|
|
7282
|
+
const data = target[MONKEY_PATCH_KEY_NAME];
|
|
7283
|
+
return (typeof data === 'number') ? getLViewById(data) : data || null;
|
|
7284
|
+
}
|
|
7285
|
+
function readPatchedLView(target) {
|
|
7286
|
+
const value = readPatchedData(target);
|
|
7287
|
+
if (value) {
|
|
7288
|
+
return (isLView(value) ? value : value.lView);
|
|
7289
|
+
}
|
|
7290
|
+
return null;
|
|
7291
|
+
}
|
|
7292
|
+
function isComponentInstance(instance) {
|
|
7293
|
+
return instance && instance.constructor && instance.constructor.ɵcmp;
|
|
7294
|
+
}
|
|
7295
|
+
function isDirectiveInstance(instance) {
|
|
7296
|
+
return instance && instance.constructor && instance.constructor.ɵdir;
|
|
7297
|
+
}
|
|
7298
|
+
/**
|
|
7299
|
+
* Locates the element within the given LView and returns the matching index
|
|
7300
|
+
*/
|
|
7301
|
+
function findViaNativeElement(lView, target) {
|
|
7302
|
+
const tView = lView[TVIEW];
|
|
7303
|
+
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
7304
|
+
if (unwrapRNode(lView[i]) === target) {
|
|
7305
|
+
return i;
|
|
7306
|
+
}
|
|
7307
|
+
}
|
|
7308
|
+
return -1;
|
|
7309
|
+
}
|
|
7310
|
+
/**
|
|
7311
|
+
* Locates the next tNode (child, sibling or parent).
|
|
7312
|
+
*/
|
|
7313
|
+
function traverseNextElement(tNode) {
|
|
7314
|
+
if (tNode.child) {
|
|
7315
|
+
return tNode.child;
|
|
7316
|
+
}
|
|
7317
|
+
else if (tNode.next) {
|
|
7318
|
+
return tNode.next;
|
|
7319
|
+
}
|
|
7320
|
+
else {
|
|
7321
|
+
// Let's take the following template: <div><span>text</span></div><component/>
|
|
7322
|
+
// After checking the text node, we need to find the next parent that has a "next" TNode,
|
|
7323
|
+
// in this case the parent `div`, so that we can find the component.
|
|
7324
|
+
while (tNode.parent && !tNode.parent.next) {
|
|
7325
|
+
tNode = tNode.parent;
|
|
7326
|
+
}
|
|
7327
|
+
return tNode.parent && tNode.parent.next;
|
|
7328
|
+
}
|
|
7329
|
+
}
|
|
7330
|
+
/**
|
|
7331
|
+
* Locates the component within the given LView and returns the matching index
|
|
7332
|
+
*/
|
|
7333
|
+
function findViaComponent(lView, componentInstance) {
|
|
7334
|
+
const componentIndices = lView[TVIEW].components;
|
|
7335
|
+
if (componentIndices) {
|
|
7336
|
+
for (let i = 0; i < componentIndices.length; i++) {
|
|
7337
|
+
const elementComponentIndex = componentIndices[i];
|
|
7338
|
+
const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
|
|
7339
|
+
if (componentView[CONTEXT] === componentInstance) {
|
|
7340
|
+
return elementComponentIndex;
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
}
|
|
7344
|
+
else {
|
|
7345
|
+
const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
|
|
7346
|
+
const rootComponent = rootComponentView[CONTEXT];
|
|
7347
|
+
if (rootComponent === componentInstance) {
|
|
7348
|
+
// we are dealing with the root element here therefore we know that the
|
|
7349
|
+
// element is the very first element after the HEADER data in the lView
|
|
7350
|
+
return HEADER_OFFSET;
|
|
7351
|
+
}
|
|
7352
|
+
}
|
|
7353
|
+
return -1;
|
|
7354
|
+
}
|
|
7355
|
+
/**
|
|
7356
|
+
* Locates the directive within the given LView and returns the matching index
|
|
7357
|
+
*/
|
|
7358
|
+
function findViaDirective(lView, directiveInstance) {
|
|
7359
|
+
// if a directive is monkey patched then it will (by default)
|
|
7360
|
+
// have a reference to the LView of the current view. The
|
|
7361
|
+
// element bound to the directive being search lives somewhere
|
|
7362
|
+
// in the view data. We loop through the nodes and check their
|
|
7363
|
+
// list of directives for the instance.
|
|
7364
|
+
let tNode = lView[TVIEW].firstChild;
|
|
7365
|
+
while (tNode) {
|
|
7366
|
+
const directiveIndexStart = tNode.directiveStart;
|
|
7367
|
+
const directiveIndexEnd = tNode.directiveEnd;
|
|
7368
|
+
for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
|
|
7369
|
+
if (lView[i] === directiveInstance) {
|
|
7370
|
+
return tNode.index;
|
|
7371
|
+
}
|
|
7372
|
+
}
|
|
7373
|
+
tNode = traverseNextElement(tNode);
|
|
7374
|
+
}
|
|
7375
|
+
return -1;
|
|
7376
|
+
}
|
|
7377
|
+
/**
|
|
7378
|
+
* Returns a list of directives applied to a node at a specific index. The list includes
|
|
7379
|
+
* directives matched by selector and any host directives, but it excludes components.
|
|
7380
|
+
* Use `getComponentAtNodeIndex` to find the component applied to a node.
|
|
7381
|
+
*
|
|
7382
|
+
* @param nodeIndex The node index
|
|
7383
|
+
* @param lView The target view data
|
|
7384
|
+
*/
|
|
7385
|
+
function getDirectivesAtNodeIndex(nodeIndex, lView) {
|
|
7386
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
7387
|
+
if (tNode.directiveStart === 0)
|
|
7388
|
+
return EMPTY_ARRAY;
|
|
7389
|
+
const results = [];
|
|
7390
|
+
for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
|
|
7391
|
+
const directiveInstance = lView[i];
|
|
7392
|
+
if (!isComponentInstance(directiveInstance)) {
|
|
7393
|
+
results.push(directiveInstance);
|
|
7394
|
+
}
|
|
7395
|
+
}
|
|
7396
|
+
return results;
|
|
7397
|
+
}
|
|
7398
|
+
function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
7399
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
7400
|
+
const { directiveStart, componentOffset } = tNode;
|
|
7401
|
+
return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
|
|
7402
|
+
}
|
|
7403
|
+
/**
|
|
7404
|
+
* Returns a map of local references (local reference name => element or directive instance) that
|
|
7405
|
+
* exist on a given element.
|
|
7406
|
+
*/
|
|
7407
|
+
function discoverLocalRefs(lView, nodeIndex) {
|
|
7408
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
7409
|
+
if (tNode && tNode.localNames) {
|
|
7410
|
+
const result = {};
|
|
7411
|
+
let localIndex = tNode.index + 1;
|
|
7412
|
+
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
7413
|
+
result[tNode.localNames[i]] = lView[localIndex];
|
|
7414
|
+
localIndex++;
|
|
7415
|
+
}
|
|
7416
|
+
return result;
|
|
7417
|
+
}
|
|
7418
|
+
return null;
|
|
7419
|
+
}
|
|
7420
|
+
|
|
7421
|
+
/**
|
|
7422
|
+
* Retrieve the root view from any component or `LView` by walking the parent `LView` until
|
|
7423
|
+
* reaching the root `LView`.
|
|
7424
|
+
*
|
|
7425
|
+
* @param componentOrLView any component or `LView`
|
|
7426
|
+
*/
|
|
7427
|
+
function getRootView(componentOrLView) {
|
|
7428
|
+
ngDevMode && assertDefined(componentOrLView, 'component');
|
|
7429
|
+
let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
|
|
7430
|
+
while (lView && !(lView[FLAGS] & 512 /* LViewFlags.IsRoot */)) {
|
|
7431
|
+
lView = getLViewParent(lView);
|
|
7432
|
+
}
|
|
7433
|
+
ngDevMode && assertLView(lView);
|
|
7434
|
+
return lView;
|
|
7435
|
+
}
|
|
7436
|
+
/**
|
|
7437
|
+
* Returns the context information associated with the application where the target is situated. It
|
|
7438
|
+
* does this by walking the parent views until it gets to the root view, then getting the context
|
|
7439
|
+
* off of that.
|
|
7440
|
+
*
|
|
7441
|
+
* @param viewOrComponent the `LView` or component to get the root context for.
|
|
7442
|
+
*/
|
|
7443
|
+
function getRootContext(viewOrComponent) {
|
|
7444
|
+
const rootView = getRootView(viewOrComponent);
|
|
7445
|
+
ngDevMode &&
|
|
7446
|
+
assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
|
|
7447
|
+
return rootView[CONTEXT];
|
|
7448
|
+
}
|
|
7449
|
+
/**
|
|
7450
|
+
* Gets the first `LContainer` in the LView or `null` if none exists.
|
|
7451
|
+
*/
|
|
7452
|
+
function getFirstLContainer(lView) {
|
|
7453
|
+
return getNearestLContainer(lView[CHILD_HEAD]);
|
|
7454
|
+
}
|
|
7455
|
+
/**
|
|
7456
|
+
* Gets the next `LContainer` that is a sibling of the given container.
|
|
7457
|
+
*/
|
|
7458
|
+
function getNextLContainer(container) {
|
|
7459
|
+
return getNearestLContainer(container[NEXT]);
|
|
7460
|
+
}
|
|
7461
|
+
function getNearestLContainer(viewOrContainer) {
|
|
7462
|
+
while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {
|
|
7463
|
+
viewOrContainer = viewOrContainer[NEXT];
|
|
7464
|
+
}
|
|
7465
|
+
return viewOrContainer;
|
|
7466
|
+
}
|
|
7467
|
+
|
|
7468
|
+
/**
|
|
7469
|
+
* Retrieves the component instance associated with a given DOM element.
|
|
7470
|
+
*
|
|
7471
|
+
* @usageNotes
|
|
7472
|
+
* Given the following DOM structure:
|
|
7473
|
+
*
|
|
7474
|
+
* ```html
|
|
7475
|
+
* <app-root>
|
|
7476
|
+
* <div>
|
|
7477
|
+
* <child-comp></child-comp>
|
|
7478
|
+
* </div>
|
|
7479
|
+
* </app-root>
|
|
7480
|
+
* ```
|
|
7481
|
+
*
|
|
7482
|
+
* Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
|
|
7483
|
+
* associated with this DOM element.
|
|
7484
|
+
*
|
|
7485
|
+
* Calling the function on `<app-root>` will return the `MyApp` instance.
|
|
7486
|
+
*
|
|
7487
|
+
*
|
|
7488
|
+
* @param element DOM element from which the component should be retrieved.
|
|
7489
|
+
* @returns Component instance associated with the element or `null` if there
|
|
7490
|
+
* is no component associated with it.
|
|
7491
|
+
*
|
|
7492
|
+
* @publicApi
|
|
7493
|
+
* @globalApi ng
|
|
7494
|
+
*/
|
|
7495
|
+
function getComponent$1(element) {
|
|
7496
|
+
ngDevMode && assertDomElement(element);
|
|
7497
|
+
const context = getLContext(element);
|
|
7498
|
+
if (context === null)
|
|
7499
|
+
return null;
|
|
7500
|
+
if (context.component === undefined) {
|
|
7501
|
+
const lView = context.lView;
|
|
7502
|
+
if (lView === null) {
|
|
7503
|
+
return null;
|
|
7504
|
+
}
|
|
7505
|
+
context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
|
|
7506
|
+
}
|
|
7507
|
+
return context.component;
|
|
7508
|
+
}
|
|
7509
|
+
/**
|
|
7510
|
+
* If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
|
|
7511
|
+
* view that the element is part of. Otherwise retrieves the instance of the component whose view
|
|
7512
|
+
* owns the element (in this case, the result is the same as calling `getOwningComponent`).
|
|
7513
|
+
*
|
|
7514
|
+
* @param element Element for which to get the surrounding component instance.
|
|
7515
|
+
* @returns Instance of the component that is around the element or null if the element isn't
|
|
7516
|
+
* inside any component.
|
|
7517
|
+
*
|
|
7518
|
+
* @publicApi
|
|
7519
|
+
* @globalApi ng
|
|
7520
|
+
*/
|
|
7521
|
+
function getContext(element) {
|
|
7522
|
+
assertDomElement(element);
|
|
7523
|
+
const context = getLContext(element);
|
|
7524
|
+
const lView = context ? context.lView : null;
|
|
7525
|
+
return lView === null ? null : lView[CONTEXT];
|
|
7526
|
+
}
|
|
7527
|
+
/**
|
|
7528
|
+
* Retrieves the component instance whose view contains the DOM element.
|
|
7529
|
+
*
|
|
7530
|
+
* For example, if `<child-comp>` is used in the template of `<app-comp>`
|
|
7531
|
+
* (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
|
|
7532
|
+
* would return `<app-comp>`.
|
|
7533
|
+
*
|
|
7534
|
+
* @param elementOrDir DOM element, component or directive instance
|
|
7535
|
+
* for which to retrieve the root components.
|
|
7536
|
+
* @returns Component instance whose view owns the DOM element or null if the element is not
|
|
7537
|
+
* part of a component view.
|
|
7538
|
+
*
|
|
7539
|
+
* @publicApi
|
|
7540
|
+
* @globalApi ng
|
|
7541
|
+
*/
|
|
7542
|
+
function getOwningComponent(elementOrDir) {
|
|
7543
|
+
const context = getLContext(elementOrDir);
|
|
7544
|
+
let lView = context ? context.lView : null;
|
|
7545
|
+
if (lView === null)
|
|
7546
|
+
return null;
|
|
7547
|
+
let parent;
|
|
7548
|
+
while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
|
|
7549
|
+
lView = parent;
|
|
7550
|
+
}
|
|
7551
|
+
return lView[FLAGS] & 512 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
|
|
7552
|
+
}
|
|
7553
|
+
/**
|
|
7554
|
+
* Retrieves all root components associated with a DOM element, directive or component instance.
|
|
7555
|
+
* Root components are those which have been bootstrapped by Angular.
|
|
7556
|
+
*
|
|
7557
|
+
* @param elementOrDir DOM element, component or directive instance
|
|
7558
|
+
* for which to retrieve the root components.
|
|
7559
|
+
* @returns Root components associated with the target object.
|
|
7560
|
+
*
|
|
7561
|
+
* @publicApi
|
|
7562
|
+
* @globalApi ng
|
|
7563
|
+
*/
|
|
7564
|
+
function getRootComponents(elementOrDir) {
|
|
7565
|
+
const lView = readPatchedLView(elementOrDir);
|
|
7566
|
+
return lView !== null ? [getRootContext(lView)] : [];
|
|
7567
|
+
}
|
|
7568
|
+
/**
|
|
7569
|
+
* Retrieves an `Injector` associated with an element, component or directive instance.
|
|
7570
|
+
*
|
|
7571
|
+
* @param elementOrDir DOM element, component or directive instance for which to
|
|
7572
|
+
* retrieve the injector.
|
|
7573
|
+
* @returns Injector associated with the element, component or directive instance.
|
|
7574
|
+
*
|
|
7575
|
+
* @publicApi
|
|
7576
|
+
* @globalApi ng
|
|
7577
|
+
*/
|
|
7578
|
+
function getInjector(elementOrDir) {
|
|
7579
|
+
const context = getLContext(elementOrDir);
|
|
7580
|
+
const lView = context ? context.lView : null;
|
|
7581
|
+
if (lView === null)
|
|
7582
|
+
return Injector.NULL;
|
|
7583
|
+
const tNode = lView[TVIEW].data[context.nodeIndex];
|
|
7584
|
+
return new NodeInjector(tNode, lView);
|
|
7585
|
+
}
|
|
7586
|
+
/**
|
|
7587
|
+
* Retrieve a set of injection tokens at a given DOM node.
|
|
7588
|
+
*
|
|
7589
|
+
* @param element Element for which the injection tokens should be retrieved.
|
|
7590
|
+
*/
|
|
7591
|
+
function getInjectionTokens(element) {
|
|
7592
|
+
const context = getLContext(element);
|
|
7593
|
+
const lView = context ? context.lView : null;
|
|
7594
|
+
if (lView === null)
|
|
7595
|
+
return [];
|
|
7596
|
+
const tView = lView[TVIEW];
|
|
7597
|
+
const tNode = tView.data[context.nodeIndex];
|
|
7598
|
+
const providerTokens = [];
|
|
7599
|
+
const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
|
|
7600
|
+
const endIndex = tNode.directiveEnd;
|
|
7601
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
7602
|
+
let value = tView.data[i];
|
|
7603
|
+
if (isDirectiveDefHack(value)) {
|
|
7604
|
+
// The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
|
|
7605
|
+
// design flaw. We should always store same type so that we can be monomorphic. The issue
|
|
7606
|
+
// is that for Components/Directives we store the def instead the type. The correct behavior
|
|
7607
|
+
// is that we should always be storing injectable type in this location.
|
|
7608
|
+
value = value.type;
|
|
7609
|
+
}
|
|
7610
|
+
providerTokens.push(value);
|
|
7611
|
+
}
|
|
7612
|
+
return providerTokens;
|
|
7613
|
+
}
|
|
7614
|
+
/**
|
|
7615
|
+
* Retrieves directive instances associated with a given DOM node. Does not include
|
|
7616
|
+
* component instances.
|
|
7617
|
+
*
|
|
7618
|
+
* @usageNotes
|
|
7619
|
+
* Given the following DOM structure:
|
|
7620
|
+
*
|
|
7621
|
+
* ```html
|
|
7622
|
+
* <app-root>
|
|
7623
|
+
* <button my-button></button>
|
|
7624
|
+
* <my-comp></my-comp>
|
|
7625
|
+
* </app-root>
|
|
7626
|
+
* ```
|
|
7627
|
+
*
|
|
7628
|
+
* Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
|
|
7629
|
+
* directive that is associated with the DOM node.
|
|
7630
|
+
*
|
|
7631
|
+
* Calling `getDirectives` on `<my-comp>` will return an empty array.
|
|
7632
|
+
*
|
|
7633
|
+
* @param node DOM node for which to get the directives.
|
|
7634
|
+
* @returns Array of directives associated with the node.
|
|
7635
|
+
*
|
|
7636
|
+
* @publicApi
|
|
7637
|
+
* @globalApi ng
|
|
7638
|
+
*/
|
|
7639
|
+
function getDirectives(node) {
|
|
7640
|
+
// Skip text nodes because we can't have directives associated with them.
|
|
7641
|
+
if (node instanceof Text) {
|
|
7642
|
+
return [];
|
|
7643
|
+
}
|
|
7644
|
+
const context = getLContext(node);
|
|
7645
|
+
const lView = context ? context.lView : null;
|
|
7646
|
+
if (lView === null) {
|
|
7647
|
+
return [];
|
|
7648
|
+
}
|
|
7649
|
+
const tView = lView[TVIEW];
|
|
7650
|
+
const nodeIndex = context.nodeIndex;
|
|
7651
|
+
if (!tView?.data[nodeIndex]) {
|
|
7652
|
+
return [];
|
|
7653
|
+
}
|
|
7654
|
+
if (context.directives === undefined) {
|
|
7655
|
+
context.directives = getDirectivesAtNodeIndex(nodeIndex, lView);
|
|
7656
|
+
}
|
|
7657
|
+
// The `directives` in this case are a named array called `LComponentView`. Clone the
|
|
7658
|
+
// result so we don't expose an internal data structure in the user's console.
|
|
7659
|
+
return context.directives === null ? [] : [...context.directives];
|
|
7660
|
+
}
|
|
7661
|
+
/**
|
|
7662
|
+
* Returns the debug (partial) metadata for a particular directive or component instance.
|
|
7663
|
+
* The function accepts an instance of a directive or component and returns the corresponding
|
|
7664
|
+
* metadata.
|
|
7665
|
+
*
|
|
7666
|
+
* @param directiveOrComponentInstance Instance of a directive or component
|
|
7667
|
+
* @returns metadata of the passed directive or component
|
|
7668
|
+
*
|
|
7669
|
+
* @publicApi
|
|
7670
|
+
* @globalApi ng
|
|
7671
|
+
*/
|
|
7672
|
+
function getDirectiveMetadata$1(directiveOrComponentInstance) {
|
|
7673
|
+
const { constructor } = directiveOrComponentInstance;
|
|
7674
|
+
if (!constructor) {
|
|
7675
|
+
throw new Error('Unable to find the instance constructor');
|
|
7676
|
+
}
|
|
7677
|
+
// In case a component inherits from a directive, we may have component and directive metadata
|
|
7678
|
+
// To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
|
|
7679
|
+
const componentDef = getComponentDef(constructor);
|
|
7680
|
+
if (componentDef) {
|
|
7681
|
+
const inputs = extractInputDebugMetadata(componentDef.inputs);
|
|
7682
|
+
return {
|
|
7683
|
+
inputs,
|
|
7684
|
+
outputs: componentDef.outputs,
|
|
7685
|
+
encapsulation: componentDef.encapsulation,
|
|
7686
|
+
changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
|
|
7687
|
+
ChangeDetectionStrategy.Default
|
|
7688
|
+
};
|
|
7689
|
+
}
|
|
7690
|
+
const directiveDef = getDirectiveDef(constructor);
|
|
7691
|
+
if (directiveDef) {
|
|
7692
|
+
const inputs = extractInputDebugMetadata(directiveDef.inputs);
|
|
7693
|
+
return { inputs, outputs: directiveDef.outputs };
|
|
7694
|
+
}
|
|
7695
|
+
return null;
|
|
7696
|
+
}
|
|
7697
|
+
/**
|
|
7698
|
+
* Retrieve map of local references.
|
|
7699
|
+
*
|
|
7700
|
+
* The references are retrieved as a map of local reference name to element or directive instance.
|
|
7701
|
+
*
|
|
7702
|
+
* @param target DOM element, component or directive instance for which to retrieve
|
|
7703
|
+
* the local references.
|
|
7704
|
+
*/
|
|
7705
|
+
function getLocalRefs(target) {
|
|
7706
|
+
const context = getLContext(target);
|
|
7707
|
+
if (context === null)
|
|
7708
|
+
return {};
|
|
7709
|
+
if (context.localRefs === undefined) {
|
|
7710
|
+
const lView = context.lView;
|
|
7711
|
+
if (lView === null) {
|
|
7712
|
+
return {};
|
|
7713
|
+
}
|
|
7714
|
+
context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
|
|
7715
|
+
}
|
|
7716
|
+
return context.localRefs || {};
|
|
7717
|
+
}
|
|
7718
|
+
/**
|
|
7719
|
+
* Retrieves the host element of a component or directive instance.
|
|
7720
|
+
* The host element is the DOM element that matched the selector of the directive.
|
|
7721
|
+
*
|
|
7722
|
+
* @param componentOrDirective Component or directive instance for which the host
|
|
7723
|
+
* element should be retrieved.
|
|
7724
|
+
* @returns Host element of the target.
|
|
7725
|
+
*
|
|
7726
|
+
* @publicApi
|
|
7727
|
+
* @globalApi ng
|
|
7728
|
+
*/
|
|
7729
|
+
function getHostElement(componentOrDirective) {
|
|
7730
|
+
return getLContext(componentOrDirective).native;
|
|
7731
|
+
}
|
|
7732
|
+
/**
|
|
7733
|
+
* Retrieves the rendered text for a given component.
|
|
7734
|
+
*
|
|
7735
|
+
* This function retrieves the host element of a component and
|
|
7736
|
+
* and then returns the `textContent` for that element. This implies
|
|
7737
|
+
* that the text returned will include re-projected content of
|
|
7738
|
+
* the component as well.
|
|
7739
|
+
*
|
|
7740
|
+
* @param component The component to return the content text for.
|
|
7741
|
+
*/
|
|
7742
|
+
function getRenderedText(component) {
|
|
7743
|
+
const hostElement = getHostElement(component);
|
|
7744
|
+
return hostElement.textContent || '';
|
|
7745
|
+
}
|
|
7746
|
+
/**
|
|
7747
|
+
* Retrieves a list of event listeners associated with a DOM element. The list does include host
|
|
7748
|
+
* listeners, but it does not include event listeners defined outside of the Angular context
|
|
7749
|
+
* (e.g. through `addEventListener`).
|
|
7750
|
+
*
|
|
7751
|
+
* @usageNotes
|
|
7752
|
+
* Given the following DOM structure:
|
|
7753
|
+
*
|
|
7754
|
+
* ```html
|
|
7755
|
+
* <app-root>
|
|
7756
|
+
* <div (click)="doSomething()"></div>
|
|
7757
|
+
* </app-root>
|
|
7758
|
+
* ```
|
|
7759
|
+
*
|
|
7760
|
+
* Calling `getListeners` on `<div>` will return an object that looks as follows:
|
|
7761
|
+
*
|
|
7762
|
+
* ```ts
|
|
7763
|
+
* {
|
|
7764
|
+
* name: 'click',
|
|
7765
|
+
* element: <div>,
|
|
7766
|
+
* callback: () => doSomething(),
|
|
7767
|
+
* useCapture: false
|
|
7768
|
+
* }
|
|
7769
|
+
* ```
|
|
7770
|
+
*
|
|
7771
|
+
* @param element Element for which the DOM listeners should be retrieved.
|
|
7772
|
+
* @returns Array of event listeners on the DOM element.
|
|
7773
|
+
*
|
|
7774
|
+
* @publicApi
|
|
7775
|
+
* @globalApi ng
|
|
7776
|
+
*/
|
|
7777
|
+
function getListeners(element) {
|
|
7778
|
+
ngDevMode && assertDomElement(element);
|
|
7779
|
+
const lContext = getLContext(element);
|
|
7780
|
+
const lView = lContext === null ? null : lContext.lView;
|
|
7781
|
+
if (lView === null)
|
|
7782
|
+
return [];
|
|
7783
|
+
const tView = lView[TVIEW];
|
|
7784
|
+
const lCleanup = lView[CLEANUP];
|
|
7785
|
+
const tCleanup = tView.cleanup;
|
|
7786
|
+
const listeners = [];
|
|
7787
|
+
if (tCleanup && lCleanup) {
|
|
7788
|
+
for (let i = 0; i < tCleanup.length;) {
|
|
7789
|
+
const firstParam = tCleanup[i++];
|
|
7790
|
+
const secondParam = tCleanup[i++];
|
|
7791
|
+
if (typeof firstParam === 'string') {
|
|
7792
|
+
const name = firstParam;
|
|
7793
|
+
const listenerElement = unwrapRNode(lView[secondParam]);
|
|
7794
|
+
const callback = lCleanup[tCleanup[i++]];
|
|
7795
|
+
const useCaptureOrIndx = tCleanup[i++];
|
|
7796
|
+
// if useCaptureOrIndx is boolean then report it as is.
|
|
7797
|
+
// if useCaptureOrIndx is positive number then it in unsubscribe method
|
|
7798
|
+
// if useCaptureOrIndx is negative number then it is a Subscription
|
|
7799
|
+
const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
|
|
7800
|
+
const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
|
|
7801
|
+
if (element == listenerElement) {
|
|
7802
|
+
listeners.push({ element, name, callback, useCapture, type });
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
}
|
|
7807
|
+
listeners.sort(sortListeners);
|
|
7808
|
+
return listeners;
|
|
7809
|
+
}
|
|
7810
|
+
function sortListeners(a, b) {
|
|
7811
|
+
if (a.name == b.name)
|
|
7812
|
+
return 0;
|
|
7813
|
+
return a.name < b.name ? -1 : 1;
|
|
7814
|
+
}
|
|
7815
|
+
/**
|
|
7816
|
+
* This function should not exist because it is megamorphic and only mostly correct.
|
|
7817
|
+
*
|
|
7818
|
+
* See call site for more info.
|
|
7819
|
+
*/
|
|
7820
|
+
function isDirectiveDefHack(obj) {
|
|
7821
|
+
return obj.type !== undefined && obj.declaredInputs !== undefined &&
|
|
7822
|
+
obj.findHostDirectiveDefs !== undefined;
|
|
7823
|
+
}
|
|
7824
|
+
/**
|
|
7825
|
+
* Retrieve the component `LView` from component/element.
|
|
7826
|
+
*
|
|
7827
|
+
* NOTE: `LView` is a private and should not be leaked outside.
|
|
7828
|
+
* Don't export this method to `ng.*` on window.
|
|
7829
|
+
*
|
|
7830
|
+
* @param target DOM element or component instance for which to retrieve the LView.
|
|
7831
|
+
*/
|
|
7832
|
+
function getComponentLView(target) {
|
|
7833
|
+
const lContext = getLContext(target);
|
|
7834
|
+
const nodeIndx = lContext.nodeIndex;
|
|
7835
|
+
const lView = lContext.lView;
|
|
7836
|
+
ngDevMode && assertLView(lView);
|
|
7837
|
+
const componentLView = lView[nodeIndx];
|
|
7838
|
+
ngDevMode && assertLView(componentLView);
|
|
7839
|
+
return componentLView;
|
|
7840
|
+
}
|
|
7841
|
+
/** Asserts that a value is a DOM Element. */
|
|
7842
|
+
function assertDomElement(value) {
|
|
7843
|
+
if (typeof Element !== 'undefined' && !(value instanceof Element)) {
|
|
7844
|
+
throw new Error('Expecting instance of DOM Element');
|
|
7845
|
+
}
|
|
7846
|
+
}
|
|
7847
|
+
/**
|
|
7848
|
+
* A directive definition holds additional metadata using bitwise flags to indicate
|
|
7849
|
+
* for example whether it is signal based.
|
|
7850
|
+
*
|
|
7851
|
+
* This information needs to be separate from the `publicName -> minifiedName`
|
|
7852
|
+
* mappings for backwards compatibility.
|
|
7853
|
+
*/
|
|
7854
|
+
function extractInputDebugMetadata(inputs) {
|
|
7855
|
+
const res = {};
|
|
7856
|
+
for (const key in inputs) {
|
|
7857
|
+
if (!inputs.hasOwnProperty(key)) {
|
|
7858
|
+
continue;
|
|
7859
|
+
}
|
|
7860
|
+
const value = inputs[key];
|
|
7861
|
+
if (value === undefined) {
|
|
7862
|
+
continue;
|
|
7863
|
+
}
|
|
7864
|
+
let minifiedName;
|
|
7865
|
+
if (Array.isArray(value)) {
|
|
7866
|
+
minifiedName = value[0];
|
|
7867
|
+
// flags are not used for now.
|
|
7868
|
+
// TODO: Consider exposing flag information in discovery.
|
|
7869
|
+
}
|
|
7870
|
+
else {
|
|
7871
|
+
minifiedName = value;
|
|
7872
|
+
}
|
|
7873
|
+
res[key] = minifiedName;
|
|
7874
|
+
}
|
|
7875
|
+
return res;
|
|
7876
|
+
}
|
|
7877
|
+
|
|
6986
7878
|
/**
|
|
6987
7879
|
* Most of the use of `document` in Angular is from within the DI system so it is possible to simply
|
|
6988
7880
|
* inject the `DOCUMENT` token and are done.
|
|
@@ -7521,10 +8413,10 @@ function markRNodeAsHavingHydrationMismatch(node, expectedNodeDetails = null, ac
|
|
|
7521
8413
|
throw new Error('Calling `markRNodeAsMismatchedByHydration` in prod mode ' +
|
|
7522
8414
|
'is not supported and likely a mistake.');
|
|
7523
8415
|
}
|
|
7524
|
-
// The RNode can be a standard HTMLElement
|
|
8416
|
+
// The RNode can be a standard HTMLElement (not an Angular component or directive)
|
|
7525
8417
|
// The devtools component tree only displays Angular components & directives
|
|
7526
|
-
// Therefore we attach the debug info to the closest
|
|
7527
|
-
while (node &&
|
|
8418
|
+
// Therefore we attach the debug info to the closest component/directive
|
|
8419
|
+
while (node && !getComponent$1(node)) {
|
|
7528
8420
|
node = node?.parentNode;
|
|
7529
8421
|
}
|
|
7530
8422
|
if (node) {
|
|
@@ -7593,79 +8485,6 @@ function isDisconnectedNode$1(hydrationInfo, index) {
|
|
|
7593
8485
|
return !!hydrationInfo.disconnectedNodes?.has(index);
|
|
7594
8486
|
}
|
|
7595
8487
|
|
|
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
8488
|
/**
|
|
7670
8489
|
* Internal token that specifies whether DOM reuse logic
|
|
7671
8490
|
* during hydration is enabled.
|
|
@@ -7682,6 +8501,11 @@ const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefine
|
|
|
7682
8501
|
providedIn: 'root',
|
|
7683
8502
|
factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
|
|
7684
8503
|
});
|
|
8504
|
+
/**
|
|
8505
|
+
* Internal token that indicates whether hydration support for i18n
|
|
8506
|
+
* is enabled.
|
|
8507
|
+
*/
|
|
8508
|
+
const IS_I18N_HYDRATION_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode ? 'IS_I18N_HYDRATION_ENABLED' : ''));
|
|
7685
8509
|
|
|
7686
8510
|
/**
|
|
7687
8511
|
* @fileoverview
|
|
@@ -8185,6 +9009,7 @@ class SanitizingHtmlSerializer {
|
|
|
8185
9009
|
// again, so it shouldn't be vulnerable to DOM clobbering.
|
|
8186
9010
|
let current = el.firstChild;
|
|
8187
9011
|
let traverseContent = true;
|
|
9012
|
+
let parentNodes = [];
|
|
8188
9013
|
while (current) {
|
|
8189
9014
|
if (current.nodeType === Node.ELEMENT_NODE) {
|
|
8190
9015
|
traverseContent = this.startElement(current);
|
|
@@ -8197,20 +9022,24 @@ class SanitizingHtmlSerializer {
|
|
|
8197
9022
|
this.sanitizedSomething = true;
|
|
8198
9023
|
}
|
|
8199
9024
|
if (traverseContent && current.firstChild) {
|
|
8200
|
-
current
|
|
9025
|
+
// Push current node to the parent stack before entering its content.
|
|
9026
|
+
parentNodes.push(current);
|
|
9027
|
+
current = getFirstChild(current);
|
|
8201
9028
|
continue;
|
|
8202
9029
|
}
|
|
8203
9030
|
while (current) {
|
|
8204
|
-
// Leaving the element.
|
|
9031
|
+
// Leaving the element.
|
|
9032
|
+
// Walk up and to the right, closing tags as we go.
|
|
8205
9033
|
if (current.nodeType === Node.ELEMENT_NODE) {
|
|
8206
9034
|
this.endElement(current);
|
|
8207
9035
|
}
|
|
8208
|
-
let next =
|
|
9036
|
+
let next = getNextSibling(current);
|
|
8209
9037
|
if (next) {
|
|
8210
9038
|
current = next;
|
|
8211
9039
|
break;
|
|
8212
9040
|
}
|
|
8213
|
-
|
|
9041
|
+
// There was no next sibling, walk up to the parent node (extract it from the stack).
|
|
9042
|
+
current = parentNodes.pop();
|
|
8214
9043
|
}
|
|
8215
9044
|
}
|
|
8216
9045
|
return this.buf.join('');
|
|
@@ -8224,7 +9053,7 @@ class SanitizingHtmlSerializer {
|
|
|
8224
9053
|
* @return True if the element's contents should be traversed.
|
|
8225
9054
|
*/
|
|
8226
9055
|
startElement(element) {
|
|
8227
|
-
const tagName = element.
|
|
9056
|
+
const tagName = getNodeName(element).toLowerCase();
|
|
8228
9057
|
if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
|
|
8229
9058
|
this.sanitizedSomething = true;
|
|
8230
9059
|
return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
|
|
@@ -8250,7 +9079,7 @@ class SanitizingHtmlSerializer {
|
|
|
8250
9079
|
return true;
|
|
8251
9080
|
}
|
|
8252
9081
|
endElement(current) {
|
|
8253
|
-
const tagName = current.
|
|
9082
|
+
const tagName = getNodeName(current).toLowerCase();
|
|
8254
9083
|
if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
|
|
8255
9084
|
this.buf.push('</');
|
|
8256
9085
|
this.buf.push(tagName);
|
|
@@ -8260,14 +9089,49 @@ class SanitizingHtmlSerializer {
|
|
|
8260
9089
|
chars(chars) {
|
|
8261
9090
|
this.buf.push(encodeEntities(chars));
|
|
8262
9091
|
}
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
9092
|
+
}
|
|
9093
|
+
/**
|
|
9094
|
+
* Verifies whether a given child node is a descendant of a given parent node.
|
|
9095
|
+
* It may not be the case when properties like `.firstChild` are clobbered and
|
|
9096
|
+
* accessing `.firstChild` results in an unexpected node returned.
|
|
9097
|
+
*/
|
|
9098
|
+
function isClobberedElement(parentNode, childNode) {
|
|
9099
|
+
return (parentNode.compareDocumentPosition(childNode) & Node.DOCUMENT_POSITION_CONTAINED_BY) !==
|
|
9100
|
+
Node.DOCUMENT_POSITION_CONTAINED_BY;
|
|
9101
|
+
}
|
|
9102
|
+
/**
|
|
9103
|
+
* Retrieves next sibling node and makes sure that there is no
|
|
9104
|
+
* clobbering of the `nextSibling` property happening.
|
|
9105
|
+
*/
|
|
9106
|
+
function getNextSibling(node) {
|
|
9107
|
+
const nextSibling = node.nextSibling;
|
|
9108
|
+
// Make sure there is no `nextSibling` clobbering: navigating to
|
|
9109
|
+
// the next sibling and going back to the previous one should result
|
|
9110
|
+
// in the original node.
|
|
9111
|
+
if (nextSibling && node !== nextSibling.previousSibling) {
|
|
9112
|
+
throw clobberedElementError(nextSibling);
|
|
8270
9113
|
}
|
|
9114
|
+
return nextSibling;
|
|
9115
|
+
}
|
|
9116
|
+
/**
|
|
9117
|
+
* Retrieves first child node and makes sure that there is no
|
|
9118
|
+
* clobbering of the `firstChild` property happening.
|
|
9119
|
+
*/
|
|
9120
|
+
function getFirstChild(node) {
|
|
9121
|
+
const firstChild = node.firstChild;
|
|
9122
|
+
if (firstChild && isClobberedElement(node, firstChild)) {
|
|
9123
|
+
throw clobberedElementError(firstChild);
|
|
9124
|
+
}
|
|
9125
|
+
return firstChild;
|
|
9126
|
+
}
|
|
9127
|
+
/** Gets a reasonable nodeName, even for clobbered nodes. */
|
|
9128
|
+
function getNodeName(node) {
|
|
9129
|
+
const nodeName = node.nodeName;
|
|
9130
|
+
// If the property is clobbered, assume it is an `HTMLFormElement`.
|
|
9131
|
+
return (typeof nodeName === 'string') ? nodeName : 'FORM';
|
|
9132
|
+
}
|
|
9133
|
+
function clobberedElementError(node) {
|
|
9134
|
+
return new Error(`Failed to sanitize html because the element is clobbered: ${node.outerHTML}`);
|
|
8271
9135
|
}
|
|
8272
9136
|
// Regular Expressions for parsing tags and attributes
|
|
8273
9137
|
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
@@ -8643,365 +9507,6 @@ function normalizeDebugBindingValue(value) {
|
|
|
8643
9507
|
}
|
|
8644
9508
|
}
|
|
8645
9509
|
|
|
8646
|
-
// Keeps track of the currently-active LViews.
|
|
8647
|
-
const TRACKED_LVIEWS = new Map();
|
|
8648
|
-
// Used for generating unique IDs for LViews.
|
|
8649
|
-
let uniqueIdCounter = 0;
|
|
8650
|
-
/** Gets a unique ID that can be assigned to an LView. */
|
|
8651
|
-
function getUniqueLViewId() {
|
|
8652
|
-
return uniqueIdCounter++;
|
|
8653
|
-
}
|
|
8654
|
-
/** Starts tracking an LView. */
|
|
8655
|
-
function registerLView(lView) {
|
|
8656
|
-
ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
|
|
8657
|
-
TRACKED_LVIEWS.set(lView[ID], lView);
|
|
8658
|
-
}
|
|
8659
|
-
/** Gets an LView by its unique ID. */
|
|
8660
|
-
function getLViewById(id) {
|
|
8661
|
-
ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
|
|
8662
|
-
return TRACKED_LVIEWS.get(id) || null;
|
|
8663
|
-
}
|
|
8664
|
-
/** Stops tracking an LView. */
|
|
8665
|
-
function unregisterLView(lView) {
|
|
8666
|
-
ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
|
|
8667
|
-
TRACKED_LVIEWS.delete(lView[ID]);
|
|
8668
|
-
}
|
|
8669
|
-
|
|
8670
|
-
/**
|
|
8671
|
-
* The internal view context which is specific to a given DOM element, directive or
|
|
8672
|
-
* component instance. Each value in here (besides the LView and element node details)
|
|
8673
|
-
* can be present, null or undefined. If undefined then it implies the value has not been
|
|
8674
|
-
* looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
|
|
8675
|
-
*
|
|
8676
|
-
* Each value will get filled when the respective value is examined within the getContext
|
|
8677
|
-
* function. The component, element and each directive instance will share the same instance
|
|
8678
|
-
* of the context.
|
|
8679
|
-
*/
|
|
8680
|
-
class LContext {
|
|
8681
|
-
/** Component's parent view data. */
|
|
8682
|
-
get lView() {
|
|
8683
|
-
return getLViewById(this.lViewId);
|
|
8684
|
-
}
|
|
8685
|
-
constructor(
|
|
8686
|
-
/**
|
|
8687
|
-
* ID of the component's parent view data.
|
|
8688
|
-
*/
|
|
8689
|
-
lViewId,
|
|
8690
|
-
/**
|
|
8691
|
-
* The index instance of the node.
|
|
8692
|
-
*/
|
|
8693
|
-
nodeIndex,
|
|
8694
|
-
/**
|
|
8695
|
-
* The instance of the DOM node that is attached to the lNode.
|
|
8696
|
-
*/
|
|
8697
|
-
native) {
|
|
8698
|
-
this.lViewId = lViewId;
|
|
8699
|
-
this.nodeIndex = nodeIndex;
|
|
8700
|
-
this.native = native;
|
|
8701
|
-
}
|
|
8702
|
-
}
|
|
8703
|
-
|
|
8704
|
-
/**
|
|
8705
|
-
* Returns the matching `LContext` data for a given DOM node, directive or component instance.
|
|
8706
|
-
*
|
|
8707
|
-
* This function will examine the provided DOM element, component, or directive instance\'s
|
|
8708
|
-
* monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
|
|
8709
|
-
* value will be that of the newly created `LContext`.
|
|
8710
|
-
*
|
|
8711
|
-
* If the monkey-patched value is the `LView` instance then the context value for that
|
|
8712
|
-
* target will be created and the monkey-patch reference will be updated. Therefore when this
|
|
8713
|
-
* function is called it may mutate the provided element\'s, component\'s or any of the associated
|
|
8714
|
-
* directive\'s monkey-patch values.
|
|
8715
|
-
*
|
|
8716
|
-
* If the monkey-patch value is not detected then the code will walk up the DOM until an element
|
|
8717
|
-
* is found which contains a monkey-patch reference. When that occurs then the provided element
|
|
8718
|
-
* will be updated with a new context (which is then returned). If the monkey-patch value is not
|
|
8719
|
-
* detected for a component/directive instance then it will throw an error (all components and
|
|
8720
|
-
* directives should be automatically monkey-patched by ivy).
|
|
8721
|
-
*
|
|
8722
|
-
* @param target Component, Directive or DOM Node.
|
|
8723
|
-
*/
|
|
8724
|
-
function getLContext(target) {
|
|
8725
|
-
let mpValue = readPatchedData(target);
|
|
8726
|
-
if (mpValue) {
|
|
8727
|
-
// only when it's an array is it considered an LView instance
|
|
8728
|
-
// ... otherwise it's an already constructed LContext instance
|
|
8729
|
-
if (isLView(mpValue)) {
|
|
8730
|
-
const lView = mpValue;
|
|
8731
|
-
let nodeIndex;
|
|
8732
|
-
let component = undefined;
|
|
8733
|
-
let directives = undefined;
|
|
8734
|
-
if (isComponentInstance(target)) {
|
|
8735
|
-
nodeIndex = findViaComponent(lView, target);
|
|
8736
|
-
if (nodeIndex == -1) {
|
|
8737
|
-
throw new Error('The provided component was not found in the application');
|
|
8738
|
-
}
|
|
8739
|
-
component = target;
|
|
8740
|
-
}
|
|
8741
|
-
else if (isDirectiveInstance(target)) {
|
|
8742
|
-
nodeIndex = findViaDirective(lView, target);
|
|
8743
|
-
if (nodeIndex == -1) {
|
|
8744
|
-
throw new Error('The provided directive was not found in the application');
|
|
8745
|
-
}
|
|
8746
|
-
directives = getDirectivesAtNodeIndex(nodeIndex, lView);
|
|
8747
|
-
}
|
|
8748
|
-
else {
|
|
8749
|
-
nodeIndex = findViaNativeElement(lView, target);
|
|
8750
|
-
if (nodeIndex == -1) {
|
|
8751
|
-
return null;
|
|
8752
|
-
}
|
|
8753
|
-
}
|
|
8754
|
-
// the goal is not to fill the entire context full of data because the lookups
|
|
8755
|
-
// are expensive. Instead, only the target data (the element, component, container, ICU
|
|
8756
|
-
// expression or directive details) are filled into the context. If called multiple times
|
|
8757
|
-
// with different target values then the missing target data will be filled in.
|
|
8758
|
-
const native = unwrapRNode(lView[nodeIndex]);
|
|
8759
|
-
const existingCtx = readPatchedData(native);
|
|
8760
|
-
const context = (existingCtx && !Array.isArray(existingCtx)) ?
|
|
8761
|
-
existingCtx :
|
|
8762
|
-
createLContext(lView, nodeIndex, native);
|
|
8763
|
-
// only when the component has been discovered then update the monkey-patch
|
|
8764
|
-
if (component && context.component === undefined) {
|
|
8765
|
-
context.component = component;
|
|
8766
|
-
attachPatchData(context.component, context);
|
|
8767
|
-
}
|
|
8768
|
-
// only when the directives have been discovered then update the monkey-patch
|
|
8769
|
-
if (directives && context.directives === undefined) {
|
|
8770
|
-
context.directives = directives;
|
|
8771
|
-
for (let i = 0; i < directives.length; i++) {
|
|
8772
|
-
attachPatchData(directives[i], context);
|
|
8773
|
-
}
|
|
8774
|
-
}
|
|
8775
|
-
attachPatchData(context.native, context);
|
|
8776
|
-
mpValue = context;
|
|
8777
|
-
}
|
|
8778
|
-
}
|
|
8779
|
-
else {
|
|
8780
|
-
const rElement = target;
|
|
8781
|
-
ngDevMode && assertDomNode(rElement);
|
|
8782
|
-
// if the context is not found then we need to traverse upwards up the DOM
|
|
8783
|
-
// to find the nearest element that has already been monkey patched with data
|
|
8784
|
-
let parent = rElement;
|
|
8785
|
-
while (parent = parent.parentNode) {
|
|
8786
|
-
const parentContext = readPatchedData(parent);
|
|
8787
|
-
if (parentContext) {
|
|
8788
|
-
const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView;
|
|
8789
|
-
// the edge of the app was also reached here through another means
|
|
8790
|
-
// (maybe because the DOM was changed manually).
|
|
8791
|
-
if (!lView) {
|
|
8792
|
-
return null;
|
|
8793
|
-
}
|
|
8794
|
-
const index = findViaNativeElement(lView, rElement);
|
|
8795
|
-
if (index >= 0) {
|
|
8796
|
-
const native = unwrapRNode(lView[index]);
|
|
8797
|
-
const context = createLContext(lView, index, native);
|
|
8798
|
-
attachPatchData(native, context);
|
|
8799
|
-
mpValue = context;
|
|
8800
|
-
break;
|
|
8801
|
-
}
|
|
8802
|
-
}
|
|
8803
|
-
}
|
|
8804
|
-
}
|
|
8805
|
-
return mpValue || null;
|
|
8806
|
-
}
|
|
8807
|
-
/**
|
|
8808
|
-
* Creates an empty instance of a `LContext` context
|
|
8809
|
-
*/
|
|
8810
|
-
function createLContext(lView, nodeIndex, native) {
|
|
8811
|
-
return new LContext(lView[ID], nodeIndex, native);
|
|
8812
|
-
}
|
|
8813
|
-
/**
|
|
8814
|
-
* Takes a component instance and returns the view for that component.
|
|
8815
|
-
*
|
|
8816
|
-
* @param componentInstance
|
|
8817
|
-
* @returns The component's view
|
|
8818
|
-
*/
|
|
8819
|
-
function getComponentViewByInstance(componentInstance) {
|
|
8820
|
-
let patchedData = readPatchedData(componentInstance);
|
|
8821
|
-
let lView;
|
|
8822
|
-
if (isLView(patchedData)) {
|
|
8823
|
-
const contextLView = patchedData;
|
|
8824
|
-
const nodeIndex = findViaComponent(contextLView, componentInstance);
|
|
8825
|
-
lView = getComponentLViewByIndex(nodeIndex, contextLView);
|
|
8826
|
-
const context = createLContext(contextLView, nodeIndex, lView[HOST]);
|
|
8827
|
-
context.component = componentInstance;
|
|
8828
|
-
attachPatchData(componentInstance, context);
|
|
8829
|
-
attachPatchData(context.native, context);
|
|
8830
|
-
}
|
|
8831
|
-
else {
|
|
8832
|
-
const context = patchedData;
|
|
8833
|
-
const contextLView = context.lView;
|
|
8834
|
-
ngDevMode && assertLView(contextLView);
|
|
8835
|
-
lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
|
|
8836
|
-
}
|
|
8837
|
-
return lView;
|
|
8838
|
-
}
|
|
8839
|
-
/**
|
|
8840
|
-
* This property will be monkey-patched on elements, components and directives.
|
|
8841
|
-
*/
|
|
8842
|
-
const MONKEY_PATCH_KEY_NAME = '__ngContext__';
|
|
8843
|
-
/**
|
|
8844
|
-
* Assigns the given data to the given target (which could be a component,
|
|
8845
|
-
* directive or DOM node instance) using monkey-patching.
|
|
8846
|
-
*/
|
|
8847
|
-
function attachPatchData(target, data) {
|
|
8848
|
-
ngDevMode && assertDefined(target, 'Target expected');
|
|
8849
|
-
// Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
|
|
8850
|
-
// for `LView`, because we have control over when an `LView` is created and destroyed, whereas
|
|
8851
|
-
// we can't know when to remove an `LContext`.
|
|
8852
|
-
if (isLView(data)) {
|
|
8853
|
-
target[MONKEY_PATCH_KEY_NAME] = data[ID];
|
|
8854
|
-
registerLView(data);
|
|
8855
|
-
}
|
|
8856
|
-
else {
|
|
8857
|
-
target[MONKEY_PATCH_KEY_NAME] = data;
|
|
8858
|
-
}
|
|
8859
|
-
}
|
|
8860
|
-
/**
|
|
8861
|
-
* Returns the monkey-patch value data present on the target (which could be
|
|
8862
|
-
* a component, directive or a DOM node).
|
|
8863
|
-
*/
|
|
8864
|
-
function readPatchedData(target) {
|
|
8865
|
-
ngDevMode && assertDefined(target, 'Target expected');
|
|
8866
|
-
const data = target[MONKEY_PATCH_KEY_NAME];
|
|
8867
|
-
return (typeof data === 'number') ? getLViewById(data) : data || null;
|
|
8868
|
-
}
|
|
8869
|
-
function readPatchedLView(target) {
|
|
8870
|
-
const value = readPatchedData(target);
|
|
8871
|
-
if (value) {
|
|
8872
|
-
return (isLView(value) ? value : value.lView);
|
|
8873
|
-
}
|
|
8874
|
-
return null;
|
|
8875
|
-
}
|
|
8876
|
-
function isComponentInstance(instance) {
|
|
8877
|
-
return instance && instance.constructor && instance.constructor.ɵcmp;
|
|
8878
|
-
}
|
|
8879
|
-
function isDirectiveInstance(instance) {
|
|
8880
|
-
return instance && instance.constructor && instance.constructor.ɵdir;
|
|
8881
|
-
}
|
|
8882
|
-
/**
|
|
8883
|
-
* Locates the element within the given LView and returns the matching index
|
|
8884
|
-
*/
|
|
8885
|
-
function findViaNativeElement(lView, target) {
|
|
8886
|
-
const tView = lView[TVIEW];
|
|
8887
|
-
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
8888
|
-
if (unwrapRNode(lView[i]) === target) {
|
|
8889
|
-
return i;
|
|
8890
|
-
}
|
|
8891
|
-
}
|
|
8892
|
-
return -1;
|
|
8893
|
-
}
|
|
8894
|
-
/**
|
|
8895
|
-
* Locates the next tNode (child, sibling or parent).
|
|
8896
|
-
*/
|
|
8897
|
-
function traverseNextElement(tNode) {
|
|
8898
|
-
if (tNode.child) {
|
|
8899
|
-
return tNode.child;
|
|
8900
|
-
}
|
|
8901
|
-
else if (tNode.next) {
|
|
8902
|
-
return tNode.next;
|
|
8903
|
-
}
|
|
8904
|
-
else {
|
|
8905
|
-
// Let's take the following template: <div><span>text</span></div><component/>
|
|
8906
|
-
// After checking the text node, we need to find the next parent that has a "next" TNode,
|
|
8907
|
-
// in this case the parent `div`, so that we can find the component.
|
|
8908
|
-
while (tNode.parent && !tNode.parent.next) {
|
|
8909
|
-
tNode = tNode.parent;
|
|
8910
|
-
}
|
|
8911
|
-
return tNode.parent && tNode.parent.next;
|
|
8912
|
-
}
|
|
8913
|
-
}
|
|
8914
|
-
/**
|
|
8915
|
-
* Locates the component within the given LView and returns the matching index
|
|
8916
|
-
*/
|
|
8917
|
-
function findViaComponent(lView, componentInstance) {
|
|
8918
|
-
const componentIndices = lView[TVIEW].components;
|
|
8919
|
-
if (componentIndices) {
|
|
8920
|
-
for (let i = 0; i < componentIndices.length; i++) {
|
|
8921
|
-
const elementComponentIndex = componentIndices[i];
|
|
8922
|
-
const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
|
|
8923
|
-
if (componentView[CONTEXT] === componentInstance) {
|
|
8924
|
-
return elementComponentIndex;
|
|
8925
|
-
}
|
|
8926
|
-
}
|
|
8927
|
-
}
|
|
8928
|
-
else {
|
|
8929
|
-
const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
|
|
8930
|
-
const rootComponent = rootComponentView[CONTEXT];
|
|
8931
|
-
if (rootComponent === componentInstance) {
|
|
8932
|
-
// we are dealing with the root element here therefore we know that the
|
|
8933
|
-
// element is the very first element after the HEADER data in the lView
|
|
8934
|
-
return HEADER_OFFSET;
|
|
8935
|
-
}
|
|
8936
|
-
}
|
|
8937
|
-
return -1;
|
|
8938
|
-
}
|
|
8939
|
-
/**
|
|
8940
|
-
* Locates the directive within the given LView and returns the matching index
|
|
8941
|
-
*/
|
|
8942
|
-
function findViaDirective(lView, directiveInstance) {
|
|
8943
|
-
// if a directive is monkey patched then it will (by default)
|
|
8944
|
-
// have a reference to the LView of the current view. The
|
|
8945
|
-
// element bound to the directive being search lives somewhere
|
|
8946
|
-
// in the view data. We loop through the nodes and check their
|
|
8947
|
-
// list of directives for the instance.
|
|
8948
|
-
let tNode = lView[TVIEW].firstChild;
|
|
8949
|
-
while (tNode) {
|
|
8950
|
-
const directiveIndexStart = tNode.directiveStart;
|
|
8951
|
-
const directiveIndexEnd = tNode.directiveEnd;
|
|
8952
|
-
for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
|
|
8953
|
-
if (lView[i] === directiveInstance) {
|
|
8954
|
-
return tNode.index;
|
|
8955
|
-
}
|
|
8956
|
-
}
|
|
8957
|
-
tNode = traverseNextElement(tNode);
|
|
8958
|
-
}
|
|
8959
|
-
return -1;
|
|
8960
|
-
}
|
|
8961
|
-
/**
|
|
8962
|
-
* Returns a list of directives applied to a node at a specific index. The list includes
|
|
8963
|
-
* directives matched by selector and any host directives, but it excludes components.
|
|
8964
|
-
* Use `getComponentAtNodeIndex` to find the component applied to a node.
|
|
8965
|
-
*
|
|
8966
|
-
* @param nodeIndex The node index
|
|
8967
|
-
* @param lView The target view data
|
|
8968
|
-
*/
|
|
8969
|
-
function getDirectivesAtNodeIndex(nodeIndex, lView) {
|
|
8970
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
8971
|
-
if (tNode.directiveStart === 0)
|
|
8972
|
-
return EMPTY_ARRAY;
|
|
8973
|
-
const results = [];
|
|
8974
|
-
for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
|
|
8975
|
-
const directiveInstance = lView[i];
|
|
8976
|
-
if (!isComponentInstance(directiveInstance)) {
|
|
8977
|
-
results.push(directiveInstance);
|
|
8978
|
-
}
|
|
8979
|
-
}
|
|
8980
|
-
return results;
|
|
8981
|
-
}
|
|
8982
|
-
function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
8983
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
8984
|
-
const { directiveStart, componentOffset } = tNode;
|
|
8985
|
-
return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
|
|
8986
|
-
}
|
|
8987
|
-
/**
|
|
8988
|
-
* Returns a map of local references (local reference name => element or directive instance) that
|
|
8989
|
-
* exist on a given element.
|
|
8990
|
-
*/
|
|
8991
|
-
function discoverLocalRefs(lView, nodeIndex) {
|
|
8992
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
8993
|
-
if (tNode && tNode.localNames) {
|
|
8994
|
-
const result = {};
|
|
8995
|
-
let localIndex = tNode.index + 1;
|
|
8996
|
-
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
8997
|
-
result[tNode.localNames[i]] = lView[localIndex];
|
|
8998
|
-
localIndex++;
|
|
8999
|
-
}
|
|
9000
|
-
return result;
|
|
9001
|
-
}
|
|
9002
|
-
return null;
|
|
9003
|
-
}
|
|
9004
|
-
|
|
9005
9510
|
/**
|
|
9006
9511
|
* Defines a schema that allows an NgModule to contain the following:
|
|
9007
9512
|
* - Non-Angular elements named with dash case (`-`).
|
|
@@ -9597,6 +10102,10 @@ function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, bef
|
|
|
9597
10102
|
* @param lView the `LView` to be detached.
|
|
9598
10103
|
*/
|
|
9599
10104
|
function detachViewFromDOM(tView, lView) {
|
|
10105
|
+
// When we remove a view from the DOM, we need to rerun afterRender hooks
|
|
10106
|
+
// We don't necessarily needs to run change detection. DOM removal only requires
|
|
10107
|
+
// change detection if animations are enabled (this notification is handled by animations).
|
|
10108
|
+
lView[ENVIRONMENT].changeDetectionScheduler?.notify(1 /* NotificationType.AfterRenderHooks */);
|
|
9600
10109
|
applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
|
|
9601
10110
|
}
|
|
9602
10111
|
/**
|
|
@@ -11974,7 +12483,7 @@ function createAndRenderEmbeddedLView(declarationLView, templateTNode, context,
|
|
|
11974
12483
|
// Embedded views follow the change detection strategy of the view they're declared in.
|
|
11975
12484
|
const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
|
|
11976
12485
|
const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
|
|
11977
|
-
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, null, options?.
|
|
12486
|
+
const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, options?.injector ?? null, options?.embeddedViewInjector ?? null, options?.dehydratedView ?? null);
|
|
11978
12487
|
const declarationLContainer = declarationLView[templateTNode.index];
|
|
11979
12488
|
ngDevMode && assertLContainer(declarationLContainer);
|
|
11980
12489
|
embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
|
|
@@ -12142,53 +12651,6 @@ const REACTIVE_LVIEW_CONSUMER_NODE = {
|
|
|
12142
12651
|
},
|
|
12143
12652
|
};
|
|
12144
12653
|
|
|
12145
|
-
/**
|
|
12146
|
-
* Retrieve the root view from any component or `LView` by walking the parent `LView` until
|
|
12147
|
-
* reaching the root `LView`.
|
|
12148
|
-
*
|
|
12149
|
-
* @param componentOrLView any component or `LView`
|
|
12150
|
-
*/
|
|
12151
|
-
function getRootView(componentOrLView) {
|
|
12152
|
-
ngDevMode && assertDefined(componentOrLView, 'component');
|
|
12153
|
-
let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
|
|
12154
|
-
while (lView && !(lView[FLAGS] & 512 /* LViewFlags.IsRoot */)) {
|
|
12155
|
-
lView = getLViewParent(lView);
|
|
12156
|
-
}
|
|
12157
|
-
ngDevMode && assertLView(lView);
|
|
12158
|
-
return lView;
|
|
12159
|
-
}
|
|
12160
|
-
/**
|
|
12161
|
-
* Returns the context information associated with the application where the target is situated. It
|
|
12162
|
-
* does this by walking the parent views until it gets to the root view, then getting the context
|
|
12163
|
-
* off of that.
|
|
12164
|
-
*
|
|
12165
|
-
* @param viewOrComponent the `LView` or component to get the root context for.
|
|
12166
|
-
*/
|
|
12167
|
-
function getRootContext(viewOrComponent) {
|
|
12168
|
-
const rootView = getRootView(viewOrComponent);
|
|
12169
|
-
ngDevMode &&
|
|
12170
|
-
assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
|
|
12171
|
-
return rootView[CONTEXT];
|
|
12172
|
-
}
|
|
12173
|
-
/**
|
|
12174
|
-
* Gets the first `LContainer` in the LView or `null` if none exists.
|
|
12175
|
-
*/
|
|
12176
|
-
function getFirstLContainer(lView) {
|
|
12177
|
-
return getNearestLContainer(lView[CHILD_HEAD]);
|
|
12178
|
-
}
|
|
12179
|
-
/**
|
|
12180
|
-
* Gets the next `LContainer` that is a sibling of the given container.
|
|
12181
|
-
*/
|
|
12182
|
-
function getNextLContainer(container) {
|
|
12183
|
-
return getNearestLContainer(container[NEXT]);
|
|
12184
|
-
}
|
|
12185
|
-
function getNearestLContainer(viewOrContainer) {
|
|
12186
|
-
while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {
|
|
12187
|
-
viewOrContainer = viewOrContainer[NEXT];
|
|
12188
|
-
}
|
|
12189
|
-
return viewOrContainer;
|
|
12190
|
-
}
|
|
12191
|
-
|
|
12192
12654
|
/**
|
|
12193
12655
|
* The maximum number of times the change detection traversal will rerun before throwing an error.
|
|
12194
12656
|
*/
|
|
@@ -12883,7 +13345,7 @@ const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
|
|
|
12883
13345
|
* @internal
|
|
12884
13346
|
*/
|
|
12885
13347
|
createEmbeddedViewImpl(context, injector, dehydratedView) {
|
|
12886
|
-
const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { injector, dehydratedView });
|
|
13348
|
+
const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, { embeddedViewInjector: injector, dehydratedView });
|
|
12887
13349
|
return new ViewRef$1(embeddedLView);
|
|
12888
13350
|
}
|
|
12889
13351
|
};
|
|
@@ -12954,18 +13416,21 @@ function validateMatchingNode(node, nodeType, tagName, lView, tNode, isViewConta
|
|
|
12954
13416
|
const expectedDom = describeExpectedDom(lView, tNode, isViewContainerAnchor);
|
|
12955
13417
|
const expected = `Angular expected this DOM:\n\n${expectedDom}\n\n`;
|
|
12956
13418
|
let actual = '';
|
|
13419
|
+
const componentHostElement = unwrapRNode(lView[HOST]);
|
|
12957
13420
|
if (!node) {
|
|
12958
13421
|
// No node found during hydration.
|
|
12959
13422
|
header += `the node was not found.\n\n`;
|
|
12960
13423
|
// Since the node is missing, we use the closest node to attach the error to
|
|
12961
|
-
markRNodeAsHavingHydrationMismatch(
|
|
13424
|
+
markRNodeAsHavingHydrationMismatch(componentHostElement, expectedDom);
|
|
12962
13425
|
}
|
|
12963
13426
|
else {
|
|
12964
13427
|
const actualNode = shortRNodeDescription(node.nodeType, node.tagName ?? null, node.textContent ?? null);
|
|
12965
13428
|
header += `found ${actualNode}.\n\n`;
|
|
12966
13429
|
const actualDom = describeDomFromNode(node);
|
|
12967
13430
|
actual = `Actual DOM is:\n\n${actualDom}\n\n`;
|
|
12968
|
-
|
|
13431
|
+
// DevTools only report hydration issues on the component level, so we attach extra debug
|
|
13432
|
+
// info to a component host element to make it available to DevTools.
|
|
13433
|
+
markRNodeAsHavingHydrationMismatch(componentHostElement, expectedDom, actualDom);
|
|
12969
13434
|
}
|
|
12970
13435
|
const footer = getHydrationErrorFooter(componentClassName);
|
|
12971
13436
|
const message = header + expected + actual + getHydrationAttributeNote() + footer;
|
|
@@ -13325,11 +13790,27 @@ function cleanupLContainer(lContainer) {
|
|
|
13325
13790
|
cleanupLView(lContainer[i]);
|
|
13326
13791
|
}
|
|
13327
13792
|
}
|
|
13793
|
+
/**
|
|
13794
|
+
* Removes any remaining dehydrated i18n nodes from a given LView,
|
|
13795
|
+
* both in internal data structure, as well as removing the
|
|
13796
|
+
* corresponding DOM nodes.
|
|
13797
|
+
*/
|
|
13798
|
+
function cleanupDehydratedI18nNodes(lView) {
|
|
13799
|
+
const i18nNodes = lView[HYDRATION]?.i18nNodes;
|
|
13800
|
+
if (i18nNodes) {
|
|
13801
|
+
const renderer = lView[RENDERER];
|
|
13802
|
+
for (const node of i18nNodes.values()) {
|
|
13803
|
+
nativeRemoveNode(renderer, node, false);
|
|
13804
|
+
}
|
|
13805
|
+
lView[HYDRATION].i18nNodes = undefined;
|
|
13806
|
+
}
|
|
13807
|
+
}
|
|
13328
13808
|
/**
|
|
13329
13809
|
* Walks over `LContainer`s and components registered within
|
|
13330
13810
|
* this LView and invokes dehydrated views cleanup function for each one.
|
|
13331
13811
|
*/
|
|
13332
13812
|
function cleanupLView(lView) {
|
|
13813
|
+
cleanupDehydratedI18nNodes(lView);
|
|
13333
13814
|
const tView = lView[TVIEW];
|
|
13334
13815
|
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
13335
13816
|
if (isLContainer(lView[i])) {
|
|
@@ -13448,6 +13929,24 @@ function isDisconnectedNode(tNode, lView) {
|
|
|
13448
13929
|
return !(tNode.type & 16 /* TNodeType.Projection */) && !!lView[tNode.index] &&
|
|
13449
13930
|
!unwrapRNode(lView[tNode.index])?.isConnected;
|
|
13450
13931
|
}
|
|
13932
|
+
/**
|
|
13933
|
+
* Locate a node in an i18n tree that corresponds to a given instruction index.
|
|
13934
|
+
*
|
|
13935
|
+
* @param hydrationInfo The hydration annotation data
|
|
13936
|
+
* @param noOffsetIndex the instruction index
|
|
13937
|
+
* @returns an RNode that corresponds to the instruction index
|
|
13938
|
+
*/
|
|
13939
|
+
function locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex) {
|
|
13940
|
+
const i18nNodes = hydrationInfo.i18nNodes;
|
|
13941
|
+
if (i18nNodes) {
|
|
13942
|
+
const native = i18nNodes.get(noOffsetIndex);
|
|
13943
|
+
if (native) {
|
|
13944
|
+
i18nNodes.delete(noOffsetIndex);
|
|
13945
|
+
}
|
|
13946
|
+
return native;
|
|
13947
|
+
}
|
|
13948
|
+
return null;
|
|
13949
|
+
}
|
|
13451
13950
|
/**
|
|
13452
13951
|
* Locate a node in DOM tree that corresponds to a given TNode.
|
|
13453
13952
|
*
|
|
@@ -13458,51 +13957,53 @@ function isDisconnectedNode(tNode, lView) {
|
|
|
13458
13957
|
* @returns an RNode that represents a given tNode
|
|
13459
13958
|
*/
|
|
13460
13959
|
function locateNextRNode(hydrationInfo, tView, lView, tNode) {
|
|
13461
|
-
let native = null;
|
|
13462
13960
|
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);
|
|
13961
|
+
let native = locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex);
|
|
13962
|
+
if (!native) {
|
|
13963
|
+
const nodes = hydrationInfo.data[NODES];
|
|
13964
|
+
if (nodes?.[noOffsetIndex]) {
|
|
13965
|
+
// We know the exact location of the node.
|
|
13966
|
+
native = locateRNodeByPath(nodes[noOffsetIndex], lView);
|
|
13967
|
+
}
|
|
13968
|
+
else if (tView.firstChild === tNode) {
|
|
13969
|
+
// We create a first node in this view, so we use a reference
|
|
13970
|
+
// to the first child in this DOM segment.
|
|
13971
|
+
native = hydrationInfo.firstChild;
|
|
13483
13972
|
}
|
|
13484
13973
|
else {
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13974
|
+
// Locate a node based on a previous sibling or a parent node.
|
|
13975
|
+
const previousTNodeParent = tNode.prev === null;
|
|
13976
|
+
const previousTNode = (tNode.prev ?? tNode.parent);
|
|
13977
|
+
ngDevMode &&
|
|
13978
|
+
assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
|
|
13979
|
+
'to the previous node or a parent node.');
|
|
13980
|
+
if (isFirstElementInNgContainer(tNode)) {
|
|
13981
|
+
const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
|
|
13982
|
+
native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
|
|
13488
13983
|
}
|
|
13489
13984
|
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);
|
|
13985
|
+
let previousRElement = getNativeByTNode(previousTNode, lView);
|
|
13986
|
+
if (previousTNodeParent) {
|
|
13987
|
+
native = previousRElement.firstChild;
|
|
13503
13988
|
}
|
|
13504
13989
|
else {
|
|
13505
|
-
|
|
13990
|
+
// If the previous node is an element, but it also has container info,
|
|
13991
|
+
// this means that we are processing a node like `<div #vcrTarget>`, which is
|
|
13992
|
+
// represented in the DOM as `<div></div>...<!--container-->`.
|
|
13993
|
+
// In this case, there are nodes *after* this element and we need to skip
|
|
13994
|
+
// all of them to reach an element that we are looking for.
|
|
13995
|
+
const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
|
|
13996
|
+
const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13997
|
+
if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
|
|
13998
|
+
const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
|
|
13999
|
+
// `+1` stands for an anchor comment node after all the views in this container.
|
|
14000
|
+
const nodesToSkip = numRootNodesToSkip + 1;
|
|
14001
|
+
// First node after this segment.
|
|
14002
|
+
native = siblingAfter(nodesToSkip, segmentHead);
|
|
14003
|
+
}
|
|
14004
|
+
else {
|
|
14005
|
+
native = previousRElement.nextSibling;
|
|
14006
|
+
}
|
|
13506
14007
|
}
|
|
13507
14008
|
}
|
|
13508
14009
|
}
|
|
@@ -13818,7 +14319,7 @@ function noComponentFactoryError(component) {
|
|
|
13818
14319
|
return error;
|
|
13819
14320
|
}
|
|
13820
14321
|
const ERROR_COMPONENT = 'ngComponent';
|
|
13821
|
-
function getComponent
|
|
14322
|
+
function getComponent(error) {
|
|
13822
14323
|
return error[ERROR_COMPONENT];
|
|
13823
14324
|
}
|
|
13824
14325
|
class _NullComponentFactoryResolver {
|
|
@@ -14590,7 +15091,7 @@ function afterRender(callback, options) {
|
|
|
14590
15091
|
unregisterFn();
|
|
14591
15092
|
};
|
|
14592
15093
|
const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
|
|
14593
|
-
const instance = new AfterRenderCallback(
|
|
15094
|
+
const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, callback));
|
|
14594
15095
|
callbackHandler.register(instance);
|
|
14595
15096
|
return { destroy };
|
|
14596
15097
|
}
|
|
@@ -14660,10 +15161,10 @@ function afterNextRender(callback, options) {
|
|
|
14660
15161
|
unregisterFn();
|
|
14661
15162
|
};
|
|
14662
15163
|
const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
|
|
14663
|
-
const instance = new AfterRenderCallback(
|
|
15164
|
+
const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, () => {
|
|
14664
15165
|
destroy();
|
|
14665
15166
|
callback();
|
|
14666
|
-
});
|
|
15167
|
+
}));
|
|
14667
15168
|
callbackHandler.register(instance);
|
|
14668
15169
|
return { destroy };
|
|
14669
15170
|
}
|
|
@@ -14671,11 +15172,13 @@ function afterNextRender(callback, options) {
|
|
|
14671
15172
|
* A wrapper around a function to be used as an after render callback.
|
|
14672
15173
|
*/
|
|
14673
15174
|
class AfterRenderCallback {
|
|
14674
|
-
constructor(
|
|
15175
|
+
constructor(phase, callbackFn) {
|
|
14675
15176
|
this.phase = phase;
|
|
14676
15177
|
this.callbackFn = callbackFn;
|
|
14677
|
-
this.zone =
|
|
14678
|
-
this.errorHandler =
|
|
15178
|
+
this.zone = inject(NgZone);
|
|
15179
|
+
this.errorHandler = inject(ErrorHandler, { optional: true });
|
|
15180
|
+
// Registering a callback will notify the scheduler.
|
|
15181
|
+
inject(ChangeDetectionScheduler, { optional: true })?.notify(1 /* NotificationType.AfterRenderHooks */);
|
|
14679
15182
|
}
|
|
14680
15183
|
invoke() {
|
|
14681
15184
|
try {
|
|
@@ -15474,7 +15977,7 @@ function createRootComponent(componentView, rootComponentDef, rootDirectives, ho
|
|
|
15474
15977
|
function setRootNodeAttributes(hostRenderer, componentDef, hostRNode, rootSelectorOrNode) {
|
|
15475
15978
|
if (rootSelectorOrNode) {
|
|
15476
15979
|
// The placeholder will be replaced with the actual version at build time.
|
|
15477
|
-
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '17.3.
|
|
15980
|
+
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '17.3.1']);
|
|
15478
15981
|
}
|
|
15479
15982
|
else {
|
|
15480
15983
|
// If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
|
|
@@ -16500,9 +17003,11 @@ function refreshSignalQuery(node, firstOnly) {
|
|
|
16500
17003
|
}
|
|
16501
17004
|
|
|
16502
17005
|
function viewChildFn(locator, opts) {
|
|
17006
|
+
ngDevMode && assertInInjectionContext(viewChild);
|
|
16503
17007
|
return createSingleResultOptionalQuerySignalFn();
|
|
16504
17008
|
}
|
|
16505
17009
|
function viewChildRequiredFn(locator, opts) {
|
|
17010
|
+
ngDevMode && assertInInjectionContext(viewChild);
|
|
16506
17011
|
return createSingleResultRequiredQuerySignalFn();
|
|
16507
17012
|
}
|
|
16508
17013
|
/**
|
|
@@ -16551,12 +17056,15 @@ const viewChild = (() => {
|
|
|
16551
17056
|
* ```
|
|
16552
17057
|
*/
|
|
16553
17058
|
function viewChildren(locator, opts) {
|
|
17059
|
+
ngDevMode && assertInInjectionContext(viewChildren);
|
|
16554
17060
|
return createMultiResultQuerySignalFn();
|
|
16555
17061
|
}
|
|
16556
17062
|
function contentChildFn(locator, opts) {
|
|
17063
|
+
ngDevMode && assertInInjectionContext(contentChild);
|
|
16557
17064
|
return createSingleResultOptionalQuerySignalFn();
|
|
16558
17065
|
}
|
|
16559
17066
|
function contentChildRequiredFn(locator, opts) {
|
|
17067
|
+
ngDevMode && assertInInjectionContext(contentChildren);
|
|
16560
17068
|
return createSingleResultRequiredQuerySignalFn();
|
|
16561
17069
|
}
|
|
16562
17070
|
/**
|
|
@@ -17831,6 +18339,15 @@ function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
|
|
|
17831
18339
|
return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
|
|
17832
18340
|
}
|
|
17833
18341
|
|
|
18342
|
+
/**
|
|
18343
|
+
* Checks whether a TNode is considered detached, i.e. not present in the
|
|
18344
|
+
* translated i18n template. We should not attempt hydration for such nodes
|
|
18345
|
+
* and instead, use a regular "creation mode".
|
|
18346
|
+
*/
|
|
18347
|
+
function isDetachedByI18n(tNode) {
|
|
18348
|
+
return (tNode.flags & 32 /* TNodeFlags.isDetached */) === 32 /* TNodeFlags.isDetached */;
|
|
18349
|
+
}
|
|
18350
|
+
|
|
17834
18351
|
function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
|
|
17835
18352
|
ngDevMode && assertFirstCreatePass(tView);
|
|
17836
18353
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
@@ -17907,7 +18424,8 @@ function createContainerAnchorImpl(tView, lView, tNode, index) {
|
|
|
17907
18424
|
*/
|
|
17908
18425
|
function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
|
|
17909
18426
|
const hydrationInfo = lView[HYDRATION];
|
|
17910
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
18427
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
18428
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
17911
18429
|
lastNodeWasCreated(isNodeCreationMode);
|
|
17912
18430
|
// Regular creation mode.
|
|
17913
18431
|
if (isNodeCreationMode) {
|
|
@@ -19124,7 +19642,7 @@ function applyDeferBlockState(newState, lDetails, lContainer, tNode, hostLView)
|
|
|
19124
19642
|
}
|
|
19125
19643
|
}
|
|
19126
19644
|
const dehydratedView = findMatchingDehydratedView(lContainer, activeBlockTNode.tView.ssrId);
|
|
19127
|
-
const embeddedLView = createAndRenderEmbeddedLView(hostLView, activeBlockTNode, null, { dehydratedView, injector });
|
|
19645
|
+
const embeddedLView = createAndRenderEmbeddedLView(hostLView, activeBlockTNode, null, { dehydratedView, embeddedViewInjector: injector });
|
|
19128
19646
|
addLViewToLContainer(lContainer, embeddedLView, viewIndex, shouldAddViewToDom(activeBlockTNode, dehydratedView));
|
|
19129
19647
|
markViewDirty(embeddedLView);
|
|
19130
19648
|
}
|
|
@@ -22194,6 +22712,8 @@ class RepeaterMetadata {
|
|
|
22194
22712
|
*/
|
|
22195
22713
|
function ɵɵrepeaterCreate(index, templateFn, decls, vars, tagName, attrsIndex, trackByFn, trackByUsesComponentInstance, emptyTemplateFn, emptyDecls, emptyVars, emptyTagName, emptyAttrsIndex) {
|
|
22196
22714
|
performanceMarkFeature('NgControlFlow');
|
|
22715
|
+
ngDevMode &&
|
|
22716
|
+
assertFunction(trackByFn, `A track expression must be a function, was ${typeof trackByFn} instead.`);
|
|
22197
22717
|
const hasEmptyBlock = emptyTemplateFn !== undefined;
|
|
22198
22718
|
const hostLView = getLView();
|
|
22199
22719
|
const boundTrackBy = trackByUsesComponentInstance ?
|
|
@@ -22389,7 +22909,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
|
|
|
22389
22909
|
}
|
|
22390
22910
|
setCurrentTNode(tNode, true);
|
|
22391
22911
|
setupStaticAttributes(renderer, native, tNode);
|
|
22392
|
-
if ((tNode
|
|
22912
|
+
if (!isDetachedByI18n(tNode) && wasLastNodeCreated()) {
|
|
22393
22913
|
// In the i18n case, the translation may have removed this element, so only add it if it is not
|
|
22394
22914
|
// detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
|
|
22395
22915
|
appendChild(tView, lView, native, tNode);
|
|
@@ -22474,7 +22994,8 @@ let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) =>
|
|
|
22474
22994
|
*/
|
|
22475
22995
|
function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, index) {
|
|
22476
22996
|
const hydrationInfo = lView[HYDRATION];
|
|
22477
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
22997
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
22998
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
22478
22999
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22479
23000
|
// Regular creation mode.
|
|
22480
23001
|
if (isNodeCreationMode) {
|
|
@@ -22632,7 +23153,7 @@ let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
|
|
|
22632
23153
|
function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
|
|
22633
23154
|
let comment;
|
|
22634
23155
|
const hydrationInfo = lView[HYDRATION];
|
|
22635
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
|
|
23156
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode);
|
|
22636
23157
|
lastNodeWasCreated(isNodeCreationMode);
|
|
22637
23158
|
// Regular creation mode.
|
|
22638
23159
|
if (isNodeCreationMode) {
|
|
@@ -23245,6 +23766,29 @@ function applyI18n(tView, lView, index) {
|
|
|
23245
23766
|
changeMask = 0b0;
|
|
23246
23767
|
changeMaskCounter = 0;
|
|
23247
23768
|
}
|
|
23769
|
+
function createNodeWithoutHydration(lView, textOrName, nodeType) {
|
|
23770
|
+
const renderer = lView[RENDERER];
|
|
23771
|
+
switch (nodeType) {
|
|
23772
|
+
case Node.COMMENT_NODE:
|
|
23773
|
+
return createCommentNode(renderer, textOrName);
|
|
23774
|
+
case Node.TEXT_NODE:
|
|
23775
|
+
return createTextNode(renderer, textOrName);
|
|
23776
|
+
case Node.ELEMENT_NODE:
|
|
23777
|
+
return createElementNode(renderer, textOrName, null);
|
|
23778
|
+
}
|
|
23779
|
+
}
|
|
23780
|
+
let _locateOrCreateNode = (lView, index, textOrName, nodeType) => {
|
|
23781
|
+
lastNodeWasCreated(true);
|
|
23782
|
+
return createNodeWithoutHydration(lView, textOrName, nodeType);
|
|
23783
|
+
};
|
|
23784
|
+
function locateOrCreateNodeImpl(lView, index, textOrName, nodeType) {
|
|
23785
|
+
// TODO: Add support for hydration
|
|
23786
|
+
lastNodeWasCreated(true);
|
|
23787
|
+
return createNodeWithoutHydration(lView, textOrName, nodeType);
|
|
23788
|
+
}
|
|
23789
|
+
function enableLocateOrCreateI18nNodeImpl() {
|
|
23790
|
+
_locateOrCreateNode = locateOrCreateNodeImpl;
|
|
23791
|
+
}
|
|
23248
23792
|
/**
|
|
23249
23793
|
* Apply `I18nCreateOpCodes` op-codes as stored in `TI18n.create`.
|
|
23250
23794
|
*
|
|
@@ -23265,13 +23809,15 @@ function applyCreateOpCodes(lView, createOpCodes, parentRNode, insertInFrontOf)
|
|
|
23265
23809
|
const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
|
|
23266
23810
|
const index = opCode >>> I18nCreateOpCode.SHIFT;
|
|
23267
23811
|
let rNode = lView[index];
|
|
23812
|
+
let lastNodeWasCreated = false;
|
|
23268
23813
|
if (rNode === null) {
|
|
23269
23814
|
// We only create new DOM nodes if they don't already exist: If ICU switches case back to a
|
|
23270
23815
|
// case which was already instantiated, no need to create new DOM nodes.
|
|
23271
23816
|
rNode = lView[index] =
|
|
23272
|
-
isComment ?
|
|
23817
|
+
_locateOrCreateNode(lView, index, text, isComment ? Node.COMMENT_NODE : Node.TEXT_NODE);
|
|
23818
|
+
lastNodeWasCreated = wasLastNodeCreated();
|
|
23273
23819
|
}
|
|
23274
|
-
if (appendNow && parentRNode !== null) {
|
|
23820
|
+
if (appendNow && parentRNode !== null && lastNodeWasCreated) {
|
|
23275
23821
|
nativeInsertBefore(renderer, parentRNode, rNode, insertInFrontOf, false);
|
|
23276
23822
|
}
|
|
23277
23823
|
}
|
|
@@ -23302,7 +23848,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23302
23848
|
if (lView[textNodeIndex] === null) {
|
|
23303
23849
|
ngDevMode && ngDevMode.rendererCreateTextNode++;
|
|
23304
23850
|
ngDevMode && assertIndexInRange(lView, textNodeIndex);
|
|
23305
|
-
lView[textNodeIndex] =
|
|
23851
|
+
lView[textNodeIndex] = _locateOrCreateNode(lView, textNodeIndex, opCode, Node.TEXT_NODE);
|
|
23306
23852
|
}
|
|
23307
23853
|
}
|
|
23308
23854
|
else if (typeof opCode == 'number') {
|
|
@@ -23377,7 +23923,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23377
23923
|
ngDevMode && ngDevMode.rendererCreateComment++;
|
|
23378
23924
|
ngDevMode && assertIndexInExpandoRange(lView, commentNodeIndex);
|
|
23379
23925
|
const commentRNode = lView[commentNodeIndex] =
|
|
23380
|
-
|
|
23926
|
+
_locateOrCreateNode(lView, commentNodeIndex, commentValue, Node.COMMENT_NODE);
|
|
23381
23927
|
// FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
|
|
23382
23928
|
attachPatchData(commentRNode, lView);
|
|
23383
23929
|
}
|
|
@@ -23391,7 +23937,7 @@ function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
|
|
|
23391
23937
|
ngDevMode && ngDevMode.rendererCreateElement++;
|
|
23392
23938
|
ngDevMode && assertIndexInExpandoRange(lView, elementNodeIndex);
|
|
23393
23939
|
const elementRNode = lView[elementNodeIndex] =
|
|
23394
|
-
|
|
23940
|
+
_locateOrCreateNode(lView, elementNodeIndex, tagName, Node.ELEMENT_NODE);
|
|
23395
23941
|
// FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
|
|
23396
23942
|
attachPatchData(elementRNode, lView);
|
|
23397
23943
|
}
|
|
@@ -23918,6 +24464,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23918
24464
|
const createOpCodes = [];
|
|
23919
24465
|
const updateOpCodes = [];
|
|
23920
24466
|
const existingTNodeStack = [[]];
|
|
24467
|
+
const astStack = [[]];
|
|
23921
24468
|
if (ngDevMode) {
|
|
23922
24469
|
attachDebugGetter(createOpCodes, i18nCreateOpCodesToString);
|
|
23923
24470
|
attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
|
|
@@ -23936,7 +24483,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23936
24483
|
const text = part;
|
|
23937
24484
|
ngDevMode && assertString(text, 'Parsed ICU part should be string');
|
|
23938
24485
|
if (text !== '') {
|
|
23939
|
-
i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
|
|
24486
|
+
i18nStartFirstCreatePassProcessTextNode(astStack[0], tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
|
|
23940
24487
|
}
|
|
23941
24488
|
}
|
|
23942
24489
|
else {
|
|
@@ -23955,7 +24502,7 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23955
24502
|
const icuNodeIndex = icuContainerTNode.index;
|
|
23956
24503
|
ngDevMode &&
|
|
23957
24504
|
assertGreaterThanOrEqual(icuNodeIndex, HEADER_OFFSET, 'Index must be in absolute LView offset');
|
|
23958
|
-
icuStart(tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
|
|
24505
|
+
icuStart(astStack[0], tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
|
|
23959
24506
|
}
|
|
23960
24507
|
}
|
|
23961
24508
|
}
|
|
@@ -23968,18 +24515,29 @@ function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message
|
|
|
23968
24515
|
const index = HEADER_OFFSET + Number.parseInt(value.substring((isClosing ? 2 : 1)));
|
|
23969
24516
|
if (isClosing) {
|
|
23970
24517
|
existingTNodeStack.shift();
|
|
24518
|
+
astStack.shift();
|
|
23971
24519
|
setCurrentTNode(getCurrentParentTNode(), false);
|
|
23972
24520
|
}
|
|
23973
24521
|
else {
|
|
23974
24522
|
const tNode = createTNodePlaceholder(tView, existingTNodeStack[0], index);
|
|
23975
24523
|
existingTNodeStack.unshift([]);
|
|
23976
24524
|
setCurrentTNode(tNode, true);
|
|
24525
|
+
const placeholderNode = {
|
|
24526
|
+
kind: 2 /* I18nNodeKind.PLACEHOLDER */,
|
|
24527
|
+
index,
|
|
24528
|
+
children: [],
|
|
24529
|
+
type: type === 35 /* CharCode.HASH */ ? 0 /* I18nPlaceholderType.ELEMENT */ :
|
|
24530
|
+
1 /* I18nPlaceholderType.SUBTEMPLATE */,
|
|
24531
|
+
};
|
|
24532
|
+
astStack[0].push(placeholderNode);
|
|
24533
|
+
astStack.unshift(placeholderNode.children);
|
|
23977
24534
|
}
|
|
23978
24535
|
}
|
|
23979
24536
|
}
|
|
23980
24537
|
tView.data[index] = {
|
|
23981
24538
|
create: createOpCodes,
|
|
23982
24539
|
update: updateOpCodes,
|
|
24540
|
+
ast: astStack[0],
|
|
23983
24541
|
};
|
|
23984
24542
|
}
|
|
23985
24543
|
/**
|
|
@@ -24048,12 +24606,14 @@ function createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, create
|
|
|
24048
24606
|
* @param lView Current `LView`
|
|
24049
24607
|
* @param text The translated text (which may contain binding)
|
|
24050
24608
|
*/
|
|
24051
|
-
function i18nStartFirstCreatePassProcessTextNode(tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
|
|
24609
|
+
function i18nStartFirstCreatePassProcessTextNode(ast, tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
|
|
24052
24610
|
const hasBinding = text.match(BINDING_REGEXP);
|
|
24053
24611
|
const tNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, hasBinding ? null : text, false);
|
|
24612
|
+
const index = tNode.index;
|
|
24054
24613
|
if (hasBinding) {
|
|
24055
|
-
generateBindingUpdateOpCodes(updateOpCodes, text,
|
|
24614
|
+
generateBindingUpdateOpCodes(updateOpCodes, text, index, null, 0, null);
|
|
24056
24615
|
}
|
|
24616
|
+
ast.push({ kind: 0 /* I18nNodeKind.TEXT */, index });
|
|
24057
24617
|
}
|
|
24058
24618
|
/**
|
|
24059
24619
|
* See `i18nAttributes` above.
|
|
@@ -24231,7 +24791,7 @@ function getTranslationForTemplate(message, subTemplateIndex) {
|
|
|
24231
24791
|
* - `lView[anchorIdx]` points to a `Comment` node representing the anchor for the ICU.
|
|
24232
24792
|
* - `tView.data[anchorIdx]` points to the `TIcuContainerNode` if ICU is root (`null` otherwise)
|
|
24233
24793
|
*/
|
|
24234
|
-
function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
|
|
24794
|
+
function icuStart(ast, tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
|
|
24235
24795
|
ngDevMode && assertDefined(icuExpression, 'ICU expression must be defined');
|
|
24236
24796
|
let bindingMask = 0;
|
|
24237
24797
|
const tIcu = {
|
|
@@ -24246,6 +24806,7 @@ function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorI
|
|
|
24246
24806
|
addUpdateIcuSwitch(updateOpCodes, icuExpression, anchorIdx);
|
|
24247
24807
|
setTIcu(tView, anchorIdx, tIcu);
|
|
24248
24808
|
const values = icuExpression.values;
|
|
24809
|
+
const cases = [];
|
|
24249
24810
|
for (let i = 0; i < values.length; i++) {
|
|
24250
24811
|
// Each value is an array of strings & other ICU expressions
|
|
24251
24812
|
const valueArr = values[i];
|
|
@@ -24259,12 +24820,20 @@ function icuStart(tView, lView, updateOpCodes, parentIdx, icuExpression, anchorI
|
|
|
24259
24820
|
valueArr[j] = `<!--�${icuIndex}�-->`;
|
|
24260
24821
|
}
|
|
24261
24822
|
}
|
|
24262
|
-
|
|
24823
|
+
const caseAst = [];
|
|
24824
|
+
cases.push(caseAst);
|
|
24825
|
+
bindingMask = parseIcuCase(caseAst, tView, tIcu, lView, updateOpCodes, parentIdx, icuExpression.cases[i], valueArr.join(''), nestedIcus) |
|
|
24263
24826
|
bindingMask;
|
|
24264
24827
|
}
|
|
24265
24828
|
if (bindingMask) {
|
|
24266
24829
|
addUpdateIcuUpdate(updateOpCodes, bindingMask, anchorIdx);
|
|
24267
24830
|
}
|
|
24831
|
+
ast.push({
|
|
24832
|
+
kind: 3 /* I18nNodeKind.ICU */,
|
|
24833
|
+
index: anchorIdx,
|
|
24834
|
+
cases,
|
|
24835
|
+
currentCaseLViewIndex: tIcu.currentCaseLViewIndex
|
|
24836
|
+
});
|
|
24268
24837
|
}
|
|
24269
24838
|
/**
|
|
24270
24839
|
* Parses text containing an ICU expression and produces a JSON object for it.
|
|
@@ -24361,7 +24930,7 @@ function i18nParseTextIntoPartsAndICU(pattern) {
|
|
|
24361
24930
|
* Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
|
|
24362
24931
|
*
|
|
24363
24932
|
*/
|
|
24364
|
-
function parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
|
|
24933
|
+
function parseIcuCase(ast, tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
|
|
24365
24934
|
const create = [];
|
|
24366
24935
|
const remove = [];
|
|
24367
24936
|
const update = [];
|
|
@@ -24379,13 +24948,13 @@ function parseIcuCase(tView, tIcu, lView, updateOpCodes, parentIdx, caseName, un
|
|
|
24379
24948
|
ngDevMode && assertDefined(inertBodyElement, 'Unable to generate inert body element');
|
|
24380
24949
|
const inertRootNode = getTemplateContent(inertBodyElement) || inertBodyElement;
|
|
24381
24950
|
if (inertRootNode) {
|
|
24382
|
-
return walkIcuTree(tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
|
|
24951
|
+
return walkIcuTree(ast, tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
|
|
24383
24952
|
}
|
|
24384
24953
|
else {
|
|
24385
24954
|
return 0;
|
|
24386
24955
|
}
|
|
24387
24956
|
}
|
|
24388
|
-
function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
|
|
24957
|
+
function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
|
|
24389
24958
|
let bindingMask = 0;
|
|
24390
24959
|
let currentNode = parentNode.firstChild;
|
|
24391
24960
|
while (currentNode) {
|
|
@@ -24423,9 +24992,16 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24423
24992
|
addCreateAttribute(create, newIndex, attr);
|
|
24424
24993
|
}
|
|
24425
24994
|
}
|
|
24995
|
+
const elementNode = {
|
|
24996
|
+
kind: 1 /* I18nNodeKind.ELEMENT */,
|
|
24997
|
+
index: newIndex,
|
|
24998
|
+
children: [],
|
|
24999
|
+
};
|
|
25000
|
+
ast.push(elementNode);
|
|
24426
25001
|
// Parse the children of this node (if any)
|
|
24427
|
-
bindingMask =
|
|
24428
|
-
|
|
25002
|
+
bindingMask =
|
|
25003
|
+
walkIcuTree(elementNode.children, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, currentNode, newIndex, nestedIcus, depth + 1) |
|
|
25004
|
+
bindingMask;
|
|
24429
25005
|
addRemoveNode(remove, newIndex, depth);
|
|
24430
25006
|
}
|
|
24431
25007
|
break;
|
|
@@ -24438,6 +25014,10 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24438
25014
|
bindingMask =
|
|
24439
25015
|
generateBindingUpdateOpCodes(update, value, newIndex, null, 0, null) | bindingMask;
|
|
24440
25016
|
}
|
|
25017
|
+
ast.push({
|
|
25018
|
+
kind: 0 /* I18nNodeKind.TEXT */,
|
|
25019
|
+
index: newIndex,
|
|
25020
|
+
});
|
|
24441
25021
|
break;
|
|
24442
25022
|
case Node.COMMENT_NODE:
|
|
24443
25023
|
// Check if the comment node is a placeholder for a nested ICU
|
|
@@ -24447,7 +25027,7 @@ function walkIcuTree(tView, tIcu, lView, sharedUpdateOpCodes, create, remove, up
|
|
|
24447
25027
|
const icuExpression = nestedIcus[nestedIcuIndex];
|
|
24448
25028
|
// Create the comment node that will anchor the ICU expression
|
|
24449
25029
|
addCreateNodeAndAppend(create, ICU_MARKER, ngDevMode ? `nested ICU ${nestedIcuIndex}` : '', parentIdx, newIndex);
|
|
24450
|
-
icuStart(tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
|
|
25030
|
+
icuStart(ast, tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
|
|
24451
25031
|
addRemoveNestedIcu(remove, newIndex, depth);
|
|
24452
25032
|
}
|
|
24453
25033
|
break;
|
|
@@ -26410,7 +26990,8 @@ let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
|
|
|
26410
26990
|
*/
|
|
26411
26991
|
function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
|
|
26412
26992
|
const hydrationInfo = lView[HYDRATION];
|
|
26413
|
-
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
26993
|
+
const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() ||
|
|
26994
|
+
isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
|
|
26414
26995
|
lastNodeWasCreated(isNodeCreationMode);
|
|
26415
26996
|
// Regular creation mode.
|
|
26416
26997
|
if (isNodeCreationMode) {
|
|
@@ -27191,416 +27772,6 @@ function maybeUnwrapModuleWithProviders(value) {
|
|
|
27191
27772
|
return isModuleWithProviders(value) ? value.ngModule : value;
|
|
27192
27773
|
}
|
|
27193
27774
|
|
|
27194
|
-
/**
|
|
27195
|
-
* Retrieves the component instance associated with a given DOM element.
|
|
27196
|
-
*
|
|
27197
|
-
* @usageNotes
|
|
27198
|
-
* Given the following DOM structure:
|
|
27199
|
-
*
|
|
27200
|
-
* ```html
|
|
27201
|
-
* <app-root>
|
|
27202
|
-
* <div>
|
|
27203
|
-
* <child-comp></child-comp>
|
|
27204
|
-
* </div>
|
|
27205
|
-
* </app-root>
|
|
27206
|
-
* ```
|
|
27207
|
-
*
|
|
27208
|
-
* Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
|
|
27209
|
-
* associated with this DOM element.
|
|
27210
|
-
*
|
|
27211
|
-
* Calling the function on `<app-root>` will return the `MyApp` instance.
|
|
27212
|
-
*
|
|
27213
|
-
*
|
|
27214
|
-
* @param element DOM element from which the component should be retrieved.
|
|
27215
|
-
* @returns Component instance associated with the element or `null` if there
|
|
27216
|
-
* is no component associated with it.
|
|
27217
|
-
*
|
|
27218
|
-
* @publicApi
|
|
27219
|
-
* @globalApi ng
|
|
27220
|
-
*/
|
|
27221
|
-
function getComponent(element) {
|
|
27222
|
-
ngDevMode && assertDomElement(element);
|
|
27223
|
-
const context = getLContext(element);
|
|
27224
|
-
if (context === null)
|
|
27225
|
-
return null;
|
|
27226
|
-
if (context.component === undefined) {
|
|
27227
|
-
const lView = context.lView;
|
|
27228
|
-
if (lView === null) {
|
|
27229
|
-
return null;
|
|
27230
|
-
}
|
|
27231
|
-
context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
|
|
27232
|
-
}
|
|
27233
|
-
return context.component;
|
|
27234
|
-
}
|
|
27235
|
-
/**
|
|
27236
|
-
* If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
|
|
27237
|
-
* view that the element is part of. Otherwise retrieves the instance of the component whose view
|
|
27238
|
-
* owns the element (in this case, the result is the same as calling `getOwningComponent`).
|
|
27239
|
-
*
|
|
27240
|
-
* @param element Element for which to get the surrounding component instance.
|
|
27241
|
-
* @returns Instance of the component that is around the element or null if the element isn't
|
|
27242
|
-
* inside any component.
|
|
27243
|
-
*
|
|
27244
|
-
* @publicApi
|
|
27245
|
-
* @globalApi ng
|
|
27246
|
-
*/
|
|
27247
|
-
function getContext(element) {
|
|
27248
|
-
assertDomElement(element);
|
|
27249
|
-
const context = getLContext(element);
|
|
27250
|
-
const lView = context ? context.lView : null;
|
|
27251
|
-
return lView === null ? null : lView[CONTEXT];
|
|
27252
|
-
}
|
|
27253
|
-
/**
|
|
27254
|
-
* Retrieves the component instance whose view contains the DOM element.
|
|
27255
|
-
*
|
|
27256
|
-
* For example, if `<child-comp>` is used in the template of `<app-comp>`
|
|
27257
|
-
* (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
|
|
27258
|
-
* would return `<app-comp>`.
|
|
27259
|
-
*
|
|
27260
|
-
* @param elementOrDir DOM element, component or directive instance
|
|
27261
|
-
* for which to retrieve the root components.
|
|
27262
|
-
* @returns Component instance whose view owns the DOM element or null if the element is not
|
|
27263
|
-
* part of a component view.
|
|
27264
|
-
*
|
|
27265
|
-
* @publicApi
|
|
27266
|
-
* @globalApi ng
|
|
27267
|
-
*/
|
|
27268
|
-
function getOwningComponent(elementOrDir) {
|
|
27269
|
-
const context = getLContext(elementOrDir);
|
|
27270
|
-
let lView = context ? context.lView : null;
|
|
27271
|
-
if (lView === null)
|
|
27272
|
-
return null;
|
|
27273
|
-
let parent;
|
|
27274
|
-
while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
|
|
27275
|
-
lView = parent;
|
|
27276
|
-
}
|
|
27277
|
-
return lView[FLAGS] & 512 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
|
|
27278
|
-
}
|
|
27279
|
-
/**
|
|
27280
|
-
* Retrieves all root components associated with a DOM element, directive or component instance.
|
|
27281
|
-
* Root components are those which have been bootstrapped by Angular.
|
|
27282
|
-
*
|
|
27283
|
-
* @param elementOrDir DOM element, component or directive instance
|
|
27284
|
-
* for which to retrieve the root components.
|
|
27285
|
-
* @returns Root components associated with the target object.
|
|
27286
|
-
*
|
|
27287
|
-
* @publicApi
|
|
27288
|
-
* @globalApi ng
|
|
27289
|
-
*/
|
|
27290
|
-
function getRootComponents(elementOrDir) {
|
|
27291
|
-
const lView = readPatchedLView(elementOrDir);
|
|
27292
|
-
return lView !== null ? [getRootContext(lView)] : [];
|
|
27293
|
-
}
|
|
27294
|
-
/**
|
|
27295
|
-
* Retrieves an `Injector` associated with an element, component or directive instance.
|
|
27296
|
-
*
|
|
27297
|
-
* @param elementOrDir DOM element, component or directive instance for which to
|
|
27298
|
-
* retrieve the injector.
|
|
27299
|
-
* @returns Injector associated with the element, component or directive instance.
|
|
27300
|
-
*
|
|
27301
|
-
* @publicApi
|
|
27302
|
-
* @globalApi ng
|
|
27303
|
-
*/
|
|
27304
|
-
function getInjector(elementOrDir) {
|
|
27305
|
-
const context = getLContext(elementOrDir);
|
|
27306
|
-
const lView = context ? context.lView : null;
|
|
27307
|
-
if (lView === null)
|
|
27308
|
-
return Injector.NULL;
|
|
27309
|
-
const tNode = lView[TVIEW].data[context.nodeIndex];
|
|
27310
|
-
return new NodeInjector(tNode, lView);
|
|
27311
|
-
}
|
|
27312
|
-
/**
|
|
27313
|
-
* Retrieve a set of injection tokens at a given DOM node.
|
|
27314
|
-
*
|
|
27315
|
-
* @param element Element for which the injection tokens should be retrieved.
|
|
27316
|
-
*/
|
|
27317
|
-
function getInjectionTokens(element) {
|
|
27318
|
-
const context = getLContext(element);
|
|
27319
|
-
const lView = context ? context.lView : null;
|
|
27320
|
-
if (lView === null)
|
|
27321
|
-
return [];
|
|
27322
|
-
const tView = lView[TVIEW];
|
|
27323
|
-
const tNode = tView.data[context.nodeIndex];
|
|
27324
|
-
const providerTokens = [];
|
|
27325
|
-
const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
|
|
27326
|
-
const endIndex = tNode.directiveEnd;
|
|
27327
|
-
for (let i = startIndex; i < endIndex; i++) {
|
|
27328
|
-
let value = tView.data[i];
|
|
27329
|
-
if (isDirectiveDefHack(value)) {
|
|
27330
|
-
// The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
|
|
27331
|
-
// design flaw. We should always store same type so that we can be monomorphic. The issue
|
|
27332
|
-
// is that for Components/Directives we store the def instead the type. The correct behavior
|
|
27333
|
-
// is that we should always be storing injectable type in this location.
|
|
27334
|
-
value = value.type;
|
|
27335
|
-
}
|
|
27336
|
-
providerTokens.push(value);
|
|
27337
|
-
}
|
|
27338
|
-
return providerTokens;
|
|
27339
|
-
}
|
|
27340
|
-
/**
|
|
27341
|
-
* Retrieves directive instances associated with a given DOM node. Does not include
|
|
27342
|
-
* component instances.
|
|
27343
|
-
*
|
|
27344
|
-
* @usageNotes
|
|
27345
|
-
* Given the following DOM structure:
|
|
27346
|
-
*
|
|
27347
|
-
* ```html
|
|
27348
|
-
* <app-root>
|
|
27349
|
-
* <button my-button></button>
|
|
27350
|
-
* <my-comp></my-comp>
|
|
27351
|
-
* </app-root>
|
|
27352
|
-
* ```
|
|
27353
|
-
*
|
|
27354
|
-
* Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
|
|
27355
|
-
* directive that is associated with the DOM node.
|
|
27356
|
-
*
|
|
27357
|
-
* Calling `getDirectives` on `<my-comp>` will return an empty array.
|
|
27358
|
-
*
|
|
27359
|
-
* @param node DOM node for which to get the directives.
|
|
27360
|
-
* @returns Array of directives associated with the node.
|
|
27361
|
-
*
|
|
27362
|
-
* @publicApi
|
|
27363
|
-
* @globalApi ng
|
|
27364
|
-
*/
|
|
27365
|
-
function getDirectives(node) {
|
|
27366
|
-
// Skip text nodes because we can't have directives associated with them.
|
|
27367
|
-
if (node instanceof Text) {
|
|
27368
|
-
return [];
|
|
27369
|
-
}
|
|
27370
|
-
const context = getLContext(node);
|
|
27371
|
-
const lView = context ? context.lView : null;
|
|
27372
|
-
if (lView === null) {
|
|
27373
|
-
return [];
|
|
27374
|
-
}
|
|
27375
|
-
const tView = lView[TVIEW];
|
|
27376
|
-
const nodeIndex = context.nodeIndex;
|
|
27377
|
-
if (!tView?.data[nodeIndex]) {
|
|
27378
|
-
return [];
|
|
27379
|
-
}
|
|
27380
|
-
if (context.directives === undefined) {
|
|
27381
|
-
context.directives = getDirectivesAtNodeIndex(nodeIndex, lView);
|
|
27382
|
-
}
|
|
27383
|
-
// The `directives` in this case are a named array called `LComponentView`. Clone the
|
|
27384
|
-
// result so we don't expose an internal data structure in the user's console.
|
|
27385
|
-
return context.directives === null ? [] : [...context.directives];
|
|
27386
|
-
}
|
|
27387
|
-
/**
|
|
27388
|
-
* Returns the debug (partial) metadata for a particular directive or component instance.
|
|
27389
|
-
* The function accepts an instance of a directive or component and returns the corresponding
|
|
27390
|
-
* metadata.
|
|
27391
|
-
*
|
|
27392
|
-
* @param directiveOrComponentInstance Instance of a directive or component
|
|
27393
|
-
* @returns metadata of the passed directive or component
|
|
27394
|
-
*
|
|
27395
|
-
* @publicApi
|
|
27396
|
-
* @globalApi ng
|
|
27397
|
-
*/
|
|
27398
|
-
function getDirectiveMetadata$1(directiveOrComponentInstance) {
|
|
27399
|
-
const { constructor } = directiveOrComponentInstance;
|
|
27400
|
-
if (!constructor) {
|
|
27401
|
-
throw new Error('Unable to find the instance constructor');
|
|
27402
|
-
}
|
|
27403
|
-
// In case a component inherits from a directive, we may have component and directive metadata
|
|
27404
|
-
// To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
|
|
27405
|
-
const componentDef = getComponentDef(constructor);
|
|
27406
|
-
if (componentDef) {
|
|
27407
|
-
const inputs = extractInputDebugMetadata(componentDef.inputs);
|
|
27408
|
-
return {
|
|
27409
|
-
inputs,
|
|
27410
|
-
outputs: componentDef.outputs,
|
|
27411
|
-
encapsulation: componentDef.encapsulation,
|
|
27412
|
-
changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
|
|
27413
|
-
ChangeDetectionStrategy.Default
|
|
27414
|
-
};
|
|
27415
|
-
}
|
|
27416
|
-
const directiveDef = getDirectiveDef(constructor);
|
|
27417
|
-
if (directiveDef) {
|
|
27418
|
-
const inputs = extractInputDebugMetadata(directiveDef.inputs);
|
|
27419
|
-
return { inputs, outputs: directiveDef.outputs };
|
|
27420
|
-
}
|
|
27421
|
-
return null;
|
|
27422
|
-
}
|
|
27423
|
-
/**
|
|
27424
|
-
* Retrieve map of local references.
|
|
27425
|
-
*
|
|
27426
|
-
* The references are retrieved as a map of local reference name to element or directive instance.
|
|
27427
|
-
*
|
|
27428
|
-
* @param target DOM element, component or directive instance for which to retrieve
|
|
27429
|
-
* the local references.
|
|
27430
|
-
*/
|
|
27431
|
-
function getLocalRefs(target) {
|
|
27432
|
-
const context = getLContext(target);
|
|
27433
|
-
if (context === null)
|
|
27434
|
-
return {};
|
|
27435
|
-
if (context.localRefs === undefined) {
|
|
27436
|
-
const lView = context.lView;
|
|
27437
|
-
if (lView === null) {
|
|
27438
|
-
return {};
|
|
27439
|
-
}
|
|
27440
|
-
context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
|
|
27441
|
-
}
|
|
27442
|
-
return context.localRefs || {};
|
|
27443
|
-
}
|
|
27444
|
-
/**
|
|
27445
|
-
* Retrieves the host element of a component or directive instance.
|
|
27446
|
-
* The host element is the DOM element that matched the selector of the directive.
|
|
27447
|
-
*
|
|
27448
|
-
* @param componentOrDirective Component or directive instance for which the host
|
|
27449
|
-
* element should be retrieved.
|
|
27450
|
-
* @returns Host element of the target.
|
|
27451
|
-
*
|
|
27452
|
-
* @publicApi
|
|
27453
|
-
* @globalApi ng
|
|
27454
|
-
*/
|
|
27455
|
-
function getHostElement(componentOrDirective) {
|
|
27456
|
-
return getLContext(componentOrDirective).native;
|
|
27457
|
-
}
|
|
27458
|
-
/**
|
|
27459
|
-
* Retrieves the rendered text for a given component.
|
|
27460
|
-
*
|
|
27461
|
-
* This function retrieves the host element of a component and
|
|
27462
|
-
* and then returns the `textContent` for that element. This implies
|
|
27463
|
-
* that the text returned will include re-projected content of
|
|
27464
|
-
* the component as well.
|
|
27465
|
-
*
|
|
27466
|
-
* @param component The component to return the content text for.
|
|
27467
|
-
*/
|
|
27468
|
-
function getRenderedText(component) {
|
|
27469
|
-
const hostElement = getHostElement(component);
|
|
27470
|
-
return hostElement.textContent || '';
|
|
27471
|
-
}
|
|
27472
|
-
/**
|
|
27473
|
-
* Retrieves a list of event listeners associated with a DOM element. The list does include host
|
|
27474
|
-
* listeners, but it does not include event listeners defined outside of the Angular context
|
|
27475
|
-
* (e.g. through `addEventListener`).
|
|
27476
|
-
*
|
|
27477
|
-
* @usageNotes
|
|
27478
|
-
* Given the following DOM structure:
|
|
27479
|
-
*
|
|
27480
|
-
* ```html
|
|
27481
|
-
* <app-root>
|
|
27482
|
-
* <div (click)="doSomething()"></div>
|
|
27483
|
-
* </app-root>
|
|
27484
|
-
* ```
|
|
27485
|
-
*
|
|
27486
|
-
* Calling `getListeners` on `<div>` will return an object that looks as follows:
|
|
27487
|
-
*
|
|
27488
|
-
* ```ts
|
|
27489
|
-
* {
|
|
27490
|
-
* name: 'click',
|
|
27491
|
-
* element: <div>,
|
|
27492
|
-
* callback: () => doSomething(),
|
|
27493
|
-
* useCapture: false
|
|
27494
|
-
* }
|
|
27495
|
-
* ```
|
|
27496
|
-
*
|
|
27497
|
-
* @param element Element for which the DOM listeners should be retrieved.
|
|
27498
|
-
* @returns Array of event listeners on the DOM element.
|
|
27499
|
-
*
|
|
27500
|
-
* @publicApi
|
|
27501
|
-
* @globalApi ng
|
|
27502
|
-
*/
|
|
27503
|
-
function getListeners(element) {
|
|
27504
|
-
ngDevMode && assertDomElement(element);
|
|
27505
|
-
const lContext = getLContext(element);
|
|
27506
|
-
const lView = lContext === null ? null : lContext.lView;
|
|
27507
|
-
if (lView === null)
|
|
27508
|
-
return [];
|
|
27509
|
-
const tView = lView[TVIEW];
|
|
27510
|
-
const lCleanup = lView[CLEANUP];
|
|
27511
|
-
const tCleanup = tView.cleanup;
|
|
27512
|
-
const listeners = [];
|
|
27513
|
-
if (tCleanup && lCleanup) {
|
|
27514
|
-
for (let i = 0; i < tCleanup.length;) {
|
|
27515
|
-
const firstParam = tCleanup[i++];
|
|
27516
|
-
const secondParam = tCleanup[i++];
|
|
27517
|
-
if (typeof firstParam === 'string') {
|
|
27518
|
-
const name = firstParam;
|
|
27519
|
-
const listenerElement = unwrapRNode(lView[secondParam]);
|
|
27520
|
-
const callback = lCleanup[tCleanup[i++]];
|
|
27521
|
-
const useCaptureOrIndx = tCleanup[i++];
|
|
27522
|
-
// if useCaptureOrIndx is boolean then report it as is.
|
|
27523
|
-
// if useCaptureOrIndx is positive number then it in unsubscribe method
|
|
27524
|
-
// if useCaptureOrIndx is negative number then it is a Subscription
|
|
27525
|
-
const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
|
|
27526
|
-
const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
|
|
27527
|
-
if (element == listenerElement) {
|
|
27528
|
-
listeners.push({ element, name, callback, useCapture, type });
|
|
27529
|
-
}
|
|
27530
|
-
}
|
|
27531
|
-
}
|
|
27532
|
-
}
|
|
27533
|
-
listeners.sort(sortListeners);
|
|
27534
|
-
return listeners;
|
|
27535
|
-
}
|
|
27536
|
-
function sortListeners(a, b) {
|
|
27537
|
-
if (a.name == b.name)
|
|
27538
|
-
return 0;
|
|
27539
|
-
return a.name < b.name ? -1 : 1;
|
|
27540
|
-
}
|
|
27541
|
-
/**
|
|
27542
|
-
* This function should not exist because it is megamorphic and only mostly correct.
|
|
27543
|
-
*
|
|
27544
|
-
* See call site for more info.
|
|
27545
|
-
*/
|
|
27546
|
-
function isDirectiveDefHack(obj) {
|
|
27547
|
-
return obj.type !== undefined && obj.declaredInputs !== undefined &&
|
|
27548
|
-
obj.findHostDirectiveDefs !== undefined;
|
|
27549
|
-
}
|
|
27550
|
-
/**
|
|
27551
|
-
* Retrieve the component `LView` from component/element.
|
|
27552
|
-
*
|
|
27553
|
-
* NOTE: `LView` is a private and should not be leaked outside.
|
|
27554
|
-
* Don't export this method to `ng.*` on window.
|
|
27555
|
-
*
|
|
27556
|
-
* @param target DOM element or component instance for which to retrieve the LView.
|
|
27557
|
-
*/
|
|
27558
|
-
function getComponentLView(target) {
|
|
27559
|
-
const lContext = getLContext(target);
|
|
27560
|
-
const nodeIndx = lContext.nodeIndex;
|
|
27561
|
-
const lView = lContext.lView;
|
|
27562
|
-
ngDevMode && assertLView(lView);
|
|
27563
|
-
const componentLView = lView[nodeIndx];
|
|
27564
|
-
ngDevMode && assertLView(componentLView);
|
|
27565
|
-
return componentLView;
|
|
27566
|
-
}
|
|
27567
|
-
/** Asserts that a value is a DOM Element. */
|
|
27568
|
-
function assertDomElement(value) {
|
|
27569
|
-
if (typeof Element !== 'undefined' && !(value instanceof Element)) {
|
|
27570
|
-
throw new Error('Expecting instance of DOM Element');
|
|
27571
|
-
}
|
|
27572
|
-
}
|
|
27573
|
-
/**
|
|
27574
|
-
* A directive definition holds additional metadata using bitwise flags to indicate
|
|
27575
|
-
* for example whether it is signal based.
|
|
27576
|
-
*
|
|
27577
|
-
* This information needs to be separate from the `publicName -> minifiedName`
|
|
27578
|
-
* mappings for backwards compatibility.
|
|
27579
|
-
*/
|
|
27580
|
-
function extractInputDebugMetadata(inputs) {
|
|
27581
|
-
const res = {};
|
|
27582
|
-
for (const key in inputs) {
|
|
27583
|
-
if (!inputs.hasOwnProperty(key)) {
|
|
27584
|
-
continue;
|
|
27585
|
-
}
|
|
27586
|
-
const value = inputs[key];
|
|
27587
|
-
if (value === undefined) {
|
|
27588
|
-
continue;
|
|
27589
|
-
}
|
|
27590
|
-
let minifiedName;
|
|
27591
|
-
if (Array.isArray(value)) {
|
|
27592
|
-
minifiedName = value[0];
|
|
27593
|
-
// flags are not used for now.
|
|
27594
|
-
// TODO: Consider exposing flag information in discovery.
|
|
27595
|
-
}
|
|
27596
|
-
else {
|
|
27597
|
-
minifiedName = value;
|
|
27598
|
-
}
|
|
27599
|
-
res[key] = minifiedName;
|
|
27600
|
-
}
|
|
27601
|
-
return res;
|
|
27602
|
-
}
|
|
27603
|
-
|
|
27604
27775
|
/**
|
|
27605
27776
|
* Bindings for pure functions are stored after regular bindings.
|
|
27606
27777
|
*
|
|
@@ -29570,7 +29741,7 @@ class Version {
|
|
|
29570
29741
|
/**
|
|
29571
29742
|
* @publicApi
|
|
29572
29743
|
*/
|
|
29573
|
-
const VERSION = new Version('17.3.
|
|
29744
|
+
const VERSION = new Version('17.3.1');
|
|
29574
29745
|
|
|
29575
29746
|
class Console {
|
|
29576
29747
|
log(message) {
|
|
@@ -29590,14 +29761,6 @@ class Console {
|
|
|
29590
29761
|
args: [{ providedIn: 'platform' }]
|
|
29591
29762
|
}], null, null); })();
|
|
29592
29763
|
|
|
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
29764
|
/**
|
|
29602
29765
|
* These are the data structures that our framework injector profiler will fill with data in order
|
|
29603
29766
|
* to support DI debugging APIs.
|
|
@@ -30415,7 +30578,7 @@ const globalUtilsFunctions = {
|
|
|
30415
30578
|
'ɵgetInjectorMetadata': getInjectorMetadata,
|
|
30416
30579
|
'ɵsetProfiler': setProfiler,
|
|
30417
30580
|
'getDirectiveMetadata': getDirectiveMetadata$1,
|
|
30418
|
-
'getComponent': getComponent,
|
|
30581
|
+
'getComponent': getComponent$1,
|
|
30419
30582
|
'getContext': getContext,
|
|
30420
30583
|
'getListeners': getListeners,
|
|
30421
30584
|
'getOwningComponent': getOwningComponent,
|
|
@@ -31229,6 +31392,10 @@ class ApplicationRef {
|
|
|
31229
31392
|
* detection pass during which all change detection must complete.
|
|
31230
31393
|
*/
|
|
31231
31394
|
tick() {
|
|
31395
|
+
this._tick(true);
|
|
31396
|
+
}
|
|
31397
|
+
/** @internal */
|
|
31398
|
+
_tick(refreshViews) {
|
|
31232
31399
|
(typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
|
|
31233
31400
|
if (this._runningTick) {
|
|
31234
31401
|
throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, ngDevMode && 'ApplicationRef.tick is called recursively');
|
|
@@ -31236,7 +31403,7 @@ class ApplicationRef {
|
|
|
31236
31403
|
const prevConsumer = setActiveConsumer$1(null);
|
|
31237
31404
|
try {
|
|
31238
31405
|
this._runningTick = true;
|
|
31239
|
-
this.detectChangesInAttachedViews();
|
|
31406
|
+
this.detectChangesInAttachedViews(refreshViews);
|
|
31240
31407
|
if ((typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
31241
31408
|
for (let view of this._views) {
|
|
31242
31409
|
view.checkNoChanges();
|
|
@@ -31253,7 +31420,7 @@ class ApplicationRef {
|
|
|
31253
31420
|
setActiveConsumer$1(prevConsumer);
|
|
31254
31421
|
}
|
|
31255
31422
|
}
|
|
31256
|
-
detectChangesInAttachedViews() {
|
|
31423
|
+
detectChangesInAttachedViews(refreshViews) {
|
|
31257
31424
|
let runs = 0;
|
|
31258
31425
|
const afterRenderEffectManager = this.afterRenderEffectManager;
|
|
31259
31426
|
while (true) {
|
|
@@ -31262,10 +31429,12 @@ class ApplicationRef {
|
|
|
31262
31429
|
'Infinite change detection while refreshing application views. ' +
|
|
31263
31430
|
'Ensure afterRender or queueStateUpdate hooks are not continuously causing updates.');
|
|
31264
31431
|
}
|
|
31265
|
-
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31432
|
+
if (refreshViews) {
|
|
31433
|
+
const isFirstPass = runs === 0;
|
|
31434
|
+
this.beforeRender.next(isFirstPass);
|
|
31435
|
+
for (let { _lView, notifyErrorHandler } of this._views) {
|
|
31436
|
+
detectChangesInViewIfRequired(_lView, isFirstPass, notifyErrorHandler);
|
|
31437
|
+
}
|
|
31269
31438
|
}
|
|
31270
31439
|
runs++;
|
|
31271
31440
|
afterRenderEffectManager.executeInternalCallbacks();
|
|
@@ -31412,9 +31581,7 @@ function detectChangesInViewIfRequired(lView, isFirstPass, notifyErrorHandler) {
|
|
|
31412
31581
|
detectChangesInView(lView, notifyErrorHandler, isFirstPass);
|
|
31413
31582
|
}
|
|
31414
31583
|
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 */));
|
|
31584
|
+
return requiresRefreshOrTraversal(view);
|
|
31418
31585
|
}
|
|
31419
31586
|
function detectChangesInView(lView, notifyErrorHandler, isFirstPass) {
|
|
31420
31587
|
let mode;
|
|
@@ -32451,7 +32618,7 @@ class DebugNode {
|
|
|
32451
32618
|
get componentInstance() {
|
|
32452
32619
|
const nativeElement = this.nativeNode;
|
|
32453
32620
|
return nativeElement &&
|
|
32454
|
-
(getComponent(nativeElement) || getOwningComponent(nativeElement));
|
|
32621
|
+
(getComponent$1(nativeElement) || getOwningComponent(nativeElement));
|
|
32455
32622
|
}
|
|
32456
32623
|
/**
|
|
32457
32624
|
* An object that provides parent context for this element. Often an ancestor component instance
|
|
@@ -32462,7 +32629,7 @@ class DebugNode {
|
|
|
32462
32629
|
* of heroes"`.
|
|
32463
32630
|
*/
|
|
32464
32631
|
get context() {
|
|
32465
|
-
return getComponent(this.nativeNode) || getContext(this.nativeNode);
|
|
32632
|
+
return getComponent$1(this.nativeNode) || getContext(this.nativeNode);
|
|
32466
32633
|
}
|
|
32467
32634
|
/**
|
|
32468
32635
|
* The callbacks attached to the component's @Output properties and/or the element's event
|
|
@@ -34833,10 +35000,15 @@ class ChangeDetectionSchedulerImpl {
|
|
|
34833
35000
|
this.appRef = inject(ApplicationRef);
|
|
34834
35001
|
this.taskService = inject(PendingTasks);
|
|
34835
35002
|
this.pendingRenderTaskId = null;
|
|
35003
|
+
this.shouldRefreshViews = false;
|
|
34836
35004
|
}
|
|
34837
|
-
notify() {
|
|
34838
|
-
|
|
35005
|
+
notify(type = 0 /* NotificationType.RefreshViews */) {
|
|
35006
|
+
// When the only source of notification is an afterRender hook will skip straight to the hooks
|
|
35007
|
+
// rather than refreshing views in ApplicationRef.tick
|
|
35008
|
+
this.shouldRefreshViews ||= type === 0 /* NotificationType.RefreshViews */;
|
|
35009
|
+
if (this.pendingRenderTaskId !== null) {
|
|
34839
35010
|
return;
|
|
35011
|
+
}
|
|
34840
35012
|
this.pendingRenderTaskId = this.taskService.add();
|
|
34841
35013
|
this.raceTimeoutAndRequestAnimationFrame();
|
|
34842
35014
|
}
|
|
@@ -34874,10 +35046,11 @@ class ChangeDetectionSchedulerImpl {
|
|
|
34874
35046
|
tick() {
|
|
34875
35047
|
try {
|
|
34876
35048
|
if (!this.appRef.destroyed) {
|
|
34877
|
-
this.appRef.
|
|
35049
|
+
this.appRef._tick(this.shouldRefreshViews);
|
|
34878
35050
|
}
|
|
34879
35051
|
}
|
|
34880
35052
|
finally {
|
|
35053
|
+
this.shouldRefreshViews = false;
|
|
34881
35054
|
// If this is the last task, the service will synchronously emit a stable notification. If
|
|
34882
35055
|
// there is a subscriber that then acts in a way that tries to notify the scheduler again,
|
|
34883
35056
|
// we need to be able to respond to schedule a new change detection. Therefore, we should
|
|
@@ -34939,6 +35112,226 @@ function getDeferBlocks(lView, deferBlocks) {
|
|
|
34939
35112
|
}
|
|
34940
35113
|
}
|
|
34941
35114
|
|
|
35115
|
+
/**
|
|
35116
|
+
* Indicates whether the hydration-related code was added,
|
|
35117
|
+
* prevents adding it multiple times.
|
|
35118
|
+
*/
|
|
35119
|
+
let isHydrationSupportEnabled = false;
|
|
35120
|
+
/**
|
|
35121
|
+
* Indicates whether support for hydrating i18n blocks is enabled.
|
|
35122
|
+
*/
|
|
35123
|
+
let _isI18nHydrationSupportEnabled = false;
|
|
35124
|
+
/**
|
|
35125
|
+
* Defines a period of time that Angular waits for the `ApplicationRef.isStable` to emit `true`.
|
|
35126
|
+
* If there was no event with the `true` value during this time, Angular reports a warning.
|
|
35127
|
+
*/
|
|
35128
|
+
const APPLICATION_IS_STABLE_TIMEOUT = 10_000;
|
|
35129
|
+
/**
|
|
35130
|
+
* Brings the necessary hydration code in tree-shakable manner.
|
|
35131
|
+
* The code is only present when the `provideClientHydration` is
|
|
35132
|
+
* invoked. Otherwise, this code is tree-shaken away during the
|
|
35133
|
+
* build optimization step.
|
|
35134
|
+
*
|
|
35135
|
+
* This technique allows us to swap implementations of methods so
|
|
35136
|
+
* tree shaking works appropriately when hydration is disabled or
|
|
35137
|
+
* enabled. It brings in the appropriate version of the method that
|
|
35138
|
+
* supports hydration only when enabled.
|
|
35139
|
+
*/
|
|
35140
|
+
function enableHydrationRuntimeSupport() {
|
|
35141
|
+
if (!isHydrationSupportEnabled) {
|
|
35142
|
+
isHydrationSupportEnabled = true;
|
|
35143
|
+
enableRetrieveHydrationInfoImpl();
|
|
35144
|
+
enableLocateOrCreateElementNodeImpl();
|
|
35145
|
+
enableLocateOrCreateTextNodeImpl();
|
|
35146
|
+
enableLocateOrCreateElementContainerNodeImpl();
|
|
35147
|
+
enableLocateOrCreateContainerAnchorImpl();
|
|
35148
|
+
enableLocateOrCreateContainerRefImpl();
|
|
35149
|
+
enableFindMatchingDehydratedViewImpl();
|
|
35150
|
+
enableApplyRootElementTransformImpl();
|
|
35151
|
+
enableLocateOrCreateI18nNodeImpl();
|
|
35152
|
+
}
|
|
35153
|
+
}
|
|
35154
|
+
/**
|
|
35155
|
+
* Outputs a message with hydration stats into a console.
|
|
35156
|
+
*/
|
|
35157
|
+
function printHydrationStats(injector) {
|
|
35158
|
+
const console = injector.get(Console);
|
|
35159
|
+
const message = `Angular hydrated ${ngDevMode.hydratedComponents} component(s) ` +
|
|
35160
|
+
`and ${ngDevMode.hydratedNodes} node(s), ` +
|
|
35161
|
+
`${ngDevMode.componentsSkippedHydration} component(s) were skipped. ` +
|
|
35162
|
+
`Learn more at https://angular.io/guide/hydration.`;
|
|
35163
|
+
// tslint:disable-next-line:no-console
|
|
35164
|
+
console.log(message);
|
|
35165
|
+
}
|
|
35166
|
+
/**
|
|
35167
|
+
* Returns a Promise that is resolved when an application becomes stable.
|
|
35168
|
+
*/
|
|
35169
|
+
function whenStableWithTimeout(appRef, injector) {
|
|
35170
|
+
const whenStablePromise = whenStable(appRef);
|
|
35171
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35172
|
+
const timeoutTime = APPLICATION_IS_STABLE_TIMEOUT;
|
|
35173
|
+
const console = injector.get(Console);
|
|
35174
|
+
const ngZone = injector.get(NgZone);
|
|
35175
|
+
// The following call should not and does not prevent the app to become stable
|
|
35176
|
+
// We cannot use RxJS timer here because the app would remain unstable.
|
|
35177
|
+
// This also avoids an extra change detection cycle.
|
|
35178
|
+
const timeoutId = ngZone.runOutsideAngular(() => {
|
|
35179
|
+
return setTimeout(() => logWarningOnStableTimedout(timeoutTime, console), timeoutTime);
|
|
35180
|
+
});
|
|
35181
|
+
whenStablePromise.finally(() => clearTimeout(timeoutId));
|
|
35182
|
+
}
|
|
35183
|
+
return whenStablePromise;
|
|
35184
|
+
}
|
|
35185
|
+
/**
|
|
35186
|
+
* Returns a set of providers required to setup hydration support
|
|
35187
|
+
* for an application that is server side rendered. This function is
|
|
35188
|
+
* included into the `provideClientHydration` public API function from
|
|
35189
|
+
* the `platform-browser` package.
|
|
35190
|
+
*
|
|
35191
|
+
* The function sets up an internal flag that would be recognized during
|
|
35192
|
+
* the server side rendering time as well, so there is no need to
|
|
35193
|
+
* configure or change anything in NgUniversal to enable the feature.
|
|
35194
|
+
*/
|
|
35195
|
+
function withDomHydration() {
|
|
35196
|
+
return makeEnvironmentProviders([
|
|
35197
|
+
{
|
|
35198
|
+
provide: IS_HYDRATION_DOM_REUSE_ENABLED,
|
|
35199
|
+
useFactory: () => {
|
|
35200
|
+
let isEnabled = true;
|
|
35201
|
+
if (isPlatformBrowser()) {
|
|
35202
|
+
// On the client, verify that the server response contains
|
|
35203
|
+
// hydration annotations. Otherwise, keep hydration disabled.
|
|
35204
|
+
const transferState = inject(TransferState, { optional: true });
|
|
35205
|
+
isEnabled = !!transferState?.get(NGH_DATA_KEY, null);
|
|
35206
|
+
if (!isEnabled && (typeof ngDevMode !== 'undefined' && ngDevMode)) {
|
|
35207
|
+
const console = inject(Console);
|
|
35208
|
+
const message = formatRuntimeError(-505 /* RuntimeErrorCode.MISSING_HYDRATION_ANNOTATIONS */, 'Angular hydration was requested on the client, but there was no ' +
|
|
35209
|
+
'serialized information present in the server response, ' +
|
|
35210
|
+
'thus hydration was not enabled. ' +
|
|
35211
|
+
'Make sure the `provideClientHydration()` is included into the list ' +
|
|
35212
|
+
'of providers in the server part of the application configuration.');
|
|
35213
|
+
// tslint:disable-next-line:no-console
|
|
35214
|
+
console.warn(message);
|
|
35215
|
+
}
|
|
35216
|
+
}
|
|
35217
|
+
if (isEnabled) {
|
|
35218
|
+
performanceMarkFeature('NgHydration');
|
|
35219
|
+
}
|
|
35220
|
+
return isEnabled;
|
|
35221
|
+
},
|
|
35222
|
+
},
|
|
35223
|
+
{
|
|
35224
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
35225
|
+
useValue: () => {
|
|
35226
|
+
_isI18nHydrationSupportEnabled = !!inject(IS_I18N_HYDRATION_ENABLED, { optional: true });
|
|
35227
|
+
// Since this function is used across both server and client,
|
|
35228
|
+
// make sure that the runtime code is only added when invoked
|
|
35229
|
+
// on the client. Moving forward, the `isPlatformBrowser` check should
|
|
35230
|
+
// be replaced with a tree-shakable alternative (e.g. `isServer`
|
|
35231
|
+
// flag).
|
|
35232
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35233
|
+
verifySsrContentsIntegrity();
|
|
35234
|
+
enableHydrationRuntimeSupport();
|
|
35235
|
+
}
|
|
35236
|
+
},
|
|
35237
|
+
multi: true,
|
|
35238
|
+
},
|
|
35239
|
+
{
|
|
35240
|
+
provide: PRESERVE_HOST_CONTENT,
|
|
35241
|
+
useFactory: () => {
|
|
35242
|
+
// Preserve host element content only in a browser
|
|
35243
|
+
// environment and when hydration is configured properly.
|
|
35244
|
+
// On a server, an application is rendered from scratch,
|
|
35245
|
+
// so the host content needs to be empty.
|
|
35246
|
+
return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
|
|
35247
|
+
}
|
|
35248
|
+
},
|
|
35249
|
+
{
|
|
35250
|
+
provide: APP_BOOTSTRAP_LISTENER,
|
|
35251
|
+
useFactory: () => {
|
|
35252
|
+
if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
|
|
35253
|
+
const appRef = inject(ApplicationRef);
|
|
35254
|
+
const injector = inject(Injector);
|
|
35255
|
+
return () => {
|
|
35256
|
+
// Wait until an app becomes stable and cleanup all views that
|
|
35257
|
+
// were not claimed during the application bootstrap process.
|
|
35258
|
+
// The timing is similar to when we start the serialization process
|
|
35259
|
+
// on the server.
|
|
35260
|
+
//
|
|
35261
|
+
// Note: the cleanup task *MUST* be scheduled within the Angular zone
|
|
35262
|
+
// to ensure that change detection is properly run afterward.
|
|
35263
|
+
whenStableWithTimeout(appRef, injector).then(() => {
|
|
35264
|
+
NgZone.assertInAngularZone();
|
|
35265
|
+
cleanupDehydratedViews(appRef);
|
|
35266
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
35267
|
+
printHydrationStats(injector);
|
|
35268
|
+
}
|
|
35269
|
+
});
|
|
35270
|
+
};
|
|
35271
|
+
}
|
|
35272
|
+
return () => { }; // noop
|
|
35273
|
+
},
|
|
35274
|
+
multi: true,
|
|
35275
|
+
}
|
|
35276
|
+
]);
|
|
35277
|
+
}
|
|
35278
|
+
/**
|
|
35279
|
+
* Returns a set of providers required to setup support for i18n hydration.
|
|
35280
|
+
* Requires hydration to be enabled separately.
|
|
35281
|
+
*/
|
|
35282
|
+
function withI18nHydration() {
|
|
35283
|
+
return makeEnvironmentProviders([
|
|
35284
|
+
{
|
|
35285
|
+
provide: IS_I18N_HYDRATION_ENABLED,
|
|
35286
|
+
useValue: true,
|
|
35287
|
+
},
|
|
35288
|
+
]);
|
|
35289
|
+
}
|
|
35290
|
+
/**
|
|
35291
|
+
* Returns whether i18n hydration support is enabled.
|
|
35292
|
+
*/
|
|
35293
|
+
function isI18nHydrationSupportEnabled() {
|
|
35294
|
+
return _isI18nHydrationSupportEnabled;
|
|
35295
|
+
}
|
|
35296
|
+
/**
|
|
35297
|
+
*
|
|
35298
|
+
* @param time The time in ms until the stable timedout warning message is logged
|
|
35299
|
+
*/
|
|
35300
|
+
function logWarningOnStableTimedout(time, console) {
|
|
35301
|
+
const message = `Angular hydration expected the ApplicationRef.isStable() to emit \`true\`, but it ` +
|
|
35302
|
+
`didn't happen within ${time}ms. Angular hydration logic depends on the application becoming stable ` +
|
|
35303
|
+
`as a signal to complete hydration process.`;
|
|
35304
|
+
console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
|
|
35305
|
+
}
|
|
35306
|
+
/**
|
|
35307
|
+
* Verifies whether the DOM contains a special marker added during SSR time to make sure
|
|
35308
|
+
* there is no SSR'ed contents transformations happen after SSR is completed. Typically that
|
|
35309
|
+
* happens either by CDN or during the build process as an optimization to remove comment nodes.
|
|
35310
|
+
* Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
|
|
35311
|
+
* When this special marker is *not* present - throw an error and do not proceed with hydration,
|
|
35312
|
+
* since it will not be able to function correctly.
|
|
35313
|
+
*
|
|
35314
|
+
* Note: this function is invoked only on the client, so it's safe to use DOM APIs.
|
|
35315
|
+
*/
|
|
35316
|
+
function verifySsrContentsIntegrity() {
|
|
35317
|
+
const doc = getDocument();
|
|
35318
|
+
let hydrationMarker;
|
|
35319
|
+
for (const node of doc.body.childNodes) {
|
|
35320
|
+
if (node.nodeType === Node.COMMENT_NODE &&
|
|
35321
|
+
node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
|
|
35322
|
+
hydrationMarker = node;
|
|
35323
|
+
break;
|
|
35324
|
+
}
|
|
35325
|
+
}
|
|
35326
|
+
if (!hydrationMarker) {
|
|
35327
|
+
throw new RuntimeError(-507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode &&
|
|
35328
|
+
'Angular hydration logic detected that HTML content of this page was modified after it ' +
|
|
35329
|
+
'was produced during server side rendering. Make sure that there are no optimizations ' +
|
|
35330
|
+
'that remove comment nodes from HTML enabled on your CDN. Angular hydration ' +
|
|
35331
|
+
'relies on HTML produced by the server, including whitespaces and comment nodes.');
|
|
35332
|
+
}
|
|
35333
|
+
}
|
|
35334
|
+
|
|
34942
35335
|
/**
|
|
34943
35336
|
* A collection that tracks all serialized views (`ngh` DOM annotations)
|
|
34944
35337
|
* to avoid duplication. An attempt to add a duplicate view results in the
|
|
@@ -35396,7 +35789,8 @@ function componentUsesShadowDomEncapsulation(lView) {
|
|
|
35396
35789
|
*/
|
|
35397
35790
|
function annotateHostElementForHydration(element, lView, context) {
|
|
35398
35791
|
const renderer = lView[RENDERER];
|
|
35399
|
-
if (hasI18n(lView)
|
|
35792
|
+
if ((hasI18n(lView) && !isI18nHydrationSupportEnabled()) ||
|
|
35793
|
+
componentUsesShadowDomEncapsulation(lView)) {
|
|
35400
35794
|
// Attach the skip hydration attribute if this component:
|
|
35401
35795
|
// - either has i18n blocks, since hydrating such blocks is not yet supported
|
|
35402
35796
|
// - or uses ShadowDom view encapsulation, since Domino doesn't support
|
|
@@ -35443,202 +35837,6 @@ function isContentProjectedNode(tNode) {
|
|
|
35443
35837
|
return false;
|
|
35444
35838
|
}
|
|
35445
35839
|
|
|
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
35840
|
/**
|
|
35643
35841
|
* Queue a state update to be performed asynchronously.
|
|
35644
35842
|
*
|
|
@@ -35664,9 +35862,7 @@ function queueStateUpdate(callback, options) {
|
|
|
35664
35862
|
callback();
|
|
35665
35863
|
};
|
|
35666
35864
|
internalAfterNextRender(runCallbackOnce, { injector, runOnServer: true });
|
|
35667
|
-
queueMicrotask(
|
|
35668
|
-
runCallbackOnce();
|
|
35669
|
-
});
|
|
35865
|
+
queueMicrotask(runCallbackOnce);
|
|
35670
35866
|
}
|
|
35671
35867
|
|
|
35672
35868
|
/**
|
|
@@ -36176,5 +36372,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
36176
36372
|
* Generated bundle index. Do not edit.
|
|
36177
36373
|
*/
|
|
36178
36374
|
|
|
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 };
|
|
36375
|
+
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
36376
|
//# sourceMappingURL=core.mjs.map
|