@angular/core 16.0.0-rc.0 → 16.0.0-rc.2

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 (42) hide show
  1. package/esm2022/rxjs-interop/src/index.mjs +1 -1
  2. package/esm2022/rxjs-interop/src/to_observable.mjs +1 -1
  3. package/esm2022/rxjs-interop/src/to_signal.mjs +2 -2
  4. package/esm2022/src/application_tokens.mjs +2 -2
  5. package/esm2022/src/core_private_export.mjs +2 -2
  6. package/esm2022/src/debug/debug_node.mjs +4 -9
  7. package/esm2022/src/di/interface/defs.mjs +3 -18
  8. package/esm2022/src/di/r3_injector.mjs +2 -1
  9. package/esm2022/src/errors.mjs +1 -1
  10. package/esm2022/src/hydration/annotate.mjs +5 -2
  11. package/esm2022/src/hydration/api.mjs +7 -7
  12. package/esm2022/src/hydration/node_lookup_utils.mjs +13 -8
  13. package/esm2022/src/hydration/tokens.mjs +5 -5
  14. package/esm2022/src/render3/assert.mjs +1 -1
  15. package/esm2022/src/render3/collect_native_nodes.mjs +18 -3
  16. package/esm2022/src/render3/i18n/i18n_parse.mjs +5 -6
  17. package/esm2022/src/render3/instructions/element_validation.mjs +4 -5
  18. package/esm2022/src/render3/instructions/shared.mjs +52 -25
  19. package/esm2022/src/render3/instructions/styling.mjs +22 -2
  20. package/esm2022/src/render3/instructions/template.mjs +2 -2
  21. package/esm2022/src/render3/reactive_lview_consumer.mjs +5 -5
  22. package/esm2022/src/render3/reactivity/effect.mjs +8 -3
  23. package/esm2022/src/render3/util/view_utils.mjs +5 -1
  24. package/esm2022/src/signals/src/signal.mjs +8 -1
  25. package/esm2022/src/version.mjs +1 -1
  26. package/esm2022/testing/src/logger.mjs +3 -3
  27. package/esm2022/testing/src/styling.mjs +1 -2
  28. package/esm2022/testing/src/test_bed_compiler.mjs +3 -8
  29. package/esm2022/testing/src/testing_internal.mjs +1 -2
  30. package/fesm2022/core.mjs +148 -85
  31. package/fesm2022/core.mjs.map +1 -1
  32. package/fesm2022/rxjs-interop.mjs +62 -2
  33. package/fesm2022/rxjs-interop.mjs.map +1 -1
  34. package/fesm2022/testing.mjs +137 -77
  35. package/fesm2022/testing.mjs.map +1 -1
  36. package/index.d.ts +12 -4
  37. package/package.json +1 -1
  38. package/rxjs-interop/index.d.ts +3 -3
  39. package/schematics/ng-generate/standalone-migration/bundle.js +618 -161
  40. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  41. package/testing/index.d.ts +1 -1
  42. package/esm2022/testing/src/ng_zone_mock.mjs +0 -34
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v16.0.0-rc.0
2
+ * @license Angular v16.0.0-rc.2
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { getDebugNode, RendererFactory2 as RendererFactory2$1, InjectionToken as InjectionToken$1, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef as resolveForwardRef$1, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID as LOCALE_ID$1, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, provideZoneChangeDetection, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ɵisEnvironmentProviders, ModuleWithComponentFactories, ɵconvertToBitFlags, Injector as Injector$1, InjectFlags as InjectFlags$1, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode as ɵsetUnknownElementStrictMode$1, ɵsetUnknownPropertyStrictMode as ɵsetUnknownPropertyStrictMode$1, ɵgetUnknownElementStrictMode as ɵgetUnknownElementStrictMode$1, ɵgetUnknownPropertyStrictMode as ɵgetUnknownPropertyStrictMode$1, EnvironmentInjector as EnvironmentInjector$1, NgZone, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
7
+ import { getDebugNode, RendererFactory2 as RendererFactory2$1, InjectionToken as InjectionToken$1, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef as resolveForwardRef$1, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID as LOCALE_ID$1, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, provideZoneChangeDetection, Compiler, COMPILER_OPTIONS, Injector as Injector$1, ɵisEnvironmentProviders, ɵNgModuleFactory, ModuleWithComponentFactories, ɵconvertToBitFlags, InjectFlags as InjectFlags$1, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode as ɵsetUnknownElementStrictMode$1, ɵsetUnknownPropertyStrictMode as ɵsetUnknownPropertyStrictMode$1, ɵgetUnknownElementStrictMode as ɵgetUnknownElementStrictMode$1, ɵgetUnknownPropertyStrictMode as ɵgetUnknownPropertyStrictMode$1, EnvironmentInjector as EnvironmentInjector$1, NgZone, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
8
8
  import { ResourceLoader } from '@angular/compiler';
9
9
  import { Subject, Subscription } from 'rxjs';
10
10
 
@@ -771,30 +771,15 @@ function getOwnDefinition(type, field) {
771
771
  function getInheritedInjectableDef(type) {
772
772
  const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);
773
773
  if (def) {
774
- const typeName = getTypeName(type);
775
774
  ngDevMode &&
776
- console.warn(`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` +
777
- `This will become an error in a future version of Angular. Please add @Injectable() to the "${typeName}" class.`);
775
+ console.warn(`DEPRECATED: DI is instantiating a token "${type.name}" that inherits its @Injectable decorator but does not provide one itself.\n` +
776
+ `This will become an error in a future version of Angular. Please add @Injectable() to the "${type.name}" class.`);
778
777
  return def;
779
778
  }
780
779
  else {
781
780
  return null;
782
781
  }
783
782
  }
784
- /** Gets the name of a type, accounting for some cross-browser differences. */
785
- function getTypeName(type) {
786
- // `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
787
- // it'll always return the name of the function itself, no matter how many other functions it
788
- // inherits from. On IE the function doesn't have its own `name` property, but it takes it from
789
- // the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
790
- // browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
791
- // the issue by converting the function to a string and parsing its name out that way via a regex.
792
- if (type.hasOwnProperty('name')) {
793
- return type.name;
794
- }
795
- const match = ('' + type).match(/^function\s*([^\s(]+)/);
796
- return match === null ? '' : match[1];
797
- }
798
783
  /**
799
784
  * Read the injector def type in a way which is immune to accidentally reading inherited value.
800
785
  *
@@ -3894,6 +3879,12 @@ class WritableSignalImpl extends ReactiveNode {
3894
3879
  this.producerMayHaveChanged();
3895
3880
  postSignalSetFn?.();
3896
3881
  }
3882
+ asReadonly() {
3883
+ if (this.readonlySignal === undefined) {
3884
+ this.readonlySignal = createSignalFromFunction(this, () => this.signal());
3885
+ }
3886
+ return this.readonlySignal;
3887
+ }
3897
3888
  signal() {
3898
3889
  this.producerAccessed();
3899
3890
  return this.value;
@@ -3912,6 +3903,7 @@ function signal(initialValue, options) {
3912
3903
  set: signalNode.set.bind(signalNode),
3913
3904
  update: signalNode.update.bind(signalNode),
3914
3905
  mutate: signalNode.mutate.bind(signalNode),
3906
+ asReadonly: signalNode.asReadonly.bind(signalNode)
3915
3907
  });
3916
3908
  return signalFn;
3917
3909
  }
@@ -4290,6 +4282,9 @@ function updateTransplantedViewCount(lContainer, amount) {
4290
4282
  * Stores a LView-specific destroy callback.
4291
4283
  */
4292
4284
  function storeLViewOnDestroy(lView, onDestroyCallback) {
4285
+ if ((lView[FLAGS] & 256 /* LViewFlags.Destroyed */) === 256 /* LViewFlags.Destroyed */) {
4286
+ throw new RuntimeError(911 /* RuntimeErrorCode.VIEW_ALREADY_DESTROYED */, ngDevMode && 'View has already been destroyed.');
4287
+ }
4293
4288
  if (lView[ON_DESTROY_HOOKS] === null) {
4294
4289
  lView[ON_DESTROY_HOOKS] = [];
4295
4290
  }
@@ -6314,8 +6309,8 @@ function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives)
6314
6309
  // as a custom element. Note that unknown elements with a dash in their name won't be instances
6315
6310
  // of HTMLUnknownElement in browsers that support web components.
6316
6311
  const isUnknown =
6317
- // Note that we can't check for `typeof HTMLUnknownElement === 'function'`,
6318
- // because while most browsers return 'function', IE returns 'object'.
6312
+ // Note that we can't check for `typeof HTMLUnknownElement === 'function'` because
6313
+ // Domino doesn't expose HTMLUnknownElement globally.
6319
6314
  (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&
6320
6315
  element instanceof HTMLUnknownElement) ||
6321
6316
  (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
@@ -6372,8 +6367,7 @@ function isPropertyValid(element, propName, tagName, schemas) {
6372
6367
  if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
6373
6368
  return true;
6374
6369
  }
6375
- // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
6376
- // need to account for both here, while being careful with `typeof null` also returning 'object'.
6370
+ // Note: `typeof Node` returns 'function' in most browsers, but is undefined with domino.
6377
6371
  return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
6378
6372
  }
6379
6373
  /**
@@ -9403,6 +9397,7 @@ class R3Injector extends EnvironmentInjector {
9403
9397
  }
9404
9398
  }
9405
9399
  onDestroy(callback) {
9400
+ this.assertNotDestroyed();
9406
9401
  this._onDestroyHooks.push(callback);
9407
9402
  return () => this.removeOnDestroy(callback);
9408
9403
  }
@@ -9798,7 +9793,7 @@ const CSP_NONCE = new InjectionToken('CSP nonce', {
9798
9793
  // 4. Have the `ComponentFactory` read the attribute and provide it to the injector under the
9799
9794
  // hood - has the same problem as #1 and #2 in that the renderer is used to query for the root
9800
9795
  // node and the nonce value needs to be available when the renderer is created.
9801
- return getDocument().body.querySelector('[ngCspNonce]')?.getAttribute('ngCspNonce') || null;
9796
+ return getDocument().body?.querySelector('[ngCspNonce]')?.getAttribute('ngCspNonce') || null;
9802
9797
  },
9803
9798
  });
9804
9799
  /**
@@ -10364,7 +10359,7 @@ class Version {
10364
10359
  /**
10365
10360
  * @publicApi
10366
10361
  */
10367
- const VERSION = new Version('16.0.0-rc.0');
10362
+ const VERSION = new Version('16.0.0-rc.2');
10368
10363
 
10369
10364
  // This default value is when checking the hierarchy for a token.
10370
10365
  //
@@ -10512,11 +10507,11 @@ function isInSkipHydrationBlock(tNode) {
10512
10507
  return false;
10513
10508
  }
10514
10509
 
10515
- const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
10516
10510
  /**
10517
- * Internal token that specifies whether hydration is enabled.
10511
+ * Internal token that specifies whether DOM reuse logic
10512
+ * during hydration is enabled.
10518
10513
  */
10519
- const IS_HYDRATION_FEATURE_ENABLED = new InjectionToken(NG_DEV_MODE$1 ? 'IS_HYDRATION_FEATURE_ENABLED' : '');
10514
+ const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
10520
10515
  // By default (in client rendering mode), we remove all the contents
10521
10516
  // of the host element and render an application after that.
10522
10517
  const PRESERVE_HOST_CONTENT_DEFAULT = false;
@@ -10524,7 +10519,7 @@ const PRESERVE_HOST_CONTENT_DEFAULT = false;
10524
10519
  * Internal token that indicates whether host element content should be
10525
10520
  * retained during the bootstrap.
10526
10521
  */
10527
- const PRESERVE_HOST_CONTENT = new InjectionToken(NG_DEV_MODE$1 ? 'PRESERVE_HOST_CONTENT' : '', {
10522
+ const PRESERVE_HOST_CONTENT = new InjectionToken((typeof ngDevMode === 'undefined' || !!ngDevMode) ? 'PRESERVE_HOST_CONTENT' : '', {
10528
10523
  providedIn: 'root',
10529
10524
  factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
10530
10525
  });
@@ -10634,7 +10629,6 @@ function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValu
10634
10629
  return { propName: undefined, oldValue, newValue };
10635
10630
  }
10636
10631
 
10637
- const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
10638
10632
  class ReactiveLViewConsumer extends ReactiveNode {
10639
10633
  constructor() {
10640
10634
  super(...arguments);
@@ -10642,11 +10636,12 @@ class ReactiveLViewConsumer extends ReactiveNode {
10642
10636
  this._lView = null;
10643
10637
  }
10644
10638
  set lView(lView) {
10645
- NG_DEV_MODE && assertEqual(this._lView, null, 'Consumer already associated with a view.');
10639
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
10640
+ assertEqual(this._lView, null, 'Consumer already associated with a view.');
10646
10641
  this._lView = lView;
10647
10642
  }
10648
10643
  onConsumerDependencyMayHaveChanged() {
10649
- NG_DEV_MODE &&
10644
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
10650
10645
  assertDefined(this._lView, 'Updating a signal during template or host binding execution is not allowed.');
10651
10646
  markViewDirty(this._lView);
10652
10647
  }
@@ -11064,8 +11059,9 @@ function processHostBindingOpCodes(tView, lView) {
11064
11059
  }
11065
11060
  }
11066
11061
  finally {
11067
- lView[REACTIVE_HOST_BINDING_CONSUMER] === null &&
11062
+ if (lView[REACTIVE_HOST_BINDING_CONSUMER] === null) {
11068
11063
  commitLViewConsumerIfHasProducers(lView, REACTIVE_HOST_BINDING_CONSUMER);
11064
+ }
11069
11065
  setSelectedIndex(-1);
11070
11066
  }
11071
11067
  }
@@ -11120,7 +11116,6 @@ function createLView(parentLView, tView, context, flags, host, tHostNode, enviro
11120
11116
  lView[ID] = getUniqueLViewId();
11121
11117
  lView[HYDRATION] = hydrationInfo;
11122
11118
  lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
11123
- lView[REACTIVE_TEMPLATE_CONSUMER] = null;
11124
11119
  ngDevMode &&
11125
11120
  assertEqual(tView.type == 2 /* TViewType.Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
11126
11121
  lView[DECLARATION_COMPONENT_VIEW] =
@@ -11418,10 +11413,21 @@ function executeTemplate(tView, lView, templateFn, rf, context) {
11418
11413
  }
11419
11414
  const preHookType = isUpdatePhase ? 2 /* ProfilerEvent.TemplateUpdateStart */ : 0 /* ProfilerEvent.TemplateCreateStart */;
11420
11415
  profiler(preHookType, context);
11421
- consumer.runInContext(templateFn, rf, context);
11416
+ if (isUpdatePhase) {
11417
+ consumer.runInContext(templateFn, rf, context);
11418
+ }
11419
+ else {
11420
+ const prevConsumer = setActiveConsumer(null);
11421
+ try {
11422
+ templateFn(rf, context);
11423
+ }
11424
+ finally {
11425
+ setActiveConsumer(prevConsumer);
11426
+ }
11427
+ }
11422
11428
  }
11423
11429
  finally {
11424
- if (lView[REACTIVE_TEMPLATE_CONSUMER] === null) {
11430
+ if (isUpdatePhase && lView[REACTIVE_TEMPLATE_CONSUMER] === null) {
11425
11431
  commitLViewConsumerIfHasProducers(lView, REACTIVE_TEMPLATE_CONSUMER);
11426
11432
  }
11427
11433
  setSelectedIndex(prevSelectedIndex);
@@ -11434,14 +11440,20 @@ function executeTemplate(tView, lView, templateFn, rf, context) {
11434
11440
  //////////////////////////
11435
11441
  function executeContentQueries(tView, tNode, lView) {
11436
11442
  if (isContentQueryHost(tNode)) {
11437
- const start = tNode.directiveStart;
11438
- const end = tNode.directiveEnd;
11439
- for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
11440
- const def = tView.data[directiveIndex];
11441
- if (def.contentQueries) {
11442
- def.contentQueries(1 /* RenderFlags.Create */, lView[directiveIndex], directiveIndex);
11443
+ const prevConsumer = setActiveConsumer(null);
11444
+ try {
11445
+ const start = tNode.directiveStart;
11446
+ const end = tNode.directiveEnd;
11447
+ for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
11448
+ const def = tView.data[directiveIndex];
11449
+ if (def.contentQueries) {
11450
+ def.contentQueries(1 /* RenderFlags.Create */, lView[directiveIndex], directiveIndex);
11451
+ }
11443
11452
  }
11444
11453
  }
11454
+ finally {
11455
+ setActiveConsumer(prevConsumer);
11456
+ }
11445
11457
  }
11446
11458
  }
11447
11459
  /**
@@ -12260,17 +12272,11 @@ function setElementAttribute(renderer, element, namespace, tagName, name, value,
12260
12272
  function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
12261
12273
  const initialInputs = initialInputData[directiveIndex];
12262
12274
  if (initialInputs !== null) {
12263
- const setInput = def.setInput;
12264
12275
  for (let i = 0; i < initialInputs.length;) {
12265
12276
  const publicName = initialInputs[i++];
12266
12277
  const privateName = initialInputs[i++];
12267
12278
  const value = initialInputs[i++];
12268
- if (setInput !== null) {
12269
- def.setInput(instance, value, publicName, privateName);
12270
- }
12271
- else {
12272
- instance[privateName] = value;
12273
- }
12279
+ writeToDirectiveInput(def, instance, publicName, privateName, value);
12274
12280
  if (ngDevMode) {
12275
12281
  const nativeElement = getNativeByTNode(tNode, lView);
12276
12282
  setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
@@ -12278,6 +12284,20 @@ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initial
12278
12284
  }
12279
12285
  }
12280
12286
  }
12287
+ function writeToDirectiveInput(def, instance, publicName, privateName, value) {
12288
+ const prevConsumer = setActiveConsumer(null);
12289
+ try {
12290
+ if (def.setInput !== null) {
12291
+ def.setInput(instance, value, publicName, privateName);
12292
+ }
12293
+ else {
12294
+ instance[privateName] = value;
12295
+ }
12296
+ }
12297
+ finally {
12298
+ setActiveConsumer(prevConsumer);
12299
+ }
12300
+ }
12281
12301
  /**
12282
12302
  * Generates initialInputData for a node and stores it in the template's static storage
12283
12303
  * so subsequent template invocations don't have to recalculate it.
@@ -12572,7 +12592,13 @@ function checkNoChangesInternal(tView, lView, context, notifyErrorHandler = true
12572
12592
  function executeViewQueryFn(flags, viewQueryFn, component) {
12573
12593
  ngDevMode && assertDefined(viewQueryFn, 'View queries function to execute must be defined.');
12574
12594
  setCurrentQueryIndex(0);
12575
- viewQueryFn(flags, component);
12595
+ const prevConsumer = setActiveConsumer(null);
12596
+ try {
12597
+ viewQueryFn(flags, component);
12598
+ }
12599
+ finally {
12600
+ setActiveConsumer(prevConsumer);
12601
+ }
12576
12602
  }
12577
12603
  ///////////////////////////////
12578
12604
  //// Bindings & interpolations
@@ -12660,12 +12686,7 @@ function setInputsForProperty(tView, lView, inputs, publicName, value) {
12660
12686
  const instance = lView[index];
12661
12687
  ngDevMode && assertIndexInRange(lView, index);
12662
12688
  const def = tView.data[index];
12663
- if (def.setInput !== null) {
12664
- def.setInput(instance, value, publicName, privateName);
12665
- }
12666
- else {
12667
- instance[privateName] = value;
12668
- }
12689
+ writeToDirectiveInput(def, instance, publicName, privateName, value);
12669
12690
  }
12670
12691
  }
12671
12692
  /**
@@ -12723,7 +12744,7 @@ class EffectManager {
12723
12744
  this.queue = new Map();
12724
12745
  }
12725
12746
  create(effectFn, destroyRef, allowSignalWrites) {
12726
- const zone = Zone.current;
12747
+ const zone = (typeof Zone === 'undefined') ? null : Zone.current;
12727
12748
  const watch = new Watch(effectFn, (watch) => {
12728
12749
  if (!this.all.has(watch)) {
12729
12750
  return;
@@ -12751,7 +12772,12 @@ class EffectManager {
12751
12772
  }
12752
12773
  for (const [watch, zone] of this.queue) {
12753
12774
  this.queue.delete(watch);
12754
- zone.run(() => watch.run());
12775
+ if (zone) {
12776
+ zone.run(() => watch.run());
12777
+ }
12778
+ else {
12779
+ watch.run();
12780
+ }
12755
12781
  }
12756
12782
  }
12757
12783
  get isQueueEmpty() {
@@ -12833,6 +12859,21 @@ function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
12833
12859
  collectNativeNodes(lViewInAContainer[TVIEW], lViewInAContainer, lViewFirstChildTNode, result);
12834
12860
  }
12835
12861
  }
12862
+ // When an LContainer is created, the anchor (comment) node is:
12863
+ // - (1) either reused in case of an ElementContainer (<ng-container>)
12864
+ // - (2) or a new comment node is created
12865
+ // In the first case, the anchor comment node would be added to the final
12866
+ // list by the code above (`result.push(unwrapRNode(lNode))`), but the second
12867
+ // case requires extra handling: the anchor node needs to be added to the
12868
+ // final list manually. See additional information in the `createAnchorNode`
12869
+ // function in the `view_container_ref.ts`.
12870
+ //
12871
+ // In the first case, the same reference would be stored in the `NATIVE`
12872
+ // and `HOST` slots in an LContainer. Otherwise, this is the second case and
12873
+ // we should add an element to the final list.
12874
+ if (lNode[NATIVE] !== lNode[HOST]) {
12875
+ result.push(lNode[NATIVE]);
12876
+ }
12836
12877
  }
12837
12878
  const tNodeType = tNode.type;
12838
12879
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
@@ -15100,10 +15141,10 @@ function locateRNodeByPath(path, lView) {
15100
15141
  const [referenceNode, ...navigationInstructions] = decompressNodeLocation(path);
15101
15142
  let ref;
15102
15143
  if (referenceNode === REFERENCE_NODE_HOST) {
15103
- ref = lView[0];
15144
+ ref = lView[DECLARATION_COMPONENT_VIEW][HOST];
15104
15145
  }
15105
15146
  else if (referenceNode === REFERENCE_NODE_BODY) {
15106
- ref = ɵɵresolveBody(lView[0]);
15147
+ ref = ɵɵresolveBody(lView[DECLARATION_COMPONENT_VIEW][HOST]);
15107
15148
  }
15108
15149
  else {
15109
15150
  const parentElementId = Number(referenceNode);
@@ -15147,6 +15188,7 @@ function navigateBetween(start, finish) {
15147
15188
  }
15148
15189
  /**
15149
15190
  * Calculates a path between 2 sibling nodes (generates a number of `NextSibling` navigations).
15191
+ * Returns `null` if no such path exists between the given nodes.
15150
15192
  */
15151
15193
  function navigateBetweenSiblings(start, finish) {
15152
15194
  const nav = [];
@@ -15154,7 +15196,10 @@ function navigateBetweenSiblings(start, finish) {
15154
15196
  for (node = start; node != null && node !== finish; node = node.nextSibling) {
15155
15197
  nav.push(NodeNavigationStep.NextSibling);
15156
15198
  }
15157
- return node === null ? [] : nav;
15199
+ // If the `node` becomes `null` or `undefined` at the end, that means that we
15200
+ // didn't find the `end` node, thus return `null` (which would trigger serialization
15201
+ // error to be produced).
15202
+ return node == null ? null : nav;
15158
15203
  }
15159
15204
  /**
15160
15205
  * Calculates a path between 2 nodes in terms of `nextSibling` and `firstChild`
@@ -15177,10 +15222,11 @@ function calcPathForNode(tNode, lView) {
15177
15222
  let parentIndex;
15178
15223
  let parentRNode;
15179
15224
  let referenceNodeName;
15180
- if (parentTNode === null) {
15181
- // No parent TNode - use host element as a reference node.
15225
+ if (parentTNode === null || !(parentTNode.type & 3 /* TNodeType.AnyRNode */)) {
15226
+ // If there is no parent TNode or a parent TNode does not represent an RNode
15227
+ // (i.e. not a DOM node), use component host element as a reference node.
15182
15228
  parentIndex = referenceNodeName = REFERENCE_NODE_HOST;
15183
- parentRNode = lView[HOST];
15229
+ parentRNode = lView[DECLARATION_COMPONENT_VIEW][HOST];
15184
15230
  }
15185
15231
  else {
15186
15232
  // Use parent TNode as a reference node.
@@ -15232,7 +15278,7 @@ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, t
15232
15278
  const hydrationInfo = lView[HYDRATION];
15233
15279
  if (hydrationInfo) {
15234
15280
  const noOffsetIndex = index - HEADER_OFFSET;
15235
- ssrId = (hydrationInfo && hydrationInfo.data[TEMPLATES]?.[noOffsetIndex]) ?? null;
15281
+ ssrId = hydrationInfo.data[TEMPLATES]?.[noOffsetIndex] ?? null;
15236
15282
  }
15237
15283
  // TODO(pk): refactor getOrCreateTNode to have the "create" only version
15238
15284
  const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
@@ -17349,7 +17395,7 @@ function styleStringParser(keyValueArray, text) {
17349
17395
  * @codeGenApi
17350
17396
  */
17351
17397
  function ɵɵclassMap(classes) {
17352
- checkStylingMap(keyValueArraySet, classStringParser, classes, true);
17398
+ checkStylingMap(classKeyValueArraySet, classStringParser, classes, true);
17353
17399
  }
17354
17400
  /**
17355
17401
  * Parse text as class and add values to KeyValueArray.
@@ -17791,6 +17837,26 @@ function toStylingKeyValueArray(keyValueArraySet, stringParser, value) {
17791
17837
  function styleKeyValueArraySet(keyValueArray, key, value) {
17792
17838
  keyValueArraySet(keyValueArray, key, unwrapSafeValue(value));
17793
17839
  }
17840
+ /**
17841
+ * Class-binding-specific function for setting the `value` for a `key`.
17842
+ *
17843
+ * See: `keyValueArraySet` for details
17844
+ *
17845
+ * @param keyValueArray KeyValueArray to add to.
17846
+ * @param key Style key to add.
17847
+ * @param value The value to set.
17848
+ */
17849
+ function classKeyValueArraySet(keyValueArray, key, value) {
17850
+ // We use `classList.add` to eventually add the CSS classes to the DOM node. Any value passed into
17851
+ // `add` is stringified and added to the `class` attribute, e.g. even null, undefined or numbers
17852
+ // will be added. Stringify the key here so that our internal data structure matches the value in
17853
+ // the DOM. The only exceptions are empty strings and strings that contain spaces for which
17854
+ // the browser throws an error. We ignore such values, because the error is somewhat cryptic.
17855
+ const stringKey = String(key);
17856
+ if (stringKey !== '' && !stringKey.includes(' ')) {
17857
+ keyValueArraySet(keyValueArray, stringKey, value);
17858
+ }
17859
+ }
17794
17860
  /**
17795
17861
  * Update map based styling.
17796
17862
  *
@@ -20520,11 +20586,10 @@ const MARKER = `�`;
20520
20586
  const SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
20521
20587
  const PH_REGEXP = /�(\/?[#*]\d+):?\d*�/gi;
20522
20588
  /**
20523
- * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see:
20524
- * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32
20525
- * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character
20526
- * and later on replaced by a space. We are re-implementing the same idea here, since translations
20527
- * might contain this special character.
20589
+ * Angular uses the special entity &ngsp; as a placeholder for non-removable space.
20590
+ * It's replaced by the 0xE500 PUA (Private Use Areas) unicode character and later on replaced by a
20591
+ * space.
20592
+ * We are re-implementing the same idea since translations might contain this special character.
20528
20593
  */
20529
20594
  const NGSP_UNICODE_REGEXP = /\uE500/g;
20530
20595
  function replaceNgsp(value) {
@@ -25667,12 +25732,7 @@ class TestBedCompiler {
25667
25732
  if (this.compilerProviders !== null) {
25668
25733
  providers.push(...this.compilerProviders);
25669
25734
  }
25670
- // TODO(ocombe): make this work with an Injector directly instead of creating a module for it
25671
- class CompilerModule {
25672
- }
25673
- ɵcompileNgModuleDefs(CompilerModule, { providers });
25674
- const CompilerModuleFactory = new ɵNgModuleFactory(CompilerModule);
25675
- this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
25735
+ this._injector = Injector$1.create({ providers, parent: this.platform.injector });
25676
25736
  return this._injector;
25677
25737
  }
25678
25738
  // get overrides for a specific provider (if any)