@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.
- package/fesm2022/compiler.mjs +1006 -307
- package/fesm2022/compiler.mjs.map +1 -1
- package/index.d.ts +83 -9
- package/package.json +1 -1
package/fesm2022/compiler.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.0.0-next.
|
|
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(
|
|
6185
|
-
return
|
|
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(
|
|
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(
|
|
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
|
|
16546
|
+
let closingTagName;
|
|
16547
|
+
let openToken;
|
|
16407
16548
|
try {
|
|
16408
|
-
if (
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
|
|
16416
|
-
|
|
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
|
-
|
|
16422
|
-
|
|
16423
|
-
|
|
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.
|
|
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 (
|
|
16591
|
+
if (openToken) {
|
|
16432
16592
|
// We errored before we could close the opening tag, so it is incomplete.
|
|
16433
|
-
|
|
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(
|
|
16610
|
+
this._consumeRawTextWithTagClose(openToken, closingTagName, false);
|
|
16448
16611
|
}
|
|
16449
16612
|
else if (contentTokenType === TagContentType.ESCAPABLE_RAW_TEXT) {
|
|
16450
|
-
this._consumeRawTextWithTagClose(
|
|
16613
|
+
this._consumeRawTextWithTagClose(openToken, closingTagName, true);
|
|
16451
16614
|
}
|
|
16452
16615
|
}
|
|
16453
|
-
_consumeRawTextWithTagClose(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
17383
|
+
constructor(tokens, tagDefinitionResolver) {
|
|
17090
17384
|
this.tokens = tokens;
|
|
17091
|
-
this.
|
|
17385
|
+
this.tagDefinitionResolver = tagDefinitionResolver;
|
|
17092
17386
|
this._advance();
|
|
17093
17387
|
}
|
|
17094
17388
|
build() {
|
|
17095
|
-
while (this._peek.type !==
|
|
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.
|
|
17392
|
+
this._consumeElementStartTag(this._advance());
|
|
17099
17393
|
}
|
|
17100
17394
|
else if (this._peek.type === 3 /* TokenType.TAG_CLOSE */) {
|
|
17101
|
-
this.
|
|
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:
|
|
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.
|
|
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 ===
|
|
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.
|
|
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
|
|
17600
|
+
if (el !== null && this._getTagDefinition(el)?.isVoid) {
|
|
17300
17601
|
this._containerStack.pop();
|
|
17301
17602
|
}
|
|
17302
17603
|
}
|
|
17303
|
-
|
|
17304
|
-
const [prefix, name] = startTagToken.parts;
|
|
17604
|
+
_consumeElementStartTag(startTagToken) {
|
|
17305
17605
|
const attrs = [];
|
|
17306
|
-
|
|
17307
|
-
|
|
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.
|
|
17317
|
-
if (!(tagDef
|
|
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
|
|
17331
|
-
|
|
17332
|
-
|
|
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
|
-
|
|
17353
|
-
const fullName = this._getElementFullName(endTagToken
|
|
17354
|
-
if (this.
|
|
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
|
-
|
|
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
|
-
|
|
17924
|
+
_getClosestElementLikeParent() {
|
|
17534
17925
|
for (let i = this._containerStack.length - 1; i > -1; i--) {
|
|
17535
|
-
|
|
17536
|
-
|
|
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(
|
|
17551
|
-
|
|
17552
|
-
|
|
17553
|
-
|
|
17554
|
-
|
|
17555
|
-
|
|
17556
|
-
|
|
17557
|
-
|
|
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
|
|
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
|
-
|
|
20619
|
-
|
|
20620
|
-
|
|
20621
|
-
|
|
20622
|
-
|
|
20623
|
-
|
|
20624
|
-
|
|
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(
|
|
21503
|
+
if (hasI18nAttrs(node)) {
|
|
20977
21504
|
this.hasI18nMeta = true;
|
|
20978
21505
|
const attrs = [];
|
|
20979
21506
|
const attrsMeta = {};
|
|
20980
|
-
for (const attr of
|
|
21507
|
+
for (const attr of node.attrs) {
|
|
20981
21508
|
if (attr.name === I18N_ATTR) {
|
|
20982
21509
|
// root 'i18n' node attribute
|
|
20983
|
-
const i18n =
|
|
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
|
-
?
|
|
20998
|
-
: visitAllWithSiblings(new WhitespaceVisitor(false /* preserveSignificantWhitespace */, originalNodeMap),
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
21569
|
+
node.attrs = attrs;
|
|
21036
21570
|
}
|
|
21037
21571
|
}
|
|
21038
|
-
visitAll(this,
|
|
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
|
-
|
|
27505
|
-
|
|
27506
|
-
|
|
27507
|
-
|
|
27508
|
-
|
|
27509
|
-
|
|
27510
|
-
|
|
27511
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
28898
|
-
|
|
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 */ [],
|
|
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.
|
|
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
|
|
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) =>
|
|
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(
|
|
31547
|
-
translatedChildNodes = this._translateMessage(
|
|
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(
|
|
31553
|
-
visitAll(this,
|
|
32235
|
+
this._openTranslatableSection(node);
|
|
32236
|
+
visitAll(this, node.children);
|
|
31554
32237
|
if (isTranslatable)
|
|
31555
|
-
this._closeTranslatableSection(
|
|
32238
|
+
this._closeTranslatableSection(node, node.children);
|
|
31556
32239
|
}
|
|
31557
32240
|
}
|
|
31558
32241
|
else {
|
|
31559
32242
|
if (i18nAttr || isTopLevelImplicit) {
|
|
31560
|
-
this._reportError(
|
|
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,
|
|
32247
|
+
visitAll(this, node.children);
|
|
31565
32248
|
}
|
|
31566
32249
|
}
|
|
31567
32250
|
if (this._mode === _VisitorMode.Merge) {
|
|
31568
|
-
const visitNodes = translatedChildNodes ||
|
|
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(
|
|
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
|
-
|
|
31584
|
-
|
|
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) =>
|
|
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(
|
|
31693
|
-
const attributes = el.attrs;
|
|
32356
|
+
_translateAttributes(node) {
|
|
31694
32357
|
const i18nParsedMessageMeta = {};
|
|
31695
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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, {
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|