From a5fd28a14bcdce10d8b9fcee1d323d5b8788cbc6 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 20 May 2024 22:05:39 +0100 Subject: [PATCH 01/17] fix: inline pointer events now correctly work in Chrome (#11695) * fix: inline pointer events now correctly work in Chrome * fix more --- .changeset/quiet-cobras-smile.md | 5 +++ .../client/dom/elements/attributes.js | 10 +++-- .../internal/client/dom/elements/events.js | 38 +++++++++++++++---- 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 .changeset/quiet-cobras-smile.md diff --git a/.changeset/quiet-cobras-smile.md b/.changeset/quiet-cobras-smile.md new file mode 100644 index 0000000000..10b4879837 --- /dev/null +++ b/.changeset/quiet-cobras-smile.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: inline pointer events now correctly work in Chrome diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 399c0ee9aa..c81c3c2d53 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -2,7 +2,7 @@ import { DEV } from 'esm-env'; import { hydrating } from '../hydration.js'; import { get_descriptors, get_prototype_of, map_get, map_set } from '../../utils.js'; import { AttributeAliases, DelegatedEvents, namespace_svg } from '../../../../constants.js'; -import { delegate } from './events.js'; +import { create_event, delegate } from './events.js'; import { autofocus } from './misc.js'; import { effect, effect_root } from '../../reactivity/effects.js'; import * as w from '../../warnings.js'; @@ -151,9 +151,13 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha if (!delegated) { // we use `addEventListener` here because these events are not delegated if (!prev) { - events.push([key, value, () => element.addEventListener(event_name, value, opts)]); + events.push([ + key, + value, + () => (next[key] = create_event(event_name, element, value, opts)) + ]); } else { - element.addEventListener(event_name, value, opts); + next[key] = create_event(event_name, element, value, opts); } } else { // @ts-ignore diff --git a/packages/svelte/src/internal/client/dom/elements/events.js b/packages/svelte/src/internal/client/dom/elements/events.js index e0298af92a..fdce8de147 100644 --- a/packages/svelte/src/internal/client/dom/elements/events.js +++ b/packages/svelte/src/internal/client/dom/elements/events.js @@ -2,6 +2,7 @@ import { render_effect } from '../../reactivity/effects.js'; import { all_registered_events, root_event_handles } from '../../render.js'; import { define_property, is_array } from '../../utils.js'; import { hydrating } from '../hydration.js'; +import { queue_task } from '../task.js'; /** * SSR adds onload and onerror attributes to catch those events before the hydration. @@ -34,18 +35,14 @@ export function replay_events(dom) { * @param {string} event_name * @param {Element} dom * @param {EventListener} handler - * @param {boolean} capture - * @param {boolean} [passive] - * @returns {void} + * @param {AddEventListenerOptions} options */ -export function event(event_name, dom, handler, capture, passive) { - var options = { capture, passive }; - +export function create_event(event_name, dom, handler, options) { /** * @this {EventTarget} */ function target_handler(/** @type {Event} */ event) { - if (!capture) { + if (!options.capture) { // Only call in the bubble phase, else delegated events would be called before the capturing events handle_event_propagation(dom, event); } @@ -54,7 +51,32 @@ export function event(event_name, dom, handler, capture, passive) { } } - dom.addEventListener(event_name, target_handler, options); + // Chrome has a bug where pointer events don't work when attached to a DOM element that has been cloned + // with cloneNode() and the DOM element is disconnected from the document. To ensure the event works, we + // defer the attachment till after it's been appended to the document. TODO: remove this once Chrome fixes + // this bug. + if (event_name.startsWith('pointer')) { + queue_task(() => { + dom.addEventListener(event_name, target_handler, options); + }); + } else { + dom.addEventListener(event_name, target_handler, options); + } + + return target_handler; +} + +/** + * @param {string} event_name + * @param {Element} dom + * @param {EventListener} handler + * @param {boolean} capture + * @param {boolean} [passive] + * @returns {void} + */ +export function event(event_name, dom, handler, capture, passive) { + var options = { capture, passive }; + var target_handler = create_event(event_name, dom, handler, options); // @ts-ignore if (dom === document.body || dom === window || dom === document) { From 506f9d2892501e103610b75ddbc0d3e931c72f13 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 20 May 2024 17:14:48 -0400 Subject: [PATCH 02/17] add pnpm prod command to playground (#11697) --- .gitignore | 1 - playgrounds/demo/.gitignore | 3 ++- playgrounds/demo/dist/index.js | 22 ++++++++++++++++++++++ playgrounds/demo/package.json | 3 ++- playgrounds/demo/vite.config.js | 3 +++ 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 playgrounds/demo/dist/index.js diff --git a/.gitignore b/.gitignore index 16cac3b27f..4ce5c243c7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ coverage .env.test # build output -dist .vercel # OS-specific diff --git a/playgrounds/demo/.gitignore b/playgrounds/demo/.gitignore index 13c523dea0..3653d28870 100644 --- a/playgrounds/demo/.gitignore +++ b/playgrounds/demo/.gitignore @@ -1,4 +1,5 @@ src/* -dist/* +dist/client/* +dist/server/* !src/entry-client.ts !src/entry-server.ts diff --git a/playgrounds/demo/dist/index.js b/playgrounds/demo/dist/index.js new file mode 100644 index 0000000000..4aa70d0f14 --- /dev/null +++ b/playgrounds/demo/dist/index.js @@ -0,0 +1,22 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import express from 'express'; +import { head, html } from './server/entry-server.js'; + +const rendered = fs + .readFileSync(path.resolve('./dist/client/index.html'), 'utf-8') + .replace(``, html) + .replace(``, head); + +express() + .use('*', async (req, res) => { + if (req.originalUrl !== '/') { + res.sendFile(path.resolve('./dist/client' + req.originalUrl)); + return; + } + + res.status(200).set({ 'Content-Type': 'text/html' }).end(rendered); + }) + .listen('3000'); + +console.log('listening on http://localhost:3000'); diff --git a/playgrounds/demo/package.json b/playgrounds/demo/package.json index 7f0c920d0f..e96e8011ba 100644 --- a/playgrounds/demo/package.json +++ b/playgrounds/demo/package.json @@ -7,7 +7,8 @@ "prepare": "node scripts/create-app-svelte.js", "dev": "vite --host", "ssr": "node ./server.js", - "build": "vite build", + "build": "vite build --outDir dist/client && vite build --outDir dist/server --ssr src/entry-server.ts", + "prod": "npm run build && node dist", "preview": "vite preview" }, "devDependencies": { diff --git a/playgrounds/demo/vite.config.js b/playgrounds/demo/vite.config.js index a6a970e8cd..0feb57810d 100644 --- a/playgrounds/demo/vite.config.js +++ b/playgrounds/demo/vite.config.js @@ -3,6 +3,9 @@ import inspect from 'vite-plugin-inspect'; import { svelte } from '@sveltejs/vite-plugin-svelte'; export default defineConfig({ + build: { + minify: false + }, plugins: [inspect(), svelte()], optimizeDeps: { // svelte is a local workspace package, optimizing it would require dev server restarts with --force for every change From 02520aea48ccccee495bca01704afedb9ae8c72a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 20 May 2024 22:07:57 -0400 Subject: [PATCH 03/17] better tooltips in playground (#11705) * better tooltips in playground * update some tests that a drive-by fix broke --- .../compiler/phases/1-parse/state/element.js | 2 +- .../attribute-unique-binding/_config.js | 2 +- .../attribute-unique-shorthand/_config.js | 2 +- .../samples/attribute-unique/_config.js | 2 +- pnpm-lock.yaml | 16 +-- sites/svelte-5-preview/package.json | 2 +- .../src/lib/CodeMirror.svelte | 135 ++++++++++++++++-- .../src/lib/Input/ModuleEditor.svelte | 22 ++- sites/svelte-5-preview/src/lib/theme.js | 24 +--- 9 files changed, 153 insertions(+), 54 deletions(-) diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index cb6f24f868..235f64f893 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -217,7 +217,7 @@ export default function tag(parser) { while ((attribute = read(parser))) { if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') { if (unique_names.includes(attribute.name)) { - e.attribute_duplicate(attribute.start); + e.attribute_duplicate(attribute); // is allowed } else if (attribute.name !== 'this') { unique_names.push(attribute.name); diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/_config.js b/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/_config.js index 8995f44a3f..a32893bab1 100644 --- a/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/attribute-unique-binding/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'attribute_duplicate', message: 'Attributes need to be unique', - position: [17, 17] + position: [17, 25] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/_config.js b/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/_config.js index 8995f44a3f..51b367edc1 100644 --- a/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/attribute-unique-shorthand/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'attribute_duplicate', message: 'Attributes need to be unique', - position: [17, 17] + position: [17, 24] } }); diff --git a/packages/svelte/tests/compiler-errors/samples/attribute-unique/_config.js b/packages/svelte/tests/compiler-errors/samples/attribute-unique/_config.js index 8995f44a3f..ecdb54018d 100644 --- a/packages/svelte/tests/compiler-errors/samples/attribute-unique/_config.js +++ b/packages/svelte/tests/compiler-errors/samples/attribute-unique/_config.js @@ -4,6 +4,6 @@ export default test({ error: { code: 'attribute_duplicate', message: 'Attributes need to be unique', - position: [17, 17] + position: [17, 28] } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9ff6ad1c2..3eef183e05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,8 +223,8 @@ importers: specifier: ^6.0.0 version: 6.0.0(@codemirror/autocomplete@6.12.0)(@codemirror/lang-css@6.2.1)(@codemirror/lang-html@6.4.9)(@codemirror/lang-javascript@6.2.1)(@codemirror/language@6.10.1)(@codemirror/state@6.4.0)(@codemirror/view@6.24.0)(@lezer/common@1.2.1)(@lezer/highlight@1.2.0)(@lezer/javascript@1.4.15)(@lezer/lr@1.4.0) '@rich_harris/svelte-split-pane': - specifier: ^1.1.2 - version: 1.1.2(svelte@packages+svelte) + specifier: ^1.1.3 + version: 1.1.3(svelte@packages+svelte) '@rollup/browser': specifier: ^3.28.0 version: 3.29.4 @@ -2320,16 +2320,16 @@ packages: '@resvg/resvg-js-win32-x64-msvc': 2.6.0 dev: true - /@rich_harris/svelte-split-pane@1.1.1(svelte@4.2.9): - resolution: {integrity: sha512-y2RRLyrN6DCeIgwA423aAIv/T5JqQeOl2XogBQ/21DvA2IF7oyrLUtXMxmQL2va2NFdeJO6MDx6nDX5X7kau7A==} + /@rich_harris/svelte-split-pane@1.1.2(svelte@4.2.9): + resolution: {integrity: sha512-O601UlgGzrn6Nva7uLAF25h63wvrI2rxDh5KTEXd0pdTP7LetHR/rqgi8jyPIgRDCL86eoopEdC3ejOOQoWGWQ==} peerDependencies: - svelte: ^3.54.0 + svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0 dependencies: svelte: 4.2.9 dev: false - /@rich_harris/svelte-split-pane@1.1.2(svelte@packages+svelte): - resolution: {integrity: sha512-O601UlgGzrn6Nva7uLAF25h63wvrI2rxDh5KTEXd0pdTP7LetHR/rqgi8jyPIgRDCL86eoopEdC3ejOOQoWGWQ==} + /@rich_harris/svelte-split-pane@1.1.3(svelte@packages+svelte): + resolution: {integrity: sha512-eziKez1ncDfLqJQsViwLG2rYNfMEa3pYBKFUBfNTChgT5lUnofm5IDHxupAKklKvRpTXCVhQXb1MxLUfj5UgFQ==} peerDependencies: svelte: ^3.54.0 || ^4.0.0 || ^5.0.0-next.0 dependencies: @@ -2739,7 +2739,7 @@ packages: '@neocodemirror/svelte': 0.0.15(@codemirror/autocomplete@6.12.0)(@codemirror/commands@6.3.3)(@codemirror/language@6.10.1)(@codemirror/lint@6.5.0)(@codemirror/search@6.5.6)(@codemirror/state@6.4.0)(@codemirror/view@6.24.0) '@replit/codemirror-lang-svelte': 6.0.0(@codemirror/autocomplete@6.12.0)(@codemirror/lang-css@6.2.1)(@codemirror/lang-html@6.4.9)(@codemirror/lang-javascript@6.2.1)(@codemirror/language@6.10.1)(@codemirror/state@6.4.0)(@codemirror/view@6.24.0)(@lezer/common@1.2.1)(@lezer/highlight@1.2.0)(@lezer/javascript@1.4.15)(@lezer/lr@1.4.0) '@replit/codemirror-vim': 6.1.0(@codemirror/commands@6.3.3)(@codemirror/language@6.10.1)(@codemirror/search@6.5.6)(@codemirror/state@6.4.0)(@codemirror/view@6.24.0) - '@rich_harris/svelte-split-pane': 1.1.1(svelte@4.2.9) + '@rich_harris/svelte-split-pane': 1.1.2(svelte@4.2.9) '@rollup/browser': 3.29.4 '@sveltejs/site-kit': 5.2.2(@sveltejs/kit@2.4.3)(svelte@4.2.9) acorn: 8.11.3 diff --git a/sites/svelte-5-preview/package.json b/sites/svelte-5-preview/package.json index 137cb17a4e..8325e66a87 100644 --- a/sites/svelte-5-preview/package.json +++ b/sites/svelte-5-preview/package.json @@ -46,7 +46,7 @@ "@lezer/highlight": "^1.1.6", "@neocodemirror/svelte": "0.0.15", "@replit/codemirror-lang-svelte": "^6.0.0", - "@rich_harris/svelte-split-pane": "^1.1.2", + "@rich_harris/svelte-split-pane": "^1.1.3", "@rollup/browser": "^3.28.0", "acorn": "^8.10.0", "codemirror": "^6.0.1", diff --git a/sites/svelte-5-preview/src/lib/CodeMirror.svelte b/sites/svelte-5-preview/src/lib/CodeMirror.svelte index 07432235e0..9abde98261 100644 --- a/sites/svelte-5-preview/src/lib/CodeMirror.svelte +++ b/sites/svelte-5-preview/src/lib/CodeMirror.svelte @@ -246,6 +246,8 @@ \ No newline at end of file From d590cd8bea8dd10dbaf925b144db30ca37d12275 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 22 May 2024 12:00:42 +0200 Subject: [PATCH 12/17] fix: ignore value attribute on select during SSR (#11724) The value attribute on select elements does nothing - it does not influence the initial value (in SSR that's the job of the `selected` attribute on an option element), updating it does not influence the current value either. Instead of rendering it out and then removing it on hydration (which is costly because the mutation causes work) we just don't render it in SSR. No test/changeset because no change in behavior. --- .../3-transform/client/visitors/template.js | 2 +- .../3-transform/server/transform-server.js | 31 ++++++++++++------- .../client/dom/elements/attributes.js | 2 +- .../samples/binding-select-late-3/_config.js | 5 --- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 4cc0c836bf..cf4f3adc73 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -1990,7 +1990,7 @@ export const template_visitors = { child_metadata.bound_contenteditable = true; } - if (needs_input_reset && (node.name === 'input' || node.name === 'select')) { + if (needs_input_reset && node.name === 'input') { context.state.init.push(b.stmt(b.call('$.remove_input_attr_defaults', context.state.node))); } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index d57f848f1e..1800479a68 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -1851,18 +1851,27 @@ function serialize_element_attributes(node, context) { for (const attribute of node.attributes) { if (attribute.type === 'Attribute') { - if (attribute.name === 'value' && node.name === 'textarea') { - if ( - attribute.value !== true && - attribute.value[0].type === 'Text' && - regex_starts_with_newline.test(attribute.value[0].data) - ) { - // Two or more leading newlines are required to restore the leading newline immediately after ` + + + + \ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/_config.js b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/_config.js new file mode 100644 index 0000000000..d2a0703301 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/_config.js @@ -0,0 +1,34 @@ +import { test, ok } from '../../test'; +import { flushSync } from 'svelte'; + +export default test({ + mode: ['client'], + + async test({ assert, target }) { + /** + * @type {HTMLInputElement | null} + */ + const input = target.querySelector('input[type=text]'); + const button = target.querySelector('button'); + /** + * @type {HTMLInputElement | null} + */ + const checkbox = target.querySelector('input[type=checkbox]'); + const textarea = target.querySelector('textarea'); + ok(input); + ok(button); + ok(checkbox); + ok(textarea); + + flushSync(() => { + input.value = 'foo'; + checkbox.click(); + textarea.innerHTML = 'bar'; + button.click(); + }); + + assert.equal(input.value, 'foo'); + assert.equal(checkbox.checked, true); + assert.equal(textarea.innerHTML, 'bar'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/main.svelte b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/main.svelte new file mode 100644 index 0000000000..b5c47f0131 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update-spread/main.svelte @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/_config.js b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/_config.js new file mode 100644 index 0000000000..d2a0703301 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/_config.js @@ -0,0 +1,34 @@ +import { test, ok } from '../../test'; +import { flushSync } from 'svelte'; + +export default test({ + mode: ['client'], + + async test({ assert, target }) { + /** + * @type {HTMLInputElement | null} + */ + const input = target.querySelector('input[type=text]'); + const button = target.querySelector('button'); + /** + * @type {HTMLInputElement | null} + */ + const checkbox = target.querySelector('input[type=checkbox]'); + const textarea = target.querySelector('textarea'); + ok(input); + ok(button); + ok(checkbox); + ok(textarea); + + flushSync(() => { + input.value = 'foo'; + checkbox.click(); + textarea.innerHTML = 'bar'; + button.click(); + }); + + assert.equal(input.value, 'foo'); + assert.equal(checkbox.checked, true); + assert.equal(textarea.innerHTML, 'bar'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/main.svelte b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/main.svelte new file mode 100644 index 0000000000..35bd481a4c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/value-attribute-isolated-update/main.svelte @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file From 4a3f7ac2572e07a5e9b013a97309c9551ebf838b Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Wed, 22 May 2024 12:09:49 +0100 Subject: [PATCH 15/17] fix: improved checked/value handling (#11726) * fix: improved checked/value handling * tweak --- .../3-transform/client/visitors/template.js | 34 ++++--------------- .../client/dom/elements/attributes.js | 26 ++++++++++++++ packages/svelte/src/internal/client/index.js | 4 ++- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 7b317a1f1b..ce8068371e 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -467,16 +467,9 @@ function serialize_dynamic_element_attributes(attributes, context, element_id) { * @param {import('estree').Identifier} node_id * @param {import('#compiler').Attribute} attribute * @param {import('../types.js').ComponentContext} context - * @param {boolean} needs_isolation * @returns {boolean} */ -function serialize_element_attribute_update_assignment( - element, - node_id, - attribute, - context, - needs_isolation -) { +function serialize_element_attribute_update_assignment(element, node_id, attribute, context) { const state = context.state; const name = get_attribute_name(element, attribute, context); const is_svg = context.state.metadata.namespace === 'svg'; @@ -513,6 +506,10 @@ function serialize_element_attribute_update_assignment( value ) ); + } else if (name === 'value') { + update = b.stmt(b.call('$.set_value', node_id, value)); + } else if (name === 'checked') { + update = b.stmt(b.call('$.set_checked', node_id, value)); } else if (DOMProperties.includes(name)) { update = b.stmt(b.assignment('=', b.member(node_id, b.id(name)), value)); } else { @@ -521,7 +518,7 @@ function serialize_element_attribute_update_assignment( } if (attribute.metadata.dynamic) { - if (contains_call_expression || needs_isolation) { + if (contains_call_expression) { state.init.push(serialize_update(update)); } else { state.update.push(update); @@ -2072,24 +2069,7 @@ export const template_visitors = { const is = is_custom_element && child_metadata.namespace !== 'foreign' ? serialize_custom_element_attribute_update_assignment(node_id, attribute, context) - : serialize_element_attribute_update_assignment( - node, - node_id, - attribute, - context, - /** - * if the input needs input or content reset we also - * want to isolate the template effect or else every - * unrelated change will reset the value (and the user could) - * change the value outside of the reactivity - * - * - * - * should only be updated when val changes and not when another - * unrelated variable changes. - * */ - needs_content_reset || needs_input_reset - ); + : serialize_element_attribute_update_assignment(node, node_id, attribute, context); if (is) is_attributes_reactive = true; } } diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 0db7f7ecf5..07c9504ccf 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -37,6 +37,32 @@ export function remove_input_attr_defaults(dom) { } } +/** + * @param {Element} element + * @param {any} value + */ +export function set_value(element, value) { + // @ts-expect-error + var attributes = (element.__attributes ??= {}); + + if (attributes.value === (attributes.value = value)) return; + // @ts-expect-error + element.value = value; +} + +/** + * @param {Element} element + * @param {boolean} checked + */ +export function set_checked(element, checked) { + // @ts-expect-error + var attributes = (element.__attributes ??= {}); + + if (attributes.checked === (attributes.checked = checked)) return; + // @ts-expect-error + element.checked = checked; +} + /** * @param {Element} element * @param {string} attribute diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 1a7eb86cc5..8b42493219 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -27,7 +27,9 @@ export { set_custom_element_data, set_dynamic_element_attributes, set_xlink_attribute, - handle_lazy_img + handle_lazy_img, + set_value, + set_checked } from './dom/elements/attributes.js'; export { set_class, set_svg_class, set_mathml_class, toggle_class } from './dom/elements/class.js'; export { event, delegate, replay_events } from './dom/elements/events.js'; From c3489eb5deb9005fa7aaf2c9eeab468493f80cfd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 12:37:10 +0100 Subject: [PATCH 16/17] Version Packages (next) (#11714) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 5 +++++ packages/svelte/CHANGELOG.md | 14 ++++++++++++++ packages/svelte/package.json | 2 +- packages/svelte/src/version.js | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index ec18b64559..a5505b0a82 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -60,6 +60,7 @@ "chilly-snakes-scream", "clean-eels-beg", "clever-chefs-relate", + "clever-maps-travel", "clever-rockets-burn", "clever-sloths-push", "cold-birds-own", @@ -208,6 +209,7 @@ "hungry-tips-unite", "hungry-trees-travel", "itchy-beans-melt", + "itchy-beds-kneel", "itchy-bulldogs-tan", "itchy-eels-marry", "itchy-kings-deliver", @@ -268,6 +270,7 @@ "lucky-toes-begin", "many-rockets-give", "many-trees-fix", + "mean-jokes-exist", "metal-clouds-raise", "metal-lobsters-burn", "mighty-cooks-scream", @@ -435,6 +438,7 @@ "soft-tigers-wink", "sour-bags-fail", "sour-forks-stare", + "sour-jeans-collect", "sour-rules-march", "sour-weeks-fix", "spicy-jeans-deliver", @@ -469,6 +473,7 @@ "tall-shrimps-worry", "tall-tigers-wait", "tame-cycles-kneel", + "tame-dots-battle", "tame-spies-drum", "tasty-cheetahs-appear", "tasty-numbers-perform", diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 920660a952..fb590bf82b 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,19 @@ # svelte +## 5.0.0-next.138 + +### Patch Changes + +- fix: allow comments after last selector in css ([#11723](https://github.com/sveltejs/svelte/pull/11723)) + +- fix: don't add scoping modifier to nesting selectors ([#11713](https://github.com/sveltejs/svelte/pull/11713)) + +- chore: speedup hydration around input and select values ([#11717](https://github.com/sveltejs/svelte/pull/11717)) + +- fix: update value like attributes in a separate template_effect ([#11720](https://github.com/sveltejs/svelte/pull/11720)) + +- fix: improve handling of unowned derived signal ([#11712](https://github.com/sveltejs/svelte/pull/11712)) + ## 5.0.0-next.137 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 1750f56df9..7ec190a899 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.0.0-next.137", + "version": "5.0.0-next.138", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 0f612fa828..8b1e478f5d 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -6,5 +6,5 @@ * https://svelte.dev/docs/svelte-compiler#svelte-version * @type {string} */ -export const VERSION = '5.0.0-next.137'; +export const VERSION = '5.0.0-next.138'; export const PUBLIC_VERSION = '5'; From 4f9096a5a8e93c5fa1eff333857e6007b646956a Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 22 May 2024 17:43:16 +0200 Subject: [PATCH 17/17] chore: delegate input event (#11732) We didn't delegate the input event back when we were also delegating `on:x` events, because it messes up the event/bindings/actions order. Since we're only doing that for `onx` event attributes now that reason is obsolete and we can start delegating it. --- packages/svelte/src/constants.js | 2 +- .../runtime-runes/samples/event-spread-rerun/_config.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/svelte/src/constants.js b/packages/svelte/src/constants.js index 1083561d81..2d98a8eb19 100644 --- a/packages/svelte/src/constants.js +++ b/packages/svelte/src/constants.js @@ -40,7 +40,7 @@ export const DelegatedEvents = [ 'contextmenu', 'focusin', 'focusout', - // 'input', This conflicts with bind:input + 'input', 'keydown', 'keyup', 'mousedown', diff --git a/packages/svelte/tests/runtime-runes/samples/event-spread-rerun/_config.js b/packages/svelte/tests/runtime-runes/samples/event-spread-rerun/_config.js index 2b320e0a86..b624051a18 100644 --- a/packages/svelte/tests/runtime-runes/samples/event-spread-rerun/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/event-spread-rerun/_config.js @@ -1,14 +1,16 @@ +import { flushSync } from 'svelte'; import { test, ok } from '../../test'; export default test({ mode: ['client'], - async test({ assert, logs, target }) { + test({ assert, logs, target }) { const input = target.querySelector('input'); ok(input); input.value = 'foo'; - await input.dispatchEvent(new Event('input')); + input.dispatchEvent(new Event('input', { bubbles: true })); + flushSync(); assert.deepEqual(logs, ['hi']); }