@angular/core 14.0.0 → 14.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/src/application_ref.mjs +10 -24
- package/esm2020/src/change_detection/differs/default_iterable_differ.mjs +3 -5
- package/esm2020/src/change_detection/differs/default_keyvalue_differ.mjs +3 -5
- package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -5
- package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +2 -5
- package/esm2020/src/di/injector_compatibility.mjs +4 -9
- package/esm2020/src/di/provider_collection.mjs +1 -1
- package/esm2020/src/error_handler.mjs +4 -7
- package/esm2020/src/errors.mjs +6 -3
- package/esm2020/src/render3/component.mjs +9 -9
- package/esm2020/src/render3/definition.mjs +4 -4
- package/esm2020/src/render3/features/inherit_definition_feature.mjs +3 -5
- package/esm2020/src/render3/features/standalone_feature.mjs +4 -4
- package/esm2020/src/render3/instructions/all.mjs +2 -2
- package/esm2020/src/render3/instructions/element.mjs +3 -79
- package/esm2020/src/render3/instructions/element_validation.mjs +264 -0
- package/esm2020/src/render3/instructions/shared.mjs +7 -184
- package/esm2020/src/render3/interfaces/definition.mjs +1 -1
- package/esm2020/src/render3/jit/directive.mjs +20 -3
- package/esm2020/src/render3/jit/module.mjs +3 -2
- package/esm2020/src/render3/pipe.mjs +20 -6
- package/esm2020/src/render3/state.mjs +1 -3
- package/esm2020/src/render3/view_ref.mjs +3 -5
- package/esm2020/src/sanitization/sanitization.mjs +4 -9
- package/esm2020/src/util/errors.mjs +1 -8
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/logger.mjs +3 -3
- package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
- package/esm2020/testing/src/r3_test_bed_compiler.mjs +30 -25
- package/fesm2015/core.mjs +636 -644
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +633 -630
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +637 -645
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +634 -631
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +7 -6
- package/package.json +1 -1
- package/testing/index.d.ts +1 -1
package/fesm2015/testing.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v14.0.
|
|
2
|
+
* @license Angular v14.0.3
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -1843,9 +1843,12 @@ function formatRuntimeError(code, message) {
|
|
|
1843
1843
|
// Error code might be a negative number, which is a special marker that instructs the logic to
|
|
1844
1844
|
// generate a link to the error details page on angular.io.
|
|
1845
1845
|
const fullCode = `NG0${Math.abs(code)}`;
|
|
1846
|
-
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
1846
|
+
let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
|
|
1847
1847
|
if (ngDevMode && code < 0) {
|
|
1848
|
-
|
|
1848
|
+
const addPeriodSeparator = !errorMessage.match(/[.,;!?]$/);
|
|
1849
|
+
const separator = addPeriodSeparator ? '.' : '';
|
|
1850
|
+
errorMessage =
|
|
1851
|
+
`${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
|
|
1849
1852
|
}
|
|
1850
1853
|
return errorMessage;
|
|
1851
1854
|
}
|
|
@@ -2043,10 +2046,8 @@ function setCurrentInjector(injector) {
|
|
|
2043
2046
|
}
|
|
2044
2047
|
function injectInjectorOnly(token, flags = InjectFlags.Default) {
|
|
2045
2048
|
if (_currentInjector === undefined) {
|
|
2046
|
-
|
|
2047
|
-
`inject() must be called from an injection context (a constructor, a factory function or a field initializer)`
|
|
2048
|
-
'';
|
|
2049
|
-
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
|
|
2049
|
+
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
|
|
2050
|
+
`inject() must be called from an injection context (a constructor, a factory function or a field initializer)`);
|
|
2050
2051
|
}
|
|
2051
2052
|
else if (_currentInjector === null) {
|
|
2052
2053
|
return injectRootLimpMode(token, undefined, flags);
|
|
@@ -2152,10 +2153,7 @@ function injectArgs(types) {
|
|
|
2152
2153
|
const arg = resolveForwardRef(types[i]);
|
|
2153
2154
|
if (Array.isArray(arg)) {
|
|
2154
2155
|
if (arg.length === 0) {
|
|
2155
|
-
|
|
2156
|
-
'Arguments array must have arguments.' :
|
|
2157
|
-
'';
|
|
2158
|
-
throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, errorMessage);
|
|
2156
|
+
throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
|
|
2159
2157
|
}
|
|
2160
2158
|
let type = undefined;
|
|
2161
2159
|
let flags = InjectFlags.Default;
|
|
@@ -2471,7 +2469,8 @@ const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafe
|
|
|
2471
2469
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2472
2470
|
* found in the LICENSE file at https://angular.io/license
|
|
2473
2471
|
*/
|
|
2474
|
-
|
|
2472
|
+
/** Counter used to generate unique IDs for component definitions. */
|
|
2473
|
+
let componentDefCount = 0;
|
|
2475
2474
|
/**
|
|
2476
2475
|
* Create a component definition object.
|
|
2477
2476
|
*
|
|
@@ -2524,7 +2523,7 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
2524
2523
|
features: componentDefinition.features || null,
|
|
2525
2524
|
data: componentDefinition.data || {},
|
|
2526
2525
|
encapsulation: componentDefinition.encapsulation || ViewEncapsulation.Emulated,
|
|
2527
|
-
id:
|
|
2526
|
+
id: `c${componentDefCount++}`,
|
|
2528
2527
|
styles: componentDefinition.styles || EMPTY_ARRAY,
|
|
2529
2528
|
_: null,
|
|
2530
2529
|
setInput: null,
|
|
@@ -2533,7 +2532,6 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
2533
2532
|
};
|
|
2534
2533
|
const dependencies = componentDefinition.dependencies;
|
|
2535
2534
|
const feature = componentDefinition.features;
|
|
2536
|
-
def.id += _renderCompCount++;
|
|
2537
2535
|
def.inputs = invertObject(componentDefinition.inputs, declaredInputs),
|
|
2538
2536
|
def.outputs = invertObject(componentDefinition.outputs),
|
|
2539
2537
|
feature && feature.forEach((fn) => fn(def));
|
|
@@ -3540,7 +3538,6 @@ function getLView() {
|
|
|
3540
3538
|
function getTView() {
|
|
3541
3539
|
return instructionState.lFrame.tView;
|
|
3542
3540
|
}
|
|
3543
|
-
// TODO(crisbeto): revert the @noinline once Closure issue is resolved.
|
|
3544
3541
|
/**
|
|
3545
3542
|
* Restores `contextViewData` to the given OpaqueViewState instance.
|
|
3546
3543
|
*
|
|
@@ -3552,7 +3549,6 @@ function getTView() {
|
|
|
3552
3549
|
* @returns Context of the restored OpaqueViewState instance.
|
|
3553
3550
|
*
|
|
3554
3551
|
* @codeGenApi
|
|
3555
|
-
* @noinline Disable inlining due to issue with Closure in listeners inside embedded views.
|
|
3556
3552
|
*/
|
|
3557
3553
|
function ɵɵrestoreView(viewToRestore) {
|
|
3558
3554
|
instructionState.lFrame.contextLView = viewToRestore;
|
|
@@ -6488,10 +6484,8 @@ function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
|
|
|
6488
6484
|
if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL" /* BypassType.ResourceUrl */)) {
|
|
6489
6485
|
return trustedScriptURLFromStringBypass(unwrapSafeValue(unsafeResourceUrl));
|
|
6490
6486
|
}
|
|
6491
|
-
|
|
6492
|
-
'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)'
|
|
6493
|
-
'';
|
|
6494
|
-
throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, errorMessage);
|
|
6487
|
+
throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, ngDevMode &&
|
|
6488
|
+
'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
|
|
6495
6489
|
}
|
|
6496
6490
|
/**
|
|
6497
6491
|
* A `script` sanitizer which only lets trusted javascript through.
|
|
@@ -6513,10 +6507,7 @@ function ɵɵsanitizeScript(unsafeScript) {
|
|
|
6513
6507
|
if (allowSanitizationBypassAndThrow(unsafeScript, "Script" /* BypassType.Script */)) {
|
|
6514
6508
|
return trustedScriptFromStringBypass(unwrapSafeValue(unsafeScript));
|
|
6515
6509
|
}
|
|
6516
|
-
|
|
6517
|
-
'unsafe value used in a script context' :
|
|
6518
|
-
'';
|
|
6519
|
-
throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, errorMessage);
|
|
6510
|
+
throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && 'unsafe value used in a script context');
|
|
6520
6511
|
}
|
|
6521
6512
|
/**
|
|
6522
6513
|
* A template tag function for promoting the associated constant literal to a
|
|
@@ -6623,6 +6614,155 @@ function getSanitizer() {
|
|
|
6623
6614
|
return lView && lView[SANITIZER];
|
|
6624
6615
|
}
|
|
6625
6616
|
|
|
6617
|
+
/**
|
|
6618
|
+
* @license
|
|
6619
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6620
|
+
*
|
|
6621
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6622
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6623
|
+
*/
|
|
6624
|
+
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
6625
|
+
function wrappedError(message, originalError) {
|
|
6626
|
+
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
6627
|
+
const error = Error(msg);
|
|
6628
|
+
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
6629
|
+
return error;
|
|
6630
|
+
}
|
|
6631
|
+
function getOriginalError(error) {
|
|
6632
|
+
return error[ERROR_ORIGINAL_ERROR];
|
|
6633
|
+
}
|
|
6634
|
+
|
|
6635
|
+
/**
|
|
6636
|
+
* @license
|
|
6637
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6638
|
+
*
|
|
6639
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6640
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6641
|
+
*/
|
|
6642
|
+
/**
|
|
6643
|
+
* Provides a hook for centralized exception handling.
|
|
6644
|
+
*
|
|
6645
|
+
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
6646
|
+
* intercept error handling, write a custom exception handler that replaces this default as
|
|
6647
|
+
* appropriate for your app.
|
|
6648
|
+
*
|
|
6649
|
+
* @usageNotes
|
|
6650
|
+
* ### Example
|
|
6651
|
+
*
|
|
6652
|
+
* ```
|
|
6653
|
+
* class MyErrorHandler implements ErrorHandler {
|
|
6654
|
+
* handleError(error) {
|
|
6655
|
+
* // do something with the exception
|
|
6656
|
+
* }
|
|
6657
|
+
* }
|
|
6658
|
+
*
|
|
6659
|
+
* @NgModule({
|
|
6660
|
+
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
6661
|
+
* })
|
|
6662
|
+
* class MyModule {}
|
|
6663
|
+
* ```
|
|
6664
|
+
*
|
|
6665
|
+
* @publicApi
|
|
6666
|
+
*/
|
|
6667
|
+
class ErrorHandler {
|
|
6668
|
+
constructor() {
|
|
6669
|
+
/**
|
|
6670
|
+
* @internal
|
|
6671
|
+
*/
|
|
6672
|
+
this._console = console;
|
|
6673
|
+
}
|
|
6674
|
+
handleError(error) {
|
|
6675
|
+
const originalError = this._findOriginalError(error);
|
|
6676
|
+
this._console.error('ERROR', error);
|
|
6677
|
+
if (originalError) {
|
|
6678
|
+
this._console.error('ORIGINAL ERROR', originalError);
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6681
|
+
/** @internal */
|
|
6682
|
+
_findOriginalError(error) {
|
|
6683
|
+
let e = error && getOriginalError(error);
|
|
6684
|
+
while (e && getOriginalError(e)) {
|
|
6685
|
+
e = getOriginalError(e);
|
|
6686
|
+
}
|
|
6687
|
+
return e || null;
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6691
|
+
/**
|
|
6692
|
+
* @license
|
|
6693
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6694
|
+
*
|
|
6695
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6696
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6697
|
+
*/
|
|
6698
|
+
/**
|
|
6699
|
+
* Disallowed strings in the comment.
|
|
6700
|
+
*
|
|
6701
|
+
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6702
|
+
*/
|
|
6703
|
+
const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
|
|
6704
|
+
/**
|
|
6705
|
+
* Delimiter in the disallowed strings which needs to be wrapped with zero with character.
|
|
6706
|
+
*/
|
|
6707
|
+
const COMMENT_DELIMITER = /(<|>)/;
|
|
6708
|
+
const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
|
|
6709
|
+
/**
|
|
6710
|
+
* Escape the content of comment strings so that it can be safely inserted into a comment node.
|
|
6711
|
+
*
|
|
6712
|
+
* The issue is that HTML does not specify any way to escape comment end text inside the comment.
|
|
6713
|
+
* Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
|
|
6714
|
+
* "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
|
|
6715
|
+
* can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
|
|
6716
|
+
*
|
|
6717
|
+
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6718
|
+
*
|
|
6719
|
+
* ```
|
|
6720
|
+
* div.innerHTML = div.innerHTML
|
|
6721
|
+
* ```
|
|
6722
|
+
*
|
|
6723
|
+
* One would expect that the above code would be safe to do, but it turns out that because comment
|
|
6724
|
+
* text is not escaped, the comment may contain text which will prematurely close the comment
|
|
6725
|
+
* opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
|
|
6726
|
+
* may contain such text and expect them to be safe.)
|
|
6727
|
+
*
|
|
6728
|
+
* This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
|
|
6729
|
+
* surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
|
|
6730
|
+
* comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
|
|
6731
|
+
* text it will render normally but it will not cause the HTML parser to close/open the comment.
|
|
6732
|
+
*
|
|
6733
|
+
* @param value text to make safe for comment node by escaping the comment open/close character
|
|
6734
|
+
* sequence.
|
|
6735
|
+
*/
|
|
6736
|
+
function escapeCommentText(value) {
|
|
6737
|
+
return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
|
|
6738
|
+
}
|
|
6739
|
+
|
|
6740
|
+
/**
|
|
6741
|
+
* @license
|
|
6742
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6743
|
+
*
|
|
6744
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6745
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6746
|
+
*/
|
|
6747
|
+
function normalizeDebugBindingName(name) {
|
|
6748
|
+
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
6749
|
+
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
6750
|
+
return `ng-reflect-${name}`;
|
|
6751
|
+
}
|
|
6752
|
+
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
|
6753
|
+
function camelCaseToDashCase(input) {
|
|
6754
|
+
return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
|
|
6755
|
+
}
|
|
6756
|
+
function normalizeDebugBindingValue(value) {
|
|
6757
|
+
try {
|
|
6758
|
+
// Limit the size of the value as otherwise the DOM just gets polluted.
|
|
6759
|
+
return value != null ? value.toString().slice(0, 30) : value;
|
|
6760
|
+
}
|
|
6761
|
+
catch (e) {
|
|
6762
|
+
return '[ERROR] Exception while trying to serialize the value';
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
|
|
6626
6766
|
/**
|
|
6627
6767
|
* @license
|
|
6628
6768
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -6977,217 +7117,27 @@ function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
|
|
|
6977
7117
|
directiveStartIndex++;
|
|
6978
7118
|
return lView.slice(directiveStartIndex, directiveEndIndex);
|
|
6979
7119
|
}
|
|
6980
|
-
function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
6981
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
6982
|
-
let directiveStartIndex = tNode.directiveStart;
|
|
6983
|
-
return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
|
|
6984
|
-
}
|
|
6985
|
-
/**
|
|
6986
|
-
* Returns a map of local references (local reference name => element or directive instance) that
|
|
6987
|
-
* exist on a given element.
|
|
6988
|
-
*/
|
|
6989
|
-
function discoverLocalRefs(lView, nodeIndex) {
|
|
6990
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
6991
|
-
if (tNode && tNode.localNames) {
|
|
6992
|
-
const result = {};
|
|
6993
|
-
let localIndex = tNode.index + 1;
|
|
6994
|
-
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
6995
|
-
result[tNode.localNames[i]] = lView[localIndex];
|
|
6996
|
-
localIndex++;
|
|
6997
|
-
}
|
|
6998
|
-
return result;
|
|
6999
|
-
}
|
|
7000
|
-
return null;
|
|
7001
|
-
}
|
|
7002
|
-
|
|
7003
|
-
/**
|
|
7004
|
-
* @license
|
|
7005
|
-
* Copyright Google LLC All Rights Reserved.
|
|
7006
|
-
*
|
|
7007
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7008
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7009
|
-
*/
|
|
7010
|
-
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
7011
|
-
const ERROR_LOGGER = 'ngErrorLogger';
|
|
7012
|
-
function wrappedError(message, originalError) {
|
|
7013
|
-
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
7014
|
-
const error = Error(msg);
|
|
7015
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
7016
|
-
return error;
|
|
7017
|
-
}
|
|
7018
|
-
function getOriginalError(error) {
|
|
7019
|
-
return error[ERROR_ORIGINAL_ERROR];
|
|
7020
|
-
}
|
|
7021
|
-
function getErrorLogger(error) {
|
|
7022
|
-
return error && error[ERROR_LOGGER] || defaultErrorLogger;
|
|
7023
|
-
}
|
|
7024
|
-
function defaultErrorLogger(console, ...values) {
|
|
7025
|
-
console.error(...values);
|
|
7026
|
-
}
|
|
7027
|
-
|
|
7028
|
-
/**
|
|
7029
|
-
* @license
|
|
7030
|
-
* Copyright Google LLC All Rights Reserved.
|
|
7031
|
-
*
|
|
7032
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7033
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7034
|
-
*/
|
|
7035
|
-
/**
|
|
7036
|
-
* Provides a hook for centralized exception handling.
|
|
7037
|
-
*
|
|
7038
|
-
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
7039
|
-
* intercept error handling, write a custom exception handler that replaces this default as
|
|
7040
|
-
* appropriate for your app.
|
|
7041
|
-
*
|
|
7042
|
-
* @usageNotes
|
|
7043
|
-
* ### Example
|
|
7044
|
-
*
|
|
7045
|
-
* ```
|
|
7046
|
-
* class MyErrorHandler implements ErrorHandler {
|
|
7047
|
-
* handleError(error) {
|
|
7048
|
-
* // do something with the exception
|
|
7049
|
-
* }
|
|
7050
|
-
* }
|
|
7051
|
-
*
|
|
7052
|
-
* @NgModule({
|
|
7053
|
-
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
7054
|
-
* })
|
|
7055
|
-
* class MyModule {}
|
|
7056
|
-
* ```
|
|
7057
|
-
*
|
|
7058
|
-
* @publicApi
|
|
7059
|
-
*/
|
|
7060
|
-
class ErrorHandler {
|
|
7061
|
-
constructor() {
|
|
7062
|
-
/**
|
|
7063
|
-
* @internal
|
|
7064
|
-
*/
|
|
7065
|
-
this._console = console;
|
|
7066
|
-
}
|
|
7067
|
-
handleError(error) {
|
|
7068
|
-
const originalError = this._findOriginalError(error);
|
|
7069
|
-
// Note: Browser consoles show the place from where console.error was called.
|
|
7070
|
-
// We can use this to give users additional information about the error.
|
|
7071
|
-
const errorLogger = getErrorLogger(error);
|
|
7072
|
-
errorLogger(this._console, `ERROR`, error);
|
|
7073
|
-
if (originalError) {
|
|
7074
|
-
errorLogger(this._console, `ORIGINAL ERROR`, originalError);
|
|
7075
|
-
}
|
|
7076
|
-
}
|
|
7077
|
-
/** @internal */
|
|
7078
|
-
_findOriginalError(error) {
|
|
7079
|
-
let e = error && getOriginalError(error);
|
|
7080
|
-
while (e && getOriginalError(e)) {
|
|
7081
|
-
e = getOriginalError(e);
|
|
7082
|
-
}
|
|
7083
|
-
return e || null;
|
|
7084
|
-
}
|
|
7085
|
-
}
|
|
7086
|
-
|
|
7087
|
-
/**
|
|
7088
|
-
* @license
|
|
7089
|
-
* Copyright Google LLC All Rights Reserved.
|
|
7090
|
-
*
|
|
7091
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7092
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7093
|
-
*/
|
|
7094
|
-
/**
|
|
7095
|
-
* Defines a schema that allows an NgModule to contain the following:
|
|
7096
|
-
* - Non-Angular elements named with dash case (`-`).
|
|
7097
|
-
* - Element properties named with dash case (`-`).
|
|
7098
|
-
* Dash case is the naming convention for custom elements.
|
|
7099
|
-
*
|
|
7100
|
-
* @publicApi
|
|
7101
|
-
*/
|
|
7102
|
-
const CUSTOM_ELEMENTS_SCHEMA = {
|
|
7103
|
-
name: 'custom-elements'
|
|
7104
|
-
};
|
|
7105
|
-
/**
|
|
7106
|
-
* Defines a schema that allows any property on any element.
|
|
7107
|
-
*
|
|
7108
|
-
* This schema allows you to ignore the errors related to any unknown elements or properties in a
|
|
7109
|
-
* template. The usage of this schema is generally discouraged because it prevents useful validation
|
|
7110
|
-
* and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
|
|
7111
|
-
*
|
|
7112
|
-
* @publicApi
|
|
7113
|
-
*/
|
|
7114
|
-
const NO_ERRORS_SCHEMA = {
|
|
7115
|
-
name: 'no-errors-schema'
|
|
7116
|
-
};
|
|
7117
|
-
|
|
7118
|
-
/**
|
|
7119
|
-
* @license
|
|
7120
|
-
* Copyright Google LLC All Rights Reserved.
|
|
7121
|
-
*
|
|
7122
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7123
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7124
|
-
*/
|
|
7125
|
-
/**
|
|
7126
|
-
* Disallowed strings in the comment.
|
|
7127
|
-
*
|
|
7128
|
-
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
7129
|
-
*/
|
|
7130
|
-
const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
|
|
7131
|
-
/**
|
|
7132
|
-
* Delimiter in the disallowed strings which needs to be wrapped with zero with character.
|
|
7133
|
-
*/
|
|
7134
|
-
const COMMENT_DELIMITER = /(<|>)/;
|
|
7135
|
-
const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
|
|
7136
|
-
/**
|
|
7137
|
-
* Escape the content of comment strings so that it can be safely inserted into a comment node.
|
|
7138
|
-
*
|
|
7139
|
-
* The issue is that HTML does not specify any way to escape comment end text inside the comment.
|
|
7140
|
-
* Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
|
|
7141
|
-
* "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
|
|
7142
|
-
* can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
|
|
7143
|
-
*
|
|
7144
|
-
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
7145
|
-
*
|
|
7146
|
-
* ```
|
|
7147
|
-
* div.innerHTML = div.innerHTML
|
|
7148
|
-
* ```
|
|
7149
|
-
*
|
|
7150
|
-
* One would expect that the above code would be safe to do, but it turns out that because comment
|
|
7151
|
-
* text is not escaped, the comment may contain text which will prematurely close the comment
|
|
7152
|
-
* opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
|
|
7153
|
-
* may contain such text and expect them to be safe.)
|
|
7154
|
-
*
|
|
7155
|
-
* This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
|
|
7156
|
-
* surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
|
|
7157
|
-
* comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
|
|
7158
|
-
* text it will render normally but it will not cause the HTML parser to close/open the comment.
|
|
7159
|
-
*
|
|
7160
|
-
* @param value text to make safe for comment node by escaping the comment open/close character
|
|
7161
|
-
* sequence.
|
|
7162
|
-
*/
|
|
7163
|
-
function escapeCommentText(value) {
|
|
7164
|
-
return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
|
|
7165
|
-
}
|
|
7166
|
-
|
|
7120
|
+
function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
7121
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
7122
|
+
let directiveStartIndex = tNode.directiveStart;
|
|
7123
|
+
return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
|
|
7124
|
+
}
|
|
7167
7125
|
/**
|
|
7168
|
-
*
|
|
7169
|
-
*
|
|
7170
|
-
*
|
|
7171
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7172
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7126
|
+
* Returns a map of local references (local reference name => element or directive instance) that
|
|
7127
|
+
* exist on a given element.
|
|
7173
7128
|
*/
|
|
7174
|
-
function
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
}
|
|
7183
|
-
|
|
7184
|
-
try {
|
|
7185
|
-
// Limit the size of the value as otherwise the DOM just gets polluted.
|
|
7186
|
-
return value != null ? value.toString().slice(0, 30) : value;
|
|
7187
|
-
}
|
|
7188
|
-
catch (e) {
|
|
7189
|
-
return '[ERROR] Exception while trying to serialize the value';
|
|
7129
|
+
function discoverLocalRefs(lView, nodeIndex) {
|
|
7130
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
7131
|
+
if (tNode && tNode.localNames) {
|
|
7132
|
+
const result = {};
|
|
7133
|
+
let localIndex = tNode.index + 1;
|
|
7134
|
+
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
7135
|
+
result[tNode.localNames[i]] = lView[localIndex];
|
|
7136
|
+
localIndex++;
|
|
7137
|
+
}
|
|
7138
|
+
return result;
|
|
7190
7139
|
}
|
|
7140
|
+
return null;
|
|
7191
7141
|
}
|
|
7192
7142
|
|
|
7193
7143
|
/**
|
|
@@ -10655,113 +10605,403 @@ class ReflectiveInjector_ {
|
|
|
10655
10605
|
return this.objs[i];
|
|
10656
10606
|
}
|
|
10657
10607
|
}
|
|
10658
|
-
return UNDEFINED;
|
|
10608
|
+
return UNDEFINED;
|
|
10609
|
+
}
|
|
10610
|
+
/** @internal */
|
|
10611
|
+
_throwOrNull(key, notFoundValue) {
|
|
10612
|
+
if (notFoundValue !== THROW_IF_NOT_FOUND) {
|
|
10613
|
+
return notFoundValue;
|
|
10614
|
+
}
|
|
10615
|
+
else {
|
|
10616
|
+
throw noProviderError(this, key);
|
|
10617
|
+
}
|
|
10618
|
+
}
|
|
10619
|
+
/** @internal */
|
|
10620
|
+
_getByKeySelf(key, notFoundValue) {
|
|
10621
|
+
const obj = this._getObjByKeyId(key.id);
|
|
10622
|
+
return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
|
|
10623
|
+
}
|
|
10624
|
+
/** @internal */
|
|
10625
|
+
_getByKeyDefault(key, notFoundValue, visibility) {
|
|
10626
|
+
let inj;
|
|
10627
|
+
if (visibility instanceof SkipSelf) {
|
|
10628
|
+
inj = this.parent;
|
|
10629
|
+
}
|
|
10630
|
+
else {
|
|
10631
|
+
inj = this;
|
|
10632
|
+
}
|
|
10633
|
+
while (inj instanceof ReflectiveInjector_) {
|
|
10634
|
+
const inj_ = inj;
|
|
10635
|
+
const obj = inj_._getObjByKeyId(key.id);
|
|
10636
|
+
if (obj !== UNDEFINED)
|
|
10637
|
+
return obj;
|
|
10638
|
+
inj = inj_.parent;
|
|
10639
|
+
}
|
|
10640
|
+
if (inj !== null) {
|
|
10641
|
+
return inj.get(key.token, notFoundValue);
|
|
10642
|
+
}
|
|
10643
|
+
else {
|
|
10644
|
+
return this._throwOrNull(key, notFoundValue);
|
|
10645
|
+
}
|
|
10646
|
+
}
|
|
10647
|
+
get displayName() {
|
|
10648
|
+
const providers = _mapProviders(this, (b) => ' "' + b.key.displayName + '" ')
|
|
10649
|
+
.join(', ');
|
|
10650
|
+
return `ReflectiveInjector(providers: [${providers}])`;
|
|
10651
|
+
}
|
|
10652
|
+
toString() {
|
|
10653
|
+
return this.displayName;
|
|
10654
|
+
}
|
|
10655
|
+
}
|
|
10656
|
+
ReflectiveInjector_.INJECTOR_KEY = ( /* @__PURE__ */ReflectiveKey.get(Injector));
|
|
10657
|
+
function _mapProviders(injector, fn) {
|
|
10658
|
+
const res = [];
|
|
10659
|
+
for (let i = 0; i < injector._providers.length; ++i) {
|
|
10660
|
+
res[i] = fn(injector.getProviderAtIndex(i));
|
|
10661
|
+
}
|
|
10662
|
+
return res;
|
|
10663
|
+
}
|
|
10664
|
+
|
|
10665
|
+
/**
|
|
10666
|
+
* @license
|
|
10667
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10668
|
+
*
|
|
10669
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10670
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10671
|
+
*/
|
|
10672
|
+
|
|
10673
|
+
/**
|
|
10674
|
+
* @license
|
|
10675
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10676
|
+
*
|
|
10677
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10678
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10679
|
+
*/
|
|
10680
|
+
|
|
10681
|
+
/**
|
|
10682
|
+
* @license
|
|
10683
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10684
|
+
*
|
|
10685
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10686
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10687
|
+
*/
|
|
10688
|
+
function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
|
|
10689
|
+
const lView = getLView();
|
|
10690
|
+
// Fall back to inject() if view hasn't been created. This situation can happen in tests
|
|
10691
|
+
// if inject utilities are used before bootstrapping.
|
|
10692
|
+
if (lView === null) {
|
|
10693
|
+
// Verify that we will not get into infinite loop.
|
|
10694
|
+
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
|
10695
|
+
return ɵɵinject(token, flags);
|
|
10696
|
+
}
|
|
10697
|
+
const tNode = getCurrentTNode();
|
|
10698
|
+
return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
10699
|
+
}
|
|
10700
|
+
/**
|
|
10701
|
+
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
10702
|
+
* particular class.
|
|
10703
|
+
*
|
|
10704
|
+
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
10705
|
+
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
10706
|
+
*
|
|
10707
|
+
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
10708
|
+
* and thus in the stack trace.
|
|
10709
|
+
*
|
|
10710
|
+
* @codeGenApi
|
|
10711
|
+
*/
|
|
10712
|
+
function ɵɵinvalidFactory() {
|
|
10713
|
+
const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
|
|
10714
|
+
throw new Error(msg);
|
|
10715
|
+
}
|
|
10716
|
+
|
|
10717
|
+
/**
|
|
10718
|
+
* @license
|
|
10719
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10720
|
+
*
|
|
10721
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10722
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10723
|
+
*/
|
|
10724
|
+
/**
|
|
10725
|
+
* Defines a schema that allows an NgModule to contain the following:
|
|
10726
|
+
* - Non-Angular elements named with dash case (`-`).
|
|
10727
|
+
* - Element properties named with dash case (`-`).
|
|
10728
|
+
* Dash case is the naming convention for custom elements.
|
|
10729
|
+
*
|
|
10730
|
+
* @publicApi
|
|
10731
|
+
*/
|
|
10732
|
+
const CUSTOM_ELEMENTS_SCHEMA = {
|
|
10733
|
+
name: 'custom-elements'
|
|
10734
|
+
};
|
|
10735
|
+
/**
|
|
10736
|
+
* Defines a schema that allows any property on any element.
|
|
10737
|
+
*
|
|
10738
|
+
* This schema allows you to ignore the errors related to any unknown elements or properties in a
|
|
10739
|
+
* template. The usage of this schema is generally discouraged because it prevents useful validation
|
|
10740
|
+
* and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
|
|
10741
|
+
*
|
|
10742
|
+
* @publicApi
|
|
10743
|
+
*/
|
|
10744
|
+
const NO_ERRORS_SCHEMA = {
|
|
10745
|
+
name: 'no-errors-schema'
|
|
10746
|
+
};
|
|
10747
|
+
|
|
10748
|
+
/**
|
|
10749
|
+
* @license
|
|
10750
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10751
|
+
*
|
|
10752
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10753
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10754
|
+
*/
|
|
10755
|
+
let shouldThrowErrorOnUnknownElement = false;
|
|
10756
|
+
/**
|
|
10757
|
+
* Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
|
|
10758
|
+
* instead of just logging the error.
|
|
10759
|
+
* (for AOT-compiled ones this check happens at build time).
|
|
10760
|
+
*/
|
|
10761
|
+
function ɵsetUnknownElementStrictMode(shouldThrow) {
|
|
10762
|
+
shouldThrowErrorOnUnknownElement = shouldThrow;
|
|
10763
|
+
}
|
|
10764
|
+
/**
|
|
10765
|
+
* Gets the current value of the strict mode.
|
|
10766
|
+
*/
|
|
10767
|
+
function ɵgetUnknownElementStrictMode() {
|
|
10768
|
+
return shouldThrowErrorOnUnknownElement;
|
|
10769
|
+
}
|
|
10770
|
+
let shouldThrowErrorOnUnknownProperty = false;
|
|
10771
|
+
/**
|
|
10772
|
+
* Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
|
|
10773
|
+
* instead of just logging the error.
|
|
10774
|
+
* (for AOT-compiled ones this check happens at build time).
|
|
10775
|
+
*/
|
|
10776
|
+
function ɵsetUnknownPropertyStrictMode(shouldThrow) {
|
|
10777
|
+
shouldThrowErrorOnUnknownProperty = shouldThrow;
|
|
10778
|
+
}
|
|
10779
|
+
/**
|
|
10780
|
+
* Gets the current value of the strict mode.
|
|
10781
|
+
*/
|
|
10782
|
+
function ɵgetUnknownPropertyStrictMode() {
|
|
10783
|
+
return shouldThrowErrorOnUnknownProperty;
|
|
10784
|
+
}
|
|
10785
|
+
/**
|
|
10786
|
+
* Validates that the element is known at runtime and produces
|
|
10787
|
+
* an error if it's not the case.
|
|
10788
|
+
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
10789
|
+
* ones this check happens at build time).
|
|
10790
|
+
*
|
|
10791
|
+
* The element is considered known if either:
|
|
10792
|
+
* - it's a known HTML element
|
|
10793
|
+
* - it's a known custom element
|
|
10794
|
+
* - the element matches any directive
|
|
10795
|
+
* - the element is allowed by one of the schemas
|
|
10796
|
+
*
|
|
10797
|
+
* @param element Element to validate
|
|
10798
|
+
* @param lView An `LView` that represents a current component that is being rendered
|
|
10799
|
+
* @param tagName Name of the tag to check
|
|
10800
|
+
* @param schemas Array of schemas
|
|
10801
|
+
* @param hasDirectives Boolean indicating that the element matches any directive
|
|
10802
|
+
*/
|
|
10803
|
+
function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
|
|
10804
|
+
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
10805
|
+
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
10806
|
+
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
10807
|
+
// execute the check below.
|
|
10808
|
+
if (schemas === null)
|
|
10809
|
+
return;
|
|
10810
|
+
// If the element matches any directive, it's considered as valid.
|
|
10811
|
+
if (!hasDirectives && tagName !== null) {
|
|
10812
|
+
// The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
|
|
10813
|
+
// as a custom element. Note that unknown elements with a dash in their name won't be instances
|
|
10814
|
+
// of HTMLUnknownElement in browsers that support web components.
|
|
10815
|
+
const isUnknown =
|
|
10816
|
+
// Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
|
|
10817
|
+
// because while most browsers return 'function', IE returns 'object'.
|
|
10818
|
+
(typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
|
|
10819
|
+
element instanceof HTMLUnknownElement) ||
|
|
10820
|
+
(typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
|
|
10821
|
+
!customElements.get(tagName));
|
|
10822
|
+
if (isUnknown && !matchingSchemas(schemas, tagName)) {
|
|
10823
|
+
const isHostStandalone = isHostComponentStandalone(lView);
|
|
10824
|
+
const templateLocation = getTemplateLocationDetails(lView);
|
|
10825
|
+
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
10826
|
+
let message = `'${tagName}' is not a known element${templateLocation}:\n`;
|
|
10827
|
+
message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
10828
|
+
'a part of an @NgModule where this component is declared'}.\n`;
|
|
10829
|
+
if (tagName && tagName.indexOf('-') > -1) {
|
|
10830
|
+
message +=
|
|
10831
|
+
`2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
|
|
10832
|
+
}
|
|
10833
|
+
else {
|
|
10834
|
+
message +=
|
|
10835
|
+
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
|
|
10836
|
+
}
|
|
10837
|
+
if (shouldThrowErrorOnUnknownElement) {
|
|
10838
|
+
throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
|
|
10839
|
+
}
|
|
10840
|
+
else {
|
|
10841
|
+
console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
|
|
10842
|
+
}
|
|
10843
|
+
}
|
|
10659
10844
|
}
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10845
|
+
}
|
|
10846
|
+
/**
|
|
10847
|
+
* Validates that the property of the element is known at runtime and returns
|
|
10848
|
+
* false if it's not the case.
|
|
10849
|
+
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
10850
|
+
* ones this check happens at build time).
|
|
10851
|
+
*
|
|
10852
|
+
* The property is considered known if either:
|
|
10853
|
+
* - it's a known property of the element
|
|
10854
|
+
* - the element is allowed by one of the schemas
|
|
10855
|
+
* - the property is used for animations
|
|
10856
|
+
*
|
|
10857
|
+
* @param element Element to validate
|
|
10858
|
+
* @param propName Name of the property to check
|
|
10859
|
+
* @param tagName Name of the tag hosting the property
|
|
10860
|
+
* @param schemas Array of schemas
|
|
10861
|
+
*/
|
|
10862
|
+
function isPropertyValid(element, propName, tagName, schemas) {
|
|
10863
|
+
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
10864
|
+
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
10865
|
+
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
10866
|
+
// execute the check below.
|
|
10867
|
+
if (schemas === null)
|
|
10868
|
+
return true;
|
|
10869
|
+
// The property is considered valid if the element matches the schema, it exists on the element,
|
|
10870
|
+
// or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
|
|
10871
|
+
if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
|
|
10872
|
+
return true;
|
|
10668
10873
|
}
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10874
|
+
// Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
|
|
10875
|
+
// need to account for both here, while being careful with `typeof null` also returning 'object'.
|
|
10876
|
+
return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
|
|
10877
|
+
}
|
|
10878
|
+
/**
|
|
10879
|
+
* Logs or throws an error that a property is not supported on an element.
|
|
10880
|
+
*
|
|
10881
|
+
* @param propName Name of the invalid property
|
|
10882
|
+
* @param tagName Name of the tag hosting the property
|
|
10883
|
+
* @param nodeType Type of the node hosting the property
|
|
10884
|
+
* @param lView An `LView` that represents a current component
|
|
10885
|
+
*/
|
|
10886
|
+
function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
|
|
10887
|
+
// Special-case a situation when a structural directive is applied to
|
|
10888
|
+
// an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
|
|
10889
|
+
// In this case the compiler generates the `ɵɵtemplate` instruction with
|
|
10890
|
+
// the `null` as the tagName. The directive matching logic at runtime relies
|
|
10891
|
+
// on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
|
|
10892
|
+
// a default value of the `tNode.value` is not feasible at this moment.
|
|
10893
|
+
if (!tagName && nodeType === 4 /* TNodeType.Container */) {
|
|
10894
|
+
tagName = 'ng-template';
|
|
10673
10895
|
}
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
}
|
|
10690
|
-
|
|
10691
|
-
|
|
10896
|
+
const isHostStandalone = isHostComponentStandalone(lView);
|
|
10897
|
+
const templateLocation = getTemplateLocationDetails(lView);
|
|
10898
|
+
let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
|
|
10899
|
+
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
10900
|
+
const importLocation = isHostStandalone ?
|
|
10901
|
+
'included in the \'@Component.imports\' of this component' :
|
|
10902
|
+
'a part of an @NgModule where this component is declared';
|
|
10903
|
+
if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
|
|
10904
|
+
// Most likely this is a control flow directive (such as `*ngIf`) used in
|
|
10905
|
+
// a template, but the `CommonModule` is not imported.
|
|
10906
|
+
message += `\nIf the '${propName}' is an Angular control flow directive, ` +
|
|
10907
|
+
`please make sure that the 'CommonModule' is ${importLocation}.`;
|
|
10908
|
+
}
|
|
10909
|
+
else {
|
|
10910
|
+
// May be an Angular component, which is not imported/declared?
|
|
10911
|
+
message += `\n1. If '${tagName}' is an Angular component and it has the ` +
|
|
10912
|
+
`'${propName}' input, then verify that it is ${importLocation}.`;
|
|
10913
|
+
// May be a Web Component?
|
|
10914
|
+
if (tagName && tagName.indexOf('-') > -1) {
|
|
10915
|
+
message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
|
|
10916
|
+
`to the ${schemas} of this component to suppress this message.`;
|
|
10917
|
+
message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
10918
|
+
`the ${schemas} of this component.`;
|
|
10692
10919
|
}
|
|
10693
10920
|
else {
|
|
10694
|
-
|
|
10921
|
+
// If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
|
|
10922
|
+
message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
10923
|
+
`the ${schemas} of this component.`;
|
|
10695
10924
|
}
|
|
10696
10925
|
}
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
.join(', ');
|
|
10700
|
-
return `ReflectiveInjector(providers: [${providers}])`;
|
|
10701
|
-
}
|
|
10702
|
-
toString() {
|
|
10703
|
-
return this.displayName;
|
|
10926
|
+
if (shouldThrowErrorOnUnknownProperty) {
|
|
10927
|
+
throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
|
|
10704
10928
|
}
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
function _mapProviders(injector, fn) {
|
|
10708
|
-
const res = [];
|
|
10709
|
-
for (let i = 0; i < injector._providers.length; ++i) {
|
|
10710
|
-
res[i] = fn(injector.getProviderAtIndex(i));
|
|
10929
|
+
else {
|
|
10930
|
+
console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
|
|
10711
10931
|
}
|
|
10712
|
-
return res;
|
|
10713
10932
|
}
|
|
10714
|
-
|
|
10715
10933
|
/**
|
|
10716
|
-
*
|
|
10717
|
-
*
|
|
10934
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10935
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10936
|
+
* be too slow for production mode and also it relies on the constructor function being available.
|
|
10718
10937
|
*
|
|
10719
|
-
*
|
|
10720
|
-
* found in the LICENSE file at https://angular.io/license
|
|
10721
|
-
*/
|
|
10722
|
-
|
|
10723
|
-
/**
|
|
10724
|
-
* @license
|
|
10725
|
-
* Copyright Google LLC All Rights Reserved.
|
|
10938
|
+
* Gets a reference to the host component def (where a current component is declared).
|
|
10726
10939
|
*
|
|
10727
|
-
*
|
|
10728
|
-
* found in the LICENSE file at https://angular.io/license
|
|
10940
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10729
10941
|
*/
|
|
10730
|
-
|
|
10942
|
+
function getDeclarationComponentDef(lView) {
|
|
10943
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10944
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
10945
|
+
const context = declarationLView[CONTEXT];
|
|
10946
|
+
// Unable to obtain a context.
|
|
10947
|
+
if (!context)
|
|
10948
|
+
return null;
|
|
10949
|
+
return context.constructor ? getComponentDef$1(context.constructor) : null;
|
|
10950
|
+
}
|
|
10731
10951
|
/**
|
|
10732
|
-
*
|
|
10733
|
-
*
|
|
10952
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10953
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10954
|
+
* be too slow for production mode.
|
|
10734
10955
|
*
|
|
10735
|
-
*
|
|
10736
|
-
*
|
|
10956
|
+
* Checks if the current component is declared inside of a standalone component template.
|
|
10957
|
+
*
|
|
10958
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10737
10959
|
*/
|
|
10738
|
-
function
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
// if
|
|
10742
|
-
|
|
10743
|
-
// Verify that we will not get into infinite loop.
|
|
10744
|
-
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
|
10745
|
-
return ɵɵinject(token, flags);
|
|
10746
|
-
}
|
|
10747
|
-
const tNode = getCurrentTNode();
|
|
10748
|
-
return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
10960
|
+
function isHostComponentStandalone(lView) {
|
|
10961
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10962
|
+
const componentDef = getDeclarationComponentDef(lView);
|
|
10963
|
+
// Treat host component as non-standalone if we can't obtain the def.
|
|
10964
|
+
return !!(componentDef === null || componentDef === void 0 ? void 0 : componentDef.standalone);
|
|
10749
10965
|
}
|
|
10750
10966
|
/**
|
|
10751
|
-
*
|
|
10752
|
-
*
|
|
10753
|
-
*
|
|
10754
|
-
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
10755
|
-
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
10967
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10968
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10969
|
+
* be too slow for production mode.
|
|
10756
10970
|
*
|
|
10757
|
-
*
|
|
10758
|
-
*
|
|
10971
|
+
* Constructs a string describing the location of the host component template. The function is used
|
|
10972
|
+
* in dev mode to produce error messages.
|
|
10759
10973
|
*
|
|
10760
|
-
* @
|
|
10974
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10761
10975
|
*/
|
|
10762
|
-
function
|
|
10763
|
-
|
|
10764
|
-
|
|
10976
|
+
function getTemplateLocationDetails(lView) {
|
|
10977
|
+
var _a;
|
|
10978
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10979
|
+
const hostComponentDef = getDeclarationComponentDef(lView);
|
|
10980
|
+
const componentClassName = (_a = hostComponentDef === null || hostComponentDef === void 0 ? void 0 : hostComponentDef.type) === null || _a === void 0 ? void 0 : _a.name;
|
|
10981
|
+
return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
|
|
10982
|
+
}
|
|
10983
|
+
/**
|
|
10984
|
+
* The set of known control flow directives.
|
|
10985
|
+
* We use this set to produce a more precises error message with a note
|
|
10986
|
+
* that the `CommonModule` should also be included.
|
|
10987
|
+
*/
|
|
10988
|
+
const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
|
|
10989
|
+
/**
|
|
10990
|
+
* Returns true if the tag name is allowed by specified schemas.
|
|
10991
|
+
* @param schemas Array of schemas
|
|
10992
|
+
* @param tagName Name of the tag
|
|
10993
|
+
*/
|
|
10994
|
+
function matchingSchemas(schemas, tagName) {
|
|
10995
|
+
if (schemas !== null) {
|
|
10996
|
+
for (let i = 0; i < schemas.length; i++) {
|
|
10997
|
+
const schema = schemas[i];
|
|
10998
|
+
if (schema === NO_ERRORS_SCHEMA ||
|
|
10999
|
+
schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
|
|
11000
|
+
return true;
|
|
11001
|
+
}
|
|
11002
|
+
}
|
|
11003
|
+
}
|
|
11004
|
+
return false;
|
|
10765
11005
|
}
|
|
10766
11006
|
|
|
10767
11007
|
/**
|
|
@@ -11563,28 +11803,13 @@ class LContainerDebug {
|
|
|
11563
11803
|
return this._raw_lContainer[HOST];
|
|
11564
11804
|
}
|
|
11565
11805
|
get native() {
|
|
11566
|
-
return this._raw_lContainer[NATIVE];
|
|
11567
|
-
}
|
|
11568
|
-
get next() {
|
|
11569
|
-
return toDebug(this._raw_lContainer[NEXT]);
|
|
11570
|
-
}
|
|
11571
|
-
}
|
|
11572
|
-
|
|
11573
|
-
let shouldThrowErrorOnUnknownProperty = false;
|
|
11574
|
-
/**
|
|
11575
|
-
* Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
|
|
11576
|
-
* instead of just logging the error.
|
|
11577
|
-
* (for AOT-compiled ones this check happens at build time).
|
|
11578
|
-
*/
|
|
11579
|
-
function ɵsetUnknownPropertyStrictMode(shouldThrow) {
|
|
11580
|
-
shouldThrowErrorOnUnknownProperty = shouldThrow;
|
|
11581
|
-
}
|
|
11582
|
-
/**
|
|
11583
|
-
* Gets the current value of the strict mode.
|
|
11584
|
-
*/
|
|
11585
|
-
function ɵgetUnknownPropertyStrictMode() {
|
|
11586
|
-
return shouldThrowErrorOnUnknownProperty;
|
|
11806
|
+
return this._raw_lContainer[NATIVE];
|
|
11807
|
+
}
|
|
11808
|
+
get next() {
|
|
11809
|
+
return toDebug(this._raw_lContainer[NEXT]);
|
|
11810
|
+
}
|
|
11587
11811
|
}
|
|
11812
|
+
|
|
11588
11813
|
/**
|
|
11589
11814
|
* A permanent marker promise which signifies that the current CD tree is
|
|
11590
11815
|
* clean.
|
|
@@ -11743,56 +11968,6 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
|
|
|
11743
11968
|
}
|
|
11744
11969
|
return tNode;
|
|
11745
11970
|
}
|
|
11746
|
-
/**
|
|
11747
|
-
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
11748
|
-
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
11749
|
-
* be too slow for production mode and also it relies on the constructor function being available.
|
|
11750
|
-
*
|
|
11751
|
-
* Gets a reference to the host component def (where a current component is declared).
|
|
11752
|
-
*
|
|
11753
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
11754
|
-
*/
|
|
11755
|
-
function getDeclarationComponentDef(lView) {
|
|
11756
|
-
!ngDevMode && throwError('Must never be called in production mode');
|
|
11757
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
11758
|
-
const context = declarationLView[CONTEXT];
|
|
11759
|
-
// Unable to obtain a context.
|
|
11760
|
-
if (!context)
|
|
11761
|
-
return null;
|
|
11762
|
-
return context.constructor ? getComponentDef$1(context.constructor) : null;
|
|
11763
|
-
}
|
|
11764
|
-
/**
|
|
11765
|
-
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
11766
|
-
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
11767
|
-
* be too slow for production mode.
|
|
11768
|
-
*
|
|
11769
|
-
* Checks if the current component is declared inside of a standalone component template.
|
|
11770
|
-
*
|
|
11771
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
11772
|
-
*/
|
|
11773
|
-
function isHostComponentStandalone(lView) {
|
|
11774
|
-
!ngDevMode && throwError('Must never be called in production mode');
|
|
11775
|
-
const componentDef = getDeclarationComponentDef(lView);
|
|
11776
|
-
// Treat host component as non-standalone if we can't obtain the def.
|
|
11777
|
-
return !!(componentDef === null || componentDef === void 0 ? void 0 : componentDef.standalone);
|
|
11778
|
-
}
|
|
11779
|
-
/**
|
|
11780
|
-
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
11781
|
-
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
11782
|
-
* be too slow for production mode.
|
|
11783
|
-
*
|
|
11784
|
-
* Constructs a string describing the location of the host component template. The function is used
|
|
11785
|
-
* in dev mode to produce error messages.
|
|
11786
|
-
*
|
|
11787
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
11788
|
-
*/
|
|
11789
|
-
function getTemplateLocationDetails(lView) {
|
|
11790
|
-
var _a;
|
|
11791
|
-
!ngDevMode && throwError('Must never be called in production mode');
|
|
11792
|
-
const hostComponentDef = getDeclarationComponentDef(lView);
|
|
11793
|
-
const componentClassName = (_a = hostComponentDef === null || hostComponentDef === void 0 ? void 0 : hostComponentDef.type) === null || _a === void 0 ? void 0 : _a.name;
|
|
11794
|
-
return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
|
|
11795
|
-
}
|
|
11796
11971
|
/**
|
|
11797
11972
|
* When elements are created dynamically after a view blueprint is created (e.g. through
|
|
11798
11973
|
* i18nApply()), we need to adjust the blueprint for future
|
|
@@ -12459,10 +12634,8 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
|
|
|
12459
12634
|
propName = mapPropName(propName);
|
|
12460
12635
|
if (ngDevMode) {
|
|
12461
12636
|
validateAgainstEventProperties(propName);
|
|
12462
|
-
if (!
|
|
12463
|
-
|
|
12464
|
-
handleUnknownPropertyError(propName, tNode, lView);
|
|
12465
|
-
return;
|
|
12637
|
+
if (!isPropertyValid(element, propName, tNode.value, tView.schemas)) {
|
|
12638
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
12466
12639
|
}
|
|
12467
12640
|
ngDevMode.rendererSetProperty++;
|
|
12468
12641
|
}
|
|
@@ -12481,7 +12654,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
|
|
|
12481
12654
|
// If the node is a container and the property didn't
|
|
12482
12655
|
// match any of the inputs or schemas we should throw.
|
|
12483
12656
|
if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
|
|
12484
|
-
handleUnknownPropertyError(propName, tNode, lView);
|
|
12657
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
12485
12658
|
}
|
|
12486
12659
|
}
|
|
12487
12660
|
}
|
|
@@ -12533,116 +12706,6 @@ function setNgReflectProperties(lView, element, type, dataValue, value) {
|
|
|
12533
12706
|
}
|
|
12534
12707
|
}
|
|
12535
12708
|
}
|
|
12536
|
-
/**
|
|
12537
|
-
* Validates that the property of the element is known at runtime and returns
|
|
12538
|
-
* false if it's not the case.
|
|
12539
|
-
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
12540
|
-
* ones this check happens at build time).
|
|
12541
|
-
*
|
|
12542
|
-
* The property is considered known if either:
|
|
12543
|
-
* - it's a known property of the element
|
|
12544
|
-
* - the element is allowed by one of the schemas
|
|
12545
|
-
* - the property is used for animations
|
|
12546
|
-
*
|
|
12547
|
-
* @param element Element to validate
|
|
12548
|
-
* @param tagName Name of the tag to check
|
|
12549
|
-
* @param propName Name of the property to check
|
|
12550
|
-
* @param schemas Array of schemas
|
|
12551
|
-
*/
|
|
12552
|
-
function validateProperty(element, tagName, propName, schemas) {
|
|
12553
|
-
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
12554
|
-
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
12555
|
-
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
12556
|
-
// execute the check below.
|
|
12557
|
-
if (schemas === null)
|
|
12558
|
-
return true;
|
|
12559
|
-
// The property is considered valid if the element matches the schema, it exists on the element,
|
|
12560
|
-
// or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
|
|
12561
|
-
if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
|
|
12562
|
-
return true;
|
|
12563
|
-
}
|
|
12564
|
-
// Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
|
|
12565
|
-
// need to account for both here, while being careful with `typeof null` also returning 'object'.
|
|
12566
|
-
return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
|
|
12567
|
-
}
|
|
12568
|
-
/**
|
|
12569
|
-
* Returns true if the tag name is allowed by specified schemas.
|
|
12570
|
-
* @param schemas Array of schemas
|
|
12571
|
-
* @param tagName Name of the tag
|
|
12572
|
-
*/
|
|
12573
|
-
function matchingSchemas(schemas, tagName) {
|
|
12574
|
-
if (schemas !== null) {
|
|
12575
|
-
for (let i = 0; i < schemas.length; i++) {
|
|
12576
|
-
const schema = schemas[i];
|
|
12577
|
-
if (schema === NO_ERRORS_SCHEMA ||
|
|
12578
|
-
schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
|
|
12579
|
-
return true;
|
|
12580
|
-
}
|
|
12581
|
-
}
|
|
12582
|
-
}
|
|
12583
|
-
return false;
|
|
12584
|
-
}
|
|
12585
|
-
/**
|
|
12586
|
-
* The set of known control flow directives.
|
|
12587
|
-
* We use this set to produce a more precises error message with a note
|
|
12588
|
-
* that the `CommonModule` should also be included.
|
|
12589
|
-
*/
|
|
12590
|
-
const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
|
|
12591
|
-
/**
|
|
12592
|
-
* Logs or throws an error that a property is not supported on an element.
|
|
12593
|
-
*
|
|
12594
|
-
* @param propName Name of the invalid property.
|
|
12595
|
-
* @param tNode A `TNode` that represents a current component that is being rendered.
|
|
12596
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
12597
|
-
*/
|
|
12598
|
-
function handleUnknownPropertyError(propName, tNode, lView) {
|
|
12599
|
-
let tagName = tNode.value;
|
|
12600
|
-
// Special-case a situation when a structural directive is applied to
|
|
12601
|
-
// an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
|
|
12602
|
-
// In this case the compiler generates the `ɵɵtemplate` instruction with
|
|
12603
|
-
// the `null` as the tagName. The directive matching logic at runtime relies
|
|
12604
|
-
// on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
|
|
12605
|
-
// a default value of the `tNode.value` is not feasible at this moment.
|
|
12606
|
-
if (!tagName && tNode.type === 4 /* TNodeType.Container */) {
|
|
12607
|
-
tagName = 'ng-template';
|
|
12608
|
-
}
|
|
12609
|
-
const isHostStandalone = isHostComponentStandalone(lView);
|
|
12610
|
-
const templateLocation = getTemplateLocationDetails(lView);
|
|
12611
|
-
let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
|
|
12612
|
-
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
12613
|
-
const importLocation = isHostStandalone ?
|
|
12614
|
-
'included in the \'@Component.imports\' of this component' :
|
|
12615
|
-
'a part of an @NgModule where this component is declared';
|
|
12616
|
-
if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
|
|
12617
|
-
// Most likely this is a control flow directive (such as `*ngIf`) used in
|
|
12618
|
-
// a template, but the `CommonModule` is not imported.
|
|
12619
|
-
message += `\nIf the '${propName}' is an Angular control flow directive, ` +
|
|
12620
|
-
`please make sure that the 'CommonModule' is ${importLocation}.`;
|
|
12621
|
-
}
|
|
12622
|
-
else {
|
|
12623
|
-
// May be an Angular component, which is not imported/declared?
|
|
12624
|
-
message += `\n1. If '${tagName}' is an Angular component and it has the ` +
|
|
12625
|
-
`'${propName}' input, then verify that it is ${importLocation}.`;
|
|
12626
|
-
// May be a Web Component?
|
|
12627
|
-
if (tagName && tagName.indexOf('-') > -1) {
|
|
12628
|
-
message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
|
|
12629
|
-
`to the ${schemas} of this component to suppress this message.`;
|
|
12630
|
-
message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
12631
|
-
`the ${schemas} of this component.`;
|
|
12632
|
-
}
|
|
12633
|
-
else {
|
|
12634
|
-
// If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
|
|
12635
|
-
message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
12636
|
-
`the ${schemas} of this component.`;
|
|
12637
|
-
}
|
|
12638
|
-
}
|
|
12639
|
-
if (shouldThrowErrorOnUnknownProperty) {
|
|
12640
|
-
throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
|
|
12641
|
-
}
|
|
12642
|
-
else {
|
|
12643
|
-
console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
|
|
12644
|
-
}
|
|
12645
|
-
}
|
|
12646
12709
|
/**
|
|
12647
12710
|
* Instantiate a root component.
|
|
12648
12711
|
*/
|
|
@@ -14216,7 +14279,11 @@ function createRootComponent(componentView, componentDef, rootLView, rootContext
|
|
|
14216
14279
|
const component = instantiateRootComponent(tView, rootLView, componentDef);
|
|
14217
14280
|
rootContext.components.push(component);
|
|
14218
14281
|
componentView[CONTEXT] = component;
|
|
14219
|
-
hostFeatures
|
|
14282
|
+
if (hostFeatures !== null) {
|
|
14283
|
+
for (const feature of hostFeatures) {
|
|
14284
|
+
feature(component, componentDef);
|
|
14285
|
+
}
|
|
14286
|
+
}
|
|
14220
14287
|
// We want to generate an empty QueryList for root content queries for backwards
|
|
14221
14288
|
// compatibility with ViewEngine.
|
|
14222
14289
|
if (componentDef.contentQueries) {
|
|
@@ -14257,13 +14324,10 @@ function createRootContext(scheduler, playerHandler) {
|
|
|
14257
14324
|
* renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
|
|
14258
14325
|
* ```
|
|
14259
14326
|
*/
|
|
14260
|
-
function LifecycleHooksFeature(
|
|
14261
|
-
const lView = readPatchedLView(component);
|
|
14262
|
-
ngDevMode && assertDefined(lView, 'LView is required');
|
|
14263
|
-
const tView = lView[TVIEW];
|
|
14327
|
+
function LifecycleHooksFeature() {
|
|
14264
14328
|
const tNode = getCurrentTNode();
|
|
14265
14329
|
ngDevMode && assertDefined(tNode, 'TNode is required');
|
|
14266
|
-
registerPostOrderHooks(
|
|
14330
|
+
registerPostOrderHooks(getLView()[TVIEW], tNode);
|
|
14267
14331
|
}
|
|
14268
14332
|
/**
|
|
14269
14333
|
* Wait on component until it is rendered.
|
|
@@ -14313,10 +14377,8 @@ function ɵɵInheritDefinitionFeature(definition) {
|
|
|
14313
14377
|
}
|
|
14314
14378
|
else {
|
|
14315
14379
|
if (superType.ɵcmp) {
|
|
14316
|
-
|
|
14317
|
-
`Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`
|
|
14318
|
-
'';
|
|
14319
|
-
throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, errorMessage);
|
|
14380
|
+
throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
|
|
14381
|
+
`Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
|
|
14320
14382
|
}
|
|
14321
14383
|
// Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
|
|
14322
14384
|
superDef = superType.ɵdir;
|
|
@@ -15398,21 +15460,6 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
|
|
|
15398
15460
|
* Use of this source code is governed by an MIT-style license that can be
|
|
15399
15461
|
* found in the LICENSE file at https://angular.io/license
|
|
15400
15462
|
*/
|
|
15401
|
-
let shouldThrowErrorOnUnknownElement = false;
|
|
15402
|
-
/**
|
|
15403
|
-
* Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
|
|
15404
|
-
* instead of just logging the error.
|
|
15405
|
-
* (for AOT-compiled ones this check happens at build time).
|
|
15406
|
-
*/
|
|
15407
|
-
function ɵsetUnknownElementStrictMode(shouldThrow) {
|
|
15408
|
-
shouldThrowErrorOnUnknownElement = shouldThrow;
|
|
15409
|
-
}
|
|
15410
|
-
/**
|
|
15411
|
-
* Gets the current value of the strict mode.
|
|
15412
|
-
*/
|
|
15413
|
-
function ɵgetUnknownElementStrictMode() {
|
|
15414
|
-
return shouldThrowErrorOnUnknownElement;
|
|
15415
|
-
}
|
|
15416
15463
|
function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
|
|
15417
15464
|
ngDevMode && assertFirstCreatePass(tView);
|
|
15418
15465
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
@@ -15546,67 +15593,6 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
|
|
|
15546
15593
|
ɵɵelementEnd();
|
|
15547
15594
|
return ɵɵelement;
|
|
15548
15595
|
}
|
|
15549
|
-
/**
|
|
15550
|
-
* Validates that the element is known at runtime and produces
|
|
15551
|
-
* an error if it's not the case.
|
|
15552
|
-
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
15553
|
-
* ones this check happens at build time).
|
|
15554
|
-
*
|
|
15555
|
-
* The element is considered known if either:
|
|
15556
|
-
* - it's a known HTML element
|
|
15557
|
-
* - it's a known custom element
|
|
15558
|
-
* - the element matches any directive
|
|
15559
|
-
* - the element is allowed by one of the schemas
|
|
15560
|
-
*
|
|
15561
|
-
* @param element Element to validate
|
|
15562
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
15563
|
-
* @param tagName Name of the tag to check
|
|
15564
|
-
* @param schemas Array of schemas
|
|
15565
|
-
* @param hasDirectives Boolean indicating that the element matches any directive
|
|
15566
|
-
*/
|
|
15567
|
-
function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
|
|
15568
|
-
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
15569
|
-
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
15570
|
-
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
15571
|
-
// execute the check below.
|
|
15572
|
-
if (schemas === null)
|
|
15573
|
-
return;
|
|
15574
|
-
// If the element matches any directive, it's considered as valid.
|
|
15575
|
-
if (!hasDirectives && tagName !== null) {
|
|
15576
|
-
// The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
|
|
15577
|
-
// as a custom element. Note that unknown elements with a dash in their name won't be instances
|
|
15578
|
-
// of HTMLUnknownElement in browsers that support web components.
|
|
15579
|
-
const isUnknown =
|
|
15580
|
-
// Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
|
|
15581
|
-
// because while most browsers return 'function', IE returns 'object'.
|
|
15582
|
-
(typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
|
|
15583
|
-
element instanceof HTMLUnknownElement) ||
|
|
15584
|
-
(typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
|
|
15585
|
-
!customElements.get(tagName));
|
|
15586
|
-
if (isUnknown && !matchingSchemas(schemas, tagName)) {
|
|
15587
|
-
const isHostStandalone = isHostComponentStandalone(lView);
|
|
15588
|
-
const templateLocation = getTemplateLocationDetails(lView);
|
|
15589
|
-
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
15590
|
-
let message = `'${tagName}' is not a known element${templateLocation}:\n`;
|
|
15591
|
-
message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
15592
|
-
'a part of an @NgModule where this component is declared'}.\n`;
|
|
15593
|
-
if (tagName && tagName.indexOf('-') > -1) {
|
|
15594
|
-
message +=
|
|
15595
|
-
`2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
|
|
15596
|
-
}
|
|
15597
|
-
else {
|
|
15598
|
-
message +=
|
|
15599
|
-
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
|
|
15600
|
-
}
|
|
15601
|
-
if (shouldThrowErrorOnUnknownElement) {
|
|
15602
|
-
throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
|
|
15603
|
-
}
|
|
15604
|
-
else {
|
|
15605
|
-
console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
|
|
15606
|
-
}
|
|
15607
|
-
}
|
|
15608
|
-
}
|
|
15609
|
-
}
|
|
15610
15596
|
|
|
15611
15597
|
/**
|
|
15612
15598
|
* @license
|
|
@@ -22089,7 +22075,7 @@ class Version {
|
|
|
22089
22075
|
/**
|
|
22090
22076
|
* @publicApi
|
|
22091
22077
|
*/
|
|
22092
|
-
const VERSION = new Version('14.0.
|
|
22078
|
+
const VERSION = new Version('14.0.3');
|
|
22093
22079
|
|
|
22094
22080
|
/**
|
|
22095
22081
|
* @license
|
|
@@ -22427,8 +22413,7 @@ class ViewRef {
|
|
|
22427
22413
|
}
|
|
22428
22414
|
attachToViewContainerRef() {
|
|
22429
22415
|
if (this._appRef) {
|
|
22430
|
-
|
|
22431
|
-
throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
|
|
22416
|
+
throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached directly to the ApplicationRef!');
|
|
22432
22417
|
}
|
|
22433
22418
|
this._attachedToViewContainer = true;
|
|
22434
22419
|
}
|
|
@@ -22438,8 +22423,7 @@ class ViewRef {
|
|
|
22438
22423
|
}
|
|
22439
22424
|
attachToAppRef(appRef) {
|
|
22440
22425
|
if (this._attachedToViewContainer) {
|
|
22441
|
-
|
|
22442
|
-
throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
|
|
22426
|
+
throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
|
|
22443
22427
|
}
|
|
22444
22428
|
this._appRef = appRef;
|
|
22445
22429
|
}
|
|
@@ -22789,14 +22773,14 @@ class StandaloneService {
|
|
|
22789
22773
|
if (!componentDef.standalone) {
|
|
22790
22774
|
return null;
|
|
22791
22775
|
}
|
|
22792
|
-
if (!this.cachedInjectors.has(componentDef)) {
|
|
22776
|
+
if (!this.cachedInjectors.has(componentDef.id)) {
|
|
22793
22777
|
const providers = internalImportProvidersFrom(false, componentDef.type);
|
|
22794
22778
|
const standaloneInjector = providers.length > 0 ?
|
|
22795
22779
|
createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
|
|
22796
22780
|
null;
|
|
22797
|
-
this.cachedInjectors.set(componentDef, standaloneInjector);
|
|
22781
|
+
this.cachedInjectors.set(componentDef.id, standaloneInjector);
|
|
22798
22782
|
}
|
|
22799
|
-
return this.cachedInjectors.get(componentDef);
|
|
22783
|
+
return this.cachedInjectors.get(componentDef.id);
|
|
22800
22784
|
}
|
|
22801
22785
|
ngOnDestroy() {
|
|
22802
22786
|
try {
|
|
@@ -23296,13 +23280,26 @@ function getPipeDef(name, registry) {
|
|
|
23296
23280
|
}
|
|
23297
23281
|
}
|
|
23298
23282
|
if (ngDevMode) {
|
|
23299
|
-
|
|
23300
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
23301
|
-
const context = declarationLView[CONTEXT];
|
|
23302
|
-
const component = context ? ` in the '${context.constructor.name}' component` : '';
|
|
23303
|
-
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, `The pipe '${name}' could not be found${component}!`);
|
|
23283
|
+
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
|
|
23304
23284
|
}
|
|
23305
23285
|
}
|
|
23286
|
+
/**
|
|
23287
|
+
* Generates a helpful error message for the user when a pipe is not found.
|
|
23288
|
+
*
|
|
23289
|
+
* @param name Name of the missing pipe
|
|
23290
|
+
* @returns The error message
|
|
23291
|
+
*/
|
|
23292
|
+
function getPipeNotFoundErrorMessage(name) {
|
|
23293
|
+
const lView = getLView();
|
|
23294
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
23295
|
+
const context = declarationLView[CONTEXT];
|
|
23296
|
+
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
23297
|
+
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
23298
|
+
const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
23299
|
+
'declared or imported in this module'}`;
|
|
23300
|
+
const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
|
|
23301
|
+
return errorMessage;
|
|
23302
|
+
}
|
|
23306
23303
|
/**
|
|
23307
23304
|
* Invokes a pipe with 1 arguments.
|
|
23308
23305
|
*
|
|
@@ -24705,7 +24702,7 @@ function patchModuleCompilation() {
|
|
|
24705
24702
|
function isModuleWithProviders$1(value) {
|
|
24706
24703
|
return value.ngModule !== undefined;
|
|
24707
24704
|
}
|
|
24708
|
-
function isNgModule(value) {
|
|
24705
|
+
function isNgModule$1(value) {
|
|
24709
24706
|
return !!getNgModuleDef(value);
|
|
24710
24707
|
}
|
|
24711
24708
|
|
|
@@ -25094,6 +25091,7 @@ function setScopeOnDeclaredComponents(moduleType, ngModule) {
|
|
|
25094
25091
|
const declarations = flatten$1(ngModule.declarations || EMPTY_ARRAY);
|
|
25095
25092
|
const transitiveScopes = transitiveScopesFor(moduleType);
|
|
25096
25093
|
declarations.forEach(declaration => {
|
|
25094
|
+
declaration = resolveForwardRef(declaration);
|
|
25097
25095
|
if (declaration.hasOwnProperty(NG_COMP_DEF)) {
|
|
25098
25096
|
// A `ɵcmp` field exists - go ahead and patch the component directly.
|
|
25099
25097
|
const component = declaration;
|
|
@@ -25124,10 +25122,10 @@ function patchComponentDefWithScope(componentDef, transitiveScopes) {
|
|
|
25124
25122
|
}
|
|
25125
25123
|
/**
|
|
25126
25124
|
* Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
|
|
25127
|
-
* (
|
|
25125
|
+
* (either a NgModule or a standalone component / directive / pipe).
|
|
25128
25126
|
*/
|
|
25129
25127
|
function transitiveScopesFor(type) {
|
|
25130
|
-
if (isNgModule(type)) {
|
|
25128
|
+
if (isNgModule$1(type)) {
|
|
25131
25129
|
return transitiveScopesForNgModule(type);
|
|
25132
25130
|
}
|
|
25133
25131
|
else if (isStandalone(type)) {
|
|
@@ -25211,7 +25209,7 @@ function transitiveScopesForNgModule(moduleType) {
|
|
|
25211
25209
|
const exportedType = exported;
|
|
25212
25210
|
// Either the type is a module, a pipe, or a component/directive (which may not have a
|
|
25213
25211
|
// ɵcmp as it might be compiled asynchronously).
|
|
25214
|
-
if (isNgModule(exportedType)) {
|
|
25212
|
+
if (isNgModule$1(exportedType)) {
|
|
25215
25213
|
// When this module exports another, the exported module's exported directives and pipes are
|
|
25216
25214
|
// added to both the compilation and exported scopes of this module.
|
|
25217
25215
|
const exportedScope = transitiveScopesFor(exportedType);
|
|
@@ -25511,7 +25509,7 @@ class R3TestBedCompiler {
|
|
|
25511
25509
|
// module's provider list.
|
|
25512
25510
|
this.providerOverridesByModule = new Map();
|
|
25513
25511
|
this.providerOverridesByToken = new Map();
|
|
25514
|
-
this.
|
|
25512
|
+
this.scopesWithOverriddenProviders = new Set();
|
|
25515
25513
|
this.testModuleRef = null;
|
|
25516
25514
|
class DynamicTestModule {
|
|
25517
25515
|
}
|
|
@@ -25682,7 +25680,7 @@ class R3TestBedCompiler {
|
|
|
25682
25680
|
this.queueTypesFromModulesArray([moduleType]);
|
|
25683
25681
|
this.compileTypesSync();
|
|
25684
25682
|
this.applyProviderOverrides();
|
|
25685
|
-
this.
|
|
25683
|
+
this.applyProviderOverridesInScope(moduleType);
|
|
25686
25684
|
this.applyTransitiveScopes();
|
|
25687
25685
|
}
|
|
25688
25686
|
/**
|
|
@@ -25693,7 +25691,7 @@ class R3TestBedCompiler {
|
|
|
25693
25691
|
this.queueTypesFromModulesArray([moduleType]);
|
|
25694
25692
|
yield this.compileComponents();
|
|
25695
25693
|
this.applyProviderOverrides();
|
|
25696
|
-
this.
|
|
25694
|
+
this.applyProviderOverridesInScope(moduleType);
|
|
25697
25695
|
this.applyTransitiveScopes();
|
|
25698
25696
|
});
|
|
25699
25697
|
}
|
|
@@ -25795,51 +25793,53 @@ class R3TestBedCompiler {
|
|
|
25795
25793
|
this.seenComponents.clear();
|
|
25796
25794
|
this.seenDirectives.clear();
|
|
25797
25795
|
}
|
|
25798
|
-
|
|
25796
|
+
/**
|
|
25797
|
+
* Applies provider overrides to a given type (either an NgModule or a standalone component)
|
|
25798
|
+
* and all imported NgModules and standalone components recursively.
|
|
25799
|
+
*/
|
|
25800
|
+
applyProviderOverridesInScope(type) {
|
|
25799
25801
|
var _a;
|
|
25800
|
-
|
|
25802
|
+
const hasScope = isStandaloneComponent(type) || isNgModule(type);
|
|
25803
|
+
// The function can be re-entered recursively while inspecting dependencies
|
|
25804
|
+
// of an NgModule or a standalone component. Exit early if we come across a
|
|
25805
|
+
// type that can not have a scope (directive or pipe) or the type is already
|
|
25806
|
+
// processed earlier.
|
|
25807
|
+
if (!hasScope || this.scopesWithOverriddenProviders.has(type)) {
|
|
25801
25808
|
return;
|
|
25802
25809
|
}
|
|
25803
|
-
this.
|
|
25810
|
+
this.scopesWithOverriddenProviders.add(type);
|
|
25804
25811
|
// NOTE: the line below triggers JIT compilation of the module injector,
|
|
25805
25812
|
// which also invokes verification of the NgModule semantics, which produces
|
|
25806
25813
|
// detailed error messages. The fact that the code relies on this line being
|
|
25807
25814
|
// present here is suspicious and should be refactored in a way that the line
|
|
25808
25815
|
// below can be moved (for ex. after an early exit check below).
|
|
25809
|
-
const injectorDef =
|
|
25816
|
+
const injectorDef = type[ɵNG_INJ_DEF];
|
|
25810
25817
|
// No provider overrides, exit early.
|
|
25811
25818
|
if (this.providerOverridesByToken.size === 0)
|
|
25812
25819
|
return;
|
|
25813
|
-
if (isStandaloneComponent(
|
|
25820
|
+
if (isStandaloneComponent(type)) {
|
|
25814
25821
|
// Visit all component dependencies and override providers there.
|
|
25815
|
-
const def = getComponentDef(
|
|
25822
|
+
const def = getComponentDef(type);
|
|
25816
25823
|
const dependencies = maybeUnwrapFn((_a = def.dependencies) !== null && _a !== void 0 ? _a : []);
|
|
25817
25824
|
for (const dependency of dependencies) {
|
|
25818
|
-
|
|
25819
|
-
// when a dependency is a standalone component or an NgModule.
|
|
25820
|
-
// In AOT, the `dependencies` might also contain regular (NgModule-based)
|
|
25821
|
-
// Component, Directive and Pipes. Skip them here, they are handled in a
|
|
25822
|
-
// different location (in the `configureTestingModule` function).
|
|
25823
|
-
if (isStandaloneComponent(dependency) || hasNgModuleDef(dependency)) {
|
|
25824
|
-
this.applyProviderOverridesToModule(dependency);
|
|
25825
|
-
}
|
|
25825
|
+
this.applyProviderOverridesInScope(dependency);
|
|
25826
25826
|
}
|
|
25827
25827
|
}
|
|
25828
25828
|
else {
|
|
25829
25829
|
const providers = [
|
|
25830
25830
|
...injectorDef.providers,
|
|
25831
|
-
...(this.providerOverridesByModule.get(
|
|
25831
|
+
...(this.providerOverridesByModule.get(type) || [])
|
|
25832
25832
|
];
|
|
25833
25833
|
if (this.hasProviderOverrides(providers)) {
|
|
25834
|
-
this.maybeStoreNgDef(ɵNG_INJ_DEF,
|
|
25835
|
-
this.storeFieldOfDefOnType(
|
|
25834
|
+
this.maybeStoreNgDef(ɵNG_INJ_DEF, type);
|
|
25835
|
+
this.storeFieldOfDefOnType(type, ɵNG_INJ_DEF, 'providers');
|
|
25836
25836
|
injectorDef.providers = this.getOverriddenProviders(providers);
|
|
25837
25837
|
}
|
|
25838
25838
|
// Apply provider overrides to imported modules recursively
|
|
25839
|
-
const moduleDef =
|
|
25839
|
+
const moduleDef = type[ɵNG_MOD_DEF];
|
|
25840
25840
|
const imports = maybeUnwrapFn(moduleDef.imports);
|
|
25841
25841
|
for (const importedModule of imports) {
|
|
25842
|
-
this.
|
|
25842
|
+
this.applyProviderOverridesInScope(importedModule);
|
|
25843
25843
|
}
|
|
25844
25844
|
// Also override the providers on any ModuleWithProviders imports since those don't appear in
|
|
25845
25845
|
// the moduleDef.
|
|
@@ -26077,7 +26077,7 @@ class R3TestBedCompiler {
|
|
|
26077
26077
|
});
|
|
26078
26078
|
});
|
|
26079
26079
|
this.initialNgDefs.clear();
|
|
26080
|
-
this.
|
|
26080
|
+
this.scopesWithOverriddenProviders.clear();
|
|
26081
26081
|
this.restoreComponentResolutionQueue();
|
|
26082
26082
|
// Restore the locale ID to the default value, this shouldn't be necessary but we never know
|
|
26083
26083
|
ɵsetLocaleId(ɵDEFAULT_LOCALE_ID);
|
|
@@ -26104,7 +26104,7 @@ class R3TestBedCompiler {
|
|
|
26104
26104
|
providers,
|
|
26105
26105
|
}, /* allowDuplicateDeclarationsInRoot */ true);
|
|
26106
26106
|
// clang-format on
|
|
26107
|
-
this.
|
|
26107
|
+
this.applyProviderOverridesInScope(this.testModuleType);
|
|
26108
26108
|
}
|
|
26109
26109
|
get injector() {
|
|
26110
26110
|
if (this._injector !== null) {
|
|
@@ -26205,6 +26205,9 @@ function getComponentDef(value) {
|
|
|
26205
26205
|
function hasNgModuleDef(value) {
|
|
26206
26206
|
return value.hasOwnProperty('ɵmod');
|
|
26207
26207
|
}
|
|
26208
|
+
function isNgModule(value) {
|
|
26209
|
+
return hasNgModuleDef(value);
|
|
26210
|
+
}
|
|
26208
26211
|
function maybeUnwrapFn(maybeFn) {
|
|
26209
26212
|
return maybeFn instanceof Function ? maybeFn() : maybeFn;
|
|
26210
26213
|
}
|