From aa77a7896da735b68b74c62f1726d35e8a6b1774 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 18:30:39 -0400 Subject: [PATCH 01/13] Group all two-column settings together --- ext/bg/settings.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 85b7ee5f..6c649251 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -107,6 +107,16 @@ +
+ + +
+ +
+ + +
+
@@ -129,16 +139,6 @@
-
- - -
- -
- - -
-
From 2e87cd72bc87ebbb5eb25dd8e967f31ab14ca444 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 18:39:28 -0400 Subject: [PATCH 02/13] Use consistent styling for all two-column settings --- ext/bg/settings.html | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 6c649251..ccd749b9 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -140,26 +140,41 @@
-
-
-
+
+ + +
+
+ + +
-
-
-
+
+ + +
+
+ + +
-
-
-
+
+ + +
+
+ + +
From fb8cb3db43c38e5a984cf4a45b5b9def311cf0a0 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 18:45:42 -0400 Subject: [PATCH 03/13] Collapse two-column options on smaller screens --- ext/bg/settings.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ext/bg/settings.html b/ext/bg/settings.html index ccd749b9..093a3c26 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -49,6 +49,16 @@ [data-browser=firefox-mobile] [data-show-for-browser~=firefox-mobile] { display: initial; } + + @media screen and (max-width: 740px) { + .col-xs-6 { + float: none; + width: 100%; + } + .col-xs-6+.col-xs-6 { + margin-top: 15px; + } + } From dbfbf9d12dd4a5be16fa31cecf53c5eb300d8978 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 18:53:12 -0400 Subject: [PATCH 04/13] Use non-bold text for label information Units, etc. --- ext/bg/settings.html | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 093a3c26..76078274 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -30,6 +30,10 @@ padding-bottom: 1em; } + .label-light { + font-weight: normal; + } + #custom-popup-css { width: 100%; min-height: 34px; @@ -118,7 +122,7 @@
- +
@@ -152,11 +156,11 @@
- +
- +
@@ -165,11 +169,11 @@
- +
- +
@@ -178,11 +182,11 @@
- +
- +
@@ -230,12 +234,12 @@
- +
- +
@@ -351,12 +355,12 @@
- +
- +
@@ -374,7 +378,7 @@
- +
From bc7759d94c4d4bbe2480e5328a4c3488ff29e493 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 20:57:10 -0400 Subject: [PATCH 05/13] Add some parameters to field-templates textarea --- ext/bg/settings.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 76078274..ddda8303 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -442,7 +442,7 @@ their Anki cards. If you encounter problems with your changes you can always reset to default template settings.

- +
From 1c767711bb553fa828596f95f8ed9e91a3e13b5d Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 19:21:50 -0400 Subject: [PATCH 06/13] Prevent infinite loops for corrupt options --- ext/bg/js/options.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index df95aae9..d903250e 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -305,14 +305,19 @@ function optionsVersion(options) { ]; optionsSetDefaults(options); - if (!options.hasOwnProperty('version')) { - options.version = fixups.length; + + let version = options.version; + if (typeof version !== 'number' || !Number.isFinite(version)) { + version = fixups.length; + } else { + version = Math.max(0, Math.floor(version)); } - while (options.version < fixups.length) { - fixups[options.version++](); + for (; version < fixups.length; ++version) { + fixups[version](); } + options.version = version; return options; } From ec110fa1b7299a947ea3eabc0e2c46094408c8ba Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 20:35:04 -0400 Subject: [PATCH 07/13] Add some validation to options loading --- ext/bg/js/options.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index d903250e..976f8e55 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -323,10 +323,23 @@ function optionsVersion(options) { function optionsLoad() { return new Promise((resolve, reject) => { - chrome.storage.local.get(null, store => resolve(store.options)); + chrome.storage.local.get(['options'], store => { + const error = chrome.runtime.lastError; + if (error) { + reject(error); + } else { + resolve(store.options); + } + }); }).then(optionsStr => { - return optionsStr ? JSON.parse(optionsStr) : {}; - }).catch(error => { + if (typeof optionsStr === 'string') { + const options = JSON.parse(optionsStr); + if (typeof options === 'object' && options !== null && !Array.isArray(options)) { + return options; + } + } + return {}; + }).catch(() => { return {}; }).then(options => { return optionsVersion(options); @@ -334,7 +347,7 @@ function optionsLoad() { } function optionsSave(options) { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { chrome.storage.local.set({options: JSON.stringify(options)}, resolve); }).then(() => { apiOptionsSet(options); From 5ddbb0373f93632109458725e0f18f1fc75ff643 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Sep 2019 19:56:29 -0400 Subject: [PATCH 08/13] Add function to create default options --- ext/bg/js/options.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 976f8e55..be27f71f 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -183,8 +183,8 @@ function optionsFieldTemplates() { `.trim(); } -function optionsSetDefaults(options) { - const defaults = { +function optionsCreateDefaults() { + return { general: { enable: true, audioSource: 'jpod101', @@ -238,6 +238,10 @@ function optionsSetDefaults(options) { fieldTemplates: optionsFieldTemplates() } }; +} + +function optionsSetDefaults(options) { + const defaults = optionsCreateDefaults(); const combine = (target, source) => { for (const key in source) { From a74cdbff1dbfad48ae18cc101645b7a2b9ec8817 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 6 Sep 2019 18:21:20 -0400 Subject: [PATCH 09/13] Change update process --- ext/bg/js/options.js | 112 ++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index be27f71f..0e871567 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -17,6 +17,57 @@ */ +function optionsApplyUpdates(options, updates) { + const targetVersion = updates.length; + const currentVersion = options.version; + if (typeof currentVersion === 'number' && Number.isFinite(currentVersion)) { + for (let i = Math.max(0, Math.floor(currentVersion)); i < targetVersion; ++i) { + const update = updates[i]; + if (update !== null) { + update(options); + } + } + } + + options.version = targetVersion; + return options; +} + +const optionsVersionUpdates = [ + null, + null, + null, + null, + (options) => { + options.general.audioSource = options.general.audioPlayback ? 'jpod101' : 'disabled'; + }, + (options) => { + options.general.showGuide = false; + }, + (options) => { + options.scanning.modifier = options.scanning.requireShift ? 'shift' : 'none'; + }, + (options) => { + const fieldTemplatesDefault = profileCreateDefaultFieldTemplates(); + options.general.resultOutputMode = options.general.groupResults ? 'group' : 'split'; + options.anki.fieldTemplates = ( + (utilStringHashCode(options.anki.fieldTemplates) !== -805327496) ? + `{{#if merge}}${fieldTemplatesDefault}{{else}}${options.anki.fieldTemplates}{{/if}}` : + fieldTemplatesDefault + ); + }, + (options) => { + if (utilStringHashCode(options.anki.fieldTemplates) === 1285806040) { + options.anki.fieldTemplates = profileCreateDefaultFieldTemplates(); + } + }, + (options) => { + if (utilStringHashCode(options.anki.fieldTemplates) === -250091611) { + options.anki.fieldTemplates = profileCreateDefaultFieldTemplates(); + } + } +]; + function optionsFieldTemplates() { return ` {{#*inline "glossary-single"}} @@ -262,67 +313,8 @@ function optionsSetDefaults(options) { } function optionsVersion(options) { - const fixups = [ - () => {}, - () => {}, - () => {}, - () => {}, - () => { - if (options.general.audioPlayback) { - options.general.audioSource = 'jpod101'; - } else { - options.general.audioSource = 'disabled'; - } - }, - () => { - options.general.showGuide = false; - }, - () => { - if (options.scanning.requireShift) { - options.scanning.modifier = 'shift'; - } else { - options.scanning.modifier = 'none'; - } - }, - () => { - if (options.general.groupResults) { - options.general.resultOutputMode = 'group'; - } else { - options.general.resultOutputMode = 'split'; - } - if (utilStringHashCode(options.anki.fieldTemplates) !== -805327496) { - options.anki.fieldTemplates = `{{#if merge}}${optionsFieldTemplates()}{{else}}${options.anki.fieldTemplates}{{/if}}`; - } else { - options.anki.fieldTemplates = optionsFieldTemplates(); - } - }, - () => { - if (utilStringHashCode(options.anki.fieldTemplates) === 1285806040) { - options.anki.fieldTemplates = optionsFieldTemplates(); - } - }, - () => { - if (utilStringHashCode(options.anki.fieldTemplates) === -250091611) { - options.anki.fieldTemplates = optionsFieldTemplates(); - } - } - ]; - optionsSetDefaults(options); - - let version = options.version; - if (typeof version !== 'number' || !Number.isFinite(version)) { - version = fixups.length; - } else { - version = Math.max(0, Math.floor(version)); - } - - for (; version < fixups.length; ++version) { - fixups[version](); - } - - options.version = version; - return options; + return optionsApplyUpdates(options, optionsVersionUpdates); } function optionsLoad() { From 35ca0f35dd2cfea3223e5a38d5465002dd54993b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 6 Sep 2019 20:49:12 -0400 Subject: [PATCH 10/13] Create common function for utilBackend().options --- ext/bg/js/api.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index b8ef4362..7126cab7 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -21,12 +21,16 @@ async function apiOptionsSet(options) { utilBackend().onOptionsUpdated(options); } -async function apiOptionsGet() { +function apiOptionsGetSync() { return utilBackend().options; } +async function apiOptionsGet() { + return apiOptionsGetSync(); +} + async function apiTermsFind(text) { - const options = utilBackend().options; + const options = apiOptionsGetSync(); const translator = utilBackend().translator; const searcher = { @@ -48,13 +52,13 @@ async function apiTermsFind(text) { } async function apiKanjiFind(text) { - const options = utilBackend().options; + const options = apiOptionsGetSync(); const definitions = await utilBackend().translator.findKanji(text, dictEnabledSet(options)); return definitions.slice(0, options.general.maxResults); } async function apiDefinitionAdd(definition, mode, context) { - const options = utilBackend().options; + const options = apiOptionsGetSync(); if (mode !== 'kanji') { await audioInject( @@ -83,7 +87,7 @@ async function apiDefinitionsAddable(definitions, modes) { const notes = []; for (const definition of definitions) { for (const mode of modes) { - const note = await dictNoteFormat(definition, mode, utilBackend().options); + const note = await dictNoteFormat(definition, mode, apiOptionsGetSync()); notes.push(note); } } @@ -131,7 +135,7 @@ async function apiCommandExec(command) { }, toggle: async () => { - const options = utilBackend().options; + const options = apiOptionsGetSync(); options.general.enable = !options.general.enable; await optionsSave(options); await apiOptionsSet(options); From 13b184707b1bb0c5150645d6cdd186accb345f60 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 6 Sep 2019 21:06:45 -0400 Subject: [PATCH 11/13] Remove unnecessary functions apiOptionsSet not required in bg/js/api.js after optionsSave; optionsSave already invokes apiOptionsSet. apiOptionsSet not required in fg/js/api.js since it's never invoked by the foreground. optionsSet handler not required in bg/js/backend.js since the message is never sent by the foreground. --- ext/bg/js/api.js | 1 - ext/bg/js/backend.js | 4 ---- ext/fg/js/api.js | 4 ---- 3 files changed, 9 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 7126cab7..ff54ae81 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -138,7 +138,6 @@ async function apiCommandExec(command) { const options = apiOptionsGetSync(); options.general.enable = !options.general.enable; await optionsSave(options); - await apiOptionsSet(options); } }; diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 39fd4288..c1cef0c5 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -85,10 +85,6 @@ class Backend { forward(apiOptionsGet(), callback); }, - optionsSet: ({options, callback}) => { - forward(apiOptionsSet(options), callback); - }, - kanjiFind: ({text, callback}) => { forward(apiKanjiFind(text), callback); }, diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js index 6bcb0dbb..aa3b2629 100644 --- a/ext/fg/js/api.js +++ b/ext/fg/js/api.js @@ -17,10 +17,6 @@ */ -function apiOptionsSet(options) { - return utilInvoke('optionsSet', {options}); -} - function apiOptionsGet() { return utilInvoke('optionsGet'); } From 7db2c661054113966644c9055e5b60e29bbeb068 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 6 Sep 2019 21:07:29 -0400 Subject: [PATCH 12/13] Use consistent structure for params --- ext/bg/js/backend.js | 2 +- ext/fg/js/frontend.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index c1cef0c5..f05ae9e6 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -62,7 +62,7 @@ class Backend { const callback = () => this.checkLastError(chrome.runtime.lastError); chrome.tabs.query({}, tabs => { for (const tab of tabs) { - chrome.tabs.sendMessage(tab.id, {action: 'optionsSet', params: options}, callback); + chrome.tabs.sendMessage(tab.id, {action: 'optionsSet', params: {options}}, callback); } }); } diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index b70bf036..6806e2c3 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -261,7 +261,7 @@ class Frontend { onBgMessage({action, params}, sender, callback) { const handlers = { - optionsSet: options => { + optionsSet: ({options}) => { this.options = options; if (!this.options.enable) { this.searchClear(); From eb98dfb1a86d42a0ecfe54d8eb978c47aa1c0f8b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 6 Sep 2019 21:23:00 -0400 Subject: [PATCH 13/13] Simplify logic for how option updates are propagated --- ext/bg/js/api.js | 4 ---- ext/bg/js/backend.js | 13 +++++-------- ext/bg/js/options.js | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index ff54ae81..9839aef5 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -17,10 +17,6 @@ */ -async function apiOptionsSet(options) { - utilBackend().onOptionsUpdated(options); -} - function apiOptionsGetSync() { return utilBackend().options; } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index f05ae9e6..b3e737da 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -28,7 +28,7 @@ class Backend { async prepare() { await this.translator.prepare(); - await apiOptionsSet(await optionsLoad()); + this.onOptionsUpdated(await optionsLoad()); if (chrome.commands !== null && typeof chrome.commands === 'object') { chrome.commands.onCommand.addListener(this.onCommand.bind(this)); @@ -41,7 +41,8 @@ class Backend { } onOptionsUpdated(options) { - this.options = utilIsolate(options); + options = utilIsolate(options); + this.options = options; if (!options.general.enable) { this.setExtensionBadgeBackgroundColor('#555555'); @@ -53,11 +54,7 @@ class Backend { this.setExtensionBadgeText(''); } - if (options.anki.enable) { - this.anki = new AnkiConnect(options.anki.server); - } else { - this.anki = new AnkiNull(); - } + this.anki = options.anki.enable ? new AnkiConnect(options.anki.server) : new AnkiNull(); const callback = () => this.checkLastError(chrome.runtime.lastError); chrome.tabs.query({}, tabs => { @@ -144,7 +141,7 @@ class Backend { chrome.browserAction.setBadgeBackgroundColor({color}); } } - + setExtensionBadgeText(text) { if (typeof chrome.browserAction.setBadgeText === 'function') { chrome.browserAction.setBadgeText({text}); diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 0e871567..69c662e6 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -346,6 +346,6 @@ function optionsSave(options) { return new Promise((resolve) => { chrome.storage.local.set({options: JSON.stringify(options)}, resolve); }).then(() => { - apiOptionsSet(options); + utilBackend().onOptionsUpdated(options); }); }