@angular/compiler 17.1.0-next.0 → 17.1.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.
Files changed (61) hide show
  1. package/esm2022/src/compiler.mjs +3 -3
  2. package/esm2022/src/expression_parser/parser.mjs +2 -2
  3. package/esm2022/src/i18n/digest.mjs +4 -1
  4. package/esm2022/src/i18n/extractor_merger.mjs +4 -2
  5. package/esm2022/src/i18n/i18n_ast.mjs +27 -1
  6. package/esm2022/src/i18n/i18n_html_parser.mjs +2 -2
  7. package/esm2022/src/i18n/i18n_parser.mjs +23 -6
  8. package/esm2022/src/i18n/message_bundle.mjs +7 -1
  9. package/esm2022/src/i18n/serializers/placeholder.mjs +29 -1
  10. package/esm2022/src/i18n/serializers/serializer.mjs +6 -1
  11. package/esm2022/src/i18n/serializers/xliff.mjs +7 -1
  12. package/esm2022/src/i18n/serializers/xliff2.mjs +19 -1
  13. package/esm2022/src/i18n/serializers/xmb.mjs +12 -1
  14. package/esm2022/src/i18n/translation_bundle.mjs +6 -1
  15. package/esm2022/src/jit_compiler_facade.mjs +2 -2
  16. package/esm2022/src/ml_parser/ast.mjs +4 -4
  17. package/esm2022/src/ml_parser/defaults.mjs +24 -0
  18. package/esm2022/src/ml_parser/lexer.mjs +2 -2
  19. package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
  20. package/esm2022/src/render3/partial/component.mjs +2 -2
  21. package/esm2022/src/render3/partial/directive.mjs +1 -1
  22. package/esm2022/src/render3/partial/factory.mjs +1 -1
  23. package/esm2022/src/render3/partial/injectable.mjs +1 -1
  24. package/esm2022/src/render3/partial/injector.mjs +1 -1
  25. package/esm2022/src/render3/partial/ng_module.mjs +1 -1
  26. package/esm2022/src/render3/partial/pipe.mjs +1 -1
  27. package/esm2022/src/render3/r3_ast.mjs +17 -9
  28. package/esm2022/src/render3/r3_control_flow.mjs +7 -7
  29. package/esm2022/src/render3/r3_deferred_blocks.mjs +5 -5
  30. package/esm2022/src/render3/view/api.mjs +1 -1
  31. package/esm2022/src/render3/view/compiler.mjs +6 -4
  32. package/esm2022/src/render3/view/i18n/context.mjs +13 -1
  33. package/esm2022/src/render3/view/i18n/get_msg_utils.mjs +4 -1
  34. package/esm2022/src/render3/view/i18n/icu_serializer.mjs +4 -1
  35. package/esm2022/src/render3/view/i18n/localize_utils.mjs +6 -1
  36. package/esm2022/src/render3/view/i18n/meta.mjs +5 -4
  37. package/esm2022/src/render3/view/t2_api.mjs +1 -1
  38. package/esm2022/src/render3/view/t2_binder.mjs +6 -7
  39. package/esm2022/src/render3/view/template.mjs +79 -52
  40. package/esm2022/src/render3/view/util.mjs +24 -2
  41. package/esm2022/src/template/pipeline/ir/src/enums.mjs +9 -1
  42. package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +3 -2
  43. package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +2 -1
  44. package/esm2022/src/template/pipeline/src/emit.mjs +1 -3
  45. package/esm2022/src/template/pipeline/src/instruction.mjs +3 -3
  46. package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +2 -7
  47. package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +20 -6
  48. package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +94 -23
  49. package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +3 -2
  50. package/esm2022/src/template/pipeline/src/phases/reify.mjs +2 -2
  51. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +70 -57
  52. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +4 -4
  53. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_icu_placeholders.mjs +16 -25
  54. package/esm2022/src/template_parser/binding_parser.mjs +1 -1
  55. package/esm2022/src/version.mjs +1 -1
  56. package/fesm2022/compiler.mjs +554 -303
  57. package/fesm2022/compiler.mjs.map +1 -1
  58. package/index.d.ts +56 -12
  59. package/package.json +2 -2
  60. package/esm2022/src/ml_parser/interpolation_config.mjs +0 -23
  61. package/esm2022/src/template/pipeline/src/phases/merge_i18n_contexts.mjs +0 -59
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v17.1.0-next.0
2
+ * @license Angular v17.1.0-next.2
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -539,6 +539,9 @@ class _SerializerVisitor {
539
539
  visitIcuPlaceholder(ph, context) {
540
540
  return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
541
541
  }
542
+ visitBlockPlaceholder(ph, context) {
543
+ return `<ph block name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
544
+ }
542
545
  }
543
546
  const serializerVisitor$1 = new _SerializerVisitor();
544
547
  function serializeNodes(nodes) {
@@ -3676,6 +3679,41 @@ function getInjectFn(target) {
3676
3679
  }
3677
3680
  }
3678
3681
 
3682
+ var TagContentType;
3683
+ (function (TagContentType) {
3684
+ TagContentType[TagContentType["RAW_TEXT"] = 0] = "RAW_TEXT";
3685
+ TagContentType[TagContentType["ESCAPABLE_RAW_TEXT"] = 1] = "ESCAPABLE_RAW_TEXT";
3686
+ TagContentType[TagContentType["PARSABLE_DATA"] = 2] = "PARSABLE_DATA";
3687
+ })(TagContentType || (TagContentType = {}));
3688
+ function splitNsName(elementName) {
3689
+ if (elementName[0] != ':') {
3690
+ return [null, elementName];
3691
+ }
3692
+ const colonIndex = elementName.indexOf(':', 1);
3693
+ if (colonIndex === -1) {
3694
+ throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
3695
+ }
3696
+ return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
3697
+ }
3698
+ // `<ng-container>` tags work the same regardless the namespace
3699
+ function isNgContainer(tagName) {
3700
+ return splitNsName(tagName)[1] === 'ng-container';
3701
+ }
3702
+ // `<ng-content>` tags work the same regardless the namespace
3703
+ function isNgContent(tagName) {
3704
+ return splitNsName(tagName)[1] === 'ng-content';
3705
+ }
3706
+ // `<ng-template>` tags work the same regardless the namespace
3707
+ function isNgTemplate(tagName) {
3708
+ return splitNsName(tagName)[1] === 'ng-template';
3709
+ }
3710
+ function getNsPrefix(fullName) {
3711
+ return fullName === null ? null : splitNsName(fullName)[0];
3712
+ }
3713
+ function mergeNsAndName(prefix, localName) {
3714
+ return prefix ? `:${prefix}:${localName}` : localName;
3715
+ }
3716
+
3679
3717
  /**
3680
3718
  * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
3681
3719
  * require the implementation of a visitor for Comments as they are only collected at
@@ -3847,43 +3885,47 @@ class BlockNode {
3847
3885
  }
3848
3886
  }
3849
3887
  class DeferredBlockPlaceholder extends BlockNode {
3850
- constructor(children, minimumTime, nameSpan, sourceSpan, startSourceSpan, endSourceSpan) {
3888
+ constructor(children, minimumTime, nameSpan, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3851
3889
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3852
3890
  this.children = children;
3853
3891
  this.minimumTime = minimumTime;
3892
+ this.i18n = i18n;
3854
3893
  }
3855
3894
  visit(visitor) {
3856
3895
  return visitor.visitDeferredBlockPlaceholder(this);
3857
3896
  }
3858
3897
  }
3859
3898
  class DeferredBlockLoading extends BlockNode {
3860
- constructor(children, afterTime, minimumTime, nameSpan, sourceSpan, startSourceSpan, endSourceSpan) {
3899
+ constructor(children, afterTime, minimumTime, nameSpan, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3861
3900
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3862
3901
  this.children = children;
3863
3902
  this.afterTime = afterTime;
3864
3903
  this.minimumTime = minimumTime;
3904
+ this.i18n = i18n;
3865
3905
  }
3866
3906
  visit(visitor) {
3867
3907
  return visitor.visitDeferredBlockLoading(this);
3868
3908
  }
3869
3909
  }
3870
3910
  class DeferredBlockError extends BlockNode {
3871
- constructor(children, nameSpan, sourceSpan, startSourceSpan, endSourceSpan) {
3911
+ constructor(children, nameSpan, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3872
3912
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3873
3913
  this.children = children;
3914
+ this.i18n = i18n;
3874
3915
  }
3875
3916
  visit(visitor) {
3876
3917
  return visitor.visitDeferredBlockError(this);
3877
3918
  }
3878
3919
  }
3879
3920
  class DeferredBlock extends BlockNode {
3880
- constructor(children, triggers, prefetchTriggers, placeholder, loading, error, nameSpan, sourceSpan, mainBlockSpan, startSourceSpan, endSourceSpan) {
3921
+ constructor(children, triggers, prefetchTriggers, placeholder, loading, error, nameSpan, sourceSpan, mainBlockSpan, startSourceSpan, endSourceSpan, i18n) {
3881
3922
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3882
3923
  this.children = children;
3883
3924
  this.placeholder = placeholder;
3884
3925
  this.loading = loading;
3885
3926
  this.error = error;
3886
3927
  this.mainBlockSpan = mainBlockSpan;
3928
+ this.i18n = i18n;
3887
3929
  this.triggers = triggers;
3888
3930
  this.prefetchTriggers = prefetchTriggers;
3889
3931
  // We cache the keys since we know that they won't change and we
@@ -3922,17 +3964,18 @@ class SwitchBlock extends BlockNode {
3922
3964
  }
3923
3965
  }
3924
3966
  class SwitchBlockCase extends BlockNode {
3925
- constructor(expression, children, sourceSpan, startSourceSpan, endSourceSpan, nameSpan) {
3967
+ constructor(expression, children, sourceSpan, startSourceSpan, endSourceSpan, nameSpan, i18n) {
3926
3968
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3927
3969
  this.expression = expression;
3928
3970
  this.children = children;
3971
+ this.i18n = i18n;
3929
3972
  }
3930
3973
  visit(visitor) {
3931
3974
  return visitor.visitSwitchBlockCase(this);
3932
3975
  }
3933
3976
  }
3934
3977
  class ForLoopBlock extends BlockNode {
3935
- constructor(item, expression, trackBy, trackKeywordSpan, contextVariables, children, empty, sourceSpan, mainBlockSpan, startSourceSpan, endSourceSpan, nameSpan) {
3978
+ constructor(item, expression, trackBy, trackKeywordSpan, contextVariables, children, empty, sourceSpan, mainBlockSpan, startSourceSpan, endSourceSpan, nameSpan, i18n) {
3936
3979
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3937
3980
  this.item = item;
3938
3981
  this.expression = expression;
@@ -3942,15 +3985,17 @@ class ForLoopBlock extends BlockNode {
3942
3985
  this.children = children;
3943
3986
  this.empty = empty;
3944
3987
  this.mainBlockSpan = mainBlockSpan;
3988
+ this.i18n = i18n;
3945
3989
  }
3946
3990
  visit(visitor) {
3947
3991
  return visitor.visitForLoopBlock(this);
3948
3992
  }
3949
3993
  }
3950
3994
  class ForLoopBlockEmpty extends BlockNode {
3951
- constructor(children, sourceSpan, startSourceSpan, endSourceSpan, nameSpan) {
3995
+ constructor(children, sourceSpan, startSourceSpan, endSourceSpan, nameSpan, i18n) {
3952
3996
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3953
3997
  this.children = children;
3998
+ this.i18n = i18n;
3954
3999
  }
3955
4000
  visit(visitor) {
3956
4001
  return visitor.visitForLoopBlockEmpty(this);
@@ -3966,11 +4011,12 @@ class IfBlock extends BlockNode {
3966
4011
  }
3967
4012
  }
3968
4013
  class IfBlockBranch extends BlockNode {
3969
- constructor(expression, children, expressionAlias, sourceSpan, startSourceSpan, endSourceSpan, nameSpan) {
4014
+ constructor(expression, children, expressionAlias, sourceSpan, startSourceSpan, endSourceSpan, nameSpan, i18n) {
3970
4015
  super(nameSpan, sourceSpan, startSourceSpan, endSourceSpan);
3971
4016
  this.expression = expression;
3972
4017
  this.children = children;
3973
4018
  this.expressionAlias = expressionAlias;
4019
+ this.i18n = i18n;
3974
4020
  }
3975
4021
  visit(visitor) {
3976
4022
  return visitor.visitIfBlockBranch(this);
@@ -4240,6 +4286,21 @@ class IcuPlaceholder {
4240
4286
  return visitor.visitIcuPlaceholder(this, context);
4241
4287
  }
4242
4288
  }
4289
+ class BlockPlaceholder {
4290
+ constructor(name, parameters, startName, closeName, children, sourceSpan, startSourceSpan, endSourceSpan) {
4291
+ this.name = name;
4292
+ this.parameters = parameters;
4293
+ this.startName = startName;
4294
+ this.closeName = closeName;
4295
+ this.children = children;
4296
+ this.sourceSpan = sourceSpan;
4297
+ this.startSourceSpan = startSourceSpan;
4298
+ this.endSourceSpan = endSourceSpan;
4299
+ }
4300
+ visit(visitor, context) {
4301
+ return visitor.visitBlockPlaceholder(this, context);
4302
+ }
4303
+ }
4243
4304
  // Clone the AST
4244
4305
  class CloneVisitor {
4245
4306
  visitText(text, context) {
@@ -4265,6 +4326,10 @@ class CloneVisitor {
4265
4326
  visitIcuPlaceholder(ph, context) {
4266
4327
  return new IcuPlaceholder(ph.value, ph.name, ph.sourceSpan);
4267
4328
  }
4329
+ visitBlockPlaceholder(ph, context) {
4330
+ const children = ph.children.map(n => n.visit(this, context));
4331
+ return new BlockPlaceholder(ph.name, ph.parameters, ph.startName, ph.closeName, children, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan);
4332
+ }
4268
4333
  }
4269
4334
  // Visit all the nodes recursively
4270
4335
  class RecurseVisitor {
@@ -4282,6 +4347,9 @@ class RecurseVisitor {
4282
4347
  }
4283
4348
  visitPlaceholder(ph, context) { }
4284
4349
  visitIcuPlaceholder(ph, context) { }
4350
+ visitBlockPlaceholder(ph, context) {
4351
+ ph.children.forEach(child => child.visit(this));
4352
+ }
4285
4353
  }
4286
4354
  /**
4287
4355
  * Serialize the message to the Localize backtick string format that would appear in compiled code.
@@ -4312,6 +4380,10 @@ class LocalizeMessageStringVisitor {
4312
4380
  visitIcuPlaceholder(ph) {
4313
4381
  return `{$${ph.name}}`;
4314
4382
  }
4383
+ visitBlockPlaceholder(ph) {
4384
+ const children = ph.children.map(child => child.visit(this)).join('');
4385
+ return `{$${ph.startName}}${children}{$${ph.closeName}}`;
4386
+ }
4315
4387
  }
4316
4388
 
4317
4389
  class Serializer {
@@ -4354,6 +4426,11 @@ class SimplePlaceholderMapper extends RecurseVisitor {
4354
4426
  visitPlaceholder(ph, context) {
4355
4427
  this.visitPlaceholderName(ph.name);
4356
4428
  }
4429
+ visitBlockPlaceholder(ph, context) {
4430
+ this.visitPlaceholderName(ph.startName);
4431
+ super.visitBlockPlaceholder(ph, context);
4432
+ this.visitPlaceholderName(ph.closeName);
4433
+ }
4357
4434
  visitIcuPlaceholder(ph, context) {
4358
4435
  this.visitPlaceholderName(ph.name);
4359
4436
  }
@@ -4566,6 +4643,17 @@ class _Visitor$1 {
4566
4643
  new Tag(_PLACEHOLDER_TAG$3, { name: ph.name }, [exTag, interpolationAsText])
4567
4644
  ];
4568
4645
  }
4646
+ visitBlockPlaceholder(ph, context) {
4647
+ const startAsText = new Text$1(`@${ph.name}`);
4648
+ const startEx = new Tag(_EXAMPLE_TAG, {}, [startAsText]);
4649
+ // TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
4650
+ const startTagPh = new Tag(_PLACEHOLDER_TAG$3, { name: ph.startName }, [startEx, startAsText]);
4651
+ const closeAsText = new Text$1(`}`);
4652
+ const closeEx = new Tag(_EXAMPLE_TAG, {}, [closeAsText]);
4653
+ // TC requires PH to have a non empty EX, and uses the text node to show the "original" value.
4654
+ const closeTagPh = new Tag(_PLACEHOLDER_TAG$3, { name: ph.closeName }, [closeEx, closeAsText]);
4655
+ return [startTagPh, ...this.serialize(ph.children), closeTagPh];
4656
+ }
4569
4657
  visitIcuPlaceholder(ph, context) {
4570
4658
  const icuExpression = ph.value.expression;
4571
4659
  const icuType = ph.value.type;
@@ -4966,6 +5054,26 @@ class DefinitionMap {
4966
5054
  return literalMap(this.values);
4967
5055
  }
4968
5056
  }
5057
+ /**
5058
+ * Creates a `CssSelector` from an AST node.
5059
+ */
5060
+ function createCssSelectorFromNode(node) {
5061
+ const elementName = node instanceof Element$1 ? node.name : 'ng-template';
5062
+ const attributes = getAttrsForDirectiveMatching(node);
5063
+ const cssSelector = new CssSelector();
5064
+ const elementNameNoNs = splitNsName(elementName)[1];
5065
+ cssSelector.setElement(elementNameNoNs);
5066
+ Object.getOwnPropertyNames(attributes).forEach((name) => {
5067
+ const nameNoNs = splitNsName(name)[1];
5068
+ const value = attributes[name];
5069
+ cssSelector.addAttribute(nameNoNs, value);
5070
+ if (name.toLowerCase() === 'class') {
5071
+ const classes = value.trim().split(/\s+/);
5072
+ classes.forEach(className => cssSelector.addClassName(className));
5073
+ }
5074
+ });
5075
+ return cssSelector;
5076
+ }
4969
5077
  /**
4970
5078
  * Extract a map of properties to values for a given element or template node, which can be used
4971
5079
  * by the directive matching machinery.
@@ -5211,6 +5319,7 @@ class InterpolationConfig {
5211
5319
  }
5212
5320
  }
5213
5321
  const DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}');
5322
+ const DEFAULT_CONTAINER_BLOCKS = new Set(['switch']);
5214
5323
 
5215
5324
  const $EOF = 0;
5216
5325
  const $BSPACE = 8;
@@ -9141,6 +9250,14 @@ var DerivedRepeaterVarIdentity;
9141
9250
  DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["Even"] = 2] = "Even";
9142
9251
  DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["Odd"] = 3] = "Odd";
9143
9252
  })(DerivedRepeaterVarIdentity || (DerivedRepeaterVarIdentity = {}));
9253
+ /**
9254
+ * Kinds of i18n contexts. They can be created because of root i18n blocks, or ICUs.
9255
+ */
9256
+ var I18nContextKind;
9257
+ (function (I18nContextKind) {
9258
+ I18nContextKind[I18nContextKind["RootI18n"] = 0] = "RootI18n";
9259
+ I18nContextKind[I18nContextKind["Icu"] = 1] = "Icu";
9260
+ })(I18nContextKind || (I18nContextKind = {}));
9144
9261
 
9145
9262
  /**
9146
9263
  * Marker symbol for `ConsumesSlotOpTrait`.
@@ -9414,6 +9531,7 @@ function createRepeaterOp(repeaterCreate, targetSlot, collection, sourceSpan) {
9414
9531
  collection,
9415
9532
  sourceSpan,
9416
9533
  ...NEW_OP,
9534
+ ...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
9417
9535
  };
9418
9536
  }
9419
9537
  function createDeferWhenOp(target, expr, prefetch, sourceSpan) {
@@ -10924,9 +11042,10 @@ function createIcuEndOp(xref) {
10924
11042
  ...NEW_OP,
10925
11043
  };
10926
11044
  }
10927
- function createI18nContextOp(xref, i18nBlock, message, sourceSpan) {
11045
+ function createI18nContextOp(contextKind, xref, i18nBlock, message, sourceSpan) {
10928
11046
  return {
10929
11047
  kind: OpKind.I18nContext,
11048
+ contextKind,
10930
11049
  xref,
10931
11050
  i18nBlock,
10932
11051
  message,
@@ -11212,7 +11331,6 @@ function needsApplication(i18nContexts, op) {
11212
11331
  */
11213
11332
  function assignI18nSlotDependencies(job) {
11214
11333
  const i18nLastSlotConsumers = new Map();
11215
- const i18nContexts = new Map();
11216
11334
  let lastSlotConsumer = null;
11217
11335
  let currentI18nOp = null;
11218
11336
  for (const unit of job.units) {
@@ -11229,16 +11347,12 @@ function assignI18nSlotDependencies(job) {
11229
11347
  i18nLastSlotConsumers.set(currentI18nOp.xref, lastSlotConsumer);
11230
11348
  currentI18nOp = null;
11231
11349
  break;
11232
- case OpKind.I18nContext:
11233
- i18nContexts.set(op.xref, op);
11234
- break;
11235
11350
  }
11236
11351
  }
11237
11352
  // Assign i18n expressions to target the last slot in its owning block.
11238
11353
  for (const op of unit.update) {
11239
11354
  if (op.kind === OpKind.I18nExpression) {
11240
- const i18nContext = i18nContexts.get(op.context);
11241
- op.target = i18nLastSlotConsumers.get(i18nContext.i18nBlock);
11355
+ op.target = i18nLastSlotConsumers.get(op.target);
11242
11356
  }
11243
11357
  }
11244
11358
  }
@@ -11569,41 +11683,6 @@ function generateConditionalExpressions(job) {
11569
11683
  }
11570
11684
  }
11571
11685
 
11572
- var TagContentType;
11573
- (function (TagContentType) {
11574
- TagContentType[TagContentType["RAW_TEXT"] = 0] = "RAW_TEXT";
11575
- TagContentType[TagContentType["ESCAPABLE_RAW_TEXT"] = 1] = "ESCAPABLE_RAW_TEXT";
11576
- TagContentType[TagContentType["PARSABLE_DATA"] = 2] = "PARSABLE_DATA";
11577
- })(TagContentType || (TagContentType = {}));
11578
- function splitNsName(elementName) {
11579
- if (elementName[0] != ':') {
11580
- return [null, elementName];
11581
- }
11582
- const colonIndex = elementName.indexOf(':', 1);
11583
- if (colonIndex === -1) {
11584
- throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
11585
- }
11586
- return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
11587
- }
11588
- // `<ng-container>` tags work the same regardless the namespace
11589
- function isNgContainer(tagName) {
11590
- return splitNsName(tagName)[1] === 'ng-container';
11591
- }
11592
- // `<ng-content>` tags work the same regardless the namespace
11593
- function isNgContent(tagName) {
11594
- return splitNsName(tagName)[1] === 'ng-content';
11595
- }
11596
- // `<ng-template>` tags work the same regardless the namespace
11597
- function isNgTemplate(tagName) {
11598
- return splitNsName(tagName)[1] === 'ng-template';
11599
- }
11600
- function getNsPrefix(fullName) {
11601
- return fullName === null ? null : splitNsName(fullName)[0];
11602
- }
11603
- function mergeNsAndName(prefix, localName) {
11604
- return prefix ? `:${prefix}:${localName}` : localName;
11605
- }
11606
-
11607
11686
  const BINARY_OPERATORS = new Map([
11608
11687
  ['&&', BinaryOperator.And],
11609
11688
  ['>', BinaryOperator.Bigger],
@@ -11847,17 +11926,22 @@ function createDeferDepsFns(job) {
11847
11926
  * message.)
11848
11927
  */
11849
11928
  function createI18nContexts(job) {
11929
+ const rootContexts = new Map();
11850
11930
  let currentI18nOp = null;
11851
11931
  let xref;
11852
11932
  for (const unit of job.units) {
11853
11933
  for (const op of unit.create) {
11854
11934
  switch (op.kind) {
11855
11935
  case OpKind.I18nStart:
11856
- // Each i18n block gets its own context.
11857
- xref = job.allocateXrefId();
11858
- unit.create.push(createI18nContextOp(xref, op.xref, op.message, null));
11859
- op.context = xref;
11860
11936
  currentI18nOp = op;
11937
+ // Each root i18n block gets its own context, child ones refer to the context for their
11938
+ // root block.
11939
+ if (op.xref === op.root) {
11940
+ xref = job.allocateXrefId();
11941
+ unit.create.push(createI18nContextOp(I18nContextKind.RootI18n, xref, op.xref, op.message, null));
11942
+ op.context = xref;
11943
+ rootContexts.set(op.xref, xref);
11944
+ }
11861
11945
  break;
11862
11946
  case OpKind.I18nEnd:
11863
11947
  currentI18nOp = null;
@@ -11871,7 +11955,7 @@ function createI18nContexts(job) {
11871
11955
  if (op.message.id !== currentI18nOp.message.id) {
11872
11956
  // There was an enclosing i18n block around this ICU somewhere.
11873
11957
  xref = job.allocateXrefId();
11874
- unit.create.push(createI18nContextOp(xref, currentI18nOp.xref, op.message, null));
11958
+ unit.create.push(createI18nContextOp(I18nContextKind.Icu, xref, currentI18nOp.xref, op.message, null));
11875
11959
  op.context = xref;
11876
11960
  }
11877
11961
  else {
@@ -11883,6 +11967,15 @@ function createI18nContexts(job) {
11883
11967
  }
11884
11968
  }
11885
11969
  }
11970
+ // Assign contexts to child i18n blocks, now that all root i18n blocks have their context
11971
+ // assigned.
11972
+ for (const unit of job.units) {
11973
+ for (const op of unit.create) {
11974
+ if (op.kind === OpKind.I18nStart && op.xref !== op.root) {
11975
+ op.context = rootContexts.get(op.root);
11976
+ }
11977
+ }
11978
+ }
11886
11979
  }
11887
11980
 
11888
11981
  /**
@@ -12265,11 +12358,9 @@ const LIST_DELIMITER = '|';
12265
12358
  * used in the final output.
12266
12359
  */
12267
12360
  function extractI18nMessages(job) {
12268
- // Save the i18n context ops for later use.
12361
+ // Save the i18n start and i18n context ops for later use.
12269
12362
  const i18nContexts = new Map();
12270
- // Record which contexts represent i18n blocks (any other contexts are assumed to have been
12271
- // created from ICUs).
12272
- const i18nBlockContexts = new Set();
12363
+ const i18nBlocks = new Map();
12273
12364
  for (const unit of job.units) {
12274
12365
  for (const op of unit.create) {
12275
12366
  switch (op.kind) {
@@ -12277,7 +12368,7 @@ function extractI18nMessages(job) {
12277
12368
  i18nContexts.set(op.xref, op);
12278
12369
  break;
12279
12370
  case OpKind.I18nStart:
12280
- i18nBlockContexts.add(op.context);
12371
+ i18nBlocks.set(op.xref, op);
12281
12372
  break;
12282
12373
  }
12283
12374
  }
@@ -12304,11 +12395,12 @@ function extractI18nMessages(job) {
12304
12395
  if (!op.context) {
12305
12396
  throw Error('ICU op should have its context set.');
12306
12397
  }
12307
- if (!i18nBlockContexts.has(op.context)) {
12308
- const i18nContext = i18nContexts.get(op.context);
12398
+ const i18nContext = i18nContexts.get(op.context);
12399
+ if (i18nContext.contextKind === I18nContextKind.Icu) {
12309
12400
  const subMessage = createI18nMessage(job, i18nContext, op.messagePlaceholder);
12310
12401
  unit.create.push(subMessage);
12311
- const parentMessage = i18nBlockMessages.get(i18nContext.i18nBlock);
12402
+ const rootI18nId = i18nBlocks.get(i18nContext.i18nBlock).root;
12403
+ const parentMessage = i18nBlockMessages.get(rootI18nId);
12312
12404
  parentMessage?.subMessages.push(subMessage.xref);
12313
12405
  }
12314
12406
  OpList.remove(op);
@@ -12324,38 +12416,110 @@ function extractI18nMessages(job) {
12324
12416
  * Create an i18n message op from an i18n context op.
12325
12417
  */
12326
12418
  function createI18nMessage(job, context, messagePlaceholder) {
12327
- let needsPostprocessing = context.postprocessingParams.size > 0;
12328
- for (const values of context.params.values()) {
12329
- if (values.length > 1) {
12330
- needsPostprocessing = true;
12331
- }
12332
- }
12333
- return createI18nMessageOp(job.allocateXrefId(), context.i18nBlock, context.message, messagePlaceholder ?? null, formatParams(context.params), formatParams(context.postprocessingParams), needsPostprocessing);
12419
+ let [formattedParams, needsPostprocessing] = formatParams(context.params);
12420
+ const [formattedPostprocessingParams] = formatParams(context.postprocessingParams);
12421
+ needsPostprocessing ||= formattedPostprocessingParams.size > 0;
12422
+ return createI18nMessageOp(job.allocateXrefId(), context.i18nBlock, context.message, messagePlaceholder ?? null, formattedParams, formattedPostprocessingParams, needsPostprocessing);
12334
12423
  }
12335
12424
  /**
12336
12425
  * Formats a map of `I18nParamValue[]` values into a map of `Expression` values.
12426
+ * @return A tuple of the formatted params and a boolean indicating whether postprocessing is needed
12427
+ * for any of the params
12337
12428
  */
12338
12429
  function formatParams(params) {
12339
- const result = new Map();
12430
+ const formattedParams = new Map();
12431
+ let needsPostprocessing = false;
12340
12432
  for (const [placeholder, placeholderValues] of params) {
12341
- const serializedValues = formatParamValues(placeholderValues);
12433
+ const [serializedValues, paramNeedsPostprocessing] = formatParamValues(placeholderValues);
12434
+ needsPostprocessing ||= paramNeedsPostprocessing;
12342
12435
  if (serializedValues !== null) {
12343
- result.set(placeholder, literal(formatParamValues(placeholderValues)));
12436
+ formattedParams.set(placeholder, literal(serializedValues));
12344
12437
  }
12345
12438
  }
12346
- return result;
12439
+ return [formattedParams, needsPostprocessing];
12347
12440
  }
12348
12441
  /**
12349
12442
  * Formats an `I18nParamValue[]` into a string (or null for empty array).
12443
+ * @return A tuple of the formatted value and a boolean indicating whether postprocessing is needed
12444
+ * for the value
12350
12445
  */
12351
12446
  function formatParamValues(values) {
12352
12447
  if (values.length === 0) {
12353
- return null;
12448
+ return [null, false];
12354
12449
  }
12450
+ collapseElementTemplatePairs(values);
12355
12451
  const serializedValues = values.map(value => formatValue(value));
12356
12452
  return serializedValues.length === 1 ?
12357
- serializedValues[0] :
12358
- `${LIST_START_MARKER}${serializedValues.join(LIST_DELIMITER)}${LIST_END_MARKER}`;
12453
+ [serializedValues[0], false] :
12454
+ [`${LIST_START_MARKER}${serializedValues.join(LIST_DELIMITER)}${LIST_END_MARKER}`, true];
12455
+ }
12456
+ /**
12457
+ * Collapses element/template pairs that refer to the same subTemplateIndex, i.e. elements and
12458
+ * templates that refer to the same element instance.
12459
+ *
12460
+ * This accounts for the case of a structural directive inside an i18n block, e.g.:
12461
+ * ```
12462
+ * <div i18n>
12463
+ * <div *ngIf="condition">
12464
+ * </div>
12465
+ * ```
12466
+ *
12467
+ * In this case, both the element start and template start placeholders are the same,
12468
+ * and we collapse them down into a single compound placeholder value. Rather than produce
12469
+ * `[\uFFFD#1:1\uFFFD|\uFFFD*2:1\uFFFD]`, we want to produce `\uFFFD#1:1\uFFFD\uFFFD*2:1\uFFFD`,
12470
+ * likewise for the closing of the element/template.
12471
+ */
12472
+ function collapseElementTemplatePairs(values) {
12473
+ // Record the indicies of element and template values in the values array by subTemplateIndex.
12474
+ const valueIndiciesBySubTemplateIndex = new Map();
12475
+ for (let i = 0; i < values.length; i++) {
12476
+ const value = values[i];
12477
+ if (value.subTemplateIndex !== null &&
12478
+ (value.flags & (I18nParamValueFlags.ElementTag | I18nParamValueFlags.TemplateTag))) {
12479
+ const valueIndicies = valueIndiciesBySubTemplateIndex.get(value.subTemplateIndex) ?? [];
12480
+ valueIndicies.push(i);
12481
+ valueIndiciesBySubTemplateIndex.set(value.subTemplateIndex, valueIndicies);
12482
+ }
12483
+ }
12484
+ // For each subTemplateIndex, check if any values can be collapsed.
12485
+ for (const [subTemplateIndex, valueIndicies] of valueIndiciesBySubTemplateIndex) {
12486
+ if (valueIndicies.length > 1) {
12487
+ const elementIndex = valueIndicies.find(index => values[index].flags & I18nParamValueFlags.ElementTag);
12488
+ const templateIndex = valueIndicies.find(index => values[index].flags & I18nParamValueFlags.TemplateTag);
12489
+ // If the values list contains both an element and template value, we can collapse.
12490
+ if (elementIndex !== undefined && templateIndex !== undefined) {
12491
+ const elementValue = values[elementIndex];
12492
+ const templateValue = values[templateIndex];
12493
+ // To match the TemplateDefinitionBuilder output, flip the order depending on whether the
12494
+ // values represent a closing or opening tag (or both).
12495
+ // TODO(mmalerba): Figure out if this makes a difference in terms of either functionality,
12496
+ // or the resulting message ID. If not, we can remove the special-casing in the future.
12497
+ let compundValue;
12498
+ if ((elementValue.flags & I18nParamValueFlags.OpenTag) &&
12499
+ (elementValue.flags & I18nParamValueFlags.CloseTag)) {
12500
+ // TODO(mmalerba): Is this a TDB bug? I don't understand why it would put the template
12501
+ // value twice.
12502
+ compundValue = `${formatValue(templateValue)}${formatValue(elementValue)}${formatValue(templateValue)}`;
12503
+ }
12504
+ else if (elementValue.flags & I18nParamValueFlags.OpenTag) {
12505
+ compundValue = `${formatValue(templateValue)}${formatValue(elementValue)}`;
12506
+ }
12507
+ else {
12508
+ compundValue = `${formatValue(elementValue)}${formatValue(templateValue)}`;
12509
+ }
12510
+ // Replace the element value with the combined value.
12511
+ values.splice(elementIndex, 1, { value: compundValue, subTemplateIndex, flags: I18nParamValueFlags.None });
12512
+ // Replace the template value with null to preserve the indicies we calculated earlier.
12513
+ values.splice(templateIndex, 1, null);
12514
+ }
12515
+ }
12516
+ }
12517
+ // Strip out any nulled out values we introduced above.
12518
+ for (let i = values.length - 1; i >= 0; i--) {
12519
+ if (values[i] === null) {
12520
+ values.splice(i, 1);
12521
+ }
12522
+ }
12359
12523
  }
12360
12524
  /**
12361
12525
  * Formats a single `I18nParamValue` into a string
@@ -12723,6 +12887,9 @@ class IcuSerializerVisitor {
12723
12887
  visitPlaceholder(ph) {
12724
12888
  return this.formatPh(ph.name);
12725
12889
  }
12890
+ visitBlockPlaceholder(ph) {
12891
+ return `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`;
12892
+ }
12726
12893
  visitIcuPlaceholder(ph, context) {
12727
12894
  return this.formatPh(ph.name);
12728
12895
  }
@@ -14446,12 +14613,12 @@ class Comment {
14446
14613
  return visitor.visitComment(this, context);
14447
14614
  }
14448
14615
  }
14449
- class Block {
14450
- constructor(name, parameters, children, sourceSpan, nameSpan, startSourceSpan, endSourceSpan = null) {
14616
+ class Block extends NodeWithI18n {
14617
+ constructor(name, parameters, children, sourceSpan, nameSpan, startSourceSpan, endSourceSpan = null, i18n) {
14618
+ super(sourceSpan, i18n);
14451
14619
  this.name = name;
14452
14620
  this.parameters = parameters;
14453
14621
  this.children = children;
14454
- this.sourceSpan = sourceSpan;
14455
14622
  this.nameSpan = nameSpan;
14456
14623
  this.startSourceSpan = startSourceSpan;
14457
14624
  this.endSourceSpan = endSourceSpan;
@@ -15137,6 +15304,24 @@ class PlaceholderRegistry {
15137
15304
  getUniquePlaceholder(name) {
15138
15305
  return this._generateUniqueName(name.toUpperCase());
15139
15306
  }
15307
+ getStartBlockPlaceholderName(name, parameters) {
15308
+ const signature = this._hashBlock(name, parameters);
15309
+ if (this._signatureToName[signature]) {
15310
+ return this._signatureToName[signature];
15311
+ }
15312
+ const placeholder = this._generateUniqueName(`START_BLOCK_${this._toSnakeCase(name)}`);
15313
+ this._signatureToName[signature] = placeholder;
15314
+ return placeholder;
15315
+ }
15316
+ getCloseBlockPlaceholderName(name) {
15317
+ const signature = this._hashClosingBlock(name);
15318
+ if (this._signatureToName[signature]) {
15319
+ return this._signatureToName[signature];
15320
+ }
15321
+ const placeholder = this._generateUniqueName(`CLOSE_BLOCK_${this._toSnakeCase(name)}`);
15322
+ this._signatureToName[signature] = placeholder;
15323
+ return placeholder;
15324
+ }
15140
15325
  // Generate a hash for a tag - does not take attribute order into account
15141
15326
  _hashTag(tag, attrs, isVoid) {
15142
15327
  const start = `<${tag}`;
@@ -15147,6 +15332,16 @@ class PlaceholderRegistry {
15147
15332
  _hashClosingTag(tag) {
15148
15333
  return this._hashTag(`/${tag}`, {}, false);
15149
15334
  }
15335
+ _hashBlock(name, parameters) {
15336
+ const params = parameters.length === 0 ? '' : ` (${parameters.sort().join('; ')})`;
15337
+ return `@${name}${params} {}`;
15338
+ }
15339
+ _hashClosingBlock(name) {
15340
+ return this._hashBlock(`close_${name}`, []);
15341
+ }
15342
+ _toSnakeCase(name) {
15343
+ return name.toUpperCase().replace(/[^A-Z0-9]/g, '_');
15344
+ }
15150
15345
  _generateUniqueName(base) {
15151
15346
  const seen = this._placeHolderNameCounts.hasOwnProperty(base);
15152
15347
  if (!seen) {
@@ -15163,17 +15358,18 @@ const _expParser = new Parser$1(new Lexer());
15163
15358
  /**
15164
15359
  * Returns a function converting html nodes to an i18n Message given an interpolationConfig
15165
15360
  */
15166
- function createI18nMessageFactory(interpolationConfig) {
15167
- const visitor = new _I18nVisitor(_expParser, interpolationConfig);
15361
+ function createI18nMessageFactory(interpolationConfig, containerBlocks) {
15362
+ const visitor = new _I18nVisitor(_expParser, interpolationConfig, containerBlocks);
15168
15363
  return (nodes, meaning, description, customId, visitNodeFn) => visitor.toI18nMessage(nodes, meaning, description, customId, visitNodeFn);
15169
15364
  }
15170
15365
  function noopVisitNodeFn(_html, i18n) {
15171
15366
  return i18n;
15172
15367
  }
15173
15368
  class _I18nVisitor {
15174
- constructor(_expressionParser, _interpolationConfig) {
15369
+ constructor(_expressionParser, _interpolationConfig, _containerBlocks) {
15175
15370
  this._expressionParser = _expressionParser;
15176
15371
  this._interpolationConfig = _interpolationConfig;
15372
+ this._containerBlocks = _containerBlocks;
15177
15373
  }
15178
15374
  toI18nMessage(nodes, meaning = '', description = '', customId = '', visitNodeFn) {
15179
15375
  const context = {
@@ -15260,10 +15456,26 @@ class _I18nVisitor {
15260
15456
  }
15261
15457
  visitBlock(block, context) {
15262
15458
  const children = visitAll(this, block.children, context);
15263
- const node = new Container(children, block.sourceSpan);
15459
+ if (this._containerBlocks.has(block.name)) {
15460
+ return new Container(children, block.sourceSpan);
15461
+ }
15462
+ const parameters = block.parameters.map(param => param.expression);
15463
+ const startPhName = context.placeholderRegistry.getStartBlockPlaceholderName(block.name, parameters);
15464
+ const closePhName = context.placeholderRegistry.getCloseBlockPlaceholderName(block.name);
15465
+ context.placeholderToContent[startPhName] = {
15466
+ text: block.startSourceSpan.toString(),
15467
+ sourceSpan: block.startSourceSpan,
15468
+ };
15469
+ context.placeholderToContent[closePhName] = {
15470
+ text: block.endSourceSpan ? block.endSourceSpan.toString() : '}',
15471
+ sourceSpan: block.endSourceSpan ?? block.sourceSpan,
15472
+ };
15473
+ const node = new BlockPlaceholder(block.name, parameters, startPhName, closePhName, children, block.sourceSpan, block.startSourceSpan, block.endSourceSpan);
15264
15474
  return context.visitNodeFn(block, node);
15265
15475
  }
15266
- visitBlockParameter(_parameter, _context) { }
15476
+ visitBlockParameter(_parameter, _context) {
15477
+ throw new Error('Unreachable code');
15478
+ }
15267
15479
  /**
15268
15480
  * Convert, text and interpolated tokens up into text and placeholder pieces.
15269
15481
  *
@@ -19132,17 +19344,18 @@ const setI18nRefs = (htmlNode, i18nNode) => {
19132
19344
  * stored with other element's and attribute's information.
19133
19345
  */
19134
19346
  class I18nMetaVisitor {
19135
- constructor(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG, keepI18nAttrs = false, enableI18nLegacyMessageIdFormat = false) {
19347
+ constructor(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG, keepI18nAttrs = false, enableI18nLegacyMessageIdFormat = false, containerBlocks = DEFAULT_CONTAINER_BLOCKS) {
19136
19348
  this.interpolationConfig = interpolationConfig;
19137
19349
  this.keepI18nAttrs = keepI18nAttrs;
19138
19350
  this.enableI18nLegacyMessageIdFormat = enableI18nLegacyMessageIdFormat;
19351
+ this.containerBlocks = containerBlocks;
19139
19352
  // whether visited nodes contain i18n information
19140
19353
  this.hasI18nMeta = false;
19141
19354
  this._errors = [];
19142
19355
  }
19143
19356
  _generateI18nMessage(nodes, meta = '', visitNodeFn) {
19144
19357
  const { meaning, description, customId } = this._parseMetadata(meta);
19145
- const createI18nMessage = createI18nMessageFactory(this.interpolationConfig);
19358
+ const createI18nMessage = createI18nMessageFactory(this.interpolationConfig, this.containerBlocks);
19146
19359
  const message = createI18nMessage(nodes, meaning, description, customId, visitNodeFn);
19147
19360
  this._setMessageId(message, meta);
19148
19361
  this._setLegacyIds(message, meta);
@@ -19443,6 +19656,9 @@ class GetMsgSerializerVisitor {
19443
19656
  visitPlaceholder(ph) {
19444
19657
  return this.formatPh(ph.name);
19445
19658
  }
19659
+ visitBlockPlaceholder(ph) {
19660
+ return `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`;
19661
+ }
19446
19662
  visitIcuPlaceholder(ph, context) {
19447
19663
  return this.formatPh(ph.name);
19448
19664
  }
@@ -19496,6 +19712,11 @@ class LocalizeSerializerVisitor {
19496
19712
  visitPlaceholder(ph) {
19497
19713
  this.pieces.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan));
19498
19714
  }
19715
+ visitBlockPlaceholder(ph) {
19716
+ this.pieces.push(this.createPlaceholderPiece(ph.startName, ph.startSourceSpan ?? ph.sourceSpan));
19717
+ ph.children.forEach(child => child.visit(this));
19718
+ this.pieces.push(this.createPlaceholderPiece(ph.closeName, ph.endSourceSpan ?? ph.sourceSpan));
19719
+ }
19499
19720
  visitIcuPlaceholder(ph) {
19500
19721
  this.pieces.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan, this.placeholderToMessage[ph.name]));
19501
19722
  }
@@ -19826,57 +20047,6 @@ function serializeLocalRefs(refs) {
19826
20047
  return literalArr(constRefs);
19827
20048
  }
19828
20049
 
19829
- /**
19830
- * Merge i18n contexts for child i18n blocks into their ancestor root contexts.
19831
- */
19832
- function mergeI18nContexts(job) {
19833
- // Record all of the i18n and extracted message ops for use later.
19834
- const i18nOps = new Map();
19835
- const i18nContexts = new Map();
19836
- for (const unit of job.units) {
19837
- for (const op of unit.create) {
19838
- switch (op.kind) {
19839
- case OpKind.I18nStart:
19840
- if (!op.context) {
19841
- throw Error('I18n op should have its context set.');
19842
- }
19843
- i18nOps.set(op.xref, op);
19844
- break;
19845
- case OpKind.I18nContext:
19846
- i18nContexts.set(op.xref, op);
19847
- break;
19848
- }
19849
- }
19850
- }
19851
- // For each non-root i18n op, merge its context into the root i18n op's context.
19852
- for (const childI18nOp of i18nOps.values()) {
19853
- if (childI18nOp.xref !== childI18nOp.root) {
19854
- const childContext = i18nContexts.get(childI18nOp.context);
19855
- const rootI18nOp = i18nOps.get(childI18nOp.root);
19856
- const rootContext = i18nContexts.get(rootI18nOp.context);
19857
- mergeParams(rootContext.params, childContext.params);
19858
- mergeParams(rootContext.postprocessingParams, childContext.postprocessingParams);
19859
- }
19860
- }
19861
- }
19862
- /**
19863
- * Merges the params in the `from` map to into the `to` map.
19864
- */
19865
- function mergeParams(to, from) {
19866
- for (const [placeholder, fromValues] of from) {
19867
- const toValues = to.get(placeholder) || [];
19868
- // TODO(mmalerba): Child element close tag params should be prepended to maintain the same order
19869
- // as TemplateDefinitionBuilder. Can be cleaned up when compatibility is no longer required.
19870
- const flags = fromValues[0].flags;
19871
- if ((flags & I18nParamValueFlags.CloseTag) && !(flags & I18nParamValueFlags.OpenTag)) {
19872
- to.set(placeholder, [...fromValues, ...toValues]);
19873
- }
19874
- else {
19875
- to.set(placeholder, [...toValues, ...fromValues]);
19876
- }
19877
- }
19878
- }
19879
-
19880
20050
  /**
19881
20051
  * Change namespaces between HTML, SVG and MathML, depending on the next element.
19882
20052
  */
@@ -20540,9 +20710,10 @@ function propagateI18nBlocksToTemplates(unit, subTemplateIndex) {
20540
20710
  wrapTemplateWithI18n(templateView, i18nBlock);
20541
20711
  }
20542
20712
  // Continue traversing inside the template's view.
20543
- propagateI18nBlocksToTemplates(templateView, subTemplateIndex);
20713
+ subTemplateIndex = propagateI18nBlocksToTemplates(templateView, subTemplateIndex);
20544
20714
  }
20545
20715
  }
20716
+ return subTemplateIndex;
20546
20717
  }
20547
20718
  /**
20548
20719
  * Wraps a template view with i18n start and end ops.
@@ -20850,8 +21021,8 @@ function repeaterCreate(slot, viewFnName, decls, vars, tag, constIndex, trackByF
20850
21021
  }
20851
21022
  return call(Identifiers.repeaterCreate, args, sourceSpan);
20852
21023
  }
20853
- function repeater(metadataSlot, collection, sourceSpan) {
20854
- return call(Identifiers.repeater, [literal(metadataSlot), collection], sourceSpan);
21024
+ function repeater(collection, sourceSpan) {
21025
+ return call(Identifiers.repeater, [collection], sourceSpan);
20855
21026
  }
20856
21027
  function deferWhen(prefetch, expr, sourceSpan) {
20857
21028
  return call(prefetch ? Identifiers.deferPrefetchWhen : Identifiers.deferWhen, [expr], sourceSpan);
@@ -21459,7 +21630,7 @@ function reifyUpdateOperations(_unit, ops) {
21459
21630
  OpList.replace(op, conditional(op.targetSlot.slot, op.processed, op.contextValue, op.sourceSpan));
21460
21631
  break;
21461
21632
  case OpKind.Repeater:
21462
- OpList.replace(op, repeater(op.targetSlot.slot, op.collection, op.sourceSpan));
21633
+ OpList.replace(op, repeater(op.collection, op.sourceSpan));
21463
21634
  break;
21464
21635
  case OpKind.DeferWhen:
21465
21636
  OpList.replace(op, deferWhen(op.prefetch, op.expr, op.sourceSpan));
@@ -21722,66 +21893,79 @@ function resolveI18nElementPlaceholders(job) {
21722
21893
  }
21723
21894
  }
21724
21895
  }
21725
- for (const unit of job.units) {
21726
- // Track the current i18n op and corresponding i18n context op as we step through the creation
21727
- // IR.
21728
- let currentOps = null;
21729
- for (const op of unit.create) {
21730
- switch (op.kind) {
21731
- case OpKind.I18nStart:
21732
- if (!op.context) {
21733
- throw Error('Could not find i18n context for i18n op');
21896
+ resolvePlaceholdersForView(job, job.root, i18nContexts, elements);
21897
+ }
21898
+ function resolvePlaceholdersForView(job, unit, i18nContexts, elements) {
21899
+ // Track the current i18n op and corresponding i18n context op as we step through the creation
21900
+ // IR.
21901
+ let currentOps = null;
21902
+ for (const op of unit.create) {
21903
+ switch (op.kind) {
21904
+ case OpKind.I18nStart:
21905
+ if (!op.context) {
21906
+ throw Error('Could not find i18n context for i18n op');
21907
+ }
21908
+ currentOps = { i18nBlock: op, i18nContext: i18nContexts.get(op.context) };
21909
+ break;
21910
+ case OpKind.I18nEnd:
21911
+ currentOps = null;
21912
+ break;
21913
+ case OpKind.ElementStart:
21914
+ // For elements with i18n placeholders, record its slot value in the params map under the
21915
+ // corresponding tag start placeholder.
21916
+ if (op.i18nPlaceholder !== undefined) {
21917
+ if (currentOps === null) {
21918
+ throw Error('i18n tag placeholder should only occur inside an i18n block');
21734
21919
  }
21735
- currentOps = { i18nBlock: op, i18nContext: i18nContexts.get(op.context) };
21736
- break;
21737
- case OpKind.I18nEnd:
21738
- currentOps = null;
21739
- break;
21740
- case OpKind.ElementStart:
21741
- // For elements with i18n placeholders, record its slot value in the params map under the
21742
- // corresponding tag start placeholder.
21743
- if (op.i18nPlaceholder !== undefined) {
21744
- if (currentOps === null) {
21745
- throw Error('i18n tag placeholder should only occur inside an i18n block');
21746
- }
21747
- const { startName, closeName } = op.i18nPlaceholder;
21748
- let flags = I18nParamValueFlags.ElementTag | I18nParamValueFlags.OpenTag;
21749
- // For self-closing tags, there is no close tag placeholder. Instead, the start tag
21750
- // placeholder accounts for the start and close of the element.
21751
- if (closeName === '') {
21752
- flags |= I18nParamValueFlags.CloseTag;
21753
- }
21754
- addParam(currentOps.i18nContext.params, startName, op.handle.slot, currentOps.i18nBlock.subTemplateIndex, flags);
21920
+ const { startName, closeName } = op.i18nPlaceholder;
21921
+ let flags = I18nParamValueFlags.ElementTag | I18nParamValueFlags.OpenTag;
21922
+ // For self-closing tags, there is no close tag placeholder. Instead, the start tag
21923
+ // placeholder accounts for the start and close of the element.
21924
+ if (closeName === '') {
21925
+ flags |= I18nParamValueFlags.CloseTag;
21755
21926
  }
21756
- break;
21757
- case OpKind.ElementEnd:
21758
- // For elements with i18n placeholders, record its slot value in the params map under the
21759
- // corresponding tag close placeholder.
21760
- const startOp = elements.get(op.xref);
21761
- if (startOp && startOp.i18nPlaceholder !== undefined) {
21762
- if (currentOps === null) {
21763
- throw Error('i18n tag placeholder should only occur inside an i18n block');
21764
- }
21765
- const { closeName } = startOp.i18nPlaceholder;
21766
- // Self-closing tags don't have a closing tag placeholder.
21767
- if (closeName !== '') {
21768
- addParam(currentOps.i18nContext.params, closeName, startOp.handle.slot, currentOps.i18nBlock.subTemplateIndex, I18nParamValueFlags.ElementTag | I18nParamValueFlags.CloseTag);
21769
- }
21927
+ addParam(currentOps.i18nContext.params, startName, op.handle.slot, currentOps.i18nBlock.subTemplateIndex, flags);
21928
+ }
21929
+ break;
21930
+ case OpKind.ElementEnd:
21931
+ // For elements with i18n placeholders, record its slot value in the params map under the
21932
+ // corresponding tag close placeholder.
21933
+ const startOp = elements.get(op.xref);
21934
+ if (startOp && startOp.i18nPlaceholder !== undefined) {
21935
+ if (currentOps === null) {
21936
+ throw Error('i18n tag placeholder should only occur inside an i18n block');
21770
21937
  }
21771
- break;
21772
- case OpKind.Template:
21773
- // For templates with i18n placeholders, record its slot value in the params map under the
21774
- // corresponding template start and close placeholders.
21775
- if (op.i18nPlaceholder !== undefined) {
21776
- if (currentOps === null) {
21777
- throw Error('i18n tag placeholder should only occur inside an i18n block');
21778
- }
21779
- const subTemplateIndex = getSubTemplateIndexForTemplateTag(job, currentOps.i18nBlock, op);
21780
- addParam(currentOps.i18nContext.params, op.i18nPlaceholder.startName, op.handle.slot, subTemplateIndex, I18nParamValueFlags.TemplateTag);
21781
- addParam(currentOps.i18nContext.params, op.i18nPlaceholder.closeName, op.handle.slot, subTemplateIndex, I18nParamValueFlags.TemplateTag | I18nParamValueFlags.CloseTag);
21938
+ const { closeName } = startOp.i18nPlaceholder;
21939
+ // Self-closing tags don't have a closing tag placeholder.
21940
+ if (closeName !== '') {
21941
+ addParam(currentOps.i18nContext.params, closeName, startOp.handle.slot, currentOps.i18nBlock.subTemplateIndex, I18nParamValueFlags.ElementTag | I18nParamValueFlags.CloseTag);
21782
21942
  }
21783
- break;
21784
- }
21943
+ }
21944
+ break;
21945
+ case OpKind.Template:
21946
+ // For templates with i18n placeholders, record its slot value in the params map under the
21947
+ // corresponding template start and close placeholders.
21948
+ if (op.i18nPlaceholder !== undefined) {
21949
+ if (currentOps === null) {
21950
+ throw Error('i18n tag placeholder should only occur inside an i18n block');
21951
+ }
21952
+ let startFlags = I18nParamValueFlags.TemplateTag | I18nParamValueFlags.OpenTag;
21953
+ const subTemplateIndex = getSubTemplateIndexForTemplateTag(job, currentOps.i18nBlock, op);
21954
+ const { startName, closeName } = op.i18nPlaceholder;
21955
+ const isSelfClosing = closeName === '';
21956
+ if (isSelfClosing) {
21957
+ startFlags |= I18nParamValueFlags.CloseTag;
21958
+ }
21959
+ addParam(currentOps.i18nContext.params, startName, op.handle.slot, subTemplateIndex, startFlags);
21960
+ resolvePlaceholdersForView(job, job.views.get(op.xref), i18nContexts, elements);
21961
+ if (!isSelfClosing) {
21962
+ addParam(currentOps.i18nContext.params, closeName, op.handle.slot, subTemplateIndex, I18nParamValueFlags.TemplateTag | I18nParamValueFlags.CloseTag);
21963
+ }
21964
+ }
21965
+ else {
21966
+ resolvePlaceholdersForView(job, job.views.get(op.xref), i18nContexts, elements);
21967
+ }
21968
+ break;
21785
21969
  }
21786
21970
  }
21787
21971
  }
@@ -21829,8 +22013,8 @@ function resolveI18nExpressionPlaceholders(job) {
21829
22013
  for (const op of unit.update) {
21830
22014
  if (op.kind === OpKind.I18nExpression) {
21831
22015
  const i18nContext = i18nContexts.get(op.context);
21832
- const index = expressionIndices.get(i18nContext.i18nBlock) || 0;
21833
- const subTemplateIndex = subTemplateIndicies.get(i18nContext.i18nBlock);
22016
+ const index = expressionIndices.get(op.target) || 0;
22017
+ const subTemplateIndex = subTemplateIndicies.get(op.target);
21834
22018
  // Add the expression index in the appropriate params map.
21835
22019
  const params = op.resolutionTime === I18nParamResolutionTime.Creation ?
21836
22020
  i18nContext.params :
@@ -21842,7 +22026,7 @@ function resolveI18nExpressionPlaceholders(job) {
21842
22026
  flags: I18nParamValueFlags.ExpressionIndex
21843
22027
  });
21844
22028
  params.set(op.i18nPlaceholder, values);
21845
- expressionIndices.set(i18nContext.i18nBlock, index + 1);
22029
+ expressionIndices.set(op.target, index + 1);
21846
22030
  }
21847
22031
  }
21848
22032
  }
@@ -21852,28 +22036,12 @@ function resolveI18nExpressionPlaceholders(job) {
21852
22036
  * Resolves placeholders for element tags inside of an ICU.
21853
22037
  */
21854
22038
  function resolveI18nIcuPlaceholders(job) {
21855
- const contextOps = new Map();
21856
- for (const unit of job.units) {
21857
- for (const op of unit.create) {
21858
- switch (op.kind) {
21859
- case OpKind.I18nContext:
21860
- contextOps.set(op.xref, op);
21861
- break;
21862
- }
21863
- }
21864
- }
21865
22039
  for (const unit of job.units) {
21866
22040
  for (const op of unit.create) {
21867
- switch (op.kind) {
21868
- case OpKind.IcuStart:
21869
- if (op.context === null) {
21870
- throw Error('Icu should have its i18n context set.');
21871
- }
21872
- const i18nContext = contextOps.get(op.context);
21873
- for (const node of op.message.nodes) {
21874
- node.visit(new ResolveIcuPlaceholdersVisitor(i18nContext.postprocessingParams));
21875
- }
21876
- break;
22041
+ if (op.kind === OpKind.I18nContext && op.contextKind === I18nContextKind.Icu) {
22042
+ for (const node of op.message.nodes) {
22043
+ node.visit(new ResolveIcuPlaceholdersVisitor(op.postprocessingParams));
22044
+ }
21877
22045
  }
21878
22046
  }
21879
22047
  }
@@ -21886,10 +22054,9 @@ class ResolveIcuPlaceholdersVisitor extends RecurseVisitor {
21886
22054
  super();
21887
22055
  this.params = params;
21888
22056
  }
21889
- visitTagPlaceholder(placeholder) {
21890
- super.visitTagPlaceholder(placeholder);
21891
- // Add the start and end source span for tag placeholders. These need to be recorded for
21892
- // elements inside ICUs. The slots for the elements were recorded separately under the i18n
22057
+ visitContainerPlaceholder(placeholder) {
22058
+ // Add the start and end source span for container placeholders. These need to be recorded for
22059
+ // elements inside ICUs. The slots for the nodes were recorded separately under the i18n
21893
22060
  // block's context as part of the `resolveI18nElementPlaceholders` phase.
21894
22061
  if (placeholder.startName && placeholder.startSourceSpan &&
21895
22062
  !this.params.has(placeholder.startName)) {
@@ -21908,6 +22075,14 @@ class ResolveIcuPlaceholdersVisitor extends RecurseVisitor {
21908
22075
  }]);
21909
22076
  }
21910
22077
  }
22078
+ visitTagPlaceholder(placeholder) {
22079
+ super.visitTagPlaceholder(placeholder);
22080
+ this.visitContainerPlaceholder(placeholder);
22081
+ }
22082
+ visitBlockPlaceholder(placeholder) {
22083
+ super.visitBlockPlaceholder(placeholder);
22084
+ this.visitContainerPlaceholder(placeholder);
22085
+ }
21911
22086
  }
21912
22087
 
21913
22088
  /**
@@ -23036,7 +23211,6 @@ const phases = [
23036
23211
  { kind: CompilationJobKind.Tmpl, fn: resolveI18nElementPlaceholders },
23037
23212
  { kind: CompilationJobKind.Tmpl, fn: resolveI18nExpressionPlaceholders },
23038
23213
  { kind: CompilationJobKind.Tmpl, fn: resolveI18nIcuPlaceholders },
23039
- { kind: CompilationJobKind.Tmpl, fn: mergeI18nContexts },
23040
23214
  { kind: CompilationJobKind.Tmpl, fn: extractI18nMessages },
23041
23215
  { kind: CompilationJobKind.Tmpl, fn: generateTrackFns },
23042
23216
  { kind: CompilationJobKind.Tmpl, fn: collectI18nConsts },
@@ -25102,19 +25276,19 @@ function createIfBlock(ast, connectedBlocks, visitor, bindingParser) {
25102
25276
  const branches = [];
25103
25277
  const mainBlockParams = parseConditionalBlockParameters(ast, errors, bindingParser);
25104
25278
  if (mainBlockParams !== null) {
25105
- branches.push(new IfBlockBranch(mainBlockParams.expression, visitAll(visitor, ast.children, ast.children), mainBlockParams.expressionAlias, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan));
25279
+ branches.push(new IfBlockBranch(mainBlockParams.expression, visitAll(visitor, ast.children, ast.children), mainBlockParams.expressionAlias, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan, ast.i18n));
25106
25280
  }
25107
25281
  for (const block of connectedBlocks) {
25108
25282
  if (ELSE_IF_PATTERN.test(block.name)) {
25109
25283
  const params = parseConditionalBlockParameters(block, errors, bindingParser);
25110
25284
  if (params !== null) {
25111
25285
  const children = visitAll(visitor, block.children, block.children);
25112
- branches.push(new IfBlockBranch(params.expression, children, params.expressionAlias, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan));
25286
+ branches.push(new IfBlockBranch(params.expression, children, params.expressionAlias, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
25113
25287
  }
25114
25288
  }
25115
25289
  else if (block.name === 'else') {
25116
25290
  const children = visitAll(visitor, block.children, block.children);
25117
- branches.push(new IfBlockBranch(null, children, null, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan));
25291
+ branches.push(new IfBlockBranch(null, children, null, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
25118
25292
  }
25119
25293
  }
25120
25294
  // The outer IfBlock should have a span that encapsulates all branches.
@@ -25145,7 +25319,7 @@ function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
25145
25319
  errors.push(new ParseError(block.sourceSpan, '@empty block cannot have parameters'));
25146
25320
  }
25147
25321
  else {
25148
- empty = new ForLoopBlockEmpty(visitAll(visitor, block.children, block.children), block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan);
25322
+ empty = new ForLoopBlockEmpty(visitAll(visitor, block.children, block.children), block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n);
25149
25323
  }
25150
25324
  }
25151
25325
  else {
@@ -25163,7 +25337,7 @@ function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
25163
25337
  // main `for` body, use `mainSourceSpan`.
25164
25338
  const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
25165
25339
  const sourceSpan = new ParseSourceSpan(ast.sourceSpan.start, endSpan?.end ?? ast.sourceSpan.end);
25166
- 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);
25340
+ 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);
25167
25341
  }
25168
25342
  }
25169
25343
  return { node, errors };
@@ -25189,7 +25363,7 @@ function createSwitchBlock(ast, visitor, bindingParser) {
25189
25363
  const expression = node.name === 'case' ?
25190
25364
  parseBlockParameterToBinding(node.parameters[0], bindingParser) :
25191
25365
  null;
25192
- const ast = new SwitchBlockCase(expression, visitAll(visitor, node.children, node.children), node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.nameSpan);
25366
+ const ast = new SwitchBlockCase(expression, visitAll(visitor, node.children, node.children), node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.nameSpan, node.i18n);
25193
25367
  if (expression === null) {
25194
25368
  defaultCase = ast;
25195
25369
  }
@@ -25776,7 +25950,7 @@ function createDeferredBlock(ast, connectedBlocks, visitor, bindingParser) {
25776
25950
  endOfLastSourceSpan = lastConnectedBlock.sourceSpan.end;
25777
25951
  }
25778
25952
  const sourceSpanWithConnectedBlocks = new ParseSourceSpan(ast.sourceSpan.start, endOfLastSourceSpan);
25779
- const node = new DeferredBlock(visitAll(visitor, ast.children, ast.children), triggers, prefetchTriggers, placeholder, loading, error, ast.nameSpan, sourceSpanWithConnectedBlocks, ast.sourceSpan, ast.startSourceSpan, lastEndSourceSpan);
25953
+ const node = new DeferredBlock(visitAll(visitor, ast.children, ast.children), triggers, prefetchTriggers, placeholder, loading, error, ast.nameSpan, sourceSpanWithConnectedBlocks, ast.sourceSpan, ast.startSourceSpan, lastEndSourceSpan, ast.i18n);
25780
25954
  return { node, errors };
25781
25955
  }
25782
25956
  function parseConnectedBlocks(connectedBlocks, errors, visitor) {
@@ -25839,7 +26013,7 @@ function parsePlaceholderBlock(ast, visitor) {
25839
26013
  throw new Error(`Unrecognized parameter in @placeholder block: "${param.expression}"`);
25840
26014
  }
25841
26015
  }
25842
- return new DeferredBlockPlaceholder(visitAll(visitor, ast.children, ast.children), minimumTime, ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
26016
+ return new DeferredBlockPlaceholder(visitAll(visitor, ast.children, ast.children), minimumTime, ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.i18n);
25843
26017
  }
25844
26018
  function parseLoadingBlock(ast, visitor) {
25845
26019
  let afterTime = null;
@@ -25869,13 +26043,13 @@ function parseLoadingBlock(ast, visitor) {
25869
26043
  throw new Error(`Unrecognized parameter in @loading block: "${param.expression}"`);
25870
26044
  }
25871
26045
  }
25872
- return new DeferredBlockLoading(visitAll(visitor, ast.children, ast.children), afterTime, minimumTime, ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
26046
+ return new DeferredBlockLoading(visitAll(visitor, ast.children, ast.children), afterTime, minimumTime, ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.i18n);
25873
26047
  }
25874
26048
  function parseErrorBlock(ast, visitor) {
25875
26049
  if (ast.parameters.length > 0) {
25876
26050
  throw new Error(`@error block cannot have parameters`);
25877
26051
  }
25878
- return new DeferredBlockError(visitAll(visitor, ast.children, ast.children), ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
26052
+ return new DeferredBlockError(visitAll(visitor, ast.children, ast.children), ast.nameSpan, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.i18n);
25879
26053
  }
25880
26054
  function parsePrimaryTriggers(params, bindingParser, errors, placeholder) {
25881
26055
  const triggers = {};
@@ -26475,6 +26649,11 @@ class I18nContext {
26475
26649
  const content = { type, index, ctx: this.id, isVoid: node.isVoid, closed };
26476
26650
  updatePlaceholderMap(this.placeholders, ph, content);
26477
26651
  }
26652
+ appendBlockPart(node, index, closed) {
26653
+ const ph = closed ? node.closeName : node.startName;
26654
+ const content = { type: TagType.TEMPLATE, index, ctx: this.id, closed };
26655
+ updatePlaceholderMap(this.placeholders, ph, content);
26656
+ }
26478
26657
  get icus() {
26479
26658
  return this._registry.icus;
26480
26659
  }
@@ -26507,6 +26686,13 @@ class I18nContext {
26507
26686
  this.appendTag(TagType.TEMPLATE, node, index, true);
26508
26687
  this._unresolvedCtxCount++;
26509
26688
  }
26689
+ appendBlock(node, index) {
26690
+ // add open and close tags at the same time,
26691
+ // since we process nested templates separately
26692
+ this.appendBlockPart(node, index, false);
26693
+ this.appendBlockPart(node, index, true);
26694
+ this._unresolvedCtxCount++;
26695
+ }
26510
26696
  appendElement(node, index, closed) {
26511
26697
  this.appendTag(TagType.ELEMENT, node, index, closed);
26512
26698
  }
@@ -26785,13 +26971,19 @@ class TemplateDefinitionBuilder {
26785
26971
  this.creationInstruction(null, Identifiers.pipe, [literal(slot), literal(name)]);
26786
26972
  });
26787
26973
  }
26788
- buildTemplateFunction(nodes, variables, ngContentSelectorsOffset = 0, i18n) {
26974
+ buildTemplateFunction(nodes, variables, ngContentSelectorsOffset = 0, i18n, variableAliases) {
26789
26975
  this._ngContentSelectorsOffset = ngContentSelectorsOffset;
26790
26976
  if (this._namespace !== Identifiers.namespaceHTML) {
26791
26977
  this.creationInstruction(null, this._namespace);
26792
26978
  }
26793
26979
  // Create variable bindings
26794
- variables.forEach(v => this.registerContextVariables(v));
26980
+ variables.forEach(v => {
26981
+ const alias = variableAliases?.[v.name];
26982
+ this.registerContextVariables(v.name, v.value);
26983
+ if (alias) {
26984
+ this.registerContextVariables(alias, v.value);
26985
+ }
26986
+ });
26795
26987
  // Initiate i18n context in case:
26796
26988
  // - this template has parent i18n context
26797
26989
  // - or the template has i18n meta associated with it,
@@ -26885,12 +27077,12 @@ class TemplateDefinitionBuilder {
26885
27077
  this._constants.prepareStatements.push(...statements);
26886
27078
  return _ref;
26887
27079
  }
26888
- registerContextVariables(variable$1) {
27080
+ registerContextVariables(name, value) {
26889
27081
  const scopedName = this._bindingScope.freshReferenceName();
26890
27082
  const retrievalLevel = this.level;
26891
- const isDirect = variable$1.value === DIRECT_CONTEXT_REFERENCE;
26892
- const lhs = variable(variable$1.name + scopedName);
26893
- this._bindingScope.set(retrievalLevel, variable$1.name, scope => {
27083
+ const isDirect = value === DIRECT_CONTEXT_REFERENCE;
27084
+ const lhs = variable(name + scopedName);
27085
+ this._bindingScope.set(retrievalLevel, name, scope => {
26894
27086
  // If we're at the top level and we're referring to the context variable directly, we
26895
27087
  // can do so through the implicit receiver, instead of renaming it. Note that this does
26896
27088
  // not apply to listeners, because they need to restore the context.
@@ -26926,7 +27118,7 @@ class TemplateDefinitionBuilder {
26926
27118
  return [
26927
27119
  // e.g. const $items$ = x(2) for direct context references and
26928
27120
  // const $item$ = x(2).$implicit for indirect ones.
26929
- lhs.set(isDirect ? rhs : rhs.prop(variable$1.value || IMPLICIT_REFERENCE)).toConstDecl()
27121
+ lhs.set(isDirect ? rhs : rhs.prop(value || IMPLICIT_REFERENCE)).toConstDecl()
26930
27122
  ];
26931
27123
  });
26932
27124
  }
@@ -27349,10 +27541,15 @@ class TemplateDefinitionBuilder {
27349
27541
  this.creationInstruction(span, isNgContainer$1 ? Identifiers.elementContainerEnd : Identifiers.elementEnd);
27350
27542
  }
27351
27543
  }
27352
- prepareEmbeddedTemplateFn(children, contextNameSuffix, variables = [], i18n) {
27544
+ prepareEmbeddedTemplateFn(children, contextNameSuffix, variables = [], i18nMeta, variableAliases) {
27353
27545
  const index = this.allocateDataSlot();
27354
- if (this.i18n && i18n) {
27355
- this.i18n.appendTemplate(i18n, index);
27546
+ if (this.i18n && i18nMeta) {
27547
+ if (i18nMeta instanceof BlockPlaceholder) {
27548
+ this.i18n.appendBlock(i18nMeta, index);
27549
+ }
27550
+ else {
27551
+ this.i18n.appendTemplate(i18nMeta, index);
27552
+ }
27356
27553
  }
27357
27554
  const contextName = `${this.contextName}${contextNameSuffix}_${index}`;
27358
27555
  const name = `${contextName}_Template`;
@@ -27363,7 +27560,7 @@ class TemplateDefinitionBuilder {
27363
27560
  // be able to support bindings in nested templates to local refs that occur after the
27364
27561
  // template definition. e.g. <div *ngIf="showing">{{ foo }}</div> <div #foo></div>
27365
27562
  this._nestedTemplateFns.push(() => {
27366
- const templateFunctionExpr = visitor.buildTemplateFunction(children, variables, this._ngContentReservedSlots.length + this._ngContentSelectorsOffset, i18n);
27563
+ const templateFunctionExpr = visitor.buildTemplateFunction(children, variables, this._ngContentReservedSlots.length + this._ngContentSelectorsOffset, i18nMeta, variableAliases);
27367
27564
  this.constantPool.statements.push(templateFunctionExpr.toDeclStmt(name));
27368
27565
  if (visitor._ngContentReservedSlots.length) {
27369
27566
  this._ngContentReservedSlots.push(...visitor._ngContentReservedSlots);
@@ -27520,7 +27717,7 @@ class TemplateDefinitionBuilder {
27520
27717
  }
27521
27718
  // Note: the template needs to be created *before* we process the expression,
27522
27719
  // otherwise pipes injecting some symbols won't work (see #52102).
27523
- const templateIndex = this.createEmbeddedTemplateFn(tagName, children, '_Conditional', sourceSpan, variables, attrsExprs);
27720
+ const templateIndex = this.createEmbeddedTemplateFn(tagName, children, '_Conditional', sourceSpan, variables, attrsExprs, undefined, branch.i18n);
27524
27721
  const processedExpression = expression === null ? null : expression.visit(this._valueConverter);
27525
27722
  return { index: templateIndex, expression: processedExpression, alias: expressionAlias };
27526
27723
  });
@@ -27571,7 +27768,7 @@ class TemplateDefinitionBuilder {
27571
27768
  // We have to process the block in two steps: once here and again in the update instruction
27572
27769
  // callback in order to generate the correct expressions when pipes or pure functions are used.
27573
27770
  const caseData = block.cases.map(currentCase => {
27574
- const index = this.createEmbeddedTemplateFn(null, currentCase.children, '_Case', currentCase.sourceSpan);
27771
+ const index = this.createEmbeddedTemplateFn(null, currentCase.children, '_Case', currentCase.sourceSpan, undefined, undefined, undefined, currentCase.i18n);
27575
27772
  const expression = currentCase.expression === null ?
27576
27773
  null :
27577
27774
  currentCase.expression.visit(this._valueConverter);
@@ -27619,23 +27816,21 @@ class TemplateDefinitionBuilder {
27619
27816
  if (!metadata) {
27620
27817
  throw new Error('Could not resolve `defer` block metadata. Block may need to be analyzed.');
27621
27818
  }
27622
- const primaryTemplateIndex = this.createEmbeddedTemplateFn(null, deferred.children, '_Defer', deferred.sourceSpan);
27623
- const loadingIndex = loading ?
27624
- this.createEmbeddedTemplateFn(null, loading.children, '_DeferLoading', loading.sourceSpan) :
27819
+ const primaryTemplateIndex = this.createEmbeddedTemplateFn(null, deferred.children, '_Defer', deferred.sourceSpan, undefined, undefined, undefined, deferred.i18n);
27820
+ const loadingIndex = loading ? this.createEmbeddedTemplateFn(null, loading.children, '_DeferLoading', loading.sourceSpan, undefined, undefined, undefined, loading.i18n) :
27625
27821
  null;
27626
27822
  const loadingConsts = loading ?
27627
27823
  trimTrailingNulls([literal(loading.minimumTime), literal(loading.afterTime)]) :
27628
27824
  null;
27629
27825
  const placeholderIndex = placeholder ?
27630
- this.createEmbeddedTemplateFn(null, placeholder.children, '_DeferPlaceholder', placeholder.sourceSpan) :
27826
+ this.createEmbeddedTemplateFn(null, placeholder.children, '_DeferPlaceholder', placeholder.sourceSpan, undefined, undefined, undefined, placeholder.i18n) :
27631
27827
  null;
27632
27828
  const placeholderConsts = placeholder && placeholder.minimumTime !== null ?
27633
27829
  // TODO(crisbeto): potentially pass the time directly instead of storing it in the `consts`
27634
27830
  // since the placeholder block can only have one parameter?
27635
27831
  literalArr([literal(placeholder.minimumTime)]) :
27636
27832
  null;
27637
- const errorIndex = error ?
27638
- this.createEmbeddedTemplateFn(null, error.children, '_DeferError', error.sourceSpan) :
27833
+ const errorIndex = error ? this.createEmbeddedTemplateFn(null, error.children, '_DeferError', error.sourceSpan, undefined, undefined, undefined, error.i18n) :
27639
27834
  null;
27640
27835
  // Note: we generate this last so the index matches the instruction order.
27641
27836
  const deferredIndex = this.allocateDataSlot();
@@ -27789,11 +27984,18 @@ class TemplateDefinitionBuilder {
27789
27984
  // are implicitly inferred by the runtime to index + 1 and index + 2.
27790
27985
  const blockIndex = this.allocateDataSlot();
27791
27986
  const { tagName, attrsExprs } = this.inferProjectionDataFromInsertionPoint(block);
27792
- const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [block.item, block.contextVariables.$index, block.contextVariables.$count]);
27987
+ const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [block.item, block.contextVariables.$index, block.contextVariables.$count], block.i18n, {
27988
+ // We need to provide level-specific versions of `$index` and `$count`, because
27989
+ // they're used when deriving the remaining variables (`$odd`, `$even` etc.) while at the
27990
+ // same time being available implicitly. Without these aliases, we wouldn't be able to
27991
+ // access the `$index` of a parent loop from inside of a nested loop.
27992
+ [block.contextVariables.$index.name]: this.getLevelSpecificVariableName('$index', this.level + 1),
27993
+ [block.contextVariables.$count.name]: this.getLevelSpecificVariableName('$count', this.level + 1),
27994
+ });
27793
27995
  const { expression: trackByExpression, usesComponentInstance: trackByUsesComponentInstance } = this.createTrackByFunction(block);
27794
27996
  let emptyData = null;
27795
27997
  if (block.empty !== null) {
27796
- emptyData = this.prepareEmbeddedTemplateFn(block.empty.children, '_ForEmpty');
27998
+ emptyData = this.prepareEmbeddedTemplateFn(block.empty.children, '_ForEmpty', undefined, block.empty.i18n);
27797
27999
  // Allocate an extra slot for the empty block tracking.
27798
28000
  this.allocateBindingSlots(null);
27799
28001
  }
@@ -27823,17 +28025,44 @@ class TemplateDefinitionBuilder {
27823
28025
  // Note: we don't allocate binding slots for this expression,
27824
28026
  // because its value isn't stored in the LView.
27825
28027
  const value = block.expression.visit(this._valueConverter);
27826
- // `repeater(0, iterable)`
27827
- this.updateInstruction(block.sourceSpan, Identifiers.repeater, () => [literal(blockIndex), this.convertPropertyBinding(value)]);
28028
+ // `advance(x); repeater(iterable)`
28029
+ this.updateInstructionWithAdvance(blockIndex, block.sourceSpan, Identifiers.repeater, () => [this.convertPropertyBinding(value)]);
27828
28030
  }
27829
28031
  registerComputedLoopVariables(block, bindingScope) {
27830
- const indexLocalName = block.contextVariables.$index.name;
27831
- const countLocalName = block.contextVariables.$count.name;
27832
28032
  const level = bindingScope.bindingLevel;
27833
- bindingScope.set(level, block.contextVariables.$odd.name, scope => scope.get(indexLocalName).modulo(literal(2)).notIdentical(literal(0)));
27834
- bindingScope.set(level, block.contextVariables.$even.name, scope => scope.get(indexLocalName).modulo(literal(2)).identical(literal(0)));
27835
- bindingScope.set(level, block.contextVariables.$first.name, scope => scope.get(indexLocalName).identical(literal(0)));
27836
- bindingScope.set(level, block.contextVariables.$last.name, scope => scope.get(indexLocalName).identical(scope.get(countLocalName).minus(literal(1))));
28033
+ bindingScope.set(level, block.contextVariables.$odd.name, (scope, retrievalLevel) => {
28034
+ return this.getLevelSpecificForLoopVariable(block, scope, retrievalLevel, '$index')
28035
+ .modulo(literal(2))
28036
+ .notIdentical(literal(0));
28037
+ });
28038
+ bindingScope.set(level, block.contextVariables.$even.name, (scope, retrievalLevel) => {
28039
+ return this.getLevelSpecificForLoopVariable(block, scope, retrievalLevel, '$index')
28040
+ .modulo(literal(2))
28041
+ .identical(literal(0));
28042
+ });
28043
+ bindingScope.set(level, block.contextVariables.$first.name, (scope, retrievalLevel) => {
28044
+ return this.getLevelSpecificForLoopVariable(block, scope, retrievalLevel, '$index')
28045
+ .identical(literal(0));
28046
+ });
28047
+ bindingScope.set(level, block.contextVariables.$last.name, (scope, retrievalLevel) => {
28048
+ const index = this.getLevelSpecificForLoopVariable(block, scope, retrievalLevel, '$index');
28049
+ const count = this.getLevelSpecificForLoopVariable(block, scope, retrievalLevel, '$count');
28050
+ return index.identical(count.minus(literal(1)));
28051
+ });
28052
+ }
28053
+ getLevelSpecificVariableName(name, level) {
28054
+ // We use the `ɵ` here to ensure that there are no name conflicts with user-defined variables.
28055
+ return `ɵ${name}_${level}`;
28056
+ }
28057
+ /**
28058
+ * Gets the name of a for loop variable at a specific binding level. This allows us to look
28059
+ * up implicitly shadowed variables like `$index` and `$count` at a specific level.
28060
+ */
28061
+ getLevelSpecificForLoopVariable(block, scope, retrievalLevel, name) {
28062
+ const scopeName = scope.bindingLevel === retrievalLevel ?
28063
+ block.contextVariables[name].name :
28064
+ this.getLevelSpecificVariableName(name, retrievalLevel);
28065
+ return scope.get(scopeName);
27837
28066
  }
27838
28067
  optimizeTrackByFunction(block) {
27839
28068
  const indexLocalName = block.contextVariables.$index.name;
@@ -28371,7 +28600,7 @@ class BindingScope {
28371
28600
  if (value.declareLocalCallback && !value.declare) {
28372
28601
  value.declare = true;
28373
28602
  }
28374
- return typeof value.lhs === 'function' ? value.lhs(this) : value.lhs;
28603
+ return typeof value.lhs === 'function' ? value.lhs(this, value.retrievalLevel) : value.lhs;
28375
28604
  }
28376
28605
  current = current.parent;
28377
28606
  }
@@ -28479,7 +28708,9 @@ class BindingScope {
28479
28708
  const componentValue = this.map.get(SHARED_CONTEXT_KEY + 0);
28480
28709
  componentValue.declare = true;
28481
28710
  this.maybeRestoreView();
28482
- const lhs = typeof componentValue.lhs === 'function' ? componentValue.lhs(this) : componentValue.lhs;
28711
+ const lhs = typeof componentValue.lhs === 'function' ?
28712
+ componentValue.lhs(this, componentValue.retrievalLevel) :
28713
+ componentValue.lhs;
28483
28714
  return name === DIRECT_CONTEXT_REFERENCE ? lhs : lhs.prop(name);
28484
28715
  }
28485
28716
  maybeRestoreView() {
@@ -28573,24 +28804,6 @@ class TrackByBindingScope extends BindingScope {
28573
28804
  return this.componentAccessCount;
28574
28805
  }
28575
28806
  }
28576
- /**
28577
- * Creates a `CssSelector` given a tag name and a map of attributes
28578
- */
28579
- function createCssSelector(elementName, attributes) {
28580
- const cssSelector = new CssSelector();
28581
- const elementNameNoNs = splitNsName(elementName)[1];
28582
- cssSelector.setElement(elementNameNoNs);
28583
- Object.getOwnPropertyNames(attributes).forEach((name) => {
28584
- const nameNoNs = splitNsName(name)[1];
28585
- const value = attributes[name];
28586
- cssSelector.addAttribute(nameNoNs, value);
28587
- if (name.toLowerCase() === 'class') {
28588
- const classes = value.trim().split(/\s+/);
28589
- classes.forEach(className => cssSelector.addClassName(className));
28590
- }
28591
- });
28592
- return cssSelector;
28593
- }
28594
28807
  /**
28595
28808
  * Creates an array of expressions out of an `ngProjectAs` attributes
28596
28809
  * which can be added to the instruction parameters.
@@ -28951,6 +29164,11 @@ function addFeatures(definitionMap, meta) {
28951
29164
  break;
28952
29165
  }
28953
29166
  }
29167
+ // Note: host directives feature needs to be inserted before the
29168
+ // inheritance feature to ensure the correct execution order.
29169
+ if (meta.hostDirectives?.length) {
29170
+ features.push(importExpr(Identifiers.HostDirectivesFeature).callFn([createHostDirectivesFeatureArg(meta.hostDirectives)]));
29171
+ }
28954
29172
  if (meta.usesInheritance) {
28955
29173
  features.push(importExpr(Identifiers.InheritDefinitionFeature));
28956
29174
  }
@@ -28964,9 +29182,6 @@ function addFeatures(definitionMap, meta) {
28964
29182
  if (meta.hasOwnProperty('template') && meta.isStandalone) {
28965
29183
  features.push(importExpr(Identifiers.StandaloneFeature));
28966
29184
  }
28967
- if (meta.hostDirectives?.length) {
28968
- features.push(importExpr(Identifiers.HostDirectivesFeature).callFn([createHostDirectivesFeatureArg(meta.hostDirectives)]));
28969
- }
28970
29185
  if (features.length) {
28971
29186
  definitionMap.set('features', literalArr(features));
28972
29187
  }
@@ -29927,15 +30142,15 @@ class DirectiveBinder {
29927
30142
  template.forEach(node => node.visit(this));
29928
30143
  }
29929
30144
  visitElement(element) {
29930
- this.visitElementOrTemplate(element.name, element);
30145
+ this.visitElementOrTemplate(element);
29931
30146
  }
29932
30147
  visitTemplate(template) {
29933
- this.visitElementOrTemplate('ng-template', template);
30148
+ this.visitElementOrTemplate(template);
29934
30149
  }
29935
- visitElementOrTemplate(elementName, node) {
30150
+ visitElementOrTemplate(node) {
29936
30151
  // First, determine the HTML shape of the node for the purpose of directive matching.
29937
30152
  // Do this by building up a `CssSelector` for the node.
29938
- const cssSelector = createCssSelector(elementName, getAttrsForDirectiveMatching(node));
30153
+ const cssSelector = createCssSelectorFromNode(node);
29939
30154
  // Next, use the `SelectorMatcher` to get the list of directives on the node.
29940
30155
  const directives = [];
29941
30156
  this.matcher.match(cssSelector, (_selector, results) => directives.push(...results));
@@ -31064,7 +31279,7 @@ function publishFacade(global) {
31064
31279
  * @description
31065
31280
  * Entry point for all public APIs of the compiler package.
31066
31281
  */
31067
- const VERSION = new Version('17.1.0-next.0');
31282
+ const VERSION = new Version('17.1.0-next.2');
31068
31283
 
31069
31284
  class CompilerConfig {
31070
31285
  constructor({ defaultEncapsulation = ViewEncapsulation.Emulated, preserveWhitespaces, strictInjectionParameters } = {}) {
@@ -31297,7 +31512,8 @@ class _Visitor {
31297
31512
  this._errors = [];
31298
31513
  this._messages = [];
31299
31514
  this._inImplicitNode = false;
31300
- this._createI18nMessage = createI18nMessageFactory(interpolationConfig);
31515
+ this._createI18nMessage =
31516
+ createI18nMessageFactory(interpolationConfig, DEFAULT_CONTAINER_BLOCKS);
31301
31517
  }
31302
31518
  // looks for translatable attributes
31303
31519
  _visitAttributesOf(el) {
@@ -31605,6 +31821,12 @@ class _WriteVisitor$1 {
31605
31821
  visitPlaceholder(ph, context) {
31606
31822
  return [new Tag(_PLACEHOLDER_TAG$2, { id: ph.name, 'equiv-text': `{{${ph.value}}}` })];
31607
31823
  }
31824
+ visitBlockPlaceholder(ph, context) {
31825
+ const ctype = `x-${ph.name.toLowerCase().replace(/[^a-z0-9]/g, '-')}`;
31826
+ const startTagPh = new Tag(_PLACEHOLDER_TAG$2, { id: ph.startName, ctype, 'equiv-text': `@${ph.name}` });
31827
+ const closeTagPh = new Tag(_PLACEHOLDER_TAG$2, { id: ph.closeName, ctype, 'equiv-text': `}` });
31828
+ return [startTagPh, ...this.serialize(ph.children), closeTagPh];
31829
+ }
31608
31830
  visitIcuPlaceholder(ph, context) {
31609
31831
  const equivText = `{${ph.value.expression}, ${ph.value.type}, ${Object.keys(ph.value.cases).map((value) => value + ' {...}').join(' ')}}`;
31610
31832
  return [new Tag(_PLACEHOLDER_TAG$2, { id: ph.name, 'equiv-text': equivText })];
@@ -31876,6 +32098,24 @@ class _WriteVisitor {
31876
32098
  disp: `{{${ph.value}}}`,
31877
32099
  })];
31878
32100
  }
32101
+ visitBlockPlaceholder(ph, context) {
32102
+ const tagPc = new Tag(_PLACEHOLDER_SPANNING_TAG, {
32103
+ id: (this._nextPlaceholderId++).toString(),
32104
+ equivStart: ph.startName,
32105
+ equivEnd: ph.closeName,
32106
+ type: 'other',
32107
+ dispStart: `@${ph.name}`,
32108
+ dispEnd: `}`,
32109
+ });
32110
+ const nodes = [].concat(...ph.children.map(node => node.visit(this)));
32111
+ if (nodes.length) {
32112
+ nodes.forEach((node) => tagPc.children.push(node));
32113
+ }
32114
+ else {
32115
+ tagPc.children.push(new Text$1(''));
32116
+ }
32117
+ return [tagPc];
32118
+ }
31879
32119
  visitIcuPlaceholder(ph, context) {
31880
32120
  const cases = Object.keys(ph.value.cases).map((value) => value + ' {...}').join(' ');
31881
32121
  const idStr = (this._nextPlaceholderId++).toString();
@@ -32324,6 +32564,11 @@ class I18nToHtmlVisitor {
32324
32564
  // An ICU placeholder references the source message to be serialized
32325
32565
  return this._convertToText(this._srcMsg.placeholderToMessage[ph.name]);
32326
32566
  }
32567
+ visitBlockPlaceholder(ph, context) {
32568
+ const params = ph.parameters.length === 0 ? '' : ` (${ph.parameters.join('; ')})`;
32569
+ const children = ph.children.map((c) => c.visit(this)).join('');
32570
+ return `@${ph.name}${params} {${children}}`;
32571
+ }
32327
32572
  /**
32328
32573
  * Convert a source message to a translated text string:
32329
32574
  * - text nodes are replaced with their translation,
@@ -32476,6 +32721,12 @@ class MapPlaceholderNames extends CloneVisitor {
32476
32721
  const children = ph.children.map(n => n.visit(this, mapper));
32477
32722
  return new TagPlaceholder(ph.tag, ph.attrs, startName, closeName, children, ph.isVoid, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan);
32478
32723
  }
32724
+ visitBlockPlaceholder(ph, mapper) {
32725
+ const startName = mapper.toPublicName(ph.startName);
32726
+ const closeName = ph.closeName ? mapper.toPublicName(ph.closeName) : ph.closeName;
32727
+ const children = ph.children.map(n => n.visit(this, mapper));
32728
+ return new BlockPlaceholder(ph.name, ph.parameters, startName, closeName, children, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan);
32729
+ }
32479
32730
  visitPlaceholder(ph, mapper) {
32480
32731
  return new Placeholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan);
32481
32732
  }
@@ -32594,7 +32845,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
32594
32845
  function compileDeclareClassMetadata(metadata) {
32595
32846
  const definitionMap = new DefinitionMap();
32596
32847
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
32597
- definitionMap.set('version', literal('17.1.0-next.0'));
32848
+ definitionMap.set('version', literal('17.1.0-next.2'));
32598
32849
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32599
32850
  definitionMap.set('type', metadata.type);
32600
32851
  definitionMap.set('decorators', metadata.decorators);
@@ -32702,7 +32953,7 @@ function createDirectiveDefinitionMap(meta) {
32702
32953
  // in 16.1 is actually used.
32703
32954
  const minVersion = hasTransformFunctions ? MINIMUM_PARTIAL_LINKER_VERSION$5 : '14.0.0';
32704
32955
  definitionMap.set('minVersion', literal(minVersion));
32705
- definitionMap.set('version', literal('17.1.0-next.0'));
32956
+ definitionMap.set('version', literal('17.1.0-next.2'));
32706
32957
  // e.g. `type: MyDirective`
32707
32958
  definitionMap.set('type', meta.type.value);
32708
32959
  if (meta.isStandalone) {
@@ -32979,7 +33230,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
32979
33230
  function compileDeclareFactoryFunction(meta) {
32980
33231
  const definitionMap = new DefinitionMap();
32981
33232
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
32982
- definitionMap.set('version', literal('17.1.0-next.0'));
33233
+ definitionMap.set('version', literal('17.1.0-next.2'));
32983
33234
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32984
33235
  definitionMap.set('type', meta.type.value);
32985
33236
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -33014,7 +33265,7 @@ function compileDeclareInjectableFromMetadata(meta) {
33014
33265
  function createInjectableDefinitionMap(meta) {
33015
33266
  const definitionMap = new DefinitionMap();
33016
33267
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
33017
- definitionMap.set('version', literal('17.1.0-next.0'));
33268
+ definitionMap.set('version', literal('17.1.0-next.2'));
33018
33269
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33019
33270
  definitionMap.set('type', meta.type.value);
33020
33271
  // Only generate providedIn property if it has a non-null value
@@ -33065,7 +33316,7 @@ function compileDeclareInjectorFromMetadata(meta) {
33065
33316
  function createInjectorDefinitionMap(meta) {
33066
33317
  const definitionMap = new DefinitionMap();
33067
33318
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
33068
- definitionMap.set('version', literal('17.1.0-next.0'));
33319
+ definitionMap.set('version', literal('17.1.0-next.2'));
33069
33320
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33070
33321
  definitionMap.set('type', meta.type.value);
33071
33322
  definitionMap.set('providers', meta.providers);
@@ -33098,7 +33349,7 @@ function createNgModuleDefinitionMap(meta) {
33098
33349
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
33099
33350
  }
33100
33351
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
33101
- definitionMap.set('version', literal('17.1.0-next.0'));
33352
+ definitionMap.set('version', literal('17.1.0-next.2'));
33102
33353
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33103
33354
  definitionMap.set('type', meta.type.value);
33104
33355
  // We only generate the keys in the metadata if the arrays contain values.
@@ -33149,7 +33400,7 @@ function compileDeclarePipeFromMetadata(meta) {
33149
33400
  function createPipeDefinitionMap(meta) {
33150
33401
  const definitionMap = new DefinitionMap();
33151
33402
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
33152
- definitionMap.set('version', literal('17.1.0-next.0'));
33403
+ definitionMap.set('version', literal('17.1.0-next.2'));
33153
33404
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33154
33405
  // e.g. `type: MyPipe`
33155
33406
  definitionMap.set('type', meta.type.value);
@@ -33182,5 +33433,5 @@ publishFacade(_global);
33182
33433
 
33183
33434
  // This file is not used to build this module. It is only used during editing
33184
33435
 
33185
- export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, ArrowFunctionExpr, AstMemoryEfficientTransformer, AstTransformer, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, Block, BlockParameter, BoundElementProperty, BuiltinType, BuiltinTypeName, CUSTOM_ELEMENTS_SCHEMA, Call, Chain, ChangeDetectionStrategy, CommaExpr, Comment, CompilerConfig, Conditional, ConditionalExpr, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DYNAMIC_TYPE, DeclareFunctionStmt, DeclareVarStmt, DomElementSchemaRegistry, DynamicImportExpr, EOF, Element, ElementSchemaRegistry, EmitterVisitorContext, EmptyExpr$1 as EmptyExpr, Expansion, ExpansionCase, Expression, ExpressionBinding, ExpressionStatement, ExpressionType, ExternalExpr, ExternalReference, FactoryTarget$1 as FactoryTarget, FunctionExpr, HtmlParser, HtmlTagDefinition, I18NHtmlParser, IfStmt, ImplicitReceiver, InstantiateExpr, Interpolation$1 as Interpolation, InterpolationConfig, InvokeFunctionExpr, JSDocComment, JitEvaluator, KeyedRead, KeyedWrite, LeadingComment, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser$1 as Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, R3BoundTarget, Identifiers as R3Identifiers, R3NgModuleMetadataKind, R3SelectorScopeMode, R3TargetBinder, R3TemplateDependencyKind, ReadKeyExpr, ReadPropExpr, ReadVarExpr, RecursiveAstVisitor, RecursiveVisitor, ResourceLoader, ReturnStatement, STRING_TYPE, SafeCall, SafeKeyedRead, SafePropertyRead, SelectorContext, SelectorListContext, SelectorMatcher, Serializer, SplitInterpolation, Statement, StmtModifier, TagContentType, TaggedTemplateExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, Text, ThisReceiver, BoundAttribute as TmplAstBoundAttribute, BoundDeferredTrigger as TmplAstBoundDeferredTrigger, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, DeferredBlock as TmplAstDeferredBlock, DeferredBlockError as TmplAstDeferredBlockError, DeferredBlockLoading as TmplAstDeferredBlockLoading, DeferredBlockPlaceholder as TmplAstDeferredBlockPlaceholder, DeferredTrigger as TmplAstDeferredTrigger, Element$1 as TmplAstElement, ForLoopBlock as TmplAstForLoopBlock, ForLoopBlockEmpty as TmplAstForLoopBlockEmpty, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, Icu$1 as TmplAstIcu, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, RecursiveVisitor$1 as TmplAstRecursiveVisitor, Reference as TmplAstReference, SwitchBlock as TmplAstSwitchBlock, SwitchBlockCase as TmplAstSwitchBlockCase, Template as TmplAstTemplate, Text$3 as TmplAstText, TextAttribute as TmplAstTextAttribute, TimerDeferredTrigger as TmplAstTimerDeferredTrigger, UnknownBlock as TmplAstUnknownBlock, Variable as TmplAstVariable, ViewportDeferredTrigger as TmplAstViewportDeferredTrigger, Token, TokenType, TransplantedType, TreeError, Type, TypeModifier, TypeofExpr, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, _ParseAST, compileClassDebugInfo, compileClassMetadata, compileComponentClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDirectiveFromMetadata, compileFactoryFunction, compileInjectable, compileInjector, compileNgModule, compilePipeFromMetadata, computeMsgId, core, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isIdentifier, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literal, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, verifyHostBindings, visitAll };
33436
+ export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, ArrowFunctionExpr, AstMemoryEfficientTransformer, AstTransformer, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, Block, BlockParameter, BoundElementProperty, BuiltinType, BuiltinTypeName, CUSTOM_ELEMENTS_SCHEMA, Call, Chain, ChangeDetectionStrategy, CommaExpr, Comment, CompilerConfig, Conditional, ConditionalExpr, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DYNAMIC_TYPE, DeclareFunctionStmt, DeclareVarStmt, DomElementSchemaRegistry, DynamicImportExpr, EOF, Element, ElementSchemaRegistry, EmitterVisitorContext, EmptyExpr$1 as EmptyExpr, Expansion, ExpansionCase, Expression, ExpressionBinding, ExpressionStatement, ExpressionType, ExternalExpr, ExternalReference, FactoryTarget$1 as FactoryTarget, FunctionExpr, HtmlParser, HtmlTagDefinition, I18NHtmlParser, IfStmt, ImplicitReceiver, InstantiateExpr, Interpolation$1 as Interpolation, InterpolationConfig, InvokeFunctionExpr, JSDocComment, JitEvaluator, KeyedRead, KeyedWrite, LeadingComment, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser$1 as Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, R3BoundTarget, Identifiers as R3Identifiers, R3NgModuleMetadataKind, R3SelectorScopeMode, R3TargetBinder, R3TemplateDependencyKind, ReadKeyExpr, ReadPropExpr, ReadVarExpr, RecursiveAstVisitor, RecursiveVisitor, ResourceLoader, ReturnStatement, STRING_TYPE, SafeCall, SafeKeyedRead, SafePropertyRead, SelectorContext, SelectorListContext, SelectorMatcher, Serializer, SplitInterpolation, Statement, StmtModifier, TagContentType, TaggedTemplateExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, Text, ThisReceiver, BoundAttribute as TmplAstBoundAttribute, BoundDeferredTrigger as TmplAstBoundDeferredTrigger, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, DeferredBlock as TmplAstDeferredBlock, DeferredBlockError as TmplAstDeferredBlockError, DeferredBlockLoading as TmplAstDeferredBlockLoading, DeferredBlockPlaceholder as TmplAstDeferredBlockPlaceholder, DeferredTrigger as TmplAstDeferredTrigger, Element$1 as TmplAstElement, ForLoopBlock as TmplAstForLoopBlock, ForLoopBlockEmpty as TmplAstForLoopBlockEmpty, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, Icu$1 as TmplAstIcu, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, RecursiveVisitor$1 as TmplAstRecursiveVisitor, Reference as TmplAstReference, SwitchBlock as TmplAstSwitchBlock, SwitchBlockCase as TmplAstSwitchBlockCase, Template as TmplAstTemplate, Text$3 as TmplAstText, TextAttribute as TmplAstTextAttribute, TimerDeferredTrigger as TmplAstTimerDeferredTrigger, UnknownBlock as TmplAstUnknownBlock, Variable as TmplAstVariable, ViewportDeferredTrigger as TmplAstViewportDeferredTrigger, Token, TokenType, TransplantedType, TreeError, Type, TypeModifier, TypeofExpr, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, _ParseAST, compileClassDebugInfo, compileClassMetadata, compileComponentClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDirectiveFromMetadata, compileFactoryFunction, compileInjectable, compileInjector, compileNgModule, compilePipeFromMetadata, computeMsgId, core, createCssSelectorFromNode, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isIdentifier, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literal, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, verifyHostBindings, visitAll };
33186
33437
  //# sourceMappingURL=compiler.mjs.map