From 7bcbe67939d0d5ecf4552ce964b3eef5355f9597 Mon Sep 17 00:00:00 2001 From: Jonnie Date: Sat, 10 Jul 2021 07:07:37 +0300 Subject: [PATCH] add ssr for group bindings (#4621) * add ssr for group bindings * remove unnecessary chunk length check * check if checkbox or radio Co-authored-by: tanhauhau --- .../compile/render_ssr/handlers/Element.ts | 11 ++++- .../handlers/shared/get_attribute_value.ts | 7 +++ .../attribute-prefer-expression/_config.js | 1 - .../binding-indirect-spread/_config.js | 10 +++- .../_config.js | 15 ++++++ .../binding-input-checkbox-group/_config.js | 15 ++++++ .../binding-input-group-each-1/_config.js | 48 +++++++++++++++++++ .../binding-input-group-each-2/_config.js | 13 +++++ .../binding-input-group-each-3/_config.js | 46 ++++++++++++++++++ .../binding-input-group-each-4/_config.js | 19 +++++++- .../binding-input-group-each-5/_config.js | 19 +++++++- .../binding-input-group-each-6/_config.js | 1 - .../binding-input-radio-group/_config.js | 15 ++++++ .../samples/bindings-group/_expected.html | 5 ++ .../samples/bindings-group/main.svelte | 12 +++++ 15 files changed, 230 insertions(+), 7 deletions(-) create mode 100644 test/server-side-rendering/samples/bindings-group/_expected.html create mode 100644 test/server-side-rendering/samples/bindings-group/main.svelte diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 03838039ad..5ef354a85a 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -1,5 +1,5 @@ import { is_void } from '../../../utils/names'; -import { get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value'; +import { get_attribute_expression, get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value'; import { boolean_attributes } from './shared/boolean_attributes'; import Renderer, { RenderOptions } from '../Renderer'; import Element from '../../nodes/Element'; @@ -110,7 +110,14 @@ export default function(node: Element, renderer: Renderer, options: RenderOption } if (name === 'group') { - // TODO server-render group bindings + const value_attribute = node.attributes.find(({ name }) => name === 'value'); + if (value_attribute) { + const value = get_attribute_expression(value_attribute); + const type = node.get_static_attribute_value('type'); + const bound = expression.node; + const condition = type === 'checkbox' ? x`~${bound}.indexOf(${value})`: x`${value} === ${bound}`; + renderer.add_expression(x`${condition} ? @add_attribute("checked", true, 1) : ""`); + } } else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) { node_contents = expression.node; diff --git a/src/compiler/compile/render_ssr/handlers/shared/get_attribute_value.ts b/src/compiler/compile/render_ssr/handlers/shared/get_attribute_value.ts index 5c89a7a008..8af58bcc24 100644 --- a/src/compiler/compile/render_ssr/handlers/shared/get_attribute_value.ts +++ b/src/compiler/compile/render_ssr/handlers/shared/get_attribute_value.ts @@ -26,3 +26,10 @@ export function get_attribute_value(attribute: Attribute): ESTreeExpression { }) .reduce((lhs, rhs) => x`${lhs} + ${rhs}`); } + +export function get_attribute_expression(attribute: Attribute): ESTreeExpression { + if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Expression') { + return (attribute.chunks[0] as Expression).node as ESTreeExpression; + } + return get_attribute_value(attribute); +} diff --git a/test/runtime/samples/attribute-prefer-expression/_config.js b/test/runtime/samples/attribute-prefer-expression/_config.js index 2388ff35df..22bed8a6bc 100644 --- a/test/runtime/samples/attribute-prefer-expression/_config.js +++ b/test/runtime/samples/attribute-prefer-expression/_config.js @@ -1,5 +1,4 @@ export default { - skip_if_ssr: true, props: { foo: false diff --git a/test/runtime/samples/binding-indirect-spread/_config.js b/test/runtime/samples/binding-indirect-spread/_config.js index 1f24fcdbcb..b0701bdc7c 100644 --- a/test/runtime/samples/binding-indirect-spread/_config.js +++ b/test/runtime/samples/binding-indirect-spread/_config.js @@ -1,5 +1,13 @@ export default { - skip_if_ssr: true, + ssrHtml: ` + + + + + + + + `, async test({ assert, component, target, window }) { const event = new window.MouseEvent('click'); diff --git a/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js b/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js index ab89bc8daa..0948797865 100644 --- a/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js +++ b/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js @@ -25,6 +25,21 @@ export default {

Beta

`, + ssrHtml: ` + + + + + + +

Beta

`, + async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/runtime/samples/binding-input-checkbox-group/_config.js b/test/runtime/samples/binding-input-checkbox-group/_config.js index ab89bc8daa..0948797865 100644 --- a/test/runtime/samples/binding-input-checkbox-group/_config.js +++ b/test/runtime/samples/binding-input-checkbox-group/_config.js @@ -25,6 +25,21 @@ export default {

Beta

`, + ssrHtml: ` + + + + + + +

Beta

`, + async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/runtime/samples/binding-input-group-each-1/_config.js b/test/runtime/samples/binding-input-group-each-1/_config.js index 92010296dc..9bdf784f73 100644 --- a/test/runtime/samples/binding-input-group-each-1/_config.js +++ b/test/runtime/samples/binding-input-group-each-1/_config.js @@ -64,6 +64,54 @@ export default { `, + ssrHtml: ` +
+ + + + + + +

Beta

+
+
+ + + + + + +

+
+
+ + + + + + +

Gamma

+
+ `, + async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/runtime/samples/binding-input-group-each-2/_config.js b/test/runtime/samples/binding-input-group-each-2/_config.js index 78d692d979..880b183f88 100644 --- a/test/runtime/samples/binding-input-group-each-2/_config.js +++ b/test/runtime/samples/binding-input-group-each-2/_config.js @@ -12,6 +12,19 @@ export default {

1, 2, 3

`, + ssrHtml: ` + + + + +

1, 2, 3

`, + async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, true); diff --git a/test/runtime/samples/binding-input-group-each-3/_config.js b/test/runtime/samples/binding-input-group-each-3/_config.js index 92010296dc..f4018295d7 100644 --- a/test/runtime/samples/binding-input-group-each-3/_config.js +++ b/test/runtime/samples/binding-input-group-each-3/_config.js @@ -63,7 +63,53 @@ export default {

Gamma

`, + ssrHtml: ` +
+ + + + + + +

Beta

+
+
+ + + + + +

+
+
+ + + + + + +

Gamma

+
+ `, async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/runtime/samples/binding-input-group-each-4/_config.js b/test/runtime/samples/binding-input-group-each-4/_config.js index f1168858b0..da5edf18bc 100644 --- a/test/runtime/samples/binding-input-group-each-4/_config.js +++ b/test/runtime/samples/binding-input-group-each-4/_config.js @@ -17,7 +17,24 @@ export default {

3

`, - + ssrHtml: ` + + + +

1

+ + + +

2

+ + + +

+ + + +

3

+ `, async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, true); diff --git a/test/runtime/samples/binding-input-group-each-5/_config.js b/test/runtime/samples/binding-input-group-each-5/_config.js index 579225c627..cdfe9308df 100644 --- a/test/runtime/samples/binding-input-group-each-5/_config.js +++ b/test/runtime/samples/binding-input-group-each-5/_config.js @@ -17,7 +17,24 @@ export default {

1

`, - + ssrHtml: ` + + + +

1

+ + + +

1, 2, 3

+ + + +

2

+ + + +

1

+ `, async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, true); diff --git a/test/runtime/samples/binding-input-group-each-6/_config.js b/test/runtime/samples/binding-input-group-each-6/_config.js index 9eb251bf5d..4d280ed7ac 100644 --- a/test/runtime/samples/binding-input-group-each-6/_config.js +++ b/test/runtime/samples/binding-input-group-each-6/_config.js @@ -13,7 +13,6 @@ export default {

`, - async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/runtime/samples/binding-input-radio-group/_config.js b/test/runtime/samples/binding-input-radio-group/_config.js index e289d48597..9684f60fa6 100644 --- a/test/runtime/samples/binding-input-radio-group/_config.js +++ b/test/runtime/samples/binding-input-radio-group/_config.js @@ -25,6 +25,21 @@ export default {

Beta

`, + ssrHtml: ` + + + + + + +

Beta

`, + async test({ assert, component, target, window }) { const inputs = target.querySelectorAll('input'); assert.equal(inputs[0].checked, false); diff --git a/test/server-side-rendering/samples/bindings-group/_expected.html b/test/server-side-rendering/samples/bindings-group/_expected.html new file mode 100644 index 0000000000..06d4242b07 --- /dev/null +++ b/test/server-side-rendering/samples/bindings-group/_expected.html @@ -0,0 +1,5 @@ +
Cheese
+ + + + diff --git a/test/server-side-rendering/samples/bindings-group/main.svelte b/test/server-side-rendering/samples/bindings-group/main.svelte new file mode 100644 index 0000000000..a88d3fb200 --- /dev/null +++ b/test/server-side-rendering/samples/bindings-group/main.svelte @@ -0,0 +1,12 @@ + + +
{fillings.toString()}
+ + + + + +