diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index 762152f4d5..1f7c0b7b9f 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -1,5 +1,4 @@ import { is_void } from '../../../utils/names'; -import Attribute from '../../nodes/Attribute'; import Class from '../../nodes/Class'; import { get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value'; import { get_slot_scope } from './shared/get_slot_scope'; @@ -80,62 +79,61 @@ export default function(node: Element, renderer: Renderer, options: RenderOption let add_class_attribute = class_expression ? true : false; - if (node.attributes.find(attr => attr.is_spread)) { + if (node.attributes.some(attr => attr.is_spread)) { // TODO dry this out const args = []; node.attributes.forEach(attribute => { if (attribute.is_spread) { args.push(attribute.expression.node); } else { - if (attribute.name === 'value' && node.name === 'textarea') { + const name = attribute.name.toLowerCase(); + if (name === 'value' && node.name.toLowerCase() === 'textarea') { node_contents = get_attribute_value(attribute); } else if (attribute.is_true) { args.push(x`{ ${attribute.name}: true }`); } else if ( - boolean_attributes.has(attribute.name) && + boolean_attributes.has(name) && attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text' ) { // a boolean attribute with one non-Text chunk - args.push(x`{ ${attribute.name}: ${(attribute.chunks[0] as Expression).node} }`); - } else if (attribute.name === 'class' && class_expression) { + args.push(x`{ ${attribute.name}: ${(attribute.chunks[0] as Expression).node} || null }`); + } else if (name === 'class' && class_expression) { // Add class expression args.push(x`{ ${attribute.name}: [${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim() }`); } else { - args.push(x`{ ${attribute.name}: ${attribute.name === 'class' ? get_class_attribute_value(attribute) : get_attribute_value(attribute)} }`); + args.push(x`{ ${attribute.name}: ${(name === 'class' ? get_class_attribute_value : get_attribute_value)(attribute)} }`); } } }); renderer.add_expression(x`@spread([${args}])`); } else { - node.attributes.forEach((attribute: Attribute) => { - if (attribute.type !== 'Attribute') return; - - if (attribute.name === 'value' && node.name === 'textarea') { + node.attributes.forEach(attribute => { + const name = attribute.name.toLowerCase(); + if (name === 'value' && node.name.toLowerCase() === 'textarea') { node_contents = get_attribute_value(attribute); } else if (attribute.is_true) { renderer.add_string(` ${attribute.name}`); } else if ( - boolean_attributes.has(attribute.name) && + boolean_attributes.has(name) && attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text' ) { // a boolean attribute with one non-Text chunk renderer.add_string(` `); renderer.add_expression(x`${(attribute.chunks[0] as Expression).node} ? "${attribute.name}" : ""`); - } else if (attribute.name === 'class' && class_expression) { + } else if (name === 'class' && class_expression) { add_class_attribute = false; - renderer.add_string(` class="`); + renderer.add_string(` ${attribute.name}="`); renderer.add_expression(x`[${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim()`); renderer.add_string(`"`); } else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { - const { name } = attribute; const snippet = (attribute.chunks[0] as Expression).node; - renderer.add_expression(x`@add_attribute("${name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`); + renderer.add_expression(x`@add_attribute("${attribute.name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`); } else { renderer.add_string(` ${attribute.name}="`); - renderer.add_expression(attribute.name === 'class' ? get_class_attribute_value(attribute) : get_attribute_value(attribute)); + renderer.add_expression((name === 'class' ? get_class_attribute_value : get_attribute_value)(attribute)); renderer.add_string(`"`); } }); diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts index d8fbf15f0a..208a4637c7 100644 --- a/src/runtime/internal/ssr.ts +++ b/src/runtime/internal/ssr.ts @@ -13,7 +13,7 @@ export function spread(args) { if (invalid_attribute_name_character.test(name)) return; const value = attributes[name]; - if (value === undefined) return; + if (value == null) return; if (value === true) str += " " + name; const escaped = String(value)