Merge remote-tracking branch 'origin/version-4' into sites

pull/8671/head
Puru Vijay 1 year ago
parent 4cde4eaada
commit bd51e6f3ea

@ -49,4 +49,4 @@ jobs:
with:
node-version: 16
cache: pnpm
- run: 'pnpm i && pnpm format:check && pnpm lint'
- run: 'pnpm i && pnpm check && pnpm lint'

20
.gitignore vendored

@ -2,24 +2,4 @@
.DS_Store
.vscode
node_modules
*.map
/src/compiler/compile/internal_exports.js
/src/shared/version.js
/compiler.d.ts
/compiler.cjs
/index.d.ts
/action.d.ts
/internal.d.ts
/store.d.ts
/easing.d.ts
/motion.d.ts
/transition.d.ts
/animate.d.ts
/scratch/
/test/*/samples/_
/test/runtime/shards
/yarn-error.log
_actual*.*
_output
/types
.eslintcache

@ -14,7 +14,7 @@ There are many ways to contribute to Svelte, and many of them do not involve wri
- Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/docs#getting-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues).
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). A good starting point would be issues tagged [good first issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#pull-requests).
- Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page.
- Read through our [tutorials](https://learn.svelte.dev/). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this page" at the bottom left of the tutorial page.
- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/feature%20request) by others in the community and consider opening a pull request if you see something you want to work on.
Contributions are very welcome. If you think you need help planning your contribution, please ping us on Discord at [svelte.dev/chat](https://svelte.dev/chat) and let us know you are looking for a bit of help.
@ -74,9 +74,10 @@ Small pull requests are much easier to review and more likely to get merged.
### Installation
1. Ensure you have [pnpm](https://pnpm.io/installation) installed.
1. After cloning the repository, run `pnpm install` in the root of the repository.
1. To compile in watch mode, run `pnpm dev`.
1. Ensure you have [pnpm](https://pnpm.io/installation) installed
1. After cloning the repository, run `pnpm install`. You can do this in the root directory or in the `svelte` project
1. Move into the `svelte` directory with `cd packages/svelte`
1. To compile in watch mode, run `pnpm dev`
### Creating a branch

@ -1,6 +1,6 @@
[![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev)
[![npm version](https://img.shields.io/npm/v/svelte.svg)](https://www.npmjs.com/package/svelte) [![license](https://img.shields.io/npm/l/svelte.svg)](LICENSE.md) [![Chat](https://img.shields.io/discord/457912077277855764?label=chat&logo=discord)](https://svelte.dev/chat)
[![license](https://img.shields.io/npm/l/svelte.svg)](LICENSE.md) [![Chat](https://img.shields.io/discord/457912077277855764?label=chat&logo=discord)](https://svelte.dev/chat)
## What is Svelte?
@ -20,7 +20,11 @@ Funds donated via Open Collective will be used for compensating expenses related
You may view [our roadmap](https://svelte.dev/roadmap) if you'd like to see what we're currently working on.
## Development
## Contributing
Please see the [Contributing Guide](CONTRIBUTING.md) and [svelte package](packages/svelte) for contributing to Svelte.
### Development
Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out!
@ -32,7 +36,7 @@ cd svelte
pnpm install
```
> Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte.
> Do not use Yarn to install the dependencies, as the specific package versions in `pnpm-lock.json` are used to build and test Svelte.
To build the compiler and all the other modules included in the package:
@ -60,11 +64,11 @@ To filter tests, use `-g` (aka `--grep`). For example, to only run tests involvi
pnpm test -- -g transition
```
## svelte.dev
### svelte.dev
The source code for https://svelte.dev lives in the [sites](https://github.com/sveltejs/sites) repository, with all the documentation in the [site/content](site/content) directory. The site is built with [SvelteKit](https://kit.svelte.dev).
### Is svelte.dev down?
## Is svelte.dev down?
Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).

@ -120,6 +120,8 @@ An each block can also have an `{:else}` clause, which is rendered if the list i
{/each}
```
It is possible to iterate over iterables like `Map` or `Set`. Iterables need to be finite and static (they shouldn't change while being iterated over). Under the hood, they are transformed to an array using `Array.from` before being passed off to rendering. If you're writing performance-sensitive code, try to avoid iterables and use regular arrays as they are more performant.
## {#await ...}
```svelte

@ -467,6 +467,14 @@ transition:fn
transition:fn={params}
```
```svelte
transition:fn|global
```
```svelte
transition:fn|global={params}
```
```svelte
transition:fn|local
```
@ -498,7 +506,21 @@ The `transition:` directive indicates a _bidirectional_ transition, which means
{/if}
```
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs/client-side-component-api).
Transitions are local by default (in Svelte 3, they were global by default). Local transitions only play when the block they belong to is created or destroyed, _not_ when parent blocks are created or destroyed.
```svelte
{#if x}
{#if y}
<!-- Svelte 3: <p transition:fade|local> -->
<p transition:fade>fades in and out only when y changes</p>
<!-- Svelte 3: <p transition:fade> -->
<p transition:fade|global>fades in and out when x or y change</p>
{/if}
{/if}
```
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs#run-time-client-side-component-api) and marking the transition as `global`.
## Transition parameters
@ -618,26 +640,22 @@ An element with transitions will dispatch the following events in addition to an
{/if}
```
Local transitions only play when the block they belong to is created or destroyed, _not_ when parent blocks are created or destroyed.
## in:_fn_/out:_fn_
```svelte
{#if x}
{#if y}
<p transition:fade>fades in and out when x or y change</p>
<p transition:fade|local>fades in and out only when y changes</p>
{/if}
{/if}
in:fn
```
## in:_fn_/out:_fn_
```svelte
in:fn={params}
```
```svelte
in:fn
in:fn|global
```
```svelte
in:fn={params}
in:fn|global={params}
```
```svelte
@ -656,6 +674,14 @@ out:fn
out:fn={params}
```
```svelte
out:fn|global
```
```svelte
out:fn|global={params}
```
```svelte
out:fn|local
```

@ -1,145 +1,31 @@
{
"name": "svelte",
"version": "4.0.0-next.0",
"description": "Cybernetically enhanced web apps",
"name": "svelte-monorepo",
"version": "0.0.1",
"description": "monorepo for svelte and friends",
"private": true,
"type": "module",
"module": "src/runtime/index.js",
"main": "src/runtime/index.js",
"files": [
"src",
"types",
"compiler.*",
"register.js",
"index.d.ts",
"internal.d.ts",
"store.d.ts",
"animate.d.ts",
"transition.d.ts",
"easing.d.ts",
"motion.d.ts",
"action.d.ts",
"elements.d.ts",
"README.md"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/runtime/index.d.ts",
"browser": {
"import": "./src/runtime/index.js"
},
"import": "./src/runtime/ssr.js"
},
"./compiler": {
"types": "./types/compiler/index.d.ts",
"import": "./src/compiler/index.js",
"require": "./compiler.cjs"
},
"./action": {
"types": "./types/runtime/action/index.d.ts"
},
"./animate": {
"types": "./types/runtime/animate/index.d.ts",
"import": "./src/runtime/animate/index.js"
},
"./easing": {
"types": "./types/runtime/easing/index.d.ts",
"import": "./src/runtime/easing/index.js"
},
"./internal": {
"types": "./types/runtime/internal/index.d.ts",
"import": "./src/runtime/internal/index.js"
},
"./motion": {
"types": "./types/runtime/motion/index.d.ts",
"import": "./src/runtime/motion/index.js"
},
"./store": {
"types": "./types/runtime/store/index.d.ts",
"import": "./src/runtime/store/index.js"
},
"./transition": {
"types": "./types/runtime/transition/index.d.ts",
"import": "./src/runtime/transition/index.js"
},
"./elements": {
"types": "./elements.d.ts"
}
},
"engines": {
"node": ">=16"
},
"types": "types/runtime/index.d.ts",
"scripts": {
"format:fix": "prettier . --cache --plugin-search-dir=. --write",
"format:check": "prettier . --cache --plugin-search-dir=. --check",
"test": "vitest run && echo \"manually check that there are no type errors in test/types by opening the files in there\"",
"build": "rollup -c && npm run tsd",
"prepare": "npm run build",
"dev": "rollup -cw",
"posttest": "agadoo src/internal/index.js",
"prepublishOnly": "npm run lint && npm run build && npm test",
"tsd": "node ./generate-types.js",
"lint": "eslint \"{src,test}/**/*.{ts,js}\" --cache"
"test": "pnpm test -r --filter=./packages/*",
"build": "pnpm -r build",
"check": "pnpm -r check",
"lint": "pnpm -r lint",
"format": "pnpm -r format"
},
"repository": {
"type": "git",
"url": "https://github.com/sveltejs/svelte.git"
"url": "git+https://github.com/sveltejs/svelte.git"
},
"keywords": [
"UI",
"framework",
"templates",
"templating"
],
"author": "Rich Harris",
"license": "MIT",
"bugs": {
"url": "https://github.com/sveltejs/svelte/issues"
},
"homepage": "https://svelte.dev",
"dependencies": {
"@ampproject/remapping": "^2.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
"acorn": "^8.8.2",
"aria-query": "^5.1.3",
"axobject-query": "^3.1.1",
"code-red": "^1.0.0",
"css-tree": "^2.3.1",
"estree-walker": "^3.0.3",
"is-reference": "^3.0.1",
"locate-character": "^2.0.5",
"magic-string": "^0.30.0",
"periscopic": "^3.1.0"
},
"devDependencies": {
"@playwright/test": "^1.33.0",
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-replace": "^5.0.2",
"@sveltejs/eslint-config": "^6.0.1",
"@types/aria-query": "^5.0.1",
"@types/estree": "^1.0.0",
"@types/node": "^14.14.31",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"agadoo": "^3.0.0",
"esbuild": "^0.17.19",
"@changesets/cli": "^2.26.0",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"eslint": "^8.40.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-svelte": "^2.28.0",
"eslint-plugin-unicorn": "^47.0.0",
"happy-dom": "^9.18.3",
"jsdom": "^21.1.1",
"kleur": "^4.1.5",
"playwright": "^1.34.3",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.0",
"rollup": "^3.20.2",
"source-map": "^0.7.4",
"tiny-glob": "^0.2.9",
"typescript": "^5.0.4",
"util": "^0.12.5",
"vitest": "^0.31.1"
"prettier-plugin-svelte": "^2.10.0"
},
"packageManager": "pnpm@8.4.0"
}

@ -0,0 +1,19 @@
*.map
/src/compiler/compile/internal_exports.js
/src/shared/version.js
/compiler.d.ts
/compiler.cjs
/index.d.ts
/action.d.ts
/internal.d.ts
/store.d.ts
/easing.d.ts
/motion.d.ts
/transition.d.ts
/animate.d.ts
/scratch/
/test/*/samples/_
/test/runtime/shards
_actual*.*
_output
/types

@ -13,9 +13,13 @@
* **breaking** Stricter types for `onMount` - now throws a type error when returning a function asynchronously to catch potential mistakes around callback functions (see PR for migration instructions) ([#8136](https://github.com/sveltejs/svelte/pull/8136))
* **breaking** Overhaul and drastically improve creating custom elements with Svelte (see PR for list of changes and migration instructions) ([#8457](https://github.com/sveltejs/svelte/pull/8457))
* **breaking** Deprecate `SvelteComponentTyped`, use `SvelteComponent` instead ([#8512](https://github.com/sveltejs/svelte/pull/8512))
* **breaking** Make transitions local by default to prevent confusion around page navigations ([#6686](https://github.com/sveltejs/svelte/issues/6686))
* **breaking** Error on falsy values instead of stores passed to `derived` ([#7947](https://github.com/sveltejs/svelte/pull/7947))
* **breaking** Custom store implementers now need to pass an `update` function additionally to the `set` function ([#6750](https://github.com/sveltejs/svelte/pull/6750))
* **breaking** Do not expose default slot bindings to named slots and vice versa ([#6049](https://github.com/sveltejs/svelte/pull/6049))
* **breaking** Change order in which preprocessors are applied ([#8618](https://github.com/sveltejs/svelte/pull/8618))
* **breaking** The runtime now makes use of `classList.toggle(name, boolean)` which does not work in very old browsers ([#8629](https://github.com/sveltejs/svelte/pull/8629))
* **breaking** apply `inert` to outroing elements ([#8627](https://github.com/sveltejs/svelte/pull/8627))
* Add a way to modify attributes for script/style preprocessors ([#8618](https://github.com/sveltejs/svelte/pull/8618))
* Improve hydration speed by adding `data-svelte-h` attribute to detect unchanged HTML elements ([#7426](https://github.com/sveltejs/svelte/pull/7426))
* Add `a11y no-noninteractive-element-interactions` rule ([#8391](https://github.com/sveltejs/svelte/pull/8391))
@ -27,6 +31,9 @@
* Treat slots as if they don't exist when using CSS adjacent and general sibling combinators ([#8284](https://github.com/sveltejs/svelte/issues/8284))
* Fix transitions so that they don't require a `style-src 'unsafe-inline'` Content Security Policy (CSP) ([#6662](https://github.com/sveltejs/svelte/issues/6662)).
* Explicitly disallow `var` declarations extending the reactive statement scope ([#6800](https://github.com/sveltejs/svelte/pull/6800))
* Allow `#each` to iterate over iterables like `Set`, `Map` etc ([#7425](https://github.com/sveltejs/svelte/issues/7425))
* Warn about `:` in attributes and props to prevent ambiguity with Svelte directives ([#6823](https://github.com/sveltejs/svelte/issues/6823))
* Improve error message when trying to use `animate:` directives on inline components ([#8641](https://github.com/sveltejs/svelte/issues/8641))
## 3.59.1

@ -0,0 +1,38 @@
[![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev)
[![npm version](https://img.shields.io/npm/v/svelte.svg)](https://www.npmjs.com/package/svelte) [![license](https://img.shields.io/npm/l/svelte.svg)](LICENSE.md) [![Chat](https://img.shields.io/discord/457912077277855764?label=chat&logo=discord)](https://svelte.dev/chat)
## What is Svelte?
Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.
Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
## Getting started
You can play around with Svelte in the [tutorial](https://learn.svelte.dev/), [examples](https://svelte.dev/examples), and [REPL](https://svelte.dev/repl).
When you're ready to build a full-fledge application, we recommend using [SvelteKit](https://kit.svelte.dev):
```bash
npm create svelte@latest my-app
cd my-app
npm install
npm run dev
```
See [the SvelteKit documentation](https://kit.svelte.dev/docs) to learn more.
## Changelog
[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
## Supporting Svelte
Svelte is an MIT-licensed open source project with its ongoing development made possible entirely by fantastic volunteers. If you'd like to support their efforts, please consider:
- [Becoming a backer on Open Collective](https://opencollective.com/svelte).
Funds donated via Open Collective will be used for compensating expenses related to Svelte's development.

@ -0,0 +1,139 @@
{
"name": "svelte",
"version": "4.0.0-next.0",
"description": "Cybernetically enhanced web apps",
"type": "module",
"module": "src/runtime/index.js",
"main": "src/runtime/index.js",
"files": [
"src",
"types",
"compiler.*",
"register.js",
"index.d.ts",
"internal.d.ts",
"store.d.ts",
"animate.d.ts",
"transition.d.ts",
"easing.d.ts",
"motion.d.ts",
"action.d.ts",
"elements.d.ts",
"README.md"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/runtime/index.d.ts",
"browser": {
"import": "./src/runtime/index.js"
},
"import": "./src/runtime/ssr.js"
},
"./compiler": {
"types": "./types/compiler/index.d.ts",
"import": "./src/compiler/index.js",
"require": "./compiler.cjs"
},
"./action": {
"types": "./types/runtime/action/index.d.ts"
},
"./animate": {
"types": "./types/runtime/animate/index.d.ts",
"import": "./src/runtime/animate/index.js"
},
"./easing": {
"types": "./types/runtime/easing/index.d.ts",
"import": "./src/runtime/easing/index.js"
},
"./internal": {
"types": "./types/runtime/internal/index.d.ts",
"import": "./src/runtime/internal/index.js"
},
"./motion": {
"types": "./types/runtime/motion/index.d.ts",
"import": "./src/runtime/motion/index.js"
},
"./store": {
"types": "./types/runtime/store/index.d.ts",
"import": "./src/runtime/store/index.js"
},
"./transition": {
"types": "./types/runtime/transition/index.d.ts",
"import": "./src/runtime/transition/index.js"
},
"./elements": {
"types": "./elements.d.ts"
}
},
"engines": {
"node": ">=16"
},
"types": "types/runtime/index.d.ts",
"scripts": {
"format": "prettier . --cache --plugin-search-dir=. --write",
"check": "prettier . --cache --plugin-search-dir=. --check",
"test": "vitest run && echo \"manually check that there are no type errors in test/types by opening the files in there\"",
"build": "rollup -c && npm run tsd",
"prepare": "npm run build",
"dev": "rollup -cw",
"posttest": "agadoo src/internal/index.js",
"prepublishOnly": "npm run lint && npm run build && npm test",
"tsd": "node ./generate-types.js",
"lint": "eslint \"{src,test}/**/*.{ts,js}\" --cache"
},
"repository": {
"type": "git",
"url": "https://github.com/sveltejs/svelte.git",
"directory":"packages/svelte"
},
"keywords": [
"UI",
"framework",
"templates",
"templating"
],
"author": "Rich Harris",
"license": "MIT",
"bugs": {
"url": "https://github.com/sveltejs/svelte/issues"
},
"homepage": "https://svelte.dev",
"dependencies": {
"@ampproject/remapping": "^2.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
"acorn": "^8.8.2",
"aria-query": "^5.1.3",
"axobject-query": "^3.1.1",
"code-red": "^1.0.0",
"css-tree": "^2.3.1",
"estree-walker": "^3.0.3",
"is-reference": "^3.0.1",
"locate-character": "^2.0.5",
"magic-string": "^0.30.0",
"periscopic": "^3.1.0"
},
"devDependencies": {
"@playwright/test": "^1.34.3",
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-replace": "^5.0.2",
"@sveltejs/eslint-config": "^6.0.1",
"@types/aria-query": "^5.0.1",
"@types/estree": "^1.0.1",
"@types/node": "^14.14.31",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"agadoo": "^3.0.0",
"esbuild": "^0.17.19",
"happy-dom": "^9.18.3",
"jsdom": "^21.1.1",
"kleur": "^4.1.5",
"rollup": "^3.20.2",
"source-map": "^0.7.4",
"tiny-glob": "^0.2.9",
"typescript": "^5.0.4",
"util": "^0.12.5",
"vitest": "^0.31.1"
}
}

@ -67,7 +67,7 @@ export default [
},
resolve(),
commonjs({
include: ['node_modules/**']
include: ['../../node_modules/**', 'node_modules/**']
}),
json()
],

@ -0,0 +1,40 @@
// Compile all Svelte files in a directory to JS and CSS files
// Usage: node scripts/compile-test.js <directory>
import { mkdirSync, readFileSync, writeFileSync } from 'fs';
import path from 'path';
import glob from 'tiny-glob/sync.js';
import { compile } from '../src/compiler/index.js';
const cwd = path.resolve(process.argv[2]);
const options = [
['normal', {}],
['hydrate', { hydratable: true }],
['ssr', { generate: 'ssr' }]
];
for (const file of glob('**/*.svelte', { cwd })) {
const contents = readFileSync(`${cwd}/${file}`, 'utf-8').replace(/\r/g, '');
let w;
for (const [name, opts] of options) {
const dir = `${cwd}/_output/${name}`;
const { js, css, warnings } = compile(contents, {
...opts,
filename: file
});
if (warnings.length) {
w = warnings;
}
mkdirSync(dir, { recursive: true });
js.code && writeFileSync(`${dir}/${file.replace(/\.svelte$/, '.js')}`, js.code);
css.code && writeFileSync(`${dir}/${file.replace(/\.svelte$/, '.css')}`, css.code);
}
if (w) {
console.log(`Warnings for ${file}:`);
console.log(w);
}
}

@ -1643,8 +1643,9 @@ export default class Component {
* @param {string} name
* @param {any} node
* @param {import('./nodes/shared/TemplateScope.js').default} template_scope
* @param {import("./nodes/shared/Node.js").default} [owner]
*/
warn_if_undefined(name, node, template_scope) {
warn_if_undefined(name, node, template_scope, owner) {
if (name[0] === '$') {
if (name === '$' || (name[1] === '$' && !is_reserved_keyword(name))) {
return this.error(node, compiler_errors.illegal_global(name));
@ -1656,6 +1657,34 @@ export default class Component {
if (this.var_lookup.has(name) && !this.var_lookup.get(name).global) return;
if (template_scope && template_scope.names.has(name)) return;
if (globals.has(name) && node.type !== 'InlineComponent') return;
function has_out_of_scope_let() {
for (let parent = owner.parent; parent; parent = parent.parent) {
if (parent.type === 'InlineComponent') {
const { let_attributes } = parent;
for (const attr of let_attributes) {
if (
// @ts-expect-error
// TODO extract_names only considers patterns but let attributes return expressions
(attr.expression && extract_names(attr.expression).includes(name)) ||
attr.name === name
)
return true;
}
}
}
return false;
}
if (owner && has_out_of_scope_let()) {
return this.warn(node, {
code: 'missing-declaration',
message: `let:${name} declared on parent component cannot be used inside named slot`
});
}
this.warn(node, compiler_warnings.missing_declaration(name, !!this.ast.instance));
}

@ -138,6 +138,10 @@ export default {
code: 'invalid-action',
message: 'Actions can only be applied to DOM elements, not components'
},
invalid_animation: {
code: 'invalid-animation',
message: 'Animations can only be applied to DOM elements, not components'
},
invalid_class: {
code: 'invalid-class',
message: 'Classes can only be applied to DOM elements, not components'

@ -301,5 +301,10 @@ export default {
code: 'avoid-mouse-events-on-document',
message:
'Mouse enter/leave events on the document are not supported in all browsers and should be avoided'
},
illegal_attribute_character: {
code: 'illegal-attribute-character',
message:
"Attributes should not contain ':' characters to prevent ambiguity with Svelte directives"
}
};

@ -8,7 +8,6 @@ import get_name_from_filename from './utils/get_name_from_filename.js';
import { valid_namespaces } from '../utils/namespaces.js';
const valid_options = [
'format',
'name',
'filename',
'sourcemap',
@ -37,11 +36,24 @@ const valid_css_values = [true, false, 'injected', 'external', 'none'];
const regex_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
const regex_starts_with_lowercase_character = /^[a-z]/;
let warned_of_format = false;
/**
* @param {import('../interfaces.js').CompileOptions} options
* @param {import('../interfaces.js').Warning[]} warnings
*/
function validate_options(options, warnings) {
if (/** @type {any} */ (options).format) {
if (!warned_of_format) {
warned_of_format = true;
console.warn(
'The format option has been removed in Svelte 4, the compiler only outputs ESM now. Remove "format" from your compiler options. ' +
'If you did not set this yourself, bump the version of your bundler plugin (vite-plugin-svelte/rollup-plugin-svelte/svelte-loader)'
);
}
delete (/** @type {any} */ (options).format);
}
const { name, filename, loopGuardTimeout, dev, namespace, css } = options;
Object.keys(options).forEach(
/** @param {any} key */ (key) => {

@ -3,6 +3,7 @@ import add_to_set from '../utils/add_to_set.js';
import Node from './shared/Node.js';
import Expression from './shared/Expression.js';
import { x } from 'code-red';
import compiler_warnings from '../compiler_warnings.js';
/** @extends Node<'Attribute' | 'Spread', import('./Element.js').default> */
export default class Attribute extends Node {
@ -39,6 +40,7 @@ export default class Attribute extends Node {
constructor(component, parent, scope, info) {
super(component, parent, scope, info);
this.scope = scope;
if (info.type === 'Spread') {
this.name = null;
this.is_spread = true;
@ -64,10 +66,22 @@ export default class Attribute extends Node {
}
);
}
if (this.dependencies.size > 0) {
parent.cannot_use_innerhtml();
parent.not_static_content();
}
// TODO Svelte 5: Think about moving this into the parser and make it an error
if (
this.name &&
this.name.includes(':') &&
!this.name.startsWith('xmlns:') &&
!this.name.startsWith('xlink:') &&
!this.name.startsWith('xml:')
) {
component.warn(this, compiler_warnings.illegal_attribute_character);
}
}
get_dependencies() {
if (this.is_spread) return this.expression.dynamic_dependencies();

@ -4,7 +4,6 @@ import map_children from './shared/map_children.js';
import Binding from './Binding.js';
import EventHandler from './EventHandler.js';
import Expression from './shared/Expression.js';
import Let from './Let.js';
import compiler_errors from '../compiler_errors.js';
import { regex_only_whitespaces } from '../../utils/patterns.js';
@ -22,9 +21,6 @@ export default class InlineComponent extends Node {
/** @type {import('./EventHandler.js').default[]} */
handlers = [];
/** @type {import('./Let.js').default[]} */
lets = [];
/** @type {import('./Attribute.js').default[]} */
css_custom_properties = [];
@ -37,6 +33,8 @@ export default class InlineComponent extends Node {
/** @type {string} */
namespace;
/** @type {Attribute[]} */
let_attributes;
/**
* @param {import('../Component.js').default} component
* @param {import('./shared/Node.js').default} parent
@ -58,8 +56,12 @@ export default class InlineComponent extends Node {
this.name === 'svelte:component'
? new Expression(component, this, scope, info.expression)
: null;
const let_attributes = (this.let_attributes = []);
info.attributes.forEach(
/** @param {any} node */ (node) => {
/** @param {import('../../interfaces.js').BaseDirective | import('../../interfaces.js').Attribute | import('../../interfaces.js').SpreadAttribute} node */ (
node
) => {
/* eslint-disable no-fallthrough */
switch (node.type) {
case 'Action':
@ -82,33 +84,23 @@ export default class InlineComponent extends Node {
this.handlers.push(new EventHandler(component, this, scope, node));
break;
case 'Let':
this.lets.push(new Let(component, this, scope, node));
let_attributes.push(node);
break;
case 'Transition':
return component.error(node, compiler_errors.invalid_transition);
case 'StyleDirective':
return component.error(node, compiler_errors.invalid_component_style_directive);
case 'Animation':
return component.error(node, compiler_errors.invalid_animation);
default:
throw new Error(`Not implemented: ${node.type}`);
}
/* eslint-enable no-fallthrough */
}
);
if (this.lets.length > 0) {
this.scope = scope.child();
this.lets.forEach(
/** @param {any} l */ (l) => {
const dependencies = new Set([l.name.name]);
l.names.forEach(
/** @param {any} name */ (name) => {
this.scope.add(name, dependencies, this);
}
);
}
);
} else {
this.scope = scope;
}
this.scope = scope;
this.handlers.forEach(
/** @param {any} handler */ (handler) => {
handler.modifiers.forEach(
@ -174,6 +166,18 @@ export default class InlineComponent extends Node {
children: info.children
});
}
if (let_attributes.length) {
// copy let: attribute from <Component /> to <svelte:fragment slot="default" />
// as they are for `slot="default"` only
children.forEach((child) => {
const slot = child.attributes.find((attribute) => attribute.name === 'slot');
if (!slot || slot.value[0].data === 'default') {
child.attributes.push(...let_attributes);
}
});
}
this.children = map_children(component, this, this.scope, children);
}
get slot_template_name() {

@ -40,39 +40,7 @@ export default class Slot extends Element {
}
);
if (!this.slot_name) this.slot_name = 'default';
if (this.slot_name === 'default') {
// if this is the default slot, add our dependencies to any
// other slots (which inherit our slot values) that were
// previously encountered
component.slots.forEach(
/** @param {any} slot */ (slot) => {
this.values.forEach(
/**
* @param {any} attribute
* @param {any} name
*/ (attribute, name) => {
if (!slot.values.has(name)) {
slot.values.set(name, attribute);
}
}
);
}
);
} else if (component.slots.has('default')) {
// otherwise, go the other way — inherit values from
// a previously encountered default slot
const default_slot = component.slots.get('default');
default_slot.values.forEach(
/**
* @param {any} attribute
* @param {any} name
*/ (attribute, name) => {
if (!this.values.has(name)) {
this.values.set(name, attribute);
}
}
);
}
component.slots.set(this.slot_name, this);
this.cannot_use_innerhtml();
this.not_static_content();

@ -28,7 +28,7 @@ export default class Transition extends Node {
this.name = info.name;
component.add_reference(/** @type {any} */ (this), info.name.split('.')[0]);
this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
this.is_local = info.modifiers.includes('local');
this.is_local = !info.modifiers.includes('global');
if ((info.intro && parent.intro) || (info.outro && parent.outro)) {
const parent_transition = parent.intro || parent.outro;
component.error(

@ -77,6 +77,7 @@ export default class Expression {
this.scope_map = map;
const expression = this;
let function_expression;
// discover dependencies, but don't change the code yet
walk(info, {
/**
@ -125,7 +126,7 @@ export default class Expression {
dependencies.add(name);
}
component.add_reference(node, name);
component.warn_if_undefined(name, nodes[0], template_scope);
component.warn_if_undefined(name, nodes[0], template_scope, owner);
}
this.skip();
}
@ -376,8 +377,9 @@ export default class Expression {
node = node.parent;
}
const func_expression = func_declaration[0];
if (node.type === 'InlineComponent' || node.type === 'SlotTemplate') {
// <Comp let:data />
if (node.type === 'SlotTemplate') {
// <svelte:fragment let:data />
this.replace(func_expression);
} else {
// {#each}, {#await}
@ -458,6 +460,7 @@ export default class Expression {
}
}
});
if (declarations.length > 0) {
block.maintain_context = true;
declarations.forEach(

@ -206,11 +206,8 @@ export default class EachBlockWrapper extends Wrapper {
const needs_anchor = this.next
? !this.next.is_dom_node()
: !parent_node || !this.parent.is_dom_node();
const snippet = this.node.expression.manipulate(block);
const snippet = x`@ensure_array_like(${this.node.expression.manipulate(block)})`;
block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`);
if (this.renderer.options.dev) {
block.chunks.init.push(b`@validate_each_argument(${this.vars.each_block_value});`);
}
/** @type {import('estree').Identifier} */
const initial_anchor_node = {
@ -480,7 +477,6 @@ export default class EachBlockWrapper extends Wrapper {
this.block.maintain_context = true;
this.updates.push(b`
${this.vars.each_block_value} = ${snippet};
${this.renderer.options.dev && b`@validate_each_argument(${this.vars.each_block_value});`}
${this.block.has_outros && b`@group_outros();`}
${
@ -628,7 +624,6 @@ export default class EachBlockWrapper extends Wrapper {
const update = b`
${!this.block.has_update_method && b`const #old_length = ${this.vars.each_block_value}.length;`}
${this.vars.each_block_value} = ${snippet};
${this.renderer.options.dev && b`@validate_each_argument(${this.vars.each_block_value});`}
let #i;
for (#i = ${start}; #i < ${data_length}; #i += 1) {

@ -422,10 +422,10 @@ export default class ElementWrapper extends Wrapper {
`);
}
if (this.child_dynamic_element_block.has_intros) {
block.chunks.intro.push(b`@transition_in(${this.var});`);
block.chunks.intro.push(b`@transition_in(${this.var}, #local);`);
}
if (this.child_dynamic_element_block.has_outros) {
block.chunks.outro.push(b`@transition_out(${this.var});`);
block.chunks.outro.push(b`@transition_out(${this.var}, #local);`);
}
block.chunks.destroy.push(b`if (${this.var}) ${this.var}.d(detaching)`);
if (this.node.animation) {

@ -1,19 +1,18 @@
import Wrapper from '../shared/Wrapper.js';
import BindingWrapper from '../Element/Binding.js';
import SlotTemplateWrapper from '../SlotTemplate.js';
import { b, p, x } from 'code-red';
import { extract_ignores_above_node } from '../../../../utils/extract_svelte_ignore.js';
import { sanitize } from '../../../../utils/names.js';
import { namespaces } from '../../../../utils/namespaces.js';
import compiler_warnings from '../../../compiler_warnings.js';
import add_to_set from '../../../utils/add_to_set.js';
import { b, x, p } from 'code-red';
import is_dynamic from '../shared/is_dynamic.js';
import bind_this from '../shared/bind_this.js';
import EventHandler from '../Element/EventHandler.js';
import { extract_names } from 'periscopic';
import mark_each_block_bindings from '../shared/mark_each_block_bindings.js';
import { string_to_member_expression } from '../../../utils/string_to_member_expression.js';
import BindingWrapper from '../Element/Binding.js';
import EventHandler from '../Element/EventHandler.js';
import SlotTemplateWrapper from '../SlotTemplate.js';
import Wrapper from '../shared/Wrapper.js';
import bind_this from '../shared/bind_this.js';
import is_dynamic from '../shared/is_dynamic.js';
import { is_head } from '../shared/is_head.js';
import compiler_warnings from '../../../compiler_warnings.js';
import { namespaces } from '../../../../utils/namespaces.js';
import { extract_ignores_above_node } from '../../../../utils/extract_svelte_ignore.js';
import mark_each_block_bindings from '../shared/mark_each_block_bindings.js';
const regex_invalid_variable_identifier_characters = /[^a-zA-Z_$]/g;
@ -77,11 +76,6 @@ export default class InlineComponentWrapper extends Wrapper {
).toLowerCase()
};
if (this.node.children.length) {
this.node.lets.forEach((l) => {
extract_names(l.value || l.name).forEach((name) => {
renderer.add_to_context(name, true);
});
});
this.children = this.node.children.map(
(child) =>
new SlotTemplateWrapper(

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save