Merge branch 'master' into init-contenteditable

pull/2996/head
Rich Harris 6 years ago
commit 4a7f5a2da2

@ -1,5 +1,27 @@
# Svelte changelog # Svelte changelog
## 3.5.4
* Preserve whitespace at the boundaries of `{#each}` blocks ([#713](https://github.com/sveltejs/svelte/issues/713))
* Fix dynamic `bind:this` on components ([#2333](https://github.com/sveltejs/svelte/issues/2333))
* Fix binding to values in a component when it uses `$$props` ([#2725](https://github.com/sveltejs/svelte/issues/2725))
* Fix parsing ambiguous HTML entities ([#3071](https://github.com/sveltejs/svelte/pull/3071))
## 3.5.3
* Don't double-destroy keyed each blocks with outros ([#3055](https://github.com/sveltejs/svelte/issues/3055))
## 3.5.2
* Prevent duplicated outros causing errors ([#3001](https://github.com/sveltejs/svelte/issues/3001))
* Fix automatic name generation ([#2843](https://github.com/sveltejs/svelte/issues/2843))
* Fix .d.ts stubs ([#3009](https://github.com/sveltejs/svelte/pull/3009))
* Don't strip non-breaking spaces ([#3014](https://github.com/sveltejs/svelte/issues/3014))
* Fix `requestAnimationFrame` context ([#2933](https://github.com/sveltejs/svelte/issues/2933))
* Allow space before attribute value ([#3026](https://github.com/sveltejs/svelte/issues/3026))
* Remove null/undefined attributes ([#1434](https://github.com/sveltejs/svelte/issues/1434))
* Fix whitespace in static markup ([#3030](https://github.com/sveltejs/svelte/pull/3030))
## 3.5.1 ## 3.5.1
* Accommodate webpack idiosyncracies * Accommodate webpack idiosyncracies

16
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.5.1", "version": "3.5.4",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -253,7 +253,7 @@
}, },
"array-equal": { "array-equal": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
"dev": true "dev": true
}, },
@ -676,7 +676,7 @@
}, },
"commander": { "commander": {
"version": "2.15.1", "version": "2.15.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"dev": true "dev": true
}, },
@ -1876,7 +1876,7 @@
}, },
"is-builtin-module": { "is-builtin-module": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2357,7 +2357,7 @@
}, },
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true "dev": true
}, },
@ -2384,7 +2384,7 @@
}, },
"mkdirp": { "mkdirp": {
"version": "0.5.1", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2790,7 +2790,7 @@
}, },
"path-is-absolute": { "path-is-absolute": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true "dev": true
}, },
@ -3527,7 +3527,7 @@
}, },
"safe-regex": { "safe-regex": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true, "dev": true,
"requires": { "requires": {

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.5.1", "version": "3.5.4",
"description": "Cybernetically enhanced web apps", "description": "Cybernetically enhanced web apps",
"module": "index.mjs", "module": "index.mjs",
"main": "index", "main": "index",

@ -4,7 +4,10 @@ Set up the project:
```bash ```bash
git clone https://github.com/sveltejs/svelte.git git clone https://github.com/sveltejs/svelte.git
cd svelte/site cd svelte
npm ci
PUBLISH=1 npm run build
cd site
npm ci npm ci
npm run update npm run update
``` ```
@ -17,7 +20,7 @@ By default, the REPL will fetch the most recent version of Svelte from https://u
To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the root of this repository with the `PUBLISH` environment variable set to any non-empty string. To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the root of this repository with the `PUBLISH` environment variable set to any non-empty string.
Then visit the REPL at [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). Then visit the REPL at [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). Please note that the local REPL only works with `npm run dev` and not when building the site for production usage.
## REPL GitHub integration ## REPL GitHub integration
@ -32,6 +35,13 @@ In order for the REPL's GitHub integration to work properly when running locally
GITHUB_CLIENT_SECRET=[your app's Client Secret] GITHUB_CLIENT_SECRET=[your app's Client Secret]
BASEURL=http://localhost:3000 BASEURL=http://localhost:3000
``` ```
## Building the site
To build the website, run `npm run sapper`. The output can be found in `__sapper__/build`.
## Testing
Tests can be run using `npm run test`.
## Translating the API docs ## Translating the API docs

@ -188,12 +188,20 @@ If a *key* expression is provided — which must uniquely identify each list ite
--- ---
You can freely use destructuring patterns in each blocks. You can freely use destructuring and rest patterns in each blocks.
```html ```html
{#each items as { id, name, qty }, i (id)} {#each items as { id, name, qty }, i (id)}
<li>{i + 1}: {name} x {qty}</li> <li>{i + 1}: {name} x {qty}</li>
{/each} {/each}
{#each objects as { id, ...rest }}
<li><span>{id}</span><MyComponent {...rest}/></li>
{/each}
{#each items as [id, ...rest]}
<li><span>{id}</span><MyComponent values={rest}/></li>
{/each}
``` ```
--- ---
@ -1241,7 +1249,7 @@ It cannot appear at the top level of your markup; it must be inside an if or eac
### `<svelte:component>` ### `<svelte:component>`
```sv ```sv
<svelte:component this={expression}> <svelte:component this={expression}/>
``` ```
--- ---
@ -1318,7 +1326,7 @@ As with `<svelte:window>`, this element allows you to add listeners to events on
### `<svelte:head>` ### `<svelte:head>`
```sv ```sv
<svelte:head> <svelte:head>...</svelte:head>
``` ```
--- ---
@ -1335,7 +1343,7 @@ This element makes it possible to insert elements into `document.head`. During s
### `<svelte:options>` ### `<svelte:options>`
```sv ```sv
<svelte:options option={value}> <svelte:options option={value}/>
``` ```
--- ---
@ -1351,4 +1359,4 @@ The `<svelte:options>` element provides a place to specify per-component compile
```html ```html
<svelte:options tag="my-custom-element"/> <svelte:options tag="my-custom-element"/>
``` ```

@ -7,7 +7,7 @@
<svelte:window/> <svelte:window/>
<a class="parallax-container" href="https://www.firewatchgame.com"> <a class="parallax-container" href="https://www.firewatchgame.com">
{#each [0, 1, 2, 3, 4, 5, 6, 7, 8] as layer} {#each layers as layer}
<img <img
style="transform: translate(0,{-y * layer / (layers.length - 1)}px)" style="transform: translate(0,{-y * layer / (layers.length - 1)}px)"
src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png" src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png"

@ -7,7 +7,7 @@
<svelte:window bind:scrollY={y}/> <svelte:window bind:scrollY={y}/>
<a class="parallax-container" href="https://www.firewatchgame.com"> <a class="parallax-container" href="https://www.firewatchgame.com">
{#each [0, 1, 2, 3, 4, 5, 6, 7, 8] as layer} {#each layers as layer}
<img <img
style="transform: translate(0,{-y * layer / (layers.length - 1)}px)" style="transform: translate(0,{-y * layer / (layers.length - 1)}px)"
src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png" src="https://www.firewatchgame.com/images/parallax/parallax{layer}.png"

@ -4671,9 +4671,9 @@
} }
}, },
"svelte": { "svelte": {
"version": "3.5.1", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.5.1.tgz", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.5.2.tgz",
"integrity": "sha512-iMnuyteFGQ8Yl68G/DHTHY1sLwoAMya1eS0ZOHIm/dqn2etR8WEe8hUAoluLryde4Cft4gvMhtHV3NhE60nBmQ==", "integrity": "sha512-tDLd2ghONtUQeepa6LkcWEf9KkxuTQmfM4LwhWx1SH4Xzg38Kc0u051of34mWEfm3gG5h4dtk7Wuu2Aw7c60Yw==",
"dev": true "dev": true
}, },
"tar": { "tar": {

@ -55,7 +55,7 @@
"rollup-plugin-terser": "^4.0.4", "rollup-plugin-terser": "^4.0.4",
"sapper": "^0.27.3", "sapper": "^0.27.3",
"shelljs": "^0.8.3", "shelljs": "^0.8.3",
"svelte": "^3.5.1" "svelte": "^3.5.2"
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"

@ -52,6 +52,7 @@
<a target="_blank" rel="noopener" href="https://itslearning.com"><img src="organisations/itslearning.svg" alt="itslearning logo"></a> <a target="_blank" rel="noopener" href="https://itslearning.com"><img src="organisations/itslearning.svg" alt="itslearning logo"></a>
<a target="_blank" rel="noopener" href="http://mustlab.ru"><img src="organisations/mustlab.png" alt="Mustlab logo"></a> <a target="_blank" rel="noopener" href="http://mustlab.ru"><img src="organisations/mustlab.png" alt="Mustlab logo"></a>
<a target="_blank" rel="noopener" href="https://www.nesta.org.uk"><img src="organisations/nesta.svg" alt="Nesta logo"></a> <a target="_blank" rel="noopener" href="https://www.nesta.org.uk"><img src="organisations/nesta.svg" alt="Nesta logo"></a>
<a target="_blank" rel="noopener" href="https://www.nzz.ch"><img src="organisations/nzz.svg" alt="Neue Zürcher Zeitung logo"></a>
<a target="_blank" rel="noopener" href="https://nytimes.com"><img src="organisations/nyt.svg" alt="The New York Times logo"></a> <a target="_blank" rel="noopener" href="https://nytimes.com"><img src="organisations/nyt.svg" alt="The New York Times logo"></a>
<a target="_blank" rel="noopener" href="https://openstate.eu"><img src="organisations/open-state-foundation.svg" alt="Open State Foundation logo"></a> <a target="_blank" rel="noopener" href="https://openstate.eu"><img src="organisations/open-state-foundation.svg" alt="Open State Foundation logo"></a>
<a target="_blank" rel="noopener" href="https://razorpay.com"><img src="organisations/razorpay.svg" alt="Razorpay logo"></a> <a target="_blank" rel="noopener" href="https://razorpay.com"><img src="organisations/razorpay.svg" alt="Razorpay logo"></a>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

@ -80,7 +80,7 @@ export default function dom(
${$$props} => { ${$$props} => {
${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)} ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)}
${writable_props.map(prop => ${writable_props.map(prop =>
`if ('${prop.export_name}' in $$props) ${component.invalidate(prop.name, `${prop.name} = $$props.${prop.export_name}`)};` `if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.export_name}`)};`
)} )}
${component.slots.size > 0 && ${component.slots.size > 0 &&
`if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', `$$scope = ${$$props}.$$scope`)};`} `if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', `$$scope = ${$$props}.$$scope`)};`}

@ -177,7 +177,7 @@ export default class AwaitBlockWrapper extends Wrapper {
`); `);
if (has_transitions) { if (has_transitions) {
block.builders.intro.add_line(`${info}.block.i();`); block.builders.intro.add_line(`@transition_in(${info}.block);`);
} }
const conditions = []; const conditions = [];
@ -216,7 +216,7 @@ export default class AwaitBlockWrapper extends Wrapper {
block.builders.outro.add_block(deindent` block.builders.outro.add_block(deindent`
for (let #i = 0; #i < 3; #i += 1) { for (let #i = 0; #i < 3; #i += 1) {
const block = ${info}.blocks[#i]; const block = ${info}.blocks[#i];
if (block) block.o(); @transition_out(block);
} }
`); `);
} }

@ -204,7 +204,7 @@ export default class EachBlockWrapper extends Wrapper {
if (this.block.has_intro_method || this.block.has_outro_method) { if (this.block.has_intro_method || this.block.has_outro_method) {
block.builders.intro.add_block(deindent` block.builders.intro.add_block(deindent`
for (var #i = 0; #i < ${this.vars.data_length}; #i += 1) ${this.vars.iterations}[#i].i(); for (var #i = 0; #i < ${this.vars.data_length}; #i += 1) @transition_in(${this.vars.iterations}[#i]);
`); `);
} }
@ -362,7 +362,7 @@ export default class EachBlockWrapper extends Wrapper {
if (this.block.has_outros) { if (this.block.has_outros) {
block.builders.outro.add_block(deindent` block.builders.outro.add_block(deindent`
for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].o(); for (#i = 0; #i < ${view_length}; #i += 1) @transition_out(${iterations}[#i]);
`); `);
} }
@ -425,24 +425,6 @@ export default class EachBlockWrapper extends Wrapper {
all_dependencies.add(dependency); all_dependencies.add(dependency);
}); });
const outro_block = this.block.has_outros && block.get_unique_name('outro_block');
if (outro_block) {
block.builders.init.add_block(deindent`
function ${outro_block}(i, detaching, local) {
if (${iterations}[i]) {
if (detaching) {
@on_outro(() => {
${iterations}[i].d(detaching);
${iterations}[i] = null;
});
}
${iterations}[i].o(local);
}
}
`);
}
const condition = Array.from(all_dependencies) const condition = Array.from(all_dependencies)
.map(dependency => `changed.${dependency}`) .map(dependency => `changed.${dependency}`)
.join(' || '); .join(' || ');
@ -454,18 +436,18 @@ export default class EachBlockWrapper extends Wrapper {
? deindent` ? deindent`
if (${iterations}[#i]) { if (${iterations}[#i]) {
${iterations}[#i].p(changed, child_ctx); ${iterations}[#i].p(changed, child_ctx);
${has_transitions && `${iterations}[#i].i(1);`} ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
} else { } else {
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${has_transitions && `${iterations}[#i].i(1);`} ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
${iterations}[#i].m(${update_mount_node}, ${anchor}); ${iterations}[#i].m(${update_mount_node}, ${anchor});
} }
` `
: deindent` : deindent`
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${has_transitions && `${iterations}[#i].i(1);`} ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
${iterations}[#i].m(${update_mount_node}, ${anchor}); ${iterations}[#i].m(${update_mount_node}, ${anchor});
`; `;
@ -474,9 +456,16 @@ export default class EachBlockWrapper extends Wrapper {
let remove_old_blocks; let remove_old_blocks;
if (this.block.has_outros) { if (this.block.has_outros) {
const out = block.get_unique_name('out');
block.builders.init.add_block(deindent`
const ${out} = i => @transition_out(${iterations}[i], 1, () => {
${iterations}[i] = null;
});
`);
remove_old_blocks = deindent` remove_old_blocks = deindent`
@group_outros(); @group_outros();
for (; #i < ${view_length}; #i += 1) ${outro_block}(#i, 1, 1); for (; #i < ${view_length}; #i += 1) ${out}(#i);
@check_outros(); @check_outros();
`; `;
} else { } else {
@ -507,10 +496,10 @@ export default class EachBlockWrapper extends Wrapper {
`); `);
} }
if (outro_block) { if (this.block.has_outros) {
block.builders.outro.add_block(deindent` block.builders.outro.add_block(deindent`
${iterations} = ${iterations}.filter(Boolean); ${iterations} = ${iterations}.filter(Boolean);
for (let #i = 0; #i < ${view_length}; #i += 1) ${outro_block}(#i, 0, 0);` for (let #i = 0; #i < ${view_length}; #i += 1) @transition_out(${iterations}[#i]);`
); );
} }

@ -335,6 +335,8 @@ export default class ElementWrapper extends Wrapper {
function to_html(wrapper: ElementWrapper | TextWrapper) { function to_html(wrapper: ElementWrapper | TextWrapper) {
if (wrapper.node.type === 'Text') { if (wrapper.node.type === 'Text') {
if (wrapper.node.use_space) return ' ';
const parent = wrapper.node.parent as Element; const parent = wrapper.node.parent as Element;
const raw = parent && ( const raw = parent && (
@ -342,9 +344,9 @@ export default class ElementWrapper extends Wrapper {
parent.name === 'style' parent.name === 'style'
); );
return raw return (raw
? wrapper.node.data ? wrapper.node.data
: escape_html(wrapper.node.data) : escape_html(wrapper.node.data))
.replace(/\\/g, '\\\\') .replace(/\\/g, '\\\\')
.replace(/`/g, '\\`') .replace(/`/g, '\\`')
.replace(/\$/g, '\\$'); .replace(/\$/g, '\\$');

@ -42,6 +42,13 @@ function link(next: Wrapper, prev: Wrapper) {
if (next) next.prev = prev; if (next) next.prev = prev;
} }
function trimmable_at(child: INode, next_sibling: Wrapper): boolean {
// Whitespace is trimmable if one of the following is true:
// The child and its sibling share a common nearest each block (not at an each block boundary)
// The next sibling's previous node is an each block
return (next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/)) || next_sibling.node.prev.type === 'EachBlock';
}
export default class FragmentWrapper { export default class FragmentWrapper {
nodes: Wrapper[]; nodes: Wrapper[];
@ -85,7 +92,7 @@ export default class FragmentWrapper {
if (this.nodes.length === 0) { if (this.nodes.length === 0) {
const should_trim = ( const should_trim = (
// @ts-ignore todo: probably error, should it be next_sibling.node.data? // @ts-ignore todo: probably error, should it be next_sibling.node.data?
next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.data)) : !child.has_ancestor('EachBlock') next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock')
); );
if (should_trim) { if (should_trim) {

@ -160,7 +160,7 @@ export default class IfBlockWrapper extends Wrapper {
if (has_outros) { if (has_outros) {
this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching); this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching);
block.builders.outro.add_line(`if (${name}) ${name}.o();`); block.builders.outro.add_line(`@transition_out(${name});`);
} else { } else {
this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching); this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching);
} }
@ -168,7 +168,7 @@ export default class IfBlockWrapper extends Wrapper {
this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching); this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching);
if (has_outros) { if (has_outros) {
block.builders.outro.add_line(`if (${name}) ${name}.o();`); block.builders.outro.add_line(`@transition_out(${name});`);
} }
} }
@ -181,7 +181,7 @@ export default class IfBlockWrapper extends Wrapper {
} }
if (has_intros || has_outros) { if (has_intros || has_outros) {
block.builders.intro.add_line(`if (${name}) ${name}.i();`); block.builders.intro.add_line(`@transition_in(${name});`);
} }
if (needs_anchor) { if (needs_anchor) {
@ -238,7 +238,7 @@ export default class IfBlockWrapper extends Wrapper {
${name} = ${current_block_type_and}${current_block_type}(ctx); ${name} = ${current_block_type_and}${current_block_type}(ctx);
if (${name}) { if (${name}) {
${name}.c(); ${name}.c();
${has_transitions && `${name}.i(1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
} }
`; `;
@ -326,11 +326,9 @@ export default class IfBlockWrapper extends Wrapper {
const destroy_old_block = deindent` const destroy_old_block = deindent`
@group_outros(); @group_outros();
@on_outro(() => { @transition_out(${if_blocks}[${previous_block_index}], 1, () => {
${if_blocks}[${previous_block_index}].d(1);
${if_blocks}[${previous_block_index}] = null; ${if_blocks}[${previous_block_index}] = null;
}); });
${name}.o(1);
@check_outros(); @check_outros();
`; `;
@ -340,7 +338,7 @@ export default class IfBlockWrapper extends Wrapper {
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
${name}.c(); ${name}.c();
} }
${has_transitions && `${name}.i(1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
`; `;
@ -414,11 +412,11 @@ export default class IfBlockWrapper extends Wrapper {
? deindent` ? deindent`
if (${name}) { if (${name}) {
${name}.p(changed, ctx); ${name}.p(changed, ctx);
${has_transitions && `${name}.i(1);`} ${has_transitions && `@transition_in(${name}, 1);`}
} else { } else {
${name} = ${branch.block.name}(ctx); ${name} = ${branch.block.name}(ctx);
${name}.c(); ${name}.c();
${has_transitions && `${name}.i(1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
} }
` `
@ -426,38 +424,37 @@ export default class IfBlockWrapper extends Wrapper {
if (!${name}) { if (!${name}) {
${name} = ${branch.block.name}(ctx); ${name} = ${branch.block.name}(ctx);
${name}.c(); ${name}.c();
${has_transitions && `${name}.i(1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
${has_transitions && `} else { ${has_transitions && `} else {
${name}.i(1);`} @transition_in(${name}, 1);`}
} }
`; `;
// no `p()` here — we don't want to update outroing nodes, // no `p()` here — we don't want to update outroing nodes,
// as that will typically result in glitching // as that will typically result in glitching
const exit = branch.block.has_outro_method if (branch.block.has_outro_method) {
? deindent` block.builders.update.add_block(deindent`
@group_outros(); if (${branch.condition}) {
@on_outro(() => { ${enter}
} else if (${name}) {
@group_outros();
@transition_out(${name}, 1, () => {
${name} = null;
});
@check_outros();
}
`);
} else {
block.builders.update.add_block(deindent`
if (${branch.condition}) {
${enter}
} else if (${name}) {
${name}.d(1); ${name}.d(1);
${name} = null; ${name} = null;
}); }
`);
${name}.o(1); }
@check_outros();
`
: deindent`
${name}.d(1);
${name} = null;
`;
block.builders.update.add_block(deindent`
if (${branch.condition}) {
${enter}
} else if (${name}) {
${exit}
}
`);
block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`); block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
} }

@ -276,15 +276,17 @@ export default class InlineComponentWrapper extends Wrapper {
lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim(); lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim();
} }
const contextual_dependencies = [...binding.expression.contextual_dependencies];
component.partly_hoisted.push(deindent` component.partly_hoisted.push(deindent`
function ${fn}($$component) { function ${fn}(${['$$component', ...contextual_dependencies].join(', ')}) {
${lhs} = $$component; ${lhs} = $$component;
${object && component.invalidate(object)} ${object && component.invalidate(object)}
} }
`); `);
block.builders.destroy.add_line(`ctx.${fn}(null);`); block.builders.destroy.add_line(`ctx.${fn}(null);`);
return `@add_binding_callback(() => ctx.${fn}(${this.var}));`; return `@add_binding_callback(() => ctx.${fn}(${[this.var, ...contextual_dependencies.map(name => `ctx.${name}`)].join(', ')}));`;
} }
const name = component.get_unique_name(`${this.var}_${binding.name}_binding`); const name = component.get_unique_name(`${this.var}_${binding.name}_binding`);
@ -423,10 +425,9 @@ export default class InlineComponentWrapper extends Wrapper {
if (${name}) { if (${name}) {
@group_outros(); @group_outros();
const old_component = ${name}; const old_component = ${name};
@on_outro(() => { @transition_out(old_component.$$.fragment, 1, () => {
old_component.$destroy(); @destroy_component(old_component);
}); });
old_component.$$.fragment.o(1);
@check_outros(); @check_outros();
} }
@ -437,7 +438,7 @@ export default class InlineComponentWrapper extends Wrapper {
${munged_handlers} ${munged_handlers}
${name}.$$.fragment.c(); ${name}.$$.fragment.c();
${name}.$$.fragment.i(1); @transition_in(${name}.$$.fragment, 1);
@mount_component(${name}, ${update_mount_node}, ${anchor}); @mount_component(${name}, ${update_mount_node}, ${anchor});
} else { } else {
${name} = null; ${name} = null;
@ -446,7 +447,7 @@ export default class InlineComponentWrapper extends Wrapper {
`); `);
block.builders.intro.add_block(deindent` block.builders.intro.add_block(deindent`
if (${name}) ${name}.$$.fragment.i(#local); @transition_in(${name}.$$.fragment, #local);
`); `);
if (updates.length) { if (updates.length) {
@ -458,10 +459,10 @@ export default class InlineComponentWrapper extends Wrapper {
} }
block.builders.outro.add_line( block.builders.outro.add_line(
`if (${name}) ${name}.$$.fragment.o(#local);` `if (${name}) @transition_out(${name}.$$.fragment, #local);`
); );
block.builders.destroy.add_line(`if (${name}) ${name}.$destroy(${parent_node ? '' : 'detaching'});`); block.builders.destroy.add_line(`if (${name}) @destroy_component(${name}, ${parent_node ? '' : 'detaching'});`);
} else { } else {
const expression = this.node.name === 'svelte:self' const expression = this.node.name === 'svelte:self'
? '__svelte:self__' // TODO conflict-proof this ? '__svelte:self__' // TODO conflict-proof this
@ -490,7 +491,7 @@ export default class InlineComponentWrapper extends Wrapper {
); );
block.builders.intro.add_block(deindent` block.builders.intro.add_block(deindent`
${name}.$$.fragment.i(#local); @transition_in(${name}.$$.fragment, #local);
`); `);
if (updates.length) { if (updates.length) {
@ -501,11 +502,11 @@ export default class InlineComponentWrapper extends Wrapper {
} }
block.builders.destroy.add_block(deindent` block.builders.destroy.add_block(deindent`
${name}.$destroy(${parent_node ? '' : 'detaching'}); @destroy_component(${name}, ${parent_node ? '' : 'detaching'});
`); `);
block.builders.outro.add_line( block.builders.outro.add_line(
`${name}.$$.fragment.o(#local);` `@transition_out(${name}.$$.fragment, #local);`
); );
} }
} }

@ -142,11 +142,11 @@ export default class SlotWrapper extends Wrapper {
`); `);
block.builders.intro.add_line( block.builders.intro.add_line(
`if (${slot} && ${slot}.i) ${slot}.i(#local);` `@transition_in(${slot}, #local);`
); );
block.builders.outro.add_line( block.builders.outro.add_line(
`if (${slot} && ${slot}.o) ${slot}.o(#local);` `@transition_out(${slot}, #local);`
); );
let update_conditions = [...this.dependencies].map(name => `changed.${name}`).join(' || '); let update_conditions = [...this.dependencies].map(name => `changed.${name}`).join(' || ');

@ -7,10 +7,11 @@ export default function flatten_reference(node: Node) {
const prop_end = node.end; const prop_end = node.end;
while (node.type === 'MemberExpression') { while (node.type === 'MemberExpression') {
if (node.computed) return null;
nodes.unshift(node.property); nodes.unshift(node.property);
parts.unshift(node.property.name);
if (!node.computed) {
parts.unshift(node.property.name);
}
node = node.object; node = node.object;
} }
@ -20,10 +21,11 @@ export default function flatten_reference(node: Node) {
? node.name ? node.name
: node.type === 'ThisExpression' ? 'this' : null; : node.type === 'ThisExpression' ? 'this' : null;
if (!name) return null;
parts.unshift(name);
nodes.unshift(node); nodes.unshift(node);
if (!node.computed) {
parts.unshift(name);
}
return { name, nodes, parts, keypath: `${name}[✂${prop_start}-${prop_end}✂]` }; return { name, nodes, parts, keypath: `${name}[✂${prop_start}-${prop_end}✂]` };
} }

@ -36,7 +36,7 @@ const windows_1252 = [
]; ];
const entity_pattern = new RegExp( const entity_pattern = new RegExp(
`&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}));?`, `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}))(?:;|\\b)`,
'g' 'g'
); );

@ -2,6 +2,7 @@ import { add_render_callback, flush, schedule_update, dirty_components } from '.
import { current_component, set_current_component } from './lifecycle'; import { current_component, set_current_component } from './lifecycle';
import { blank_object, is_function, run, run_all, noop } from './utils'; import { blank_object, is_function, run, run_all, noop } from './utils';
import { children } from './dom'; import { children } from './dom';
import { transition_in } from './transitions';
// eslint-disable-next-line @typescript-eslint/class-name-casing // eslint-disable-next-line @typescript-eslint/class-name-casing
interface T$$ { interface T$$ {
@ -49,10 +50,11 @@ export function mount_component(component, target, anchor) {
after_render.forEach(add_render_callback); after_render.forEach(add_render_callback);
} }
function destroy(component, detaching) { export function destroy_component(component, detaching) {
if (component.$$) { if (component.$$.fragment) {
run_all(component.$$.on_destroy); run_all(component.$$.on_destroy);
component.$$.fragment.d(detaching);
if (detaching) component.$$.fragment.d(1);
// TODO null out other refs, including component.$$ (but need to // TODO null out other refs, including component.$$ (but need to
// preserve final state?) // preserve final state?)
@ -123,7 +125,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
$$.fragment!.c(); $$.fragment!.c();
} }
if (options.intro && component.$$.fragment.i) component.$$.fragment.i(); if (options.intro) transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor); mount_component(component, options.target, options.anchor);
flush(); flush();
} }
@ -153,7 +155,7 @@ if (typeof HTMLElement !== 'undefined') {
} }
$destroy() { $destroy() {
destroy(this, true); destroy_component(this, 1);
this.$destroy = noop; this.$destroy = noop;
} }
@ -178,7 +180,7 @@ export class SvelteComponent {
$$: T$$; $$: T$$;
$destroy() { $destroy() {
destroy(this, true); destroy_component(this, 1);
this.$destroy = noop; this.$destroy = noop;
} }

@ -1,5 +1,5 @@
import { assign, is_promise } from './utils'; import { assign, is_promise } from './utils';
import { check_outros, group_outros, on_outro } from './transitions'; import { check_outros, group_outros, transition_in, transition_out } from './transitions';
import { flush } from '../internal/scheduler'; import { flush } from '../internal/scheduler';
export function handle_promise(promise, info) { export function handle_promise(promise, info) {
@ -18,11 +18,9 @@ export function handle_promise(promise, info) {
info.blocks.forEach((block, i) => { info.blocks.forEach((block, i) => {
if (i !== index && block) { if (i !== index && block) {
group_outros(); group_outros();
on_outro(() => { transition_out(block, 1, () => {
block.d(1);
info.blocks[i] = null; info.blocks[i] = null;
}); });
block.o(1);
check_outros(); check_outros();
} }
}); });
@ -31,7 +29,7 @@ export function handle_promise(promise, info) {
} }
block.c(); block.c();
if (block.i) block.i(1); transition_in(block, 1);
block.m(info.mount(), info.anchor); block.m(info.mount(), info.anchor);
flush(); flush();

@ -1,4 +1,4 @@
import { on_outro } from './transitions'; import { transition_in, transition_out } from './transitions';
export function destroy_block(block, lookup) { export function destroy_block(block, lookup) {
block.d(1); block.d(1);
@ -6,11 +6,9 @@ export function destroy_block(block, lookup) {
} }
export function outro_and_destroy_block(block, lookup) { export function outro_and_destroy_block(block, lookup) {
on_outro(() => { transition_out(block, 1, () => {
destroy_block(block, lookup); lookup.delete(block.key);
}); });
block.o(1);
} }
export function fix_and_destroy_block(block, lookup) { export function fix_and_destroy_block(block, lookup) {
@ -57,7 +55,7 @@ export function update_keyed_each(old_blocks, changed, get_key, dynamic, ctx, li
const did_move = new Set(); const did_move = new Set();
function insert(block) { function insert(block) {
if (block.i) block.i(1); transition_in(block, 1);
block.m(node, next); block.m(node, next);
lookup.set(block.key, block); lookup.set(block.key, block);
next = block.first; next = block.first;

@ -23,6 +23,7 @@ function dispatch(node: Element, direction: boolean, kind: 'start' | 'end') {
node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`)); node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));
} }
const outroing = new Set();
let outros; let outros;
export function group_outros() { export function group_outros() {
@ -38,9 +39,30 @@ export function check_outros() {
} }
} }
export function on_outro(callback) { export function transition_in(block, local?: 0 | 1) {
outros.callbacks.push(callback); if (block && block.i) {
outroing.delete(block);
block.i(local);
}
} }
export function transition_out(block, local: 0 | 1, callback) {
if (block && block.o) {
if (outroing.has(block)) return;
outroing.add(block);
outros.callbacks.push(() => {
outroing.delete(block);
if (callback) {
block.d(1);
callback();
}
});
block.o(local);
}
}
type TransitionFn = (node: Element, params: any) => TransitionConfig; type TransitionFn = (node: Element, params: any) => TransitionConfig;
export function create_in_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) { export function create_in_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) {

@ -1,10 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
init, init,
mount_component, mount_component,
noop, noop,
safe_not_equal safe_not_equal,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
@ -26,18 +29,18 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
nested.$$.fragment.i(local); transition_in(nested.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
nested.$$.fragment.o(local); transition_out(nested.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
nested.$destroy(detaching); destroy_component(nested, detaching);
} }
}; };
} }

@ -1,10 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
init, init,
mount_component, mount_component,
noop, noop,
not_equal not_equal,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
@ -26,18 +29,18 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
nested.$$.fragment.i(local); transition_in(nested.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
nested.$$.fragment.o(local); transition_out(nested.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
nested.$destroy(detaching); destroy_component(nested, detaching);
} }
}; };
} }

@ -1,10 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
init, init,
mount_component, mount_component,
noop, noop,
not_equal not_equal,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
@ -26,18 +29,18 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
nested.$$.fragment.i(local); transition_in(nested.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
nested.$$.fragment.o(local); transition_out(nested.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
nested.$destroy(detaching); destroy_component(nested, detaching);
} }
}; };
} }

@ -1,10 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
init, init,
mount_component, mount_component,
noop, noop,
safe_not_equal safe_not_equal,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
function create_fragment(ctx) { function create_fragment(ctx) {
@ -26,18 +29,18 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
nested.$$.fragment.i(local); transition_in(nested.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
nested.$$.fragment.o(local); transition_out(nested.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
nested.$destroy(detaching); destroy_component(nested, detaching);
} }
}; };
} }

@ -1,10 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
init, init,
mount_component, mount_component,
noop, noop,
safe_not_equal safe_not_equal,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
import LazyLoad from "./LazyLoad.svelte"; import LazyLoad from "./LazyLoad.svelte";
@ -27,18 +30,18 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
lazyload.$$.fragment.i(local); transition_in(lazyload.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
lazyload.$$.fragment.o(local); transition_out(lazyload.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
lazyload.$destroy(detaching); destroy_component(lazyload, detaching);
} }
}; };
} }

@ -1,13 +1,16 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponent, SvelteComponent,
destroy_component,
detach, detach,
init, init,
insert, insert,
mount_component, mount_component,
noop, noop,
safe_not_equal, safe_not_equal,
space space,
transition_in,
transition_out
} from "svelte/internal"; } from "svelte/internal";
import Imported from "Imported.svelte"; import Imported from "Imported.svelte";
@ -36,27 +39,27 @@ function create_fragment(ctx) {
i(local) { i(local) {
if (current) return; if (current) return;
imported.$$.fragment.i(local); transition_in(imported.$$.fragment, local);
nonimported.$$.fragment.i(local); transition_in(nonimported.$$.fragment, local);
current = true; current = true;
}, },
o(local) { o(local) {
imported.$$.fragment.o(local); transition_out(imported.$$.fragment, local);
nonimported.$$.fragment.o(local); transition_out(nonimported.$$.fragment, local);
current = false; current = false;
}, },
d(detaching) { d(detaching) {
imported.$destroy(detaching); destroy_component(imported, detaching);
if (detaching) { if (detaching) {
detach(t); detach(t);
} }
nonimported.$destroy(detaching); destroy_component(nonimported, detaching);
} }
}; };
} }

@ -9,7 +9,8 @@ import {
init, init,
insert, insert,
noop, noop,
safe_not_equal safe_not_equal,
transition_in
} from "svelte/internal"; } from "svelte/internal";
// (8:0) {#if x} // (8:0) {#if x}
@ -34,10 +35,10 @@ function create_if_block(ctx) {
if (!if_block) { if (!if_block) {
if_block = create_if_block_1(ctx); if_block = create_if_block_1(ctx);
if_block.c(); if_block.c();
if_block.i(1); transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor); if_block.m(if_block_anchor.parentNode, if_block_anchor);
} else { } else {
if_block.i(1); transition_in(if_block, 1);
} }
} else if (if_block) { } else if (if_block) {
if_block.d(1); if_block.d(1);

@ -0,0 +1,129 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
check_outros,
create_out_transition,
detach,
element,
empty,
group_outros,
init,
insert,
safe_not_equal,
transition_in,
transition_out
} from "svelte/internal";
import { fade } from "svelte/transition";
// (7:0) {#if num < 5}
function create_if_block(ctx) {
var div, div_outro, current;
return {
c() {
div = element("div");
div.innerHTML = `<p>wheeee</p>`;
},
m(target, anchor) {
insert(target, div, anchor);
current = true;
},
i(local) {
if (current) return;
if (div_outro) div_outro.end(1);
current = true;
},
o(local) {
div_outro = create_out_transition(div, fade, {});
current = false;
},
d(detaching) {
if (detaching) {
detach(div);
if (div_outro) div_outro.end();
}
}
};
}
function create_fragment(ctx) {
var if_block_anchor, current;
var if_block = (ctx.num < 5) && create_if_block(ctx);
return {
c() {
if (if_block) if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
current = true;
},
p(changed, ctx) {
if (ctx.num < 5) {
if (!if_block) {
if_block = create_if_block(ctx);
if_block.c();
transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor);
} else {
transition_in(if_block, 1);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, () => {
if_block = null;
});
check_outros();
}
},
i(local) {
if (current) return;
transition_in(if_block);
current = true;
},
o(local) {
transition_out(if_block);
current = false;
},
d(detaching) {
if (if_block) if_block.d(detaching);
if (detaching) {
detach(if_block_anchor);
}
}
};
}
function instance($$self, $$props, $$invalidate) {
let { num = 1 } = $$props;
$$self.$set = $$props => {
if ('num' in $$props) $$invalidate('num', num = $$props.num);
};
return { num };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, ["num"]);
}
}
export default Component;

@ -0,0 +1,11 @@
<script>
import { fade } from 'svelte/transition';
export let num = 1;
</script>
{#if num < 5}
<div out:fade>
<p>wheeee</p>
</div>
{/if}

@ -1 +1 @@
<div data-foo='&quot;quoted&quot;'></div> <div data-foo='semi:&quot;space:&quot letter:&quote number:&quot1 end:&quot'></div>

@ -1,27 +1,27 @@
{ {
"html": { "html": {
"start": 0, "start": 0,
"end": 41, "end": 83,
"type": "Fragment", "type": "Fragment",
"children": [ "children": [
{ {
"start": 0, "start": 0,
"end": 41, "end": 83,
"type": "Element", "type": "Element",
"name": "div", "name": "div",
"attributes": [ "attributes": [
{ {
"start": 5, "start": 5,
"end": 34, "end": 76,
"type": "Attribute", "type": "Attribute",
"name": "data-foo", "name": "data-foo",
"value": [ "value": [
{ {
"start": 15, "start": 15,
"end": 33, "end": 75,
"type": "Text", "type": "Text",
"raw": "&quot;quoted&quot;", "raw": "semi:&quot;space:&quot letter:&quote number:&quot1 end:&quot",
"data": "\"quoted\"" "data": "semi:\"space:\" letter:&quote number:&quot1 end:\""
} }
] ]
} }

@ -0,0 +1,8 @@
export default {
skip_if_ssr: true,
html: `
<div>foo</div>
<div>has foo: true</div>
`
};

@ -0,0 +1,9 @@
<script>
import Foo from './Foo.svelte';
export let foo = {};
</script>
<Foo bind:this={foo['computed']}/>
<div>
has foo: {!!foo.computed}
</div>

@ -0,0 +1,12 @@
export default {
skip_if_ssr: true,
html: `
<div>foo</div>
<div>first has foo: true</div>
<div>foo</div>
<div>second has foo: true</div>
<div>foo</div>
<div>third has foo: true</div>
`
};

@ -0,0 +1,11 @@
<script>
import Foo from './Foo.svelte';
export let foo = {};
</script>
{#each ["first", "second", "third"] as value}
<Foo bind:this={foo[value]}/>
<div>
{value} has foo: {!!foo[value]}
</div>
{/each}

@ -0,0 +1,12 @@
export default {
skip_if_ssr: true,
html: `
<div>foo</div>
<div>0 has foo: true</div>
<div>foo</div>
<div>1 has foo: true</div>
<div>foo</div>
<div>2 has foo: true</div>
`
};

@ -0,0 +1,11 @@
<script>
import Foo from './Foo.svelte';
export let foo = [];
</script>
{#each Array(3) as _, i}
<Foo bind:this={foo[i]}/>
<div>
{i} has foo: {!!foo[i]}
</div>
{/each}

@ -0,0 +1,6 @@
<script>
export let actualValue;
let x = $$props;
</script>
<input bind:value={actualValue}>

@ -0,0 +1,14 @@
export default {
async test({ assert, target, window }) {
const input = target.querySelector('input');
const event = new window.Event('input');
input.value = 'changed';
await input.dispatchEvent(event);
assert.htmlEqual(target.innerHTML, `
<input>
<p>changed</p>
`);
}
};

@ -0,0 +1,7 @@
<script>
import Input from './TextInput.svelte';
export let actualValue = '';
</script>
<Input bind:actualValue />
<p>{actualValue}</p>

@ -0,0 +1,5 @@
<script>
export let title;
</script>
<p>{title}</p>

@ -0,0 +1,27 @@
export default {
props: {
titles: [{ name: 'a', }, { name: 'b' }, { name: 'c' }]
},
html: `
<p>a</p>
<p>b</p>
<p>c</p>
`,
test({ assert, component, target }) {
component.titles = [{ name: 'b' }, { name: 'c' }];
assert.htmlEqual(target.innerHTML, `
<p>b</p>
<p>c</p>
`);
component.titles = [{ name: 'c' }];
assert.htmlEqual(target.innerHTML, `
<p>c</p>
`);
}
};

@ -0,0 +1,9 @@
<script>
import Nested from './Nested.svelte';
export let titles;
</script>
{#each titles as title (title.name)}
<Nested title="{title.name}"/>
{/each}

@ -0,0 +1,16 @@
const message = "the quick brown fox jumps over the lazy dog";
const expected = [...message].map(c => `<span>${c + " "}</span>`).join("");
export default {
props: {
message
},
async test({ assert, target }) {
const firstSpanList = target.children[0];
assert.equal(firstSpanList.innerHTML, expected);
const secondSpanList = target.children[1];
assert.equal(secondSpanList.innerHTML, expected);
}
};

@ -0,0 +1,11 @@
<script>
let message = "the quick brown fox jumps over the lazy dog"
</script>
<div id="first">
{#each message as char}
<span>{char} </span>
{/each}
</div>
<div id="second">{#each message as char}<span>{char} </span>{/each}</div>

@ -9,6 +9,6 @@ export default {
<span>A</span> <span>A</span>
<span></span> <span></span>
<span>&notanentity;</span> <span>&amp;notanentity;</span>
` `
}; };

@ -2,7 +2,7 @@ export default {
html: ` html: `
<div> <div>
<style>div { color: red; }</style> <style>div { color: red; }</style>
<script>alert('<>');</script> <script>alert(\`<>\`);</script>
</div> </div>
` `
}; };

@ -1,4 +1,4 @@
<div> <div>
<style>div { color: red; }</style> <style>div { color: red; }</style>
<script>alert('<>');</script> <script>alert(`<>`);</script>
</div> </div>
Loading…
Cancel
Save