@angular/core 14.0.0-rc.2 → 14.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/src/di/injector_compatibility.mjs +57 -15
- package/esm2020/src/di/interface/provider.mjs +1 -1
- package/esm2020/src/di/provider_collection.mjs +32 -2
- package/esm2020/src/di/r3_injector.mjs +3 -1
- package/esm2020/src/error_handler.mjs +4 -7
- package/esm2020/src/errors.mjs +6 -3
- package/esm2020/src/metadata/directives.mjs +1 -1
- package/esm2020/src/render3/component.mjs +9 -9
- package/esm2020/src/render3/definition.mjs +6 -6
- 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 +4 -79
- package/esm2020/src/render3/instructions/element_validation.mjs +264 -0
- package/esm2020/src/render3/instructions/shared.mjs +7 -113
- package/esm2020/src/render3/interfaces/definition.mjs +1 -1
- package/esm2020/src/render3/jit/module.mjs +2 -2
- package/esm2020/src/render3/ng_module_ref.mjs +2 -1
- package/esm2020/src/render3/pipe.mjs +20 -6
- package/esm2020/src/render3/state.mjs +1 -3
- 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/test_bed.mjs +5 -2
- package/fesm2015/core.mjs +630 -471
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +696 -534
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +626 -468
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +701 -540
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +80 -33
- package/package.json +1 -1
- package/testing/index.d.ts +5 -2
package/fesm2015/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v14.0.
|
|
2
|
+
* @license Angular v14.0.1
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -181,9 +181,12 @@ function formatRuntimeError(code, message) {
|
|
|
181
181
|
// Error code might be a negative number, which is a special marker that instructs the logic to
|
|
182
182
|
// generate a link to the error details page on angular.io.
|
|
183
183
|
const fullCode = `NG0${Math.abs(code)}`;
|
|
184
|
-
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
184
|
+
let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
|
|
185
185
|
if (ngDevMode && code < 0) {
|
|
186
|
-
|
|
186
|
+
const addPeriodSeparator = !errorMessage.match(/[.,;!?]$/);
|
|
187
|
+
const separator = addPeriodSeparator ? '.' : '';
|
|
188
|
+
errorMessage =
|
|
189
|
+
`${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
|
|
187
190
|
}
|
|
188
191
|
return errorMessage;
|
|
189
192
|
}
|
|
@@ -864,7 +867,8 @@ const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafe
|
|
|
864
867
|
* Use of this source code is governed by an MIT-style license that can be
|
|
865
868
|
* found in the LICENSE file at https://angular.io/license
|
|
866
869
|
*/
|
|
867
|
-
|
|
870
|
+
/** Counter used to generate unique IDs for component definitions. */
|
|
871
|
+
let componentDefCount = 0;
|
|
868
872
|
/**
|
|
869
873
|
* Create a component definition object.
|
|
870
874
|
*
|
|
@@ -917,7 +921,7 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
917
921
|
features: componentDefinition.features || null,
|
|
918
922
|
data: componentDefinition.data || {},
|
|
919
923
|
encapsulation: componentDefinition.encapsulation || ViewEncapsulation$1.Emulated,
|
|
920
|
-
id:
|
|
924
|
+
id: `c${componentDefCount++}`,
|
|
921
925
|
styles: componentDefinition.styles || EMPTY_ARRAY,
|
|
922
926
|
_: null,
|
|
923
927
|
setInput: null,
|
|
@@ -926,7 +930,6 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
926
930
|
};
|
|
927
931
|
const dependencies = componentDefinition.dependencies;
|
|
928
932
|
const feature = componentDefinition.features;
|
|
929
|
-
def.id += _renderCompCount++;
|
|
930
933
|
def.inputs = invertObject(componentDefinition.inputs, declaredInputs),
|
|
931
934
|
def.outputs = invertObject(componentDefinition.outputs),
|
|
932
935
|
feature && feature.forEach((fn) => fn(def));
|
|
@@ -954,8 +957,8 @@ function ɵɵdefineComponent(componentDefinition) {
|
|
|
954
957
|
*/
|
|
955
958
|
function ɵɵsetComponentScope(type, directives, pipes) {
|
|
956
959
|
const def = type.ɵcmp;
|
|
957
|
-
def.directiveDefs = () => directives.map(extractDirectiveDef);
|
|
958
|
-
def.pipeDefs = () => pipes.map(getPipeDef$1);
|
|
960
|
+
def.directiveDefs = () => (typeof directives === 'function' ? directives() : directives).map(extractDirectiveDef);
|
|
961
|
+
def.pipeDefs = () => (typeof pipes === 'function' ? pipes() : pipes).map(getPipeDef$1);
|
|
959
962
|
}
|
|
960
963
|
function extractDirectiveDef(type) {
|
|
961
964
|
return getComponentDef(type) || getDirectiveDef(type);
|
|
@@ -1933,7 +1936,6 @@ function getLView() {
|
|
|
1933
1936
|
function getTView() {
|
|
1934
1937
|
return instructionState.lFrame.tView;
|
|
1935
1938
|
}
|
|
1936
|
-
// TODO(crisbeto): revert the @noinline once Closure issue is resolved.
|
|
1937
1939
|
/**
|
|
1938
1940
|
* Restores `contextViewData` to the given OpaqueViewState instance.
|
|
1939
1941
|
*
|
|
@@ -1945,7 +1947,6 @@ function getTView() {
|
|
|
1945
1947
|
* @returns Context of the restored OpaqueViewState instance.
|
|
1946
1948
|
*
|
|
1947
1949
|
* @codeGenApi
|
|
1948
|
-
* @noinline Disable inlining due to issue with Closure in listeners inside embedded views.
|
|
1949
1950
|
*/
|
|
1950
1951
|
function ɵɵrestoreView(viewToRestore) {
|
|
1951
1952
|
instructionState.lFrame.contextLView = viewToRestore;
|
|
@@ -4837,9 +4838,9 @@ function setCurrentInjector(injector) {
|
|
|
4837
4838
|
function injectInjectorOnly(token, flags = InjectFlags.Default) {
|
|
4838
4839
|
if (_currentInjector === undefined) {
|
|
4839
4840
|
const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
|
|
4840
|
-
`inject() must be called from an injection context` :
|
|
4841
|
+
`inject() must be called from an injection context (a constructor, a factory function or a field initializer)` :
|
|
4841
4842
|
'';
|
|
4842
|
-
throw new RuntimeError(203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
|
|
4843
|
+
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
|
|
4843
4844
|
}
|
|
4844
4845
|
else if (_currentInjector === null) {
|
|
4845
4846
|
return injectRootLimpMode(token, undefined, flags);
|
|
@@ -4874,29 +4875,71 @@ Please check that 1) the type for the parameter at index ${index} is correct and
|
|
|
4874
4875
|
}
|
|
4875
4876
|
/**
|
|
4876
4877
|
* Injects a token from the currently active injector.
|
|
4877
|
-
*
|
|
4878
|
-
*
|
|
4879
|
-
* `
|
|
4880
|
-
*
|
|
4881
|
-
*
|
|
4882
|
-
*
|
|
4883
|
-
*
|
|
4884
|
-
*
|
|
4885
|
-
* @param token
|
|
4878
|
+
* `inject` is only supported during instantiation of a dependency by the DI system. It can be used
|
|
4879
|
+
* during:
|
|
4880
|
+
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
4881
|
+
* as an `@Injectable` or `@Component`.
|
|
4882
|
+
* - In the initializer for fields of such classes.
|
|
4883
|
+
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
4884
|
+
* - In the `factory` function specified for an `InjectionToken`.
|
|
4885
|
+
*
|
|
4886
|
+
* @param token A token that represents a dependency that should be injected.
|
|
4886
4887
|
* @param flags Optional flags that control how injection is executed.
|
|
4887
4888
|
* The flags correspond to injection strategies that can be specified with
|
|
4888
4889
|
* parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
|
|
4889
|
-
* @returns the injected value if
|
|
4890
|
+
* @returns the injected value if operation is successful, `null` otherwise.
|
|
4891
|
+
* @throws if called outside of a supported context.
|
|
4890
4892
|
*
|
|
4891
4893
|
* @usageNotes
|
|
4894
|
+
* In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
|
|
4895
|
+
* field initializer:
|
|
4892
4896
|
*
|
|
4893
|
-
*
|
|
4897
|
+
* ```typescript
|
|
4898
|
+
* @Injectable({providedIn: 'root'})
|
|
4899
|
+
* export class Car {
|
|
4900
|
+
* radio: Radio|undefined;
|
|
4901
|
+
* // OK: field initializer
|
|
4902
|
+
* spareTyre = inject(Tyre);
|
|
4894
4903
|
*
|
|
4895
|
-
* {
|
|
4904
|
+
* constructor() {
|
|
4905
|
+
* // OK: constructor body
|
|
4906
|
+
* this.radio = inject(Radio);
|
|
4907
|
+
* }
|
|
4908
|
+
* }
|
|
4909
|
+
* ```
|
|
4910
|
+
*
|
|
4911
|
+
* It is also legal to call `inject` from a provider's factory:
|
|
4912
|
+
*
|
|
4913
|
+
* ```typescript
|
|
4914
|
+
* providers: [
|
|
4915
|
+
* {provide: Car, useFactory: () => {
|
|
4916
|
+
* // OK: a class factory
|
|
4917
|
+
* const engine = inject(Engine);
|
|
4918
|
+
* return new Car(engine);
|
|
4919
|
+
* }}
|
|
4920
|
+
* ]
|
|
4921
|
+
* ```
|
|
4922
|
+
*
|
|
4923
|
+
* Calls to the `inject()` function outside of the class creation context will result in error. Most
|
|
4924
|
+
* notably, calls to `inject()` are disallowed after a class instance was created, in methods
|
|
4925
|
+
* (including lifecycle hooks):
|
|
4926
|
+
*
|
|
4927
|
+
* ```typescript
|
|
4928
|
+
* @Component({ ... })
|
|
4929
|
+
* export class CarComponent {
|
|
4930
|
+
* ngOnInit() {
|
|
4931
|
+
* // ERROR: too late, the component instance was already created
|
|
4932
|
+
* const engine = inject(Engine);
|
|
4933
|
+
* engine.start();
|
|
4934
|
+
* }
|
|
4935
|
+
* }
|
|
4936
|
+
* ```
|
|
4896
4937
|
*
|
|
4897
4938
|
* @publicApi
|
|
4898
4939
|
*/
|
|
4899
|
-
|
|
4940
|
+
function inject(token, flags = InjectFlags.Default) {
|
|
4941
|
+
return ɵɵinject(token, flags);
|
|
4942
|
+
}
|
|
4900
4943
|
function injectArgs(types) {
|
|
4901
4944
|
const args = [];
|
|
4902
4945
|
for (let i = 0; i < types.length; i++) {
|
|
@@ -6292,6 +6335,155 @@ function getSanitizer() {
|
|
|
6292
6335
|
return lView && lView[SANITIZER];
|
|
6293
6336
|
}
|
|
6294
6337
|
|
|
6338
|
+
/**
|
|
6339
|
+
* @license
|
|
6340
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6341
|
+
*
|
|
6342
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6343
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6344
|
+
*/
|
|
6345
|
+
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
6346
|
+
function wrappedError(message, originalError) {
|
|
6347
|
+
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
6348
|
+
const error = Error(msg);
|
|
6349
|
+
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
6350
|
+
return error;
|
|
6351
|
+
}
|
|
6352
|
+
function getOriginalError(error) {
|
|
6353
|
+
return error[ERROR_ORIGINAL_ERROR];
|
|
6354
|
+
}
|
|
6355
|
+
|
|
6356
|
+
/**
|
|
6357
|
+
* @license
|
|
6358
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6359
|
+
*
|
|
6360
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6361
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6362
|
+
*/
|
|
6363
|
+
/**
|
|
6364
|
+
* Provides a hook for centralized exception handling.
|
|
6365
|
+
*
|
|
6366
|
+
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
6367
|
+
* intercept error handling, write a custom exception handler that replaces this default as
|
|
6368
|
+
* appropriate for your app.
|
|
6369
|
+
*
|
|
6370
|
+
* @usageNotes
|
|
6371
|
+
* ### Example
|
|
6372
|
+
*
|
|
6373
|
+
* ```
|
|
6374
|
+
* class MyErrorHandler implements ErrorHandler {
|
|
6375
|
+
* handleError(error) {
|
|
6376
|
+
* // do something with the exception
|
|
6377
|
+
* }
|
|
6378
|
+
* }
|
|
6379
|
+
*
|
|
6380
|
+
* @NgModule({
|
|
6381
|
+
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
6382
|
+
* })
|
|
6383
|
+
* class MyModule {}
|
|
6384
|
+
* ```
|
|
6385
|
+
*
|
|
6386
|
+
* @publicApi
|
|
6387
|
+
*/
|
|
6388
|
+
class ErrorHandler {
|
|
6389
|
+
constructor() {
|
|
6390
|
+
/**
|
|
6391
|
+
* @internal
|
|
6392
|
+
*/
|
|
6393
|
+
this._console = console;
|
|
6394
|
+
}
|
|
6395
|
+
handleError(error) {
|
|
6396
|
+
const originalError = this._findOriginalError(error);
|
|
6397
|
+
this._console.error('ERROR', error);
|
|
6398
|
+
if (originalError) {
|
|
6399
|
+
this._console.error('ORIGINAL ERROR', originalError);
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
/** @internal */
|
|
6403
|
+
_findOriginalError(error) {
|
|
6404
|
+
let e = error && getOriginalError(error);
|
|
6405
|
+
while (e && getOriginalError(e)) {
|
|
6406
|
+
e = getOriginalError(e);
|
|
6407
|
+
}
|
|
6408
|
+
return e || null;
|
|
6409
|
+
}
|
|
6410
|
+
}
|
|
6411
|
+
|
|
6412
|
+
/**
|
|
6413
|
+
* @license
|
|
6414
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6415
|
+
*
|
|
6416
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6417
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6418
|
+
*/
|
|
6419
|
+
/**
|
|
6420
|
+
* Disallowed strings in the comment.
|
|
6421
|
+
*
|
|
6422
|
+
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6423
|
+
*/
|
|
6424
|
+
const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
|
|
6425
|
+
/**
|
|
6426
|
+
* Delimiter in the disallowed strings which needs to be wrapped with zero with character.
|
|
6427
|
+
*/
|
|
6428
|
+
const COMMENT_DELIMITER = /(<|>)/;
|
|
6429
|
+
const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
|
|
6430
|
+
/**
|
|
6431
|
+
* Escape the content of comment strings so that it can be safely inserted into a comment node.
|
|
6432
|
+
*
|
|
6433
|
+
* The issue is that HTML does not specify any way to escape comment end text inside the comment.
|
|
6434
|
+
* Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
|
|
6435
|
+
* "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
|
|
6436
|
+
* can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
|
|
6437
|
+
*
|
|
6438
|
+
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6439
|
+
*
|
|
6440
|
+
* ```
|
|
6441
|
+
* div.innerHTML = div.innerHTML
|
|
6442
|
+
* ```
|
|
6443
|
+
*
|
|
6444
|
+
* One would expect that the above code would be safe to do, but it turns out that because comment
|
|
6445
|
+
* text is not escaped, the comment may contain text which will prematurely close the comment
|
|
6446
|
+
* opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
|
|
6447
|
+
* may contain such text and expect them to be safe.)
|
|
6448
|
+
*
|
|
6449
|
+
* This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
|
|
6450
|
+
* surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
|
|
6451
|
+
* comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
|
|
6452
|
+
* text it will render normally but it will not cause the HTML parser to close/open the comment.
|
|
6453
|
+
*
|
|
6454
|
+
* @param value text to make safe for comment node by escaping the comment open/close character
|
|
6455
|
+
* sequence.
|
|
6456
|
+
*/
|
|
6457
|
+
function escapeCommentText(value) {
|
|
6458
|
+
return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
|
|
6459
|
+
}
|
|
6460
|
+
|
|
6461
|
+
/**
|
|
6462
|
+
* @license
|
|
6463
|
+
* Copyright Google LLC All Rights Reserved.
|
|
6464
|
+
*
|
|
6465
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6466
|
+
* found in the LICENSE file at https://angular.io/license
|
|
6467
|
+
*/
|
|
6468
|
+
function normalizeDebugBindingName(name) {
|
|
6469
|
+
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
6470
|
+
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
6471
|
+
return `ng-reflect-${name}`;
|
|
6472
|
+
}
|
|
6473
|
+
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
|
6474
|
+
function camelCaseToDashCase(input) {
|
|
6475
|
+
return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
|
|
6476
|
+
}
|
|
6477
|
+
function normalizeDebugBindingValue(value) {
|
|
6478
|
+
try {
|
|
6479
|
+
// Limit the size of the value as otherwise the DOM just gets polluted.
|
|
6480
|
+
return value != null ? value.toString().slice(0, 30) : value;
|
|
6481
|
+
}
|
|
6482
|
+
catch (e) {
|
|
6483
|
+
return '[ERROR] Exception while trying to serialize the value';
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
|
|
6295
6487
|
/**
|
|
6296
6488
|
* @license
|
|
6297
6489
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -6651,212 +6843,22 @@ function getComponentAtNodeIndex(nodeIndex, lView) {
|
|
|
6651
6843
|
let directiveStartIndex = tNode.directiveStart;
|
|
6652
6844
|
return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
|
|
6653
6845
|
}
|
|
6654
|
-
/**
|
|
6655
|
-
* Returns a map of local references (local reference name => element or directive instance) that
|
|
6656
|
-
* exist on a given element.
|
|
6657
|
-
*/
|
|
6658
|
-
function discoverLocalRefs(lView, nodeIndex) {
|
|
6659
|
-
const tNode = lView[TVIEW].data[nodeIndex];
|
|
6660
|
-
if (tNode && tNode.localNames) {
|
|
6661
|
-
const result = {};
|
|
6662
|
-
let localIndex = tNode.index + 1;
|
|
6663
|
-
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
6664
|
-
result[tNode.localNames[i]] = lView[localIndex];
|
|
6665
|
-
localIndex++;
|
|
6666
|
-
}
|
|
6667
|
-
return result;
|
|
6668
|
-
}
|
|
6669
|
-
return null;
|
|
6670
|
-
}
|
|
6671
|
-
|
|
6672
|
-
/**
|
|
6673
|
-
* @license
|
|
6674
|
-
* Copyright Google LLC All Rights Reserved.
|
|
6675
|
-
*
|
|
6676
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6677
|
-
* found in the LICENSE file at https://angular.io/license
|
|
6678
|
-
*/
|
|
6679
|
-
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
|
6680
|
-
const ERROR_LOGGER = 'ngErrorLogger';
|
|
6681
|
-
function wrappedError(message, originalError) {
|
|
6682
|
-
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
6683
|
-
const error = Error(msg);
|
|
6684
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
6685
|
-
return error;
|
|
6686
|
-
}
|
|
6687
|
-
function getOriginalError(error) {
|
|
6688
|
-
return error[ERROR_ORIGINAL_ERROR];
|
|
6689
|
-
}
|
|
6690
|
-
function getErrorLogger(error) {
|
|
6691
|
-
return error && error[ERROR_LOGGER] || defaultErrorLogger;
|
|
6692
|
-
}
|
|
6693
|
-
function defaultErrorLogger(console, ...values) {
|
|
6694
|
-
console.error(...values);
|
|
6695
|
-
}
|
|
6696
|
-
|
|
6697
|
-
/**
|
|
6698
|
-
* @license
|
|
6699
|
-
* Copyright Google LLC All Rights Reserved.
|
|
6700
|
-
*
|
|
6701
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6702
|
-
* found in the LICENSE file at https://angular.io/license
|
|
6703
|
-
*/
|
|
6704
|
-
/**
|
|
6705
|
-
* Provides a hook for centralized exception handling.
|
|
6706
|
-
*
|
|
6707
|
-
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
|
|
6708
|
-
* intercept error handling, write a custom exception handler that replaces this default as
|
|
6709
|
-
* appropriate for your app.
|
|
6710
|
-
*
|
|
6711
|
-
* @usageNotes
|
|
6712
|
-
* ### Example
|
|
6713
|
-
*
|
|
6714
|
-
* ```
|
|
6715
|
-
* class MyErrorHandler implements ErrorHandler {
|
|
6716
|
-
* handleError(error) {
|
|
6717
|
-
* // do something with the exception
|
|
6718
|
-
* }
|
|
6719
|
-
* }
|
|
6720
|
-
*
|
|
6721
|
-
* @NgModule({
|
|
6722
|
-
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
|
|
6723
|
-
* })
|
|
6724
|
-
* class MyModule {}
|
|
6725
|
-
* ```
|
|
6726
|
-
*
|
|
6727
|
-
* @publicApi
|
|
6728
|
-
*/
|
|
6729
|
-
class ErrorHandler {
|
|
6730
|
-
constructor() {
|
|
6731
|
-
/**
|
|
6732
|
-
* @internal
|
|
6733
|
-
*/
|
|
6734
|
-
this._console = console;
|
|
6735
|
-
}
|
|
6736
|
-
handleError(error) {
|
|
6737
|
-
const originalError = this._findOriginalError(error);
|
|
6738
|
-
// Note: Browser consoles show the place from where console.error was called.
|
|
6739
|
-
// We can use this to give users additional information about the error.
|
|
6740
|
-
const errorLogger = getErrorLogger(error);
|
|
6741
|
-
errorLogger(this._console, `ERROR`, error);
|
|
6742
|
-
if (originalError) {
|
|
6743
|
-
errorLogger(this._console, `ORIGINAL ERROR`, originalError);
|
|
6744
|
-
}
|
|
6745
|
-
}
|
|
6746
|
-
/** @internal */
|
|
6747
|
-
_findOriginalError(error) {
|
|
6748
|
-
let e = error && getOriginalError(error);
|
|
6749
|
-
while (e && getOriginalError(e)) {
|
|
6750
|
-
e = getOriginalError(e);
|
|
6751
|
-
}
|
|
6752
|
-
return e || null;
|
|
6753
|
-
}
|
|
6754
|
-
}
|
|
6755
|
-
|
|
6756
|
-
/**
|
|
6757
|
-
* @license
|
|
6758
|
-
* Copyright Google LLC All Rights Reserved.
|
|
6759
|
-
*
|
|
6760
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6761
|
-
* found in the LICENSE file at https://angular.io/license
|
|
6762
|
-
*/
|
|
6763
|
-
/**
|
|
6764
|
-
* Defines a schema that allows an NgModule to contain the following:
|
|
6765
|
-
* - Non-Angular elements named with dash case (`-`).
|
|
6766
|
-
* - Element properties named with dash case (`-`).
|
|
6767
|
-
* Dash case is the naming convention for custom elements.
|
|
6768
|
-
*
|
|
6769
|
-
* @publicApi
|
|
6770
|
-
*/
|
|
6771
|
-
const CUSTOM_ELEMENTS_SCHEMA = {
|
|
6772
|
-
name: 'custom-elements'
|
|
6773
|
-
};
|
|
6774
|
-
/**
|
|
6775
|
-
* Defines a schema that allows any property on any element.
|
|
6776
|
-
*
|
|
6777
|
-
* This schema allows you to ignore the errors related to any unknown elements or properties in a
|
|
6778
|
-
* template. The usage of this schema is generally discouraged because it prevents useful validation
|
|
6779
|
-
* and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
|
|
6780
|
-
*
|
|
6781
|
-
* @publicApi
|
|
6782
|
-
*/
|
|
6783
|
-
const NO_ERRORS_SCHEMA = {
|
|
6784
|
-
name: 'no-errors-schema'
|
|
6785
|
-
};
|
|
6786
|
-
|
|
6787
|
-
/**
|
|
6788
|
-
* @license
|
|
6789
|
-
* Copyright Google LLC All Rights Reserved.
|
|
6790
|
-
*
|
|
6791
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6792
|
-
* found in the LICENSE file at https://angular.io/license
|
|
6793
|
-
*/
|
|
6794
|
-
/**
|
|
6795
|
-
* Disallowed strings in the comment.
|
|
6796
|
-
*
|
|
6797
|
-
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6798
|
-
*/
|
|
6799
|
-
const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
|
|
6800
|
-
/**
|
|
6801
|
-
* Delimiter in the disallowed strings which needs to be wrapped with zero with character.
|
|
6802
|
-
*/
|
|
6803
|
-
const COMMENT_DELIMITER = /(<|>)/;
|
|
6804
|
-
const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
|
|
6805
|
-
/**
|
|
6806
|
-
* Escape the content of comment strings so that it can be safely inserted into a comment node.
|
|
6807
|
-
*
|
|
6808
|
-
* The issue is that HTML does not specify any way to escape comment end text inside the comment.
|
|
6809
|
-
* Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
|
|
6810
|
-
* "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
|
|
6811
|
-
* can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
|
|
6812
|
-
*
|
|
6813
|
-
* see: https://html.spec.whatwg.org/multipage/syntax.html#comments
|
|
6814
|
-
*
|
|
6815
|
-
* ```
|
|
6816
|
-
* div.innerHTML = div.innerHTML
|
|
6817
|
-
* ```
|
|
6818
|
-
*
|
|
6819
|
-
* One would expect that the above code would be safe to do, but it turns out that because comment
|
|
6820
|
-
* text is not escaped, the comment may contain text which will prematurely close the comment
|
|
6821
|
-
* opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
|
|
6822
|
-
* may contain such text and expect them to be safe.)
|
|
6823
|
-
*
|
|
6824
|
-
* This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
|
|
6825
|
-
* surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
|
|
6826
|
-
* comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
|
|
6827
|
-
* text it will render normally but it will not cause the HTML parser to close/open the comment.
|
|
6828
|
-
*
|
|
6829
|
-
* @param value text to make safe for comment node by escaping the comment open/close character
|
|
6830
|
-
* sequence.
|
|
6831
|
-
*/
|
|
6832
|
-
function escapeCommentText(value) {
|
|
6833
|
-
return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
|
|
6834
|
-
}
|
|
6835
|
-
|
|
6836
|
-
/**
|
|
6837
|
-
* @license
|
|
6838
|
-
* Copyright Google LLC All Rights Reserved.
|
|
6839
|
-
*
|
|
6840
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6841
|
-
* found in the LICENSE file at https://angular.io/license
|
|
6842
|
-
*/
|
|
6843
|
-
function normalizeDebugBindingName(name) {
|
|
6844
|
-
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
|
|
6845
|
-
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
|
|
6846
|
-
return `ng-reflect-${name}`;
|
|
6847
|
-
}
|
|
6848
|
-
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
|
6849
|
-
function camelCaseToDashCase(input) {
|
|
6850
|
-
return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
|
|
6851
|
-
}
|
|
6852
|
-
function normalizeDebugBindingValue(value) {
|
|
6853
|
-
try {
|
|
6854
|
-
// Limit the size of the value as otherwise the DOM just gets polluted.
|
|
6855
|
-
return value != null ? value.toString().slice(0, 30) : value;
|
|
6856
|
-
}
|
|
6857
|
-
catch (e) {
|
|
6858
|
-
return '[ERROR] Exception while trying to serialize the value';
|
|
6846
|
+
/**
|
|
6847
|
+
* Returns a map of local references (local reference name => element or directive instance) that
|
|
6848
|
+
* exist on a given element.
|
|
6849
|
+
*/
|
|
6850
|
+
function discoverLocalRefs(lView, nodeIndex) {
|
|
6851
|
+
const tNode = lView[TVIEW].data[nodeIndex];
|
|
6852
|
+
if (tNode && tNode.localNames) {
|
|
6853
|
+
const result = {};
|
|
6854
|
+
let localIndex = tNode.index + 1;
|
|
6855
|
+
for (let i = 0; i < tNode.localNames.length; i += 2) {
|
|
6856
|
+
result[tNode.localNames[i]] = lView[localIndex];
|
|
6857
|
+
localIndex++;
|
|
6858
|
+
}
|
|
6859
|
+
return result;
|
|
6859
6860
|
}
|
|
6861
|
+
return null;
|
|
6860
6862
|
}
|
|
6861
6863
|
|
|
6862
6864
|
/**
|
|
@@ -8816,8 +8818,38 @@ const INJECTOR_DEF_TYPES = new InjectionToken('INJECTOR_DEF_TYPES');
|
|
|
8816
8818
|
* another environment injector (such as a route injector). They should not be used in component
|
|
8817
8819
|
* providers.
|
|
8818
8820
|
*
|
|
8819
|
-
*
|
|
8821
|
+
* More information about standalone components can be found in [this
|
|
8822
|
+
* guide](guide/standalone-components).
|
|
8823
|
+
*
|
|
8824
|
+
* @usageNotes
|
|
8825
|
+
* The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
|
|
8826
|
+
*
|
|
8827
|
+
* ```typescript
|
|
8828
|
+
* await bootstrapApplication(RootComponent, {
|
|
8829
|
+
* providers: [
|
|
8830
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
8831
|
+
* ]
|
|
8832
|
+
* });
|
|
8833
|
+
* ```
|
|
8834
|
+
*
|
|
8835
|
+
* You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
|
|
8836
|
+
* standalone component is used:
|
|
8837
|
+
*
|
|
8838
|
+
* ```typescript
|
|
8839
|
+
* export const ROUTES: Route[] = [
|
|
8840
|
+
* {
|
|
8841
|
+
* path: 'foo',
|
|
8842
|
+
* providers: [
|
|
8843
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
8844
|
+
* ],
|
|
8845
|
+
* component: YourStandaloneComponent
|
|
8846
|
+
* }
|
|
8847
|
+
* ];
|
|
8848
|
+
* ```
|
|
8849
|
+
*
|
|
8850
|
+
* @returns Collected providers from the specified list of types.
|
|
8820
8851
|
* @publicApi
|
|
8852
|
+
* @developerPreview
|
|
8821
8853
|
*/
|
|
8822
8854
|
function importProvidersFrom(...sources) {
|
|
8823
8855
|
return { ɵproviders: internalImportProvidersFrom(true, sources) };
|
|
@@ -9095,6 +9127,8 @@ function getNullInjector() {
|
|
|
9095
9127
|
/**
|
|
9096
9128
|
* An `Injector` that's part of the environment injector hierarchy, which exists outside of the
|
|
9097
9129
|
* component tree.
|
|
9130
|
+
*
|
|
9131
|
+
* @developerPreview
|
|
9098
9132
|
*/
|
|
9099
9133
|
class EnvironmentInjector {
|
|
9100
9134
|
}
|
|
@@ -10320,59 +10354,349 @@ function _mapProviders(injector, fn) {
|
|
|
10320
10354
|
for (let i = 0; i < injector._providers.length; ++i) {
|
|
10321
10355
|
res[i] = fn(injector.getProviderAtIndex(i));
|
|
10322
10356
|
}
|
|
10323
|
-
return res;
|
|
10357
|
+
return res;
|
|
10358
|
+
}
|
|
10359
|
+
|
|
10360
|
+
/**
|
|
10361
|
+
* @license
|
|
10362
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10363
|
+
*
|
|
10364
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10365
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10366
|
+
*/
|
|
10367
|
+
|
|
10368
|
+
/**
|
|
10369
|
+
* @license
|
|
10370
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10371
|
+
*
|
|
10372
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10373
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10374
|
+
*/
|
|
10375
|
+
|
|
10376
|
+
/**
|
|
10377
|
+
* @license
|
|
10378
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10379
|
+
*
|
|
10380
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10381
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10382
|
+
*/
|
|
10383
|
+
function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
|
|
10384
|
+
const lView = getLView();
|
|
10385
|
+
// Fall back to inject() if view hasn't been created. This situation can happen in tests
|
|
10386
|
+
// if inject utilities are used before bootstrapping.
|
|
10387
|
+
if (lView === null) {
|
|
10388
|
+
// Verify that we will not get into infinite loop.
|
|
10389
|
+
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
|
10390
|
+
return ɵɵinject(token, flags);
|
|
10391
|
+
}
|
|
10392
|
+
const tNode = getCurrentTNode();
|
|
10393
|
+
return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
10394
|
+
}
|
|
10395
|
+
/**
|
|
10396
|
+
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
10397
|
+
* particular class.
|
|
10398
|
+
*
|
|
10399
|
+
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
10400
|
+
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
10401
|
+
*
|
|
10402
|
+
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
10403
|
+
* and thus in the stack trace.
|
|
10404
|
+
*
|
|
10405
|
+
* @codeGenApi
|
|
10406
|
+
*/
|
|
10407
|
+
function ɵɵinvalidFactory() {
|
|
10408
|
+
const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
|
|
10409
|
+
throw new Error(msg);
|
|
10410
|
+
}
|
|
10411
|
+
|
|
10412
|
+
/**
|
|
10413
|
+
* @license
|
|
10414
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10415
|
+
*
|
|
10416
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10417
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10418
|
+
*/
|
|
10419
|
+
/**
|
|
10420
|
+
* Defines a schema that allows an NgModule to contain the following:
|
|
10421
|
+
* - Non-Angular elements named with dash case (`-`).
|
|
10422
|
+
* - Element properties named with dash case (`-`).
|
|
10423
|
+
* Dash case is the naming convention for custom elements.
|
|
10424
|
+
*
|
|
10425
|
+
* @publicApi
|
|
10426
|
+
*/
|
|
10427
|
+
const CUSTOM_ELEMENTS_SCHEMA = {
|
|
10428
|
+
name: 'custom-elements'
|
|
10429
|
+
};
|
|
10430
|
+
/**
|
|
10431
|
+
* Defines a schema that allows any property on any element.
|
|
10432
|
+
*
|
|
10433
|
+
* This schema allows you to ignore the errors related to any unknown elements or properties in a
|
|
10434
|
+
* template. The usage of this schema is generally discouraged because it prevents useful validation
|
|
10435
|
+
* and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
|
|
10436
|
+
*
|
|
10437
|
+
* @publicApi
|
|
10438
|
+
*/
|
|
10439
|
+
const NO_ERRORS_SCHEMA = {
|
|
10440
|
+
name: 'no-errors-schema'
|
|
10441
|
+
};
|
|
10442
|
+
|
|
10443
|
+
/**
|
|
10444
|
+
* @license
|
|
10445
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10446
|
+
*
|
|
10447
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10448
|
+
* found in the LICENSE file at https://angular.io/license
|
|
10449
|
+
*/
|
|
10450
|
+
let shouldThrowErrorOnUnknownElement = false;
|
|
10451
|
+
/**
|
|
10452
|
+
* Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
|
|
10453
|
+
* instead of just logging the error.
|
|
10454
|
+
* (for AOT-compiled ones this check happens at build time).
|
|
10455
|
+
*/
|
|
10456
|
+
function ɵsetUnknownElementStrictMode(shouldThrow) {
|
|
10457
|
+
shouldThrowErrorOnUnknownElement = shouldThrow;
|
|
10458
|
+
}
|
|
10459
|
+
/**
|
|
10460
|
+
* Gets the current value of the strict mode.
|
|
10461
|
+
*/
|
|
10462
|
+
function ɵgetUnknownElementStrictMode() {
|
|
10463
|
+
return shouldThrowErrorOnUnknownElement;
|
|
10464
|
+
}
|
|
10465
|
+
let shouldThrowErrorOnUnknownProperty = false;
|
|
10466
|
+
/**
|
|
10467
|
+
* Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
|
|
10468
|
+
* instead of just logging the error.
|
|
10469
|
+
* (for AOT-compiled ones this check happens at build time).
|
|
10470
|
+
*/
|
|
10471
|
+
function ɵsetUnknownPropertyStrictMode(shouldThrow) {
|
|
10472
|
+
shouldThrowErrorOnUnknownProperty = shouldThrow;
|
|
10473
|
+
}
|
|
10474
|
+
/**
|
|
10475
|
+
* Gets the current value of the strict mode.
|
|
10476
|
+
*/
|
|
10477
|
+
function ɵgetUnknownPropertyStrictMode() {
|
|
10478
|
+
return shouldThrowErrorOnUnknownProperty;
|
|
10479
|
+
}
|
|
10480
|
+
/**
|
|
10481
|
+
* Validates that the element is known at runtime and produces
|
|
10482
|
+
* an error if it's not the case.
|
|
10483
|
+
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
10484
|
+
* ones this check happens at build time).
|
|
10485
|
+
*
|
|
10486
|
+
* The element is considered known if either:
|
|
10487
|
+
* - it's a known HTML element
|
|
10488
|
+
* - it's a known custom element
|
|
10489
|
+
* - the element matches any directive
|
|
10490
|
+
* - the element is allowed by one of the schemas
|
|
10491
|
+
*
|
|
10492
|
+
* @param element Element to validate
|
|
10493
|
+
* @param lView An `LView` that represents a current component that is being rendered
|
|
10494
|
+
* @param tagName Name of the tag to check
|
|
10495
|
+
* @param schemas Array of schemas
|
|
10496
|
+
* @param hasDirectives Boolean indicating that the element matches any directive
|
|
10497
|
+
*/
|
|
10498
|
+
function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
|
|
10499
|
+
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
10500
|
+
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
10501
|
+
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
10502
|
+
// execute the check below.
|
|
10503
|
+
if (schemas === null)
|
|
10504
|
+
return;
|
|
10505
|
+
// If the element matches any directive, it's considered as valid.
|
|
10506
|
+
if (!hasDirectives && tagName !== null) {
|
|
10507
|
+
// The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
|
|
10508
|
+
// as a custom element. Note that unknown elements with a dash in their name won't be instances
|
|
10509
|
+
// of HTMLUnknownElement in browsers that support web components.
|
|
10510
|
+
const isUnknown =
|
|
10511
|
+
// Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
|
|
10512
|
+
// because while most browsers return 'function', IE returns 'object'.
|
|
10513
|
+
(typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
|
|
10514
|
+
element instanceof HTMLUnknownElement) ||
|
|
10515
|
+
(typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
|
|
10516
|
+
!customElements.get(tagName));
|
|
10517
|
+
if (isUnknown && !matchingSchemas(schemas, tagName)) {
|
|
10518
|
+
const isHostStandalone = isHostComponentStandalone(lView);
|
|
10519
|
+
const templateLocation = getTemplateLocationDetails(lView);
|
|
10520
|
+
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
10521
|
+
let message = `'${tagName}' is not a known element${templateLocation}:\n`;
|
|
10522
|
+
message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
10523
|
+
'a part of an @NgModule where this component is declared'}.\n`;
|
|
10524
|
+
if (tagName && tagName.indexOf('-') > -1) {
|
|
10525
|
+
message +=
|
|
10526
|
+
`2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
|
|
10527
|
+
}
|
|
10528
|
+
else {
|
|
10529
|
+
message +=
|
|
10530
|
+
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
|
|
10531
|
+
}
|
|
10532
|
+
if (shouldThrowErrorOnUnknownElement) {
|
|
10533
|
+
throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
|
|
10534
|
+
}
|
|
10535
|
+
else {
|
|
10536
|
+
console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
|
|
10537
|
+
}
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
}
|
|
10541
|
+
/**
|
|
10542
|
+
* Validates that the property of the element is known at runtime and returns
|
|
10543
|
+
* false if it's not the case.
|
|
10544
|
+
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
10545
|
+
* ones this check happens at build time).
|
|
10546
|
+
*
|
|
10547
|
+
* The property is considered known if either:
|
|
10548
|
+
* - it's a known property of the element
|
|
10549
|
+
* - the element is allowed by one of the schemas
|
|
10550
|
+
* - the property is used for animations
|
|
10551
|
+
*
|
|
10552
|
+
* @param element Element to validate
|
|
10553
|
+
* @param propName Name of the property to check
|
|
10554
|
+
* @param tagName Name of the tag hosting the property
|
|
10555
|
+
* @param schemas Array of schemas
|
|
10556
|
+
*/
|
|
10557
|
+
function isPropertyValid(element, propName, tagName, schemas) {
|
|
10558
|
+
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
10559
|
+
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
10560
|
+
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
10561
|
+
// execute the check below.
|
|
10562
|
+
if (schemas === null)
|
|
10563
|
+
return true;
|
|
10564
|
+
// The property is considered valid if the element matches the schema, it exists on the element,
|
|
10565
|
+
// or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
|
|
10566
|
+
if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
|
|
10567
|
+
return true;
|
|
10568
|
+
}
|
|
10569
|
+
// Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
|
|
10570
|
+
// need to account for both here, while being careful with `typeof null` also returning 'object'.
|
|
10571
|
+
return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
|
|
10572
|
+
}
|
|
10573
|
+
/**
|
|
10574
|
+
* Logs or throws an error that a property is not supported on an element.
|
|
10575
|
+
*
|
|
10576
|
+
* @param propName Name of the invalid property
|
|
10577
|
+
* @param tagName Name of the tag hosting the property
|
|
10578
|
+
* @param nodeType Type of the node hosting the property
|
|
10579
|
+
* @param lView An `LView` that represents a current component
|
|
10580
|
+
*/
|
|
10581
|
+
function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
|
|
10582
|
+
// Special-case a situation when a structural directive is applied to
|
|
10583
|
+
// an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
|
|
10584
|
+
// In this case the compiler generates the `ɵɵtemplate` instruction with
|
|
10585
|
+
// the `null` as the tagName. The directive matching logic at runtime relies
|
|
10586
|
+
// on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
|
|
10587
|
+
// a default value of the `tNode.value` is not feasible at this moment.
|
|
10588
|
+
if (!tagName && nodeType === 4 /* TNodeType.Container */) {
|
|
10589
|
+
tagName = 'ng-template';
|
|
10590
|
+
}
|
|
10591
|
+
const isHostStandalone = isHostComponentStandalone(lView);
|
|
10592
|
+
const templateLocation = getTemplateLocationDetails(lView);
|
|
10593
|
+
let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
|
|
10594
|
+
const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
10595
|
+
const importLocation = isHostStandalone ?
|
|
10596
|
+
'included in the \'@Component.imports\' of this component' :
|
|
10597
|
+
'a part of an @NgModule where this component is declared';
|
|
10598
|
+
if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
|
|
10599
|
+
// Most likely this is a control flow directive (such as `*ngIf`) used in
|
|
10600
|
+
// a template, but the `CommonModule` is not imported.
|
|
10601
|
+
message += `\nIf the '${propName}' is an Angular control flow directive, ` +
|
|
10602
|
+
`please make sure that the 'CommonModule' is ${importLocation}.`;
|
|
10603
|
+
}
|
|
10604
|
+
else {
|
|
10605
|
+
// May be an Angular component, which is not imported/declared?
|
|
10606
|
+
message += `\n1. If '${tagName}' is an Angular component and it has the ` +
|
|
10607
|
+
`'${propName}' input, then verify that it is ${importLocation}.`;
|
|
10608
|
+
// May be a Web Component?
|
|
10609
|
+
if (tagName && tagName.indexOf('-') > -1) {
|
|
10610
|
+
message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
|
|
10611
|
+
`to the ${schemas} of this component to suppress this message.`;
|
|
10612
|
+
message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
10613
|
+
`the ${schemas} of this component.`;
|
|
10614
|
+
}
|
|
10615
|
+
else {
|
|
10616
|
+
// If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
|
|
10617
|
+
message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
|
|
10618
|
+
`the ${schemas} of this component.`;
|
|
10619
|
+
}
|
|
10620
|
+
}
|
|
10621
|
+
if (shouldThrowErrorOnUnknownProperty) {
|
|
10622
|
+
throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
|
|
10623
|
+
}
|
|
10624
|
+
else {
|
|
10625
|
+
console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
|
|
10626
|
+
}
|
|
10324
10627
|
}
|
|
10325
|
-
|
|
10326
10628
|
/**
|
|
10327
|
-
*
|
|
10328
|
-
*
|
|
10629
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10630
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10631
|
+
* be too slow for production mode and also it relies on the constructor function being available.
|
|
10329
10632
|
*
|
|
10330
|
-
*
|
|
10331
|
-
* found in the LICENSE file at https://angular.io/license
|
|
10332
|
-
*/
|
|
10333
|
-
|
|
10334
|
-
/**
|
|
10335
|
-
* @license
|
|
10336
|
-
* Copyright Google LLC All Rights Reserved.
|
|
10633
|
+
* Gets a reference to the host component def (where a current component is declared).
|
|
10337
10634
|
*
|
|
10338
|
-
*
|
|
10339
|
-
* found in the LICENSE file at https://angular.io/license
|
|
10635
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10340
10636
|
*/
|
|
10341
|
-
|
|
10637
|
+
function getDeclarationComponentDef(lView) {
|
|
10638
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10639
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
10640
|
+
const context = declarationLView[CONTEXT];
|
|
10641
|
+
// Unable to obtain a context.
|
|
10642
|
+
if (!context)
|
|
10643
|
+
return null;
|
|
10644
|
+
return context.constructor ? getComponentDef(context.constructor) : null;
|
|
10645
|
+
}
|
|
10342
10646
|
/**
|
|
10343
|
-
*
|
|
10344
|
-
*
|
|
10647
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10648
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10649
|
+
* be too slow for production mode.
|
|
10345
10650
|
*
|
|
10346
|
-
*
|
|
10347
|
-
*
|
|
10651
|
+
* Checks if the current component is declared inside of a standalone component template.
|
|
10652
|
+
*
|
|
10653
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10348
10654
|
*/
|
|
10349
|
-
function
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
// if
|
|
10353
|
-
|
|
10354
|
-
// Verify that we will not get into infinite loop.
|
|
10355
|
-
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
|
10356
|
-
return ɵɵinject(token, flags);
|
|
10357
|
-
}
|
|
10358
|
-
const tNode = getCurrentTNode();
|
|
10359
|
-
return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
|
|
10655
|
+
function isHostComponentStandalone(lView) {
|
|
10656
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10657
|
+
const componentDef = getDeclarationComponentDef(lView);
|
|
10658
|
+
// Treat host component as non-standalone if we can't obtain the def.
|
|
10659
|
+
return !!(componentDef === null || componentDef === void 0 ? void 0 : componentDef.standalone);
|
|
10360
10660
|
}
|
|
10361
10661
|
/**
|
|
10362
|
-
*
|
|
10363
|
-
*
|
|
10364
|
-
*
|
|
10365
|
-
* This instruction allows the actual error message to be optimized away when ngDevMode is turned
|
|
10366
|
-
* off, saving bytes of generated code while still providing a good experience in dev mode.
|
|
10662
|
+
* WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
|
|
10663
|
+
* and must **not** be used in production bundles. The function makes megamorphic reads, which might
|
|
10664
|
+
* be too slow for production mode.
|
|
10367
10665
|
*
|
|
10368
|
-
*
|
|
10369
|
-
*
|
|
10666
|
+
* Constructs a string describing the location of the host component template. The function is used
|
|
10667
|
+
* in dev mode to produce error messages.
|
|
10370
10668
|
*
|
|
10371
|
-
* @
|
|
10669
|
+
* @param lView An `LView` that represents a current component that is being rendered.
|
|
10372
10670
|
*/
|
|
10373
|
-
function
|
|
10374
|
-
|
|
10375
|
-
|
|
10671
|
+
function getTemplateLocationDetails(lView) {
|
|
10672
|
+
var _a;
|
|
10673
|
+
!ngDevMode && throwError('Must never be called in production mode');
|
|
10674
|
+
const hostComponentDef = getDeclarationComponentDef(lView);
|
|
10675
|
+
const componentClassName = (_a = hostComponentDef === null || hostComponentDef === void 0 ? void 0 : hostComponentDef.type) === null || _a === void 0 ? void 0 : _a.name;
|
|
10676
|
+
return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
|
|
10677
|
+
}
|
|
10678
|
+
/**
|
|
10679
|
+
* The set of known control flow directives.
|
|
10680
|
+
* We use this set to produce a more precises error message with a note
|
|
10681
|
+
* that the `CommonModule` should also be included.
|
|
10682
|
+
*/
|
|
10683
|
+
const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
|
|
10684
|
+
/**
|
|
10685
|
+
* Returns true if the tag name is allowed by specified schemas.
|
|
10686
|
+
* @param schemas Array of schemas
|
|
10687
|
+
* @param tagName Name of the tag
|
|
10688
|
+
*/
|
|
10689
|
+
function matchingSchemas(schemas, tagName) {
|
|
10690
|
+
if (schemas !== null) {
|
|
10691
|
+
for (let i = 0; i < schemas.length; i++) {
|
|
10692
|
+
const schema = schemas[i];
|
|
10693
|
+
if (schema === NO_ERRORS_SCHEMA ||
|
|
10694
|
+
schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
|
|
10695
|
+
return true;
|
|
10696
|
+
}
|
|
10697
|
+
}
|
|
10698
|
+
}
|
|
10699
|
+
return false;
|
|
10376
10700
|
}
|
|
10377
10701
|
|
|
10378
10702
|
/**
|
|
@@ -11181,21 +11505,6 @@ class LContainerDebug {
|
|
|
11181
11505
|
}
|
|
11182
11506
|
}
|
|
11183
11507
|
|
|
11184
|
-
let shouldThrowErrorOnUnknownProperty = false;
|
|
11185
|
-
/**
|
|
11186
|
-
* Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
|
|
11187
|
-
* instead of just logging the error.
|
|
11188
|
-
* (for AOT-compiled ones this check happens at build time).
|
|
11189
|
-
*/
|
|
11190
|
-
function ɵsetUnknownPropertyStrictMode(shouldThrow) {
|
|
11191
|
-
shouldThrowErrorOnUnknownProperty = shouldThrow;
|
|
11192
|
-
}
|
|
11193
|
-
/**
|
|
11194
|
-
* Gets the current value of the strict mode.
|
|
11195
|
-
*/
|
|
11196
|
-
function ɵgetUnknownPropertyStrictMode() {
|
|
11197
|
-
return shouldThrowErrorOnUnknownProperty;
|
|
11198
|
-
}
|
|
11199
11508
|
/**
|
|
11200
11509
|
* A permanent marker promise which signifies that the current CD tree is
|
|
11201
11510
|
* clean.
|
|
@@ -11354,21 +11663,6 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
|
|
|
11354
11663
|
}
|
|
11355
11664
|
return tNode;
|
|
11356
11665
|
}
|
|
11357
|
-
/**
|
|
11358
|
-
* Checks if the current component is declared inside of a standalone component template.
|
|
11359
|
-
*
|
|
11360
|
-
* @param lView An `LView` that represents a current component that is being rendered.
|
|
11361
|
-
*/
|
|
11362
|
-
function isHostComponentStandalone(lView) {
|
|
11363
|
-
!ngDevMode && throwError('Must never be called in production mode');
|
|
11364
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
11365
|
-
const context = declarationLView[CONTEXT];
|
|
11366
|
-
// Unable to obtain a context, fall back to the non-standalone scenario.
|
|
11367
|
-
if (!context)
|
|
11368
|
-
return false;
|
|
11369
|
-
const componentDef = getComponentDef(context.constructor);
|
|
11370
|
-
return !!(componentDef === null || componentDef === void 0 ? void 0 : componentDef.standalone);
|
|
11371
|
-
}
|
|
11372
11666
|
/**
|
|
11373
11667
|
* When elements are created dynamically after a view blueprint is created (e.g. through
|
|
11374
11668
|
* i18nApply()), we need to adjust the blueprint for future
|
|
@@ -12035,10 +12329,8 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
|
|
|
12035
12329
|
propName = mapPropName(propName);
|
|
12036
12330
|
if (ngDevMode) {
|
|
12037
12331
|
validateAgainstEventProperties(propName);
|
|
12038
|
-
if (!
|
|
12039
|
-
|
|
12040
|
-
handleUnknownPropertyError(propName, tNode);
|
|
12041
|
-
return;
|
|
12332
|
+
if (!isPropertyValid(element, propName, tNode.value, tView.schemas)) {
|
|
12333
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
12042
12334
|
}
|
|
12043
12335
|
ngDevMode.rendererSetProperty++;
|
|
12044
12336
|
}
|
|
@@ -12057,7 +12349,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
|
|
|
12057
12349
|
// If the node is a container and the property didn't
|
|
12058
12350
|
// match any of the inputs or schemas we should throw.
|
|
12059
12351
|
if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
|
|
12060
|
-
handleUnknownPropertyError(propName, tNode);
|
|
12352
|
+
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
12061
12353
|
}
|
|
12062
12354
|
}
|
|
12063
12355
|
}
|
|
@@ -12109,79 +12401,6 @@ function setNgReflectProperties(lView, element, type, dataValue, value) {
|
|
|
12109
12401
|
}
|
|
12110
12402
|
}
|
|
12111
12403
|
}
|
|
12112
|
-
/**
|
|
12113
|
-
* Validates that the property of the element is known at runtime and returns
|
|
12114
|
-
* false if it's not the case.
|
|
12115
|
-
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
12116
|
-
* ones this check happens at build time).
|
|
12117
|
-
*
|
|
12118
|
-
* The property is considered known if either:
|
|
12119
|
-
* - it's a known property of the element
|
|
12120
|
-
* - the element is allowed by one of the schemas
|
|
12121
|
-
* - the property is used for animations
|
|
12122
|
-
*
|
|
12123
|
-
* @param element Element to validate
|
|
12124
|
-
* @param tagName Name of the tag to check
|
|
12125
|
-
* @param propName Name of the property to check
|
|
12126
|
-
* @param schemas Array of schemas
|
|
12127
|
-
*/
|
|
12128
|
-
function validateProperty(element, tagName, propName, schemas) {
|
|
12129
|
-
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
12130
|
-
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
12131
|
-
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
12132
|
-
// execute the check below.
|
|
12133
|
-
if (schemas === null)
|
|
12134
|
-
return true;
|
|
12135
|
-
// The property is considered valid if the element matches the schema, it exists on the element,
|
|
12136
|
-
// or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
|
|
12137
|
-
if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
|
|
12138
|
-
return true;
|
|
12139
|
-
}
|
|
12140
|
-
// Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
|
|
12141
|
-
// need to account for both here, while being careful with `typeof null` also returning 'object'.
|
|
12142
|
-
return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
|
|
12143
|
-
}
|
|
12144
|
-
/**
|
|
12145
|
-
* Returns true if the tag name is allowed by specified schemas.
|
|
12146
|
-
* @param schemas Array of schemas
|
|
12147
|
-
* @param tagName Name of the tag
|
|
12148
|
-
*/
|
|
12149
|
-
function matchingSchemas(schemas, tagName) {
|
|
12150
|
-
if (schemas !== null) {
|
|
12151
|
-
for (let i = 0; i < schemas.length; i++) {
|
|
12152
|
-
const schema = schemas[i];
|
|
12153
|
-
if (schema === NO_ERRORS_SCHEMA ||
|
|
12154
|
-
schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
|
|
12155
|
-
return true;
|
|
12156
|
-
}
|
|
12157
|
-
}
|
|
12158
|
-
}
|
|
12159
|
-
return false;
|
|
12160
|
-
}
|
|
12161
|
-
/**
|
|
12162
|
-
* Logs or throws an error that a property is not supported on an element.
|
|
12163
|
-
* @param propName Name of the invalid property.
|
|
12164
|
-
* @param tagName Name of the node on which we encountered the property.
|
|
12165
|
-
*/
|
|
12166
|
-
function handleUnknownPropertyError(propName, tNode) {
|
|
12167
|
-
let tagName = tNode.value;
|
|
12168
|
-
// Special-case a situation when a structural directive is applied to
|
|
12169
|
-
// an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
|
|
12170
|
-
// In this case the compiler generates the `ɵɵtemplate` instruction with
|
|
12171
|
-
// the `null` as the tagName. The directive matching logic at runtime relies
|
|
12172
|
-
// on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
|
|
12173
|
-
// a default value of the `tNode.value` is not feasible at this moment.
|
|
12174
|
-
if (!tagName && tNode.type === 4 /* TNodeType.Container */) {
|
|
12175
|
-
tagName = 'ng-template';
|
|
12176
|
-
}
|
|
12177
|
-
const message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'.`;
|
|
12178
|
-
if (shouldThrowErrorOnUnknownProperty) {
|
|
12179
|
-
throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
|
|
12180
|
-
}
|
|
12181
|
-
else {
|
|
12182
|
-
console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
|
|
12183
|
-
}
|
|
12184
|
-
}
|
|
12185
12404
|
/**
|
|
12186
12405
|
* Instantiate a root component.
|
|
12187
12406
|
*/
|
|
@@ -13755,7 +13974,11 @@ function createRootComponent(componentView, componentDef, rootLView, rootContext
|
|
|
13755
13974
|
const component = instantiateRootComponent(tView, rootLView, componentDef);
|
|
13756
13975
|
rootContext.components.push(component);
|
|
13757
13976
|
componentView[CONTEXT] = component;
|
|
13758
|
-
hostFeatures
|
|
13977
|
+
if (hostFeatures !== null) {
|
|
13978
|
+
for (const feature of hostFeatures) {
|
|
13979
|
+
feature(component, componentDef);
|
|
13980
|
+
}
|
|
13981
|
+
}
|
|
13759
13982
|
// We want to generate an empty QueryList for root content queries for backwards
|
|
13760
13983
|
// compatibility with ViewEngine.
|
|
13761
13984
|
if (componentDef.contentQueries) {
|
|
@@ -13796,13 +14019,10 @@ function createRootContext(scheduler, playerHandler) {
|
|
|
13796
14019
|
* renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
|
|
13797
14020
|
* ```
|
|
13798
14021
|
*/
|
|
13799
|
-
function LifecycleHooksFeature(
|
|
13800
|
-
const lView = readPatchedLView(component);
|
|
13801
|
-
ngDevMode && assertDefined(lView, 'LView is required');
|
|
13802
|
-
const tView = lView[TVIEW];
|
|
14022
|
+
function LifecycleHooksFeature() {
|
|
13803
14023
|
const tNode = getCurrentTNode();
|
|
13804
14024
|
ngDevMode && assertDefined(tNode, 'TNode is required');
|
|
13805
|
-
registerPostOrderHooks(
|
|
14025
|
+
registerPostOrderHooks(getLView()[TVIEW], tNode);
|
|
13806
14026
|
}
|
|
13807
14027
|
/**
|
|
13808
14028
|
* Wait on component until it is rendered.
|
|
@@ -14937,21 +15157,6 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
|
|
|
14937
15157
|
* Use of this source code is governed by an MIT-style license that can be
|
|
14938
15158
|
* found in the LICENSE file at https://angular.io/license
|
|
14939
15159
|
*/
|
|
14940
|
-
let shouldThrowErrorOnUnknownElement = false;
|
|
14941
|
-
/**
|
|
14942
|
-
* Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
|
|
14943
|
-
* instead of just logging the error.
|
|
14944
|
-
* (for AOT-compiled ones this check happens at build time).
|
|
14945
|
-
*/
|
|
14946
|
-
function ɵsetUnknownElementStrictMode(shouldThrow) {
|
|
14947
|
-
shouldThrowErrorOnUnknownElement = shouldThrow;
|
|
14948
|
-
}
|
|
14949
|
-
/**
|
|
14950
|
-
* Gets the current value of the strict mode.
|
|
14951
|
-
*/
|
|
14952
|
-
function ɵgetUnknownElementStrictMode() {
|
|
14953
|
-
return shouldThrowErrorOnUnknownElement;
|
|
14954
|
-
}
|
|
14955
15160
|
function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
|
|
14956
15161
|
ngDevMode && assertFirstCreatePass(tView);
|
|
14957
15162
|
ngDevMode && ngDevMode.firstCreatePass++;
|
|
@@ -14960,8 +15165,7 @@ function elementStartFirstCreatePass(index, tView, lView, native, name, attrsInd
|
|
|
14960
15165
|
const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
|
|
14961
15166
|
const hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
|
|
14962
15167
|
if (ngDevMode) {
|
|
14963
|
-
|
|
14964
|
-
validateElementIsKnown(native, tNode.value, tView.schemas, hasDirectives, hostIsStandalone);
|
|
15168
|
+
validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
|
|
14965
15169
|
}
|
|
14966
15170
|
if (tNode.attrs !== null) {
|
|
14967
15171
|
computeStaticStyling(tNode, tNode.attrs, false);
|
|
@@ -15086,65 +15290,6 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
|
|
|
15086
15290
|
ɵɵelementEnd();
|
|
15087
15291
|
return ɵɵelement;
|
|
15088
15292
|
}
|
|
15089
|
-
/**
|
|
15090
|
-
* Validates that the element is known at runtime and produces
|
|
15091
|
-
* an error if it's not the case.
|
|
15092
|
-
* This check is relevant for JIT-compiled components (for AOT-compiled
|
|
15093
|
-
* ones this check happens at build time).
|
|
15094
|
-
*
|
|
15095
|
-
* The element is considered known if either:
|
|
15096
|
-
* - it's a known HTML element
|
|
15097
|
-
* - it's a known custom element
|
|
15098
|
-
* - the element matches any directive
|
|
15099
|
-
* - the element is allowed by one of the schemas
|
|
15100
|
-
*
|
|
15101
|
-
* @param element Element to validate
|
|
15102
|
-
* @param tagName Name of the tag to check
|
|
15103
|
-
* @param schemas Array of schemas
|
|
15104
|
-
* @param hasDirectives Boolean indicating that the element matches any directive
|
|
15105
|
-
* @param hostIsStandalone Boolean indicating whether the host is a standalone component
|
|
15106
|
-
*/
|
|
15107
|
-
function validateElementIsKnown(element, tagName, schemas, hasDirectives, hostIsStandalone) {
|
|
15108
|
-
// If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
|
|
15109
|
-
// mode where this check happens at compile time. In JIT mode, `schemas` is always present and
|
|
15110
|
-
// defined as an array (as an empty array in case `schemas` field is not defined) and we should
|
|
15111
|
-
// execute the check below.
|
|
15112
|
-
if (schemas === null)
|
|
15113
|
-
return;
|
|
15114
|
-
// If the element matches any directive, it's considered as valid.
|
|
15115
|
-
if (!hasDirectives && tagName !== null) {
|
|
15116
|
-
// The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
|
|
15117
|
-
// as a custom element. Note that unknown elements with a dash in their name won't be instances
|
|
15118
|
-
// of HTMLUnknownElement in browsers that support web components.
|
|
15119
|
-
const isUnknown =
|
|
15120
|
-
// Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
|
|
15121
|
-
// because while most browsers return 'function', IE returns 'object'.
|
|
15122
|
-
(typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
|
|
15123
|
-
element instanceof HTMLUnknownElement) ||
|
|
15124
|
-
(typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
|
|
15125
|
-
!customElements.get(tagName));
|
|
15126
|
-
if (isUnknown && !matchingSchemas(schemas, tagName)) {
|
|
15127
|
-
const schemas = `'${hostIsStandalone ? '@Component' : '@NgModule'}.schemas'`;
|
|
15128
|
-
let message = `'${tagName}' is not a known element:\n`;
|
|
15129
|
-
message += `1. If '${tagName}' is an Angular component, then verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
15130
|
-
'a part of this module'}.\n`;
|
|
15131
|
-
if (tagName && tagName.indexOf('-') > -1) {
|
|
15132
|
-
message +=
|
|
15133
|
-
`2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
|
|
15134
|
-
}
|
|
15135
|
-
else {
|
|
15136
|
-
message +=
|
|
15137
|
-
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
|
|
15138
|
-
}
|
|
15139
|
-
if (shouldThrowErrorOnUnknownElement) {
|
|
15140
|
-
throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
|
|
15141
|
-
}
|
|
15142
|
-
else {
|
|
15143
|
-
console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
|
|
15144
|
-
}
|
|
15145
|
-
}
|
|
15146
|
-
}
|
|
15147
|
-
}
|
|
15148
15293
|
|
|
15149
15294
|
/**
|
|
15150
15295
|
* @license
|
|
@@ -21627,7 +21772,7 @@ class Version {
|
|
|
21627
21772
|
/**
|
|
21628
21773
|
* @publicApi
|
|
21629
21774
|
*/
|
|
21630
|
-
const VERSION = new Version('14.0.
|
|
21775
|
+
const VERSION = new Version('14.0.1');
|
|
21631
21776
|
|
|
21632
21777
|
/**
|
|
21633
21778
|
* @license
|
|
@@ -22299,6 +22444,7 @@ class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
|
|
|
22299
22444
|
* Create a new environment injector.
|
|
22300
22445
|
*
|
|
22301
22446
|
* @publicApi
|
|
22447
|
+
* @developerPreview
|
|
22302
22448
|
*/
|
|
22303
22449
|
function createEnvironmentInjector(providers, parent = null, debugName = null) {
|
|
22304
22450
|
const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
|
|
@@ -22326,14 +22472,14 @@ class StandaloneService {
|
|
|
22326
22472
|
if (!componentDef.standalone) {
|
|
22327
22473
|
return null;
|
|
22328
22474
|
}
|
|
22329
|
-
if (!this.cachedInjectors.has(componentDef)) {
|
|
22475
|
+
if (!this.cachedInjectors.has(componentDef.id)) {
|
|
22330
22476
|
const providers = internalImportProvidersFrom(false, componentDef.type);
|
|
22331
22477
|
const standaloneInjector = providers.length > 0 ?
|
|
22332
22478
|
createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
|
|
22333
22479
|
null;
|
|
22334
|
-
this.cachedInjectors.set(componentDef, standaloneInjector);
|
|
22480
|
+
this.cachedInjectors.set(componentDef.id, standaloneInjector);
|
|
22335
22481
|
}
|
|
22336
|
-
return this.cachedInjectors.get(componentDef);
|
|
22482
|
+
return this.cachedInjectors.get(componentDef.id);
|
|
22337
22483
|
}
|
|
22338
22484
|
ngOnDestroy() {
|
|
22339
22485
|
try {
|
|
@@ -22833,13 +22979,26 @@ function getPipeDef(name, registry) {
|
|
|
22833
22979
|
}
|
|
22834
22980
|
}
|
|
22835
22981
|
if (ngDevMode) {
|
|
22836
|
-
|
|
22837
|
-
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
22838
|
-
const context = declarationLView[CONTEXT];
|
|
22839
|
-
const component = context ? ` in the '${context.constructor.name}' component` : '';
|
|
22840
|
-
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, `The pipe '${name}' could not be found${component}!`);
|
|
22982
|
+
throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
|
|
22841
22983
|
}
|
|
22842
22984
|
}
|
|
22985
|
+
/**
|
|
22986
|
+
* Generates a helpful error message for the user when a pipe is not found.
|
|
22987
|
+
*
|
|
22988
|
+
* @param name Name of the missing pipe
|
|
22989
|
+
* @returns The error message
|
|
22990
|
+
*/
|
|
22991
|
+
function getPipeNotFoundErrorMessage(name) {
|
|
22992
|
+
const lView = getLView();
|
|
22993
|
+
const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
|
|
22994
|
+
const context = declarationLView[CONTEXT];
|
|
22995
|
+
const hostIsStandalone = isHostComponentStandalone(lView);
|
|
22996
|
+
const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
|
|
22997
|
+
const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
|
|
22998
|
+
'declared or imported in this module'}`;
|
|
22999
|
+
const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
|
|
23000
|
+
return errorMessage;
|
|
23001
|
+
}
|
|
22843
23002
|
/**
|
|
22844
23003
|
* Invokes a pipe with 1 arguments.
|
|
22845
23004
|
*
|
|
@@ -24684,7 +24843,7 @@ function patchComponentDefWithScope(componentDef, transitiveScopes) {
|
|
|
24684
24843
|
}
|
|
24685
24844
|
/**
|
|
24686
24845
|
* Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
|
|
24687
|
-
* (
|
|
24846
|
+
* (either a NgModule or a standalone component / directive / pipe).
|
|
24688
24847
|
*/
|
|
24689
24848
|
function transitiveScopesFor(type) {
|
|
24690
24849
|
if (isNgModule(type)) {
|