@angular/compiler 21.0.0-next.7 → 21.0.0-next.9

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 v21.0.0-next.7
2
+ * @license Angular v21.0.0-next.9
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -3026,6 +3026,16 @@ class Identifiers {
3026
3026
  name: 'ɵɵvalidateIframeAttribute',
3027
3027
  moduleName: CORE,
3028
3028
  };
3029
+ // Decorators
3030
+ static inputDecorator = { name: 'Input', moduleName: CORE };
3031
+ static outputDecorator = { name: 'Output', moduleName: CORE };
3032
+ static viewChildDecorator = { name: 'ViewChild', moduleName: CORE };
3033
+ static viewChildrenDecorator = { name: 'ViewChildren', moduleName: CORE };
3034
+ static contentChildDecorator = { name: 'ContentChild', moduleName: CORE };
3035
+ static contentChildrenDecorator = {
3036
+ name: 'ContentChildren',
3037
+ moduleName: CORE,
3038
+ };
3029
3039
  // type-checking
3030
3040
  static InputSignalBrandWriteType = { name: 'ɵINPUT_SIGNAL_BRAND_WRITE_TYPE', moduleName: CORE };
3031
3041
  static UnwrapDirectiveSignalInputs = { name: 'ɵUnwrapDirectiveSignalInputs', moduleName: CORE };
@@ -4959,9 +4969,11 @@ class InteractionDeferredTrigger extends DeferredTrigger {
4959
4969
  }
4960
4970
  class ViewportDeferredTrigger extends DeferredTrigger {
4961
4971
  reference;
4962
- constructor(reference, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan) {
4972
+ options;
4973
+ constructor(reference, options, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan) {
4963
4974
  super(nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
4964
4975
  this.reference = reference;
4976
+ this.options = options;
4965
4977
  }
4966
4978
  }
4967
4979
  class BlockNode {
@@ -8786,14 +8798,14 @@ var OpKind;
8786
8798
  */
8787
8799
  OpKind[OpKind["AnimationListener"] = 56] = "AnimationListener";
8788
8800
  /**
8789
- * An operation to bind an expression to a `control` property of an element.
8801
+ * An operation to bind an expression to a `field` property of an element.
8790
8802
  */
8791
8803
  OpKind[OpKind["Control"] = 57] = "Control";
8792
8804
  /**
8793
8805
  * An operation to set up a corresponding {@link Control} operation.
8794
8806
  *
8795
8807
  * This is responsible for setting up event listeners on a native or custom form control when
8796
- * bound to a specialized control directive.
8808
+ * bound to a specialized field directive.
8797
8809
  */
8798
8810
  OpKind[OpKind["ControlCreate"] = 58] = "ControlCreate";
8799
8811
  })(OpKind || (OpKind = {}));
@@ -11779,7 +11791,7 @@ function extractAttributes(job) {
11779
11791
  case OpKind.Control:
11780
11792
  OpList.insertBefore(
11781
11793
  // Deliberately null i18nMessage value
11782
- createExtractedAttributeOp(op.target, BindingKind.Property, null, 'control',
11794
+ createExtractedAttributeOp(op.target, BindingKind.Property, null, 'field',
11783
11795
  /* expression */ null,
11784
11796
  /* i18nContext */ null,
11785
11797
  /* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
@@ -11943,7 +11955,7 @@ function specializeBindings(job) {
11943
11955
  else if (job.kind === CompilationJobKind.Host) {
11944
11956
  OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind, op.i18nContext, op.securityContext, op.sourceSpan));
11945
11957
  }
11946
- else if (op.name === 'control') {
11958
+ else if (op.name === 'field') {
11947
11959
  OpList.replace(op, createControlOp(op));
11948
11960
  }
11949
11961
  else {
@@ -16522,7 +16534,7 @@ class _Tokenizer {
16522
16534
  this._cursor.advance();
16523
16535
  try {
16524
16536
  const charCode = parseInt(strNum, isHex ? 16 : 10);
16525
- this._endToken([String.fromCharCode(charCode), this._cursor.getChars(start)]);
16537
+ this._endToken([String.fromCodePoint(charCode), this._cursor.getChars(start)]);
16526
16538
  }
16527
16539
  catch {
16528
16540
  throw this._createError(_unknownEntityErrorMsg(this._cursor.getChars(start)), this._cursor.getSpan());
@@ -23829,7 +23841,7 @@ function deferOn(trigger, args, modifier, sourceSpan) {
23829
23841
  if (instructionToCall === undefined) {
23830
23842
  throw new Error(`Unable to determine instruction for trigger ${trigger}`);
23831
23843
  }
23832
- return call(instructionToCall, args.map((a) => literal(a)), sourceSpan);
23844
+ return call(instructionToCall, args, sourceSpan);
23833
23845
  }
23834
23846
  function projectionDef(def) {
23835
23847
  return call(Identifiers.projectionDef, def ? [def] : [], null);
@@ -24420,11 +24432,30 @@ function reifyCreateOperations(unit, ops) {
24420
24432
  case DeferTriggerKind.Immediate:
24421
24433
  break;
24422
24434
  case DeferTriggerKind.Timer:
24423
- args = [op.trigger.delay];
24435
+ args = [literal(op.trigger.delay)];
24436
+ break;
24437
+ case DeferTriggerKind.Viewport:
24438
+ // `hydrate` triggers don't support targets.
24439
+ if (op.modifier === "hydrate" /* ir.DeferOpModifierKind.HYDRATE */) {
24440
+ args = op.trigger.options ? [op.trigger.options] : [];
24441
+ }
24442
+ else {
24443
+ // The slots not being defined at this point is invalid, however we
24444
+ // catch it during type checking. Pass in null in such cases.
24445
+ args = [literal(op.trigger.targetSlot?.slot ?? null)];
24446
+ if (op.trigger.targetSlotViewSteps !== 0) {
24447
+ args.push(literal(op.trigger.targetSlotViewSteps));
24448
+ }
24449
+ else if (op.trigger.options) {
24450
+ args.push(literal(null));
24451
+ }
24452
+ if (op.trigger.options) {
24453
+ args.push(op.trigger.options);
24454
+ }
24455
+ }
24424
24456
  break;
24425
24457
  case DeferTriggerKind.Interaction:
24426
24458
  case DeferTriggerKind.Hover:
24427
- case DeferTriggerKind.Viewport:
24428
24459
  // `hydrate` triggers don't support targets.
24429
24460
  if (op.modifier === "hydrate" /* ir.DeferOpModifierKind.HYDRATE */) {
24430
24461
  args = [];
@@ -24432,9 +24463,9 @@ function reifyCreateOperations(unit, ops) {
24432
24463
  else {
24433
24464
  // The slots not being defined at this point is invalid, however we
24434
24465
  // catch it during type checking. Pass in null in such cases.
24435
- args = [op.trigger.targetSlot?.slot ?? null];
24466
+ args = [literal(op.trigger.targetSlot?.slot ?? null)];
24436
24467
  if (op.trigger.targetSlotViewSteps !== 0) {
24437
- args.push(op.trigger.targetSlotViewSteps);
24468
+ args.push(literal(op.trigger.targetSlotViewSteps));
24438
24469
  }
24439
24470
  }
24440
24471
  break;
@@ -27310,6 +27341,9 @@ function ingestDeferTriggers(modifier, triggers, onOps, whenOps, unit, deferXref
27310
27341
  targetSlot: null,
27311
27342
  targetView: null,
27312
27343
  targetSlotViewSteps: null,
27344
+ options: triggers.viewport.options
27345
+ ? convertAst(triggers.viewport.options, unit.job, triggers.viewport.sourceSpan)
27346
+ : null,
27313
27347
  }, modifier, triggers.viewport.sourceSpan);
27314
27348
  onOps.push(deferOnOp);
27315
27349
  }
@@ -27640,9 +27674,9 @@ function ingestElementBindings(unit, op, element) {
27640
27674
  }
27641
27675
  // All dynamic bindings (both attribute and property bindings).
27642
27676
  bindings.push(createBindingOp(op.xref, BINDING_KINDS.get(input.type), input.name, convertAstWithInterpolation(unit.job, astOf(input.value), input.i18n), input.unit, input.securityContext, false, false, null, asMessage(input.i18n) ?? null, input.sourceSpan));
27643
- // If the input name is 'control', this could be a form control binding which requires a
27677
+ // If the input name is 'field', this could be a form control binding which requires a
27644
27678
  // `ControlCreateOp` to properly initialize.
27645
- if (input.type === BindingType.Property && input.name === 'control') {
27679
+ if (input.type === BindingType.Property && input.name === 'field') {
27646
27680
  unit.create.push(createControlCreateOp(input.sourceSpan));
27647
27681
  }
27648
27682
  }
@@ -28827,6 +28861,7 @@ function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
28827
28861
  // main `for` body, use `mainSourceSpan`.
28828
28862
  const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
28829
28863
  const sourceSpan = new ParseSourceSpan(ast.sourceSpan.start, endSpan?.end ?? ast.sourceSpan.end);
28864
+ validateTrackByExpression(params.trackBy.expression, params.trackBy.keywordSpan, errors);
28830
28865
  node = new ForLoopBlock(params.itemName, params.expression, params.trackBy.expression, params.trackBy.keywordSpan, params.context, visitAll(visitor, ast.children, ast.children), empty, sourceSpan, ast.sourceSpan, ast.startSourceSpan, endSpan, ast.nameSpan, ast.i18n);
28831
28866
  }
28832
28867
  }
@@ -28926,6 +28961,13 @@ function parseForLoopParameters(block, errors, bindingParser) {
28926
28961
  }
28927
28962
  return result;
28928
28963
  }
28964
+ function validateTrackByExpression(expression, parseSourceSpan, errors) {
28965
+ const visitor = new PipeVisitor();
28966
+ expression.ast.visit(visitor);
28967
+ if (visitor.hasPipe) {
28968
+ errors.push(new ParseError(parseSourceSpan, 'Cannot use pipes in track expressions'));
28969
+ }
28970
+ }
28929
28971
  /** Parses the `let` parameter of a `for` loop block. */
28930
28972
  function parseLetParameter(sourceSpan, expression, span, loopItemName, context, errors) {
28931
28973
  const parts = expression.split(',');
@@ -29136,6 +29178,12 @@ function stripOptionalParentheses(param, errors) {
29136
29178
  }
29137
29179
  return expression.slice(start, end);
29138
29180
  }
29181
+ class PipeVisitor extends RecursiveAstVisitor {
29182
+ hasPipe = false;
29183
+ visitPipe() {
29184
+ this.hasPipe = true;
29185
+ }
29186
+ }
29139
29187
 
29140
29188
  /** Pattern for a timing value in a trigger. */
29141
29189
  const TIME_PATTERN = /^\d+\.?\d*(ms|s)?$/;
@@ -29191,7 +29239,7 @@ function parseWhenTrigger({ expression, sourceSpan }, bindingParser, triggers, e
29191
29239
  }
29192
29240
  }
29193
29241
  /** Parses an `on` trigger */
29194
- function parseOnTrigger({ expression, sourceSpan }, triggers, errors, placeholder) {
29242
+ function parseOnTrigger({ expression, sourceSpan }, bindingParser, triggers, errors, placeholder) {
29195
29243
  const onIndex = expression.indexOf('on');
29196
29244
  const onSourceSpan = new ParseSourceSpan(sourceSpan.start.moveBy(onIndex), sourceSpan.start.moveBy(onIndex + 'on'.length));
29197
29245
  const prefetchSpan = getPrefetchSpan(expression, sourceSpan);
@@ -29203,9 +29251,10 @@ function parseOnTrigger({ expression, sourceSpan }, triggers, errors, placeholde
29203
29251
  }
29204
29252
  else {
29205
29253
  const start = getTriggerParametersStart(expression, onIndex + 1);
29206
- const parser = new OnTriggerParser(expression, start, sourceSpan, triggers, errors, expression.startsWith('hydrate')
29254
+ const isHydrationTrigger = expression.startsWith('hydrate');
29255
+ const parser = new OnTriggerParser(expression, bindingParser, start, sourceSpan, triggers, errors, isHydrationTrigger
29207
29256
  ? validateHydrateReferenceBasedTrigger
29208
- : validatePlainReferenceBasedTrigger, placeholder, prefetchSpan, onSourceSpan, hydrateSpan);
29257
+ : validatePlainReferenceBasedTrigger, isHydrationTrigger, prefetchSpan, onSourceSpan, hydrateSpan);
29209
29258
  parser.parse();
29210
29259
  }
29211
29260
  }
@@ -29223,25 +29272,27 @@ function getHydrateSpan(expression, sourceSpan) {
29223
29272
  }
29224
29273
  class OnTriggerParser {
29225
29274
  expression;
29275
+ bindingParser;
29226
29276
  start;
29227
29277
  span;
29228
29278
  triggers;
29229
29279
  errors;
29230
29280
  validator;
29231
- placeholder;
29281
+ isHydrationTrigger;
29232
29282
  prefetchSpan;
29233
29283
  onSourceSpan;
29234
29284
  hydrateSpan;
29235
29285
  index = 0;
29236
29286
  tokens;
29237
- constructor(expression, start, span, triggers, errors, validator, placeholder, prefetchSpan, onSourceSpan, hydrateSpan) {
29287
+ constructor(expression, bindingParser, start, span, triggers, errors, validator, isHydrationTrigger, prefetchSpan, onSourceSpan, hydrateSpan) {
29238
29288
  this.expression = expression;
29289
+ this.bindingParser = bindingParser;
29239
29290
  this.start = start;
29240
29291
  this.span = span;
29241
29292
  this.triggers = triggers;
29242
29293
  this.errors = errors;
29243
29294
  this.validator = validator;
29244
- this.placeholder = placeholder;
29295
+ this.isHydrationTrigger = isHydrationTrigger;
29245
29296
  this.prefetchSpan = prefetchSpan;
29246
29297
  this.onSourceSpan = onSourceSpan;
29247
29298
  this.hydrateSpan = hydrateSpan;
@@ -29315,10 +29366,10 @@ class OnTriggerParser {
29315
29366
  this.trackTrigger('immediate', createImmediateTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan));
29316
29367
  break;
29317
29368
  case OnTriggerType.HOVER:
29318
- this.trackTrigger('hover', createHoverTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.placeholder, this.validator));
29369
+ this.trackTrigger('hover', createHoverTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29319
29370
  break;
29320
29371
  case OnTriggerType.VIEWPORT:
29321
- this.trackTrigger('viewport', createViewportTrigger(parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29372
+ this.trackTrigger('viewport', createViewportTrigger(this.start, this.isHydrationTrigger, this.bindingParser, parameters, nameSpan, sourceSpan, this.prefetchSpan, this.onSourceSpan, this.hydrateSpan, this.validator));
29322
29373
  break;
29323
29374
  default:
29324
29375
  throw new Error(`Unrecognized trigger type "${identifier}"`);
@@ -29336,15 +29387,15 @@ class OnTriggerParser {
29336
29387
  }
29337
29388
  this.advance();
29338
29389
  const commaDelimStack = [];
29339
- let current = '';
29390
+ let tokens = [];
29340
29391
  while (this.index < this.tokens.length) {
29341
29392
  const token = this.token();
29342
29393
  // Stop parsing if we've hit the end character and we're outside of a comma-delimited syntax.
29343
29394
  // Note that we don't need to account for strings here since the lexer already parsed them
29344
29395
  // into string tokens.
29345
29396
  if (token.isCharacter($RPAREN) && commaDelimStack.length === 0) {
29346
- if (current.length) {
29347
- parameters.push(current);
29397
+ if (tokens.length) {
29398
+ parameters.push({ expression: this.tokenRangeText(tokens), start: tokens[0].index });
29348
29399
  }
29349
29400
  break;
29350
29401
  }
@@ -29363,14 +29414,14 @@ class OnTriggerParser {
29363
29414
  }
29364
29415
  // If we hit a comma outside of a comma-delimited syntax, it means
29365
29416
  // that we're at the top level and we're starting a new parameter.
29366
- if (commaDelimStack.length === 0 && token.isCharacter($COMMA) && current.length > 0) {
29367
- parameters.push(current);
29368
- current = '';
29417
+ if (commaDelimStack.length === 0 && token.isCharacter($COMMA) && tokens.length > 0) {
29418
+ parameters.push({ expression: this.tokenRangeText(tokens), start: tokens[0].index });
29369
29419
  this.advance();
29420
+ tokens = [];
29370
29421
  continue;
29371
29422
  }
29372
29423
  // Otherwise treat the token as a plain text character in the current parameter.
29373
- current += this.tokenText();
29424
+ tokens.push(token);
29374
29425
  this.advance();
29375
29426
  }
29376
29427
  if (!this.token().isCharacter($RPAREN) || commaDelimStack.length > 0) {
@@ -29382,10 +29433,11 @@ class OnTriggerParser {
29382
29433
  }
29383
29434
  return parameters;
29384
29435
  }
29385
- tokenText() {
29386
- // Tokens have a toString already which we could use, but for string tokens it omits the quotes.
29387
- // Eventually we could expose this information on the token directly.
29388
- return this.expression.slice(this.start + this.token().index, this.start + this.token().end);
29436
+ tokenRangeText(tokens) {
29437
+ if (tokens.length === 0) {
29438
+ return '';
29439
+ }
29440
+ return this.expression.slice(this.start + tokens[0].index, this.start + tokens[tokens.length - 1].end);
29389
29441
  }
29390
29442
  trackTrigger(name, trigger) {
29391
29443
  trackTrigger(name, this.triggers, this.errors, trigger);
@@ -29418,7 +29470,7 @@ function createTimerTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSo
29418
29470
  if (parameters.length !== 1) {
29419
29471
  throw new Error(`"${OnTriggerType.TIMER}" trigger must have exactly one parameter`);
29420
29472
  }
29421
- const delay = parseDeferredTime(parameters[0]);
29473
+ const delay = parseDeferredTime(parameters[0].expression);
29422
29474
  if (delay === null) {
29423
29475
  throw new Error(`Could not parse time value of trigger "${OnTriggerType.TIMER}"`);
29424
29476
  }
@@ -29430,17 +29482,61 @@ function createImmediateTrigger(parameters, nameSpan, sourceSpan, prefetchSpan,
29430
29482
  }
29431
29483
  return new ImmediateDeferredTrigger(nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29432
29484
  }
29433
- function createHoverTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, placeholder, validator) {
29485
+ function createHoverTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29434
29486
  validator(OnTriggerType.HOVER, parameters);
29435
- return new HoverDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29487
+ return new HoverDeferredTrigger(parameters[0]?.expression ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29436
29488
  }
29437
29489
  function createInteractionTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29438
29490
  validator(OnTriggerType.INTERACTION, parameters);
29439
- return new InteractionDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29491
+ return new InteractionDeferredTrigger(parameters[0]?.expression ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29440
29492
  }
29441
- function createViewportTrigger(parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29493
+ function createViewportTrigger(start, isHydrationTrigger, bindingParser, parameters, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan, validator) {
29442
29494
  validator(OnTriggerType.VIEWPORT, parameters);
29443
- return new ViewportDeferredTrigger(parameters[0] ?? null, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29495
+ let reference;
29496
+ let options;
29497
+ if (parameters.length === 0) {
29498
+ reference = options = null;
29499
+ }
29500
+ else if (!parameters[0].expression.startsWith('{')) {
29501
+ reference = parameters[0].expression;
29502
+ options = null;
29503
+ }
29504
+ else {
29505
+ const parsed = bindingParser.parseBinding(parameters[0].expression, false, sourceSpan, sourceSpan.start.offset + start + parameters[0].start);
29506
+ if (!(parsed.ast instanceof LiteralMap)) {
29507
+ throw new Error('Options parameter of the "viewport" trigger must be an object literal');
29508
+ }
29509
+ else if (parsed.ast.keys.some((key) => key.key === 'root')) {
29510
+ throw new Error('The "root" option is not supported in the options parameter of the "viewport" trigger');
29511
+ }
29512
+ const triggerIndex = parsed.ast.keys.findIndex((key) => key.key === 'trigger');
29513
+ if (triggerIndex === -1) {
29514
+ reference = null;
29515
+ options = parsed.ast;
29516
+ }
29517
+ else {
29518
+ const value = parsed.ast.values[triggerIndex];
29519
+ const triggerFilter = (_, index) => index !== triggerIndex;
29520
+ if (!(value instanceof PropertyRead) ||
29521
+ !(value.receiver instanceof ImplicitReceiver) ||
29522
+ value.receiver instanceof ThisReceiver) {
29523
+ throw new Error(`"trigger" option of the "viewport" trigger must be an identifier`);
29524
+ }
29525
+ reference = value.name;
29526
+ options = new LiteralMap(parsed.ast.span, parsed.ast.sourceSpan, parsed.ast.keys.filter(triggerFilter), parsed.ast.values.filter(triggerFilter));
29527
+ }
29528
+ }
29529
+ if (isHydrationTrigger && reference !== null) {
29530
+ throw new Error(`"viewport" hydration trigger cannot have a "trigger"`);
29531
+ }
29532
+ else if (options) {
29533
+ const dynamicNode = DynamicAstValidator.findDynamicNode(options);
29534
+ if (dynamicNode !== null) {
29535
+ throw new Error(`Options of the "viewport" trigger must be an object ` +
29536
+ `literal containing only literal values, but "${dynamicNode.constructor.name}" was found`);
29537
+ }
29538
+ }
29539
+ return new ViewportDeferredTrigger(reference, options, nameSpan, sourceSpan, prefetchSpan, onSourceSpan, hydrateSpan);
29444
29540
  }
29445
29541
  /**
29446
29542
  * Checks whether the structure of a non-hydrate reference-based trigger is valid.
@@ -29458,6 +29554,12 @@ function validatePlainReferenceBasedTrigger(type, parameters) {
29458
29554
  * @param parameters Parameters of the trigger.
29459
29555
  */
29460
29556
  function validateHydrateReferenceBasedTrigger(type, parameters) {
29557
+ if (type === OnTriggerType.VIEWPORT) {
29558
+ if (parameters.length > 1) {
29559
+ throw new Error(`Hydration trigger "${type}" cannot have more than one parameter`);
29560
+ }
29561
+ return;
29562
+ }
29461
29563
  if (parameters.length > 0) {
29462
29564
  throw new Error(`Hydration trigger "${type}" cannot have parameters`);
29463
29565
  }
@@ -29487,6 +29589,25 @@ function parseDeferredTime(value) {
29487
29589
  const [time, units] = match;
29488
29590
  return parseFloat(time) * (units === 's' ? 1000 : 1);
29489
29591
  }
29592
+ class DynamicAstValidator extends RecursiveAstVisitor {
29593
+ dynamicNode = null;
29594
+ static findDynamicNode(ast) {
29595
+ const visitor = new DynamicAstValidator();
29596
+ visitor.visit(ast);
29597
+ return visitor.dynamicNode;
29598
+ }
29599
+ visit(ast) {
29600
+ if (!(ast instanceof ASTWithSource) &&
29601
+ !(ast instanceof LiteralPrimitive) &&
29602
+ !(ast instanceof LiteralArray) &&
29603
+ !(ast instanceof LiteralMap)) {
29604
+ this.dynamicNode = ast;
29605
+ }
29606
+ else {
29607
+ super.visit(ast);
29608
+ }
29609
+ }
29610
+ }
29490
29611
 
29491
29612
  /** Pattern to identify a `prefetch when` trigger. */
29492
29613
  const PREFETCH_WHEN_PATTERN = /^prefetch\s+when\s/;
@@ -29517,7 +29638,7 @@ function isConnectedDeferLoopBlock(name) {
29517
29638
  function createDeferredBlock(ast, connectedBlocks, visitor, bindingParser) {
29518
29639
  const errors = [];
29519
29640
  const { placeholder, loading, error } = parseConnectedBlocks(connectedBlocks, errors, visitor);
29520
- const { triggers, prefetchTriggers, hydrateTriggers } = parsePrimaryTriggers(ast, bindingParser, errors, placeholder);
29641
+ const { triggers, prefetchTriggers, hydrateTriggers } = parsePrimaryTriggers(ast, bindingParser, errors);
29521
29642
  // The `defer` block has a main span encompassing all of the connected branches as well.
29522
29643
  let lastEndSourceSpan = ast.endSourceSpan;
29523
29644
  let endOfLastSourceSpan = ast.sourceSpan.end;
@@ -29639,19 +29760,19 @@ function parsePrimaryTriggers(ast, bindingParser, errors, placeholder) {
29639
29760
  parseWhenTrigger(param, bindingParser, triggers, errors);
29640
29761
  }
29641
29762
  else if (ON_PARAMETER_PATTERN.test(param.expression)) {
29642
- parseOnTrigger(param, triggers, errors, placeholder);
29763
+ parseOnTrigger(param, bindingParser, triggers, errors);
29643
29764
  }
29644
29765
  else if (PREFETCH_WHEN_PATTERN.test(param.expression)) {
29645
29766
  parseWhenTrigger(param, bindingParser, prefetchTriggers, errors);
29646
29767
  }
29647
29768
  else if (PREFETCH_ON_PATTERN.test(param.expression)) {
29648
- parseOnTrigger(param, prefetchTriggers, errors, placeholder);
29769
+ parseOnTrigger(param, bindingParser, prefetchTriggers, errors);
29649
29770
  }
29650
29771
  else if (HYDRATE_WHEN_PATTERN.test(param.expression)) {
29651
29772
  parseWhenTrigger(param, bindingParser, hydrateTriggers, errors);
29652
29773
  }
29653
29774
  else if (HYDRATE_ON_PATTERN.test(param.expression)) {
29654
- parseOnTrigger(param, hydrateTriggers, errors, placeholder);
29775
+ parseOnTrigger(param, bindingParser, hydrateTriggers, errors);
29655
29776
  }
29656
29777
  else if (HYDRATE_NEVER_PATTERN.test(param.expression)) {
29657
29778
  parseNeverTrigger(param, hydrateTriggers, errors);
@@ -31080,6 +31201,9 @@ class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
31080
31201
  if (trigger instanceof BoundDeferredTrigger) {
31081
31202
  this.visit(trigger.value);
31082
31203
  }
31204
+ else if (trigger instanceof ViewportDeferredTrigger && trigger.options !== null) {
31205
+ this.visit(trigger.options);
31206
+ }
31083
31207
  }
31084
31208
  visitDeferredBlockPlaceholder(block) {
31085
31209
  this.visitAllTemplateNodes(block.children);
@@ -34514,7 +34638,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
34514
34638
  function compileDeclareClassMetadata(metadata) {
34515
34639
  const definitionMap = new DefinitionMap();
34516
34640
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
34517
- definitionMap.set('version', literal('21.0.0-next.7'));
34641
+ definitionMap.set('version', literal('21.0.0-next.9'));
34518
34642
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34519
34643
  definitionMap.set('type', metadata.type);
34520
34644
  definitionMap.set('decorators', metadata.decorators);
@@ -34532,7 +34656,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
34532
34656
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
34533
34657
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
34534
34658
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
34535
- definitionMap.set('version', literal('21.0.0-next.7'));
34659
+ definitionMap.set('version', literal('21.0.0-next.9'));
34536
34660
  definitionMap.set('ngImport', importExpr(Identifiers.core));
34537
34661
  definitionMap.set('type', metadata.type);
34538
34662
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -34627,7 +34751,7 @@ function createDirectiveDefinitionMap(meta) {
34627
34751
  const definitionMap = new DefinitionMap();
34628
34752
  const minVersion = getMinimumVersionForPartialOutput(meta);
34629
34753
  definitionMap.set('minVersion', literal(minVersion));
34630
- definitionMap.set('version', literal('21.0.0-next.7'));
34754
+ definitionMap.set('version', literal('21.0.0-next.9'));
34631
34755
  // e.g. `type: MyDirective`
34632
34756
  definitionMap.set('type', meta.type.value);
34633
34757
  if (meta.isStandalone !== undefined) {
@@ -35040,7 +35164,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
35040
35164
  function compileDeclareFactoryFunction(meta) {
35041
35165
  const definitionMap = new DefinitionMap();
35042
35166
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
35043
- definitionMap.set('version', literal('21.0.0-next.7'));
35167
+ definitionMap.set('version', literal('21.0.0-next.9'));
35044
35168
  definitionMap.set('ngImport', importExpr(Identifiers.core));
35045
35169
  definitionMap.set('type', meta.type.value);
35046
35170
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -35075,7 +35199,7 @@ function compileDeclareInjectableFromMetadata(meta) {
35075
35199
  function createInjectableDefinitionMap(meta) {
35076
35200
  const definitionMap = new DefinitionMap();
35077
35201
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
35078
- definitionMap.set('version', literal('21.0.0-next.7'));
35202
+ definitionMap.set('version', literal('21.0.0-next.9'));
35079
35203
  definitionMap.set('ngImport', importExpr(Identifiers.core));
35080
35204
  definitionMap.set('type', meta.type.value);
35081
35205
  // Only generate providedIn property if it has a non-null value
@@ -35126,7 +35250,7 @@ function compileDeclareInjectorFromMetadata(meta) {
35126
35250
  function createInjectorDefinitionMap(meta) {
35127
35251
  const definitionMap = new DefinitionMap();
35128
35252
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
35129
- definitionMap.set('version', literal('21.0.0-next.7'));
35253
+ definitionMap.set('version', literal('21.0.0-next.9'));
35130
35254
  definitionMap.set('ngImport', importExpr(Identifiers.core));
35131
35255
  definitionMap.set('type', meta.type.value);
35132
35256
  definitionMap.set('providers', meta.providers);
@@ -35159,7 +35283,7 @@ function createNgModuleDefinitionMap(meta) {
35159
35283
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
35160
35284
  }
35161
35285
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
35162
- definitionMap.set('version', literal('21.0.0-next.7'));
35286
+ definitionMap.set('version', literal('21.0.0-next.9'));
35163
35287
  definitionMap.set('ngImport', importExpr(Identifiers.core));
35164
35288
  definitionMap.set('type', meta.type.value);
35165
35289
  // We only generate the keys in the metadata if the arrays contain values.
@@ -35210,7 +35334,7 @@ function compileDeclarePipeFromMetadata(meta) {
35210
35334
  function createPipeDefinitionMap(meta) {
35211
35335
  const definitionMap = new DefinitionMap();
35212
35336
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
35213
- definitionMap.set('version', literal('21.0.0-next.7'));
35337
+ definitionMap.set('version', literal('21.0.0-next.9'));
35214
35338
  definitionMap.set('ngImport', importExpr(Identifiers.core));
35215
35339
  // e.g. `type: MyPipe`
35216
35340
  definitionMap.set('type', meta.type.value);
@@ -35366,7 +35490,7 @@ function compileHmrUpdateCallback(definitions, constantStatements, meta) {
35366
35490
  * @description
35367
35491
  * Entry point for all public APIs of the compiler package.
35368
35492
  */
35369
- const VERSION = new Version('21.0.0-next.7');
35493
+ const VERSION = new Version('21.0.0-next.9');
35370
35494
 
35371
35495
  //////////////////////////////////////
35372
35496
  // THIS FILE HAS GLOBAL SIDE EFFECT //