mirror of https://github.com/sveltejs/svelte
commit
80de680c0a
@ -0,0 +1,12 @@
|
||||
<script>
|
||||
const options = ['h1', 'h3', 'p'];
|
||||
let selected = options[0];
|
||||
</script>
|
||||
|
||||
<select bind:value={selected}>
|
||||
{#each options as option}
|
||||
<option value={option}>{option}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"title": "<svelte:element>"
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
const options = ['h1', 'h3', 'p'];
|
||||
let selected = options[0];
|
||||
</script>
|
||||
|
||||
<select bind:value={selected}>
|
||||
{#each options as option}
|
||||
<option value={option}>{option}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
{#if selected === 'h1'}
|
||||
<h1>I'm a h1 tag</h1>
|
||||
{:else if selected === 'h3'}
|
||||
<h3>I'm a h3 tag</h3>
|
||||
{:else if selected === 'p'}
|
||||
<p>I'm a p tag</p>
|
||||
{/if}
|
||||
@ -0,0 +1,12 @@
|
||||
<script>
|
||||
const options = ['h1', 'h3', 'p'];
|
||||
let selected = options[0];
|
||||
</script>
|
||||
|
||||
<select bind:value={selected}>
|
||||
{#each options as option}
|
||||
<option value={option}>{option}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: <svelte:element>
|
||||
---
|
||||
|
||||
Sometimes we don't know in advance what kind of DOM element to render. `<svelte:element>` comes in handy here. Instead of a sequence of `if` blocks...
|
||||
|
||||
```html
|
||||
{#if selected === 'h1'}
|
||||
<h1>I'm a h1 tag</h1>
|
||||
{:else if selected === 'h3'}
|
||||
<h3>I'm a h3 tag</h3>
|
||||
{:else if selected === 'p'}
|
||||
<p>I'm a p tag</p>
|
||||
{/if}
|
||||
```
|
||||
|
||||
...we can have a single dynamic component:
|
||||
|
||||
```html
|
||||
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||
```
|
||||
|
||||
The `this` value can be any string, or a falsy value — if it's falsy, no element is rendered.
|
||||
@ -0,0 +1,21 @@
|
||||
export default {
|
||||
warnings: [
|
||||
{
|
||||
code: 'css-unused-selector',
|
||||
end: {
|
||||
character: 86,
|
||||
column: 8,
|
||||
line: 7
|
||||
},
|
||||
frame:
|
||||
' 5: color: red;\n 6: }\n 7: .unused {\n ^\n 8: font-style: italic;\n 9: }',
|
||||
message: 'Unused CSS selector ".unused"',
|
||||
pos: 79,
|
||||
start: {
|
||||
character: 79,
|
||||
column: 1,
|
||||
line: 7
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
.used.svelte-xyz{color:red}
|
||||
@ -0,0 +1 @@
|
||||
<div class="used svelte-xyz"></div>
|
||||
@ -0,0 +1,10 @@
|
||||
<svelte:element this="div" class="used" />
|
||||
|
||||
<style>
|
||||
.used {
|
||||
color: red;
|
||||
}
|
||||
.unused {
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,2 @@
|
||||
<svelte:element this="div"></svelte:element>
|
||||
<svelte:element this="div" class="foo"></svelte:element>
|
||||
@ -0,0 +1,50 @@
|
||||
{
|
||||
"html": {
|
||||
"start": 0,
|
||||
"end": 101,
|
||||
"type": "Fragment",
|
||||
"children": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 44,
|
||||
"type": "Element",
|
||||
"name": "svelte:element",
|
||||
"attributes": [],
|
||||
"children": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"start": 44,
|
||||
"end": 45,
|
||||
"data": "\n",
|
||||
"raw": "\n"
|
||||
},
|
||||
{
|
||||
"start": 45,
|
||||
"end": 101,
|
||||
"type": "Element",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
<svelte:element this={tag}></svelte:element>
|
||||
<svelte:element this={tag} class="foo"></svelte:element>
|
||||
@ -0,0 +1,80 @@
|
||||
{
|
||||
"html": {
|
||||
"start": 0,
|
||||
"end": 101,
|
||||
"type": "Fragment",
|
||||
"children": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 44,
|
||||
"type": "Element",
|
||||
"name": "svelte:element",
|
||||
"attributes": [],
|
||||
"children": [],
|
||||
"tag": {
|
||||
"start": 22,
|
||||
"end": 25,
|
||||
"loc": {
|
||||
"start": {
|
||||
"line": 1,
|
||||
"column": 22
|
||||
},
|
||||
"end": {
|
||||
"line": 1,
|
||||
"column": 25
|
||||
}
|
||||
},
|
||||
"name": "tag",
|
||||
"type": "Identifier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"start": 44,
|
||||
"end": 45,
|
||||
"data": "\n",
|
||||
"raw": "\n"
|
||||
},
|
||||
{
|
||||
"start": 45,
|
||||
"end": 101,
|
||||
"type": "Element",
|
||||
"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",
|
||||
"type": "Identifier"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.nums = [1, 2, 3];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
|
||||
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
<script>
|
||||
export let nums = [1, 2];
|
||||
let foos = [
|
||||
{
|
||||
nums: [1, 2, 3],
|
||||
},
|
||||
{
|
||||
nums: [0, 2, 4],
|
||||
},
|
||||
{
|
||||
nums: [-100, 0, 100],
|
||||
},
|
||||
];
|
||||
let foo = 0;
|
||||
</script>
|
||||
|
||||
<p>{foo}</p>
|
||||
{#each nums as num, index}
|
||||
{@const bar = nums.map((num) => {
|
||||
const func = (foos, num) => {
|
||||
return [...foos.map((foo) => foo), num];
|
||||
}
|
||||
return func(foos[index].nums, num);
|
||||
})}
|
||||
<p>bar: {bar}, num: {num}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.nums = [1, 2, 3, 4];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 4</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
<script>
|
||||
export let nums = [1, 2, 3];
|
||||
let foos = [
|
||||
{
|
||||
nums: [1, 2, 3],
|
||||
},
|
||||
{
|
||||
nums: [0, 2, 4],
|
||||
},
|
||||
{
|
||||
nums: [-100, 0, 100],
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
{#each nums as num}
|
||||
{@const bar = foos.map((foos) => foos.nums)}
|
||||
<p>bar: {bar}, num: {num}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,32 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>foo: dummy-foo, num: dummy-num</p>
|
||||
<p>bar: 1,2,3,2,, num: 1</p>
|
||||
<p>bar: 1,2,3,2,, num: 2</p>
|
||||
<p>bar: 1,2,3,2,, num: 3</p>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>foo: dummy-foo, num: dummy-num</p>
|
||||
<p>bar: 1,2,3,2,, num: 1</p>
|
||||
<p>bar: 1,2,3,2,, num: 2</p>
|
||||
<p>bar: 1,2,3,2,, num: 3</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.nums = [1, 2, 3, 4];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>foo: dummy-foo, num: dummy-num</p>
|
||||
<p>bar: 1,2,3,2,4,, num: 1</p>
|
||||
<p>bar: 1,2,3,2,4,, num: 2</p>
|
||||
<p>bar: 1,2,3,2,4,, num: 3</p>
|
||||
<p>bar: 1,2,3,2,4,, num: 4</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,33 @@
|
||||
<script>
|
||||
export let nums = [1, 2, 3];
|
||||
let foos = [
|
||||
{
|
||||
nums: [1, 2, 3],
|
||||
},
|
||||
{
|
||||
nums: [0, 2, 4],
|
||||
},
|
||||
{
|
||||
nums: [-100, 0, 100],
|
||||
},
|
||||
];
|
||||
let default_nums = [-1];
|
||||
let foo = "dummy-foo";
|
||||
let num = "dummy-num";
|
||||
</script>
|
||||
|
||||
<p>foo: {foo}, num: {num}</p>
|
||||
{#each nums as num}
|
||||
{@const bar = foos.map((foo) =>
|
||||
foo.nums.filter((num) => {
|
||||
if (Object.keys($$slots).length) {
|
||||
return false;
|
||||
} else if (Object.keys(foo).length) {
|
||||
return nums.includes(num) || default_nums.includes(num);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}) || num
|
||||
)}
|
||||
<p>bar: {bar}, num: {num}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.nums = [1, 2, 3];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
|
||||
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,25 @@
|
||||
<script>
|
||||
export let nums = [1, 2];
|
||||
let foos = [
|
||||
{
|
||||
nums: [1, 2, 3],
|
||||
},
|
||||
{
|
||||
nums: [0, 2, 4],
|
||||
},
|
||||
{
|
||||
nums: [-100, 0, 100],
|
||||
},
|
||||
];
|
||||
let foo = 0;
|
||||
</script>
|
||||
|
||||
<p>{foo}</p>
|
||||
{#each nums as num, index}
|
||||
{@const bar = nums.map((num) => {
|
||||
return (function (foos, num) {
|
||||
return [...foos.map((foo) => foo), num];
|
||||
})(foos[index].nums, num);
|
||||
})}
|
||||
<p>bar: {bar}, num: {num}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.nums = [1, 2, 3];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>0</p>
|
||||
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
|
||||
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
|
||||
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
<script>
|
||||
export let nums = [1, 2];
|
||||
let foos = [
|
||||
{
|
||||
nums: [1, 2, 3],
|
||||
},
|
||||
{
|
||||
nums: [0, 2, 4],
|
||||
},
|
||||
{
|
||||
nums: [-100, 0, 100],
|
||||
},
|
||||
];
|
||||
let foo = 0;
|
||||
</script>
|
||||
|
||||
<p>{foo}</p>
|
||||
{#each nums as num, index}
|
||||
{@const bar = nums.map((num) => {
|
||||
function func(foos, num) {
|
||||
return [...foos.map((foo) => foo), num];
|
||||
}
|
||||
return func(foos[index].nums, num);
|
||||
})}
|
||||
<p>bar: {bar}, num: {num}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,37 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>1</p>
|
||||
<p>3,6,9</p>
|
||||
<p>2</p>
|
||||
<p>3,6,9</p>
|
||||
<p>3</p>
|
||||
<p>3,6,9</p>
|
||||
`,
|
||||
test({ component, target, assert }) {
|
||||
component.baz = 5;
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>1</p>
|
||||
<p>5,10,15</p>
|
||||
<p>2</p>
|
||||
<p>5,10,15</p>
|
||||
<p>3</p>
|
||||
<p>5,10,15</p>
|
||||
`
|
||||
);
|
||||
|
||||
component.array = [3, 4, 5];
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<p>3</p>
|
||||
<p>15,20,25</p>
|
||||
<p>4</p>
|
||||
<p>15,20,25</p>
|
||||
<p>5</p>
|
||||
<p>15,20,25</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
<script>
|
||||
export let array = [1, 2, 3];
|
||||
export let baz = 3;
|
||||
const foo = (item) => item;
|
||||
</script>
|
||||
|
||||
{#each array as item}
|
||||
<p>{foo(item)}</p>
|
||||
{@const bar = array.map((item) => {
|
||||
const bar = baz;
|
||||
const foo = (item) => item * bar;
|
||||
return foo(item);
|
||||
})}
|
||||
<p>{bar}</p>
|
||||
{/each}
|
||||
@ -0,0 +1,5 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>true</div>
|
||||
`
|
||||
};
|
||||
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
import { setContext } from 'svelte';
|
||||
const a = {};
|
||||
const b = setContext('foo', a);
|
||||
</script>
|
||||
|
||||
<div>{a === b}</div>
|
||||
@ -0,0 +1,45 @@
|
||||
let logs = [];
|
||||
|
||||
export default {
|
||||
html: `
|
||||
<h1>tag is h1.</h1>
|
||||
`,
|
||||
props: {
|
||||
logs
|
||||
},
|
||||
after_test() {
|
||||
logs = [];
|
||||
},
|
||||
|
||||
async test({ assert, component, target }) {
|
||||
assert.equal(component.tag, 'h1');
|
||||
|
||||
assert.deepEqual(logs, ['create: h1,opt1']);
|
||||
component.opt = 'opt2';
|
||||
|
||||
assert.equal(component.tag, 'h1');
|
||||
assert.deepEqual(logs, ['create: h1,opt1', 'update: h1,opt2']);
|
||||
|
||||
component.tag = 'h2';
|
||||
|
||||
assert.equal(component.tag, 'h2');
|
||||
assert.deepEqual(logs, [
|
||||
'create: h1,opt1',
|
||||
'update: h1,opt2',
|
||||
'destroy',
|
||||
'create: h2,opt2'
|
||||
]);
|
||||
assert.htmlEqual(target.innerHTML, '<h2>tag is h2.</h2>');
|
||||
|
||||
component.tag = false;
|
||||
assert.deepEqual(logs, [
|
||||
'create: h1,opt1',
|
||||
'update: h1,opt2',
|
||||
'destroy',
|
||||
'create: h2,opt2',
|
||||
'destroy'
|
||||
]);
|
||||
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
<script>
|
||||
export let logs = [];
|
||||
export let tag = "h1";
|
||||
export let opt = "opt1";
|
||||
function foo(node, {tag, opt}) {
|
||||
logs.push(`create: ${tag},${opt}`);
|
||||
return {
|
||||
update: ({tag, opt}) => logs.push(`update: ${tag},${opt}`),
|
||||
destroy: () => logs.push('destroy'),
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} use:foo={{tag, opt}}>tag is {tag}.</svelte:element>
|
||||
@ -0,0 +1,105 @@
|
||||
let originalDivGetBoundingClientRect;
|
||||
let originalSpanGetBoundingClientRect;
|
||||
let originalParagraphGetBoundingClientRect;
|
||||
|
||||
export default {
|
||||
skip_if_ssr: true,
|
||||
props: {
|
||||
things: [
|
||||
{ id: 1, name: 'a' },
|
||||
{ id: 2, name: 'b' },
|
||||
{ id: 3, name: 'c' },
|
||||
{ id: 4, name: 'd' },
|
||||
{ id: 5, name: 'e' }
|
||||
],
|
||||
tag: 'div'
|
||||
},
|
||||
|
||||
html: `
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>c</div>
|
||||
<div>d</div>
|
||||
<div>e</div>
|
||||
`,
|
||||
|
||||
before_test() {
|
||||
originalDivGetBoundingClientRect =
|
||||
window.HTMLDivElement.prototype.getBoundingClientRect;
|
||||
originalSpanGetBoundingClientRect =
|
||||
window.HTMLSpanElement.prototype.getBoundingClientRect;
|
||||
originalParagraphGetBoundingClientRect =
|
||||
window.HTMLParagraphElement.prototype.getBoundingClientRect;
|
||||
|
||||
window.HTMLDivElement.prototype.getBoundingClientRect =
|
||||
fakeGetBoundingClientRect;
|
||||
window.HTMLSpanElement.prototype.getBoundingClientRect =
|
||||
fakeGetBoundingClientRect;
|
||||
window.HTMLParagraphElement.prototype.getBoundingClientRect =
|
||||
fakeGetBoundingClientRect;
|
||||
|
||||
function fakeGetBoundingClientRect() {
|
||||
const index = [...this.parentNode.children].indexOf(this);
|
||||
const top = index * 30;
|
||||
|
||||
return {
|
||||
left: 0,
|
||||
right: 100,
|
||||
top,
|
||||
bottom: top + 20
|
||||
};
|
||||
}
|
||||
},
|
||||
after_test() {
|
||||
window.HTMLDivElement.prototype.getBoundingClientRect =
|
||||
originalDivGetBoundingClientRect;
|
||||
window.HTMLSpanElement.prototype.getBoundingClientRect =
|
||||
originalSpanGetBoundingClientRect;
|
||||
window.HTMLParagraphElement.prototype.getBoundingClientRect =
|
||||
originalParagraphGetBoundingClientRect;
|
||||
},
|
||||
|
||||
async test({ assert, component, target, raf }) {
|
||||
// switch tag and things at the same time
|
||||
await component.update('p', [
|
||||
{ id: 5, name: 'e' },
|
||||
{ id: 2, name: 'b' },
|
||||
{ id: 3, name: 'c' },
|
||||
{ id: 4, name: 'd' },
|
||||
{ id: 1, name: 'a' }
|
||||
]);
|
||||
|
||||
const ps = document.querySelectorAll('p');
|
||||
assert.equal(ps[0].dy, 120);
|
||||
assert.equal(ps[4].dy, -120);
|
||||
|
||||
raf.tick(50);
|
||||
assert.equal(ps[0].dy, 60);
|
||||
assert.equal(ps[4].dy, -60);
|
||||
|
||||
raf.tick(100);
|
||||
assert.equal(ps[0].dy, 0);
|
||||
assert.equal(ps[4].dy, 0);
|
||||
|
||||
await component.update('span', [
|
||||
{ id: 1, name: 'a' },
|
||||
{ id: 2, name: 'b' },
|
||||
{ id: 3, name: 'c' },
|
||||
{ id: 4, name: 'd' },
|
||||
{ id: 5, name: 'e' }
|
||||
]);
|
||||
|
||||
const spans = document.querySelectorAll('span');
|
||||
|
||||
assert.equal(spans[0].dy, 120);
|
||||
assert.equal(spans[4].dy, -120);
|
||||
|
||||
raf.tick(150);
|
||||
assert.equal(spans[0].dy, 60);
|
||||
assert.equal(spans[4].dy, -60);
|
||||
|
||||
raf.tick(200);
|
||||
assert.equal(spans[0].dy, 0);
|
||||
assert.equal(spans[4].dy, 0);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
<script>
|
||||
export let things;
|
||||
export let tag;
|
||||
|
||||
function flip(node, animation, params) {
|
||||
const dx = animation.from.left - animation.to.left;
|
||||
const dy = animation.from.top - animation.to.top;
|
||||
|
||||
return {
|
||||
duration: 100,
|
||||
tick: (t, u) => {
|
||||
node.dx = u * dx;
|
||||
node.dy = u * dy;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function update(new_tag, new_things) {
|
||||
things = new_things;
|
||||
tag = new_tag;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each things as thing (thing.id)}
|
||||
<svelte:element this={tag} animate:flip>{thing.name}</svelte:element>
|
||||
{/each}
|
||||
@ -0,0 +1,62 @@
|
||||
export default {
|
||||
props: {
|
||||
things: [
|
||||
{ id: 1, name: 'a' },
|
||||
{ id: 2, name: 'b' },
|
||||
{ id: 3, name: 'c' },
|
||||
{ id: 4, name: 'd' },
|
||||
{ id: 5, name: 'e' }
|
||||
],
|
||||
tag: 'div'
|
||||
},
|
||||
|
||||
html: `
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>c</div>
|
||||
<div>d</div>
|
||||
<div>e</div>
|
||||
`,
|
||||
|
||||
test({ assert, component, target, raf }) {
|
||||
component.tag = 'p';
|
||||
assert.equal(target.querySelectorAll('p').length, 5);
|
||||
|
||||
component.tag = 'div';
|
||||
let divs = target.querySelectorAll('div');
|
||||
divs.forEach(div => {
|
||||
div.getBoundingClientRect = function() {
|
||||
const index = [...this.parentNode.children].indexOf(this);
|
||||
const top = index * 30;
|
||||
|
||||
return {
|
||||
left: 0,
|
||||
right: 100,
|
||||
top,
|
||||
bottom: top + 20
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
component.things = [
|
||||
{ id: 5, name: 'e' },
|
||||
{ id: 2, name: 'b' },
|
||||
{ id: 3, name: 'c' },
|
||||
{ id: 4, name: 'd' },
|
||||
{ id: 1, name: 'a' }
|
||||
];
|
||||
|
||||
divs = target.querySelectorAll('div');
|
||||
assert.ok(~divs[0].style.animation.indexOf('__svelte'));
|
||||
assert.equal(divs[1].style.animation, '');
|
||||
assert.equal(divs[2].style.animation, '');
|
||||
assert.equal(divs[3].style.animation, '');
|
||||
assert.ok(~divs[4].style.animation.indexOf('__svelte'));
|
||||
|
||||
raf.tick(100);
|
||||
assert.deepEqual([
|
||||
divs[0].style.animation,
|
||||
divs[4].style.animation
|
||||
], ['', '']);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
export let things;
|
||||
export let tag;
|
||||
|
||||
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>{thing.name}</svelte:element>
|
||||
{/each}
|
||||
@ -0,0 +1,17 @@
|
||||
export default {
|
||||
props: {
|
||||
tag: 'div'
|
||||
},
|
||||
html: '<div style="color: red;">Foo</div>',
|
||||
|
||||
test({ assert, component, target }) {
|
||||
component.tag = 'h1';
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<h1 style="color: red;">Foo</h1>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
export let tag = 'div';
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} style="color: red;">Foo</svelte:element>
|
||||
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
error: "'value' is not a valid binding on <svelte:element> elements"
|
||||
};
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
const tag = "div";
|
||||
let value;
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} bind:value></svelte:element>
|
||||
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
html: '<div></div>',
|
||||
|
||||
test({ assert, component, target }) {
|
||||
const div = target.querySelector('div');
|
||||
assert.equal(div, component.foo);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
const tag = "div";
|
||||
export let foo;
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} bind:this={foo}></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 this={tag}>Foo</svelte:element>
|
||||
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
html: ''
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
let tag = '';
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag}>Foo</svelte:element>
|
||||
@ -0,0 +1,21 @@
|
||||
let clicked = false;
|
||||
function handler() {
|
||||
clicked = true;
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
handler
|
||||
},
|
||||
html: '<button>Foo</button>',
|
||||
|
||||
test({ assert, target }) {
|
||||
assert.equal(clicked, false);
|
||||
|
||||
const button = target.querySelector('button');
|
||||
const click = new window.MouseEvent('click');
|
||||
button.dispatchEvent(click);
|
||||
|
||||
assert.equal(clicked, true);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
const tag = "button";
|
||||
export let handler;
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} on:click={handler}>Foo</svelte:element>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue