@angular/compiler 20.2.0-next.1 → 20.2.0-next.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.2.0-next.1
2
+ * @license Angular v20.2.0-next.2
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -2812,7 +2812,18 @@ class Identifiers {
2812
2812
  static pipeBind4 = { name: 'ɵɵpipeBind4', moduleName: CORE };
2813
2813
  static pipeBindV = { name: 'ɵɵpipeBindV', moduleName: CORE };
2814
2814
  static domProperty = { name: 'ɵɵdomProperty', moduleName: CORE };
2815
+ static ariaProperty = { name: 'ɵɵariaProperty', moduleName: CORE };
2815
2816
  static property = { name: 'ɵɵproperty', moduleName: CORE };
2817
+ static animationEnterListener = {
2818
+ name: 'ɵɵanimateEnterListener',
2819
+ moduleName: CORE,
2820
+ };
2821
+ static animationLeaveListener = {
2822
+ name: 'ɵɵanimateLeaveListener',
2823
+ moduleName: CORE,
2824
+ };
2825
+ static animationEnter = { name: 'ɵɵanimateEnter', moduleName: CORE };
2826
+ static animationLeave = { name: 'ɵɵanimateLeave', moduleName: CORE };
2816
2827
  static i18n = { name: 'ɵɵi18n', moduleName: CORE };
2817
2828
  static i18nAttributes = { name: 'ɵɵi18nAttributes', moduleName: CORE };
2818
2829
  static i18nExp = { name: 'ɵɵi18nExp', moduleName: CORE };
@@ -2956,6 +2967,10 @@ class Identifiers {
2956
2967
  name: 'ɵɵExternalStylesFeature',
2957
2968
  moduleName: CORE,
2958
2969
  };
2970
+ static AnimationsFeature = {
2971
+ name: 'ɵɵAnimationsFeature',
2972
+ moduleName: CORE,
2973
+ };
2959
2974
  static listener = { name: 'ɵɵlistener', moduleName: CORE };
2960
2975
  static getInheritedFactory = {
2961
2976
  name: 'ɵɵgetInheritedFactory',
@@ -4538,6 +4553,7 @@ class ParsedProperty {
4538
4553
  valueSpan;
4539
4554
  isLiteral;
4540
4555
  isLegacyAnimation;
4556
+ isAnimation;
4541
4557
  constructor(name, expression, type, sourceSpan, keySpan, valueSpan) {
4542
4558
  this.name = name;
4543
4559
  this.expression = expression;
@@ -4547,6 +4563,7 @@ class ParsedProperty {
4547
4563
  this.valueSpan = valueSpan;
4548
4564
  this.isLiteral = this.type === ParsedPropertyType.LITERAL_ATTR;
4549
4565
  this.isLegacyAnimation = this.type === ParsedPropertyType.LEGACY_ANIMATION;
4566
+ this.isAnimation = this.type === ParsedPropertyType.ANIMATION;
4550
4567
  }
4551
4568
  }
4552
4569
  var ParsedPropertyType;
@@ -4555,6 +4572,7 @@ var ParsedPropertyType;
4555
4572
  ParsedPropertyType[ParsedPropertyType["LITERAL_ATTR"] = 1] = "LITERAL_ATTR";
4556
4573
  ParsedPropertyType[ParsedPropertyType["LEGACY_ANIMATION"] = 2] = "LEGACY_ANIMATION";
4557
4574
  ParsedPropertyType[ParsedPropertyType["TWO_WAY"] = 3] = "TWO_WAY";
4575
+ ParsedPropertyType[ParsedPropertyType["ANIMATION"] = 4] = "ANIMATION";
4558
4576
  })(ParsedPropertyType || (ParsedPropertyType = {}));
4559
4577
  var ParsedEventType;
4560
4578
  (function (ParsedEventType) {
@@ -4564,6 +4582,8 @@ var ParsedEventType;
4564
4582
  ParsedEventType[ParsedEventType["LegacyAnimation"] = 1] = "LegacyAnimation";
4565
4583
  // Event side of a two-way binding (e.g. `[(property)]="expression"`).
4566
4584
  ParsedEventType[ParsedEventType["TwoWay"] = 2] = "TwoWay";
4585
+ // Animation specific event
4586
+ ParsedEventType[ParsedEventType["Animation"] = 3] = "Animation";
4567
4587
  })(ParsedEventType || (ParsedEventType = {}));
4568
4588
  class ParsedEvent {
4569
4589
  name;
@@ -4614,6 +4634,8 @@ var BindingType;
4614
4634
  BindingType[BindingType["LegacyAnimation"] = 4] = "LegacyAnimation";
4615
4635
  // Property side of a two-way binding (e.g. `[(property)]="expression"`).
4616
4636
  BindingType[BindingType["TwoWay"] = 5] = "TwoWay";
4637
+ // A binding to an animation CSS class or function (e.g. `[animate.leave]="expression"`).
4638
+ BindingType[BindingType["Animation"] = 6] = "Animation";
4617
4639
  })(BindingType || (BindingType = {}));
4618
4640
  class BoundElementProperty {
4619
4641
  name;
@@ -8744,6 +8766,22 @@ var OpKind;
8744
8766
  * Creation op that attaches the location at which an element was defined in a template to it.
8745
8767
  */
8746
8768
  OpKind[OpKind["SourceLocation"] = 52] = "SourceLocation";
8769
+ /**
8770
+ * An operation to bind animation css classes to an element.
8771
+ */
8772
+ OpKind[OpKind["Animation"] = 53] = "Animation";
8773
+ /**
8774
+ * An operation to bind animation css classes to an element.
8775
+ */
8776
+ OpKind[OpKind["AnimationString"] = 54] = "AnimationString";
8777
+ /**
8778
+ * An operation to bind animation css classes to an element.
8779
+ */
8780
+ OpKind[OpKind["AnimationBinding"] = 55] = "AnimationBinding";
8781
+ /**
8782
+ * An operation to bind animation events to an element.
8783
+ */
8784
+ OpKind[OpKind["AnimationListener"] = 56] = "AnimationListener";
8747
8785
  })(OpKind || (OpKind = {}));
8748
8786
  /**
8749
8787
  * Distinguishes different kinds of IR expressions.
@@ -8934,6 +8972,10 @@ var BindingKind;
8934
8972
  * Property side of a two-way binding.
8935
8973
  */
8936
8974
  BindingKind[BindingKind["TwoWayProperty"] = 7] = "TwoWayProperty";
8975
+ /**
8976
+ * Property side of an animation binding.
8977
+ */
8978
+ BindingKind[BindingKind["Animation"] = 8] = "Animation";
8937
8979
  })(BindingKind || (BindingKind = {}));
8938
8980
  /**
8939
8981
  * Enumeration of possible times i18n params can be resolved.
@@ -9174,13 +9216,13 @@ function createBindingOp(target, kind, name, expression, unit, securityContext,
9174
9216
  /**
9175
9217
  * Create a `PropertyOp`.
9176
9218
  */
9177
- function createPropertyOp(target, name, expression, isLegacyAnimationTrigger, securityContext, isStructuralTemplateAttribute, templateKind, i18nContext, i18nMessage, sourceSpan) {
9219
+ function createPropertyOp(target, name, expression, bindingKind, securityContext, isStructuralTemplateAttribute, templateKind, i18nContext, i18nMessage, sourceSpan) {
9178
9220
  return {
9179
9221
  kind: OpKind.Property,
9180
9222
  target,
9181
9223
  name,
9182
9224
  expression,
9183
- isLegacyAnimationTrigger,
9225
+ bindingKind,
9184
9226
  securityContext,
9185
9227
  sanitizer: null,
9186
9228
  isStructuralTemplateAttribute,
@@ -9331,6 +9373,24 @@ function createRepeaterOp(repeaterCreate, targetSlot, collection, sourceSpan) {
9331
9373
  ...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
9332
9374
  };
9333
9375
  }
9376
+ /**
9377
+ * Create an `AnimationBindingOp`.
9378
+ */
9379
+ function createAnimationBindingOp(name, target, animationKind, expression, securityContext, sourceSpan, animationBindingKind) {
9380
+ return {
9381
+ kind: OpKind.AnimationBinding,
9382
+ name,
9383
+ target,
9384
+ animationKind,
9385
+ expression,
9386
+ i18nMessage: null,
9387
+ securityContext,
9388
+ sanitizer: null,
9389
+ sourceSpan,
9390
+ animationBindingKind,
9391
+ ...NEW_OP,
9392
+ };
9393
+ }
9334
9394
  function createDeferWhenOp(target, expr, modifier, sourceSpan) {
9335
9395
  return {
9336
9396
  kind: OpKind.DeferWhen,
@@ -10161,6 +10221,8 @@ function transformExpressionsInOp(op, transform, flags) {
10161
10221
  case OpKind.StyleMap:
10162
10222
  case OpKind.ClassProp:
10163
10223
  case OpKind.ClassMap:
10224
+ case OpKind.AnimationString:
10225
+ case OpKind.AnimationBinding:
10164
10226
  case OpKind.Binding:
10165
10227
  if (op.expression instanceof Interpolation) {
10166
10228
  transformExpressionsInInterpolation(op.expression, transform, flags);
@@ -10213,6 +10275,8 @@ function transformExpressionsInOp(op, transform, flags) {
10213
10275
  op.contextValue = transformExpressionsInExpression(op.contextValue, transform, flags);
10214
10276
  }
10215
10277
  break;
10278
+ case OpKind.Animation:
10279
+ case OpKind.AnimationListener:
10216
10280
  case OpKind.Listener:
10217
10281
  case OpKind.TwoWayListener:
10218
10282
  for (const innerOp of op.handlerOps) {
@@ -10864,6 +10928,43 @@ function createTextOp(xref, initialValue, icuPlaceholder, sourceSpan) {
10864
10928
  ...NEW_OP,
10865
10929
  };
10866
10930
  }
10931
+ /**
10932
+ * Create an `AnimationOp`.
10933
+ */
10934
+ function createAnimationStringOp(name, target, animationKind, expression, securityContext, sourceSpan) {
10935
+ return {
10936
+ kind: OpKind.AnimationString,
10937
+ name,
10938
+ target,
10939
+ animationKind,
10940
+ expression,
10941
+ i18nMessage: null,
10942
+ securityContext,
10943
+ sanitizer: null,
10944
+ sourceSpan,
10945
+ ...NEW_OP,
10946
+ };
10947
+ }
10948
+ /**
10949
+ * Create an `AnimationOp`.
10950
+ */
10951
+ function createAnimationOp(name, target, animationKind, callbackOps, securityContext, sourceSpan) {
10952
+ const handlerOps = new OpList();
10953
+ handlerOps.push(callbackOps);
10954
+ return {
10955
+ kind: OpKind.Animation,
10956
+ name,
10957
+ target,
10958
+ animationKind,
10959
+ handlerOps,
10960
+ handlerFnName: null,
10961
+ i18nMessage: null,
10962
+ securityContext,
10963
+ sanitizer: null,
10964
+ sourceSpan,
10965
+ ...NEW_OP,
10966
+ };
10967
+ }
10867
10968
  /**
10868
10969
  * Create a `ListenerOp`. Host bindings reuse all the listener logic.
10869
10970
  */
@@ -10887,6 +10988,28 @@ function createListenerOp(target, targetSlot, name, tag, handlerOps, legacyAnima
10887
10988
  ...NEW_OP,
10888
10989
  };
10889
10990
  }
10991
+ /**
10992
+ * Create a `ListenerOp`. Host bindings reuse all the listener logic.
10993
+ */
10994
+ function createAnimationListenerOp(target, targetSlot, name, tag, handlerOps, animationKind, eventTarget, hostListener, sourceSpan) {
10995
+ const handlerList = new OpList();
10996
+ handlerList.push(handlerOps);
10997
+ return {
10998
+ kind: OpKind.AnimationListener,
10999
+ target,
11000
+ targetSlot,
11001
+ tag,
11002
+ hostListener,
11003
+ name,
11004
+ animationKind,
11005
+ handlerOps: handlerList,
11006
+ handlerFnName: null,
11007
+ consumesDollarEvent: false,
11008
+ eventTarget,
11009
+ sourceSpan,
11010
+ ...NEW_OP,
11011
+ };
11012
+ }
10890
11013
  /**
10891
11014
  * Create a `TwoWayListenerOp`.
10892
11015
  */
@@ -11136,12 +11259,12 @@ function createSourceLocationOp(templatePath, locations) {
11136
11259
  };
11137
11260
  }
11138
11261
 
11139
- function createDomPropertyOp(name, expression, isLegacyAnimationTrigger, i18nContext, securityContext, sourceSpan) {
11262
+ function createDomPropertyOp(name, expression, bindingKind, i18nContext, securityContext, sourceSpan) {
11140
11263
  return {
11141
11264
  kind: OpKind.DomProperty,
11142
11265
  name,
11143
11266
  expression,
11144
- isLegacyAnimationTrigger,
11267
+ bindingKind,
11145
11268
  i18nContext,
11146
11269
  securityContext,
11147
11270
  sanitizer: null,
@@ -11308,7 +11431,10 @@ class CompilationUnit {
11308
11431
  *ops() {
11309
11432
  for (const op of this.create) {
11310
11433
  yield op;
11311
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
11434
+ if (op.kind === OpKind.Listener ||
11435
+ op.kind === OpKind.Animation ||
11436
+ op.kind === OpKind.AnimationListener ||
11437
+ op.kind === OpKind.TwoWayListener) {
11312
11438
  for (const listenerOp of op.handlerOps) {
11313
11439
  yield listenerOp;
11314
11440
  }
@@ -11588,7 +11714,8 @@ function extractAttributes(job) {
11588
11714
  extractAttributeOp(unit, op, elements);
11589
11715
  break;
11590
11716
  case OpKind.Property:
11591
- if (!op.isLegacyAnimationTrigger) {
11717
+ if (op.bindingKind !== BindingKind.LegacyAnimation &&
11718
+ op.bindingKind !== BindingKind.Animation) {
11592
11719
  let bindingKind;
11593
11720
  if (op.i18nMessage !== null && op.templateKind === null) {
11594
11721
  // If the binding has an i18n context, it is an i18n attribute, and should have that
@@ -11606,14 +11733,14 @@ function extractAttributes(job) {
11606
11733
  createExtractedAttributeOp(op.target, bindingKind, null, op.name,
11607
11734
  /* expression */ null,
11608
11735
  /* i18nContext */ null,
11609
- /* i18nMessage */ null, op.securityContext), lookupElement$2(elements, op.target));
11736
+ /* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
11610
11737
  }
11611
11738
  break;
11612
11739
  case OpKind.TwoWayProperty:
11613
11740
  OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.TwoWayProperty, null, op.name,
11614
11741
  /* expression */ null,
11615
11742
  /* i18nContext */ null,
11616
- /* i18nMessage */ null, op.securityContext), lookupElement$2(elements, op.target));
11743
+ /* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
11617
11744
  break;
11618
11745
  case OpKind.StyleProp:
11619
11746
  case OpKind.ClassProp:
@@ -11626,7 +11753,7 @@ function extractAttributes(job) {
11626
11753
  OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, null, op.name,
11627
11754
  /* expression */ null,
11628
11755
  /* i18nContext */ null,
11629
- /* i18nMessage */ null, SecurityContext.STYLE), lookupElement$2(elements, op.target));
11756
+ /* i18nMessage */ null, SecurityContext.STYLE), lookupElement$3(elements, op.target));
11630
11757
  }
11631
11758
  break;
11632
11759
  case OpKind.Listener:
@@ -11646,7 +11773,7 @@ function extractAttributes(job) {
11646
11773
  unit.create.push(extractedAttributeOp);
11647
11774
  }
11648
11775
  else {
11649
- OpList.insertBefore(extractedAttributeOp, lookupElement$2(elements, op.target));
11776
+ OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
11650
11777
  }
11651
11778
  }
11652
11779
  break;
@@ -11657,7 +11784,7 @@ function extractAttributes(job) {
11657
11784
  /* expression */ null,
11658
11785
  /* i18nContext */ null,
11659
11786
  /* i18nMessage */ null, SecurityContext.NONE);
11660
- OpList.insertBefore(extractedAttributeOp, lookupElement$2(elements, op.target));
11787
+ OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
11661
11788
  }
11662
11789
  break;
11663
11790
  }
@@ -11667,7 +11794,7 @@ function extractAttributes(job) {
11667
11794
  /**
11668
11795
  * Looks up an element in the given map by xref ID.
11669
11796
  */
11670
- function lookupElement$2(elements, xref) {
11797
+ function lookupElement$3(elements, xref) {
11671
11798
  const el = elements.get(xref);
11672
11799
  if (el === undefined) {
11673
11800
  throw new Error('All attributes should have an element-like target.');
@@ -11695,7 +11822,7 @@ function extractAttributeOp(unit, op, elements) {
11695
11822
  unit.create.push(extractedAttributeOp);
11696
11823
  }
11697
11824
  else {
11698
- const ownerOp = lookupElement$2(elements, op.target);
11825
+ const ownerOp = lookupElement$3(elements, op.target);
11699
11826
  OpList.insertBefore(extractedAttributeOp, ownerOp);
11700
11827
  }
11701
11828
  OpList.remove(op);
@@ -11705,7 +11832,7 @@ function extractAttributeOp(unit, op, elements) {
11705
11832
  /**
11706
11833
  * Looks up an element in the given map by xref ID.
11707
11834
  */
11708
- function lookupElement$1(elements, xref) {
11835
+ function lookupElement$2(elements, xref) {
11709
11836
  const el = elements.get(xref);
11710
11837
  if (el === undefined) {
11711
11838
  throw new Error('All attributes should have an element-like target.');
@@ -11731,21 +11858,27 @@ function specializeBindings(job) {
11731
11858
  case BindingKind.Attribute:
11732
11859
  if (op.name === 'ngNonBindable') {
11733
11860
  OpList.remove(op);
11734
- const target = lookupElement$1(elements, op.target);
11861
+ const target = lookupElement$2(elements, op.target);
11735
11862
  target.nonBindable = true;
11736
11863
  }
11864
+ else if (op.name.startsWith('animate.')) {
11865
+ OpList.replace(op, createAnimationBindingOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan, 0 /* ir.AnimationBindingKind.STRING */));
11866
+ }
11737
11867
  else {
11738
11868
  const [namespace, name] = splitNsName(op.name);
11739
11869
  OpList.replace(op, createAttributeOp(op.target, namespace, name, op.expression, op.securityContext, op.isTextAttribute, op.isStructuralTemplateAttribute, op.templateKind, op.i18nMessage, op.sourceSpan));
11740
11870
  }
11741
11871
  break;
11872
+ case BindingKind.Animation:
11873
+ OpList.replace(op, createAnimationBindingOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan, 1 /* ir.AnimationBindingKind.VALUE */));
11874
+ break;
11742
11875
  case BindingKind.Property:
11743
11876
  case BindingKind.LegacyAnimation:
11744
11877
  if (job.kind === CompilationJobKind.Host) {
11745
- OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind === BindingKind.LegacyAnimation, op.i18nContext, op.securityContext, op.sourceSpan));
11878
+ OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind, op.i18nContext, op.securityContext, op.sourceSpan));
11746
11879
  }
11747
11880
  else {
11748
- OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind === BindingKind.LegacyAnimation, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
11881
+ OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
11749
11882
  }
11750
11883
  break;
11751
11884
  case BindingKind.TwoWayProperty:
@@ -11767,6 +11900,7 @@ function specializeBindings(job) {
11767
11900
  }
11768
11901
 
11769
11902
  const CHAIN_COMPATIBILITY = new Map([
11903
+ [Identifiers.ariaProperty, Identifiers.ariaProperty],
11770
11904
  [Identifiers.attribute, Identifiers.attribute],
11771
11905
  [Identifiers.classProp, Identifiers.classProp],
11772
11906
  [Identifiers.element, Identifiers.element],
@@ -11797,6 +11931,10 @@ const CHAIN_COMPATIBILITY = new Map([
11797
11931
  [Identifiers.domElementContainerEnd, Identifiers.domElementContainerEnd],
11798
11932
  [Identifiers.domListener, Identifiers.domListener],
11799
11933
  [Identifiers.domTemplate, Identifiers.domTemplate],
11934
+ [Identifiers.animationEnter, Identifiers.animationEnter],
11935
+ [Identifiers.animationLeave, Identifiers.animationLeave],
11936
+ [Identifiers.animationEnterListener, Identifiers.animationEnterListener],
11937
+ [Identifiers.animationLeaveListener, Identifiers.animationLeaveListener],
11800
11938
  ]);
11801
11939
  /**
11802
11940
  * Chaining results in repeated call expressions, causing a deep AST of receiver expressions. To prevent running out of
@@ -12217,6 +12355,52 @@ function serializeAttributes({ attributes, bindings, classes, i18n, projectAs, s
12217
12355
  return literalArr(attrArray);
12218
12356
  }
12219
12357
 
12358
+ /**
12359
+ * Looks up an element in the given map by xref ID.
12360
+ */
12361
+ function lookupElement$1(elements, xref) {
12362
+ const el = elements.get(xref);
12363
+ if (el === undefined) {
12364
+ throw new Error('All attributes should have an element-like target.');
12365
+ }
12366
+ return el;
12367
+ }
12368
+ function convertAnimations(job) {
12369
+ const elements = new Map();
12370
+ for (const unit of job.units) {
12371
+ for (const op of unit.create) {
12372
+ if (!isElementOrContainerOp(op)) {
12373
+ continue;
12374
+ }
12375
+ elements.set(op.xref, op);
12376
+ }
12377
+ }
12378
+ for (const unit of job.units) {
12379
+ for (const op of unit.ops()) {
12380
+ if (op.kind === OpKind.AnimationBinding) {
12381
+ const createAnimationOp = getAnimationOp(op);
12382
+ if (job.kind === CompilationJobKind.Host) {
12383
+ unit.create.push(createAnimationOp);
12384
+ }
12385
+ else {
12386
+ OpList.insertAfter(createAnimationOp, lookupElement$1(elements, op.target));
12387
+ }
12388
+ OpList.remove(op);
12389
+ }
12390
+ }
12391
+ }
12392
+ }
12393
+ function getAnimationOp(op) {
12394
+ if (op.animationBindingKind === 0 /* ir.AnimationBindingKind.STRING */) {
12395
+ // this is a simple string case
12396
+ return createAnimationStringOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan);
12397
+ }
12398
+ else {
12399
+ const expression = op.expression;
12400
+ return createAnimationOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, [createStatementOp(new ReturnStatement(expression, expression.sourceSpan))], op.securityContext, op.sourceSpan);
12401
+ }
12402
+ }
12403
+
12220
12404
  /**
12221
12405
  * Some binding instructions in the update block may actually correspond to i18n bindings. In that
12222
12406
  * case, they should be replaced with i18nExp instructions for the dynamic portions.
@@ -13105,6 +13289,8 @@ function recursivelyProcessView(view, parentScope) {
13105
13289
  op.trackByOps.prepend(generateVariablesInScopeForView(view, scope, false));
13106
13290
  }
13107
13291
  break;
13292
+ case OpKind.Animation:
13293
+ case OpKind.AnimationListener:
13108
13294
  case OpKind.Listener:
13109
13295
  case OpKind.TwoWayListener:
13110
13296
  // Prepend variables to listener handler functions.
@@ -13187,7 +13373,7 @@ function getScopeForView(view, parent) {
13187
13373
  * This is a recursive process, as views inherit variables available from their parent view, which
13188
13374
  * itself may have inherited variables, etc.
13189
13375
  */
13190
- function generateVariablesInScopeForView(view, scope, isListener) {
13376
+ function generateVariablesInScopeForView(view, scope, isCallback) {
13191
13377
  const newOps = [];
13192
13378
  if (scope.view !== view.xref) {
13193
13379
  // Before generating variables for a parent view, we need to switch to the context of the parent
@@ -13211,7 +13397,7 @@ function generateVariablesInScopeForView(view, scope, isListener) {
13211
13397
  for (const ref of scope.references) {
13212
13398
  newOps.push(createVariableOp(view.job.allocateXrefId(), ref.variable, new ReferenceExpr(ref.targetId, ref.targetSlot, ref.offset), VariableFlags.None));
13213
13399
  }
13214
- if (scope.view !== view.xref || isListener) {
13400
+ if (scope.view !== view.xref || isCallback) {
13215
13401
  for (const decl of scope.letDeclarations) {
13216
13402
  newOps.push(createVariableOp(view.job.allocateXrefId(), decl.variable, new ContextLetReferenceExpr(decl.targetId, decl.targetSlot), VariableFlags.None));
13217
13403
  }
@@ -16510,6 +16696,23 @@ class _Tokenizer {
16510
16696
  return isNameEnd(code);
16511
16697
  };
16512
16698
  }
16699
+ else if (attrNameStart === $LBRACKET) {
16700
+ let openBrackets = 0;
16701
+ // Be more permissive for which characters are allowed inside square-bracketed attributes,
16702
+ // because they usually end up being bound as attribute values. Some third-party packages
16703
+ // like Tailwind take advantage of this.
16704
+ nameEndPredicate = (code) => {
16705
+ if (code === $LBRACKET) {
16706
+ openBrackets++;
16707
+ }
16708
+ else if (code === $RBRACKET) {
16709
+ openBrackets--;
16710
+ }
16711
+ // Only check for name-ending characters if the brackets are balanced or mismatched.
16712
+ // Also interrupt the matching on new lines.
16713
+ return openBrackets <= 0 ? isNameEnd(code) : isNewLine(code);
16714
+ };
16715
+ }
16513
16716
  else {
16514
16717
  nameEndPredicate = isNameEnd;
16515
16718
  }
@@ -20433,6 +20636,44 @@ const _ATTR_TO_PROP = new Map(Object.entries({
20433
20636
  'innerHtml': 'innerHTML',
20434
20637
  'readonly': 'readOnly',
20435
20638
  'tabindex': 'tabIndex',
20639
+ // https://www.w3.org/TR/wai-aria-1.2/#accessibilityroleandproperties-correspondence
20640
+ 'aria-atomic': 'ariaAtomic',
20641
+ 'aria-autocomplete': 'ariaAutoComplete',
20642
+ 'aria-busy': 'ariaBusy',
20643
+ 'aria-checked': 'ariaChecked',
20644
+ 'aria-colcount': 'ariaColCount',
20645
+ 'aria-colindex': 'ariaColIndex',
20646
+ 'aria-colspan': 'ariaColSpan',
20647
+ 'aria-current': 'ariaCurrent',
20648
+ 'aria-disabled': 'ariaDisabled',
20649
+ 'aria-expanded': 'ariaExpanded',
20650
+ 'aria-haspopup': 'ariaHasPopup',
20651
+ 'aria-hidden': 'ariaHidden',
20652
+ 'aria-invalid': 'ariaInvalid',
20653
+ 'aria-keyshortcuts': 'ariaKeyShortcuts',
20654
+ 'aria-label': 'ariaLabel',
20655
+ 'aria-level': 'ariaLevel',
20656
+ 'aria-live': 'ariaLive',
20657
+ 'aria-modal': 'ariaModal',
20658
+ 'aria-multiline': 'ariaMultiLine',
20659
+ 'aria-multiselectable': 'ariaMultiSelectable',
20660
+ 'aria-orientation': 'ariaOrientation',
20661
+ 'aria-placeholder': 'ariaPlaceholder',
20662
+ 'aria-posinset': 'ariaPosInSet',
20663
+ 'aria-pressed': 'ariaPressed',
20664
+ 'aria-readonly': 'ariaReadOnly',
20665
+ 'aria-required': 'ariaRequired',
20666
+ 'aria-roledescription': 'ariaRoleDescription',
20667
+ 'aria-rowcount': 'ariaRowCount',
20668
+ 'aria-rowindex': 'ariaRowIndex',
20669
+ 'aria-rowspan': 'ariaRowSpan',
20670
+ 'aria-selected': 'ariaSelected',
20671
+ 'aria-setsize': 'ariaSetSize',
20672
+ 'aria-sort': 'ariaSort',
20673
+ 'aria-valuemax': 'ariaValueMax',
20674
+ 'aria-valuemin': 'ariaValueMin',
20675
+ 'aria-valuenow': 'ariaValueNow',
20676
+ 'aria-valuetext': 'ariaValueText',
20436
20677
  }));
20437
20678
  // Invert _ATTR_TO_PROP.
20438
20679
  const _PROP_TO_ATTR = Array.from(_ATTR_TO_PROP).reduce((inverted, [propertyName, attributeName]) => {
@@ -22379,10 +22620,33 @@ function addNamesToView(unit, baseName, state, compatibility) {
22379
22620
  switch (op.kind) {
22380
22621
  case OpKind.Property:
22381
22622
  case OpKind.DomProperty:
22382
- if (op.isLegacyAnimationTrigger) {
22623
+ if (op.bindingKind === BindingKind.LegacyAnimation) {
22383
22624
  op.name = '@' + op.name;
22384
22625
  }
22385
22626
  break;
22627
+ case OpKind.Animation:
22628
+ if (op.handlerFnName === null) {
22629
+ const animationKind = op.name.replace('.', '');
22630
+ op.handlerFnName = `${unit.fnName}_${animationKind}_cb`;
22631
+ op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
22632
+ }
22633
+ break;
22634
+ case OpKind.AnimationListener:
22635
+ if (op.handlerFnName !== null) {
22636
+ break;
22637
+ }
22638
+ if (!op.hostListener && op.targetSlot.slot === null) {
22639
+ throw new Error(`Expected a slot to be assigned`);
22640
+ }
22641
+ const animationKind = op.name.replace('.', '');
22642
+ if (op.hostListener) {
22643
+ op.handlerFnName = `${baseName}_${animationKind}_HostBindingHandler`;
22644
+ }
22645
+ else {
22646
+ op.handlerFnName = `${unit.fnName}_${op.tag.replace('-', '_')}_${animationKind}_${op.targetSlot.slot}_listener`;
22647
+ }
22648
+ op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
22649
+ break;
22386
22650
  case OpKind.Listener:
22387
22651
  if (op.handlerFnName !== null) {
22388
22652
  break;
@@ -22540,7 +22804,10 @@ function stripImportant(name) {
22540
22804
  function mergeNextContextExpressions(job) {
22541
22805
  for (const unit of job.units) {
22542
22806
  for (const op of unit.create) {
22543
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
22807
+ if (op.kind === OpKind.Listener ||
22808
+ op.kind === OpKind.Animation ||
22809
+ op.kind === OpKind.AnimationListener ||
22810
+ op.kind === OpKind.TwoWayListener) {
22544
22811
  mergeNextContextsInOps(op.handlerOps);
22545
22812
  }
22546
22813
  }
@@ -22661,7 +22928,9 @@ function kindWithInterpolationTest(kind, interpolation) {
22661
22928
  }
22662
22929
  function basicListenerKindTest(op) {
22663
22930
  return ((op.kind === OpKind.Listener && !(op.hostListener && op.isLegacyAnimationListener)) ||
22664
- op.kind === OpKind.TwoWayListener);
22931
+ op.kind === OpKind.TwoWayListener ||
22932
+ op.kind === OpKind.Animation ||
22933
+ op.kind === OpKind.AnimationListener);
22665
22934
  }
22666
22935
  function nonInterpolationPropertyKindTest(op) {
22667
22936
  return ((op.kind === OpKind.Property || op.kind === OpKind.TwoWayProperty) &&
@@ -22708,6 +22977,7 @@ const UPDATE_HOST_ORDERING = [
22708
22977
  const handledOpKinds = new Set([
22709
22978
  OpKind.Listener,
22710
22979
  OpKind.TwoWayListener,
22980
+ OpKind.AnimationListener,
22711
22981
  OpKind.StyleMap,
22712
22982
  OpKind.ClassMap,
22713
22983
  OpKind.StyleProp,
@@ -22716,6 +22986,7 @@ const handledOpKinds = new Set([
22716
22986
  OpKind.TwoWayProperty,
22717
22987
  OpKind.DomProperty,
22718
22988
  OpKind.Attribute,
22989
+ OpKind.Animation,
22719
22990
  ]);
22720
22991
  /**
22721
22992
  * Many type of operations have ordering constraints that must be respected. For example, a
@@ -23406,6 +23677,9 @@ function i18nAttributes(slot, i18nAttributesConfig) {
23406
23677
  const args = [literal(slot), literal(i18nAttributesConfig)];
23407
23678
  return call(Identifiers.i18nAttributes, args, null);
23408
23679
  }
23680
+ function ariaProperty(name, expression, sourceSpan) {
23681
+ return propertyBase(Identifiers.ariaProperty, name, expression, null, sourceSpan);
23682
+ }
23409
23683
  function property(name, expression, sanitizer, sourceSpan) {
23410
23684
  return propertyBase(Identifiers.property, name, expression, sanitizer, sourceSpan);
23411
23685
  }
@@ -23519,6 +23793,36 @@ function i18nApply(slot, sourceSpan) {
23519
23793
  function domProperty(name, expression, sanitizer, sourceSpan) {
23520
23794
  return propertyBase(Identifiers.domProperty, name, expression, sanitizer, sourceSpan);
23521
23795
  }
23796
+ function animation(animationKind, handlerFn, sanitizer, sourceSpan) {
23797
+ const args = [handlerFn];
23798
+ if (sanitizer !== null) {
23799
+ args.push(sanitizer);
23800
+ }
23801
+ const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
23802
+ ? Identifiers.animationEnter
23803
+ : Identifiers.animationLeave;
23804
+ return call(identifier, args, sourceSpan);
23805
+ }
23806
+ function animationString(animationKind, expression, sanitizer, sourceSpan) {
23807
+ const value = expression instanceof Interpolation
23808
+ ? interpolationToExpression(expression, sourceSpan)
23809
+ : expression;
23810
+ const args = [value];
23811
+ if (sanitizer !== null) {
23812
+ args.push(sanitizer);
23813
+ }
23814
+ const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
23815
+ ? Identifiers.animationEnter
23816
+ : Identifiers.animationLeave;
23817
+ return call(identifier, args, sourceSpan);
23818
+ }
23819
+ function animationListener(animationKind, handlerFn, eventTargetResolver, sourceSpan) {
23820
+ const args = [handlerFn];
23821
+ const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
23822
+ ? Identifiers.animationEnterListener
23823
+ : Identifiers.animationLeaveListener;
23824
+ return call(identifier, args, sourceSpan);
23825
+ }
23522
23826
  function syntheticHostProperty(name, expression, sourceSpan) {
23523
23827
  return call(Identifiers.syntheticHostProperty, [literal(name), expression], sourceSpan);
23524
23828
  }
@@ -23652,6 +23956,7 @@ function callVariadicInstruction(config, baseArgs, interpolationArgs, extraArgs,
23652
23956
  return createStatementOp(callVariadicInstructionExpr(config, baseArgs, interpolationArgs, extraArgs, sourceSpan).toStmt());
23653
23957
  }
23654
23958
 
23959
+ const ARIA_PREFIX = 'aria';
23655
23960
  /**
23656
23961
  * Map of target resolvers for event listeners.
23657
23962
  */
@@ -23765,6 +24070,18 @@ function reifyCreateOperations(unit, ops) {
23765
24070
  case OpKind.DeclareLet:
23766
24071
  OpList.replace(op, declareLet(op.handle.slot, op.sourceSpan));
23767
24072
  break;
24073
+ case OpKind.AnimationString:
24074
+ OpList.replace(op, animationString(op.animationKind, op.expression, op.sanitizer, op.sourceSpan));
24075
+ break;
24076
+ case OpKind.Animation:
24077
+ const animationCallbackFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps,
24078
+ /* consumesDollarEvent */ false);
24079
+ OpList.replace(op, animation(op.animationKind, animationCallbackFn, op.sanitizer, op.sourceSpan));
24080
+ break;
24081
+ case OpKind.AnimationListener:
24082
+ const animationListenerFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, op.consumesDollarEvent);
24083
+ OpList.replace(op, animationListener(op.animationKind, animationListenerFn, null, op.sourceSpan));
24084
+ break;
23768
24085
  case OpKind.Listener:
23769
24086
  const listenerFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, op.consumesDollarEvent);
23770
24087
  const eventTargetResolver = op.eventTarget
@@ -23943,9 +24260,11 @@ function reifyUpdateOperations(unit, ops) {
23943
24260
  OpList.replace(op, advance(op.delta, op.sourceSpan));
23944
24261
  break;
23945
24262
  case OpKind.Property:
23946
- OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly && !op.isLegacyAnimationTrigger
23947
- ? domProperty(DOM_PROPERTY_REMAPPING.get(op.name) ?? op.name, op.expression, op.sanitizer, op.sourceSpan)
23948
- : property(op.name, op.expression, op.sanitizer, op.sourceSpan));
24263
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly &&
24264
+ op.bindingKind !== BindingKind.LegacyAnimation &&
24265
+ op.bindingKind !== BindingKind.Animation
24266
+ ? reifyDomProperty(op)
24267
+ : reifyProperty(op));
23949
24268
  break;
23950
24269
  case OpKind.TwoWayProperty:
23951
24270
  OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
@@ -23979,11 +24298,12 @@ function reifyUpdateOperations(unit, ops) {
23979
24298
  throw new Error('not yet handled');
23980
24299
  }
23981
24300
  else {
23982
- if (op.isLegacyAnimationTrigger) {
24301
+ if (op.bindingKind === BindingKind.LegacyAnimation ||
24302
+ op.bindingKind === BindingKind.Animation) {
23983
24303
  OpList.replace(op, syntheticHostProperty(op.name, op.expression, op.sourceSpan));
23984
24304
  }
23985
24305
  else {
23986
- OpList.replace(op, domProperty(DOM_PROPERTY_REMAPPING.get(op.name) ?? op.name, op.expression, op.sanitizer, op.sourceSpan));
24306
+ OpList.replace(op, reifyDomProperty(op));
23987
24307
  }
23988
24308
  }
23989
24309
  break;
@@ -24015,6 +24335,61 @@ function reifyUpdateOperations(unit, ops) {
24015
24335
  }
24016
24336
  }
24017
24337
  }
24338
+ /**
24339
+ * Converts an ARIA property name to its corresponding attribute name, if necessary.
24340
+ *
24341
+ * For example, converts `ariaLabel` to `aria-label`.
24342
+ *
24343
+ * https://www.w3.org/TR/wai-aria-1.2/#accessibilityroleandproperties-correspondence
24344
+ *
24345
+ * This must be kept in sync with the the function of the same name in
24346
+ * packages/core/src/render3/instructions/aria_property.ts.
24347
+ *
24348
+ * @param name A property name that starts with `aria`.
24349
+ * @returns The corresponding attribute name.
24350
+ */
24351
+ function ariaAttrName(name) {
24352
+ return name.charAt(ARIA_PREFIX.length) !== '-'
24353
+ ? ARIA_PREFIX + '-' + name.slice(ARIA_PREFIX.length).toLowerCase()
24354
+ : name; // Property already has attribute name.
24355
+ }
24356
+ /**
24357
+ * Returns whether `name` is an ARIA property (or attribute) name.
24358
+ *
24359
+ * This is a heuristic based on whether name begins with and is longer than `aria`. For example,
24360
+ * this returns true for both `ariaLabel` and `aria-label`.
24361
+ */
24362
+ function isAriaProperty(name) {
24363
+ return name.startsWith(ARIA_PREFIX) && name.length > ARIA_PREFIX.length;
24364
+ }
24365
+ /**
24366
+ * Reifies a DOM property binding operation.
24367
+ *
24368
+ * This is an optimized version of {@link reifyProperty} that avoids unnecessarily trying to bind
24369
+ * to directive inputs at runtime for views that don't import any directives.
24370
+ *
24371
+ * @param op A property binding operation.
24372
+ * @returns A statement to update the property at runtime.
24373
+ */
24374
+ function reifyDomProperty(op) {
24375
+ return isAriaProperty(op.name)
24376
+ ? attribute(ariaAttrName(op.name), op.expression, null, null, op.sourceSpan)
24377
+ : domProperty(DOM_PROPERTY_REMAPPING.get(op.name) ?? op.name, op.expression, op.sanitizer, op.sourceSpan);
24378
+ }
24379
+ /**
24380
+ * Reifies a property binding operation.
24381
+ *
24382
+ * The returned statement attempts to bind to directive inputs before falling back to a DOM
24383
+ * property.
24384
+ *
24385
+ * @param op A property binding operation.
24386
+ * @returns A statement to update the property at runtime.
24387
+ */
24388
+ function reifyProperty(op) {
24389
+ return isAriaProperty(op.name)
24390
+ ? ariaProperty(op.name, op.expression, op.sourceSpan)
24391
+ : property(op.name, op.expression, op.sanitizer, op.sourceSpan);
24392
+ }
24018
24393
  function reifyIrExpression(expr) {
24019
24394
  if (!isIrExpression(expr)) {
24020
24395
  return expr;
@@ -24256,6 +24631,8 @@ function processLexicalScope$1(view, ops) {
24256
24631
  break;
24257
24632
  }
24258
24633
  break;
24634
+ case OpKind.Animation:
24635
+ case OpKind.AnimationListener:
24259
24636
  case OpKind.Listener:
24260
24637
  case OpKind.TwoWayListener:
24261
24638
  processLexicalScope$1(view, op.handlerOps);
@@ -24321,11 +24698,13 @@ function resolveDollarEvent(job) {
24321
24698
  }
24322
24699
  function transformDollarEvent(ops) {
24323
24700
  for (const op of ops) {
24324
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
24701
+ if (op.kind === OpKind.Listener ||
24702
+ op.kind === OpKind.TwoWayListener ||
24703
+ op.kind === OpKind.AnimationListener) {
24325
24704
  transformExpressionsInOp(op, (expr) => {
24326
24705
  if (expr instanceof LexicalReadExpr && expr.name === '$event') {
24327
24706
  // Two-way listeners always consume `$event` so they omit this field.
24328
- if (op.kind === OpKind.Listener) {
24707
+ if (op.kind === OpKind.Listener || op.kind === OpKind.AnimationListener) {
24329
24708
  op.consumesDollarEvent = true;
24330
24709
  }
24331
24710
  return new ReadVarExpr(expr.name);
@@ -24716,6 +25095,8 @@ function processLexicalScope(unit, ops, savedView) {
24716
25095
  break;
24717
25096
  }
24718
25097
  break;
25098
+ case OpKind.Animation:
25099
+ case OpKind.AnimationListener:
24719
25100
  case OpKind.Listener:
24720
25101
  case OpKind.TwoWayListener:
24721
25102
  // Listener functions have separate variable declarations, so process them as a separate
@@ -24733,7 +25114,10 @@ function processLexicalScope(unit, ops, savedView) {
24733
25114
  // scope. Also, look for `ir.RestoreViewExpr`s and match them with the snapshotted view context
24734
25115
  // variable.
24735
25116
  for (const op of ops) {
24736
- if (op.kind == OpKind.Listener || op.kind === OpKind.TwoWayListener) {
25117
+ if (op.kind == OpKind.Listener ||
25118
+ op.kind === OpKind.TwoWayListener ||
25119
+ op.kind === OpKind.Animation ||
25120
+ op.kind === OpKind.AnimationListener) {
24737
25121
  // Listeners were already processed above with their own scopes.
24738
25122
  continue;
24739
25123
  }
@@ -24902,7 +25286,10 @@ function saveAndRestoreView(job) {
24902
25286
  }, new GetCurrentViewExpr(), VariableFlags.None),
24903
25287
  ]);
24904
25288
  for (const op of unit.create) {
24905
- if (op.kind !== OpKind.Listener && op.kind !== OpKind.TwoWayListener) {
25289
+ if (op.kind !== OpKind.Listener &&
25290
+ op.kind !== OpKind.TwoWayListener &&
25291
+ op.kind !== OpKind.Animation &&
25292
+ op.kind !== OpKind.AnimationListener) {
24906
25293
  continue;
24907
25294
  }
24908
25295
  // Embedded views always need the save/restore view operation.
@@ -25222,7 +25609,10 @@ function generateTemporaries(ops) {
25222
25609
  // Add declarations for the temp vars.
25223
25610
  generatedStatements.push(...Array.from(new Set(defs.values())).map((name) => createStatementOp(new DeclareVarStmt(name))));
25224
25611
  opCount++;
25225
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
25612
+ if (op.kind === OpKind.Listener ||
25613
+ op.kind === OpKind.Animation ||
25614
+ op.kind === OpKind.AnimationListener ||
25615
+ op.kind === OpKind.TwoWayListener) {
25226
25616
  op.handlerOps.prepend(generateTemporaries(op.handlerOps));
25227
25617
  }
25228
25618
  else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
@@ -25566,7 +25956,10 @@ function optimizeVariables(job) {
25566
25956
  inlineAlwaysInlineVariables(unit.create);
25567
25957
  inlineAlwaysInlineVariables(unit.update);
25568
25958
  for (const op of unit.create) {
25569
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
25959
+ if (op.kind === OpKind.Listener ||
25960
+ op.kind === OpKind.Animation ||
25961
+ op.kind === OpKind.AnimationListener ||
25962
+ op.kind === OpKind.TwoWayListener) {
25570
25963
  inlineAlwaysInlineVariables(op.handlerOps);
25571
25964
  }
25572
25965
  else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
@@ -25576,7 +25969,10 @@ function optimizeVariables(job) {
25576
25969
  optimizeVariablesInOpList(unit.create, job.compatibility);
25577
25970
  optimizeVariablesInOpList(unit.update, job.compatibility);
25578
25971
  for (const op of unit.create) {
25579
- if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
25972
+ if (op.kind === OpKind.Listener ||
25973
+ op.kind === OpKind.Animation ||
25974
+ op.kind === OpKind.AnimationListener ||
25975
+ op.kind === OpKind.TwoWayListener) {
25580
25976
  optimizeVariablesInOpList(op.handlerOps, job.compatibility);
25581
25977
  }
25582
25978
  else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
@@ -26013,6 +26409,7 @@ const phases = [
26013
26409
  { kind: CompilationJobKind.Both, fn: deduplicateTextBindings },
26014
26410
  { kind: CompilationJobKind.Both, fn: specializeStyleBindings },
26015
26411
  { kind: CompilationJobKind.Both, fn: specializeBindings },
26412
+ { kind: CompilationJobKind.Both, fn: convertAnimations },
26016
26413
  { kind: CompilationJobKind.Both, fn: extractAttributes },
26017
26414
  { kind: CompilationJobKind.Tmpl, fn: createI18nContexts },
26018
26415
  { kind: CompilationJobKind.Both, fn: parseExtractedStyles },
@@ -26172,6 +26569,8 @@ const compatibilityMode = CompatibilityMode.TemplateDefinitionBuilder;
26172
26569
  const domSchema = new DomElementSchemaRegistry();
26173
26570
  // Tag name of the `ng-template` element.
26174
26571
  const NG_TEMPLATE_TAG_NAME = 'ng-template';
26572
+ // prefix for any animation binding
26573
+ const ANIMATE_PREFIX$1 = 'animate.';
26175
26574
  function isI18nRootNode(meta) {
26176
26575
  return meta instanceof Message;
26177
26576
  }
@@ -26204,6 +26603,9 @@ function ingestHostBinding(input, bindingParser, constantPool) {
26204
26603
  if (property.isLegacyAnimation) {
26205
26604
  bindingKind = BindingKind.LegacyAnimation;
26206
26605
  }
26606
+ if (property.isAnimation) {
26607
+ bindingKind = BindingKind.Animation;
26608
+ }
26207
26609
  const securityContexts = bindingParser
26208
26610
  .calcPossibleSecurityContexts(input.componentSelector, property.name, bindingKind === BindingKind.Attribute)
26209
26611
  .filter((context) => context !== SecurityContext.NONE);
@@ -26870,6 +27272,7 @@ const BINDING_KINDS = new Map([
26870
27272
  [BindingType.Class, BindingKind.ClassName],
26871
27273
  [BindingType.Style, BindingKind.StyleProperty],
26872
27274
  [BindingType.LegacyAnimation, BindingKind.LegacyAnimation],
27275
+ [BindingType.Animation, BindingKind.Animation],
26873
27276
  ]);
26874
27277
  /**
26875
27278
  * Checks whether the given template is a plain ng-template (as opposed to another kind of template
@@ -26934,6 +27337,9 @@ function ingestElementBindings(unit, op, element) {
26934
27337
  if (output.type === ParsedEventType.TwoWay) {
26935
27338
  unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
26936
27339
  }
27340
+ else if (output.type === ParsedEventType.Animation) {
27341
+ unit.create.push(createAnimationListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.name.endsWith('enter') ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, output.target, false, output.sourceSpan));
27342
+ }
26937
27343
  else {
26938
27344
  unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
26939
27345
  }
@@ -27042,7 +27448,9 @@ function createTemplateBinding(view, xref, type, name, value, unit, securityCont
27042
27448
  }
27043
27449
  }
27044
27450
  if (!isTextBinding &&
27045
- (type === BindingType.Attribute || type === BindingType.LegacyAnimation)) {
27451
+ (type === BindingType.Attribute ||
27452
+ type === BindingType.LegacyAnimation ||
27453
+ type === BindingType.Animation)) {
27046
27454
  // Again, this binding doesn't really target the ng-template; it actually targets the element
27047
27455
  // inside the structural template. In the case of non-text attribute or animation bindings,
27048
27456
  // the binding doesn't even show up on the ng-template const array, so we just skip it
@@ -27200,14 +27608,18 @@ function ingestControlFlowInsertionPoint(unit, xref, node) {
27200
27608
  if (root !== null) {
27201
27609
  // Collect the static attributes for content projection purposes.
27202
27610
  for (const attr of root.attributes) {
27203
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
27204
- unit.update.push(createBindingOp(xref, BindingKind.Attribute, attr.name, literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
27611
+ if (!attr.name.startsWith(ANIMATE_PREFIX$1)) {
27612
+ const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
27613
+ unit.update.push(createBindingOp(xref, BindingKind.Attribute, attr.name, literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
27614
+ }
27205
27615
  }
27206
27616
  // Also collect the inputs since they participate in content projection as well.
27207
27617
  // Note that TDB used to collect the outputs as well, but it wasn't passing them into
27208
27618
  // the template instruction. Here we just don't collect them.
27209
27619
  for (const attr of root.inputs) {
27210
- if (attr.type !== BindingType.LegacyAnimation && attr.type !== BindingType.Attribute) {
27620
+ if (attr.type !== BindingType.LegacyAnimation &&
27621
+ attr.type !== BindingType.Animation &&
27622
+ attr.type !== BindingType.Attribute) {
27211
27623
  const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
27212
27624
  unit.create.push(createExtractedAttributeOp(xref, BindingKind.Property, null, attr.name, null, null, null, securityContext));
27213
27625
  }
@@ -27425,6 +27837,7 @@ class HtmlParser extends Parser$1 {
27425
27837
 
27426
27838
  const PROPERTY_PARTS_SEPARATOR = '.';
27427
27839
  const ATTRIBUTE_PREFIX = 'attr';
27840
+ const ANIMATE_PREFIX = 'animate';
27428
27841
  const CLASS_PREFIX = 'class';
27429
27842
  const STYLE_PREFIX = 'style';
27430
27843
  const TEMPLATE_ATTR_PREFIX$1 = '*';
@@ -27624,6 +28037,9 @@ class BindingParser {
27624
28037
  if (isLegacyAnimationProp) {
27625
28038
  this._parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
27626
28039
  }
28040
+ else if (name.startsWith(ANIMATE_PREFIX)) {
28041
+ this._parseAnimation(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
28042
+ }
27627
28043
  else {
27628
28044
  this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
27629
28045
  }
@@ -27640,6 +28056,10 @@ class BindingParser {
27640
28056
  targetMatchableAttrs.push([name, ast.source]);
27641
28057
  targetProps.push(new ParsedProperty(name, ast, isPartOfAssignmentBinding ? ParsedPropertyType.TWO_WAY : ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
27642
28058
  }
28059
+ _parseAnimation(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
28060
+ targetMatchableAttrs.push([name, ast.source]);
28061
+ targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
28062
+ }
27643
28063
  _parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
27644
28064
  if (name.length === 0) {
27645
28065
  this._reportError('Animation trigger is missing', sourceSpan);
@@ -27702,6 +28122,11 @@ class BindingParser {
27702
28122
  bindingType = BindingType.Style;
27703
28123
  securityContexts = [SecurityContext.STYLE];
27704
28124
  }
28125
+ else if (parts[0] == ANIMATE_PREFIX) {
28126
+ boundPropertyName = boundProp.name;
28127
+ bindingType = BindingType.Animation;
28128
+ securityContexts = [SecurityContext.NONE];
28129
+ }
27705
28130
  }
27706
28131
  // If not a special case, use the full property name
27707
28132
  if (boundPropertyName === null) {
@@ -27716,7 +28141,6 @@ class BindingParser {
27716
28141
  }
27717
28142
  return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
27718
28143
  }
27719
- // TODO: keySpan should be required but was made optional to avoid changing VE parser.
27720
28144
  parseEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
27721
28145
  if (name.length === 0) {
27722
28146
  this._reportError(`Event name is missing in binding`, sourceSpan);
@@ -27772,7 +28196,14 @@ class BindingParser {
27772
28196
  if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
27773
28197
  this._reportError('Unsupported expression in a two-way binding', sourceSpan);
27774
28198
  }
27775
- targetEvents.push(new ParsedEvent(eventName, target, isAssignmentEvent ? ParsedEventType.TwoWay : ParsedEventType.Regular, ast, sourceSpan, handlerSpan, keySpan));
28199
+ let eventType = ParsedEventType.Regular;
28200
+ if (isAssignmentEvent) {
28201
+ eventType = ParsedEventType.TwoWay;
28202
+ }
28203
+ if (name.startsWith(ANIMATE_PREFIX)) {
28204
+ eventType = ParsedEventType.Animation;
28205
+ }
28206
+ targetEvents.push(new ParsedEvent(eventName, target, eventType, ast, sourceSpan, handlerSpan, keySpan));
27776
28207
  // Don't detect directives for event names for now,
27777
28208
  // so don't add the event name to the matchableAttrs
27778
28209
  }
@@ -29343,7 +29774,7 @@ class HtmlAstToIvyAst {
29343
29774
  const identifier = bindParts[IDENT_KW_IDX];
29344
29775
  const keySpan = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX], identifier);
29345
29776
  this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
29346
- this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
29777
+ this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan, absoluteOffset);
29347
29778
  }
29348
29779
  else if (bindParts[KW_AT_IDX]) {
29349
29780
  const keySpan = createKeySpan(srcSpan, '', name);
@@ -29374,7 +29805,7 @@ class HtmlAstToIvyAst {
29374
29805
  const keySpan = createKeySpan(srcSpan, delims.start, identifier);
29375
29806
  if (delims.start === BINDING_DELIMS.BANANA_BOX.start) {
29376
29807
  this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
29377
- this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
29808
+ this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan, absoluteOffset);
29378
29809
  }
29379
29810
  else if (delims.start === BINDING_DELIMS.PROPERTY.start) {
29380
29811
  this.bindingParser.parsePropertyBinding(identifier, value, false, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
@@ -29494,7 +29925,7 @@ class HtmlAstToIvyAst {
29494
29925
  }
29495
29926
  references.push(new Reference(identifier, value, sourceSpan, keySpan, valueSpan));
29496
29927
  }
29497
- parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
29928
+ parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan, absoluteOffset) {
29498
29929
  const events = [];
29499
29930
  this.bindingParser.parseEvent(`${name}Change`, expression,
29500
29931
  /* isAssignmentEvent */ true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
@@ -29722,9 +30153,184 @@ function makeBindingParser(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG, s
29722
30153
  return new BindingParser(new Parser(new Lexer(), selectorlessEnabled), interpolationConfig, elementRegistry, []);
29723
30154
  }
29724
30155
 
30156
+ /*!
30157
+ * @license
30158
+ * Copyright Google LLC All Rights Reserved.
30159
+ *
30160
+ * Use of this source code is governed by an MIT-style license that can be
30161
+ * found in the LICENSE file at https://angular.dev/license
30162
+ */
30163
+ /**
30164
+ * Visitor that traverses all template and expression AST nodes in a template.
30165
+ * Useful for cases where every single node needs to be visited.
30166
+ */
30167
+ class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
30168
+ visit(node) {
30169
+ if (node instanceof ASTWithSource) {
30170
+ this.visit(node.ast);
30171
+ }
30172
+ else {
30173
+ node.visit(this);
30174
+ }
30175
+ }
30176
+ visitElement(element) {
30177
+ this.visitAllTemplateNodes(element.attributes);
30178
+ this.visitAllTemplateNodes(element.inputs);
30179
+ this.visitAllTemplateNodes(element.outputs);
30180
+ this.visitAllTemplateNodes(element.directives);
30181
+ this.visitAllTemplateNodes(element.references);
30182
+ this.visitAllTemplateNodes(element.children);
30183
+ }
30184
+ visitTemplate(template) {
30185
+ this.visitAllTemplateNodes(template.attributes);
30186
+ this.visitAllTemplateNodes(template.inputs);
30187
+ this.visitAllTemplateNodes(template.outputs);
30188
+ this.visitAllTemplateNodes(template.directives);
30189
+ this.visitAllTemplateNodes(template.templateAttrs);
30190
+ this.visitAllTemplateNodes(template.variables);
30191
+ this.visitAllTemplateNodes(template.references);
30192
+ this.visitAllTemplateNodes(template.children);
30193
+ }
30194
+ visitContent(content) {
30195
+ this.visitAllTemplateNodes(content.children);
30196
+ }
30197
+ visitBoundAttribute(attribute) {
30198
+ this.visit(attribute.value);
30199
+ }
30200
+ visitBoundEvent(attribute) {
30201
+ this.visit(attribute.handler);
30202
+ }
30203
+ visitBoundText(text) {
30204
+ this.visit(text.value);
30205
+ }
30206
+ visitIcu(icu) {
30207
+ Object.keys(icu.vars).forEach((key) => this.visit(icu.vars[key]));
30208
+ Object.keys(icu.placeholders).forEach((key) => this.visit(icu.placeholders[key]));
30209
+ }
30210
+ visitDeferredBlock(deferred) {
30211
+ deferred.visitAll(this);
30212
+ }
30213
+ visitDeferredTrigger(trigger) {
30214
+ if (trigger instanceof BoundDeferredTrigger) {
30215
+ this.visit(trigger.value);
30216
+ }
30217
+ }
30218
+ visitDeferredBlockPlaceholder(block) {
30219
+ this.visitAllTemplateNodes(block.children);
30220
+ }
30221
+ visitDeferredBlockError(block) {
30222
+ this.visitAllTemplateNodes(block.children);
30223
+ }
30224
+ visitDeferredBlockLoading(block) {
30225
+ this.visitAllTemplateNodes(block.children);
30226
+ }
30227
+ visitSwitchBlock(block) {
30228
+ this.visit(block.expression);
30229
+ this.visitAllTemplateNodes(block.cases);
30230
+ }
30231
+ visitSwitchBlockCase(block) {
30232
+ block.expression && this.visit(block.expression);
30233
+ this.visitAllTemplateNodes(block.children);
30234
+ }
30235
+ visitForLoopBlock(block) {
30236
+ block.item.visit(this);
30237
+ this.visitAllTemplateNodes(block.contextVariables);
30238
+ this.visit(block.expression);
30239
+ this.visitAllTemplateNodes(block.children);
30240
+ block.empty?.visit(this);
30241
+ }
30242
+ visitForLoopBlockEmpty(block) {
30243
+ this.visitAllTemplateNodes(block.children);
30244
+ }
30245
+ visitIfBlock(block) {
30246
+ this.visitAllTemplateNodes(block.branches);
30247
+ }
30248
+ visitIfBlockBranch(block) {
30249
+ block.expression && this.visit(block.expression);
30250
+ block.expressionAlias?.visit(this);
30251
+ this.visitAllTemplateNodes(block.children);
30252
+ }
30253
+ visitLetDeclaration(decl) {
30254
+ this.visit(decl.value);
30255
+ }
30256
+ visitComponent(component) {
30257
+ this.visitAllTemplateNodes(component.attributes);
30258
+ this.visitAllTemplateNodes(component.inputs);
30259
+ this.visitAllTemplateNodes(component.outputs);
30260
+ this.visitAllTemplateNodes(component.directives);
30261
+ this.visitAllTemplateNodes(component.references);
30262
+ this.visitAllTemplateNodes(component.children);
30263
+ }
30264
+ visitDirective(directive) {
30265
+ this.visitAllTemplateNodes(directive.attributes);
30266
+ this.visitAllTemplateNodes(directive.inputs);
30267
+ this.visitAllTemplateNodes(directive.outputs);
30268
+ this.visitAllTemplateNodes(directive.references);
30269
+ }
30270
+ visitVariable(variable) { }
30271
+ visitReference(reference) { }
30272
+ visitTextAttribute(attribute) { }
30273
+ visitText(text) { }
30274
+ visitUnknownBlock(block) { }
30275
+ visitAllTemplateNodes(nodes) {
30276
+ for (const node of nodes) {
30277
+ this.visit(node);
30278
+ }
30279
+ }
30280
+ }
30281
+
30282
+ /*!
30283
+ * @license
30284
+ * Copyright Google LLC All Rights Reserved.
30285
+ *
30286
+ * Use of this source code is governed by an MIT-style license that can be
30287
+ * found in the LICENSE file at https://angular.dev/license
30288
+ */
30289
+ const ANIMATE_LEAVE$1 = `animate.leave`;
30290
+ /**
30291
+ * Analyzes a component's template to determine if it's using animate.enter
30292
+ * or animate.leave syntax.
30293
+ */
30294
+ function analyzeTemplateForAnimations(template) {
30295
+ const analyzer = new AnimationsAnalyzer();
30296
+ visitAll$1(analyzer, template);
30297
+ // The template is considered selectorless only if there
30298
+ // are direct references to directives or pipes.
30299
+ return analyzer.hasAnimations;
30300
+ }
30301
+ /**
30302
+ * Visitor that traverses all the template nodes and
30303
+ * expressions to look for selectorless references.
30304
+ */
30305
+ class AnimationsAnalyzer extends CombinedRecursiveAstVisitor {
30306
+ hasAnimations = false;
30307
+ visitElement(element) {
30308
+ // check for regular strings
30309
+ for (const attr of element.attributes) {
30310
+ if (attr.name === ANIMATE_LEAVE$1) {
30311
+ this.hasAnimations = true;
30312
+ }
30313
+ }
30314
+ // check for attribute bindings
30315
+ for (const input of element.inputs) {
30316
+ if (input.name === ANIMATE_LEAVE$1) {
30317
+ this.hasAnimations = true;
30318
+ }
30319
+ }
30320
+ // check for event bindings
30321
+ for (const output of element.outputs) {
30322
+ if (output.name === ANIMATE_LEAVE$1) {
30323
+ this.hasAnimations = true;
30324
+ }
30325
+ }
30326
+ super.visitElement(element);
30327
+ }
30328
+ }
30329
+
29725
30330
  const COMPONENT_VARIABLE = '%COMP%';
29726
30331
  const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
29727
30332
  const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
30333
+ const ANIMATE_LEAVE = `animate.leave`;
29728
30334
  function baseDirectiveFields(meta, constantPool, bindingParser) {
29729
30335
  const definitionMap = new DefinitionMap();
29730
30336
  const selectors = parseSelectorToR3Selector(meta.selector);
@@ -29758,6 +30364,11 @@ function baseDirectiveFields(meta, constantPool, bindingParser) {
29758
30364
  }
29759
30365
  return definitionMap;
29760
30366
  }
30367
+ function hasAnimationHostBinding(meta) {
30368
+ return (meta.host.attributes[ANIMATE_LEAVE] !== undefined ||
30369
+ meta.host.properties[ANIMATE_LEAVE] !== undefined ||
30370
+ meta.host.listeners[ANIMATE_LEAVE] !== undefined);
30371
+ }
29761
30372
  /**
29762
30373
  * Add features to the definition map.
29763
30374
  */
@@ -29792,6 +30403,12 @@ function addFeatures(definitionMap, meta) {
29792
30403
  const externalStyleNodes = meta.externalStyles.map((externalStyle) => literal(externalStyle));
29793
30404
  features.push(importExpr(Identifiers.ExternalStylesFeature).callFn([literalArr(externalStyleNodes)]));
29794
30405
  }
30406
+ const template = meta.template;
30407
+ if (hasAnimationHostBinding(meta) || (template && template.nodes.length > 0)) {
30408
+ if (hasAnimationHostBinding(meta) || analyzeTemplateForAnimations(template.nodes)) {
30409
+ features.push(importExpr(Identifiers.AnimationsFeature).callFn([]));
30410
+ }
30411
+ }
29795
30412
  if (features.length) {
29796
30413
  definitionMap.set('features', literalArr(features));
29797
30414
  }
@@ -30251,132 +30868,6 @@ function compileDeferResolverFunction(meta) {
30251
30868
  return arrowFn([], literalArr(depExpressions));
30252
30869
  }
30253
30870
 
30254
- /*!
30255
- * @license
30256
- * Copyright Google LLC All Rights Reserved.
30257
- *
30258
- * Use of this source code is governed by an MIT-style license that can be
30259
- * found in the LICENSE file at https://angular.dev/license
30260
- */
30261
- /**
30262
- * Visitor that traverses all template and expression AST nodes in a template.
30263
- * Useful for cases where every single node needs to be visited.
30264
- */
30265
- class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
30266
- visit(node) {
30267
- if (node instanceof ASTWithSource) {
30268
- this.visit(node.ast);
30269
- }
30270
- else {
30271
- node.visit(this);
30272
- }
30273
- }
30274
- visitElement(element) {
30275
- this.visitAllTemplateNodes(element.attributes);
30276
- this.visitAllTemplateNodes(element.inputs);
30277
- this.visitAllTemplateNodes(element.outputs);
30278
- this.visitAllTemplateNodes(element.directives);
30279
- this.visitAllTemplateNodes(element.references);
30280
- this.visitAllTemplateNodes(element.children);
30281
- }
30282
- visitTemplate(template) {
30283
- this.visitAllTemplateNodes(template.attributes);
30284
- this.visitAllTemplateNodes(template.inputs);
30285
- this.visitAllTemplateNodes(template.outputs);
30286
- this.visitAllTemplateNodes(template.directives);
30287
- this.visitAllTemplateNodes(template.templateAttrs);
30288
- this.visitAllTemplateNodes(template.variables);
30289
- this.visitAllTemplateNodes(template.references);
30290
- this.visitAllTemplateNodes(template.children);
30291
- }
30292
- visitContent(content) {
30293
- this.visitAllTemplateNodes(content.children);
30294
- }
30295
- visitBoundAttribute(attribute) {
30296
- this.visit(attribute.value);
30297
- }
30298
- visitBoundEvent(attribute) {
30299
- this.visit(attribute.handler);
30300
- }
30301
- visitBoundText(text) {
30302
- this.visit(text.value);
30303
- }
30304
- visitIcu(icu) {
30305
- Object.keys(icu.vars).forEach((key) => this.visit(icu.vars[key]));
30306
- Object.keys(icu.placeholders).forEach((key) => this.visit(icu.placeholders[key]));
30307
- }
30308
- visitDeferredBlock(deferred) {
30309
- deferred.visitAll(this);
30310
- }
30311
- visitDeferredTrigger(trigger) {
30312
- if (trigger instanceof BoundDeferredTrigger) {
30313
- this.visit(trigger.value);
30314
- }
30315
- }
30316
- visitDeferredBlockPlaceholder(block) {
30317
- this.visitAllTemplateNodes(block.children);
30318
- }
30319
- visitDeferredBlockError(block) {
30320
- this.visitAllTemplateNodes(block.children);
30321
- }
30322
- visitDeferredBlockLoading(block) {
30323
- this.visitAllTemplateNodes(block.children);
30324
- }
30325
- visitSwitchBlock(block) {
30326
- this.visit(block.expression);
30327
- this.visitAllTemplateNodes(block.cases);
30328
- }
30329
- visitSwitchBlockCase(block) {
30330
- block.expression && this.visit(block.expression);
30331
- this.visitAllTemplateNodes(block.children);
30332
- }
30333
- visitForLoopBlock(block) {
30334
- block.item.visit(this);
30335
- this.visitAllTemplateNodes(block.contextVariables);
30336
- this.visit(block.expression);
30337
- this.visitAllTemplateNodes(block.children);
30338
- block.empty?.visit(this);
30339
- }
30340
- visitForLoopBlockEmpty(block) {
30341
- this.visitAllTemplateNodes(block.children);
30342
- }
30343
- visitIfBlock(block) {
30344
- this.visitAllTemplateNodes(block.branches);
30345
- }
30346
- visitIfBlockBranch(block) {
30347
- block.expression && this.visit(block.expression);
30348
- block.expressionAlias?.visit(this);
30349
- this.visitAllTemplateNodes(block.children);
30350
- }
30351
- visitLetDeclaration(decl) {
30352
- this.visit(decl.value);
30353
- }
30354
- visitComponent(component) {
30355
- this.visitAllTemplateNodes(component.attributes);
30356
- this.visitAllTemplateNodes(component.inputs);
30357
- this.visitAllTemplateNodes(component.outputs);
30358
- this.visitAllTemplateNodes(component.directives);
30359
- this.visitAllTemplateNodes(component.references);
30360
- this.visitAllTemplateNodes(component.children);
30361
- }
30362
- visitDirective(directive) {
30363
- this.visitAllTemplateNodes(directive.attributes);
30364
- this.visitAllTemplateNodes(directive.inputs);
30365
- this.visitAllTemplateNodes(directive.outputs);
30366
- this.visitAllTemplateNodes(directive.references);
30367
- }
30368
- visitVariable(variable) { }
30369
- visitReference(reference) { }
30370
- visitTextAttribute(attribute) { }
30371
- visitText(text) { }
30372
- visitUnknownBlock(block) { }
30373
- visitAllTemplateNodes(nodes) {
30374
- for (const node of nodes) {
30375
- this.visit(node);
30376
- }
30377
- }
30378
- }
30379
-
30380
30871
  /**
30381
30872
  * Computes a difference between full list (first argument) and
30382
30873
  * list of items that should be excluded from the full list (second
@@ -31699,7 +32190,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
31699
32190
  declarations.push(...decl.directives.map((dir) => convertDirectiveDeclarationToMetadata(dir)));
31700
32191
  decl.pipes && declarations.push(...convertPipeMapToMetadata(decl.pipes));
31701
32192
  }
31702
- const hasDirectiveDependencies = declarations.every(({ kind }) => kind === R3TemplateDependencyKind.Directive || kind === R3TemplateDependencyKind.NgModule);
32193
+ const hasDirectiveDependencies = declarations.some(({ kind }) => kind === R3TemplateDependencyKind.Directive || kind === R3TemplateDependencyKind.NgModule);
31703
32194
  return {
31704
32195
  ...convertDeclareDirectiveFacadeToMetadata(decl, typeSourceSpan),
31705
32196
  template,
@@ -33757,7 +34248,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
33757
34248
  function compileDeclareClassMetadata(metadata) {
33758
34249
  const definitionMap = new DefinitionMap();
33759
34250
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
33760
- definitionMap.set('version', literal('20.2.0-next.1'));
34251
+ definitionMap.set('version', literal('20.2.0-next.2'));
33761
34252
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33762
34253
  definitionMap.set('type', metadata.type);
33763
34254
  definitionMap.set('decorators', metadata.decorators);
@@ -33775,7 +34266,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
33775
34266
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
33776
34267
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
33777
34268
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
33778
- definitionMap.set('version', literal('20.2.0-next.1'));
34269
+ definitionMap.set('version', literal('20.2.0-next.2'));
33779
34270
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33780
34271
  definitionMap.set('type', metadata.type);
33781
34272
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -33870,7 +34361,7 @@ function createDirectiveDefinitionMap(meta) {
33870
34361
  const definitionMap = new DefinitionMap();
33871
34362
  const minVersion = getMinimumVersionForPartialOutput(meta);
33872
34363
  definitionMap.set('minVersion', literal(minVersion));
33873
- definitionMap.set('version', literal('20.2.0-next.1'));
34364
+ definitionMap.set('version', literal('20.2.0-next.2'));
33874
34365
  // e.g. `type: MyDirective`
33875
34366
  definitionMap.set('type', meta.type.value);
33876
34367
  if (meta.isStandalone !== undefined) {
@@ -34286,7 +34777,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
34286
34777
  function compileDeclareFactoryFunction(meta) {
34287
34778
  const definitionMap = new DefinitionMap();
34288
34779
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
34289
- definitionMap.set('version', literal('20.2.0-next.1'));
34780
+ definitionMap.set('version', literal('20.2.0-next.2'));
34290
34781
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34291
34782
  definitionMap.set('type', meta.type.value);
34292
34783
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -34321,7 +34812,7 @@ function compileDeclareInjectableFromMetadata(meta) {
34321
34812
  function createInjectableDefinitionMap(meta) {
34322
34813
  const definitionMap = new DefinitionMap();
34323
34814
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
34324
- definitionMap.set('version', literal('20.2.0-next.1'));
34815
+ definitionMap.set('version', literal('20.2.0-next.2'));
34325
34816
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34326
34817
  definitionMap.set('type', meta.type.value);
34327
34818
  // Only generate providedIn property if it has a non-null value
@@ -34372,7 +34863,7 @@ function compileDeclareInjectorFromMetadata(meta) {
34372
34863
  function createInjectorDefinitionMap(meta) {
34373
34864
  const definitionMap = new DefinitionMap();
34374
34865
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
34375
- definitionMap.set('version', literal('20.2.0-next.1'));
34866
+ definitionMap.set('version', literal('20.2.0-next.2'));
34376
34867
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34377
34868
  definitionMap.set('type', meta.type.value);
34378
34869
  definitionMap.set('providers', meta.providers);
@@ -34405,7 +34896,7 @@ function createNgModuleDefinitionMap(meta) {
34405
34896
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
34406
34897
  }
34407
34898
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
34408
- definitionMap.set('version', literal('20.2.0-next.1'));
34899
+ definitionMap.set('version', literal('20.2.0-next.2'));
34409
34900
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34410
34901
  definitionMap.set('type', meta.type.value);
34411
34902
  // We only generate the keys in the metadata if the arrays contain values.
@@ -34456,7 +34947,7 @@ function compileDeclarePipeFromMetadata(meta) {
34456
34947
  function createPipeDefinitionMap(meta) {
34457
34948
  const definitionMap = new DefinitionMap();
34458
34949
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
34459
- definitionMap.set('version', literal('20.2.0-next.1'));
34950
+ definitionMap.set('version', literal('20.2.0-next.2'));
34460
34951
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34461
34952
  // e.g. `type: MyPipe`
34462
34953
  definitionMap.set('type', meta.type.value);
@@ -34612,7 +35103,7 @@ function compileHmrUpdateCallback(definitions, constantStatements, meta) {
34612
35103
  * @description
34613
35104
  * Entry point for all public APIs of the compiler package.
34614
35105
  */
34615
- const VERSION = new Version('20.2.0-next.1');
35106
+ const VERSION = new Version('20.2.0-next.2');
34616
35107
 
34617
35108
  //////////////////////////////////////
34618
35109
  // THIS FILE HAS GLOBAL SIDE EFFECT //