Merge branch 'master' into feat/orama

feat/orama
Puru Vijay 1 year ago
commit 8f5370aa6b

@ -1,5 +0,0 @@
---
'svelte': patch
---
fix: align `disclose-version` exports specification

@ -1,5 +0,0 @@
---
'svelte': patch
---
fix: check srcset when hydrating to prevent needless requests

@ -7,7 +7,7 @@ permissions:
contents: read # to fetch code (actions/checkout)
env:
# We only install Chromium manually
# We only install Chromium manually
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
jobs:

@ -16,13 +16,9 @@ We think it'll give you a much nicer development experience — one that also sc
## Try it now
You can start a new Svelte TypeScript project using the [normal template](https://github.com/sveltejs/template) and by running `node scripts/setupTypeScript.js` before you do anything else:
You can start a new Svelte TypeScript project using Svelte's official scaffolding CLI by running `npm create svelte@latest` and following the prompts. This sets up a new SvelteKit project for you.
```bash
npx degit sveltejs/template svelte-typescript-app
cd svelte-typescript-app
node scripts/setupTypeScript.js
```
Alternatively you can run `npm create vite@latest myapp -- --template svelte-ts` to scaffold a Vite project using Svelte and TypeScript.
If you're a VS Code user, make sure you're using the (new) [official extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which replaces the popular extension by James Birtles.
Later in this blog post, we'll detail the individual steps involved in using TypeScript in an existing Svelte project.

@ -0,0 +1,95 @@
---
title: "What's new in Svelte: July 2023"
description: "Svelte 4.0, new website and a tour around the community"
author: Dani Sandoval
authorURL: https://dreamindani.com
---
Svelte 4 is out and folks have been building! There's a bunch of new showcases, libraries and tutorials to share. So let's get right into it...
## What's new in Svelte
The big news this month was the release of Svelte 4.0! You can read all about it in the [Announcing Svelte 4 post](https://svelte.dev/blog/svelte-4). From performance fixes and developer experience improvements to [a brand new site, docs and tutorial](https://svelte.dev/blog/svelte-dev-overhaul)... this new release sets the stage for Svelte 5 with minimal breaking changes.
If you're already on Node.js 16, it's possible you won't see any breaking changes in your project. But be sure to read the [migration guide](https://svelte.dev/docs/v4-migration-guide) for all the details.
For a full list of all the changes to the Svelte compiler, including unreleased changes, check out the [CHANGELOG](https://github.com/sveltejs/svelte/blob/master/packages/svelte/CHANGELOG.md).
## What's new in SvelteKit
This month there were lots of awesome [bug fixes](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md), so be sure to upgrade to the latest version! There are also a few new features to mention:
- The new `event.isSubRequest` boolean indicates whether this is a same-origin fetch request to one of the app's own APIs during a server request (**1.21.0**, [Docs](https://kit.svelte.dev/docs/types#public-types-requestevent), [#10170](https://github.com/sveltejs/kit/pull/10170))
- A new config option, `config.kit.env.privatePrefix` will set a private prefix on environment variables. This defaults to `''` (**1.21.0**, [Docs](https://kit.svelte.dev/docs/configuration), [#9996](https://github.com/sveltejs/kit/pull/9996))
- `VERSION` is now exported and accessible via `@sveltejs/kit`. This can be used for feature detection or anything else that requires knowledge of the current version of SvelteKit (**1.21.0**, [Docs](https://kit.svelte.dev/docs/modules#sveltejs-kit-version), [#9969](https://github.com/sveltejs/kit/pull/9969))
For adapter-specific changes, check out the CHANGELOGs in each of [the `adapter` directories](https://github.com/sveltejs/kit/tree/master/packages).
---
## Community Showcase
**Apps & Sites built with Svelte**
- [Heerdle](https://github.com/DreaminDani/heerdle) is a remake of Spotify's now-defunct Heardle - the daily music guessing game
- [Meoweler](https://meoweler.com/) is a travel site filled with cats and helpful facts about popular destinations
- [A tech lead from IKEA](https://www.reddit.com/r/sveltejs/comments/13w4zg3/comment/jmaxial/?utm_source=share&utm_medium=web2x&context=3) gave a few more details on the way they build pages (and page template) using Svelte
- [The Quest to Replace Passwords](https://notes.ekzhang.com/papers/passwords) features an interactive comparison visualization for all the popular password management tools
- [audiogest](https://audiogest.app/en) lets you turn speech to text & summarize any audio in one click
- [heroify](https://www.heroify.lol/) generates 3D graphics for your website with AI
- [Diesel Legacy: The Brazen Age](https://store.steampowered.com/app/1959140/Diesel_Legacy_The_Brazen_Age/) is a fighting game whose leaderboard and profile pages were all built in Svelte
- [markmyimages](https://www.markmyimages.com/) is a watermarking tool with bulk image resize, rename, effects, and more
- [md.robino.dev](https://github.com/rossrobino/md) is a web based markdown editor
- [YABin](https://github.com/Yureien/YABin) is Yet Another Pastebin with some very specific features
**Learning Resources**
- [Announcing Svelte 4 post](https://svelte.dev/blog/svelte-4)
- [svelte.dev: A complete overhaul](https://svelte.dev/blog/svelte-dev-overhaul)
_Featuring Svelte Contributors and Ambassadors_
- [Dev Vlog: June 2023](https://www.youtube.com/watch?v=AOXq89h8saI) - Svelte 4.0 with Rich Harris
- [PodRocket: Svelte 4](https://podrocket.logrocket.com/svelte-4) with Geoff
- [This Dot Media: Svelte 4 Launch Party](https://www.youtube.com/watch?v=-9gy_leMmcQ) with Simon, Ben, Geoff, and Puru
- [Exposing Svelte: Between Two Nerds](https://www.youtube.com/watch?v=kAfotLrebhY) is a comedic conversation between Rich Harris and Dax Raad
- [Community Tutorial: Self-hosting SvelteKit with a VPS, Docker, CapRover and GitHub Actions](https://www.youtube.com/watch?v=KbIFRVvdgA8) with Stanislav Khromov
- [SvelteKit and Storybook](https://www.youtube.com/watch?v=1wH7rR7hZlg) with Jeppe Reinhold
- This Week in Svelte:
- [2023 June 2](https://www.youtube.com/watch?v=B2AOYWs6eko) - SvelteKit 1.20.1, Svelte 4 pre-release, Headless UI libraries
- [2023 June 9](https://www.youtube.com/watch?v=OG70PKD0hEU) - Updates, Self-hosting SvelteKit, Passing styles to children
- [2023 June 16](https://www.youtube.com/watch?v=GNEbC5K34Po) - Svelte 4 next.1, how to create a hamburger menu, group layouts
- [2023 June 23](https://www.youtube.com/watch?v=o-qnnbMbmE4) - Svelte 4, Popovers and hover, Real Time requests with SvelteKit
- Svelte Radio
- [SvelteLab - a Svelte REPL for SvelteKit](https://www.svelteradio.com/episodes/sveltelab-a-svelte-repl-for-sveltekit-with-antonio-and-paolo) with Antonio and Paolo
- [Svelte Radio Live - Svelte 4 Summer Special](https://www.youtube.com/watch?v=72TIVhRtyWE) with Simon and Puru
- [Svelte Society - London June 2023](https://www.youtube.com/watch?v=EkH0aMgeIKw)
- [Using The Svelte Context API With Stores](https://www.youtube.com/watch?v=dp-7NvLDrK4), [Impossible FLIP Layout Animations With Svelte And GSAP](https://www.youtube.com/watch?v=ecP8RwpkiQw) and [Create Beautiful Presentations With Svelte](https://www.youtube.com/watch?v=67lqa5kTQkA) by Joy of Code
_To Watch_
- [Server-side filtered, paginated and sorted Table in SvelteKit](https://www.youtube.com/watch?v=VgCU0cVWgJE) by hartenfellerdev
- [Best Icon Library for Svelte and SvelteKit in 2023](https://www.youtube.com/watch?v=qJP6hC4YIhk) by SvelteRust
_To Read_
- [From Zero to Production with SvelteKit](https://www.okupter.com/events/from-zero-to-production-with-sveltekit) by Justin Ahinon
- [Thoughts on Svelte(Kit), one year and 3 billion requests later](https://claudioholanda.ch/en/blog/svelte-kit-after-3-billion-requests/) by Claudio Holanda
- [How I published a gratitude journaling app for iOS and Android using SvelteKit and Capacitor](https://khromov.se/how-i-published-a-gratitude-journaling-app-for-ios-and-android-using-sveltekit-and-capacitor/) by Stanislav Khromov
- [Learning by doing - Vue devs build a Svelte Single Page App](https://www.blackspike.com/blog/learning-svelte-by-building-a-single-page-application/) by Black Spike
- [Generate Breadcrumb and Navigation in SvelteKit](https://blog.aakashgoplani.in/generate-breadcrumb-and-navigation-in-sveltekit), [SvelteKit Authentication using SvelteKitAuth and OAuth providers: A Comprehensive Guide](https://blog.aakashgoplani.in/sveltekit-authentication-using-sveltekitauth-and-oauth-providers-a-comprehensive-guide) and [SvelteKitAuth with Salesforce OAuth provider](https://blog.aakashgoplani.in/sveltekitauth-with-salesforce-oauth-provider) by Aakash Goplani
- [Instantly find and remove Svelte component orphans](https://node-jz.medium.com/instantly-find-and-remove-svelte-component-orphans-9b2838ea2d99) by Jeremy Zaborowski
- [Migration Guide from Routify to SvelteKit Router](https://blog.aakashgoplani.in/migration-guide-from-routify-to-sveltekit-router) by Aakash Goplani
- [Creating 3D data visualization using Threlte and D3](https://www.datavizcubed.com/) by DataViz Cubed
- [Svelte Realtime Multiplayer Game: User Presence](https://rodneylab.com/svelte-realtime-multiplayer-game/) and [SvelteKit PostCSS Tutorial: use Future CSS Today](https://rodneylab.com/sveltekit-postcss-tutorial/) by Rodney Lab
- [SvelteKits World of Routing: Unleash power of your app using Dynamic Routes and Parameters](https://www.inow.dev/sveltekits-world-of-routing-unleash-power-of-your-app-using-dynamic-routes-and-parameters/) by Igor Nowosad
**Libraries, Tools & Components**
- [The Vercel AI SDK](https://vercel.com/blog/introducing-the-vercel-ai-sdk) is an interoperable, streaming-enabled, edge-ready software development kit for AI apps built with React and Svelte
- [Superforms 1.0](https://superforms.rocks/) has been released. Check out the [migration guide](https://superforms.rocks/migration) and [new feature list](https://superforms.rocks/whats-new-v1) for more details
- [Panda CSS](https://panda-css.com/docs/getting-started/svelte) is CSS-in-JS with build time generated styles, RSC compatibility and multi-variant support
- [svelte-section-list](https://github.com/TIKramer/svelte-section-list) is a headless Svelte npm package that provides drag-and-drop functionality for managing items and sections
- [WebStorm](https://twitter.com/tomblachut/status/1669759906579185681?t=6WzLPUi65wsLtbVvYky7UQ&s=19) is starting to use the Svelte Language Server in its IDE tooling
- [shadcn-svelte](https://www.shadcn-svelte.com/) is an unofficial port of [shadcn/ui](https://github.com/shadcn/ui) to Svelte that makes it easy to build your component library from common base components
- [sveltekit-multibuild](https://github.com/MrNNP/sveltekit-multibuild) is a starter repo to create Android apps, web sites, desktop apps, and Chrome extensions automatically
- [SvelteKit AI Chatbot](https://github.com/jianyuan/sveltekit-ai-chatbot) is an open-source AI chatbot app template built with SvelteKit, the Vercel AI SDK, OpenAI, and Vercel KV.
- [KitAI](https://kit-ai.vercel.app/) provides batteries-included AI templates for SvelteKit and Next.js
- [Svelte Form Builder](https://github.com/pragmatic-engineering/svelte-form-builder-community) is a no-code drag&drop form builder for Svelte
Thanks for reading! As always, feel free to let us know if we missed anything on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.gg/svelte).
Until next time 👋

@ -121,7 +121,18 @@ The migration script will do both automatically for you. ([#8512](https://github
## Transitions are local by default
Transitions are now local by default to prevent confusion around page navigations. To make them global, add the `|global` modifier. The migration script will do this automatically for you. ([#6686](https://github.com/sveltejs/svelte/issues/6686))
Transitions are now local by default to prevent confusion around page navigations. "local" means that a transition will not play if it's within a nested control flow block (`each/if/await/key`) and not the direct parent block but a block above it is created/destroyed. In the following example, the `slide` intro animation will only play when `success` goes from `false` to `true`, but it will _not_ play when `show` goes from `false` to `true`:
```svelte
{#if show}
...
{#if success}
<p in:slide>Success</p>
{/each}
{/if}
```
To make transitions global, add the `|global` modifier - then they will play when _any_ control flow block above is created/destroyed. The migration script will do this automatically for you. ([#6686](https://github.com/sveltejs/svelte/issues/6686))
## Default slot bindings
@ -152,7 +163,7 @@ The order in which preprocessors are applied has changed. Now, preprocessors are
- the `inert` attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction. ([#8628](https://github.com/sveltejs/svelte/pull/8628))
- the runtime now uses `classList.toggle(name, boolean)` which may not work in very old browsers. Consider using a [polyfill](https://github.com/eligrey/classList.js) if you need to support these browsers. ([#8629](https://github.com/sveltejs/svelte/issues/8629))
- the runtime now uses the `CustomElement` constructor which may not work in very old browsers. Consider using a [polyfill](https://github.com/theftprevention/event-constructor-polyfill/tree/master) if you need to support these browsers. ([#8775](https://github.com/sveltejs/svelte/pull/8775))
- the runtime now uses the `CustomEvent` constructor which may not work in very old browsers. Consider using a [polyfill](https://github.com/theftprevention/event-constructor-polyfill/tree/master) if you need to support these browsers. ([#8775](https://github.com/sveltejs/svelte/pull/8775))
- people implementing their own stores from scratch using the `StartStopNotifier` interface (which is passed to the create function of `writable` etc) from `svelte/store` now need to pass an update function in addition to the set function. This has no effect on people using stores or creating stores using the existing Svelte stores. ([#6750](https://github.com/sveltejs/svelte/issues/6750))
- `derived` will now throw an error on falsy values instead of stores passed to it. ([#7947](https://github.com/sveltejs/svelte/issues/7947))
- type definitions for `svelte/internal` were removed to further discourage usage of those internal methods which are not public API. Most of these will likely change for Svelte 5

@ -10,3 +10,9 @@
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
<style>
button {
width:200px;
}
</style>

@ -10,3 +10,9 @@
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
<style>
button {
width:200px;
}
</style>

@ -10,6 +10,4 @@ You can also declare event handlers inline:
</div>
```
The quote marks are optional, but they're helpful for syntax highlighting in some environments.
> In some frameworks you may see recommendations to avoid inline event handlers for performance reasons, particularly inside loops. That advice doesn't apply to Svelte — the compiler will always do the right thing, whichever form you choose.

@ -9,7 +9,7 @@
"build": "pnpm -r --filter=./packages/* build",
"build:sites": "pnpm -r --filter=./sites/* build",
"check": "cd packages/svelte && pnpm build && cd ../../ && pnpm -r check",
"lint": "pnpm -r lint",
"lint": "cd packages/svelte && pnpm build && cd ../../ && pnpm -r lint",
"format": "pnpm -r format",
"changeset:version": "changeset version && pnpm -r generate:version && git add --all",
"changeset:publish": "changeset publish"

@ -1,5 +1,25 @@
# svelte
## 4.0.3
### Patch Changes
- fix: handle falsy srcset values ([#8901](https://github.com/sveltejs/svelte/pull/8901))
## 4.0.2
### Patch Changes
- fix: reflect all custom element prop updates back to attribute ([#8898](https://github.com/sveltejs/svelte/pull/8898))
- fix: shrink custom element baseline a bit ([#8858](https://github.com/sveltejs/svelte/pull/8858))
- fix: use non-destructive hydration for all `@html` tags ([#8880](https://github.com/sveltejs/svelte/pull/8880))
- fix: align `disclose-version` exports specification ([#8874](https://github.com/sveltejs/svelte/pull/8874))
- fix: check srcset when hydrating to prevent needless requests ([#8868](https://github.com/sveltejs/svelte/pull/8868))
## 4.0.1
### Patch Changes

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "4.0.1",
"version": "4.0.3",
"description": "Cybernetically enhanced web apps",
"type": "module",
"module": "src/runtime/index.js",
@ -74,7 +74,7 @@
"types": "types/index.d.ts",
"scripts": {
"format": "prettier . --cache --plugin-search-dir=. --write",
"check": "prettier . --cache --plugin-search-dir=. --check",
"check": "tsc --noEmit",
"test": "vitest run && echo \"manually check that there are no type errors in test/types by opening the files in there\"",
"build": "rollup -c && pnpm types",
"generate:version": "node ./scripts/generate-version.js",
@ -82,7 +82,7 @@
"posttest": "agadoo src/internal/index.js",
"prepublishOnly": "pnpm build",
"types": "node ./scripts/generate-dts.js",
"lint": "eslint \"{src,test}/**/*.{ts,js}\" --cache"
"lint": "prettier . --cache --plugin-search-dir=. --check && eslint \"{src,test}/**/*.{ts,js}\" --cache"
},
"repository": {
"type": "git",

@ -26,7 +26,7 @@ export default class RawMustacheTagWrapper extends Tag {
render(block, parent_node, _parent_nodes) {
const in_head = is_head(parent_node);
const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next;
if (can_use_innerhtml) {
if (can_use_innerhtml && !this.renderer.options.hydratable) {
/** @param {import('estree').Node} content */
const insert = (content) => b`${parent_node}.innerHTML = ${content};`[0];
const { init } = this.rename_this_method(block, (content) => insert(content));

@ -13,7 +13,9 @@ import {
start_hydrating,
end_hydrating,
get_custom_elements_slots,
insert
insert,
element,
attr
} from './dom.js';
import { transition_in } from './transitions.js';
@ -157,23 +159,29 @@ export let SvelteElement;
if (typeof HTMLElement === 'function') {
SvelteElement = class extends HTMLElement {
$$componentCtor;
$$slots;
$$component;
$$connected = false;
$$data = {};
$$reflecting = false;
/** @type {Record<string, CustomElementPropDefinition>} */
$$props_definition = {};
/** @type {Record<string, Function[]>} */
$$listeners = {};
/** @type {Map<Function, Function>} */
$$listener_unsubscribe_fns = new Map();
/** The Svelte component constructor */
$$ctor;
/** Slots */
$$s;
/** The Svelte component instance */
$$c;
/** Whether or not the custom element is connected */
$$cn = false;
/** Component props data */
$$d = {};
/** `true` if currently in the process of reflecting component props back to attributes */
$$r = false;
/** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
$$p_d = {};
/** @type {Record<string, Function[]>} Event listeners */
$$l = {};
/** @type {Map<Function, Function>} Event listener unsubscribe functions */
$$l_u = new Map();
constructor($$componentCtor, $$slots, use_shadow_dom) {
super();
this.$$componentCtor = $$componentCtor;
this.$$slots = $$slots;
this.$$ctor = $$componentCtor;
this.$$s = $$slots;
if (use_shadow_dom) {
this.attachShadow({ mode: 'open' });
}
@ -183,32 +191,32 @@ if (typeof HTMLElement === 'function') {
// We can't determine upfront if the event is a custom event or not, so we have to
// listen to both. If someone uses a custom event with the same name as a regular
// browser event, this fires twice - we can't avoid that.
this.$$listeners[type] = this.$$listeners[type] || [];
this.$$listeners[type].push(listener);
if (this.$$component) {
const unsub = this.$$component.$on(type, listener);
this.$$listener_unsubscribe_fns.set(listener, unsub);
this.$$l[type] = this.$$l[type] || [];
this.$$l[type].push(listener);
if (this.$$c) {
const unsub = this.$$c.$on(type, listener);
this.$$l_u.set(listener, unsub);
}
super.addEventListener(type, listener, options);
}
removeEventListener(type, listener, options) {
super.removeEventListener(type, listener, options);
if (this.$$component) {
const unsub = this.$$listener_unsubscribe_fns.get(listener);
if (this.$$c) {
const unsub = this.$$l_u.get(listener);
if (unsub) {
unsub();
this.$$listener_unsubscribe_fns.delete(listener);
this.$$l_u.delete(listener);
}
}
}
async connectedCallback() {
this.$$connected = true;
if (!this.$$component) {
this.$$cn = true;
if (!this.$$c) {
// We wait one tick to let possible child slot elements be created/mounted
await Promise.resolve();
if (!this.$$connected) {
if (!this.$$cn) {
return;
}
function create_slot(name) {
@ -216,9 +224,9 @@ if (typeof HTMLElement === 'function') {
let node;
const obj = {
c: function create() {
node = document.createElement('slot');
node = element('slot');
if (name !== 'default') {
node.setAttribute('name', name);
attr(node, 'name', name);
}
},
/**
@ -239,74 +247,89 @@ if (typeof HTMLElement === 'function') {
}
const $$slots = {};
const existing_slots = get_custom_elements_slots(this);
for (const name of this.$$slots) {
for (const name of this.$$s) {
if (name in existing_slots) {
$$slots[name] = [create_slot(name)];
}
}
for (const attribute of this.attributes) {
// this.$$data takes precedence over this.attributes
const name = this.$$get_prop_name(attribute.name);
if (!(name in this.$$data)) {
this.$$data[name] = get_custom_element_value(
name,
attribute.value,
this.$$props_definition,
'toProp'
);
const name = this.$$g_p(attribute.name);
if (!(name in this.$$d)) {
this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, 'toProp');
}
}
this.$$component = new this.$$componentCtor({
this.$$c = new this.$$ctor({
target: this.shadowRoot || this,
props: {
...this.$$data,
...this.$$d,
$$slots,
$$scope: {
ctx: []
}
}
});
for (const type in this.$$listeners) {
for (const listener of this.$$listeners[type]) {
const unsub = this.$$component.$on(type, listener);
this.$$listener_unsubscribe_fns.set(listener, unsub);
// Reflect component props as attributes
const reflect_attributes = () => {
this.$$r = true;
for (const key in this.$$p_d) {
this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]];
if (this.$$p_d[key].reflect) {
const attribute_value = get_custom_element_value(
key,
this.$$d[key],
this.$$p_d,
'toAttribute'
);
if (attribute_value == null) {
this.removeAttribute(key);
} else {
this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
}
}
}
this.$$r = false;
};
this.$$c.$$.after_update.push(reflect_attributes);
reflect_attributes(); // once initially because after_update is added too late for first render
for (const type in this.$$l) {
for (const listener of this.$$l[type]) {
const unsub = this.$$c.$on(type, listener);
this.$$l_u.set(listener, unsub);
}
}
this.$$listeners = {};
this.$$l = {};
}
}
// We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
// and setting attributes through setAttribute etc, this is helpful
attributeChangedCallback(attr, _oldValue, newValue) {
if (this.$$reflecting) return;
attr = this.$$get_prop_name(attr);
this.$$data[attr] = get_custom_element_value(
attr,
newValue,
this.$$props_definition,
'toProp'
);
this.$$component?.$set({ [attr]: this.$$data[attr] });
if (this.$$r) return;
attr = this.$$g_p(attr);
this.$$d[attr] = get_custom_element_value(attr, newValue, this.$$p_d, 'toProp');
this.$$c?.$set({ [attr]: this.$$d[attr] });
}
disconnectedCallback() {
this.$$connected = false;
this.$$cn = false;
// In a microtask, because this could be a move within the DOM
Promise.resolve().then(() => {
if (!this.$$connected) {
this.$$component.$destroy();
this.$$component = undefined;
if (!this.$$cn) {
this.$$c.$destroy();
this.$$c = undefined;
}
});
}
$$get_prop_name(attribute_name) {
$$g_p(attribute_name) {
return (
Object.keys(this.$$props_definition).find(
Object.keys(this.$$p_d).find(
(key) =>
this.$$props_definition[key].attribute === attribute_name ||
(!this.$$props_definition[key].attribute && key.toLowerCase() === attribute_name)
this.$$p_d[key].attribute === attribute_name ||
(!this.$$p_d[key].attribute && key.toLowerCase() === attribute_name)
) || attribute_name
);
}
@ -371,7 +394,7 @@ export function create_custom_element(
const Class = class extends SvelteElement {
constructor() {
super(Component, slots, use_shadow_dom);
this.$$props_definition = props_definition;
this.$$p_d = props_definition;
}
static get observedAttributes() {
return Object.keys(props_definition).map((key) =>
@ -382,36 +405,19 @@ export function create_custom_element(
Object.keys(props_definition).forEach((prop) => {
Object.defineProperty(Class.prototype, prop, {
get() {
return this.$$component && prop in this.$$component
? this.$$component[prop]
: this.$$data[prop];
return this.$$c && prop in this.$$c ? this.$$c[prop] : this.$$d[prop];
},
set(value) {
value = get_custom_element_value(prop, value, props_definition);
this.$$data[prop] = value;
this.$$component?.$set({ [prop]: value });
if (props_definition[prop].reflect) {
this.$$reflecting = true;
const attribute_value = get_custom_element_value(
prop,
value,
props_definition,
'toAttribute'
);
if (attribute_value == null) {
this.removeAttribute(prop);
} else {
this.setAttribute(props_definition[prop].attribute || prop, attribute_value);
}
this.$$reflecting = false;
}
this.$$d[prop] = value;
this.$$c?.$set({ [prop]: value });
}
});
});
accessors.forEach((accessor) => {
Object.defineProperty(Class.prototype, accessor, {
get() {
return this.$$component?.[accessor];
return this.$$c?.[accessor];
}
});
});

@ -90,12 +90,12 @@ function split_srcset(srcset) {
/**
* @param {HTMLSourceElement | HTMLImageElement} element_srcset
* @param {string} srcset
* @param {string | undefined | null} srcset
* @returns {boolean}
*/
export function srcset_url_equal(element_srcset, srcset) {
const element_urls = split_srcset(element_srcset.srcset);
const urls = split_srcset(srcset);
const urls = split_srcset(srcset || '');
return (
urls.length === element_urls.length &&

@ -6,5 +6,5 @@
* https://svelte.dev/docs/svelte-compiler#svelte-version
* @type {string}
*/
export const VERSION = '4.0.1';
export const VERSION = '4.0.3';
export const PUBLIC_VERSION = '4';

Binary file not shown.

@ -1,19 +1,20 @@
<svelte:options
customElement={{
tag: "custom-element",
props: { red: { reflect: true, type: "Boolean" } },
tag: 'custom-element',
props: { red: { reflect: true, type: 'Boolean' } }
}}
/>
<script>
import "./my-widget.svelte";
import './my-widget.svelte';
export let red;
red;
</script>
<div>hi</div>
<p>hi</p>
<my-widget red white />
<button on:click={() => (red = false)}>off</button>
<my-widget {red} white />
<style>
:host([red]) div {

@ -9,6 +9,7 @@ export default async function (target) {
const ceRoot = target.querySelector('custom-element').shadowRoot;
const div = ceRoot.querySelector('div');
const p = ceRoot.querySelector('p');
const button = ceRoot.querySelector('button');
assert.equal(getComputedStyle(div).color, 'rgb(255, 0, 0)');
assert.equal(getComputedStyle(p).color, 'rgb(255, 255, 255)');
@ -19,4 +20,11 @@ export default async function (target) {
assert.equal(getComputedStyle(innerDiv).color, 'rgb(255, 0, 0)');
assert.equal(getComputedStyle(innerP).color, 'rgb(255, 255, 255)');
button.click();
await tick();
await tick();
assert.equal(getComputedStyle(div).color, 'rgb(0, 0, 0)');
assert.equal(getComputedStyle(innerDiv).color, 'rgb(0, 0, 0)');
}

@ -1,9 +1,7 @@
export default {
html: `
<svg>
<foreignObject>
<circle cx="25" cy="30" r="24" fill="#FFD166"></circle>
</foreignObject>
<foreignObject><!-- HTML_TAG_START --><circle cx="25" cy="30" r="24" fill="#FFD166"></circle><!-- HTML_TAG_END --></foreignObject>
</svg>
`,
test({ assert, target, component }) {

@ -1,7 +1,7 @@
<script>
export let width = 100
export let height = 60
$: circle = `<circle cx="${width/4}" cy="${height/2}" r="24" fill="#FFD166"/>`
export let width = 100;
export let height = 60;
$: circle = `<circle cx="${width / 4}" cy="${height / 2}" r="24" fill="#FFD166"></circle>`;
</script>
<svg>

@ -162,6 +162,7 @@ describe('utils', () => {
it('should return false if urls are different', () => {
assert.notOk(srcset_url_equal(create_element('a 1x'), 'b 1x'));
assert.notOk(srcset_url_equal(create_element('a 2x'), 'a 1x'));
assert.notOk(srcset_url_equal(create_element('a 2x'), null));
});
});
});

@ -35,6 +35,9 @@
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"typeRoots": ["./node_modules/@types"]
"typeRoots": ["./node_modules/@types"],
"paths": {
"svelte": ["./src/runtime/public.d.ts"]
}
}
}

@ -157,8 +157,8 @@ importers:
specifier: ^2.26.0
version: 2.26.0
'@sveltejs/repl':
specifier: 0.5.0-next.8
version: 0.5.0-next.8(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte)
specifier: 0.5.0-next.10
version: 0.5.0-next.10(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte)
cookie:
specifier: ^0.5.0
version: 0.5.0
@ -186,7 +186,7 @@ importers:
version: 1.21.0(svelte@packages+svelte)(vite@4.3.9)
'@sveltejs/site-kit':
specifier: 6.0.0-next.18
version: 6.0.0-next.18(@sveltejs/kit@1.20.5)(svelte@packages+svelte)
version: 6.0.0-next.18(@sveltejs/kit@1.21.0)(svelte@packages+svelte)
'@sveltejs/vite-plugin-svelte':
specifier: ^2.4.2
version: 2.4.2(svelte@packages+svelte)(vite@4.3.9)
@ -1318,8 +1318,8 @@ packages:
- supports-color
dev: true
/@neocodemirror/svelte@0.0.14(@codemirror/autocomplete@6.8.1)(@codemirror/commands@6.2.4)(@codemirror/language@6.8.0)(@codemirror/lint@6.3.0)(@codemirror/search@6.5.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0):
resolution: {integrity: sha512-1kHm3IyBJJyRfItxodSbbLxBknYGKLahaiF6Vb/BcVfdwwFLLj4dvWKY78ep1YQIhDhklgBQztjRMuLn9tTTWg==}
/@neocodemirror/svelte@0.0.15(@codemirror/autocomplete@6.8.1)(@codemirror/commands@6.2.4)(@codemirror/language@6.8.0)(@codemirror/lint@6.3.0)(@codemirror/search@6.5.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0):
resolution: {integrity: sha512-MCux+QCR40CboJu/TFwnqK7gYQ3fvtvHX8F/mk85DRH7vMoG3VDjJhqneAITX5IzohWKeP36hzcV+oHC2LYJqA==}
peerDependencies:
'@codemirror/autocomplete': ^6.7.1
'@codemirror/commands': ^6.2.4
@ -1723,33 +1723,6 @@ packages:
typescript: 5.1.3
dev: true
/@sveltejs/kit@1.20.5(svelte@packages+svelte)(vite@4.3.9):
resolution: {integrity: sha512-8rJYZ2boRlO75lwpbpB+DlSzIwmTuamXTpVlDtw4dBk86o3UaDe/+Ro4xCsV/4FtTw2U8xPHyV83edAWbQHG0w==}
engines: {node: ^16.14 || >=18}
hasBin: true
requiresBuild: true
peerDependencies:
svelte: ^3.54.0 || ^4.0.0-next.0
vite: ^4.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 2.4.2(svelte@packages+svelte)(vite@4.3.9)
'@types/cookie': 0.5.1
cookie: 0.5.0
devalue: 4.3.2
esm-env: 1.0.0
kleur: 4.1.5
magic-string: 0.30.0
mime: 3.0.0
sade: 1.8.1
set-cookie-parser: 2.6.0
sirv: 2.0.3
svelte: link:packages/svelte
undici: 5.22.1
vite: 4.3.9(@types/node@20.3.1)(sass@1.63.6)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/kit@1.21.0(svelte@packages+svelte)(vite@4.3.9):
resolution: {integrity: sha512-CBsYoI34SjtOQp0eG85dmVnvTR3Pjs8VgAQhO0CgQja9BIorKl808F1X8EunPhCcyek5r5lKQE1Mmbi0RuzHqA==}
engines: {node: ^16.14 || >=18}
@ -1776,8 +1749,8 @@ packages:
transitivePeerDependencies:
- supports-color
/@sveltejs/repl@0.5.0-next.8(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte):
resolution: {integrity: sha512-kEEXAqukfFRIrjnO8Hur/h+bys+Krv36dR29jp4uomXDRNTI/IXHvsAL6HcBwykKH9tVm+yiJzFaPaiC9Ggx2g==}
/@sveltejs/repl@0.5.0-next.10(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte):
resolution: {integrity: sha512-Y167w5wExssjloafIeLeTCzN9Vh22Sg/DgE4ARfw4J/5VVkEkEINVBbHalpjDMHhXnvOejnbNCJEw0TYW2lN4A==}
peerDependencies:
svelte: ^3.54.0 || ^4.0.0-next.0 || ^4.0.0
dependencies:
@ -1793,7 +1766,7 @@ packages:
'@codemirror/view': 6.14.0
'@jridgewell/sourcemap-codec': 1.4.15
'@lezer/highlight': 1.1.6
'@neocodemirror/svelte': 0.0.14(@codemirror/autocomplete@6.8.1)(@codemirror/commands@6.2.4)(@codemirror/language@6.8.0)(@codemirror/lint@6.3.0)(@codemirror/search@6.5.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0)
'@neocodemirror/svelte': 0.0.15(@codemirror/autocomplete@6.8.1)(@codemirror/commands@6.2.4)(@codemirror/language@6.8.0)(@codemirror/lint@6.3.0)(@codemirror/search@6.5.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0)
'@replit/codemirror-lang-svelte': 6.0.0(@codemirror/autocomplete@6.8.1)(@codemirror/lang-css@6.2.0)(@codemirror/lang-html@6.4.5)(@codemirror/lang-javascript@6.1.9)(@codemirror/language@6.8.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0)(@lezer/common@1.0.3)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)
'@rich_harris/svelte-split-pane': 1.1.1(svelte@packages+svelte)
'@rollup/browser': 3.25.3
@ -1827,13 +1800,13 @@ packages:
svelte-local-storage-store: 0.4.0(svelte@packages+svelte)
dev: false
/@sveltejs/site-kit@6.0.0-next.18(@sveltejs/kit@1.20.5)(svelte@packages+svelte):
/@sveltejs/site-kit@6.0.0-next.18(@sveltejs/kit@1.21.0)(svelte@packages+svelte):
resolution: {integrity: sha512-8uWjP61UAkCqWf9UuQQWSCpyPNk4cqnGaQozjIr3sGbQnauTQDiS4K8AxqyBSyphEIrhxd68iYMEFQDQVAHjcg==}
peerDependencies:
'@sveltejs/kit': ^1.0.0
svelte: ^3.54.0 || ^4.0.0-next.1 || ^4.0.0
dependencies:
'@sveltejs/kit': 1.20.5(svelte@packages+svelte)(vite@4.3.9)
'@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9)
esm-env: 1.0.0
svelte: link:packages/svelte
svelte-local-storage-store: 0.5.0(svelte@packages+svelte)
@ -1942,10 +1915,6 @@ packages:
resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==}
dev: true
/@types/node@20.3.1:
resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==}
dev: true
/@types/node@20.3.2:
resolution: {integrity: sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==}
@ -6500,40 +6469,6 @@ packages:
fsevents: 2.3.2
dev: true
/vite@4.3.9(@types/node@20.3.1)(sass@1.63.6):
resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 20.3.1
esbuild: 0.17.19
postcss: 8.4.24
rollup: 3.25.1
sass: 1.63.6
optionalDependencies:
fsevents: 2.3.2
dev: true
/vite@4.3.9(@types/node@20.3.2)(sass@1.63.6):
resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
engines: {node: ^14.18.0 || >=16.0.0}

@ -2,14 +2,15 @@
A local database is only required in dev mode if you want to test reading and writing saved REPLs on it. Without a local database in dev mode, the REPL will be able to load saved REPLs from the production database, but not save them.
Note also that in dev mode, the REPL will currently only work in Chrome, [as noted in the Vite documentation](https://vitejs.dev/guide/features.html#web-workers), pending support in Firefox for `import` statements in web workers.
Note also that in dev mode, the REPL requires support for [`import` statements in web workers](https://caniuse.com/mdn-javascript_operators_import_worker_support), [as noted in the Vite documentation](https://vitejs.dev/guide/features.html#web-workers). You may need to update your browser to the latest version.
If you do want to use a database, set it up on [Supabase](https://supabase.com) with the instructions [here](https://github.com/sveltejs/sites/tree/master/db) and set the corresponding environment variables.
Run the site sub-project:
Build the `svelte` package, then run the site sub-project:
```bash
pnpm install
pnpm --dir ../../packages/svelte build
pnpm dev
```

@ -19,7 +19,7 @@
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
"@supabase/supabase-js": "^2.26.0",
"@sveltejs/repl": "0.5.0-next.8",
"@sveltejs/repl": "0.5.0-next.10",
"cookie": "^0.5.0",
"devalue": "^4.3.2",
"do-not-zip": "^1.0.0",

@ -24,7 +24,7 @@
<div class="text" id="docs-content">
<a
class="edit"
href="https://github.com/sveltejs/svelte/edit/master/documentation/{data.page.file}"
href="https://github.com/sveltejs/svelte/edit/master/documentation/docs/{data.page.file}"
>
<Icon size={50} name="edit" /> Edit this page on GitHub
</a>

Loading…
Cancel
Save