@angular/core 20.3.0 → 20.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/api.d.d.ts +7 -4
  2. package/chrome_dev_tools_performance.d.d.ts +1 -1
  3. package/discovery.d.d.ts +47 -6
  4. package/effect.d.d.ts +1 -2
  5. package/event_dispatcher.d.d.ts +1 -1
  6. package/fesm2022/attribute.mjs +1 -1
  7. package/fesm2022/attribute.mjs.map +1 -1
  8. package/fesm2022/core.mjs +7 -30
  9. package/fesm2022/core.mjs.map +1 -1
  10. package/fesm2022/debug_node.mjs +514 -493
  11. package/fesm2022/debug_node.mjs.map +1 -1
  12. package/fesm2022/effect.mjs +3 -4
  13. package/fesm2022/effect.mjs.map +1 -1
  14. package/fesm2022/not_found.mjs +1 -1
  15. package/fesm2022/not_found.mjs.map +1 -1
  16. package/fesm2022/primitives/di.mjs +1 -1
  17. package/fesm2022/primitives/di.mjs.map +1 -1
  18. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  19. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  20. package/fesm2022/primitives/signals.mjs +4 -5
  21. package/fesm2022/primitives/signals.mjs.map +1 -1
  22. package/fesm2022/resource.mjs +5 -4
  23. package/fesm2022/resource.mjs.map +1 -1
  24. package/fesm2022/root_effect_scheduler.mjs +47 -27
  25. package/fesm2022/root_effect_scheduler.mjs.map +1 -1
  26. package/fesm2022/rxjs-interop.mjs +3 -1
  27. package/fesm2022/rxjs-interop.mjs.map +1 -1
  28. package/fesm2022/signal.mjs +32 -11
  29. package/fesm2022/signal.mjs.map +1 -1
  30. package/fesm2022/testing.mjs +1 -1
  31. package/fesm2022/testing.mjs.map +1 -1
  32. package/fesm2022/weak_ref.mjs +1 -1
  33. package/fesm2022/weak_ref.mjs.map +1 -1
  34. package/graph.d.d.ts +24 -4
  35. package/index.d.ts +13 -96
  36. package/package.json +2 -2
  37. package/primitives/di/index.d.ts +1 -1
  38. package/primitives/event-dispatch/index.d.ts +1 -1
  39. package/primitives/signals/index.d.ts +2 -3
  40. package/rxjs-interop/index.d.ts +3 -1
  41. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  42. package/schematics/bundles/{apply_import_manager-CeOmw2t5.cjs → apply_import_manager-Ch2ALAC9.cjs} +3 -3
  43. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  44. package/schematics/bundles/{compiler_host-CXabxf2P.cjs → compiler_host-Jw4hNUf8.cjs} +2 -2
  45. package/schematics/bundles/control-flow-migration.cjs +70 -38
  46. package/schematics/bundles/document-core.cjs +5 -5
  47. package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
  48. package/schematics/bundles/{index-CKtFJ_6n.cjs → index-DWTTHy-7.cjs} +4 -4
  49. package/schematics/bundles/{index-CLpTl6rd.cjs → index-Gg0PI_fh.cjs} +124 -38
  50. package/schematics/bundles/inject-flags.cjs +5 -5
  51. package/schematics/bundles/inject-migration.cjs +3 -3
  52. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  53. package/schematics/bundles/{migrate_ts_type_references-CjIN7lkE.cjs → migrate_ts_type_references-D_xIwAQ5.cjs} +5 -5
  54. package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
  55. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  56. package/schematics/bundles/output-migration.cjs +6 -6
  57. package/schematics/bundles/{project_paths-CGqaSutM.cjs → project_paths-CfXVBYVk.cjs} +3 -3
  58. package/schematics/bundles/{project_tsconfig_paths-RAvhwg8f.cjs → project_tsconfig_paths-C11WBTJF.cjs} +184 -200
  59. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  60. package/schematics/bundles/route-lazy-loading.cjs +48 -4
  61. package/schematics/bundles/router-current-navigation.cjs +4 -4
  62. package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
  63. package/schematics/bundles/signal-input-migration.cjs +17 -9
  64. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  65. package/schematics/bundles/signals.cjs +7 -7
  66. package/schematics/bundles/standalone-migration.cjs +14 -7
  67. package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
  68. package/schematics/bundles/test-bed-get.cjs +4 -4
  69. package/testing/index.d.ts +1 -1
  70. package/weak_ref.d.d.ts +1 -1
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v20.3.0
2
+ * @license Angular v20.3.2
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
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, 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, getAnimationElementRemovalRegistry, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, setAnimationElementRemovalRegistry, 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, 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';
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';
@@ -6804,9 +6804,11 @@ function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove)
6804
6804
  * @param renderer A renderer to be used
6805
6805
  * @param rNode The native node that should be removed
6806
6806
  * @param isHostElement A flag indicating if a node to be removed is a host of a component.
6807
+ * @param requireSynchronousElementRemoval A flag indicating if a node requires synchronous
6808
+ * removal from the DOM.
6807
6809
  */
6808
- function nativeRemoveNode(renderer, rNode, isHostElement) {
6809
- renderer.removeChild(null, rNode, isHostElement);
6810
+ function nativeRemoveNode(renderer, rNode, isHostElement, requireSynchronousElementRemoval) {
6811
+ renderer.removeChild(null, rNode, isHostElement, requireSynchronousElementRemoval);
6810
6812
  }
6811
6813
  /**
6812
6814
  * Clears the contents of a given RElement.
@@ -7209,11 +7211,123 @@ function ensureIcuContainerVisitorLoaded(loader) {
7209
7211
  }
7210
7212
  }
7211
7213
 
7214
+ /** Parses a CSS time value to milliseconds. */
7215
+ function parseCssTimeUnitsToMs(value) {
7216
+ // Some browsers will return it in seconds, whereas others will return milliseconds.
7217
+ const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
7218
+ return parseFloat(value) * multiplier;
7219
+ }
7220
+ /** Parses out multiple values from a computed style into an array. */
7221
+ function parseCssPropertyValue(computedStyle, name) {
7222
+ const value = computedStyle.getPropertyValue(name);
7223
+ return value.split(',').map((part) => part.trim());
7224
+ }
7225
+ /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
7226
+ function getLongestComputedTransition(computedStyle) {
7227
+ const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
7228
+ const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
7229
+ const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
7230
+ const longest = { propertyName: '', duration: 0, animationName: undefined };
7231
+ for (let i = 0; i < transitionedProperties.length; i++) {
7232
+ const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
7233
+ if (duration > longest.duration) {
7234
+ longest.propertyName = transitionedProperties[i];
7235
+ longest.duration = duration;
7236
+ }
7237
+ }
7238
+ return longest;
7239
+ }
7240
+ function getLongestComputedAnimation(computedStyle) {
7241
+ const rawNames = parseCssPropertyValue(computedStyle, 'animation-name');
7242
+ const rawDelays = parseCssPropertyValue(computedStyle, 'animation-delay');
7243
+ const rawDurations = parseCssPropertyValue(computedStyle, 'animation-duration');
7244
+ const longest = { animationName: '', propertyName: undefined, duration: 0 };
7245
+ for (let i = 0; i < rawNames.length; i++) {
7246
+ const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
7247
+ if (duration > longest.duration) {
7248
+ longest.animationName = rawNames[i];
7249
+ longest.duration = duration;
7250
+ }
7251
+ }
7252
+ return longest;
7253
+ }
7254
+ function isShorterThanExistingAnimation(existing, longest) {
7255
+ return existing !== undefined && existing.duration > longest.duration;
7256
+ }
7257
+ function longestExists(longest) {
7258
+ return ((longest.animationName != undefined || longest.propertyName != undefined) &&
7259
+ longest.duration > 0);
7260
+ }
7261
+ /**
7262
+ * Determines the longest animation, but with `getComputedStyles` instead of `getAnimations`. This
7263
+ * is ultimately safer than getAnimations because it can be used when recalculations are in
7264
+ * progress. `getAnimations()` will be empty in that case.
7265
+ */
7266
+ function determineLongestAnimationFromComputedStyles(el, animationsMap) {
7267
+ const computedStyle = getComputedStyle(el);
7268
+ const longestAnimation = getLongestComputedAnimation(computedStyle);
7269
+ const longestTransition = getLongestComputedTransition(computedStyle);
7270
+ const longest = longestAnimation.duration > longestTransition.duration ? longestAnimation : longestTransition;
7271
+ if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
7272
+ return;
7273
+ if (longestExists(longest)) {
7274
+ animationsMap.set(el, longest);
7275
+ }
7276
+ }
7277
+ /**
7278
+ * Multiple animations can be set on an element. This grabs an element and
7279
+ * determines which of those will be the longest duration. If we didn't do
7280
+ * this, elements would be removed whenever the first animation completes.
7281
+ * This ensures we get the longest running animation and only remove when
7282
+ * that animation completes.
7283
+ */
7284
+ function determineLongestAnimation(el, animationsMap, areAnimationSupported) {
7285
+ if (!areAnimationSupported)
7286
+ return;
7287
+ const animations = el.getAnimations();
7288
+ return animations.length === 0
7289
+ ? // fallback to computed styles if getAnimations is empty. This would happen if styles are
7290
+ // currently recalculating due to a reflow happening elsewhere.
7291
+ determineLongestAnimationFromComputedStyles(el, animationsMap)
7292
+ : determineLongestAnimationFromElementAnimations(el, animationsMap, animations);
7293
+ }
7294
+ function determineLongestAnimationFromElementAnimations(el, animationsMap, animations) {
7295
+ let longest = {
7296
+ animationName: undefined,
7297
+ propertyName: undefined,
7298
+ duration: 0,
7299
+ };
7300
+ for (const animation of animations) {
7301
+ const timing = animation.effect?.getTiming();
7302
+ // duration can be a string 'auto' or a number.
7303
+ const animDuration = typeof timing?.duration === 'number' ? timing.duration : 0;
7304
+ let duration = (timing?.delay ?? 0) + animDuration;
7305
+ let propertyName;
7306
+ let animationName;
7307
+ if (animation.animationName) {
7308
+ animationName = animation.animationName;
7309
+ }
7310
+ else {
7311
+ // Check for CSSTransition specific property
7312
+ propertyName = animation.transitionProperty;
7313
+ }
7314
+ if (duration >= longest.duration) {
7315
+ longest = { animationName, propertyName, duration };
7316
+ }
7317
+ }
7318
+ if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
7319
+ return;
7320
+ if (longestExists(longest)) {
7321
+ animationsMap.set(el, longest);
7322
+ }
7323
+ }
7324
+ const allLeavingAnimations = new Set();
7325
+
7212
7326
  /**
7213
7327
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7214
7328
  * being passed as an argument.
7215
7329
  */
7216
- function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
7330
+ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode, parentLView) {
7217
7331
  // If this slot was allocated for a text node dynamically created by i18n, the text node itself
7218
7332
  // won't be created until i18nApply() in the update block, so this node should be skipped.
7219
7333
  // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
@@ -7245,10 +7359,17 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7245
7359
  nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7246
7360
  }
7247
7361
  else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
7248
- nativeRemoveNode(renderer, rNode, isComponent);
7362
+ runLeaveAnimationsWithCallback(parentLView, (nodeHasLeaveAnimations) => {
7363
+ // the nodeHasLeaveAnimations indicates to the renderer that the element needs to
7364
+ // be removed synchronously and sets the requireSynchronousElementRemoval flag in
7365
+ // the renderer.
7366
+ nativeRemoveNode(renderer, rNode, isComponent, nodeHasLeaveAnimations);
7367
+ });
7249
7368
  }
7250
7369
  else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
7251
- renderer.destroyNode(rNode);
7370
+ runLeaveAnimationsWithCallback(parentLView, () => {
7371
+ renderer.destroyNode(rNode);
7372
+ });
7252
7373
  }
7253
7374
  if (lContainer != null) {
7254
7375
  applyContainer(renderer, action, lContainer, parent, beforeNode);
@@ -7428,6 +7549,37 @@ function cleanUpView(tView, lView) {
7428
7549
  setActiveConsumer(prevConsumer);
7429
7550
  }
7430
7551
  }
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;
7559
+ const runningAnimations = [];
7560
+ for (let index = 0; index < leaveAnimations.length; index++) {
7561
+ const animateFn = leaveAnimations[index];
7562
+ runningAnimations.push(animateFn());
7563
+ }
7564
+ lView[ANIMATIONS].running = Promise.allSettled(runningAnimations);
7565
+ lView[ANIMATIONS].leave = undefined;
7566
+ }
7567
+ }
7568
+ runAfterLeaveAnimations(lView, callback);
7569
+ }
7570
+ 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
+ }
7576
+ allLeavingAnimations.delete(lView);
7577
+ callback(true);
7578
+ });
7579
+ return;
7580
+ }
7581
+ callback(false);
7582
+ }
7431
7583
  /** Removes listeners and unsubscribes from output subscriptions */
7432
7584
  function processCleanups(tView, lView) {
7433
7585
  ngDevMode && assertNotReactive(processCleanups.name);
@@ -7765,22 +7917,22 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
7765
7917
  if (!isDetachedByI18n(tNode)) {
7766
7918
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
7767
7919
  applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
7768
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7920
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7769
7921
  }
7770
7922
  else if (tNodeType & 32 /* TNodeType.Icu */) {
7771
7923
  const nextRNode = icuContainerIterate(tNode, lView);
7772
7924
  let rNode;
7773
7925
  while ((rNode = nextRNode())) {
7774
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
7926
+ applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
7775
7927
  }
7776
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7928
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7777
7929
  }
7778
7930
  else if (tNodeType & 16 /* TNodeType.Projection */) {
7779
7931
  applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
7780
7932
  }
7781
7933
  else {
7782
7934
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
7783
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7935
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7784
7936
  }
7785
7937
  }
7786
7938
  tNode = isProjection ? tNode.projectionNext : tNode.next;
@@ -7834,7 +7986,7 @@ function applyProjectionRecursive(renderer, action, lView, tProjectionNode, pare
7834
7986
  // This should be refactored and cleaned up.
7835
7987
  for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
7836
7988
  const rNode = nodeToProjectOrRNodes[i];
7837
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
7989
+ applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
7838
7990
  }
7839
7991
  }
7840
7992
  else {
@@ -8974,6 +9126,7 @@ function refreshView(tView, lView, templateFn, context) {
8974
9126
  if (templateFn !== null) {
8975
9127
  executeTemplate(tView, lView, templateFn, 2 /* RenderFlags.Update */, context);
8976
9128
  }
9129
+ runEnterAnimations(lView);
8977
9130
  const hooksInitPhaseCompleted = (flags & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
8978
9131
  // execute pre-order hooks (OnInit, OnChanges, DoCheck)
8979
9132
  // PERF WARNING: do NOT extract this to a separate function without running benchmarks
@@ -9101,6 +9254,15 @@ function refreshView(tView, lView, templateFn, context) {
9101
9254
  leaveView();
9102
9255
  }
9103
9256
  }
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
+ }
9104
9266
  /**
9105
9267
  * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
9106
9268
  * them by executing an associated template function.
@@ -9740,15 +9902,20 @@ class ViewRef {
9740
9902
  * introduce other changes.
9741
9903
  */
9742
9904
  checkNoChanges() {
9743
- if (!ngDevMode)
9744
- return;
9745
- try {
9746
- this.exhaustive ??= this._lView[INJECTOR].get(UseExhaustiveCheckNoChanges, USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT);
9747
- }
9748
- catch {
9749
- this.exhaustive = USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT;
9905
+ // Note: we use `if (ngDevMode) { ... }` instead of an early return.
9906
+ // ESBuild is conservative about removing dead code that follows `return;`
9907
+ // inside a function body, so the block may remain in the bundle.
9908
+ // Using a conditional ensures the dev-only logic is reliably tree-shaken
9909
+ // in production builds.
9910
+ if (ngDevMode) {
9911
+ try {
9912
+ this.exhaustive ??= this._lView[INJECTOR].get(UseExhaustiveCheckNoChanges, USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT);
9913
+ }
9914
+ catch {
9915
+ this.exhaustive = USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT;
9916
+ }
9917
+ checkNoChangesInternal(this._lView, this.exhaustive);
9750
9918
  }
9751
- checkNoChangesInternal(this._lView, this.exhaustive);
9752
9919
  }
9753
9920
  attachToViewContainerRef() {
9754
9921
  if (this._appRef) {
@@ -13053,13 +13220,21 @@ function listenToDomEvent(tNode, tView, lView, eventTargetResolver, renderer, ev
13053
13220
  const target = eventTargetResolver ? eventTargetResolver(native) : native;
13054
13221
  stashEventListenerImpl(lView, target, eventName, wrappedListener);
13055
13222
  const cleanupFn = renderer.listen(target, eventName, wrappedListener);
13056
- const idxOrTargetGetter = eventTargetResolver
13057
- ? (_lView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
13058
- : tNode.index;
13059
- storeListenerCleanup(idxOrTargetGetter, tView, lView, eventName, wrappedListener, cleanupFn, false);
13223
+ // We skip cleaning up animation event types to ensure leaving animation events can be used.
13224
+ // These events should be automatically garbage collected anyway after the element is
13225
+ // removed from the DOM.
13226
+ if (!isAnimationEventType(eventName)) {
13227
+ const idxOrTargetGetter = eventTargetResolver
13228
+ ? (_lView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
13229
+ : tNode.index;
13230
+ storeListenerCleanup(idxOrTargetGetter, tView, lView, eventName, wrappedListener, cleanupFn, false);
13231
+ }
13060
13232
  }
13061
13233
  return hasCoalesced;
13062
13234
  }
13235
+ function isAnimationEventType(eventName) {
13236
+ return eventName.startsWith('animation') || eventName.startsWith('transition');
13237
+ }
13063
13238
  /**
13064
13239
  * A utility function that checks if a given element has already an event handler registered for an
13065
13240
  * event with a specified name. The TView.cleanup data structure is used to find out which events
@@ -13480,13 +13655,8 @@ class ComponentFactory extends ComponentFactory$1 {
13480
13655
  try {
13481
13656
  const hostTNode = directiveHostFirstCreatePass(HEADER_OFFSET, rootLView, 2 /* TNodeType.Element */, '#host', () => rootTView.directiveRegistry, true, 0);
13482
13657
  // ---- element instruction
13483
- // TODO(crisbeto): in practice `hostElement` should always be defined, but there are some
13484
- // tests where the renderer is mocked out and `undefined` is returned. We should update the
13485
- // tests so that this check can be removed.
13486
- if (hostElement) {
13487
- setupStaticAttributes(hostRenderer, hostElement, hostTNode);
13488
- attachPatchData(hostElement, rootLView);
13489
- }
13658
+ setupStaticAttributes(hostRenderer, hostElement, hostTNode);
13659
+ attachPatchData(hostElement, rootLView);
13490
13660
  // TODO(pk): this logic is similar to the instruction code where a node can have directives
13491
13661
  createDirectivesInstances(rootTView, rootLView, hostTNode);
13492
13662
  executeContentQueries(rootTView, hostTNode, rootLView);
@@ -13521,7 +13691,7 @@ class ComponentFactory extends ComponentFactory$1 {
13521
13691
  }
13522
13692
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
13523
13693
  const tAttributes = rootSelectorOrNode
13524
- ? ['ng-version', '20.3.0']
13694
+ ? ['ng-version', '20.3.2']
13525
13695
  : // Extract attributes and classes from the first selector only to match VE behavior.
13526
13696
  extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
13527
13697
  let creationBindings = null;
@@ -20528,6 +20698,22 @@ function remove(list, el) {
20528
20698
  }
20529
20699
  }
20530
20700
 
20701
+ /**
20702
+ * Replace with `Promise.withResolvers()` once it's available.
20703
+ * NET September 2026
20704
+ *
20705
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers.
20706
+ */
20707
+ function promiseWithResolvers() {
20708
+ let resolve;
20709
+ let reject;
20710
+ const promise = new Promise((res, rej) => {
20711
+ resolve = res;
20712
+ reject = rej;
20713
+ });
20714
+ return { promise, resolve, reject };
20715
+ }
20716
+
20531
20717
  /**
20532
20718
  * Schedules triggering of a defer block for `on idle` and `on timer` conditions.
20533
20719
  */
@@ -20897,7 +21083,7 @@ function cleanupRemainingHydrationQueue(hydrationQueue, dehydratedBlockRegistry)
20897
21083
  */
20898
21084
  function populateHydratingStateForQueue(registry, queue) {
20899
21085
  for (let blockId of queue) {
20900
- registry.hydrating.set(blockId, Promise.withResolvers());
21086
+ registry.hydrating.set(blockId, promiseWithResolvers());
20901
21087
  }
20902
21088
  }
20903
21089
  // Waits for the next render cycle to complete
@@ -21219,7 +21405,6 @@ function ɵɵdeferPrefetchWhen(rawValue) {
21219
21405
  try {
21220
21406
  const value = Boolean(rawValue); // handle truthy or falsy values
21221
21407
  const tView = lView[TVIEW];
21222
- const tNode = getSelectedTNode();
21223
21408
  const tDetails = getTDeferBlockDetails(tView, tNode);
21224
21409
  if (value === true && tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
21225
21410
  // If loading has not been started yet, trigger it now.
@@ -21745,278 +21930,88 @@ const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined
21745
21930
  });
21746
21931
  const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
21747
21932
 
21933
+ const DEFAULT_ANIMATIONS_DISABLED = false;
21934
+ const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21935
+ typeof document !== 'undefined' &&
21936
+ // tslint:disable-next-line:no-toplevel-property-access
21937
+ typeof document?.documentElement?.getAnimations === 'function';
21748
21938
  /**
21749
- * Registers elements for delayed removal action for animation in the case
21750
- * that `animate.leave` is used. This stores the target element and any
21751
- * classes, class resolvers, and callback functions that may be needed
21752
- * to apply the removal animation, and then stashes the actual element
21753
- * removal function from the dom renderer to be called after the
21754
- * animation is finished.
21755
- */
21756
- class ElementRegistry {
21757
- outElements = new WeakMap();
21758
- remove(el) {
21759
- this.outElements.delete(el);
21760
- }
21761
- /** Used when animate.leave is only applying classes */
21762
- trackClasses(details, classes) {
21763
- const classList = getClassListFromValue(classes);
21764
- if (!classList)
21765
- return;
21766
- for (let klass of classList) {
21767
- details.classes?.add(klass);
21768
- }
21939
+ * Helper function to check if animations are disabled via injection token
21940
+ */
21941
+ function areAnimationsDisabled(lView) {
21942
+ const injector = lView[INJECTOR];
21943
+ return injector.get(ANIMATIONS_DISABLED, DEFAULT_ANIMATIONS_DISABLED);
21944
+ }
21945
+ /**
21946
+ * Asserts a value passed in is actually an animation type and not something else
21947
+ */
21948
+ function assertAnimationTypes(value, instruction) {
21949
+ if (value == null || (typeof value !== 'string' && typeof value !== 'function')) {
21950
+ throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' value must be a string of CSS classes or an animation function, got ${stringify(value)}`);
21769
21951
  }
21770
- /** Used when animate.leave is applying classes via a bound attribute
21771
- * which requires resolving the binding function at the right time
21772
- * to get the proper class list. There may be multiple resolvers due
21773
- * to composition via host bindings.
21774
- */
21775
- trackResolver(details, resolver) {
21776
- if (!details.classFns) {
21777
- details.classFns = [resolver];
21778
- }
21779
- else {
21780
- details.classFns.push(resolver);
21781
- }
21952
+ }
21953
+ /**
21954
+ * Asserts a given native element is an actual Element node and not something like a comment node.
21955
+ */
21956
+ function assertElementNodes(nativeElement, instruction) {
21957
+ if (nativeElement.nodeType !== Node.ELEMENT_NODE) {
21958
+ throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' can only be used on an element node, got ${stringify(nativeElement.nodeType)}`);
21782
21959
  }
21783
- /** Used when `animate.leave` is using the function signature and will have a
21784
- * callback function, rather than a list of classes.
21785
- */
21786
- addCallback(el, value, animateWrapperFn) {
21787
- const details = this.outElements.get(el) ?? {
21788
- classes: null,
21789
- animateFn: () => { },
21790
- isEventBinding: true,
21791
- };
21792
- details.animateFn = animateWrapperFn(el, value);
21793
- this.outElements.set(el, details);
21794
- }
21795
- /** Used when `animate.leave` is using classes. */
21796
- add(el, value, animateWrapperFn) {
21797
- const details = this.outElements.get(el) ?? {
21798
- classes: new Set(),
21799
- animateFn: () => { },
21800
- isEventBinding: false,
21801
- };
21802
- if (typeof value === 'function') {
21803
- this.trackResolver(details, value);
21960
+ }
21961
+ /**
21962
+ * trackEnterClasses is necessary in the case of composition where animate.enter
21963
+ * is used on the same element in multiple places, like on the element and in a
21964
+ * host binding. When removing classes, we need the entire list of animation classes
21965
+ * added to properly remove them when the longest animation fires.
21966
+ */
21967
+ function trackEnterClasses(el, classList, cleanupFns) {
21968
+ const elementData = enterClassMap.get(el);
21969
+ if (elementData) {
21970
+ for (const klass of classList) {
21971
+ elementData.classList.push(klass);
21804
21972
  }
21805
- else {
21806
- this.trackClasses(details, value);
21973
+ for (const fn of cleanupFns) {
21974
+ elementData.cleanupFns.push(fn);
21807
21975
  }
21808
- details.animateFn = animateWrapperFn(el, details.classes, details.classFns);
21809
- this.outElements.set(el, details);
21810
21976
  }
21811
- has(el) {
21812
- return this.outElements.has(el);
21977
+ else {
21978
+ enterClassMap.set(el, { classList, cleanupFns });
21813
21979
  }
21814
- /** This is called by the dom renderer to actually initiate the animation
21815
- * using the animateFn stored in the registry. The DOM renderer passes in
21816
- * the removal function to be fired off when the animation finishes.
21817
- */
21818
- animate(el, removeFn, maxAnimationTimeout) {
21819
- if (!this.outElements.has(el))
21820
- return removeFn();
21821
- const details = this.outElements.get(el);
21822
- let timeoutId;
21823
- let called = false;
21824
- const remove = () => {
21825
- // This called check is to prevent a rare race condition where the timing of removal
21826
- // might result in the removal function being called twice.
21827
- if (called)
21828
- return;
21829
- called = true;
21830
- clearTimeout(timeoutId);
21831
- this.remove(el);
21832
- removeFn();
21833
- };
21834
- // this timeout is used to ensure elements actually get removed in the case
21835
- // that the user forgot to call the remove callback. The timeout is cleared
21836
- // in the DOM renderer during the remove child process. It only applies
21837
- // to the event binding use case.
21838
- if (details.isEventBinding) {
21839
- timeoutId = setTimeout(remove, maxAnimationTimeout);
21980
+ }
21981
+ /**
21982
+ * Helper function to cleanup enterClassMap data safely
21983
+ */
21984
+ function cleanupEnterClassData(element) {
21985
+ const elementData = enterClassMap.get(element);
21986
+ if (elementData) {
21987
+ for (const fn of elementData.cleanupFns) {
21988
+ fn();
21840
21989
  }
21841
- details.animateFn(remove);
21990
+ enterClassMap.delete(element);
21842
21991
  }
21992
+ longestAnimations.delete(element);
21843
21993
  }
21844
- function getClassListFromValue(value) {
21845
- const classes = typeof value === 'function' ? value() : value;
21846
- let classList = Array.isArray(classes) ? classes : null;
21847
- if (typeof classes === 'string') {
21848
- classList = classes
21849
- .trim()
21850
- .split(/\s+/)
21851
- .filter((k) => k);
21852
- }
21853
- return classList;
21854
- }
21855
-
21856
- /** Parses a CSS time value to milliseconds. */
21857
- function parseCssTimeUnitsToMs(value) {
21858
- // Some browsers will return it in seconds, whereas others will return milliseconds.
21859
- const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
21860
- return parseFloat(value) * multiplier;
21861
- }
21862
- /** Parses out multiple values from a computed style into an array. */
21863
- function parseCssPropertyValue(computedStyle, name) {
21864
- const value = computedStyle.getPropertyValue(name);
21865
- return value.split(',').map((part) => part.trim());
21866
- }
21867
- /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
21868
- function getLongestComputedTransition(computedStyle) {
21869
- const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
21870
- const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
21871
- const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
21872
- const longest = { propertyName: '', duration: 0, animationName: undefined };
21873
- for (let i = 0; i < transitionedProperties.length; i++) {
21874
- const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
21875
- if (duration > longest.duration) {
21876
- longest.propertyName = transitionedProperties[i];
21877
- longest.duration = duration;
21878
- }
21879
- }
21880
- return longest;
21881
- }
21882
- function getLongestComputedAnimation(computedStyle) {
21883
- const rawNames = parseCssPropertyValue(computedStyle, 'animation-name');
21884
- const rawDelays = parseCssPropertyValue(computedStyle, 'animation-delay');
21885
- const rawDurations = parseCssPropertyValue(computedStyle, 'animation-duration');
21886
- const longest = { animationName: '', propertyName: undefined, duration: 0 };
21887
- for (let i = 0; i < rawNames.length; i++) {
21888
- const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
21889
- if (duration > longest.duration) {
21890
- longest.animationName = rawNames[i];
21891
- longest.duration = duration;
21892
- }
21893
- }
21894
- return longest;
21895
- }
21896
- function isShorterThanExistingAnimation(existing, longest) {
21897
- return existing !== undefined && existing.duration > longest.duration;
21898
- }
21899
- function longestExists(longest) {
21900
- return ((longest.animationName != undefined || longest.propertyName != undefined) &&
21901
- longest.duration > 0);
21902
- }
21903
- /**
21904
- * Determines the longest animation, but with `getComputedStyles` instead of `getAnimations`. This
21905
- * is ultimately safer than getAnimations because it can be used when recalculations are in
21906
- * progress. `getAnimations()` will be empty in that case.
21907
- */
21908
- function determineLongestAnimationFromComputedStyles(el, animationsMap) {
21909
- const computedStyle = getComputedStyle(el);
21910
- const longestAnimation = getLongestComputedAnimation(computedStyle);
21911
- const longestTransition = getLongestComputedTransition(computedStyle);
21912
- const longest = longestAnimation.duration > longestTransition.duration ? longestAnimation : longestTransition;
21913
- if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
21914
- return;
21915
- if (longestExists(longest)) {
21916
- animationsMap.set(el, longest);
21917
- }
21918
- }
21919
- /**
21920
- * Multiple animations can be set on an element. This grabs an element and
21921
- * determines which of those will be the longest duration. If we didn't do
21922
- * this, elements would be removed whenever the first animation completes.
21923
- * This ensures we get the longest running animation and only remove when
21924
- * that animation completes.
21925
- */
21926
- function determineLongestAnimation(el, animationsMap, areAnimationSupported) {
21927
- if (!areAnimationSupported)
21928
- return;
21929
- const animations = el.getAnimations();
21930
- return animations.length === 0
21931
- ? // fallback to computed styles if getAnimations is empty. This would happen if styles are
21932
- // currently recalculating due to a reflow happening elsewhere.
21933
- determineLongestAnimationFromComputedStyles(el, animationsMap)
21934
- : determineLongestAnimationFromElementAnimations(el, animationsMap, animations);
21935
- }
21936
- function determineLongestAnimationFromElementAnimations(el, animationsMap, animations) {
21937
- let longest = {
21938
- animationName: undefined,
21939
- propertyName: undefined,
21940
- duration: 0,
21941
- };
21942
- for (const animation of animations) {
21943
- const timing = animation.effect?.getTiming();
21944
- // duration can be a string 'auto' or a number.
21945
- const animDuration = typeof timing?.duration === 'number' ? timing.duration : 0;
21946
- let duration = (timing?.delay ?? 0) + animDuration;
21947
- let propertyName;
21948
- let animationName;
21949
- if (animation.animationName) {
21950
- animationName = animation.animationName;
21951
- }
21952
- else {
21953
- // Check for CSSTransition specific property
21954
- propertyName = animation.transitionProperty;
21955
- }
21956
- if (duration >= longest.duration) {
21957
- longest = { animationName, propertyName, duration };
21958
- }
21959
- }
21960
- if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
21961
- return;
21962
- if (longestExists(longest)) {
21963
- animationsMap.set(el, longest);
21964
- }
21965
- }
21966
-
21967
- const DEFAULT_ANIMATIONS_DISABLED = false;
21968
- const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21969
- typeof document !== 'undefined' &&
21970
- // tslint:disable-next-line:no-toplevel-property-access
21971
- typeof document?.documentElement?.getAnimations === 'function';
21972
- /**
21973
- * Helper function to check if animations are disabled via injection token
21974
- */
21975
- function areAnimationsDisabled(lView) {
21976
- const injector = lView[INJECTOR];
21977
- return injector.get(ANIMATIONS_DISABLED, DEFAULT_ANIMATIONS_DISABLED);
21978
- }
21979
- /**
21980
- * Helper function to setup element registry cleanup when LView is destroyed
21981
- */
21982
- function setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement) {
21983
- if (lView[FLAGS] & 8 /* LViewFlags.FirstLViewPass */) {
21984
- storeCleanupWithContext(tView, lView, nativeElement, (elToClean) => {
21985
- elementRegistry.elements.remove(elToClean);
21986
- });
21987
- }
21988
- }
21989
- /**
21990
- * Helper function to cleanup enterClassMap data safely
21991
- */
21992
- function cleanupEnterClassData(element) {
21993
- const elementData = enterClassMap.get(element);
21994
- if (elementData) {
21995
- for (const fn of elementData.cleanupFns) {
21996
- fn();
21997
- }
21998
- enterClassMap.delete(element);
21999
- }
22000
- longestAnimations.delete(element);
22001
- }
22002
- const noOpAnimationComplete = () => { };
22003
- // Tracks the list of classes added to a DOM node from `animate.enter` calls to ensure
22004
- // we remove all of the classes in the case of animation composition via host bindings.
22005
- const enterClassMap = new WeakMap();
22006
- const longestAnimations = new WeakMap();
22007
- // Tracks nodes that are animating away for the duration of the animation. This is
22008
- // used to prevent duplicate nodes from showing up when nodes have been toggled quickly
22009
- // from an `@if` or `@for`.
22010
- const leavingNodes = new WeakMap();
22011
- function clearLeavingNodes(tNode, el) {
22012
- const nodes = leavingNodes.get(tNode);
22013
- if (nodes && nodes.length > 0) {
22014
- const ix = nodes.findIndex((node) => node === el);
22015
- if (ix > -1)
22016
- nodes.splice(ix, 1);
22017
- }
22018
- if (nodes?.length === 0) {
22019
- leavingNodes.delete(tNode);
21994
+ const noOpAnimationComplete = () => { };
21995
+ // Tracks the list of classes added to a DOM node from `animate.enter` calls to ensure
21996
+ // we remove all of the classes in the case of animation composition via host bindings.
21997
+ const enterClassMap = new WeakMap();
21998
+ const longestAnimations = new WeakMap();
21999
+ // Tracks nodes that are animating away for the duration of the animation. This is
22000
+ // used to prevent duplicate nodes from showing up when nodes have been toggled quickly
22001
+ // from an `@if` or `@for`.
22002
+ const leavingNodes = new WeakMap();
22003
+ /**
22004
+ * This actually removes the leaving HTML Element in the TNode
22005
+ */
22006
+ function clearLeavingNodes(tNode, el) {
22007
+ const nodes = leavingNodes.get(tNode);
22008
+ if (nodes && nodes.length > 0) {
22009
+ const ix = nodes.findIndex((node) => node === el);
22010
+ if (ix > -1)
22011
+ nodes.splice(ix, 1);
22012
+ }
22013
+ if (nodes?.length === 0) {
22014
+ leavingNodes.delete(tNode);
22020
22015
  }
22021
22016
  }
22022
22017
  /**
@@ -22031,7 +22026,9 @@ function cancelLeavingNodes(tNode, lView) {
22031
22026
  // this is the insertion point for the new TNode element.
22032
22027
  // it will be inserted before the declaring containers anchor.
22033
22028
  const beforeNode = getBeforeNodeForView(tNode.index, lContainer);
22034
- // here we need to check the previous sibling of that anchor
22029
+ // here we need to check the previous sibling of that anchor. The first
22030
+ // previousSibling node will be the new element added. The second
22031
+ // previousSibling will be the one that's being removed.
22035
22032
  const previousNode = beforeNode?.previousSibling;
22036
22033
  // We really only want to cancel animations if the leaving node is the
22037
22034
  // same as the node before where the new node will be inserted. This is
@@ -22041,6 +22038,11 @@ function cancelLeavingNodes(tNode, lView) {
22041
22038
  }
22042
22039
  }
22043
22040
  }
22041
+ /**
22042
+ * Tracks the nodes list of nodes that are leaving the DOM so we can cancel any leave animations
22043
+ * and remove the node before adding a new entering instance of the DOM node. This prevents
22044
+ * duplicates from showing up on screen mid-animation.
22045
+ */
22044
22046
  function trackLeavingNodes(tNode, el) {
22045
22047
  // We need to track this tNode's element just to be sure we don't add
22046
22048
  // a new RNode for this TNode while this one is still animating away.
@@ -22052,6 +22054,80 @@ function trackLeavingNodes(tNode, el) {
22052
22054
  leavingNodes.set(tNode, [el]);
22053
22055
  }
22054
22056
  }
22057
+ /**
22058
+ * Retrieves the list of specified enter animations from the lView
22059
+ */
22060
+ function getLViewEnterAnimations(lView) {
22061
+ const animationData = (lView[ANIMATIONS] ??= {});
22062
+ return (animationData.enter ??= []);
22063
+ }
22064
+ /**
22065
+ * Retrieves the list of specified leave animations from the lView
22066
+ */
22067
+ function getLViewLeaveAnimations(lView) {
22068
+ const animationData = (lView[ANIMATIONS] ??= {});
22069
+ return (animationData.leave ??= []);
22070
+ }
22071
+ /**
22072
+ * Gets the list of classes from a passed in value
22073
+ */
22074
+ function getClassListFromValue(value) {
22075
+ const classes = typeof value === 'function' ? value() : value;
22076
+ let classList = Array.isArray(classes) ? classes : null;
22077
+ if (typeof classes === 'string') {
22078
+ classList = classes
22079
+ .trim()
22080
+ .split(/\s+/)
22081
+ .filter((k) => k);
22082
+ }
22083
+ return classList;
22084
+ }
22085
+ /**
22086
+ * Cancels any running enter animations on a given element to prevent them from interfering
22087
+ * with leave animations.
22088
+ */
22089
+ function cancelAnimationsIfRunning(element, renderer) {
22090
+ if (!areAnimationSupported)
22091
+ return;
22092
+ const elementData = enterClassMap.get(element);
22093
+ if (elementData &&
22094
+ elementData.classList.length > 0 &&
22095
+ elementHasClassList(element, elementData.classList)) {
22096
+ for (const klass of elementData.classList) {
22097
+ renderer.removeClass(element, klass);
22098
+ }
22099
+ }
22100
+ // We need to prevent any enter animation listeners from firing if they exist.
22101
+ cleanupEnterClassData(element);
22102
+ }
22103
+ /**
22104
+ * Checks if a given element contains the classes is a provided list
22105
+ */
22106
+ function elementHasClassList(element, classList) {
22107
+ for (const className of classList) {
22108
+ if (element.classList.contains(className))
22109
+ return true;
22110
+ }
22111
+ return false;
22112
+ }
22113
+ /**
22114
+ * Determines if the animation or transition event is currently the expected longest animation
22115
+ * based on earlier determined data in `longestAnimations`
22116
+ *
22117
+ * @param event
22118
+ * @param nativeElement
22119
+ * @returns
22120
+ */
22121
+ function isLongestAnimation(event, nativeElement) {
22122
+ const longestAnimation = longestAnimations.get(nativeElement);
22123
+ return (nativeElement === event.target &&
22124
+ longestAnimation !== undefined &&
22125
+ ((longestAnimation.animationName !== undefined &&
22126
+ event.animationName === longestAnimation.animationName) ||
22127
+ (longestAnimation.propertyName !== undefined &&
22128
+ event.propertyName === longestAnimation.propertyName)));
22129
+ }
22130
+
22055
22131
  /**
22056
22132
  * Instruction to handle the `animate.enter` behavior for class bindings.
22057
22133
  *
@@ -22071,6 +22147,11 @@ function ɵɵanimateEnter(value) {
22071
22147
  return ɵɵanimateEnter;
22072
22148
  }
22073
22149
  const tNode = getCurrentTNode();
22150
+ cancelLeavingNodes(tNode, lView);
22151
+ getLViewEnterAnimations(lView).push(() => runEnterAnimation(lView, tNode, value));
22152
+ return ɵɵanimateEnter; // For chaining
22153
+ }
22154
+ function runEnterAnimation(lView, tNode, value) {
22074
22155
  const nativeElement = getNativeByTNode(tNode, lView);
22075
22156
  ngDevMode && assertElementNodes(nativeElement, 'animate.enter');
22076
22157
  const renderer = lView[RENDERER];
@@ -22083,23 +22164,22 @@ function ɵɵanimateEnter(value) {
22083
22164
  // to get the longest animation to ensure we don't complete animations early.
22084
22165
  // This also allows us to setup cancellation of animations in progress if the
22085
22166
  // gets removed early.
22086
- const handleAnimationStart = (event) => {
22167
+ const handleEnterAnimationStart = (event) => {
22087
22168
  const eventName = event instanceof AnimationEvent ? 'animationend' : 'transitionend';
22088
22169
  ngZone.runOutsideAngular(() => {
22089
- cleanupFns.push(renderer.listen(nativeElement, eventName, handleInAnimationEnd));
22170
+ cleanupFns.push(renderer.listen(nativeElement, eventName, handleEnterAnimationEnd));
22090
22171
  });
22091
22172
  };
22092
22173
  // When the longest animation ends, we can remove all the classes
22093
- const handleInAnimationEnd = (event) => {
22094
- animationEnd(event, nativeElement, renderer);
22174
+ const handleEnterAnimationEnd = (event) => {
22175
+ enterAnimationEnd(event, nativeElement, renderer);
22095
22176
  };
22096
22177
  // We only need to add these event listeners if there are actual classes to apply
22097
22178
  if (activeClasses && activeClasses.length > 0) {
22098
22179
  ngZone.runOutsideAngular(() => {
22099
- cleanupFns.push(renderer.listen(nativeElement, 'animationstart', handleAnimationStart));
22100
- cleanupFns.push(renderer.listen(nativeElement, 'transitionstart', handleAnimationStart));
22180
+ cleanupFns.push(renderer.listen(nativeElement, 'animationstart', handleEnterAnimationStart));
22181
+ cleanupFns.push(renderer.listen(nativeElement, 'transitionstart', handleEnterAnimationStart));
22101
22182
  });
22102
- cancelLeavingNodes(tNode, lView);
22103
22183
  trackEnterClasses(nativeElement, activeClasses, cleanupFns);
22104
22184
  for (const klass of activeClasses) {
22105
22185
  renderer.addClass(nativeElement, klass);
@@ -22119,26 +22199,21 @@ function ɵɵanimateEnter(value) {
22119
22199
  });
22120
22200
  });
22121
22201
  }
22122
- return ɵɵanimateEnter; // For chaining
22123
22202
  }
22124
- /**
22125
- * trackEnterClasses is necessary in the case of composition where animate.enter
22126
- * is used on the same element in multiple places, like on the element and in a
22127
- * host binding. When removing classes, we need the entire list of animation classes
22128
- * added to properly remove them when the longest animation fires.
22129
- */
22130
- function trackEnterClasses(el, classList, cleanupFns) {
22131
- const elementData = enterClassMap.get(el);
22132
- if (elementData) {
22133
- for (const klass of classList) {
22134
- elementData.classList.push(klass);
22135
- }
22136
- for (const fn of cleanupFns) {
22137
- elementData.cleanupFns.push(fn);
22203
+ function enterAnimationEnd(event, nativeElement, renderer) {
22204
+ const elementData = enterClassMap.get(nativeElement);
22205
+ if (!elementData)
22206
+ return;
22207
+ if (isLongestAnimation(event, nativeElement)) {
22208
+ // Now that we've found the longest animation, there's no need
22209
+ // to keep bubbling up this event as it's not going to apply to
22210
+ // other elements further up. We don't want it to inadvertently
22211
+ // affect any other animations on the page.
22212
+ event.stopImmediatePropagation();
22213
+ for (const klass of elementData.classList) {
22214
+ renderer.removeClass(nativeElement, klass);
22138
22215
  }
22139
- }
22140
- else {
22141
- enterClassMap.set(el, { classList, cleanupFns });
22216
+ cleanupEnterClassData(nativeElement);
22142
22217
  }
22143
22218
  }
22144
22219
  /**
@@ -22161,16 +22236,22 @@ function ɵɵanimateEnterListener(value) {
22161
22236
  return ɵɵanimateEnterListener;
22162
22237
  }
22163
22238
  const tNode = getCurrentTNode();
22239
+ cancelLeavingNodes(tNode, lView);
22240
+ getLViewEnterAnimations(lView).push(() => runEnterAnimationFunction(lView, tNode, value));
22241
+ return ɵɵanimateEnterListener;
22242
+ }
22243
+ /**
22244
+ * runs enter animations when a custom function is provided
22245
+ */
22246
+ function runEnterAnimationFunction(lView, tNode, value) {
22164
22247
  const nativeElement = getNativeByTNode(tNode, lView);
22165
22248
  ngDevMode && assertElementNodes(nativeElement, 'animate.enter');
22166
- cancelLeavingNodes(tNode, lView);
22167
22249
  value.call(lView[CONTEXT], { target: nativeElement, animationComplete: noOpAnimationComplete });
22168
- return ɵɵanimateEnterListener;
22169
22250
  }
22170
22251
  /**
22171
22252
  * Instruction to handle the `animate.leave` behavior for class animations.
22172
- * It registers an animation with the ElementRegistry to be run when the element
22173
- * is scheduled for removal from the DOM.
22253
+ * It creates a leave animation function that's tracked in the LView to
22254
+ * be run before DOM node removal and cleanup.
22174
22255
  *
22175
22256
  * @param value The value bound to `animate.leave`, which can be a string or a function.
22176
22257
  * @returns This function returns itself so that it may be chained.
@@ -22188,170 +22269,34 @@ function ɵɵanimateLeave(value) {
22188
22269
  if (animationsDisabled) {
22189
22270
  return ɵɵanimateLeave;
22190
22271
  }
22191
- const tView = getTView();
22192
22272
  const tNode = getCurrentTNode();
22193
- const nativeElement = getNativeByTNode(tNode, lView);
22194
- ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
22195
- // This instruction is called in the update pass.
22196
- const renderer = lView[RENDERER];
22197
- const elementRegistry = getAnimationElementRemovalRegistry();
22198
- ngDevMode &&
22199
- assertDefined(elementRegistry.elements, 'Expected `ElementRegistry` to be present in animations subsystem');
22200
- const ngZone = lView[INJECTOR].get(NgZone);
22201
- // This function gets stashed in the registry to be used once the element removal process
22202
- // begins. We pass in the values and resolvers so as to evaluate the resolved classes
22203
- // at the latest possible time, meaning we evaluate them right before the animation
22204
- // begins.
22205
- const animate = (el, value, resolvers) => {
22206
- return (removalFn) => {
22207
- animateLeaveClassRunner(el, tNode, getClassList(value, resolvers), removalFn, renderer, animationsDisabled, ngZone);
22208
- };
22209
- };
22210
- // Ensure cleanup if the LView is destroyed before the animation runs.
22211
- setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement);
22212
- elementRegistry.elements.add(nativeElement, value, animate);
22273
+ getLViewLeaveAnimations(lView).push(() => runLeaveAnimations(lView, tNode, value, animationsDisabled));
22213
22274
  return ɵɵanimateLeave; // For chaining
22214
22275
  }
22215
- /**
22216
- * Instruction to handle the `(animate.leave)` behavior for event bindings, aka when
22217
- * a user wants to use a custom animation function rather than a class. It registers
22218
- * an animation with the ElementRegistry to be run when the element is scheduled for
22219
- * removal from the DOM.
22220
- *
22221
- * @param value The value bound to `(animate.leave)`, an AnimationFunction.
22222
- * @returns This function returns itself so that it may be chained.
22223
- *
22224
- * @codeGenApi
22225
- */
22226
- function ɵɵanimateLeaveListener(value) {
22227
- performanceMarkFeature('NgAnimateLeave');
22228
- if ((typeof ngServerMode !== 'undefined' && ngServerMode) || !areAnimationSupported) {
22229
- return ɵɵanimateLeaveListener;
22230
- }
22231
- ngDevMode && assertAnimationTypes(value, 'animate.leave');
22232
- // Even when animations are disabled, we still need to register the element for removal
22233
- // to ensure proper cleanup and allow developers to handle element removal in tests
22234
- // So we don't have an early return here.
22235
- const lView = getLView();
22236
- const tNode = getCurrentTNode();
22237
- const tView = getTView();
22276
+ function runLeaveAnimations(lView, tNode, value, animationsDisabled) {
22277
+ const { promise, resolve } = promiseWithResolvers();
22238
22278
  const nativeElement = getNativeByTNode(tNode, lView);
22239
22279
  ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
22240
- const elementRegistry = getAnimationElementRemovalRegistry();
22241
- ngDevMode &&
22242
- assertDefined(elementRegistry.elements, 'Expected `ElementRegistry` to be present in animations subsystem');
22243
22280
  const renderer = lView[RENDERER];
22244
- const animationsDisabled = areAnimationsDisabled(lView);
22245
22281
  const ngZone = lView[INJECTOR].get(NgZone);
22246
- const animate = (_el, value) => {
22247
- return (removeFn) => {
22248
- if (animationsDisabled) {
22249
- removeFn();
22250
- }
22251
- else {
22252
- const event = {
22253
- target: nativeElement,
22254
- animationComplete: () => {
22255
- clearLeavingNodes(tNode, _el);
22256
- removeFn();
22257
- },
22258
- };
22259
- trackLeavingNodes(tNode, _el);
22260
- ngZone.runOutsideAngular(() => {
22261
- renderer.listen(_el, 'animationend', () => removeFn(), { once: true });
22262
- });
22263
- value.call(lView[CONTEXT], event);
22264
- }
22265
- };
22266
- };
22267
- // Ensure cleanup if the LView is destroyed before the animation runs.
22268
- setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement);
22269
- elementRegistry.elements.addCallback(nativeElement, value, animate);
22270
- return ɵɵanimateLeaveListener; // For chaining
22271
- }
22272
- /**
22273
- * Builds the list of classes to apply to an element based on either the passed in list of strings
22274
- * or the set of resolver functions that are coming from bindings. Those resolver functions should
22275
- * resolve into either a string or a string array. There may be multiple to support composition.
22276
- */
22277
- function getClassList(value, resolvers) {
22278
- const classList = new Set(value);
22279
- if (resolvers && resolvers.length) {
22280
- for (const resolverFn of resolvers) {
22281
- const resolvedValue = getClassListFromValue(resolverFn);
22282
- if (resolvedValue) {
22283
- for (const rv of resolvedValue) {
22284
- classList.add(rv);
22285
- }
22286
- }
22287
- }
22288
- }
22289
- return classList;
22290
- }
22291
- function cancelAnimationsIfRunning(element, renderer) {
22292
- if (!areAnimationSupported)
22293
- return;
22294
- const elementData = enterClassMap.get(element);
22295
- if (elementData &&
22296
- elementData.classList.length > 0 &&
22297
- elementHasClassList(element, elementData.classList)) {
22298
- for (const klass of elementData.classList) {
22299
- renderer.removeClass(element, klass);
22300
- }
22301
- }
22302
- // We need to prevent any enter animation listeners from firing if they exist.
22303
- cleanupEnterClassData(element);
22304
- }
22305
- function elementHasClassList(element, classList) {
22306
- for (const className of classList) {
22307
- if (element.classList.contains(className))
22308
- return true;
22309
- }
22310
- return false;
22311
- }
22312
- function isLongestAnimation(event, nativeElement) {
22313
- const longestAnimation = longestAnimations.get(nativeElement);
22314
- return (nativeElement === event.target &&
22315
- longestAnimation !== undefined &&
22316
- ((longestAnimation.animationName !== undefined &&
22317
- event.animationName === longestAnimation.animationName) ||
22318
- (longestAnimation.propertyName !== undefined &&
22319
- event.propertyName === longestAnimation.propertyName)));
22320
- }
22321
- function animationEnd(event, nativeElement, renderer) {
22322
- const elementData = enterClassMap.get(nativeElement);
22323
- if (!elementData)
22324
- return;
22325
- if (isLongestAnimation(event, nativeElement)) {
22326
- // Now that we've found the longest animation, there's no need
22327
- // to keep bubbling up this event as it's not going to apply to
22328
- // other elements further up. We don't want it to inadvertently
22329
- // affect any other animations on the page.
22330
- event.stopImmediatePropagation();
22331
- for (const klass of elementData.classList) {
22332
- renderer.removeClass(nativeElement, klass);
22333
- }
22334
- cleanupEnterClassData(nativeElement);
22335
- }
22336
- }
22337
- function assertAnimationTypes(value, instruction) {
22338
- if (value == null || (typeof value !== 'string' && typeof value !== 'function')) {
22339
- throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' value must be a string of CSS classes or an animation function, got ${stringify(value)}`);
22282
+ allLeavingAnimations.add(lView);
22283
+ const activeClasses = getClassListFromValue(value);
22284
+ if (activeClasses && activeClasses.length > 0) {
22285
+ animateLeaveClassRunner(nativeElement, tNode, activeClasses, renderer, animationsDisabled, ngZone, resolve);
22340
22286
  }
22341
- }
22342
- function assertElementNodes(nativeElement, instruction) {
22343
- if (nativeElement.nodeType !== Node.ELEMENT_NODE) {
22344
- throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' can only be used on an element node, got ${stringify(nativeElement.nodeType)}`);
22287
+ else {
22288
+ resolve();
22345
22289
  }
22290
+ return promise;
22346
22291
  }
22347
22292
  /**
22348
22293
  * This function actually adds the classes that animate element that's leaving the DOM.
22349
22294
  * Once it finishes, it calls the remove function that was provided by the DOM renderer.
22350
22295
  */
22351
- function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer, animationsDisabled, ngZone) {
22296
+ function animateLeaveClassRunner(el, tNode, classList, renderer, animationsDisabled, ngZone, resolver) {
22352
22297
  if (animationsDisabled) {
22353
22298
  longestAnimations.delete(el);
22354
- finalRemoveFn();
22299
+ resolver();
22355
22300
  return;
22356
22301
  }
22357
22302
  cancelAnimationsIfRunning(el, renderer);
@@ -22364,8 +22309,16 @@ function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer,
22364
22309
  event.stopImmediatePropagation();
22365
22310
  longestAnimations.delete(el);
22366
22311
  clearLeavingNodes(tNode, el);
22367
- finalRemoveFn();
22312
+ if (Array.isArray(tNode.projection)) {
22313
+ // in the content projection case, the element is not destroyed.
22314
+ // So we need to remove the class at the end so that it isn't left
22315
+ // behind for whenever the item shows up again.
22316
+ for (const item of classList) {
22317
+ renderer.removeClass(el, item);
22318
+ }
22319
+ }
22368
22320
  }
22321
+ resolver();
22369
22322
  };
22370
22323
  ngZone.runOutsideAngular(() => {
22371
22324
  renderer.listen(el, 'animationend', handleOutAnimationEnd);
@@ -22383,11 +22336,75 @@ function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer,
22383
22336
  determineLongestAnimation(el, longestAnimations, areAnimationSupported);
22384
22337
  if (!longestAnimations.has(el)) {
22385
22338
  clearLeavingNodes(tNode, el);
22386
- finalRemoveFn();
22339
+ resolver();
22387
22340
  }
22388
22341
  });
22389
22342
  });
22390
22343
  }
22344
+ /**
22345
+ * Instruction to handle the `(animate.leave)` behavior for event bindings, aka when
22346
+ * a user wants to use a custom animation function rather than a class. It registers
22347
+ * a leave animation function in the LView to be run at right before removal from the
22348
+ * DOM.
22349
+ *
22350
+ * @param value The value bound to `(animate.leave)`, an AnimationFunction.
22351
+ * @returns This function returns itself so that it may be chained.
22352
+ *
22353
+ * @codeGenApi
22354
+ */
22355
+ function ɵɵanimateLeaveListener(value) {
22356
+ performanceMarkFeature('NgAnimateLeave');
22357
+ if ((typeof ngServerMode !== 'undefined' && ngServerMode) || !areAnimationSupported) {
22358
+ return ɵɵanimateLeaveListener;
22359
+ }
22360
+ ngDevMode && assertAnimationTypes(value, 'animate.leave');
22361
+ // Even when animations are disabled, we still need to register the element for removal
22362
+ // to ensure proper cleanup and allow developers to handle element removal in tests
22363
+ // So we don't have an early return here.
22364
+ const lView = getLView();
22365
+ const tNode = getCurrentTNode();
22366
+ allLeavingAnimations.add(lView);
22367
+ getLViewLeaveAnimations(lView).push(() => runLeaveAnimationFunction(lView, tNode, value));
22368
+ return ɵɵanimateLeaveListener; // For chaining
22369
+ }
22370
+ /**
22371
+ * runs leave animations when a custom function is provided
22372
+ */
22373
+ function runLeaveAnimationFunction(lView, tNode, value) {
22374
+ const { promise, resolve } = promiseWithResolvers();
22375
+ const nativeElement = getNativeByTNode(tNode, lView);
22376
+ ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
22377
+ const renderer = lView[RENDERER];
22378
+ const animationsDisabled = areAnimationsDisabled(lView);
22379
+ const ngZone = lView[INJECTOR].get(NgZone);
22380
+ const maxAnimationTimeout = lView[INJECTOR].get(MAX_ANIMATION_TIMEOUT);
22381
+ if (animationsDisabled) {
22382
+ resolve();
22383
+ }
22384
+ else {
22385
+ const timeoutId = setTimeout(() => {
22386
+ clearLeavingNodes(tNode, nativeElement);
22387
+ resolve();
22388
+ }, maxAnimationTimeout);
22389
+ const event = {
22390
+ target: nativeElement,
22391
+ animationComplete: () => {
22392
+ clearLeavingNodes(tNode, nativeElement);
22393
+ clearTimeout(timeoutId);
22394
+ resolve();
22395
+ },
22396
+ };
22397
+ trackLeavingNodes(tNode, nativeElement);
22398
+ ngZone.runOutsideAngular(() => {
22399
+ renderer.listen(nativeElement, 'animationend', () => {
22400
+ resolve();
22401
+ }, { once: true });
22402
+ });
22403
+ value.call(lView[CONTEXT], event);
22404
+ }
22405
+ // Ensure cleanup if the LView is destroyed before the animation runs.
22406
+ return promise;
22407
+ }
22391
22408
 
22392
22409
  /*!
22393
22410
  * @license
@@ -22438,7 +22455,11 @@ class LiveCollection {
22438
22455
  }
22439
22456
  }
22440
22457
  move(prevIndex, newIdx) {
22441
- this.attach(newIdx, this.detach(prevIndex));
22458
+ // For move operations, the detach code path is the same one used for removing
22459
+ // DOM nodes, which would trigger `animate.leave` bindings. We need to skip
22460
+ // those animations in the case of a move operation so the moving elements don't
22461
+ // unexpectedly disappear.
22462
+ this.attach(newIdx, this.detach(prevIndex, true /* skipLeaveAnimations */));
22442
22463
  }
22443
22464
  }
22444
22465
  function valuesMatching(liveIdx, liveValue, newIdx, newValue, trackBy) {
@@ -23010,8 +23031,10 @@ class LiveCollectionLContainerImpl extends LiveCollection {
23010
23031
  this.needsIndexUpdate ||= index !== this.length;
23011
23032
  addLViewToLContainer(this.lContainer, lView, index, shouldAddViewToDom(this.templateTNode, dehydratedView));
23012
23033
  }
23013
- detach(index) {
23034
+ detach(index, skipLeaveAnimations) {
23014
23035
  this.needsIndexUpdate ||= index !== this.length - 1;
23036
+ if (skipLeaveAnimations)
23037
+ setSkipLeaveAnimations(this.lContainer, index);
23015
23038
  return detachExistingView(this.lContainer, index);
23016
23039
  }
23017
23040
  create(index, value) {
@@ -23117,6 +23140,15 @@ function getLContainer(lView, index) {
23117
23140
  ngDevMode && assertLContainer(lContainer);
23118
23141
  return lContainer;
23119
23142
  }
23143
+ function setSkipLeaveAnimations(lContainer, index) {
23144
+ if (lContainer.length <= CONTAINER_HEADER_OFFSET)
23145
+ return;
23146
+ const indexInContainer = CONTAINER_HEADER_OFFSET + index;
23147
+ const viewToDetach = lContainer[indexInContainer];
23148
+ if (viewToDetach && viewToDetach[ANIMATIONS]) {
23149
+ viewToDetach[ANIMATIONS].skipLeaveAnimations = true;
23150
+ }
23151
+ }
23120
23152
  function detachExistingView(lContainer, index) {
23121
23153
  const existingLView = detachView(lContainer, index);
23122
23154
  ngDevMode && assertLView(existingLView);
@@ -23604,7 +23636,7 @@ function plural(val) {
23604
23636
  return 1;
23605
23637
  return 5;
23606
23638
  }
23607
- var localeEn = ["en", [["a", "p"], ["AM", "PM"], u], [["AM", "PM"], u, u], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
23639
+ var localeEn = ["en", [["a", "p"], ["AM", "PM"]], [["AM", "PM"]], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
23608
23640
 
23609
23641
  /**
23610
23642
  * This const is used to store the locale data registered with `registerLocaleData`
@@ -23772,6 +23804,7 @@ const ICU_MARKER = {
23772
23804
  */
23773
23805
  var I18nCreateOpCode;
23774
23806
  (function (I18nCreateOpCode) {
23807
+ /* tslint:disable:no-duplicate-enum-values */
23775
23808
  /**
23776
23809
  * Number of bits to shift index so that it can be combined with the `APPEND_EAGERLY` and
23777
23810
  * `COMMENT`.
@@ -23785,6 +23818,7 @@ var I18nCreateOpCode;
23785
23818
  * If set the node should be comment (rather than a text) node.
23786
23819
  */
23787
23820
  I18nCreateOpCode[I18nCreateOpCode["COMMENT"] = 2] = "COMMENT";
23821
+ /* tslint:enable:no-duplicate-enum-values */
23788
23822
  })(I18nCreateOpCode || (I18nCreateOpCode = {}));
23789
23823
 
23790
23824
  /**
@@ -28310,18 +28344,6 @@ function ɵɵExternalStylesFeature(styleUrls) {
28310
28344
  };
28311
28345
  }
28312
28346
 
28313
- /**
28314
- * This feature adds the element registry for delayed element removal when animate.leave
28315
- * is utilized.
28316
- *
28317
- * @codeGenApi
28318
- */
28319
- function ɵɵAnimationsFeature() {
28320
- return () => {
28321
- setAnimationElementRemovalRegistry(new ElementRegistry());
28322
- };
28323
- }
28324
-
28325
28347
  /**
28326
28348
  * Generated next to NgModules to monkey-patch directive and pipe references onto a component's
28327
28349
  * definition, when generating a direct reference in the component file would otherwise create an
@@ -29280,7 +29302,6 @@ const angularCoreEnv = (() => ({
29280
29302
  'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
29281
29303
  'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
29282
29304
  'ɵɵExternalStylesFeature': ɵɵExternalStylesFeature,
29283
- 'ɵɵAnimationsFeature': ɵɵAnimationsFeature,
29284
29305
  'ɵɵnextContext': ɵɵnextContext,
29285
29306
  'ɵɵnamespaceHTML': __namespaceHTML,
29286
29307
  'ɵɵnamespaceMathML': __namespaceMathML,
@@ -31827,5 +31848,5 @@ function getDebugNode(nativeNode) {
31827
31848
  return null;
31828
31849
  }
31829
31850
 
31830
- export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, ElementRegistry, EnvironmentNgModuleRefAdapter, EventEmitter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, NgProbeToken, NgZone, NoopNgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, PROVIDED_NG_ZONE, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getNgZone, getNgZoneOptions, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, internalProvideZoneChangeDetection, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZoneChangeDetection, provideZonelessChangeDetection, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵAnimationsFeature, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31851
+ export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, EnvironmentNgModuleRefAdapter, EventEmitter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, NgProbeToken, NgZone, NoopNgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, PROVIDED_NG_ZONE, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allLeavingAnimations, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getNgZone, getNgZoneOptions, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, internalProvideZoneChangeDetection, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZoneChangeDetection, provideZonelessChangeDetection, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31831
31852
  //# sourceMappingURL=debug_node.mjs.map