fix boolean attributes along with spreads (SSR mode)

pull/3775/head
Conduitry 6 years ago
parent 2ffdfcb197
commit ee467e46af

@ -1,5 +1,4 @@
import { is_void } from '../../../utils/names'; import { is_void } from '../../../utils/names';
import Attribute from '../../nodes/Attribute';
import Class from '../../nodes/Class'; import Class from '../../nodes/Class';
import { get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value'; import { get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value';
import { get_slot_scope } from './shared/get_slot_scope'; 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; 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 // TODO dry this out
const args = []; const args = [];
node.attributes.forEach(attribute => { node.attributes.forEach(attribute => {
if (attribute.is_spread) { if (attribute.is_spread) {
args.push(attribute.expression.node); args.push(attribute.expression.node);
} else { } 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); node_contents = get_attribute_value(attribute);
} else if (attribute.is_true) { } else if (attribute.is_true) {
args.push(x`{ ${attribute.name}: true }`); args.push(x`{ ${attribute.name}: true }`);
} else if ( } else if (
boolean_attributes.has(attribute.name) && boolean_attributes.has(name) &&
attribute.chunks.length === 1 && attribute.chunks.length === 1 &&
attribute.chunks[0].type !== 'Text' attribute.chunks[0].type !== 'Text'
) { ) {
// a boolean attribute with one non-Text chunk // a boolean attribute with one non-Text chunk
args.push(x`{ ${attribute.name}: ${(attribute.chunks[0] as Expression).node} }`); args.push(x`{ ${attribute.name}: ${(attribute.chunks[0] as Expression).node} || null }`);
} else if (attribute.name === 'class' && class_expression) { } else if (name === 'class' && class_expression) {
// Add class expression // Add class expression
args.push(x`{ ${attribute.name}: [${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim() }`); args.push(x`{ ${attribute.name}: [${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim() }`);
} else { } 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}])`); renderer.add_expression(x`@spread([${args}])`);
} else { } else {
node.attributes.forEach((attribute: Attribute) => { node.attributes.forEach(attribute => {
if (attribute.type !== 'Attribute') return; const name = attribute.name.toLowerCase();
if (name === 'value' && node.name.toLowerCase() === 'textarea') {
if (attribute.name === 'value' && node.name === 'textarea') {
node_contents = get_attribute_value(attribute); node_contents = get_attribute_value(attribute);
} else if (attribute.is_true) { } else if (attribute.is_true) {
renderer.add_string(` ${attribute.name}`); renderer.add_string(` ${attribute.name}`);
} else if ( } else if (
boolean_attributes.has(attribute.name) && boolean_attributes.has(name) &&
attribute.chunks.length === 1 && attribute.chunks.length === 1 &&
attribute.chunks[0].type !== 'Text' attribute.chunks[0].type !== 'Text'
) { ) {
// a boolean attribute with one non-Text chunk // a boolean attribute with one non-Text chunk
renderer.add_string(` `); renderer.add_string(` `);
renderer.add_expression(x`${(attribute.chunks[0] as Expression).node} ? "${attribute.name}" : ""`); 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; 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_expression(x`[${get_class_attribute_value(attribute)}, ${class_expression}].join(' ').trim()`);
renderer.add_string(`"`); renderer.add_string(`"`);
} else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') { } else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
const { name } = attribute;
const snippet = (attribute.chunks[0] as Expression).node; 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 { } else {
renderer.add_string(` ${attribute.name}="`); 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(`"`); renderer.add_string(`"`);
} }
}); });

@ -13,7 +13,7 @@ export function spread(args) {
if (invalid_attribute_name_character.test(name)) return; if (invalid_attribute_name_character.test(name)) return;
const value = attributes[name]; const value = attributes[name];
if (value === undefined) return; if (value == null) return;
if (value === true) str += " " + name; if (value === true) str += " " + name;
const escaped = String(value) const escaped = String(value)

Loading…
Cancel
Save