diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index a495c4f58a..a4a22a39f6 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -13,8 +13,6 @@ import map_children from './shared/map_children'; import { dimensions } from '../../utils/patterns'; import fuzzymatch from '../../utils/fuzzymatch'; import list from '../../utils/list'; -import { string_literal } from '../utils/stringify'; -import { Literal } from 'estree'; import Let from './Let'; import TemplateScope from './shared/TemplateScope'; import { INode } from './interfaces'; @@ -119,7 +117,7 @@ function get_namespace(parent: Element, element: Element, explicit_namespace: st } export default class Element extends Node { - type: 'Element'; + type: 'Element' | 'DynamicElement'; name: string; scope: TemplateScope; attributes: Attribute[] = []; @@ -134,21 +132,18 @@ export default class Element extends Node { children: INode[]; namespace: string; needs_manual_style_scoping: boolean; - // If tag is , it will be set. dynamic_tag_expr?: Expression = null; - get is_dynamic_tag(): boolean { - return this.name === 'svelte:element'; - } - constructor(component: Component, parent: Node, scope: TemplateScope, info: any) { super(component, parent, scope, info); this.name = info.name; if (this.name === 'svelte:element') { if (typeof info.tag === 'string') { - this.dynamic_tag_expr = new Expression(component, this, scope, string_literal(info.tag) as Literal); + this.type = 'Element'; + this.name = info.tag; } else { + this.type = 'DynamicElement'; this.dynamic_tag_expr = new Expression(component, this, scope, info.tag); } } diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index e4039b4663..62fab592d0 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -211,7 +211,7 @@ export default class ElementWrapper extends Wrapper { } }); - if (node.is_dynamic_tag) { + if (node.type === 'DynamicElement') { block.add_dependencies(node.dynamic_tag_expr.dependencies); } @@ -248,7 +248,7 @@ export default class ElementWrapper extends Wrapper { b`${node} = ${render_statement};` ); - if (this.node.is_dynamic_tag && this.renderer.options.dev) { + if (this.node.type === 'DynamicElement' && this.renderer.options.dev) { block.chunks.create.push(b`@validate_dynamic_element(${this.node.dynamic_tag_expr.manipulate(block)});`); if (renderer.options.hydratable) { @@ -354,7 +354,7 @@ export default class ElementWrapper extends Wrapper { this.add_classes(block); this.add_manual_style_scoping(block); - if (this.node.is_dynamic_tag) { + if (this.node.type === 'DynamicElement') { const dependencies = this.node.dynamic_tag_expr.dynamic_dependencies(); if (dependencies.length) { const condition = block.renderer.dirty( @@ -405,7 +405,7 @@ export default class ElementWrapper extends Wrapper { return x`@element_is("${name}", ${is.render_chunks(block).reduce((lhs, rhs) => x`${lhs} + ${rhs}`)})`; } - const reference = this.node.is_dynamic_tag ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; + const reference = this.node.type === 'DynamicElement' ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; return x`@element(${reference})`; } @@ -417,7 +417,7 @@ export default class ElementWrapper extends Wrapper { const name = this.node.namespace ? this.node.name : this.node.name.toUpperCase(); - const reference = this.node.is_dynamic_tag ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; + const reference = this.node.type === 'DynamicElement' ? this.node.dynamic_tag_expr.manipulate(block) : `"${name}"`; if (this.node.namespace === namespaces.svg) { return x`@claim_svg_element(${nodes}, ${reference}, { ${attributes} })`; diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index e1b14b760f..8d84ea0bc0 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -23,7 +23,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption node.attributes.some((attribute) => attribute.name === 'contenteditable') ); - if (node.is_dynamic_tag) { + if (node.type === 'DynamicElement') { renderer.add_string('<'); renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); } else { @@ -158,7 +158,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption } if (!is_void(node.name)) { - if (node.is_dynamic_tag) { + if (node.type === 'DynamicElement') { renderer.add_string(''); @@ -170,7 +170,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption renderer.render(children, options); if (!is_void(node.name)) { - if (node.is_dynamic_tag) { + if (node.type === 'DynamicElement') { renderer.add_string(''); diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index b999fbd803..85feb72ce0 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -47,7 +47,7 @@ interface BaseDirective extends BaseNode { } export interface Element extends BaseNode { - type: 'InlineComponent' | 'SlotTemplate' | 'Title' | 'Slot' | 'Element' | 'Head' | 'Options' | 'Window' | 'Body'; + type: 'InlineComponent' | 'SlotTemplate' | 'Title' | 'Slot' | 'Element' | 'DynamicElement' | 'Head' | 'Options' | 'Window' | 'Body'; attributes: Array; name: string; }