diff --git a/slhx-js/runtime/slhx.js b/slhx-js/runtime/slhx.js index 9e7a6a6..64bdb58 100644 --- a/slhx-js/runtime/slhx.js +++ b/slhx-js/runtime/slhx.js @@ -8,6 +8,7 @@ const pending = new WeakMap(); const queues = new WeakMap(); const timers = new WeakMap(); + const disabledStates = new WeakMap(); const sseSources = new WeakMap(); const atomStores = new WeakMap(); const dragKeys = new WeakMap(); @@ -77,7 +78,23 @@ const controls = []; if (isDisableControl(el)) controls.push(el); forEachElement(el, (child) => { if (isDisableControl(child)) controls.push(child); }); - controls.forEach((c) => { c.disabled = on; }); + controls.forEach((c) => toggleDisabled(c, on)); + } + } + + function toggleDisabled(control, on) { + const state = disabledStates.get(control); + if (on) { + if (state) state.count += 1; + else disabledStates.set(control, { count: 1, disabled: control.disabled }); + control.disabled = true; + return; + } + if (!state) return; + state.count -= 1; + if (state.count <= 0) { + control.disabled = state.disabled; + disabledStates.delete(control); } } diff --git a/slhx-js/tests/runtime.rs b/slhx-js/tests/runtime.rs index cfb80b1..2662adf 100644 --- a/slhx-js/tests/runtime.rs +++ b/slhx-js/tests/runtime.rs @@ -61,7 +61,11 @@ fn runtime_toggles_pending_conventions_around_requests() { assert!(source.contains("el.hasAttribute(\"data-slhx-disable-while-pending\")")); assert!(source.contains("if (isDisableControl(el)) controls.push(el)")); assert!(source.contains("forEachElement(el, (child) => { if (isDisableControl(child)) controls.push(child); })")); - assert!(source.contains("c.disabled = on")); + assert!(source.contains("const disabledStates = new WeakMap()")); + assert!(source.contains("function toggleDisabled(control, on)")); + assert!(source.contains("else disabledStates.set(control, { count: 1, disabled: control.disabled })")); + assert!(source.contains("control.disabled = state.disabled")); + assert!(source.contains("controls.forEach((c) => toggleDisabled(c, on))")); assert!(source.contains("showPending(target, true)")); assert!(source.contains("showPending(target, false)")); }