Merge branch 'master' of github.com:sveltejs/svelte into fix/bind-out-of-sync

pull/3886/head
Richard Harris 5 years ago
commit 25f4428b8a

@ -1,6 +1,6 @@
# Svelte changelog # Svelte changelog
## Unreleased ## 3.13.0
* New structured code generation, which eliminates a number of edge cases and obscure bugs ([#3539](https://github.com/sveltejs/svelte/pull/3539)) * New structured code generation, which eliminates a number of edge cases and obscure bugs ([#3539](https://github.com/sveltejs/svelte/pull/3539))
@ -25,6 +25,23 @@ Also:
* Throw exception immediately when calling `createEventDispatcher()` after component instantiation ([#3667](https://github.com/sveltejs/svelte/pull/3667)) * Throw exception immediately when calling `createEventDispatcher()` after component instantiation ([#3667](https://github.com/sveltejs/svelte/pull/3667))
* Fix globals shadowing contextual template scope ([#3674](https://github.com/sveltejs/svelte/issues/3674)) * Fix globals shadowing contextual template scope ([#3674](https://github.com/sveltejs/svelte/issues/3674))
* Fix `<svelte:window>` bindings to stores ([#3832](https://github.com/sveltejs/svelte/issues/3832)) * Fix `<svelte:window>` bindings to stores ([#3832](https://github.com/sveltejs/svelte/issues/3832))
* Deconflict generated var names with builtins ([#3724](https://github.com/sveltejs/svelte/issues/3724))
* Allow spring/tweened values to be initially undefined ([#3761](https://github.com/sveltejs/svelte/issues/3761))
* Warn if using `<svelte:options tag="...">` without `customElement: true` option ([#3782](https://github.com/sveltejs/svelte/pull/3782))
* Add `Event` to list of known globals ([#3810](https://github.com/sveltejs/svelte/pull/3810))
* Throw helpful error on empty CSS declaration ([#3801](https://github.com/sveltejs/svelte/issues/3801))
* Support `easing` param on `fade` transition ([#3823](https://github.com/sveltejs/svelte/pull/3823))
* Generate valid names from filenames with unicode characters ([#3845](https://github.com/sveltejs/svelte/issues/3845))
* Don't generate any code for markup-less components ([#2200](https://github.com/sveltejs/svelte/issues/2200))
* Deconflict with internal name `block` ([#3854](https://github.com/sveltejs/svelte/issues/3854))
* Set attributes before bindings, to prevent erroneous assignments to `input.files` ([#3828](https://github.com/sveltejs/svelte/issues/3828))
* Smarter unused CSS detection ([#3825](https://github.com/sveltejs/svelte/pull/3825))
* Allow dynamic event handlers ([#3040](https://github.com/sveltejs/svelte/issues/3040))
* Prevent erroneous `"undefined"` class name ([#3876](https://github.com/sveltejs/svelte/pull/3876))
* Prevent resetting of `src` attribute unless changed ([#3579](https://github.com/sveltejs/svelte/pull/3579))
* Prevent hydration of void element 'children' ([#3882](https://github.com/sveltejs/svelte/issues/3882))
* Hoist globals even if mentioned in `<script>` block ([#3745](https://github.com/sveltejs/svelte/pull/3745))
## 3.12.1 ## 3.12.1

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.13.0-alpha.2", "version": "3.13.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

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

@ -6,7 +6,9 @@ authorURL: https://twitter.com/Rich_Harris
draft: true draft: true
--- ---
*Coming soon* This post will walk you through setting up your editor so that recognises Svelte files: *__Coming soon__*
This post will walk you through setting up your editor so that recognises Svelte files:
* eslint-plugin-svelte3 * eslint-plugin-svelte3
* svelte-vscode * svelte-vscode
@ -14,7 +16,7 @@ draft: true
## Atom ## Atom
To treat `*.svelte` files as HTML, open Edit → Config... and add the following lines to your `core` section: To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the following lines to your `core` section:
```cson ```cson
"*": "*":
@ -45,3 +47,23 @@ To set the filetype for a single file, use a [modeline](https://vim.fandom.com/w
``` ```
<!-- vim: set ft=html :--> <!-- vim: set ft=html :-->
``` ```
## Visual Studio Code
To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file:
```cson
"files.associations": {
"*.svelte": "html"
}
```
## JetBrains WebStorm
To treat `*.svelte` files as HTML in WebStorm, you need to create a new file type association. Please refer to the [JetBrains website](https://www.jetbrains.com/help/webstorm/creating-and-registering-file-types.html) to see how.
## Sublime Text 3
Open any `.svelte` file.
Go to *__View → Syntax → Open all with current extension as... → HTML__*.

@ -27,7 +27,7 @@ import Slot from './nodes/Slot';
import { Node, ImportDeclaration, Identifier, Program, ExpressionStatement, AssignmentExpression, Literal } from 'estree'; import { Node, ImportDeclaration, Identifier, Program, ExpressionStatement, AssignmentExpression, Literal } from 'estree';
import add_to_set from './utils/add_to_set'; import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles'; import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, x } from 'code-red'; import { print, x, b } from 'code-red';
interface ComponentOptions { interface ComponentOptions {
namespace?: string; namespace?: string;
@ -717,11 +717,13 @@ export default class Component {
let scope = instance_scope; let scope = instance_scope;
const toRemove = []; const to_remove = [];
const remove = (parent, prop, index) => { const remove = (parent, prop, index) => {
toRemove.unshift([parent, prop, index]); to_remove.unshift([parent, prop, index]);
}; };
const to_insert = new Map();
walk(content, { walk(content, {
enter(node, parent, prop, index) { enter(node, parent, prop, index) {
if (map.has(node)) { if (map.has(node)) {
@ -747,16 +749,41 @@ export default class Component {
} }
component.warn_on_undefined_store_value_references(node, parent, scope); component.warn_on_undefined_store_value_references(node, parent, scope);
if (component.compile_options.dev) {
const to_insert_for_loop_protect = component.loop_protect(node, prop, index);
if (to_insert_for_loop_protect) {
if (!Array.isArray(parent[prop])) {
parent[prop] = {
type: 'BlockStatement',
body: [to_insert_for_loop_protect.node, node],
};
} else {
// can't insert directly, will screw up the index in the for-loop of estree-walker
if (!to_insert.has(parent)) {
to_insert.set(parent, []);
}
to_insert.get(parent).push(to_insert_for_loop_protect);
}
}
}
}, },
leave(node) { leave(node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
if (to_insert.has(node)) {
const nodes_to_insert = to_insert.get(node);
for (const { index, prop, node: node_to_insert } of nodes_to_insert.reverse()) {
node[prop].splice(index, 0, node_to_insert);
}
to_insert.delete(node);
}
}, },
}); });
for (const [parent, prop, index] of toRemove) { for (const [parent, prop, index] of to_remove) {
if (parent) { if (parent) {
if (index !== null) { if (index !== null) {
parent[prop].splice(index, 1); parent[prop].splice(index, 1);
@ -836,6 +863,32 @@ export default class Component {
} }
} }
loop_protect(node, prop, index) {
if (node.type === 'WhileStatement' ||
node.type === 'ForStatement' ||
node.type === 'DoWhileStatement') {
const guard = this.get_unique_name('guard');
this.add_var({
name: guard.name,
internal: true,
});
const before = b`const ${guard} = @loop_guard()`;
const inside = b`${guard}();`;
// wrap expression statement with BlockStatement
if (node.body.type !== 'BlockStatement') {
node.body = {
type: 'BlockStatement',
body: [node.body],
};
}
node.body.body.push(inside[0]);
return { index, prop, node: before[0] };
}
return null;
}
invalidate(name, value?) { invalidate(name, value?) {
const variable = this.var_lookup.get(name); const variable = this.var_lookup.get(name);

@ -95,3 +95,12 @@ export class SvelteComponentDev extends SvelteComponent {
}; };
} }
} }
export function loop_guard() {
const start = Date.now();
return () => {
if (Date.now() - start > 100) {
throw new Error(`Infinite loop detected`);
}
};
}

@ -16,6 +16,7 @@ import {
function create_fragment(ctx) { function create_fragment(ctx) {
let img; let img;
let img_src_value;
let t; let t;
let div; let div;
@ -34,7 +35,7 @@ function create_fragment(ctx) {
this.h(); this.h();
}, },
h() { h() {
attr(img, "src", "donuts.jpg"); if (img.src !== (img_src_value = "donuts.jpg")) attr(img, "src", img_src_value);
attr(img, "alt", "donuts"); attr(img, "alt", "donuts");
}, },
m(target, anchor) { m(target, anchor) {

@ -0,0 +1,5 @@
export default {
options: {
dev: true
}
};

@ -0,0 +1,109 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponentDev,
dispatch_dev,
init,
loop_guard,
noop,
safe_not_equal
} from "svelte/internal";
const file = undefined;
function create_fragment(ctx) {
const block = {
c: noop,
l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
},
m: noop,
p: noop,
i: noop,
o: noop,
d: noop
};
dispatch_dev("SvelteRegisterBlock", {
block,
id: create_fragment.name,
type: "component",
source: "",
ctx
});
return block;
}
function instance($$self) {
const guard = loop_guard();
while (true) {
foo();
guard();
}
const guard_1 = loop_guard();
for (; ; ) {
foo();
guard_1();
}
const guard_2 = loop_guard();
while (true) {
foo();
guard_2();
}
const guard_4 = loop_guard();
do {
foo();
guard_4();
} while (true);
$$self.$capture_state = () => {
return {};
};
$$self.$inject_state = $$props => {
};
$: {
const guard_3 = loop_guard();
while (true) {
foo();
guard_3();
}
}
$: {
const guard_5 = loop_guard();
do {
foo();
guard_5();
} while (true);
}
return {};
}
class Component extends SvelteComponentDev {
constructor(options) {
super(options);
init(this, options, instance, create_fragment, safe_not_equal, {});
dispatch_dev("SvelteRegisterComponent", {
component: this,
tagName: "Component",
options,
id: create_fragment.name
});
}
}
export default Component;

@ -0,0 +1,12 @@
<script>
while(true) {
foo();
}
for(;;) {
foo();
}
while(true) foo();
$: while(true) foo();
do foo(); while(true);
$: do foo(); while(true);
</script>

@ -2,7 +2,6 @@
import { import {
SvelteComponent, SvelteComponent,
attr, attr,
children,
claim_element, claim_element,
claim_space, claim_space,
detach, detach,
@ -30,12 +29,8 @@ function create_fragment(ctx) {
}, },
l(nodes) { l(nodes) {
img0 = claim_element(nodes, "IMG", { alt: true, src: true }); img0 = claim_element(nodes, "IMG", { alt: true, src: true });
var img0_nodes = children(img0);
img0_nodes.forEach(detach);
t = claim_space(nodes); t = claim_space(nodes);
img1 = claim_element(nodes, "IMG", { alt: true, src: true }); img1 = claim_element(nodes, "IMG", { alt: true, src: true });
var img1_nodes = children(img1);
img1_nodes.forEach(detach);
this.h(); this.h();
}, },
h() { h() {

@ -0,0 +1,6 @@
export default {
error: 'Infinite loop detected',
compileOptions: {
dev: true,
}
};

@ -0,0 +1,5 @@
<script>
while(true) {
// do nothing
}
</script>
Loading…
Cancel
Save