feat(compiler): Support comments in html element.

```
      <div
        // comment 0
        /* comment 1 */
        attr1="value1"
        /*
           comment 2
           spanning multiple lines
        */
        attr2="value2"
      ></div>
```
This commit is contained in:
Matthieu Riegler
2026-02-20 17:54:47 +01:00
committed by Leon Senft
parent 74f76d8075
commit e850643b1b
9 changed files with 611 additions and 112 deletions
@@ -23,5 +23,6 @@ syntaxes/inline-styles.json
syntaxes/inline-template.json
syntaxes/let-declaration.json
syntaxes/template-blocks.json
syntaxes/template-tag-language-configuration.json
syntaxes/template-tag.json
syntaxes/template.json
+37 -1
View File
@@ -804,6 +804,28 @@ class _Tokenizer {
return [prefix, name];
}
private _consumeSingleLineComment() {
this._attemptCharCodeUntilFn((code) => chars.isNewLine(code) || code === chars.$EOF);
this._attemptCharCodeUntilFn(isNotWhitespace);
}
private _consumeMultiLineComment() {
this._attemptCharCodeUntilFn((code) => {
if (code === chars.$EOF) {
return true;
}
if (code === chars.$STAR) {
const next = this._cursor.clone();
next.advance();
return next.peek() === chars.$SLASH;
}
return false;
});
if (this._attemptStr('*/')) {
this._attemptCharCodeUntilFn(isNotWhitespace);
}
}
private _consumeTagOpen(start: CharacterCursor) {
let tagName: string;
let prefix: string;
@@ -840,7 +862,21 @@ class _Tokenizer {
this._attemptCharCodeUntilFn(isNotWhitespace);
}
while (!isAttributeTerminator(this._cursor.peek())) {
while (true) {
if (this._attemptStr('//')) {
this._consumeSingleLineComment();
continue;
}
if (this._attemptStr('/*')) {
this._consumeMultiLineComment();
continue;
}
if (isAttributeTerminator(this._cursor.peek())) {
break;
}
if (this._selectorlessEnabled && this._cursor.peek() === chars.$AT) {
const start = this._cursor.clone();
const nameStart = start.clone();
@@ -0,0 +1,145 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as html from '../../src/ml_parser/ast';
import {Parser} from '../../src/ml_parser/parser';
import {TagContentType} from '../../src/ml_parser/tags';
describe('Inline comments in attributes', () => {
const parser = new Parser((tagName) => ({
closedByParent: false,
implicitNamespacePrefix: null,
isVoid: false,
ignoreFirstLf: false,
canSelfClose: false,
preventNamespaceInheritance: false,
isClosedByChild: () => false,
getContentType: () => TagContentType.PARSABLE_DATA,
}));
it('should ignore single line comments between attributes', () => {
const source = `
<div
// comment 1
attr1="value1"
// comment 2
attr2="value2"
></div>
`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(2);
expect(element.attrs[0].name).toBe('attr1');
expect(element.attrs[1].name).toBe('attr2');
});
it('should ignore single line comments between inputs and outputs', () => {
const source = `
<div
// comment 1
[input]="value1"
// comment 2
(output)="handler()"
></div>
`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(2);
expect(element.attrs[0].name).toBe('[input]');
expect(element.attrs[1].name).toBe('(output)');
});
it('should ignore single line comments at the end of tag', () => {
const source = `<div attr1="value1" // comment
></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(1);
expect(element.attrs[0].name).toBe('attr1');
});
it('should handle commented out attribute', () => {
const source = `<div /* attr1="value1" */ attr2="value2"></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(1);
expect(element.attrs[0].name).toBe('attr2');
});
it('should comment an attribute with a // on a new line', () => {
const source = `<div
// attr1="value1"
attr2="value2"></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(1);
expect(element.attrs[0].name).toBe('attr2');
});
it('should ignore multi-line comments between attributes', () => {
const source = `
<div
/* comment 1 */
attr1="value1"
/*
comment 2
spanning multiple lines
*/
attr2="value2"
></div>
`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(2);
expect(element.attrs[0].name).toBe('attr1');
expect(element.attrs[1].name).toBe('attr2');
});
it('should ignore multi-line comments at the end of tag', () => {
const source = `<div attr1="value1" /* comment */ ></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(1);
expect(element.attrs[0].name).toBe('attr1');
});
it('should handle * inside multi-line comments', () => {
const source = `<div attr1="value1" /* comment with * inside */ attr2="value2"></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(2);
expect(element.attrs[0].name).toBe('attr1');
expect(element.attrs[1].name).toBe('attr2');
});
it('should maintain correct source spans with comments', () => {
const source = `<div attr1="a" /* comment */ attr2="b"></div>`;
const result = parser.parse(source, 'url');
expect(result.errors.length).toBe(0);
const element = result.rootNodes.find((n) => n instanceof html.Element) as html.Element;
expect(element.attrs.length).toBe(2);
const attr1 = element.attrs[0];
expect(attr1.name).toBe('attr1');
expect(attr1.sourceSpan.start.offset).toBe(5);
expect(attr1.sourceSpan.end.offset).toBe(14);
const attr2 = element.attrs[1];
expect(attr2.name).toBe('attr2');
expect(attr2.sourceSpan.start.offset).toBe(29);
expect(attr2.sourceSpan.end.offset).toBe(38);
});
});
+10 -1
View File
@@ -361,7 +361,10 @@
"injectTo": [
"text.html.derivative",
"source.ts"
]
],
"embeddedLanguages": {
"template.tag.ng": "angular-tag-comment"
}
},
{
"path": "./syntaxes/expression.json",
@@ -373,6 +376,12 @@
"fileMatch": "tsconfig*.json",
"url": "./schemas/tsconfig-ng.schema.json"
}
],
"languages": [
{
"id": "angular-tag-comment",
"configuration": "./syntaxes/template-tag-language-configuration.json"
}
]
},
"activationEvents": [
@@ -12,12 +12,34 @@ export const TemplateTag: GrammarDefinition = {
scopeName: 'template.tag.ng',
injectionSelector: 'L:text.html#meta.tag -comment',
patterns: [
{include: '#inlineComments'},
{include: '#twoWayBinding'},
{include: '#propertyBinding'},
{include: '#eventBinding'},
{include: '#templateBinding'},
{include: '#standardAttribute'},
{include: '#other'},
],
repository: {
other: {
match: /\s+/,
name: 'template.tag.ng',
},
standardAttribute: {
begin: /([-_a-zA-Z0-9.$:]+)(=)(["'])/,
beginCaptures: {
1: {name: 'entity.other.attribute-name.html'},
2: {name: 'punctuation.separator.key-value.html'},
3: {name: 'string.quoted.html punctuation.definition.string.begin.html'},
},
// @ts-ignore
end: /\3/,
endCaptures: {
0: {name: 'string.quoted.html punctuation.definition.string.end.html'},
},
name: 'meta.attribute.standard.html',
patterns: [{include: 'expression.ng'}],
},
propertyBinding: {
begin: /(\[\s*@?(?:[-_a-zA-Z0-9.$]+|\[[^\[\]]*]|\([^()]*\))*%?\s*])(=)(["'])/,
beginCaptures: {
@@ -119,5 +141,21 @@ export const TemplateTag: GrammarDefinition = {
},
],
},
inlineComments: {
patterns: [
{
begin: /\/\*/,
captures: {0: {name: 'punctuation.definition.comment.ts'}},
name: 'comment.block.ts',
end: /\*\//,
},
{
begin: /\/\//,
beginCaptures: {0: {name: 'punctuation.definition.comment.ts'}},
name: 'comment.line.double-slash.ts',
end: /(?=$)/,
},
],
},
},
};
@@ -0,0 +1,5 @@
{
"comments": {
"blockComment": ["/*", "*/"]
}
}
@@ -2,6 +2,9 @@
"scopeName": "template.tag.ng",
"injectionSelector": "L:text.html#meta.tag -comment",
"patterns": [
{
"include": "#inlineComments"
},
{
"include": "#twoWayBinding"
},
@@ -13,9 +16,45 @@
},
{
"include": "#templateBinding"
},
{
"include": "#standardAttribute"
},
{
"include": "#other"
}
],
"repository": {
"other": {
"match": "\\s+",
"name": "template.tag.ng"
},
"standardAttribute": {
"begin": "([-_a-zA-Z0-9.$:]+)(=)([\"'])",
"beginCaptures": {
"1": {
"name": "entity.other.attribute-name.html"
},
"2": {
"name": "punctuation.separator.key-value.html"
},
"3": {
"name": "string.quoted.html punctuation.definition.string.begin.html"
}
},
"end": "\\3",
"endCaptures": {
"0": {
"name": "string.quoted.html punctuation.definition.string.end.html"
}
},
"name": "meta.attribute.standard.html",
"patterns": [
{
"include": "expression.ng"
}
]
},
"propertyBinding": {
"begin": "(\\[\\s*@?(?:[-_a-zA-Z0-9.$]+|\\[[^\\[\\]]*]|\\([^()]*\\))*%?\\s*])(=)([\"'])",
"beginCaptures": {
@@ -167,6 +206,30 @@
}
}
]
},
"inlineComments": {
"patterns": [
{
"begin": "\\/\\*",
"captures": {
"0": {
"name": "punctuation.definition.comment.ts"
}
},
"name": "comment.block.ts",
"end": "\\*\\/"
},
{
"begin": "\\/\\/",
"beginCaptures": {
"0": {
"name": "punctuation.definition.comment.ts"
}
},
"name": "comment.line.double-slash.ts",
"end": "(?=$)"
}
]
}
}
}
@@ -77,3 +77,15 @@
<div *matHeaderCellDef></div>
<!-- #613 -->
<div *ngIf="x$ | async as a"></div>
<!-- inline comments in the HTML element -->
<div
// comment 0
/* comment 1 */
attr1="value1"
/*
comment 2
spanning multiple lines
*/
attr2="value2"
></div>
@@ -1,7 +1,16 @@
><!-- Property binding test -->
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div [ ngStyle ]="{'max-width.px': i * 2 + 5}"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html
# ^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.ngStyle.html
@@ -25,9 +34,10 @@
# ^ template.tag.ng meta.ng-binding.property.html expression.ng constant.numeric.decimal.ts
# ^ template.tag.ng meta.ng-binding.property.html expression.ng
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [ngClass]="[
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.ngClass.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.end.html
@@ -54,9 +64,10 @@
>]"></div>
#^ template.tag.ng meta.ng-binding.property.html expression.ng meta.array.literal.ts meta.brace.square.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [style.right.%]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.style.right.%.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.style.right.%.html punctuation.accessor.html
@@ -68,9 +79,10 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [@animation.trigger]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.@animation.trigger.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.@animation.trigger.html punctuation.accessor.html
@@ -80,9 +92,10 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><img [attr.aria-label]="val" />
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.attr.aria-label.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.attr.aria-label.html punctuation.accessor.html
@@ -92,9 +105,11 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng
><div [my-property]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.my-property.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.end.html
@@ -102,9 +117,10 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [my_property]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.my_property.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.end.html
@@ -112,9 +128,10 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [myProperty$]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.myProperty$.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.end.html
@@ -122,13 +139,18 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [%invalidProperty]="val"></div>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
><div [invalidProperty)="val"></div>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
><div [class.min-h-[calc(100vh-var(--header-height))]]="val"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.class.min-h-[calc(100vh-var(--header-height))].html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.class.min-h-[calc(100vh-var(--header-height))].html punctuation.accessor.html
@@ -138,12 +160,21 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
>
><!-- Event binding test -->
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><button (click)="onClick($event)"></button>
#^^^^^^^^ template.tag.ng
#^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.click.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -154,9 +185,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^ template.tag.ng
><input (ngModelChange)="onModelChange($event)" />
#^^^^^^^ template.tag.ng
#^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.ngModelChange.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -167,9 +199,11 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng
><div (@animation.done)="onAnimationDone($event)"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.@animation.done.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.@animation.done.html punctuation.accessor.html
@@ -182,9 +216,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div (someEvent)="
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.someEvent.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -220,9 +255,10 @@
#^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng
>"></div>
#^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div ( extraSpacing )="onExtraSpacing($event)"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html
# ^^^^^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.extraSpacing.html
@@ -235,9 +271,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><my-component (myEvent)="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.myEvent.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -248,9 +285,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component (my-event)="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.my-event.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -261,9 +299,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component (my_event)="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.my_event.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -274,9 +313,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component (myEvent$)="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html entity.other.ng-binding-name.myEvent$.html
# ^ template.tag.ng meta.ng-binding.event.html entity.other.attribute-name.html entity.other.ng-binding-name.event.html punctuation.definition.ng-binding-name.end.html
@@ -287,16 +327,29 @@
# ^^^^^^ template.tag.ng meta.ng-binding.event.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.event.html expression.ng meta.brace.round.ts
# ^ template.tag.ng meta.ng-binding.event.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component (%invalidEvent)="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
><my-component (invalidEvent]="onMyEvent($event)"></my-component>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
>
><!-- Two-way binding test -->
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><button [(click)]="clickProp"></button>
#^^^^^^^^ template.tag.ng
#^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.click.html
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.end.html
@@ -304,9 +357,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^ template.tag.ng
><div [( extraSpacing )]="extraSpacing"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html
# ^^^^^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.extraSpacing.html
@@ -316,9 +370,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div [(@animation.done)]="animation"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.@animation.done.html
# ^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.@animation.done.html punctuation.accessor.html
@@ -328,9 +383,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><my-component [(my-prop)]="myProp"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.my-prop.html
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.end.html
@@ -338,9 +394,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component [(my_prop)]="myProp"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.my_prop.html
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.end.html
@@ -348,9 +405,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component [($my_prop)]="myProp"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html entity.other.ng-binding-name.$my_prop.html
# ^^ template.tag.ng meta.ng-binding.two-way.html entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html punctuation.definition.ng-binding-name.end.html
@@ -358,9 +416,10 @@
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^ template.tag.ng meta.ng-binding.two-way.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.two-way.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component [(%invalid)]="invalid"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html punctuation.definition.ng-binding-name.begin.html
# ^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html entity.other.ng-binding-name.%.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.property.html entity.other.attribute-name.html entity.other.ng-binding-name.property.html
@@ -368,23 +427,35 @@
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.property.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.property.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component ([invalid)]="invalid"></my-component>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
>
><!-- Event binding test -->
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><button *ngModel="title"></button>
#^^^^^^^^ template.tag.ng
#^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngModel.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^ template.tag.ng
><div *ngFor="let book of books"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -397,9 +468,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><my-component *custom-if="true != false"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.custom-if.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -410,9 +482,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng constant.language.boolean.false.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component *custom_if="true != false"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.custom_if.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -423,9 +496,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng constant.language.boolean.false.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component *custom_$if="true != false"></my-component>
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.custom_$if.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -436,16 +510,35 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng constant.language.boolean.false.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^^ template.tag.ng
# ^^^^^^^^^^^^^^^^ template.tag.ng
><my-component *%invalid="expr"></my-component>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng
# ^^^^^^^ template.tag.ng meta.attribute.standard.html entity.other.attribute-name.html
# ^ template.tag.ng meta.attribute.standard.html punctuation.separator.key-value.html
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^ template.tag.ng meta.attribute.standard.html variable.other.readwrite.ts
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^^^^^^^^^ template.tag.ng
>
><!-- Microsyntax -->
#^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><!-- Let Expression -->
#^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngFor="let i = index;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -459,9 +552,10 @@
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let i = index"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -474,11 +568,18 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><!-- Key Expression -->
#^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngFor="let i = index; trackBy: hash;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -497,9 +598,10 @@
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let i = index; trackBy: hash"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -517,9 +619,10 @@
# ^^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -533,9 +636,10 @@
# ^^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -548,11 +652,18 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><!-- As Expression -->
#^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngFor="let param of params; index as i;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -573,9 +684,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params; index as i"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -595,9 +707,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngIf='x as y'></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngIf.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -608,11 +721,16 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><!-- Mixed -->
#^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngFor="let param of params; let i = index; let last = last"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -643,9 +761,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params; let i = index; let last = last;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -677,9 +796,10 @@
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng variable.other.readwrite.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params; let i = index; last as last"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -708,9 +828,10 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *ngFor="let param of params; let i = index; last as last;"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -740,14 +861,23 @@
# ^^^^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html expression.ng punctuation.terminator.statement.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
>
><!-- Regression -->
#^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><!-- #575 -->
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngFor="let n of nums; index as i"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngFor.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -767,13 +897,20 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
# ^^^^^^^ template.tag.ng
><div *matHeaderCellDef></div>
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng
><!-- #613 -->
#^^^^^^^^^^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div *ngIf="x$ | async as a"></div>
#^^^^^ template.tag.ng
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html punctuation.definition.ng-binding-name.begin.html
# ^^^^ template.tag.ng meta.ng-binding.template.html entity.other.attribute-name.html entity.other.ng-binding-name.template.html entity.other.ng-binding-name.ngIf.html
# ^ template.tag.ng meta.ng-binding.template.html punctuation.separator.key-value.html
@@ -788,5 +925,58 @@
# ^ template.tag.ng meta.ng-binding.template.html expression.ng
# ^ template.tag.ng meta.ng-binding.template.html expression.ng entity.name.type.ts
# ^ template.tag.ng meta.ng-binding.template.html string.quoted.html punctuation.definition.string.end.html
# ^^^^^^^^ template.tag.ng
>
# ^^^^^^^ template.tag.ng
>
><!-- inline comments in the HTML element -->
#^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^^^^^ template.tag.ng
# ^ template.tag.ng template.tag.ng
# ^^^ template.tag.ng
><div
#^^^^ template.tag.ng
> // comment 0
#^^ template.tag.ng template.tag.ng
# ^^ template.tag.ng comment.line.double-slash.ts punctuation.definition.comment.ts
# ^^^^^^^^^^ template.tag.ng comment.line.double-slash.ts
> /* comment 1 */
#^^ template.tag.ng template.tag.ng
# ^^ template.tag.ng comment.block.ts punctuation.definition.comment.ts
# ^^^^^^^^^^^ template.tag.ng comment.block.ts
# ^^ template.tag.ng comment.block.ts punctuation.definition.comment.ts
> attr1="value1"
#^^ template.tag.ng template.tag.ng
# ^^^^^ template.tag.ng meta.attribute.standard.html entity.other.attribute-name.html
# ^ template.tag.ng meta.attribute.standard.html punctuation.separator.key-value.html
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^ template.tag.ng meta.attribute.standard.html variable.other.readwrite.ts
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.end.html
> /*
#^^ template.tag.ng template.tag.ng
# ^^ template.tag.ng comment.block.ts punctuation.definition.comment.ts
> comment 2
#^^^^^^^^^^^^^^^ template.tag.ng comment.block.ts
> spanning multiple lines
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.tag.ng comment.block.ts
> */
#^^ template.tag.ng comment.block.ts
# ^^ template.tag.ng comment.block.ts punctuation.definition.comment.ts
> attr2="value2"
#^^ template.tag.ng template.tag.ng
# ^^^^^ template.tag.ng meta.attribute.standard.html entity.other.attribute-name.html
# ^ template.tag.ng meta.attribute.standard.html punctuation.separator.key-value.html
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.begin.html
# ^^^^^^ template.tag.ng meta.attribute.standard.html variable.other.readwrite.ts
# ^ template.tag.ng meta.attribute.standard.html string.quoted.html punctuation.definition.string.end.html
>></div>
#^^^^^^^ template.tag.ng