From 0c4cca79484b398f53fc07d412e77448a97481af Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Sun, 26 Jul 2020 03:15:22 +0800 Subject: [PATCH] consider template literal the same as text with expression --- .../wrappers/Element/StyleAttribute.ts | 37 ++++++++++++++++++- .../expected.js | 37 ++++++++++++++----- .../input.svelte | 3 +- .../inline-style-optimized-url/expected.js | 28 ++++++++++---- .../inline-style-optimized-url/input.svelte | 3 +- .../inline-style-optimized/expected.js | 28 ++++++++++---- .../inline-style-optimized/input.svelte | 3 +- 7 files changed, 112 insertions(+), 27 deletions(-) diff --git a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts index 06ead11a3c..76b4f69e22 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/StyleAttribute.ts @@ -7,6 +7,7 @@ import { string_literal } from '../../../utils/stringify'; import add_to_set from '../../../utils/add_to_set'; import Expression from '../../../nodes/shared/Expression'; import Text from '../../../nodes/Text'; +import { TemplateLiteral } from 'estree'; export interface StyleProp { key: string; @@ -19,7 +20,7 @@ export default class StyleAttributeWrapper extends AttributeWrapper { parent: ElementWrapper; render(block: Block) { - const style_props = optimize_style(this.node.chunks); + const style_props = optimize_style(template_literal_to_text(this.node.chunks, this)); if (!style_props) return super.render(block); style_props.forEach((prop: StyleProp) => { @@ -190,3 +191,37 @@ function get_style_value(chunks: Array) { function is_dynamic(value: Array) { return value.length > 1 || value[0].type !== 'Text'; } + +function template_literal_to_text( + value: Array, + wrapper: StyleAttributeWrapper +) { + if (value.length > 1) return value; + const expression = value[0]; + if (expression.type !== "Expression") return value; + if (expression.node.type !== "TemplateLiteral") return value; + const template = expression.node as TemplateLiteral; + + const chunks = []; + + for (let i = 0; i < template.expressions.length; i++) { + chunks.push({ + type: "Text", + data: template.quasis[i].value.raw, + }); + chunks.push( + new Expression( + wrapper.node.component, + wrapper.node, + wrapper.node.scope, + template.expressions[i] + ) + ); + } + chunks.push({ + type: "Text", + data: template.quasis[template.quasis.length - 1].value.raw, + }); + + return chunks; +} diff --git a/test/js/samples/inline-style-optimized-multiple/expected.js b/test/js/samples/inline-style-optimized-multiple/expected.js index 0a9d0a1e8e..d2cb87e1b1 100644 --- a/test/js/samples/inline-style-optimized-multiple/expected.js +++ b/test/js/samples/inline-style-optimized-multiple/expected.js @@ -7,34 +7,53 @@ import { insert, noop, safe_not_equal, - set_style + set_style, + space } from "svelte/internal"; function create_fragment(ctx) { - let div; + let div0; + let t; + let div1; return { c() { - div = element("div"); - set_style(div, "color", /*color*/ ctx[0]); - set_style(div, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); + div0 = element("div"); + t = space(); + div1 = element("div"); + set_style(div0, "color", /*color*/ ctx[0]); + set_style(div0, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); + set_style(div1, "color", /*color*/ ctx[0]); + set_style(div1, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); }, m(target, anchor) { - insert(target, div, anchor); + insert(target, div0, anchor); + insert(target, t, anchor); + insert(target, div1, anchor); }, p(ctx, [dirty]) { if (dirty & /*color*/ 1) { - set_style(div, "color", /*color*/ ctx[0]); + set_style(div0, "color", /*color*/ ctx[0]); } if (dirty & /*x, y*/ 6) { - set_style(div, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); + set_style(div0, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); + } + + if (dirty & /*color*/ 1) { + set_style(div1, "color", /*color*/ ctx[0]); + } + + if (dirty & /*x, y*/ 6) { + set_style(div1, "transform", "translate(" + /*x*/ ctx[1] + "px," + /*y*/ ctx[2] + "px)"); } }, i: noop, o: noop, d(detaching) { - if (detaching) detach(div); + if (detaching) detach(div0); + if (detaching) detach(t); + if (detaching) detach(div1); } }; } diff --git a/test/js/samples/inline-style-optimized-multiple/input.svelte b/test/js/samples/inline-style-optimized-multiple/input.svelte index d5e2beb609..17e2cc7c05 100644 --- a/test/js/samples/inline-style-optimized-multiple/input.svelte +++ b/test/js/samples/inline-style-optimized-multiple/input.svelte @@ -4,4 +4,5 @@ export let y; -
\ No newline at end of file +
+
\ No newline at end of file diff --git a/test/js/samples/inline-style-optimized-url/expected.js b/test/js/samples/inline-style-optimized-url/expected.js index 0debb03585..2d099690e4 100644 --- a/test/js/samples/inline-style-optimized-url/expected.js +++ b/test/js/samples/inline-style-optimized-url/expected.js @@ -7,29 +7,43 @@ import { insert, noop, safe_not_equal, - set_style + set_style, + space } from "svelte/internal"; function create_fragment(ctx) { - let div; + let div0; + let t; + let div1; return { c() { - div = element("div"); - set_style(div, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); + div0 = element("div"); + t = space(); + div1 = element("div"); + set_style(div0, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); + set_style(div1, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); }, m(target, anchor) { - insert(target, div, anchor); + insert(target, div0, anchor); + insert(target, t, anchor); + insert(target, div1, anchor); }, p(ctx, [dirty]) { if (dirty & /*data*/ 1) { - set_style(div, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); + set_style(div0, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); + } + + if (dirty & /*data*/ 1) { + set_style(div1, "background", "url(data:image/png;base64," + /*data*/ ctx[0] + ")"); } }, i: noop, o: noop, d(detaching) { - if (detaching) detach(div); + if (detaching) detach(div0); + if (detaching) detach(t); + if (detaching) detach(div1); } }; } diff --git a/test/js/samples/inline-style-optimized-url/input.svelte b/test/js/samples/inline-style-optimized-url/input.svelte index 2e660fe02d..b28dfa3ed1 100644 --- a/test/js/samples/inline-style-optimized-url/input.svelte +++ b/test/js/samples/inline-style-optimized-url/input.svelte @@ -2,4 +2,5 @@ export let data; -
\ No newline at end of file +
+
\ No newline at end of file diff --git a/test/js/samples/inline-style-optimized/expected.js b/test/js/samples/inline-style-optimized/expected.js index b7db0f1cf3..aa90c4c3b3 100644 --- a/test/js/samples/inline-style-optimized/expected.js +++ b/test/js/samples/inline-style-optimized/expected.js @@ -7,29 +7,43 @@ import { insert, noop, safe_not_equal, - set_style + set_style, + space } from "svelte/internal"; function create_fragment(ctx) { - let div; + let div0; + let t; + let div1; return { c() { - div = element("div"); - set_style(div, "color", /*color*/ ctx[0]); + div0 = element("div"); + t = space(); + div1 = element("div"); + set_style(div0, "color", /*color*/ ctx[0]); + set_style(div1, "color", /*color*/ ctx[0]); }, m(target, anchor) { - insert(target, div, anchor); + insert(target, div0, anchor); + insert(target, t, anchor); + insert(target, div1, anchor); }, p(ctx, [dirty]) { if (dirty & /*color*/ 1) { - set_style(div, "color", /*color*/ ctx[0]); + set_style(div0, "color", /*color*/ ctx[0]); + } + + if (dirty & /*color*/ 1) { + set_style(div1, "color", /*color*/ ctx[0]); } }, i: noop, o: noop, d(detaching) { - if (detaching) detach(div); + if (detaching) detach(div0); + if (detaching) detach(t); + if (detaching) detach(div1); } }; } diff --git a/test/js/samples/inline-style-optimized/input.svelte b/test/js/samples/inline-style-optimized/input.svelte index b47ca48093..87c160a9ff 100644 --- a/test/js/samples/inline-style-optimized/input.svelte +++ b/test/js/samples/inline-style-optimized/input.svelte @@ -2,4 +2,5 @@ export let color; -
\ No newline at end of file +
+
\ No newline at end of file