throw error if <svelte:element> uses animation

pull/6898/head
Yuichiro Yamashita 5 years ago
parent 8c9e93bd62
commit a86ec67d41

@ -238,6 +238,10 @@ export default {
code: 'invalid-animation', code: 'invalid-animation',
message: 'An element that uses the animate directive must be the sole child of a keyed each block' message: 'An element that uses the animate directive must be the sole child of a keyed each block'
}, },
invalid_animation_dynamic_element: {
code: 'invalid-animation',
message: '<svelte:element> cannot have a animate directive'
},
invalid_directive_value: { invalid_directive_value: {
code: 'invalid-directive-value', code: 'invalid-directive-value',
message: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)' message: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)'

@ -16,6 +16,7 @@ import list from '../../utils/list';
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';
import { TemplateNode } from '../../interfaces';
import Component from '../Component'; import Component from '../Component';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
import compiler_warnings from '../compiler_warnings'; import compiler_warnings from '../compiler_warnings';
@ -134,7 +135,7 @@ export default class Element extends Node {
needs_manual_style_scoping: boolean; needs_manual_style_scoping: boolean;
dynamic_tag_expr?: Expression = null; dynamic_tag_expr?: Expression = null;
constructor(component: Component, parent: Node, scope: TemplateScope, info: any) { 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;
@ -251,6 +252,9 @@ 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) {
this.validate_dynamic_element(info);
}
this.validate(); this.validate();
this.optimise(); this.optimise();
@ -258,6 +262,14 @@ export default class Element extends Node {
component.apply_stylesheet(this); component.apply_stylesheet(this);
} }
validate_dynamic_element(info: TemplateNode) {
info.attributes.forEach(node => {
if (node.type === 'Animation') {
this.component.error(node, compiler_errors.invalid_animation_dynamic_element);
}
});
}
validate() { validate() {
if (this.component.var_lookup.has(this.name) && this.component.var_lookup.get(this.name).imported) { if (this.component.var_lookup.has(this.name) && this.component.var_lookup.get(this.name).imported) {
this.component.warn(this, compiler_warnings.component_name_lowercase(this.name)); this.component.warn(this, compiler_warnings.component_name_lowercase(this.name));

@ -0,0 +1,3 @@
export default {
error: '<svelte:element> cannot have a animate directive'
};

@ -0,0 +1,20 @@
<script>
let tag = 'div';
let things = [
{ id: 1, name: 'a' },
];
function flip(node, animation, params) {
const dx = animation.from.left - animation.to.left;
const dy = animation.from.top - animation.to.top;
return {
duration: 100,
css: (t, u) => `transform: translate(${u + dx}px, ${u * dy}px)`
};
}
</script>
{#each things as thing (thing.id)}
<svelte:element this={tag} animate:flip></svelte:element>
{/each}
Loading…
Cancel
Save