refactor nodes

pull/6898/head
Yuichiro Yamashita 5 years ago
parent 89d273323e
commit 14ca99006f

@ -13,8 +13,6 @@ import map_children from './shared/map_children';
import { dimensions } from '../../utils/patterns'; import { dimensions } from '../../utils/patterns';
import fuzzymatch from '../../utils/fuzzymatch'; import fuzzymatch from '../../utils/fuzzymatch';
import list from '../../utils/list'; import list from '../../utils/list';
import { string_literal } from '../utils/stringify';
import { Literal } from 'estree';
import Let from './Let'; import Let from './Let';
import TemplateScope from './shared/TemplateScope'; import TemplateScope from './shared/TemplateScope';
import { INode } from './interfaces'; import { INode } from './interfaces';
@ -119,7 +117,7 @@ function get_namespace(parent: Element, element: Element, explicit_namespace: st
} }
export default class Element extends Node { export default class Element extends Node {
type: 'Element'; type: 'Element' | 'DynamicElement';
name: string; name: string;
scope: TemplateScope; scope: TemplateScope;
attributes: Attribute[] = []; attributes: Attribute[] = [];
@ -134,21 +132,18 @@ export default class Element extends Node {
children: INode[]; children: INode[];
namespace: string; namespace: string;
needs_manual_style_scoping: boolean; needs_manual_style_scoping: boolean;
// If tag is <svelte:element>, it will be set.
dynamic_tag_expr?: Expression = null; dynamic_tag_expr?: Expression = null;
get is_dynamic_tag(): boolean {
return this.name === 'svelte:element';
}
constructor(component: Component, parent: Node, scope: TemplateScope, info: any) { constructor(component: Component, parent: Node, scope: TemplateScope, info: any) {
super(component, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
if (this.name === 'svelte:element') { if (this.name === 'svelte:element') {
if (typeof info.tag === 'string') { 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 { } else {
this.type = 'DynamicElement';
this.dynamic_tag_expr = new Expression(component, this, scope, info.tag); this.dynamic_tag_expr = new Expression(component, this, scope, info.tag);
} }
} }

@ -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); block.add_dependencies(node.dynamic_tag_expr.dependencies);
} }
@ -248,7 +248,7 @@ export default class ElementWrapper extends Wrapper {
b`${node} = ${render_statement};` 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)});`); block.chunks.create.push(b`@validate_dynamic_element(${this.node.dynamic_tag_expr.manipulate(block)});`);
if (renderer.options.hydratable) { if (renderer.options.hydratable) {
@ -354,7 +354,7 @@ export default class ElementWrapper extends Wrapper {
this.add_classes(block); this.add_classes(block);
this.add_manual_style_scoping(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(); const dependencies = this.node.dynamic_tag_expr.dynamic_dependencies();
if (dependencies.length) { if (dependencies.length) {
const condition = block.renderer.dirty( 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}`)})`; 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})`; return x`@element(${reference})`;
} }
@ -417,7 +417,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.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) { if (this.node.namespace === namespaces.svg) {
return x`@claim_svg_element(${nodes}, ${reference}, { ${attributes} })`; return x`@claim_svg_element(${nodes}, ${reference}, { ${attributes} })`;

@ -23,7 +23,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
node.attributes.some((attribute) => attribute.name === 'contenteditable') node.attributes.some((attribute) => attribute.name === 'contenteditable')
); );
if (node.is_dynamic_tag) { if (node.type === 'DynamicElement') {
renderer.add_string('<'); renderer.add_string('<');
renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); renderer.add_expression(node.dynamic_tag_expr.node as ESExpression);
} else { } else {
@ -158,7 +158,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
} }
if (!is_void(node.name)) { if (!is_void(node.name)) {
if (node.is_dynamic_tag) { if (node.type === 'DynamicElement') {
renderer.add_string('</'); renderer.add_string('</');
renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); renderer.add_expression(node.dynamic_tag_expr.node as ESExpression);
renderer.add_string('>'); renderer.add_string('>');
@ -170,7 +170,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
renderer.render(children, options); renderer.render(children, options);
if (!is_void(node.name)) { if (!is_void(node.name)) {
if (node.is_dynamic_tag) { if (node.type === 'DynamicElement') {
renderer.add_string('</'); renderer.add_string('</');
renderer.add_expression(node.dynamic_tag_expr.node as ESExpression); renderer.add_expression(node.dynamic_tag_expr.node as ESExpression);
renderer.add_string('>'); renderer.add_string('>');

@ -47,7 +47,7 @@ interface BaseDirective extends BaseNode {
} }
export interface Element 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<BaseDirective | Attribute | SpreadAttribute>; attributes: Array<BaseDirective | Attribute | SpreadAttribute>;
name: string; name: string;
} }

Loading…
Cancel
Save