@angular/compiler 21.0.0-next.5 → 21.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 +214 -153
- package/fesm2022/compiler.mjs.map +1 -1
- package/package.json +3 -3
- package/{index.d.ts → types/compiler.d.ts} +23 -41
package/fesm2022/compiler.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v21.0.0-next.
|
|
3
|
-
* (c) 2010-2025 Google LLC. https://angular.
|
|
2
|
+
* @license Angular v21.0.0-next.7
|
|
3
|
+
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -2844,6 +2844,8 @@ class Identifiers {
|
|
|
2844
2844
|
static domProperty = { name: 'ɵɵdomProperty', moduleName: CORE };
|
|
2845
2845
|
static ariaProperty = { name: 'ɵɵariaProperty', moduleName: CORE };
|
|
2846
2846
|
static property = { name: 'ɵɵproperty', moduleName: CORE };
|
|
2847
|
+
static control = { name: 'ɵɵcontrol', moduleName: CORE };
|
|
2848
|
+
static controlCreate = { name: 'ɵɵcontrolCreate', moduleName: CORE };
|
|
2847
2849
|
static animationEnterListener = {
|
|
2848
2850
|
name: 'ɵɵanimateEnterListener',
|
|
2849
2851
|
moduleName: CORE,
|
|
@@ -6430,48 +6432,6 @@ function createFactoryFunction(type) {
|
|
|
6430
6432
|
return arrowFn([t], type.prop('ɵfac').callFn([variable(t.name)]));
|
|
6431
6433
|
}
|
|
6432
6434
|
|
|
6433
|
-
const UNUSABLE_INTERPOLATION_REGEXPS = [
|
|
6434
|
-
/@/, // control flow reserved symbol
|
|
6435
|
-
/^\s*$/, // empty
|
|
6436
|
-
/[<>]/, // html tag
|
|
6437
|
-
/^[{}]$/, // i18n expansion
|
|
6438
|
-
/&(#|[a-z])/i, // character reference,
|
|
6439
|
-
/^\/\//, // comment
|
|
6440
|
-
];
|
|
6441
|
-
function assertInterpolationSymbols(identifier, value) {
|
|
6442
|
-
if (value != null && !(Array.isArray(value) && value.length == 2)) {
|
|
6443
|
-
throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
|
|
6444
|
-
}
|
|
6445
|
-
else if (value != null) {
|
|
6446
|
-
const start = value[0];
|
|
6447
|
-
const end = value[1];
|
|
6448
|
-
// Check for unusable interpolation symbols
|
|
6449
|
-
UNUSABLE_INTERPOLATION_REGEXPS.forEach((regexp) => {
|
|
6450
|
-
if (regexp.test(start) || regexp.test(end)) {
|
|
6451
|
-
throw new Error(`['${start}', '${end}'] contains unusable interpolation symbol.`);
|
|
6452
|
-
}
|
|
6453
|
-
});
|
|
6454
|
-
}
|
|
6455
|
-
}
|
|
6456
|
-
|
|
6457
|
-
class InterpolationConfig {
|
|
6458
|
-
start;
|
|
6459
|
-
end;
|
|
6460
|
-
static fromArray(markers) {
|
|
6461
|
-
if (!markers) {
|
|
6462
|
-
return DEFAULT_INTERPOLATION_CONFIG;
|
|
6463
|
-
}
|
|
6464
|
-
assertInterpolationSymbols('interpolation', markers);
|
|
6465
|
-
return new InterpolationConfig(markers[0], markers[1]);
|
|
6466
|
-
}
|
|
6467
|
-
constructor(start, end) {
|
|
6468
|
-
this.start = start;
|
|
6469
|
-
this.end = end;
|
|
6470
|
-
}
|
|
6471
|
-
}
|
|
6472
|
-
const DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}');
|
|
6473
|
-
const DEFAULT_CONTAINER_BLOCKS = new Set(['switch']);
|
|
6474
|
-
|
|
6475
6435
|
const $EOF = 0;
|
|
6476
6436
|
const $BSPACE = 8;
|
|
6477
6437
|
const $TAB = 9;
|
|
@@ -8825,6 +8785,17 @@ var OpKind;
|
|
|
8825
8785
|
* An operation to bind animation events to an element.
|
|
8826
8786
|
*/
|
|
8827
8787
|
OpKind[OpKind["AnimationListener"] = 56] = "AnimationListener";
|
|
8788
|
+
/**
|
|
8789
|
+
* An operation to bind an expression to a `control` property of an element.
|
|
8790
|
+
*/
|
|
8791
|
+
OpKind[OpKind["Control"] = 57] = "Control";
|
|
8792
|
+
/**
|
|
8793
|
+
* An operation to set up a corresponding {@link Control} operation.
|
|
8794
|
+
*
|
|
8795
|
+
* This is responsible for setting up event listeners on a native or custom form control when
|
|
8796
|
+
* bound to a specialized control directive.
|
|
8797
|
+
*/
|
|
8798
|
+
OpKind[OpKind["ControlCreate"] = 58] = "ControlCreate";
|
|
8828
8799
|
})(OpKind || (OpKind = {}));
|
|
8829
8800
|
/**
|
|
8830
8801
|
* Distinguishes different kinds of IR expressions.
|
|
@@ -9495,6 +9466,25 @@ function createStoreLetOp(target, declaredName, value, sourceSpan) {
|
|
|
9495
9466
|
...NEW_OP,
|
|
9496
9467
|
};
|
|
9497
9468
|
}
|
|
9469
|
+
/** Creates a {@link ControlOp}. */
|
|
9470
|
+
function createControlOp(op) {
|
|
9471
|
+
return {
|
|
9472
|
+
kind: OpKind.Control,
|
|
9473
|
+
target: op.target,
|
|
9474
|
+
expression: op.expression,
|
|
9475
|
+
bindingKind: op.bindingKind,
|
|
9476
|
+
securityContext: op.securityContext,
|
|
9477
|
+
sanitizer: null,
|
|
9478
|
+
isStructuralTemplateAttribute: op.isStructuralTemplateAttribute,
|
|
9479
|
+
templateKind: op.templateKind,
|
|
9480
|
+
i18nContext: op.i18nContext,
|
|
9481
|
+
i18nMessage: op.i18nMessage,
|
|
9482
|
+
sourceSpan: op.sourceSpan,
|
|
9483
|
+
...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
|
|
9484
|
+
...TRAIT_CONSUMES_VARS,
|
|
9485
|
+
...NEW_OP,
|
|
9486
|
+
};
|
|
9487
|
+
}
|
|
9498
9488
|
|
|
9499
9489
|
/**
|
|
9500
9490
|
* Check whether a given `o.Expression` is a logical IR expression type.
|
|
@@ -10277,6 +10267,7 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
10277
10267
|
case OpKind.Property:
|
|
10278
10268
|
case OpKind.DomProperty:
|
|
10279
10269
|
case OpKind.Attribute:
|
|
10270
|
+
case OpKind.Control:
|
|
10280
10271
|
if (op.expression instanceof Interpolation) {
|
|
10281
10272
|
transformExpressionsInInterpolation(op.expression, transform, flags);
|
|
10282
10273
|
}
|
|
@@ -10402,6 +10393,7 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
10402
10393
|
case OpKind.SourceLocation:
|
|
10403
10394
|
case OpKind.ConditionalCreate:
|
|
10404
10395
|
case OpKind.ConditionalBranchCreate:
|
|
10396
|
+
case OpKind.ControlCreate:
|
|
10405
10397
|
// These operations contain no expressions.
|
|
10406
10398
|
break;
|
|
10407
10399
|
default:
|
|
@@ -11302,6 +11294,10 @@ function createSourceLocationOp(templatePath, locations) {
|
|
|
11302
11294
|
...NEW_OP,
|
|
11303
11295
|
};
|
|
11304
11296
|
}
|
|
11297
|
+
/** Creates a {@link ControlCreateOp}. */
|
|
11298
|
+
function createControlCreateOp(sourceSpan) {
|
|
11299
|
+
return { kind: OpKind.ControlCreate, sourceSpan, ...NEW_OP };
|
|
11300
|
+
}
|
|
11305
11301
|
|
|
11306
11302
|
function createDomPropertyOp(name, expression, bindingKind, i18nContext, securityContext, sourceSpan) {
|
|
11307
11303
|
return {
|
|
@@ -11780,6 +11776,14 @@ function extractAttributes(job) {
|
|
|
11780
11776
|
/* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
|
|
11781
11777
|
}
|
|
11782
11778
|
break;
|
|
11779
|
+
case OpKind.Control:
|
|
11780
|
+
OpList.insertBefore(
|
|
11781
|
+
// Deliberately null i18nMessage value
|
|
11782
|
+
createExtractedAttributeOp(op.target, BindingKind.Property, null, 'control',
|
|
11783
|
+
/* expression */ null,
|
|
11784
|
+
/* i18nContext */ null,
|
|
11785
|
+
/* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
|
|
11786
|
+
break;
|
|
11783
11787
|
case OpKind.TwoWayProperty:
|
|
11784
11788
|
OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.TwoWayProperty, null, op.name,
|
|
11785
11789
|
/* expression */ null,
|
|
@@ -11939,6 +11943,9 @@ function specializeBindings(job) {
|
|
|
11939
11943
|
else if (job.kind === CompilationJobKind.Host) {
|
|
11940
11944
|
OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind, op.i18nContext, op.securityContext, op.sourceSpan));
|
|
11941
11945
|
}
|
|
11946
|
+
else if (op.name === 'control') {
|
|
11947
|
+
OpList.replace(op, createControlOp(op));
|
|
11948
|
+
}
|
|
11942
11949
|
else {
|
|
11943
11950
|
OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
|
|
11944
11951
|
}
|
|
@@ -16053,12 +16060,15 @@ const SUPPORTED_BLOCKS = [
|
|
|
16053
16060
|
'@loading',
|
|
16054
16061
|
'@error',
|
|
16055
16062
|
];
|
|
16063
|
+
const INTERPOLATION = {
|
|
16064
|
+
start: '{{',
|
|
16065
|
+
end: '}}',
|
|
16066
|
+
};
|
|
16056
16067
|
// See https://www.w3.org/TR/html51/syntax.html#writing-html-documents
|
|
16057
16068
|
class _Tokenizer {
|
|
16058
16069
|
_getTagDefinition;
|
|
16059
16070
|
_cursor;
|
|
16060
16071
|
_tokenizeIcu;
|
|
16061
|
-
_interpolationConfig;
|
|
16062
16072
|
_leadingTriviaCodePoints;
|
|
16063
16073
|
_currentTokenStart = null;
|
|
16064
16074
|
_currentTokenType = null;
|
|
@@ -16081,7 +16091,6 @@ class _Tokenizer {
|
|
|
16081
16091
|
constructor(_file, _getTagDefinition, options) {
|
|
16082
16092
|
this._getTagDefinition = _getTagDefinition;
|
|
16083
16093
|
this._tokenizeIcu = options.tokenizeExpansionForms || false;
|
|
16084
|
-
this._interpolationConfig = options.interpolationConfig || DEFAULT_INTERPOLATION_CONFIG;
|
|
16085
16094
|
this._leadingTriviaCodePoints =
|
|
16086
16095
|
options.leadingTriviaChars && options.leadingTriviaChars.map((c) => c.codePointAt(0) || 0);
|
|
16087
16096
|
const range = options.range || {
|
|
@@ -16912,7 +16921,7 @@ class _Tokenizer {
|
|
|
16912
16921
|
const parts = [];
|
|
16913
16922
|
while (!endPredicate()) {
|
|
16914
16923
|
const current = this._cursor.clone();
|
|
16915
|
-
if (this.
|
|
16924
|
+
if (this._attemptStr(INTERPOLATION.start)) {
|
|
16916
16925
|
this._endToken([this._processCarriageReturns(parts.join(''))], current);
|
|
16917
16926
|
parts.length = 0;
|
|
16918
16927
|
this._consumeInterpolation(interpolationTokenType, current, endInterpolation);
|
|
@@ -16944,7 +16953,7 @@ class _Tokenizer {
|
|
|
16944
16953
|
_consumeInterpolation(interpolationTokenType, interpolationStart, prematureEndPredicate) {
|
|
16945
16954
|
const parts = [];
|
|
16946
16955
|
this._beginToken(interpolationTokenType, interpolationStart);
|
|
16947
|
-
parts.push(
|
|
16956
|
+
parts.push(INTERPOLATION.start);
|
|
16948
16957
|
// Find the end of the interpolation, ignoring content inside quotes.
|
|
16949
16958
|
const expressionStart = this._cursor.clone();
|
|
16950
16959
|
let inQuote = null;
|
|
@@ -16962,10 +16971,10 @@ class _Tokenizer {
|
|
|
16962
16971
|
return;
|
|
16963
16972
|
}
|
|
16964
16973
|
if (inQuote === null) {
|
|
16965
|
-
if (this._attemptStr(
|
|
16974
|
+
if (this._attemptStr(INTERPOLATION.end)) {
|
|
16966
16975
|
// We are not in a string, and we hit the end interpolation marker
|
|
16967
16976
|
parts.push(this._getProcessedChars(expressionStart, current));
|
|
16968
|
-
parts.push(
|
|
16977
|
+
parts.push(INTERPOLATION.end);
|
|
16969
16978
|
this._endToken(parts);
|
|
16970
16979
|
return;
|
|
16971
16980
|
}
|
|
@@ -17104,13 +17113,10 @@ class _Tokenizer {
|
|
|
17104
17113
|
if (this._cursor.peek() !== $LBRACE) {
|
|
17105
17114
|
return false;
|
|
17106
17115
|
}
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
return !isInterpolation;
|
|
17112
|
-
}
|
|
17113
|
-
return true;
|
|
17116
|
+
const start = this._cursor.clone();
|
|
17117
|
+
const isInterpolation = this._attemptStr(INTERPOLATION.start);
|
|
17118
|
+
this._cursor = start;
|
|
17119
|
+
return !isInterpolation;
|
|
17114
17120
|
}
|
|
17115
17121
|
}
|
|
17116
17122
|
function isNotWhitespace(code) {
|
|
@@ -18430,9 +18436,6 @@ class Token {
|
|
|
18430
18436
|
isTemplateLiteralInterpolationStart() {
|
|
18431
18437
|
return this.isOperator('${');
|
|
18432
18438
|
}
|
|
18433
|
-
isTemplateLiteralInterpolationEnd() {
|
|
18434
|
-
return this.isOperator('}');
|
|
18435
|
-
}
|
|
18436
18439
|
toString() {
|
|
18437
18440
|
switch (this.type) {
|
|
18438
18441
|
case TokenType.Character:
|
|
@@ -18615,7 +18618,7 @@ class _Scanner {
|
|
|
18615
18618
|
this.advance();
|
|
18616
18619
|
const currentBrace = this.braceStack.pop();
|
|
18617
18620
|
if (currentBrace === 'interpolation') {
|
|
18618
|
-
this.tokens.push(
|
|
18621
|
+
this.tokens.push(newCharacterToken(start, this.index, $RBRACE));
|
|
18619
18622
|
return this.scanTemplateLiteralPart(this.index);
|
|
18620
18623
|
}
|
|
18621
18624
|
return newCharacterToken(start, this.index, code);
|
|
@@ -18979,17 +18982,17 @@ class Parser {
|
|
|
18979
18982
|
this._lexer = _lexer;
|
|
18980
18983
|
this._supportsDirectPipeReferences = _supportsDirectPipeReferences;
|
|
18981
18984
|
}
|
|
18982
|
-
parseAction(input, parseSourceSpan, absoluteOffset
|
|
18985
|
+
parseAction(input, parseSourceSpan, absoluteOffset) {
|
|
18983
18986
|
const errors = [];
|
|
18984
|
-
this._checkNoInterpolation(errors, input, parseSourceSpan
|
|
18987
|
+
this._checkNoInterpolation(errors, input, parseSourceSpan);
|
|
18985
18988
|
const { stripped: sourceToLex } = this._stripComments(input);
|
|
18986
18989
|
const tokens = this._lexer.tokenize(sourceToLex);
|
|
18987
18990
|
const ast = new _ParseAST(input, parseSourceSpan, absoluteOffset, tokens, 1 /* ParseFlags.Action */, errors, 0, this._supportsDirectPipeReferences).parseChain();
|
|
18988
18991
|
return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
|
|
18989
18992
|
}
|
|
18990
|
-
parseBinding(input, parseSourceSpan, absoluteOffset
|
|
18993
|
+
parseBinding(input, parseSourceSpan, absoluteOffset) {
|
|
18991
18994
|
const errors = [];
|
|
18992
|
-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset,
|
|
18995
|
+
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
|
|
18993
18996
|
return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
|
|
18994
18997
|
}
|
|
18995
18998
|
checkSimpleExpression(ast) {
|
|
@@ -18998,17 +19001,17 @@ class Parser {
|
|
|
18998
19001
|
return checker.errors;
|
|
18999
19002
|
}
|
|
19000
19003
|
// Host bindings parsed here
|
|
19001
|
-
parseSimpleBinding(input, parseSourceSpan, absoluteOffset
|
|
19004
|
+
parseSimpleBinding(input, parseSourceSpan, absoluteOffset) {
|
|
19002
19005
|
const errors = [];
|
|
19003
|
-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset,
|
|
19006
|
+
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
|
|
19004
19007
|
const simplExpressionErrors = this.checkSimpleExpression(ast);
|
|
19005
19008
|
if (simplExpressionErrors.length > 0) {
|
|
19006
19009
|
errors.push(getParseError(`Host binding expression cannot contain ${simplExpressionErrors.join(' ')}`, input, '', parseSourceSpan));
|
|
19007
19010
|
}
|
|
19008
19011
|
return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
|
|
19009
19012
|
}
|
|
19010
|
-
_parseBindingAst(input, parseSourceSpan, absoluteOffset,
|
|
19011
|
-
this._checkNoInterpolation(errors, input, parseSourceSpan
|
|
19013
|
+
_parseBindingAst(input, parseSourceSpan, absoluteOffset, errors) {
|
|
19014
|
+
this._checkNoInterpolation(errors, input, parseSourceSpan);
|
|
19012
19015
|
const { stripped: sourceToLex } = this._stripComments(input);
|
|
19013
19016
|
const tokens = this._lexer.tokenize(sourceToLex);
|
|
19014
19017
|
return new _ParseAST(input, parseSourceSpan, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, 0, this._supportsDirectPipeReferences).parseChain();
|
|
@@ -19048,9 +19051,9 @@ class Parser {
|
|
|
19048
19051
|
span: new AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length),
|
|
19049
19052
|
});
|
|
19050
19053
|
}
|
|
19051
|
-
parseInterpolation(input, parseSourceSpan, absoluteOffset, interpolatedTokens
|
|
19054
|
+
parseInterpolation(input, parseSourceSpan, absoluteOffset, interpolatedTokens) {
|
|
19052
19055
|
const errors = [];
|
|
19053
|
-
const { strings, expressions, offsets } = this.splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens
|
|
19056
|
+
const { strings, expressions, offsets } = this.splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens);
|
|
19054
19057
|
if (expressions.length === 0)
|
|
19055
19058
|
return null;
|
|
19056
19059
|
const expressionNodes = [];
|
|
@@ -19097,7 +19100,7 @@ class Parser {
|
|
|
19097
19100
|
* `SplitInterpolation` with splits that look like
|
|
19098
19101
|
* <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
|
|
19099
19102
|
*/
|
|
19100
|
-
splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens
|
|
19103
|
+
splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens) {
|
|
19101
19104
|
const strings = [];
|
|
19102
19105
|
const expressions = [];
|
|
19103
19106
|
const offsets = [];
|
|
@@ -19107,7 +19110,8 @@ class Parser {
|
|
|
19107
19110
|
let i = 0;
|
|
19108
19111
|
let atInterpolation = false;
|
|
19109
19112
|
let extendLastString = false;
|
|
19110
|
-
|
|
19113
|
+
const interpStart = '{{';
|
|
19114
|
+
const interpEnd = '}}';
|
|
19111
19115
|
while (i < input.length) {
|
|
19112
19116
|
if (!atInterpolation) {
|
|
19113
19117
|
// parse until starting {{
|
|
@@ -19186,24 +19190,24 @@ class Parser {
|
|
|
19186
19190
|
}
|
|
19187
19191
|
return null;
|
|
19188
19192
|
}
|
|
19189
|
-
_checkNoInterpolation(errors, input, parseSourceSpan
|
|
19193
|
+
_checkNoInterpolation(errors, input, parseSourceSpan) {
|
|
19190
19194
|
let startIndex = -1;
|
|
19191
19195
|
let endIndex = -1;
|
|
19192
19196
|
for (const charIndex of this._forEachUnquotedChar(input, 0)) {
|
|
19193
19197
|
if (startIndex === -1) {
|
|
19194
|
-
if (input.startsWith(
|
|
19198
|
+
if (input.startsWith('{{')) {
|
|
19195
19199
|
startIndex = charIndex;
|
|
19196
19200
|
}
|
|
19197
19201
|
}
|
|
19198
19202
|
else {
|
|
19199
|
-
endIndex = this._getInterpolationEndIndex(input,
|
|
19203
|
+
endIndex = this._getInterpolationEndIndex(input, '}}', charIndex);
|
|
19200
19204
|
if (endIndex > -1) {
|
|
19201
19205
|
break;
|
|
19202
19206
|
}
|
|
19203
19207
|
}
|
|
19204
19208
|
}
|
|
19205
19209
|
if (startIndex > -1 && endIndex > -1) {
|
|
19206
|
-
errors.push(getParseError(`Got interpolation (
|
|
19210
|
+
errors.push(getParseError(`Got interpolation ({{}}) where expression was expected`, input, `at column ${startIndex} in`, parseSourceSpan));
|
|
19207
19211
|
}
|
|
19208
19212
|
}
|
|
19209
19213
|
/**
|
|
@@ -20189,6 +20193,7 @@ class _ParseAST {
|
|
|
20189
20193
|
}
|
|
20190
20194
|
else if (token.isTemplateLiteralInterpolationStart()) {
|
|
20191
20195
|
this.advance();
|
|
20196
|
+
this.rbracesExpected++;
|
|
20192
20197
|
const expression = this.parsePipe();
|
|
20193
20198
|
if (expression instanceof EmptyExpr$1) {
|
|
20194
20199
|
this.error('Template literal interpolation cannot be empty');
|
|
@@ -20196,6 +20201,7 @@ class _ParseAST {
|
|
|
20196
20201
|
else {
|
|
20197
20202
|
expressions.push(expression);
|
|
20198
20203
|
}
|
|
20204
|
+
this.rbracesExpected--;
|
|
20199
20205
|
}
|
|
20200
20206
|
else {
|
|
20201
20207
|
this.advance();
|
|
@@ -21369,10 +21375,10 @@ class PlaceholderRegistry {
|
|
|
21369
21375
|
|
|
21370
21376
|
const _expParser = new Parser(new Lexer());
|
|
21371
21377
|
/**
|
|
21372
|
-
* Returns a function converting html nodes to an i18n Message
|
|
21378
|
+
* Returns a function converting html nodes to an i18n Message
|
|
21373
21379
|
*/
|
|
21374
|
-
function createI18nMessageFactory(
|
|
21375
|
-
const visitor = new _I18nVisitor(_expParser,
|
|
21380
|
+
function createI18nMessageFactory(containerBlocks, retainEmptyTokens, preserveExpressionWhitespace) {
|
|
21381
|
+
const visitor = new _I18nVisitor(_expParser, containerBlocks, retainEmptyTokens, preserveExpressionWhitespace);
|
|
21376
21382
|
return (nodes, meaning, description, customId, visitNodeFn) => visitor.toI18nMessage(nodes, meaning, description, customId, visitNodeFn);
|
|
21377
21383
|
}
|
|
21378
21384
|
function noopVisitNodeFn(_html, i18n) {
|
|
@@ -21380,13 +21386,11 @@ function noopVisitNodeFn(_html, i18n) {
|
|
|
21380
21386
|
}
|
|
21381
21387
|
class _I18nVisitor {
|
|
21382
21388
|
_expressionParser;
|
|
21383
|
-
_interpolationConfig;
|
|
21384
21389
|
_containerBlocks;
|
|
21385
21390
|
_retainEmptyTokens;
|
|
21386
21391
|
_preserveExpressionWhitespace;
|
|
21387
|
-
constructor(_expressionParser,
|
|
21392
|
+
constructor(_expressionParser, _containerBlocks, _retainEmptyTokens, _preserveExpressionWhitespace) {
|
|
21388
21393
|
this._expressionParser = _expressionParser;
|
|
21389
|
-
this._interpolationConfig = _interpolationConfig;
|
|
21390
21394
|
this._containerBlocks = _containerBlocks;
|
|
21391
21395
|
this._retainEmptyTokens = _retainEmptyTokens;
|
|
21392
21396
|
this._preserveExpressionWhitespace = _preserveExpressionWhitespace;
|
|
@@ -21608,7 +21612,7 @@ class _I18nVisitor {
|
|
|
21608
21612
|
const expression = token.parts[1];
|
|
21609
21613
|
const expr = this._expressionParser.parseBinding(expression,
|
|
21610
21614
|
/* location */ token.sourceSpan,
|
|
21611
|
-
/* absoluteOffset */ token.sourceSpan.start.offset
|
|
21615
|
+
/* absoluteOffset */ token.sourceSpan.start.offset);
|
|
21612
21616
|
return serialize(expr);
|
|
21613
21617
|
}
|
|
21614
21618
|
}
|
|
@@ -21673,6 +21677,51 @@ function extractPlaceholderName(input) {
|
|
|
21673
21677
|
return input.split(_CUSTOM_PH_EXP)[2];
|
|
21674
21678
|
}
|
|
21675
21679
|
|
|
21680
|
+
const UNUSABLE_INTERPOLATION_REGEXPS = [
|
|
21681
|
+
/@/, // control flow reserved symbol
|
|
21682
|
+
/^\s*$/, // empty
|
|
21683
|
+
/[<>]/, // html tag
|
|
21684
|
+
/^[{}]$/, // i18n expansion
|
|
21685
|
+
/&(#|[a-z])/i, // character reference,
|
|
21686
|
+
/^\/\//, // comment
|
|
21687
|
+
];
|
|
21688
|
+
function assertInterpolationSymbols(identifier, value) {
|
|
21689
|
+
if (value != null && !(Array.isArray(value) && value.length == 2)) {
|
|
21690
|
+
throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
|
|
21691
|
+
}
|
|
21692
|
+
else if (value != null) {
|
|
21693
|
+
const start = value[0];
|
|
21694
|
+
const end = value[1];
|
|
21695
|
+
// Check for unusable interpolation symbols
|
|
21696
|
+
UNUSABLE_INTERPOLATION_REGEXPS.forEach((regexp) => {
|
|
21697
|
+
if (regexp.test(start) || regexp.test(end)) {
|
|
21698
|
+
throw new Error(`['${start}', '${end}'] contains unusable interpolation symbol.`);
|
|
21699
|
+
}
|
|
21700
|
+
});
|
|
21701
|
+
}
|
|
21702
|
+
}
|
|
21703
|
+
|
|
21704
|
+
class InterpolationConfig {
|
|
21705
|
+
start;
|
|
21706
|
+
end;
|
|
21707
|
+
static fromArray(markers) {
|
|
21708
|
+
if (!markers) {
|
|
21709
|
+
return DEFAULT_INTERPOLATION_CONFIG;
|
|
21710
|
+
}
|
|
21711
|
+
assertInterpolationSymbols('interpolation', markers);
|
|
21712
|
+
return new InterpolationConfig(markers[0], markers[1]);
|
|
21713
|
+
}
|
|
21714
|
+
constructor(start, end) {
|
|
21715
|
+
this.start = start;
|
|
21716
|
+
this.end = end;
|
|
21717
|
+
}
|
|
21718
|
+
}
|
|
21719
|
+
/**
|
|
21720
|
+
* This symbol is referenced inside G3 and will require some cleanup.
|
|
21721
|
+
*/
|
|
21722
|
+
const DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}');
|
|
21723
|
+
const DEFAULT_CONTAINER_BLOCKS = new Set(['switch']);
|
|
21724
|
+
|
|
21676
21725
|
/**
|
|
21677
21726
|
* Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all
|
|
21678
21727
|
* tags use '*'.
|
|
@@ -21734,7 +21783,6 @@ const setI18nRefs = (originalNodeMap) => {
|
|
|
21734
21783
|
* stored with other element's and attribute's information.
|
|
21735
21784
|
*/
|
|
21736
21785
|
class I18nMetaVisitor {
|
|
21737
|
-
interpolationConfig;
|
|
21738
21786
|
keepI18nAttrs;
|
|
21739
21787
|
enableI18nLegacyMessageIdFormat;
|
|
21740
21788
|
containerBlocks;
|
|
@@ -21743,7 +21791,7 @@ class I18nMetaVisitor {
|
|
|
21743
21791
|
// whether visited nodes contain i18n information
|
|
21744
21792
|
hasI18nMeta = false;
|
|
21745
21793
|
_errors = [];
|
|
21746
|
-
constructor(
|
|
21794
|
+
constructor(keepI18nAttrs = false, enableI18nLegacyMessageIdFormat = false, containerBlocks = DEFAULT_CONTAINER_BLOCKS, preserveSignificantWhitespace = true,
|
|
21747
21795
|
// When dropping significant whitespace we need to retain empty tokens or
|
|
21748
21796
|
// else we won't be able to reuse source spans because empty tokens would be
|
|
21749
21797
|
// removed and cause a mismatch. Unfortunately this still needs to be
|
|
@@ -21751,7 +21799,6 @@ class I18nMetaVisitor {
|
|
|
21751
21799
|
// sure the number of nodes don't change between parses, even when
|
|
21752
21800
|
// `preserveSignificantWhitespace` changes.
|
|
21753
21801
|
retainEmptyTokens = !preserveSignificantWhitespace) {
|
|
21754
|
-
this.interpolationConfig = interpolationConfig;
|
|
21755
21802
|
this.keepI18nAttrs = keepI18nAttrs;
|
|
21756
21803
|
this.enableI18nLegacyMessageIdFormat = enableI18nLegacyMessageIdFormat;
|
|
21757
21804
|
this.containerBlocks = containerBlocks;
|
|
@@ -21760,7 +21807,7 @@ class I18nMetaVisitor {
|
|
|
21760
21807
|
}
|
|
21761
21808
|
_generateI18nMessage(nodes, meta = '', visitNodeFn) {
|
|
21762
21809
|
const { meaning, description, customId } = this._parseMetadata(meta);
|
|
21763
|
-
const createI18nMessage = createI18nMessageFactory(this.
|
|
21810
|
+
const createI18nMessage = createI18nMessageFactory(this.containerBlocks, this.retainEmptyTokens,
|
|
21764
21811
|
/* preserveExpressionWhitespace */ this.preserveSignificantWhitespace);
|
|
21765
21812
|
const message = createI18nMessage(nodes, meaning, description, customId, visitNodeFn);
|
|
21766
21813
|
this._setMessageId(message, meta);
|
|
@@ -23911,6 +23958,22 @@ function ariaProperty(name, expression, sourceSpan) {
|
|
|
23911
23958
|
function property(name, expression, sanitizer, sourceSpan) {
|
|
23912
23959
|
return propertyBase(Identifiers.property, name, expression, sanitizer, sourceSpan);
|
|
23913
23960
|
}
|
|
23961
|
+
function control(expression, sanitizer, sourceSpan) {
|
|
23962
|
+
const args = [];
|
|
23963
|
+
if (expression instanceof Interpolation) {
|
|
23964
|
+
args.push(interpolationToExpression(expression, sourceSpan));
|
|
23965
|
+
}
|
|
23966
|
+
else {
|
|
23967
|
+
args.push(expression);
|
|
23968
|
+
}
|
|
23969
|
+
if (sanitizer !== null) {
|
|
23970
|
+
args.push(sanitizer);
|
|
23971
|
+
}
|
|
23972
|
+
return call(Identifiers.control, args, sourceSpan);
|
|
23973
|
+
}
|
|
23974
|
+
function controlCreate(sourceSpan) {
|
|
23975
|
+
return call(Identifiers.controlCreate, [], sourceSpan);
|
|
23976
|
+
}
|
|
23914
23977
|
function twoWayProperty(name, expression, sanitizer, sourceSpan) {
|
|
23915
23978
|
const args = [literal(name), expression];
|
|
23916
23979
|
if (sanitizer !== null) {
|
|
@@ -24471,6 +24534,9 @@ function reifyCreateOperations(unit, ops) {
|
|
|
24471
24534
|
}));
|
|
24472
24535
|
OpList.replace(op, attachSourceLocation(op.templatePath, locationsLiteral));
|
|
24473
24536
|
break;
|
|
24537
|
+
case OpKind.ControlCreate:
|
|
24538
|
+
OpList.replace(op, controlCreate(op.sourceSpan));
|
|
24539
|
+
break;
|
|
24474
24540
|
case OpKind.Statement:
|
|
24475
24541
|
// Pass statement operations directly through.
|
|
24476
24542
|
break;
|
|
@@ -24493,6 +24559,9 @@ function reifyUpdateOperations(unit, ops) {
|
|
|
24493
24559
|
? reifyDomProperty(op)
|
|
24494
24560
|
: reifyProperty(op));
|
|
24495
24561
|
break;
|
|
24562
|
+
case OpKind.Control:
|
|
24563
|
+
OpList.replace(op, reifyControl(op));
|
|
24564
|
+
break;
|
|
24496
24565
|
case OpKind.TwoWayProperty:
|
|
24497
24566
|
OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
|
|
24498
24567
|
break;
|
|
@@ -24588,6 +24657,9 @@ function reifyProperty(op) {
|
|
|
24588
24657
|
? ariaProperty(op.name, op.expression, op.sourceSpan)
|
|
24589
24658
|
: property(op.name, op.expression, op.sanitizer, op.sourceSpan);
|
|
24590
24659
|
}
|
|
24660
|
+
function reifyControl(op) {
|
|
24661
|
+
return control(op.expression, op.sanitizer, op.sourceSpan);
|
|
24662
|
+
}
|
|
24591
24663
|
function reifyIrExpression(expr) {
|
|
24592
24664
|
if (!isIrExpression(expr)) {
|
|
24593
24665
|
return expr;
|
|
@@ -26100,6 +26172,7 @@ function varsUsedByOp(op) {
|
|
|
26100
26172
|
return slots;
|
|
26101
26173
|
case OpKind.Property:
|
|
26102
26174
|
case OpKind.DomProperty:
|
|
26175
|
+
case OpKind.Control:
|
|
26103
26176
|
slots = 1;
|
|
26104
26177
|
// We need to assign a slot even for singleton interpolations, because the
|
|
26105
26178
|
// runtime needs to store both the raw value and the stringified one.
|
|
@@ -27567,6 +27640,11 @@ function ingestElementBindings(unit, op, element) {
|
|
|
27567
27640
|
}
|
|
27568
27641
|
// All dynamic bindings (both attribute and property bindings).
|
|
27569
27642
|
bindings.push(createBindingOp(op.xref, BINDING_KINDS.get(input.type), input.name, convertAstWithInterpolation(unit.job, astOf(input.value), input.i18n), input.unit, input.securityContext, false, false, null, asMessage(input.i18n) ?? null, input.sourceSpan));
|
|
27643
|
+
// If the input name is 'control', this could be a form control binding which requires a
|
|
27644
|
+
// `ControlCreateOp` to properly initialize.
|
|
27645
|
+
if (input.type === BindingType.Property && input.name === 'control') {
|
|
27646
|
+
unit.create.push(createControlCreateOp(input.sourceSpan));
|
|
27647
|
+
}
|
|
27570
27648
|
}
|
|
27571
27649
|
unit.create.push(bindings.filter((b) => b?.kind === OpKind.ExtractedAttribute));
|
|
27572
27650
|
unit.update.push(bindings.filter((b) => b?.kind === OpKind.Binding));
|
|
@@ -28087,18 +28165,13 @@ const LEGACY_ANIMATE_PROP_PREFIX = 'animate-';
|
|
|
28087
28165
|
*/
|
|
28088
28166
|
class BindingParser {
|
|
28089
28167
|
_exprParser;
|
|
28090
|
-
_interpolationConfig;
|
|
28091
28168
|
_schemaRegistry;
|
|
28092
28169
|
errors;
|
|
28093
|
-
constructor(_exprParser,
|
|
28170
|
+
constructor(_exprParser, _schemaRegistry, errors) {
|
|
28094
28171
|
this._exprParser = _exprParser;
|
|
28095
|
-
this._interpolationConfig = _interpolationConfig;
|
|
28096
28172
|
this._schemaRegistry = _schemaRegistry;
|
|
28097
28173
|
this.errors = errors;
|
|
28098
28174
|
}
|
|
28099
|
-
get interpolationConfig() {
|
|
28100
|
-
return this._interpolationConfig;
|
|
28101
|
-
}
|
|
28102
28175
|
createBoundHostProperties(properties, sourceSpan) {
|
|
28103
28176
|
const boundProps = [];
|
|
28104
28177
|
for (const propName of Object.keys(properties)) {
|
|
@@ -28142,7 +28215,7 @@ class BindingParser {
|
|
|
28142
28215
|
parseInterpolation(value, sourceSpan, interpolatedTokens) {
|
|
28143
28216
|
const absoluteOffset = sourceSpan.fullStart.offset;
|
|
28144
28217
|
try {
|
|
28145
|
-
const ast = this._exprParser.parseInterpolation(value, sourceSpan, absoluteOffset, interpolatedTokens
|
|
28218
|
+
const ast = this._exprParser.parseInterpolation(value, sourceSpan, absoluteOffset, interpolatedTokens);
|
|
28146
28219
|
if (ast) {
|
|
28147
28220
|
this.errors.push(...ast.errors);
|
|
28148
28221
|
}
|
|
@@ -28314,8 +28387,8 @@ class BindingParser {
|
|
|
28314
28387
|
parseBinding(value, isHostBinding, sourceSpan, absoluteOffset) {
|
|
28315
28388
|
try {
|
|
28316
28389
|
const ast = isHostBinding
|
|
28317
|
-
? this._exprParser.parseSimpleBinding(value, sourceSpan, absoluteOffset
|
|
28318
|
-
: this._exprParser.parseBinding(value, sourceSpan, absoluteOffset
|
|
28390
|
+
? this._exprParser.parseSimpleBinding(value, sourceSpan, absoluteOffset)
|
|
28391
|
+
: this._exprParser.parseBinding(value, sourceSpan, absoluteOffset);
|
|
28319
28392
|
if (ast) {
|
|
28320
28393
|
this.errors.push(...ast.errors);
|
|
28321
28394
|
}
|
|
@@ -28450,7 +28523,7 @@ class BindingParser {
|
|
|
28450
28523
|
_parseAction(value, sourceSpan) {
|
|
28451
28524
|
const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
|
|
28452
28525
|
try {
|
|
28453
|
-
const ast = this._exprParser.parseAction(value, sourceSpan, absoluteOffset
|
|
28526
|
+
const ast = this._exprParser.parseAction(value, sourceSpan, absoluteOffset);
|
|
28454
28527
|
if (ast) {
|
|
28455
28528
|
this.errors.push(...ast.errors);
|
|
28456
28529
|
}
|
|
@@ -29716,6 +29789,13 @@ class HtmlAstToIvyAst {
|
|
|
29716
29789
|
}
|
|
29717
29790
|
else {
|
|
29718
29791
|
const attrs = this.categorizePropertyAttributes(element.name, parsedProperties, i18nAttrsMeta);
|
|
29792
|
+
if (element.name === 'ng-container') {
|
|
29793
|
+
for (const bound of attrs.bound) {
|
|
29794
|
+
if (bound.type === BindingType.Attribute) {
|
|
29795
|
+
this.reportError(`Attribute bindings are not supported on ng-container. Use property bindings instead.`, bound.sourceSpan);
|
|
29796
|
+
}
|
|
29797
|
+
}
|
|
29798
|
+
}
|
|
29719
29799
|
parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, directives, children, references, element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.isVoid, element.i18n);
|
|
29720
29800
|
}
|
|
29721
29801
|
if (elementHasInlineTemplate) {
|
|
@@ -30300,9 +30380,9 @@ const LEADING_TRIVIA_CHARS = [' ', '\n', '\r', '\t'];
|
|
|
30300
30380
|
* @param options options to modify how the template is parsed
|
|
30301
30381
|
*/
|
|
30302
30382
|
function parseTemplate(template, templateUrl, options = {}) {
|
|
30303
|
-
const {
|
|
30383
|
+
const { preserveWhitespaces, enableI18nLegacyMessageIdFormat } = options;
|
|
30304
30384
|
const selectorlessEnabled = options.enableSelectorless ?? false;
|
|
30305
|
-
const bindingParser = makeBindingParser(
|
|
30385
|
+
const bindingParser = makeBindingParser(selectorlessEnabled);
|
|
30306
30386
|
const htmlParser = new HtmlParser();
|
|
30307
30387
|
const parseResult = htmlParser.parse(template, templateUrl, {
|
|
30308
30388
|
leadingTriviaChars: LEADING_TRIVIA_CHARS,
|
|
@@ -30316,7 +30396,6 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
30316
30396
|
parseResult.errors &&
|
|
30317
30397
|
parseResult.errors.length > 0) {
|
|
30318
30398
|
const parsedTemplate = {
|
|
30319
|
-
interpolationConfig,
|
|
30320
30399
|
preserveWhitespaces,
|
|
30321
30400
|
errors: parseResult.errors,
|
|
30322
30401
|
nodes: [],
|
|
@@ -30339,7 +30418,7 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
30339
30418
|
// before we run whitespace removal process, because existing i18n
|
|
30340
30419
|
// extraction process (ng extract-i18n) relies on a raw content to generate
|
|
30341
30420
|
// message ids
|
|
30342
|
-
const i18nMetaVisitor = new I18nMetaVisitor(
|
|
30421
|
+
const i18nMetaVisitor = new I18nMetaVisitor(
|
|
30343
30422
|
/* keepI18nAttrs */ !preserveWhitespaces, enableI18nLegacyMessageIdFormat,
|
|
30344
30423
|
/* containerBlocks */ undefined, options.preserveSignificantWhitespace, retainEmptyTokens);
|
|
30345
30424
|
const i18nMetaResult = i18nMetaVisitor.visitAllWithErrors(rootNodes);
|
|
@@ -30347,7 +30426,6 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
30347
30426
|
i18nMetaResult.errors &&
|
|
30348
30427
|
i18nMetaResult.errors.length > 0) {
|
|
30349
30428
|
const parsedTemplate = {
|
|
30350
|
-
interpolationConfig,
|
|
30351
30429
|
preserveWhitespaces,
|
|
30352
30430
|
errors: i18nMetaResult.errors,
|
|
30353
30431
|
nodes: [],
|
|
@@ -30382,7 +30460,7 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
30382
30460
|
// template. During this pass i18n IDs generated at the first pass will be preserved, so we can
|
|
30383
30461
|
// mimic existing extraction process (ng extract-i18n)
|
|
30384
30462
|
if (i18nMetaVisitor.hasI18nMeta) {
|
|
30385
|
-
rootNodes = visitAll(new I18nMetaVisitor(
|
|
30463
|
+
rootNodes = visitAll(new I18nMetaVisitor(
|
|
30386
30464
|
/* keepI18nAttrs */ false,
|
|
30387
30465
|
/* enableI18nLegacyMessageIdFormat */ undefined,
|
|
30388
30466
|
/* containerBlocks */ undefined,
|
|
@@ -30392,7 +30470,6 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
30392
30470
|
const { nodes, errors, styleUrls, styles, ngContentSelectors, commentNodes } = htmlAstToRender3Ast(rootNodes, bindingParser, { collectCommentNodes: !!options.collectCommentNodes });
|
|
30393
30471
|
errors.push(...parseResult.errors, ...i18nMetaResult.errors);
|
|
30394
30472
|
const parsedTemplate = {
|
|
30395
|
-
interpolationConfig,
|
|
30396
30473
|
preserveWhitespaces,
|
|
30397
30474
|
errors: errors.length > 0 ? errors : null,
|
|
30398
30475
|
nodes,
|
|
@@ -30409,8 +30486,8 @@ const elementRegistry = new DomElementSchemaRegistry();
|
|
|
30409
30486
|
/**
|
|
30410
30487
|
* Construct a `BindingParser` with a default configuration.
|
|
30411
30488
|
*/
|
|
30412
|
-
function makeBindingParser(
|
|
30413
|
-
return new BindingParser(new Parser(new Lexer(), selectorlessEnabled),
|
|
30489
|
+
function makeBindingParser(selectorlessEnabled = false) {
|
|
30490
|
+
return new BindingParser(new Parser(new Lexer(), selectorlessEnabled), elementRegistry, []);
|
|
30414
30491
|
}
|
|
30415
30492
|
|
|
30416
30493
|
const COMPONENT_VARIABLE = '%COMP%';
|
|
@@ -30529,7 +30606,7 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
|
|
|
30529
30606
|
: TemplateCompilationMode.Full;
|
|
30530
30607
|
// First the template is ingested into IR:
|
|
30531
30608
|
const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, compilationMode, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.defer, allDeferrableDepsFn, meta.relativeTemplatePath, getTemplateSourceLocationsEnabled());
|
|
30532
|
-
// Then the IR is transformed to prepare it for
|
|
30609
|
+
// Then the IR is transformed to prepare it for code generation.
|
|
30533
30610
|
transform(tpl, CompilationJobKind.Tmpl);
|
|
30534
30611
|
// Finally we emit the template function:
|
|
30535
30612
|
const templateFn = emitTemplateFn(tpl, constantPool);
|
|
@@ -32132,7 +32209,7 @@ class CompilerFacadeImpl {
|
|
|
32132
32209
|
}
|
|
32133
32210
|
compileComponent(angularCoreEnv, sourceMapUrl, facade) {
|
|
32134
32211
|
// Parse the template and check for errors.
|
|
32135
|
-
const { template,
|
|
32212
|
+
const { template, defer } = parseJitTemplate(facade.template, facade.name, sourceMapUrl, facade.preserveWhitespaces, undefined);
|
|
32136
32213
|
// Compile the component metadata, including template, into an expression.
|
|
32137
32214
|
const meta = {
|
|
32138
32215
|
...facade,
|
|
@@ -32144,7 +32221,6 @@ class CompilerFacadeImpl {
|
|
|
32144
32221
|
defer,
|
|
32145
32222
|
styles: [...facade.styles, ...template.styles],
|
|
32146
32223
|
encapsulation: facade.encapsulation,
|
|
32147
|
-
interpolation,
|
|
32148
32224
|
changeDetection: facade.changeDetection ?? null,
|
|
32149
32225
|
animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
|
|
32150
32226
|
viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) : null,
|
|
@@ -32162,7 +32238,7 @@ class CompilerFacadeImpl {
|
|
|
32162
32238
|
}
|
|
32163
32239
|
compileComponentFromMeta(angularCoreEnv, sourceMapUrl, meta) {
|
|
32164
32240
|
const constantPool = new ConstantPool();
|
|
32165
|
-
const bindingParser = makeBindingParser(
|
|
32241
|
+
const bindingParser = makeBindingParser();
|
|
32166
32242
|
const res = compileComponentFromMetadata(meta, constantPool, bindingParser);
|
|
32167
32243
|
return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, constantPool.statements);
|
|
32168
32244
|
}
|
|
@@ -32368,7 +32444,7 @@ function convertOpaqueValuesToExpressions(obj) {
|
|
|
32368
32444
|
return result;
|
|
32369
32445
|
}
|
|
32370
32446
|
function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMapUrl) {
|
|
32371
|
-
const { template,
|
|
32447
|
+
const { template, defer } = parseJitTemplate(decl.template, decl.type.name, sourceMapUrl, decl.preserveWhitespaces ?? false, decl.deferBlockDependencies);
|
|
32372
32448
|
const declarations = [];
|
|
32373
32449
|
if (decl.dependencies) {
|
|
32374
32450
|
for (const innerDep of decl.dependencies) {
|
|
@@ -32403,7 +32479,6 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
|
|
|
32403
32479
|
defer,
|
|
32404
32480
|
changeDetection: decl.changeDetection ?? ChangeDetectionStrategy.Default,
|
|
32405
32481
|
encapsulation: decl.encapsulation ?? ViewEncapsulation$1.Emulated,
|
|
32406
|
-
interpolation,
|
|
32407
32482
|
declarationListEmitMode: 2 /* DeclarationListEmitMode.ClosureResolved */,
|
|
32408
32483
|
relativeContextFilePath: '',
|
|
32409
32484
|
i18nUseExternalIds: true,
|
|
@@ -32447,15 +32522,9 @@ function convertPipeDeclarationToMetadata(pipe) {
|
|
|
32447
32522
|
type: new WrappedNodeExpr(pipe.type),
|
|
32448
32523
|
};
|
|
32449
32524
|
}
|
|
32450
|
-
function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces,
|
|
32451
|
-
const interpolationConfig = interpolation
|
|
32452
|
-
? InterpolationConfig.fromArray(interpolation)
|
|
32453
|
-
: DEFAULT_INTERPOLATION_CONFIG;
|
|
32525
|
+
function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces, deferBlockDependencies) {
|
|
32454
32526
|
// Parse the template and check for errors.
|
|
32455
|
-
const parsed = parseTemplate(template, sourceMapUrl, {
|
|
32456
|
-
preserveWhitespaces,
|
|
32457
|
-
interpolationConfig,
|
|
32458
|
-
});
|
|
32527
|
+
const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces });
|
|
32459
32528
|
if (parsed.errors !== null) {
|
|
32460
32529
|
const errors = parsed.errors.map((err) => err.toString()).join(', ');
|
|
32461
32530
|
throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
|
|
@@ -32464,7 +32533,6 @@ function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces,
|
|
|
32464
32533
|
const boundTarget = binder.bind({ template: parsed.nodes });
|
|
32465
32534
|
return {
|
|
32466
32535
|
template: parsed,
|
|
32467
|
-
interpolation: interpolationConfig,
|
|
32468
32536
|
defer: createR3ComponentDeferMetadata(boundTarget, deferBlockDependencies),
|
|
32469
32537
|
};
|
|
32470
32538
|
}
|
|
@@ -32702,13 +32770,13 @@ let i18nCommentsWarned = false;
|
|
|
32702
32770
|
/**
|
|
32703
32771
|
* Extract translatable messages from an html AST
|
|
32704
32772
|
*/
|
|
32705
|
-
function extractMessages(nodes,
|
|
32773
|
+
function extractMessages(nodes, implicitTags, implicitAttrs, preserveSignificantWhitespace) {
|
|
32706
32774
|
const visitor = new _Visitor(implicitTags, implicitAttrs, preserveSignificantWhitespace);
|
|
32707
|
-
return visitor.extract(nodes
|
|
32775
|
+
return visitor.extract(nodes);
|
|
32708
32776
|
}
|
|
32709
|
-
function mergeTranslations(nodes, translations,
|
|
32777
|
+
function mergeTranslations(nodes, translations, implicitTags, implicitAttrs) {
|
|
32710
32778
|
const visitor = new _Visitor(implicitTags, implicitAttrs);
|
|
32711
|
-
return visitor.merge(nodes, translations
|
|
32779
|
+
return visitor.merge(nodes, translations);
|
|
32712
32780
|
}
|
|
32713
32781
|
class ExtractionResult {
|
|
32714
32782
|
messages;
|
|
@@ -32763,8 +32831,8 @@ class _Visitor {
|
|
|
32763
32831
|
/**
|
|
32764
32832
|
* Extracts the messages from the tree
|
|
32765
32833
|
*/
|
|
32766
|
-
extract(nodes
|
|
32767
|
-
this._init(_VisitorMode.Extract
|
|
32834
|
+
extract(nodes) {
|
|
32835
|
+
this._init(_VisitorMode.Extract);
|
|
32768
32836
|
nodes.forEach((node) => node.visit(this, null));
|
|
32769
32837
|
if (this._inI18nBlock) {
|
|
32770
32838
|
this._reportError(nodes[nodes.length - 1], 'Unclosed block');
|
|
@@ -32774,8 +32842,8 @@ class _Visitor {
|
|
|
32774
32842
|
/**
|
|
32775
32843
|
* Returns a tree where all translatable nodes are translated
|
|
32776
32844
|
*/
|
|
32777
|
-
merge(nodes, translations
|
|
32778
|
-
this._init(_VisitorMode.Merge
|
|
32845
|
+
merge(nodes, translations) {
|
|
32846
|
+
this._init(_VisitorMode.Merge);
|
|
32779
32847
|
this._translations = translations;
|
|
32780
32848
|
// Construct a single fake root element
|
|
32781
32849
|
const wrapper = new Element('wrapper', [], [], nodes, false, undefined, undefined, undefined, false);
|
|
@@ -32880,7 +32948,7 @@ class _Visitor {
|
|
|
32880
32948
|
visitDirective(directive, context) {
|
|
32881
32949
|
throw new Error('unreachable code');
|
|
32882
32950
|
}
|
|
32883
|
-
_init(mode
|
|
32951
|
+
_init(mode) {
|
|
32884
32952
|
this._mode = mode;
|
|
32885
32953
|
this._inI18nBlock = false;
|
|
32886
32954
|
this._inI18nNode = false;
|
|
@@ -32890,7 +32958,7 @@ class _Visitor {
|
|
|
32890
32958
|
this._errors = [];
|
|
32891
32959
|
this._messages = [];
|
|
32892
32960
|
this._inImplicitNode = false;
|
|
32893
|
-
this._createI18nMessage = createI18nMessageFactory(
|
|
32961
|
+
this._createI18nMessage = createI18nMessageFactory(DEFAULT_CONTAINER_BLOCKS,
|
|
32894
32962
|
// When dropping significant whitespace we need to retain whitespace tokens or
|
|
32895
32963
|
// else we won't be able to reuse source spans because empty tokens would be
|
|
32896
32964
|
// removed and cause a mismatch.
|
|
@@ -34233,12 +34301,11 @@ class I18NHtmlParser {
|
|
|
34233
34301
|
}
|
|
34234
34302
|
}
|
|
34235
34303
|
parse(source, url, options = {}) {
|
|
34236
|
-
const
|
|
34237
|
-
const parseResult = this._htmlParser.parse(source, url, { interpolationConfig, ...options });
|
|
34304
|
+
const parseResult = this._htmlParser.parse(source, url, { ...options });
|
|
34238
34305
|
if (parseResult.errors.length) {
|
|
34239
34306
|
return new ParseTreeResult(parseResult.rootNodes, parseResult.errors);
|
|
34240
34307
|
}
|
|
34241
|
-
return mergeTranslations(parseResult.rootNodes, this._translationBundle,
|
|
34308
|
+
return mergeTranslations(parseResult.rootNodes, this._translationBundle, [], {});
|
|
34242
34309
|
}
|
|
34243
34310
|
}
|
|
34244
34311
|
function createSerializer(format) {
|
|
@@ -34275,11 +34342,8 @@ class MessageBundle {
|
|
|
34275
34342
|
this._locale = _locale;
|
|
34276
34343
|
this._preserveWhitespace = _preserveWhitespace;
|
|
34277
34344
|
}
|
|
34278
|
-
updateFromTemplate(source, url
|
|
34279
|
-
const htmlParserResult = this._htmlParser.parse(source, url, {
|
|
34280
|
-
tokenizeExpansionForms: true,
|
|
34281
|
-
interpolationConfig,
|
|
34282
|
-
});
|
|
34345
|
+
updateFromTemplate(source, url) {
|
|
34346
|
+
const htmlParserResult = this._htmlParser.parse(source, url, { tokenizeExpansionForms: true });
|
|
34283
34347
|
if (htmlParserResult.errors.length) {
|
|
34284
34348
|
return htmlParserResult.errors;
|
|
34285
34349
|
}
|
|
@@ -34289,7 +34353,7 @@ class MessageBundle {
|
|
|
34289
34353
|
const rootNodes = this._preserveWhitespace
|
|
34290
34354
|
? htmlParserResult.rootNodes
|
|
34291
34355
|
: visitAllWithSiblings(new WhitespaceVisitor(/* preserveSignificantWhitespace */ false), htmlParserResult.rootNodes);
|
|
34292
|
-
const i18nParserResult = extractMessages(rootNodes,
|
|
34356
|
+
const i18nParserResult = extractMessages(rootNodes, this._implicitTags, this._implicitAttrs,
|
|
34293
34357
|
/* preserveSignificantWhitespace */ this._preserveWhitespace);
|
|
34294
34358
|
if (i18nParserResult.errors.length) {
|
|
34295
34359
|
return i18nParserResult.errors;
|
|
@@ -34450,7 +34514,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
|
|
|
34450
34514
|
function compileDeclareClassMetadata(metadata) {
|
|
34451
34515
|
const definitionMap = new DefinitionMap();
|
|
34452
34516
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
34453
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
34517
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
34454
34518
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34455
34519
|
definitionMap.set('type', metadata.type);
|
|
34456
34520
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -34468,7 +34532,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
|
|
|
34468
34532
|
callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
|
|
34469
34533
|
callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
|
|
34470
34534
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
|
|
34471
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
34535
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
34472
34536
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34473
34537
|
definitionMap.set('type', metadata.type);
|
|
34474
34538
|
definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
|
|
@@ -34563,7 +34627,7 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
34563
34627
|
const definitionMap = new DefinitionMap();
|
|
34564
34628
|
const minVersion = getMinimumVersionForPartialOutput(meta);
|
|
34565
34629
|
definitionMap.set('minVersion', literal(minVersion));
|
|
34566
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
34630
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
34567
34631
|
// e.g. `type: MyDirective`
|
|
34568
34632
|
definitionMap.set('type', meta.type.value);
|
|
34569
34633
|
if (meta.isStandalone !== undefined) {
|
|
@@ -34833,9 +34897,6 @@ function createComponentDefinitionMap(meta, template, templateInfo) {
|
|
|
34833
34897
|
if (meta.encapsulation !== ViewEncapsulation$1.Emulated) {
|
|
34834
34898
|
definitionMap.set('encapsulation', importExpr(Identifiers.ViewEncapsulation).prop(ViewEncapsulation$1[meta.encapsulation]));
|
|
34835
34899
|
}
|
|
34836
|
-
if (meta.interpolation !== DEFAULT_INTERPOLATION_CONFIG) {
|
|
34837
|
-
definitionMap.set('interpolation', literalArr([literal(meta.interpolation.start), literal(meta.interpolation.end)]));
|
|
34838
|
-
}
|
|
34839
34900
|
if (template.preserveWhitespaces === true) {
|
|
34840
34901
|
definitionMap.set('preserveWhitespaces', literal(true));
|
|
34841
34902
|
}
|
|
@@ -34979,7 +35040,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
34979
35040
|
function compileDeclareFactoryFunction(meta) {
|
|
34980
35041
|
const definitionMap = new DefinitionMap();
|
|
34981
35042
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
34982
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
35043
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
34983
35044
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34984
35045
|
definitionMap.set('type', meta.type.value);
|
|
34985
35046
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -35014,7 +35075,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
35014
35075
|
function createInjectableDefinitionMap(meta) {
|
|
35015
35076
|
const definitionMap = new DefinitionMap();
|
|
35016
35077
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
35017
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
35078
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
35018
35079
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
35019
35080
|
definitionMap.set('type', meta.type.value);
|
|
35020
35081
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -35065,7 +35126,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
35065
35126
|
function createInjectorDefinitionMap(meta) {
|
|
35066
35127
|
const definitionMap = new DefinitionMap();
|
|
35067
35128
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
35068
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
35129
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
35069
35130
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
35070
35131
|
definitionMap.set('type', meta.type.value);
|
|
35071
35132
|
definitionMap.set('providers', meta.providers);
|
|
@@ -35098,7 +35159,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
35098
35159
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
35099
35160
|
}
|
|
35100
35161
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
35101
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
35162
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
35102
35163
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
35103
35164
|
definitionMap.set('type', meta.type.value);
|
|
35104
35165
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -35149,7 +35210,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
35149
35210
|
function createPipeDefinitionMap(meta) {
|
|
35150
35211
|
const definitionMap = new DefinitionMap();
|
|
35151
35212
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
35152
|
-
definitionMap.set('version', literal('21.0.0-next.
|
|
35213
|
+
definitionMap.set('version', literal('21.0.0-next.7'));
|
|
35153
35214
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
35154
35215
|
// e.g. `type: MyPipe`
|
|
35155
35216
|
definitionMap.set('type', meta.type.value);
|
|
@@ -35305,7 +35366,7 @@ function compileHmrUpdateCallback(definitions, constantStatements, meta) {
|
|
|
35305
35366
|
* @description
|
|
35306
35367
|
* Entry point for all public APIs of the compiler package.
|
|
35307
35368
|
*/
|
|
35308
|
-
const VERSION = new Version('21.0.0-next.
|
|
35369
|
+
const VERSION = new Version('21.0.0-next.7');
|
|
35309
35370
|
|
|
35310
35371
|
//////////////////////////////////////
|
|
35311
35372
|
// THIS FILE HAS GLOBAL SIDE EFFECT //
|