From 2ab871e7ee93ddc4a2f1ca41aad10e4b189b6c0f Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 2 Nov 2019 14:06:16 -0400 Subject: Update how dictionaries are displayed on the settings page --- ext/bg/js/util.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ext/bg/js/util.js') diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 1ca0833b..3554ec3d 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -84,6 +84,14 @@ function utilDatabaseSummarize() { return utilBackend().translator.database.summarize(); } +function utilDatabaseGetDictionaryInfo() { + return utilBackend().translator.database.getDictionaryInfo(); +} + +function utilDatabaseGetDictionaryCounts(dictionaryNames, getTotal) { + return utilBackend().translator.database.getDictionaryCounts(dictionaryNames, getTotal); +} + function utilAnkiGetModelFieldNames(modelName) { return utilBackend().anki.getModelFieldNames(modelName); } -- cgit v1.2.3 From e091c7ebe2f6780b6a88df313c9f20170a8e5c1c Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 2 Nov 2019 16:21:06 -0400 Subject: Add support for deleting individual dictionaries --- ext/bg/css/settings.css | 18 +++++++ ext/bg/js/database.js | 104 +++++++++++++++++++++++++++++++++++++ ext/bg/js/settings-dictionaries.js | 64 +++++++++++++++++++++++ ext/bg/js/translator.js | 5 ++ ext/bg/js/util.js | 4 ++ ext/bg/settings.html | 30 ++++++++++- 6 files changed, 224 insertions(+), 1 deletion(-) (limited to 'ext/bg/js/util.js') diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css index 102d53de..35b4a152 100644 --- a/ext/bg/css/settings.css +++ b/ext/bg/css/settings.css @@ -165,6 +165,24 @@ input[type=checkbox].storage-button-checkbox { height: 320px; } +.dict-delete-table { + display: table; + width: 100%; +} +.dict-delete-table>*:first-child { + display: table-cell; + vertical-align: middle; + padding-right: 1em; +} +.dict-delete-table>*:nth-child(n+2) { + display: table-cell; + width: 100%; + vertical-align: middle; +} +.dict-delete-table .progress { + margin: 0; +} + [data-show-for-browser], [data-show-for-operating-system] { display: none; diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index fc0af049..dc2198ac 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -56,6 +56,42 @@ class Database { await this.prepare(); } + async deleteDictionary(dictionaryName, onProgress, progressSettings) { + this.validate(); + + const targets = [ + ['dictionaries', 'title'], + ['kanji', 'dictionary'], + ['kanjiMeta', 'dictionary'], + ['terms', 'dictionary'], + ['termMeta', 'dictionary'], + ['tagMeta', 'dictionary'] + ]; + const promises = []; + const progressData = { + count: 0, + processed: 0, + storeCount: targets.length, + storesProcesed: 0 + }; + let progressRate = (typeof progressSettings === 'object' && progressSettings !== null ? progressSettings.rate : 0); + if (typeof progressRate !== 'number' || progressRate <= 0) { + progressRate = 1000; + } + + const db = this.db.backendDB(); + + for (const [objectStoreName, index] of targets) { + const dbTransaction = db.transaction([objectStoreName], 'readwrite'); + const dbObjectStore = dbTransaction.objectStore(objectStoreName); + const dbIndex = dbObjectStore.index(index); + const only = IDBKeyRange.only(dictionaryName); + promises.push(Database.deleteValues(dbObjectStore, dbIndex, only, onProgress, progressData, progressRate)); + } + + await Promise.all(promises); + } + async findTermsBulk(termList, titles) { this.validate(); @@ -612,4 +648,72 @@ class Database { request.onsuccess = (e) => resolve(e.target.result); }); } + + static getAllKeys(dbIndex, query) { + const fn = typeof dbIndex.getAllKeys === 'function' ? Database.getAllKeysFast : Database.getAllKeysUsingCursor; + return fn(dbIndex, query); + } + + static getAllKeysFast(dbIndex, query) { + return new Promise((resolve, reject) => { + const request = dbIndex.getAllKeys(query); + request.onerror = (e) => reject(e); + request.onsuccess = (e) => resolve(e.target.result); + }); + } + + static getAllKeysUsingCursor(dbIndex, query) { + return new Promise((resolve, reject) => { + const primaryKeys = []; + const request = dbIndex.openKeyCursor(query, 'next'); + request.onerror = (e) => reject(e); + request.onsuccess = (e) => { + const cursor = e.target.result; + if (cursor) { + primaryKeys.push(cursor.primaryKey); + cursor.continue(); + } else { + resolve(primaryKeys); + } + }; + }); + } + + static async deleteValues(dbObjectStore, dbIndex, query, onProgress, progressData, progressRate) { + const hasProgress = (typeof onProgress === 'function'); + const count = await Database.getCount(dbIndex, query); + ++progressData.storesProcesed; + progressData.count += count; + if (hasProgress) { + onProgress(progressData); + } + + const onValueDeleted = ( + hasProgress ? + () => { + const p = ++progressData.processed; + if ((p % progressRate) === 0 || p === progressData.count) { + onProgress(progressData); + } + } : + () => {} + ); + + const promises = []; + const primaryKeys = await Database.getAllKeys(dbIndex, query); + for (const key of primaryKeys) { + const promise = Database.deleteValue(dbObjectStore, key).then(onValueDeleted); + promises.push(promise); + } + + await Promise.all(promises); + } + + static deleteValue(dbObjectStore, key) { + return new Promise((resolve, reject) => { + const request = dbObjectStore.delete(key); + request.onerror = (e) => reject(e); + request.onsuccess = () => resolve(); + }); + } } diff --git a/ext/bg/js/settings-dictionaries.js b/ext/bg/js/settings-dictionaries.js index 2f33d1ac..bf1b232f 100644 --- a/ext/bg/js/settings-dictionaries.js +++ b/ext/bg/js/settings-dictionaries.js @@ -30,6 +30,8 @@ class SettingsDictionaryListUI { this.dictionaryEntries = []; this.extra = null; + + document.querySelector('#dict-delete-confirm').addEventListener('click', (e) => this.onDictionaryConfirmDelete(e), false); } setDictionaries(dictionaries) { @@ -126,6 +128,19 @@ class SettingsDictionaryListUI { save() { // Overwrite } + + onDictionaryConfirmDelete(e) { + e.preventDefault(); + const n = document.querySelector('#dict-delete-modal'); + const title = n.dataset.dict; + delete n.dataset.dict; + $(n).modal('hide'); + + const index = this.dictionaryEntries.findIndex(e => e.dictionaryInfo.title === title); + if (index >= 0) { + this.dictionaryEntries[index].deleteDictionary(); + } + } } class SettingsDictionaryEntryUI { @@ -135,11 +150,13 @@ class SettingsDictionaryEntryUI { this.optionsDictionary = optionsDictionary; this.counts = null; this.eventListeners = []; + this.isDeleting = false; this.content = content; this.enabledCheckbox = this.content.querySelector('.dict-enabled'); this.allowSecondarySearchesCheckbox = this.content.querySelector('.dict-allow-secondary-searches'); this.priorityInput = this.content.querySelector('.dict-priority'); + this.deleteButton = this.content.querySelector('.dict-delete-button'); this.content.querySelector('.dict-title').textContent = this.dictionaryInfo.title; this.content.querySelector('.dict-revision').textContent = `rev.${this.dictionaryInfo.revision}`; @@ -149,6 +166,7 @@ class SettingsDictionaryEntryUI { 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); } cleanup() { @@ -194,6 +212,38 @@ class SettingsDictionaryEntryUI { this.priorityInput.value = `${this.optionsDictionary.priority}`; } + async deleteDictionary() { + if (this.isDeleting) { + return; + } + + const progress = this.content.querySelector('.progress'); + progress.hidden = false; + const progressBar = this.content.querySelector('.progress-bar'); + this.isDeleting = true; + + try { + const onProgress = ({processed, count, storeCount, storesProcesed}) => { + let percent = 0.0; + if (count > 0 && storesProcesed > 0) { + percent = (processed / count) * (storesProcesed / storeCount) * 100.0; + } + progressBar.style.width = `${percent}%`; + }; + + await utilDatabaseDeleteDictionary(this.dictionaryInfo.title, onProgress, {rate: 1000}); + } catch (e) { + dictionaryErrorsShow([e]); + } finally { + this.isDeleting = false; + progress.hidden = true; + + const optionsContext = getOptionsContext(); + const options = await apiOptionsGet(optionsContext); + onDatabaseUpdated(options); + } + } + onEnabledChanged(e) { this.optionsDictionary.enabled = !!e.target.checked; this.save(); @@ -215,6 +265,20 @@ class SettingsDictionaryEntryUI { e.target.value = `${value}`; } + + onDeleteButtonClicked(e) { + e.preventDefault(); + + if (this.isDeleting) { + return; + } + + const title = this.dictionaryInfo.title; + const n = document.querySelector('#dict-delete-modal'); + n.dataset.dict = title; + document.querySelector('#dict-remove-modal-dict-name').textContent = title; + $(n).modal('show'); + } } class SettingsDictionaryExtraUI { diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 9d90136b..ff1d24f3 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -42,6 +42,11 @@ class Translator { await this.database.purge(); } + async deleteDictionary(dictionaryName) { + this.tagCache = {}; + await this.database.deleteDictionary(dictionaryName); + } + async findTermsGrouped(text, dictionaries, alphanumeric, options) { const titles = Object.keys(dictionaries); const {length, definitions} = await this.findTerms(text, dictionaries, alphanumeric); diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index 3554ec3d..f9686943 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -100,6 +100,10 @@ function utilDatabasePurge() { return utilBackend().translator.purgeDatabase(); } +function utilDatabaseDeleteDictionary(dictionaryName, onProgress) { + return utilBackend().translator.database.deleteDictionary(dictionaryName, onProgress); +} + async function utilDatabaseImport(data, progress, exceptions) { // Edge cannot read data on the background page due to the File object // being created from a different window. Read on the same page instead. diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 4fc20d77..5842e97a 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -418,7 +418,6 @@

Yomichan can import and use a variety of dictionary formats. Unneeded dictionaries can be disabled. - Deleting individual dictionaries is not currently feasible due to limitations of browser database technology.

@@ -471,6 +470,25 @@
+ + -- cgit v1.2.3 From cad0648cbe2b7511cd530eabfe526a40c1c090ba Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 3 Nov 2019 10:39:43 -0500 Subject: Remove unused function --- ext/bg/js/database.js | 6 ------ ext/bg/js/util.js | 4 ---- 2 files changed, 10 deletions(-) (limited to 'ext/bg/js/util.js') diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index dc2198ac..3476b715 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -232,12 +232,6 @@ class Database { return result; } - async summarize() { - this.validate(); - - return this.db.dictionaries.toArray(); - } - async getDictionaryInfo() { this.validate(); diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index f9686943..a6126677 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -80,10 +80,6 @@ function utilAnkiGetDeckNames() { return utilBackend().anki.getDeckNames(); } -function utilDatabaseSummarize() { - return utilBackend().translator.database.summarize(); -} - function utilDatabaseGetDictionaryInfo() { return utilBackend().translator.database.getDictionaryInfo(); } -- cgit v1.2.3 From 7f9a73135da4244e779f32179c7d19e6984bbc55 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 26 Nov 2019 15:07:11 -0500 Subject: Remove utilAsync --- ext/bg/js/settings-profiles.js | 14 +++++++------- ext/bg/js/settings.js | 8 ++++---- ext/bg/js/util.js | 6 ------ ext/fg/js/util.js | 6 ------ 4 files changed, 11 insertions(+), 23 deletions(-) (limited to 'ext/bg/js/util.js') diff --git a/ext/bg/js/settings-profiles.js b/ext/bg/js/settings-profiles.js index 3ae9db14..357a1b9b 100644 --- a/ext/bg/js/settings-profiles.js +++ b/ext/bg/js/settings-profiles.js @@ -35,16 +35,16 @@ async function profileOptionsSetup() { } function profileOptionsSetupEventListeners() { - $('#profile-target').change(utilAsync(onTargetProfileChanged)); + $('#profile-target').change((e) => onTargetProfileChanged(e)); $('#profile-name').change(onProfileNameChanged); - $('#profile-add').click(utilAsync(onProfileAdd)); - $('#profile-remove').click(utilAsync(onProfileRemove)); - $('#profile-remove-confirm').click(utilAsync(onProfileRemoveConfirm)); - $('#profile-copy').click(utilAsync(onProfileCopy)); - $('#profile-copy-confirm').click(utilAsync(onProfileCopyConfirm)); + $('#profile-add').click((e) => onProfileAdd(e)); + $('#profile-remove').click((e) => onProfileRemove(e)); + $('#profile-remove-confirm').click((e) => onProfileRemoveConfirm(e)); + $('#profile-copy').click((e) => onProfileCopy(e)); + $('#profile-copy-confirm').click((e) => onProfileCopyConfirm(e)); $('#profile-move-up').click(() => onProfileMove(-1)); $('#profile-move-down').click(() => onProfileMove(1)); - $('.profile-form').find('input, select, textarea').not('.profile-form-manual').change(utilAsync(onProfileOptionsChanged)); + $('.profile-form').find('input, select, textarea').not('.profile-form-manual').change((e) => onProfileOptionsChanged(e)); } function tryGetIntegerValue(selector, min, max) { diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index ab267c32..d1f9d0d1 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -155,8 +155,8 @@ async function formWrite(options) { } function formSetupEventListeners() { - $('input, select, textarea').not('.anki-model').not('.ignore-form-changes *').change(utilAsync(onFormOptionsChanged)); - $('.anki-model').change(utilAsync(onAnkiModelChanged)); + $('input, select, textarea').not('.anki-model').not('.ignore-form-changes *').change((e) => onFormOptionsChanged(e)); + $('.anki-model').change((e) => onAnkiModelChanged(e)); } function formUpdateVisibility(options) { @@ -219,7 +219,7 @@ async function onReady() { chrome.runtime.onMessage.addListener(onMessage); } -$(document).ready(utilAsync(onReady)); +$(document).ready(() => onReady()); /* @@ -582,7 +582,7 @@ async function ankiFieldsPopulate(element, options) { container.append($(html)); } - tab.find('.anki-field-value').change(utilAsync(onFormOptionsChanged)); + tab.find('.anki-field-value').change((e) => onFormOptionsChanged(e)); tab.find('.marker-link').click(onAnkiMarkerClicked); } diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index a6126677..b9e602b3 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -16,12 +16,6 @@ * along with this program. If not, see . */ -function utilAsync(func) { - return function(...args) { - func.apply(this, args); - }; -} - function utilIsolate(data) { return JSON.parse(JSON.stringify(data)); } diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js index 9a7968a7..f28bd636 100644 --- a/ext/fg/js/util.js +++ b/ext/fg/js/util.js @@ -17,12 +17,6 @@ */ -function utilAsync(func) { - return function(...args) { - func.apply(this, args); - }; -} - function utilInvoke(action, params={}) { const data = {action, params}; return new Promise((resolve, reject) => { -- cgit v1.2.3 From 099847729c471c3ff6e8c28673114eae81c6a4f4 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 26 Nov 2019 17:33:09 -0500 Subject: utilIsObject => isObject, move to core.js --- ext/bg/js/options.js | 4 ++-- ext/bg/js/util.js | 4 ---- ext/mixed/js/core.js | 4 ++++ 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'ext/bg/js/util.js') diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index b9bf85f3..63d88789 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -389,7 +389,7 @@ function optionsUpdateVersion(options, defaultProfileOptions) { // Remove invalid const profiles = options.profiles; for (let i = profiles.length - 1; i >= 0; --i) { - if (!utilIsObject(profiles[i])) { + if (!isObject(profiles[i])) { profiles.splice(i, 1); } } @@ -440,7 +440,7 @@ function optionsLoad() { }).then(optionsStr => { if (typeof optionsStr === 'string') { const options = JSON.parse(optionsStr); - if (utilIsObject(options)) { + if (isObject(options)) { return options; } } diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index b9e602b3..c21fd68c 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -111,7 +111,3 @@ function utilReadFile(file) { reader.readAsBinaryString(file); }); } - -function utilIsObject(value) { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index 12ed9c1f..513d6211 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -148,3 +148,7 @@ function stringReplaceAsync(str, regex, replacer) { parts.push(str.substring(index)); return Promise.all(parts).then(v => v.join('')); } + +function isObject(value) { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} -- cgit v1.2.3 From 5a1046bc906a74ca39906a52acc62fc702a658f2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 26 Nov 2019 22:01:54 -0500 Subject: Update arrow-parens to always --- .eslintrc.json | 2 +- ext/bg/js/anki.js | 2 +- ext/bg/js/api.js | 2 +- ext/bg/js/backend-api-forwarder.js | 4 ++-- ext/bg/js/backend.js | 6 +++--- ext/bg/js/context.js | 2 +- ext/bg/js/database.js | 22 +++++++++++----------- ext/bg/js/dictionary.js | 10 +++++----- ext/bg/js/options.js | 6 +++--- ext/bg/js/profile-conditions.js | 2 +- ext/bg/js/request.js | 2 +- ext/bg/js/search-query-parser.js | 4 ++-- ext/bg/js/settings-dictionaries.js | 10 +++++----- ext/bg/js/settings-profiles.js | 2 +- ext/bg/js/settings.js | 8 ++++---- ext/bg/js/translator.js | 8 ++++---- ext/bg/js/util.js | 4 ++-- ext/fg/js/frontend-api-receiver.js | 4 ++-- ext/fg/js/popup.js | 4 ++-- ext/mixed/js/core.js | 2 +- 20 files changed, 53 insertions(+), 53 deletions(-) (limited to 'ext/bg/js/util.js') diff --git a/.eslintrc.json b/.eslintrc.json index fce4b884..0e3b939a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,7 @@ "/ext/bg/js/templates.js" ], "rules": { - "arrow-parens": ["error", "as-needed"], + "arrow-parens": ["error", "always"], "comma-dangle": ["error", "never"], "curly": ["error", "all"], "dot-notation": "error", diff --git a/ext/bg/js/anki.js b/ext/bg/js/anki.js index ac45784b..17b93620 100644 --- a/ext/bg/js/anki.js +++ b/ext/bg/js/anki.js @@ -74,7 +74,7 @@ class AnkiConnect { async findNoteIds(notes) { await this.checkVersion(); - const actions = notes.map(note => ({ + const actions = notes.map((note) => ({ action: 'findNotes', params: { query: `deck:"${AnkiConnect.escapeQuery(note.deckName)}" ${AnkiConnect.fieldsToQuery(note.fields)}` diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index d5256acb..b489b8d2 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -207,7 +207,7 @@ async function apiDefinitionsAddable(definitions, modes, optionsContext) { } if (cannotAdd.length > 0) { - const noteIdsArray = await anki.findNoteIds(cannotAdd.map(e => e[0])); + const noteIdsArray = await anki.findNoteIds(cannotAdd.map((e) => e[0])); for (let i = 0, ii = Math.min(cannotAdd.length, noteIdsArray.length); i < ii; ++i) { const noteIds = noteIdsArray[i]; if (noteIds.length > 0) { diff --git a/ext/bg/js/backend-api-forwarder.js b/ext/bg/js/backend-api-forwarder.js index 979afd16..db4d30b9 100644 --- a/ext/bg/js/backend-api-forwarder.js +++ b/ext/bg/js/backend-api-forwarder.js @@ -37,8 +37,8 @@ class BackendApiForwarder { const forwardPort = chrome.tabs.connect(tabId, {name: 'frontend-api-receiver'}); - port.onMessage.addListener(message => forwardPort.postMessage(message)); - forwardPort.onMessage.addListener(message => port.postMessage(message)); + port.onMessage.addListener((message) => forwardPort.postMessage(message)); + forwardPort.onMessage.addListener((message) => port.postMessage(message)); port.onDisconnect.addListener(() => forwardPort.disconnect()); forwardPort.onDisconnect.addListener(() => port.disconnect()); } diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 73df7cf5..d9f9b586 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -60,7 +60,7 @@ class Backend { this.applyOptions(); const callback = () => this.checkLastError(chrome.runtime.lastError); - chrome.tabs.query({}, tabs => { + chrome.tabs.query({}, (tabs) => { for (const tab of tabs) { chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdate', params: {source}}, callback); } @@ -77,8 +77,8 @@ class Backend { const handler = handlers[action]; const promise = handler(params, sender); promise.then( - result => callback({result}), - error => callback({error: errorToJson(error)}) + (result) => callback({result}), + (error) => callback({error: errorToJson(error)}) ); } diff --git a/ext/bg/js/context.js b/ext/bg/js/context.js index b288a79a..38a82636 100644 --- a/ext/bg/js/context.js +++ b/ext/bg/js/context.js @@ -63,7 +63,7 @@ window.addEventListener('DOMContentLoaded', () => { depth: 0, url: window.location.href }; - apiOptionsGet(optionsContext).then(options => { + apiOptionsGet(optionsContext).then((options) => { const toggle = document.querySelector('#enable-search'); toggle.checked = options.general.enable; toggle.addEventListener('change', () => apiCommandExec('toggle'), false); diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index c53c9f77..a20d5f15 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -257,7 +257,7 @@ class Database { const dbTerms = dbTransaction.objectStore('tagMeta'); const dbIndex = dbTerms.index('name'); const only = IDBKeyRange.only(name); - await Database.getAll(dbIndex, only, null, row => { + await Database.getAll(dbIndex, only, null, (row) => { if (title === row.dictionary) { result = row; } @@ -273,7 +273,7 @@ class Database { const dbTransaction = this.db.transaction(['dictionaries'], 'readonly'); const dbDictionaries = dbTransaction.objectStore('dictionaries'); - await Database.getAll(dbDictionaries, null, null, info => results.push(info)); + await Database.getAll(dbDictionaries, null, null, (info) => results.push(info)); return results; } @@ -308,7 +308,7 @@ class Database { counts.push(null); const index = i; const query2 = IDBKeyRange.only(dictionaryNames[i]); - const countPromise = Database.getCounts(targets, query2).then(v => counts[index] = v); + const countPromise = Database.getCounts(targets, query2).then((v) => counts[index] = v); countPromises.push(countPromise); } await Promise.all(countPromises); @@ -346,7 +346,7 @@ class Database { } }; - const indexDataLoaded = async summary => { + const indexDataLoaded = async (summary) => { if (summary.version > 3) { throw new Error('Unsupported dictionary version'); } @@ -522,13 +522,13 @@ class Database { await indexDataLoaded(summary); - const buildTermBankName = index => `term_bank_${index + 1}.json`; - const buildTermMetaBankName = index => `term_meta_bank_${index + 1}.json`; - const buildKanjiBankName = index => `kanji_bank_${index + 1}.json`; - const buildKanjiMetaBankName = index => `kanji_meta_bank_${index + 1}.json`; - const buildTagBankName = index => `tag_bank_${index + 1}.json`; + const buildTermBankName = (index) => `term_bank_${index + 1}.json`; + const buildTermMetaBankName = (index) => `term_meta_bank_${index + 1}.json`; + const buildKanjiBankName = (index) => `kanji_bank_${index + 1}.json`; + const buildKanjiMetaBankName = (index) => `kanji_meta_bank_${index + 1}.json`; + const buildTagBankName = (index) => `tag_bank_${index + 1}.json`; - const countBanks = namer => { + const countBanks = (namer) => { let count = 0; while (zip.files[namer(count)]) { ++count; @@ -657,7 +657,7 @@ class Database { const counts = {}; for (const [objectStoreName, index] of targets) { const n = objectStoreName; - const countPromise = Database.getCount(index, query).then(count => counts[n] = count); + const countPromise = Database.getCount(index, query).then((count) => counts[n] = count); countPromises.push(countPromise); } return Promise.all(countPromises).then(() => counts); diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js index 409bed85..0b35e32e 100644 --- a/ext/bg/js/dictionary.js +++ b/ext/bg/js/dictionary.js @@ -99,8 +99,8 @@ function dictTermsCompressTags(definitions) { let lastPartOfSpeech = ''; for (const definition of definitions) { - const dictionary = JSON.stringify(definition.definitionTags.filter(tag => tag.category === 'dictionary').map(tag => tag.name).sort()); - const partOfSpeech = JSON.stringify(definition.definitionTags.filter(tag => tag.category === 'partOfSpeech').map(tag => tag.name).sort()); + const dictionary = JSON.stringify(definition.definitionTags.filter((tag) => tag.category === 'dictionary').map((tag) => tag.name).sort()); + const partOfSpeech = JSON.stringify(definition.definitionTags.filter((tag) => tag.category === 'partOfSpeech').map((tag) => tag.name).sort()); const filterOutCategories = []; @@ -117,7 +117,7 @@ function dictTermsCompressTags(definitions) { lastPartOfSpeech = partOfSpeech; } - definition.definitionTags = definition.definitionTags.filter(tag => !filterOutCategories.includes(tag.category)); + definition.definitionTags = definition.definitionTags.filter((tag) => !filterOutCategories.includes(tag.category)); } } @@ -231,7 +231,7 @@ function dictTermsMergeByGloss(result, definitions, appendTo, mergedIndices) { result.reading.add(definition.reading); for (const tag of definition.definitionTags) { - if (!definitionsByGloss[gloss].definitionTags.find(existingTag => existingTag.name === tag.name)) { + if (!definitionsByGloss[gloss].definitionTags.find((existingTag) => existingTag.name === tag.name)) { definitionsByGloss[gloss].definitionTags.push(tag); } } @@ -246,7 +246,7 @@ function dictTermsMergeByGloss(result, definitions, appendTo, mergedIndices) { } for (const tag of definition.termTags) { - if (!result.expressions.get(definition.expression).get(definition.reading).find(existingTag => existingTag.name === tag.name)) { + if (!result.expressions.get(definition.expression).get(definition.reading).find((existingTag) => existingTag.name === tag.name)) { result.expressions.get(definition.expression).get(definition.reading).push(tag); } } diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 358a6b45..e53a8a13 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -429,7 +429,7 @@ function optionsUpdateVersion(options, defaultProfileOptions) { function optionsLoad() { return new Promise((resolve, reject) => { - chrome.storage.local.get(['options'], store => { + chrome.storage.local.get(['options'], (store) => { const error = chrome.runtime.lastError; if (error) { reject(new Error(error)); @@ -437,7 +437,7 @@ function optionsLoad() { resolve(store.options); } }); - }).then(optionsStr => { + }).then((optionsStr) => { if (typeof optionsStr === 'string') { const options = JSON.parse(optionsStr); if (isObject(options)) { @@ -447,7 +447,7 @@ function optionsLoad() { return {}; }).catch(() => { return {}; - }).then(options => { + }).then((options) => { return ( Array.isArray(options.profiles) ? optionsUpdateVersion(options, {}) : diff --git a/ext/bg/js/profile-conditions.js b/ext/bg/js/profile-conditions.js index 8272e5dd..ebc6680a 100644 --- a/ext/bg/js/profile-conditions.js +++ b/ext/bg/js/profile-conditions.js @@ -86,7 +86,7 @@ const profileConditionsDescriptor = { placeholder: 'Comma separated list of domains', defaultValue: 'example.com', transformCache: {}, - transform: (optionValue) => optionValue.split(/[,;\s]+/).map(v => v.trim().toLowerCase()).filter(v => v.length > 0), + transform: (optionValue) => optionValue.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0), transformReverse: (transformedOptionValue) => transformedOptionValue.join(', '), validateTransformed: (transformedOptionValue) => (transformedOptionValue.length > 0), test: ({url}, transformedOptionValue) => _profileConditionTestDomainList(url, transformedOptionValue) diff --git a/ext/bg/js/request.js b/ext/bg/js/request.js index 3afc1506..7d73d49b 100644 --- a/ext/bg/js/request.js +++ b/ext/bg/js/request.js @@ -29,7 +29,7 @@ function requestJson(url, action, params) { } else { xhr.send(); } - }).then(responseText => { + }).then((responseText) => { try { return JSON.parse(responseText); } diff --git a/ext/bg/js/search-query-parser.js b/ext/bg/js/search-query-parser.js index 74ef32d8..c7222212 100644 --- a/ext/bg/js/search-query-parser.js +++ b/ext/bg/js/search-query-parser.js @@ -107,7 +107,7 @@ class QueryParser { } getParseResult() { - return this.parseResults.find(r => r.id === this.selectedParser); + return this.parseResults.find((r) => r.id === this.selectedParser); } async setText(text) { @@ -216,7 +216,7 @@ class QueryParser { static processParseResultForDisplay(result) { return result.map((term) => { - return term.filter(part => part.text.trim()).map((part) => { + return term.filter((part) => part.text.trim()).map((part) => { return { text: Array.from(part.text), reading: part.reading, diff --git a/ext/bg/js/settings-dictionaries.js b/ext/bg/js/settings-dictionaries.js index 177379b0..065a8abc 100644 --- a/ext/bg/js/settings-dictionaries.js +++ b/ext/bg/js/settings-dictionaries.js @@ -62,8 +62,8 @@ class SettingsDictionaryListUI { this.updateDictionaryOrder(); - const titles = this.dictionaryEntries.map(e => e.dictionaryInfo.title); - const removeKeys = Object.keys(this.optionsDictionaries).filter(key => titles.indexOf(key) < 0); + const titles = this.dictionaryEntries.map((e) => e.dictionaryInfo.title); + const removeKeys = Object.keys(this.optionsDictionaries).filter((key) => titles.indexOf(key) < 0); if (removeKeys.length > 0) { for (const key of toIterable(removeKeys)) { delete this.optionsDictionaries[key]; @@ -161,7 +161,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((e) => e.dictionaryInfo.title === title); if (index >= 0) { this.dictionaryEntries[index].deleteDictionary(); } @@ -377,7 +377,7 @@ async function onDatabaseUpdated(options) { updateMainDictionarySelect(options, dictionaries); - const {counts, total} = await utilDatabaseGetDictionaryCounts(dictionaries.map(v => v.title), true); + const {counts, total} = await utilDatabaseGetDictionaryCounts(dictionaries.map((v) => v.title), true); dictionaryUI.setCounts(counts, total); } catch (e) { dictionaryErrorsShow([e]); @@ -564,7 +564,7 @@ async function onDictionaryImport(e) { dictionaryErrorsShow(null); dictionarySpinnerShow(true); - const setProgress = percent => dictProgress.find('.progress-bar').css('width', `${percent}%`); + const setProgress = (percent) => dictProgress.find('.progress-bar').css('width', `${percent}%`); const updateProgress = (total, current) => { setProgress(current / total * 100.0); if (storageEstimate.mostRecent !== null && !storageUpdateStats.isUpdating) { diff --git a/ext/bg/js/settings-profiles.js b/ext/bg/js/settings-profiles.js index 9532e3eb..8c218e97 100644 --- a/ext/bg/js/settings-profiles.js +++ b/ext/bg/js/settings-profiles.js @@ -147,7 +147,7 @@ function profileOptionsCreateCopyName(name, profiles, maxUniqueAttempts) { let i = 0; while (true) { const newName = `${prefix}${space}${index}${suffix}`; - if (i++ >= maxUniqueAttempts || profiles.findIndex(profile => profile.name === newName) < 0) { + if (i++ >= maxUniqueAttempts || profiles.findIndex((profile) => profile.name === newName) < 0) { return newName; } if (typeof index !== 'number') { diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index 48026794..abe6f389 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -18,7 +18,7 @@ async function getOptionsArray() { const optionsFull = await apiOptionsGetFull(); - return optionsFull.profiles.map(profile => profile.options); + return optionsFull.profiles.map((profile) => profile.options); } async function formRead(options) { @@ -484,12 +484,12 @@ async function ankiDeckAndModelPopulate(options) { const deckNames = await utilAnkiGetDeckNames(); const ankiDeck = $('.anki-deck'); ankiDeck.find('option').remove(); - deckNames.sort().forEach(name => ankiDeck.append($('