@angular/core 16.0.1 → 16.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 (34) hide show
  1. package/esm2022/src/change_detection/change_detector_ref.mjs +2 -2
  2. package/esm2022/src/core_private_export.mjs +1 -2
  3. package/esm2022/src/di/forward_ref.mjs +29 -2
  4. package/esm2022/src/di/r3_injector.mjs +6 -3
  5. package/esm2022/src/errors.mjs +1 -1
  6. package/esm2022/src/hydration/api.mjs +31 -3
  7. package/esm2022/src/i18n/locale_data_api.mjs +2 -2
  8. package/esm2022/src/interface/lifecycle_hooks.mjs +1 -1
  9. package/esm2022/src/render3/bindings.mjs +2 -2
  10. package/esm2022/src/render3/component.mjs +4 -4
  11. package/esm2022/src/render3/definition.mjs +6 -6
  12. package/esm2022/src/render3/di.mjs +5 -2
  13. package/esm2022/src/render3/errors.mjs +24 -3
  14. package/esm2022/src/render3/features/host_directives_feature.mjs +2 -2
  15. package/esm2022/src/render3/instructions/listener.mjs +1 -3
  16. package/esm2022/src/render3/jit/module.mjs +11 -11
  17. package/esm2022/src/render3/node_manipulation.mjs +4 -2
  18. package/esm2022/src/signals/src/api.mjs +5 -3
  19. package/esm2022/src/transfer_state.mjs +7 -23
  20. package/esm2022/src/version.mjs +1 -1
  21. package/esm2022/testing/src/logger.mjs +3 -3
  22. package/esm2022/testing/src/test_bed_common.mjs +1 -1
  23. package/fesm2022/core.mjs +126 -60
  24. package/fesm2022/core.mjs.map +1 -1
  25. package/fesm2022/rxjs-interop.mjs +5 -3
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +92 -53
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/index.d.ts +44 -17
  30. package/package.json +1 -1
  31. package/rxjs-interop/index.d.ts +1 -1
  32. package/schematics/ng-generate/standalone-migration/bundle.js +10 -10
  33. package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
  34. package/testing/index.d.ts +5 -5
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.0.1
2
+ * @license Angular v16.0.3
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -656,9 +656,36 @@ const __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafe
656
656
  * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
657
657
  * a query is not yet defined.
658
658
  *
659
+ * `forwardRef` is also used to break circularities in standalone components imports.
660
+ *
659
661
  * @usageNotes
660
- * ### Example
662
+ * ### Circular dependency example
661
663
  * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
664
+ *
665
+ * ### Circular standalone reference import example
666
+ * ```ts
667
+ * @Component({
668
+ * standalone: true,
669
+ * imports: [ChildComponent],
670
+ * selector: 'app-parent',
671
+ * template: `<app-child [hideParent]="hideParent"></app-child>`,
672
+ * })
673
+ * export class ParentComponent {
674
+ * @Input() hideParent: boolean;
675
+ * }
676
+ *
677
+ *
678
+ * @Component({
679
+ * standalone: true,
680
+ * imports: [CommonModule, forwardRef(() => ParentComponent)],
681
+ * selector: 'app-child',
682
+ * template: `<app-parent *ngIf="!hideParent"></app-parent>`,
683
+ * })
684
+ * export class ChildComponent {
685
+ * @Input() hideParent: boolean;
686
+ * }
687
+ * ```
688
+ *
662
689
  * @publicApi
663
690
  */
664
691
  function forwardRef(forwardRefFn) {
@@ -3084,7 +3111,7 @@ function getPipeDef$1(type) {
3084
3111
  /**
3085
3112
  * Checks whether a given Component, Directive or Pipe is marked as standalone.
3086
3113
  * This will return false if passed anything other than a Component, Directive, or Pipe class
3087
- * See this guide for additional information: https://angular.io/guide/standalone-components
3114
+ * See [this guide](/guide/standalone-components) for additional information:
3088
3115
  *
3089
3116
  * @param type A reference to a Component, Directive or Pipe.
3090
3117
  * @publicApi
@@ -3154,7 +3181,7 @@ function getComponentId(componentDef) {
3154
3181
  // Example:
3155
3182
  // https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248
3156
3183
  // https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32
3157
- const hashSelectors = JSON.stringify([
3184
+ const hashSelectors = [
3158
3185
  componentDef.selectors,
3159
3186
  componentDef.ngContentSelectors,
3160
3187
  componentDef.hostVars,
@@ -3165,14 +3192,14 @@ function getComponentId(componentDef) {
3165
3192
  componentDef.encapsulation,
3166
3193
  componentDef.standalone,
3167
3194
  componentDef.exportAs,
3168
- componentDef.inputs,
3169
- componentDef.outputs,
3195
+ JSON.stringify(componentDef.inputs),
3196
+ JSON.stringify(componentDef.outputs),
3170
3197
  // We cannot use 'componentDef.type.name' as the name of the symbol will change and will not
3171
3198
  // match in the server and browser bundles.
3172
3199
  Object.getOwnPropertyNames(componentDef.type.prototype),
3173
3200
  !!componentDef.contentQueries,
3174
3201
  !!componentDef.viewQuery,
3175
- ]);
3202
+ ].join('|');
3176
3203
  for (const char of hashSelectors) {
3177
3204
  hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;
3178
3205
  }
@@ -3430,10 +3457,12 @@ function getFactoryDef(type, throwNotFound) {
3430
3457
  */
3431
3458
  const SIGNAL = Symbol('SIGNAL');
3432
3459
  /**
3433
- * Checks if the given `value` function is a reactive `Signal`.
3460
+ * Checks if the given `value` is a reactive `Signal`.
3461
+ *
3462
+ * @developerPreview
3434
3463
  */
3435
3464
  function isSignal(value) {
3436
- return value[SIGNAL] !== undefined;
3465
+ return typeof value === 'function' && value[SIGNAL] !== undefined;
3437
3466
  }
3438
3467
  /**
3439
3468
  * Converts `fn` into a marked signal function (where `isSignal(fn)` will be `true`), and
@@ -5681,7 +5710,10 @@ function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default,
5681
5710
  if (tNode !== null) {
5682
5711
  // If the view or any of its ancestors have an embedded
5683
5712
  // view injector, we have to look it up there first.
5684
- if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */) {
5713
+ if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */ &&
5714
+ // The token must be present on the current node injector when the `Self`
5715
+ // flag is set, so the lookup on embedded view injector(s) can be skipped.
5716
+ !(flags & InjectFlags.Self)) {
5685
5717
  const embeddedInjectorValue = lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);
5686
5718
  if (embeddedInjectorValue !== NOT_FOUND) {
5687
5719
  return embeddedInjectorValue;
@@ -7459,12 +7491,14 @@ function processCleanups(tView, lView) {
7459
7491
  }
7460
7492
  const destroyHooks = lView[ON_DESTROY_HOOKS];
7461
7493
  if (destroyHooks !== null) {
7494
+ // Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister
7495
+ // themselves from mutating the array during iteration.
7496
+ lView[ON_DESTROY_HOOKS] = null;
7462
7497
  for (let i = 0; i < destroyHooks.length; i++) {
7463
7498
  const destroyHooksFn = destroyHooks[i];
7464
7499
  ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
7465
7500
  destroyHooksFn();
7466
7501
  }
7467
- lView[ON_DESTROY_HOOKS] = null;
7468
7502
  }
7469
7503
  }
7470
7504
  /** Calls onDestroy hooks for this view */
@@ -9461,7 +9495,11 @@ class R3Injector extends EnvironmentInjector {
9461
9495
  for (const service of this._ngOnDestroyHooks) {
9462
9496
  service.ngOnDestroy();
9463
9497
  }
9464
- for (const hook of this._onDestroyHooks) {
9498
+ const onDestroyHooks = this._onDestroyHooks;
9499
+ // Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
9500
+ // themselves from mutating the array during iteration.
9501
+ this._onDestroyHooks = [];
9502
+ for (const hook of onDestroyHooks) {
9465
9503
  hook();
9466
9504
  }
9467
9505
  }
@@ -9470,7 +9508,6 @@ class R3Injector extends EnvironmentInjector {
9470
9508
  this.records.clear();
9471
9509
  this._ngOnDestroyHooks.clear();
9472
9510
  this.injectorDefTypes.clear();
9473
- this._onDestroyHooks.length = 0;
9474
9511
  }
9475
9512
  }
9476
9513
  onDestroy(callback) {
@@ -9884,26 +9921,6 @@ const ENABLED_SSR_FEATURES = new InjectionToken((typeof ngDevMode === 'undefined
9884
9921
  factory: () => new Set(),
9885
9922
  });
9886
9923
 
9887
- function escapeTransferStateContent(text) {
9888
- const escapedText = {
9889
- '&': '&a;',
9890
- '"': '&q;',
9891
- '\'': '&s;',
9892
- '<': '&l;',
9893
- '>': '&g;',
9894
- };
9895
- return text.replace(/[&"'<>]/g, s => escapedText[s]);
9896
- }
9897
- function unescapeTransferStateContent(text) {
9898
- const unescapedText = {
9899
- '&a;': '&',
9900
- '&q;': '"',
9901
- '&s;': '\'',
9902
- '&l;': '<',
9903
- '&g;': '>',
9904
- };
9905
- return text.replace(/&[^;]+;/g, s => unescapedText[s]);
9906
- }
9907
9924
  /**
9908
9925
  * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
9909
9926
  *
@@ -10007,7 +10024,9 @@ class TransferState {
10007
10024
  }
10008
10025
  }
10009
10026
  }
10010
- return JSON.stringify(this.store);
10027
+ // Escape script tag to avoid break out of <script> tag in serialized output.
10028
+ // Encoding of `<` is the same behaviour as G3 script_builders.
10029
+ return JSON.stringify(this.store).replace(/</g, '\\u003C');
10011
10030
  }
10012
10031
  }
10013
10032
  function retrieveTransferredState(doc, appId) {
@@ -10017,7 +10036,9 @@ function retrieveTransferredState(doc, appId) {
10017
10036
  if (script?.textContent) {
10018
10037
  try {
10019
10038
  // Avoid using any here as it triggers lint errors in google3 (any is not allowed).
10020
- return JSON.parse(unescapeTransferStateContent(script.textContent));
10039
+ // Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3
10040
+ // script_builders.
10041
+ return JSON.parse(script.textContent);
10021
10042
  }
10022
10043
  catch (e) {
10023
10044
  console.warn('Exception while restoring TransferState for app ' + appId, e);
@@ -10443,7 +10464,7 @@ class Version {
10443
10464
  /**
10444
10465
  * @publicApi
10445
10466
  */
10446
- const VERSION = new Version('16.0.1');
10467
+ const VERSION = new Version('16.0.3');
10447
10468
 
10448
10469
  // This default value is when checking the hierarchy for a token.
10449
10470
  //
@@ -10585,6 +10606,10 @@ function normalizeDebugBindingValue(value) {
10585
10606
  }
10586
10607
  }
10587
10608
 
10609
+ /**
10610
+ * The max length of the string representation of a value in an error message
10611
+ */
10612
+ const VALUE_STRING_LENGTH_LIMIT = 200;
10588
10613
  /** Verifies that a given type is a Standalone Component. */
10589
10614
  function assertStandaloneComponentType(type) {
10590
10615
  assertComponentDef(type);
@@ -10610,9 +10635,11 @@ function throwMultipleComponentError(tNode, first, second) {
10610
10635
  `${stringifyForError(second)}`);
10611
10636
  }
10612
10637
  /** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
10613
- function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName) {
10638
+ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName, lView) {
10639
+ const hostComponentDef = getDeclarationComponentDef(lView);
10640
+ const componentClassName = hostComponentDef?.type?.name;
10614
10641
  const field = propName ? ` for '${propName}'` : '';
10615
- let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${oldValue}'. Current value: '${currValue}'.`;
10642
+ let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${formatValue(oldValue)}'. Current value: '${formatValue(currValue)}'.${componentClassName ? ` Expression location: ${componentClassName} component` : ''}`;
10616
10643
  if (creationMode) {
10617
10644
  msg +=
10618
10645
  ` It seems like the view has been created after its parent and its children have been dirty checked.` +
@@ -10620,6 +10647,20 @@ function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName)
10620
10647
  }
10621
10648
  throw new RuntimeError(-100 /* RuntimeErrorCode.EXPRESSION_CHANGED_AFTER_CHECKED */, msg);
10622
10649
  }
10650
+ function formatValue(value) {
10651
+ let strValue = String(value);
10652
+ // JSON.stringify will throw on circular references
10653
+ try {
10654
+ if (Array.isArray(value) || strValue === '[object Object]') {
10655
+ strValue = JSON.stringify(value);
10656
+ }
10657
+ }
10658
+ catch (error) {
10659
+ }
10660
+ return strValue.length > VALUE_STRING_LENGTH_LIMIT ?
10661
+ (strValue.substring(0, VALUE_STRING_LENGTH_LIMIT) + '…') :
10662
+ strValue;
10663
+ }
10623
10664
  function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
10624
10665
  const [propName, prefix, ...chunks] = meta.split(INTERPOLATION_DELIMITER);
10625
10666
  let oldValue = prefix, newValue = prefix;
@@ -13955,7 +13996,7 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
13955
13996
  throw new RuntimeError(311 /* RuntimeErrorCode.HOST_DIRECTIVE_UNDEFINED_BINDING */, `Directive ${className} does not have an ${bindingType} with a public name of ${publicName}.`);
13956
13997
  }
13957
13998
  const remappedPublicName = hostDirectiveBindings[publicName];
13958
- if (bindings.hasOwnProperty(remappedPublicName) &&
13999
+ if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName &&
13959
14000
  bindings[remappedPublicName] !== publicName) {
13960
14001
  throw new RuntimeError(312 /* RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS */, `Cannot alias ${bindingType} ${publicName} of host directive ${className} to ${remappedPublicName}, because it already has a different ${bindingType} with the same public name.`);
13961
14002
  }
@@ -14063,7 +14104,7 @@ function bindingUpdated(lView, bindingIndex, value) {
14063
14104
  const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14064
14105
  if (!devModeEqual(oldValueToCompare, value)) {
14065
14106
  const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14066
- throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14107
+ throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName, lView);
14067
14108
  }
14068
14109
  // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14069
14110
  // For this reason we exit as if no change. The early exit is needed to prevent the changed
@@ -16048,8 +16089,6 @@ function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault)
16048
16089
  }
16049
16090
  if (wrapWithPreventDefault && result === false) {
16050
16091
  e.preventDefault();
16051
- // Necessary for legacy browsers that don't support preventDefault (e.g. IE)
16052
- e.returnValue = false;
16053
16092
  }
16054
16093
  return result;
16055
16094
  };
@@ -19582,7 +19621,7 @@ function getLocaleCurrencyCode(locale) {
19582
19621
  * @param locale A locale code for the locale format rules to use.
19583
19622
  * @returns The plural function for the locale.
19584
19623
  * @see `NgPlural`
19585
- * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
19624
+ * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
19586
19625
  */
19587
19626
  function getLocalePluralCase(locale) {
19588
19627
  const data = findLocaleData(locale);
@@ -24761,16 +24800,16 @@ function computeCombinedExports(type) {
24761
24800
  if (ngModuleDef === null) {
24762
24801
  return [type];
24763
24802
  }
24764
- return [...flatten$1(maybeUnwrapFn$1(ngModuleDef.exports).map((type) => {
24765
- const ngModuleDef = getNgModuleDef(type);
24766
- if (ngModuleDef) {
24767
- verifySemanticsOfNgModuleDef(type, false);
24768
- return computeCombinedExports(type);
24769
- }
24770
- else {
24771
- return type;
24772
- }
24773
- }))];
24803
+ return flatten$1(maybeUnwrapFn$1(ngModuleDef.exports).map((type) => {
24804
+ const ngModuleDef = getNgModuleDef(type);
24805
+ if (ngModuleDef) {
24806
+ verifySemanticsOfNgModuleDef(type, false);
24807
+ return computeCombinedExports(type);
24808
+ }
24809
+ else {
24810
+ return type;
24811
+ }
24812
+ }));
24774
24813
  }
24775
24814
  /**
24776
24815
  * Some declared components may be compiled asynchronously, and thus may not have their