diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 03838039ad10..5ef354a85abc 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 5c89a7a0087f..8af58bcc24e1 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 2388ff35df6a..22bed8a6bcac 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 1f24fcdbcb12..b0701bdc7c16 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 ab89bc8daa38..09487978651d 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 ab89bc8daa38..09487978651d 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 92010296dc8a..9bdf784f73ee 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
+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 92010296dc8a..f4018295d7b8 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
+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 579225c627c5..cdfe9308df92 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 9eb251bf5d06..4d280ed7ac65 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 e289d48597d6..9684f60fa65b 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 000000000000..06d4242b072c --- /dev/null +++ b/test/server-side-rendering/samples/bindings-group/_expected.html @@ -0,0 +1,5 @@ +