pull/6898/head
Yuichiro Yamashita 5 years ago
parent 75621dc88b
commit 42e465635e

@ -19,6 +19,8 @@ import { INode } from './interfaces';
import { TemplateNode } from '../../interfaces'; import { TemplateNode } from '../../interfaces';
import Component from '../Component'; import Component from '../Component';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
import { string_literal } from '../utils/stringify';
import { Literal } from 'estree';
import compiler_warnings from '../compiler_warnings'; import compiler_warnings from '../compiler_warnings';
import compiler_errors from '../compiler_errors'; import compiler_errors from '../compiler_errors';
@ -133,18 +135,25 @@ export default class Element extends Node {
children: INode[]; children: INode[];
namespace: string; namespace: string;
needs_manual_style_scoping: boolean; needs_manual_style_scoping: boolean;
dynamic_tag_expr?: Expression = null; tag_expr: Expression;
is_dynamic_element() {
return this.name === 'svelte:element';
}
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) { constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
super(component, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
if (this.name === 'svelte:element') { if (info.name === 'svelte:element') {
if (typeof info.tag === 'string') { if (typeof info.tag === 'string') {
this.name = info.tag; this.name = info.tag;
this.tag_expr = new Expression(component, this, scope, string_literal(info.tag) as Literal);
} else { } else {
this.dynamic_tag_expr = new Expression(component, this, scope, info.tag); this.tag_expr = new Expression(component, this, scope, info.tag);
} }
} else {
this.tag_expr = new Expression(component, this, scope, string_literal(info.name) as Literal);
} }
this.namespace = get_namespace(parent as Element, this, component.namespace); this.namespace = get_namespace(parent as Element, this, component.namespace);
@ -252,7 +261,7 @@ export default class Element extends Node {
this.scope = scope; this.scope = scope;
this.children = map_children(component, this, this.scope, info.children); this.children = map_children(component, this, this.scope, info.children);
if (this.dynamic_tag_expr) { if (this.is_dynamic_element()) {
this.validate_dynamic_element(info); this.validate_dynamic_element(info);
} }
this.validate(); this.validate();

@ -165,7 +165,7 @@ export default class ElementWrapper extends Wrapper {
name: node.name.replace(/[^a-zA-Z0-9_$]/g, '_') name: node.name.replace(/[^a-zA-Z0-9_$]/g, '_')
}; };
if (node.dynamic_tag_expr) { if (node.is_dynamic_element()) {
if (block.type !== 'child_dynamic_element') { if (block.type !== 'child_dynamic_element') {
this.not_static_content(); this.not_static_content();
this.child_dynamic_element_block = block.child({ this.child_dynamic_element_block = block.child({
@ -225,6 +225,8 @@ export default class ElementWrapper extends Wrapper {
block.add_animation(); block.add_animation();
} }
block.add_dependencies(node.tag_expr.dependencies);
// add directive and handler dependencies // add directive and handler dependencies
[node.animation, node.outro, ...node.actions, ...node.classes].forEach(directive => { [node.animation, node.outro, ...node.actions, ...node.classes].forEach(directive => {
if (directive && directive.expression) { if (directive && directive.expression) {
@ -238,10 +240,6 @@ export default class ElementWrapper extends Wrapper {
} }
}); });
if (node.dynamic_tag_expr) {
block.add_dependencies(node.dynamic_tag_expr.dependencies);
}
if (this.parent) { if (this.parent) {
if (node.actions.length > 0 || if (node.actions.length > 0 ||
node.animation || node.animation ||
@ -283,11 +281,11 @@ export default class ElementWrapper extends Wrapper {
b`${node} = ${render_statement};` b`${node} = ${render_statement};`
); );
if (this.node.dynamic_tag_expr && this.renderer.options.dev) { if (this.node.is_dynamic_element() && this.renderer.options.dev) {
block.chunks.create.push(b`@validate_dynamic_element(${this.node.dynamic_tag_expr.manipulate(block)});`); block.chunks.create.push(b`@validate_dynamic_element(${this.node.tag_expr.manipulate(block)});`);
if (renderer.options.hydratable) { if (renderer.options.hydratable) {
block.chunks.claim.push(b`@validate_dynamic_element(${this.node.dynamic_tag_expr.manipulate(block)});`); block.chunks.claim.push(b`@validate_dynamic_element(${this.node.tag_expr.manipulate(block)});`);
} }
} }
@ -402,8 +400,8 @@ export default class ElementWrapper extends Wrapper {
); );
} }
if (this.node.dynamic_tag_expr) { if (this.node.is_dynamic_element()) {
const dependencies = this.node.dynamic_tag_expr.dynamic_dependencies(); const dependencies = this.node.tag_expr.dynamic_dependencies();
if (dependencies.length) { if (dependencies.length) {
const condition = block.renderer.dirty( const condition = block.renderer.dirty(
dependencies dependencies
@ -414,7 +412,7 @@ export default class ElementWrapper extends Wrapper {
if (${condition}) { if (${condition}) {
@detach(${node}); @detach(${node});
${node} = ${render_statement}; ${node} = ${render_statement};
@validate_dynamic_element(${this.node.dynamic_tag_expr.manipulate(block)}); @validate_dynamic_element(${this.node.tag_expr.manipulate(block)});
${block.chunks.hydrate} ${block.chunks.hydrate}
${block.event_listeners.length && b`${mounted} = false`}; ${block.event_listeners.length && b`${mounted} = false`};
${staticChildren} ${staticChildren}
@ -432,7 +430,7 @@ export default class ElementWrapper extends Wrapper {
); );
const previous_tag = block.get_unique_name('previous_tag'); const previous_tag = block.get_unique_name('previous_tag');
const snippet = this.node.dynamic_tag_expr.manipulate(block); const snippet = this.node.tag_expr.manipulate(block);
block.add_variable(previous_tag, snippet); block.add_variable(previous_tag, snippet);
block.chunks.init.push(b` block.chunks.init.push(b`
@ -497,7 +495,7 @@ export default class ElementWrapper extends Wrapper {
} }
get_render_statement(block: Block) { get_render_statement(block: Block) {
const { name, namespace } = this.node; const { name, namespace, tag_expr } = this.node;
if (namespace === namespaces.svg) { if (namespace === namespaces.svg) {
return x`@svg_element("${name}")`; return x`@svg_element("${name}")`;
@ -512,7 +510,7 @@ export default class ElementWrapper extends Wrapper {
return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`; return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`;
} }
const reference = this.node.dynamic_tag_expr ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; const reference = tag_expr.manipulate(block);
return x`@element(${reference})`; return x`@element(${reference})`;
} }
@ -524,7 +522,7 @@ export default class ElementWrapper extends Wrapper {
const name = this.node.namespace const name = this.node.namespace
? this.node.name ? this.node.name
: this.node.name.toUpperCase(); : this.node.name.toUpperCase();
const reference = this.node.dynamic_tag_expr ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; const reference = this.node.is_dynamic_element() ? this.node.tag_expr.manipulate(block) : `"${name}"`;
if (this.node.namespace === namespaces.svg) { if (this.node.namespace === namespaces.svg) {
return x`@claim_svg_element(${nodes}, ${reference}, { ${attributes} })`; return x`@claim_svg_element(${nodes}, ${reference}, { ${attributes} })`;

@ -23,12 +23,8 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
node.attributes.some((attribute) => attribute.name === 'contenteditable') node.attributes.some((attribute) => attribute.name === 'contenteditable')
); );
if (node.dynamic_tag_expr) {
renderer.add_string('<'); renderer.add_string('<');
renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); renderer.add_expression(node.tag_expr.node as ESExpression);
} else {
renderer.add_string(`<${node.name}`);
}
const class_expression_list = node.classes.map(class_directive => { const class_expression_list = node.classes.map(class_directive => {
const { expression, name } = class_directive; const { expression, name } = class_directive;
@ -165,13 +161,9 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
function add_close_tag() { function add_close_tag() {
if (!is_void(node.name)) { if (!is_void(node.name)) {
if (node.dynamic_tag_expr) {
renderer.add_string('</'); renderer.add_string('</');
renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); renderer.add_expression(node.tag_expr.node as ESExpression);
renderer.add_string('>'); renderer.add_string('>');
} else {
renderer.add_string(`</${node.name}>`);
}
} }
} }
} }

@ -7,10 +7,10 @@ const Component = create_ssr_component(($$result, $$props, $$bindings, slots) =>
if ($$props.things === void 0 && $$bindings.things && things !== void 0) $$bindings.things(things); if ($$props.things === void 0 && $$bindings.things && things !== void 0) $$bindings.things(things);
if ($$props.foo === void 0 && $$bindings.foo && foo !== void 0) $$bindings.foo(foo); if ($$props.foo === void 0 && $$bindings.foo && foo !== void 0) $$bindings.foo(foo);
return `${each(things, thing => `<span>${escape(thing.name)}</span> return `${each(things, thing => `<${"span"}>${escape(thing.name)}</${"span"}>
${debug(null, 7, 2, { foo })}`)} ${debug(null, 7, 2, { foo })}`)}
<p>foo: ${escape(foo)}</p>`; <${"p"}>foo: ${escape(foo)}</${"p"}>`;
}); });
export default Component; export default Component;

@ -2,9 +2,9 @@
import { create_ssr_component } from "svelte/internal"; import { create_ssr_component } from "svelte/internal";
const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => {
return `<div>content</div> return `<${"div"}>content</${"div"}>
<!-- comment --> <!-- comment -->
<div>more content</div>`; <${"div"}>more content</${"div"}>`;
}); });
export default Component; export default Component;

Loading…
Cancel
Save