mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-07 15:26:49 +01:00
fixes #5919: [html] Angular 2 directives break HTML syntax highlighting
This commit is contained in:
@@ -85,10 +85,14 @@ export class State extends AbstractState {
|
||||
return false;
|
||||
}
|
||||
|
||||
private nextName(stream:Modes.IStream):string {
|
||||
private nextElementName(stream:Modes.IStream):string {
|
||||
return stream.advanceIfRegExp(/^[_:\w][_:\w-.\d]*/).toLowerCase();
|
||||
}
|
||||
|
||||
private nextAttributeName(stream:Modes.IStream):string {
|
||||
return stream.advanceIfRegExp(/^[^\s"'>/=\x00-\x0F\x7F\x80-\x9F]*/).toLowerCase();
|
||||
}
|
||||
|
||||
public tokenize(stream:Modes.IStream) : Modes.ITokenizationResult {
|
||||
|
||||
switch(this.kind){
|
||||
@@ -133,7 +137,7 @@ export class State extends AbstractState {
|
||||
break;
|
||||
|
||||
case States.OpeningEndTag:
|
||||
var tagName = this.nextName(stream);
|
||||
var tagName = this.nextElementName(stream);
|
||||
if (tagName.length > 0){
|
||||
return {
|
||||
type: State.escapeTagName(tagName),
|
||||
@@ -149,7 +153,7 @@ export class State extends AbstractState {
|
||||
}
|
||||
|
||||
case States.OpeningStartTag:
|
||||
this.lastTagName = this.nextName(stream);
|
||||
this.lastTagName = this.nextElementName(stream);
|
||||
if (this.lastTagName.length > 0) {
|
||||
this.lastAttributeName = null;
|
||||
if ('script' === this.lastTagName || 'style' === this.lastTagName) {
|
||||
@@ -165,18 +169,22 @@ export class State extends AbstractState {
|
||||
|
||||
case States.WithinTag:
|
||||
if (stream.skipWhitespace2() || stream.eos()) {
|
||||
this.lastAttributeName = ''; // remember that we have seen a whitespace
|
||||
return { type: '' };
|
||||
} else {
|
||||
var name:string = this.nextName(stream);
|
||||
if (name.length > 0) {
|
||||
this.lastAttributeName = name;
|
||||
this.kind = States.AttributeName;
|
||||
return { type: htmlTokenTypes.ATTRIB_NAME };
|
||||
|
||||
} else if (stream.advanceIfString2('/>')) {
|
||||
this.kind = States.Content;
|
||||
return { type: htmlTokenTypes.DELIM_START, dontMergeWithPrev: true };
|
||||
} if (stream.advanceIfCharCode2('>'.charCodeAt(0))) {
|
||||
if (this.lastAttributeName === '') {
|
||||
var name = this.nextAttributeName(stream);
|
||||
if (name.length > 0) {
|
||||
this.lastAttributeName = name;
|
||||
this.kind = States.AttributeName;
|
||||
return { type: htmlTokenTypes.ATTRIB_NAME };
|
||||
}
|
||||
}
|
||||
if (stream.advanceIfString2('/>')) {
|
||||
this.kind = States.Content;
|
||||
return { type: htmlTokenTypes.DELIM_START, dontMergeWithPrev: true };
|
||||
}
|
||||
if (stream.advanceIfCharCode2('>'.charCodeAt(0))) {
|
||||
if (tagsEmbeddingContent.indexOf(this.lastTagName) !== -1) {
|
||||
this.kind = States.WithinEmbeddedContent;
|
||||
return { type: htmlTokenTypes.DELIM_START, dontMergeWithPrev: true };
|
||||
@@ -200,6 +208,7 @@ export class State extends AbstractState {
|
||||
return { type: htmlTokenTypes.DELIM_ASSIGN };
|
||||
} else {
|
||||
this.kind = States.WithinTag;
|
||||
this.lastAttributeName = '';
|
||||
return this.tokenize(stream); // no advance yet - jump to WithinTag
|
||||
}
|
||||
|
||||
@@ -231,6 +240,7 @@ export class State extends AbstractState {
|
||||
this.kind = States.WithinTag;
|
||||
this.attributeValue = '';
|
||||
this.attributeValueQuote = '';
|
||||
this.lastAttributeName = null;
|
||||
} else {
|
||||
var part = stream.next();
|
||||
this.attributeValue += part;
|
||||
@@ -241,6 +251,7 @@ export class State extends AbstractState {
|
||||
let attributeValue = stream.advanceIfRegExp(/^[^\s"'`=<>]+/);
|
||||
if (attributeValue.length > 0) {
|
||||
this.kind = States.WithinTag;
|
||||
this.lastAttributeName = null;
|
||||
return { type: htmlTokenTypes.ATTRIB_VALUE };
|
||||
}
|
||||
var ch = stream.peek();
|
||||
@@ -251,6 +262,7 @@ export class State extends AbstractState {
|
||||
return { type: htmlTokenTypes.ATTRIB_VALUE };
|
||||
} else {
|
||||
this.kind = States.WithinTag;
|
||||
this.lastAttributeName = null;
|
||||
return this.tokenize(stream); // no advance yet - jump to WithinTag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ suite('Colorizing - HTML', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('Tag with empty atrributes', () => {
|
||||
test('Tag with empty attributes', () => {
|
||||
modesUtil.assertTokenization(tokenizationSupport, [{
|
||||
line: '<abc foo="">',
|
||||
tokens: [
|
||||
@@ -580,7 +580,7 @@ suite('Colorizing - HTML', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test('Tag with Invalid Attribute Name', () => {
|
||||
test('Tag with Interesting Attribute Name', () => {
|
||||
modesUtil.assertTokenization(tokenizationSupport, [{
|
||||
line: '<abc foo!@#="bar">',
|
||||
tokens: [
|
||||
@@ -588,14 +588,38 @@ suite('Colorizing - HTML', () => {
|
||||
{ startIndex:1, type: getTag('abc') },
|
||||
{ startIndex:4, type: '' },
|
||||
{ startIndex:5, type: ATTRIB_NAME },
|
||||
{ startIndex:8, type: '' },
|
||||
{ startIndex:13, type: ATTRIB_NAME },
|
||||
{ startIndex:16, type: '' },
|
||||
{ startIndex:11, type: DELIM_ASSIGN },
|
||||
{ startIndex:12, type: ATTRIB_VALUE },
|
||||
{ startIndex:17, type: DELIM_START }
|
||||
]}
|
||||
]);
|
||||
});
|
||||
|
||||
test('Tag with Angular Attribute Name', () => {
|
||||
modesUtil.assertTokenization(tokenizationSupport, [{
|
||||
line: '<abc #myinput (click)="bar" [value]="someProperty" *ngIf="someCondition">',
|
||||
tokens: [
|
||||
{ startIndex:0, type: DELIM_START },
|
||||
{ startIndex:1, type: getTag('abc') },
|
||||
{ startIndex:4, type: '' },
|
||||
{ startIndex:5, type: ATTRIB_NAME },
|
||||
{ startIndex:13, type: '' },
|
||||
{ startIndex:14, type: ATTRIB_NAME },
|
||||
{ startIndex:21, type: DELIM_ASSIGN },
|
||||
{ startIndex:22, type: ATTRIB_VALUE },
|
||||
{ startIndex:27, type: '' },
|
||||
{ startIndex:28, type: ATTRIB_NAME },
|
||||
{ startIndex:35, type: DELIM_ASSIGN },
|
||||
{ startIndex:36, type: ATTRIB_VALUE },
|
||||
{ startIndex:50, type: '' },
|
||||
{ startIndex:51, type: ATTRIB_NAME },
|
||||
{ startIndex:56, type: DELIM_ASSIGN },
|
||||
{ startIndex:57, type: ATTRIB_VALUE },
|
||||
{ startIndex:72, type: DELIM_START }
|
||||
]}
|
||||
]);
|
||||
});
|
||||
|
||||
test('Tag with Invalid Attribute Value', () => {
|
||||
modesUtil.assertTokenization(tokenizationSupport, [{
|
||||
line: '<abc foo=">',
|
||||
|
||||
Reference in New Issue
Block a user