diff --git a/packages/language-javascript/lib/main.js b/packages/language-javascript/lib/main.js index 015c289b65..6433360293 100644 --- a/packages/language-javascript/lib/main.js +++ b/packages/language-javascript/lib/main.js @@ -21,7 +21,7 @@ exports.activate = function () { content(callExpression) { const { lastChild } = callExpression; if (lastChild.type === 'template_string') { - return lastChild; + return stringFragmentsOfTemplateString(lastChild); } } }); @@ -29,8 +29,8 @@ exports.activate = function () { atom.grammars.addInjectionPoint('source.js', { type: 'assignment_expression', - language(callExpression) { - const { firstChild } = callExpression; + language(expression) { + const { firstChild } = expression; if (firstChild.type === 'member_expression') { if (firstChild.lastChild.text === 'innerHTML') { return 'html'; @@ -38,10 +38,10 @@ exports.activate = function () { } }, - content(callExpression) { - const { lastChild } = callExpression; + content(expression) { + const { lastChild } = expression; if (lastChild.type === 'template_string') { - return lastChild; + return stringFragmentsOfTemplateString(lastChild); } } }); @@ -95,3 +95,9 @@ function languageStringForTemplateTag(tag) { return tag; } } + +function stringFragmentsOfTemplateString(templateStringNode) { + return templateStringNode.children.filter( + c => c.type === 'string_fragment' + ); +} diff --git a/packages/language-typescript/grammars/common/highlights.scm b/packages/language-typescript/grammars/common/highlights.scm index 265165b26b..97a8614f41 100644 --- a/packages/language-typescript/grammars/common/highlights.scm +++ b/packages/language-typescript/grammars/common/highlights.scm @@ -110,7 +110,8 @@ ; The "bar" in `foo.bar = true` (assignment_expression left: (member_expression - property: (property_identifier) @variable.other.assignment.property._LANG_)) + property: (property_identifier) @variable.other.assignment.property._LANG_) + (#set! capture.final)) ; The "foo" in `foo += 1`. (augmented_assignment_expression diff --git a/packages/language-typescript/lib/main.js b/packages/language-typescript/lib/main.js index 339496549d..9ef84aa33b 100644 --- a/packages/language-typescript/lib/main.js +++ b/packages/language-typescript/lib/main.js @@ -30,7 +30,7 @@ exports.activate = function () { content(callExpression) { const { lastChild } = callExpression; if (lastChild.type === 'template_string') { - return lastChild; + return stringFragmentsOfTemplateString(lastChild); } } }); @@ -50,7 +50,7 @@ exports.activate = function () { content(callExpression) { const { lastChild } = callExpression; if (lastChild.type === 'template_string') { - return lastChild; + return stringFragmentsOfTemplateString(lastChild); } } }); @@ -92,3 +92,9 @@ function languageStringForTemplateTag(tag) { return tag; } } + +function stringFragmentsOfTemplateString(templateStringNode) { + return templateStringNode.children.filter( + c => c.type === 'string_fragment' + ); +} diff --git a/spec/wasm-tree-sitter-language-mode-spec.js b/spec/wasm-tree-sitter-language-mode-spec.js index c9205dbcfc..0fb41f2473 100644 --- a/spec/wasm-tree-sitter-language-mode-spec.js +++ b/spec/wasm-tree-sitter-language-mode-spec.js @@ -766,6 +766,7 @@ describe('WASMTreeSitterLanguageMode', () => { `); jsGrammar.addInjectionPoint(HTML_TEMPLATE_LITERAL_INJECTION_POINT); + jsGrammar.addInjectionPoint(HTML_INNERHTML_ASSIGNMENT_INJECTION_POINT); jsGrammar.addInjectionPoint(JSDOC_INJECTION_POINT); let tempHtmlConfig = { ...htmlConfig }; @@ -784,7 +785,7 @@ describe('WASMTreeSitterLanguageMode', () => { jasmine.useRealClock(); atom.grammars.addGrammar(jsGrammar); atom.grammars.addGrammar(htmlGrammar); - buffer.setText('node.innerHTML = html `\na ${b}\n`;'); + buffer.setText('node.x = html `\na ${b}\n`;'); const languageMode = new WASMTreeSitterLanguageMode({ grammar: jsGrammar, @@ -800,7 +801,7 @@ describe('WASMTreeSitterLanguageMode', () => { expectTokensToEqual(editor, [ [ { text: 'node.', scopes: [] }, - { text: 'innerHTML', scopes: ['property'] }, + { text: 'x', scopes: ['property'] }, { text: ' = ', scopes: [] }, { text: 'html', scopes: ['function'] }, { text: ' ', scopes: [] }, @@ -829,7 +830,7 @@ describe('WASMTreeSitterLanguageMode', () => { expectTokensToEqual(editor, [ [ { text: 'node.', scopes: [] }, - { text: 'innerHTML', scopes: ['property'] }, + { text: 'x', scopes: ['property'] }, { text: ' = ', scopes: [] }, { text: 'xml', scopes: ['function'] }, { text: ' ', scopes: [] }, @@ -893,7 +894,7 @@ describe('WASMTreeSitterLanguageMode', () => { jasmine.useRealClock(); atom.grammars.addGrammar(jsGrammar); - buffer.setText('node.innerHTML = html `\na ${b}\n`;'); + buffer.setText('node.innerHTML = `\na ${b}\n`;'); const languageMode = new WASMTreeSitterLanguageMode({ grammar: jsGrammar, buffer, @@ -908,8 +909,6 @@ describe('WASMTreeSitterLanguageMode', () => { { text: 'node.', scopes: [] }, { text: 'innerHTML', scopes: ['property'] }, { text: ' = ', scopes: [] }, - { text: 'html', scopes: ['function'] }, - { text: ' ', scopes: [] }, { text: '`', scopes: ['string'] } ], [ @@ -931,8 +930,6 @@ describe('WASMTreeSitterLanguageMode', () => { { text: 'node.', scopes: [] }, { text: 'innerHTML', scopes: ['property'] }, { text: ' = ', scopes: [] }, - { text: 'html', scopes: ['function'] }, - { text: ' ', scopes: [] }, { text: '`', scopes: ['string'] }, { text: '', scopes: ['string', 'html'] } ], @@ -1057,6 +1054,8 @@ describe('WASMTreeSitterLanguageMode', () => { '
' ); await languageMode.nextTransaction; + expect(buffer.getText()).toEqual(`text = html \`
\`;`); + await wait(100); expectTokensToEqual(editor, [ [ { text: 'text = ', scopes: [] }, @@ -4822,6 +4821,27 @@ function expectTokensToEqual(editor, expectedTokenLines) { editor.displayLayer.getScreenLines(0, Infinity); } +const HTML_INNERHTML_ASSIGNMENT_INJECTION_POINT = { + type: 'assignment_expression', + + language(callExpression) { + const { firstChild } = callExpression; + if (firstChild.type === 'member_expression') { + if (firstChild.lastChild.text === 'innerHTML') { + return 'html'; + } + } + }, + + content(callExpression) { + const { lastChild } = callExpression; + if (lastChild.type === 'template_string') { + return stringFragmentsOfTemplateString(lastChild); + } + }, +}; + + const HTML_TEMPLATE_LITERAL_INJECTION_POINT = { type: 'call_expression', language(node) { @@ -4833,7 +4853,7 @@ const HTML_TEMPLATE_LITERAL_INJECTION_POINT = { } }, content(node) { - return node?.lastChild; + return stringFragmentsOfTemplateString(node.lastChild); } }; @@ -4856,3 +4876,10 @@ const JSDOC_INJECTION_POINT = { return comment; } }; + + +function stringFragmentsOfTemplateString(templateStringNode) { + return templateStringNode.children.filter( + c => c.type === 'string_fragment' + ); +}