mirror of https://github.com/sveltejs/svelte
parent
7b5247d7a4
commit
185332e409
@ -1,151 +0,0 @@
|
||||
import Node from './shared/Node';
|
||||
import Attribute from './Attribute';
|
||||
import Binding from './Binding';
|
||||
import EventHandler from './EventHandler';
|
||||
import Let from './Let';
|
||||
import TemplateScope from './shared/TemplateScope';
|
||||
import { INode } from './interfaces';
|
||||
import Expression from './shared/Expression';
|
||||
import Component from '../Component';
|
||||
import map_children from './shared/map_children';
|
||||
import Class from './Class';
|
||||
import Transition from './Transition';
|
||||
import Animation from './Animation';
|
||||
import Action from './Action';
|
||||
import { string_literal } from '../utils/stringify';
|
||||
import { Literal } from 'estree';
|
||||
import Text from './Text';
|
||||
|
||||
export default class DynamicElement extends Node {
|
||||
type: 'DynamicElement';
|
||||
name: string;
|
||||
tag: Expression;
|
||||
attributes: Attribute[] = [];
|
||||
actions: Action[] = [];
|
||||
bindings: Binding[] = [];
|
||||
classes: Class[] = [];
|
||||
handlers: EventHandler[] = [];
|
||||
lets: Let[] = [];
|
||||
intro?: Transition = null;
|
||||
outro?: Transition = null;
|
||||
animation?: Animation = null;
|
||||
children: INode[];
|
||||
scope: TemplateScope;
|
||||
needs_manual_style_scoping: boolean;
|
||||
|
||||
constructor(component: Component, parent, scope, info) {
|
||||
super(component, parent, scope, info);
|
||||
|
||||
this.name = info.name;
|
||||
|
||||
if (typeof info.tag === 'string') {
|
||||
this.tag = new Expression(component, this, scope, string_literal(info.tag) as Literal);
|
||||
} else {
|
||||
this.tag = new Expression(component, this, scope, info.tag);
|
||||
}
|
||||
|
||||
info.attributes.forEach((node) => {
|
||||
switch (node.type) {
|
||||
case 'Action':
|
||||
this.actions.push(new Action(component, this, scope, node));
|
||||
break;
|
||||
|
||||
case 'Attribute':
|
||||
case 'Spread':
|
||||
this.attributes.push(new Attribute(component, this, scope, node));
|
||||
break;
|
||||
|
||||
case 'Binding':
|
||||
this.bindings.push(new Binding(component, this, scope, node));
|
||||
break;
|
||||
|
||||
case 'Class':
|
||||
this.classes.push(new Class(component, this, scope, node));
|
||||
break;
|
||||
|
||||
case 'EventHandler':
|
||||
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||
break;
|
||||
|
||||
case 'Let': {
|
||||
const l = new Let(component, this, scope, node);
|
||||
this.lets.push(l);
|
||||
const dependencies = new Set([l.name.name]);
|
||||
|
||||
l.names.forEach((name) => {
|
||||
scope.add(name, dependencies, this);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Transition': {
|
||||
const transition = new Transition(component, this, scope, node);
|
||||
if (node.intro) this.intro = transition;
|
||||
if (node.outro) this.outro = transition;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Animation':
|
||||
this.animation = new Animation(component, this, scope, node);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Not implemented: ${node.type}`);
|
||||
}
|
||||
});
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
this.children = map_children(component, this, this.scope, info.children);
|
||||
|
||||
this.validate();
|
||||
|
||||
// TODO create BaseElement class or an interface which both DynamicElement and Element use
|
||||
// to resolve the hacky cast
|
||||
component.apply_stylesheet(this as any);
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.bindings.forEach(binding => {
|
||||
if (binding.name !== 'this') {
|
||||
this.component.error(binding, {
|
||||
code: 'invalid-binding',
|
||||
message: `'${binding.name}' is not a valid binding. svelte:element only supports bind:this`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
add_css_class() {
|
||||
if (this.attributes.some(attr => attr.is_spread)) {
|
||||
this.needs_manual_style_scoping = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = this.component.stylesheet;
|
||||
|
||||
const class_attribute = this.attributes.find(a => a.name === 'class');
|
||||
|
||||
if (class_attribute && !class_attribute.is_true) {
|
||||
if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') {
|
||||
(class_attribute.chunks[0] as Text).data += ` ${id}`;
|
||||
} else {
|
||||
(class_attribute.chunks as Node[]).push(
|
||||
new Text(this.component, this, this.scope, {
|
||||
type: 'Text',
|
||||
data: ` ${id}`,
|
||||
synthetic: true
|
||||
} as any)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.attributes.push(
|
||||
new Attribute(this.component, this, this.scope, {
|
||||
type: 'Attribute',
|
||||
name: 'class',
|
||||
value: [{ type: 'Text', data: id, synthetic: true }]
|
||||
} as any)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,3 @@
|
||||
export default {
|
||||
error: "'value' is not a valid binding. svelte:element only supports bind:this"
|
||||
error: "'value' is not a valid binding on <svelte:element> elements"
|
||||
};
|
||||
|
||||
Loading…
Reference in new issue