|
|
|
@ -5,8 +5,6 @@
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
import { conf as htmlConf, language as htmlLanguage } from '../html/html';
|
|
|
|
|
|
|
|
|
|
import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
|
|
|
|
|
import ILanguage = monaco.languages.IMonarchLanguage;
|
|
|
|
|
|
|
|
|
@ -23,7 +21,10 @@ export const conf: IRichLanguageConfiguration = {
|
|
|
|
|
['{{', '}}'],
|
|
|
|
|
['(', ')'],
|
|
|
|
|
['[', ']'],
|
|
|
|
|
...htmlConf.brackets,
|
|
|
|
|
|
|
|
|
|
// HTML
|
|
|
|
|
['<!--', '-->'],
|
|
|
|
|
['<', '>'],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
autoClosingPairs: [
|
|
|
|
@ -39,7 +40,9 @@ export const conf: IRichLanguageConfiguration = {
|
|
|
|
|
surroundingPairs: [
|
|
|
|
|
{ open: '"', close: '"' },
|
|
|
|
|
{ open: '\'', close: '\'' },
|
|
|
|
|
...htmlConf.surroundingPairs,
|
|
|
|
|
|
|
|
|
|
// HTML
|
|
|
|
|
{ open: '<', close: '>' },
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -61,13 +64,25 @@ export const language = <ILanguage>{
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
tokenizer: {
|
|
|
|
|
...htmlLanguage.tokenizer,
|
|
|
|
|
|
|
|
|
|
root: [
|
|
|
|
|
// whitespace
|
|
|
|
|
[/\s+/],
|
|
|
|
|
|
|
|
|
|
// Twig Tag Delimiters
|
|
|
|
|
[/{#/, 'comment.twig', '@commentState'],
|
|
|
|
|
[/{%[-~]?/, 'delimiter.twig', '@blockState'],
|
|
|
|
|
[/{{[-~]?/, 'delimiter.twig', '@variableState'],
|
|
|
|
|
...htmlLanguage.tokenizer.root,
|
|
|
|
|
|
|
|
|
|
// HTML
|
|
|
|
|
[/<!DOCTYPE/, 'metatag.html', '@doctype'],
|
|
|
|
|
[/<!--/, 'comment.html', '@comment'],
|
|
|
|
|
[/(<)((?:[\w\-]+:)?[\w\-]+)(\s*)(\/>)/, ['delimiter.html', 'tag.html', '', 'delimiter.html']],
|
|
|
|
|
[/(<)(script)/, ['delimiter.html', { token: 'tag.html', next: '@script' }]],
|
|
|
|
|
[/(<)(style)/, ['delimiter.html', { token: 'tag.html', next: '@style' }]],
|
|
|
|
|
[/(<)((?:[\w\-]+:)?[\w\-]+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
|
|
|
|
|
[/(<\/)((?:[\w\-]+:)?[\w\-]+)/, ['delimiter.html', { token: 'tag.html', next: '@otherTag' }]],
|
|
|
|
|
[/</, 'delimiter.html'],
|
|
|
|
|
[/[^<]+/], // text
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -175,5 +190,125 @@ export const language = <ILanguage>{
|
|
|
|
|
// assignment
|
|
|
|
|
[/=/, 'operators.twig'],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* HTML
|
|
|
|
|
*/
|
|
|
|
|
doctype: [
|
|
|
|
|
[/[^>]+/, 'metatag.content.html'],
|
|
|
|
|
[/>/, 'metatag.html', '@pop'],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
comment: [
|
|
|
|
|
[/-->/, 'comment.html', '@pop'],
|
|
|
|
|
[/[^-]+/, 'comment.content.html'],
|
|
|
|
|
[/./, 'comment.content.html']
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
otherTag: [
|
|
|
|
|
[/\/?>/, 'delimiter.html', '@pop'],
|
|
|
|
|
[/"([^"]*)"/, 'attribute.value.html'],
|
|
|
|
|
[/'([^']*)'/, 'attribute.value.html'],
|
|
|
|
|
[/[\w\-]+/, 'attribute.name.html'],
|
|
|
|
|
[/=/, 'delimiter.html'],
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// -- BEGIN <script> tags handling
|
|
|
|
|
|
|
|
|
|
// After <script
|
|
|
|
|
script: [
|
|
|
|
|
[/type/, 'attribute.name.html', '@scriptAfterType'],
|
|
|
|
|
[/"([^"]*)"/, 'attribute.value.html'],
|
|
|
|
|
[/'([^']*)'/, 'attribute.value.html'],
|
|
|
|
|
[/[\w\-]+/, 'attribute.name.html'],
|
|
|
|
|
[/=/, 'delimiter.html'],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }],
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/(<\/)(script\s*)(>)/, ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <script ... type
|
|
|
|
|
scriptAfterType: [
|
|
|
|
|
[/=/, 'delimiter.html', '@scriptAfterTypeEquals'],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }], // cover invalid e.g. <script type>
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <script ... type =
|
|
|
|
|
scriptAfterTypeEquals: [
|
|
|
|
|
[/"([^"]*)"/, { token: 'attribute.value.html', switchTo: '@scriptWithCustomType.$1' }],
|
|
|
|
|
[/'([^']*)'/, { token: 'attribute.value.html', switchTo: '@scriptWithCustomType.$1' }],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@scriptEmbedded', nextEmbedded: 'text/javascript' }], // cover invalid e.g. <script type=>
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <script ... type = $S2
|
|
|
|
|
scriptWithCustomType: [
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@scriptEmbedded.$S2', nextEmbedded: '$S2' }],
|
|
|
|
|
[/"([^"]*)"/, 'attribute.value.html'],
|
|
|
|
|
[/'([^']*)'/, 'attribute.value.html'],
|
|
|
|
|
[/[\w\-]+/, 'attribute.name.html'],
|
|
|
|
|
[/=/, 'delimiter.html'],
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/script\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
scriptEmbedded: [
|
|
|
|
|
[/<\/script/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
|
|
|
|
|
[/[^<]+/, '']
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// -- END <script> tags handling
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// -- BEGIN <style> tags handling
|
|
|
|
|
|
|
|
|
|
// After <style
|
|
|
|
|
style: [
|
|
|
|
|
[/type/, 'attribute.name.html', '@styleAfterType'],
|
|
|
|
|
[/"([^"]*)"/, 'attribute.value.html'],
|
|
|
|
|
[/'([^']*)'/, 'attribute.value.html'],
|
|
|
|
|
[/[\w\-]+/, 'attribute.name.html'],
|
|
|
|
|
[/=/, 'delimiter.html'],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@styleEmbedded', nextEmbedded: 'text/css' }],
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/(<\/)(style\s*)(>)/, ['delimiter.html', 'tag.html', { token: 'delimiter.html', next: '@pop' }]]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <style ... type
|
|
|
|
|
styleAfterType: [
|
|
|
|
|
[/=/, 'delimiter.html', '@styleAfterTypeEquals'],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@styleEmbedded', nextEmbedded: 'text/css' }], // cover invalid e.g. <style type>
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <style ... type =
|
|
|
|
|
styleAfterTypeEquals: [
|
|
|
|
|
[/"([^"]*)"/, { token: 'attribute.value.html', switchTo: '@styleWithCustomType.$1' }],
|
|
|
|
|
[/'([^']*)'/, { token: 'attribute.value.html', switchTo: '@styleWithCustomType.$1' }],
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@styleEmbedded', nextEmbedded: 'text/css' }], // cover invalid e.g. <style type=>
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// After <style ... type = $S2
|
|
|
|
|
styleWithCustomType: [
|
|
|
|
|
[/>/, { token: 'delimiter.html', next: '@styleEmbedded.$S2', nextEmbedded: '$S2' }],
|
|
|
|
|
[/"([^"]*)"/, 'attribute.value.html'],
|
|
|
|
|
[/'([^']*)'/, 'attribute.value.html'],
|
|
|
|
|
[/[\w\-]+/, 'attribute.name.html'],
|
|
|
|
|
[/=/, 'delimiter.html'],
|
|
|
|
|
[/[ \t\r\n]+/], // whitespace
|
|
|
|
|
[/<\/style\s*>/, { token: '@rematch', next: '@pop' }]
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
styleEmbedded: [
|
|
|
|
|
[/<\/style/, { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
|
|
|
|
|
[/[^<]+/, '']
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|