mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-02 14:31:31 +01:00
[html] enable handlebars
This commit is contained in:
@@ -62,4 +62,19 @@ export function activate(context: ExtensionContext) {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
languages.setLanguageConfiguration('handlebars', {
|
||||||
|
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|('(?:[^\\\']*(?:\\.)?)*'?)|[^\s<>={}\[\],]+/,
|
||||||
|
onEnterRules:[
|
||||||
|
{
|
||||||
|
beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
|
||||||
|
afterText: /^<\/([_:\w][_:\w-.\d]*)\s*>$/i,
|
||||||
|
action: { indentAction: IndentAction.IndentOutdent }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
|
||||||
|
action: { indentAction: IndentAction.Indent }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -206,6 +206,10 @@ export interface Scanner {
|
|||||||
getScannerState(): ScannerState;
|
getScannerState(): ScannerState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const htmlScriptContents = {
|
||||||
|
'text/x-handlebars-template': true
|
||||||
|
};
|
||||||
|
|
||||||
export function createScanner(input: string, initialOffset = 0, initialState: ScannerState = ScannerState.WithinContent) : Scanner {
|
export function createScanner(input: string, initialOffset = 0, initialState: ScannerState = ScannerState.WithinContent) : Scanner {
|
||||||
|
|
||||||
let stream = new MultiLineStream(input, initialOffset);
|
let stream = new MultiLineStream(input, initialOffset);
|
||||||
@@ -216,6 +220,8 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
|
|
||||||
let hasSpaceAfterTag: boolean;
|
let hasSpaceAfterTag: boolean;
|
||||||
let lastTag: string;
|
let lastTag: string;
|
||||||
|
let lastAttributeName: string;
|
||||||
|
let lastTypeValue: string;
|
||||||
|
|
||||||
function nextElementName(): string {
|
function nextElementName(): string {
|
||||||
return stream.advanceIfRegExp(/^[_:\w][_:\w-.\d]*/).toLowerCase();
|
return stream.advanceIfRegExp(/^[_:\w][_:\w-.\d]*/).toLowerCase();
|
||||||
@@ -299,6 +305,8 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
break;
|
break;
|
||||||
case ScannerState.AfterOpeningStartTag:
|
case ScannerState.AfterOpeningStartTag:
|
||||||
lastTag = nextElementName();
|
lastTag = nextElementName();
|
||||||
|
lastTypeValue = null;
|
||||||
|
lastAttributeName = null;
|
||||||
if (lastTag.length > 0) {
|
if (lastTag.length > 0) {
|
||||||
hasSpaceAfterTag = false;
|
hasSpaceAfterTag = false;
|
||||||
state = ScannerState.WithinTag;
|
state = ScannerState.WithinTag;
|
||||||
@@ -316,8 +324,8 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
return finishToken(offset, TokenType.Whitespace);
|
return finishToken(offset, TokenType.Whitespace);
|
||||||
}
|
}
|
||||||
if (hasSpaceAfterTag) {
|
if (hasSpaceAfterTag) {
|
||||||
let name = nextAttributeName();
|
lastAttributeName = nextAttributeName();
|
||||||
if (name.length > 0) {
|
if (lastAttributeName.length > 0) {
|
||||||
state = ScannerState.AfterAttributeName;
|
state = ScannerState.AfterAttributeName;
|
||||||
hasSpaceAfterTag = false;
|
hasSpaceAfterTag = false;
|
||||||
return finishToken(offset, TokenType.AttributeName);
|
return finishToken(offset, TokenType.AttributeName);
|
||||||
@@ -329,7 +337,12 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
}
|
}
|
||||||
if (stream.advanceIfChar(_RAN)) { // >
|
if (stream.advanceIfChar(_RAN)) { // >
|
||||||
if (lastTag === 'script') {
|
if (lastTag === 'script') {
|
||||||
state = ScannerState.WithinScriptContent;
|
if (lastTypeValue && htmlScriptContents[lastTypeValue]) {
|
||||||
|
// stay in html
|
||||||
|
state = ScannerState.WithinContent;
|
||||||
|
} else {
|
||||||
|
state = ScannerState.WithinScriptContent;
|
||||||
|
}
|
||||||
} else if (lastTag === 'style') {
|
} else if (lastTag === 'style') {
|
||||||
state = ScannerState.WithinStyleContent;
|
state = ScannerState.WithinStyleContent;
|
||||||
} else {
|
} else {
|
||||||
@@ -357,6 +370,9 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
}
|
}
|
||||||
let attributeValue = stream.advanceIfRegExp(/^[^\s"'`=<>]+/);
|
let attributeValue = stream.advanceIfRegExp(/^[^\s"'`=<>]+/);
|
||||||
if (attributeValue.length > 0) {
|
if (attributeValue.length > 0) {
|
||||||
|
if (lastAttributeName === 'type') {
|
||||||
|
lastTypeValue = attributeValue;
|
||||||
|
}
|
||||||
state = ScannerState.WithinTag;
|
state = ScannerState.WithinTag;
|
||||||
hasSpaceAfterTag = false;
|
hasSpaceAfterTag = false;
|
||||||
return finishToken(offset, TokenType.AttributeValue);
|
return finishToken(offset, TokenType.AttributeValue);
|
||||||
@@ -367,6 +383,9 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc
|
|||||||
if (stream.advanceUntilChar(ch)) {
|
if (stream.advanceUntilChar(ch)) {
|
||||||
stream.advance(1); // consume quote
|
stream.advance(1); // consume quote
|
||||||
}
|
}
|
||||||
|
if (lastAttributeName === 'type') {
|
||||||
|
lastTypeValue = stream.getSource().substring(offset + 1, stream.pos() - 1);
|
||||||
|
}
|
||||||
state = ScannerState.WithinTag;
|
state = ScannerState.WithinTag;
|
||||||
hasSpaceAfterTag = false;
|
hasSpaceAfterTag = false;
|
||||||
return finishToken(offset, TokenType.AttributeValue);
|
return finishToken(offset, TokenType.AttributeValue);
|
||||||
|
|||||||
@@ -269,6 +269,17 @@ suite('HTML Completion', () => {
|
|||||||
], testDone);
|
], testDone);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
suite('Handlevar Completion', (testDone) => {
|
||||||
|
run([
|
||||||
|
|
||||||
|
testCompletionFor('<script id="entry-template" type="text/x-handlebars-template"> | </script>' , {
|
||||||
|
items: [
|
||||||
|
{ label: 'div', resultText: '<script id="entry-template" type="text/x-handlebars-template"> <div></div> </script>' },
|
||||||
|
]
|
||||||
|
})
|
||||||
|
], testDone);
|
||||||
|
});
|
||||||
|
|
||||||
test('Intellisense aria', function (testDone): any {
|
test('Intellisense aria', function (testDone): any {
|
||||||
let expectedAriaAttributes = [
|
let expectedAriaAttributes = [
|
||||||
{ label: 'aria-activedescendant' },
|
{ label: 'aria-activedescendant' },
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import 'vs/editor/contrib/quickOpen/browser/quickCommand';
|
|||||||
import 'vs/languages/languages.main';
|
import 'vs/languages/languages.main';
|
||||||
import 'vs/languages/php/common/php.contribution';
|
import 'vs/languages/php/common/php.contribution';
|
||||||
import 'vs/languages/html/common/html.contribution';
|
import 'vs/languages/html/common/html.contribution';
|
||||||
|
import 'vs/languages/handlebars/common/handlebars.contribution';
|
||||||
|
|
||||||
import {createMonacoBaseAPI} from 'vs/editor/common/standalone/standaloneBase';
|
import {createMonacoBaseAPI} from 'vs/editor/common/standalone/standaloneBase';
|
||||||
import {createMonacoEditorAPI} from 'vs/editor/browser/standalone/standaloneEditor';
|
import {createMonacoEditorAPI} from 'vs/editor/browser/standalone/standaloneEditor';
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
import 'vs/languages/handlebars/common/handlebars.contribution';
|
|
||||||
import 'vs/languages/razor/common/razor.contribution';
|
import 'vs/languages/razor/common/razor.contribution';
|
||||||
|
|||||||
Reference in New Issue
Block a user