Merge branch 'gh-3113' into gh-2086

pull/3159/head
Richard Harris 6 years ago
commit a28dfb2b40

@ -1,6 +1,7 @@
**/_actual.js
**/expected.js
test/*/samples/*/output.js
node_modules
# output files
animate/*.js

@ -21,6 +21,7 @@
"prefer-const": [2, { "destructuring": "all" }],
"arrow-spacing": 2,
"no-inner-declarations": 0,
"require-atomic-updates": "off",
"@typescript-eslint/indent": ["error", "tab", {
"SwitchCase": 1,
"ignoredNodes": ["TemplateLiteral"]

@ -1,5 +1,11 @@
# Svelte changelog
## 3.6.4
* Run `onMount` functions in correct order, and before initial `afterUpdate` functions ([#2281](https://github.com/sveltejs/svelte/issues/2281))
* Fix code transformation for shorthand methods ([#2906](https://github.com/sveltejs/svelte/issues/2906))
* Fix assignments in inline functions ([#3038](https://github.com/sveltejs/svelte/issues/3038))
## 3.6.3
* Fix await block mounting inside removed if block ([#1496](https://github.com/sveltejs/svelte/issues/1496))

157
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.6.2",
"version": "3.6.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -30,6 +30,12 @@
"integrity": "sha512-UdVB1rSL7H8TS8674fH02p5lRbhfIqQ18YKLxLKEnHFztHUH6bhMqjebMxgSTmWVrs5raS5JSLJIKKHFT4WfPg==",
"dev": true
},
"@types/eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
"dev": true
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
@ -55,45 +61,44 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.9.0.tgz",
"integrity": "sha512-FOgfBorxjlBGpDIw+0LaZIXRX6GEEUfzj8LXwaQIUCp+gDOvkI+1WgugJ7SmWiISqK9Vj5r8S7NDKO/LB+6X9A==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.11.0.tgz",
"integrity": "sha512-mXv9ccCou89C8/4avKHuPB2WkSZyY/XcTQUXd5LFZAcLw1I3mWYVjUu6eS9Ja0QkP/ClolbcW9tb3Ov/pMdcqw==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.9.0",
"@typescript-eslint/parser": "1.9.0",
"@typescript-eslint/experimental-utils": "1.11.0",
"eslint-utils": "^1.3.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"requireindex": "^1.2.0",
"tsutils": "^3.7.0"
}
},
"@typescript-eslint/experimental-utils": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.9.0.tgz",
"integrity": "sha512-1s2dY9XxBwtS9IlSnRIlzqILPyeMly5tz1bfAmQ84Ul687xBBve5YsH5A5EKeIcGurYYqY2w6RkHETXIwnwV0A==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.11.0.tgz",
"integrity": "sha512-7LbfaqF6B8oa8cp/315zxKk8FFzosRzzhF8Kn/ZRsRsnpm7Qcu25cR/9RnAQo5utZ2KIWVgaALr+ZmcbG47ruw==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "1.9.0"
"@typescript-eslint/typescript-estree": "1.11.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/parser": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.9.0.tgz",
"integrity": "sha512-CWgC1XrQ34H/+LwAU7vY5xteZDkNqeAkeidEpJnJgkKu0yqQ3ZhQ7S+dI6MX4vmmM1TKRbOrKuXc6W0fIHhdbA==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.11.0.tgz",
"integrity": "sha512-5xBExyXaxVyczrZvbRKEXvaTUFFq7gIM9BynXukXZE0zF3IQP/FxF4mPmmh3gJ9egafZFqByCpPTFm3dk4SY7Q==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.9.0",
"@typescript-eslint/typescript-estree": "1.9.0",
"eslint-scope": "^4.0.0",
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "1.11.0",
"@typescript-eslint/typescript-estree": "1.11.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.9.0.tgz",
"integrity": "sha512-7Eg0TEQpCkTsEwsl1lIzd6i7L3pJLQFWesV08dS87bNz0NeSjbL78gNAP1xCKaCejkds4PhpLnZkaAjx9SU8OA==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.11.0.tgz",
"integrity": "sha512-fquUHF5tAx1sM2OeRCC7wVxFd1iMELWMGCzOSmJ3pLzArj9+kRixdlC4d5MncuzXpjEqc6045p3KwM0o/3FuUA==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
@ -676,7 +681,7 @@
},
"commander": {
"version": "2.15.1",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"dev": true
},
@ -1035,13 +1040,13 @@
}
},
"eslint": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.1.tgz",
"integrity": "sha512-DyQRaMmORQ+JsWShYsSg4OPTjY56u1nCjAmICrE8vLWqyLKxhFXOthwMj1SA8xwfrv0CofLNVnqbfyhwCkaO0w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.9.1",
"ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
@ -1049,18 +1054,19 @@
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.1",
"espree": "^6.0.0",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"glob-parent": "^3.1.0",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
"js-yaml": "^3.13.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
@ -1068,7 +1074,6 @@
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
@ -1147,9 +1152,9 @@
}
},
"eslint-plugin-import": {
"version": "2.17.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz",
"integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==",
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz",
"integrity": "sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
@ -1224,9 +1229,9 @@
"dev": true
},
"espree": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
"integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
"integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
@ -1430,9 +1435,9 @@
}
},
"flatted": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
"integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
"dev": true
},
"for-in": {
@ -1561,6 +1566,27 @@
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"dev": true,
"requires": {
"is-glob": "^3.1.0",
"path-dirname": "^1.0.0"
},
"dependencies": {
"is-glob": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
"integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
"dev": true,
"requires": {
"is-extglob": "^2.1.0"
}
}
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@ -1778,9 +1804,9 @@
}
},
"import-fresh": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
"integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
"integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
@ -1810,9 +1836,9 @@
"dev": true
},
"inquirer": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
"integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz",
"integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
@ -1929,12 +1955,27 @@
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
@ -2357,7 +2398,7 @@
},
"minimist": {
"version": "0.0.8",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
@ -2782,6 +2823,12 @@
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
"path-dirname": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
"integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
"dev": true
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@ -2794,12 +2841,6 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"path-is-inside": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
"dev": true
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
@ -3052,12 +3093,6 @@
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true
},
"requireindex": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
"dev": true
},
"resolve": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
@ -3527,7 +3562,7 @@
},
"safe-regex": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
@ -3950,9 +3985,9 @@
"dev": true
},
"table": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz",
"integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==",
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz",
"integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==",
"dev": true,
"requires": {
"ajv": "^6.9.1",

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.6.3",
"version": "3.6.4",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -58,16 +58,16 @@
"devDependencies": {
"@types/mocha": "^5.2.0",
"@types/node": "=8",
"@typescript-eslint/eslint-plugin": "^1.9.0",
"@typescript-eslint/parser": "^1.9.0",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.11.0",
"acorn": "^6.1.1",
"acorn-dynamic-import": "^4.0.0",
"agadoo": "^1.0.1",
"c8": "^3.4.0",
"codecov": "^3.0.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^5.16.0",
"eslint-plugin-import": "^2.17.3",
"eslint": "^6.0.1",
"eslint-plugin-import": "^2.18.0",
"estree-walker": "^0.6.1",
"is-reference": "^1.1.1",
"jsdom": "^12.2.0",

@ -20,7 +20,8 @@
"prefer-arrow-callback": 2,
"prefer-const": [2, { "destructuring": "all" }],
"arrow-spacing": 2,
"no-inner-declarations": 0
"no-inner-declarations": 0,
"require-atomic-updates": 0
},
"env": {
"es6": true,
@ -34,6 +35,12 @@
"plugin:import/warnings"
],
"plugins": ["svelte3"],
"overrides": [
{
"files": "*.svelte",
"processor": "svelte3/svelte3"
}
],
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module"

@ -10,4 +10,24 @@ draft: true
* eslint-plugin-svelte3
* svelte-vscode
* associating .svelte files with HTML in VSCode, Sublime, Atom, etc etc etc
* associating .svelte files with HTML in VSCode, Sublime, Atom, etc etc etc
## Vim/Neovim
To treat all `*.svelte` files as HTML, add the following line to your `init.vim`:
```bash
au! BufNewFile,BufRead *.svelte set ft=html
```
To temporarily turn on HTML syntax highlighting for the current buffer, use:
```bash
:set ft=html
```
To set the filetype for a single file, use a [modeline](https://vim.fandom.com/wiki/Modeline_magic):
```bash
<!-- vim: set ft=html :-->
```

@ -2125,9 +2125,9 @@
"dev": true
},
"eslint-plugin-svelte3": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte3/-/eslint-plugin-svelte3-1.2.0.tgz",
"integrity": "sha512-7tuYh8YdwE9PP96U9qNJUSVMaxxUS/HZEZtEDlNGSAe0g40xd12pJo6lrc5wGxOmXpR6adGy5DnkSSF1UXGDKg==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte3/-/eslint-plugin-svelte3-2.5.0.tgz",
"integrity": "sha512-oFRl4fbI/b1+Wp0igAssyTSkGwTv3iVaZVFSQl+k+4J9vKQ1T0niAM35EMfZ/nm9747Um3Vr032RMtqw3M8GmA==",
"dev": true
},
"esm": {

@ -38,7 +38,7 @@
"@sveltejs/svelte-repl": "^0.1.8",
"degit": "^2.1.3",
"dotenv": "^8.0.0",
"eslint-plugin-svelte3": "^1.0.0",
"eslint-plugin-svelte3": "^2.5.0",
"esm": "^3.2.22",
"jimp": "^0.6.0",
"mocha": "^6.1.3",

@ -270,7 +270,7 @@ export default class Expression {
});
} else {
dependencies.add(name);
component.add_reference(name);
component.add_reference(name); // TODO is this redundant/misplaced?
}
} else if (!is_synthetic && is_contextual(component, template_scope, name)) {
code.prependRight(node.start, key === 'key' && parent.shorthand
@ -288,41 +288,7 @@ export default class Expression {
this.skip();
}
if (function_expression) {
if (node.type === 'AssignmentExpression') {
const names = node.left.type === 'MemberExpression'
? [get_object(node.left).name]
: extract_names(node.left);
if (node.operator === '=' && nodes_match(node.left, node.right)) {
const dirty = names.filter(name => {
return !scope.declarations.has(name);
});
if (dirty.length) component.has_reactive_assignments = true;
code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
} else {
names.forEach(name => {
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
});
}
} else if (node.type === 'UpdateExpression') {
const { name } = get_object(node.argument);
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
}
} else {
if (!function_expression) {
if (node.type === 'AssignmentExpression') {
// TODO should this be a warning/error? `<p>{foo = 1}</p>`
}
@ -442,11 +408,49 @@ export default class Expression {
`);
}
if (parent && parent.method) {
code.prependRight(node.start, ': ');
}
function_expression = null;
dependencies = null;
contextual_dependencies = null;
}
if (node.type === 'AssignmentExpression') {
const names = node.left.type === 'MemberExpression'
? [get_object(node.left).name]
: extract_names(node.left);
if (node.operator === '=' && nodes_match(node.left, node.right)) {
const dirty = names.filter(name => {
return !scope.declarations.has(name);
});
if (dirty.length) component.has_reactive_assignments = true;
code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
} else {
names.forEach(name => {
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
});
}
} else if (node.type === 'UpdateExpression') {
const { name } = get_object(node.argument);
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
}
if (/Statement/.test(node.type)) {
if (pending_assignments.size > 0) {
const has_semi = code.original[node.end - 1] === ';';
@ -459,7 +463,7 @@ export default class Expression {
if (/^(Break|Continue|Return)Statement/.test(node.type)) {
if (node.argument) {
code.overwrite(node.start, node.argument.start, `var $$result = `);
code.appendLeft(node.argument.end, `${insert}; return $$result`);
code.appendLeft(node.end, `${insert}; return $$result`);
} else {
code.prependRight(node.start, `${insert}; `);
}

@ -493,7 +493,7 @@ export default class EachBlockWrapper extends Wrapper {
const out = block.get_unique_name('out');
block.builders.init.add_block(deindent`
const ${out} = i => @transition_out(${iterations}[i], 1, () => {
const ${out} = i => @transition_out(${iterations}[i], 1, 1, () => {
${iterations}[i] = null;
});
`);

@ -326,7 +326,7 @@ export default class IfBlockWrapper extends Wrapper {
const destroy_old_block = deindent`
@group_outros();
@transition_out(${if_blocks}[${previous_block_index}], 1, () => {
@transition_out(${if_blocks}[${previous_block_index}], 1, 1, () => {
${if_blocks}[${previous_block_index}] = null;
});
@check_outros();
@ -439,7 +439,7 @@ export default class IfBlockWrapper extends Wrapper {
${enter}
} else if (${name}) {
@group_outros();
@transition_out(${name}, 1, () => {
@transition_out(${name}, 1, 1, () => {
${name} = null;
});
@check_outros();

@ -388,8 +388,8 @@ export default class InlineComponentWrapper extends Wrapper {
if (${name}) {
@group_outros();
const old_component = ${name};
@transition_out(old_component.$$.fragment, 1, () => {
@destroy_component(old_component);
@transition_out(old_component.$$.fragment, 1, 0, () => {
@destroy_component(old_component, 1);
});
@check_outros();
}

@ -11,11 +11,11 @@ interface T$$ {
bound: any;
update: () => void;
callbacks: any;
after_render: any[];
after_update: any[];
props: any;
fragment: null|any;
not_equal: any;
before_render: any[];
before_update: any[];
context: Map<any, any>;
on_mount: any[];
on_destroy: any[];
@ -28,13 +28,11 @@ export function bind(component, name, callback) {
}
export function mount_component(component, target, anchor) {
const { fragment, on_mount, on_destroy, after_render } = component.$$;
const { fragment, on_mount, on_destroy, after_update } = component.$$;
fragment.m(target, anchor);
// onMount happens after the initial afterUpdate. Because
// afterUpdate callbacks happen in reverse order (inner first)
// we schedule onMount callbacks before afterUpdate callbacks
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function);
if (on_destroy) {
@ -47,7 +45,7 @@ export function mount_component(component, target, anchor) {
component.$$.on_mount = [];
});
after_render.forEach(add_render_callback);
after_update.forEach(add_render_callback);
}
export function destroy_component(component, detaching) {
@ -91,8 +89,8 @@ export function init(component, options, instance, create_fragment, not_equal, p
// lifecycle
on_mount: [],
on_destroy: [],
before_render: [],
after_render: [],
before_update: [],
after_update: [],
context: new Map(parent_component ? parent_component.$$.context : []),
// everything else
@ -113,7 +111,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
$$.update();
ready = true;
run_all($$.before_render);
run_all($$.before_update);
$$.fragment = create_fragment($$.ctx);
if (options.target) {

@ -18,7 +18,7 @@ export function handle_promise(promise, info) {
info.blocks.forEach((block, i) => {
if (i !== index && block) {
group_outros();
transition_out(block, 1, () => {
transition_out(block, 1, 1, () => {
info.blocks[i] = null;
});
check_outros();

@ -6,7 +6,7 @@ export function destroy_block(block, lookup) {
}
export function outro_and_destroy_block(block, lookup) {
transition_out(block, 1, () => {
transition_out(block, 1, 1, () => {
lookup.delete(block.key);
});
}

@ -12,7 +12,7 @@ function get_current_component() {
}
export function beforeUpdate(fn) {
get_current_component().$$.before_render.push(fn);
get_current_component().$$.before_update.push(fn);
}
export function onMount(fn) {
@ -20,7 +20,7 @@ export function onMount(fn) {
}
export function afterUpdate(fn) {
get_current_component().$$.after_render.push(fn);
get_current_component().$$.after_update.push(fn);
}
export function onDestroy(fn) {

@ -48,8 +48,9 @@ export function flush() {
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
while (render_callbacks.length) {
const callback = render_callbacks.pop();
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
callback();
@ -57,6 +58,8 @@ export function flush() {
seen_callbacks.add(callback);
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
@ -69,10 +72,10 @@ export function flush() {
function update($$) {
if ($$.fragment) {
$$.update($$.dirty);
run_all($$.before_render);
run_all($$.before_update);
$$.fragment.p($$.dirty, $$.ctx);
$$.dirty = null;
$$.after_render.forEach(add_render_callback);
$$.after_update.forEach(add_render_callback);
}
}

@ -78,8 +78,8 @@ export function create_ssr_component(fn) {
// these will be immediately discarded
on_mount: [],
before_render: [],
after_render: [],
before_update: [],
after_update: [],
callbacks: blank_object()
};

@ -46,7 +46,7 @@ export function transition_in(block, local?: 0 | 1) {
}
}
export function transition_out(block, local: 0 | 1, callback) {
export function transition_out(block, local: 0 | 1, detach: 0 | 1, callback) {
if (block && block.o) {
if (outroing.has(block)) return;
outroing.add(block);
@ -54,7 +54,7 @@ export function transition_out(block, local: 0 | 1, callback) {
outros.callbacks.push(() => {
outroing.delete(block);
if (callback) {
block.d(1);
if (detach) block.d(1);
callback();
}
});

@ -81,7 +81,7 @@ function create_fragment(ctx) {
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, () => {
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();

@ -0,0 +1,5 @@
export default {
test({ component }) {
component.flag = false;
}
};

@ -0,0 +1,6 @@
<script>
export let flag = true;
import Widget from './Widget.svelte';
</script>
<svelte:component this={flag && Widget}/>

@ -0,0 +1,22 @@
export default {
html: `
<button>click me</button>
<p>1</p>
<p>2</p>
<p>3</p>
`,
async test({ assert, target, window }) {
const button = target.querySelector('button');
const click = new window.MouseEvent('click');
await button.dispatchEvent(click);
assert.htmlEqual(target.innerHTML, `
<button>click me</button>
<p>2</p>
<p>4</p>
<p>6</p>
`);
}
};

@ -0,0 +1,13 @@
<script>
let list = [1, 2, 3];
</script>
<button on:click={event => {
list = list.map(item => {
return item * 2;
});
}}>click me</button>
{#each list as number}
<p>{number}</p>
{/each}

@ -0,0 +1,29 @@
<script>
import { onMount, beforeUpdate, afterUpdate } from 'svelte';
import order from './order.js';
export let index;
export let id;
export let name;
function logRender () {
order.push(`${index}: render`);
return index;
}
beforeUpdate(() => {
order.push(`${index}: beforeUpdate`);
});
afterUpdate(() => {
order.push(`${index}: afterUpdate`);
});
onMount(() => {
order.push(`${index}: onMount`);
});
</script>
<li>
{logRender()}
</li>

@ -0,0 +1,28 @@
import order from './order.js';
export default {
skip_if_ssr: true,
test({ assert, component, target }) {
assert.deepEqual(order, [
'0: beforeUpdate',
'0: render',
'1: beforeUpdate',
'1: render',
'2: beforeUpdate',
'2: render',
'3: beforeUpdate',
'3: render',
'1: onMount',
'1: afterUpdate',
'2: onMount',
'2: afterUpdate',
'3: onMount',
'3: afterUpdate',
'0: onMount',
'0: afterUpdate'
]);
order.length = 0;
}
};

@ -0,0 +1,33 @@
<script>
import { onMount, beforeUpdate, afterUpdate } from 'svelte';
import order from './order.js';
import Item from './Item.svelte';
const parentIndex = 0;
function logRender () {
order.push(`${parentIndex}: render`);
return parentIndex;
}
beforeUpdate(() => {
order.push(`${parentIndex}: beforeUpdate`);
});
afterUpdate(() => {
order.push(`${parentIndex}: afterUpdate`);
});
onMount(() => {
order.push(`${parentIndex}: onMount`);
})
</script>
{logRender()}
<ul>
{#each [1,2,3] as index}
<Item {index} />
{/each}
</ul>

@ -3,12 +3,12 @@ import order from './order.js';
export default {
skip_if_ssr: true,
test({ assert, component, target }) {
test({ assert }) {
assert.deepEqual(order, [
'beforeUpdate',
'render',
'afterUpdate',
'onMount'
'onMount',
'afterUpdate'
]);
order.length = 0;

@ -0,0 +1,5 @@
<script>
export let bar;
</script>
{bar.answer()}

@ -0,0 +1,9 @@
<script>
import Foo from './Foo.svelte';
</script>
<Foo bar={{
answer() {
return 42;
}
}} />
Loading…
Cancel
Save