mirror of https://github.com/sveltejs/svelte
commit
63217887f9
@ -1,26 +1,23 @@
|
|||||||
import Block from '../Block';
|
import Block from '../Block';
|
||||||
import Wrapper from './shared/Wrapper';
|
import Wrapper from './shared/Wrapper';
|
||||||
import { b } from 'code-red';
|
import { x } from 'code-red';
|
||||||
import Body from '../../nodes/Body';
|
import Body from '../../nodes/Body';
|
||||||
import { Identifier } from 'estree';
|
import { Identifier } from 'estree';
|
||||||
import EventHandler from './Element/EventHandler';
|
import EventHandler from './Element/EventHandler';
|
||||||
|
import add_event_handlers from './shared/add_event_handlers';
|
||||||
|
import { TemplateNode } from '../../../interfaces';
|
||||||
|
import Renderer from '../Renderer';
|
||||||
|
|
||||||
export default class BodyWrapper extends Wrapper {
|
export default class BodyWrapper extends Wrapper {
|
||||||
node: Body;
|
node: Body;
|
||||||
|
handlers: EventHandler[];
|
||||||
|
|
||||||
render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
|
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: TemplateNode) {
|
||||||
this.node.handlers
|
super(renderer, block, parent, node);
|
||||||
.map(handler => new EventHandler(handler, this))
|
this.handlers = this.node.handlers.map(handler => new EventHandler(handler, this));
|
||||||
.forEach(handler => {
|
}
|
||||||
const snippet = handler.get_snippet(block);
|
|
||||||
|
|
||||||
block.chunks.init.push(b`
|
|
||||||
@_document.body.addEventListener("${handler.node.name}", ${snippet});
|
|
||||||
`);
|
|
||||||
|
|
||||||
block.chunks.destroy.push(b`
|
render(block: Block, _parent_node: Identifier, _parent_nodes: Identifier) {
|
||||||
@_document.body.removeEventListener("${handler.node.name}", ${snippet});
|
add_event_handlers(block, x`@_document.body`, this.handlers);
|
||||||
`);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import * as acorn from 'acorn';
|
import { Node } from 'acorn';
|
||||||
|
import * as code_red from 'code-red';
|
||||||
|
|
||||||
const Parser = acorn.Parser;
|
export const parse = (source: string): Node => code_red.parse(source, {
|
||||||
|
|
||||||
export const parse = (source: string) => Parser.parse(source, {
|
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaVersion: 11,
|
ecmaVersion: 11,
|
||||||
locations: true
|
locations: true
|
||||||
});
|
});
|
||||||
|
|
||||||
export const parse_expression_at = (source: string, index: number) => Parser.parseExpressionAt(source, index, {
|
export const parse_expression_at = (source: string, index: number): Node => code_red.parseExpressionAt(source, index, {
|
||||||
ecmaVersion: 11,
|
ecmaVersion: 11,
|
||||||
locations: true
|
locations: true
|
||||||
});
|
});
|
@ -0,0 +1 @@
|
|||||||
|
.foo.svelte-xyz{color:red}[class~="bar"].svelte-xyz{background:blue}
|
@ -0,0 +1,13 @@
|
|||||||
|
<div class="
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
"></div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.foo {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
[class~="bar"] {
|
||||||
|
background: blue;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,24 @@
|
|||||||
|
export default {
|
||||||
|
warnings: [{
|
||||||
|
code: 'css-unused-selector',
|
||||||
|
end: {
|
||||||
|
character: 27,
|
||||||
|
column: 19,
|
||||||
|
line: 2
|
||||||
|
},
|
||||||
|
frame: `
|
||||||
|
1: <style>
|
||||||
|
2: :global(.foo) .bar {
|
||||||
|
^
|
||||||
|
3: color: red;
|
||||||
|
4: }
|
||||||
|
`,
|
||||||
|
message: 'Unused CSS selector',
|
||||||
|
pos: 9,
|
||||||
|
start: {
|
||||||
|
character: 9,
|
||||||
|
column: 1,
|
||||||
|
line: 2
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
<style>
|
||||||
|
:global(.foo) .bar {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1 +1 @@
|
|||||||
<div class='foo'></div>
|
<div class='foo' title='bar'></div>
|
@ -1,4 +1,4 @@
|
|||||||
<title data-svelte="svelte-1s8aodm">Some Title</title>
|
<title>Some Title</title>
|
||||||
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
|
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
|
||||||
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
|
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
|
||||||
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
|
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
|
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"code": "duplicate-attribute",
|
||||||
|
"message": "Attributes need to be unique",
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 17,
|
||||||
|
"character": 17
|
||||||
|
},
|
||||||
|
"pos": 17
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
<Widget foo={42} bind:foo/>
|
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"code": "duplicate-attribute",
|
||||||
|
"message": "Attributes need to be unique",
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 17,
|
||||||
|
"character": 17
|
||||||
|
},
|
||||||
|
"pos": 17
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
<div title='foo' {title}></div>
|
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
export let x;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot name="foo" reflected={x}/>
|
@ -0,0 +1,22 @@
|
|||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<span slot="foo" class="1">1</span>
|
||||||
|
0
|
||||||
|
`,
|
||||||
|
async test({ assert, target, component, window }) {
|
||||||
|
component.x = 2;
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `
|
||||||
|
<span slot="foo" class="2">2</span>
|
||||||
|
0
|
||||||
|
`);
|
||||||
|
|
||||||
|
const span = target.querySelector('span');
|
||||||
|
await span.dispatchEvent(new window.MouseEvent('click'));
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `
|
||||||
|
<span slot="foo" class="2">2</span>
|
||||||
|
2
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,17 @@
|
|||||||
|
<script>
|
||||||
|
import A from './A.svelte';
|
||||||
|
export let x = 1;
|
||||||
|
let y = 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<A {x}>
|
||||||
|
<span
|
||||||
|
on:click={() => y = reflected}
|
||||||
|
slot="foo"
|
||||||
|
let:reflected
|
||||||
|
class={reflected}
|
||||||
|
>
|
||||||
|
{reflected}
|
||||||
|
</span>
|
||||||
|
</A>
|
||||||
|
{ y }
|
@ -0,0 +1,2 @@
|
|||||||
|
Display:
|
||||||
|
<slot></slot>
|
@ -0,0 +1,6 @@
|
|||||||
|
<script>
|
||||||
|
let val;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input bind:value={val} />
|
||||||
|
<slot {val}></slot>
|
@ -0,0 +1,30 @@
|
|||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<input>
|
||||||
|
`,
|
||||||
|
async test({ assert, target, snapshot, component, window }) {
|
||||||
|
const input = target.querySelector('input');
|
||||||
|
|
||||||
|
input.value = 'a';
|
||||||
|
await input.dispatchEvent(new window.Event('input'));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<input>
|
||||||
|
Display: a
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
input.value = 'abc';
|
||||||
|
await input.dispatchEvent(new window.Event('input'));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<input>
|
||||||
|
Display: abc
|
||||||
|
`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1,10 @@
|
|||||||
|
<script>
|
||||||
|
import Input from "./Input.svelte";
|
||||||
|
import Display from "./Display.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Input let:val={foo}>
|
||||||
|
{#if foo}
|
||||||
|
<Display>{foo}</Display>
|
||||||
|
{/if}
|
||||||
|
</Input>
|
@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
async test({ assert, component, window }) {
|
||||||
|
const event = new window.MouseEvent('click');
|
||||||
|
|
||||||
|
await window.document.body.dispatchEvent(event);
|
||||||
|
assert.equal(component.count, 1);
|
||||||
|
|
||||||
|
await window.document.body.dispatchEvent(event);
|
||||||
|
assert.equal(component.count, 1);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
export let count = 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:body on:click|once="{() => count += 1}"/>
|
@ -0,0 +1,7 @@
|
|||||||
|
export default {
|
||||||
|
compileOptions: {
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
|
||||||
|
error: `Cannot have duplicate keys in a keyed each`
|
||||||
|
};
|
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
const array = [1, 2, 3, 1];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each array as item (item)}
|
||||||
|
{item}
|
||||||
|
{/each}
|
@ -0,0 +1 @@
|
|||||||
|
Child
|
@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
test({ assert, component }) {
|
||||||
|
const { count } = component;
|
||||||
|
assert.deepEqual(count, 1);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,16 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import Child from './Child.svelte';
|
||||||
|
|
||||||
|
let root;
|
||||||
|
export let count = 0;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (count < 5) {
|
||||||
|
count++;
|
||||||
|
new Child({ target: root });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={root}></div>
|
@ -0,0 +1,13 @@
|
|||||||
|
import { writable } from '../../../../store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<p>undefined</p>
|
||||||
|
`,
|
||||||
|
async test({ assert, component, target }) {
|
||||||
|
component.store = writable('foo');
|
||||||
|
assert.htmlEqual(target.innerHTML, `
|
||||||
|
<p>foo</p>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
export let store;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{$store}</p>
|
@ -1,4 +1,4 @@
|
|||||||
<title data-svelte="svelte-1s8aodm">Some Title</title>
|
<title>Some Title</title>
|
||||||
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
|
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
|
||||||
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
|
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
|
||||||
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
|
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
|
@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"code": "invalid-binding",
|
||||||
|
"message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
|
||||||
|
"pos": 79,
|
||||||
|
"start": { "line": 6, "column": 9, "character": 79 },
|
||||||
|
"end": { "line": 6, "column": 27, "character": 97 }
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
let promise = 0;
|
||||||
|
</script>
|
||||||
|
{#await promise}
|
||||||
|
{:catch error}
|
||||||
|
<input bind:value={error} />
|
||||||
|
{/await}
|
@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"code": "invalid-binding",
|
||||||
|
"message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
|
||||||
|
"pos": 78,
|
||||||
|
"start": { "line": 6, "column": 9, "character": 78 },
|
||||||
|
"end": { "line": 6, "column": 19, "character": 88 }
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
let promise = 0;
|
||||||
|
</script>
|
||||||
|
{#await promise}
|
||||||
|
{:then value}
|
||||||
|
<input bind:value />
|
||||||
|
{/await}
|
@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"code": "invalid-binding",
|
||||||
|
"message": "Cannot bind to a variable declared with {#await ... then} or {:catch} blocks",
|
||||||
|
"pos": 75,
|
||||||
|
"start": { "line": 5, "column": 9, "character": 75 },
|
||||||
|
"end": { "line": 5, "column": 19, "character": 85 }
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,6 @@
|
|||||||
|
<script>
|
||||||
|
let promise = 0;
|
||||||
|
</script>
|
||||||
|
{#await promise then value}
|
||||||
|
<input bind:value />
|
||||||
|
{/await}
|
Loading…
Reference in new issue