fix: add doctype and stop self-echoed saves overwriting active edits

This commit is contained in:
golem 2026-08-01 22:45:17 -06:00
parent b42b11755c
commit 5e56503244
2 changed files with 22 additions and 7 deletions

@ -1,3 +1,4 @@
<!doctype html>
<!-- Rendered inline inside about:addons. Keep it narrow-friendly and do not <!-- Rendered inline inside about:addons. Keep it narrow-friendly and do not
rely on window sizing; a pref can degrade this to a standalone tab. --> rely on window sizing; a pref can degrade this to a standalone tab. -->
<meta charset="utf-8" /> <meta charset="utf-8" />

@ -14,11 +14,19 @@ let applying = false;
function render(settings) { function render(settings) {
applying = true; applying = true;
field("model").value = settings.model; for (const [id, value] of Object.entries(settings)) {
field("temporaryChat").checked = settings.temporaryChat; const element = field(id);
field("webSearch").checked = settings.webSearch; // Never overwrite the control the user is actively editing — this page's
field("openIn").value = settings.openIn; // own saves echo back through storage.onChanged (see below).
field("promptTemplate").value = settings.promptTemplate; if (element === document.activeElement) {
continue;
}
if (typeof value === "boolean") {
element.checked = value;
} else {
element.value = value;
}
}
applying = false; applying = false;
} }
@ -69,12 +77,18 @@ for (const id of Object.keys(DEFAULT_SETTINGS)) {
field("restore").addEventListener("click", () => { field("restore").addEventListener("click", () => {
clearTimeout(saveTimer); clearTimeout(saveTimer);
// Restoring defaults is an explicit user action, so it should reset every
// field even if one currently has focus. Blur first so render()'s
// activeElement guard (see below) has nothing to skip.
document.activeElement?.blur();
render(DEFAULT_SETTINGS); render(DEFAULT_SETTINGS);
persist({ ...DEFAULT_SETTINGS }); persist({ ...DEFAULT_SETTINGS });
}); });
// A remote sync landing while the panel is open must update the controls rather // browser.storage.onChanged fires for every write to the "sync" area, not just
// than being clobbered by stale field values on the next edit. // a remote sync landing on another device — this page's own debounced
// autosaves and its Restore-defaults save re-enter this listener too, which
// render()'s activeElement guard makes safe to react to unconditionally.
browser.storage.onChanged.addListener(async (changes, area) => { browser.storage.onChanged.addListener(async (changes, area) => {
if (area !== "sync") { if (area !== "sync") {
return; return;