|
|
@ -1,12 +1,12 @@
|
|
|
|
import { is_void, quote_prop_if_necessary, quote_name_if_necessary } from '../../../utils/names';
|
|
|
|
import { is_void, quote_prop_if_necessary, quote_name_if_necessary } from '../../../utils/names';
|
|
|
|
import Attribute from '../../nodes/Attribute';
|
|
|
|
import Attribute from '../../nodes/Attribute';
|
|
|
|
import Class from '../../nodes/Class';
|
|
|
|
import Class from '../../nodes/Class';
|
|
|
|
import { snip } from '../../utils/snip';
|
|
|
|
|
|
|
|
import { stringify_attribute, stringify_class_attribute } from '../../utils/stringify_attribute';
|
|
|
|
import { stringify_attribute, stringify_class_attribute } from '../../utils/stringify_attribute';
|
|
|
|
import { get_slot_scope } from './shared/get_slot_scope';
|
|
|
|
import { get_slot_scope } from './shared/get_slot_scope';
|
|
|
|
import Renderer, { RenderOptions } from '../Renderer';
|
|
|
|
import Renderer, { RenderOptions } from '../Renderer';
|
|
|
|
import Element from '../../nodes/Element';
|
|
|
|
import Element from '../../nodes/Element';
|
|
|
|
import Text from '../../nodes/Text';
|
|
|
|
import Text from '../../nodes/Text';
|
|
|
|
|
|
|
|
import { x } from 'code-red';
|
|
|
|
|
|
|
|
|
|
|
|
// source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
|
|
|
|
// source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
|
|
|
|
const boolean_attributes = new Set([
|
|
|
|
const boolean_attributes = new Set([
|
|
|
@ -52,7 +52,7 @@ const boolean_attributes = new Set([
|
|
|
|
export default function(node: Element, renderer: Renderer, options: RenderOptions & {
|
|
|
|
export default function(node: Element, renderer: Renderer, options: RenderOptions & {
|
|
|
|
slot_scopes: Map<any, any>;
|
|
|
|
slot_scopes: Map<any, any>;
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
let opening_tag = `<${node.name}`;
|
|
|
|
renderer.add_string(`<${node.name}`);
|
|
|
|
|
|
|
|
|
|
|
|
// awkward special case
|
|
|
|
// awkward special case
|
|
|
|
let node_contents;
|
|
|
|
let node_contents;
|
|
|
@ -96,29 +96,29 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
|
|
|
|
const args = [];
|
|
|
|
const args = [];
|
|
|
|
node.attributes.forEach(attribute => {
|
|
|
|
node.attributes.forEach(attribute => {
|
|
|
|
if (attribute.is_spread) {
|
|
|
|
if (attribute.is_spread) {
|
|
|
|
args.push(snip(attribute.expression));
|
|
|
|
args.push(attribute.expression.node);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (attribute.name === 'value' && node.name === 'textarea') {
|
|
|
|
if (attribute.name === 'value' && node.name === 'textarea') {
|
|
|
|
node_contents = stringify_attribute(attribute, true);
|
|
|
|
node_contents = stringify_attribute(attribute, true);
|
|
|
|
} else if (attribute.is_true) {
|
|
|
|
} else if (attribute.is_true) {
|
|
|
|
args.push(`{ ${quote_name_if_necessary(attribute.name)}: true }`);
|
|
|
|
args.push(x`{ ${attribute.name}: true }`);
|
|
|
|
} else if (
|
|
|
|
} else if (
|
|
|
|
boolean_attributes.has(attribute.name) &&
|
|
|
|
boolean_attributes.has(attribute.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(`{ ${quote_name_if_necessary(attribute.name)}: ${snip(attribute.chunks[0])} }`);
|
|
|
|
args.push(x`{ ${attribute.name}: ${attribute.chunks[0].node} }`);
|
|
|
|
} else if (attribute.name === 'class' && class_expression) {
|
|
|
|
} else if (attribute.name === 'class' && class_expression) {
|
|
|
|
// Add class expression
|
|
|
|
// Add class expression
|
|
|
|
args.push(`{ ${quote_name_if_necessary(attribute.name)}: [\`${stringify_class_attribute(attribute)}\`, \`\${${class_expression}}\`].join(' ').trim() }`);
|
|
|
|
args.push(x`{ ${attribute.name}: [${stringify_class_attribute(attribute)}, ${class_expression}}].join(' ').trim() }`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
args.push(`{ ${quote_name_if_necessary(attribute.name)}: \`${attribute.name === 'class' ? stringify_class_attribute(attribute) : stringify_attribute(attribute, true)}\` }`);
|
|
|
|
args.push(x`{ ${attribute.name}: ${attribute.name === 'class' ? stringify_class_attribute(attribute) : stringify_attribute(attribute, true)} }`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
opening_tag += "${@spread([" + args.join(', ') + "])}";
|
|
|
|
renderer.add_expression(x`@spread([${args}])`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
node.attributes.forEach((attribute: Attribute) => {
|
|
|
|
node.attributes.forEach((attribute: Attribute) => {
|
|
|
|
if (attribute.type !== 'Attribute') return;
|
|
|
|
if (attribute.type !== 'Attribute') return;
|
|
|
@ -126,23 +126,32 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
|
|
|
|
if (attribute.name === 'value' && node.name === 'textarea') {
|
|
|
|
if (attribute.name === 'value' && node.name === 'textarea') {
|
|
|
|
node_contents = stringify_attribute(attribute, true);
|
|
|
|
node_contents = stringify_attribute(attribute, true);
|
|
|
|
} else if (attribute.is_true) {
|
|
|
|
} else if (attribute.is_true) {
|
|
|
|
opening_tag += ` ${attribute.name}`;
|
|
|
|
renderer.add_string(` ${attribute.name}`);
|
|
|
|
} else if (
|
|
|
|
} else if (
|
|
|
|
boolean_attributes.has(attribute.name) &&
|
|
|
|
boolean_attributes.has(attribute.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
|
|
|
|
opening_tag += '${' + snip(attribute.chunks[0]) + ' ? " ' + attribute.name + '" : "" }';
|
|
|
|
throw new Error('here');
|
|
|
|
|
|
|
|
renderer.add_expression(x`${attribute.chunks[0]} ? "${attribute.name}" : ""`);
|
|
|
|
} else if (attribute.name === 'class' && class_expression) {
|
|
|
|
} else if (attribute.name === 'class' && class_expression) {
|
|
|
|
add_class_attribute = false;
|
|
|
|
add_class_attribute = false;
|
|
|
|
opening_tag += ` class="\${[\`${stringify_class_attribute(attribute)}\`, ${class_expression}].join(' ').trim() }"`;
|
|
|
|
renderer.add_string(` class="`);
|
|
|
|
|
|
|
|
renderer.add_expression(x`[${stringify_class_attribute(attribute)}, ${class_expression}].join(' ').trim()`);
|
|
|
|
|
|
|
|
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 { name } = attribute;
|
|
|
|
const snippet = snip(attribute.chunks[0]);
|
|
|
|
const snippet = attribute.chunks[0].node;
|
|
|
|
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', ' + (boolean_attributes.has(name) ? 1 : 0) + ')}';
|
|
|
|
console.log(snippet);
|
|
|
|
|
|
|
|
renderer.add_expression(x`@add_attribute("${name}", ${snippet}, ${boolean_attributes.has(name) ? 1 : 0})`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
opening_tag += ` ${attribute.name}="${attribute.name === 'class' ? stringify_class_attribute(attribute) : stringify_attribute(attribute, true)}"`;
|
|
|
|
renderer.add_string(` ${attribute.name}="`);
|
|
|
|
|
|
|
|
attribute.chunks.forEach(chunk => {
|
|
|
|
|
|
|
|
if (chunk.type === 'Text') renderer.add_string(chunk.data);
|
|
|
|
|
|
|
|
else renderer.add_expression(x`@escape(${chunk.node})`);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
renderer.add_string(`"`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -157,38 +166,36 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
|
|
|
|
if (name === 'group') {
|
|
|
|
if (name === 'group') {
|
|
|
|
// TODO server-render group bindings
|
|
|
|
// TODO server-render group bindings
|
|
|
|
} else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) {
|
|
|
|
} else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) {
|
|
|
|
node_contents = snip(expression);
|
|
|
|
node_contents = expression.node;
|
|
|
|
value = name === 'textContent' ? '@escape($$value)' : '$$value';
|
|
|
|
value = name === 'textContent' ? x`@escape($$value)` : x`$$value`;
|
|
|
|
} else if (binding.name === 'value' && node.name === 'textarea') {
|
|
|
|
} else if (binding.name === 'value' && node.name === 'textarea') {
|
|
|
|
const snippet = snip(expression);
|
|
|
|
const snippet = expression.node;
|
|
|
|
node_contents = '${(' + snippet + ') || ""}';
|
|
|
|
node_contents = x`${snippet} || ""`;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
const snippet = snip(expression);
|
|
|
|
const snippet = expression.node;
|
|
|
|
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', 1)}';
|
|
|
|
renderer.add_expression(x`@add_attribute("${name}", ${snippet}, 1)`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (add_class_attribute) {
|
|
|
|
// if (add_class_attribute) {
|
|
|
|
opening_tag += `\${@add_classes([${class_expression}].join(' ').trim())}`;
|
|
|
|
// opening_tag += `\${@add_classes([${class_expression}].join(' ').trim())}`;
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
opening_tag += '>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
renderer.append(opening_tag);
|
|
|
|
renderer.add_string('>');
|
|
|
|
|
|
|
|
|
|
|
|
if (node_contents !== undefined) {
|
|
|
|
if (node_contents !== undefined) {
|
|
|
|
if (contenteditable) {
|
|
|
|
// if (contenteditable) {
|
|
|
|
renderer.append('${($$value => $$value === void 0 ? `');
|
|
|
|
// renderer.append('${($$value => $$value === void 0 ? `');
|
|
|
|
renderer.render(node.children, options);
|
|
|
|
// renderer.render(node.children, options);
|
|
|
|
renderer.append('` : ' + value + ')(' + node_contents + ')}');
|
|
|
|
// renderer.append('` : ' + value + ')(' + node_contents + ')}');
|
|
|
|
} else {
|
|
|
|
// } else {
|
|
|
|
renderer.append(node_contents);
|
|
|
|
// renderer.append(node_contents);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
renderer.render(node.children, options);
|
|
|
|
renderer.render(node.children, options);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!is_void(node.name)) {
|
|
|
|
if (!is_void(node.name)) {
|
|
|
|
renderer.append(`</${node.name}>`);
|
|
|
|
renderer.add_string(`</${node.name}>`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|