Merge pull request #447 from toasted-nutbread/util-conversions
Util conversions
This commit is contained in:
commit
106172e2c1
@ -100,7 +100,13 @@ class Backend {
|
|||||||
['getQueryParserTemplatesHtml', {handler: this._onApiGetQueryParserTemplatesHtml.bind(this), async: true}],
|
['getQueryParserTemplatesHtml', {handler: this._onApiGetQueryParserTemplatesHtml.bind(this), async: true}],
|
||||||
['getZoom', {handler: this._onApiGetZoom.bind(this), async: true}],
|
['getZoom', {handler: this._onApiGetZoom.bind(this), async: true}],
|
||||||
['getMessageToken', {handler: this._onApiGetMessageToken.bind(this), async: false}],
|
['getMessageToken', {handler: this._onApiGetMessageToken.bind(this), async: false}],
|
||||||
['getDefaultAnkiFieldTemplates', {handler: this._onApiGetDefaultAnkiFieldTemplates.bind(this), async: false}]
|
['getDefaultAnkiFieldTemplates', {handler: this._onApiGetDefaultAnkiFieldTemplates.bind(this), async: false}],
|
||||||
|
['getAnkiDeckNames', {handler: this._onApiGetAnkiDeckNames.bind(this), async: true}],
|
||||||
|
['getAnkiModelNames', {handler: this._onApiGetAnkiModelNames.bind(this), async: true}],
|
||||||
|
['getAnkiModelFieldNames', {handler: this._onApiGetAnkiModelFieldNames.bind(this), async: true}],
|
||||||
|
['getDictionaryInfo', {handler: this._onApiGetDictionaryInfo.bind(this), async: true}],
|
||||||
|
['getDictionaryCounts', {handler: this._onApiGetDictionaryCounts.bind(this), async: true}],
|
||||||
|
['purgeDatabase', {handler: this._onApiPurgeDatabase.bind(this), async: true}]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this._commandHandlers = new Map([
|
this._commandHandlers = new Map([
|
||||||
@ -722,6 +728,36 @@ class Backend {
|
|||||||
return this.defaultAnkiFieldTemplates;
|
return this.defaultAnkiFieldTemplates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onApiGetAnkiDeckNames(params, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.anki.getDeckNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onApiGetAnkiModelNames(params, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.anki.getModelNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onApiGetAnkiModelFieldNames({modelName}, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.anki.getModelFieldNames(modelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onApiGetDictionaryInfo(params, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.translator.database.getDictionaryInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onApiGetDictionaryCounts({dictionaryNames, getTotal}, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.translator.database.getDictionaryCounts(dictionaryNames, getTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onApiPurgeDatabase(params, sender) {
|
||||||
|
this._validatePrivilegedMessageSender(sender);
|
||||||
|
return await this.translator.purgeDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
async _onCommandSearch(params) {
|
async _onCommandSearch(params) {
|
||||||
@ -818,6 +854,13 @@ class Backend {
|
|||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
|
_validatePrivilegedMessageSender(sender) {
|
||||||
|
const url = sender.url;
|
||||||
|
if (!(typeof url === 'string' && yomichan.isExtensionUrl(url))) {
|
||||||
|
throw new Error('Invalid message sender');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async _getAudioUri(definition, source, details) {
|
async _getAudioUri(definition, source, details) {
|
||||||
let optionsContext = (typeof details === 'object' && details !== null ? details.optionsContext : null);
|
let optionsContext = (typeof details === 'object' && details !== null ? details.optionsContext : null);
|
||||||
if (!(typeof optionsContext === 'object' && optionsContext !== null)) {
|
if (!(typeof optionsContext === 'object' && optionsContext !== null)) {
|
||||||
|
@ -15,14 +15,23 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
|
||||||
* utilStringHashCode
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic options functions
|
* Generic options functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function optionsGetStringHashCode(string) {
|
||||||
|
let hashCode = 0;
|
||||||
|
|
||||||
|
if (typeof string !== 'string') { return hashCode; }
|
||||||
|
|
||||||
|
for (let i = 0, charCode = string.charCodeAt(i); i < string.length; charCode = string.charCodeAt(++i)) {
|
||||||
|
hashCode = ((hashCode << 5) - hashCode) + charCode;
|
||||||
|
hashCode |= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
function optionsGenericApplyUpdates(options, updates) {
|
function optionsGenericApplyUpdates(options, updates) {
|
||||||
const targetVersion = updates.length;
|
const targetVersion = updates.length;
|
||||||
const currentVersion = options.version;
|
const currentVersion = options.version;
|
||||||
@ -63,12 +72,12 @@ const profileOptionsVersionUpdates = [
|
|||||||
options.anki.fieldTemplates = null;
|
options.anki.fieldTemplates = null;
|
||||||
},
|
},
|
||||||
(options) => {
|
(options) => {
|
||||||
if (utilStringHashCode(options.anki.fieldTemplates) === 1285806040) {
|
if (optionsGetStringHashCode(options.anki.fieldTemplates) === 1285806040) {
|
||||||
options.anki.fieldTemplates = null;
|
options.anki.fieldTemplates = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(options) => {
|
(options) => {
|
||||||
if (utilStringHashCode(options.anki.fieldTemplates) === -250091611) {
|
if (optionsGetStringHashCode(options.anki.fieldTemplates) === -250091611) {
|
||||||
options.anki.fieldTemplates = null;
|
options.anki.fieldTemplates = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -87,7 +96,7 @@ const profileOptionsVersionUpdates = [
|
|||||||
(options) => {
|
(options) => {
|
||||||
// Version 12 changes:
|
// Version 12 changes:
|
||||||
// The preferred default value of options.anki.fieldTemplates has been changed to null.
|
// The preferred default value of options.anki.fieldTemplates has been changed to null.
|
||||||
if (utilStringHashCode(options.anki.fieldTemplates) === 1444379824) {
|
if (optionsGetStringHashCode(options.anki.fieldTemplates) === 1444379824) {
|
||||||
options.anki.fieldTemplates = null;
|
options.anki.fieldTemplates = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
/* global
|
||||||
|
* apiGetAnkiDeckNames
|
||||||
|
* apiGetAnkiModelFieldNames
|
||||||
|
* apiGetAnkiModelNames
|
||||||
* getOptionsContext
|
* getOptionsContext
|
||||||
* getOptionsMutable
|
* getOptionsMutable
|
||||||
* onFormOptionsChanged
|
* onFormOptionsChanged
|
||||||
* settingsSaveOptions
|
* settingsSaveOptions
|
||||||
* utilAnkiGetDeckNames
|
|
||||||
* utilAnkiGetModelFieldNames
|
|
||||||
* utilAnkiGetModelNames
|
|
||||||
* utilBackgroundIsolate
|
* utilBackgroundIsolate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ async function _ankiDeckAndModelPopulate(options) {
|
|||||||
const kanjiModel = {value: options.anki.kanji.model, selector: '#anki-kanji-model'};
|
const kanjiModel = {value: options.anki.kanji.model, selector: '#anki-kanji-model'};
|
||||||
try {
|
try {
|
||||||
_ankiSpinnerShow(true);
|
_ankiSpinnerShow(true);
|
||||||
const [deckNames, modelNames] = await Promise.all([utilAnkiGetDeckNames(), utilAnkiGetModelNames()]);
|
const [deckNames, modelNames] = await Promise.all([apiGetAnkiDeckNames(), apiGetAnkiModelNames()]);
|
||||||
deckNames.sort();
|
deckNames.sort();
|
||||||
modelNames.sort();
|
modelNames.sort();
|
||||||
termsDeck.values = deckNames;
|
termsDeck.values = deckNames;
|
||||||
@ -180,7 +180,7 @@ async function _onAnkiModelChanged(e) {
|
|||||||
let fieldNames;
|
let fieldNames;
|
||||||
try {
|
try {
|
||||||
const modelName = node.value;
|
const modelName = node.value;
|
||||||
fieldNames = await utilAnkiGetModelFieldNames(modelName);
|
fieldNames = await apiGetAnkiModelFieldNames(modelName);
|
||||||
_ankiSetError(null);
|
_ankiSetError(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_ankiSetError(error);
|
_ankiSetError(error);
|
||||||
|
@ -17,8 +17,11 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* PageExitPrevention
|
* PageExitPrevention
|
||||||
|
* apiGetDictionaryCounts
|
||||||
|
* apiGetDictionaryInfo
|
||||||
* apiOptionsGet
|
* apiOptionsGet
|
||||||
* apiOptionsGetFull
|
* apiOptionsGetFull
|
||||||
|
* apiPurgeDatabase
|
||||||
* getOptionsContext
|
* getOptionsContext
|
||||||
* getOptionsFullMutable
|
* getOptionsFullMutable
|
||||||
* getOptionsMutable
|
* getOptionsMutable
|
||||||
@ -27,10 +30,7 @@
|
|||||||
* storageUpdateStats
|
* storageUpdateStats
|
||||||
* utilBackgroundIsolate
|
* utilBackgroundIsolate
|
||||||
* utilDatabaseDeleteDictionary
|
* utilDatabaseDeleteDictionary
|
||||||
* utilDatabaseGetDictionaryCounts
|
|
||||||
* utilDatabaseGetDictionaryInfo
|
|
||||||
* utilDatabaseImport
|
* utilDatabaseImport
|
||||||
* utilDatabasePurge
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let dictionaryUI = null;
|
let dictionaryUI = null;
|
||||||
@ -431,7 +431,7 @@ async function onDictionaryOptionsChanged() {
|
|||||||
|
|
||||||
async function onDatabaseUpdated() {
|
async function onDatabaseUpdated() {
|
||||||
try {
|
try {
|
||||||
const dictionaries = await utilDatabaseGetDictionaryInfo();
|
const dictionaries = await apiGetDictionaryInfo();
|
||||||
dictionaryUI.setDictionaries(dictionaries);
|
dictionaryUI.setDictionaries(dictionaries);
|
||||||
|
|
||||||
document.querySelector('#dict-warning').hidden = (dictionaries.length > 0);
|
document.querySelector('#dict-warning').hidden = (dictionaries.length > 0);
|
||||||
@ -439,7 +439,7 @@ async function onDatabaseUpdated() {
|
|||||||
updateMainDictionarySelectOptions(dictionaries);
|
updateMainDictionarySelectOptions(dictionaries);
|
||||||
await updateMainDictionarySelectValue();
|
await updateMainDictionarySelectValue();
|
||||||
|
|
||||||
const {counts, total} = await utilDatabaseGetDictionaryCounts(dictionaries.map((v) => v.title), true);
|
const {counts, total} = await apiGetDictionaryCounts(dictionaries.map((v) => v.title), true);
|
||||||
dictionaryUI.setCounts(counts, total);
|
dictionaryUI.setCounts(counts, total);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dictionaryErrorsShow([e]);
|
dictionaryErrorsShow([e]);
|
||||||
@ -618,7 +618,7 @@ async function onDictionaryPurge(e) {
|
|||||||
dictionaryErrorsShow(null);
|
dictionaryErrorsShow(null);
|
||||||
dictionarySpinnerShow(true);
|
dictionarySpinnerShow(true);
|
||||||
|
|
||||||
await utilDatabasePurge();
|
await apiPurgeDatabase();
|
||||||
for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) {
|
for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) {
|
||||||
options.dictionaries = utilBackgroundIsolate({});
|
options.dictionaries = utilBackgroundIsolate({});
|
||||||
options.general.mainDictionary = '';
|
options.general.mainDictionary = '';
|
||||||
|
@ -58,19 +58,6 @@ function utilBackgroundFunctionIsolate(func) {
|
|||||||
return backgroundPage.utilFunctionIsolate(func);
|
return backgroundPage.utilFunctionIsolate(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
function utilStringHashCode(string) {
|
|
||||||
let hashCode = 0;
|
|
||||||
|
|
||||||
if (typeof string !== 'string') { return hashCode; }
|
|
||||||
|
|
||||||
for (let i = 0, charCode = string.charCodeAt(i); i < string.length; charCode = string.charCodeAt(++i)) {
|
|
||||||
hashCode = ((hashCode << 5) - hashCode) + charCode;
|
|
||||||
hashCode |= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
function utilBackend() {
|
function utilBackend() {
|
||||||
const backend = chrome.extension.getBackgroundPage().yomichanBackend;
|
const backend = chrome.extension.getBackgroundPage().yomichanBackend;
|
||||||
if (!backend.isPrepared) {
|
if (!backend.isPrepared) {
|
||||||
@ -79,35 +66,6 @@ function utilBackend() {
|
|||||||
return backend;
|
return backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function utilAnkiGetModelNames() {
|
|
||||||
return utilIsolate(await utilBackend().anki.getModelNames());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilAnkiGetDeckNames() {
|
|
||||||
return utilIsolate(await utilBackend().anki.getDeckNames());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilDatabaseGetDictionaryInfo() {
|
|
||||||
return utilIsolate(await utilBackend().translator.database.getDictionaryInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilDatabaseGetDictionaryCounts(dictionaryNames, getTotal) {
|
|
||||||
return utilIsolate(await utilBackend().translator.database.getDictionaryCounts(
|
|
||||||
utilBackgroundIsolate(dictionaryNames),
|
|
||||||
utilBackgroundIsolate(getTotal)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilAnkiGetModelFieldNames(modelName) {
|
|
||||||
return utilIsolate(await utilBackend().anki.getModelFieldNames(
|
|
||||||
utilBackgroundIsolate(modelName)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilDatabasePurge() {
|
|
||||||
return utilIsolate(await utilBackend().translator.purgeDatabase());
|
|
||||||
}
|
|
||||||
|
|
||||||
async function utilDatabaseDeleteDictionary(dictionaryName, onProgress) {
|
async function utilDatabaseDeleteDictionary(dictionaryName, onProgress) {
|
||||||
return utilIsolate(await utilBackend().translator.database.deleteDictionary(
|
return utilIsolate(await utilBackend().translator.database.deleteDictionary(
|
||||||
utilBackgroundIsolate(dictionaryName),
|
utilBackgroundIsolate(dictionaryName),
|
||||||
|
@ -539,19 +539,10 @@ class Popup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
static async _injectStylesheet(id, type, value, useWebExtensionApi) {
|
||||||
const injectedStylesheets = Popup._injectedStylesheets;
|
const injectedStylesheets = Popup._injectedStylesheets;
|
||||||
|
|
||||||
if (Popup._isOnExtensionPage()) {
|
if (yomichan.isExtensionUrl(window.location.href)) {
|
||||||
// Permissions error will occur if trying to use the WebExtension API to inject
|
// Permissions error will occur if trying to use the WebExtension API to inject
|
||||||
// into an extension page.
|
// into an extension page.
|
||||||
useWebExtensionApi = false;
|
useWebExtensionApi = false;
|
||||||
|
@ -116,6 +116,30 @@ function apiGetDefaultAnkiFieldTemplates() {
|
|||||||
return _apiInvoke('getDefaultAnkiFieldTemplates');
|
return _apiInvoke('getDefaultAnkiFieldTemplates');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function apiGetAnkiDeckNames() {
|
||||||
|
return _apiInvoke('getAnkiDeckNames');
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiGetAnkiModelNames() {
|
||||||
|
return _apiInvoke('getAnkiModelNames');
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiGetAnkiModelFieldNames(modelName) {
|
||||||
|
return _apiInvoke('getAnkiModelFieldNames', {modelName});
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiGetDictionaryInfo() {
|
||||||
|
return _apiInvoke('getDictionaryInfo');
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiGetDictionaryCounts(dictionaryNames, getTotal) {
|
||||||
|
return _apiInvoke('getDictionaryCounts', {dictionaryNames, getTotal});
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiPurgeDatabase() {
|
||||||
|
return _apiInvoke('purgeDatabase');
|
||||||
|
}
|
||||||
|
|
||||||
function _apiInvoke(action, params={}) {
|
function _apiInvoke(action, params={}) {
|
||||||
const data = {action, params};
|
const data = {action, params};
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -316,6 +316,15 @@ const yomichan = (() => {
|
|||||||
this.trigger('orphaned', {error});
|
this.trigger('orphaned', {error});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isExtensionUrl(url) {
|
||||||
|
try {
|
||||||
|
const urlBase = chrome.runtime.getURL('/');
|
||||||
|
return url.substring(0, urlBase.length) === urlBase;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getTemporaryListenerResult(eventHandler, userCallback, timeout=null) {
|
getTemporaryListenerResult(eventHandler, userCallback, timeout=null) {
|
||||||
if (!(
|
if (!(
|
||||||
typeof eventHandler.addListener === 'function' &&
|
typeof eventHandler.addListener === 'function' &&
|
||||||
|
Loading…
Reference in New Issue
Block a user