Repository: sveltejs/language-tools
Pull request #1367 (2022-02-03 14:56:20)

(fix) handle multiline attributes
#1352


Patch:
diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Attribute.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Attribute.ts
index 9e3d7950..cd2ed92d 100644
--- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Attribute.ts
+++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Attribute.ts
@@ -165,13 +165,23 @@ export function handleAttribute(
                 parent.type === 'Element' &&
                 numberOnlyAttributes.has(attr.name.toLowerCase()) &&
                 !isNaN(attrVal.data);
-            const quote = ['"', "'"].includes(str.original[attrVal.start - 1])
+            const includesTemplateLiteralQuote = attrVal.data.includes('`');
+            const quote = !includesTemplateLiteralQuote
+                ? '`'
+                : ['"', "'"].includes(str.original[attrVal.start - 1])
                 ? str.original[attrVal.start - 1]
                 : '"';
 
             if (!needsNumberConversion) {
                 attributeValue.push(quote);
             }
+            if (includesTemplateLiteralQuote && attrVal.data.split('\n').length > 1) {
+                // Multiline attribute value text which can't be wrapped in a template literal
+                // -> ensure it's still a valid transformation by transforming the actual line break
+                str.overwrite(attrVal.start, attrVal.end, attrVal.data.split('\n').join('\\n'), {
+                    contentOnly: true
+                });
+            }
             attributeValue.push([attrVal.start, attrVal.end]);
             if (!needsNumberConversion) {
                 attributeValue.push(quote);


Test patch:
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-data/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-data/expectedv2.js
index 4586f377..ffd77163 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-data/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-data/expectedv2.js
@@ -1,1 +1,1 @@
- { svelteHTML.createElement("div", {     ...__sveltets_2_empty({"data-foo":true}),...__sveltets_2_empty({"data-bare":true}),...__sveltets_2_empty({"data-bar":"to"}),});}
\ No newline at end of file
+ { svelteHTML.createElement("div", {     ...__sveltets_2_empty({"data-foo":true}),...__sveltets_2_empty({"data-bare":true}),...__sveltets_2_empty({"data-bar":`to`}),});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-foreign-ns/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-foreign-ns/expectedv2.js
index 4c723071..b80d44af 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-foreign-ns/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-foreign-ns/expectedv2.js
@@ -1,2 +1,2 @@
-  { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {   "attrName":"text","attrCase":"text",}});}
-  { svelteHTML.createElement("someelement", {  "attrName":"text","attrCase":true,});}
\ No newline at end of file
+  { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {   "attrName":`text`,"attrCase":`text`,}});}
+  { svelteHTML.createElement("someelement", {  "attrName":`text`,"attrCase":true,});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expectedv2.js
index b7a3d288..e227d11c 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expectedv2.js
@@ -1,2 +1,2 @@
- { const $$_Hello0C = __sveltets_2_ensureComponent(Hello); new $$_Hello0C({ target: __sveltets_2_any(), props: { "|-wtf":"foo",}}); Hello}
- { svelteHTML.createElement("div", { "--custom-prop":"foo",}); }
\ No newline at end of file
+ { const $$_Hello0C = __sveltets_2_ensureComponent(Hello); new $$_Hello0C({ target: __sveltets_2_any(), props: { "|-wtf":`foo`,}}); Hello}
+ { svelteHTML.createElement("div", { "--custom-prop":`foo`,}); }
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expected.jsx
new file mode 100644
index 00000000..d81ec5a9
--- /dev/null
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expected.jsx
@@ -0,0 +1,15 @@
+<><Comp multilineattr="hello
+world" />
+<Comp multilineattr="he`llo
+world" />
+<Comp multilineattr={`
+color: ${color}
+display: block`} />
+
+<div multilineattr="hello
+world" />
+<div multilineattr="he`llo
+world" />
+<div multilineattr={`
+color: ${color}
+display: block`} /></>
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expectedv2.js
new file mode 100644
index 00000000..7f1b80cf
--- /dev/null
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/expectedv2.js
@@ -0,0 +1,13 @@
+ { const $$_Comp0C = __sveltets_2_ensureComponent(Comp); new $$_Comp0C({ target: __sveltets_2_any(), props: {  "multilineattr":`hello
+world`,}});}
+ { const $$_Comp0C = __sveltets_2_ensureComponent(Comp); new $$_Comp0C({ target: __sveltets_2_any(), props: {  "multilineattr":"he`llo\nworld",}});}
+ { const $$_Comp0C = __sveltets_2_ensureComponent(Comp); new $$_Comp0C({ target: __sveltets_2_any(), props: {  "multilineattr":`
+color: ${color}
+display: block`,}});}
+
+ { svelteHTML.createElement("div", {  "multilineattr":`hello
+world`,});}
+ { svelteHTML.createElement("div", {  "multilineattr":"he`llo\nworld",});}
+ { svelteHTML.createElement("div", {  "multilineattr":`
+color: ${color}
+display: block`,});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/input.svelte
new file mode 100644
index 00000000..66ca84ff
--- /dev/null
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-multiline/input.svelte
@@ -0,0 +1,15 @@
+<Comp multilineattr="hello
+world" />
+<Comp multilineattr="he`llo
+world" />
+<Comp multilineattr="
+color: {color}
+display: block" />
+
+<div multilineattr="hello
+world" />
+<div multilineattr="he`llo
+world" />
+<div multilineattr="
+color: {color}
+display: block" />
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-number/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-number/expectedv2.js
index 1df385a5..45289a4e 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-number/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-number/expectedv2.js
@@ -1,2 +1,2 @@
- { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {  "tabindex":"1",}});}
- { svelteHTML.createElement("div", {         "tabindex":1,"maxlength":1,"minlength":1,"span":1,"role":"none",}); }
\ No newline at end of file
+ { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {  "tabindex":`1`,}});}
+ { svelteHTML.createElement("div", {         "tabindex":1,"maxlength":1,"minlength":1,"span":1,"role":`none`,}); }
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-text/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-text/expectedv2.js
index 540aca91..a4833164 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-text/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-text/expectedv2.js
@@ -1,1 +1,1 @@
-  { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {   "attr":"text","attrtwo":"text",}});}
\ No newline at end of file
+  { const $$_SomeComponent0C = __sveltets_2_ensureComponent(SomeComponent); new $$_SomeComponent0C({ target: __sveltets_2_any(), props: {   "attr":`text`,"attrtwo":`text`,}});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expectedv2.js
index 47ec1a14..5b866147 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expectedv2.js
@@ -1,2 +1,2 @@
- { svelteHTML.createElement("input", {  "type":"text",value,});}
- { svelteHTML.createElement("input", {  "type":"checkbox",checked,});}
\ No newline at end of file
+ { svelteHTML.createElement("input", {  "type":`text`,value,});}
+ { svelteHTML.createElement("input", {  "type":`checkbox`,checked,});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group-bare/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group-bare/expectedv2.js
index ad0bced8..41011fd4 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group-bare/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group-bare/expectedv2.js
@@ -1,2 +1,2 @@
-  { svelteHTML.createElement("input", {    "type":"radio","value":"Plain",});group;}
- { svelteHTML.createElement("input", {    "type":"radio","value":"Plain",});group;}
\ No newline at end of file
+  { svelteHTML.createElement("input", {    "type":`radio`,"value":`Plain`,});group;}
+ { svelteHTML.createElement("input", {    "type":`radio`,"value":`Plain`,});group;}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group/expectedv2.js
index 0c121e3f..3f052544 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-group/expectedv2.js
@@ -1,1 +1,1 @@
-  { svelteHTML.createElement("input", {    "type":"radio","value":"Plain",});tortilla;}
\ No newline at end of file
+  { svelteHTML.createElement("input", {    "type":`radio`,"value":`Plain`,});tortilla;}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-oneway/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-oneway/expectedv2.js
index 062d318a..24fef7a5 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-oneway/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-oneway/expectedv2.js
@@ -1,3 +1,3 @@
- { const $$_div0 = svelteHTML.createElement("div", {      "type":"text",});width= $$_div0.clientWidth;height= $$_div0.clientHeight;offsetWidth= $$_div0.offsetWidth;offsetHeight= $$_div0.offsetHeight;}
+ { const $$_div0 = svelteHTML.createElement("div", {      "type":`text`,});width= $$_div0.clientWidth;height= $$_div0.clientHeight;offsetWidth= $$_div0.offsetWidth;offsetHeight= $$_div0.offsetHeight;}
 
  { const $$_video0 = svelteHTML.createElement("video", {        "src":clip,});duration= $$_video0.duration;buffered= $$_video0.buffered;seekable= $$_video0.seekable;seeking= $$_video0.seeking;played= $$_video0.played;ended= $$_video0.ended; }
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this-component/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this-component/expectedv2.js
index 6fe1a8d6..368c2a44 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this-component/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this-component/expectedv2.js
@@ -1,1 +1,1 @@
-  { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "type":"radio","value":"Plain",}});element = $$_Component0;}
\ No newline at end of file
+  { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "type":`radio`,"value":`Plain`,}});element = $$_Component0;}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this/expectedv2.js
index 4bbd846d..68dee173 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-this/expectedv2.js
@@ -1,1 +1,1 @@
-  { const $$_input0 = svelteHTML.createElement("input", {    "type":"radio","value":"Plain",});element = $$_input0;}
\ No newline at end of file
+  { const $$_input0 = svelteHTML.createElement("input", {    "type":`radio`,"value":`Plain`,});element = $$_input0;}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expectedv2.js
index f8c1524e..4cd1d112 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expectedv2.js
@@ -1,3 +1,3 @@
-  { svelteHTML.createElement("input", {   "type":"text",value:test,});}
- { svelteHTML.createElement("input", {    "type":"text",value:test,});}
- { svelteHTML.createElement("input", {    "type":"text",value:test,});}
\ No newline at end of file
+  { svelteHTML.createElement("input", {   "type":`text`,value:test,});}
+ { svelteHTML.createElement("input", {    "type":`text`,value:test,});}
+ { svelteHTML.createElement("input", {    "type":`text`,value:test,});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expectedv2.js
index c5b3e2b2..eeb189f5 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expectedv2.js
@@ -1,4 +1,4 @@
- { const $$_Parent0C = __sveltets_2_ensureComponent(Parent); const $$_Parent0 = new $$_Parent0C({ target: __sveltets_2_any(), props: {                   "bare":true,shorthand,"text1":"val1","text2":"val2","text3":`a${a}b${b}`,"textEmpty":"","literal":true,"strLiteral":'foo',"complex":{a},"a-dashed-complex":{a},...__sveltets_2_cssProp({"--custom-cssprop":"foo"}),}});{const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,foo,} = $$_Parent0.$$slot_def.default;$$_$$;
+ { const $$_Parent0C = __sveltets_2_ensureComponent(Parent); const $$_Parent0 = new $$_Parent0C({ target: __sveltets_2_any(), props: {                   "bare":true,shorthand,"text1":`val1`,"text2":`val2`,"text3":`a${a}b${b}`,"textEmpty":``,"literal":true,"strLiteral":'foo',"complex":{a},"a-dashed-complex":{a},...__sveltets_2_cssProp({"--custom-cssprop":`foo`}),}});{const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,foo,} = $$_Parent0.$$slot_def.default;$$_$$;
      {const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,bar,} = $$_Parent0.$$slot_def["named"];$$_$$;{ const $$_Component1C = __sveltets_2_ensureComponent(Component); new $$_Component1C({ target: __sveltets_2_any(), props: {  }});
         foo; bar;
      }Component}
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expectedv2.js
index d609b1b6..ad4eea58 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expectedv2.js
@@ -1,1 +1,1 @@
-  { const $$_Component0C = __sveltets_2_ensureComponent(Component); new $$_Component0C({ target: __sveltets_2_any(), props: {           ...__sveltets_2_cssProp({"--custom-css-property1":'hi'}),...__sveltets_2_cssProp({"--custom-css-property2":"hi"}),"betweenprop":true,...__sveltets_2_cssProp({"--custom-css-property3":`hi${jo}hi`}),...__sveltets_2_cssProp({"--custom-css-property4":`hi${jo}hi`}),...__sveltets_2_cssProp({"--custom-css-property5":`hi${jo}hi`}),}});}
\ No newline at end of file
+  { const $$_Component0C = __sveltets_2_ensureComponent(Component); new $$_Component0C({ target: __sveltets_2_any(), props: {           ...__sveltets_2_cssProp({"--custom-css-property1":'hi'}),...__sveltets_2_cssProp({"--custom-css-property2":`hi`}),"betweenprop":true,...__sveltets_2_cssProp({"--custom-css-property3":`hi${jo}hi`}),...__sveltets_2_cssProp({"--custom-css-property4":`hi${jo}hi`}),...__sveltets_2_cssProp({"--custom-css-property5":`hi${jo}hi`}),}});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/doctype/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/doctype/expectedv2.js
index 7552067d..b6eb534c 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/doctype/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/doctype/expectedv2.js
@@ -1,5 +1,5 @@
 
- { svelteHTML.createElement("html", { "lang":"en",});
+ { svelteHTML.createElement("html", { "lang":`en`,});
  { svelteHTML.createElement("body", {});
      { svelteHTML.createElement("h1", {});  }
  }
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expectedv2.js
index fb1e8cd0..d435a8a7 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expectedv2.js
@@ -1,1 +1,1 @@
- { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {                     "bare":true,shorthand,"text1":"val1","text2":"val2","text3":`a${a}b${b}`,"textEmpty":"","literal":true,"strLiteral":'foo',"complex":{a},"a-dashed-complex":{a},...__sveltets_2_cssProp({"--custom-cssprop":"foo"}),}});$$_Component0.$on("click", e => e);}
\ No newline at end of file
+ { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {                     "bare":true,shorthand,"text1":`val1`,"text2":`val2`,"text3":`a${a}b${b}`,"textEmpty":``,"literal":true,"strLiteral":'foo',"complex":{a},"a-dashed-complex":{a},...__sveltets_2_cssProp({"--custom-cssprop":`foo`}),}});$$_Component0.$on("click", e => e);}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/quotes-inside-quotes/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/quotes-inside-quotes/expectedv2.js
index 5dfce594..1819265e 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/quotes-inside-quotes/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/quotes-inside-quotes/expectedv2.js
@@ -1,2 +1,2 @@
- { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "placeholder":"'",}});$$_Component0.$on("keydown", () => {});}
- { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "placeholder":'"',}});$$_Component0.$on("keydown", () => {});}
\ No newline at end of file
+ { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "placeholder":`'`,}});$$_Component0.$on("keydown", () => {});}
+ { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {    "placeholder":`"`,}});$$_Component0.$on("keydown", () => {});}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/svg-attributes/expectedv2.js b/packages/svelte2tsx/test/htmlx2jsx/samples/svg-attributes/expectedv2.js
index 32798578..f88ef1d2 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/svg-attributes/expectedv2.js
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/svg-attributes/expectedv2.js
@@ -1,1 +1,1 @@
- { svelteHTML.createElement("svg", {     "width":"12","height":"12","viewBox":"0 0 24 24",}); }
\ No newline at end of file
+ { svelteHTML.createElement("svg", {     "width":`12`,"height":`12`,"viewBox":`0 0 24 24`,}); }
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/attributes-foreign-ns/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/attributes-foreign-ns/expectedv2.ts
index 034c48d6..e77f672b 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/attributes-foreign-ns/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/attributes-foreign-ns/expectedv2.ts
@@ -1,7 +1,7 @@
 ///<reference types="svelte" />
 ;function render() {
-async () => { { svelteHTML.createElement("element", {   "someAttr":"hi","someOtherAttribute":"there",});  }
- { const $$_Component0C = __sveltets_2_ensureComponent(Component); new $$_Component0C({ target: __sveltets_2_any(), props: {    "someAttr":"5","otherAttr":6,}});}};
+async () => { { svelteHTML.createElement("element", {   "someAttr":`hi`,"someOtherAttribute":`there`,});  }
+ { const $$_Component0C = __sveltets_2_ensureComponent(Component); new $$_Component0C({ target: __sveltets_2_any(), props: {    "someAttr":`5`,"otherAttr":6,}});}};
 return { props: {}, slots: {}, getters: {}, events: {} }}
 
 export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) {
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/binding-group-store/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/binding-group-store/expectedv2.ts
index 8ed7910e..e107051d 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/binding-group-store/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/binding-group-store/expectedv2.ts
@@ -1,6 +1,6 @@
 ///<reference types="svelte" />
 ;function render() {
-async () => { { svelteHTML.createElement("input", {      "id":"dom-input","type":"radio","value":"dom",});(__sveltets_1_store_get(compile_options), $compile_options).generate;}};
+async () => { { svelteHTML.createElement("input", {      "id":`dom-input`,"type":`radio`,"value":`dom`,});(__sveltets_1_store_get(compile_options), $compile_options).generate;}};
 return { props: {}, slots: {}, getters: {}, events: {} }}
 
 export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) {
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/circle-drawer-example/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/circle-drawer-example/expectedv2.ts
index 88732f18..18e7444c 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/circle-drawer-example/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/circle-drawer-example/expectedv2.ts
@@ -64,7 +64,7 @@ async () => {
 
 
 
- { svelteHTML.createElement("div", { "class":"controls",});
+ { svelteHTML.createElement("div", { "class":`controls`,});
 	  { svelteHTML.createElement("button", {    "onclick":() => travel(-1),"disabled":i === 0,});  }
 	  { svelteHTML.createElement("button", {    "onclick":() => travel(+1),"disabled":i === undoStack.length -1,});  }
  }
@@ -79,9 +79,9 @@ async () => {
  }
 
 if(adjusting){
-	 { svelteHTML.createElement("div", { "class":"adjuster",});
+	 { svelteHTML.createElement("div", { "class":`adjuster`,});
 		 { svelteHTML.createElement("p", {});     selected.cx; selected.cy; }
-		 { svelteHTML.createElement("input", {     "type":"range","value":selected.r,"oninput":adjust,});}
+		 { svelteHTML.createElement("input", {     "type":`range`,"value":selected.r,"oninput":adjust,});}
 	 }
 }};
 return { props: {}, slots: {}, getters: {}, events: {} }}
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expectedv2.ts
index 100353a1..f47af72e 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expectedv2.ts
@@ -6,7 +6,7 @@
 /*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/;
 async () => {
  { svelteHTML.createElement("div", {});
-     { __sveltets_createSlot("default", {         "a":b,b,"c":"b","d":`a${b}`,"e":b,});  }
+     { __sveltets_createSlot("default", {         "a":b,b,"c":`b`,"d":`a${b}`,"e":b,});  }
  }};
 return { props: {}, slots: {'default': {a:b, b:b, c:"b", d:"__svelte_ts_string", e:b}}, getters: {}, events: {} }}
 
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expectedv2.ts
index 0368b7e8..65219e2d 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expectedv2.ts
@@ -2,7 +2,7 @@
 ;function render() {
 /*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/
 async () => { { __sveltets_createSlot("default", {}); { svelteHTML.createElement("div", {});  } }
- { __sveltets_createSlot("foo", {    bar,"baz":"boo",});
+ { __sveltets_createSlot("foo", {    bar,"baz":`boo`,});
      { svelteHTML.createElement("p", {});  }
  }};
 return { props: {}, slots: {'default': {}, 'foo': {bar:bar, baz:"boo"}}, getters: {}, events: {} }}
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expectedv2.ts
index 32d7eb6e..4636cac5 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expectedv2.ts
@@ -1,7 +1,7 @@
 ///<reference types="svelte" />
 ;function render() {
 /*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/
-async () => { { const $$_Parent0C = __sveltets_2_ensureComponent(Parent); const $$_Parent0 = new $$_Parent0C({ target: __sveltets_2_any(), props: {        "propA":true,propB,"propC":"val1","propD":"val2","propE":`a${a}b${b}`,}});{const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,foo,} = $$_Parent0.$$slot_def.default;$$_$$;
+async () => { { const $$_Parent0C = __sveltets_2_ensureComponent(Parent); const $$_Parent0 = new $$_Parent0C({ target: __sveltets_2_any(), props: {        "propA":true,propB,"propC":`val1`,"propD":`val2`,"propE":`a${a}b${b}`,}});{const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,foo,} = $$_Parent0.$$slot_def.default;$$_$$;
      { __sveltets_createSlot("default", {  foo,});}
  }Parent}};
 return { props: {}, slots: {'default': {foo:__sveltets_1_instanceOf(Parent).$$slot_def['default'].foo}}, getters: {}, events: {} }}
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-with-props/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-with-props/expectedv2.ts
index 88118db1..e8cc129f 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-with-props/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-with-props/expectedv2.ts
@@ -1,6 +1,6 @@
 ///<reference types="svelte" />
 ;function render() {
-async () => {  { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {        "propA":true,propB,"propC":"val1","propD":"val2","propE":`a${a}b${b}`,}});$$_Component0.$on("click", () => {});}};
+async () => {  { const $$_Component0C = __sveltets_2_ensureComponent(Component); const $$_Component0 = new $$_Component0C({ target: __sveltets_2_any(), props: {        "propA":true,propB,"propC":`val1`,"propD":`val2`,"propE":`a${a}b${b}`,}});$$_Component0.$on("click", () => {});}};
 return { props: {}, slots: {}, getters: {}, events: {'click':__sveltets_1_bubbleEventDef(__sveltets_1_instanceOf(Component).$$events_def, 'click')} }}
 
 export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) {
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/import-single-quote/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/import-single-quote/expectedv2.ts
index 9285455a..e8524ca9 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/import-single-quote/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/import-single-quote/expectedv2.ts
@@ -5,7 +5,7 @@ function render() {
 
      
 ;
-async () => {  { const $$_Test0C = __sveltets_2_ensureComponent(Test); new $$_Test0C({ target: __sveltets_2_any(), props: { "b":"6",}}); Test} 
+async () => {  { const $$_Test0C = __sveltets_2_ensureComponent(Test); new $$_Test0C({ target: __sveltets_2_any(), props: { "b":`6`,}}); Test} 
 };
 return { props: {}, slots: {}, getters: {}, events: {} }}
 
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/script-inside-head-after-toplevel-script/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/script-inside-head-after-toplevel-script/expectedv2.ts
index 5a183d32..a52d14b9 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/script-inside-head-after-toplevel-script/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/script-inside-head-after-toplevel-script/expectedv2.ts
@@ -10,7 +10,7 @@ async () => { { svelteHTML.createElement("div", {});
 
 
  { svelteHTML.createElement("sveltehead", {});
-   { svelteHTML.createElement("link", {    "rel":"stylesheet","href":"/lib/jodit.es2018.min.css",});}
+   { svelteHTML.createElement("link", {    "rel":`stylesheet`,"href":`/lib/jodit.es2018.min.css`,});}
   
  }};
 return { props: {}, slots: {}, getters: {}, events: {} }}
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/self-closing-component/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/self-closing-component/expectedv2.ts
index 8d350800..d3fecfad 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/self-closing-component/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/self-closing-component/expectedv2.ts
@@ -6,7 +6,7 @@ function render() {
 
 let a = 'b';
 ;
-async () => { { const $$_Test0C = __sveltets_2_ensureComponent(Test); new $$_Test0C({ target: __sveltets_2_any(), props: {  "b":"6",}});}
+async () => { { const $$_Test0C = __sveltets_2_ensureComponent(Test); new $$_Test0C({ target: __sveltets_2_any(), props: {  "b":`6`,}});}
 };
 return { props: {}, slots: {}, getters: {}, events: {} }}
 
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/style-after-selfclosing-iframe/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/style-after-selfclosing-iframe/expectedv2.ts
index 4473b5ce..93e85b4e 100644
--- a/packages/svelte2tsx/test/svelte2tsx/samples/style-after-selfclosing-iframe/expectedv2.ts
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/style-after-selfclosing-iframe/expectedv2.ts
@@ -1,6 +1,6 @@
 ///<reference types="svelte" />
 ;function render() {
-async () => { { svelteHTML.createElement("iframe", { "src":"",});}
+async () => { { svelteHTML.createElement("iframe", { "src":``,});}
 };
 return { props: {}, slots: {}, getters: {}, events: {} }}