Fix startup crash and autosave input interruption

This commit is contained in:
daniellee2015
2026-05-20 04:00:33 +08:00
parent a4810c421f
commit 098b9c3516
4 changed files with 208 additions and 39 deletions
+54 -5
View File
@@ -8883,15 +8883,37 @@ function updateSaveButtonState() {
btnSaveSettings.textContent = settingsSaveInFlight ? '保存中' : '保存';
}
function isEditableElementInSettingsCard(element) {
if (!element || !(element instanceof Element)) {
return false;
}
const tagName = String(element.tagName || '').toLowerCase();
const isEditableInput = (
tagName === 'textarea'
|| (tagName === 'input' && !['checkbox', 'radio', 'button', 'submit', 'reset', 'range', 'file', 'color'].includes(String(element.type || '').toLowerCase()))
|| Boolean(element.isContentEditable)
);
if (!isEditableInput) {
return false;
}
return !settingsCard || settingsCard.contains(element);
}
function scheduleSettingsAutoSave() {
clearTimeout(settingsAutoSaveTimer);
settingsAutoSaveTimer = setTimeout(() => {
saveSettings({ silent: true }).catch(() => { });
}, 500);
const tryAutoSave = () => {
const activeEl = typeof document !== 'undefined' ? document.activeElement : null;
if (isEditableElementInSettingsCard(activeEl)) {
settingsAutoSaveTimer = setTimeout(tryAutoSave, 800);
return;
}
saveSettings({ silent: true, source: 'autosave' }).catch(() => { });
};
settingsAutoSaveTimer = setTimeout(tryAutoSave, 1200);
}
async function saveSettings(options = {}) {
const { silent = false, force = false } = options;
const { silent = false, force = false, source = '' } = options;
clearTimeout(settingsAutoSaveTimer);
if (!force && !settingsDirty && !settingsSaveInFlight && silent) {
@@ -8903,6 +8925,14 @@ async function saveSettings(options = {}) {
settingsSaveInFlight = true;
updateSaveButtonState();
const shouldSkipStateApplyForFocusedEditor = (() => {
if (!silent || source !== 'autosave') {
return false;
}
const activeEl = typeof document !== 'undefined' ? document.activeElement : null;
return isEditableElementInSettingsCard(activeEl);
})();
try {
const response = await chrome.runtime.sendMessage({
type: 'SAVE_SETTING',
@@ -8915,7 +8945,12 @@ async function saveSettings(options = {}) {
}
if (response?.state && saveRevision === settingsSaveRevision) {
applySettingsState(response.state);
if (shouldSkipStateApplyForFocusedEditor) {
syncLatestState(response.state);
markSettingsDirty(false);
} else {
applySettingsState(response.state);
}
} else {
syncLatestState(payload);
if (saveRevision === settingsSaveRevision) {
@@ -14963,6 +14998,20 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
case 'DATA_UPDATED': {
syncLatestState(message.payload);
const activeSettingsEditor = typeof document !== 'undefined' ? document.activeElement : null;
const shouldDeferDataUpdatedUiApply = settingsSaveInFlight
&& isEditableElementInSettingsCard(activeSettingsEditor);
if (shouldDeferDataUpdatedUiApply) {
// Avoid overwriting the focused editor while the current save request
// is still in flight; otherwise typing can be interrupted by DATA_UPDATED.
if (message.payload.operationDelayEnabled !== undefined && typeof applyOperationDelayState === 'function') {
applyOperationDelayState(message.payload);
}
updateAccountRunHistorySettingsUI();
renderContributionMode();
void syncPlusManualConfirmationDialog();
break;
}
if (message.payload.operationDelayEnabled !== undefined && typeof applyOperationDelayState === 'function') {
applyOperationDelayState(message.payload);
}