diff --git a/.vscode/settings.json b/.vscode/settings.json index 1dc255b6..5dc190ce 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,7 @@ "**/node_modules": true, "**/release": true, "**/out": true - } + }, + "editor.tabSize": 4, + "editor.insertSpaces": false } \ No newline at end of file diff --git a/src/html.ts b/src/html.ts index 9115d3d7..dae63cdf 100644 --- a/src/html.ts +++ b/src/html.ts @@ -8,6 +8,9 @@ import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration; import ILanguage = monaco.languages.IMonarchLanguage; +// Allow for running under nodejs/requirejs in tests +var _monaco: typeof monaco = (typeof monaco === 'undefined' ? (self).monaco : monaco); + const EMPTY_ELEMENTS:string[] = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']; export var conf:IRichLanguageConfiguration = { @@ -43,11 +46,11 @@ export var conf:IRichLanguageConfiguration = { { beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'), afterText: /^<\/([_:\w][_:\w-.\d]*)\s*>$/i, - action: { indentAction: monaco.languages.IndentAction.IndentOutdent } + action: { indentAction: _monaco.languages.IndentAction.IndentOutdent } }, { beforeText: new RegExp(`<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i'), - action: { indentAction: monaco.languages.IndentAction.Indent } + action: { indentAction: _monaco.languages.IndentAction.Indent } } ], }; @@ -64,6 +67,7 @@ export const htmlTokenTypes = { export var language = { defaultToken: '', tokenPostfix: '.html', + ignoreCase: true, // The main tokenizer for our languages tokenizer: { @@ -73,9 +77,10 @@ export var language = { [/(<)(\w+)(\/>)/, [htmlTokenTypes.DELIM_START, 'tag', htmlTokenTypes.DELIM_END]], [/(<)(script)/, [htmlTokenTypes.DELIM_START, { token: 'tag', next: '@script'} ]], [/(<)(style)/, [htmlTokenTypes.DELIM_START, { token: 'tag', next: '@style'} ]], - [/(<)(\w+)/, [htmlTokenTypes.DELIM_START, { token: 'tag', next: '@otherTag'} ]], + [/(<)([:\w]+)/, [htmlTokenTypes.DELIM_START, { token: 'tag', next: '@otherTag'} ]], [/(<\/)(\w+)/, [htmlTokenTypes.DELIM_START, { token: 'tag', next: '@otherTag' }]], - [/[^<]+/] // text + [/ { comment: [ [/-->/, 'comment', '@pop'], - [/[^-]+/, 'comment'], - [/./, 'comment'] + [/[^-]+/, 'comment.content'], + [/./, 'comment.content'] ], otherTag: [ @@ -130,6 +135,10 @@ export var language = { // After ', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('script') }, + { startIndex:7, type: '' }, + { startIndex:8, type: ATTRIB_NAME }, + { startIndex:12, type: DELIM_ASSIGN }, + { startIndex:13, type: ATTRIB_VALUE }, + { startIndex:30, type: DELIM_END }, + { startIndex:31, type: '' }, + { startIndex:41, type: DELIM_START }, + { startIndex:43, type: getTag('script') }, + { startIndex:49, type: DELIM_END } + ] + }], + + // Embedded Content #2 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:2, type: getTag('script') }, + { startIndex:8, type: DELIM_END } + ] + }], + + // Embedded Content #3 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:2, type: getTag('script') }, + { startIndex:8, type: DELIM_END } + ] + }], + + // Embedded Content #4 + [{ + line: '', + tokens: [ + { startIndex:0, type: '' }, + { startIndex:10, type: DELIM_START }, + { startIndex:12, type: getTag('script') }, + { startIndex:18, type: DELIM_END } + ] + }], + + // Embedded Content #5 + [{ + line: '', + tokens: [ + { startIndex:0, type: '' }, + { startIndex:2, type: DELIM_START }, + { startIndex:4, type: getTag('script') }, + { startIndex:10, type: DELIM_END } + ] + }], + + // Embedded Content #6 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('script') }, + { startIndex:7, type: DELIM_END }, + { startIndex:8, type: '' }, + { startIndex:9, type: DELIM_START }, + { startIndex:11, type: getTag('script') }, + { startIndex:17, type: DELIM_END }, + { startIndex:18, type: DELIM_START }, + { startIndex:19, type: getTag('script') }, + { startIndex:25, type: DELIM_END }, + { startIndex:26, type: '' }, + { startIndex:27, type: DELIM_START }, + { startIndex:29, type: getTag('script') }, + { startIndex:35, type: DELIM_END } + ] + }], + + // Embedded Content #7 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('script') }, + { startIndex:7, type: '' }, + { startIndex:8, type: ATTRIB_NAME }, + { startIndex:12, type: DELIM_ASSIGN }, + { startIndex:13, type: ATTRIB_VALUE }, + { startIndex:30, type: DELIM_END }, + { startIndex:31, type: DELIM_START }, + { startIndex:33, type: getTag('script') }, + { startIndex:39, type: DELIM_END } + ] + }], + + // Embedded Content #8 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('script') }, + { startIndex:7, type: DELIM_END }, + { startIndex:8, type: '' }, + { startIndex:18, type: DELIM_START }, + { startIndex:20, type: getTag('script') }, + { startIndex:26, type: DELIM_END } + ] + }], + + // Embedded Content #9 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('script') }, + { startIndex:7, type: '' }, + { startIndex:8, type: ATTRIB_NAME }, + { startIndex:12, type: DELIM_ASSIGN }, + { startIndex:13, type: ATTRIB_VALUE }, + { startIndex:30, type: '' }, + { startIndex:31, type: ATTRIB_NAME }, + { startIndex:34, type: DELIM_ASSIGN }, + { startIndex:35, type: ATTRIB_VALUE }, + { startIndex:44, type: DELIM_END }, + { startIndex:45, type: DELIM_START }, + { startIndex:47, type: getTag('script') }, + { startIndex:53, type: DELIM_END } + ] + }], + + // Tag with Attribute + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: ATTRIB_VALUE }, + { startIndex:14, type: DELIM_END } + ] + }], + + // Tag with Empty Attribute Value + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: ATTRIB_VALUE }, + { startIndex:14, type: DELIM_END } + ] + }], + + // Tag with empty attributes + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: ATTRIB_VALUE }, + { startIndex:11, type: DELIM_END } + ] + }], + + // Tag with Attributes + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: ATTRIB_VALUE }, + { startIndex:14, type: '' }, + { startIndex:15, type: ATTRIB_NAME }, + { startIndex:18, type: DELIM_ASSIGN }, + { startIndex:19, type: ATTRIB_VALUE }, + { startIndex:24, type: DELIM_END } + ] + }], + + // Tag with Attributes, no quotes + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: ATTRIB_NAME }, // slightly incorrect + { startIndex:12, type: '' }, + { startIndex:13, type: ATTRIB_NAME }, + { startIndex:16, type: DELIM_ASSIGN }, + { startIndex:17, type: ATTRIB_NAME }, // slightly incorrect + { startIndex:24, type: DELIM_END } + ] + }], + + // Tag with Attribute And Whitespace + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_ASSIGN }, + { startIndex:9, type: '' }, + { startIndex:11, type: ATTRIB_VALUE }, + { startIndex:16, type: DELIM_END } + ] + }], + + // Tag with Attribute And Whitespace #2 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: '' }, + { startIndex:9, type: DELIM_ASSIGN }, + { startIndex:10, type: '' }, + { startIndex:11, type: ATTRIB_VALUE }, + { startIndex:16, type: DELIM_END } + ] + }], + + // Tag with Name-Only-Attribute #1 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: DELIM_END } + ] + }], + + // Tag with Name-Only-Attribute #2 + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: '' }, + { startIndex:9, type: ATTRIB_NAME }, + { startIndex:12, type: DELIM_END } + ] + }], + + // Tag with Interesting Attribute Name + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:5, type: ATTRIB_NAME }, + { startIndex:8, type: '' }, + { startIndex:11, type: DELIM_ASSIGN }, + { startIndex:12, type: ATTRIB_VALUE }, + { startIndex:17, type: DELIM_END } + ] + }], + + // Tag with Angular Attribute Name + [{ + line: '', + tokens: [ + { startIndex:0, type: DELIM_START }, + { startIndex:1, type: getTag('abc') }, + { startIndex:4, type: '' }, + { startIndex:6, type: ATTRIB_NAME }, + { startIndex:13, type: '' }, + { startIndex:15, type: ATTRIB_NAME }, + { startIndex:20, type: '' }, + { startIndex:21, type: DELIM_ASSIGN }, + { startIndex:22, type: ATTRIB_VALUE }, + { startIndex:27, type: '' }, + { startIndex:29, type: ATTRIB_NAME }, + { startIndex:34, type: '' }, + { startIndex:35, type: DELIM_ASSIGN }, + { startIndex:36, type: ATTRIB_VALUE }, + { startIndex:50, type: '' }, + { startIndex:52, type: ATTRIB_NAME }, + { startIndex:56, type: DELIM_ASSIGN }, + { startIndex:57, type: ATTRIB_VALUE }, + { startIndex:72, type: DELIM_END } + ] + }], + + // Tag with Invalid Attribute Value + [{ + line: '', + tokens: [ + { startIndex:0, type: DOCTYPE }, + { startIndex:11, type: DELIM_DOCTYPE } + ] + }] +]); diff --git a/test/php.test.ts b/test/php.test.ts index 808ba134..34671eaa 100644 --- a/test/php.test.ts +++ b/test/php.test.ts @@ -13,8 +13,8 @@ testTokenization(['php', 'css'], [ // We're testing the fact that tokenize does not throw [ { line: ' { test('', (done) => { _monaco.Promise.join(languages.map(l => loadLanguage(l))).then(() => { - runTests(mainLanguage, tests); - done(); + // clean stack + setTimeout(() => { + runTests(mainLanguage, tests); + done(); + }); }).then(null, done); }); }); diff --git a/tsconfig.json b/tsconfig.json index d7ad5943..351910e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -46,6 +46,7 @@ "test/dockerfile.test.ts", "test/fsharp.test.ts", "test/go.test.ts", + "test/html.test.ts", "test/jade.test.ts", "test/java.test.ts", "test/lua.test.ts",