From 4a3f7ac2572e07a5e9b013a97309c9551ebf838b Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Wed, 22 May 2024 12:09:49 +0100 Subject: [PATCH] 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';