From 2dbb24ea0416cb83185b6f92624bd9b6e937eade Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 26 Jan 2020 21:01:00 -0500 Subject: Improve error messages when Interface server is invalid --- ext/bg/js/settings/anki.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js index 9adb2f2a..3b0912d4 100644 --- a/ext/bg/js/settings/anki.js +++ b/ext/bg/js/settings/anki.js @@ -35,9 +35,15 @@ function _ankiSetError(error) { const node = document.querySelector('#anki-error'); if (!node) { return; } if (error) { + const errorString = `${error}`; node.hidden = false; - node.textContent = `${error}`; + node.textContent = errorString; _ankiSetErrorData(node, error); + + const node2 = document.querySelector('#anki-invalid-response-error'); + if (node2 !== null) { + node2.hidden = (errorString.indexOf('Invalid response') < 0); + } } else { node.hidden = true; node.textContent = ''; -- cgit v1.2.3 From 566012f228452a4113e83f76d1c53be1f1f41643 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 1 Feb 2020 11:40:17 -0500 Subject: Use await --- ext/bg/js/settings/dictionaries.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index ed171ae9..545e128d 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -427,7 +427,7 @@ async function onDictionaryMainChanged(e) { const optionsContext = getOptionsContext(); const options = await getOptionsMutable(optionsContext); options.general.mainDictionary = value; - settingsSaveOptions(); + await settingsSaveOptions(); } -- cgit v1.2.3 From 748cd27ad09526e4ec8fd309c6a85fdba1e2462c Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 1 Feb 2020 11:20:50 -0500 Subject: Remove argument from onDictionaryOptionsChanged --- ext/bg/js/settings/dictionaries.js | 8 ++++++-- ext/bg/js/settings/main.js | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 545e128d..31f47bfd 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -361,12 +361,16 @@ async function dictSettingsInitialize() { const optionsContext = getOptionsContext(); const options = await getOptionsMutable(optionsContext); - onDictionaryOptionsChanged(options); + onDictionaryOptionsChanged(); onDatabaseUpdated(options); } -async function onDictionaryOptionsChanged(options) { +async function onDictionaryOptionsChanged() { if (dictionaryUI === null) { return; } + + const optionsContext = getOptionsContext(); + const options = await getOptionsMutable(optionsContext); + dictionaryUI.setOptionsDictionaries(options.dictionaries); const optionsFull = await apiOptionsGetFull(); diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 3bf65eda..6e162ffc 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -167,7 +167,7 @@ async function formWrite(options) { await ankiTemplatesUpdateValue(); await onAnkiOptionsChanged(options); - await onDictionaryOptionsChanged(options); + await onDictionaryOptionsChanged(); formUpdateVisibility(options); } -- cgit v1.2.3 From 55047def9dad485b4ad6e118c5d9eaed5d09af0c Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 1 Feb 2020 11:40:09 -0500 Subject: Separate the functionality of updateMainDictionarySelect One function now updates the options, and another handles updating the value. The options are no longer mutated due to updating this Enable search when clicking glossary entries +
@@ -492,6 +492,10 @@
+
+ +
+
diff --git a/ext/mixed/css/display-dark.css b/ext/mixed/css/display-dark.css index 088fc741..c9cd9f90 100644 --- a/ext/mixed/css/display-dark.css +++ b/ext/mixed/css/display-dark.css @@ -38,6 +38,7 @@ body { background-color: #1e1e1e; color: #d4d4d4; } .tag[data-category=dictionary] { background-color: #9057ad; } .tag[data-category=frequency] { background-color: #489148; } .tag[data-category=partOfSpeech] { background-color: #565656; } +.tag[data-category=search] { background-color: #69696e; } .term-reasons { color: #888888; } diff --git a/ext/mixed/css/display-default.css b/ext/mixed/css/display-default.css index 69141c9d..6eee43c4 100644 --- a/ext/mixed/css/display-default.css +++ b/ext/mixed/css/display-default.css @@ -38,6 +38,7 @@ body { background-color: #ffffff; color: #333333; } .tag[data-category=dictionary] { background-color: #aa66cc; } .tag[data-category=frequency] { background-color: #5cb85c; } .tag[data-category=partOfSpeech] { background-color: #565656; } +.tag[data-category=search] { background-color: #8a8a91; } .term-reasons { color: #777777; } diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css index fefd500f..3a66cec3 100644 --- a/ext/mixed/css/display.css +++ b/ext/mixed/css/display.css @@ -227,6 +227,10 @@ button.action-button { margin-left: 0.375em; } +html:root:not([data-enable-search-tags=true]) .tag[data-category=search] { + display: none; +} + .entry-header2, .entry-header3 { display: inline; diff --git a/ext/mixed/display-templates.html b/ext/mixed/display-templates.html index 6c611be9..6fcf4c74 100644 --- a/ext/mixed/display-templates.html +++ b/ext/mixed/display-templates.html @@ -77,5 +77,6 @@ + diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js index b2dc373b..c90e693a 100644 --- a/ext/mixed/js/display-generator.js +++ b/ext/mixed/js/display-generator.js @@ -111,7 +111,11 @@ class DisplayGenerator { // Fallback termTags = details.termTags; } + const searchQueries = [details.expression, details.reading] + .filter((x) => !!x) + .map((x) => ({query: x})); DisplayGenerator._appendMultiple(tagContainer, this.createTag.bind(this), termTags); + DisplayGenerator._appendMultiple(tagContainer, this.createSearchTag.bind(this), searchQueries); DisplayGenerator._appendMultiple(frequencyContainer, this.createFrequencyTag.bind(this), details.frequencies); return node; @@ -270,6 +274,16 @@ class DisplayGenerator { return node; } + createSearchTag(details) { + const node = DisplayGenerator._instantiateTemplate(this._tagSearchTemplate); + + node.textContent = details.query; + + node.dataset.query = details.query; + + return node; + } + createFrequencyTag(details) { const node = DisplayGenerator._instantiateTemplate(this._tagFrequencyTemplate); @@ -311,6 +325,7 @@ class DisplayGenerator { this._kanjiReadingTemplate = doc.querySelector('#kanji-reading-template'); this._tagTemplate = doc.querySelector('#tag-template'); + this._tagSearchTemplate = doc.querySelector('#tag-search-template'); this._tagFrequencyTemplate = doc.querySelector('#tag-frequency-template'); } diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 70ef8ec3..54cda0eb 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -257,6 +257,7 @@ class Display { data.ankiEnabled = `${options.anki.enable}`; data.audioEnabled = `${options.audio.enable}`; data.compactGlossaries = `${options.general.compactGlossaries}`; + data.enableSearchTags = `${options.scanning.enableSearchTags}`; data.debug = `${options.general.debugInfo}`; } @@ -312,9 +313,9 @@ class Display { this.addEventListeners('.action-play-audio', 'click', this.onAudioPlay.bind(this)); this.addEventListeners('.kanji-link', 'click', this.onKanjiLookup.bind(this)); if (this.options.scanning.enablePopupSearch) { - this.addEventListeners('.term-glossary-item', 'mouseup', this.onGlossaryMouseUp.bind(this)); - this.addEventListeners('.term-glossary-item', 'mousedown', this.onGlossaryMouseDown.bind(this)); - this.addEventListeners('.term-glossary-item', 'mousemove', this.onGlossaryMouseMove.bind(this)); + this.addEventListeners('.term-glossary-item, .tag', 'mouseup', this.onGlossaryMouseUp.bind(this)); + this.addEventListeners('.term-glossary-item, .tag', 'mousedown', this.onGlossaryMouseDown.bind(this)); + this.addEventListeners('.term-glossary-item, .tag', 'mousemove', this.onGlossaryMouseMove.bind(this)); } } else { Display.clearEventListeners(this.eventListeners); -- cgit v1.2.3 From e8701cb950edd4c90f6c911e340db3af32194113 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 2 Feb 2020 14:53:32 -0500 Subject: Hide anki-invalid-response-error when there is no error --- ext/bg/js/settings/anki.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js index 3b0912d4..f55989fc 100644 --- a/ext/bg/js/settings/anki.js +++ b/ext/bg/js/settings/anki.js @@ -33,20 +33,27 @@ function _ankiSpinnerShow(show) { function _ankiSetError(error) { const node = document.querySelector('#anki-error'); - if (!node) { return; } + const node2 = document.querySelector('#anki-invalid-response-error'); if (error) { const errorString = `${error}`; - node.hidden = false; - node.textContent = errorString; - _ankiSetErrorData(node, error); + if (node !== null) { + node.hidden = false; + node.textContent = errorString; + _ankiSetErrorData(node, error); + } - const node2 = document.querySelector('#anki-invalid-response-error'); if (node2 !== null) { node2.hidden = (errorString.indexOf('Invalid response') < 0); } } else { - node.hidden = true; - node.textContent = ''; + if (node !== null) { + node.hidden = true; + node.textContent = ''; + } + + if (node2 !== null) { + node2.hidden = true; + } } } -- cgit v1.2.3 From 939ad42dacfeff566497f3c2f8e9c64d59b8168d Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 25 Jan 2020 19:00:36 +0200 Subject: add global clipboard monitor that spawns popups TODO: refactor the search page clipboard monitor and popup clipboard monitor to use a common ClipboardMonitor class --- ext/bg/data/options-schema.json | 5 +++++ ext/bg/js/backend.js | 17 +++++++++++++++++ ext/bg/js/options.js | 1 + ext/bg/js/settings/main.js | 1 + ext/bg/settings.html | 4 ++++ 5 files changed, 28 insertions(+) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/data/options-schema.json b/ext/bg/data/options-schema.json index 7e12481d..d6207952 100644 --- a/ext/bg/data/options-schema.json +++ b/ext/bg/data/options-schema.json @@ -79,6 +79,7 @@ "type": "object", "required": [ "enable", + "enableClipboardPopups", "resultOutputMode", "debugInfo", "maxResults", @@ -111,6 +112,10 @@ "type": "boolean", "default": true }, + "enableClipboardPopups": { + "type": "boolean", + "default": false + }, "resultOutputMode": { "type": "string", "enum": ["group", "merge", "split"], diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 3cb9ce1d..407dc965 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -34,6 +34,9 @@ class Backend { this.clipboardPasteTarget = document.querySelector('#clipboard-paste-target'); this.popupWindow = null; + this.clipboardPopupTimerId = null; + this.clipboardInterval = 250; + this.clipboardPreviousText = null; this.apiForwarder = new BackendApiForwarder(); } @@ -122,6 +125,20 @@ class Backend { } else { this.mecab.stopListener(); } + + window.clearInterval(this.clipboardPopupTimerId); + if (options.general.enableClipboardPopups) { + this.clipboardPopupTimerId = setInterval(() => { + this._onApiClipboardGet() + .then((result) => { + if (this.clipboardPreviousText === result) { + return; + } + this._onCommandSearch({mode: 'popup', query: result}); + this.clipboardPreviousText = result; + }); + }, this.clipboardInterval); + } } async getOptionsSchema() { diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 78508059..97032660 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -266,6 +266,7 @@ function profileOptionsCreateDefaults() { return { general: { enable: true, + enableClipboardPopups: false, resultOutputMode: 'group', debugInfo: false, maxResults: 32, diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 4492cd42..ad3459f0 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -28,6 +28,7 @@ function getOptionsFullMutable() { async function formRead(options) { options.general.enable = $('#enable').prop('checked'); + options.general.enableClipboardPopups = $('#enable-clipboard-popups').prop('checked'); options.general.showGuide = $('#show-usage-guide').prop('checked'); options.general.compactTags = $('#compact-tags').prop('checked'); options.general.compactGlossaries = $('#compact-glossaries').prop('checked'); diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 3480b124..b0fcec2b 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -134,6 +134,10 @@
+
+ +
+
-- cgit v1.2.3 From 37a922adc0721520dac2f376b85ed2c8b5e42e69 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 26 Jan 2020 02:13:01 +0200 Subject: fix settings page checkbox --- ext/bg/js/settings/main.js | 1 + 1 file changed, 1 insertion(+) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index ad3459f0..55472a7b 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -105,6 +105,7 @@ async function formRead(options) { async function formWrite(options) { $('#enable').prop('checked', options.general.enable); + $('#enable-clipboard-popups').prop('checked', options.general.enableClipboardPopups); $('#show-usage-guide').prop('checked', options.general.showGuide); $('#compact-tags').prop('checked', options.general.compactTags); $('#compact-glossaries').prop('checked', options.general.compactGlossaries); -- cgit v1.2.3 From 91682dd63334da7acf458a320fbd48bbf7dff766 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 26 Jan 2020 04:16:02 +0200 Subject: add permission check to formRead --- ext/bg/js/settings/main.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 55472a7b..cf0f08db 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -28,7 +28,22 @@ function getOptionsFullMutable() { async function formRead(options) { options.general.enable = $('#enable').prop('checked'); - options.general.enableClipboardPopups = $('#enable-clipboard-popups').prop('checked'); + const enableClipboardPopups = $('#enable-clipboard-popups').prop('checked'); + if (enableClipboardPopups) { + options.general.enableClipboardPopups = await new Promise((resolve, _reject) => { + chrome.permissions.request( + {permissions: ['clipboardRead']}, + (granted) => { + if (!granted) { + $('#enable-clipboard-popups').prop('checked', false); + } + resolve(granted); + } + ); + }); + } else { + options.general.enableClipboardPopups = false; + } options.general.showGuide = $('#show-usage-guide').prop('checked'); options.general.compactTags = $('#compact-tags').prop('checked'); options.general.compactGlossaries = $('#compact-glossaries').prop('checked'); -- cgit v1.2.3 From 4629fb3639ec28e6c514b4a364b71e4192575b9b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 1 Feb 2020 15:00:34 -0500 Subject: Change no-undef from off to error --- .eslintrc.json | 37 +++++++++++++++++++++++++++++-- ext/bg/js/anki.js | 1 + ext/bg/js/audio.js | 1 + ext/bg/js/backend.js | 8 +++++++ ext/bg/js/context.js | 1 + ext/bg/js/database.js | 1 + ext/bg/js/dictionary.js | 1 + ext/bg/js/handlebars.js | 1 + ext/bg/js/japanese.js | 1 + ext/bg/js/options.js | 1 + ext/bg/js/search-frontend.js | 1 + ext/bg/js/search-query-parser.js | 1 + ext/bg/js/search.js | 3 +++ ext/bg/js/settings/anki-templates.js | 3 +++ ext/bg/js/settings/anki.js | 3 +++ ext/bg/js/settings/audio-ui.js | 1 + ext/bg/js/settings/audio.js | 2 ++ ext/bg/js/settings/backup.js | 4 ++++ ext/bg/js/settings/conditions-ui.js | 1 + ext/bg/js/settings/dictionaries.js | 5 +++++ ext/bg/js/settings/main.js | 8 +++++++ ext/bg/js/settings/popup-preview-frame.js | 1 + ext/bg/js/settings/profiles.js | 4 ++++ ext/bg/js/settings/storage.js | 1 + ext/bg/js/translator.js | 6 +++++ ext/mixed/js/audio.js | 1 + ext/mixed/js/display-generator.js | 1 + ext/mixed/js/display.js | 5 +++++ ext/mixed/js/text-scanner.js | 1 + 29 files changed, 103 insertions(+), 2 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/.eslintrc.json b/.eslintrc.json index 81fe517f..9b1a19b3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,7 +23,8 @@ "no-case-declarations": "error", "no-const-assign": "error", "no-constant-condition": "off", - "no-undef": "off", + "no-global-assign": "error", + "no-undef": "error", "no-unused-vars": ["error", {"vars": "local", "args": "after-used", "argsIgnorePattern": "^_", "caughtErrors": "none"}], "no-unused-expressions": "error", "no-var": "error", @@ -32,5 +33,37 @@ "quotes": ["error", "single", "avoid-escape"], "require-atomic-updates": "off", "semi": "error" - } + }, + "overrides": [ + { + "files": ["*.js"], + "excludedFiles": ["ext/mixed/js/core.js"], + "globals": { + "yomichan": "readonly", + "errorToJson": "readonly", + "jsonToError": "readonly", + "logError": "readonly", + "isObject": "readonly", + "hasOwn": "readonly", + "toIterable": "readonly", + "stringReverse": "readonly", + "promiseTimeout": "readonly", + "stringReplaceAsync": "readonly", + "EventDispatcher": "readonly", + "EXTENSION_IS_BROWSER_EDGE": "readonly" + } + }, + { + "files": ["ext/mixed/js/core.js"], + "globals": { + "chrome": "writable" + } + }, + { + "files": ["ext/bg/js/settings/*.js"], + "env": { + "jquery": true + } + } + ] } diff --git a/ext/bg/js/anki.js b/ext/bg/js/anki.js index 10a07061..39c6ad51 100644 --- a/ext/bg/js/anki.js +++ b/ext/bg/js/anki.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global requestJson*/ /* * AnkiConnect diff --git a/ext/bg/js/audio.js b/ext/bg/js/audio.js index d1e4af9e..6389528b 100644 --- a/ext/bg/js/audio.js +++ b/ext/bg/js/audio.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global jpIsStringEntirelyKana, audioGetFromSources*/ const audioUrlBuilders = new Map([ ['jpod101', async (definition) => { diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 529055d2..1a1dc735 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -16,6 +16,14 @@ * along with this program. If not, see . */ +/*global optionsSave, utilIsolate +conditionsTestValue, profileConditionsDescriptor, profileOptionsGetDefaultFieldTemplates +handlebarsRenderDynamic, handlebarsRenderStatic +requestText, requestJson, optionsLoad +dictConfigured, dictTermsSort, dictEnabledSet, dictNoteFormat +audioGetUrl, audioInject +jpConvertReading, jpDistributeFuriganaInflected, jpKatakanaToHiragana +Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema*/ class Backend { constructor() { diff --git a/ext/bg/js/context.js b/ext/bg/js/context.js index 37adb6b7..bec964fb 100644 --- a/ext/bg/js/context.js +++ b/ext/bg/js/context.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiCommandExec, apiGetEnvironmentInfo, apiOptionsGet*/ function showExtensionInfo() { const node = document.getElementById('extension-info'); diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index e87cc64b..b54d832c 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global dictFieldSplit, dictTagSanitize, JSZip*/ class Database { constructor() { diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js index 48f65d6c..e03dece0 100644 --- a/ext/bg/js/dictionary.js +++ b/ext/bg/js/dictionary.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global utilSetEqual, utilSetIntersection, apiTemplateRender*/ function dictEnabledSet(options) { const dictionaries = {}; diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js index 62f89ee4..e8cb67eb 100644 --- a/ext/bg/js/handlebars.js +++ b/ext/bg/js/handlebars.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global jpIsCharCodeKanji, jpDistributeFurigana, Handlebars*/ function handlebarsEscape(text) { return Handlebars.Utils.escapeExpression(text); diff --git a/ext/bg/js/japanese.js b/ext/bg/js/japanese.js index c45c0958..e8a6fa08 100644 --- a/ext/bg/js/japanese.js +++ b/ext/bg/js/japanese.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global wanakana*/ const JP_HALFWIDTH_KATAKANA_MAPPING = new Map([ ['ヲ', 'ヲヺ-'], diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 97032660..f9db99a2 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global utilStringHashCode*/ /* * Generic options functions diff --git a/ext/bg/js/search-frontend.js b/ext/bg/js/search-frontend.js index e453ccef..509c4009 100644 --- a/ext/bg/js/search-frontend.js +++ b/ext/bg/js/search-frontend.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiOptionsGet*/ async function searchFrontendSetup() { const optionsContext = { diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index f648fdd4..ff0dbaef 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiTermsFind, apiOptionsSet, apiTextParse, apiTextParseMecab, apiTemplateRender, TextScanner*/ class QueryParser extends TextScanner { constructor(search) { diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 6641255f..312d1de4 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +/*global jpIsStringPartiallyJapanese, apiOptionsSet, apiTermsFind, apiClipboardGet, apiGetEnvironmentInfo +Display, QueryParser*/ + class DisplaySearch extends Display { constructor() { super(document.querySelector('#spinner'), document.querySelector('#content')); diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js index 5e74358f..2e80e334 100644 --- a/ext/bg/js/settings/anki-templates.js +++ b/ext/bg/js/settings/anki-templates.js @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +/*global getOptionsContext, getOptionsMutable, settingsSaveOptions +profileOptionsGetDefaultFieldTemplates, ankiGetFieldMarkers, ankiGetFieldMarkersHtml, dictFieldFormat +apiOptionsGet, apiTermsFind*/ function onAnkiFieldTemplatesReset(e) { e.preventDefault(); diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js index f55989fc..4263fc51 100644 --- a/ext/bg/js/settings/anki.js +++ b/ext/bg/js/settings/anki.js @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +/*global getOptionsContext, getOptionsMutable, settingsSaveOptions +utilBackgroundIsolate, utilAnkiGetDeckNames, utilAnkiGetModelNames, utilAnkiGetModelFieldNames +onFormOptionsChanged*/ // Private diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js index 711c2291..e918609e 100644 --- a/ext/bg/js/settings/audio-ui.js +++ b/ext/bg/js/settings/audio-ui.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global toIterable*/ class AudioSourceUI { static instantiateTemplate(templateSelector) { diff --git a/ext/bg/js/settings/audio.js b/ext/bg/js/settings/audio.js index cff3f521..588d9a11 100644 --- a/ext/bg/js/settings/audio.js +++ b/ext/bg/js/settings/audio.js @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +/*global getOptionsContext, getOptionsMutable, settingsSaveOptions +AudioSourceUI, audioGetTextToSpeechVoice*/ let audioSourceUI = null; diff --git a/ext/bg/js/settings/backup.js b/ext/bg/js/settings/backup.js index becdc568..6d1f28e9 100644 --- a/ext/bg/js/settings/backup.js +++ b/ext/bg/js/settings/backup.js @@ -16,6 +16,10 @@ * along with this program. If not, see . */ +/*global apiOptionsGetFull, apiGetEnvironmentInfo +utilBackend, utilIsolate, utilBackgroundIsolate, utilReadFileArrayBuffer +optionsGetDefault, optionsUpdateVersion +profileOptionsGetDefaultFieldTemplates*/ // Exporting diff --git a/ext/bg/js/settings/conditions-ui.js b/ext/bg/js/settings/conditions-ui.js index 4d041451..5a271321 100644 --- a/ext/bg/js/settings/conditions-ui.js +++ b/ext/bg/js/settings/conditions-ui.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global conditionsNormalizeOptionValue*/ class ConditionsUI { static instantiateTemplate(templateSelector) { diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 0d827f49..c80aac73 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -16,6 +16,11 @@ * along with this program. If not, see . */ +/*global getOptionsContext, getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull +utilBackgroundIsolate, utilDatabaseDeleteDictionary, utilDatabaseGetDictionaryInfo, utilDatabaseGetDictionaryCounts +utilDatabasePurge, utilDatabaseImport +storageUpdateStats, storageEstimate +PageExitPrevention*/ let dictionaryUI = null; diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index cf0f08db..1ba4a7ef 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -16,6 +16,14 @@ * along with this program. If not, see . */ +/*global getOptionsContext, apiOptionsSave +utilBackend, utilIsolate, utilBackgroundIsolate +ankiErrorShown, ankiFieldsToDict +ankiTemplatesUpdateValue, onAnkiOptionsChanged, onDictionaryOptionsChanged +appearanceInitialize, audioSettingsInitialize, profileOptionsSetup, dictSettingsInitialize +ankiInitialize, ankiTemplatesInitialize, storageInfoInitialize +*/ + function getOptionsMutable(optionsContext) { return utilBackend().getOptions( utilBackgroundIsolate(optionsContext) diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 37a4b416..042f335f 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiOptionsGet, Popup, PopupProxyHost, Frontend, TextSourceRange*/ class SettingsPopupPreview { constructor() { diff --git a/ext/bg/js/settings/profiles.js b/ext/bg/js/settings/profiles.js index c4e68b53..3e589809 100644 --- a/ext/bg/js/settings/profiles.js +++ b/ext/bg/js/settings/profiles.js @@ -16,6 +16,10 @@ * along with this program. If not, see . */ +/*global getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull +utilBackgroundIsolate, formWrite +conditionsClearCaches, ConditionsUI, profileConditionsDescriptor*/ + let currentProfileIndex = 0; let profileConditionsContainer = null; diff --git a/ext/bg/js/settings/storage.js b/ext/bg/js/settings/storage.js index 6c10f665..cbe1bb4d 100644 --- a/ext/bg/js/settings/storage.js +++ b/ext/bg/js/settings/storage.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetEnvironmentInfo*/ function storageBytesToLabeledString(size) { const base = 1000; diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index d32f8c67..81c2464b 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -16,6 +16,12 @@ * along with this program. If not, see . */ +/*global requestJson +dictTermsMergeBySequence, dictTagBuildSource, dictTermsMergeByGloss, dictTermsSort, dictTagsSort +dictEnabledSet, dictTermsGroup, dictTermsCompressTags, dictTermsUndupe, dictTagSanitize +jpDistributeFurigana, jpConvertHalfWidthKanaToFullWidth, jpConvertNumericTofullWidth +jpConvertAlphabeticToKana, jpHiraganaToKatakana, jpKatakanaToHiragana, jpIsCharCodeJapanese +Database, Deinflector*/ class Translator { constructor() { diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js index b0c5fa82..76a3e7da 100644 --- a/ext/mixed/js/audio.js +++ b/ext/mixed/js/audio.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiAudioGetUrl*/ class TextToSpeechAudio { constructor(text, voice) { diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js index d5ab9dbc..3617e546 100644 --- a/ext/mixed/js/display-generator.js +++ b/ext/mixed/js/display-generator.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetDisplayTemplatesHtml*/ class DisplayGenerator { constructor() { diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index a6cfe848..b18e275d 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -16,6 +16,11 @@ * along with this program. If not, see . */ +/*global docRangeFromPoint, docSentenceExtract +apiKanjiFind, apiTermsFind, apiNoteView, apiOptionsGet, apiDefinitionsAddable, apiDefinitionAdd +apiScreenshotGet, apiForward +audioPrepareTextToSpeech, audioGetFromSources +DisplayGenerator, WindowScroll, DisplayContext, DOM*/ class Display { constructor(spinner, container) { diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index 88f1e27a..e6da1e5e 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global docRangeFromPoint, TextSourceRange, DOM*/ class TextScanner { constructor(node, ignoreNodes, ignoreElements, ignorePoints) { -- cgit v1.2.3 From ab9d2b38e04c9909d0a7f4cbb28fe069a6515b2a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 1 Feb 2020 17:27:48 -0500 Subject: Remove redundant declaration --- ext/bg/js/settings/audio-ui.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js index e918609e..555380b4 100644 --- a/ext/bg/js/settings/audio-ui.js +++ b/ext/bg/js/settings/audio-ui.js @@ -16,8 +16,6 @@ * along with this program. If not, see . */ -/*global toIterable*/ - class AudioSourceUI { static instantiateTemplate(templateSelector) { const template = document.querySelector(templateSelector); -- cgit v1.2.3 From e2ac478cb7635cbd15d0033bd2c486689a7b4e67 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 11 Feb 2020 22:19:47 -0500 Subject: Define more globals --- .eslintrc.json | 1 + ext/bg/js/backend.js | 2 +- ext/bg/js/clipboard-monitor.js | 1 + ext/bg/js/search-query-parser-generator.js | 1 + ext/bg/js/search-query-parser.js | 2 +- ext/bg/js/search.js | 2 +- ext/bg/js/settings/dictionaries.js | 2 +- ext/fg/js/document.js | 1 + ext/fg/js/float.js | 1 + ext/fg/js/frontend-initialize.js | 1 + ext/fg/js/frontend.js | 1 + ext/fg/js/popup-nested.js | 1 + ext/fg/js/popup-proxy-host.js | 1 + ext/fg/js/popup-proxy.js | 1 + ext/fg/js/popup.js | 1 + 15 files changed, 15 insertions(+), 4 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/.eslintrc.json b/.eslintrc.json index 9b1a19b3..f502479d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -49,6 +49,7 @@ "stringReverse": "readonly", "promiseTimeout": "readonly", "stringReplaceAsync": "readonly", + "parseUrl": "readonly", "EventDispatcher": "readonly", "EXTENSION_IS_BROWSER_EDGE": "readonly" } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 1a1dc735..7b2ec46d 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -23,7 +23,7 @@ requestText, requestJson, optionsLoad dictConfigured, dictTermsSort, dictEnabledSet, dictNoteFormat audioGetUrl, audioInject jpConvertReading, jpDistributeFuriganaInflected, jpKatakanaToHiragana -Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema*/ +Translator, AnkiConnect, AnkiNull, Mecab, BackendApiForwarder, JsonSchema, ClipboardMonitor*/ class Backend { constructor() { diff --git a/ext/bg/js/clipboard-monitor.js b/ext/bg/js/clipboard-monitor.js index b4a27fa2..c2f41385 100644 --- a/ext/bg/js/clipboard-monitor.js +++ b/ext/bg/js/clipboard-monitor.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiClipboardGet, jpIsStringPartiallyJapanese*/ class ClipboardMonitor { constructor() { diff --git a/ext/bg/js/search-query-parser-generator.js b/ext/bg/js/search-query-parser-generator.js index 8d71890b..f842644e 100644 --- a/ext/bg/js/search-query-parser-generator.js +++ b/ext/bg/js/search-query-parser-generator.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetQueryParserTemplatesHtml, TemplateHandler*/ class QueryParserGenerator { constructor() { diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index ff0dbaef..49c0bb34 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global apiTermsFind, apiOptionsSet, apiTextParse, apiTextParseMecab, apiTemplateRender, TextScanner*/ +/*global apiTermsFind, apiOptionsSet, apiTextParse, apiTextParseMecab, apiTemplateRender, TextScanner, QueryParserGenerator*/ class QueryParser extends TextScanner { constructor(search) { diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 312d1de4..50ec146f 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -17,7 +17,7 @@ */ /*global jpIsStringPartiallyJapanese, apiOptionsSet, apiTermsFind, apiClipboardGet, apiGetEnvironmentInfo -Display, QueryParser*/ +Display, QueryParser, ClipboardMonitor*/ class DisplaySearch extends Display { constructor() { diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index c80aac73..fb459404 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/*global getOptionsContext, getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull +/*global getOptionsContext, getOptionsMutable, getOptionsFullMutable, settingsSaveOptions, apiOptionsGetFull, apiOptionsGet utilBackgroundIsolate, utilDatabaseDeleteDictionary, utilDatabaseGetDictionaryInfo, utilDatabaseGetDictionaryCounts utilDatabasePurge, utilDatabaseImport storageUpdateStats, storageEstimate diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 71654b29..7284cdd1 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global TextSourceElement, TextSourceRange, DOM*/ const REGEX_TRANSPARENT_COLOR = /rgba\s*\([^)]*,\s*0(?:\.0+)?\s*\)/; diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8d61d8f6..d31b8336 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global popupNestedInitialize, Display*/ class DisplayFloat extends Display { constructor() { diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 9c923fea..c32e97d4 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global PopupProxyHost, PopupProxy, Frontend*/ async function main() { const data = window.frontendInitializationData || {}; diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 2286bf19..3611d44e 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiGetZoom, apiOptionsGet, apiTermsFind, apiKanjiFind, docSentenceExtract, TextScanner*/ class Frontend extends TextScanner { constructor(popup, ignoreNodes) { diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js index 3f3c945e..3e5f5b80 100644 --- a/ext/fg/js/popup-nested.js +++ b/ext/fg/js/popup-nested.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiOptionsGet*/ let popupNestedInitialized = false; diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 427172c6..98729796 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiFrameInformationGet, FrontendApiReceiver, Popup*/ class PopupProxyHost { constructor() { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 63aa6bbe..db6dffb1 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global FrontendApiSender*/ class PopupProxy { constructor(depth, parentId, parentFrameId, url) { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index e7dae93e..0b142dda 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +/*global apiInjectStylesheet*/ class Popup { constructor(id, depth, frameIdPromise) { -- cgit v1.2.3 From faf15c08aa6777d1ae2d112c55659e08d53156c6 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 14 Feb 2020 22:34:44 -0500 Subject: Rename optionsUpdate event to optionsUpdated Past tense better indicates that the options were changed, but no data is being included as part of the event. It is also more consistent with the other event names the yomichan object currently provides. --- ext/bg/js/backend.js | 2 +- ext/bg/js/settings/main.js | 4 ++-- ext/fg/js/frontend.js | 2 +- ext/mixed/js/core.js | 6 +++--- ext/mixed/js/display.js | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index da50bade..d1a34f82 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -88,7 +88,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: 'optionsUpdate', params: {source}}, callback); + chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdated', params: {source}}, callback); } }); } diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 1ba4a7ef..c6683427 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -242,7 +242,7 @@ async function settingsSaveOptions() { await apiOptionsSave(source); } -async function onOptionsUpdate({source}) { +async function onOptionsUpdated({source}) { const thisSource = await settingsGetSource(); if (source === thisSource) { return; } @@ -274,7 +274,7 @@ async function onReady() { storageInfoInitialize(); - yomichan.on('optionsUpdate', onOptionsUpdate); + yomichan.on('optionsUpdated', onOptionsUpdated); } $(document).ready(() => onReady()); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index a620fb03..c3050514 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -56,7 +56,7 @@ class Frontend extends TextScanner { } yomichan.on('orphaned', () => this.onOrphaned()); - yomichan.on('optionsUpdate', () => this.updateOptions()); + yomichan.on('optionsUpdated', () => this.updateOptions()); yomichan.on('zoomChanged', (e) => this.onZoomChanged(e)); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index c273bb87..2dd9cf40 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -248,7 +248,7 @@ const yomichan = (() => { this._messageHandlers = new Map([ ['getUrl', this._onMessageGetUrl.bind(this)], - ['optionsUpdate', this._onMessageOptionsUpdate.bind(this)], + ['optionsUpdated', this._onMessageOptionsUpdated.bind(this)], ['zoomChanged', this._onMessageZoomChanged.bind(this)] ]); @@ -276,8 +276,8 @@ const yomichan = (() => { return {url: window.location.href}; } - _onMessageOptionsUpdate({source}) { - this.trigger('optionsUpdate', {source}); + _onMessageOptionsUpdated({source}) { + this.trigger('optionsUpdated', {source}); } _onMessageZoomChanged({oldZoomFactor, newZoomFactor}) { diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 90b7aaf3..045ce906 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -52,7 +52,7 @@ class Display { const displayGeneratorPromise = this.displayGenerator.prepare(); const updateOptionsPromise = this.updateOptions(options); await Promise.all([displayGeneratorPromise, updateOptionsPromise]); - yomichan.on('optionsUpdate', () => this.updateOptions(null)); + yomichan.on('optionsUpdated', () => this.updateOptions(null)); } onError(_error) { -- cgit v1.2.3 From 070ae70f7cd635f2b8742a6c406d1ef7b09ccc51 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 16:33:48 -0500 Subject: Create EventListenerCollection class --- .eslintrc.json | 1 + ext/bg/js/settings/dictionaries.js | 24 ++++------------ ext/mixed/js/core.js | 23 +++++++++++++++ ext/mixed/js/display.js | 59 ++++++++++++++++++-------------------- ext/mixed/js/text-scanner.js | 24 ++++------------ 5 files changed, 64 insertions(+), 67 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/.eslintrc.json b/.eslintrc.json index d4ae215b..bda308e2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -51,6 +51,7 @@ "stringReplaceAsync": "readonly", "parseUrl": "readonly", "EventDispatcher": "readonly", + "EventListenerCollection": "readonly", "EXTENSION_IS_BROWSER_EDGE": "readonly" } }, diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index fb459404..adad76fb 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -179,7 +179,7 @@ class SettingsDictionaryEntryUI { this.dictionaryInfo = dictionaryInfo; this.optionsDictionary = optionsDictionary; this.counts = null; - this.eventListeners = []; + this.eventListeners = new EventListenerCollection(); this.isDeleting = false; this.content = content; @@ -198,10 +198,10 @@ class SettingsDictionaryEntryUI { this.applyValues(); - this.addEventListener(this.enabledCheckbox, 'change', (e) => this.onEnabledChanged(e), false); - this.addEventListener(this.allowSecondarySearchesCheckbox, 'change', (e) => this.onAllowSecondarySearchesChanged(e), false); - this.addEventListener(this.priorityInput, 'change', (e) => this.onPriorityChanged(e), false); - this.addEventListener(this.deleteButton, 'click', (e) => this.onDeleteButtonClicked(e), false); + this.eventListeners.addEventListener(this.enabledCheckbox, 'change', (e) => this.onEnabledChanged(e), false); + this.eventListeners.addEventListener(this.allowSecondarySearchesCheckbox, 'change', (e) => this.onAllowSecondarySearchesChanged(e), false); + this.eventListeners.addEventListener(this.priorityInput, 'change', (e) => this.onPriorityChanged(e), false); + this.eventListeners.addEventListener(this.deleteButton, 'click', (e) => this.onDeleteButtonClicked(e), false); } cleanup() { @@ -212,7 +212,7 @@ class SettingsDictionaryEntryUI { this.content = null; } this.dictionaryInfo = null; - this.clearEventListeners(); + this.eventListeners.removeAllEventListeners(); } setCounts(counts) { @@ -229,18 +229,6 @@ class SettingsDictionaryEntryUI { this.parent.save(); } - addEventListener(node, type, listener, options) { - node.addEventListener(type, listener, options); - this.eventListeners.push([node, type, listener, options]); - } - - clearEventListeners() { - for (const [node, type, listener, options] of this.eventListeners) { - node.removeEventListener(type, listener, options); - } - this.eventListeners = []; - } - applyValues() { this.enabledCheckbox.checked = this.optionsDictionary.enabled; this.allowSecondarySearchesCheckbox.checked = this.optionsDictionary.allowSecondarySearches; diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index b6ecb48b..330a30fb 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -236,6 +236,29 @@ class EventDispatcher { } } +class EventListenerCollection { + constructor() { + this._eventListeners = []; + } + + get size() { + return this._eventListeners.length; + } + + addEventListener(node, type, listener, options) { + node.addEventListener(type, listener, options); + this._eventListeners.push([node, type, listener, options]); + } + + removeAllEventListeners() { + if (this._eventListeners.length === 0) { return; } + for (const [node, type, listener, options] of this._eventListeners) { + node.removeEventListener(type, listener, options); + } + this._eventListeners = []; + } +} + /* * Default message handlers diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index e914b082..8113260c 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -35,8 +35,8 @@ class Display { this.audioCache = new Map(); this.styleNode = null; - this.eventListeners = []; - this.persistentEventListeners = []; + this.eventListeners = new EventListenerCollection(); + this.persistentEventListeners = new EventListenerCollection(); this.interactive = false; this.eventListenersActive = false; this.clickScanPrevent = false; @@ -301,13 +301,23 @@ class Display { this.interactive = interactive; if (interactive) { - Display.addEventListener(this.persistentEventListeners, document, 'keydown', this.onKeyDown.bind(this), false); - Display.addEventListener(this.persistentEventListeners, document, 'wheel', this.onWheel.bind(this), {passive: false}); - Display.addEventListener(this.persistentEventListeners, document.querySelector('.action-previous'), 'click', this.onSourceTermView.bind(this)); - Display.addEventListener(this.persistentEventListeners, document.querySelector('.action-next'), 'click', this.onNextTermView.bind(this)); - Display.addEventListener(this.persistentEventListeners, document.querySelector('.navigation-header'), 'wheel', this.onHistoryWheel.bind(this), {passive: false}); + const actionPrevious = document.querySelector('.action-previous'); + const actionNext = document.querySelector('.action-next'); + const navigationHeader = document.querySelector('.navigation-header'); + + this.persistentEventListeners.addEventListener(document, 'keydown', this.onKeyDown.bind(this), false); + this.persistentEventListeners.addEventListener(document, 'wheel', this.onWheel.bind(this), {passive: false}); + if (actionPrevious !== null) { + this.persistentEventListeners.addEventListener(actionPrevious, 'click', this.onSourceTermView.bind(this)); + } + if (actionNext !== null) { + this.persistentEventListeners.addEventListener(actionNext, 'click', this.onNextTermView.bind(this)); + } + if (navigationHeader !== null) { + this.persistentEventListeners.addEventListener(navigationHeader, 'wheel', this.onHistoryWheel.bind(this), {passive: false}); + } } else { - Display.clearEventListeners(this.persistentEventListeners); + this.persistentEventListeners.removeAllEventListeners(); } this.setEventListenersActive(this.eventListenersActive); } @@ -318,23 +328,23 @@ class Display { this.eventListenersActive = active; if (active) { - this.addEventListeners('.action-add-note', 'click', this.onNoteAdd.bind(this)); - this.addEventListeners('.action-view-note', 'click', this.onNoteView.bind(this)); - this.addEventListeners('.action-play-audio', 'click', this.onAudioPlay.bind(this)); - this.addEventListeners('.kanji-link', 'click', this.onKanjiLookup.bind(this)); + this.addMultipleEventListeners('.action-add-note', 'click', this.onNoteAdd.bind(this)); + this.addMultipleEventListeners('.action-view-note', 'click', this.onNoteView.bind(this)); + this.addMultipleEventListeners('.action-play-audio', 'click', this.onAudioPlay.bind(this)); + this.addMultipleEventListeners('.kanji-link', 'click', this.onKanjiLookup.bind(this)); if (this.options.scanning.enablePopupSearch) { - this.addEventListeners('.term-glossary-item, .tag', 'mouseup', this.onGlossaryMouseUp.bind(this)); - this.addEventListeners('.term-glossary-item, .tag', 'mousedown', this.onGlossaryMouseDown.bind(this)); - this.addEventListeners('.term-glossary-item, .tag', 'mousemove', this.onGlossaryMouseMove.bind(this)); + this.addMultipleEventListeners('.term-glossary-item, .tag', 'mouseup', this.onGlossaryMouseUp.bind(this)); + this.addMultipleEventListeners('.term-glossary-item, .tag', 'mousedown', this.onGlossaryMouseDown.bind(this)); + this.addMultipleEventListeners('.term-glossary-item, .tag', 'mousemove', this.onGlossaryMouseMove.bind(this)); } } else { - Display.clearEventListeners(this.eventListeners); + this.eventListeners.removeAllEventListeners(); } } - addEventListeners(selector, type, listener, options) { + addMultipleEventListeners(selector, type, listener, options) { for (const node of this.container.querySelectorAll(selector)) { - Display.addEventListener(this.eventListeners, node, type, listener, options); + this.eventListeners.addEventListener(node, type, listener, options); } } @@ -793,19 +803,6 @@ class Display { return -1; } - static addEventListener(eventListeners, object, type, listener, options) { - if (object === null) { return; } - object.addEventListener(type, listener, options); - eventListeners.push([object, type, listener, options]); - } - - static clearEventListeners(eventListeners) { - for (const [object, type, listener, options] of eventListeners) { - object.removeEventListener(type, listener, options); - } - eventListeners.length = 0; - } - static getElementTop(element) { const elementRect = element.getBoundingClientRect(); const documentRect = document.documentElement.getBoundingClientRect(); diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index e6da1e5e..aa10bbaf 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -31,7 +31,7 @@ class TextScanner { this.options = null; this.enabled = false; - this.eventListeners = []; + this.eventListeners = new EventListenerCollection(); this.primaryTouchIdentifier = null; this.preventNextContextMenu = false; @@ -229,7 +229,7 @@ class TextScanner { } } else { if (this.enabled) { - this.clearEventListeners(); + this.eventListeners.removeAllEventListeners(); this.enabled = false; } this.onSearchClear(false); @@ -237,13 +237,13 @@ class TextScanner { } hookEvents() { - let eventListeners = this.getMouseEventListeners(); + let eventListenerInfos = this.getMouseEventListeners(); if (this.options.scanning.touchInputEnabled) { - eventListeners = eventListeners.concat(this.getTouchEventListeners()); + eventListenerInfos = eventListenerInfos.concat(this.getTouchEventListeners()); } - for (const [node, type, listener, options] of eventListeners) { - this.addEventListener(node, type, listener, options); + for (const [node, type, listener, options] of eventListenerInfos) { + this.eventListeners.addEventListener(node, type, listener, options); } } @@ -268,18 +268,6 @@ class TextScanner { ]; } - addEventListener(node, type, listener, options) { - node.addEventListener(type, listener, options); - this.eventListeners.push([node, type, listener, options]); - } - - clearEventListeners() { - for (const [node, type, listener, options] of this.eventListeners) { - node.removeEventListener(type, listener, options); - } - this.eventListeners = []; - } - setOptions(options) { this.options = options; this.setEnabled(this.options.general.enable); -- cgit v1.2.3 From dcd243c9e9f3af3fedb0bb0db9795f377f175587 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 17:27:55 -0500 Subject: Update how popups are created --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/frontend-initialize.js | 11 ++++-- ext/fg/js/popup-proxy-host.js | 64 +++++++++++++++++++++---------- ext/fg/js/popup-proxy.js | 6 +-- ext/fg/js/popup.js | 8 ++++ 5 files changed, 62 insertions(+), 29 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 042f335f..8fd06222 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -50,7 +50,7 @@ class SettingsPopupPreview { const popupHost = new PopupProxyHost(); await popupHost.prepare(); - const popup = popupHost.createPopup(null, 0); + const popup = popupHost.getOrCreatePopup(); popup.setChildrenSupported(false); this.frontend = new Frontend(popup); diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index c32e97d4..54b874f2 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -22,13 +22,16 @@ async function main() { const data = window.frontendInitializationData || {}; const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data; - let popupHost = null; - if (!proxy) { - popupHost = new PopupProxyHost(); + let popup; + if (proxy) { + popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); + } else { + const popupHost = new PopupProxyHost(); await popupHost.prepare(); + + popup = popupHost.getOrCreatePopup(); } - const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : popupHost.createPopup(null, depth); const frontend = new Frontend(popup, ignoreNodes); await frontend.prepare(); } diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 98729796..e55801ff 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -34,7 +34,7 @@ class PopupProxyHost { if (typeof frameId !== 'number') { return; } this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([ - ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)], + ['getOrCreatePopup', ({id, parentId}) => this._onApiGetOrCreatePopup(id, parentId)], ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)], ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)], ['isVisible', ({id}) => this._onApiIsVisibleAsync(id)], @@ -47,14 +47,51 @@ class PopupProxyHost { ])); } - createPopup(parentId, depth) { - return this._createPopupInternal(parentId, depth).popup; + getOrCreatePopup(id=null, parentId=null) { + // Find by existing id + if (id !== null) { + const popup = this._popups.get(id); + if (typeof popup !== 'undefined') { + return popup; + } + } + + // Find by existing parent id + let parent = null; + if (parentId !== null) { + parent = this._popups.get(parentId); + if (typeof parent !== 'undefined') { + const popup = parent.child; + if (popup !== null) { + return popup; + } + } else { + parent = null; + } + } + + // New unique id + if (id === null) { + id = this._nextId++; + } + + // Create new popup + const depth = (parent !== null ? parent.depth + 1 : 0); + const popup = new Popup(id, depth, this._frameIdPromise); + if (parent !== null) { + popup.setParent(parent); + } + this._popups.set(id, popup); + return popup; } // Message handlers - async _onApiCreateNestedPopup(parentId) { - return this._createPopupInternal(parentId, 0).id; + async _onApiGetOrCreatePopup(id, parentId) { + const popup = this.getOrCreatePopup(id, parentId); + return { + id: popup.id + }; } async _onApiSetOptions(id, options) { @@ -106,25 +143,10 @@ class PopupProxyHost { // Private functions - _createPopupInternal(parentId, depth) { - const parent = (typeof parentId === 'string' && this._popups.has(parentId) ? this._popups.get(parentId) : null); - const id = `${this._nextId}`; - if (parent !== null) { - depth = parent.depth + 1; - } - ++this._nextId; - const popup = new Popup(id, depth, this._frameIdPromise); - if (parent !== null) { - popup.setParent(parent); - } - this._popups.set(id, popup); - return {popup, id}; - } - _getPopup(id) { const popup = this._popups.get(id); if (typeof popup === 'undefined') { - throw new Error('Invalid popup ID'); + throw new Error(`Invalid popup ID ${id}`); } return popup; } diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index db6dffb1..093cdd2e 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -19,10 +19,10 @@ /*global FrontendApiSender*/ class PopupProxy { - constructor(depth, parentId, parentFrameId, url) { + constructor(id, depth, parentId, parentFrameId, url) { this._parentId = parentId; this._parentFrameId = parentFrameId; - this._id = null; + this._id = id; this._idPromise = null; this._depth = depth; this._url = url; @@ -113,7 +113,7 @@ class PopupProxy { } async _getPopupIdAsync() { - const id = await this._invokeHostApi('createNestedPopup', {parentId: this._parentId}); + const {id} = await this._invokeHostApi('getOrCreatePopup', {id: this._id, parentId: this._parentId}); this._id = id; return id; } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 0fc40475..8d4d2b14 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -49,10 +49,18 @@ class Popup { // Public properties + get id() { + return this._id; + } + get parent() { return this._parent; } + get child() { + return this._child; + } + get depth() { return this._depth; } -- cgit v1.2.3 From b6a50e234cf4fc6179725082f9f53ddd7325ba01 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:29:55 -0500 Subject: Change parameter name --- ext/bg/js/settings/popup-preview-frame.js | 2 +- ext/fg/js/popup.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 8fd06222..a7863b3a 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -137,7 +137,7 @@ class SettingsPopupPreview { setCustomOuterCss(css) { if (this.frontend === null) { return; } - this.frontend.popup.setCustomOuterCss(css, true); + this.frontend.popup.setCustomOuterCss(css, false); } async updateSearch() { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 970c5343..6fbab62b 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -158,11 +158,11 @@ class Popup { this._container.dataset.yomichanSiteColor = this._getSiteColor(); } - async setCustomOuterCss(css, injectDirectly) { + async setCustomOuterCss(css, useWebExtensionApi) { // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. if (this._stylesheetInjectedViaApi) { return; } - if (injectDirectly || Popup._isOnExtensionPage()) { + if (!useWebExtensionApi || Popup._isOnExtensionPage()) { Popup.injectOuterStylesheet(css); } else { if (!css) { return; } -- cgit v1.2.3 From d3aefdc4e3f78b87b99bff576137f530ac7ac163 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:37:03 -0500 Subject: Override setCustomOuterCss instead of Popup.injectOuterStylesheet --- ext/bg/js/settings/popup-preview-frame.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index a7863b3a..8c354bf7 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -22,7 +22,8 @@ class SettingsPopupPreview { constructor() { this.frontend = null; this.apiOptionsGetOld = apiOptionsGet; - this.popupInjectOuterStylesheetOld = Popup.injectOuterStylesheet; + this.popup = null; + this.popupSetCustomOuterCssOld = null; this.popupShown = false; this.themeChangeTimeout = null; this.textSource = null; @@ -50,19 +51,19 @@ class SettingsPopupPreview { const popupHost = new PopupProxyHost(); await popupHost.prepare(); - const popup = popupHost.getOrCreatePopup(); - popup.setChildrenSupported(false); + this.popup = popupHost.getOrCreatePopup(); + this.popup.setChildrenSupported(false); - this.frontend = new Frontend(popup); + this.popupSetCustomOuterCssOld = this.popup.setCustomOuterCss; + this.popup.setCustomOuterCss = (...args) => this.popupSetCustomOuterCss(...args); + + this.frontend = new Frontend(this.popup); this.frontend.setEnabled = function () {}; this.frontend.searchClear = function () {}; await this.frontend.prepare(); - // Overwrite popup - Popup.injectOuterStylesheet = (...args) => this.popupInjectOuterStylesheet(...args); - // Update search this.updateSearch(); } @@ -83,9 +84,9 @@ class SettingsPopupPreview { return options; } - popupInjectOuterStylesheet(...args) { + async popupSetCustomOuterCss(...args) { // This simulates the stylesheet priorities when injecting using the web extension API. - const result = this.popupInjectOuterStylesheetOld(...args); + const result = await this.popupSetCustomOuterCssOld.call(this.popup, ...args); const outerStylesheet = Popup.outerStylesheet; const node = document.querySelector('#client-css'); -- cgit v1.2.3 From 9fd6ee382d35fb5fcfc3e6d0f4fab711b37b693e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 13:48:06 -0500 Subject: Create more generic function for injecting stylesheets --- ext/bg/js/settings/popup-preview-frame.js | 5 +- ext/fg/js/popup.js | 132 +++++++++++++++++++----------- 2 files changed, 88 insertions(+), 49 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 8c354bf7..e900d4e2 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -88,10 +88,9 @@ class SettingsPopupPreview { // This simulates the stylesheet priorities when injecting using the web extension API. const result = await this.popupSetCustomOuterCssOld.call(this.popup, ...args); - const outerStylesheet = Popup.outerStylesheet; const node = document.querySelector('#client-css'); - if (node !== null && outerStylesheet !== null) { - node.parentNode.insertBefore(outerStylesheet, node); + if (node !== null && result !== null) { + node.parentNode.insertBefore(result, node); } return result; diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 6fbab62b..d799e371 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -31,7 +31,6 @@ class Popup { this._visible = false; this._visibleOverride = null; this._options = null; - this._stylesheetInjectedViaApi = false; this._contentScale = 1.0; this._containerSizeContentScale = null; @@ -159,20 +158,12 @@ class Popup { } async setCustomOuterCss(css, useWebExtensionApi) { - // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. - if (this._stylesheetInjectedViaApi) { return; } - - if (!useWebExtensionApi || Popup._isOnExtensionPage()) { - Popup.injectOuterStylesheet(css); - } else { - if (!css) { return; } - try { - await apiInjectStylesheet('code', css); - this._stylesheetInjectedViaApi = true; - } catch (e) { - // NOP - } - } + return await Popup._injectStylesheet( + 'yomichan-popup-outer-user-stylesheet', + 'code', + css, + useWebExtensionApi + ); } setChildrenSupported(value) { @@ -187,26 +178,6 @@ class Popup { return this._container.getBoundingClientRect(); } - static injectOuterStylesheet(css) { - if (Popup.outerStylesheet === null) { - if (!css) { return; } - Popup.outerStylesheet = document.createElement('style'); - Popup.outerStylesheet.id = 'yomichan-popup-outer-stylesheet'; - } - - const outerStylesheet = Popup.outerStylesheet; - if (css) { - outerStylesheet.textContent = css; - - const par = document.head; - if (par && outerStylesheet.parentNode !== par) { - par.appendChild(outerStylesheet); - } - } else { - outerStylesheet.textContent = ''; - } - } - // Private functions _inject() { @@ -248,7 +219,11 @@ class Popup { }); this._observeFullscreen(true); this._onFullscreenChanged(); - this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); + try { + this.setCustomOuterCss(this._options.general.customPopupOuterCss, true); + } catch (e) { + // NOP + } }); } @@ -526,15 +501,6 @@ class Popup { ]; } - static _isOnExtensionPage() { - try { - const url = chrome.runtime.getURL('/'); - return window.location.href.substring(0, url.length) === url; - } catch (e) { - // NOP - } - } - static _getViewport(useVisualViewport) { const visualViewport = window.visualViewport; if (visualViewport !== null && typeof visualViewport === 'object') { @@ -567,6 +533,80 @@ class Popup { bottom: window.innerHeight }; } + + static _isOnExtensionPage() { + try { + const url = chrome.runtime.getURL('/'); + return window.location.href.substring(0, url.length) === url; + } catch (e) { + // NOP + } + } + + static async _injectStylesheet(id, type, value, useWebExtensionApi) { + const injectedStylesheets = Popup._injectedStylesheets; + + if (Popup._isOnExtensionPage()) { + // Permissions error will occur if trying to use the WebExtension API to inject + // into an extension page. + useWebExtensionApi = false; + } + + let styleNode = injectedStylesheets.get(id); + if (typeof styleNode !== 'undefined') { + if (styleNode === null) { + // Previously injected via WebExtension API + throw new Error(`Stylesheet with id ${id} has already been injected using the WebExtension API`); + } + } else { + styleNode = null; + } + + if (useWebExtensionApi) { + // Inject via WebExtension API + if (styleNode !== null && styleNode.parentNode !== null) { + styleNode.parentNode.removeChild(styleNode); + } + + await apiInjectStylesheet(type, value); + + injectedStylesheets.set(id, null); + return null; + } + + // Create node in document + const parentNode = document.head; + if (parentNode === null) { + throw new Error('No parent node'); + } + + // Create or reuse node + const isFile = (type === 'file'); + const tagName = isFile ? 'link' : 'style'; + if (styleNode === null || styleNode.nodeName.toLowerCase() !== tagName) { + if (styleNode !== null && styleNode.parentNode !== null) { + styleNode.parentNode.removeChild(styleNode); + } + styleNode = document.createElement(tagName); + styleNode.id = id; + } + + // Update node style + if (isFile) { + styleNode.rel = value; + } else { + styleNode.textContent = value; + } + + // Update parent + if (styleNode.parentNode !== parentNode) { + parentNode.appendChild(styleNode); + } + + // Add to map + injectedStylesheets.set(id, styleNode); + return styleNode; + } } -Popup.outerStylesheet = null; +Popup._injectedStylesheets = new Map(); -- cgit v1.2.3 From aee16c443195ff8ab2b0f5f5e8551e44895d48a1 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 16 Feb 2020 23:41:17 -0500 Subject: Check origin on window messages --- ext/bg/js/settings/popup-preview-frame.js | 3 +++ ext/bg/js/settings/popup-preview.js | 8 +++++--- ext/fg/js/popup.js | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index e900d4e2..890b8c96 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -27,6 +27,7 @@ class SettingsPopupPreview { this.popupShown = false; this.themeChangeTimeout = null; this.textSource = null; + this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); } static create() { @@ -97,6 +98,8 @@ class SettingsPopupPreview { } onMessage(e) { + if (e.origin !== this._targetOrigin) { return; } + const {action, params} = e.data; const handler = SettingsPopupPreview._messageHandlers.get(action); if (typeof handler !== 'function') { return; } diff --git a/ext/bg/js/settings/popup-preview.js b/ext/bg/js/settings/popup-preview.js index 0d20471e..d1d2ff5e 100644 --- a/ext/bg/js/settings/popup-preview.js +++ b/ext/bg/js/settings/popup-preview.js @@ -40,20 +40,22 @@ function showAppearancePreview() { window.wanakana.bind(text[0]); + const targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); + text.on('input', () => { const action = 'setText'; const params = {text: text.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); customCss.on('input', () => { const action = 'setCustomCss'; const params = {css: customCss.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); customOuterCss.on('input', () => { const action = 'setCustomOuterCss'; const params = {css: customOuterCss.val()}; - frame.contentWindow.postMessage({action, params}, '*'); + frame.contentWindow.postMessage({action, params}, targetOrigin); }); container.append(frame); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 59c46ab8..900e7325 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -33,6 +33,7 @@ class Popup { this._options = null; this._contentScale = 1.0; this._containerSizeContentScale = null; + this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, ''); this._container = document.createElement('iframe'); this._container.className = 'yomichan-float'; @@ -349,7 +350,7 @@ class Popup { _invokeApi(action, params={}) { if (this._container.contentWindow) { - this._container.contentWindow.postMessage({action, params}, '*'); + this._container.contentWindow.postMessage({action, params}, this._targetOrigin); } } -- cgit v1.2.3 From 452eec8a881f0fcbdb2d5c75ae8253b158812d10 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 12:27:18 -0500 Subject: Use Map --- ext/bg/js/settings/dictionaries.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index adad76fb..427f47f0 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -491,15 +491,18 @@ function dictionaryErrorsShow(errors) { dialog.textContent = ''; if (errors !== null && errors.length > 0) { - const uniqueErrors = {}; + const uniqueErrors = new Map(); for (let e of errors) { console.error(e); e = dictionaryErrorToString(e); - uniqueErrors[e] = hasOwn(uniqueErrors, e) ? uniqueErrors[e] + 1 : 1; + let count = uniqueErrors.get(e); + if (typeof count === 'undefined') { + count = 0; + } + uniqueErrors.set(e, count + 1); } - for (const e in uniqueErrors) { - const count = uniqueErrors[e]; + for (const [e, count] of uniqueErrors.entries()) { const div = document.createElement('p'); if (count > 1) { div.textContent = `${e} `; -- cgit v1.2.3 From aa76113e756391da64d84d368c3b103c873519cb Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 19:49:07 -0500 Subject: Fix block padding --- ext/bg/js/settings/backup.js | 1 - ext/mixed/js/audio.js | 2 -- 2 files changed, 3 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/backup.js b/ext/bg/js/settings/backup.js index 6d1f28e9..f4d622a4 100644 --- a/ext/bg/js/settings/backup.js +++ b/ext/bg/js/settings/backup.js @@ -163,7 +163,6 @@ async function _showSettingsImportWarnings(warnings) { sanitize: e.currentTarget.dataset.importSanitize === 'true' }); modalNode.modal('hide'); - }; const onModalHide = () => { complete({result: false}); diff --git a/ext/mixed/js/audio.js b/ext/mixed/js/audio.js index fe5982dd..b5a025be 100644 --- a/ext/mixed/js/audio.js +++ b/ext/mixed/js/audio.js @@ -54,7 +54,6 @@ class TextToSpeechAudio { speechSynthesis.cancel(); speechSynthesis.speak(this._utterance); - } catch (e) { // NOP } @@ -82,7 +81,6 @@ class TextToSpeechAudio { return new TextToSpeechAudio(text, voice); } - } function audioGetFromUrl(url, willDownload) { -- cgit v1.2.3 From 56567903a5935a7e57e7a8134e3c118a2188babb Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 15 Feb 2020 19:49:56 -0500 Subject: Fix unnamed functions --- ext/bg/js/settings/popup-preview-frame.js | 4 ++-- ext/bg/js/util.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/popup-preview-frame.js b/ext/bg/js/settings/popup-preview-frame.js index 890b8c96..aa2b6100 100644 --- a/ext/bg/js/settings/popup-preview-frame.js +++ b/ext/bg/js/settings/popup-preview-frame.js @@ -60,8 +60,8 @@ class SettingsPopupPreview { this.frontend = new Frontend(this.popup); - this.frontend.setEnabled = function () {}; - this.frontend.searchClear = function () {}; + this.frontend.setEnabled = () => {}; + this.frontend.searchClear = () => {}; await this.frontend.prepare(); diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 9ebd2ac4..5ce4b08c 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -33,7 +33,7 @@ function utilIsolate(value) { } function utilFunctionIsolate(func) { - return function (...args) { + return function isolatedFunction(...args) { try { args = args.map((v) => utilIsolate(v)); return func.call(this, ...args); -- cgit v1.2.3 From c0d91bffc461c61af9d35aecb7c92e15648382b2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 17 Feb 2020 15:21:30 -0500 Subject: Add no-shadow --- .eslintrc.json | 1 + ext/bg/js/backend.js | 32 ++++++++++++++++---------------- ext/bg/js/database.js | 4 ++-- ext/bg/js/japanese.js | 12 ++++++------ ext/bg/js/json-schema.js | 2 +- ext/bg/js/search.js | 4 ++-- ext/bg/js/settings/dictionaries.js | 2 +- ext/mixed/js/core.js | 6 +++--- 8 files changed, 32 insertions(+), 31 deletions(-) (limited to 'ext/bg/js/settings') diff --git a/.eslintrc.json b/.eslintrc.json index b21c00f4..cfee7be8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,6 +26,7 @@ "no-const-assign": "error", "no-constant-condition": "off", "no-global-assign": "error", + "no-shadow": ["error", {"builtinGlobals": false}], "no-undef": "error", "no-unneeded-ternary": "error", "no-unused-vars": ["error", {"vars": "local", "args": "after-used", "argsIgnorePattern": "^_", "caughtErrors": "none"}], diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 7c71f82c..2691b7d9 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -274,18 +274,18 @@ class Backend { const node = nodes.pop(); for (const key of Object.keys(node.obj)) { const path = node.path.concat(key); - const obj = node.obj[key]; - if (obj !== null && typeof obj === 'object') { - nodes.unshift({obj, path}); + const obj2 = node.obj[key]; + if (obj2 !== null && typeof obj2 === 'object') { + nodes.unshift({obj: obj2, path}); } else { - valuePaths.push([obj, path]); + valuePaths.push([obj2, path]); } } } return valuePaths; } - function modifyOption(path, value, options) { + function modifyOption(path, value) { let pivot = options; for (const key of path.slice(0, -1)) { if (!hasOwn(pivot, key)) { @@ -298,7 +298,7 @@ class Backend { } for (const [value, path] of getValuePaths(changedOptions)) { - modifyOption(path, value, options); + modifyOption(path, value); } await this._onApiOptionsSave({source}); @@ -340,9 +340,9 @@ class Backend { dictTermsSort(definitions); const {expression, reading} = definitions[0]; const source = text.substring(0, sourceLength); - for (const {text, furigana} of jpDistributeFuriganaInflected(expression, reading, source)) { - const reading = jpConvertReading(text, furigana, options.parsing.readingMode); - term.push({text, reading}); + for (const {text: text2, furigana} of jpDistributeFuriganaInflected(expression, reading, source)) { + const reading2 = jpConvertReading(text2, furigana, options.parsing.readingMode); + term.push({text: text2, reading: reading2}); } text = text.substring(source.length); } else { @@ -365,17 +365,17 @@ class Backend { for (const {expression, reading, source} of parsedLine) { const term = []; if (expression !== null && reading !== null) { - for (const {text, furigana} of jpDistributeFuriganaInflected( + for (const {text: text2, furigana} of jpDistributeFuriganaInflected( expression, jpKatakanaToHiragana(reading), source )) { - const reading = jpConvertReading(text, furigana, options.parsing.readingMode); - term.push({text, reading}); + const reading2 = jpConvertReading(text2, furigana, options.parsing.readingMode); + term.push({text: text2, reading: reading2}); } } else { - const reading = jpConvertReading(source, null, options.parsing.readingMode); - term.push({text: source, reading}); + const reading2 = jpConvertReading(source, null, options.parsing.readingMode); + term.push({text: source, reading: reading2}); } result.push(term); } @@ -816,12 +816,12 @@ class Backend { try { const tabWindow = await new Promise((resolve, reject) => { - chrome.windows.get(tab.windowId, {}, (tabWindow) => { + chrome.windows.get(tab.windowId, {}, (value) => { const e = chrome.runtime.lastError; if (e) { reject(e); } else { - resolve(tabWindow); + resolve(value); } }); }); diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index 1f6810cf..558f3ceb 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -809,9 +809,9 @@ class Database { for (const objectStoreName of objectStoreNames) { const {primaryKey, indices} = stores[objectStoreName]; - const objectStoreNames = transaction.objectStoreNames || db.objectStoreNames; + const objectStoreNames2 = transaction.objectStoreNames || db.objectStoreNames; const objectStore = ( - Database._listContains(objectStoreNames, objectStoreName) ? + Database._listContains(objectStoreNames2, objectStoreName) ? transaction.objectStore(objectStoreName) : db.createObjectStore(objectStoreName, primaryKey) ); diff --git a/ext/bg/js/japanese.js b/ext/bg/js/japanese.js index e8a6fa08..abb32da4 100644 --- a/ext/bg/js/japanese.js +++ b/ext/bg/js/japanese.js @@ -224,15 +224,15 @@ function jpDistributeFurigana(expression, reading) { } let isAmbiguous = false; - const segmentize = (reading, groups) => { + const segmentize = (reading2, groups) => { if (groups.length === 0 || isAmbiguous) { return []; } const group = groups[0]; if (group.mode === 'kana') { - if (jpKatakanaToHiragana(reading).startsWith(jpKatakanaToHiragana(group.text))) { - const readingLeft = reading.substring(group.text.length); + if (jpKatakanaToHiragana(reading2).startsWith(jpKatakanaToHiragana(group.text))) { + const readingLeft = reading2.substring(group.text.length); const segs = segmentize(readingLeft, groups.splice(1)); if (segs) { return [{text: group.text}].concat(segs); @@ -240,9 +240,9 @@ function jpDistributeFurigana(expression, reading) { } } else { let foundSegments = null; - for (let i = reading.length; i >= group.text.length; --i) { - const readingUsed = reading.substring(0, i); - const readingLeft = reading.substring(i); + for (let i = reading2.length; i >= group.text.length; --i) { + const readingUsed = reading2.substring(0, i); + const readingLeft = reading2.substring(i); const segs = segmentize(readingLeft, groups.slice(1)); if (segs) { if (foundSegments !== null) { diff --git a/ext/bg/js/json-schema.js b/ext/bg/js/json-schema.js index 3cf24c35..58f804fd 100644 --- a/ext/bg/js/json-schema.js +++ b/ext/bg/js/json-schema.js @@ -401,7 +401,7 @@ class JsonSchemaProxyHandler { info.valuePush(i, propertyValue); JsonSchemaProxyHandler.validate(propertyValue, propertySchema, info); info.valuePop(); - for (let i = 0; i < schemaPath.length; ++i) { info.schemaPop(); } + for (let j = 0, jj = schemaPath.length; j < jj; ++j) { info.schemaPop(); } } } diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index 76a62b97..98e167ad 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -70,7 +70,7 @@ class DisplaySearch extends Display { this.wanakanaEnable.checked = false; } this.wanakanaEnable.addEventListener('change', (e) => { - const {queryParams: {query=''}} = parseUrl(window.location.href); + const {queryParams: {query: query2=''}} = parseUrl(window.location.href); if (e.target.checked) { window.wanakana.bind(this.query); apiOptionsSet({general: {enableWanakana: true}}, this.getOptionsContext()); @@ -78,7 +78,7 @@ class DisplaySearch extends Display { window.wanakana.unbind(this.query); apiOptionsSet({general: {enableWanakana: false}}, this.getOptionsContext()); } - this.setQuery(query); + this.setQuery(query2); this.onSearchQueryUpdated(this.query.value, false); }); } diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 427f47f0..70a22a16 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -166,7 +166,7 @@ class SettingsDictionaryListUI { delete n.dataset.dict; $(n).modal('hide'); - const index = this.dictionaryEntries.findIndex((e) => e.dictionaryInfo.title === title); + const index = this.dictionaryEntries.findIndex((entry) => entry.dictionaryInfo.title === title); if (index >= 0) { this.dictionaryEntries[index].deleteDictionary(); } diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index 330a30fb..83813796 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -160,9 +160,9 @@ function promiseTimeout(delay, resolveValue) { const resolve = (value) => complete(promiseResolve, value); const reject = (value) => complete(promiseReject, value); - const promise = new Promise((resolve, reject) => { - promiseResolve = resolve; - promiseReject = reject; + const promise = new Promise((resolve2, reject2) => { + promiseResolve = resolve2; + promiseReject = reject2; }); timer = window.setTimeout(() => { timer = null; -- cgit v1.2.3 From 15f79bc78b69ee808b99983861e21594ba30bb10 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 23 Feb 2020 21:12:43 -0500 Subject: Fix popupScalingFactor being limited to integer values --- ext/bg/js/settings/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/bg/js/settings') diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index c6683427..d1ad2c6b 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -68,7 +68,7 @@ async function formRead(options) { options.general.popupVerticalOffset = parseInt($('#popup-vertical-offset').val(), 10); options.general.popupHorizontalOffset2 = parseInt($('#popup-horizontal-offset2').val(), 0); options.general.popupVerticalOffset2 = parseInt($('#popup-vertical-offset2').val(), 10); - options.general.popupScalingFactor = parseInt($('#popup-scaling-factor').val(), 10); + options.general.popupScalingFactor = parseFloat($('#popup-scaling-factor').val()); options.general.popupScaleRelativeToPageZoom = $('#popup-scale-relative-to-page-zoom').prop('checked'); options.general.popupScaleRelativeToVisualViewport = $('#popup-scale-relative-to-visual-viewport').prop('checked'); options.general.popupTheme = $('#popup-theme').val(); -- cgit v1.2.3