@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.
Files changed (40) hide show
  1. package/esm2020/src/application_ref.mjs +10 -24
  2. package/esm2020/src/change_detection/differs/default_iterable_differ.mjs +3 -5
  3. package/esm2020/src/change_detection/differs/default_keyvalue_differ.mjs +3 -5
  4. package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -5
  5. package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +2 -5
  6. package/esm2020/src/di/injector_compatibility.mjs +4 -9
  7. package/esm2020/src/di/provider_collection.mjs +1 -1
  8. package/esm2020/src/error_handler.mjs +4 -7
  9. package/esm2020/src/errors.mjs +6 -3
  10. package/esm2020/src/render3/component.mjs +9 -9
  11. package/esm2020/src/render3/definition.mjs +4 -4
  12. package/esm2020/src/render3/features/inherit_definition_feature.mjs +3 -5
  13. package/esm2020/src/render3/features/standalone_feature.mjs +4 -4
  14. package/esm2020/src/render3/instructions/all.mjs +2 -2
  15. package/esm2020/src/render3/instructions/element.mjs +3 -79
  16. package/esm2020/src/render3/instructions/element_validation.mjs +264 -0
  17. package/esm2020/src/render3/instructions/shared.mjs +7 -184
  18. package/esm2020/src/render3/interfaces/definition.mjs +1 -1
  19. package/esm2020/src/render3/jit/directive.mjs +20 -3
  20. package/esm2020/src/render3/jit/module.mjs +3 -2
  21. package/esm2020/src/render3/pipe.mjs +20 -6
  22. package/esm2020/src/render3/state.mjs +1 -3
  23. package/esm2020/src/render3/view_ref.mjs +3 -5
  24. package/esm2020/src/sanitization/sanitization.mjs +4 -9
  25. package/esm2020/src/util/errors.mjs +1 -8
  26. package/esm2020/src/version.mjs +1 -1
  27. package/esm2020/testing/src/logger.mjs +3 -3
  28. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  29. package/esm2020/testing/src/r3_test_bed_compiler.mjs +30 -25
  30. package/fesm2015/core.mjs +636 -644
  31. package/fesm2015/core.mjs.map +1 -1
  32. package/fesm2015/testing.mjs +633 -630
  33. package/fesm2015/testing.mjs.map +1 -1
  34. package/fesm2020/core.mjs +637 -645
  35. package/fesm2020/core.mjs.map +1 -1
  36. package/fesm2020/testing.mjs +634 -631
  37. package/fesm2020/testing.mjs.map +1 -1
  38. package/index.d.ts +7 -6
  39. package/package.json +1 -1
  40. package/testing/index.d.ts +1 -1
package/fesm2020/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v14.0.0
2
+ * @license Angular v14.0.3
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
- errorMessage = `${errorMessage}. Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
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
- let _renderCompCount = 0;
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: 'c',
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));
@@ -1940,7 +1943,6 @@ function getLView() {
1940
1943
  function getTView() {
1941
1944
  return instructionState.lFrame.tView;
1942
1945
  }
1943
- // TODO(crisbeto): revert the @noinline once Closure issue is resolved.
1944
1946
  /**
1945
1947
  * Restores `contextViewData` to the given OpaqueViewState instance.
1946
1948
  *
@@ -1952,7 +1954,6 @@ function getTView() {
1952
1954
  * @returns Context of the restored OpaqueViewState instance.
1953
1955
  *
1954
1956
  * @codeGenApi
1955
- * @noinline Disable inlining due to issue with Closure in listeners inside embedded views.
1956
1957
  */
1957
1958
  function ɵɵrestoreView(viewToRestore) {
1958
1959
  instructionState.lFrame.contextLView = viewToRestore;
@@ -4857,10 +4858,8 @@ function setCurrentInjector(injector) {
4857
4858
  }
4858
4859
  function injectInjectorOnly(token, flags = InjectFlags.Default) {
4859
4860
  if (_currentInjector === undefined) {
4860
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
4861
- `inject() must be called from an injection context (a constructor, a factory function or a field initializer)` :
4862
- '';
4863
- throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
4861
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
4862
+ `inject() must be called from an injection context (a constructor, a factory function or a field initializer)`);
4864
4863
  }
4865
4864
  else if (_currentInjector === null) {
4866
4865
  return injectRootLimpMode(token, undefined, flags);
@@ -4966,10 +4965,7 @@ function injectArgs(types) {
4966
4965
  const arg = resolveForwardRef(types[i]);
4967
4966
  if (Array.isArray(arg)) {
4968
4967
  if (arg.length === 0) {
4969
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
4970
- 'Arguments array must have arguments.' :
4971
- '';
4972
- throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, errorMessage);
4968
+ throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
4973
4969
  }
4974
4970
  let type = undefined;
4975
4971
  let flags = InjectFlags.Default;
@@ -6214,10 +6210,8 @@ function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
6214
6210
  if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL" /* BypassType.ResourceUrl */)) {
6215
6211
  return trustedScriptURLFromStringBypass(unwrapSafeValue(unsafeResourceUrl));
6216
6212
  }
6217
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
6218
- 'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)' :
6219
- '';
6220
- throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, errorMessage);
6213
+ throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, ngDevMode &&
6214
+ 'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
6221
6215
  }
6222
6216
  /**
6223
6217
  * A `script` sanitizer which only lets trusted javascript through.
@@ -6239,10 +6233,7 @@ function ɵɵsanitizeScript(unsafeScript) {
6239
6233
  if (allowSanitizationBypassAndThrow(unsafeScript, "Script" /* BypassType.Script */)) {
6240
6234
  return trustedScriptFromStringBypass(unwrapSafeValue(unsafeScript));
6241
6235
  }
6242
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
6243
- 'unsafe value used in a script context' :
6244
- '';
6245
- throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, errorMessage);
6236
+ throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && 'unsafe value used in a script context');
6246
6237
  }
6247
6238
  /**
6248
6239
  * A template tag function for promoting the associated constant literal to a
@@ -6349,6 +6340,155 @@ function getSanitizer() {
6349
6340
  return lView && lView[SANITIZER];
6350
6341
  }
6351
6342
 
6343
+ /**
6344
+ * @license
6345
+ * Copyright Google LLC All Rights Reserved.
6346
+ *
6347
+ * Use of this source code is governed by an MIT-style license that can be
6348
+ * found in the LICENSE file at https://angular.io/license
6349
+ */
6350
+ const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
6351
+ function wrappedError(message, originalError) {
6352
+ const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
6353
+ const error = Error(msg);
6354
+ error[ERROR_ORIGINAL_ERROR] = originalError;
6355
+ return error;
6356
+ }
6357
+ function getOriginalError(error) {
6358
+ return error[ERROR_ORIGINAL_ERROR];
6359
+ }
6360
+
6361
+ /**
6362
+ * @license
6363
+ * Copyright Google LLC All Rights Reserved.
6364
+ *
6365
+ * Use of this source code is governed by an MIT-style license that can be
6366
+ * found in the LICENSE file at https://angular.io/license
6367
+ */
6368
+ /**
6369
+ * Provides a hook for centralized exception handling.
6370
+ *
6371
+ * The default implementation of `ErrorHandler` prints error messages to the `console`. To
6372
+ * intercept error handling, write a custom exception handler that replaces this default as
6373
+ * appropriate for your app.
6374
+ *
6375
+ * @usageNotes
6376
+ * ### Example
6377
+ *
6378
+ * ```
6379
+ * class MyErrorHandler implements ErrorHandler {
6380
+ * handleError(error) {
6381
+ * // do something with the exception
6382
+ * }
6383
+ * }
6384
+ *
6385
+ * @NgModule({
6386
+ * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
6387
+ * })
6388
+ * class MyModule {}
6389
+ * ```
6390
+ *
6391
+ * @publicApi
6392
+ */
6393
+ class ErrorHandler {
6394
+ constructor() {
6395
+ /**
6396
+ * @internal
6397
+ */
6398
+ this._console = console;
6399
+ }
6400
+ handleError(error) {
6401
+ const originalError = this._findOriginalError(error);
6402
+ this._console.error('ERROR', error);
6403
+ if (originalError) {
6404
+ this._console.error('ORIGINAL ERROR', originalError);
6405
+ }
6406
+ }
6407
+ /** @internal */
6408
+ _findOriginalError(error) {
6409
+ let e = error && getOriginalError(error);
6410
+ while (e && getOriginalError(e)) {
6411
+ e = getOriginalError(e);
6412
+ }
6413
+ return e || null;
6414
+ }
6415
+ }
6416
+
6417
+ /**
6418
+ * @license
6419
+ * Copyright Google LLC All Rights Reserved.
6420
+ *
6421
+ * Use of this source code is governed by an MIT-style license that can be
6422
+ * found in the LICENSE file at https://angular.io/license
6423
+ */
6424
+ /**
6425
+ * Disallowed strings in the comment.
6426
+ *
6427
+ * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
6428
+ */
6429
+ const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
6430
+ /**
6431
+ * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
6432
+ */
6433
+ const COMMENT_DELIMITER = /(<|>)/;
6434
+ const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
6435
+ /**
6436
+ * Escape the content of comment strings so that it can be safely inserted into a comment node.
6437
+ *
6438
+ * The issue is that HTML does not specify any way to escape comment end text inside the comment.
6439
+ * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
6440
+ * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
6441
+ * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
6442
+ *
6443
+ * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
6444
+ *
6445
+ * ```
6446
+ * div.innerHTML = div.innerHTML
6447
+ * ```
6448
+ *
6449
+ * One would expect that the above code would be safe to do, but it turns out that because comment
6450
+ * text is not escaped, the comment may contain text which will prematurely close the comment
6451
+ * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
6452
+ * may contain such text and expect them to be safe.)
6453
+ *
6454
+ * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
6455
+ * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
6456
+ * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
6457
+ * text it will render normally but it will not cause the HTML parser to close/open the comment.
6458
+ *
6459
+ * @param value text to make safe for comment node by escaping the comment open/close character
6460
+ * sequence.
6461
+ */
6462
+ function escapeCommentText(value) {
6463
+ return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
6464
+ }
6465
+
6466
+ /**
6467
+ * @license
6468
+ * Copyright Google LLC All Rights Reserved.
6469
+ *
6470
+ * Use of this source code is governed by an MIT-style license that can be
6471
+ * found in the LICENSE file at https://angular.io/license
6472
+ */
6473
+ function normalizeDebugBindingName(name) {
6474
+ // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
6475
+ name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
6476
+ return `ng-reflect-${name}`;
6477
+ }
6478
+ const CAMEL_CASE_REGEXP = /([A-Z])/g;
6479
+ function camelCaseToDashCase(input) {
6480
+ return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
6481
+ }
6482
+ function normalizeDebugBindingValue(value) {
6483
+ try {
6484
+ // Limit the size of the value as otherwise the DOM just gets polluted.
6485
+ return value != null ? value.toString().slice(0, 30) : value;
6486
+ }
6487
+ catch (e) {
6488
+ return '[ERROR] Exception while trying to serialize the value';
6489
+ }
6490
+ }
6491
+
6352
6492
  /**
6353
6493
  * @license
6354
6494
  * Copyright Google LLC All Rights Reserved.
@@ -6704,216 +6844,26 @@ function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
6704
6844
  return lView.slice(directiveStartIndex, directiveEndIndex);
6705
6845
  }
6706
6846
  function getComponentAtNodeIndex(nodeIndex, lView) {
6707
- const tNode = lView[TVIEW].data[nodeIndex];
6708
- let directiveStartIndex = tNode.directiveStart;
6709
- return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
6710
- }
6711
- /**
6712
- * Returns a map of local references (local reference name => element or directive instance) that
6713
- * exist on a given element.
6714
- */
6715
- function discoverLocalRefs(lView, nodeIndex) {
6716
- const tNode = lView[TVIEW].data[nodeIndex];
6717
- if (tNode && tNode.localNames) {
6718
- const result = {};
6719
- let localIndex = tNode.index + 1;
6720
- for (let i = 0; i < tNode.localNames.length; i += 2) {
6721
- result[tNode.localNames[i]] = lView[localIndex];
6722
- localIndex++;
6723
- }
6724
- return result;
6725
- }
6726
- return null;
6727
- }
6728
-
6729
- /**
6730
- * @license
6731
- * Copyright Google LLC All Rights Reserved.
6732
- *
6733
- * Use of this source code is governed by an MIT-style license that can be
6734
- * found in the LICENSE file at https://angular.io/license
6735
- */
6736
- const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
6737
- const ERROR_LOGGER = 'ngErrorLogger';
6738
- function wrappedError(message, originalError) {
6739
- const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
6740
- const error = Error(msg);
6741
- error[ERROR_ORIGINAL_ERROR] = originalError;
6742
- return error;
6743
- }
6744
- function getOriginalError(error) {
6745
- return error[ERROR_ORIGINAL_ERROR];
6746
- }
6747
- function getErrorLogger(error) {
6748
- return error && error[ERROR_LOGGER] || defaultErrorLogger;
6749
- }
6750
- function defaultErrorLogger(console, ...values) {
6751
- console.error(...values);
6752
- }
6753
-
6754
- /**
6755
- * @license
6756
- * Copyright Google LLC All Rights Reserved.
6757
- *
6758
- * Use of this source code is governed by an MIT-style license that can be
6759
- * found in the LICENSE file at https://angular.io/license
6760
- */
6761
- /**
6762
- * Provides a hook for centralized exception handling.
6763
- *
6764
- * The default implementation of `ErrorHandler` prints error messages to the `console`. To
6765
- * intercept error handling, write a custom exception handler that replaces this default as
6766
- * appropriate for your app.
6767
- *
6768
- * @usageNotes
6769
- * ### Example
6770
- *
6771
- * ```
6772
- * class MyErrorHandler implements ErrorHandler {
6773
- * handleError(error) {
6774
- * // do something with the exception
6775
- * }
6776
- * }
6777
- *
6778
- * @NgModule({
6779
- * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
6780
- * })
6781
- * class MyModule {}
6782
- * ```
6783
- *
6784
- * @publicApi
6785
- */
6786
- class ErrorHandler {
6787
- constructor() {
6788
- /**
6789
- * @internal
6790
- */
6791
- this._console = console;
6792
- }
6793
- handleError(error) {
6794
- const originalError = this._findOriginalError(error);
6795
- // Note: Browser consoles show the place from where console.error was called.
6796
- // We can use this to give users additional information about the error.
6797
- const errorLogger = getErrorLogger(error);
6798
- errorLogger(this._console, `ERROR`, error);
6799
- if (originalError) {
6800
- errorLogger(this._console, `ORIGINAL ERROR`, originalError);
6801
- }
6802
- }
6803
- /** @internal */
6804
- _findOriginalError(error) {
6805
- let e = error && getOriginalError(error);
6806
- while (e && getOriginalError(e)) {
6807
- e = getOriginalError(e);
6808
- }
6809
- return e || null;
6810
- }
6811
- }
6812
-
6813
- /**
6814
- * @license
6815
- * Copyright Google LLC All Rights Reserved.
6816
- *
6817
- * Use of this source code is governed by an MIT-style license that can be
6818
- * found in the LICENSE file at https://angular.io/license
6819
- */
6820
- /**
6821
- * Defines a schema that allows an NgModule to contain the following:
6822
- * - Non-Angular elements named with dash case (`-`).
6823
- * - Element properties named with dash case (`-`).
6824
- * Dash case is the naming convention for custom elements.
6825
- *
6826
- * @publicApi
6827
- */
6828
- const CUSTOM_ELEMENTS_SCHEMA = {
6829
- name: 'custom-elements'
6830
- };
6831
- /**
6832
- * Defines a schema that allows any property on any element.
6833
- *
6834
- * This schema allows you to ignore the errors related to any unknown elements or properties in a
6835
- * template. The usage of this schema is generally discouraged because it prevents useful validation
6836
- * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
6837
- *
6838
- * @publicApi
6839
- */
6840
- const NO_ERRORS_SCHEMA = {
6841
- name: 'no-errors-schema'
6842
- };
6843
-
6844
- /**
6845
- * @license
6846
- * Copyright Google LLC All Rights Reserved.
6847
- *
6848
- * Use of this source code is governed by an MIT-style license that can be
6849
- * found in the LICENSE file at https://angular.io/license
6850
- */
6851
- /**
6852
- * Disallowed strings in the comment.
6853
- *
6854
- * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
6855
- */
6856
- const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
6857
- /**
6858
- * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
6859
- */
6860
- const COMMENT_DELIMITER = /(<|>)/;
6861
- const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
6862
- /**
6863
- * Escape the content of comment strings so that it can be safely inserted into a comment node.
6864
- *
6865
- * The issue is that HTML does not specify any way to escape comment end text inside the comment.
6866
- * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
6867
- * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
6868
- * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
6869
- *
6870
- * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
6871
- *
6872
- * ```
6873
- * div.innerHTML = div.innerHTML
6874
- * ```
6875
- *
6876
- * One would expect that the above code would be safe to do, but it turns out that because comment
6877
- * text is not escaped, the comment may contain text which will prematurely close the comment
6878
- * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
6879
- * may contain such text and expect them to be safe.)
6880
- *
6881
- * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
6882
- * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
6883
- * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
6884
- * text it will render normally but it will not cause the HTML parser to close/open the comment.
6885
- *
6886
- * @param value text to make safe for comment node by escaping the comment open/close character
6887
- * sequence.
6888
- */
6889
- function escapeCommentText(value) {
6890
- return value.replace(COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
6847
+ const tNode = lView[TVIEW].data[nodeIndex];
6848
+ let directiveStartIndex = tNode.directiveStart;
6849
+ return tNode.flags & 2 /* TNodeFlags.isComponentHost */ ? lView[directiveStartIndex] : null;
6891
6850
  }
6892
-
6893
6851
  /**
6894
- * @license
6895
- * Copyright Google LLC All Rights Reserved.
6896
- *
6897
- * Use of this source code is governed by an MIT-style license that can be
6898
- * found in the LICENSE file at https://angular.io/license
6852
+ * Returns a map of local references (local reference name => element or directive instance) that
6853
+ * exist on a given element.
6899
6854
  */
6900
- function normalizeDebugBindingName(name) {
6901
- // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
6902
- name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
6903
- return `ng-reflect-${name}`;
6904
- }
6905
- const CAMEL_CASE_REGEXP = /([A-Z])/g;
6906
- function camelCaseToDashCase(input) {
6907
- return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
6908
- }
6909
- function normalizeDebugBindingValue(value) {
6910
- try {
6911
- // Limit the size of the value as otherwise the DOM just gets polluted.
6912
- return value != null ? value.toString().slice(0, 30) : value;
6913
- }
6914
- catch (e) {
6915
- return '[ERROR] Exception while trying to serialize the value';
6855
+ function discoverLocalRefs(lView, nodeIndex) {
6856
+ const tNode = lView[TVIEW].data[nodeIndex];
6857
+ if (tNode && tNode.localNames) {
6858
+ const result = {};
6859
+ let localIndex = tNode.index + 1;
6860
+ for (let i = 0; i < tNode.localNames.length; i += 2) {
6861
+ result[tNode.localNames[i]] = lView[localIndex];
6862
+ localIndex++;
6863
+ }
6864
+ return result;
6916
6865
  }
6866
+ return null;
6917
6867
  }
6918
6868
 
6919
6869
  /**
@@ -10354,113 +10304,402 @@ class ReflectiveInjector_ {
10354
10304
  return this.objs[i];
10355
10305
  }
10356
10306
  }
10357
- return UNDEFINED;
10307
+ return UNDEFINED;
10308
+ }
10309
+ /** @internal */
10310
+ _throwOrNull(key, notFoundValue) {
10311
+ if (notFoundValue !== THROW_IF_NOT_FOUND) {
10312
+ return notFoundValue;
10313
+ }
10314
+ else {
10315
+ throw noProviderError(this, key);
10316
+ }
10317
+ }
10318
+ /** @internal */
10319
+ _getByKeySelf(key, notFoundValue) {
10320
+ const obj = this._getObjByKeyId(key.id);
10321
+ return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
10322
+ }
10323
+ /** @internal */
10324
+ _getByKeyDefault(key, notFoundValue, visibility) {
10325
+ let inj;
10326
+ if (visibility instanceof SkipSelf) {
10327
+ inj = this.parent;
10328
+ }
10329
+ else {
10330
+ inj = this;
10331
+ }
10332
+ while (inj instanceof ReflectiveInjector_) {
10333
+ const inj_ = inj;
10334
+ const obj = inj_._getObjByKeyId(key.id);
10335
+ if (obj !== UNDEFINED)
10336
+ return obj;
10337
+ inj = inj_.parent;
10338
+ }
10339
+ if (inj !== null) {
10340
+ return inj.get(key.token, notFoundValue);
10341
+ }
10342
+ else {
10343
+ return this._throwOrNull(key, notFoundValue);
10344
+ }
10345
+ }
10346
+ get displayName() {
10347
+ const providers = _mapProviders(this, (b) => ' "' + b.key.displayName + '" ')
10348
+ .join(', ');
10349
+ return `ReflectiveInjector(providers: [${providers}])`;
10350
+ }
10351
+ toString() {
10352
+ return this.displayName;
10353
+ }
10354
+ }
10355
+ ReflectiveInjector_.INJECTOR_KEY = ( /* @__PURE__ */ReflectiveKey.get(Injector));
10356
+ function _mapProviders(injector, fn) {
10357
+ const res = [];
10358
+ for (let i = 0; i < injector._providers.length; ++i) {
10359
+ res[i] = fn(injector.getProviderAtIndex(i));
10360
+ }
10361
+ return res;
10362
+ }
10363
+
10364
+ /**
10365
+ * @license
10366
+ * Copyright Google LLC All Rights Reserved.
10367
+ *
10368
+ * Use of this source code is governed by an MIT-style license that can be
10369
+ * found in the LICENSE file at https://angular.io/license
10370
+ */
10371
+
10372
+ /**
10373
+ * @license
10374
+ * Copyright Google LLC All Rights Reserved.
10375
+ *
10376
+ * Use of this source code is governed by an MIT-style license that can be
10377
+ * found in the LICENSE file at https://angular.io/license
10378
+ */
10379
+
10380
+ /**
10381
+ * @license
10382
+ * Copyright Google LLC All Rights Reserved.
10383
+ *
10384
+ * Use of this source code is governed by an MIT-style license that can be
10385
+ * found in the LICENSE file at https://angular.io/license
10386
+ */
10387
+ function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10388
+ const lView = getLView();
10389
+ // Fall back to inject() if view hasn't been created. This situation can happen in tests
10390
+ // if inject utilities are used before bootstrapping.
10391
+ if (lView === null) {
10392
+ // Verify that we will not get into infinite loop.
10393
+ ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
10394
+ return ɵɵinject(token, flags);
10395
+ }
10396
+ const tNode = getCurrentTNode();
10397
+ return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
10398
+ }
10399
+ /**
10400
+ * Throws an error indicating that a factory function could not be generated by the compiler for a
10401
+ * particular class.
10402
+ *
10403
+ * This instruction allows the actual error message to be optimized away when ngDevMode is turned
10404
+ * off, saving bytes of generated code while still providing a good experience in dev mode.
10405
+ *
10406
+ * The name of the class is not mentioned here, but will be in the generated factory function name
10407
+ * and thus in the stack trace.
10408
+ *
10409
+ * @codeGenApi
10410
+ */
10411
+ function ɵɵinvalidFactory() {
10412
+ const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
10413
+ throw new Error(msg);
10414
+ }
10415
+
10416
+ /**
10417
+ * @license
10418
+ * Copyright Google LLC All Rights Reserved.
10419
+ *
10420
+ * Use of this source code is governed by an MIT-style license that can be
10421
+ * found in the LICENSE file at https://angular.io/license
10422
+ */
10423
+ /**
10424
+ * Defines a schema that allows an NgModule to contain the following:
10425
+ * - Non-Angular elements named with dash case (`-`).
10426
+ * - Element properties named with dash case (`-`).
10427
+ * Dash case is the naming convention for custom elements.
10428
+ *
10429
+ * @publicApi
10430
+ */
10431
+ const CUSTOM_ELEMENTS_SCHEMA = {
10432
+ name: 'custom-elements'
10433
+ };
10434
+ /**
10435
+ * Defines a schema that allows any property on any element.
10436
+ *
10437
+ * This schema allows you to ignore the errors related to any unknown elements or properties in a
10438
+ * template. The usage of this schema is generally discouraged because it prevents useful validation
10439
+ * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
10440
+ *
10441
+ * @publicApi
10442
+ */
10443
+ const NO_ERRORS_SCHEMA = {
10444
+ name: 'no-errors-schema'
10445
+ };
10446
+
10447
+ /**
10448
+ * @license
10449
+ * Copyright Google LLC All Rights Reserved.
10450
+ *
10451
+ * Use of this source code is governed by an MIT-style license that can be
10452
+ * found in the LICENSE file at https://angular.io/license
10453
+ */
10454
+ let shouldThrowErrorOnUnknownElement = false;
10455
+ /**
10456
+ * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
10457
+ * instead of just logging the error.
10458
+ * (for AOT-compiled ones this check happens at build time).
10459
+ */
10460
+ function ɵsetUnknownElementStrictMode(shouldThrow) {
10461
+ shouldThrowErrorOnUnknownElement = shouldThrow;
10462
+ }
10463
+ /**
10464
+ * Gets the current value of the strict mode.
10465
+ */
10466
+ function ɵgetUnknownElementStrictMode() {
10467
+ return shouldThrowErrorOnUnknownElement;
10468
+ }
10469
+ let shouldThrowErrorOnUnknownProperty = false;
10470
+ /**
10471
+ * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
10472
+ * instead of just logging the error.
10473
+ * (for AOT-compiled ones this check happens at build time).
10474
+ */
10475
+ function ɵsetUnknownPropertyStrictMode(shouldThrow) {
10476
+ shouldThrowErrorOnUnknownProperty = shouldThrow;
10477
+ }
10478
+ /**
10479
+ * Gets the current value of the strict mode.
10480
+ */
10481
+ function ɵgetUnknownPropertyStrictMode() {
10482
+ return shouldThrowErrorOnUnknownProperty;
10483
+ }
10484
+ /**
10485
+ * Validates that the element is known at runtime and produces
10486
+ * an error if it's not the case.
10487
+ * This check is relevant for JIT-compiled components (for AOT-compiled
10488
+ * ones this check happens at build time).
10489
+ *
10490
+ * The element is considered known if either:
10491
+ * - it's a known HTML element
10492
+ * - it's a known custom element
10493
+ * - the element matches any directive
10494
+ * - the element is allowed by one of the schemas
10495
+ *
10496
+ * @param element Element to validate
10497
+ * @param lView An `LView` that represents a current component that is being rendered
10498
+ * @param tagName Name of the tag to check
10499
+ * @param schemas Array of schemas
10500
+ * @param hasDirectives Boolean indicating that the element matches any directive
10501
+ */
10502
+ function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
10503
+ // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
10504
+ // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
10505
+ // defined as an array (as an empty array in case `schemas` field is not defined) and we should
10506
+ // execute the check below.
10507
+ if (schemas === null)
10508
+ return;
10509
+ // If the element matches any directive, it's considered as valid.
10510
+ if (!hasDirectives && tagName !== null) {
10511
+ // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
10512
+ // as a custom element. Note that unknown elements with a dash in their name won't be instances
10513
+ // of HTMLUnknownElement in browsers that support web components.
10514
+ const isUnknown =
10515
+ // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
10516
+ // because while most browsers return 'function', IE returns 'object'.
10517
+ (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
10518
+ element instanceof HTMLUnknownElement) ||
10519
+ (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
10520
+ !customElements.get(tagName));
10521
+ if (isUnknown && !matchingSchemas(schemas, tagName)) {
10522
+ const isHostStandalone = isHostComponentStandalone(lView);
10523
+ const templateLocation = getTemplateLocationDetails(lView);
10524
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
10525
+ let message = `'${tagName}' is not a known element${templateLocation}:\n`;
10526
+ message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
10527
+ 'a part of an @NgModule where this component is declared'}.\n`;
10528
+ if (tagName && tagName.indexOf('-') > -1) {
10529
+ message +=
10530
+ `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
10531
+ }
10532
+ else {
10533
+ message +=
10534
+ `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
10535
+ }
10536
+ if (shouldThrowErrorOnUnknownElement) {
10537
+ throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
10538
+ }
10539
+ else {
10540
+ console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
10541
+ }
10542
+ }
10358
10543
  }
10359
- /** @internal */
10360
- _throwOrNull(key, notFoundValue) {
10361
- if (notFoundValue !== THROW_IF_NOT_FOUND) {
10362
- return notFoundValue;
10363
- }
10364
- else {
10365
- throw noProviderError(this, key);
10366
- }
10544
+ }
10545
+ /**
10546
+ * Validates that the property of the element is known at runtime and returns
10547
+ * false if it's not the case.
10548
+ * This check is relevant for JIT-compiled components (for AOT-compiled
10549
+ * ones this check happens at build time).
10550
+ *
10551
+ * The property is considered known if either:
10552
+ * - it's a known property of the element
10553
+ * - the element is allowed by one of the schemas
10554
+ * - the property is used for animations
10555
+ *
10556
+ * @param element Element to validate
10557
+ * @param propName Name of the property to check
10558
+ * @param tagName Name of the tag hosting the property
10559
+ * @param schemas Array of schemas
10560
+ */
10561
+ function isPropertyValid(element, propName, tagName, schemas) {
10562
+ // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
10563
+ // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
10564
+ // defined as an array (as an empty array in case `schemas` field is not defined) and we should
10565
+ // execute the check below.
10566
+ if (schemas === null)
10567
+ return true;
10568
+ // The property is considered valid if the element matches the schema, it exists on the element,
10569
+ // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
10570
+ if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
10571
+ return true;
10367
10572
  }
10368
- /** @internal */
10369
- _getByKeySelf(key, notFoundValue) {
10370
- const obj = this._getObjByKeyId(key.id);
10371
- return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
10573
+ // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
10574
+ // need to account for both here, while being careful with `typeof null` also returning 'object'.
10575
+ return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
10576
+ }
10577
+ /**
10578
+ * Logs or throws an error that a property is not supported on an element.
10579
+ *
10580
+ * @param propName Name of the invalid property
10581
+ * @param tagName Name of the tag hosting the property
10582
+ * @param nodeType Type of the node hosting the property
10583
+ * @param lView An `LView` that represents a current component
10584
+ */
10585
+ function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
10586
+ // Special-case a situation when a structural directive is applied to
10587
+ // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
10588
+ // In this case the compiler generates the `ɵɵtemplate` instruction with
10589
+ // the `null` as the tagName. The directive matching logic at runtime relies
10590
+ // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
10591
+ // a default value of the `tNode.value` is not feasible at this moment.
10592
+ if (!tagName && nodeType === 4 /* TNodeType.Container */) {
10593
+ tagName = 'ng-template';
10372
10594
  }
10373
- /** @internal */
10374
- _getByKeyDefault(key, notFoundValue, visibility) {
10375
- let inj;
10376
- if (visibility instanceof SkipSelf) {
10377
- inj = this.parent;
10378
- }
10379
- else {
10380
- inj = this;
10381
- }
10382
- while (inj instanceof ReflectiveInjector_) {
10383
- const inj_ = inj;
10384
- const obj = inj_._getObjByKeyId(key.id);
10385
- if (obj !== UNDEFINED)
10386
- return obj;
10387
- inj = inj_.parent;
10388
- }
10389
- if (inj !== null) {
10390
- return inj.get(key.token, notFoundValue);
10595
+ const isHostStandalone = isHostComponentStandalone(lView);
10596
+ const templateLocation = getTemplateLocationDetails(lView);
10597
+ let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
10598
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
10599
+ const importLocation = isHostStandalone ?
10600
+ 'included in the \'@Component.imports\' of this component' :
10601
+ 'a part of an @NgModule where this component is declared';
10602
+ if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
10603
+ // Most likely this is a control flow directive (such as `*ngIf`) used in
10604
+ // a template, but the `CommonModule` is not imported.
10605
+ message += `\nIf the '${propName}' is an Angular control flow directive, ` +
10606
+ `please make sure that the 'CommonModule' is ${importLocation}.`;
10607
+ }
10608
+ else {
10609
+ // May be an Angular component, which is not imported/declared?
10610
+ message += `\n1. If '${tagName}' is an Angular component and it has the ` +
10611
+ `'${propName}' input, then verify that it is ${importLocation}.`;
10612
+ // May be a Web Component?
10613
+ if (tagName && tagName.indexOf('-') > -1) {
10614
+ message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
10615
+ `to the ${schemas} of this component to suppress this message.`;
10616
+ message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
10617
+ `the ${schemas} of this component.`;
10391
10618
  }
10392
10619
  else {
10393
- return this._throwOrNull(key, notFoundValue);
10620
+ // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
10621
+ message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
10622
+ `the ${schemas} of this component.`;
10394
10623
  }
10395
10624
  }
10396
- get displayName() {
10397
- const providers = _mapProviders(this, (b) => ' "' + b.key.displayName + '" ')
10398
- .join(', ');
10399
- return `ReflectiveInjector(providers: [${providers}])`;
10400
- }
10401
- toString() {
10402
- return this.displayName;
10625
+ if (shouldThrowErrorOnUnknownProperty) {
10626
+ throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
10403
10627
  }
10404
- }
10405
- ReflectiveInjector_.INJECTOR_KEY = ( /* @__PURE__ */ReflectiveKey.get(Injector));
10406
- function _mapProviders(injector, fn) {
10407
- const res = [];
10408
- for (let i = 0; i < injector._providers.length; ++i) {
10409
- res[i] = fn(injector.getProviderAtIndex(i));
10628
+ else {
10629
+ console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
10410
10630
  }
10411
- return res;
10412
10631
  }
10413
-
10414
10632
  /**
10415
- * @license
10416
- * Copyright Google LLC All Rights Reserved.
10633
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
10634
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
10635
+ * be too slow for production mode and also it relies on the constructor function being available.
10417
10636
  *
10418
- * Use of this source code is governed by an MIT-style license that can be
10419
- * found in the LICENSE file at https://angular.io/license
10420
- */
10421
-
10422
- /**
10423
- * @license
10424
- * Copyright Google LLC All Rights Reserved.
10637
+ * Gets a reference to the host component def (where a current component is declared).
10425
10638
  *
10426
- * Use of this source code is governed by an MIT-style license that can be
10427
- * found in the LICENSE file at https://angular.io/license
10639
+ * @param lView An `LView` that represents a current component that is being rendered.
10428
10640
  */
10429
-
10641
+ function getDeclarationComponentDef(lView) {
10642
+ !ngDevMode && throwError('Must never be called in production mode');
10643
+ const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
10644
+ const context = declarationLView[CONTEXT];
10645
+ // Unable to obtain a context.
10646
+ if (!context)
10647
+ return null;
10648
+ return context.constructor ? getComponentDef(context.constructor) : null;
10649
+ }
10430
10650
  /**
10431
- * @license
10432
- * Copyright Google LLC All Rights Reserved.
10651
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
10652
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
10653
+ * be too slow for production mode.
10433
10654
  *
10434
- * Use of this source code is governed by an MIT-style license that can be
10435
- * found in the LICENSE file at https://angular.io/license
10655
+ * Checks if the current component is declared inside of a standalone component template.
10656
+ *
10657
+ * @param lView An `LView` that represents a current component that is being rendered.
10436
10658
  */
10437
- function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
10438
- const lView = getLView();
10439
- // Fall back to inject() if view hasn't been created. This situation can happen in tests
10440
- // if inject utilities are used before bootstrapping.
10441
- if (lView === null) {
10442
- // Verify that we will not get into infinite loop.
10443
- ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
10444
- return ɵɵinject(token, flags);
10445
- }
10446
- const tNode = getCurrentTNode();
10447
- return getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
10659
+ function isHostComponentStandalone(lView) {
10660
+ !ngDevMode && throwError('Must never be called in production mode');
10661
+ const componentDef = getDeclarationComponentDef(lView);
10662
+ // Treat host component as non-standalone if we can't obtain the def.
10663
+ return !!componentDef?.standalone;
10448
10664
  }
10449
10665
  /**
10450
- * Throws an error indicating that a factory function could not be generated by the compiler for a
10451
- * particular class.
10452
- *
10453
- * This instruction allows the actual error message to be optimized away when ngDevMode is turned
10454
- * off, saving bytes of generated code while still providing a good experience in dev mode.
10666
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
10667
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
10668
+ * be too slow for production mode.
10455
10669
  *
10456
- * The name of the class is not mentioned here, but will be in the generated factory function name
10457
- * and thus in the stack trace.
10670
+ * Constructs a string describing the location of the host component template. The function is used
10671
+ * in dev mode to produce error messages.
10458
10672
  *
10459
- * @codeGenApi
10673
+ * @param lView An `LView` that represents a current component that is being rendered.
10460
10674
  */
10461
- function ɵɵinvalidFactory() {
10462
- const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
10463
- throw new Error(msg);
10675
+ function getTemplateLocationDetails(lView) {
10676
+ !ngDevMode && throwError('Must never be called in production mode');
10677
+ const hostComponentDef = getDeclarationComponentDef(lView);
10678
+ const componentClassName = hostComponentDef?.type?.name;
10679
+ return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
10680
+ }
10681
+ /**
10682
+ * The set of known control flow directives.
10683
+ * We use this set to produce a more precises error message with a note
10684
+ * that the `CommonModule` should also be included.
10685
+ */
10686
+ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
10687
+ /**
10688
+ * Returns true if the tag name is allowed by specified schemas.
10689
+ * @param schemas Array of schemas
10690
+ * @param tagName Name of the tag
10691
+ */
10692
+ function matchingSchemas(schemas, tagName) {
10693
+ if (schemas !== null) {
10694
+ for (let i = 0; i < schemas.length; i++) {
10695
+ const schema = schemas[i];
10696
+ if (schema === NO_ERRORS_SCHEMA ||
10697
+ schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
10698
+ return true;
10699
+ }
10700
+ }
10701
+ }
10702
+ return false;
10464
10703
  }
10465
10704
 
10466
10705
  /**
@@ -11258,32 +11497,17 @@ class LContainerDebug {
11258
11497
  get movedViews() {
11259
11498
  return this._raw_lContainer[MOVED_VIEWS];
11260
11499
  }
11261
- get host() {
11262
- return this._raw_lContainer[HOST];
11263
- }
11264
- get native() {
11265
- return this._raw_lContainer[NATIVE];
11266
- }
11267
- get next() {
11268
- return toDebug(this._raw_lContainer[NEXT]);
11269
- }
11270
- }
11271
-
11272
- let shouldThrowErrorOnUnknownProperty = false;
11273
- /**
11274
- * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
11275
- * instead of just logging the error.
11276
- * (for AOT-compiled ones this check happens at build time).
11277
- */
11278
- function ɵsetUnknownPropertyStrictMode(shouldThrow) {
11279
- shouldThrowErrorOnUnknownProperty = shouldThrow;
11280
- }
11281
- /**
11282
- * Gets the current value of the strict mode.
11283
- */
11284
- function ɵgetUnknownPropertyStrictMode() {
11285
- return shouldThrowErrorOnUnknownProperty;
11500
+ get host() {
11501
+ return this._raw_lContainer[HOST];
11502
+ }
11503
+ get native() {
11504
+ return this._raw_lContainer[NATIVE];
11505
+ }
11506
+ get next() {
11507
+ return toDebug(this._raw_lContainer[NEXT]);
11508
+ }
11286
11509
  }
11510
+
11287
11511
  /**
11288
11512
  * A permanent marker promise which signifies that the current CD tree is
11289
11513
  * clean.
@@ -11442,55 +11666,6 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
11442
11666
  }
11443
11667
  return tNode;
11444
11668
  }
11445
- /**
11446
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11447
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11448
- * be too slow for production mode and also it relies on the constructor function being available.
11449
- *
11450
- * Gets a reference to the host component def (where a current component is declared).
11451
- *
11452
- * @param lView An `LView` that represents a current component that is being rendered.
11453
- */
11454
- function getDeclarationComponentDef(lView) {
11455
- !ngDevMode && throwError('Must never be called in production mode');
11456
- const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
11457
- const context = declarationLView[CONTEXT];
11458
- // Unable to obtain a context.
11459
- if (!context)
11460
- return null;
11461
- return context.constructor ? getComponentDef(context.constructor) : null;
11462
- }
11463
- /**
11464
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11465
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11466
- * be too slow for production mode.
11467
- *
11468
- * Checks if the current component is declared inside of a standalone component template.
11469
- *
11470
- * @param lView An `LView` that represents a current component that is being rendered.
11471
- */
11472
- function isHostComponentStandalone(lView) {
11473
- !ngDevMode && throwError('Must never be called in production mode');
11474
- const componentDef = getDeclarationComponentDef(lView);
11475
- // Treat host component as non-standalone if we can't obtain the def.
11476
- return !!(componentDef?.standalone);
11477
- }
11478
- /**
11479
- * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11480
- * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11481
- * be too slow for production mode.
11482
- *
11483
- * Constructs a string describing the location of the host component template. The function is used
11484
- * in dev mode to produce error messages.
11485
- *
11486
- * @param lView An `LView` that represents a current component that is being rendered.
11487
- */
11488
- function getTemplateLocationDetails(lView) {
11489
- !ngDevMode && throwError('Must never be called in production mode');
11490
- const hostComponentDef = getDeclarationComponentDef(lView);
11491
- const componentClassName = hostComponentDef?.type?.name;
11492
- return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
11493
- }
11494
11669
  /**
11495
11670
  * When elements are created dynamically after a view blueprint is created (e.g. through
11496
11671
  * i18nApply()), we need to adjust the blueprint for future
@@ -12157,10 +12332,8 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12157
12332
  propName = mapPropName(propName);
12158
12333
  if (ngDevMode) {
12159
12334
  validateAgainstEventProperties(propName);
12160
- if (!validateProperty(element, tNode.value, propName, tView.schemas)) {
12161
- // Return here since we only log warnings for unknown properties.
12162
- handleUnknownPropertyError(propName, tNode, lView);
12163
- return;
12335
+ if (!isPropertyValid(element, propName, tNode.value, tView.schemas)) {
12336
+ handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
12164
12337
  }
12165
12338
  ngDevMode.rendererSetProperty++;
12166
12339
  }
@@ -12179,7 +12352,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12179
12352
  // If the node is a container and the property didn't
12180
12353
  // match any of the inputs or schemas we should throw.
12181
12354
  if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
12182
- handleUnknownPropertyError(propName, tNode, lView);
12355
+ handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
12183
12356
  }
12184
12357
  }
12185
12358
  }
@@ -12231,116 +12404,6 @@ function setNgReflectProperties(lView, element, type, dataValue, value) {
12231
12404
  }
12232
12405
  }
12233
12406
  }
12234
- /**
12235
- * Validates that the property of the element is known at runtime and returns
12236
- * false if it's not the case.
12237
- * This check is relevant for JIT-compiled components (for AOT-compiled
12238
- * ones this check happens at build time).
12239
- *
12240
- * The property is considered known if either:
12241
- * - it's a known property of the element
12242
- * - the element is allowed by one of the schemas
12243
- * - the property is used for animations
12244
- *
12245
- * @param element Element to validate
12246
- * @param tagName Name of the tag to check
12247
- * @param propName Name of the property to check
12248
- * @param schemas Array of schemas
12249
- */
12250
- function validateProperty(element, tagName, propName, schemas) {
12251
- // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
12252
- // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
12253
- // defined as an array (as an empty array in case `schemas` field is not defined) and we should
12254
- // execute the check below.
12255
- if (schemas === null)
12256
- return true;
12257
- // The property is considered valid if the element matches the schema, it exists on the element,
12258
- // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
12259
- if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
12260
- return true;
12261
- }
12262
- // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
12263
- // need to account for both here, while being careful with `typeof null` also returning 'object'.
12264
- return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
12265
- }
12266
- /**
12267
- * Returns true if the tag name is allowed by specified schemas.
12268
- * @param schemas Array of schemas
12269
- * @param tagName Name of the tag
12270
- */
12271
- function matchingSchemas(schemas, tagName) {
12272
- if (schemas !== null) {
12273
- for (let i = 0; i < schemas.length; i++) {
12274
- const schema = schemas[i];
12275
- if (schema === NO_ERRORS_SCHEMA ||
12276
- schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
12277
- return true;
12278
- }
12279
- }
12280
- }
12281
- return false;
12282
- }
12283
- /**
12284
- * The set of known control flow directives.
12285
- * We use this set to produce a more precises error message with a note
12286
- * that the `CommonModule` should also be included.
12287
- */
12288
- const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
12289
- /**
12290
- * Logs or throws an error that a property is not supported on an element.
12291
- *
12292
- * @param propName Name of the invalid property.
12293
- * @param tNode A `TNode` that represents a current component that is being rendered.
12294
- * @param lView An `LView` that represents a current component that is being rendered.
12295
- */
12296
- function handleUnknownPropertyError(propName, tNode, lView) {
12297
- let tagName = tNode.value;
12298
- // Special-case a situation when a structural directive is applied to
12299
- // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
12300
- // In this case the compiler generates the `ɵɵtemplate` instruction with
12301
- // the `null` as the tagName. The directive matching logic at runtime relies
12302
- // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
12303
- // a default value of the `tNode.value` is not feasible at this moment.
12304
- if (!tagName && tNode.type === 4 /* TNodeType.Container */) {
12305
- tagName = 'ng-template';
12306
- }
12307
- const isHostStandalone = isHostComponentStandalone(lView);
12308
- const templateLocation = getTemplateLocationDetails(lView);
12309
- let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
12310
- const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
12311
- const importLocation = isHostStandalone ?
12312
- 'included in the \'@Component.imports\' of this component' :
12313
- 'a part of an @NgModule where this component is declared';
12314
- if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
12315
- // Most likely this is a control flow directive (such as `*ngIf`) used in
12316
- // a template, but the `CommonModule` is not imported.
12317
- message += `\nIf the '${propName}' is an Angular control flow directive, ` +
12318
- `please make sure that the 'CommonModule' is ${importLocation}.`;
12319
- }
12320
- else {
12321
- // May be an Angular component, which is not imported/declared?
12322
- message += `\n1. If '${tagName}' is an Angular component and it has the ` +
12323
- `'${propName}' input, then verify that it is ${importLocation}.`;
12324
- // May be a Web Component?
12325
- if (tagName && tagName.indexOf('-') > -1) {
12326
- message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
12327
- `to the ${schemas} of this component to suppress this message.`;
12328
- message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
12329
- `the ${schemas} of this component.`;
12330
- }
12331
- else {
12332
- // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
12333
- message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
12334
- `the ${schemas} of this component.`;
12335
- }
12336
- }
12337
- if (shouldThrowErrorOnUnknownProperty) {
12338
- throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
12339
- }
12340
- else {
12341
- console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
12342
- }
12343
- }
12344
12407
  /**
12345
12408
  * Instantiate a root component.
12346
12409
  */
@@ -13914,7 +13977,11 @@ function createRootComponent(componentView, componentDef, rootLView, rootContext
13914
13977
  const component = instantiateRootComponent(tView, rootLView, componentDef);
13915
13978
  rootContext.components.push(component);
13916
13979
  componentView[CONTEXT] = component;
13917
- hostFeatures && hostFeatures.forEach((feature) => feature(component, componentDef));
13980
+ if (hostFeatures !== null) {
13981
+ for (const feature of hostFeatures) {
13982
+ feature(component, componentDef);
13983
+ }
13984
+ }
13918
13985
  // We want to generate an empty QueryList for root content queries for backwards
13919
13986
  // compatibility with ViewEngine.
13920
13987
  if (componentDef.contentQueries) {
@@ -13955,13 +14022,10 @@ function createRootContext(scheduler, playerHandler) {
13955
14022
  * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
13956
14023
  * ```
13957
14024
  */
13958
- function LifecycleHooksFeature(component, def) {
13959
- const lView = readPatchedLView(component);
13960
- ngDevMode && assertDefined(lView, 'LView is required');
13961
- const tView = lView[TVIEW];
14025
+ function LifecycleHooksFeature() {
13962
14026
  const tNode = getCurrentTNode();
13963
14027
  ngDevMode && assertDefined(tNode, 'TNode is required');
13964
- registerPostOrderHooks(tView, tNode);
14028
+ registerPostOrderHooks(getLView()[TVIEW], tNode);
13965
14029
  }
13966
14030
  /**
13967
14031
  * Wait on component until it is rendered.
@@ -14011,10 +14075,8 @@ function ɵɵInheritDefinitionFeature(definition) {
14011
14075
  }
14012
14076
  else {
14013
14077
  if (superType.ɵcmp) {
14014
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
14015
- `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}` :
14016
- '';
14017
- throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, errorMessage);
14078
+ throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
14079
+ `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
14018
14080
  }
14019
14081
  // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14020
14082
  superDef = superType.ɵdir;
@@ -15096,21 +15158,6 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
15096
15158
  * Use of this source code is governed by an MIT-style license that can be
15097
15159
  * found in the LICENSE file at https://angular.io/license
15098
15160
  */
15099
- let shouldThrowErrorOnUnknownElement = false;
15100
- /**
15101
- * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
15102
- * instead of just logging the error.
15103
- * (for AOT-compiled ones this check happens at build time).
15104
- */
15105
- function ɵsetUnknownElementStrictMode(shouldThrow) {
15106
- shouldThrowErrorOnUnknownElement = shouldThrow;
15107
- }
15108
- /**
15109
- * Gets the current value of the strict mode.
15110
- */
15111
- function ɵgetUnknownElementStrictMode() {
15112
- return shouldThrowErrorOnUnknownElement;
15113
- }
15114
15161
  function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
15115
15162
  ngDevMode && assertFirstCreatePass(tView);
15116
15163
  ngDevMode && ngDevMode.firstCreatePass++;
@@ -15244,67 +15291,6 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
15244
15291
  ɵɵelementEnd();
15245
15292
  return ɵɵelement;
15246
15293
  }
15247
- /**
15248
- * Validates that the element is known at runtime and produces
15249
- * an error if it's not the case.
15250
- * This check is relevant for JIT-compiled components (for AOT-compiled
15251
- * ones this check happens at build time).
15252
- *
15253
- * The element is considered known if either:
15254
- * - it's a known HTML element
15255
- * - it's a known custom element
15256
- * - the element matches any directive
15257
- * - the element is allowed by one of the schemas
15258
- *
15259
- * @param element Element to validate
15260
- * @param lView An `LView` that represents a current component that is being rendered.
15261
- * @param tagName Name of the tag to check
15262
- * @param schemas Array of schemas
15263
- * @param hasDirectives Boolean indicating that the element matches any directive
15264
- */
15265
- function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
15266
- // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
15267
- // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
15268
- // defined as an array (as an empty array in case `schemas` field is not defined) and we should
15269
- // execute the check below.
15270
- if (schemas === null)
15271
- return;
15272
- // If the element matches any directive, it's considered as valid.
15273
- if (!hasDirectives && tagName !== null) {
15274
- // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
15275
- // as a custom element. Note that unknown elements with a dash in their name won't be instances
15276
- // of HTMLUnknownElement in browsers that support web components.
15277
- const isUnknown =
15278
- // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
15279
- // because while most browsers return 'function', IE returns 'object'.
15280
- (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
15281
- element instanceof HTMLUnknownElement) ||
15282
- (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
15283
- !customElements.get(tagName));
15284
- if (isUnknown && !matchingSchemas(schemas, tagName)) {
15285
- const isHostStandalone = isHostComponentStandalone(lView);
15286
- const templateLocation = getTemplateLocationDetails(lView);
15287
- const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
15288
- let message = `'${tagName}' is not a known element${templateLocation}:\n`;
15289
- message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
15290
- 'a part of an @NgModule where this component is declared'}.\n`;
15291
- if (tagName && tagName.indexOf('-') > -1) {
15292
- message +=
15293
- `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
15294
- }
15295
- else {
15296
- message +=
15297
- `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
15298
- }
15299
- if (shouldThrowErrorOnUnknownElement) {
15300
- throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
15301
- }
15302
- else {
15303
- console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
15304
- }
15305
- }
15306
- }
15307
- }
15308
15294
 
15309
15295
  /**
15310
15296
  * @license
@@ -21787,7 +21773,7 @@ class Version {
21787
21773
  /**
21788
21774
  * @publicApi
21789
21775
  */
21790
- const VERSION = new Version('14.0.0');
21776
+ const VERSION = new Version('14.0.3');
21791
21777
 
21792
21778
  /**
21793
21779
  * @license
@@ -22125,8 +22111,7 @@ class ViewRef$1 {
22125
22111
  }
22126
22112
  attachToViewContainerRef() {
22127
22113
  if (this._appRef) {
22128
- const errorMessage = ngDevMode ? 'This view is already attached directly to the ApplicationRef!' : '';
22129
- throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
22114
+ throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached directly to the ApplicationRef!');
22130
22115
  }
22131
22116
  this._attachedToViewContainer = true;
22132
22117
  }
@@ -22136,8 +22121,7 @@ class ViewRef$1 {
22136
22121
  }
22137
22122
  attachToAppRef(appRef) {
22138
22123
  if (this._attachedToViewContainer) {
22139
- const errorMessage = ngDevMode ? 'This view is already attached to a ViewContainer!' : '';
22140
- throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
22124
+ throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
22141
22125
  }
22142
22126
  this._appRef = appRef;
22143
22127
  }
@@ -22487,14 +22471,14 @@ class StandaloneService {
22487
22471
  if (!componentDef.standalone) {
22488
22472
  return null;
22489
22473
  }
22490
- if (!this.cachedInjectors.has(componentDef)) {
22474
+ if (!this.cachedInjectors.has(componentDef.id)) {
22491
22475
  const providers = internalImportProvidersFrom(false, componentDef.type);
22492
22476
  const standaloneInjector = providers.length > 0 ?
22493
22477
  createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22494
22478
  null;
22495
- this.cachedInjectors.set(componentDef, standaloneInjector);
22479
+ this.cachedInjectors.set(componentDef.id, standaloneInjector);
22496
22480
  }
22497
- return this.cachedInjectors.get(componentDef);
22481
+ return this.cachedInjectors.get(componentDef.id);
22498
22482
  }
22499
22483
  ngOnDestroy() {
22500
22484
  try {
@@ -22994,13 +22978,26 @@ function getPipeDef(name, registry) {
22994
22978
  }
22995
22979
  }
22996
22980
  if (ngDevMode) {
22997
- const lView = getLView();
22998
- const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
22999
- const context = declarationLView[CONTEXT];
23000
- const component = context ? ` in the '${context.constructor.name}' component` : '';
23001
- throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, `The pipe '${name}' could not be found${component}!`);
22981
+ throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
23002
22982
  }
23003
22983
  }
22984
+ /**
22985
+ * Generates a helpful error message for the user when a pipe is not found.
22986
+ *
22987
+ * @param name Name of the missing pipe
22988
+ * @returns The error message
22989
+ */
22990
+ function getPipeNotFoundErrorMessage(name) {
22991
+ const lView = getLView();
22992
+ const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
22993
+ const context = declarationLView[CONTEXT];
22994
+ const hostIsStandalone = isHostComponentStandalone(lView);
22995
+ const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
22996
+ const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
22997
+ 'declared or imported in this module'}`;
22998
+ const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
22999
+ return errorMessage;
23000
+ }
23004
23001
  /**
23005
23002
  * Invokes a pipe with 1 arguments.
23006
23003
  *
@@ -24814,6 +24811,7 @@ function setScopeOnDeclaredComponents(moduleType, ngModule) {
24814
24811
  const declarations = flatten(ngModule.declarations || EMPTY_ARRAY);
24815
24812
  const transitiveScopes = transitiveScopesFor(moduleType);
24816
24813
  declarations.forEach(declaration => {
24814
+ declaration = resolveForwardRef(declaration);
24817
24815
  if (declaration.hasOwnProperty(NG_COMP_DEF)) {
24818
24816
  // A `ɵcmp` field exists - go ahead and patch the component directly.
24819
24817
  const component = declaration;
@@ -24844,7 +24842,7 @@ function patchComponentDefWithScope(componentDef, transitiveScopes) {
24844
24842
  }
24845
24843
  /**
24846
24844
  * Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
24847
- * (eaither a NgModule or a standalone component / directive / pipe).
24845
+ * (either a NgModule or a standalone component / directive / pipe).
24848
24846
  */
24849
24847
  function transitiveScopesFor(type) {
24850
24848
  if (isNgModule(type)) {
@@ -25165,14 +25163,20 @@ function getStandaloneDefFunctions(type, imports) {
25165
25163
  // Standalone components are always able to self-reference, so include the component's own
25166
25164
  // definition in its `directiveDefs`.
25167
25165
  cachedDirectiveDefs = [getComponentDef(type)];
25166
+ const seen = new Set();
25168
25167
  for (const rawDep of imports) {
25169
25168
  ngDevMode && verifyStandaloneImport(rawDep, type);
25170
25169
  const dep = resolveForwardRef(rawDep);
25170
+ if (seen.has(dep)) {
25171
+ continue;
25172
+ }
25173
+ seen.add(dep);
25171
25174
  if (!!getNgModuleDef(dep)) {
25172
25175
  const scope = transitiveScopesFor(dep);
25173
25176
  for (const dir of scope.exported.directives) {
25174
25177
  const def = getComponentDef(dir) || getDirectiveDef(dir);
25175
- if (def) {
25178
+ if (def && !seen.has(dir)) {
25179
+ seen.add(dir);
25176
25180
  cachedDirectiveDefs.push(def);
25177
25181
  }
25178
25182
  }
@@ -25190,11 +25194,22 @@ function getStandaloneDefFunctions(type, imports) {
25190
25194
  const pipeDefs = () => {
25191
25195
  if (cachedPipeDefs === null) {
25192
25196
  cachedPipeDefs = [];
25197
+ const seen = new Set();
25193
25198
  for (const rawDep of imports) {
25194
25199
  const dep = resolveForwardRef(rawDep);
25200
+ if (seen.has(dep)) {
25201
+ continue;
25202
+ }
25203
+ seen.add(dep);
25195
25204
  if (!!getNgModuleDef(dep)) {
25196
25205
  const scope = transitiveScopesFor(dep);
25197
- cachedPipeDefs.push(...Array.from(scope.exported.pipes).map(pipe => getPipeDef$1(pipe)));
25206
+ for (const pipe of scope.exported.pipes) {
25207
+ const def = getPipeDef$1(pipe);
25208
+ if (def && !seen.has(pipe)) {
25209
+ seen.add(pipe);
25210
+ cachedPipeDefs.push(def);
25211
+ }
25212
+ }
25198
25213
  }
25199
25214
  else {
25200
25215
  const def = getPipeDef$1(dep);
@@ -26967,10 +26982,8 @@ class NgProbeToken {
26967
26982
  */
26968
26983
  function createPlatform(injector) {
26969
26984
  if (_platformInjector && !_platformInjector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
26970
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
26971
- 'There can be only one platform. Destroy the previous one to create a new one.' :
26972
- '';
26973
- throw new RuntimeError(400 /* RuntimeErrorCode.MULTIPLE_PLATFORMS */, errorMessage);
26985
+ throw new RuntimeError(400 /* RuntimeErrorCode.MULTIPLE_PLATFORMS */, ngDevMode &&
26986
+ 'There can be only one platform. Destroy the previous one to create a new one.');
26974
26987
  }
26975
26988
  publishDefaultGlobalUtils();
26976
26989
  _platformInjector = injector;
@@ -27090,8 +27103,7 @@ function createPlatformFactory(parentPlatformFactory, name, providers = []) {
27090
27103
  function assertPlatform(requiredToken) {
27091
27104
  const platform = getPlatform();
27092
27105
  if (!platform) {
27093
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ? 'No platform exists!' : '';
27094
- throw new RuntimeError(401 /* RuntimeErrorCode.PLATFORM_NOT_FOUND */, errorMessage);
27106
+ throw new RuntimeError(401 /* RuntimeErrorCode.PLATFORM_NOT_FOUND */, ngDevMode && 'No platform exists!');
27095
27107
  }
27096
27108
  if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
27097
27109
  !platform.injector.get(requiredToken, null)) {
@@ -27169,10 +27181,7 @@ class PlatformRef {
27169
27181
  const moduleRef = moduleFactory.create(ngZoneInjector);
27170
27182
  const exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
27171
27183
  if (!exceptionHandler) {
27172
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
27173
- 'No ErrorHandler. Is platform module (BrowserModule) included?' :
27174
- '';
27175
- throw new RuntimeError(402 /* RuntimeErrorCode.ERROR_HANDLER_NOT_FOUND */, errorMessage);
27184
+ throw new RuntimeError(402 /* RuntimeErrorCode.ERROR_HANDLER_NOT_FOUND */, ngDevMode && 'No ErrorHandler. Is platform module (BrowserModule) included?');
27176
27185
  }
27177
27186
  ngZone.runOutsideAngular(() => {
27178
27187
  const subscription = ngZone.onError.subscribe({
@@ -27228,12 +27237,10 @@ class PlatformRef {
27228
27237
  moduleRef.instance.ngDoBootstrap(appRef);
27229
27238
  }
27230
27239
  else {
27231
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
27240
+ throw new RuntimeError(403 /* RuntimeErrorCode.BOOTSTRAP_COMPONENTS_NOT_FOUND */, ngDevMode &&
27232
27241
  `The module ${stringify(moduleRef.instance.constructor)} was bootstrapped, ` +
27233
27242
  `but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. ` +
27234
- `Please define one of these.` :
27235
- '';
27236
- throw new RuntimeError(403 /* RuntimeErrorCode.BOOTSTRAP_COMPONENTS_NOT_FOUND */, errorMessage);
27243
+ `Please define one of these.`);
27237
27244
  }
27238
27245
  this._modules.push(moduleRef);
27239
27246
  }
@@ -27256,10 +27263,7 @@ class PlatformRef {
27256
27263
  */
27257
27264
  destroy() {
27258
27265
  if (this._destroyed) {
27259
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
27260
- 'The platform has already been destroyed!' :
27261
- '';
27262
- throw new RuntimeError(404 /* RuntimeErrorCode.PLATFORM_ALREADY_DESTROYED */, errorMessage);
27266
+ throw new RuntimeError(404 /* RuntimeErrorCode.PLATFORM_ALREADY_DESTROYED */, ngDevMode && 'The platform has already been destroyed!');
27263
27267
  }
27264
27268
  this._modules.slice().forEach(module => module.destroy());
27265
27269
  this._destroyListeners.forEach(listener => listener());
@@ -27591,10 +27595,7 @@ class ApplicationRef {
27591
27595
  tick() {
27592
27596
  NG_DEV_MODE && this.warnIfDestroyed();
27593
27597
  if (this._runningTick) {
27594
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
27595
- 'ApplicationRef.tick is called recursively' :
27596
- '';
27597
- throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, errorMessage);
27598
+ throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, ngDevMode && 'ApplicationRef.tick is called recursively');
27598
27599
  }
27599
27600
  try {
27600
27601
  this._runningTick = true;
@@ -27683,7 +27684,7 @@ class ApplicationRef {
27683
27684
  */
27684
27685
  destroy() {
27685
27686
  if (this._destroyed) {
27686
- throw new RuntimeError(406 /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */, NG_DEV_MODE && 'This instance of the `ApplicationRef` has already been destroyed.');
27687
+ throw new RuntimeError(406 /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */, ngDevMode && 'This instance of the `ApplicationRef` has already been destroyed.');
27687
27688
  }
27688
27689
  const injector = this._injector;
27689
27690
  // Check that this injector instance supports destroy operation.
@@ -28720,10 +28721,8 @@ class DefaultIterableDiffer {
28720
28721
  if (collection == null)
28721
28722
  collection = [];
28722
28723
  if (!isListLikeIterable(collection)) {
28723
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
28724
- `Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed` :
28725
- '';
28726
- throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, errorMessage);
28724
+ throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode &&
28725
+ `Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed`);
28727
28726
  }
28728
28727
  if (this.check(collection)) {
28729
28728
  return this;
@@ -29324,10 +29323,8 @@ class DefaultKeyValueDiffer {
29324
29323
  map = new Map();
29325
29324
  }
29326
29325
  else if (!(map instanceof Map || isJsObject(map))) {
29327
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
29328
- `Error trying to diff '${stringify(map)}'. Only maps and objects are allowed` :
29329
- '';
29330
- throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, errorMessage);
29326
+ throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode &&
29327
+ `Error trying to diff '${stringify(map)}'. Only maps and objects are allowed`);
29331
29328
  }
29332
29329
  return this.check(map) ? this : null;
29333
29330
  }
@@ -29574,10 +29571,8 @@ class IterableDiffers {
29574
29571
  return factory;
29575
29572
  }
29576
29573
  else {
29577
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
29578
- `Cannot find a differ supporting object '${iterable}' of type '${getTypeNameForDebugging(iterable)}'` :
29579
- '';
29580
- throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, errorMessage);
29574
+ throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, ngDevMode &&
29575
+ `Cannot find a differ supporting object '${iterable}' of type '${getTypeNameForDebugging(iterable)}'`);
29581
29576
  }
29582
29577
  }
29583
29578
  }
@@ -29651,10 +29646,7 @@ class KeyValueDiffers {
29651
29646
  if (factory) {
29652
29647
  return factory;
29653
29648
  }
29654
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
29655
- `Cannot find a differ supporting object '${kv}'` :
29656
- '';
29657
- throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, errorMessage);
29649
+ throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, ngDevMode && `Cannot find a differ supporting object '${kv}'`);
29658
29650
  }
29659
29651
  }
29660
29652
  /** @nocollapse */