From df368be033ded0868564119af069cedaa6339e73 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 4 Jun 2024 11:09:15 -0400 Subject: [PATCH 1/3] chore: better bind_property implementation --- .../client/dom/elements/bindings/universal.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js index f42f67d59472..22aab1b4e4e2 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js @@ -40,12 +40,12 @@ export function bind_content_editable(property, element, get_value, update) { * @returns {void} */ export function bind_property(property, event_name, type, element, get_value, update) { - var target_handler = () => { + var handler = () => { // @ts-ignore update(element[property]); }; - element.addEventListener(event_name, target_handler); + element.addEventListener(event_name, handler); if (type === 'set') { render_effect(() => { @@ -55,18 +55,17 @@ export function bind_property(property, event_name, type, element, get_value, up } if (type === 'get') { - // @ts-ignore - update(element[property]); + handler(); } - render_effect(() => { - // @ts-ignore - if (element === document.body || element === window || element === document) { + // @ts-ignore + if (element === document.body || element === window || element === document) { + render_effect(() => { return () => { - element.removeEventListener(event_name, target_handler); + element.removeEventListener(event_name, handler); }; - } - }); + }); + } } /** From faa8a12eb80eeb495dc764cefc9e1b70b8d48be3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 4 Jun 2024 11:20:12 -0400 Subject: [PATCH 2/3] replace property.type with property.bidirectional --- .../compiler/phases/3-transform/client/visitors/template.js | 2 +- packages/svelte/src/compiler/phases/bindings.js | 6 +++--- 2 files changed, 4 insertions(+), 4 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 5784b7726216..0d4162d9089e 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 @@ -2743,7 +2743,7 @@ export const template_visitors = { '$.bind_property', b.literal(node.name), b.literal(property.event), - b.literal(property.type ?? 'get'), + b.literal(property.bidirectional ? 'set' : 'get'), state.node, getter, setter diff --git a/packages/svelte/src/compiler/phases/bindings.js b/packages/svelte/src/compiler/phases/bindings.js index 6ffbb2363dea..983e59fd7385 100644 --- a/packages/svelte/src/compiler/phases/bindings.js +++ b/packages/svelte/src/compiler/phases/bindings.js @@ -2,7 +2,7 @@ * @typedef BindingProperty * @property {string} [event] This is set if the binding corresponds to the property name on the dom element it's bound to * and there's an event that notifies of a change to that property - * @property {string} [type] Set this to `set` if updates are written to the dom property + * @property {boolean} [bidirectional] Set this to `true` if updates are written to the dom property * @property {boolean} [omit_in_ssr] Set this to true if the binding should not be included in SSR * @property {string[]} [valid_elements] If this is set, the binding is only valid on the given elements * @property {string[]} [invalid_elements] If this is set, the binding is invalid on the given elements @@ -166,7 +166,7 @@ export const binding_properties = { // checkbox/radio indeterminate: { event: 'change', - type: 'set', + bidirectional: true, valid_elements: ['input'], omit_in_ssr: true // no corresponding attribute }, @@ -191,7 +191,7 @@ export const binding_properties = { }, open: { event: 'toggle', - type: 'set', + bidirectional: true, valid_elements: ['details'] }, value: { From f294a7a6aecc8af21a46aa14a4ae5beaa75eced3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 4 Jun 2024 11:25:41 -0400 Subject: [PATCH 3/3] more efficient generated code --- .../3-transform/client/visitors/template.js | 5 ++--- .../client/dom/elements/bindings/universal.js | 17 +++++++---------- 2 files changed, 9 insertions(+), 13 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 0d4162d9089e..a9c74fbc4f41 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 @@ -2743,10 +2743,9 @@ export const template_visitors = { '$.bind_property', b.literal(node.name), b.literal(property.event), - b.literal(property.bidirectional ? 'set' : 'get'), state.node, - getter, - setter + setter, + property.bidirectional && getter ); } else { // special cases diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js index 22aab1b4e4e2..7e8b3f3bf4cb 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/universal.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/universal.js @@ -33,28 +33,25 @@ export function bind_content_editable(property, element, get_value, update) { /** * @param {string} property * @param {string} event_name - * @param {'get' | 'set'} type * @param {Element} element - * @param {() => unknown} get_value - * @param {(value: unknown) => void} update + * @param {(value: unknown) => void} set + * @param {() => unknown} [get] * @returns {void} */ -export function bind_property(property, event_name, type, element, get_value, update) { +export function bind_property(property, event_name, element, set, get) { var handler = () => { // @ts-ignore - update(element[property]); + set(element[property]); }; element.addEventListener(event_name, handler); - if (type === 'set') { + if (get) { render_effect(() => { // @ts-ignore - element[property] = get_value(); + element[property] = get(); }); - } - - if (type === 'get') { + } else { handler(); }