mirror of https://github.com/sveltejs/svelte
parent
26d006591d
commit
f001107711
@ -0,0 +1,99 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
import Wrapper from './shared/Wrapper';
|
||||||
|
import Renderer from '../Renderer';
|
||||||
|
import Block from '../Block';
|
||||||
|
import FragmentWrapper from './Fragment';
|
||||||
|
import { b, x } from 'code-red';
|
||||||
|
import { Identifier } from 'estree';
|
||||||
|
import DynamicElement from '../../nodes/DynamicElement';
|
||||||
|
import ElementWrapper from './Element/index';
|
||||||
|
import create_debugging_comment from './shared/create_debugging_comment';
|
||||||
|
import Element from '../../nodes/Element';
|
||||||
|
|
||||||
|
export default class DynamicElementWrapper extends Wrapper {
|
||||||
|
fragment: FragmentWrapper;
|
||||||
|
node: DynamicElement;
|
||||||
|
elementWrapper: ElementWrapper;
|
||||||
|
block: Block;
|
||||||
|
dependencies: string[];
|
||||||
|
var: Identifier = { type: 'Identifier', name: 'dynamic_element' };
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
renderer: Renderer,
|
||||||
|
block: Block,
|
||||||
|
parent: Wrapper,
|
||||||
|
node: DynamicElement,
|
||||||
|
strip_whitespace: boolean,
|
||||||
|
next_sibling: Wrapper
|
||||||
|
) {
|
||||||
|
super(renderer, block, parent, node);
|
||||||
|
|
||||||
|
this.not_static_content();
|
||||||
|
this.dependencies = node.tag.dynamic_dependencies();
|
||||||
|
|
||||||
|
if (this.dependencies.length) {
|
||||||
|
block = block.child({
|
||||||
|
comment: create_debugging_comment(node, renderer.component),
|
||||||
|
name: renderer.component.get_unique_name('dynamic_element_block'),
|
||||||
|
type: 'dynamic_element'
|
||||||
|
});
|
||||||
|
renderer.blocks.push(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
(node as unknown as Element).dynamic_tag = node.tag;
|
||||||
|
|
||||||
|
this.block = block;
|
||||||
|
this.elementWrapper = new ElementWrapper(
|
||||||
|
renderer,
|
||||||
|
this.block,
|
||||||
|
parent,
|
||||||
|
(node as unknown) as Element,
|
||||||
|
strip_whitespace,
|
||||||
|
next_sibling
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
|
||||||
|
if (this.dependencies.length === 0) {
|
||||||
|
this.render_static_tag(block, parent_node, parent_nodes);
|
||||||
|
} else {
|
||||||
|
this.render_dynamic_tag(block, parent_node, parent_nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_static_tag(
|
||||||
|
_block: Block,
|
||||||
|
parent_node: Identifier,
|
||||||
|
parent_nodes: Identifier
|
||||||
|
) {
|
||||||
|
this.elementWrapper.render(this.block, parent_node, parent_nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_dynamic_tag(
|
||||||
|
block: Block,
|
||||||
|
parent_node: Identifier,
|
||||||
|
parent_nodes: Identifier
|
||||||
|
) {
|
||||||
|
this.elementWrapper.render(
|
||||||
|
this.block,
|
||||||
|
null,
|
||||||
|
(x`#nodes` as unknown) as Identifier
|
||||||
|
);
|
||||||
|
|
||||||
|
const has_transitions = !!(
|
||||||
|
this.block.has_intro_method || this.block.has_outro_method
|
||||||
|
);
|
||||||
|
const dynamic = this.block.has_update_method;
|
||||||
|
|
||||||
|
const previous_tag = block.get_unique_name('previous_tag');
|
||||||
|
const snippet = this.node.tag.manipulate(block);
|
||||||
|
block.add_variable(previous_tag, snippet);
|
||||||
|
|
||||||
|
const not_equal = this.renderer.component.component_options.immutable
|
||||||
|
? x`@not_equal`
|
||||||
|
: x`@safe_not_equal`;
|
||||||
|
const condition = x`${this.renderer.dirty(
|
||||||
|
this.dependencies
|
||||||
|
)} && ${not_equal}(${previous_tag}, ${previous_tag} = ${snippet})`;
|
||||||
|
|
||||||
|
block.chunks.init.push(b`
|
||||||
|
let ${this.var} = ${this.block.name}(#ctx);
|
||||||
|
`);
|
||||||
|
|
||||||
|
block.chunks.create.push(b`${this.var}.c();`);
|
||||||
|
|
||||||
|
if (this.renderer.options.hydratable) {
|
||||||
|
block.chunks.claim.push(b`${this.var}.l(${parent_nodes});`);
|
||||||
|
}
|
||||||
|
|
||||||
|
block.chunks.mount.push(
|
||||||
|
b`${this.var}.m(${parent_node || '#target'}, ${
|
||||||
|
parent_node ? 'null' : '#anchor'
|
||||||
|
});`
|
||||||
|
);
|
||||||
|
|
||||||
|
const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes);
|
||||||
|
const body = b`
|
||||||
|
${
|
||||||
|
has_transitions
|
||||||
|
? b`
|
||||||
|
@group_outros();
|
||||||
|
@transition_out(${this.var}, 1, 1, @noop);
|
||||||
|
@check_outros();
|
||||||
|
`
|
||||||
|
: b`${this.var}.d(1);`
|
||||||
|
}
|
||||||
|
${this.var} = ${this.block.name}(#ctx);
|
||||||
|
${this.var}.c();
|
||||||
|
${has_transitions && b`@transition_in(${this.var})`}
|
||||||
|
${this.var}.m(${this.get_update_mount_node(anchor)}, ${anchor});
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (dynamic) {
|
||||||
|
block.chunks.update.push(b`
|
||||||
|
if (${condition}) {
|
||||||
|
${body}
|
||||||
|
} else {
|
||||||
|
${this.var}.p(#ctx, #dirty);
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
block.chunks.update.push(b`
|
||||||
|
if (${condition}) {
|
||||||
|
${body}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_transitions) {
|
||||||
|
block.chunks.intro.push(b`@transition_in(${this.var})`);
|
||||||
|
block.chunks.outro.push(b`@transition_out(${this.var})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
block.chunks.destroy.push(b`${this.var}.d(detaching)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,215 @@
|
|||||||
|
import {
|
||||||
|
get_attribute_value,
|
||||||
|
get_class_attribute_value
|
||||||
|
} from './shared/get_attribute_value';
|
||||||
|
import { get_slot_scope } from './shared/get_slot_scope';
|
||||||
|
import { boolean_attributes } from './shared/boolean_attributes';
|
||||||
|
import Renderer, { RenderOptions } from '../Renderer';
|
||||||
|
import DynamicElement from '../../nodes/DynamicElement';
|
||||||
|
import ElementHandler from './Element';
|
||||||
|
import { x } from 'code-red';
|
||||||
|
import Expression from '../../nodes/shared/Expression';
|
||||||
|
import remove_whitespace_children from './utils/remove_whitespace_children';
|
||||||
|
import Element from '../../nodes/Element';
|
||||||
|
import { Expression as ESExpression } from 'estree';
|
||||||
|
|
||||||
|
export default function (
|
||||||
|
node: DynamicElement,
|
||||||
|
renderer: Renderer,
|
||||||
|
options: RenderOptions & {
|
||||||
|
slot_scopes: Map<any, any>;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const dependencies = node.tag.dynamic_dependencies();
|
||||||
|
|
||||||
|
if (dependencies.length === 0) {
|
||||||
|
((node as unknown) as Element).dynamic_tag = node.tag;
|
||||||
|
ElementHandler((node as unknown) as Element, renderer, options);
|
||||||
|
} else {
|
||||||
|
const children = remove_whitespace_children(node.children, node.next);
|
||||||
|
|
||||||
|
// awkward special case
|
||||||
|
let node_contents;
|
||||||
|
|
||||||
|
const contenteditable = node.attributes.some(
|
||||||
|
(attribute) => attribute.name === 'contenteditable'
|
||||||
|
);
|
||||||
|
|
||||||
|
const slot = node.get_static_attribute_value('slot');
|
||||||
|
const nearest_inline_component = node.find_nearest(/InlineComponent/);
|
||||||
|
|
||||||
|
if (slot && nearest_inline_component) {
|
||||||
|
renderer.push();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.add_string('<');
|
||||||
|
renderer.add_expression(node.tag.node as ESExpression);
|
||||||
|
|
||||||
|
const class_expression_list = node.classes.map((class_directive) => {
|
||||||
|
const { expression, name } = class_directive;
|
||||||
|
const snippet = expression ? expression.node : x`#ctx.${name}`; // TODO is this right?
|
||||||
|
return x`${snippet} ? "${name}" : ""`;
|
||||||
|
});
|
||||||
|
// if (node.needs_manual_style_scoping) {
|
||||||
|
// class_expression_list.push(x`"${node.component.stylesheet.id}"`);
|
||||||
|
// }
|
||||||
|
const class_expression =
|
||||||
|
class_expression_list.length > 0 &&
|
||||||
|
class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`);
|
||||||
|
|
||||||
|
if (node.attributes.some((attr) => attr.is_spread)) {
|
||||||
|
// TODO dry this out
|
||||||
|
const args = [];
|
||||||
|
node.attributes.forEach((attribute) => {
|
||||||
|
if (attribute.is_spread) {
|
||||||
|
args.push(attribute.expression.node);
|
||||||
|
} else {
|
||||||
|
const name = attribute.name.toLowerCase();
|
||||||
|
if (attribute.is_true) {
|
||||||
|
args.push(x`{ ${attribute.name}: true }`);
|
||||||
|
} else if (
|
||||||
|
boolean_attributes.has(name) &&
|
||||||
|
attribute.chunks.length === 1 &&
|
||||||
|
attribute.chunks[0].type !== 'Text'
|
||||||
|
) {
|
||||||
|
// a boolean attribute with one non-Text chunk
|
||||||
|
args.push(
|
||||||
|
x`{ ${attribute.name}: ${
|
||||||
|
(attribute.chunks[0] as Expression).node
|
||||||
|
} || null }`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
args.push(
|
||||||
|
x`{ ${attribute.name}: ${get_attribute_value(attribute)} }`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.add_expression(x`@spread([${args}], ${class_expression})`);
|
||||||
|
} else {
|
||||||
|
let add_class_attribute = !!class_expression;
|
||||||
|
node.attributes.forEach((attribute) => {
|
||||||
|
const name = attribute.name.toLowerCase();
|
||||||
|
if (attribute.is_true) {
|
||||||
|
renderer.add_string(` ${attribute.name}`);
|
||||||
|
} else if (
|
||||||
|
boolean_attributes.has(name) &&
|
||||||
|
attribute.chunks.length === 1 &&
|
||||||
|
attribute.chunks[0].type !== 'Text'
|
||||||
|
) {
|
||||||
|
// a boolean attribute with one non-Text chunk
|
||||||
|
renderer.add_string(' ');
|
||||||
|
renderer.add_expression(
|
||||||
|
x`${(attribute.chunks[0] as Expression).node} ? "${
|
||||||
|
attribute.name
|
||||||
|
}" : ""`
|
||||||
|
);
|
||||||
|
} else if (name === 'class' && class_expression) {
|
||||||
|
add_class_attribute = false;
|
||||||
|
renderer.add_string(` ${attribute.name}="`);
|
||||||
|
renderer.add_expression(
|
||||||
|
x`[${get_class_attribute_value(
|
||||||
|
attribute
|
||||||
|
)}, ${class_expression}].join(' ').trim()`
|
||||||
|
);
|
||||||
|
renderer.add_string('"');
|
||||||
|
} else if (
|
||||||
|
attribute.chunks.length === 1 &&
|
||||||
|
attribute.chunks[0].type !== 'Text'
|
||||||
|
) {
|
||||||
|
const snippet = (attribute.chunks[0] as Expression).node;
|
||||||
|
renderer.add_expression(
|
||||||
|
x`@add_attribute("${attribute.name}", ${snippet}, ${
|
||||||
|
boolean_attributes.has(name) ? 1 : 0
|
||||||
|
})`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
renderer.add_string(` ${attribute.name}="`);
|
||||||
|
renderer.add_expression(
|
||||||
|
(name === 'class'
|
||||||
|
? get_class_attribute_value
|
||||||
|
: get_attribute_value)(attribute)
|
||||||
|
);
|
||||||
|
renderer.add_string('"');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (add_class_attribute) {
|
||||||
|
renderer.add_expression(
|
||||||
|
x`@add_classes([${class_expression}].join(' ').trim())`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node.bindings.forEach((binding) => {
|
||||||
|
const { name, expression } = binding;
|
||||||
|
|
||||||
|
if (binding.is_readonly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'group') {
|
||||||
|
// TODO server-render group bindings
|
||||||
|
} else if (
|
||||||
|
contenteditable &&
|
||||||
|
(name === 'textContent' || name === 'innerHTML')
|
||||||
|
) {
|
||||||
|
node_contents = expression.node;
|
||||||
|
|
||||||
|
// TODO where was this used?
|
||||||
|
// value = name === 'textContent' ? x`@escape($$value)` : x`$$value`;
|
||||||
|
} else {
|
||||||
|
const snippet = expression.node;
|
||||||
|
renderer.add_expression(x`@add_attribute("${name}", ${snippet}, 1)`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options.hydratable && options.head_id) {
|
||||||
|
renderer.add_string(` data-svelte="${options.head_id}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.add_string('>');
|
||||||
|
|
||||||
|
if (node_contents !== undefined) {
|
||||||
|
if (contenteditable) {
|
||||||
|
renderer.push();
|
||||||
|
renderer.render(children, options);
|
||||||
|
const result = renderer.pop();
|
||||||
|
|
||||||
|
renderer.add_expression(
|
||||||
|
x`($$value => $$value === void 0 ? ${result} : $$value)(${node_contents})`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
renderer.add_expression(node_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.add_string('</');
|
||||||
|
renderer.add_expression(node.tag.node as ESExpression);
|
||||||
|
renderer.add_string('>');
|
||||||
|
} else if (slot && nearest_inline_component) {
|
||||||
|
renderer.render(children, options);
|
||||||
|
|
||||||
|
renderer.add_string('</');
|
||||||
|
renderer.add_expression(node.tag.node as ESExpression);
|
||||||
|
renderer.add_string('>');
|
||||||
|
|
||||||
|
const lets = node.lets;
|
||||||
|
const seen = new Set(lets.map((l) => l.name.name));
|
||||||
|
|
||||||
|
nearest_inline_component.lets.forEach((l) => {
|
||||||
|
if (!seen.has(l.name.name)) lets.push(l);
|
||||||
|
});
|
||||||
|
|
||||||
|
options.slot_scopes.set(slot, {
|
||||||
|
input: get_slot_scope(node.lets),
|
||||||
|
output: renderer.pop()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
renderer.render(children, options);
|
||||||
|
|
||||||
|
renderer.add_string('</');
|
||||||
|
renderer.add_expression(node.tag.node as ESExpression);
|
||||||
|
renderer.add_string('>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svelte:element tag="div"></svelte:element>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"html": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"type": "Fragment",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"type": "DynamicElement",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"attributes": [],
|
||||||
|
"children": [],
|
||||||
|
"tag": "div"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svelte:element tag={tag}></svelte:element>
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"html": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"type": "Fragment",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"type": "DynamicElement",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"attributes": [],
|
||||||
|
"children": [],
|
||||||
|
"tag": {
|
||||||
|
"start": 21,
|
||||||
|
"end": 24,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 21
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "tag",
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
tag: 'div',
|
||||||
|
text: 'Foo'
|
||||||
|
},
|
||||||
|
html: '<div><div>Foo</div></div>',
|
||||||
|
|
||||||
|
test({ assert, component, target }) {
|
||||||
|
const innerDiv = target.querySelector('div > div');
|
||||||
|
component.tag = 'h1';
|
||||||
|
component.text = 'Bar';
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<h1><div>Bar</div></h1>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(innerDiv, target.querySelector('h1 > div'));
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
export let tag = 'div', text = 'Foo';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element tag={tag}>
|
||||||
|
<div>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
</svelte:element>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
tag: 'div'
|
||||||
|
},
|
||||||
|
html: '<div>Foo</div>',
|
||||||
|
|
||||||
|
test({ assert, component, target }) {
|
||||||
|
component.tag = 'h1';
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<h1>Foo</h1>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
export let tag = 'div';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element tag={tag}>Foo</svelte:element>
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
html: '<div>Foo</div>'
|
||||||
|
};
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svelte:element tag={"div"}>Foo</svelte:element>
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
let clicked = false;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
tag: 'div',
|
||||||
|
onClick: () => clicked = true
|
||||||
|
},
|
||||||
|
html: '<div style="display: inline;">Foo</div>',
|
||||||
|
|
||||||
|
async test({ assert, target, window }) {
|
||||||
|
const div = target.querySelector('div');
|
||||||
|
await div.dispatchEvent(new window.MouseEvent('click'));
|
||||||
|
|
||||||
|
assert.equal(clicked, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<script>
|
||||||
|
const tag = "div";
|
||||||
|
export let onClick;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element tag={tag} style="display: inline;" on:click={onClick}>Foo</svelte:element>
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
html: '<div>Foo</div>'
|
||||||
|
};
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svelte:element tag="div">Foo</svelte:element>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
tag: 'di',
|
||||||
|
text: 'Foo'
|
||||||
|
},
|
||||||
|
html: '<div>Foo</div>',
|
||||||
|
|
||||||
|
test({ assert, component, target }) {
|
||||||
|
const div = target.firstChild;
|
||||||
|
component.tag = 'na';
|
||||||
|
component.text = 'Bar';
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `
|
||||||
|
<nav>Bar</nav>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const h1 = target.firstChild;
|
||||||
|
assert.notEqual(div, h1);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<script>
|
||||||
|
export let tag = "di";
|
||||||
|
export let text = "Foo";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element tag={tag + "v"}>{text}</svelte:element>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<div>Foo</div>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svelte:element tag="div">Foo</svelte:element>
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Foo</h1>
|
||||||
|
<div>Bar</div>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
let heading = 'h1';
|
||||||
|
let tag = 'div';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:element tag={heading}>Foo</svelte:element>
|
||||||
|
<svelte:element {tag}>Bar</svelte:element>
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/* test/sourcemaps/samples/two-scripts/input.svelte generated by Svelte vx.xx.x */
|
||||||
|
import {
|
||||||
|
SvelteComponent,
|
||||||
|
detach,
|
||||||
|
init,
|
||||||
|
insert,
|
||||||
|
noop,
|
||||||
|
safe_not_equal,
|
||||||
|
text
|
||||||
|
} from "svelte/internal";
|
||||||
|
|
||||||
|
function create_fragment(ctx) {
|
||||||
|
let t_value = foo.bar.baz + "";
|
||||||
|
let t;
|
||||||
|
|
||||||
|
return {
|
||||||
|
c() {
|
||||||
|
t = text(t_value);
|
||||||
|
},
|
||||||
|
m(target, anchor) {
|
||||||
|
insert(target, t, anchor);
|
||||||
|
},
|
||||||
|
p: noop,
|
||||||
|
i: noop,
|
||||||
|
o: noop,
|
||||||
|
d(detaching) {
|
||||||
|
if (detaching) detach(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let first;
|
||||||
|
|
||||||
|
function assertThisLine() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Input extends SvelteComponent {
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
init(this, options, null, create_fragment, safe_not_equal, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Input;
|
||||||
|
export { first };
|
||||||
|
//# sourceMappingURL=output.js.map
|
||||||
Loading…
Reference in new issue