tree-sitter-html: lit-html - non quoted attribute values give ERROR

When working with lit-element webcomponents, i have a problem for binded attribute values. When the attribute value is just ${…} without quotes, the next line gives an error because the parser is not recognizing the attribute value as a quoted_attribute_value

Lit problem

As you can see, i get ERROR in the tree sitter playground. But when the binded value is enclosed with quotes the problem goes away:

lit solved

Note: for the framework, it is not necessary for attribute values to be enclosed with quotes, they work without them too.

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Comments: 19 (2 by maintainers)

Most upvoted comments

nice try, but that is still no javascript-in-javascript-string-interpolation parser

grammar.js.diff

--- a/grammar.js
+++ b/grammar.js
@@ -120,13 +120,16 @@ module.exports = grammar({
         choice(
           $.attribute_value,
           $.quoted_attribute_value,
+          $.js_expression_value,
         ),
       )),
     ),
 
-    attribute_name: _ => /[^<>"'/=\s]+/,
+    attribute_name: _ => /[^<>"/=\s]+/,
 
-    attribute_value: _ => /[^<>"'=\s]+/,
+    attribute_value: _ => /[^<>"=\s]+/,
+
+    js_expression_value : _ => /\${[^}]+}/,
 
     // An entity can be named, numeric (decimal), or numeric (hexacecimal). The
     // longest entity name is 29 characters long, and the HTML spec says that
@@ -134,7 +137,6 @@ module.exports = grammar({
     entity: _ => /&(#([xX][0-9a-fA-F]{1,6}|[0-9]{1,5})|[A-Za-z]{1,30});?/,
 
     quoted_attribute_value: $ => choice(
-      seq('\'', optional(alias(/[^']+/, $.attribute_value)), '\''),
       seq('"', optional(alias(/[^"]+/, $.attribute_value)), '"'),
     ),

js_expression_value : _ => /\${[^}]+}/,

this fails on

const tpl = html`
  <br id=${"}"}>
`;

and

const tpl = html`
  <br id=${await (async () => {
    // this can contain literally any javascript code, wrapped in an IIFE
    (await import("...")).asdf();
    return html`... including nested template strings`;
  })()}>
`;

nit: rename tree-sitter-html to tree-sitter-lit-html nit: use latest tree-sitter-cli to reduce diff noise in src/tree_sitter/parser.h nit: add online playground, example: ikatyang/tree-sitter-yaml

regardless of where i found this

it does matter where this html is stored. context matters

html templates from javascript

exactly this means the html parser will never see ${expr}

body=${function('value')}

at least this should not give a parse error but should parse ${function('value')} as attribute value

unquoted attribute values end on space or > so this would break on body=${function('va space lue')} which would parse ${function('va as attribute value space as boolean attribute and lue')} as parse error

is there a way to ignore single quotes

such hacks dont make sense either you want to support all javascript expressions in ${expr} or none

point me in the right direction

maybe look at JSX parsers maybe modify the template string parser of a javascript parser maybe find a way to merge javascript and html parser

see also