@angular/core 20.0.0-next.4 → 20.0.0-next.6

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 (76) hide show
  1. package/api.d-DQLNOR5l.d.ts +297 -0
  2. package/discovery.d-CFs2MaLO.d.ts +7383 -0
  3. package/{event_dispatcher.d-pVP0-wST.d.ts → event_dispatcher.d-DlbccpYq.d.ts} +3 -2
  4. package/fesm2022/attribute-BWp59EjE.mjs +24 -0
  5. package/fesm2022/attribute-BWp59EjE.mjs.map +1 -0
  6. package/fesm2022/core.mjs +586 -36873
  7. package/fesm2022/core.mjs.map +1 -1
  8. package/fesm2022/debug_node-z_3NG8qT.mjs +32079 -0
  9. package/fesm2022/debug_node-z_3NG8qT.mjs.map +1 -0
  10. package/fesm2022/primitives/di.mjs +18 -4
  11. package/fesm2022/primitives/di.mjs.map +1 -1
  12. package/fesm2022/primitives/event-dispatch.mjs +2 -16
  13. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  14. package/fesm2022/primitives/signals.mjs +5 -3
  15. package/fesm2022/primitives/signals.mjs.map +1 -1
  16. package/fesm2022/resource-CPPwEcg7.mjs +619 -0
  17. package/fesm2022/resource-CPPwEcg7.mjs.map +1 -0
  18. package/fesm2022/root_effect_scheduler-VSXfCzDX.mjs +3847 -0
  19. package/fesm2022/root_effect_scheduler-VSXfCzDX.mjs.map +1 -0
  20. package/fesm2022/rxjs-interop.mjs +16 -9
  21. package/fesm2022/rxjs-interop.mjs.map +1 -1
  22. package/fesm2022/{untracked-DkcXpNb_.mjs → signal-B6pMq7KS.mjs} +16 -114
  23. package/fesm2022/signal-B6pMq7KS.mjs.map +1 -0
  24. package/fesm2022/testing.mjs +265 -201
  25. package/fesm2022/testing.mjs.map +1 -1
  26. package/fesm2022/untracked-Bz5WMeU1.mjs +117 -0
  27. package/fesm2022/untracked-Bz5WMeU1.mjs.map +1 -0
  28. package/fesm2022/weak_ref-BaIq-pgY.mjs +12 -0
  29. package/fesm2022/weak_ref-BaIq-pgY.mjs.map +1 -0
  30. package/{weak_ref.d-BZ7gyRag.d.ts → graph.d-BcIOep_B.d.ts} +3 -24
  31. package/index.d.ts +2624 -10909
  32. package/ng_i18n_closure_mode.d-C9d2CaSt.d.ts +832 -0
  33. package/package.json +3 -3
  34. package/primitives/di/index.d.ts +3 -2
  35. package/primitives/event-dispatch/index.d.ts +3 -3
  36. package/primitives/signals/index.d.ts +8 -4
  37. package/rxjs-interop/index.d.ts +10 -7
  38. package/schematics/bundles/{apply_import_manager-CeNv8GIG.js → apply_import_manager-DnMqg1pY.js} +6 -6
  39. package/schematics/bundles/{compiler_host-DwM3ugW3.js → change_tracker-UMPkv-eH.js} +3 -121
  40. package/schematics/bundles/checker-BFBQyesT.js +17719 -0
  41. package/schematics/bundles/cleanup-unused-imports.js +25 -19
  42. package/schematics/bundles/{checker-k591b6WQ.js → compiler-BQ7R7w2v.js} +1325 -18286
  43. package/schematics/bundles/compiler_host-CAfDJO3W.js +129 -0
  44. package/schematics/bundles/control-flow-migration.js +28 -40
  45. package/schematics/bundles/document-core.js +96 -0
  46. package/schematics/bundles/imports-CIX-JgAN.js +1 -1
  47. package/schematics/bundles/{index-B4OAlHh8.js → index-Cv4Q415G.js} +641 -547
  48. package/schematics/bundles/{index-BhELUmYx.js → index-D8tMJPKa.js} +35 -34
  49. package/schematics/bundles/inject-flags.js +14 -13
  50. package/schematics/bundles/inject-migration.js +29 -10
  51. package/schematics/bundles/leading_space-D9nQ8UQC.js +1 -1
  52. package/schematics/bundles/{migrate_ts_type_references-Be0TNYen.js → migrate_ts_type_references-Cq_ZBuT4.js} +21 -20
  53. package/schematics/bundles/ng_decorators-DznZ5jMl.js +1 -1
  54. package/schematics/bundles/nodes-B16H9JUd.js +1 -1
  55. package/schematics/bundles/output-migration.js +88 -25
  56. package/schematics/bundles/{run_in_devkit-CkvEksWP.js → project_paths-ql6qcf_c.js} +254 -243
  57. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.js +1 -1
  58. package/schematics/bundles/property_name-BBwFuqMe.js +1 -1
  59. package/schematics/bundles/route-lazy-loading.js +7 -5
  60. package/schematics/bundles/self-closing-tags-migration.js +25 -19
  61. package/schematics/bundles/signal-input-migration.js +26 -20
  62. package/schematics/bundles/signal-queries-migration.js +51 -33
  63. package/schematics/bundles/signals.js +8 -7
  64. package/schematics/bundles/standalone-migration.js +11 -9
  65. package/schematics/bundles/symbol-VPWguRxr.js +1 -1
  66. package/schematics/bundles/test-bed-get.js +13 -12
  67. package/schematics/collection.json +0 -6
  68. package/schematics/migrations.json +11 -0
  69. package/signal.d-E0e5nW1p.d.ts +31 -0
  70. package/testing/index.d.ts +16 -28
  71. package/weak_ref.d-eGOEP9S1.d.ts +9 -0
  72. package/fesm2022/injector-BlLwZ2sr.mjs +0 -24
  73. package/fesm2022/injector-BlLwZ2sr.mjs.map +0 -1
  74. package/fesm2022/untracked-DkcXpNb_.mjs.map +0 -1
  75. package/navigation_types.d-DgDrF5rp.d.ts +0 -121
  76. package/schematics/ng-generate/control-flow-migration/schema.json +0 -20
@@ -1,14 +1,20 @@
1
1
  /**
2
- * @license Angular v20.0.0-next.4
2
+ * @license Angular v20.0.0-next.6
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import * as i0 from '@angular/core';
8
- import { ɵDeferBlockState as _DeferBlockState, ɵtriggerResourceLoading as _triggerResourceLoading, ɵrenderDeferBlockState as _renderDeferBlockState, ɵCONTAINER_HEADER_OFFSET as _CONTAINER_HEADER_OFFSET, ɵgetDeferBlocks as _getDeferBlocks, InjectionToken, ɵDeferBlockBehavior as _DeferBlockBehavior, inject as inject$1, NgZone, ErrorHandler, Injectable, ɵNoopNgZone as _NoopNgZone, ApplicationRef, ɵPendingTasksInternal as _PendingTasksInternal, ɵZONELESS_ENABLED as _ZONELESS_ENABLED, ɵChangeDetectionScheduler as _ChangeDetectionScheduler, ɵEffectScheduler as _EffectScheduler, getDebugNode, RendererFactory2, ɵstringify as _stringify, Pipe, Directive, Component, NgModule, ɵReflectionCapabilities as _ReflectionCapabilities, ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT as _USE_RUNTIME_DEPS_TRACKER_FOR_JIT, ɵdepsTracker as _depsTracker, ɵgetInjectableDef as _getInjectableDef, resolveForwardRef, ɵisComponentDefPendingResolution as _isComponentDefPendingResolution, ɵgetAsyncClassMetadataFn as _getAsyncClassMetadataFn, ɵresolveComponentResources as _resolveComponentResources, ɵRender3NgModuleRef as _Render3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID as _DEFAULT_LOCALE_ID, ɵsetLocaleId as _setLocaleId, ɵRender3ComponentFactory as _Render3ComponentFactory, ɵNG_COMP_DEF as _NG_COMP_DEF, ɵcompileComponent as _compileComponent, ɵNG_DIR_DEF as _NG_DIR_DEF, ɵcompileDirective as _compileDirective, ɵNG_PIPE_DEF as _NG_PIPE_DEF, ɵcompilePipe as _compilePipe, ɵNG_MOD_DEF as _NG_MOD_DEF, ɵpatchComponentDefWithScope as _patchComponentDefWithScope, ɵNG_INJ_DEF as _NG_INJ_DEF, ɵcompileNgModuleDefs as _compileNgModuleDefs, ɵclearResolutionOfComponentResourcesQueue as _clearResolutionOfComponentResourcesQueue, ɵrestoreComponentResolutionQueue as _restoreComponentResolutionQueue, ɵinternalProvideZoneChangeDetection as _internalProvideZoneChangeDetection, ɵChangeDetectionSchedulerImpl as _ChangeDetectionSchedulerImpl, Compiler, ɵDEFER_BLOCK_CONFIG as _DEFER_BLOCK_CONFIG, ɵINTERNAL_APPLICATION_ERROR_HANDLER as _INTERNAL_APPLICATION_ERROR_HANDLER, COMPILER_OPTIONS, Injector, ɵtransitiveScopesFor as _transitiveScopesFor, ɵgenerateStandaloneInDeclarationsError as _generateStandaloneInDeclarationsError, ɵNgModuleFactory as _NgModuleFactory, ModuleWithComponentFactories, ɵisEnvironmentProviders as _isEnvironmentProviders, ɵsetAllowDuplicateNgModuleIdsForTest as _setAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents as _resetCompiledComponents, ɵsetUnknownElementStrictMode as _setUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode as _setUnknownPropertyStrictMode, ɵgetUnknownElementStrictMode as _getUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode as _getUnknownPropertyStrictMode, runInInjectionContext, EnvironmentInjector, ɵflushModuleScopingQueueAsMuchAsPossible as _flushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
9
- export { ɵDeferBlockBehavior as DeferBlockBehavior, ɵDeferBlockState as DeferBlockState } from '@angular/core';
10
7
  import { Subscription } from 'rxjs';
8
+ import { DeferBlockState, triggerResourceLoading, renderDeferBlockState, getDeferBlocks, DeferBlockBehavior, NgZone, Injectable, NoopNgZone, ApplicationRef, getDebugNode, RendererFactory2, Pipe, Directive, Component, NgModule, ReflectionCapabilities, depsTracker, isComponentDefPendingResolution, getAsyncClassMetadataFn, resolveComponentResources, NgModuleRef, ApplicationInitStatus, LOCALE_ID, DEFAULT_LOCALE_ID, setLocaleId, ComponentFactory, compileComponent, compileDirective, compilePipe, patchComponentDefWithScope, compileNgModuleDefs, clearResolutionOfComponentResourcesQueue, restoreComponentResolutionQueue, internalProvideZoneChangeDetection, ChangeDetectionSchedulerImpl, Compiler, DEFER_BLOCK_CONFIG, COMPILER_OPTIONS, transitiveScopesFor, generateStandaloneInDeclarationsError, NgModuleFactory, ModuleWithComponentFactories, resetCompiledComponents, ɵsetUnknownElementStrictMode as _setUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode as _setUnknownPropertyStrictMode, ɵgetUnknownElementStrictMode as _getUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode as _getUnknownPropertyStrictMode, flushModuleScopingQueueAsMuchAsPossible, setAllowDuplicateNgModuleIdsForTest } from './debug_node-z_3NG8qT.mjs';
9
+ import { CONTAINER_HEADER_OFFSET, InjectionToken, inject as inject$1, EnvironmentInjector, ErrorHandler, PendingTasksInternal, ZONELESS_ENABLED, ChangeDetectionScheduler, EffectScheduler, stringify, getInjectableDef, resolveForwardRef, NG_COMP_DEF, NG_DIR_DEF, NG_PIPE_DEF, NG_INJ_DEF, NG_MOD_DEF, ENVIRONMENT_INITIALIZER, INTERNAL_APPLICATION_ERROR_HANDLER, Injector, isEnvironmentProviders, runInInjectionContext } from './root_effect_scheduler-VSXfCzDX.mjs';
10
+ import * as i0 from '@angular/core';
11
11
  import { ResourceLoader } from '@angular/compiler';
12
+ import './signal-B6pMq7KS.mjs';
13
+ import '@angular/core/primitives/signals';
14
+ import 'rxjs/operators';
15
+ import './attribute-BWp59EjE.mjs';
16
+ import './primitives/di.mjs';
17
+ import '@angular/core/primitives/di';
12
18
 
13
19
  /**
14
20
  * Wraps a test function in an asynchronous test zone. The test will automatically
@@ -68,13 +74,13 @@ class DeferBlockFixture {
68
74
  throw new Error(`Tried to render this defer block in the \`${stateAsString}\` state, ` +
69
75
  `but there was no @${stateAsString.toLowerCase()} block defined in a template.`);
70
76
  }
71
- if (state === _DeferBlockState.Complete) {
72
- await _triggerResourceLoading(this.block.tDetails, this.block.lView, this.block.tNode);
77
+ if (state === DeferBlockState.Complete) {
78
+ await triggerResourceLoading(this.block.tDetails, this.block.lView, this.block.tNode);
73
79
  }
74
80
  // If the `render` method is used explicitly - skip timer-based scheduling for
75
81
  // `@placeholder` and `@loading` blocks and render them immediately.
76
82
  const skipTimerScheduling = true;
77
- _renderDeferBlockState(state, this.block.tNode, this.block.lContainer, skipTimerScheduling);
83
+ renderDeferBlockState(state, this.block.tNode, this.block.lContainer, skipTimerScheduling);
78
84
  this.componentFixture.detectChanges();
79
85
  }
80
86
  /**
@@ -87,9 +93,9 @@ class DeferBlockFixture {
87
93
  // located right after an LContainer header. Get a hold of that view and inspect
88
94
  // it for nested defer blocks.
89
95
  const deferBlockFixtures = [];
90
- if (this.block.lContainer.length >= _CONTAINER_HEADER_OFFSET) {
91
- const lView = this.block.lContainer[_CONTAINER_HEADER_OFFSET];
92
- _getDeferBlocks(lView, deferBlocks);
96
+ if (this.block.lContainer.length >= CONTAINER_HEADER_OFFSET) {
97
+ const lView = this.block.lContainer[CONTAINER_HEADER_OFFSET];
98
+ getDeferBlocks(lView, deferBlocks);
93
99
  for (const block of deferBlocks) {
94
100
  deferBlockFixtures.push(new DeferBlockFixture(block, this.componentFixture));
95
101
  }
@@ -99,13 +105,13 @@ class DeferBlockFixture {
99
105
  }
100
106
  function hasStateTemplate(state, block) {
101
107
  switch (state) {
102
- case _DeferBlockState.Placeholder:
108
+ case DeferBlockState.Placeholder:
103
109
  return block.tDetails.placeholderTmplIndex !== null;
104
- case _DeferBlockState.Loading:
110
+ case DeferBlockState.Loading:
105
111
  return block.tDetails.loadingTmplIndex !== null;
106
- case _DeferBlockState.Error:
112
+ case DeferBlockState.Error:
107
113
  return block.tDetails.errorTmplIndex !== null;
108
- case _DeferBlockState.Complete:
114
+ case DeferBlockState.Complete:
109
115
  return true;
110
116
  default:
111
117
  return false;
@@ -113,11 +119,11 @@ function hasStateTemplate(state, block) {
113
119
  }
114
120
  function getDeferBlockStateNameFromEnum(state) {
115
121
  switch (state) {
116
- case _DeferBlockState.Placeholder:
122
+ case DeferBlockState.Placeholder:
117
123
  return 'Placeholder';
118
- case _DeferBlockState.Loading:
124
+ case DeferBlockState.Loading:
119
125
  return 'Loading';
120
- case _DeferBlockState.Error:
126
+ case DeferBlockState.Error:
121
127
  return 'Error';
122
128
  default:
123
129
  return 'Main';
@@ -131,7 +137,7 @@ const THROW_ON_UNKNOWN_ELEMENTS_DEFAULT = false;
131
137
  /** Whether unknown properties in templates should throw by default. */
132
138
  const THROW_ON_UNKNOWN_PROPERTIES_DEFAULT = false;
133
139
  /** Whether defer blocks should use manual triggering or play through normally. */
134
- const DEFER_BLOCK_DEFAULT_BEHAVIOR = _DeferBlockBehavior.Playthrough;
140
+ const DEFER_BLOCK_DEFAULT_BEHAVIOR = DeferBlockBehavior.Playthrough;
135
141
  /**
136
142
  * An abstract class for inserting the root test component element in a platform independent way.
137
143
  *
@@ -153,11 +159,15 @@ const ComponentFixtureNoNgZone = new InjectionToken('ComponentFixtureNoNgZone');
153
159
  const RETHROW_APPLICATION_ERRORS_DEFAULT = true;
154
160
  class TestBedApplicationErrorHandler {
155
161
  zone = inject$1(NgZone);
156
- userErrorHandler = inject$1(ErrorHandler);
162
+ injector = inject$1(EnvironmentInjector);
163
+ userErrorHandler;
157
164
  whenStableRejectFunctions = new Set();
158
165
  handleError(e) {
159
166
  try {
160
- this.zone.runOutsideAngular(() => this.userErrorHandler.handleError(e));
167
+ this.zone.runOutsideAngular(() => {
168
+ this.userErrorHandler ??= this.injector.get(ErrorHandler);
169
+ this.userErrorHandler.handleError(e);
170
+ });
161
171
  }
162
172
  catch (userError) {
163
173
  e = userError;
@@ -214,7 +224,7 @@ class ComponentFixture {
214
224
  /** @internal */
215
225
  _noZoneOptionIsSet = inject$1(ComponentFixtureNoNgZone, { optional: true });
216
226
  /** @internal */
217
- _ngZone = this._noZoneOptionIsSet ? new _NoopNgZone() : inject$1(NgZone);
227
+ _ngZone = this._noZoneOptionIsSet ? new NoopNgZone() : inject$1(NgZone);
218
228
  // Inject ApplicationRef to ensure NgZone stableness causes after render hooks to run
219
229
  // This will likely happen as a result of fixture.detectChanges because it calls ngZone.run
220
230
  // This is a crazy way of doing things but hey, it's the world we live in.
@@ -224,11 +234,11 @@ class ComponentFixture {
224
234
  /** @internal */
225
235
  _appRef = inject$1(ApplicationRef);
226
236
  _testAppRef = this._appRef;
227
- pendingTasks = inject$1(_PendingTasksInternal);
237
+ pendingTasks = inject$1(PendingTasksInternal);
228
238
  appErrorHandler = inject$1(TestBedApplicationErrorHandler);
229
- zonelessEnabled = inject$1(_ZONELESS_ENABLED);
230
- scheduler = inject$1(_ChangeDetectionScheduler);
231
- rootEffectScheduler = inject$1(_EffectScheduler);
239
+ zonelessEnabled = inject$1(ZONELESS_ENABLED);
240
+ scheduler = inject$1(ChangeDetectionScheduler);
241
+ rootEffectScheduler = inject$1(EffectScheduler);
232
242
  autoDetectDefault = this.zonelessEnabled ? true : false;
233
243
  autoDetect = inject$1(ComponentFixtureAutoDetect, { optional: true }) ?? this.autoDetectDefault;
234
244
  subscriptions = new Subscription();
@@ -340,7 +350,7 @@ class ComponentFixture {
340
350
  * yet.
341
351
  */
342
352
  isStable() {
343
- return !this.pendingTasks.hasPendingTasks.value;
353
+ return !this.pendingTasks.hasPendingTasks;
344
354
  }
345
355
  /**
346
356
  * Get a promise that resolves when the fixture is stable.
@@ -366,7 +376,7 @@ class ComponentFixture {
366
376
  getDeferBlocks() {
367
377
  const deferBlocks = [];
368
378
  const lView = this.componentRef.hostView['_lView'];
369
- _getDeferBlocks(lView, deferBlocks);
379
+ getDeferBlocks(lView, deferBlocks);
370
380
  const deferBlockFixtures = [];
371
381
  for (const block of deferBlocks) {
372
382
  deferBlockFixtures.push(new DeferBlockFixture(block, this));
@@ -579,7 +589,7 @@ class MetadataOverrider {
579
589
  }
580
590
  if (override.set) {
581
591
  if (override.remove || override.add) {
582
- throw new Error(`Cannot set and add/remove ${_stringify(metadataClass)} at the same time!`);
592
+ throw new Error(`Cannot set and add/remove ${stringify(metadataClass)} at the same time!`);
583
593
  }
584
594
  setMetadata(props, override.set);
585
595
  }
@@ -658,7 +668,7 @@ function _propHashKey(propName, propValue, references) {
658
668
  function _serializeReference(ref, references) {
659
669
  let id = references.get(ref);
660
670
  if (!id) {
661
- id = `${_stringify(ref)}${_nextReferenceId++}`;
671
+ id = `${stringify(ref)}${_nextReferenceId++}`;
662
672
  references.set(ref, id);
663
673
  }
664
674
  return id;
@@ -684,7 +694,7 @@ function _valueProps(obj) {
684
694
  return props;
685
695
  }
686
696
 
687
- const reflection = new _ReflectionCapabilities();
697
+ const reflection = new ReflectionCapabilities();
688
698
  /**
689
699
  * Allows to override ivy metadata for tests (via the `TestBed`).
690
700
  */
@@ -771,10 +781,10 @@ function isTestingModuleOverride(value) {
771
781
  }
772
782
  function assertNoStandaloneComponents(types, resolver, location) {
773
783
  types.forEach((type) => {
774
- if (!_getAsyncClassMetadataFn(type)) {
784
+ if (!getAsyncClassMetadataFn(type)) {
775
785
  const component = resolver.resolve(type);
776
786
  if (component && (component.standalone == null || component.standalone)) {
777
- throw new Error(_generateStandaloneInDeclarationsError(type, location));
787
+ throw new Error(generateStandaloneInDeclarationsError(type, location));
778
788
  }
779
789
  }
780
790
  });
@@ -869,8 +879,8 @@ class TestBedCompiler {
869
879
  moduleDef.rethrowApplicationErrors ?? RETHROW_APPLICATION_ERRORS_DEFAULT;
870
880
  }
871
881
  overrideModule(ngModule, override) {
872
- if (_USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
873
- _depsTracker.clearScopeCacheFor(ngModule);
882
+ {
883
+ depsTracker.clearScopeCacheFor(ngModule);
874
884
  }
875
885
  this.overriddenModules.add(ngModule);
876
886
  // Compile the module right away.
@@ -927,7 +937,7 @@ class TestBedCompiler {
927
937
  else {
928
938
  providerDef = { provide: token };
929
939
  }
930
- const injectableDef = typeof token !== 'string' ? _getInjectableDef(token) : null;
940
+ const injectableDef = typeof token !== 'string' ? getInjectableDef(token) : null;
931
941
  const providedIn = injectableDef === null ? null : resolveForwardRef(injectableDef.providedIn);
932
942
  const overridesBucket = providedIn === 'root' ? this.rootProviderOverrides : this.providerOverrides;
933
943
  overridesBucket.push(providerDef);
@@ -944,12 +954,12 @@ class TestBedCompiler {
944
954
  }
945
955
  }
946
956
  overrideTemplateUsingTestingModule(type, template) {
947
- const def = type[_NG_COMP_DEF];
957
+ const def = type[NG_COMP_DEF];
948
958
  const hasStyleUrls = () => {
949
959
  const metadata = this.resolvers.component.resolve(type);
950
960
  return !!metadata.styleUrl || !!metadata.styleUrls?.length;
951
961
  };
952
- const overrideStyleUrls = !!def && !_isComponentDefPendingResolution(type) && hasStyleUrls();
962
+ const overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
953
963
  // In Ivy, compiling a component does not require knowing the module providing the
954
964
  // component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
955
965
  // overrideComponent. Important: overriding template requires full Component re-compilation,
@@ -972,7 +982,7 @@ class TestBedCompiler {
972
982
  return;
973
983
  const promises = [];
974
984
  for (const component of this.componentsWithAsyncMetadata) {
975
- const asyncMetadataFn = _getAsyncClassMetadataFn(component);
985
+ const asyncMetadataFn = getAsyncClassMetadataFn(component);
976
986
  if (asyncMetadataFn) {
977
987
  promises.push(asyncMetadataFn());
978
988
  }
@@ -1009,7 +1019,7 @@ class TestBedCompiler {
1009
1019
  }
1010
1020
  return Promise.resolve(resourceLoader.get(url));
1011
1021
  };
1012
- await _resolveComponentResources(resolver);
1022
+ await resolveComponentResources(resolver);
1013
1023
  }
1014
1024
  }
1015
1025
  finalize() {
@@ -1026,15 +1036,15 @@ class TestBedCompiler {
1026
1036
  // every component.
1027
1037
  this.componentToModuleScope.clear();
1028
1038
  const parentInjector = this.platform.injector;
1029
- this.testModuleRef = new _Render3NgModuleRef(this.testModuleType, parentInjector, []);
1039
+ this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector, []);
1030
1040
  // ApplicationInitStatus.runInitializers() is marked @internal to core.
1031
1041
  // Cast it to any before accessing it.
1032
1042
  this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
1033
1043
  // Set locale ID after running app initializers, since locale information might be updated while
1034
1044
  // running initializers. This is also consistent with the execution order while bootstrapping an
1035
1045
  // app (see `packages/core/src/application_ref.ts` file).
1036
- const localeId = this.testModuleRef.injector.get(LOCALE_ID, _DEFAULT_LOCALE_ID);
1037
- _setLocaleId(localeId);
1046
+ const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
1047
+ setLocaleId(localeId);
1038
1048
  return this.testModuleRef;
1039
1049
  }
1040
1050
  /**
@@ -1069,7 +1079,7 @@ class TestBedCompiler {
1069
1079
  _getComponentFactories(moduleType) {
1070
1080
  return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce((factories, declaration) => {
1071
1081
  const componentDef = declaration.ɵcmp;
1072
- componentDef && factories.push(new _Render3ComponentFactory(componentDef, this.testModuleRef));
1082
+ componentDef && factories.push(new ComponentFactory(componentDef, this.testModuleRef));
1073
1083
  return factories;
1074
1084
  }, []);
1075
1085
  }
@@ -1077,20 +1087,20 @@ class TestBedCompiler {
1077
1087
  // Compile all queued components, directives, pipes.
1078
1088
  let needsAsyncResources = false;
1079
1089
  this.pendingComponents.forEach((declaration) => {
1080
- if (_getAsyncClassMetadataFn(declaration)) {
1090
+ if (getAsyncClassMetadataFn(declaration)) {
1081
1091
  throw new Error(`Component '${declaration.name}' has unresolved metadata. ` +
1082
1092
  `Please call \`await TestBed.compileComponents()\` before running this test.`);
1083
1093
  }
1084
- needsAsyncResources = needsAsyncResources || _isComponentDefPendingResolution(declaration);
1094
+ needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
1085
1095
  const metadata = this.resolvers.component.resolve(declaration);
1086
1096
  if (metadata === null) {
1087
1097
  throw invalidTypeError(declaration.name, 'Component');
1088
1098
  }
1089
- this.maybeStoreNgDef(_NG_COMP_DEF, declaration);
1090
- if (_USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
1091
- _depsTracker.clearScopeCacheFor(declaration);
1099
+ this.maybeStoreNgDef(NG_COMP_DEF, declaration);
1100
+ {
1101
+ depsTracker.clearScopeCacheFor(declaration);
1092
1102
  }
1093
- _compileComponent(declaration, metadata);
1103
+ compileComponent(declaration, metadata);
1094
1104
  });
1095
1105
  this.pendingComponents.clear();
1096
1106
  this.pendingDirectives.forEach((declaration) => {
@@ -1098,8 +1108,8 @@ class TestBedCompiler {
1098
1108
  if (metadata === null) {
1099
1109
  throw invalidTypeError(declaration.name, 'Directive');
1100
1110
  }
1101
- this.maybeStoreNgDef(_NG_DIR_DEF, declaration);
1102
- _compileDirective(declaration, metadata);
1111
+ this.maybeStoreNgDef(NG_DIR_DEF, declaration);
1112
+ compileDirective(declaration, metadata);
1103
1113
  });
1104
1114
  this.pendingDirectives.clear();
1105
1115
  this.pendingPipes.forEach((declaration) => {
@@ -1107,8 +1117,8 @@ class TestBedCompiler {
1107
1117
  if (metadata === null) {
1108
1118
  throw invalidTypeError(declaration.name, 'Pipe');
1109
1119
  }
1110
- this.maybeStoreNgDef(_NG_PIPE_DEF, declaration);
1111
- _compilePipe(declaration, metadata);
1120
+ this.maybeStoreNgDef(NG_PIPE_DEF, declaration);
1121
+ compilePipe(declaration, metadata);
1112
1122
  });
1113
1123
  this.pendingPipes.clear();
1114
1124
  return needsAsyncResources;
@@ -1118,16 +1128,12 @@ class TestBedCompiler {
1118
1128
  // Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
1119
1129
  // calculated and stored in `transitiveCompileScopes`. If module overrides are present,
1120
1130
  // collect all affected modules and reset scopes to force their re-calculation.
1121
- const testingModuleDef = this.testModuleType[_NG_MOD_DEF];
1131
+ const testingModuleDef = this.testModuleType[NG_MOD_DEF];
1122
1132
  const affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
1123
1133
  if (affectedModules.size > 0) {
1124
1134
  affectedModules.forEach((moduleType) => {
1125
- if (!_USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
1126
- this.storeFieldOfDefOnType(moduleType, _NG_MOD_DEF, 'transitiveCompileScopes');
1127
- moduleType[_NG_MOD_DEF].transitiveCompileScopes = null;
1128
- }
1129
- else {
1130
- _depsTracker.clearScopeCacheFor(moduleType);
1135
+ {
1136
+ depsTracker.clearScopeCacheFor(moduleType);
1131
1137
  }
1132
1138
  });
1133
1139
  }
@@ -1137,16 +1143,16 @@ class TestBedCompiler {
1137
1143
  if (!moduleToScope.has(moduleType)) {
1138
1144
  const isTestingModule = isTestingModuleOverride(moduleType);
1139
1145
  const realType = isTestingModule ? this.testModuleType : moduleType;
1140
- moduleToScope.set(moduleType, _transitiveScopesFor(realType));
1146
+ moduleToScope.set(moduleType, transitiveScopesFor(realType));
1141
1147
  }
1142
1148
  return moduleToScope.get(moduleType);
1143
1149
  };
1144
1150
  this.componentToModuleScope.forEach((moduleType, componentType) => {
1145
1151
  if (moduleType !== null) {
1146
1152
  const moduleScope = getScopeOfModule(moduleType);
1147
- this.storeFieldOfDefOnType(componentType, _NG_COMP_DEF, 'directiveDefs');
1148
- this.storeFieldOfDefOnType(componentType, _NG_COMP_DEF, 'pipeDefs');
1149
- _patchComponentDefWithScope(getComponentDef(componentType), moduleScope);
1153
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'directiveDefs');
1154
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'pipeDefs');
1155
+ patchComponentDefWithScope(getComponentDef(componentType), moduleScope);
1150
1156
  }
1151
1157
  // `tView` that is stored on component def contains information about directives and pipes
1152
1158
  // that are in the scope of this component. Patching component scope will cause `tView` to be
@@ -1155,20 +1161,20 @@ class TestBedCompiler {
1155
1161
  // Resetting `tView` is also needed for cases when we apply provider overrides and those
1156
1162
  // providers are defined on component's level, in which case they may end up included into
1157
1163
  // `tView.blueprint`.
1158
- this.storeFieldOfDefOnType(componentType, _NG_COMP_DEF, 'tView');
1164
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'tView');
1159
1165
  });
1160
1166
  this.componentToModuleScope.clear();
1161
1167
  }
1162
1168
  applyProviderOverrides() {
1163
1169
  const maybeApplyOverrides = (field) => (type) => {
1164
- const resolver = field === _NG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
1170
+ const resolver = field === NG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
1165
1171
  const metadata = resolver.resolve(type);
1166
1172
  if (this.hasProviderOverrides(metadata.providers)) {
1167
1173
  this.patchDefWithProviderOverrides(type, field);
1168
1174
  }
1169
1175
  };
1170
- this.seenComponents.forEach(maybeApplyOverrides(_NG_COMP_DEF));
1171
- this.seenDirectives.forEach(maybeApplyOverrides(_NG_DIR_DEF));
1176
+ this.seenComponents.forEach(maybeApplyOverrides(NG_COMP_DEF));
1177
+ this.seenDirectives.forEach(maybeApplyOverrides(NG_DIR_DEF));
1172
1178
  this.seenComponents.clear();
1173
1179
  this.seenDirectives.clear();
1174
1180
  }
@@ -1191,7 +1197,7 @@ class TestBedCompiler {
1191
1197
  // detailed error messages. The fact that the code relies on this line being
1192
1198
  // present here is suspicious and should be refactored in a way that the line
1193
1199
  // below can be moved (for ex. after an early exit check below).
1194
- const injectorDef = type[_NG_INJ_DEF];
1200
+ const injectorDef = type[NG_INJ_DEF];
1195
1201
  // No provider overrides, exit early.
1196
1202
  if (this.providerOverridesByToken.size === 0)
1197
1203
  return;
@@ -1209,12 +1215,12 @@ class TestBedCompiler {
1209
1215
  ...(this.providerOverridesByModule.get(type) || []),
1210
1216
  ];
1211
1217
  if (this.hasProviderOverrides(providers)) {
1212
- this.maybeStoreNgDef(_NG_INJ_DEF, type);
1213
- this.storeFieldOfDefOnType(type, _NG_INJ_DEF, 'providers');
1218
+ this.maybeStoreNgDef(NG_INJ_DEF, type);
1219
+ this.storeFieldOfDefOnType(type, NG_INJ_DEF, 'providers');
1214
1220
  injectorDef.providers = this.getOverriddenProviders(providers);
1215
1221
  }
1216
1222
  // Apply provider overrides to imported modules recursively
1217
- const moduleDef = type[_NG_MOD_DEF];
1223
+ const moduleDef = type[NG_MOD_DEF];
1218
1224
  const imports = maybeUnwrapFn(moduleDef.imports);
1219
1225
  for (const importedModule of imports) {
1220
1226
  this.applyProviderOverridesInScope(importedModule);
@@ -1234,7 +1240,7 @@ class TestBedCompiler {
1234
1240
  }
1235
1241
  }
1236
1242
  patchComponentsWithExistingStyles() {
1237
- this.existingComponentStyles.forEach((styles, type) => (type[_NG_COMP_DEF].styles = styles));
1243
+ this.existingComponentStyles.forEach((styles, type) => (type[NG_COMP_DEF].styles = styles));
1238
1244
  this.existingComponentStyles.clear();
1239
1245
  }
1240
1246
  queueTypeArray(arr, moduleType) {
@@ -1249,12 +1255,12 @@ class TestBedCompiler {
1249
1255
  }
1250
1256
  recompileNgModule(ngModule, metadata) {
1251
1257
  // Cache the initial ngModuleDef as it will be overwritten.
1252
- this.maybeStoreNgDef(_NG_MOD_DEF, ngModule);
1253
- this.maybeStoreNgDef(_NG_INJ_DEF, ngModule);
1254
- _compileNgModuleDefs(ngModule, metadata);
1258
+ this.maybeStoreNgDef(NG_MOD_DEF, ngModule);
1259
+ this.maybeStoreNgDef(NG_INJ_DEF, ngModule);
1260
+ compileNgModuleDefs(ngModule, metadata);
1255
1261
  }
1256
1262
  maybeRegisterComponentWithAsyncMetadata(type) {
1257
- const asyncMetadataFn = _getAsyncClassMetadataFn(type);
1263
+ const asyncMetadataFn = getAsyncClassMetadataFn(type);
1258
1264
  if (asyncMetadataFn) {
1259
1265
  this.componentsWithAsyncMetadata.add(type);
1260
1266
  }
@@ -1268,7 +1274,7 @@ class TestBedCompiler {
1268
1274
  // Check whether a give Type has respective NG def (ɵcmp) and compile if def is
1269
1275
  // missing. That might happen in case a class without any Angular decorators extends another
1270
1276
  // class where Component/Directive/Pipe decorator is defined.
1271
- if (_isComponentDefPendingResolution(type) || !type.hasOwnProperty(_NG_COMP_DEF)) {
1277
+ if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(NG_COMP_DEF)) {
1272
1278
  this.pendingComponents.add(type);
1273
1279
  }
1274
1280
  this.seenComponents.add(type);
@@ -1295,14 +1301,14 @@ class TestBedCompiler {
1295
1301
  }
1296
1302
  const directive = this.resolvers.directive.resolve(type);
1297
1303
  if (directive) {
1298
- if (!type.hasOwnProperty(_NG_DIR_DEF)) {
1304
+ if (!type.hasOwnProperty(NG_DIR_DEF)) {
1299
1305
  this.pendingDirectives.add(type);
1300
1306
  }
1301
1307
  this.seenDirectives.add(type);
1302
1308
  return;
1303
1309
  }
1304
1310
  const pipe = this.resolvers.pipe.resolve(type);
1305
- if (pipe && !type.hasOwnProperty(_NG_PIPE_DEF)) {
1311
+ if (pipe && !type.hasOwnProperty(NG_PIPE_DEF)) {
1306
1312
  this.pendingPipes.add(type);
1307
1313
  return;
1308
1314
  }
@@ -1390,7 +1396,7 @@ class TestBedCompiler {
1390
1396
  path.forEach((item) => affectedModules.add(item));
1391
1397
  }
1392
1398
  // Examine module imports recursively to look for overridden modules.
1393
- const moduleDef = value[_NG_MOD_DEF];
1399
+ const moduleDef = value[NG_MOD_DEF];
1394
1400
  calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
1395
1401
  }
1396
1402
  }
@@ -1428,7 +1434,7 @@ class TestBedCompiler {
1428
1434
  if (this.originalComponentResolutionQueue === null) {
1429
1435
  this.originalComponentResolutionQueue = new Map();
1430
1436
  }
1431
- _clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
1437
+ clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
1432
1438
  }
1433
1439
  /*
1434
1440
  * Restores component resolution queue to the previously saved state. This operation is performed
@@ -1437,7 +1443,7 @@ class TestBedCompiler {
1437
1443
  */
1438
1444
  restoreComponentResolutionQueue() {
1439
1445
  if (this.originalComponentResolutionQueue !== null) {
1440
- _restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
1446
+ restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
1441
1447
  this.originalComponentResolutionQueue = null;
1442
1448
  }
1443
1449
  }
@@ -1449,8 +1455,8 @@ class TestBedCompiler {
1449
1455
  });
1450
1456
  // Restore initial component/directive/pipe defs
1451
1457
  this.initialNgDefs.forEach((defs, type) => {
1452
- if (_USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
1453
- _depsTracker.clearScopeCacheFor(type);
1458
+ {
1459
+ depsTracker.clearScopeCacheFor(type);
1454
1460
  }
1455
1461
  defs.forEach((descriptor, prop) => {
1456
1462
  if (!descriptor) {
@@ -1471,24 +1477,31 @@ class TestBedCompiler {
1471
1477
  this.scopesWithOverriddenProviders.clear();
1472
1478
  this.restoreComponentResolutionQueue();
1473
1479
  // Restore the locale ID to the default value, this shouldn't be necessary but we never know
1474
- _setLocaleId(_DEFAULT_LOCALE_ID);
1480
+ setLocaleId(DEFAULT_LOCALE_ID);
1475
1481
  }
1476
1482
  compileTestModule() {
1477
1483
  class RootScopeModule {
1478
1484
  }
1479
- _compileNgModuleDefs(RootScopeModule, {
1485
+ compileNgModuleDefs(RootScopeModule, {
1480
1486
  providers: [
1481
1487
  ...this.rootProviderOverrides,
1482
- _internalProvideZoneChangeDetection({}),
1488
+ internalProvideZoneChangeDetection({}),
1483
1489
  TestBedApplicationErrorHandler,
1484
- { provide: _ChangeDetectionScheduler, useExisting: _ChangeDetectionSchedulerImpl },
1490
+ { provide: ChangeDetectionScheduler, useExisting: ChangeDetectionSchedulerImpl },
1491
+ {
1492
+ provide: ENVIRONMENT_INITIALIZER,
1493
+ multi: true,
1494
+ useValue: () => {
1495
+ inject$1(ErrorHandler);
1496
+ },
1497
+ },
1485
1498
  ],
1486
1499
  });
1487
1500
  const providers = [
1488
1501
  { provide: Compiler, useFactory: () => new R3TestCompiler(this) },
1489
- { provide: _DEFER_BLOCK_CONFIG, useValue: { behavior: this.deferBlockBehavior } },
1502
+ { provide: DEFER_BLOCK_CONFIG, useValue: { behavior: this.deferBlockBehavior } },
1490
1503
  {
1491
- provide: _INTERNAL_APPLICATION_ERROR_HANDLER,
1504
+ provide: INTERNAL_APPLICATION_ERROR_HANDLER,
1492
1505
  useFactory: () => {
1493
1506
  if (this.rethrowApplicationTickErrors) {
1494
1507
  const handler = inject$1(TestBedApplicationErrorHandler);
@@ -1507,7 +1520,7 @@ class TestBedCompiler {
1507
1520
  ...this.providerOverrides,
1508
1521
  ];
1509
1522
  const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
1510
- _compileNgModuleDefs(this.testModuleType, {
1523
+ compileNgModuleDefs(this.testModuleType, {
1511
1524
  declarations: this.declarations,
1512
1525
  imports,
1513
1526
  schemas: this.schemas,
@@ -1633,7 +1646,7 @@ function identityFn(value) {
1633
1646
  function flattenProviders(providers, mapFn = identityFn) {
1634
1647
  const out = [];
1635
1648
  for (let provider of providers) {
1636
- if (_isEnvironmentProviders(provider)) {
1649
+ if (isEnvironmentProviders(provider)) {
1637
1650
  provider = provider.ɵproviders;
1638
1651
  }
1639
1652
  if (Array.isArray(provider)) {
@@ -1669,11 +1682,11 @@ class R3TestCompiler {
1669
1682
  }
1670
1683
  compileModuleSync(moduleType) {
1671
1684
  this.testBed._compileNgModuleSync(moduleType);
1672
- return new _NgModuleFactory(moduleType);
1685
+ return new NgModuleFactory(moduleType);
1673
1686
  }
1674
1687
  async compileModuleAsync(moduleType) {
1675
1688
  await this.testBed._compileNgModuleAsync(moduleType);
1676
- return new _NgModuleFactory(moduleType);
1689
+ return new NgModuleFactory(moduleType);
1677
1690
  }
1678
1691
  compileModuleAndAllComponentsSync(moduleType) {
1679
1692
  const ngModuleFactory = this.compileModuleSync(moduleType);
@@ -1839,7 +1852,7 @@ class TestBedImpl {
1839
1852
  /**
1840
1853
  * Runs the given function in the `EnvironmentInjector` context of `TestBed`.
1841
1854
  *
1842
- * @see {@link EnvironmentInjector#runInContext}
1855
+ * @see {@link https://angular.dev/api/core/EnvironmentInjector#runInContext}
1843
1856
  */
1844
1857
  static runInInjectionContext(fn) {
1845
1858
  return TestBedImpl.INSTANCE.runInInjectionContext(fn);
@@ -1901,7 +1914,7 @@ class TestBedImpl {
1901
1914
  // used to track the state of the NgModule registry and reset it correctly. Instead, when we
1902
1915
  // know we're in a testing scenario, we disable the check for duplicate NgModule registration
1903
1916
  // completely.
1904
- _setAllowDuplicateNgModuleIdsForTest(true);
1917
+ setAllowDuplicateNgModuleIdsForTest(true);
1905
1918
  }
1906
1919
  /**
1907
1920
  * Reset the providers for the test injector.
@@ -1914,11 +1927,11 @@ class TestBedImpl {
1914
1927
  this.platform = null;
1915
1928
  this.ngModule = null;
1916
1929
  TestBedImpl._environmentTeardownOptions = undefined;
1917
- _setAllowDuplicateNgModuleIdsForTest(false);
1930
+ setAllowDuplicateNgModuleIdsForTest(false);
1918
1931
  }
1919
1932
  resetTestingModule() {
1920
1933
  this.checkGlobalCompilationFinished();
1921
- _resetCompiledComponents();
1934
+ resetCompiledComponents();
1922
1935
  if (this._compiler !== null) {
1923
1936
  this.compiler.restoreOriginalState();
1924
1937
  }
@@ -2040,15 +2053,15 @@ class TestBedImpl {
2040
2053
  const testComponentRenderer = this.inject(TestComponentRenderer);
2041
2054
  const rootElId = `root${_nextRootElementId++}`;
2042
2055
  testComponentRenderer.insertRootElement(rootElId);
2043
- if (_getAsyncClassMetadataFn(type)) {
2056
+ if (getAsyncClassMetadataFn(type)) {
2044
2057
  throw new Error(`Component '${type.name}' has unresolved metadata. ` +
2045
2058
  `Please call \`await TestBed.compileComponents()\` before running this test.`);
2046
2059
  }
2047
2060
  const componentDef = type.ɵcmp;
2048
2061
  if (!componentDef) {
2049
- throw new Error(`It looks like '${_stringify(type)}' has not been compiled.`);
2062
+ throw new Error(`It looks like '${stringify(type)}' has not been compiled.`);
2050
2063
  }
2051
- const componentFactory = new _Render3ComponentFactory(componentDef);
2064
+ const componentFactory = new ComponentFactory(componentDef);
2052
2065
  const initComponent = () => {
2053
2066
  const componentRef = componentFactory.create(Injector.NULL, [], `#${rootElId}`, this.testModuleRef);
2054
2067
  return this.runInInjectionContext(() => new ComponentFixture(componentRef));
@@ -2101,7 +2114,7 @@ class TestBedImpl {
2101
2114
  // Checking _testNgModuleRef is null should not be necessary, but is left in as an additional
2102
2115
  // guard that compilations queued in tests (after instantiation) are never flushed accidentally.
2103
2116
  if (!this.globalCompilationChecked && this._testModuleRef === null) {
2104
- _flushModuleScopingQueueAsMuchAsPossible();
2117
+ flushModuleScopingQueueAsMuchAsPossible();
2105
2118
  }
2106
2119
  this.globalCompilationChecked = true;
2107
2120
  }
@@ -2189,7 +2202,7 @@ class TestBedImpl {
2189
2202
  * @developerPreview
2190
2203
  */
2191
2204
  flushEffects() {
2192
- this.inject(_EffectScheduler).flush();
2205
+ this.inject(EffectScheduler).flush();
2193
2206
  }
2194
2207
  }
2195
2208
  /**
@@ -2430,7 +2443,7 @@ class FakeNavigation {
2430
2443
  historyState: null,
2431
2444
  });
2432
2445
  const result = new InternalNavigationResult(this);
2433
- this.userAgentNavigate(destination, result, {
2446
+ const intercepted = this.userAgentNavigate(destination, result, {
2434
2447
  navigationType,
2435
2448
  cancelable: true,
2436
2449
  canIntercept: true,
@@ -2439,6 +2452,9 @@ class FakeNavigation {
2439
2452
  hashChange,
2440
2453
  info: options?.info,
2441
2454
  });
2455
+ if (!intercepted) {
2456
+ this.updateNavigationEntriesForSameDocumentNavigation(this.navigateEvent);
2457
+ }
2442
2458
  return {
2443
2459
  committed: result.committed,
2444
2460
  finished: result.finished,
@@ -2462,7 +2478,7 @@ class FakeNavigation {
2462
2478
  historyState: data,
2463
2479
  });
2464
2480
  const result = new InternalNavigationResult(this);
2465
- this.userAgentNavigate(destination, result, {
2481
+ const intercepted = this.userAgentNavigate(destination, result, {
2466
2482
  navigationType,
2467
2483
  cancelable: true,
2468
2484
  canIntercept: true,
@@ -2470,6 +2486,10 @@ class FakeNavigation {
2470
2486
  userInitiated: false,
2471
2487
  hashChange,
2472
2488
  });
2489
+ if (intercepted) {
2490
+ return;
2491
+ }
2492
+ this.updateNavigationEntriesForSameDocumentNavigation(this.navigateEvent);
2473
2493
  }
2474
2494
  /** Equivalent to `navigation.traverseTo()`. */
2475
2495
  traverseTo(key, options) {
@@ -2514,7 +2534,7 @@ class FakeNavigation {
2514
2534
  this.traversalQueue.set(entry.key, result);
2515
2535
  this.runTraversal(() => {
2516
2536
  this.traversalQueue.delete(entry.key);
2517
- const event = this.userAgentNavigate(destination, result, {
2537
+ const intercepted = this.userAgentNavigate(destination, result, {
2518
2538
  navigationType: 'traverse',
2519
2539
  cancelable: true,
2520
2540
  canIntercept: true,
@@ -2523,8 +2543,9 @@ class FakeNavigation {
2523
2543
  hashChange,
2524
2544
  info: options?.info,
2525
2545
  });
2526
- // Note this does not pay attention at all to the commit status of the event (and thus, does not support deferred commit for traversals)
2527
- this.userAgentTraverse(event);
2546
+ if (!intercepted) {
2547
+ this.userAgentTraverse(this.navigateEvent);
2548
+ }
2528
2549
  });
2529
2550
  return {
2530
2551
  committed: result.committed,
@@ -2594,7 +2615,7 @@ class FakeNavigation {
2594
2615
  sameDocument: entry.sameDocument,
2595
2616
  });
2596
2617
  const result = new InternalNavigationResult(this);
2597
- const event = this.userAgentNavigate(destination, result, {
2618
+ const intercepted = this.userAgentNavigate(destination, result, {
2598
2619
  navigationType: 'traverse',
2599
2620
  cancelable: true,
2600
2621
  canIntercept: true,
@@ -2602,8 +2623,9 @@ class FakeNavigation {
2602
2623
  userInitiated: false,
2603
2624
  hashChange,
2604
2625
  });
2605
- // Note this does not pay attention at all to the commit status of the event (and thus, does not support deferred commit for traversals)
2606
- this.userAgentTraverse(event);
2626
+ if (!intercepted) {
2627
+ this.userAgentTraverse(this.navigateEvent);
2628
+ }
2607
2629
  });
2608
2630
  }
2609
2631
  /** Runs a traversal synchronously or asynchronously */
@@ -2647,7 +2669,10 @@ class FakeNavigation {
2647
2669
  isDisposed() {
2648
2670
  return this.disposed;
2649
2671
  }
2650
- /** Implementation for all navigations and traversals. */
2672
+ /**
2673
+ * Implementation for all navigations and traversals.
2674
+ * @returns true if the event was intercepted, otherwise false
2675
+ */
2651
2676
  userAgentNavigate(destination, result, options) {
2652
2677
  // The first navigation should disallow any future calls to set the initial
2653
2678
  // entry.
@@ -2669,35 +2694,11 @@ class FakeNavigation {
2669
2694
  result,
2670
2695
  });
2671
2696
  }
2672
- /**
2673
- * Implementation to commit a navigation.
2674
- * https://whatpr.org/html/10919/nav-history-apis.html#navigateevent-commit
2675
- * @internal
2676
- */
2677
- commitNavigateEvent(navigateEvent) {
2678
- navigateEvent.interceptionState = 'committed';
2679
- const from = this.currentEntry;
2680
- if (!from) {
2681
- throw new Error('cannot commit navigation when current entry is null');
2682
- }
2683
- if (!navigateEvent.sameDocument) {
2684
- const error = new Error('Cannot navigate to a non-same-document URL.');
2685
- navigateEvent.cancel(error);
2686
- throw error;
2687
- }
2688
- // "If navigationType is "push" or "replace", then run the URL and history update steps given document and event's destination's URL, with serialiedData set to event's classic history API state and historyHandling set to navigationType."
2689
- if (navigateEvent.navigationType === 'push' || navigateEvent.navigationType === 'replace') {
2690
- this.urlAndHistoryUpdateSteps(navigateEvent);
2691
- }
2692
- else if (navigateEvent.navigationType === 'reload') {
2693
- this.updateNavigationEntriesForSameDocumentNavigation(navigateEvent);
2694
- }
2695
- else ;
2696
- }
2697
2697
  /**
2698
2698
  * Implementation for a push or replace navigation.
2699
2699
  * https://whatpr.org/html/10919/browsing-the-web.html#url-and-history-update-steps
2700
2700
  * https://whatpr.org/html/10919/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation
2701
+ * @internal
2701
2702
  */
2702
2703
  urlAndHistoryUpdateSteps(navigateEvent) {
2703
2704
  this.updateNavigationEntriesForSameDocumentNavigation(navigateEvent);
@@ -2711,17 +2712,25 @@ class FakeNavigation {
2711
2712
  * > If targetEntry's document is equal to displayedDocument, then perform updateDocument.
2712
2713
  * https://whatpr.org/html/10919/browsing-the-web.html#update-document-for-history-step-application
2713
2714
  * which then goes to https://whatpr.org/html/10919/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation
2715
+ * @internal
2714
2716
  */
2715
2717
  userAgentTraverse(navigateEvent) {
2718
+ const oldUrl = this.currentEntry.url;
2716
2719
  this.updateNavigationEntriesForSameDocumentNavigation(navigateEvent);
2717
2720
  // Happens as part of "updating the document" steps https://whatpr.org/html/10919/browsing-the-web.html#updating-the-document
2718
2721
  const popStateEvent = createPopStateEvent({
2719
2722
  state: navigateEvent.destination.getHistoryState(),
2720
2723
  });
2721
2724
  this.window.dispatchEvent(popStateEvent);
2722
- // TODO(atscott): If oldURL's fragment is not equal to entry's URL's fragment, then queue a global task to fire an event named hashchange
2725
+ if (navigateEvent.hashChange) {
2726
+ const hashchangeEvent = createHashChangeEvent(oldUrl, this.currentEntry.url);
2727
+ this.window.dispatchEvent(hashchangeEvent);
2728
+ }
2723
2729
  }
2724
- /** https://whatpr.org/html/10919/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation */
2730
+ /**
2731
+ * https://whatpr.org/html/10919/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation
2732
+ * @internal
2733
+ */
2725
2734
  updateNavigationEntriesForSameDocumentNavigation({ destination, navigationType, result, }) {
2726
2735
  const oldCurrentNHE = this.currentEntry;
2727
2736
  const disposedNHEs = [];
@@ -2892,24 +2901,35 @@ function dispatchNavigateEvent({ cancelable, canIntercept, userInitiated, hashCh
2892
2901
  event.formData = null;
2893
2902
  event.result = result;
2894
2903
  event.sameDocument = sameDocument;
2895
- event.commitOption = 'immediate';
2896
- let handlersFinished = [Promise.resolve()];
2897
- let dispatchedNavigateEvent = false;
2904
+ let precommitHandlers = [];
2905
+ let handlers = [];
2906
+ // https://whatpr.org/html/10919/nav-history-apis.html#dom-navigateevent-intercept
2898
2907
  event.intercept = function (options) {
2899
2908
  if (!this.canIntercept) {
2900
2909
  throw new DOMException(`Cannot intercept when canIntercept is 'false'`, 'SecurityError');
2901
2910
  }
2902
2911
  this.interceptionState = 'intercepted';
2903
2912
  event.sameDocument = true;
2913
+ const precommitHandler = options?.precommitHandler;
2914
+ if (precommitHandler) {
2915
+ if (!this.cancelable) {
2916
+ throw new DOMException(`Cannot use precommitHandler when cancelable is 'false'`, 'InvalidStateError');
2917
+ }
2918
+ precommitHandlers.push(precommitHandler);
2919
+ }
2920
+ if (event.interceptionState !== 'none' && event.interceptionState !== 'intercepted') {
2921
+ throw new Error('Event interceptionState should be "none" or "intercepted"');
2922
+ }
2923
+ event.interceptionState = 'intercepted';
2904
2924
  const handler = options?.handler;
2905
2925
  if (handler) {
2906
- handlersFinished.push(handler());
2926
+ handlers.push(handler);
2907
2927
  }
2908
2928
  // override old options with new ones. UA _may_ report a console warning if new options differ from previous
2909
- event.commitOption = options?.commit ?? event.commitOption;
2910
- event.scrollBehavior = options?.scroll ?? event.scrollBehavior;
2911
2929
  event.focusResetBehavior = options?.focusReset ?? event.focusResetBehavior;
2930
+ event.scrollBehavior = options?.scroll ?? event.scrollBehavior;
2912
2931
  };
2932
+ // https://whatpr.org/html/10919/nav-history-apis.html#dom-navigateevent-scroll
2913
2933
  event.scroll = function () {
2914
2934
  if (event.interceptionState !== 'committed') {
2915
2935
  throw new DOMException(`Failed to execute 'scroll' on 'NavigateEvent': scroll() must be ` +
@@ -2917,43 +2937,54 @@ function dispatchNavigateEvent({ cancelable, canIntercept, userInitiated, hashCh
2917
2937
  }
2918
2938
  processScrollBehavior(event);
2919
2939
  };
2920
- event.commit = function (internal = false) {
2921
- if (!internal && this.interceptionState !== 'intercepted') {
2922
- throw new DOMException(`Failed to execute 'commit' on 'NavigateEvent': intercept() must be ` +
2923
- `called before commit() and commit() cannot be already called.`, 'InvalidStateError');
2940
+ // https://whatpr.org/html/10919/nav-history-apis.html#dom-navigationprecommitcontroller-redirect
2941
+ function redirect(url) {
2942
+ if (event.interceptionState === 'none') {
2943
+ throw new Error('cannot redirect when event is not intercepted');
2924
2944
  }
2925
- if (!internal && event.commitOption !== 'after-transition') {
2926
- throw new DOMException(`Failed to execute 'commit' on 'NavigateEvent': commit() may not be ` +
2927
- `called if commit behavior is not "after-transition",.`, 'InvalidStateError');
2945
+ if (event.interceptionState !== 'intercepted') {
2946
+ throw new DOMException(`cannot redirect when event is not in 'intercepted' state`, 'InvalidStateError');
2928
2947
  }
2929
- if (!dispatchedNavigateEvent) {
2930
- throw new DOMException(`Failed to execute 'commit' on 'NavigateEvent': commit() may not be ` +
2931
- `called during event dispatch.`, 'InvalidStateError');
2948
+ if (event.navigationType !== 'push' && event.navigationType !== 'replace') {
2949
+ throw new DOMException(`cannot redirect when navigationType is not 'push' or 'replace`, 'InvalidStateError');
2950
+ }
2951
+ const toUrl = new URL(url, navigation.currentEntry.url);
2952
+ event.destination.url = toUrl.href;
2953
+ }
2954
+ // https://whatpr.org/html/10919/nav-history-apis.html#inner-navigate-event-firing-algorithm
2955
+ // "Let commit be the following steps:"
2956
+ function commit() {
2957
+ if (result.signal.aborted) {
2958
+ return;
2932
2959
  }
2933
- this.interceptionState = 'committed';
2934
- result.navigation.commitNavigateEvent(event);
2935
- };
2936
- // Internal only.
2937
- event.cancel = function (reason) {
2938
- result.committedReject(reason);
2939
- result.finishedReject(reason);
2940
- };
2941
- function dispatch() {
2942
- navigation.navigateEvent = event;
2943
- navigation.eventTarget.dispatchEvent(event);
2944
- dispatchedNavigateEvent = true;
2945
2960
  if (event.interceptionState !== 'none') {
2961
+ event.interceptionState = 'committed';
2962
+ if (!navigation.currentEntry) {
2963
+ throw new Error('from history entry should not be null');
2964
+ }
2946
2965
  navigation.transition = new InternalNavigationTransition(navigation.currentEntry, navigationType);
2947
- if (event.commitOption !== 'after-transition') {
2948
- event.commit(/** internal */ true);
2966
+ switch (event.navigationType) {
2967
+ case 'push':
2968
+ case 'replace': {
2969
+ navigation.urlAndHistoryUpdateSteps(event);
2970
+ break;
2971
+ }
2972
+ case 'reload': {
2973
+ navigation.updateNavigationEntriesForSameDocumentNavigation(event);
2974
+ break;
2975
+ }
2976
+ case 'traverse': {
2977
+ navigation.userAgentTraverse(event);
2978
+ break;
2979
+ }
2949
2980
  }
2950
2981
  }
2951
- else {
2952
- // In the spec, this isn't really part of the navigate API. Instead, the navigate event firing returns "true" to indicate
2953
- // navigation steps should "continue" (https://whatpr.org/html/10919/browsing-the-web.html#beginning-navigation)
2954
- event.commit(/** internal */ true);
2982
+ const promisesList = handlers.map((handler) => handler());
2983
+ if (promisesList.length === 0) {
2984
+ promisesList.push(Promise.resolve());
2955
2985
  }
2956
- Promise.all(handlersFinished).then(() => {
2986
+ Promise.all(promisesList)
2987
+ .then(() => {
2957
2988
  // Follows steps outlined under "Wait for all of promisesList, with the following success steps:"
2958
2989
  // in the spec https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigate-event-firing.
2959
2990
  if (result.signal.aborted) {
@@ -2963,9 +2994,6 @@ function dispatchNavigateEvent({ cancelable, canIntercept, userInitiated, hashCh
2963
2994
  throw new Error("Navigation's ongoing event not equal to resolved event");
2964
2995
  }
2965
2996
  navigation.navigateEvent = null;
2966
- if (event.interceptionState === 'intercepted') {
2967
- navigation.commitNavigateEvent(event);
2968
- }
2969
2997
  finishNavigationEvent(event, true);
2970
2998
  const navigatesuccessEvent = new Event('navigatesuccess', { bubbles: false, cancelable });
2971
2999
  navigation.eventTarget.dispatchEvent(navigatesuccessEvent);
@@ -2974,39 +3002,66 @@ function dispatchNavigateEvent({ cancelable, canIntercept, userInitiated, hashCh
2974
3002
  navigation.transition.finishedResolve();
2975
3003
  }
2976
3004
  navigation.transition = null;
2977
- }, (reason) => {
2978
- if (result.signal.aborted) {
2979
- return;
2980
- }
2981
- if (event !== navigation.navigateEvent) {
2982
- throw new Error("Navigation's ongoing event not equal to resolved event");
2983
- }
2984
- navigation.navigateEvent = null;
2985
- event.interceptionState = 'rejected'; // TODO(atscott): this is not in the spec https://github.com/whatwg/html/issues/11087
3005
+ })
3006
+ .catch((reason) => event.cancel(reason));
3007
+ }
3008
+ // Internal only.
3009
+ // https://whatpr.org/html/10919/nav-history-apis.html#inner-navigate-event-firing-algorithm
3010
+ // "Let cancel be the following steps given reason"
3011
+ event.cancel = function (reason) {
3012
+ if (result.signal.aborted) {
3013
+ return;
3014
+ }
3015
+ if (event !== navigation.navigateEvent) {
3016
+ throw new Error("Navigation's ongoing event not equal to resolved event");
3017
+ }
3018
+ navigation.navigateEvent = null;
3019
+ if (event.interceptionState !== 'intercepted') {
2986
3020
  finishNavigationEvent(event, false);
2987
- const navigateerrorEvent = new Event('navigateerror', { bubbles: false, cancelable });
2988
- navigation.eventTarget.dispatchEvent(navigateerrorEvent);
2989
- result.finishedReject(reason);
2990
- if (navigation.transition !== null) {
2991
- navigation.transition.finishedResolve();
2992
- }
2993
- navigation.transition = null;
2994
- });
3021
+ }
3022
+ const navigateerrorEvent = new Event('navigateerror', { bubbles: false, cancelable });
3023
+ navigation.eventTarget.dispatchEvent(navigateerrorEvent);
3024
+ result.finishedReject(reason);
3025
+ if (navigation.transition !== null) {
3026
+ navigation.transition.finishedReject(reason);
3027
+ }
3028
+ navigation.transition = null;
3029
+ };
3030
+ function dispatch() {
3031
+ navigation.navigateEvent = event;
3032
+ navigation.eventTarget.dispatchEvent(event);
3033
+ if (precommitHandlers.length === 0) {
3034
+ commit();
3035
+ }
3036
+ else {
3037
+ const precommitController = { redirect };
3038
+ const precommitPromisesList = precommitHandlers.map((handler) => handler(precommitController));
3039
+ Promise.all(precommitPromisesList)
3040
+ .then(() => commit())
3041
+ .catch((reason) => event.cancel(reason));
3042
+ }
2995
3043
  }
2996
3044
  dispatch();
2997
- return event;
3045
+ return event.interceptionState !== 'none';
2998
3046
  }
2999
3047
  /** https://whatpr.org/html/10919/nav-history-apis.html#navigateevent-finish */
3000
3048
  function finishNavigationEvent(event, didFulfill) {
3001
- if (event.interceptionState === 'intercepted' || event.interceptionState === 'finished') {
3002
- throw new Error('Attempting to finish navigation event that was incomplete or already finished');
3049
+ if (event.interceptionState === 'finished') {
3050
+ throw new Error('Attempting to finish navigation event that was already finished');
3051
+ }
3052
+ if (event.interceptionState === 'intercepted') {
3053
+ if (didFulfill === true) {
3054
+ throw new Error('didFulfill should be false');
3055
+ }
3056
+ // assert precommit handlers is not empty
3057
+ event.interceptionState = 'finished';
3058
+ return;
3003
3059
  }
3004
3060
  if (event.interceptionState === 'none') {
3005
3061
  return;
3006
3062
  }
3063
+ potentiallyResetFocus(event);
3007
3064
  if (didFulfill) {
3008
- // TODO(atscott): https://github.com/whatwg/html/issues/11087 focus reset is not guarded by didFulfill in the spec
3009
- potentiallyResetFocus(event);
3010
3065
  potentiallyResetScroll(event);
3011
3066
  }
3012
3067
  event.interceptionState = 'finished';
@@ -3060,6 +3115,15 @@ function createPopStateEvent({ state }) {
3060
3115
  event.state = state;
3061
3116
  return event;
3062
3117
  }
3118
+ function createHashChangeEvent(newURL, oldURL) {
3119
+ const event = new Event('hashchange', {
3120
+ bubbles: false,
3121
+ cancelable: false,
3122
+ });
3123
+ event.newURL = newURL;
3124
+ event.oldURL = oldURL;
3125
+ return event;
3126
+ }
3063
3127
  /**
3064
3128
  * Fake equivalent of `NavigationDestination`.
3065
3129
  */
@@ -3153,5 +3217,5 @@ class InternalNavigationResult {
3153
3217
  }
3154
3218
  }
3155
3219
 
3156
- export { ComponentFixture, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, DeferBlockFixture, InjectSetupWrapper, TestBed, TestComponentRenderer, __core_private_testing_placeholder__, discardPeriodicTasks, fakeAsync, flush, flushMicrotasks, getTestBed, inject, resetFakeAsyncZone, tick, waitForAsync, withModule, FakeNavigation as ɵFakeNavigation, MetadataOverrider as ɵMetadataOverrider };
3220
+ export { ComponentFixture, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, DeferBlockBehavior, DeferBlockFixture, DeferBlockState, InjectSetupWrapper, TestBed, TestComponentRenderer, __core_private_testing_placeholder__, discardPeriodicTasks, fakeAsync, flush, flushMicrotasks, getTestBed, inject, resetFakeAsyncZone, tick, waitForAsync, withModule, FakeNavigation as ɵFakeNavigation, MetadataOverrider as ɵMetadataOverrider };
3157
3221
  //# sourceMappingURL=testing.mjs.map