diff --git a/grammars/javascript.cson b/grammars/javascript.cson
index cd0e76b7..b37c984d 100644
--- a/grammars/javascript.cson
+++ b/grammars/javascript.cson
@@ -1009,6 +1009,56 @@
}
]
}
+ {
+ 'begin': '((\\w+)?(html|HTML|Html))\\s*(`)'
+ 'beginCaptures':
+ '1':
+ 'name': 'entity.name.function.js'
+ '4':
+ 'name': 'punctuation.definition.string.begin.js'
+ 'end': '`'
+ 'endCaptures':
+ '0':
+ 'name': 'punctuation.definition.string.end.js'
+ 'name': 'string.quoted.template.html.js'
+ 'patterns': [
+ {
+ 'match': '\\\\(x\\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)'
+ 'name': 'constant.character.escape.js'
+ }
+ {
+ 'include': '#interpolated_js'
+ }
+ {
+ 'include': 'text.html.basic'
+ }
+ ]
+ }
+ {
+ 'begin': '((\\w+)?(css|CSS|Css))\\s*(`)'
+ 'beginCaptures':
+ '1':
+ 'name': 'entity.name.function.js'
+ '4':
+ 'name': 'punctuation.definition.string.begin.js'
+ 'end': '`'
+ 'endCaptures':
+ '0':
+ 'name': 'punctuation.definition.string.end.js'
+ 'name': 'string.quoted.template.css.js'
+ 'patterns': [
+ {
+ 'match': '\\\\(x\\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)'
+ 'name': 'constant.character.escape.js'
+ }
+ {
+ 'include': '#interpolated_js'
+ }
+ {
+ 'include': 'source.css'
+ }
+ ]
+ }
{
'begin': '`'
'beginCaptures':
diff --git a/spec/javascript-spec.coffee b/spec/javascript-spec.coffee
index a22d2134..2e7d26e3 100644
--- a/spec/javascript-spec.coffee
+++ b/spec/javascript-spec.coffee
@@ -495,6 +495,80 @@ describe "Javascript grammar", ->
expect(tokens[13]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
expect(tokens[14]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.js', 'punctuation.definition.string.end.js']
+ describe "ES6 tagged HTML string templates", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('html`hey ${name}`')
+ expect(tokens[0]).toEqual value: 'html', scopes: [ 'source.js', 'string.quoted.template.html.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[2]).toEqual value: 'hey ', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[3]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[4]).toEqual value: 'name', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source']
+ expect(tokens[5]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[6]).toEqual value: '', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[7]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.end.js']
+
+ describe "ES6 tagged HTML string templates with expanded function name", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('escapeHTML`hey ${name}`')
+ expect(tokens[0]).toEqual value: 'escapeHTML', scopes: [ 'source.js', 'string.quoted.template.html.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[2]).toEqual value: 'hey ', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[3]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[4]).toEqual value: 'name', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source']
+ expect(tokens[5]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[6]).toEqual value: '', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[7]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.end.js']
+
+ describe "ES6 tagged HTML string templates with expanded function name and white space", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('escapeHTML `hey ${name}`')
+ expect(tokens[0]).toEqual value: 'escapeHTML', scopes: [ 'source.js', 'string.quoted.template.html.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: ' ', scopes: [ 'source.js', 'string.quoted.template.html.js' ]
+ expect(tokens[2]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[3]).toEqual value: 'hey ', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[4]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[5]).toEqual value: 'name', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source']
+ expect(tokens[6]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.html.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[7]).toEqual value: '', scopes: ['source.js', 'string.quoted.template.html.js']
+ expect(tokens[8]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.html.js', 'punctuation.definition.string.end.js']
+
+ describe "ES6 tagged CSS string templates", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('css`.highlight { border: ${borderSize}; }`')
+ expect(tokens[0]).toEqual value: 'css', scopes: [ 'source.js', 'string.quoted.template.css.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[2]).toEqual value: '.highlight { border: ', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[3]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[4]).toEqual value: 'borderSize', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source']
+ expect(tokens[5]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[6]).toEqual value: '; }', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[7]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.end.js']
+
+ describe "ES6 tagged CSS string templates with expanded function name", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('escapeCSS`.highlight { border: ${borderSize}; }`')
+ expect(tokens[0]).toEqual value: 'escapeCSS', scopes: [ 'source.js', 'string.quoted.template.css.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[2]).toEqual value: '.highlight { border: ', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[3]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[4]).toEqual value: 'borderSize', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source']
+ expect(tokens[5]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[6]).toEqual value: '; }', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[7]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.end.js']
+
+ describe "ES6 tagged CSS string templates with expanded function name and white space", ->
+ it "tokenizes them as strings", ->
+ {tokens} = grammar.tokenizeLine('escapeCSS `.highlight { border: ${borderSize}; }`')
+ expect(tokens[0]).toEqual value: 'escapeCSS', scopes: [ 'source.js', 'string.quoted.template.css.js', 'entity.name.function.js' ]
+ expect(tokens[1]).toEqual value: ' ', scopes: [ 'source.js', 'string.quoted.template.css.js' ]
+ expect(tokens[2]).toEqual value: '`', scopes: [ 'source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.begin.js' ]
+ expect(tokens[3]).toEqual value: '.highlight { border: ', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[4]).toEqual value: '${', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[5]).toEqual value: 'borderSize', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source']
+ expect(tokens[6]).toEqual value: '}', scopes: ['source.js', 'string.quoted.template.css.js', 'source.js.embedded.source', 'punctuation.section.embedded.js']
+ expect(tokens[7]).toEqual value: '; }', scopes: ['source.js', 'string.quoted.template.css.js']
+ expect(tokens[8]).toEqual value: '`', scopes: ['source.js', 'string.quoted.template.css.js', 'punctuation.definition.string.end.js']
+
describe "ES6 class", ->
it "tokenizes class", ->
{tokens} = grammar.tokenizeLine('class MyClass')