Merge branch 'master' into master

pull/3306/head
Vadim Cebaniuc 5 years ago committed by GitHub
commit 5c5339e71c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,24 @@
# Svelte changelog
## 3.6.11
* Handle reassigned RxJS observables ([#3304](https://github.com/sveltejs/svelte/issues/3304))
* Remove commas from HTMLified attributes with multiple chunks ([#3341](https://github.com/sveltejs/svelte/issues/3341))
* Prevent `class` on element with scoped styles from rendering as `undefined` ([#3283](https://github.com/sveltejs/svelte/issues/3283))
* Allow references to index in key expression ([#3274](https://github.com/sveltejs/svelte/issues/3274))
* Mark attribute selectors as used if corresponding binding exists ([#3281](https://github.com/sveltejs/svelte/issues/3281))
* Preserve `async`/`*` when hoisting functions ([#3179](https://github.com/sveltejs/svelte/issues/3179))
* Make `raf` a noop on server ([#3324](https://github.com/sveltejs/svelte/issues/3324))
* Prevent erroneous a11y warning for image input with alt attribute ([#3331](https://github.com/sveltejs/svelte/issues/3331))
* Add several well-known globals ([#3316](https://github.com/sveltejs/svelte/pull/3316))
## 3.6.10
* Use `change` event for file inputs ([#3226](https://github.com/sveltejs/svelte/issues/3226))
* Always fire reactive declarations with `$$props` ([#3286](https://github.com/sveltejs/svelte/issues/3286))
* More conservative spread prop updates ([#3289](https://github.com/sveltejs/svelte/issues/3289))
* Quote props if necessary in SSR mode ([#3312](https://github.com/sveltejs/svelte/issues/3312))
## 3.6.9
* Always update derived stores with a derived input whose value does not change ([#3191](https://github.com/sveltejs/svelte/issues/3191))

212
package-lock.json generated

@ -1,13 +1,13 @@
{
"name": "svelte",
"version": "3.6.9",
"version": "3.6.10",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
@ -139,9 +139,9 @@
"dev": true
},
"acorn-globals": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz",
"integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==",
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.3.tgz",
"integrity": "sha512-vkR40VwS2SYO98AIeFvzWWh+xyc2qi9s7OoXSFEGIP/rOJKzjnhykaZJNnHdoq4BL2gGxI5EZOU16z896EYnOQ==",
"dev": true,
"requires": {
"acorn": "^6.0.1",
@ -192,9 +192,9 @@
}
},
"ajv": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.1.tgz",
"integrity": "sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ==",
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
@ -582,12 +582,12 @@
"dev": true
},
"cssstyle": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.3.0.tgz",
"integrity": "sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
"integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
"dev": true,
"requires": {
"cssom": "~0.3.6"
"cssom": "0.3.x"
}
},
"dashdash": {
@ -772,9 +772,9 @@
}
},
"eslint": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.1.tgz",
"integrity": "sha512-DyQRaMmORQ+JsWShYsSg4OPTjY56u1nCjAmICrE8vLWqyLKxhFXOthwMj1SA8xwfrv0CofLNVnqbfyhwCkaO0w==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz",
"integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@ -783,7 +783,7 @@
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^4.0.3",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^6.0.0",
@ -791,36 +791,31 @@
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^3.1.0",
"glob-parent": "^5.0.0",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
"inquirer": "^6.4.1",
"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",
"lodash": "^4.17.14",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
"strip-ansi": "^4.0.0",
"strip-json-comments": "^2.0.1",
"semver": "^6.1.2",
"strip-ansi": "^5.2.0",
"strip-json-comments": "^3.0.1",
"table": "^5.2.3",
"text-table": "^0.2.0"
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@ -832,6 +827,14 @@
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
},
"dependencies": {
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
}
}
},
"debug": {
@ -843,20 +846,21 @@
"ms": "^2.1.1"
}
},
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"eslint-scope": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
@ -888,9 +892,9 @@
}
},
"eslint-module-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz",
"integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz",
"integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==",
"dev": true,
"requires": {
"debug": "^2.6.8",
@ -915,9 +919,9 @@
}
},
"eslint-plugin-import": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz",
"integrity": "sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig==",
"version": "2.18.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz",
"integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
@ -927,8 +931,8 @@
"eslint-import-resolver-node": "^0.3.2",
"eslint-module-utils": "^2.4.0",
"has": "^1.0.3",
"lodash": "^4.17.11",
"minimatch": "^3.0.4",
"object.values": "^1.1.0",
"read-pkg-up": "^2.0.0",
"resolve": "^1.11.0"
},
@ -1136,9 +1140,9 @@
"dev": true
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"execa": {
@ -1178,9 +1182,9 @@
"dev": true
},
"external-editor": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
"integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"requires": {
"chardet": "^0.7.0",
@ -1397,24 +1401,12 @@
}
},
"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=",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.0"
}
}
"is-glob": "^4.0.1"
}
},
"globals": {
@ -1595,9 +1587,9 @@
"dev": true
},
"inquirer": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz",
"integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz",
"integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
@ -1606,7 +1598,7 @@
"cli-width": "^2.0.0",
"external-editor": "^3.0.3",
"figures": "^2.0.0",
"lodash": "^4.17.11",
"lodash": "^4.17.12",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rxjs": "^6.4.0",
@ -1859,9 +1851,9 @@
},
"dependencies": {
"ws": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.0.1.tgz",
"integrity": "sha512-ILHfMbuqLJvnSgYXLgy4kMntroJpe8hT41dOVWM8bxRuw6TK4mgMp9VJUNsZTEc5Bh+Mbs0DJT4M0N+wBG9l9A==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.1.1.tgz",
"integrity": "sha512-o41D/WmDeca0BqYhsr3nJzQyg9NF5X8l/UdnFNux9cS3lwB+swm8qGWX5rn+aD6xfBU3rGmtHij7g7x6LxFU3A==",
"dev": true,
"requires": {
"async-limiter": "^1.0.0"
@ -1979,9 +1971,9 @@
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"lodash.sortby": {
@ -2134,9 +2126,9 @@
}
},
"mocha": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz",
"integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==",
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz",
"integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==",
"dev": true,
"requires": {
"ansi-colors": "3.2.3",
@ -2222,6 +2214,12 @@
"ansi-regex": "^3.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
"supports-color": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
@ -2453,6 +2451,18 @@
"es-abstract": "^1.5.1"
}
},
"object.values": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
"integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.12.0",
"function-bind": "^1.1.1",
"has": "^1.0.3"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -2595,12 +2605,6 @@
"integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
"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",
@ -2760,9 +2764,9 @@
"dev": true
},
"psl": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
"integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==",
"dev": true
},
"pump": {
@ -3303,9 +3307,9 @@
"dev": true
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
"dev": true
},
"sucrase": {
@ -3336,13 +3340,13 @@
"dev": true
},
"table": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz",
"integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==",
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz",
"integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==",
"dev": true,
"requires": {
"ajv": "^6.9.1",
"lodash": "^4.17.11",
"ajv": "^6.10.2",
"lodash": "^4.17.14",
"slice-ansi": "^2.1.0",
"string-width": "^3.0.0"
}
@ -3549,6 +3553,12 @@
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"dev": true
},
"v8-compile-cache": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
"integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==",
"dev": true
},
"v8-to-istanbul": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-3.2.3.tgz",

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.6.9",
"version": "3.6.11",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -66,8 +66,8 @@
"c8": "^5.0.1",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^6.0.1",
"eslint-plugin-import": "^2.18.0",
"eslint": "^6.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-svelte3": "^2.6.0",
"estree-walker": "^0.6.1",
"is-reference": "^1.1.3",
@ -75,7 +75,7 @@
"kleur": "^3.0.3",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"mocha": "^6.1.4",
"mocha": "^6.2.0",
"puppeteer": "^1.18.1",
"rollup": "^1.16.6",
"rollup-plugin-commonjs": "^10.0.1",

@ -35,7 +35,6 @@ The markers can now add themselves to the map.
> A more finished version of `<MapMarker>` would also handle removal and prop changes, but we're only demonstrating context here.
## Context keys
In `mapbox.js` you'll see this line:
@ -44,6 +43,14 @@ In `mapbox.js` you'll see this line:
const key = {};
```
We can use anything as a key — we could do `setContext('mapbox', ...)` for example. The downside of using a string is that different component libraries might accidentally use the same one; using an object literal means the keys are guaranteed not to conflict in any circumstance, even when you have multiple different contexts operating across many component layers.
We can use anything as a key — we could do `setContext('mapbox', ...)` for example. The downside of using a string is that different component libraries might accidentally use the same one; using an object literal means the keys are guaranteed not to conflict in any circumstance (since an object only has referential equality to itself, i.e. `{} !== {}` whereas `"x" === "x"`), even when you have multiple different contexts operating across many component layers.
## Contexts vs. stores
Contexts and stores seem similar. They differ in that stores are available to *any* part of an app, while a context is only available to *a component and its descendants*. This can be helpful if you want to use several instances of a component without the state of one interfering with the state of the others.
> Remember that context is not inherently reactive. If you need context values to be reactive then you can pass a store into context, which *will* be reactive.
In fact, you might use the two together. Since context is not reactive, values that change over time should be represented as stores:
```js
const { these, are, stores } = getContext(...);
```

1937
site/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -14,25 +14,24 @@
},
"dependencies": {
"@polka/redirect": "^1.0.0-next.0",
"@polka/send": "^1.0.0-next.2",
"@polka/send": "^1.0.0-next.3",
"devalue": "^2.0.0",
"do-not-zip": "^1.0.0",
"golden-fleece": "^1.0.9",
"httpie": "^1.1.2",
"jsonwebtoken": "^8.5.1",
"marked": "^0.7.0",
"pg": "^7.11.0",
"polka": "^1.0.0-next.2",
"prismjs": "^1.16.0",
"pg": "^7.12.0",
"polka": "^1.0.0-next.4",
"prismjs": "^1.17.1",
"sirv": "^0.4.2",
"yootils": "0.0.16"
},
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/core": "^7.5.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.5.0",
"@babel/preset-env": "^7.5.4",
"@babel/runtime": "^7.5.4",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/runtime": "^7.5.5",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.1.1",
"@sveltejs/svelte-repl": "^0.1.8",
@ -40,11 +39,11 @@
"dotenv": "^8.0.0",
"esm": "^3.2.25",
"jimp": "^0.6.4",
"mocha": "^6.1.4",
"mocha": "^6.2.0",
"node-fetch": "^2.6.0",
"node-pg-migrate": "^3.21.1",
"npm-run-all": "^4.1.5",
"rollup": "^1.16.7",
"rollup": "^1.17.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-json": "^4.0.0",
@ -52,9 +51,9 @@
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-svelte": "^5.1.0",
"rollup-plugin-terser": "^5.1.1",
"sapper": "^0.27.4",
"sapper": "^0.27.8",
"shelljs": "^0.8.3",
"svelte": "^3.6.7"
"svelte": "^3.6.9"
},
"engines": {
"node": ">=10.0.0"

@ -1,22 +0,0 @@
/* version: 0.8.13 */
(function(){/*
MIT License (c) copyright 2010-2013 B Cavalier & J Hann */
(function(m){function U(){}function u(a,b){return 0==aa.call(a).indexOf("[object "+b)}function I(a){return a&&"/"==a.charAt(a.length-1)?a.substr(0,a.length-1):a}function V(a,b){var d,c,e,f;d=1;c=a;"."==c.charAt(0)&&(e=!0,c=c.replace(ba,function(a,b,c,e){c&&d++;return e||""}));if(e){e=b.split("/");f=e.length-d;if(0>f)return a;e.splice(f,d);return e.concat(c||[]).join("/")}return c}function J(a){var b=a.indexOf("!");return{h:a.substr(b+1),f:0<=b&&a.substr(0,b)}}function P(){}function v(a,b){P.prototype=
a||Q;var d=new P;P.prototype=Q;for(var c in b)d[c]=b[c];return d}function K(){function a(a,b,d){c.push([a,b,d])}function b(a,b){for(var d,e=0;d=c[e++];)(d=d[a])&&d(b)}var d,c,e;d=this;c=[];e=function(d,g){a=d?function(a){a&&a(g)}:function(a,b){b&&b(g)};e=U;b(d?0:1,g);b=U;c=k};this.then=function(b,c,e){a(b,c,e);return d};this.resolve=function(a){d.va=a;e(!0,a)};this.reject=function(a){d.ua=a;e(!1,a)};this.D=function(a){b(2,a)}}function L(a){return a instanceof K||a instanceof B}function w(a,b,d,c){L(a)?
a.then(b,d,c):b(a)}function C(a,b,d){var c;return function(){0<=--a&&b&&(c=b.apply(k,arguments));0==a&&d&&d(c);return c}}function A(){var a,b;D="";a=[].slice.call(arguments);u(a[0],"Object")&&(b=a.shift(),b=M(b));return new B(a[0],a[1],a[2],b)}function M(a,b,d){var c;D="";if(a&&(h.V(a),x=h.a(a),"preloads"in a&&(c=new B(a.preloads,k,d,E,!0),h.m(function(){E=c})),a=a.main))return new B(a,b,d)}function B(a,b,d,c,e){var f;f=h.j(x,k,[].concat(a),e);this.then=this.then=a=function(a,b){w(f,function(b){a&&
a.apply(k,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(a,b,c){return new B(a,b,c,f)};this.config=M;(b||d)&&a(b,d);h.m(function(){w(e||E,function(){w(c,function(){h.w(f)},d)})})}function W(a){var b,d;b=a.id;b==k&&(F!==k?F={L:"Multiple anonymous defines encountered"}:(b=h.ha())||(F=a));if(b!=k){d=l[b];b in l||(d=h.i(b,x),d=h.I(d.a,b),l[b]=d);if(!L(d))throw Error("duplicate define: "+b);d.ja=!1;h.J(d,a)}}function R(){var a=h.ea(arguments);W(a)}var D,x,y,G,z=m.document,S=
z&&(z.head||z.getElementsByTagName("head")[0]),ca=S&&S.getElementsByTagName("base")[0]||null,X={},Y={},N={},da="addEventListener"in m?{}:{loaded:1,complete:1},Q={},aa=Q.toString,k,l={},O={},E=!1,F,Z=/^\/|^[^:]+:\/\/|^[A-Za-z]:[\\/]/,ba=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,ea=/\/\*[\s\S]*?\*\/|\/\/.*?[\n\r]/g,fa=/require\s*\(\s*(["'])(.*?[^\\])\1\s*\)|[^\\]?(["'])/g,ga=/\s*,\s*/,T,h;h={o:function(a,b,d){var c;a=V(a,b);if("."==a.charAt(0))return a;c=J(a);a=(b=c.f)||c.h;a in d.c&&(a=d.c[a].R||a);b&&(0>
b.indexOf("/")&&!(b in d.c)&&(a=I(d.T)+"/"+b),a=a+"!"+c.h);return a},j:function(a,b,d,c){function e(b,c){var d,f;d=h.o(b,g.id,a);if(!c)return d;f=J(d);if(!f.f)return d;d=l[f.f];f.h="normalize"in d?d.normalize(f.h,e,g.a)||"":e(f.h);return f.f+"!"+f.h}function f(b,d,f){var p;p=d&&function(a){d.apply(k,a)};if(u(b,"String")){if(p)throw Error("require(id, callback) not allowed");f=e(b,!0);b=l[f];if(!(f in l))throw Error("Module not resolved: "+f);return(f=L(b)&&b.b)||b}w(h.w(h.j(a,g.id,b,c)),p,f)}var g;
g=new K;g.id=b||"";g.ia=c;g.K=d;g.a=a;g.F=f;f.toUrl=function(b){return h.i(e(b,!0),a).url};g.o=e;return g},I:function(a,b,d){var c,e,f;c=h.j(a,b,k,d);e=c.resolve;f=C(1,function(a){c.v=a;try{return h.Z(c)}catch(b){c.reject(b)}});c.resolve=function(a){w(d||E,function(){e(l[c.id]=O[c.url]=f(a))})};c.M=function(a){w(d||E,function(){c.b&&(f(a),c.D(Y))})};return c},Y:function(a,b,d,c){return h.j(a,d,k,c)},ga:function(a){return a.F},N:function(a){return a.b||(a.b={})},fa:function(a){var b=a.A;b||(b=a.A=
{id:a.id,uri:h.O(a),exports:h.N(a),config:function(){return a.a}},b.b=b.exports);return b},O:function(a){return a.url||(a.url=h.H(a.F.toUrl(a.id),a.a))},V:function(a){var b,d,c,e,f;b="curl";d="define";c=e=m;if(a&&(f=a.overwriteApi||a.sa,b=a.apiName||a.la||b,c=a.apiContext||a.ka||c,d=a.defineName||a.na||d,e=a.defineContext||a.ma||e,y&&u(y,"Function")&&(m.curl=y),y=null,G&&u(G,"Function")&&(m.define=G),G=null,!f)){if(c[b]&&c[b]!=A)throw Error(b+" already exists");if(e[d]&&e[d]!=R)throw Error(d+" already exists");
}c[b]=A;e[d]=R},a:function(a){function b(a,b){var d,c,g,n,q;for(q in a){g=a[q];u(g,"String")&&(g={path:a[q]});g.name=g.name||q;n=e;c=J(I(g.name));d=c.h;if(c=c.f)n=f[c],n||(n=f[c]=v(e),n.c=v(e.c),n.g=[]),delete a[q];c=g;var l=b,H=void 0;c.path=I(c.path||c.location||"");l&&(H=c.main||"./main","."==H.charAt(0)||(H="./"+H),c.R=V(H,c.name+"/"));c.a=c.config;c.a&&(c.a=v(e,c.a));c.W=d.split("/").length;d?(n.c[d]=c,n.g.push(d)):n.s=h.U(g.path,e)}}function d(a){var b=a.c;a.S=new RegExp("^("+a.g.sort(function(a,
c){return b[c].W-b[a].W}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.g}var c,e,f,g;"baseUrl"in a&&(a.s=a.baseUrl);"main"in a&&(a.R=a.main);"preloads"in a&&(a.ta=a.preloads);"pluginPath"in a&&(a.T=a.pluginPath);if("dontAddFileExt"in a||a.l)a.l=new RegExp(a.dontAddFileExt||a.l);c=x;e=v(c,a);e.c=v(c.c);f=a.plugins||{};e.plugins=v(c.plugins);e.C=v(c.C,a.C);e.B=v(c.B,a.B);e.g=[];b(a.packages,!0);b(a.paths,!1);for(g in f)a=h.o(g+"!","",e),e.plugins[a.substr(0,a.length-1)]=f[g];f=e.plugins;
for(g in f)if(f[g]=v(e,f[g]),a=f[g].g)f[g].g=a.concat(e.g),d(f[g]);for(g in c.c)e.c.hasOwnProperty(g)||e.g.push(g);d(e);return e},i:function(a,b){var d,c,e,f;d=b.c;e=Z.test(a)?a:a.replace(b.S,function(a){c=d[a]||{};f=c.a;return c.path||""});return{a:f||x,url:h.U(e,b)}},U:function(a,b){var d=b.s;return d&&!Z.test(a)?I(d)+"/"+a:a},H:function(a,b){return a+((b||x).l.test(a)?"":".js")},P:function(a,b,d){var c=z.createElement("script");c.onload=c.onreadystatechange=function(d){d=d||m.event;if("load"==
d.type||da[c.readyState])delete N[a.id],c.onload=c.onreadystatechange=c.onerror="",b()};c.onerror=function(){d(Error("Syntax or http error: "+a.url))};c.type=a.pa||"text/javascript";c.charset="utf-8";c.async=!a.ra;c.src=a.url;N[a.id]=c;S.insertBefore(c,ca);return c},$:function(a){var b=[],d;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(ea,"").replace(fa,function(a,e,f,g){g?d=d==g?k:d:d||b.push(f);return""});return b},ea:function(a){var b,d,c,e,f,g;f=a.length;c=a[f-1];e=u(c,"Function")?
c.length:-1;2==f?u(a[0],"Array")?d=a[0]:b=a[0]:3==f&&(b=a[0],d=a[1]);!d&&0<e&&(g=!0,d=["require","exports","module"].slice(0,e).concat(h.$(c)));return{id:b,v:d||[],G:0<=e?c:function(){return c},u:g}},Z:function(a){var b;b=a.G.apply(a.u?a.b:k,a.v);b===k&&a.b&&(b=a.A?a.b=a.A.exports:a.b);return b},J:function(a,b){a.G=b.G;a.u=b.u;a.K=b.v;h.w(a)},w:function(a){function b(a,b,c){g[b]=a;c&&r(a,b)}function d(b,c){var d,e,f,g;d=C(1,function(a){e(a);p(a,c)});e=C(1,function(a){r(a,c)});f=h.ba(b,a);(g=L(f)&&
f.b)&&e(g);w(f,d,a.reject,a.b&&function(a){f.b&&(a==X?e(f.b):a==Y&&d(f.b))})}function c(){a.resolve(g)}var e,f,g,l,t,r,p;g=[];f=a.K;l=f.length;0==f.length&&c();r=C(l,b,function(){a.M&&a.M(g)});p=C(l,b,c);for(e=0;e<l;e++)t=f[e],t in T?(p(T[t](a),e,!0),a.b&&a.D(X)):t?d(t,e):p(k,e,!0);return a},ca:function(a){h.O(a);h.P(a,function(){var b=F;F=k;!1!==a.ja&&(!b||b.L?a.reject(Error(b&&b.L||"define() missing or duplicated: "+a.url)):h.J(a,b))},a.reject);return a},ba:function(a,b){var d,c,e,f,g,k,t,r,p,m,
n,q;d=b.o;c=b.ia;e=b.a||x;g=d(a);g in l?k=g:(f=J(g),r=f.h,k=f.f||r,p=h.i(k,e));if(!(g in l))if(q=h.i(r,e).a,f.f)t=k;else if(t=q.moduleLoader||q.qa||q.loader||q.oa)r=k,k=t,p=h.i(t,e);k in l?m=l[k]:p.url in O?m=l[k]=O[p.url]:(m=h.I(q,k,c),m.url=h.H(p.url,p.a),l[k]=O[p.url]=m,h.ca(m));k==t&&(f.f&&e.plugins[f.f]&&(q=e.plugins[f.f]),n=new K,w(m,function(a){var b,e,f;f=a.dynamic;r="normalize"in a?a.normalize(r,d,m.a)||"":d(r);e=t+"!"+r;b=l[e];if(!(e in l)){b=h.Y(q,e,r,c);f||(l[e]=b);var g=function(a){f||
(l[e]=a);b.resolve(a)};g.resolve=g;g.reject=g.error=b.reject;a.load(r,b.F,g,q)}n!=b&&w(b,n.resolve,n.reject,n.D)},n.reject));return n||m},ha:function(){var a;if(!u(m.opera,"Opera"))for(var b in N)if("interactive"==N[b].readyState){a=b;break}return a},da:function(a){var b=0,d,c;for(d=z&&(z.scripts||z.getElementsByTagName("script"));d&&(c=d[b++]);)if(a(c))return c},aa:function(){var a,b="";(a=h.da(function(a){(a=a.getAttribute("data-curl-run"))&&(b=a);return a}))&&a.setAttribute("data-curl-run","");
return b},X:function(){function a(){h.P({url:c.shift()},b,b)}function b(){D&&(c.length?(h.m(d),a()):d("run.js script did not run."))}function d(a){throw Error(a||"Primary run.js failed. Trying fallback.");}var c=D.split(ga);c.length&&a()},m:function(a){setTimeout(a,0)}};T={require:h.ga,exports:h.N,module:h.fa};A.version="0.8.13";A.config=M;R.amd={plugins:!0,jQuery:!0,curl:"0.8.13"};x={s:"",T:"curl/plugin",l:/\?|\.js\b/,C:{},B:{},plugins:{},c:{},S:/$^/};y=m.curl;G=m.define;y&&u(y,"Object")?(m.curl=
k,M(y)):h.V();(D=h.aa())&&h.m(h.X);l.curl=A;l["curl/_privileged"]={core:h,cache:l,config:function(){return x},_define:W,_curl:A,Promise:K}})(this.window||"undefined"!=typeof global&&global||this);
}).call(this);

@ -1,105 +0,0 @@
(function() {
const import_cache = {};
function fetch_import(id) {
return new Promise((fulfil, reject) => {
curl([`https://bundle.run/${id}`]).then(module => {
import_cache[id] = module;
fulfil(module);
}, err => {
console.error(err.stack);
reject(new Error(`Error loading ${id} from bundle.run`));
});
});
}
function fetch_imports(imports, progress_func) {
const missing_imports = imports.filter(x => !import_cache[x]);
let pending_imports = missing_imports.length;
if (missing_imports.length) {
const promise = Promise.all(
missing_imports.map(id => fetch_import(id).then(() => {
pending_imports -= 1;
if (progress_func) progress_func(pending_imports);
}))
);
return promise;
} else {
return Promise.resolve();
}
}
function handle_message(ev) {
const { action, cmd_id } = ev.data;
const send_message = (payload) => parent.postMessage( { ...payload }, ev.origin);
const send_reply = (payload) => send_message({ ...payload, cmd_id });
const send_ok = () => send_reply({ action: 'cmd_ok' });
const send_error = (message, stack) => send_reply({ action: 'cmd_error', message, stack });
if (action === 'eval') {
try {
const { script } = ev.data.args;
eval(script);
send_ok();
} catch (e) {
send_error(e.message, e.stack);
}
}
if (action === 'catch_clicks') {
try {
const top_origin = ev.origin;
document.body.addEventListener('click', event => {
if (event.which !== 1) return;
if (event.metaKey || event.ctrlKey || event.shiftKey) return;
if (event.defaultPrevented) return;
// ensure target is a link
let el = event.target;
while (el && el.nodeName !== 'A') el = el.parentNode;
if (!el || el.nodeName !== 'A') return;
if (el.hasAttribute('download') || el.getAttribute('rel') === 'external' || el.target) return;
event.preventDefault();
if (el.href.startsWith(top_origin)) {
const url = new URL(el.href);
if (url.hash[0] === '#') {
window.location.hash = url.hash;
return;
}
}
window.open(el.href, '_blank');
});
send_ok();
} catch (e) {
send_error(e.message, e.stack);
}
}
if (action === 'fetch_imports') {
const { imports, import_map } = ev.data.args;
fetch_imports(imports, (remaining) => {
send_message({action: 'fetch_progress', args: { remaining }});
})
.then(() => {
imports.forEach(x => {
const module = import_cache[x];
const name = import_map.get(x);
window[name] = module;
});
send_ok();
})
.catch(e => {
send_error(e.message, e.stack);
});
}
}
window.addEventListener('message', handle_message, false);
})();

@ -219,6 +219,8 @@ function attribute_matches(node: Node, name: string, expected_value: string, ope
const spread = node.attributes.find(attr => attr.type === 'Spread');
if (spread) return true;
if (node.bindings.some((binding: Node) => binding.name === name)) return true;
const attr = node.attributes.find((attr: Node) => attr.name === name);
if (!attr) return false;
if (attr.is_true) return operator === null;

@ -83,16 +83,16 @@ export default class EachBlock extends AbstractBlock {
this.scope.add(context.key.name, this.expression.dependencies, this);
});
this.key = info.key
? new Expression(component, this, this.scope, info.key)
: null;
if (this.index) {
// index can only change if this is a keyed each block
const dependencies = this.key ? this.expression.dependencies : new Set([]);
const dependencies = info.key ? this.expression.dependencies : new Set([]);
this.scope.add(this.index, dependencies, this);
}
this.key = info.key
? new Expression(component, this, this.scope, info.key)
: null;
this.has_animation = false;
this.children = map_children(component, this, this.scope, info.children);

@ -451,11 +451,12 @@ export default class Element extends Node {
if (this.name === 'input') {
const type = attribute_map.get('type');
if (type && type.get_static_value() === 'image') {
should_have_attribute(
this,
['alt', 'aria-label', 'aria-labelledby'],
'input type="image"'
);
const required_attributes = ['alt', 'aria-label', 'aria-labelledby'];
const has_attribute = required_attributes.some(name => attribute_map.has(name));
if (!has_attribute) {
should_have_attribute(this, required_attributes, 'input type="image"');
}
}
}
}
@ -702,16 +703,20 @@ export default class Element extends Node {
return this.name === 'audio' || this.name === 'video';
}
add_css_class(class_name = this.component.stylesheet.id) {
add_css_class() {
const { id } = this.component.stylesheet;
const class_attribute = this.attributes.find(a => a.name === 'class');
if (class_attribute && !class_attribute.is_true) {
if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') {
(class_attribute.chunks[0] as Text).data += ` ${class_name}`;
(class_attribute.chunks[0] as Text).data += ` ${id}`;
} else {
(class_attribute.chunks as Node[]).push(
new Text(this.component, this, this.scope, {
type: 'Text',
data: ` ${class_name}`
data: ` ${id}`,
synthetic: true
})
);
}
@ -720,7 +725,7 @@ export default class Element extends Node {
new Attribute(this.component, this, this.scope, {
type: 'Attribute',
name: 'class',
value: [{ type: 'Text', data: class_name }]
value: [{ type: 'Text', data: id, synthetic: true }]
})
);
}

@ -6,9 +6,11 @@ import { INode } from './interfaces';
export default class Text extends Node {
type: 'Text';
data: string;
synthetic: boolean;
constructor(component: Component, parent: INode, scope: TemplateScope, info: any) {
super(component, parent, scope, info);
this.data = info.data;
this.synthetic = info.synthetic || false;
}
}

@ -363,7 +363,7 @@ export default class Expression {
}
const fn = deindent`
function ${name}(${args.join(', ')}) ${body}
${node.async && 'async '}function${node.generator && '*'} ${name}(${args.join(', ')}) ${body}
`;
if (dependencies.size === 0 && contextual_dependencies.size === 0) {

@ -267,9 +267,9 @@ export default function dom(
return `$$subscribe_${name}()`;
}
const subscribe = component.helper('subscribe');
const component_subscribe = component.helper('component_subscribe');
let insert = `${subscribe}($$self, ${name}, $${callback})`;
let insert = `${component_subscribe}($$self, ${name}, $${callback})`;
if (component.compile_options.dev) {
const validate_store = component.helper('validate_store');
insert = `${validate_store}(${name}, '${name}'); ${insert}`;
@ -343,7 +343,7 @@ export default function dom(
})
.map(({ name }) => deindent`
${component.compile_options.dev && `@validate_store(${name.slice(1)}, '${name.slice(1)}');`}
@subscribe($$self, ${name.slice(1)}, $$value => { ${name} = $$value; $$invalidate('${name}', ${name}); });
@component_subscribe($$self, ${name.slice(1)}, $$value => { ${name} = $$value; $$invalidate('${name}', ${name}); });
`);
const resubscribable_reactive_store_unsubscribers = reactive_stores
@ -359,15 +359,11 @@ export default function dom(
component.reactive_declarations
.forEach(d => {
let uses_props;
const dependencies = Array.from(d.dependencies);
const uses_props = !!dependencies.find(n => n === '$$props');
const condition = Array.from(d.dependencies)
const condition = !uses_props && dependencies
.filter(n => {
if (n === '$$props') {
uses_props = true;
return false;
}
const variable = component.var_lookup.get(n);
return variable && (variable.writable || variable.mutated);
})
@ -394,7 +390,7 @@ export default function dom(
const store = component.var_lookup.get(name);
if (store && store.reassigned) {
return `${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => { $$unsubscribe_${name}(); $$unsubscribe_${name} = ${name}.subscribe($$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }) }`;
return `${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => { $$unsubscribe_${name}(); $$unsubscribe_${name} = @subscribe(${name}, $$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }) }`;
}
return $name;

@ -5,6 +5,7 @@ import ElementWrapper from './index';
import { stringify } from '../../../utils/stringify';
import deindent from '../../../utils/deindent';
import Expression from '../../../nodes/shared/Expression';
import Text from '../../../nodes/Text';
export default class AttributeWrapper {
node: Attribute;
@ -69,11 +70,6 @@ export default class AttributeWrapper {
const is_legacy_input_type = element.renderer.component.compile_options.legacy && name === 'type' && this.parent.node.name === 'input';
const is_dataset = /^data-/.test(name) && !element.renderer.component.compile_options.legacy && !element.node.namespace;
const camel_case_name = is_dataset ? name.replace('data-', '').replace(/(-\w)/g, (m) => {
return m[1].toUpperCase();
}) : name;
if (this.node.is_dynamic) {
let value;
@ -84,19 +80,13 @@ export default class AttributeWrapper {
value = (this.node.chunks[0] as Expression).render(block);
} else {
// '{foo} {bar}' — treat as string concatenation
value =
(this.node.chunks[0].type === 'Text' ? '' : `"" + `) +
this.node.chunks
.map((chunk) => {
if (chunk.type === 'Text') {
return stringify(chunk.data);
} else {
return chunk.get_precedence() <= 13
? `(${chunk.render()})`
: chunk.render();
}
})
.join(' + ');
const prefix = this.node.chunks[0].type === 'Text' ? '' : `"" + `;
const text = this.node.name === 'class'
? this.get_class_name_text()
: this.render_chunks().join(' + ');
value = `${prefix}${text}`;
}
const is_select_value_attribute =
@ -150,11 +140,6 @@ export default class AttributeWrapper {
`${element.var}.${property_name} = ${init};`
);
updater = `${element.var}.${property_name} = ${should_cache ? last : value};`;
} else if (is_dataset) {
block.builders.hydrate.add_line(
`${element.var}.dataset.${camel_case_name} = ${init};`
);
updater = `${element.var}.dataset.${camel_case_name} = ${should_cache ? last : value};`;
} else {
block.builders.hydrate.add_line(
`${method}(${element.var}, "${name}", ${init});`
@ -189,8 +174,6 @@ export default class AttributeWrapper {
? `@set_input_type(${element.var}, ${value});`
: property_name
? `${element.var}.${property_name} = ${value};`
: is_dataset
? `${element.var}.dataset.${camel_case_name} = ${value === true ? '""' : value};`
: `${method}(${element.var}, "${name}", ${value === true ? '""' : value});`
);
@ -210,6 +193,31 @@ export default class AttributeWrapper {
}
}
get_class_name_text() {
const scoped_css = this.node.chunks.some((chunk: Text) => chunk.synthetic);
const rendered = this.render_chunks();
if (scoped_css && rendered.length === 2) {
// we have a situation like class={possiblyUndefined}
rendered[0] = `@null_to_empty(${rendered[0]})`;
}
return rendered.join(' + ');
}
render_chunks() {
return this.node.chunks.map((chunk) => {
if (chunk.type === 'Text') {
return stringify(chunk.data);
}
const rendered = chunk.render();
return chunk.get_precedence() <= 13
? `(${rendered})`
: rendered;
});
}
stringify() {
if (this.node.is_true) return '';
@ -220,7 +228,7 @@ export default class AttributeWrapper {
return chunk.type === 'Text'
? chunk.data.replace(/"/g, '\\"')
: `\${${chunk.render()}}`;
})}"`;
}).join('')}"`;
}
}

@ -26,7 +26,7 @@ const events = [
event_names: ['input'],
filter: (node: Element, _name: string) =>
node.name === 'textarea' ||
node.name === 'input' && !/radio|checkbox|range/.test(node.get_static_attribute_value('type') as string)
node.name === 'input' && !/radio|checkbox|range|file/.test(node.get_static_attribute_value('type') as string)
},
{
event_names: ['input'],
@ -38,7 +38,7 @@ const events = [
event_names: ['change'],
filter: (node: Element, _name: string) =>
node.name === 'select' ||
node.name === 'input' && /radio|checkbox/.test(node.get_static_attribute_value('type') as string)
node.name === 'input' && /radio|checkbox|file/.test(node.get_static_attribute_value('type') as string)
},
{
event_names: ['change', 'input'],
@ -816,29 +816,4 @@ export default class ElementWrapper extends Wrapper {
}
});
}
// todo: looks to be dead code copypasted from Element.add_css_class in src/compile/nodes/Element.ts
// add_css_class(class_name = this.component.stylesheet.id) {
// const class_attribute = this.attributes.find(a => a.name === 'class');
// if (class_attribute && !class_attribute.is_true) {
// if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') {
// (class_attribute.chunks[0] as Text).data += ` ${class_name}`;
// } else {
// (class_attribute.chunks as Node[]).push(
// new Text(this.component, this, this.scope, {
// type: 'Text',
// data: ` ${class_name}`
// })
// );
// }
// } else {
// this.attributes.push(
// new Attribute(this.component, this, this.scope, {
// type: 'Attribute',
// name: 'class',
// value: [{ type: 'Text', data: class_name }]
// })
// );
// }
// }
}

@ -185,7 +185,7 @@ export default class InlineComponentWrapper extends Wrapper {
add_to_set(all_dependencies, attr.dependencies);
});
this.node.attributes.forEach(attr => {
this.node.attributes.forEach((attr, i) => {
const { name, dependencies } = attr;
const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size)
@ -205,7 +205,7 @@ export default class InlineComponentWrapper extends Wrapper {
const obj = `{ ${quote_name_if_necessary(name)}: ${attr.get_value(block)} }`;
initial_props.push(obj);
changes.push(condition ? `${condition} && ${obj}` : obj);
changes.push(condition ? `${condition} && ${obj}` : `${levels}[${i}]`);
}
});

@ -2,7 +2,7 @@ import { is_void, quote_prop_if_necessary, quote_name_if_necessary } from '../..
import Attribute from '../../nodes/Attribute';
import Class from '../../nodes/Class';
import { snip } from '../../utils/snip';
import { stringify_attribute } from '../../utils/stringify_attribute';
import { stringify_attribute, stringify_class_attribute } from '../../utils/stringify_attribute';
import { get_slot_scope } from './shared/get_slot_scope';
import Renderer, { RenderOptions } from '../Renderer';
import Element from '../../nodes/Element';
@ -111,9 +111,9 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
args.push(`{ ${quote_name_if_necessary(attribute.name)}: ${snip(attribute.chunks[0])} }`);
} else if (attribute.name === 'class' && class_expression) {
// Add class expression
args.push(`{ ${quote_name_if_necessary(attribute.name)}: [\`${stringify_attribute(attribute, true)}\`, \`\${${class_expression}}\`].join(' ').trim() }`);
args.push(`{ ${quote_name_if_necessary(attribute.name)}: [\`${stringify_class_attribute(attribute)}\`, \`\${${class_expression}}\`].join(' ').trim() }`);
} else {
args.push(`{ ${quote_name_if_necessary(attribute.name)}: \`${stringify_attribute(attribute, true)}\` }`);
args.push(`{ ${quote_name_if_necessary(attribute.name)}: \`${attribute.name === 'class' ? stringify_class_attribute(attribute) : stringify_attribute(attribute, true)}\` }`);
}
}
});
@ -136,14 +136,13 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
opening_tag += '${' + snip(attribute.chunks[0]) + ' ? " ' + attribute.name + '" : "" }';
} else if (attribute.name === 'class' && class_expression) {
add_class_attribute = false;
opening_tag += ` class="\${[\`${stringify_attribute(attribute, true)}\`, ${class_expression}].join(' ').trim() }"`;
opening_tag += ` class="\${[\`${stringify_class_attribute(attribute)}\`, ${class_expression}].join(' ').trim() }"`;
} else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
const { name } = attribute;
const snippet = snip(attribute.chunks[0]);
opening_tag += '${(v => v == null ? "" : ` ' + name + '="${@escape(' + snippet + ')}"`)(' + snippet + ')}';
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', ' + (boolean_attributes.has(name) ? 1 : 0) + ')}';
} else {
opening_tag += ` ${attribute.name}="${stringify_attribute(attribute, true)}"`;
opening_tag += ` ${attribute.name}="${attribute.name === 'class' ? stringify_class_attribute(attribute) : stringify_attribute(attribute, true)}"`;
}
});
}
@ -165,7 +164,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
node_contents = '${(' + snippet + ') || ""}';
} else {
const snippet = snip(expression);
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ')}';
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', 1)}';
}
});

@ -58,7 +58,7 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
if (attribute.is_spread) {
return snip(attribute.expression);
} else {
return `{ ${attribute.name}: ${get_attribute_value(attribute)} }`;
return `{ ${quote_name_if_necessary(attribute.name)}: ${get_attribute_value(attribute)} }`;
}
})
.concat(binding_props.map(p => `{ ${p} }`))
@ -67,7 +67,7 @@ export default function(node: InlineComponent, renderer: Renderer, options: Rend
} else {
props = stringify_props(
node.attributes
.map(attribute => `${attribute.name}: ${get_attribute_value(attribute)}`)
.map(attribute => `${quote_name_if_necessary(attribute.name)}: ${get_attribute_value(attribute)}`)
.concat(binding_props)
);
}

@ -1,6 +1,16 @@
import Attribute from '../nodes/Attribute';
import { escape_template, escape } from './stringify';
import { snip } from './snip';
import Text from '../nodes/Text';
export function stringify_class_attribute(attribute: Attribute) {
// handle special case — `class={possiblyUndefined}` with scoped CSS
if (attribute.chunks.length === 2 && (attribute.chunks[1] as Text).synthetic) {
return '${@escape(@null_to_empty(' + snip(attribute.chunks[0]) + '))}' + (attribute.chunks[1] as Text).data;
}
return stringify_attribute(attribute, true);
}
export function stringify_attribute(attribute: Attribute, is_ssr: boolean) {
return attribute.chunks

@ -15,15 +15,18 @@ export const globals = new Set([
'encodeURIComponent',
'Error',
'EvalError',
'history',
'Infinity',
'InternalError',
'Intl',
'isFinite',
'isNaN',
'JSON',
'localStorage',
'Map',
'Math',
'NaN',
'navigator',
'Number',
'Object',
'parseFloat',
@ -34,6 +37,7 @@ export const globals = new Set([
'RangeError',
'ReferenceError',
'RegExp',
'sessionStorage',
'Set',
'String',
'SyntaxError',

@ -1,10 +1,12 @@
import { noop } from './utils';
export const is_client = typeof window !== 'undefined';
export let now: () => number = is_client
? () => window.performance.now()
: () => Date.now();
export let raf = cb => requestAnimationFrame(cb);
export let raf = is_client ? cb => requestAnimationFrame(cb) : noop;
// used internally for testing
export function set_now(fn) {

@ -1,6 +1,5 @@
import { set_current_component, current_component } from './lifecycle';
import { run_all, blank_object } from './utils';
import { Readable } from 'svelte/store';
export const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
@ -121,21 +120,9 @@ export function create_ssr_component(fn) {
};
}
/**
* Get the current value from a store by subscribing and immediately unsubscribing.
* @param store readable
*/
export function get_store_value<T>(store: Readable<T>): T | undefined {
let value;
const unsubscribe: any = store.subscribe(_ => value = _);
if (unsubscribe.unsubscribe) unsubscribe.unsubscribe();
else unsubscribe();
return value;
}
export function add_attribute(name, value) {
if (!value) return '';
return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(value) : `"${value}"`}`}`;
export function add_attribute(name, value, boolean) {
if (value == null || (boolean && !value)) return '';
return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `"${value}"`}`}`;
}
export function add_classes(classes) {

@ -48,12 +48,19 @@ export function validate_store(store, name) {
}
}
export function subscribe(component, store, callback) {
export function subscribe(store, callback) {
const unsub = store.subscribe(callback);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
export function get_store_value(store) {
let value;
subscribe(store, _ => value = _)();
return value;
}
component.$$.on_destroy.push(unsub.unsubscribe
? () => unsub.unsubscribe()
: unsub);
export function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
export function create_slot(definition, ctx, fn) {
@ -89,3 +96,7 @@ export function once(fn) {
fn.call(this, ...args);
};
}
export function null_to_empty(value) {
return value == null ? '' : value;
}

@ -1,5 +1,4 @@
import { run_all, noop, safe_not_equal, is_function } from 'svelte/internal';
export { get_store_value as get } from 'svelte/internal';
import { run_all, noop, safe_not_equal, is_function, get_store_value } from 'svelte/internal';
/** Callback to inform of a value updates. */
type Subscriber<T> = (value: T) => void;
@ -182,3 +181,9 @@ export function derived<T, S extends Stores>(
};
});
}
/**
* Get the current value from a store by subscribing and immediately unsubscribing.
* @param store readable
*/
export { get_store_value as get };

@ -0,0 +1 @@
details[open].svelte-xyz{color:red}

@ -0,0 +1,11 @@
<script>
let open = false;
</script>
<details bind:open>Hello</details>
<style>
details[open] {
color: red;
}
</style>

@ -1,67 +0,0 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
detach,
element,
init,
insert,
noop,
safe_not_equal,
space
} from "svelte/internal";
function create_fragment(ctx) {
var div0, t, div1;
return {
c() {
div0 = element("div");
t = space();
div1 = element("div");
div0.dataset.foo = "bar";
div1.dataset.foo = ctx.bar;
},
m(target, anchor) {
insert(target, div0, anchor);
insert(target, t, anchor);
insert(target, div1, anchor);
},
p(changed, ctx) {
if (changed.bar) {
div1.dataset.foo = ctx.bar;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(div0);
detach(t);
detach(div1);
}
}
};
}
function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;
$$self.$set = $$props => {
if ('bar' in $$props) $$invalidate('bar', bar = $$props.bar);
};
return { bar };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, ["bar"]);
}
}
export default Component;

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

@ -1,6 +0,0 @@
<script>
export let bar;
</script>
<div data-foo='bar'/>
<div data-foo='{bar}'/>

@ -1,66 +0,0 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
append,
attr,
detach,
init,
insert,
noop,
safe_not_equal,
svg_element
} from "svelte/internal";
function create_fragment(ctx) {
var svg, g0, g1;
return {
c() {
svg = svg_element("svg");
g0 = svg_element("g");
g1 = svg_element("g");
attr(g0, "data-foo", "bar");
attr(g1, "data-foo", ctx.bar);
},
m(target, anchor) {
insert(target, svg, anchor);
append(svg, g0);
append(svg, g1);
},
p(changed, ctx) {
if (changed.bar) {
attr(g1, "data-foo", ctx.bar);
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(svg);
}
}
};
}
function instance($$self, $$props, $$invalidate) {
let { bar } = $$props;
$$self.$set = $$props => {
if ('bar' in $$props) $$invalidate('bar', bar = $$props.bar);
};
return { bar };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, ["bar"]);
}
}
export default Component;

@ -1,8 +0,0 @@
<script>
export let bar;
</script>
<svg>
<g data-foo='bar'/>
<g data-foo='{bar}'/>
</svg>

@ -19,7 +19,7 @@ function create_fragment(ctx) {
input = element("input");
attr(input, "type", "file");
input.multiple = true;
dispose = listen(input, "input", ctx.input_input_handler);
dispose = listen(input, "change", ctx.input_change_handler);
},
m(target, anchor) {
@ -43,7 +43,7 @@ function create_fragment(ctx) {
function instance($$self, $$props, $$invalidate) {
let { files } = $$props;
function input_input_handler() {
function input_change_handler() {
files = this.files;
$$invalidate('files', files);
}
@ -52,7 +52,7 @@ function instance($$self, $$props, $$invalidate) {
if ('files' in $$props) $$invalidate('files', files = $$props.files);
};
return { files, input_input_handler };
return { files, input_change_handler };
}
class Component extends SvelteComponent {

@ -0,0 +1,3 @@
export default {
html: `<div class="false"></div>`,
};

@ -0,0 +1,42 @@
export default {
props: {
testName: "testClassName"
},
html: `<div class="testClassName"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'testClassName');
component.testName = null;
assert.equal(div.className, '');
component.testName = undefined;
assert.equal(div.className, '');
component.testName = undefined + '';
assert.equal(div.className, 'undefined');
component.testName = null + '';
assert.equal(div.className, 'null');
component.testName = 1;
assert.equal(div.className, '1');
component.testName = 0;
assert.equal(div.className, '0');
component.testName = false;
assert.equal(div.className, 'false');
component.testName = true;
assert.equal(div.className, 'true');
component.testName = {};
assert.equal(div.className, '[object Object]');
component.testName = '';
assert.equal(div.className, '');
}
};

@ -0,0 +1,5 @@
<script>
export let testName;
</script>
<div class={testName}></div>

@ -0,0 +1,40 @@
export default {
html: `<div class=" svelte-x1o6ra"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
component.testName = null;
assert.equal(div.className, ' svelte-x1o6ra');
component.testName = undefined;
assert.equal(div.className, ' svelte-x1o6ra');
component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra');
component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra');
component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra');
component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra');
component.testName = {};
assert.equal(div.className, '[object Object] svelte-x1o6ra');
component.testName = '';
assert.equal(div.className, ' svelte-x1o6ra');
component.testName = 'testClassName';
assert.equal(div.className, 'testClassName svelte-x1o6ra');
}
};

@ -0,0 +1,11 @@
<script>
export let testName;
</script>
<style>
div {
color: purple;
}
</style>
<div class={testName}></div>

@ -0,0 +1,45 @@
export default {
props: {
testName1: "test1",
testName2: "test2",
},
html: `<div class="test1test2"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'test1test2');
component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0');
component.testName1 = null;
component.testName2 = "test";
assert.equal(div.className, 'nulltest');
component.testName1 = undefined;
component.testName2 = "test";
assert.equal(div.className, 'undefinedtest');
component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN');
component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1');
component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN');
component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0');
component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN');
}
};

@ -0,0 +1,6 @@
<script>
export let testName1;
export let testName2;
</script>
<div class={testName1 + testName2}></div>

@ -0,0 +1,45 @@
export default {
props: {
testName1: "test1",
testName2: "test2",
},
html: `<div class="test1test2 svelte-x1o6ra"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'test1test2 svelte-x1o6ra');
component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName1 = null;
component.testName2 = "test";
assert.equal(div.className, 'nulltest svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = "test";
assert.equal(div.className, 'undefinedtest svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra');
component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra');
component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra');
}
};

@ -0,0 +1,12 @@
<script>
export let testName1;
export let testName2;
</script>
<style>
div {
color: purple;
}
</style>
<div class={testName1 + testName2}></div>

@ -0,0 +1,42 @@
export default {
props: {
testName: "testClassName"
},
html: `<div class="testClassName"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'testClassName');
component.testName = null;
assert.equal(div.className, '');
component.testName = undefined;
assert.equal(div.className, '');
component.testName = undefined + '';
assert.equal(div.className, 'undefined');
component.testName = null + '';
assert.equal(div.className, 'null');
component.testName = 1;
assert.equal(div.className, '1');
component.testName = 0;
assert.equal(div.className, '0');
component.testName = false;
assert.equal(div.className, 'false');
component.testName = true;
assert.equal(div.className, 'true');
component.testName = {};
assert.equal(div.className, '[object Object]');
component.testName = '';
assert.equal(div.className, '');
}
};

@ -0,0 +1,9 @@
<script>
export let testName;
function myHelper(testName) {
return testName;
}
</script>
<div class={myHelper(testName)}></div>

@ -0,0 +1,42 @@
export default {
props: {
testName: "testClassName"
},
html: `<div class="testClassName svelte-x1o6ra"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'testClassName svelte-x1o6ra');
component.testName = null;
assert.equal(div.className, ' svelte-x1o6ra');
component.testName = undefined;
assert.equal(div.className, ' svelte-x1o6ra');
component.testName = undefined + '';
assert.equal(div.className, 'undefined svelte-x1o6ra');
component.testName = null + '';
assert.equal(div.className, 'null svelte-x1o6ra');
component.testName = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
component.testName = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName = false;
assert.equal(div.className, 'false svelte-x1o6ra');
component.testName = true;
assert.equal(div.className, 'true svelte-x1o6ra');
component.testName = {};
assert.equal(div.className, '[object Object] svelte-x1o6ra');
component.testName = '';
assert.equal(div.className, ' svelte-x1o6ra');
}
};

@ -0,0 +1,15 @@
<script>
export let testName;
function myHelper(testName) {
return testName;
}
</script>
<style>
div {
color: purple;
}
</style>
<div class={myHelper(testName)}></div>

@ -0,0 +1,45 @@
export default {
props: {
testName1: "test1",
testName2: "test2",
},
html: `<div class="test1test2"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'test1test2');
component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0');
component.testName1 = null;
component.testName2 = "test";
assert.equal(div.className, 'nulltest');
component.testName1 = undefined;
component.testName2 = "test";
assert.equal(div.className, 'undefinedtest');
component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN');
component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1');
component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN');
component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0');
component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN');
}
};

@ -0,0 +1,11 @@
<script>
export let testName1;
export let testName2;
function myHelper(testName) {
return testName;
}
</script>
<div class={myHelper(testName1) + myHelper(testName2)}></div>

@ -0,0 +1,45 @@
export default {
props: {
testName1: "test1",
testName2: "test2",
},
html: `<div class="test1test2 svelte-x1o6ra"></div>`,
test({ assert, component, target }) {
const div = target.querySelector('div');
assert.equal(div.className, 'test1test2 svelte-x1o6ra');
component.testName1 = null;
component.testName2 = null;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName1 = null;
component.testName2 = "test";
assert.equal(div.className, 'nulltest svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = "test";
assert.equal(div.className, 'undefinedtest svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = undefined;
assert.equal(div.className, 'NaN svelte-x1o6ra');
component.testName1 = null;
component.testName2 = 1;
assert.equal(div.className, '1 svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = 1;
assert.equal(div.className, 'NaN svelte-x1o6ra');
component.testName1 = null;
component.testName2 = 0;
assert.equal(div.className, '0 svelte-x1o6ra');
component.testName1 = undefined;
component.testName2 = 0;
assert.equal(div.className, 'NaN svelte-x1o6ra');
}
};

@ -0,0 +1,17 @@
<script>
export let testName1;
export let testName2;
function myHelper(testName) {
return testName;
}
</script>
<style>
div {
color: purple;
}
</style>
<div class={myHelper(testName1) + myHelper(testName2)}></div>

@ -0,0 +1,3 @@
export default {
html: `<div></div>`,
};

@ -0,0 +1,3 @@
export default {
html: `<div></div>`,
};

@ -0,0 +1,5 @@
export default {
html: `
<button>nothing</button>
`,
};

@ -0,0 +1 @@
<button on:click={async () => { await null; }}>nothing</button>

@ -0,0 +1,7 @@
export default {
html: `
<div>
<span class="a/42"/>
</div>
`
};

@ -0,0 +1,12 @@
export default {
props: {
foo: 1
},
html: `1`,
async test({ assert, component, target }) {
component.foo = 2;
assert.htmlEqual(target.innerHTML, `2`);
}
};

@ -0,0 +1,7 @@
<script>
import Nested from './Nested.svelte';
export let foo;
</script>
<Nested x-y-z={foo}/>

@ -0,0 +1,30 @@
export default {
props: {
a: 1,
b: 2
},
html: `
<p>a: 1</p>
<p>b: 2</p>
<p>c: 3</p>
`,
async test({ assert, component, target }) {
await component.$set({ a: 4 });
assert.htmlEqual(target.innerHTML, `
<p>a: 4</p>
<p>b: 2</p>
<p>c: 6</p>
`);
await component.$set({ b: 5 });
assert.htmlEqual(target.innerHTML, `
<p>a: 4</p>
<p>b: 5</p>
<p>c: 9</p>
`);
}
};

@ -0,0 +1,8 @@
<script>
export let a;
$: c = a + $$props.b;
</script>
<p>a: {a}</p>
<p>b: {$$props.b}</p>
<p>c: {c}</p>

@ -0,0 +1,21 @@
<script>
import { beforeUpdate } from 'svelte';
export let a, b, c;
let changed = {};
let previous = {};
beforeUpdate(() => {
changed.a = a !== previous.a;
changed.b = b !== previous.b;
changed.c = c !== previous.c;
previous.a = a;
previous.b = b;
previous.c = c;
});
</script>
<pre>{JSON.stringify({ a, b, c })}</pre>
<pre>{JSON.stringify(changed)}</pre>

@ -0,0 +1,20 @@
export default {
html: `
<pre>{"a":1,"b":[1],"c":42}</pre>
<pre>{"a":false,"b":false,"c":false}</pre>
`,
ssrHtml: `
<pre>{"a":1,"b":[1],"c":42}</pre>
<pre>{}</pre>
`,
test({ assert, component, target }) {
component.a = 2;
assert.htmlEqual(target.innerHTML, `
<pre>{"a":2,"b":[1],"c":42}</pre>
<pre>{"a":true,"b":false,"c":false}</pre>
`);
}
};

@ -0,0 +1,8 @@
<script>
import Nested from './Nested.svelte';
export let a = 1;
let x = {};
</script>
<Nested {...x} {a} b={[1]} c={42}/>

@ -0,0 +1,11 @@
<script>
import { writable } from 'svelte/store';
function fake_observable(store) {
return { subscribe: cb => ({ unsubscribe: store.subscribe(cb) }) };
}
let foo = fake_observable(writable(0));
foo = fake_observable(writable(42));
</script>
{$foo}

@ -7,3 +7,5 @@
<object></object>
<input type='image'>
<input type='image' alt='hey'>

@ -1,6 +1,6 @@
<script>
// script block prevents auto-declaration
</script>
<p>{potato}</p>
<p>{Math.max(1, 2)}</p>
{#each window.something as foo, i (foo.x + i)}
hello
{/each}

@ -1,15 +1,15 @@
[{
"code": "missing-declaration",
"message": "'potato' is not defined",
"pos": 67,
"message": "'potato' is not defined. Consider adding a <script> block with 'export let potato' to declare a prop",
"pos": 4,
"start": {
"line": 5,
"line": 1,
"column": 4,
"character": 67
"character": 4
},
"end": {
"line": 5,
"line": 1,
"column": 10,
"character": 73
"character": 10
}
}]
Loading…
Cancel
Save