提交 d7397bca 编写于 作者: A Alex Dima

Remove vs/languages/handlebars

上级 2ea4e8e6
......@@ -41,9 +41,6 @@ exports.collectModules = function(args) {
// ---- beautify-html (shared btw html and xml) -----------------------------
// worker.define('vs/languages/lib/common/beautify-html');
// // ---- handlebars ----------------------------------
// common.define('vs/languages/handlebars/common/handlebars', ['vs/languages/html/common/html']);
// // ---- html ----------------------------------
// common.define('vs/languages/html/common/html')
// .combine(worker)
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {ModesRegistry} from 'vs/editor/common/modes/modesRegistry';
ModesRegistry.registerCompatMode({
id: 'handlebars',
extensions: ['.handlebars', '.hbs'],
aliases: ['Handlebars', 'handlebars'],
mimetypes: ['text/x-handlebars-template'],
moduleId: 'vs/languages/handlebars/common/handlebars',
ctorName: 'HandlebarsMode'
});
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import modes = require('vs/editor/common/modes');
import htmlMode = require('vs/languages/html/common/html');
import handlebarsTokenTypes = require('vs/languages/handlebars/common/handlebarsTokenTypes');
import htmlWorker = require('vs/languages/html/common/htmlWorker');
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IModeService} from 'vs/editor/common/services/modeService';
import {LanguageConfigurationRegistry, LanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {createWordRegExp} from 'vs/editor/common/modes/abstractMode';
import {wireCancellationToken} from 'vs/base/common/async';
import {ICompatWorkerService} from 'vs/editor/common/services/compatWorkerService';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {TokenizationSupport, ILeavingNestedModeData} from 'vs/editor/common/modes/supports/tokenizationSupport';
export enum States {
HTML,
Expression,
UnescapedExpression
}
export class HandlebarsState extends htmlMode.State {
constructor(modeId:string,
kind:htmlMode.States,
public handlebarsKind:States,
lastTagName:string,
lastAttributeName:string,
embeddedContentType:string,
attributeValueQuote:string,
attributeValueLength:number) {
super(modeId, kind, lastTagName, lastAttributeName, embeddedContentType, attributeValueQuote, attributeValueLength);
}
public makeClone(): HandlebarsState {
return new HandlebarsState(this.getModeId(), this.kind, this.handlebarsKind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValueLength);
}
public equals(other:modes.IState):boolean {
if (other instanceof HandlebarsState) {
return (
super.equals(other)
);
}
return false;
}
public tokenize(stream:modes.IStream) : modes.ITokenizationResult {
switch(this.handlebarsKind) {
case States.HTML:
if (stream.advanceIfString('{{{').length > 0) {
this.handlebarsKind = States.UnescapedExpression;
return { type: handlebarsTokenTypes.EMBED_UNESCAPED };
}
else if (stream.advanceIfString('{{').length > 0) {
this.handlebarsKind = States.Expression;
return { type: handlebarsTokenTypes.EMBED };
}
break;
case States.Expression:
case States.UnescapedExpression:
if (this.handlebarsKind === States.Expression && stream.advanceIfString('}}').length > 0) {
this.handlebarsKind = States.HTML;
return { type: handlebarsTokenTypes.EMBED };
}
else if (this.handlebarsKind === States.UnescapedExpression &&stream.advanceIfString('}}}').length > 0) {
this.handlebarsKind = States.HTML;
return { type: handlebarsTokenTypes.EMBED_UNESCAPED };
}
else if(stream.skipWhitespace().length > 0) {
return { type: ''};
}
if(stream.peek() === '#') {
stream.advanceWhile(/^[^\s}]/);
return { type: handlebarsTokenTypes.KEYWORD };
}
if(stream.peek() === '/') {
stream.advanceWhile(/^[^\s}]/);
return { type: handlebarsTokenTypes.KEYWORD };
}
if(stream.advanceIfString('else')) {
var next = stream.peek();
if(next === ' ' || next === '\t' || next === '}') {
return { type: handlebarsTokenTypes.KEYWORD };
}
else {
stream.goBack(4);
}
}
if(stream.advanceWhile(/^[^\s}]/).length > 0) {
return { type: handlebarsTokenTypes.VARIABLE };
}
break;
}
return super.tokenize(stream);
}
}
export class HandlebarsMode extends htmlMode.HTMLMode<htmlWorker.HTMLWorker> {
public static LANG_CONFIG:LanguageConfiguration = {
wordPattern: createWordRegExp('#-?%'),
comments: {
blockComment: ['<!--', '-->']
},
brackets: [
['<!--', '-->'],
['{{', '}}']
],
__electricCharacterSupport: {
embeddedElectricCharacters: ['*', '}', ']', ')']
},
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
],
surroundingPairs: [
{ open: '<', close: '>' },
{ open: '"', close: '"' },
{ open: '\'', close: '\'' }
],
onEnterRules: [
{
beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
afterText: /^<\/(\w[\w\d]*)\s*>$/i,
action: { indentAction: modes.IndentAction.IndentOutdent }
},
{
beforeText: new RegExp(`<(?!(?:${htmlMode.EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'),
action: { indentAction: modes.IndentAction.Indent }
}
],
};
constructor(
descriptor:modes.IModeDescriptor,
@IInstantiationService instantiationService: IInstantiationService,
@IModeService modeService: IModeService,
@ICompatWorkerService compatWorkerService: ICompatWorkerService,
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
@IConfigurationService configurationService: IConfigurationService
) {
super(descriptor, instantiationService, modeService, compatWorkerService, workspaceContextService, configurationService);
}
protected _registerSupports(): void {
modes.SuggestRegistry.register(this.getId(), {
triggerCharacters: ['.', ':', '<', '"', '=', '/'],
provideCompletionItems: (model, position, token): Thenable<modes.ISuggestResult> => {
return wireCancellationToken(token, this._provideCompletionItems(model.uri, position));
}
}, true);
modes.DocumentHighlightProviderRegistry.register(this.getId(), {
provideDocumentHighlights: (model, position, token): Thenable<modes.DocumentHighlight[]> => {
return wireCancellationToken(token, this._provideDocumentHighlights(model.uri, position));
}
}, true);
modes.LinkProviderRegistry.register(this.getId(), {
provideLinks: (model, token): Thenable<modes.ILink[]> => {
return wireCancellationToken(token, this.provideLinks(model.uri));
}
}, true);
LanguageConfigurationRegistry.register(this.getId(), HandlebarsMode.LANG_CONFIG);
modes.TokenizationRegistry.register(this.getId(), new TokenizationSupport(this._modeService, this.getId(), this, true));
}
public getInitialState() : modes.IState {
return new HandlebarsState(this.getId(), htmlMode.States.Content, States.HTML, '', '', '', '', 0);
}
public getLeavingNestedModeData(line:string, state:modes.IState):ILeavingNestedModeData {
var leavingNestedModeData = super.getLeavingNestedModeData(line, state);
if (leavingNestedModeData) {
leavingNestedModeData.stateAfterNestedMode = new HandlebarsState(this.getId(), htmlMode.States.Content, States.HTML, '', '', '', '', 0);
}
return leavingNestedModeData;
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export const EMBED = 'punctuation.expression.unescaped.handlebars';
export const EMBED_UNESCAPED = 'punctuation.expression.handlebars';
export const KEYWORD = 'keyword.helper.handlebars';
export const VARIABLE = 'variable.parameter.handlebars';
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import Modes = require('vs/editor/common/modes');
import modesUtil = require('vs/editor/test/common/modesUtil');
import {htmlTokenTypes} from 'vs/languages/html/common/html';
import handlebarsTokenTypes = require('vs/languages/handlebars/common/handlebarsTokenTypes');
import {HandlebarsMode} from 'vs/languages/handlebars/common/handlebars';
import {MockModeService} from 'vs/editor/test/common/mocks/mockModeService';
import {MockTokenizingMode} from 'vs/editor/test/common/mocks/mockMode';
class HandlebarsMockModeService extends MockModeService {
private _handlebarsMode: HandlebarsMode;
constructor() {
super();
this._handlebarsMode = null;
}
public setHandlebarsMode(handlebarsMode: HandlebarsMode): void {
this._handlebarsMode = handlebarsMode;
}
isRegisteredMode(mimetypeOrModeId: string): boolean {
if (mimetypeOrModeId === 'text/javascript') {
return true;
}
if (mimetypeOrModeId === 'text/x-handlebars-template') {
return true;
}
throw new Error('Not implemented');
}
getModeId(mimetypeOrModeId: string): string {
if (mimetypeOrModeId === 'text/javascript') {
return 'js-mode-id';
}
if (mimetypeOrModeId === 'text/x-handlebars-template') {
return 'handlebars-mode-id';
}
throw new Error('Not implemented');
}
getMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): Modes.IMode {
if (commaSeparatedMimetypesOrCommaSeparatedIds === 'js-mode-id') {
return new MockTokenizingMode('mock-js');
}
if (commaSeparatedMimetypesOrCommaSeparatedIds === 'handlebars-mode-id') {
return this._handlebarsMode;
}
throw new Error('Not implemented');
}
}
suite('Handlebars', () => {
var tokenizationSupport: Modes.ITokenizationSupport;
suiteSetup(function() {
let modeService = new HandlebarsMockModeService();
let mode = new HandlebarsMode(
{ id: 'handlebars' },
null,
modeService,
null,
null,
null
);
modeService.setHandlebarsMode(mode);
tokenizationSupport = Modes.TokenizationRegistry.get(mode.getId());
});
test('Just HTML', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<h1>handlebars!</h1>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('h1') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: '' },
{ startIndex:15, type: htmlTokenTypes.DELIM_END },
{ startIndex:17, type: htmlTokenTypes.getTag('h1') },
{ startIndex:19, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Expressions', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<h1>{{ title }}</h1>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('h1') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: handlebarsTokenTypes.EMBED },
{ startIndex:6, type: '' },
{ startIndex:7, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:12, type: '' },
{ startIndex:13, type: handlebarsTokenTypes.EMBED },
{ startIndex:15, type: htmlTokenTypes.DELIM_END },
{ startIndex:17, type: htmlTokenTypes.getTag('h1') },
{ startIndex:19, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Expressions Sans Whitespace', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<h1>{{title}}</h1>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('h1') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: handlebarsTokenTypes.EMBED },
{ startIndex:6, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:11, type: handlebarsTokenTypes.EMBED },
{ startIndex:13, type: htmlTokenTypes.DELIM_END },
{ startIndex:15, type: htmlTokenTypes.getTag('h1') },
{ startIndex:17, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Unescaped Expressions', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<h1>{{{ title }}}</h1>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('h1') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: handlebarsTokenTypes.EMBED_UNESCAPED },
{ startIndex:7, type: '' },
{ startIndex:8, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:13, type: '' },
{ startIndex:14, type: handlebarsTokenTypes.EMBED_UNESCAPED },
{ startIndex:17, type: htmlTokenTypes.DELIM_END },
{ startIndex:19, type: htmlTokenTypes.getTag('h1') },
{ startIndex:21, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Blocks', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<ul>{{#each items}}<li>{{item}}</li>{{/each}}</ul>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('ul') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: handlebarsTokenTypes.EMBED },
{ startIndex:6, type: handlebarsTokenTypes.KEYWORD },
{ startIndex:11, type: '' },
{ startIndex:12, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:17, type: handlebarsTokenTypes.EMBED },
{ startIndex:19, type: htmlTokenTypes.DELIM_START },
{ startIndex:20, type: htmlTokenTypes.getTag('li') },
{ startIndex:22, type: htmlTokenTypes.DELIM_START },
{ startIndex:23, type: handlebarsTokenTypes.EMBED },
{ startIndex:25, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:29, type: handlebarsTokenTypes.EMBED },
{ startIndex:31, type: htmlTokenTypes.DELIM_END },
{ startIndex:33, type: htmlTokenTypes.getTag('li') },
{ startIndex:35, type: htmlTokenTypes.DELIM_END },
{ startIndex:36, type: handlebarsTokenTypes.EMBED },
{ startIndex:38, type: handlebarsTokenTypes.KEYWORD },
{ startIndex:43, type: handlebarsTokenTypes.EMBED },
{ startIndex:45, type: htmlTokenTypes.DELIM_END },
{ startIndex:47, type: htmlTokenTypes.getTag('ul') },
{ startIndex:49, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Multiline', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<div>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('div') },
{ startIndex:4, type: htmlTokenTypes.DELIM_START }
]}, {
line: '{{#if foo}}',
tokens: [
{ startIndex:0, type: handlebarsTokenTypes.EMBED },
{ startIndex:2, type: handlebarsTokenTypes.KEYWORD },
{ startIndex:5, type: '' },
{ startIndex:6, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:9, type: handlebarsTokenTypes.EMBED }
]}, {
line: '<span>{{bar}}</span>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('span') },
{ startIndex:5, type: htmlTokenTypes.DELIM_START },
{ startIndex:6, type: handlebarsTokenTypes.EMBED },
{ startIndex:8, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:11, type: handlebarsTokenTypes.EMBED },
{ startIndex:13, type: htmlTokenTypes.DELIM_END },
{ startIndex:15, type: htmlTokenTypes.getTag('span') },
{ startIndex:19, type: htmlTokenTypes.DELIM_END }
]}, {
line: '{{/if}}',
tokens: null}
]);
});
test('Div end', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '</div>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_END },
{ startIndex:2, type: htmlTokenTypes.getTag('div') },
{ startIndex:5, type: htmlTokenTypes.DELIM_END }
]}
]);
});
// shamelessly stolen from the HTML test bed since Handlebars are a superset of HTML
test('Embedded Content in HTML', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<script type="text/javascript">var i= 10;</script>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('script') },
{ startIndex:7, type: '' },
{ startIndex:8, type: htmlTokenTypes.ATTRIB_NAME },
{ startIndex:12, type: htmlTokenTypes.DELIM_ASSIGN },
{ startIndex:13, type: htmlTokenTypes.ATTRIB_VALUE },
{ startIndex:30, type: htmlTokenTypes.DELIM_START },
{ startIndex:31, type: 'mock-js' },
{ startIndex:41, type: htmlTokenTypes.DELIM_END },
{ startIndex:43, type: htmlTokenTypes.getTag('script') },
{ startIndex:49, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('HTML Expressions', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<script type="text/x-handlebars-template"><h1>{{ title }}</h1></script>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('script') },
{ startIndex:7, type: '' },
{ startIndex:8, type: htmlTokenTypes.ATTRIB_NAME },
{ startIndex:12, type: htmlTokenTypes.DELIM_ASSIGN },
{ startIndex:13, type: htmlTokenTypes.ATTRIB_VALUE },
{ startIndex:41, type: htmlTokenTypes.DELIM_START },
{ startIndex:42, type: htmlTokenTypes.DELIM_START },
{ startIndex:43, type: htmlTokenTypes.getTag('h1') },
{ startIndex:45, type: htmlTokenTypes.DELIM_START },
{ startIndex:46, type: handlebarsTokenTypes.EMBED },
{ startIndex:48, type: '' },
{ startIndex:49, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:54, type: '' },
{ startIndex:55, type: handlebarsTokenTypes.EMBED },
{ startIndex:57, type: htmlTokenTypes.DELIM_END },
{ startIndex:59, type: htmlTokenTypes.getTag('h1') },
{ startIndex:61, type: htmlTokenTypes.DELIM_END },
{ startIndex:62, type: htmlTokenTypes.DELIM_END },
{ startIndex:64, type: htmlTokenTypes.getTag('script') },
{ startIndex:70, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('Multi-line HTML Expressions', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<script type="text/x-handlebars-template">',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('script') },
{ startIndex:7, type: '' },
{ startIndex:8, type: htmlTokenTypes.ATTRIB_NAME },
{ startIndex:12, type: htmlTokenTypes.DELIM_ASSIGN },
{ startIndex:13, type: htmlTokenTypes.ATTRIB_VALUE },
{ startIndex:41, type: htmlTokenTypes.DELIM_START }
]}, {
line: '<h1>{{ title }}</h1>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('h1') },
{ startIndex:3, type: htmlTokenTypes.DELIM_START },
{ startIndex:4, type: handlebarsTokenTypes.EMBED },
{ startIndex:6, type: '' },
{ startIndex:7, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:12, type: '' },
{ startIndex:13, type: handlebarsTokenTypes.EMBED },
{ startIndex:15, type: htmlTokenTypes.DELIM_END },
{ startIndex:17, type: htmlTokenTypes.getTag('h1') },
{ startIndex:19, type: htmlTokenTypes.DELIM_END }
]}, {
line: '</script>',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_END },
{ startIndex:2, type: htmlTokenTypes.getTag('script') },
{ startIndex:8, type: htmlTokenTypes.DELIM_END }
]}
]);
});
test('HTML Nested Modes', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '{{foo}}<script></script>{{bar}}',
tokens: [
{ startIndex:0, type: handlebarsTokenTypes.EMBED },
{ startIndex:2, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:5, type: handlebarsTokenTypes.EMBED },
{ startIndex:7, type: htmlTokenTypes.DELIM_START },
{ startIndex:8, type: htmlTokenTypes.getTag('script') },
{ startIndex:14, type: htmlTokenTypes.DELIM_START },
{ startIndex:15, type: htmlTokenTypes.DELIM_END },
{ startIndex:17, type: htmlTokenTypes.getTag('script') },
{ startIndex:23, type: htmlTokenTypes.DELIM_END },
{ startIndex:24, type: handlebarsTokenTypes.EMBED },
{ startIndex:26, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:29, type: handlebarsTokenTypes.EMBED }
]}
]);
});
test('else keyword', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '{{else}}',
tokens: [
{ startIndex:0, type: handlebarsTokenTypes.EMBED },
{ startIndex:2, type: handlebarsTokenTypes.KEYWORD },
{ startIndex:6, type: handlebarsTokenTypes.EMBED }
]}
]);
});
test('else keyword #2', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '{{elseFoo}}',
tokens: [
{ startIndex:0, type: handlebarsTokenTypes.EMBED },
{ startIndex:2, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:9, type: handlebarsTokenTypes.EMBED }
]}
]);
});
test('Token inside attribute', () => {
modesUtil.assertTokenization(tokenizationSupport, [{
line: '<a href="/posts/{{permalink}}">',
tokens: [
{ startIndex:0, type: htmlTokenTypes.DELIM_START },
{ startIndex:1, type: htmlTokenTypes.getTag('a') },
{ startIndex:2, type: '' },
{ startIndex:3, type: htmlTokenTypes.ATTRIB_NAME },
{ startIndex:7, type: htmlTokenTypes.DELIM_ASSIGN },
{ startIndex:8, type: htmlTokenTypes.ATTRIB_VALUE },
{ startIndex:16, type: handlebarsTokenTypes.EMBED },
{ startIndex:18, type: handlebarsTokenTypes.VARIABLE },
{ startIndex:27, type: handlebarsTokenTypes.EMBED },
{ startIndex:29, type: htmlTokenTypes.ATTRIB_VALUE },
{ startIndex:30, type: htmlTokenTypes.DELIM_START }
]}
]);
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册