1
0
Эх сурвалжийг харах

feat: store only non-default options (#1543)

tophf 3 жил өмнө
parent
commit
5e5cd64986

+ 0 - 4
src/background/index.js

@@ -10,7 +10,6 @@ import { initialize } from './utils/init';
 import { getOption, hookOptions } from './utils/options';
 import { popupTabs } from './utils/popup-tracker';
 import { getInjectedScripts } from './utils/preinject';
-import { SCRIPT_TEMPLATE, resetScriptTemplate } from './utils/template-hook';
 import { resetValueOpener, addValueOpener } from './utils/values';
 import { clearRequestsByTabId } from './utils/requests';
 import './utils/clipboard';
@@ -27,9 +26,6 @@ hookOptions((changes) => {
   if ('autoUpdate' in changes) {
     autoUpdate();
   }
-  if (SCRIPT_TEMPLATE in changes) {
-    resetScriptTemplate(changes);
-  }
   sendCmd('UpdateOptions', changes);
 });
 

+ 53 - 34
src/background/utils/options.js

@@ -1,7 +1,5 @@
-import {
-  debounce, ensureArray, initHooks, normalizeKeys,
-} from '#/common';
-import { mapEntry, objectGet, objectSet } from '#/common/object';
+import { debounce, ensureArray, initHooks, normalizeKeys } from '#/common';
+import { deepCopy, deepEqual, mapEntry, objectGet, objectSet } from '#/common/object';
 import defaults from '#/common/options-defaults';
 import { preInitialize } from './init';
 import { commands } from './message';
@@ -21,19 +19,36 @@ Object.assign(commands, {
   },
 });
 
-let changes = {};
+const STORAGE_KEY = 'options';
+const VERSION = 'version';
+const TPL_KEY = 'scriptTemplate';
+const TPL_OLD_VAL = `\
+// ==UserScript==
+// @name New Script
+// @namespace Violentmonkey Scripts
+// @match {{url}}
+// @grant none
+// ==/UserScript==
+`;
+const DELAY = 100;
 const hooks = initHooks();
-const callHooksLater = debounce(callHooks, 100);
-
+const callHooksLater = debounce(callHooks, DELAY);
+const writeOptionsLater = debounce(writeOptions, DELAY);
+let changes = {};
 let options = {};
-let initPending = browser.storage.local.get('options')
+let initPending = browser.storage.local.get(STORAGE_KEY)
 .then(({ options: data }) => {
   if (data && typeof data === 'object') options = data;
-  if (process.env.DEBUG) {
-    console.log('options:', options); // eslint-disable-line no-console
+  if (process.env.DEBUG) console.info('options:', options);
+  if (!options[VERSION]) {
+    setOption(VERSION, 1);
+  }
+  if (options[TPL_KEY] === TPL_OLD_VAL) {
+    options[TPL_KEY] = defaults[TPL_KEY]; // will be detected by omitDefaultValue below
   }
-  if (!objectGet(options, 'version')) {
-    setOption('version', 1);
+  if (Object.keys(options).map(omitDefaultValue).some(Boolean)) {
+    delete options[`${TPL_KEY}Edited`]; // TODO: remove this in 2023
+    writeOptionsLater();
   }
   initPending = null;
 });
@@ -56,34 +71,38 @@ function callHooks() {
 export function getOption(key, def) {
   const keys = normalizeKeys(key);
   const mainKey = keys[0];
-  let value = options[mainKey];
-  if (value == null) value = defaults[mainKey];
-  if (value == null) value = def;
+  const value = options[mainKey] ?? deepCopy(defaults[mainKey]) ?? def;
   return keys.length > 1 ? objectGet(value, keys.slice(1), def) : value;
 }
 
-export function setOption(key, value) {
-  if (initPending) {
-    initPending.then(() => {
-      setOption(key, value);
-    });
-    return;
-  }
+export async function setOption(key, value) {
+  if (initPending) await initPending;
   const keys = normalizeKeys(key);
-  const optionKey = keys.join('.');
-  let optionValue = value;
   const mainKey = keys[0];
-  if (mainKey in defaults) {
-    if (keys.length > 1) {
-      optionValue = objectSet(getOption(mainKey), keys.slice(1), value);
-    }
-    options[mainKey] = optionValue;
-    browser.storage.local.set({ options });
-    fireChange(keys, value);
-    if (process.env.DEBUG) {
-      console.log('Options updated:', optionKey, value, options); // eslint-disable-line no-console
-    }
+  if (!defaults::hasOwnProperty(mainKey)) {
+    if (process.env.DEBUG) console.info('Unknown option:', keys.join('.'), value, options);
+    return;
   }
+  const subKey = keys.length > 1 && keys.slice(1);
+  const mainVal = getOption([mainKey]);
+  if (deepEqual(value, subKey ? objectGet(mainVal, subKey) : mainVal)) {
+    if (process.env.DEBUG) console.info('Option unchanged:', keys.join('.'), value, options);
+    return;
+  }
+  options[mainKey] = subKey ? objectSet(mainVal, subKey, value) : value;
+  omitDefaultValue(mainKey);
+  writeOptionsLater();
+  fireChange(keys, value);
+  if (process.env.DEBUG) console.info('Options updated:', keys.join('.'), value, options);
+}
+
+function writeOptions() {
+  return browser.storage.local.set({ [STORAGE_KEY]: options });
+}
+
+function omitDefaultValue(key) {
+  return deepEqual(options[key], defaults[key])
+    && delete options[key];
 }
 
 export const hookOptions = hooks.hook;

+ 0 - 45
src/background/utils/template-hook.js

@@ -1,45 +0,0 @@
-import defaults from '#/common/options-defaults';
-import { postInitialize } from './init';
-import { getOption, setOption } from './options';
-
-export const SCRIPT_TEMPLATE = 'scriptTemplate';
-const SCRIPT_TEMPLATE_EDITED = `${SCRIPT_TEMPLATE}Edited`;
-const INITIAL_TEMPLATE = `\
-// ==UserScript==
-// @name New Script
-// @namespace Violentmonkey Scripts
-// @match {{url}}
-// @grant none
-// ==/UserScript==
-`;
-
-postInitialize.push(() => {
-  let edited = getOption(SCRIPT_TEMPLATE_EDITED);
-  // Preserve an edited template
-  if (edited) return;
-  const template = getOption(SCRIPT_TEMPLATE);
-  // When updating from an old version, set the edited flag retroactively
-  if (edited == null) {
-    edited = template !== INITIAL_TEMPLATE;
-    if (edited) setOption(SCRIPT_TEMPLATE_EDITED, true);
-    else resetScriptTemplate();
-  // When updating VM, update to the new default template
-  } else if (template !== defaults[SCRIPT_TEMPLATE]) {
-    resetScriptTemplate();
-  }
-});
-
-export function resetScriptTemplate(changes = {}) {
-  const defaultTemplate = defaults[SCRIPT_TEMPLATE];
-  let template = changes[SCRIPT_TEMPLATE];
-  if (!template) {
-    template = defaultTemplate;
-    changes[SCRIPT_TEMPLATE] = template;
-    setOption(SCRIPT_TEMPLATE, template);
-  }
-  const edited = template !== defaultTemplate;
-  if (edited !== changes[SCRIPT_TEMPLATE_EDITED]) {
-    changes[SCRIPT_TEMPLATE_EDITED] = edited;
-    setOption(SCRIPT_TEMPLATE_EDITED, edited);
-  }
-}

+ 1 - 4
src/common/options-defaults.js

@@ -24,7 +24,7 @@ export default {
   blacklist: null,
   syncScriptStatus: true,
   sync: null,
-  customCSS: null,
+  customCSS: '',
   importScriptData: true,
   importSettings: true,
   notifyUpdates: false,
@@ -75,9 +75,6 @@ export default {
 // @description {{date}}
 // ==/UserScript==
 `,
-  // Enables automatic updates to the default template with new versions of VM
-  /** @type {?Boolean} this must be |null| for template-hook.js upgrade routine */
-  scriptTemplateEdited: null,
   showAdvanced: true,
   /** @typedef {'' | 'dark' | 'light'} VMUiTheme */
   /** @type VMUiTheme */