@angular/core 20.3.3 → 20.3.4

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 (58) hide show
  1. package/api.d.d.ts +2 -2
  2. package/chrome_dev_tools_performance.d.d.ts +2 -2
  3. package/discovery.d.d.ts +11 -4
  4. package/effect.d.d.ts +2 -2
  5. package/event_dispatcher.d.d.ts +2 -2
  6. package/fesm2022/attribute.mjs +2 -2
  7. package/fesm2022/core.mjs +2 -2
  8. package/fesm2022/debug_node.mjs +193 -87
  9. package/fesm2022/debug_node.mjs.map +1 -1
  10. package/fesm2022/effect.mjs +2 -2
  11. package/fesm2022/not_found.mjs +2 -2
  12. package/fesm2022/primitives/di.mjs +2 -2
  13. package/fesm2022/primitives/event-dispatch.mjs +2 -2
  14. package/fesm2022/primitives/signals.mjs +2 -2
  15. package/fesm2022/resource.mjs +2 -2
  16. package/fesm2022/root_effect_scheduler.mjs +3 -3
  17. package/fesm2022/root_effect_scheduler.mjs.map +1 -1
  18. package/fesm2022/rxjs-interop.mjs +2 -2
  19. package/fesm2022/signal.mjs +2 -2
  20. package/fesm2022/testing.mjs +2 -2
  21. package/fesm2022/weak_ref.mjs +2 -2
  22. package/formatter.d.d.ts +2 -2
  23. package/index.d.ts +2 -2
  24. package/package.json +2 -2
  25. package/primitives/di/index.d.ts +2 -2
  26. package/primitives/event-dispatch/index.d.ts +2 -2
  27. package/primitives/signals/index.d.ts +2 -2
  28. package/rxjs-interop/index.d.ts +2 -2
  29. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +1 -1
  30. package/schematics/bundles/apply_import_manager-CUBvPp_2.cjs +1 -1
  31. package/schematics/bundles/cleanup-unused-imports.cjs +1 -1
  32. package/schematics/bundles/compiler_host-DJHZ7M9N.cjs +1 -1
  33. package/schematics/bundles/control-flow-migration.cjs +1 -1
  34. package/schematics/bundles/document-core.cjs +1 -1
  35. package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
  36. package/schematics/bundles/index-BZJ8bv9v.cjs +11 -11
  37. package/schematics/bundles/index-DU_evmAi.cjs +1 -1
  38. package/schematics/bundles/inject-flags.cjs +1 -1
  39. package/schematics/bundles/inject-migration.cjs +1 -1
  40. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  41. package/schematics/bundles/migrate_ts_type_references-58gA72Ti.cjs +1 -1
  42. package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
  43. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  44. package/schematics/bundles/output-migration.cjs +1 -1
  45. package/schematics/bundles/project_paths-DcM18127.cjs +1 -1
  46. package/schematics/bundles/project_tsconfig_paths-Dqd0J7st.cjs +2 -2
  47. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  48. package/schematics/bundles/route-lazy-loading.cjs +1 -1
  49. package/schematics/bundles/router-current-navigation.cjs +1 -1
  50. package/schematics/bundles/self-closing-tags-migration.cjs +1 -1
  51. package/schematics/bundles/signal-input-migration.cjs +1 -1
  52. package/schematics/bundles/signal-queries-migration.cjs +1 -1
  53. package/schematics/bundles/signals.cjs +1 -1
  54. package/schematics/bundles/standalone-migration.cjs +47 -7
  55. package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
  56. package/schematics/bundles/test-bed-get.cjs +1 -1
  57. package/testing/index.d.ts +2 -2
  58. package/weak_ref.d.d.ts +2 -2
package/api.d.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
package/discovery.d.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
@@ -67,9 +67,13 @@ declare const MAX_ANIMATION_TIMEOUT: InjectionToken<number>;
67
67
  * @publicApi 20.2
68
68
  */
69
69
  type AnimationFunction = (event: AnimationCallbackEvent) => void;
70
+ interface NodeAnimations {
71
+ animateFns: Function[];
72
+ resolvers?: VoidFunction[];
73
+ }
70
74
  interface AnimationLViewData {
71
- enter?: Function[];
72
- leave?: (() => Promise<void>)[];
75
+ enter?: Map<number, NodeAnimations>;
76
+ leave?: Map<number, NodeAnimations>;
73
77
  running?: Promise<unknown>;
74
78
  skipLeaveAnimations?: boolean;
75
79
  }
@@ -5441,6 +5445,9 @@ interface HostBindingDecorator {
5441
5445
  *
5442
5446
  * @usageNotes
5443
5447
  *
5448
+ * NOTE: **Always** prefer using the `host` property over `@HostBinding`.
5449
+ * This decorator exist exclusively for backwards compatibility.
5450
+ *
5444
5451
  * The following example creates a directive that sets the `valid` and `invalid`
5445
5452
  * class, a style color, and an id on the DOM element that has an `ngModel` directive on it.
5446
5453
  *
package/effect.d.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
package/fesm2022/core.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v20.3.3
3
- * (c) 2010-2025 Google LLC. https://angular.io/
2
+ * @license Angular v20.3.4
3
+ * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, ANIMATIONS, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, isInInjectionContext, DestroyRef, PendingTasksInternal, noop, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, ZONELESS_SCHEDULER_DISABLED, SCHEDULE_IN_ROOT_ZONE, PROVIDED_ZONELESS, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
7
+ import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, assertParentView, CONTAINER_HEADER_OFFSET, ANIMATIONS, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, isInInjectionContext, DestroyRef, PendingTasksInternal, noop, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, ZONELESS_SCHEDULER_DISABLED, SCHEDULE_IN_ROOT_ZONE, PROVIDED_ZONELESS, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
8
8
  import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './signal.mjs';
9
9
  import { Subject, Subscription } from 'rxjs';
10
10
  import { setActiveConsumer as setActiveConsumer$1 } from '@angular/core/primitives/signals';
@@ -7213,6 +7213,8 @@ function ensureIcuContainerVisitorLoaded(loader) {
7213
7213
 
7214
7214
  /** Parses a CSS time value to milliseconds. */
7215
7215
  function parseCssTimeUnitsToMs(value) {
7216
+ if (!value)
7217
+ return 0;
7216
7218
  // Some browsers will return it in seconds, whereas others will return milliseconds.
7217
7219
  const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
7218
7220
  return parseFloat(value) * multiplier;
@@ -7323,11 +7325,54 @@ function determineLongestAnimationFromElementAnimations(el, animationsMap, anima
7323
7325
  }
7324
7326
  const allLeavingAnimations = new Set();
7325
7327
 
7328
+ /**
7329
+ * A [DI token](api/core/InjectionToken) that enables or disables all enter and leave animations.
7330
+ */
7331
+ const ANIMATIONS_DISABLED = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationsDisabled' : '', {
7332
+ providedIn: 'root',
7333
+ factory: () => false,
7334
+ });
7335
+ /**
7336
+ * A [DI token](api/core/InjectionToken) for the queue of all animations.
7337
+ */
7338
+ const ANIMATION_QUEUE = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationQueue' : '', {
7339
+ providedIn: 'root',
7340
+ factory: () => {
7341
+ return {
7342
+ queue: new Set(),
7343
+ isScheduled: false,
7344
+ };
7345
+ },
7346
+ });
7347
+ /**
7348
+ * A [DI token](api/core/InjectionToken) that configures the maximum animation timeout
7349
+ * before element removal. The default value mirrors from Chrome's cross document
7350
+ * navigation view transition timeout. It's intended to prevent people from accidentally
7351
+ * forgetting to call the removal function in their callback. Also serves as a delay
7352
+ * for when stylesheets are pruned.
7353
+ *
7354
+ * @publicApi 20.2
7355
+ */
7356
+ const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'MaxAnimationTimeout' : '', {
7357
+ providedIn: 'root',
7358
+ factory: () => MAX_ANIMATION_TIMEOUT_DEFAULT,
7359
+ });
7360
+ const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
7361
+
7362
+ function maybeQueueEnterAnimation(parentLView, parent, tNode, injector) {
7363
+ const enterAnimations = parentLView?.[ANIMATIONS]?.enter;
7364
+ if (parent !== null && enterAnimations && enterAnimations.has(tNode.index)) {
7365
+ const animationQueue = injector.get(ANIMATION_QUEUE);
7366
+ for (const animateFn of enterAnimations.get(tNode.index).animateFns) {
7367
+ animationQueue.queue.add(animateFn);
7368
+ }
7369
+ }
7370
+ }
7326
7371
  /**
7327
7372
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7328
7373
  * being passed as an argument.
7329
7374
  */
7330
- function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode, parentLView) {
7375
+ function applyToElementOrContainer(action, renderer, injector, parent, lNodeToHandle, tNode, beforeNode, parentLView) {
7331
7376
  // If this slot was allocated for a text node dynamically created by i18n, the text node itself
7332
7377
  // won't be created until i18nApply() in the update block, so this node should be skipped.
7333
7378
  // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
@@ -7348,6 +7393,7 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7348
7393
  }
7349
7394
  const rNode = unwrapRNode(lNodeToHandle);
7350
7395
  if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7396
+ maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7351
7397
  if (beforeNode == null) {
7352
7398
  nativeAppendChild(renderer, parent, rNode);
7353
7399
  }
@@ -7356,10 +7402,11 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7356
7402
  }
7357
7403
  }
7358
7404
  else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
7405
+ maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7359
7406
  nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7360
7407
  }
7361
7408
  else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
7362
- runLeaveAnimationsWithCallback(parentLView, (nodeHasLeaveAnimations) => {
7409
+ runLeaveAnimationsWithCallback(parentLView, tNode, injector, (nodeHasLeaveAnimations) => {
7363
7410
  // the nodeHasLeaveAnimations indicates to the renderer that the element needs to
7364
7411
  // be removed synchronously and sets the requireSynchronousElementRemoval flag in
7365
7412
  // the renderer.
@@ -7367,14 +7414,25 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7367
7414
  });
7368
7415
  }
7369
7416
  else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
7370
- runLeaveAnimationsWithCallback(parentLView, () => {
7417
+ runLeaveAnimationsWithCallback(parentLView, tNode, injector, () => {
7371
7418
  renderer.destroyNode(rNode);
7372
7419
  });
7373
7420
  }
7374
7421
  if (lContainer != null) {
7375
- applyContainer(renderer, action, lContainer, parent, beforeNode);
7422
+ applyContainer(renderer, action, injector, lContainer, tNode, parent, beforeNode);
7423
+ }
7424
+ }
7425
+ }
7426
+ function addToAnimationQueue(injector, animationFns) {
7427
+ const animationQueue = injector.get(ANIMATION_QUEUE);
7428
+ if (Array.isArray(animationFns)) {
7429
+ for (const animateFn of animationFns) {
7430
+ animationQueue.queue.add(animateFn);
7376
7431
  }
7377
7432
  }
7433
+ else {
7434
+ animationQueue.queue.add(animationFns);
7435
+ }
7378
7436
  }
7379
7437
  /**
7380
7438
  * Removes all DOM elements associated with a view.
@@ -7549,30 +7607,46 @@ function cleanUpView(tView, lView) {
7549
7607
  setActiveConsumer(prevConsumer);
7550
7608
  }
7551
7609
  }
7552
- function runLeaveAnimationsWithCallback(lView, callback) {
7553
- if (lView && lView[ANIMATIONS] && lView[ANIMATIONS].leave) {
7554
- if (lView[ANIMATIONS].skipLeaveAnimations) {
7555
- lView[ANIMATIONS].skipLeaveAnimations = false;
7556
- }
7557
- else {
7558
- const leaveAnimations = lView[ANIMATIONS].leave;
7610
+ function runLeaveAnimationsWithCallback(lView, tNode, injector, callback) {
7611
+ const animations = lView?.[ANIMATIONS];
7612
+ if (animations == null || animations.leave == undefined || !animations.leave.has(tNode.index))
7613
+ return callback(false);
7614
+ // this is solely for move operations to prevent leave animations from running
7615
+ // on the moved nodes, which would have deleted the node.
7616
+ if (animations.skipLeaveAnimations) {
7617
+ animations.skipLeaveAnimations = false;
7618
+ return callback(false);
7619
+ }
7620
+ addToAnimationQueue(injector, () => {
7621
+ // it's possible that in the time between when the leave animation was
7622
+ // and the time it was executed, the data structure changed. So we need
7623
+ // to be safe here.
7624
+ if (animations.leave && animations.leave.has(tNode.index)) {
7625
+ const leaveAnimationMap = animations.leave;
7626
+ const leaveAnimations = leaveAnimationMap.get(tNode.index);
7559
7627
  const runningAnimations = [];
7560
- for (let index = 0; index < leaveAnimations.length; index++) {
7561
- const animateFn = leaveAnimations[index];
7562
- runningAnimations.push(animateFn());
7628
+ if (leaveAnimations) {
7629
+ for (let index = 0; index < leaveAnimations.animateFns.length; index++) {
7630
+ const animationFn = leaveAnimations.animateFns[index];
7631
+ const { promise } = animationFn();
7632
+ runningAnimations.push(promise);
7633
+ }
7563
7634
  }
7564
- lView[ANIMATIONS].running = Promise.allSettled(runningAnimations);
7565
- lView[ANIMATIONS].leave = undefined;
7635
+ animations.running = Promise.allSettled(runningAnimations);
7636
+ runAfterLeaveAnimations(lView, callback);
7566
7637
  }
7567
- }
7568
- runAfterLeaveAnimations(lView, callback);
7638
+ else {
7639
+ if (lView)
7640
+ allLeavingAnimations.delete(lView);
7641
+ callback(false);
7642
+ }
7643
+ });
7569
7644
  }
7570
7645
  function runAfterLeaveAnimations(lView, callback) {
7571
- if (lView && lView[ANIMATIONS] && lView[ANIMATIONS].running) {
7572
- lView[ANIMATIONS].running.then(() => {
7573
- if (lView[ANIMATIONS] && lView[ANIMATIONS].running) {
7574
- lView[ANIMATIONS].running = undefined;
7575
- }
7646
+ const runningAnimations = lView[ANIMATIONS]?.running;
7647
+ if (runningAnimations) {
7648
+ runningAnimations.then(() => {
7649
+ lView[ANIMATIONS].running = undefined;
7576
7650
  allLeavingAnimations.delete(lView);
7577
7651
  callback(true);
7578
7652
  });
@@ -7899,6 +7973,7 @@ function getBeforeNodeForView(viewIndexInContainer, lContainer) {
7899
7973
  function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
7900
7974
  while (tNode != null) {
7901
7975
  ngDevMode && assertTNodeForLView(tNode, lView);
7976
+ const injector = lView[INJECTOR];
7902
7977
  // Let declarations don't have corresponding DOM nodes so we skip over them.
7903
7978
  if (tNode.type === 128 /* TNodeType.LetDeclaration */) {
7904
7979
  tNode = tNode.next;
@@ -7917,22 +7992,22 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
7917
7992
  if (!isDetachedByI18n(tNode)) {
7918
7993
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
7919
7994
  applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
7920
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7995
+ applyToElementOrContainer(action, renderer, injector, parentRElement, rawSlotValue, tNode, beforeNode, lView);
7921
7996
  }
7922
7997
  else if (tNodeType & 32 /* TNodeType.Icu */) {
7923
7998
  const nextRNode = icuContainerIterate(tNode, lView);
7924
7999
  let rNode;
7925
8000
  while ((rNode = nextRNode())) {
7926
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
8001
+ applyToElementOrContainer(action, renderer, injector, parentRElement, rNode, tNode, beforeNode, lView);
7927
8002
  }
7928
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
8003
+ applyToElementOrContainer(action, renderer, injector, parentRElement, rawSlotValue, tNode, beforeNode, lView);
7929
8004
  }
7930
8005
  else if (tNodeType & 16 /* TNodeType.Projection */) {
7931
8006
  applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
7932
8007
  }
7933
8008
  else {
7934
8009
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
7935
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
8010
+ applyToElementOrContainer(action, renderer, injector, parentRElement, rawSlotValue, tNode, beforeNode, lView);
7936
8011
  }
7937
8012
  }
7938
8013
  tNode = isProjection ? tNode.projectionNext : tNode.next;
@@ -7986,7 +8061,7 @@ function applyProjectionRecursive(renderer, action, lView, tProjectionNode, pare
7986
8061
  // This should be refactored and cleaned up.
7987
8062
  for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
7988
8063
  const rNode = nodeToProjectOrRNodes[i];
7989
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
8064
+ applyToElementOrContainer(action, renderer, lView[INJECTOR], parentRElement, rNode, tProjectionNode, beforeNode, lView);
7990
8065
  }
7991
8066
  }
7992
8067
  else {
@@ -8013,7 +8088,7 @@ function applyProjectionRecursive(renderer, action, lView, tProjectionNode, pare
8013
8088
  * @param parentRElement parent DOM element for insertion/removal.
8014
8089
  * @param beforeNode Before which node the insertions should happen.
8015
8090
  */
8016
- function applyContainer(renderer, action, lContainer, parentRElement, beforeNode) {
8091
+ function applyContainer(renderer, action, injector, lContainer, tNode, parentRElement, beforeNode) {
8017
8092
  ngDevMode && assertLContainer(lContainer);
8018
8093
  const anchor = lContainer[NATIVE]; // LContainer has its own before node.
8019
8094
  const native = unwrapRNode(lContainer);
@@ -8028,7 +8103,7 @@ function applyContainer(renderer, action, lContainer, parentRElement, beforeNode
8028
8103
  // don't see a reason why they should be different, but they are.
8029
8104
  //
8030
8105
  // If they are we need to process the second anchor as well.
8031
- applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
8106
+ applyToElementOrContainer(action, renderer, injector, parentRElement, anchor, tNode, beforeNode);
8032
8107
  }
8033
8108
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
8034
8109
  const lView = lContainer[i];
@@ -9126,7 +9201,6 @@ function refreshView(tView, lView, templateFn, context) {
9126
9201
  if (templateFn !== null) {
9127
9202
  executeTemplate(tView, lView, templateFn, 2 /* RenderFlags.Update */, context);
9128
9203
  }
9129
- runEnterAnimations(lView);
9130
9204
  const hooksInitPhaseCompleted = (flags & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
9131
9205
  // execute pre-order hooks (OnInit, OnChanges, DoCheck)
9132
9206
  // PERF WARNING: do NOT extract this to a separate function without running benchmarks
@@ -9254,15 +9328,6 @@ function refreshView(tView, lView, templateFn, context) {
9254
9328
  leaveView();
9255
9329
  }
9256
9330
  }
9257
- function runEnterAnimations(lView) {
9258
- const animationData = lView[ANIMATIONS];
9259
- if (animationData?.enter) {
9260
- for (const animateFn of animationData.enter) {
9261
- animateFn();
9262
- }
9263
- animationData.enter = undefined;
9264
- }
9265
- }
9266
9331
  /**
9267
9332
  * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
9268
9333
  * them by executing an associated template function.
@@ -13691,7 +13756,7 @@ class ComponentFactory extends ComponentFactory$1 {
13691
13756
  }
13692
13757
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
13693
13758
  const tAttributes = rootSelectorOrNode
13694
- ? ['ng-version', '20.3.3']
13759
+ ? ['ng-version', '20.3.4']
13695
13760
  : // Extract attributes and classes from the first selector only to match VE behavior.
13696
13761
  extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
13697
13762
  let creationBindings = null;
@@ -21888,28 +21953,6 @@ function ɵɵattribute(name, value, sanitizer, namespace) {
21888
21953
  return ɵɵattribute;
21889
21954
  }
21890
21955
 
21891
- /**
21892
- * A [DI token](api/core/InjectionToken) that enables or disables all enter and leave animations.
21893
- */
21894
- const ANIMATIONS_DISABLED = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationsDisabled' : '', {
21895
- providedIn: 'root',
21896
- factory: () => false,
21897
- });
21898
- /**
21899
- * A [DI token](api/core/InjectionToken) that configures the maximum animation timeout
21900
- * before element removal. The default value mirrors from Chrome's cross document
21901
- * navigation view transition timeout. It's intended to prevent people from accidentally
21902
- * forgetting to call the removal function in their callback. Also serves as a delay
21903
- * for when stylesheets are pruned.
21904
- *
21905
- * @publicApi 20.2
21906
- */
21907
- const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'MaxAnimationTimeout' : '', {
21908
- providedIn: 'root',
21909
- factory: () => MAX_ANIMATION_TIMEOUT_DEFAULT,
21910
- });
21911
- const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
21912
-
21913
21956
  const DEFAULT_ANIMATIONS_DISABLED = false;
21914
21957
  const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21915
21958
  typeof document !== 'undefined' &&
@@ -22039,14 +22082,14 @@ function trackLeavingNodes(tNode, el) {
22039
22082
  */
22040
22083
  function getLViewEnterAnimations(lView) {
22041
22084
  const animationData = (lView[ANIMATIONS] ??= {});
22042
- return (animationData.enter ??= []);
22085
+ return (animationData.enter ??= new Map());
22043
22086
  }
22044
22087
  /**
22045
22088
  * Retrieves the list of specified leave animations from the lView
22046
22089
  */
22047
22090
  function getLViewLeaveAnimations(lView) {
22048
22091
  const animationData = (lView[ANIMATIONS] ??= {});
22049
- return (animationData.leave ??= []);
22092
+ return (animationData.leave ??= new Map());
22050
22093
  }
22051
22094
  /**
22052
22095
  * Gets the list of classes from a passed in value
@@ -22100,13 +22143,43 @@ function elementHasClassList(element, classList) {
22100
22143
  */
22101
22144
  function isLongestAnimation(event, nativeElement) {
22102
22145
  const longestAnimation = longestAnimations.get(nativeElement);
22146
+ // If we don't have any record of a longest animation, then we shouldn't
22147
+ // block the animationend/transitionend event from doing its work.
22148
+ if (longestAnimation === undefined)
22149
+ return true;
22103
22150
  return (nativeElement === event.target &&
22104
- longestAnimation !== undefined &&
22105
22151
  ((longestAnimation.animationName !== undefined &&
22106
22152
  event.animationName === longestAnimation.animationName) ||
22107
22153
  (longestAnimation.propertyName !== undefined &&
22108
22154
  event.propertyName === longestAnimation.propertyName)));
22109
22155
  }
22156
+ /**
22157
+ * Stores a given animation function in the LView's animation map for later execution
22158
+ *
22159
+ * @param animations Either the enter or leave animation map from the LView
22160
+ * @param tNode The TNode the animation is associated with
22161
+ * @param fn The animation function to be called later
22162
+ */
22163
+ function addAnimationToLView(animations, tNode, fn) {
22164
+ const nodeAnimations = animations.get(tNode.index) ?? { animateFns: [] };
22165
+ nodeAnimations.animateFns.push(fn);
22166
+ animations.set(tNode.index, nodeAnimations);
22167
+ }
22168
+ function cleanupAfterLeaveAnimations(resolvers, cleanupFns) {
22169
+ if (resolvers) {
22170
+ for (const fn of resolvers) {
22171
+ fn();
22172
+ }
22173
+ }
22174
+ for (const fn of cleanupFns) {
22175
+ fn();
22176
+ }
22177
+ }
22178
+ function clearLViewNodeAnimationResolvers(lView, tNode) {
22179
+ const nodeAnimations = getLViewLeaveAnimations(lView).get(tNode.index);
22180
+ if (nodeAnimations)
22181
+ nodeAnimations.resolvers = undefined;
22182
+ }
22110
22183
 
22111
22184
  /**
22112
22185
  * Instruction to handle the `animate.enter` behavior for class bindings.
@@ -22128,7 +22201,8 @@ function ɵɵanimateEnter(value) {
22128
22201
  }
22129
22202
  const tNode = getCurrentTNode();
22130
22203
  cancelLeavingNodes(tNode, lView);
22131
- getLViewEnterAnimations(lView).push(() => runEnterAnimation(lView, tNode, value));
22204
+ addAnimationToLView(getLViewEnterAnimations(lView), tNode, () => runEnterAnimation(lView, tNode, value));
22205
+ queueEnterAnimations(lView);
22132
22206
  return ɵɵanimateEnter; // For chaining
22133
22207
  }
22134
22208
  function runEnterAnimation(lView, tNode, value) {
@@ -22150,7 +22224,7 @@ function runEnterAnimation(lView, tNode, value) {
22150
22224
  return;
22151
22225
  const eventName = event instanceof AnimationEvent ? 'animationend' : 'transitionend';
22152
22226
  ngZone.runOutsideAngular(() => {
22153
- cleanupFns.push(renderer.listen(nativeElement, eventName, handleEnterAnimationEnd));
22227
+ renderer.listen(nativeElement, eventName, handleEnterAnimationEnd);
22154
22228
  });
22155
22229
  };
22156
22230
  // When the longest animation ends, we can remove all the classes
@@ -22224,7 +22298,8 @@ function ɵɵanimateEnterListener(value) {
22224
22298
  }
22225
22299
  const tNode = getCurrentTNode();
22226
22300
  cancelLeavingNodes(tNode, lView);
22227
- getLViewEnterAnimations(lView).push(() => runEnterAnimationFunction(lView, tNode, value));
22301
+ addAnimationToLView(getLViewEnterAnimations(lView), tNode, () => runEnterAnimationFunction(lView, tNode, value));
22302
+ queueEnterAnimations(lView);
22228
22303
  return ɵɵanimateEnterListener;
22229
22304
  }
22230
22305
  /**
@@ -22257,36 +22332,35 @@ function ɵɵanimateLeave(value) {
22257
22332
  return ɵɵanimateLeave;
22258
22333
  }
22259
22334
  const tNode = getCurrentTNode();
22260
- getLViewLeaveAnimations(lView).push(() => runLeaveAnimations(lView, tNode, value, animationsDisabled));
22335
+ addAnimationToLView(getLViewLeaveAnimations(lView), tNode, () => runLeaveAnimations(lView, tNode, value));
22336
+ enableAnimationQueueScheduler(lView[INJECTOR]);
22261
22337
  return ɵɵanimateLeave; // For chaining
22262
22338
  }
22263
- function runLeaveAnimations(lView, tNode, value, animationsDisabled) {
22339
+ function runLeaveAnimations(lView, tNode, value) {
22264
22340
  const { promise, resolve } = promiseWithResolvers();
22265
22341
  const nativeElement = getNativeByTNode(tNode, lView);
22266
22342
  ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
22267
22343
  const renderer = lView[RENDERER];
22268
22344
  const ngZone = lView[INJECTOR].get(NgZone);
22269
22345
  allLeavingAnimations.add(lView);
22346
+ (getLViewLeaveAnimations(lView).get(tNode.index).resolvers ??= []).push(resolve);
22270
22347
  const activeClasses = getClassListFromValue(value);
22271
22348
  if (activeClasses && activeClasses.length > 0) {
22272
- animateLeaveClassRunner(nativeElement, tNode, activeClasses, renderer, animationsDisabled, ngZone, resolve);
22349
+ animateLeaveClassRunner(nativeElement, tNode, lView, activeClasses, renderer, ngZone);
22273
22350
  }
22274
22351
  else {
22275
22352
  resolve();
22276
22353
  }
22277
- return promise;
22354
+ return { promise, resolve };
22278
22355
  }
22279
22356
  /**
22280
22357
  * This function actually adds the classes that animate element that's leaving the DOM.
22281
22358
  * Once it finishes, it calls the remove function that was provided by the DOM renderer.
22282
22359
  */
22283
- function animateLeaveClassRunner(el, tNode, classList, renderer, animationsDisabled, ngZone, resolver) {
22284
- if (animationsDisabled) {
22285
- longestAnimations.delete(el);
22286
- resolver();
22287
- return;
22288
- }
22360
+ function animateLeaveClassRunner(el, tNode, lView, classList, renderer, ngZone) {
22289
22361
  cancelAnimationsIfRunning(el, renderer);
22362
+ const cleanupFns = [];
22363
+ const resolvers = getLViewLeaveAnimations(lView).get(tNode.index)?.resolvers;
22290
22364
  const handleOutAnimationEnd = (event) => {
22291
22365
  // this early exit case is to prevent issues with bubbling events that are from child element animations
22292
22366
  if (event.target !== el)
@@ -22307,12 +22381,13 @@ function animateLeaveClassRunner(el, tNode, classList, renderer, animationsDisab
22307
22381
  renderer.removeClass(el, item);
22308
22382
  }
22309
22383
  }
22384
+ cleanupAfterLeaveAnimations(resolvers, cleanupFns);
22385
+ clearLViewNodeAnimationResolvers(lView, tNode);
22310
22386
  }
22311
- resolver();
22312
22387
  };
22313
22388
  ngZone.runOutsideAngular(() => {
22314
- renderer.listen(el, 'animationend', handleOutAnimationEnd);
22315
- renderer.listen(el, 'transitionend', handleOutAnimationEnd);
22389
+ cleanupFns.push(renderer.listen(el, 'animationend', handleOutAnimationEnd));
22390
+ cleanupFns.push(renderer.listen(el, 'transitionend', handleOutAnimationEnd));
22316
22391
  });
22317
22392
  trackLeavingNodes(tNode, el);
22318
22393
  for (const item of classList) {
@@ -22326,7 +22401,8 @@ function animateLeaveClassRunner(el, tNode, classList, renderer, animationsDisab
22326
22401
  determineLongestAnimation(el, longestAnimations, areAnimationSupported);
22327
22402
  if (!longestAnimations.has(el)) {
22328
22403
  clearLeavingNodes(tNode, el);
22329
- resolver();
22404
+ cleanupAfterLeaveAnimations(resolvers, cleanupFns);
22405
+ clearLViewNodeAnimationResolvers(lView, tNode);
22330
22406
  }
22331
22407
  });
22332
22408
  });
@@ -22354,7 +22430,8 @@ function ɵɵanimateLeaveListener(value) {
22354
22430
  const lView = getLView();
22355
22431
  const tNode = getCurrentTNode();
22356
22432
  allLeavingAnimations.add(lView);
22357
- getLViewLeaveAnimations(lView).push(() => runLeaveAnimationFunction(lView, tNode, value));
22433
+ addAnimationToLView(getLViewLeaveAnimations(lView), tNode, () => runLeaveAnimationFunction(lView, tNode, value));
22434
+ enableAnimationQueueScheduler(lView[INJECTOR]);
22358
22435
  return ɵɵanimateLeaveListener; // For chaining
22359
22436
  }
22360
22437
  /**
@@ -22395,6 +22472,35 @@ function runLeaveAnimationFunction(lView, tNode, value) {
22395
22472
  // Ensure cleanup if the LView is destroyed before the animation runs.
22396
22473
  return promise;
22397
22474
  }
22475
+ function queueEnterAnimations(lView) {
22476
+ enableAnimationQueueScheduler(lView[INJECTOR]);
22477
+ const enterAnimations = lView[ANIMATIONS]?.enter;
22478
+ if (enterAnimations) {
22479
+ const animationQueue = lView[INJECTOR].get(ANIMATION_QUEUE);
22480
+ for (const [_, nodeAnimations] of enterAnimations) {
22481
+ for (const animateFn of nodeAnimations.animateFns) {
22482
+ animationQueue.queue.add(animateFn);
22483
+ }
22484
+ }
22485
+ }
22486
+ }
22487
+ function enableAnimationQueueScheduler(injector) {
22488
+ const animationQueue = injector.get(ANIMATION_QUEUE);
22489
+ // We only need to schedule the animation queue runner once per application.
22490
+ if (!animationQueue.isScheduled) {
22491
+ afterEveryRender(() => {
22492
+ runQueuedAnimations(injector);
22493
+ }, { injector });
22494
+ animationQueue.isScheduled = true;
22495
+ }
22496
+ }
22497
+ function runQueuedAnimations(injector) {
22498
+ const animationQueue = injector.get(ANIMATION_QUEUE);
22499
+ for (let animateFn of animationQueue.queue) {
22500
+ animateFn();
22501
+ }
22502
+ animationQueue.queue.clear();
22503
+ }
22398
22504
 
22399
22505
  /*!
22400
22506
  * @license