Convert src/compiler/compile/render_ssr/handlers/InlineComponent.ts to JavaScript

pull/8569/head
Simon Holthausen 3 years ago
parent ac034d50ec
commit 5d329ddf2c

@ -1,115 +1,107 @@
import { string_literal } from '../../utils/stringify'; import { string_literal } from '../../utils/stringify.js';
import { get_attribute_value } from './shared/get_attribute_value'; import { get_attribute_value } from './shared/get_attribute_value';
import Renderer, { RenderOptions } from '../Renderer';
import InlineComponent from '../../nodes/InlineComponent';
import { p, x } from 'code-red'; import { p, x } from 'code-red';
import { namespaces } from '../../../utils/namespaces'; import { namespaces } from '../../../utils/namespaces';
/** @param {any} attribute */
function get_prop_value(attribute) { function get_prop_value(attribute) {
if (attribute.is_true) return x`true`; if (attribute.is_true)
if (attribute.chunks.length === 0) return x`''`; return x `true`;
if (attribute.chunks.length === 0)
return attribute.chunks return x `''`;
.map((chunk) => { return attribute.chunks
if (chunk.type === 'Text') return string_literal(chunk.data); .map((chunk) => {
return chunk.node; if (chunk.type === 'Text')
}) return string_literal(chunk.data);
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`); return chunk.node;
})
.reduce((lhs, rhs) => x `${lhs} + ${rhs}`);
} }
export default function (node: InlineComponent, renderer: Renderer, options: RenderOptions) { /**
const binding_props = []; * @param {import('../../nodes/InlineComponent.js').default} node
const binding_fns = []; * @param {import('../Renderer.js').default} renderer
* @param {import('../Renderer.js').RenderOptions} options
node.bindings.forEach((binding) => { */
renderer.has_bindings = true; export default function (node, renderer, options) {
const binding_props = [];
// TODO this probably won't work for contextual bindings const binding_fns = [];
const snippet = binding.expression.node; node.bindings.forEach((binding) => {
renderer.has_bindings = true;
binding_props.push(p`${binding.name}: ${snippet}`); // TODO this probably won't work for contextual bindings
binding_fns.push(p`${binding.name}: $$value => { ${snippet} = $$value; $$settled = false }`); const snippet = binding.expression.node;
}); binding_props.push(p `${binding.name}: ${snippet}`);
binding_fns.push(p `${binding.name}: $$value => { ${snippet} = $$value; $$settled = false }`);
const uses_spread = node.attributes.find((attr) => attr.is_spread); });
const uses_spread = node.attributes.find((attr) => attr.is_spread);
let props; let props;
if (uses_spread) {
if (uses_spread) { props = x `@_Object.assign({}, ${node.attributes
props = x`@_Object.assign({}, ${node.attributes .map((attribute) => {
.map((attribute) => { if (attribute.is_spread) {
if (attribute.is_spread) { return attribute.expression.node;
return attribute.expression.node; }
} else { else {
return x`{ ${attribute.name}: ${get_prop_value(attribute)} }`; return x `{ ${attribute.name}: ${get_prop_value(attribute)} }`;
} }
}) })
.concat(binding_props.map((p) => x`{ ${p} }`))})`; .concat(binding_props.map((p) => x `{ ${p} }`))})`;
} else { }
props = x`{ else {
${node.attributes.map((attribute) => p`${attribute.name}: ${get_prop_value(attribute)}`)}, props = x `{
${node.attributes.map((attribute) => p `${attribute.name}: ${get_prop_value(attribute)}`)},
${binding_props} ${binding_props}
}`; }`;
} }
const bindings = x `{
const bindings = x`{
${binding_fns} ${binding_fns}
}`; }`;
const expression = node.name === 'svelte:self'
const expression = ? renderer.name
node.name === 'svelte:self' : node.name === 'svelte:component'
? renderer.name ? x `(${node.expression.node}) || @missing_component`
: node.name === 'svelte:component' : node.name.split('.').reduce(/** @type {any} */ (((lhs, rhs) => x `${lhs}.${rhs}`)));
? x`(${node.expression.node}) || @missing_component` const slot_fns = [];
: node.name.split('.').reduce(((lhs, rhs) => x`${lhs}.${rhs}`) as any); const children = node.children;
if (children.length) {
const slot_fns = []; const slot_scopes = new Map();
renderer.render(children, Object.assign({}, options, {
const children = node.children; slot_scopes
}));
if (children.length) { slot_scopes.forEach(({ input, output, statements }, name) => {
const slot_scopes = new Map(); slot_fns.push(p `${name}: (${input}) => { ${statements}; return ${output}; }`);
});
renderer.render( }
children, const slots = x `{
Object.assign({}, options, {
slot_scopes
})
);
slot_scopes.forEach(({ input, output, statements }, name) => {
slot_fns.push(p`${name}: (${input}) => { ${statements}; return ${output}; }`);
});
}
const slots = x`{
${slot_fns} ${slot_fns}
}`; }`;
if (node.css_custom_properties.length > 0) {
if (node.namespace === namespaces.svg) {
renderer.add_string('<g style="');
}
else {
renderer.add_string('<div style="display: contents; ');
}
node.css_custom_properties.forEach((attr, index) => {
renderer.add_string(`${attr.name}:`);
renderer.add_expression(get_attribute_value(attr));
renderer.add_string(';');
if (index < node.css_custom_properties.length - 1)
renderer.add_string(' ');
});
renderer.add_string('">');
}
renderer.add_expression(x `@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`);
if (node.css_custom_properties.length > 0) {
if (node.namespace === namespaces.svg) {
renderer.add_string('</g>');
}
else {
renderer.add_string('</div>');
}
}
}
if (node.css_custom_properties.length > 0) {
if (node.namespace === namespaces.svg) {
renderer.add_string('<g style="');
} else {
renderer.add_string('<div style="display: contents; ');
}
node.css_custom_properties.forEach((attr, index) => {
renderer.add_string(`${attr.name}:`);
renderer.add_expression(get_attribute_value(attr));
renderer.add_string(';');
if (index < node.css_custom_properties.length - 1) renderer.add_string(' ');
});
renderer.add_string('">');
}
renderer.add_expression(
x`@validate_component(${expression}, "${node.name}").$$render($$result, ${props}, ${bindings}, ${slots})`
);
if (node.css_custom_properties.length > 0) {
if (node.namespace === namespaces.svg) {
renderer.add_string('</g>');
} else {
renderer.add_string('</div>');
}
}
}

Loading…
Cancel
Save