tag -> this

pull/5481/head
Simon Holthausen 5 years ago
parent 7d308cbb95
commit bd41b85d31

@ -1551,7 +1551,7 @@ If `this` is falsy, no component is rendered.
### `<svelte:element>`
```sv
<svelte:element tag={expression}/>
<svelte:element this={expression}/>
```
---
@ -1560,7 +1560,7 @@ The `<svelte:element>` element lets you render an element of a dynamically speci
The only supported binding is `bind:this`, since the element type specific bindings that Svelte does at build time (e.g. `bind:value` for input elements) does not work with a dynamic tag type.
If `tag` has a nullish value, a warning will be logged in development mode.
If `this` has a nullish value, a warning will be logged in development mode.
```sv
<script>
@ -1568,7 +1568,7 @@ If `tag` has a nullish value, a warning will be logged in development mode.
export let handler;
</script>
<svelte:element {tag} on:click={handler}>Foo</svelte:element>
<svelte:element this={tag} on:click={handler}>Foo</svelte:element>
```
### `<svelte:window>`

@ -99,6 +99,10 @@ export default {
code: `invalid-${slug}-content`,
message: `<${name}> cannot have children`
}),
invalid_element_definition: {
code: 'invalid-element-definition',
message: 'Invalid element definition'
},
invalid_element_placement: (slug: string, name: string) => ({
code: `invalid-${slug}-placement`,
message: `<${name}> tags cannot be inside elements or blocks`
@ -161,6 +165,10 @@ export default {
code: 'missing-attribute-value',
message: 'Expected value for the attribute'
},
missing_element_definition: {
code: 'missing-element-definition',
message: '<svelte:element> must have a \'this\' attribute'
},
unclosed_script: {
code: 'unclosed-script',
message: '<script> must have a closing tag'

@ -184,20 +184,15 @@ export default function tag(parser: Parser) {
}
if (name === 'svelte:element') {
const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'tag');
const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this');
if (index === -1) {
parser.error({
code: 'missing-element-definition',
message: '<svelte:element> must have a \'tag\' attribute'
}, start);
parser.error(parser_errors.missing_element_definition, start);
}
const definition = element.attributes.splice(index, 1)[0];
if (definition.value === true || definition.value.length !== 1 || (definition.value[0].type !== 'Text' && definition.value[0].type !== 'MustacheTag' && definition.value[0].type !== 'AttributeShorthand')) {
parser.error({
code: 'invalid-element-definition',
message: 'invalid element definition'
}, definition.start);
if (definition.value === true || definition.value.length !== 1 ||
(definition.value[0].type !== 'Text' && definition.value[0].type !== 'MustacheTag' && definition.value[0].type !== 'AttributeShorthand')) {
parser.error(parser_errors.invalid_element_definition, definition.start);
}
element.tag = definition.value[0].data || definition.value[0].expression;

@ -109,7 +109,7 @@ export function validate_slots(name, slot, keys) {
export function validate_dynamic_element(tag) {
if (tag == null) {
console.warn('<svelte:element> expects a non-nullish value in attribute "tag"');
console.warn('<svelte:element> expects a non-nullish value in attribute "this"');
}
}

@ -1 +1,2 @@
<svelte:element tag="div"></svelte:element>
<svelte:element this="div"></svelte:element>
<svelte:element this="div" class="foo"></svelte:element>

@ -1,18 +1,50 @@
{
"html": {
"start": 0,
"end": 43,
"end": 101,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 43,
"end": 44,
"type": "DynamicElement",
"name": "svelte:element",
"attributes": [],
"children": [],
"tag": "div"
},
{
"type": "Text",
"start": 44,
"end": 45,
"data": "\n",
"raw": "\n"
},
{
"start": 45,
"end": 101,
"type": "DynamicElement",
"name": "svelte:element",
"attributes": [
{
"type": "Attribute",
"start": 72,
"end": 83,
"name": "class",
"value": [
{
"type": "Text",
"start": 79,
"end": 82,
"data": "foo",
"raw": "foo"
}
]
}
],
"children": [],
"tag": "div"
}
]
}
}
}

@ -1 +1,2 @@
<svelte:element tag={tag}></svelte:element>
<svelte:element this={tag}></svelte:element>
<svelte:element this={tag} class="foo"></svelte:element>

@ -1,27 +1,74 @@
{
"html": {
"start": 0,
"end": 43,
"end": 101,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 43,
"end": 44,
"type": "DynamicElement",
"name": "svelte:element",
"attributes": [],
"children": [],
"tag": {
"start": 21,
"end": 24,
"start": 22,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 21
"column": 22
},
"end": {
"line": 1,
"column": 24
"column": 25
}
},
"name": "tag",
"type": "Identifier"
}
},
{
"type": "Text",
"start": 44,
"end": 45,
"data": "\n",
"raw": "\n"
},
{
"start": 45,
"end": 101,
"type": "DynamicElement",
"name": "svelte:element",
"children": [],
"attributes": [
{
"type": "Attribute",
"start": 72,
"end": 83,
"name": "class",
"value": [
{
"type": "Text",
"start": 79,
"end": 82,
"data": "foo",
"raw": "foo"
}
]
}
],
"tag": {
"start": 67,
"end": 70,
"loc": {
"start": {
"line": 2,
"column": 22
},
"end": {
"line": 2,
"column": 25
}
},
"name": "tag",

@ -4,6 +4,6 @@ export default {
},
warnings: [
'<svelte:element> expects a non-nullish value in attribute "tag"'
'<svelte:element> expects a non-nullish value in attribute "this"'
]
};

@ -2,4 +2,4 @@
let tag = null;
</script>
<svelte:element {tag}></svelte:element>
<svelte:element this={tag}></svelte:element>

@ -3,4 +3,4 @@
let value;
</script>
<svelte:element tag={tag} bind:value></svelte:element>
<svelte:element this={tag} bind:value></svelte:element>

@ -3,4 +3,4 @@
export let foo;
</script>
<svelte:element tag={tag} bind:this={foo}></svelte:element>
<svelte:element this={tag} bind:this={foo}></svelte:element>

@ -2,4 +2,4 @@
export let tag = 'div';
</script>
<svelte:element tag={tag}>Foo</svelte:element>
<svelte:element this={tag}>Foo</svelte:element>

@ -3,4 +3,4 @@
export let handler;
</script>
<svelte:element tag={tag} on:click={handler}>Foo</svelte:element>
<svelte:element this={tag} on:click={handler}>Foo</svelte:element>

@ -1 +1 @@
<svelte:element tag={"div"}>Foo</svelte:element>
<svelte:element this={"div"}>Foo</svelte:element>

@ -3,4 +3,4 @@
export let onClick;
</script>
<svelte:element tag={tag} style="display: inline;" on:click={onClick}>Foo</svelte:element>
<svelte:element this={tag} style="display: inline;" on:click={onClick}>Foo</svelte:element>

@ -2,7 +2,7 @@
export let tag = 'div', text = 'Foo';
</script>
<svelte:element tag={tag}>
<svelte:element this={tag}>
<div>
{text}
</div>

@ -3,4 +3,4 @@
const foo = writable('div');
</script>
<svelte:element tag={$foo}></svelte:element>
<svelte:element this={$foo}></svelte:element>

@ -1 +1 @@
<svelte:element tag="div">Foo</svelte:element>
<svelte:element this="div">Foo</svelte:element>

@ -3,4 +3,4 @@
export let text = "Foo";
</script>
<svelte:element tag={tag}>{text}</svelte:element>
<svelte:element this={tag}>{text}</svelte:element>

@ -1 +1 @@
<svelte:element tag="div">Foo</svelte:element>
<svelte:element this="div">Foo</svelte:element>

@ -3,5 +3,5 @@
let tag = 'div';
</script>
<svelte:element tag={heading}>Foo</svelte:element>
<svelte:element {tag}>Bar</svelte:element>
<svelte:element this={heading}>Foo</svelte:element>
<svelte:element this={tag}>Bar</svelte:element>
Loading…
Cancel
Save