Movie Editor: stop autosave from interrupting field editing
The inspector rebuilt on every autosave (~1s), destroying the field being typed in;
number inputs can't preserve selection (no selectionStart), so a select-all + retype
appended instead of replacing ('512' + '640' -> '512640'). Now the inspector skips
rebuilding entirely while one of its fields is focused, and re-syncs to state ~60ms
after blur (no rebuild if focus moved to another field). Typing is never interrupted.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3eef6de2b8
commit
0ca06b4431
@@ -454,12 +454,13 @@
|
||||
body.append(sw);
|
||||
}
|
||||
|
||||
// While the user is actively editing one of our fields, DON'T rebuild the inspector —
|
||||
// autosave fires ~1s and a rebuild would yank the field out, drop the selection and
|
||||
// make typing append (e.g. "512" + "640" -> "512640"). We defer and re-sync on blur.
|
||||
let _editing = false;
|
||||
|
||||
function render(st) {
|
||||
// preserve focus + caret of a text/number field across the rebuild (autosave-safe)
|
||||
const a = document.activeElement;
|
||||
let foc = null;
|
||||
if (a && body.contains(a) && (a.tagName === "TEXTAREA" || a.tagName === "INPUT") && a.dataset.k)
|
||||
foc = { k: a.dataset.k, s: a.selectionStart, e: a.selectionEnd };
|
||||
if (_editing) return; // editing in progress — leave the DOM (and the user's caret) alone
|
||||
|
||||
clear(body);
|
||||
if (!st.project) { title.textContent = "Inspector"; body.append(el("div", "pj-meta", "No project open.")); return; }
|
||||
@@ -469,12 +470,20 @@
|
||||
if (scene) renderScene(st, scene); else renderProject(st);
|
||||
renderExposed(st);
|
||||
renderSplit(st);
|
||||
|
||||
if (foc) {
|
||||
const n = body.querySelector(`[data-k="${foc.k}"]`);
|
||||
if (n) { n.focus(); try { if (foc.s != null) n.setSelectionRange(foc.s, foc.e); } catch (_) {} }
|
||||
}
|
||||
}
|
||||
|
||||
// Track edit state so autosave re-renders never interrupt the focused field.
|
||||
body.addEventListener("focusin", (e) => {
|
||||
const t = e.target;
|
||||
if (t && t.dataset && t.dataset.k) _editing = true;
|
||||
});
|
||||
body.addEventListener("focusout", (e) => {
|
||||
const t = e.target;
|
||||
if (!(t && t.dataset && t.dataset.k)) return;
|
||||
_editing = false;
|
||||
// If focus didn't move to another of our fields, re-sync the inspector to state.
|
||||
setTimeout(() => { if (!_editing) render(S.get()); }, 60);
|
||||
});
|
||||
|
||||
S.subscribe(render);
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user