Skip to content

Commit be90d2e

Browse files
committed
call binding function on form reset
1 parent e496370 commit be90d2e

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

packages/svelte/src/internal/client/operations.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { run_all } from '../common.js';
12
import { current_hydration_fragment, get_hydration_fragment } from './hydration.js';
23
import { get_descriptor } from './utils.js';
34

@@ -84,6 +85,24 @@ export function init_operations() {
8485
// @ts-expect-error
8586
element_prototype.__className = '';
8687

88+
// @ts-expect-error
89+
HTMLInputElement.prototype.__binds = undefined;
90+
// @ts-expect-error
91+
HTMLSelectElement.prototype.__binds = undefined;
92+
// @ts-expect-error
93+
HTMLTextAreaElement.prototype.__binds = undefined;
94+
95+
// On form's reset, invoke bindings on elements
96+
document.body.addEventListener('reset', (evt)=> {
97+
requestAnimationFrame(() => {
98+
if (evt.defaultPrevented) return;
99+
for (const e of (/**@type {HTMLFormElement} */(evt.target)).elements) {
100+
// @ts-expect-error
101+
if (e.__binds) run_all(e.__binds);
102+
}
103+
});
104+
});
105+
87106
first_child_get = /** @type {(this: Node) => ChildNode | null} */ (
88107
// @ts-ignore
89108
get_descriptor(node_prototype, 'firstChild').get

packages/svelte/src/internal/client/render.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ const all_registerd_events = new Set();
6565
/** @type {Set<(events: Array<string>) => void>} */
6666
const root_event_handles = new Set();
6767

68+
/**
69+
* Add the function on the __binds attribute of the element
70+
* This allow to handle form's reset correctly
71+
* @param {Element} dom
72+
* @param {(this:Element)=>void} fn
73+
*/
74+
function binds(dom, fn) {
75+
// @ts-ignore
76+
(dom.__binds ||= [])
77+
.push(fn);
78+
return fn;
79+
}
80+
6881
/** @returns {Text} */
6982
export function empty() {
7083
return document.createTextNode('');
@@ -918,7 +931,7 @@ export function selected(dom) {
918931
* @returns {void}
919932
*/
920933
export function bind_value(dom, get_value, update) {
921-
dom.addEventListener('input', () => {
934+
dom.addEventListener('input', binds(dom, () => {
922935
// @ts-ignore
923936
let value = dom.value;
924937
// @ts-ignore
@@ -927,7 +940,7 @@ export function bind_value(dom, get_value, update) {
927940
value = value === '' ? null : +value;
928941
}
929942
update(value);
930-
});
943+
}));
931944
render_effect(() => {
932945
const value = get_value();
933946
const coerced_value = value == null ? null : value + '';
@@ -946,7 +959,7 @@ export function bind_value(dom, get_value, update) {
946959
*/
947960
export function bind_select_value(dom, get_value, update) {
948961
let mounting = true;
949-
dom.addEventListener('change', () => {
962+
dom.addEventListener('change', binds(dom, () => {
950963
/** @type {unknown} */
951964
let value;
952965
if (dom.multiple) {
@@ -957,7 +970,7 @@ export function bind_select_value(dom, get_value, update) {
957970
value = selected_option && get_option_value(selected_option);
958971
}
959972
update(value);
960-
});
973+
}));
961974
// Needs to be an effect, not a render_effect, so that in case of each loops the logic runs after the each block has updated
962975
effect(() => {
963976
let value = get_value();
@@ -1048,14 +1061,14 @@ export function bind_group(group, group_index, dom, get_value, update) {
10481061
}
10491062
}
10501063
binding_group.push(dom);
1051-
dom.addEventListener('change', () => {
1064+
dom.addEventListener('change', binds(dom, () => {
10521065
// @ts-ignore
10531066
let value = dom.__value;
10541067
if (is_checkbox) {
10551068
value = get_binding_group_value(binding_group, value, dom.checked);
10561069
}
10571070
update(value);
1058-
});
1071+
}));
10591072
render_effect(() => {
10601073
let value = get_value();
10611074
if (is_checkbox) {
@@ -1084,10 +1097,10 @@ export function bind_group(group, group_index, dom, get_value, update) {
10841097
* @returns {void}
10851098
*/
10861099
export function bind_checked(dom, get_value, update) {
1087-
dom.addEventListener('change', () => {
1100+
dom.addEventListener('change', binds(dom, () => {
10881101
const value = dom.checked;
10891102
update(value);
1090-
});
1103+
}));
10911104
// eslint-disable-next-line eqeqeq
10921105
if (get_value() == undefined) {
10931106
update(false);

0 commit comments

Comments
 (0)