@angular/compiler 20.0.0-next.5 → 20.0.0-next.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.0.0-next.5
2
+ * @license Angular v20.0.0-next.7
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -5068,17 +5068,19 @@ let Element$1 = class Element {
5068
5068
  attributes;
5069
5069
  inputs;
5070
5070
  outputs;
5071
+ directives;
5071
5072
  children;
5072
5073
  references;
5073
5074
  sourceSpan;
5074
5075
  startSourceSpan;
5075
5076
  endSourceSpan;
5076
5077
  i18n;
5077
- constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5078
+ constructor(name, attributes, inputs, outputs, directives, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5078
5079
  this.name = name;
5079
5080
  this.attributes = attributes;
5080
5081
  this.inputs = inputs;
5081
5082
  this.outputs = outputs;
5083
+ this.directives = directives;
5082
5084
  this.children = children;
5083
5085
  this.references = references;
5084
5086
  this.sourceSpan = sourceSpan;
@@ -5377,11 +5379,70 @@ let LetDeclaration$1 = class LetDeclaration {
5377
5379
  return visitor.visitLetDeclaration(this);
5378
5380
  }
5379
5381
  };
5382
+ let Component$1 = class Component {
5383
+ componentName;
5384
+ tagName;
5385
+ fullName;
5386
+ attributes;
5387
+ inputs;
5388
+ outputs;
5389
+ directives;
5390
+ children;
5391
+ references;
5392
+ sourceSpan;
5393
+ startSourceSpan;
5394
+ endSourceSpan;
5395
+ i18n;
5396
+ constructor(componentName, tagName, fullName, attributes, inputs, outputs, directives, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5397
+ this.componentName = componentName;
5398
+ this.tagName = tagName;
5399
+ this.fullName = fullName;
5400
+ this.attributes = attributes;
5401
+ this.inputs = inputs;
5402
+ this.outputs = outputs;
5403
+ this.directives = directives;
5404
+ this.children = children;
5405
+ this.references = references;
5406
+ this.sourceSpan = sourceSpan;
5407
+ this.startSourceSpan = startSourceSpan;
5408
+ this.endSourceSpan = endSourceSpan;
5409
+ this.i18n = i18n;
5410
+ }
5411
+ visit(visitor) {
5412
+ return visitor.visitComponent(this);
5413
+ }
5414
+ };
5415
+ let Directive$1 = class Directive {
5416
+ name;
5417
+ attributes;
5418
+ inputs;
5419
+ outputs;
5420
+ references;
5421
+ sourceSpan;
5422
+ startSourceSpan;
5423
+ endSourceSpan;
5424
+ i18n;
5425
+ constructor(name, attributes, inputs, outputs, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5426
+ this.name = name;
5427
+ this.attributes = attributes;
5428
+ this.inputs = inputs;
5429
+ this.outputs = outputs;
5430
+ this.references = references;
5431
+ this.sourceSpan = sourceSpan;
5432
+ this.startSourceSpan = startSourceSpan;
5433
+ this.endSourceSpan = endSourceSpan;
5434
+ this.i18n = i18n;
5435
+ }
5436
+ visit(visitor) {
5437
+ return visitor.visitDirective(this);
5438
+ }
5439
+ };
5380
5440
  class Template {
5381
5441
  tagName;
5382
5442
  attributes;
5383
5443
  inputs;
5384
5444
  outputs;
5445
+ directives;
5385
5446
  templateAttrs;
5386
5447
  children;
5387
5448
  references;
@@ -5395,11 +5456,12 @@ class Template {
5395
5456
  // `null` is a special case for when there is a structural directive on an `ng-template` so
5396
5457
  // the renderer can differentiate between the synthetic template and the one written in the
5397
5458
  // file.
5398
- tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5459
+ tagName, attributes, inputs, outputs, directives, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5399
5460
  this.tagName = tagName;
5400
5461
  this.attributes = attributes;
5401
5462
  this.inputs = inputs;
5402
5463
  this.outputs = outputs;
5464
+ this.directives = directives;
5403
5465
  this.templateAttrs = templateAttrs;
5404
5466
  this.children = children;
5405
5467
  this.references = references;
@@ -5418,13 +5480,17 @@ class Content {
5418
5480
  attributes;
5419
5481
  children;
5420
5482
  sourceSpan;
5483
+ startSourceSpan;
5484
+ endSourceSpan;
5421
5485
  i18n;
5422
5486
  name = 'ng-content';
5423
- constructor(selector, attributes, children, sourceSpan, i18n) {
5487
+ constructor(selector, attributes, children, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
5424
5488
  this.selector = selector;
5425
5489
  this.attributes = attributes;
5426
5490
  this.children = children;
5427
5491
  this.sourceSpan = sourceSpan;
5492
+ this.startSourceSpan = startSourceSpan;
5493
+ this.endSourceSpan = endSourceSpan;
5428
5494
  this.i18n = i18n;
5429
5495
  }
5430
5496
  visit(visitor) {
@@ -5507,6 +5573,7 @@ let RecursiveVisitor$1 = class RecursiveVisitor {
5507
5573
  visitAll$1(this, element.attributes);
5508
5574
  visitAll$1(this, element.inputs);
5509
5575
  visitAll$1(this, element.outputs);
5576
+ visitAll$1(this, element.directives);
5510
5577
  visitAll$1(this, element.children);
5511
5578
  visitAll$1(this, element.references);
5512
5579
  }
@@ -5514,6 +5581,7 @@ let RecursiveVisitor$1 = class RecursiveVisitor {
5514
5581
  visitAll$1(this, template.attributes);
5515
5582
  visitAll$1(this, template.inputs);
5516
5583
  visitAll$1(this, template.outputs);
5584
+ visitAll$1(this, template.directives);
5517
5585
  visitAll$1(this, template.children);
5518
5586
  visitAll$1(this, template.references);
5519
5587
  visitAll$1(this, template.variables);
@@ -5555,6 +5623,20 @@ let RecursiveVisitor$1 = class RecursiveVisitor {
5555
5623
  visitContent(content) {
5556
5624
  visitAll$1(this, content.children);
5557
5625
  }
5626
+ visitComponent(component) {
5627
+ visitAll$1(this, component.attributes);
5628
+ visitAll$1(this, component.inputs);
5629
+ visitAll$1(this, component.outputs);
5630
+ visitAll$1(this, component.directives);
5631
+ visitAll$1(this, component.children);
5632
+ visitAll$1(this, component.references);
5633
+ }
5634
+ visitDirective(directive) {
5635
+ visitAll$1(this, directive.attributes);
5636
+ visitAll$1(this, directive.inputs);
5637
+ visitAll$1(this, directive.outputs);
5638
+ visitAll$1(this, directive.references);
5639
+ }
5558
5640
  visitVariable(variable) { }
5559
5641
  visitReference(reference) { }
5560
5642
  visitTextAttribute(attribute) { }
@@ -6181,8 +6263,8 @@ const I18N_ICU_VAR_PREFIX = 'VAR_';
6181
6263
  function isI18nAttribute(name) {
6182
6264
  return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
6183
6265
  }
6184
- function hasI18nAttrs(element) {
6185
- return element.attrs.some((attr) => isI18nAttribute(attr.name));
6266
+ function hasI18nAttrs(node) {
6267
+ return node.attrs.some((attr) => isI18nAttribute(attr.name));
6186
6268
  }
6187
6269
  function icuFromI18nMessage(message) {
6188
6270
  return message.nodes[0];
@@ -13567,13 +13649,15 @@ class Attribute extends NodeWithI18n {
13567
13649
  class Element extends NodeWithI18n {
13568
13650
  name;
13569
13651
  attrs;
13652
+ directives;
13570
13653
  children;
13571
13654
  startSourceSpan;
13572
13655
  endSourceSpan;
13573
- constructor(name, attrs, children, sourceSpan, startSourceSpan, endSourceSpan = null, i18n) {
13656
+ constructor(name, attrs, directives, children, sourceSpan, startSourceSpan, endSourceSpan = null, i18n) {
13574
13657
  super(sourceSpan, i18n);
13575
13658
  this.name = name;
13576
13659
  this.attrs = attrs;
13660
+ this.directives = directives;
13577
13661
  this.children = children;
13578
13662
  this.startSourceSpan = startSourceSpan;
13579
13663
  this.endSourceSpan = endSourceSpan;
@@ -13613,6 +13697,47 @@ class Block extends NodeWithI18n {
13613
13697
  return visitor.visitBlock(this, context);
13614
13698
  }
13615
13699
  }
13700
+ class Component extends NodeWithI18n {
13701
+ componentName;
13702
+ tagName;
13703
+ fullName;
13704
+ attrs;
13705
+ directives;
13706
+ children;
13707
+ startSourceSpan;
13708
+ endSourceSpan;
13709
+ constructor(componentName, tagName, fullName, attrs, directives, children, sourceSpan, startSourceSpan, endSourceSpan = null, i18n) {
13710
+ super(sourceSpan, i18n);
13711
+ this.componentName = componentName;
13712
+ this.tagName = tagName;
13713
+ this.fullName = fullName;
13714
+ this.attrs = attrs;
13715
+ this.directives = directives;
13716
+ this.children = children;
13717
+ this.startSourceSpan = startSourceSpan;
13718
+ this.endSourceSpan = endSourceSpan;
13719
+ }
13720
+ visit(visitor, context) {
13721
+ return visitor.visitComponent(this, context);
13722
+ }
13723
+ }
13724
+ class Directive {
13725
+ name;
13726
+ attrs;
13727
+ sourceSpan;
13728
+ startSourceSpan;
13729
+ endSourceSpan;
13730
+ constructor(name, attrs, sourceSpan, startSourceSpan, endSourceSpan = null) {
13731
+ this.name = name;
13732
+ this.attrs = attrs;
13733
+ this.sourceSpan = sourceSpan;
13734
+ this.startSourceSpan = startSourceSpan;
13735
+ this.endSourceSpan = endSourceSpan;
13736
+ }
13737
+ visit(visitor, context) {
13738
+ return visitor.visitDirective(this, context);
13739
+ }
13740
+ }
13616
13741
  class BlockParameter {
13617
13742
  expression;
13618
13743
  sourceSpan;
@@ -13659,6 +13784,7 @@ class RecursiveVisitor {
13659
13784
  visitElement(ast, context) {
13660
13785
  this.visitChildren(context, (visit) => {
13661
13786
  visit(ast.attrs);
13787
+ visit(ast.directives);
13662
13788
  visit(ast.children);
13663
13789
  });
13664
13790
  }
@@ -13679,6 +13805,17 @@ class RecursiveVisitor {
13679
13805
  }
13680
13806
  visitBlockParameter(ast, context) { }
13681
13807
  visitLetDeclaration(decl, context) { }
13808
+ visitComponent(component, context) {
13809
+ this.visitChildren(context, (visit) => {
13810
+ visit(component.attrs);
13811
+ visit(component.children);
13812
+ });
13813
+ }
13814
+ visitDirective(directive, context) {
13815
+ this.visitChildren(context, (visit) => {
13816
+ visit(directive.attrs);
13817
+ });
13818
+ }
13682
13819
  visitChildren(context, cb) {
13683
13820
  let results = [];
13684
13821
  let t = this;
@@ -15882,11 +16019,13 @@ class _Tokenizer {
15882
16019
  _currentTokenStart = null;
15883
16020
  _currentTokenType = null;
15884
16021
  _expansionCaseStack = [];
16022
+ _openDirectiveCount = 0;
15885
16023
  _inInterpolation = false;
15886
16024
  _preserveLineEndings;
15887
16025
  _i18nNormalizeLineEndingsInICUs;
15888
16026
  _tokenizeBlocks;
15889
16027
  _tokenizeLet;
16028
+ _selectorlessEnabled;
15890
16029
  tokens = [];
15891
16030
  errors = [];
15892
16031
  nonNormalizedIcuExpressions = [];
@@ -15914,6 +16053,7 @@ class _Tokenizer {
15914
16053
  this._i18nNormalizeLineEndingsInICUs = options.i18nNormalizeLineEndingsInICUs || false;
15915
16054
  this._tokenizeBlocks = options.tokenizeBlocks ?? true;
15916
16055
  this._tokenizeLet = options.tokenizeLet ?? true;
16056
+ this._selectorlessEnabled = options.selectorlessEnabled ?? false;
15917
16057
  try {
15918
16058
  this._cursor.init();
15919
16059
  }
@@ -15982,7 +16122,7 @@ class _Tokenizer {
15982
16122
  this.handleError(e);
15983
16123
  }
15984
16124
  }
15985
- this._beginToken(33 /* TokenType.EOF */);
16125
+ this._beginToken(41 /* TokenType.EOF */);
15986
16126
  this._endToken([]);
15987
16127
  }
15988
16128
  _getBlockName() {
@@ -16381,7 +16521,7 @@ class _Tokenizer {
16381
16521
  this._cursor.advance();
16382
16522
  this._endToken([content]);
16383
16523
  }
16384
- _consumePrefixAndName() {
16524
+ _consumePrefixAndName(endPredicate) {
16385
16525
  const nameOrPrefixStart = this._cursor.clone();
16386
16526
  let prefix = '';
16387
16527
  while (this._cursor.peek() !== $COLON && !isPrefixEnd(this._cursor.peek())) {
@@ -16396,41 +16536,64 @@ class _Tokenizer {
16396
16536
  else {
16397
16537
  nameStart = nameOrPrefixStart;
16398
16538
  }
16399
- this._requireCharCodeUntilFn(isNameEnd, prefix === '' ? 0 : 1);
16539
+ this._requireCharCodeUntilFn(endPredicate, prefix === '' ? 0 : 1);
16400
16540
  const name = this._cursor.getChars(nameStart);
16401
16541
  return [prefix, name];
16402
16542
  }
16403
16543
  _consumeTagOpen(start) {
16404
16544
  let tagName;
16405
16545
  let prefix;
16406
- let openTagToken;
16546
+ let closingTagName;
16547
+ let openToken;
16407
16548
  try {
16408
- if (!isAsciiLetter(this._cursor.peek())) {
16409
- throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start));
16410
- }
16411
- openTagToken = this._consumeTagOpenStart(start);
16412
- prefix = openTagToken.parts[0];
16413
- tagName = openTagToken.parts[1];
16414
- this._attemptCharCodeUntilFn(isNotWhitespace);
16415
- while (this._cursor.peek() !== $SLASH &&
16416
- this._cursor.peek() !== $GT &&
16417
- this._cursor.peek() !== $LT &&
16418
- this._cursor.peek() !== $EOF) {
16419
- this._consumeAttributeName();
16549
+ if (this._selectorlessEnabled && isSelectorlessNameStart(this._cursor.peek())) {
16550
+ openToken = this._consumeComponentOpenStart(start);
16551
+ [closingTagName, prefix, tagName] = openToken.parts;
16552
+ if (prefix) {
16553
+ closingTagName += `:${prefix}`;
16554
+ }
16555
+ if (tagName) {
16556
+ closingTagName += `:${tagName}`;
16557
+ }
16420
16558
  this._attemptCharCodeUntilFn(isNotWhitespace);
16421
- if (this._attemptCharCode($EQ)) {
16422
- this._attemptCharCodeUntilFn(isNotWhitespace);
16423
- this._consumeAttributeValue();
16559
+ }
16560
+ else {
16561
+ if (!isAsciiLetter(this._cursor.peek())) {
16562
+ throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start));
16424
16563
  }
16564
+ openToken = this._consumeTagOpenStart(start);
16565
+ prefix = openToken.parts[0];
16566
+ tagName = closingTagName = openToken.parts[1];
16425
16567
  this._attemptCharCodeUntilFn(isNotWhitespace);
16426
16568
  }
16427
- this._consumeTagOpenEnd();
16569
+ while (!isAttributeTerminator(this._cursor.peek())) {
16570
+ if (this._selectorlessEnabled && this._cursor.peek() === $AT) {
16571
+ const start = this._cursor.clone();
16572
+ const nameStart = start.clone();
16573
+ nameStart.advance();
16574
+ if (isSelectorlessNameStart(nameStart.peek())) {
16575
+ this._consumeDirective(start, nameStart);
16576
+ }
16577
+ }
16578
+ else {
16579
+ this._consumeAttribute();
16580
+ }
16581
+ }
16582
+ if (openToken.type === 33 /* TokenType.COMPONENT_OPEN_START */) {
16583
+ this._consumeComponentOpenEnd();
16584
+ }
16585
+ else {
16586
+ this._consumeTagOpenEnd();
16587
+ }
16428
16588
  }
16429
16589
  catch (e) {
16430
16590
  if (e instanceof _ControlFlowError) {
16431
- if (openTagToken) {
16591
+ if (openToken) {
16432
16592
  // We errored before we could close the opening tag, so it is incomplete.
16433
- openTagToken.type = 4 /* TokenType.INCOMPLETE_TAG_OPEN */;
16593
+ openToken.type =
16594
+ openToken.type === 33 /* TokenType.COMPONENT_OPEN_START */
16595
+ ? 37 /* TokenType.INCOMPLETE_COMPONENT_OPEN */
16596
+ : 4 /* TokenType.INCOMPLETE_TAG_OPEN */;
16434
16597
  }
16435
16598
  else {
16436
16599
  // When the start tag is invalid, assume we want a "<" as text.
@@ -16444,13 +16607,13 @@ class _Tokenizer {
16444
16607
  }
16445
16608
  const contentTokenType = this._getTagDefinition(tagName).getContentType(prefix);
16446
16609
  if (contentTokenType === TagContentType.RAW_TEXT) {
16447
- this._consumeRawTextWithTagClose(prefix, tagName, false);
16610
+ this._consumeRawTextWithTagClose(openToken, closingTagName, false);
16448
16611
  }
16449
16612
  else if (contentTokenType === TagContentType.ESCAPABLE_RAW_TEXT) {
16450
- this._consumeRawTextWithTagClose(prefix, tagName, true);
16613
+ this._consumeRawTextWithTagClose(openToken, closingTagName, true);
16451
16614
  }
16452
16615
  }
16453
- _consumeRawTextWithTagClose(prefix, tagName, consumeEntities) {
16616
+ _consumeRawTextWithTagClose(openToken, tagName, consumeEntities) {
16454
16617
  this._consumeRawText(consumeEntities, () => {
16455
16618
  if (!this._attemptCharCode($LT))
16456
16619
  return false;
@@ -16462,23 +16625,79 @@ class _Tokenizer {
16462
16625
  this._attemptCharCodeUntilFn(isNotWhitespace);
16463
16626
  return this._attemptCharCode($GT);
16464
16627
  });
16465
- this._beginToken(3 /* TokenType.TAG_CLOSE */);
16628
+ this._beginToken(openToken.type === 33 /* TokenType.COMPONENT_OPEN_START */
16629
+ ? 36 /* TokenType.COMPONENT_CLOSE */
16630
+ : 3 /* TokenType.TAG_CLOSE */);
16466
16631
  this._requireCharCodeUntilFn((code) => code === $GT, 3);
16467
16632
  this._cursor.advance(); // Consume the `>`
16468
- this._endToken([prefix, tagName]);
16633
+ this._endToken(openToken.parts);
16469
16634
  }
16470
16635
  _consumeTagOpenStart(start) {
16471
16636
  this._beginToken(0 /* TokenType.TAG_OPEN_START */, start);
16472
- const parts = this._consumePrefixAndName();
16637
+ const parts = this._consumePrefixAndName(isNameEnd);
16473
16638
  return this._endToken(parts);
16474
16639
  }
16640
+ _consumeComponentOpenStart(start) {
16641
+ this._beginToken(33 /* TokenType.COMPONENT_OPEN_START */, start);
16642
+ const parts = this._consumeComponentName();
16643
+ return this._endToken(parts);
16644
+ }
16645
+ _consumeComponentName() {
16646
+ const nameStart = this._cursor.clone();
16647
+ while (isSelectorlessNameChar(this._cursor.peek())) {
16648
+ this._cursor.advance();
16649
+ }
16650
+ const name = this._cursor.getChars(nameStart);
16651
+ let prefix = '';
16652
+ let tagName = '';
16653
+ if (this._cursor.peek() === $COLON) {
16654
+ this._cursor.advance();
16655
+ [prefix, tagName] = this._consumePrefixAndName(isNameEnd);
16656
+ }
16657
+ return [name, prefix, tagName];
16658
+ }
16659
+ _consumeAttribute() {
16660
+ this._consumeAttributeName();
16661
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16662
+ if (this._attemptCharCode($EQ)) {
16663
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16664
+ this._consumeAttributeValue();
16665
+ }
16666
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16667
+ }
16475
16668
  _consumeAttributeName() {
16476
16669
  const attrNameStart = this._cursor.peek();
16477
16670
  if (attrNameStart === $SQ || attrNameStart === $DQ) {
16478
16671
  throw this._createError(_unexpectedCharacterErrorMsg(attrNameStart), this._cursor.getSpan());
16479
16672
  }
16480
16673
  this._beginToken(14 /* TokenType.ATTR_NAME */);
16481
- const prefixAndName = this._consumePrefixAndName();
16674
+ let nameEndPredicate;
16675
+ if (this._openDirectiveCount > 0) {
16676
+ // If we're parsing attributes inside of directive syntax, we have to terminate the name
16677
+ // on the first non-matching closing paren. For example, if we have `@Dir(someAttr)`,
16678
+ // `@Dir` and `(` will have already been captured as `DIRECTIVE_NAME` and `DIRECTIVE_OPEN`
16679
+ // respectively, but the `)` will get captured as a part of the name for `someAttr`
16680
+ // because normally that would be an event binding.
16681
+ let openParens = 0;
16682
+ nameEndPredicate = (code) => {
16683
+ if (this._openDirectiveCount > 0) {
16684
+ if (code === $LPAREN) {
16685
+ openParens++;
16686
+ }
16687
+ else if (code === $RPAREN) {
16688
+ if (openParens === 0) {
16689
+ return true;
16690
+ }
16691
+ openParens--;
16692
+ }
16693
+ }
16694
+ return isNameEnd(code);
16695
+ };
16696
+ }
16697
+ else {
16698
+ nameEndPredicate = isNameEnd;
16699
+ }
16700
+ const prefixAndName = this._consumePrefixAndName(nameEndPredicate);
16482
16701
  this._endToken(prefixAndName);
16483
16702
  }
16484
16703
  _consumeAttributeValue() {
@@ -16509,10 +16728,32 @@ class _Tokenizer {
16509
16728
  this._requireCharCode($GT);
16510
16729
  this._endToken([]);
16511
16730
  }
16731
+ _consumeComponentOpenEnd() {
16732
+ const tokenType = this._attemptCharCode($SLASH)
16733
+ ? 35 /* TokenType.COMPONENT_OPEN_END_VOID */
16734
+ : 34 /* TokenType.COMPONENT_OPEN_END */;
16735
+ this._beginToken(tokenType);
16736
+ this._requireCharCode($GT);
16737
+ this._endToken([]);
16738
+ }
16512
16739
  _consumeTagClose(start) {
16740
+ if (this._selectorlessEnabled) {
16741
+ const clone = start.clone();
16742
+ while (clone.peek() !== $GT && !isSelectorlessNameStart(clone.peek())) {
16743
+ clone.advance();
16744
+ }
16745
+ if (isSelectorlessNameStart(clone.peek())) {
16746
+ this._beginToken(36 /* TokenType.COMPONENT_CLOSE */, start);
16747
+ const parts = this._consumeComponentName();
16748
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16749
+ this._requireCharCode($GT);
16750
+ this._endToken(parts);
16751
+ return;
16752
+ }
16753
+ }
16513
16754
  this._beginToken(3 /* TokenType.TAG_CLOSE */, start);
16514
16755
  this._attemptCharCodeUntilFn(isNotWhitespace);
16515
- const prefixAndName = this._consumePrefixAndName();
16756
+ const prefixAndName = this._consumePrefixAndName(isNameEnd);
16516
16757
  this._attemptCharCodeUntilFn(isNotWhitespace);
16517
16758
  this._requireCharCode($GT);
16518
16759
  this._endToken(prefixAndName);
@@ -16668,6 +16909,50 @@ class _Tokenizer {
16668
16909
  parts.push(this._getProcessedChars(expressionStart, this._cursor));
16669
16910
  this._endToken(parts);
16670
16911
  }
16912
+ _consumeDirective(start, nameStart) {
16913
+ this._requireCharCode($AT);
16914
+ // Skip over the @ since it's not part of the name.
16915
+ this._cursor.advance();
16916
+ // Capture the rest of the name.
16917
+ while (isSelectorlessNameChar(this._cursor.peek())) {
16918
+ this._cursor.advance();
16919
+ }
16920
+ // Capture the opening token.
16921
+ this._beginToken(38 /* TokenType.DIRECTIVE_NAME */, start);
16922
+ const name = this._cursor.getChars(nameStart);
16923
+ this._endToken([name]);
16924
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16925
+ // Optionally there might be attributes bound to the specific directive.
16926
+ // Stop parsing if there's no opening character for them.
16927
+ if (this._cursor.peek() !== $LPAREN) {
16928
+ return;
16929
+ }
16930
+ this._openDirectiveCount++;
16931
+ this._beginToken(39 /* TokenType.DIRECTIVE_OPEN */);
16932
+ this._cursor.advance();
16933
+ this._endToken([]);
16934
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16935
+ // Capture all the attributes until we hit a closing paren.
16936
+ while (!isAttributeTerminator(this._cursor.peek()) && this._cursor.peek() !== $RPAREN) {
16937
+ this._consumeAttribute();
16938
+ }
16939
+ // Trim any trailing whitespace.
16940
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16941
+ this._openDirectiveCount--;
16942
+ if (this._cursor.peek() !== $RPAREN) {
16943
+ // Stop parsing, instead of throwing, if we've hit the end of the tag.
16944
+ // This can be handled better later when turning the tokens into AST.
16945
+ if (this._cursor.peek() === $GT || this._cursor.peek() === $SLASH) {
16946
+ return;
16947
+ }
16948
+ throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start));
16949
+ }
16950
+ // Capture the closing token.
16951
+ this._beginToken(40 /* TokenType.DIRECTIVE_CLOSE */);
16952
+ this._cursor.advance();
16953
+ this._endToken([]);
16954
+ this._attemptCharCodeUntilFn(isNotWhitespace);
16955
+ }
16671
16956
  _getProcessedChars(start, end) {
16672
16957
  return this._processCarriageReturns(end.getChars(start));
16673
16958
  }
@@ -16783,6 +17068,15 @@ function isBlockNameChar(code) {
16783
17068
  function isBlockParameterChar(code) {
16784
17069
  return code !== $SEMICOLON && isNotWhitespace(code);
16785
17070
  }
17071
+ function isSelectorlessNameStart(code) {
17072
+ return code === $_ || (code >= $A && code <= $Z);
17073
+ }
17074
+ function isSelectorlessNameChar(code) {
17075
+ return isAsciiLetter(code) || isDigit(code) || code === $_;
17076
+ }
17077
+ function isAttributeTerminator(code) {
17078
+ return code === $SLASH || code === $GT || code === $LT || code === $EOF;
17079
+ }
16786
17080
  function mergeTextTokens(srcTokens) {
16787
17081
  const dstTokens = [];
16788
17082
  let lastDstToken = undefined;
@@ -17079,26 +17373,26 @@ let Parser$1 = class Parser {
17079
17373
  };
17080
17374
  class _TreeBuilder {
17081
17375
  tokens;
17082
- getTagDefinition;
17376
+ tagDefinitionResolver;
17083
17377
  _index = -1;
17084
17378
  // `_peek` will be initialized by the call to `_advance()` in the constructor.
17085
17379
  _peek;
17086
17380
  _containerStack = [];
17087
17381
  rootNodes = [];
17088
17382
  errors = [];
17089
- constructor(tokens, getTagDefinition) {
17383
+ constructor(tokens, tagDefinitionResolver) {
17090
17384
  this.tokens = tokens;
17091
- this.getTagDefinition = getTagDefinition;
17385
+ this.tagDefinitionResolver = tagDefinitionResolver;
17092
17386
  this._advance();
17093
17387
  }
17094
17388
  build() {
17095
- while (this._peek.type !== 33 /* TokenType.EOF */) {
17389
+ while (this._peek.type !== 41 /* TokenType.EOF */) {
17096
17390
  if (this._peek.type === 0 /* TokenType.TAG_OPEN_START */ ||
17097
17391
  this._peek.type === 4 /* TokenType.INCOMPLETE_TAG_OPEN */) {
17098
- this._consumeStartTag(this._advance());
17392
+ this._consumeElementStartTag(this._advance());
17099
17393
  }
17100
17394
  else if (this._peek.type === 3 /* TokenType.TAG_CLOSE */) {
17101
- this._consumeEndTag(this._advance());
17395
+ this._consumeElementEndTag(this._advance());
17102
17396
  }
17103
17397
  else if (this._peek.type === 12 /* TokenType.CDATA_START */) {
17104
17398
  this._closeVoidElement();
@@ -17137,6 +17431,13 @@ class _TreeBuilder {
17137
17431
  this._closeVoidElement();
17138
17432
  this._consumeIncompleteLet(this._advance());
17139
17433
  }
17434
+ else if (this._peek.type === 33 /* TokenType.COMPONENT_OPEN_START */ ||
17435
+ this._peek.type === 37 /* TokenType.INCOMPLETE_COMPONENT_OPEN */) {
17436
+ this._consumeComponentStartTag(this._advance());
17437
+ }
17438
+ else if (this._peek.type === 36 /* TokenType.COMPONENT_CLOSE */) {
17439
+ this._consumeComponentEndTag(this._advance());
17440
+ }
17140
17441
  else {
17141
17442
  // Skip all other tokens...
17142
17443
  this._advance();
@@ -17210,9 +17511,9 @@ class _TreeBuilder {
17210
17511
  if (!exp)
17211
17512
  return null;
17212
17513
  const end = this._advance();
17213
- exp.push({ type: 33 /* TokenType.EOF */, parts: [], sourceSpan: end.sourceSpan });
17514
+ exp.push({ type: 41 /* TokenType.EOF */, parts: [], sourceSpan: end.sourceSpan });
17214
17515
  // parse everything in between { and }
17215
- const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
17516
+ const expansionCaseParser = new _TreeBuilder(exp, this.tagDefinitionResolver);
17216
17517
  expansionCaseParser.build();
17217
17518
  if (expansionCaseParser.errors.length > 0) {
17218
17519
  this.errors = this.errors.concat(expansionCaseParser.errors);
@@ -17250,7 +17551,7 @@ class _TreeBuilder {
17250
17551
  return null;
17251
17552
  }
17252
17553
  }
17253
- if (this._peek.type === 33 /* TokenType.EOF */) {
17554
+ if (this._peek.type === 41 /* TokenType.EOF */) {
17254
17555
  this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
17255
17556
  return null;
17256
17557
  }
@@ -17265,7 +17566,7 @@ class _TreeBuilder {
17265
17566
  const parent = this._getContainer();
17266
17567
  if (parent != null &&
17267
17568
  parent.children.length === 0 &&
17268
- this.getTagDefinition(parent.name).ignoreFirstLf) {
17569
+ this._getTagDefinition(parent)?.ignoreFirstLf) {
17269
17570
  text = text.substring(1);
17270
17571
  tokens[0] = { type: token.type, sourceSpan: token.sourceSpan, parts: [text] };
17271
17572
  }
@@ -17296,25 +17597,23 @@ class _TreeBuilder {
17296
17597
  }
17297
17598
  _closeVoidElement() {
17298
17599
  const el = this._getContainer();
17299
- if (el instanceof Element && this.getTagDefinition(el.name).isVoid) {
17600
+ if (el !== null && this._getTagDefinition(el)?.isVoid) {
17300
17601
  this._containerStack.pop();
17301
17602
  }
17302
17603
  }
17303
- _consumeStartTag(startTagToken) {
17304
- const [prefix, name] = startTagToken.parts;
17604
+ _consumeElementStartTag(startTagToken) {
17305
17605
  const attrs = [];
17306
- while (this._peek.type === 14 /* TokenType.ATTR_NAME */) {
17307
- attrs.push(this._consumeAttr(this._advance()));
17308
- }
17309
- const fullName = this._getElementFullName(prefix, name, this._getClosestParentElement());
17606
+ const directives = [];
17607
+ this._consumeAttributesAndDirectives(attrs, directives);
17608
+ const fullName = this._getElementFullName(startTagToken, this._getClosestElementLikeParent());
17310
17609
  let selfClosing = false;
17311
17610
  // Note: There could have been a tokenizer error
17312
17611
  // so that we don't get a token for the end tag...
17313
17612
  if (this._peek.type === 2 /* TokenType.TAG_OPEN_END_VOID */) {
17314
17613
  this._advance();
17315
17614
  selfClosing = true;
17316
- const tagDef = this.getTagDefinition(fullName);
17317
- if (!(tagDef.canSelfClose || getNsPrefix(fullName) !== null || tagDef.isVoid)) {
17615
+ const tagDef = this._getTagDefinition(fullName);
17616
+ if (!(tagDef?.canSelfClose || getNsPrefix(fullName) !== null || tagDef?.isVoid)) {
17318
17617
  this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void, custom and foreign elements can be self closed "${startTagToken.parts[1]}"`));
17319
17618
  }
17320
17619
  }
@@ -17326,10 +17625,10 @@ class _TreeBuilder {
17326
17625
  const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
17327
17626
  // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
17328
17627
  const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
17329
- const el = new Element(fullName, attrs, [], span, startSpan, undefined);
17330
- const parentEl = this._getContainer();
17331
- this._pushContainer(el, parentEl instanceof Element &&
17332
- this.getTagDefinition(parentEl.name).isClosedByChild(el.name));
17628
+ const el = new Element(fullName, attrs, directives, [], span, startSpan, undefined);
17629
+ const parent = this._getContainer();
17630
+ const isClosedByChild = parent !== null && !!this._getTagDefinition(parent)?.isClosedByChild(el.name);
17631
+ this._pushContainer(el, isClosedByChild);
17333
17632
  if (selfClosing) {
17334
17633
  // Elements that are self-closed have their `endSourceSpan` set to the full span, as the
17335
17634
  // element start tag also represents the end tag.
@@ -17342,6 +17641,73 @@ class _TreeBuilder {
17342
17641
  this.errors.push(TreeError.create(fullName, span, `Opening tag "${fullName}" not terminated.`));
17343
17642
  }
17344
17643
  }
17644
+ _consumeComponentStartTag(startToken) {
17645
+ const componentName = startToken.parts[0];
17646
+ const attrs = [];
17647
+ const directives = [];
17648
+ this._consumeAttributesAndDirectives(attrs, directives);
17649
+ const closestElement = this._getClosestElementLikeParent();
17650
+ const tagName = this._getComponentTagName(startToken, closestElement);
17651
+ const fullName = this._getComponentFullName(startToken, closestElement);
17652
+ const selfClosing = this._peek.type === 35 /* TokenType.COMPONENT_OPEN_END_VOID */;
17653
+ this._advance();
17654
+ const end = this._peek.sourceSpan.fullStart;
17655
+ const span = new ParseSourceSpan(startToken.sourceSpan.start, end, startToken.sourceSpan.fullStart);
17656
+ const startSpan = new ParseSourceSpan(startToken.sourceSpan.start, end, startToken.sourceSpan.fullStart);
17657
+ const node = new Component(componentName, tagName, fullName, attrs, directives, [], span, startSpan, undefined);
17658
+ const parent = this._getContainer();
17659
+ const isClosedByChild = parent !== null &&
17660
+ node.tagName !== null &&
17661
+ !!this._getTagDefinition(parent)?.isClosedByChild(node.tagName);
17662
+ this._pushContainer(node, isClosedByChild);
17663
+ if (selfClosing) {
17664
+ this._popContainer(fullName, Component, span);
17665
+ }
17666
+ else if (startToken.type === 37 /* TokenType.INCOMPLETE_COMPONENT_OPEN */) {
17667
+ this._popContainer(fullName, Component, null);
17668
+ this.errors.push(TreeError.create(fullName, span, `Opening tag "${fullName}" not terminated.`));
17669
+ }
17670
+ }
17671
+ _consumeAttributesAndDirectives(attributesResult, directivesResult) {
17672
+ while (this._peek.type === 14 /* TokenType.ATTR_NAME */ ||
17673
+ this._peek.type === 38 /* TokenType.DIRECTIVE_NAME */) {
17674
+ if (this._peek.type === 38 /* TokenType.DIRECTIVE_NAME */) {
17675
+ directivesResult.push(this._consumeDirective(this._peek));
17676
+ }
17677
+ else {
17678
+ attributesResult.push(this._consumeAttr(this._advance()));
17679
+ }
17680
+ }
17681
+ }
17682
+ _consumeComponentEndTag(endToken) {
17683
+ const fullName = this._getComponentFullName(endToken, this._getClosestElementLikeParent());
17684
+ if (!this._popContainer(fullName, Component, endToken.sourceSpan)) {
17685
+ const container = this._containerStack[this._containerStack.length - 1];
17686
+ let suffix;
17687
+ if (container instanceof Component && container.componentName === endToken.parts[0]) {
17688
+ suffix = `, did you mean "${container.fullName}"?`;
17689
+ }
17690
+ else {
17691
+ suffix = '. It may happen when the tag has already been closed by another tag.';
17692
+ }
17693
+ const errMsg = `Unexpected closing tag "${fullName}"${suffix}`;
17694
+ this.errors.push(TreeError.create(fullName, endToken.sourceSpan, errMsg));
17695
+ }
17696
+ }
17697
+ _getTagDefinition(nodeOrName) {
17698
+ if (typeof nodeOrName === 'string') {
17699
+ return this.tagDefinitionResolver(nodeOrName);
17700
+ }
17701
+ else if (nodeOrName instanceof Element) {
17702
+ return this.tagDefinitionResolver(nodeOrName.name);
17703
+ }
17704
+ else if (nodeOrName instanceof Component && nodeOrName.tagName !== null) {
17705
+ return this.tagDefinitionResolver(nodeOrName.tagName);
17706
+ }
17707
+ else {
17708
+ return null;
17709
+ }
17710
+ }
17345
17711
  _pushContainer(node, isClosedByChild) {
17346
17712
  if (isClosedByChild) {
17347
17713
  this._containerStack.pop();
@@ -17349,9 +17715,9 @@ class _TreeBuilder {
17349
17715
  this._addToParent(node);
17350
17716
  this._containerStack.push(node);
17351
17717
  }
17352
- _consumeEndTag(endTagToken) {
17353
- const fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getClosestParentElement());
17354
- if (this.getTagDefinition(fullName).isVoid) {
17718
+ _consumeElementEndTag(endTagToken) {
17719
+ const fullName = this._getElementFullName(endTagToken, this._getClosestElementLikeParent());
17720
+ if (this._getTagDefinition(fullName)?.isVoid) {
17355
17721
  this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, `Void elements do not have end tags "${endTagToken.parts[1]}"`));
17356
17722
  }
17357
17723
  else if (!this._popContainer(fullName, Element, endTagToken.sourceSpan)) {
@@ -17369,7 +17735,8 @@ class _TreeBuilder {
17369
17735
  let unexpectedCloseTagDetected = false;
17370
17736
  for (let stackIndex = this._containerStack.length - 1; stackIndex >= 0; stackIndex--) {
17371
17737
  const node = this._containerStack[stackIndex];
17372
- if ((node.name === expectedName || expectedName === null) && node instanceof expectedType) {
17738
+ const nodeName = node instanceof Component ? node.fullName : node.name;
17739
+ if ((nodeName === expectedName || expectedName === null) && node instanceof expectedType) {
17373
17740
  // Record the parse span with the element that is being closed. Any elements that are
17374
17741
  // removed from the element stack at this point are closed implicitly, so they won't get
17375
17742
  // an end source span (as there is no explicit closing element).
@@ -17379,8 +17746,7 @@ class _TreeBuilder {
17379
17746
  return !unexpectedCloseTagDetected;
17380
17747
  }
17381
17748
  // Blocks and most elements are not self closing.
17382
- if (node instanceof Block ||
17383
- (node instanceof Element && !this.getTagDefinition(node.name).closedByParent)) {
17749
+ if (node instanceof Block || !this._getTagDefinition(node)?.closedByParent) {
17384
17750
  // Note that we encountered an unexpected close tag but continue processing the element
17385
17751
  // stack so we can assign an `endSourceSpan` if there is a corresponding start tag for this
17386
17752
  // end tag in the stack.
@@ -17440,6 +17806,31 @@ class _TreeBuilder {
17440
17806
  new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
17441
17807
  return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
17442
17808
  }
17809
+ _consumeDirective(nameToken) {
17810
+ const attributes = [];
17811
+ let startSourceSpanEnd = nameToken.sourceSpan.end;
17812
+ let endSourceSpan = null;
17813
+ this._advance();
17814
+ if (this._peek.type === 39 /* TokenType.DIRECTIVE_OPEN */) {
17815
+ // Capture the opening token in the start span.
17816
+ startSourceSpanEnd = this._peek.sourceSpan.end;
17817
+ this._advance();
17818
+ // Cast here is necessary, because TS doesn't know that `_advance` changed `_peek`.
17819
+ while (this._peek.type === 14 /* TokenType.ATTR_NAME */) {
17820
+ attributes.push(this._consumeAttr(this._advance()));
17821
+ }
17822
+ if (this._peek.type === 40 /* TokenType.DIRECTIVE_CLOSE */) {
17823
+ endSourceSpan = this._peek.sourceSpan;
17824
+ this._advance();
17825
+ }
17826
+ else {
17827
+ this.errors.push(TreeError.create(null, nameToken.sourceSpan, 'Unterminated directive definition'));
17828
+ }
17829
+ }
17830
+ const startSourceSpan = new ParseSourceSpan(nameToken.sourceSpan.start, startSourceSpanEnd, nameToken.sourceSpan.fullStart);
17831
+ const sourceSpan = new ParseSourceSpan(startSourceSpan.start, endSourceSpan === null ? nameToken.sourceSpan.end : endSourceSpan.end, startSourceSpan.fullStart);
17832
+ return new Directive(nameToken.parts[0], attributes, sourceSpan, startSourceSpan, endSourceSpan);
17833
+ }
17443
17834
  _consumeBlockOpen(token) {
17444
17835
  const parameters = [];
17445
17836
  while (this._peek.type === 27 /* TokenType.BLOCK_PARAMETER */) {
@@ -17530,10 +17921,11 @@ class _TreeBuilder {
17530
17921
  ? this._containerStack[this._containerStack.length - 1]
17531
17922
  : null;
17532
17923
  }
17533
- _getClosestParentElement() {
17924
+ _getClosestElementLikeParent() {
17534
17925
  for (let i = this._containerStack.length - 1; i > -1; i--) {
17535
- if (this._containerStack[i] instanceof Element) {
17536
- return this._containerStack[i];
17926
+ const current = this._containerStack[i];
17927
+ if (current instanceof Element || current instanceof Component) {
17928
+ return current;
17537
17929
  }
17538
17930
  }
17539
17931
  return null;
@@ -17547,18 +17939,57 @@ class _TreeBuilder {
17547
17939
  parent.children.push(node);
17548
17940
  }
17549
17941
  }
17550
- _getElementFullName(prefix, localName, parentElement) {
17551
- if (prefix === '') {
17552
- prefix = this.getTagDefinition(localName).implicitNamespacePrefix || '';
17553
- if (prefix === '' && parentElement != null) {
17554
- const parentTagName = splitNsName(parentElement.name)[1];
17555
- const parentTagDefinition = this.getTagDefinition(parentTagName);
17556
- if (!parentTagDefinition.preventNamespaceInheritance) {
17557
- prefix = getNsPrefix(parentElement.name);
17942
+ _getElementFullName(token, parent) {
17943
+ const prefix = this._getPrefix(token, parent);
17944
+ return mergeNsAndName(prefix, token.parts[1]);
17945
+ }
17946
+ _getComponentFullName(token, parent) {
17947
+ const componentName = token.parts[0];
17948
+ const tagName = this._getComponentTagName(token, parent);
17949
+ if (tagName === null) {
17950
+ return componentName;
17951
+ }
17952
+ return tagName.startsWith(':') ? componentName + tagName : `${componentName}:${tagName}`;
17953
+ }
17954
+ _getComponentTagName(token, parent) {
17955
+ const prefix = this._getPrefix(token, parent);
17956
+ const tagName = token.parts[2];
17957
+ if (!prefix && !tagName) {
17958
+ return null;
17959
+ }
17960
+ else if (!prefix && tagName) {
17961
+ return tagName;
17962
+ }
17963
+ else {
17964
+ // TODO(crisbeto): re-evaluate this fallback. Maybe base it off the class name?
17965
+ return mergeNsAndName(prefix, tagName || 'ng-component');
17966
+ }
17967
+ }
17968
+ _getPrefix(token, parent) {
17969
+ let prefix;
17970
+ let tagName;
17971
+ if (token.type === 33 /* TokenType.COMPONENT_OPEN_START */ ||
17972
+ token.type === 37 /* TokenType.INCOMPLETE_COMPONENT_OPEN */ ||
17973
+ token.type === 36 /* TokenType.COMPONENT_CLOSE */) {
17974
+ prefix = token.parts[1];
17975
+ tagName = token.parts[2];
17976
+ }
17977
+ else {
17978
+ prefix = token.parts[0];
17979
+ tagName = token.parts[1];
17980
+ }
17981
+ prefix = prefix || this._getTagDefinition(tagName)?.implicitNamespacePrefix || '';
17982
+ if (!prefix && parent) {
17983
+ const parentName = parent instanceof Element ? parent.name : parent.tagName;
17984
+ if (parentName !== null) {
17985
+ const parentTagName = splitNsName(parentName)[1];
17986
+ const parentTagDefinition = this._getTagDefinition(parentTagName);
17987
+ if (parentTagDefinition !== null && !parentTagDefinition.preventNamespaceInheritance) {
17988
+ prefix = getNsPrefix(parentName);
17558
17989
  }
17559
17990
  }
17560
17991
  }
17561
- return mergeNsAndName(prefix, localName);
17992
+ return prefix;
17562
17993
  }
17563
17994
  }
17564
17995
  function lastOnStack(stack, element) {
@@ -17637,11 +18068,11 @@ class WhitespaceVisitor {
17637
18068
  if (SKIP_WS_TRIM_TAGS.has(element.name) || hasPreserveWhitespacesAttr(element.attrs)) {
17638
18069
  // don't descent into elements where we need to preserve whitespaces
17639
18070
  // but still visit all attributes to eliminate one used as a market to preserve WS
17640
- const newElement = new Element(element.name, visitAllWithSiblings(this, element.attrs), element.children, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
18071
+ const newElement = new Element(element.name, visitAllWithSiblings(this, element.attrs), visitAllWithSiblings(this, element.directives), element.children, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
17641
18072
  this.originalNodeMap?.set(newElement, element);
17642
18073
  return newElement;
17643
18074
  }
17644
- const newElement = new Element(element.name, element.attrs, visitAllWithSiblings(this, element.children), element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
18075
+ const newElement = new Element(element.name, element.attrs, element.directives, visitAllWithSiblings(this, element.children), element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
17645
18076
  this.originalNodeMap?.set(newElement, element);
17646
18077
  return newElement;
17647
18078
  }
@@ -17715,6 +18146,22 @@ class WhitespaceVisitor {
17715
18146
  visitLetDeclaration(decl, context) {
17716
18147
  return decl;
17717
18148
  }
18149
+ visitComponent(node, context) {
18150
+ if ((node.tagName && SKIP_WS_TRIM_TAGS.has(node.tagName)) ||
18151
+ hasPreserveWhitespacesAttr(node.attrs)) {
18152
+ // don't descent into elements where we need to preserve whitespaces
18153
+ // but still visit all attributes to eliminate one used as a market to preserve WS
18154
+ const newElement = new Component(node.componentName, node.tagName, node.fullName, visitAllWithSiblings(this, node.attrs), visitAllWithSiblings(this, node.directives), node.children, node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.i18n);
18155
+ this.originalNodeMap?.set(newElement, node);
18156
+ return newElement;
18157
+ }
18158
+ const newElement = new Component(node.componentName, node.tagName, node.fullName, node.attrs, node.directives, visitAllWithSiblings(this, node.children), node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.i18n);
18159
+ this.originalNodeMap?.set(newElement, node);
18160
+ return newElement;
18161
+ }
18162
+ visitDirective(directive, context) {
18163
+ return directive;
18164
+ }
17718
18165
  visit(_node, context) {
17719
18166
  // `visitAllWithSiblings` provides context necessary for ICU messages to be handled correctly.
17720
18167
  // Prefer that over calling `html.visitAll` directly on this visitor.
@@ -19898,7 +20345,7 @@ const SCHEMA = [
19898
20345
  /* added manually to avoid breaking changes */
19899
20346
  ',*message,*mozfullscreenchange,*mozfullscreenerror,*mozpointerlockchange,*mozpointerlockerror,*webglcontextcreationerror,*webglcontextlost,*webglcontextrestored',
19900
20347
  '[HTMLElement]^[Element]|accessKey,autocapitalize,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,!inert,innerText,inputMode,lang,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
19901
- 'abbr,address,article,aside,b,bdi,bdo,cite,content,code,dd,dfn,dt,em,figcaption,figure,footer,header,hgroup,i,kbd,main,mark,nav,noscript,rb,rp,rt,rtc,ruby,s,samp,section,small,strong,sub,sup,u,var,wbr^[HTMLElement]|accessKey,autocapitalize,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,innerText,inputMode,lang,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
20348
+ 'abbr,address,article,aside,b,bdi,bdo,cite,content,code,dd,dfn,dt,em,figcaption,figure,footer,header,hgroup,i,kbd,main,mark,nav,noscript,rb,rp,rt,rtc,ruby,s,samp,search,section,small,strong,sub,sup,u,var,wbr^[HTMLElement]|accessKey,autocapitalize,!autofocus,contentEditable,dir,!draggable,enterKeyHint,!hidden,innerText,inputMode,lang,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,outerText,!spellcheck,%style,#tabIndex,title,!translate,virtualKeyboardPolicy',
19902
20349
  'media^[HTMLElement]|!autoplay,!controls,%controlsList,%crossOrigin,#currentTime,!defaultMuted,#defaultPlaybackRate,!disableRemotePlayback,!loop,!muted,*encrypted,*waitingforkey,#playbackRate,preload,!preservesPitch,src,%srcObject,#volume',
19903
20350
  ':svg:^[HTMLElement]|!autofocus,nonce,*abort,*animationend,*animationiteration,*animationstart,*auxclick,*beforexrselect,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*formdata,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*paste,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerrawupdate,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*securitypolicyviolation,*seeked,*seeking,*select,*selectionchange,*selectstart,*slotchange,*stalled,*submit,*suspend,*timeupdate,*toggle,*transitioncancel,*transitionend,*transitionrun,*transitionstart,*volumechange,*waiting,*webkitanimationend,*webkitanimationiteration,*webkitanimationstart,*webkittransitionend,*wheel,%style,#tabIndex',
19904
20351
  ':svg:graphics^:svg:|',
@@ -19965,6 +20412,7 @@ const SCHEMA = [
19965
20412
  'source^[HTMLElement]|#height,media,sizes,src,srcset,type,#width',
19966
20413
  'span^[HTMLElement]|',
19967
20414
  'style^[HTMLElement]|!disabled,media,type',
20415
+ 'search^[HTMLELement]|',
19968
20416
  'caption^[HTMLElement]|align',
19969
20417
  'th,td^[HTMLElement]|abbr,align,axis,bgColor,ch,chOff,#colSpan,headers,height,!noWrap,#rowSpan,scope,vAlign,width',
19970
20418
  'col,colgroup^[HTMLElement]|align,ch,chOff,#span,vAlign,width',
@@ -20615,28 +21063,13 @@ class _I18nVisitor {
20615
21063
  return new Message(i18nodes, context.placeholderToContent, context.placeholderToMessage, meaning, description, customId);
20616
21064
  }
20617
21065
  visitElement(el, context) {
20618
- const children = visitAll(this, el.children, context);
20619
- const attrs = {};
20620
- el.attrs.forEach((attr) => {
20621
- // Do not visit the attributes, translatable ones are top-level ASTs
20622
- attrs[attr.name] = attr.value;
20623
- });
20624
- const isVoid = getHtmlTagDefinition(el.name).isVoid;
20625
- const startPhName = context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
20626
- context.placeholderToContent[startPhName] = {
20627
- text: el.startSourceSpan.toString(),
20628
- sourceSpan: el.startSourceSpan,
20629
- };
20630
- let closePhName = '';
20631
- if (!isVoid) {
20632
- closePhName = context.placeholderRegistry.getCloseTagPlaceholderName(el.name);
20633
- context.placeholderToContent[closePhName] = {
20634
- text: `</${el.name}>`,
20635
- sourceSpan: el.endSourceSpan ?? el.sourceSpan,
20636
- };
20637
- }
20638
- const node = new TagPlaceholder(el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
20639
- return context.visitNodeFn(el, node);
21066
+ return this._visitElementLike(el, context);
21067
+ }
21068
+ visitComponent(component, context) {
21069
+ return this._visitElementLike(component, context);
21070
+ }
21071
+ visitDirective(directive, context) {
21072
+ throw new Error('Unreachable code');
20640
21073
  }
20641
21074
  visitAttribute(attribute, context) {
20642
21075
  const node = attribute.valueTokens === undefined || attribute.valueTokens.length === 1
@@ -20710,6 +21143,41 @@ class _I18nVisitor {
20710
21143
  visitLetDeclaration(decl, context) {
20711
21144
  return null;
20712
21145
  }
21146
+ _visitElementLike(node, context) {
21147
+ const children = visitAll(this, node.children, context);
21148
+ const attrs = {};
21149
+ const visitAttribute = (attr) => {
21150
+ // Do not visit the attributes, translatable ones are top-level ASTs
21151
+ attrs[attr.name] = attr.value;
21152
+ };
21153
+ let nodeName;
21154
+ let isVoid;
21155
+ if (node instanceof Element) {
21156
+ nodeName = node.name;
21157
+ isVoid = getHtmlTagDefinition(node.name).isVoid;
21158
+ }
21159
+ else {
21160
+ nodeName = node.fullName;
21161
+ isVoid = node.tagName ? getHtmlTagDefinition(node.tagName).isVoid : false;
21162
+ }
21163
+ node.attrs.forEach(visitAttribute);
21164
+ node.directives.forEach((dir) => dir.attrs.forEach(visitAttribute));
21165
+ const startPhName = context.placeholderRegistry.getStartTagPlaceholderName(nodeName, attrs, isVoid);
21166
+ context.placeholderToContent[startPhName] = {
21167
+ text: node.startSourceSpan.toString(),
21168
+ sourceSpan: node.startSourceSpan,
21169
+ };
21170
+ let closePhName = '';
21171
+ if (!isVoid) {
21172
+ closePhName = context.placeholderRegistry.getCloseTagPlaceholderName(nodeName);
21173
+ context.placeholderToContent[closePhName] = {
21174
+ text: `</${nodeName}>`,
21175
+ sourceSpan: node.endSourceSpan ?? node.sourceSpan,
21176
+ };
21177
+ }
21178
+ const i18nNode = new TagPlaceholder(nodeName, attrs, startPhName, closePhName, children, isVoid, node.sourceSpan, node.startSourceSpan, node.endSourceSpan);
21179
+ return context.visitNodeFn(node, i18nNode);
21180
+ }
20713
21181
  /**
20714
21182
  * Convert, text and interpolated tokens up into text and placeholder pieces.
20715
21183
  *
@@ -20972,15 +21440,74 @@ class I18nMetaVisitor {
20972
21440
  return new ParseTreeResult(result, this._errors);
20973
21441
  }
20974
21442
  visitElement(element) {
21443
+ this._visitElementLike(element);
21444
+ return element;
21445
+ }
21446
+ visitComponent(component, context) {
21447
+ this._visitElementLike(component);
21448
+ return component;
21449
+ }
21450
+ visitExpansion(expansion, currentMessage) {
21451
+ let message;
21452
+ const meta = expansion.i18n;
21453
+ this.hasI18nMeta = true;
21454
+ if (meta instanceof IcuPlaceholder) {
21455
+ // set ICU placeholder name (e.g. "ICU_1"),
21456
+ // generated while processing root element contents,
21457
+ // so we can reference it when we output translation
21458
+ const name = meta.name;
21459
+ message = this._generateI18nMessage([expansion], meta);
21460
+ const icu = icuFromI18nMessage(message);
21461
+ icu.name = name;
21462
+ if (currentMessage !== null) {
21463
+ // Also update the placeholderToMessage map with this new message
21464
+ currentMessage.placeholderToMessage[name] = message;
21465
+ }
21466
+ }
21467
+ else {
21468
+ // ICU is a top level message, try to use metadata from container element if provided via
21469
+ // `context` argument. Note: context may not be available for standalone ICUs (without
21470
+ // wrapping element), so fallback to ICU metadata in this case.
21471
+ message = this._generateI18nMessage([expansion], currentMessage || meta);
21472
+ }
21473
+ expansion.i18n = message;
21474
+ return expansion;
21475
+ }
21476
+ visitText(text) {
21477
+ return text;
21478
+ }
21479
+ visitAttribute(attribute) {
21480
+ return attribute;
21481
+ }
21482
+ visitComment(comment) {
21483
+ return comment;
21484
+ }
21485
+ visitExpansionCase(expansionCase) {
21486
+ return expansionCase;
21487
+ }
21488
+ visitBlock(block, context) {
21489
+ visitAll(this, block.children, context);
21490
+ return block;
21491
+ }
21492
+ visitBlockParameter(parameter, context) {
21493
+ return parameter;
21494
+ }
21495
+ visitLetDeclaration(decl, context) {
21496
+ return decl;
21497
+ }
21498
+ visitDirective(directive, context) {
21499
+ return directive;
21500
+ }
21501
+ _visitElementLike(node) {
20975
21502
  let message = undefined;
20976
- if (hasI18nAttrs(element)) {
21503
+ if (hasI18nAttrs(node)) {
20977
21504
  this.hasI18nMeta = true;
20978
21505
  const attrs = [];
20979
21506
  const attrsMeta = {};
20980
- for (const attr of element.attrs) {
21507
+ for (const attr of node.attrs) {
20981
21508
  if (attr.name === I18N_ATTR) {
20982
21509
  // root 'i18n' node attribute
20983
- const i18n = element.i18n || attr.value;
21510
+ const i18n = node.i18n || attr.value;
20984
21511
  // Generate a new AST with whitespace trimmed, but also generate a map
20985
21512
  // to correlate each new node to its original so we can apply i18n
20986
21513
  // information to the original node based on the trimmed content.
@@ -20994,20 +21521,27 @@ class I18nMetaVisitor {
20994
21521
  // backwards compatibility.
20995
21522
  const originalNodeMap = new Map();
20996
21523
  const trimmedNodes = this.preserveSignificantWhitespace
20997
- ? element.children
20998
- : visitAllWithSiblings(new WhitespaceVisitor(false /* preserveSignificantWhitespace */, originalNodeMap), element.children);
21524
+ ? node.children
21525
+ : visitAllWithSiblings(new WhitespaceVisitor(false /* preserveSignificantWhitespace */, originalNodeMap), node.children);
20999
21526
  message = this._generateI18nMessage(trimmedNodes, i18n, setI18nRefs(originalNodeMap));
21000
21527
  if (message.nodes.length === 0) {
21001
21528
  // Ignore the message if it is empty.
21002
21529
  message = undefined;
21003
21530
  }
21004
21531
  // Store the message on the element
21005
- element.i18n = message;
21532
+ node.i18n = message;
21006
21533
  }
21007
21534
  else if (attr.name.startsWith(I18N_ATTR_PREFIX)) {
21008
21535
  // 'i18n-*' attributes
21009
21536
  const name = attr.name.slice(I18N_ATTR_PREFIX.length);
21010
- if (isTrustedTypesSink(element.name, name)) {
21537
+ let isTrustedType;
21538
+ if (node instanceof Component) {
21539
+ isTrustedType = node.tagName === null ? false : isTrustedTypesSink(node.tagName, name);
21540
+ }
21541
+ else {
21542
+ isTrustedType = isTrustedTypesSink(node.name, name);
21543
+ }
21544
+ if (isTrustedType) {
21011
21545
  this._reportError(attr, `Translating attribute '${name}' is disallowed for security reasons.`);
21012
21546
  }
21013
21547
  else {
@@ -21032,59 +21566,10 @@ class I18nMetaVisitor {
21032
21566
  if (!this.keepI18nAttrs) {
21033
21567
  // update element's attributes,
21034
21568
  // keeping only non-i18n related ones
21035
- element.attrs = attrs;
21569
+ node.attrs = attrs;
21036
21570
  }
21037
21571
  }
21038
- visitAll(this, element.children, message);
21039
- return element;
21040
- }
21041
- visitExpansion(expansion, currentMessage) {
21042
- let message;
21043
- const meta = expansion.i18n;
21044
- this.hasI18nMeta = true;
21045
- if (meta instanceof IcuPlaceholder) {
21046
- // set ICU placeholder name (e.g. "ICU_1"),
21047
- // generated while processing root element contents,
21048
- // so we can reference it when we output translation
21049
- const name = meta.name;
21050
- message = this._generateI18nMessage([expansion], meta);
21051
- const icu = icuFromI18nMessage(message);
21052
- icu.name = name;
21053
- if (currentMessage !== null) {
21054
- // Also update the placeholderToMessage map with this new message
21055
- currentMessage.placeholderToMessage[name] = message;
21056
- }
21057
- }
21058
- else {
21059
- // ICU is a top level message, try to use metadata from container element if provided via
21060
- // `context` argument. Note: context may not be available for standalone ICUs (without
21061
- // wrapping element), so fallback to ICU metadata in this case.
21062
- message = this._generateI18nMessage([expansion], currentMessage || meta);
21063
- }
21064
- expansion.i18n = message;
21065
- return expansion;
21066
- }
21067
- visitText(text) {
21068
- return text;
21069
- }
21070
- visitAttribute(attribute) {
21071
- return attribute;
21072
- }
21073
- visitComment(comment) {
21074
- return comment;
21075
- }
21076
- visitExpansionCase(expansionCase) {
21077
- return expansionCase;
21078
- }
21079
- visitBlock(block, context) {
21080
- visitAll(this, block.children, context);
21081
- return block;
21082
- }
21083
- visitBlockParameter(parameter, context) {
21084
- return parameter;
21085
- }
21086
- visitLetDeclaration(decl, context) {
21087
- return decl;
21572
+ visitAll(this, node.children, message);
21088
21573
  }
21089
21574
  /**
21090
21575
  * Parse the general form `meta` passed into extract the explicit metadata needed to create a
@@ -27501,15 +27986,22 @@ function isAnimationLabel(name) {
27501
27986
  return name[0] == '@';
27502
27987
  }
27503
27988
  function calcPossibleSecurityContexts(registry, selector, propName, isAttribute) {
27504
- const ctxs = [];
27505
- CssSelector.parse(selector).forEach((selector) => {
27506
- const elementNames = selector.element ? [selector.element] : registry.allKnownElementNames();
27507
- const notElementNames = new Set(selector.notSelectors
27508
- .filter((selector) => selector.isElementSelector())
27509
- .map((selector) => selector.element));
27510
- const possibleElementNames = elementNames.filter((elementName) => !notElementNames.has(elementName));
27511
- ctxs.push(...possibleElementNames.map((elementName) => registry.securityContext(elementName, propName, isAttribute)));
27512
- });
27989
+ let ctxs;
27990
+ const nameToContext = (elName) => registry.securityContext(elName, propName, isAttribute);
27991
+ if (selector === null) {
27992
+ ctxs = registry.allKnownElementNames().map(nameToContext);
27993
+ }
27994
+ else {
27995
+ ctxs = [];
27996
+ CssSelector.parse(selector).forEach((selector) => {
27997
+ const elementNames = selector.element ? [selector.element] : registry.allKnownElementNames();
27998
+ const notElementNames = new Set(selector.notSelectors
27999
+ .filter((selector) => selector.isElementSelector())
28000
+ .map((selector) => selector.element));
28001
+ const possibleElementNames = elementNames.filter((elName) => !notElementNames.has(elName));
28002
+ ctxs.push(...possibleElementNames.map(nameToContext));
28003
+ });
28004
+ }
27513
28005
  return ctxs.length === 0 ? [SecurityContext.NONE] : Array.from(new Set(ctxs)).sort();
27514
28006
  }
27515
28007
  /**
@@ -28594,6 +29086,17 @@ const BINDING_DELIMS = {
28594
29086
  EVENT: { start: '(', end: ')' },
28595
29087
  };
28596
29088
  const TEMPLATE_ATTR_PREFIX = '*';
29089
+ // TODO(crisbeto): any other tag names that shouldn't be allowed here?
29090
+ const UNSUPPORTED_SELECTORLESS_TAGS = new Set([
29091
+ 'link',
29092
+ 'style',
29093
+ 'script',
29094
+ 'ng-template',
29095
+ 'ng-container',
29096
+ 'ng-content',
29097
+ ]);
29098
+ // TODO(crisbeto): any other attributes that should not be allowed here?
29099
+ const UNSUPPORTED_SELECTORLESS_DIRECTIVE_ATTRS = new Set(['ngProjectAs', 'ngNonBindable']);
28597
29100
  function htmlAstToRender3Ast(htmlNodes, bindingParser, options) {
28598
29101
  const transformer = new HtmlAstToIvyAst(bindingParser, options);
28599
29102
  const ivyNodes = visitAll(transformer, htmlNodes, htmlNodes);
@@ -28657,52 +29160,8 @@ class HtmlAstToIvyAst {
28657
29160
  }
28658
29161
  // Whether the element is a `<ng-template>`
28659
29162
  const isTemplateElement = isNgTemplate(element.name);
28660
- const parsedProperties = [];
28661
- const boundEvents = [];
28662
- const variables = [];
28663
- const references = [];
28664
- const attributes = [];
28665
- const i18nAttrsMeta = {};
28666
- const templateParsedProperties = [];
28667
- const templateVariables = [];
28668
- // Whether the element has any *-attribute
28669
- let elementHasInlineTemplate = false;
28670
- for (const attribute of element.attrs) {
28671
- let hasBinding = false;
28672
- const normalizedName = normalizeAttributeName(attribute.name);
28673
- // `*attr` defines template bindings
28674
- let isTemplateBinding = false;
28675
- if (attribute.i18n) {
28676
- i18nAttrsMeta[attribute.name] = attribute.i18n;
28677
- }
28678
- if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) {
28679
- // *-attributes
28680
- if (elementHasInlineTemplate) {
28681
- this.reportError(`Can't have multiple template bindings on one element. Use only one attribute prefixed with *`, attribute.sourceSpan);
28682
- }
28683
- isTemplateBinding = true;
28684
- elementHasInlineTemplate = true;
28685
- const templateValue = attribute.value;
28686
- const templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length);
28687
- const parsedVariables = [];
28688
- const absoluteValueOffset = attribute.valueSpan
28689
- ? attribute.valueSpan.start.offset
28690
- : // If there is no value span the attribute does not have a value, like `attr` in
28691
- //`<div attr></div>`. In this case, point to one character beyond the last character of
28692
- // the attribute name.
28693
- attribute.sourceSpan.start.offset + attribute.name.length;
28694
- this.bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables, true /* isIvyAst */);
28695
- templateVariables.push(...parsedVariables.map((v) => new Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan)));
28696
- }
28697
- else {
28698
- // Check for variables, events, property bindings, interpolation
28699
- hasBinding = this.parseAttribute(isTemplateElement, attribute, [], parsedProperties, boundEvents, variables, references);
28700
- }
28701
- if (!hasBinding && !isTemplateBinding) {
28702
- // don't include the bindings as attributes as well in the AST
28703
- attributes.push(this.visitAttribute(attribute));
28704
- }
28705
- }
29163
+ const { attributes, boundEvents, references, variables, templateVariables, elementHasInlineTemplate, parsedProperties, templateParsedProperties, i18nAttrsMeta, } = this.prepareAttributes(element.attrs, isTemplateElement);
29164
+ const directives = this.extractDirectives(element);
28706
29165
  let children;
28707
29166
  if (preparsedElement.nonBindable) {
28708
29167
  // The `NonBindableVisitor` may need to return an array of nodes for blocks so we need
@@ -28717,44 +29176,24 @@ class HtmlAstToIvyAst {
28717
29176
  if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
28718
29177
  const selector = preparsedElement.selectAttr;
28719
29178
  const attrs = element.attrs.map((attr) => this.visitAttribute(attr));
28720
- parsedElement = new Content(selector, attrs, children, element.sourceSpan, element.i18n);
29179
+ parsedElement = new Content(selector, attrs, children, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
28721
29180
  this.ngContentSelectors.push(selector);
28722
29181
  }
28723
29182
  else if (isTemplateElement) {
28724
29183
  // `<ng-template>`
28725
- const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta);
28726
- parsedElement = new Template(element.name, attributes, attrs.bound, boundEvents, [
29184
+ const attrs = this.categorizePropertyAttributes(element.name, parsedProperties, i18nAttrsMeta);
29185
+ parsedElement = new Template(element.name, attributes, attrs.bound, boundEvents, directives, [
28727
29186
  /* no template attributes */
28728
29187
  ], children, references, variables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
28729
29188
  }
28730
29189
  else {
28731
- const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta);
28732
- parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, children, references, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
29190
+ const attrs = this.categorizePropertyAttributes(element.name, parsedProperties, i18nAttrsMeta);
29191
+ parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, directives, children, references, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
28733
29192
  }
28734
29193
  if (elementHasInlineTemplate) {
28735
29194
  // If this node is an inline-template (e.g. has *ngFor) then we need to create a template
28736
29195
  // node that contains this node.
28737
- // Moreover, if the node is an element, then we need to hoist its attributes to the template
28738
- // node for matching against content projection selectors.
28739
- const attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta);
28740
- const templateAttrs = [];
28741
- attrs.literal.forEach((attr) => templateAttrs.push(attr));
28742
- attrs.bound.forEach((attr) => templateAttrs.push(attr));
28743
- const hoistedAttrs = parsedElement instanceof Element$1
28744
- ? {
28745
- attributes: parsedElement.attributes,
28746
- inputs: parsedElement.inputs,
28747
- outputs: parsedElement.outputs,
28748
- }
28749
- : { attributes: [], inputs: [], outputs: [] };
28750
- // For <ng-template>s with structural directives on them, avoid passing i18n information to
28751
- // the wrapping template to prevent unnecessary i18n instructions from being generated. The
28752
- // necessary i18n meta information will be extracted from child elements.
28753
- const i18n = isTemplateElement && isI18nRootElement ? undefined : element.i18n;
28754
- const name = parsedElement instanceof Template ? null : parsedElement.name;
28755
- parsedElement = new Template(name, hoistedAttrs.attributes, hoistedAttrs.inputs, hoistedAttrs.outputs, templateAttrs, [parsedElement], [
28756
- /* no references */
28757
- ], templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, i18n);
29196
+ parsedElement = this.wrapInTemplate(parsedElement, templateParsedProperties, templateVariables, i18nAttrsMeta, isTemplateElement, isI18nRootElement);
28758
29197
  }
28759
29198
  if (isI18nRootElement) {
28760
29199
  this.inI18nBlock = false;
@@ -28818,6 +29257,43 @@ class HtmlAstToIvyAst {
28818
29257
  }
28819
29258
  return new LetDeclaration$1(decl.name, value, decl.sourceSpan, decl.nameSpan, decl.valueSpan);
28820
29259
  }
29260
+ visitComponent(component) {
29261
+ const isI18nRootElement = isI18nRootNode(component.i18n);
29262
+ if (isI18nRootElement) {
29263
+ if (this.inI18nBlock) {
29264
+ this.reportError('Cannot mark a component as translatable inside of a translatable section. Please remove the nested i18n marker.', component.sourceSpan);
29265
+ }
29266
+ this.inI18nBlock = true;
29267
+ }
29268
+ if (component.tagName !== null && UNSUPPORTED_SELECTORLESS_TAGS.has(component.tagName)) {
29269
+ this.reportError(`Tag name "${component.tagName}" cannot be used as a component tag`, component.startSourceSpan);
29270
+ return null;
29271
+ }
29272
+ const { attributes, boundEvents, references, templateVariables, elementHasInlineTemplate, parsedProperties, templateParsedProperties, i18nAttrsMeta, } = this.prepareAttributes(component.attrs, false);
29273
+ const directives = this.extractDirectives(component);
29274
+ let children;
29275
+ if (component.attrs.find((attr) => attr.name === 'ngNonBindable')) {
29276
+ // The `NonBindableVisitor` may need to return an array of nodes for blocks so we need
29277
+ // to flatten the array here. Avoid doing this for the `HtmlAstToIvyAst` since `flat` creates
29278
+ // a new array.
29279
+ children = visitAll(NON_BINDABLE_VISITOR, component.children).flat(Infinity);
29280
+ }
29281
+ else {
29282
+ children = visitAll(this, component.children, component.children);
29283
+ }
29284
+ const attrs = this.categorizePropertyAttributes(component.tagName, parsedProperties, i18nAttrsMeta);
29285
+ let node = new Component$1(component.componentName, component.tagName, component.fullName, attributes, attrs.bound, boundEvents, directives, children, references, component.sourceSpan, component.startSourceSpan, component.endSourceSpan, component.i18n);
29286
+ if (elementHasInlineTemplate) {
29287
+ node = this.wrapInTemplate(node, templateParsedProperties, templateVariables, i18nAttrsMeta, false, isI18nRootElement);
29288
+ }
29289
+ if (isI18nRootElement) {
29290
+ this.inI18nBlock = false;
29291
+ }
29292
+ return node;
29293
+ }
29294
+ visitDirective() {
29295
+ return null;
29296
+ }
28821
29297
  visitBlockParameter() {
28822
29298
  return null;
28823
29299
  }
@@ -28894,8 +29370,8 @@ class HtmlAstToIvyAst {
28894
29370
  }
28895
29371
  return relatedBlocks;
28896
29372
  }
28897
- // convert view engine `ParsedProperty` to a format suitable for IVY
28898
- extractAttributes(elementName, properties, i18nPropsMeta) {
29373
+ /** Splits up the property attributes depending on whether they're static or bound. */
29374
+ categorizePropertyAttributes(elementName, properties, i18nPropsMeta) {
28899
29375
  const bound = [];
28900
29376
  const literal = [];
28901
29377
  properties.forEach((prop) => {
@@ -28915,6 +29391,65 @@ class HtmlAstToIvyAst {
28915
29391
  });
28916
29392
  return { bound, literal };
28917
29393
  }
29394
+ prepareAttributes(attrs, isTemplateElement) {
29395
+ const parsedProperties = [];
29396
+ const boundEvents = [];
29397
+ const variables = [];
29398
+ const references = [];
29399
+ const attributes = [];
29400
+ const i18nAttrsMeta = {};
29401
+ const templateParsedProperties = [];
29402
+ const templateVariables = [];
29403
+ // Whether the element has any *-attribute
29404
+ let elementHasInlineTemplate = false;
29405
+ for (const attribute of attrs) {
29406
+ let hasBinding = false;
29407
+ const normalizedName = normalizeAttributeName(attribute.name);
29408
+ // `*attr` defines template bindings
29409
+ let isTemplateBinding = false;
29410
+ if (attribute.i18n) {
29411
+ i18nAttrsMeta[attribute.name] = attribute.i18n;
29412
+ }
29413
+ if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) {
29414
+ // *-attributes
29415
+ if (elementHasInlineTemplate) {
29416
+ this.reportError(`Can't have multiple template bindings on one element. Use only one attribute prefixed with *`, attribute.sourceSpan);
29417
+ }
29418
+ isTemplateBinding = true;
29419
+ elementHasInlineTemplate = true;
29420
+ const templateValue = attribute.value;
29421
+ const templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length);
29422
+ const parsedVariables = [];
29423
+ const absoluteValueOffset = attribute.valueSpan
29424
+ ? attribute.valueSpan.start.offset
29425
+ : // If there is no value span the attribute does not have a value, like `attr` in
29426
+ //`<div attr></div>`. In this case, point to one character beyond the last character of
29427
+ // the attribute name.
29428
+ attribute.sourceSpan.start.offset + attribute.name.length;
29429
+ this.bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables, true /* isIvyAst */);
29430
+ templateVariables.push(...parsedVariables.map((v) => new Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan)));
29431
+ }
29432
+ else {
29433
+ // Check for variables, events, property bindings, interpolation
29434
+ hasBinding = this.parseAttribute(isTemplateElement, attribute, [], parsedProperties, boundEvents, variables, references);
29435
+ }
29436
+ if (!hasBinding && !isTemplateBinding) {
29437
+ // don't include the bindings as attributes as well in the AST
29438
+ attributes.push(this.visitAttribute(attribute));
29439
+ }
29440
+ }
29441
+ return {
29442
+ attributes,
29443
+ boundEvents,
29444
+ references,
29445
+ variables,
29446
+ templateVariables,
29447
+ elementHasInlineTemplate,
29448
+ parsedProperties,
29449
+ templateParsedProperties,
29450
+ i18nAttrsMeta,
29451
+ };
29452
+ }
28918
29453
  parseAttribute(isTemplateElement, attribute, matchableAttributes, parsedProperties, boundEvents, variables, references) {
28919
29454
  const name = normalizeAttributeName(attribute.name);
28920
29455
  const value = attribute.value;
@@ -29013,6 +29548,81 @@ class HtmlAstToIvyAst {
29013
29548
  const hasBinding = this.bindingParser.parsePropertyInterpolation(name, value, srcSpan, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan, attribute.valueTokens ?? null);
29014
29549
  return hasBinding;
29015
29550
  }
29551
+ extractDirectives(node) {
29552
+ const elementName = node instanceof Component ? node.tagName : node.name;
29553
+ const directives = [];
29554
+ const seenDirectives = new Set();
29555
+ for (const directive of node.directives) {
29556
+ let invalid = false;
29557
+ for (const attr of directive.attrs) {
29558
+ if (attr.name.startsWith(TEMPLATE_ATTR_PREFIX)) {
29559
+ invalid = true;
29560
+ this.reportError(`Shorthand template syntax "${attr.name}" is not supported inside a directive context`, attr.sourceSpan);
29561
+ }
29562
+ else if (UNSUPPORTED_SELECTORLESS_DIRECTIVE_ATTRS.has(attr.name)) {
29563
+ invalid = true;
29564
+ this.reportError(`Attribute "${attr.name}" is not supported in a directive context`, attr.sourceSpan);
29565
+ }
29566
+ }
29567
+ if (!invalid && seenDirectives.has(directive.name)) {
29568
+ invalid = true;
29569
+ this.reportError(`Cannot apply directive "${directive.name}" multiple times on the same element`, directive.sourceSpan);
29570
+ }
29571
+ if (invalid) {
29572
+ continue;
29573
+ }
29574
+ const { attributes, parsedProperties, boundEvents, references, i18nAttrsMeta } = this.prepareAttributes(directive.attrs, false);
29575
+ const { bound: inputs } = this.categorizePropertyAttributes(elementName, parsedProperties, i18nAttrsMeta);
29576
+ for (const input of inputs) {
29577
+ if (input.type !== BindingType.Property && input.type !== BindingType.TwoWay) {
29578
+ invalid = true;
29579
+ this.reportError('Binding is not supported in a directive context', input.sourceSpan);
29580
+ }
29581
+ }
29582
+ if (invalid) {
29583
+ continue;
29584
+ }
29585
+ seenDirectives.add(directive.name);
29586
+ directives.push(new Directive$1(directive.name, attributes, inputs, boundEvents, references, directive.sourceSpan, directive.startSourceSpan, directive.endSourceSpan, undefined));
29587
+ }
29588
+ return directives;
29589
+ }
29590
+ wrapInTemplate(node, templateProperties, templateVariables, i18nAttrsMeta, isTemplateElement, isI18nRootElement) {
29591
+ // We need to hoist the attributes of the node to the template for content projection purposes.
29592
+ const attrs = this.categorizePropertyAttributes('ng-template', templateProperties, i18nAttrsMeta);
29593
+ const templateAttrs = [];
29594
+ attrs.literal.forEach((attr) => templateAttrs.push(attr));
29595
+ attrs.bound.forEach((attr) => templateAttrs.push(attr));
29596
+ const hoistedAttrs = {
29597
+ attributes: [],
29598
+ inputs: [],
29599
+ outputs: [],
29600
+ };
29601
+ if (node instanceof Element$1 || node instanceof Component$1) {
29602
+ hoistedAttrs.attributes.push(...node.attributes);
29603
+ hoistedAttrs.inputs.push(...node.inputs);
29604
+ hoistedAttrs.outputs.push(...node.outputs);
29605
+ }
29606
+ // For <ng-template>s with structural directives on them, avoid passing i18n information to
29607
+ // the wrapping template to prevent unnecessary i18n instructions from being generated. The
29608
+ // necessary i18n meta information will be extracted from child elements.
29609
+ const i18n = isTemplateElement && isI18nRootElement ? undefined : node.i18n;
29610
+ let name;
29611
+ if (node instanceof Component$1) {
29612
+ name = node.tagName;
29613
+ }
29614
+ else if (node instanceof Template) {
29615
+ name = null;
29616
+ }
29617
+ else {
29618
+ name = node.name;
29619
+ }
29620
+ return new Template(name, hoistedAttrs.attributes, hoistedAttrs.inputs, hoistedAttrs.outputs, [
29621
+ // Do not copy over the directives.
29622
+ ], templateAttrs, [node], [
29623
+ // Do not copy over the references.
29624
+ ], templateVariables, node.sourceSpan, node.startSourceSpan, node.endSourceSpan, i18n);
29625
+ }
29016
29626
  _visitTextWithInterpolation(value, sourceSpan, interpolatedTokens, i18n) {
29017
29627
  const valueNoNgsp = replaceNgsp(value);
29018
29628
  const expr = this.bindingParser.parseInterpolation(valueNoNgsp, sourceSpan, interpolatedTokens);
@@ -29063,7 +29673,8 @@ class NonBindableVisitor {
29063
29673
  const children = visitAll(this, ast.children, null);
29064
29674
  return new Element$1(ast.name, visitAll(this, ast.attrs),
29065
29675
  /* inputs */ [],
29066
- /* outputs */ [], children,
29676
+ /* outputs */ [],
29677
+ /* directives */ [], children,
29067
29678
  /* references */ [], ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
29068
29679
  }
29069
29680
  visitComment(comment) {
@@ -29099,6 +29710,17 @@ class NonBindableVisitor {
29099
29710
  visitLetDeclaration(decl, context) {
29100
29711
  return new Text$3(`@let ${decl.name} = ${decl.value};`, decl.sourceSpan);
29101
29712
  }
29713
+ visitComponent(ast, context) {
29714
+ const children = visitAll(this, ast.children, null);
29715
+ return new Element$1(ast.fullName, visitAll(this, ast.attrs),
29716
+ /* inputs */ [],
29717
+ /* outputs */ [],
29718
+ /* directives */ [], children,
29719
+ /* references */ [], ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
29720
+ }
29721
+ visitDirective(directive, context) {
29722
+ return null;
29723
+ }
29102
29724
  }
29103
29725
  const NON_BINDABLE_VISITOR = new NonBindableVisitor();
29104
29726
  function normalizeAttributeName(attrName) {
@@ -29955,6 +30577,7 @@ class Scope {
29955
30577
  }
29956
30578
  }
29957
30579
  visitElement(element) {
30580
+ element.directives.forEach((node) => node.visit(this));
29958
30581
  // `Element`s in the template may have `Reference`s which are captured in the scope.
29959
30582
  element.references.forEach((node) => this.visitReference(node));
29960
30583
  // Recurse into the `Element`'s children.
@@ -29962,6 +30585,7 @@ class Scope {
29962
30585
  this.elementsInScope.add(element);
29963
30586
  }
29964
30587
  visitTemplate(template) {
30588
+ template.directives.forEach((node) => node.visit(this));
29965
30589
  // References on a <ng-template> are defined in the outer scope, so capture them before
29966
30590
  // processing the template's child scope.
29967
30591
  template.references.forEach((node) => this.visitReference(node));
@@ -30016,6 +30640,12 @@ class Scope {
30016
30640
  visitLetDeclaration(decl) {
30017
30641
  this.maybeDeclare(decl);
30018
30642
  }
30643
+ visitComponent(component) {
30644
+ throw new Error('TODO');
30645
+ }
30646
+ visitDirective(directive) {
30647
+ throw new Error('TODO');
30648
+ }
30019
30649
  // Unused visitors.
30020
30650
  visitBoundAttribute(attr) { }
30021
30651
  visitBoundEvent(event) { }
@@ -30117,6 +30747,10 @@ class DirectiveBinder {
30117
30747
  // First, determine the HTML shape of the node for the purpose of directive matching.
30118
30748
  // Do this by building up a `CssSelector` for the node.
30119
30749
  const cssSelector = createCssSelectorFromNode(node);
30750
+ // TODO(crisbeto): account for selectorless directives here.
30751
+ if (node.directives.length > 0) {
30752
+ throw new Error('TODO');
30753
+ }
30120
30754
  // Next, use the `SelectorMatcher` to get the list of directives on the node.
30121
30755
  const directives = [];
30122
30756
  this.matcher.match(cssSelector, (_selector, results) => directives.push(...results));
@@ -30216,6 +30850,12 @@ class DirectiveBinder {
30216
30850
  visitContent(content) {
30217
30851
  content.children.forEach((child) => child.visit(this));
30218
30852
  }
30853
+ visitComponent(component) {
30854
+ throw new Error('TODO');
30855
+ }
30856
+ visitDirective(directive) {
30857
+ throw new Error('TODO');
30858
+ }
30219
30859
  // Unused visitors.
30220
30860
  visitVariable(variable) { }
30221
30861
  visitReference(reference) { }
@@ -30346,6 +30986,7 @@ class TemplateBinder extends RecursiveAstVisitor {
30346
30986
  // Visit the inputs, outputs, and children of the element.
30347
30987
  element.inputs.forEach(this.visitNode);
30348
30988
  element.outputs.forEach(this.visitNode);
30989
+ element.directives.forEach(this.visitNode);
30349
30990
  element.children.forEach(this.visitNode);
30350
30991
  element.references.forEach(this.visitNode);
30351
30992
  }
@@ -30353,6 +30994,7 @@ class TemplateBinder extends RecursiveAstVisitor {
30353
30994
  // First, visit inputs, outputs and template attributes of the template node.
30354
30995
  template.inputs.forEach(this.visitNode);
30355
30996
  template.outputs.forEach(this.visitNode);
30997
+ template.directives.forEach(this.visitNode);
30356
30998
  template.templateAttrs.forEach(this.visitNode);
30357
30999
  template.references.forEach(this.visitNode);
30358
31000
  // Next, recurse into the template.
@@ -30370,6 +31012,12 @@ class TemplateBinder extends RecursiveAstVisitor {
30370
31012
  this.symbols.set(reference, this.rootNode);
30371
31013
  }
30372
31014
  }
31015
+ visitComponent(component) {
31016
+ throw new Error('TODO');
31017
+ }
31018
+ visitDirective(directive) {
31019
+ throw new Error('TODO');
31020
+ }
30373
31021
  // Unused template visitors
30374
31022
  visitText(text) { }
30375
31023
  visitTextAttribute(attribute) { }
@@ -31438,7 +32086,7 @@ class _Visitor {
31438
32086
  this._init(_VisitorMode.Merge, interpolationConfig);
31439
32087
  this._translations = translations;
31440
32088
  // Construct a single fake root element
31441
- const wrapper = new Element('wrapper', [], nodes, undefined, undefined, undefined);
32089
+ const wrapper = new Element('wrapper', [], [], nodes, undefined, undefined, undefined);
31442
32090
  const translatedNode = wrapper.visit(this, null);
31443
32091
  if (this._inI18nBlock) {
31444
32092
  this._reportError(nodes[nodes.length - 1], 'Unclosed block');
@@ -31524,7 +32172,41 @@ class _Visitor {
31524
32172
  return text;
31525
32173
  }
31526
32174
  visitElement(el, context) {
31527
- this._mayBeAddBlockChildren(el);
32175
+ return this._visitElementLike(el, context);
32176
+ }
32177
+ visitAttribute(attribute, context) {
32178
+ throw new Error('unreachable code');
32179
+ }
32180
+ visitBlock(block, context) {
32181
+ visitAll(this, block.children, context);
32182
+ }
32183
+ visitBlockParameter(parameter, context) { }
32184
+ visitLetDeclaration(decl, context) { }
32185
+ visitComponent(component, context) {
32186
+ return this._visitElementLike(component, context);
32187
+ }
32188
+ visitDirective(directive, context) {
32189
+ throw new Error('unreachable code');
32190
+ }
32191
+ _init(mode, interpolationConfig) {
32192
+ this._mode = mode;
32193
+ this._inI18nBlock = false;
32194
+ this._inI18nNode = false;
32195
+ this._depth = 0;
32196
+ this._inIcu = false;
32197
+ this._msgCountAtSectionStart = undefined;
32198
+ this._errors = [];
32199
+ this._messages = [];
32200
+ this._inImplicitNode = false;
32201
+ this._createI18nMessage = createI18nMessageFactory(interpolationConfig, DEFAULT_CONTAINER_BLOCKS,
32202
+ // When dropping significant whitespace we need to retain whitespace tokens or
32203
+ // else we won't be able to reuse source spans because empty tokens would be
32204
+ // removed and cause a mismatch.
32205
+ /* retainEmptyTokens */ !this._preserveSignificantWhitespace,
32206
+ /* preserveExpressionWhitespace */ this._preserveSignificantWhitespace);
32207
+ }
32208
+ _visitElementLike(node, context) {
32209
+ this._mayBeAddBlockChildren(node);
31528
32210
  this._depth++;
31529
32211
  const wasInI18nNode = this._inI18nNode;
31530
32212
  const wasInImplicitNode = this._inImplicitNode;
@@ -31533,9 +32215,10 @@ class _Visitor {
31533
32215
  // Extract:
31534
32216
  // - top level nodes with the (implicit) "i18n" attribute if not already in a section
31535
32217
  // - ICU messages
31536
- const i18nAttr = _getI18nAttr(el);
32218
+ const nodeName = node instanceof Component ? node.tagName : node.name;
32219
+ const i18nAttr = _getI18nAttr(node);
31537
32220
  const i18nMeta = i18nAttr ? i18nAttr.value : '';
31538
- const isImplicit = this._implicitTags.some((tag) => el.name === tag) &&
32221
+ const isImplicit = this._implicitTags.some((tag) => nodeName === tag) &&
31539
32222
  !this._inIcu &&
31540
32223
  !this._isInTranslatableSection;
31541
32224
  const isTopLevelImplicit = !wasInImplicitNode && isImplicit;
@@ -31543,29 +32226,29 @@ class _Visitor {
31543
32226
  if (!this._isInTranslatableSection && !this._inIcu) {
31544
32227
  if (i18nAttr || isTopLevelImplicit) {
31545
32228
  this._inI18nNode = true;
31546
- const message = this._addMessage(el.children, i18nMeta);
31547
- translatedChildNodes = this._translateMessage(el, message);
32229
+ const message = this._addMessage(node.children, i18nMeta);
32230
+ translatedChildNodes = this._translateMessage(node, message);
31548
32231
  }
31549
32232
  if (this._mode == _VisitorMode.Extract) {
31550
32233
  const isTranslatable = i18nAttr || isTopLevelImplicit;
31551
32234
  if (isTranslatable)
31552
- this._openTranslatableSection(el);
31553
- visitAll(this, el.children);
32235
+ this._openTranslatableSection(node);
32236
+ visitAll(this, node.children);
31554
32237
  if (isTranslatable)
31555
- this._closeTranslatableSection(el, el.children);
32238
+ this._closeTranslatableSection(node, node.children);
31556
32239
  }
31557
32240
  }
31558
32241
  else {
31559
32242
  if (i18nAttr || isTopLevelImplicit) {
31560
- this._reportError(el, 'Could not mark an element as translatable inside a translatable section');
32243
+ this._reportError(node, 'Could not mark an element as translatable inside a translatable section');
31561
32244
  }
31562
32245
  if (this._mode == _VisitorMode.Extract) {
31563
32246
  // Descend into child nodes for extraction
31564
- visitAll(this, el.children);
32247
+ visitAll(this, node.children);
31565
32248
  }
31566
32249
  }
31567
32250
  if (this._mode === _VisitorMode.Merge) {
31568
- const visitNodes = translatedChildNodes || el.children;
32251
+ const visitNodes = translatedChildNodes || node.children;
31569
32252
  visitNodes.forEach((child) => {
31570
32253
  const visited = child.visit(this, context);
31571
32254
  if (visited && !this._isInTranslatableSection) {
@@ -31575,48 +32258,29 @@ class _Visitor {
31575
32258
  }
31576
32259
  });
31577
32260
  }
31578
- this._visitAttributesOf(el);
32261
+ this._visitAttributesOf(node);
31579
32262
  this._depth--;
31580
32263
  this._inI18nNode = wasInI18nNode;
31581
32264
  this._inImplicitNode = wasInImplicitNode;
31582
32265
  if (this._mode === _VisitorMode.Merge) {
31583
- const translatedAttrs = this._translateAttributes(el);
31584
- return new Element(el.name, translatedAttrs, childNodes, el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
32266
+ if (node instanceof Element) {
32267
+ return new Element(node.name, this._translateAttributes(node), this._translateDirectives(node), childNodes, node.sourceSpan, node.startSourceSpan, node.endSourceSpan);
32268
+ }
32269
+ else {
32270
+ return new Component(node.componentName, node.tagName, node.fullName, this._translateAttributes(node), this._translateDirectives(node), childNodes, node.sourceSpan, node.startSourceSpan, node.endSourceSpan);
32271
+ }
31585
32272
  }
31586
32273
  return null;
31587
32274
  }
31588
- visitAttribute(attribute, context) {
31589
- throw new Error('unreachable code');
31590
- }
31591
- visitBlock(block, context) {
31592
- visitAll(this, block.children, context);
31593
- }
31594
- visitBlockParameter(parameter, context) { }
31595
- visitLetDeclaration(decl, context) { }
31596
- _init(mode, interpolationConfig) {
31597
- this._mode = mode;
31598
- this._inI18nBlock = false;
31599
- this._inI18nNode = false;
31600
- this._depth = 0;
31601
- this._inIcu = false;
31602
- this._msgCountAtSectionStart = undefined;
31603
- this._errors = [];
31604
- this._messages = [];
31605
- this._inImplicitNode = false;
31606
- this._createI18nMessage = createI18nMessageFactory(interpolationConfig, DEFAULT_CONTAINER_BLOCKS,
31607
- // When dropping significant whitespace we need to retain whitespace tokens or
31608
- // else we won't be able to reuse source spans because empty tokens would be
31609
- // removed and cause a mismatch.
31610
- /* retainEmptyTokens */ !this._preserveSignificantWhitespace,
31611
- /* preserveExpressionWhitespace */ this._preserveSignificantWhitespace);
31612
- }
31613
32275
  // looks for translatable attributes
31614
32276
  _visitAttributesOf(el) {
31615
32277
  const explicitAttrNameToValue = {};
31616
- const implicitAttrNames = this._implicitAttrs[el.name] || [];
32278
+ const implicitAttrNames = this._implicitAttrs[el instanceof Component ? el.tagName || '' : el.name] || [];
31617
32279
  el.attrs
31618
- .filter((attr) => attr.name.startsWith(_I18N_ATTR_PREFIX))
31619
- .forEach((attr) => (explicitAttrNameToValue[attr.name.slice(_I18N_ATTR_PREFIX.length)] = attr.value));
32280
+ .filter((attr) => attr instanceof Attribute && attr.name.startsWith(_I18N_ATTR_PREFIX))
32281
+ .forEach((attr) => {
32282
+ explicitAttrNameToValue[attr.name.slice(_I18N_ATTR_PREFIX.length)] = attr.value;
32283
+ });
31620
32284
  el.attrs.forEach((attr) => {
31621
32285
  if (attr.name in explicitAttrNameToValue) {
31622
32286
  this._addMessage([attr], explicitAttrNameToValue[attr.name]);
@@ -31689,16 +32353,15 @@ class _Visitor {
31689
32353
  return [];
31690
32354
  }
31691
32355
  // translate the attributes of an element and remove i18n specific attributes
31692
- _translateAttributes(el) {
31693
- const attributes = el.attrs;
32356
+ _translateAttributes(node) {
31694
32357
  const i18nParsedMessageMeta = {};
31695
- attributes.forEach((attr) => {
32358
+ const translatedAttributes = [];
32359
+ node.attrs.forEach((attr) => {
31696
32360
  if (attr.name.startsWith(_I18N_ATTR_PREFIX)) {
31697
32361
  i18nParsedMessageMeta[attr.name.slice(_I18N_ATTR_PREFIX.length)] = _parseMessageMeta(attr.value);
31698
32362
  }
31699
32363
  });
31700
- const translatedAttributes = [];
31701
- attributes.forEach((attr) => {
32364
+ node.attrs.forEach((attr) => {
31702
32365
  if (attr.name === _I18N_ATTR || attr.name.startsWith(_I18N_ATTR_PREFIX)) {
31703
32366
  // strip i18n specific attributes
31704
32367
  return;
@@ -31716,11 +32379,11 @@ class _Visitor {
31716
32379
  translatedAttributes.push(new Attribute(attr.name, value, attr.sourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* valueTokens */, undefined /* i18n */));
31717
32380
  }
31718
32381
  else {
31719
- this._reportError(el, `Unexpected translation for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
32382
+ this._reportError(node, `Unexpected translation for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
31720
32383
  }
31721
32384
  }
31722
32385
  else {
31723
- this._reportError(el, `Translation unavailable for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
32386
+ this._reportError(node, `Translation unavailable for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
31724
32387
  }
31725
32388
  }
31726
32389
  else {
@@ -31729,6 +32392,9 @@ class _Visitor {
31729
32392
  });
31730
32393
  return translatedAttributes;
31731
32394
  }
32395
+ _translateDirectives(node) {
32396
+ return node.directives.map((dir) => new Directive(dir.name, this._translateAttributes(dir), dir.sourceSpan, dir.startSourceSpan, dir.endSourceSpan));
32397
+ }
31732
32398
  /**
31733
32399
  * Add the node as a child of the block when:
31734
32400
  * - we are in a block,
@@ -31804,7 +32470,7 @@ function _isClosingComment(n) {
31804
32470
  return !!(n instanceof Comment && n.value && n.value === '/i18n');
31805
32471
  }
31806
32472
  function _getI18nAttr(p) {
31807
- return p.attrs.find((attr) => attr.name === _I18N_ATTR) || null;
32473
+ return (p.attrs.find((attr) => attr instanceof Attribute && attr.name === _I18N_ATTR) || null);
31808
32474
  }
31809
32475
  function _parseMessageMeta(i18n) {
31810
32476
  if (!i18n)
@@ -31852,7 +32518,12 @@ class XmlParser extends Parser$1 {
31852
32518
  }
31853
32519
  parse(source, url, options = {}) {
31854
32520
  // Blocks and let declarations aren't supported in an XML context.
31855
- return super.parse(source, url, { ...options, tokenizeBlocks: false, tokenizeLet: false });
32521
+ return super.parse(source, url, {
32522
+ ...options,
32523
+ tokenizeBlocks: false,
32524
+ tokenizeLet: false,
32525
+ selectorlessEnabled: false,
32526
+ });
31856
32527
  }
31857
32528
  }
31858
32529
 
@@ -32076,6 +32747,8 @@ class XliffParser {
32076
32747
  visitBlock(block, context) { }
32077
32748
  visitBlockParameter(parameter, context) { }
32078
32749
  visitLetDeclaration(decl, context) { }
32750
+ visitComponent(component, context) { }
32751
+ visitDirective(directive, context) { }
32079
32752
  _addError(node, message) {
32080
32753
  this._errors.push(new I18nError(node.sourceSpan, message));
32081
32754
  }
@@ -32131,6 +32804,12 @@ let XmlToI18n$2 = class XmlToI18n {
32131
32804
  visitBlock(block, context) { }
32132
32805
  visitBlockParameter(parameter, context) { }
32133
32806
  visitLetDeclaration(decl, context) { }
32807
+ visitComponent(component, context) {
32808
+ this._addError(component, 'Unexpected node');
32809
+ }
32810
+ visitDirective(directive, context) {
32811
+ this._addError(directive, 'Unexpected node');
32812
+ }
32134
32813
  _addError(node, message) {
32135
32814
  this._errors.push(new I18nError(node.sourceSpan, message));
32136
32815
  }
@@ -32391,6 +33070,8 @@ class Xliff2Parser {
32391
33070
  visitBlock(block, context) { }
32392
33071
  visitBlockParameter(parameter, context) { }
32393
33072
  visitLetDeclaration(decl, context) { }
33073
+ visitComponent(component, context) { }
33074
+ visitDirective(directive, context) { }
32394
33075
  _addError(node, message) {
32395
33076
  this._errors.push(new I18nError(node.sourceSpan, message));
32396
33077
  }
@@ -32463,6 +33144,12 @@ let XmlToI18n$1 = class XmlToI18n {
32463
33144
  visitBlock(block, context) { }
32464
33145
  visitBlockParameter(parameter, context) { }
32465
33146
  visitLetDeclaration(decl, context) { }
33147
+ visitComponent(component, context) {
33148
+ this._addError(component, 'Unexpected node');
33149
+ }
33150
+ visitDirective(directive, context) {
33151
+ this._addError(directive, 'Unexpected node');
33152
+ }
32466
33153
  _addError(node, message) {
32467
33154
  this._errors.push(new I18nError(node.sourceSpan, message));
32468
33155
  }
@@ -32602,6 +33289,12 @@ class XtbParser {
32602
33289
  visitBlock(block, context) { }
32603
33290
  visitBlockParameter(block, context) { }
32604
33291
  visitLetDeclaration(decl, context) { }
33292
+ visitComponent(component, context) {
33293
+ this._addError(component, 'Unexpected node');
33294
+ }
33295
+ visitDirective(directive, context) {
33296
+ this._addError(directive, 'Unexpected node');
33297
+ }
32605
33298
  _addError(node, message) {
32606
33299
  this._errors.push(new I18nError(node.sourceSpan, message));
32607
33300
  }
@@ -32655,6 +33348,12 @@ class XmlToI18n {
32655
33348
  visitBlock(block, context) { }
32656
33349
  visitBlockParameter(block, context) { }
32657
33350
  visitLetDeclaration(decl, context) { }
33351
+ visitComponent(component, context) {
33352
+ this._addError(component, 'Unexpected node');
33353
+ }
33354
+ visitDirective(directive, context) {
33355
+ this._addError(directive, 'Unexpected node');
33356
+ }
32658
33357
  _addError(node, message) {
32659
33358
  this._errors.push(new I18nError(node.sourceSpan, message));
32660
33359
  }
@@ -33068,7 +33767,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
33068
33767
  function compileDeclareClassMetadata(metadata) {
33069
33768
  const definitionMap = new DefinitionMap();
33070
33769
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
33071
- definitionMap.set('version', literal('20.0.0-next.5'));
33770
+ definitionMap.set('version', literal('20.0.0-next.7'));
33072
33771
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33073
33772
  definitionMap.set('type', metadata.type);
33074
33773
  definitionMap.set('decorators', metadata.decorators);
@@ -33086,7 +33785,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
33086
33785
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
33087
33786
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
33088
33787
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
33089
- definitionMap.set('version', literal('20.0.0-next.5'));
33788
+ definitionMap.set('version', literal('20.0.0-next.7'));
33090
33789
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33091
33790
  definitionMap.set('type', metadata.type);
33092
33791
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -33181,7 +33880,7 @@ function createDirectiveDefinitionMap(meta) {
33181
33880
  const definitionMap = new DefinitionMap();
33182
33881
  const minVersion = getMinimumVersionForPartialOutput(meta);
33183
33882
  definitionMap.set('minVersion', literal(minVersion));
33184
- definitionMap.set('version', literal('20.0.0-next.5'));
33883
+ definitionMap.set('version', literal('20.0.0-next.7'));
33185
33884
  // e.g. `type: MyDirective`
33186
33885
  definitionMap.set('type', meta.type.value);
33187
33886
  if (meta.isStandalone !== undefined) {
@@ -33597,7 +34296,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
33597
34296
  function compileDeclareFactoryFunction(meta) {
33598
34297
  const definitionMap = new DefinitionMap();
33599
34298
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
33600
- definitionMap.set('version', literal('20.0.0-next.5'));
34299
+ definitionMap.set('version', literal('20.0.0-next.7'));
33601
34300
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33602
34301
  definitionMap.set('type', meta.type.value);
33603
34302
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -33632,7 +34331,7 @@ function compileDeclareInjectableFromMetadata(meta) {
33632
34331
  function createInjectableDefinitionMap(meta) {
33633
34332
  const definitionMap = new DefinitionMap();
33634
34333
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
33635
- definitionMap.set('version', literal('20.0.0-next.5'));
34334
+ definitionMap.set('version', literal('20.0.0-next.7'));
33636
34335
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33637
34336
  definitionMap.set('type', meta.type.value);
33638
34337
  // Only generate providedIn property if it has a non-null value
@@ -33683,7 +34382,7 @@ function compileDeclareInjectorFromMetadata(meta) {
33683
34382
  function createInjectorDefinitionMap(meta) {
33684
34383
  const definitionMap = new DefinitionMap();
33685
34384
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
33686
- definitionMap.set('version', literal('20.0.0-next.5'));
34385
+ definitionMap.set('version', literal('20.0.0-next.7'));
33687
34386
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33688
34387
  definitionMap.set('type', meta.type.value);
33689
34388
  definitionMap.set('providers', meta.providers);
@@ -33716,7 +34415,7 @@ function createNgModuleDefinitionMap(meta) {
33716
34415
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
33717
34416
  }
33718
34417
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
33719
- definitionMap.set('version', literal('20.0.0-next.5'));
34418
+ definitionMap.set('version', literal('20.0.0-next.7'));
33720
34419
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33721
34420
  definitionMap.set('type', meta.type.value);
33722
34421
  // We only generate the keys in the metadata if the arrays contain values.
@@ -33767,7 +34466,7 @@ function compileDeclarePipeFromMetadata(meta) {
33767
34466
  function createPipeDefinitionMap(meta) {
33768
34467
  const definitionMap = new DefinitionMap();
33769
34468
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
33770
- definitionMap.set('version', literal('20.0.0-next.5'));
34469
+ definitionMap.set('version', literal('20.0.0-next.7'));
33771
34470
  definitionMap.set('ngImport', importExpr(Identifiers.core));
33772
34471
  // e.g. `type: MyPipe`
33773
34472
  definitionMap.set('type', meta.type.value);
@@ -33925,7 +34624,7 @@ function compileHmrUpdateCallback(definitions, constantStatements, meta) {
33925
34624
  * @description
33926
34625
  * Entry point for all public APIs of the compiler package.
33927
34626
  */
33928
- const VERSION = new Version('20.0.0-next.5');
34627
+ const VERSION = new Version('20.0.0-next.7');
33929
34628
 
33930
34629
  //////////////////////////////////////
33931
34630
  // THIS FILE HAS GLOBAL SIDE EFFECT //
@@ -33951,5 +34650,5 @@ const VERSION = new Version('20.0.0-next.5');
33951
34650
  // the late binding of the Compiler to the @angular/core for jit compilation.
33952
34651
  publishFacade(_global);
33953
34652
 
33954
- export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, ArrowFunctionExpr, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, BindingType, 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, LetDeclaration, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParenthesizedExpr, ParenthesizedExpression, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedEventType, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, 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, StringToken, StringTokenKind, TagContentType, TaggedTemplateLiteral, TaggedTemplateLiteralExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, TemplateLiteralElementExpr, TemplateLiteralExpr, Text, ThisReceiver, BlockNode as TmplAstBlockNode, 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, HostElement as TmplAstHostElement, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, Icu$1 as TmplAstIcu, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, LetDeclaration$1 as TmplAstLetDeclaration, NeverDeferredTrigger as TmplAstNeverDeferredTrigger, 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, TypeofExpression, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, VoidExpr, VoidExpression, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, compileClassDebugInfo, compileClassMetadata, compileComponentClassMetadata, compileComponentDeclareClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDeferResolverFunction, compileDirectiveFromMetadata, compileFactoryFunction, compileHmrInitializer, compileHmrUpdateCallback, compileInjectable, compileInjector, compileNgModule, compileOpaqueAsyncClassMetadata, compilePipeFromMetadata, computeMsgId, core, createCssSelectorFromNode, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, encapsulateStyle, findMatchingDirectivesAndPipes, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literal, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, visitAll$1 as tmplAstVisitAll, verifyHostBindings, visitAll };
34653
+ export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, ArrowFunctionExpr, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, BindingType, Block, BlockParameter, BoundElementProperty, BuiltinType, BuiltinTypeName, CUSTOM_ELEMENTS_SCHEMA, Call, Chain, ChangeDetectionStrategy, CommaExpr, Comment, CompilerConfig, Component, Conditional, ConditionalExpr, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DYNAMIC_TYPE, DeclareFunctionStmt, DeclareVarStmt, Directive, 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, LetDeclaration, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParenthesizedExpr, ParenthesizedExpression, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedEventType, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, 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, StringToken, StringTokenKind, TagContentType, TaggedTemplateLiteral, TaggedTemplateLiteralExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, TemplateLiteralElementExpr, TemplateLiteralExpr, Text, ThisReceiver, BlockNode as TmplAstBlockNode, BoundAttribute as TmplAstBoundAttribute, BoundDeferredTrigger as TmplAstBoundDeferredTrigger, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Component$1 as TmplAstComponent, Content as TmplAstContent, DeferredBlock as TmplAstDeferredBlock, DeferredBlockError as TmplAstDeferredBlockError, DeferredBlockLoading as TmplAstDeferredBlockLoading, DeferredBlockPlaceholder as TmplAstDeferredBlockPlaceholder, DeferredTrigger as TmplAstDeferredTrigger, Directive$1 as TmplAstDirective, Element$1 as TmplAstElement, ForLoopBlock as TmplAstForLoopBlock, ForLoopBlockEmpty as TmplAstForLoopBlockEmpty, HostElement as TmplAstHostElement, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, Icu$1 as TmplAstIcu, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, LetDeclaration$1 as TmplAstLetDeclaration, NeverDeferredTrigger as TmplAstNeverDeferredTrigger, 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, TypeofExpression, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, VoidExpr, VoidExpression, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, compileClassDebugInfo, compileClassMetadata, compileComponentClassMetadata, compileComponentDeclareClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDeferResolverFunction, compileDirectiveFromMetadata, compileFactoryFunction, compileHmrInitializer, compileHmrUpdateCallback, compileInjectable, compileInjector, compileNgModule, compileOpaqueAsyncClassMetadata, compilePipeFromMetadata, computeMsgId, core, createCssSelectorFromNode, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, encapsulateStyle, findMatchingDirectivesAndPipes, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literal, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, visitAll$1 as tmplAstVisitAll, verifyHostBindings, visitAll };
33955
34654
  //# sourceMappingURL=compiler.mjs.map