API refactor (#532)

* Convert api.js into a class instance

* Use new api.* functions

* Fix missing binds

* Group functions with progress callbacks together

* Change style

* Fix API override not working
This commit is contained in:
toasted-nutbread 2020-05-24 13:30:40 -04:00 committed by GitHub
parent 83a577fa56
commit c61a87b152
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 408 additions and 436 deletions

View File

@ -16,11 +16,7 @@
*/ */
/* global /* global
* apiCommandExec * api
* apiForwardLogsToBackend
* apiGetEnvironmentInfo
* apiLogIndicatorClear
* apiOptionsGet
*/ */
function showExtensionInfo() { function showExtensionInfo() {
@ -36,12 +32,12 @@ function setupButtonEvents(selector, command, url) {
for (const node of nodes) { for (const node of nodes) {
node.addEventListener('click', (e) => { node.addEventListener('click', (e) => {
if (e.button !== 0) { return; } if (e.button !== 0) { return; }
apiCommandExec(command, {mode: e.ctrlKey ? 'newTab' : 'existingOrNewTab'}); api.commandExec(command, {mode: e.ctrlKey ? 'newTab' : 'existingOrNewTab'});
e.preventDefault(); e.preventDefault();
}, false); }, false);
node.addEventListener('auxclick', (e) => { node.addEventListener('auxclick', (e) => {
if (e.button !== 1) { return; } if (e.button !== 1) { return; }
apiCommandExec(command, {mode: 'newTab'}); api.commandExec(command, {mode: 'newTab'});
e.preventDefault(); e.preventDefault();
}, false); }, false);
@ -54,14 +50,14 @@ function setupButtonEvents(selector, command, url) {
} }
async function mainInner() { async function mainInner() {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
await yomichan.prepare(); await yomichan.prepare();
await apiLogIndicatorClear(); await api.logIndicatorClear();
showExtensionInfo(); showExtensionInfo();
apiGetEnvironmentInfo().then(({browser}) => { api.getEnvironmentInfo().then(({browser}) => {
// Firefox mobile opens this page as a full webpage. // Firefox mobile opens this page as a full webpage.
document.documentElement.dataset.mode = (browser === 'firefox-mobile' ? 'full' : 'mini'); document.documentElement.dataset.mode = (browser === 'firefox-mobile' ? 'full' : 'mini');
}); });
@ -76,14 +72,14 @@ async function mainInner() {
depth: 0, depth: 0,
url: window.location.href url: window.location.href
}; };
apiOptionsGet(optionsContext).then((options) => { api.optionsGet(optionsContext).then((options) => {
const toggle = document.querySelector('#enable-search'); const toggle = document.querySelector('#enable-search');
toggle.checked = options.general.enable; toggle.checked = options.general.enable;
toggle.addEventListener('change', () => apiCommandExec('toggle'), false); toggle.addEventListener('change', () => api.commandExec('toggle'), false);
const toggle2 = document.querySelector('#enable-search2'); const toggle2 = document.querySelector('#enable-search2');
toggle2.checked = options.general.enable; toggle2.checked = options.general.enable;
toggle2.addEventListener('change', () => apiCommandExec('toggle'), false); toggle2.addEventListener('change', () => api.commandExec('toggle'), false);
setTimeout(() => { setTimeout(() => {
for (const n of document.querySelectorAll('.toggle-group')) { for (const n of document.querySelectorAll('.toggle-group')) {

View File

@ -17,8 +17,7 @@
/* global /* global
* DisplaySearch * DisplaySearch
* apiForwardLogsToBackend * api
* apiOptionsGet
* dynamicLoader * dynamicLoader
*/ */
@ -35,7 +34,7 @@ async function injectSearchFrontend() {
} }
(async () => { (async () => {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
await yomichan.prepare(); await yomichan.prepare();
const displaySearch = new DisplaySearch(); const displaySearch = new DisplaySearch();
@ -45,7 +44,7 @@ async function injectSearchFrontend() {
const applyOptions = async () => { const applyOptions = async () => {
const optionsContext = {depth: 0, url: window.location.href}; const optionsContext = {depth: 0, url: window.location.href};
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
if (!options.scanning.enableOnSearchPage || optionsApplied) { return; } if (!options.scanning.enableOnSearchPage || optionsApplied) { return; }
optionsApplied = true; optionsApplied = true;

View File

@ -17,7 +17,7 @@
/* global /* global
* TemplateHandler * TemplateHandler
* apiGetQueryParserTemplatesHtml * api
*/ */
class QueryParserGenerator { class QueryParserGenerator {
@ -26,7 +26,7 @@ class QueryParserGenerator {
} }
async prepare() { async prepare() {
const html = await apiGetQueryParserTemplatesHtml(); const html = await api.getQueryParserTemplatesHtml();
this._templateHandler = new TemplateHandler(html); this._templateHandler = new TemplateHandler(html);
} }

View File

@ -18,9 +18,7 @@
/* global /* global
* QueryParserGenerator * QueryParserGenerator
* TextScanner * TextScanner
* apiModifySettings * api
* apiTermsFind
* apiTextParse
* docSentenceExtract * docSentenceExtract
*/ */
@ -59,7 +57,7 @@ class QueryParser {
this._setPreview(text); this._setPreview(text);
this._parseResults = await apiTextParse(text, this._getOptionsContext()); this._parseResults = await api.textParse(text, this._getOptionsContext());
this._refreshSelectedParser(); this._refreshSelectedParser();
this._renderParserSelect(); this._renderParserSelect();
@ -80,7 +78,7 @@ class QueryParser {
const searchText = this._textScanner.getTextSourceContent(textSource, this._options.scanning.length); const searchText = this._textScanner.getTextSourceContent(textSource, this._options.scanning.length);
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
const {definitions, length} = await apiTermsFind(searchText, {}, this._getOptionsContext()); const {definitions, length} = await api.termsFind(searchText, {}, this._getOptionsContext());
if (definitions.length === 0) { return null; } if (definitions.length === 0) { return null; }
const sentence = docSentenceExtract(textSource, this._options.anki.sentenceExt); const sentence = docSentenceExtract(textSource, this._options.anki.sentenceExt);
@ -99,7 +97,7 @@ class QueryParser {
_onParserChange(e) { _onParserChange(e) {
const value = e.target.value; const value = e.target.value;
apiModifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'parsing.selectedParser', path: 'parsing.selectedParser',
value, value,
@ -112,7 +110,7 @@ class QueryParser {
if (this._parseResults.length > 0) { if (this._parseResults.length > 0) {
if (!this._getParseResult()) { if (!this._getParseResult()) {
const value = this._parseResults[0].id; const value = this._parseResults[0].id;
apiModifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'parsing.selectedParser', path: 'parsing.selectedParser',
value, value,

View File

@ -20,9 +20,7 @@
* DOM * DOM
* Display * Display
* QueryParser * QueryParser
* apiClipboardGet * api
* apiModifySettings
* apiTermsFind
* wanakana * wanakana
*/ */
@ -52,7 +50,7 @@ class DisplaySearch extends Display {
this.introVisible = true; this.introVisible = true;
this.introAnimationTimer = null; this.introAnimationTimer = null;
this.clipboardMonitor = new ClipboardMonitor({getClipboard: apiClipboardGet}); this.clipboardMonitor = new ClipboardMonitor({getClipboard: api.clipboardGet.bind(api)});
this._onKeyDownIgnoreKeys = new Map([ this._onKeyDownIgnoreKeys = new Map([
['ANY_MOD', new Set([ ['ANY_MOD', new Set([
@ -234,7 +232,7 @@ class DisplaySearch extends Display {
this.setIntroVisible(!valid, animate); this.setIntroVisible(!valid, animate);
this.updateSearchButton(); this.updateSearchButton();
if (valid) { if (valid) {
const {definitions} = await apiTermsFind(query, details, this.getOptionsContext()); const {definitions} = await api.termsFind(query, details, this.getOptionsContext());
this.setContent('terms', {definitions, context: { this.setContent('terms', {definitions, context: {
focus: false, focus: false,
disableHistory: true, disableHistory: true,
@ -258,7 +256,7 @@ class DisplaySearch extends Display {
} else { } else {
wanakana.unbind(this.query); wanakana.unbind(this.query);
} }
apiModifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'general.enableWanakana', path: 'general.enableWanakana',
value, value,
@ -274,7 +272,7 @@ class DisplaySearch extends Display {
(granted) => { (granted) => {
if (granted) { if (granted) {
this.clipboardMonitor.start(); this.clipboardMonitor.start();
apiModifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'general.enableClipboardMonitor', path: 'general.enableClipboardMonitor',
value: true, value: true,
@ -288,7 +286,7 @@ class DisplaySearch extends Display {
); );
} else { } else {
this.clipboardMonitor.stop(); this.clipboardMonitor.stop();
apiModifySettings([{ api.modifySettings([{
action: 'set', action: 'set',
path: 'general.enableClipboardMonitor', path: 'general.enableClipboardMonitor',
value: false, value: false,

View File

@ -19,10 +19,7 @@
* AnkiNoteBuilder * AnkiNoteBuilder
* ankiGetFieldMarkers * ankiGetFieldMarkers
* ankiGetFieldMarkersHtml * ankiGetFieldMarkersHtml
* apiGetDefaultAnkiFieldTemplates * api
* apiOptionsGet
* apiTemplateRender
* apiTermsFind
* getOptionsContext * getOptionsContext
* getOptionsMutable * getOptionsMutable
* settingsSaveOptions * settingsSaveOptions
@ -38,7 +35,7 @@ async function onAnkiFieldTemplatesResetConfirm(e) {
$('#field-template-reset-modal').modal('hide'); $('#field-template-reset-modal').modal('hide');
const value = await apiGetDefaultAnkiFieldTemplates(); const value = await api.getDefaultAnkiFieldTemplates();
const element = document.querySelector('#field-templates'); const element = document.querySelector('#field-templates');
element.value = value; element.value = value;
@ -65,9 +62,9 @@ function ankiTemplatesInitialize() {
async function ankiTemplatesUpdateValue() { async function ankiTemplatesUpdateValue() {
const optionsContext = getOptionsContext(); const optionsContext = getOptionsContext();
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
let templates = options.anki.fieldTemplates; let templates = options.anki.fieldTemplates;
if (typeof templates !== 'string') { templates = await apiGetDefaultAnkiFieldTemplates(); } if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
$('#field-templates').val(templates); $('#field-templates').val(templates);
onAnkiTemplatesValidateCompile(); onAnkiTemplatesValidateCompile();
@ -79,7 +76,7 @@ const ankiTemplatesValidateGetDefinition = (() => {
return async (text, optionsContext) => { return async (text, optionsContext) => {
if (cachedText !== text) { if (cachedText !== text) {
const {definitions} = await apiTermsFind(text, {}, optionsContext); const {definitions} = await api.termsFind(text, {}, optionsContext);
if (definitions.length === 0) { return null; } if (definitions.length === 0) { return null; }
cachedValue = definitions[0]; cachedValue = definitions[0];
@ -97,15 +94,15 @@ async function ankiTemplatesValidate(infoNode, field, mode, showSuccessResult, i
const optionsContext = getOptionsContext(); const optionsContext = getOptionsContext();
const definition = await ankiTemplatesValidateGetDefinition(text, optionsContext); const definition = await ankiTemplatesValidateGetDefinition(text, optionsContext);
if (definition !== null) { if (definition !== null) {
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
const context = { const context = {
document: { document: {
title: document.title title: document.title
} }
}; };
let templates = options.anki.fieldTemplates; let templates = options.anki.fieldTemplates;
if (typeof templates !== 'string') { templates = await apiGetDefaultAnkiFieldTemplates(); } if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
const ankiNoteBuilder = new AnkiNoteBuilder({renderTemplate: apiTemplateRender}); const ankiNoteBuilder = new AnkiNoteBuilder({renderTemplate: api.templateRender.bind(api)});
result = await ankiNoteBuilder.formatField(field, definition, mode, context, options, templates, exceptions); result = await ankiNoteBuilder.formatField(field, definition, mode, context, options, templates, exceptions);
} }
} catch (e) { } catch (e) {
@ -125,7 +122,7 @@ async function ankiTemplatesValidate(infoNode, field, mode, showSuccessResult, i
async function onAnkiFieldTemplatesChanged(e) { async function onAnkiFieldTemplatesChanged(e) {
// Get value // Get value
let templates = e.currentTarget.value; let templates = e.currentTarget.value;
if (templates === await apiGetDefaultAnkiFieldTemplates()) { if (templates === await api.getDefaultAnkiFieldTemplates()) {
// Default // Default
templates = null; templates = null;
} }

View File

@ -16,9 +16,7 @@
*/ */
/* global /* global
* apiGetAnkiDeckNames * api
* apiGetAnkiModelFieldNames
* apiGetAnkiModelNames
* getOptionsContext * getOptionsContext
* getOptionsMutable * getOptionsMutable
* onFormOptionsChanged * onFormOptionsChanged
@ -107,7 +105,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([apiGetAnkiDeckNames(), apiGetAnkiModelNames()]); const [deckNames, modelNames] = await Promise.all([api.getAnkiDeckNames(), api.getAnkiModelNames()]);
deckNames.sort(); deckNames.sort();
modelNames.sort(); modelNames.sort();
termsDeck.values = deckNames; termsDeck.values = deckNames;
@ -180,7 +178,7 @@ async function _onAnkiModelChanged(e) {
let fieldNames; let fieldNames;
try { try {
const modelName = node.value; const modelName = node.value;
fieldNames = await apiGetAnkiModelFieldNames(modelName); fieldNames = await api.getAnkiModelFieldNames(modelName);
_ankiSetError(null); _ankiSetError(null);
} catch (error) { } catch (error) {
_ankiSetError(error); _ankiSetError(error);

View File

@ -16,9 +16,7 @@
*/ */
/* global /* global
* apiGetDefaultAnkiFieldTemplates * api
* apiGetEnvironmentInfo
* apiOptionsGetFull
* optionsGetDefault * optionsGetDefault
* optionsUpdateVersion * optionsUpdateVersion
* utilBackend * utilBackend
@ -51,9 +49,9 @@ function _getSettingsExportDateString(date, dateSeparator, dateTimeSeparator, ti
} }
async function _getSettingsExportData(date) { async function _getSettingsExportData(date) {
const optionsFull = await apiOptionsGetFull(); const optionsFull = await api.optionsGetFull();
const environment = await apiGetEnvironmentInfo(); const environment = await api.getEnvironmentInfo();
const fieldTemplatesDefault = await apiGetDefaultAnkiFieldTemplates(); const fieldTemplatesDefault = await api.getDefaultAnkiFieldTemplates();
// Format options // Format options
for (const {options} of optionsFull.profiles) { for (const {options} of optionsFull.profiles) {

View File

@ -17,13 +17,7 @@
/* global /* global
* PageExitPrevention * PageExitPrevention
* apiDeleteDictionary * api
* apiGetDictionaryCounts
* apiGetDictionaryInfo
* apiImportDictionaryArchive
* apiOptionsGet
* apiOptionsGetFull
* apiPurgeDatabase
* getOptionsContext * getOptionsContext
* getOptionsFullMutable * getOptionsFullMutable
* getOptionsMutable * getOptionsMutable
@ -312,7 +306,7 @@ class SettingsDictionaryEntryUI {
progressBar.style.width = `${percent}%`; progressBar.style.width = `${percent}%`;
}; };
await apiDeleteDictionary(this.dictionaryInfo.title, onProgress); await api.deleteDictionary(this.dictionaryInfo.title, onProgress);
} catch (e) { } catch (e) {
dictionaryErrorsShow([e]); dictionaryErrorsShow([e]);
} finally { } finally {
@ -423,7 +417,7 @@ async function onDictionaryOptionsChanged() {
dictionaryUI.setOptionsDictionaries(options.dictionaries); dictionaryUI.setOptionsDictionaries(options.dictionaries);
const optionsFull = await apiOptionsGetFull(); const optionsFull = await api.optionsGetFull();
document.querySelector('#database-enable-prefix-wildcard-searches').checked = optionsFull.global.database.prefixWildcardsSupported; document.querySelector('#database-enable-prefix-wildcard-searches').checked = optionsFull.global.database.prefixWildcardsSupported;
await updateMainDictionarySelectValue(); await updateMainDictionarySelectValue();
@ -431,7 +425,7 @@ async function onDictionaryOptionsChanged() {
async function onDatabaseUpdated() { async function onDatabaseUpdated() {
try { try {
const dictionaries = await apiGetDictionaryInfo(); const dictionaries = await api.getDictionaryInfo();
dictionaryUI.setDictionaries(dictionaries); dictionaryUI.setDictionaries(dictionaries);
document.querySelector('#dict-warning').hidden = (dictionaries.length > 0); document.querySelector('#dict-warning').hidden = (dictionaries.length > 0);
@ -439,7 +433,7 @@ async function onDatabaseUpdated() {
updateMainDictionarySelectOptions(dictionaries); updateMainDictionarySelectOptions(dictionaries);
await updateMainDictionarySelectValue(); await updateMainDictionarySelectValue();
const {counts, total} = await apiGetDictionaryCounts(dictionaries.map((v) => v.title), true); const {counts, total} = await api.getDictionaryCounts(dictionaries.map((v) => v.title), true);
dictionaryUI.setCounts(counts, total); dictionaryUI.setCounts(counts, total);
} catch (e) { } catch (e) {
dictionaryErrorsShow([e]); dictionaryErrorsShow([e]);
@ -468,7 +462,7 @@ function updateMainDictionarySelectOptions(dictionaries) {
async function updateMainDictionarySelectValue() { async function updateMainDictionarySelectValue() {
const optionsContext = getOptionsContext(); const optionsContext = getOptionsContext();
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
const value = options.general.mainDictionary; const value = options.general.mainDictionary;
@ -618,7 +612,7 @@ async function onDictionaryPurge(e) {
dictionaryErrorsShow(null); dictionaryErrorsShow(null);
dictionarySpinnerShow(true); dictionarySpinnerShow(true);
await apiPurgeDatabase(); await api.purgeDatabase();
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 = '';
@ -666,7 +660,7 @@ async function onDictionaryImport(e) {
} }
}; };
const optionsFull = await apiOptionsGetFull(); const optionsFull = await api.optionsGetFull();
const importDetails = { const importDetails = {
prefixWildcardsSupported: optionsFull.global.database.prefixWildcardsSupported prefixWildcardsSupported: optionsFull.global.database.prefixWildcardsSupported
@ -680,7 +674,7 @@ async function onDictionaryImport(e) {
} }
const archiveContent = await dictReadFile(files[i]); const archiveContent = await dictReadFile(files[i]);
const {result, errors} = await apiImportDictionaryArchive(archiveContent, importDetails, updateProgress); const {result, errors} = await api.importDictionaryArchive(archiveContent, importDetails, updateProgress);
for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) { for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) {
const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions(); const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions();
dictionaryOptions.enabled = true; dictionaryOptions.enabled = true;

View File

@ -21,9 +21,7 @@
* ankiInitialize * ankiInitialize
* ankiTemplatesInitialize * ankiTemplatesInitialize
* ankiTemplatesUpdateValue * ankiTemplatesUpdateValue
* apiForwardLogsToBackend * api
* apiGetEnvironmentInfo
* apiOptionsSave
* appearanceInitialize * appearanceInitialize
* audioSettingsInitialize * audioSettingsInitialize
* backupInitialize * backupInitialize
@ -265,7 +263,7 @@ function settingsGetSource() {
async function settingsSaveOptions() { async function settingsSaveOptions() {
const source = await settingsGetSource(); const source = await settingsGetSource();
await apiOptionsSave(source); await api.optionsSave(source);
} }
async function onOptionsUpdated({source}) { async function onOptionsUpdated({source}) {
@ -290,7 +288,7 @@ async function settingsPopulateModifierKeys() {
const scanModifierKeySelect = document.querySelector('#scan-modifier-key'); const scanModifierKeySelect = document.querySelector('#scan-modifier-key');
scanModifierKeySelect.textContent = ''; scanModifierKeySelect.textContent = '';
const environment = await apiGetEnvironmentInfo(); const environment = await api.getEnvironmentInfo();
const modifierKeys = [ const modifierKeys = [
{value: 'none', name: 'None'}, {value: 'none', name: 'None'},
...environment.modifiers.keys ...environment.modifiers.keys
@ -305,7 +303,7 @@ async function settingsPopulateModifierKeys() {
async function onReady() { async function onReady() {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
await yomichan.prepare(); await yomichan.prepare();
showExtensionInformation(); showExtensionInformation();

View File

@ -17,10 +17,10 @@
/* global /* global
* SettingsPopupPreview * SettingsPopupPreview
* apiForwardLogsToBackend * api
*/ */
(() => { (() => {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
new SettingsPopupPreview(); new SettingsPopupPreview();
})(); })();

View File

@ -20,14 +20,13 @@
* Popup * Popup
* PopupFactory * PopupFactory
* TextSourceRange * TextSourceRange
* apiFrameInformationGet * api
* apiOptionsGet
*/ */
class SettingsPopupPreview { class SettingsPopupPreview {
constructor() { constructor() {
this.frontend = null; this.frontend = null;
this.apiOptionsGetOld = apiOptionsGet; this.apiOptionsGetOld = api.optionsGet.bind(api);
this.popup = null; this.popup = null;
this.popupSetCustomOuterCssOld = null; this.popupSetCustomOuterCssOld = null;
this.popupShown = false; this.popupShown = false;
@ -54,10 +53,10 @@ class SettingsPopupPreview {
document.querySelector('#theme-dark-checkbox').addEventListener('change', this.onThemeDarkCheckboxChanged.bind(this), false); document.querySelector('#theme-dark-checkbox').addEventListener('change', this.onThemeDarkCheckboxChanged.bind(this), false);
// Overwrite API functions // Overwrite API functions
window.apiOptionsGet = this.apiOptionsGet.bind(this); api.optionsGet = this.apiOptionsGet.bind(this);
// Overwrite frontend // Overwrite frontend
const {frameId} = await apiFrameInformationGet(); const {frameId} = await api.frameInformationGet();
const popupFactory = new PopupFactory(frameId); const popupFactory = new PopupFactory(frameId);
await popupFactory.prepare(); await popupFactory.prepare();

View File

@ -17,7 +17,7 @@
/* global /* global
* ConditionsUI * ConditionsUI
* apiOptionsGetFull * api
* conditionsClearCaches * conditionsClearCaches
* formWrite * formWrite
* getOptionsFullMutable * getOptionsFullMutable
@ -215,7 +215,7 @@ async function onProfileRemove(e) {
return await onProfileRemoveConfirm(); return await onProfileRemoveConfirm();
} }
const optionsFull = await apiOptionsGetFull(); const optionsFull = await api.optionsGetFull();
if (optionsFull.profiles.length <= 1) { if (optionsFull.profiles.length <= 1) {
return; return;
} }
@ -278,7 +278,7 @@ async function onProfileMove(offset) {
} }
async function onProfileCopy() { async function onProfileCopy() {
const optionsFull = await apiOptionsGetFull(); const optionsFull = await api.optionsGetFull();
if (optionsFull.profiles.length <= 1) { if (optionsFull.profiles.length <= 1) {
return; return;
} }

View File

@ -16,7 +16,7 @@
*/ */
/* global /* global
* apiGetEnvironmentInfo * api
*/ */
function storageBytesToLabeledString(size) { function storageBytesToLabeledString(size) {
@ -52,7 +52,7 @@ async function isStoragePeristent() {
async function storageInfoInitialize() { async function storageInfoInitialize() {
storagePersistInitialize(); storagePersistInitialize();
const {browser, platform} = await apiGetEnvironmentInfo(); const {browser, platform} = await api.getEnvironmentInfo();
document.documentElement.dataset.browser = browser; document.documentElement.dataset.browser = browser;
document.documentElement.dataset.operatingSystem = platform.os; document.documentElement.dataset.operatingSystem = platform.os;

View File

@ -21,10 +21,7 @@
* Frontend * Frontend
* PopupFactory * PopupFactory
* PopupProxy * PopupProxy
* apiBroadcastTab * api
* apiForwardLogsToBackend
* apiFrameInformationGet
* apiOptionsGet
*/ */
async function createIframePopupProxy(frameOffsetForwarder, setDisabled) { async function createIframePopupProxy(frameOffsetForwarder, setDisabled) {
@ -36,7 +33,7 @@ async function createIframePopupProxy(frameOffsetForwarder, setDisabled) {
} }
} }
); );
apiBroadcastTab('rootPopupRequestInformationBroadcast'); api.broadcastTab('rootPopupRequestInformationBroadcast');
const {popupId, frameId: parentFrameId} = await rootPopupInformationPromise; const {popupId, frameId: parentFrameId} = await rootPopupInformationPromise;
const getFrameOffset = frameOffsetForwarder.getOffset.bind(frameOffsetForwarder); const getFrameOffset = frameOffsetForwarder.getOffset.bind(frameOffsetForwarder);
@ -48,7 +45,7 @@ async function createIframePopupProxy(frameOffsetForwarder, setDisabled) {
} }
async function getOrCreatePopup(depth) { async function getOrCreatePopup(depth) {
const {frameId} = await apiFrameInformationGet(); const {frameId} = await api.frameInformationGet();
if (typeof frameId !== 'number') { if (typeof frameId !== 'number') {
const error = new Error('Failed to get frameId'); const error = new Error('Failed to get frameId');
yomichan.logError(error); yomichan.logError(error);
@ -71,7 +68,7 @@ async function createPopupProxy(depth, id, parentFrameId) {
} }
(async () => { (async () => {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
await yomichan.prepare(); await yomichan.prepare();
const data = window.frontendInitializationData || {}; const data = window.frontendInitializationData || {};
@ -112,7 +109,7 @@ async function createPopupProxy(depth, id, parentFrameId) {
depth: isSearchPage ? 0 : depth, depth: isSearchPage ? 0 : depth,
url: proxy ? await getPopupProxyUrl() : window.location.href url: proxy ? await getPopupProxyUrl() : window.location.href
}; };
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
if (!proxy && frameOffsetForwarder === null) { if (!proxy && frameOffsetForwarder === null) {
frameOffsetForwarder = new FrameOffsetForwarder(); frameOffsetForwarder = new FrameOffsetForwarder();

View File

@ -17,8 +17,7 @@
/* global /* global
* DisplayFloat * DisplayFloat
* apiForwardLogsToBackend * api
* apiOptionsGet
* dynamicLoader * dynamicLoader
*/ */
@ -38,7 +37,7 @@ async function popupNestedInitialize(id, depth, parentFrameId, url) {
const applyOptions = async () => { const applyOptions = async () => {
const optionsContext = {depth, url}; const optionsContext = {depth, url};
const options = await apiOptionsGet(optionsContext); const options = await api.optionsGet(optionsContext);
const maxPopupDepthExceeded = !(typeof depth === 'number' && depth < options.scanning.popupNestingMaxDepth); const maxPopupDepthExceeded = !(typeof depth === 'number' && depth < options.scanning.popupNestingMaxDepth);
if (maxPopupDepthExceeded || optionsApplied) { return; } if (maxPopupDepthExceeded || optionsApplied) { return; }
@ -55,7 +54,7 @@ async function popupNestedInitialize(id, depth, parentFrameId, url) {
} }
(async () => { (async () => {
apiForwardLogsToBackend(); api.forwardLogsToBackend();
const display = new DisplayFloat(); const display = new DisplayFloat();
await display.prepare(); await display.prepare();
})(); })();

View File

@ -17,8 +17,7 @@
/* global /* global
* Display * Display
* apiBroadcastTab * api
* apiSendMessageToFrame
* popupNestedInitialize * popupNestedInitialize
*/ */
@ -61,7 +60,7 @@ class DisplayFloat extends Display {
yomichan.on('orphaned', this.onOrphaned.bind(this)); yomichan.on('orphaned', this.onOrphaned.bind(this));
window.addEventListener('message', this.onMessage.bind(this), false); window.addEventListener('message', this.onMessage.bind(this), false);
apiBroadcastTab('popupPrepared', {secret: this._secret}); api.broadcastTab('popupPrepared', {secret: this._secret});
} }
onError(error) { onError(error) {
@ -153,7 +152,7 @@ class DisplayFloat extends Display {
}, },
2000 2000
); );
apiBroadcastTab('requestDocumentInformationBroadcast', {uniqueId}); api.broadcastTab('requestDocumentInformationBroadcast', {uniqueId});
const {title} = await promise; const {title} = await promise;
return title; return title;
@ -176,7 +175,7 @@ class DisplayFloat extends Display {
const {token, frameId} = params; const {token, frameId} = params;
this._token = token; this._token = token;
apiSendMessageToFrame(frameId, 'popupInitialized', {secret, token}); api.sendMessageToFrame(frameId, 'popupInitialized', {secret, token});
} }
async _configure({messageId, frameId, popupId, optionsContext, childrenSupported, scale}) { async _configure({messageId, frameId, popupId, optionsContext, childrenSupported, scale}) {
@ -192,7 +191,7 @@ class DisplayFloat extends Display {
this.setContentScale(scale); this.setContentScale(scale);
apiSendMessageToFrame(frameId, 'popupConfigured', {messageId}); api.sendMessageToFrame(frameId, 'popupConfigured', {messageId});
} }
_isMessageAuthenticated(message) { _isMessageAuthenticated(message) {

View File

@ -16,7 +16,7 @@
*/ */
/* global /* global
* apiBroadcastTab * api
*/ */
class FrameOffsetForwarder { class FrameOffsetForwarder {
@ -161,6 +161,6 @@ class FrameOffsetForwarder {
} }
_forwardFrameOffsetOrigin(offset, uniqueId) { _forwardFrameOffsetOrigin(offset, uniqueId) {
apiBroadcastTab('frameOffset', {offset, uniqueId}); api.broadcastTab('frameOffset', {offset, uniqueId});
} }
} }

View File

@ -17,11 +17,7 @@
/* global /* global
* TextScanner * TextScanner
* apiBroadcastTab * api
* apiGetZoom
* apiKanjiFind
* apiOptionsGet
* apiTermsFind
* docSentenceExtract * docSentenceExtract
*/ */
@ -69,7 +65,7 @@ class Frontend {
async prepare() { async prepare() {
try { try {
await this.updateOptions(); await this.updateOptions();
const {zoomFactor} = await apiGetZoom(); const {zoomFactor} = await api.getZoom();
this._pageZoomFactor = zoomFactor; this._pageZoomFactor = zoomFactor;
window.addEventListener('resize', this._onResize.bind(this), false); window.addEventListener('resize', this._onResize.bind(this), false);
@ -120,7 +116,7 @@ class Frontend {
async updateOptions() { async updateOptions() {
const optionsContext = await this.getOptionsContext(); const optionsContext = await this.getOptionsContext();
this._options = await apiOptionsGet(optionsContext); this._options = await api.optionsGet(optionsContext);
this._textScanner.setOptions(this._options); this._textScanner.setOptions(this._options);
this._updateTextScannerEnabled(); this._updateTextScannerEnabled();
@ -261,7 +257,7 @@ class Frontend {
const searchText = this._textScanner.getTextSourceContent(textSource, this._options.scanning.length); const searchText = this._textScanner.getTextSourceContent(textSource, this._options.scanning.length);
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
const {definitions, length} = await apiTermsFind(searchText, {}, optionsContext); const {definitions, length} = await api.termsFind(searchText, {}, optionsContext);
if (definitions.length === 0) { return null; } if (definitions.length === 0) { return null; }
textSource.setEndOffset(length); textSource.setEndOffset(length);
@ -273,7 +269,7 @@ class Frontend {
const searchText = this._textScanner.getTextSourceContent(textSource, 1); const searchText = this._textScanner.getTextSourceContent(textSource, 1);
if (searchText.length === 0) { return null; } if (searchText.length === 0) { return null; }
const definitions = await apiKanjiFind(searchText, optionsContext); const definitions = await api.kanjiFind(searchText, optionsContext);
if (definitions.length === 0) { return null; } if (definitions.length === 0) { return null; }
textSource.setEndOffset(1); textSource.setEndOffset(1);
@ -351,12 +347,12 @@ class Frontend {
_broadcastRootPopupInformation() { _broadcastRootPopupInformation() {
if (!this._popup.isProxy() && this._popup.depth === 0 && this._popup.frameId === 0) { if (!this._popup.isProxy() && this._popup.depth === 0 && this._popup.frameId === 0) {
apiBroadcastTab('rootPopupInformation', {popupId: this._popup.id, frameId: this._popup.frameId}); api.broadcastTab('rootPopupInformation', {popupId: this._popup.id, frameId: this._popup.frameId});
} }
} }
_broadcastDocumentInformation(uniqueId) { _broadcastDocumentInformation(uniqueId) {
apiBroadcastTab('documentInformationBroadcast', { api.broadcastTab('documentInformationBroadcast', {
uniqueId, uniqueId,
frameId: this._popup.frameId, frameId: this._popup.frameId,
title: document.title title: document.title

View File

@ -17,7 +17,7 @@
/* global /* global
* DOM * DOM
* apiOptionsGet * api
* dynamicLoader * dynamicLoader
*/ */
@ -89,7 +89,7 @@ class Popup {
this._optionsContext = optionsContext; this._optionsContext = optionsContext;
this._previousOptionsContextSource = source; this._previousOptionsContextSource = source;
this._options = await apiOptionsGet(optionsContext); this._options = await api.optionsGet(optionsContext);
this.updateTheme(); this.updateTheme();
this._invokeApi('setOptionsContext', {optionsContext}); this._invokeApi('setOptionsContext', {optionsContext});

View File

@ -15,307 +15,321 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
const api = (() => {
function apiOptionsSchemaGet() { class API {
return _apiInvoke('optionsSchemaGet'); constructor() {
} this._forwardLogsToBackendEnabled = false;
function apiOptionsGet(optionsContext) {
return _apiInvoke('optionsGet', {optionsContext});
}
function apiOptionsGetFull() {
return _apiInvoke('optionsGetFull');
}
function apiOptionsSave(source) {
return _apiInvoke('optionsSave', {source});
}
function apiTermsFind(text, details, optionsContext) {
return _apiInvoke('termsFind', {text, details, optionsContext});
}
function apiTextParse(text, optionsContext) {
return _apiInvoke('textParse', {text, optionsContext});
}
function apiKanjiFind(text, optionsContext) {
return _apiInvoke('kanjiFind', {text, optionsContext});
}
function apiDefinitionAdd(definition, mode, context, details, optionsContext) {
return _apiInvoke('definitionAdd', {definition, mode, context, details, optionsContext});
}
function apiDefinitionsAddable(definitions, modes, context, optionsContext) {
return _apiInvoke('definitionsAddable', {definitions, modes, context, optionsContext});
}
function apiNoteView(noteId) {
return _apiInvoke('noteView', {noteId});
}
function apiTemplateRender(template, data) {
return _apiInvoke('templateRender', {data, template});
}
function apiAudioGetUri(definition, source, details) {
return _apiInvoke('audioGetUri', {definition, source, details});
}
function apiCommandExec(command, params) {
return _apiInvoke('commandExec', {command, params});
}
function apiScreenshotGet(options) {
return _apiInvoke('screenshotGet', {options});
}
function apiSendMessageToFrame(frameId, action, params) {
return _apiInvoke('sendMessageToFrame', {frameId, action, params});
}
function apiBroadcastTab(action, params) {
return _apiInvoke('broadcastTab', {action, params});
}
function apiFrameInformationGet() {
return _apiInvoke('frameInformationGet');
}
function apiInjectStylesheet(type, value) {
return _apiInvoke('injectStylesheet', {type, value});
}
function apiGetEnvironmentInfo() {
return _apiInvoke('getEnvironmentInfo');
}
function apiClipboardGet() {
return _apiInvoke('clipboardGet');
}
function apiGetDisplayTemplatesHtml() {
return _apiInvoke('getDisplayTemplatesHtml');
}
function apiGetQueryParserTemplatesHtml() {
return _apiInvoke('getQueryParserTemplatesHtml');
}
function apiGetZoom() {
return _apiInvoke('getZoom');
}
function apiGetDefaultAnkiFieldTemplates() {
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 apiGetMedia(targets) {
return _apiInvoke('getMedia', {targets});
}
function apiLog(error, level, context) {
return _apiInvoke('log', {error, level, context});
}
function apiLogIndicatorClear() {
return _apiInvoke('logIndicatorClear');
}
function apiImportDictionaryArchive(archiveContent, details, onProgress) {
return _apiInvokeWithProgress('importDictionaryArchive', {archiveContent, details}, onProgress);
}
function apiDeleteDictionary(dictionaryName, onProgress) {
return _apiInvokeWithProgress('deleteDictionary', {dictionaryName}, onProgress);
}
function apiModifySettings(targets, source) {
return _apiInvoke('modifySettings', {targets, source});
}
function _apiCreateActionPort(timeout=5000) {
return new Promise((resolve, reject) => {
let timer = null;
let portNameResolve;
let portNameReject;
const portNamePromise = new Promise((resolve2, reject2) => {
portNameResolve = resolve2;
portNameReject = reject2;
});
const onConnect = async (port) => {
try {
const portName = await portNamePromise;
if (port.name !== portName || timer === null) { return; }
} catch (e) {
return;
}
clearTimeout(timer);
timer = null;
chrome.runtime.onConnect.removeListener(onConnect);
resolve(port);
};
const onError = (e) => {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
chrome.runtime.onConnect.removeListener(onConnect);
portNameReject(e);
reject(e);
};
timer = setTimeout(() => onError(new Error('Timeout')), timeout);
chrome.runtime.onConnect.addListener(onConnect);
_apiInvoke('createActionPort').then(portNameResolve, onError);
});
}
function _apiInvokeWithProgress(action, params, onProgress, timeout=5000) {
return new Promise((resolve, reject) => {
let timer = null;
let port = null;
if (typeof onProgress !== 'function') {
onProgress = () => {};
} }
const onMessage = (message) => { forwardLogsToBackend() {
switch (message.type) { if (this._forwardLogsToBackendEnabled) { return; }
case 'ack': this._forwardLogsToBackendEnabled = true;
yomichan.on('log', async ({error, level, context}) => {
try {
await this.log(errorToJson(error), level, context);
} catch (e) {
// NOP
}
});
}
// Invoke functions
optionsSchemaGet() {
return this._invoke('optionsSchemaGet');
}
optionsGet(optionsContext) {
return this._invoke('optionsGet', {optionsContext});
}
optionsGetFull() {
return this._invoke('optionsGetFull');
}
optionsSave(source) {
return this._invoke('optionsSave', {source});
}
termsFind(text, details, optionsContext) {
return this._invoke('termsFind', {text, details, optionsContext});
}
textParse(text, optionsContext) {
return this._invoke('textParse', {text, optionsContext});
}
kanjiFind(text, optionsContext) {
return this._invoke('kanjiFind', {text, optionsContext});
}
definitionAdd(definition, mode, context, details, optionsContext) {
return this._invoke('definitionAdd', {definition, mode, context, details, optionsContext});
}
definitionsAddable(definitions, modes, context, optionsContext) {
return this._invoke('definitionsAddable', {definitions, modes, context, optionsContext});
}
noteView(noteId) {
return this._invoke('noteView', {noteId});
}
templateRender(template, data) {
return this._invoke('templateRender', {data, template});
}
audioGetUri(definition, source, details) {
return this._invoke('audioGetUri', {definition, source, details});
}
commandExec(command, params) {
return this._invoke('commandExec', {command, params});
}
screenshotGet(options) {
return this._invoke('screenshotGet', {options});
}
sendMessageToFrame(frameId, action, params) {
return this._invoke('sendMessageToFrame', {frameId, action, params});
}
broadcastTab(action, params) {
return this._invoke('broadcastTab', {action, params});
}
frameInformationGet() {
return this._invoke('frameInformationGet');
}
injectStylesheet(type, value) {
return this._invoke('injectStylesheet', {type, value});
}
getEnvironmentInfo() {
return this._invoke('getEnvironmentInfo');
}
clipboardGet() {
return this._invoke('clipboardGet');
}
getDisplayTemplatesHtml() {
return this._invoke('getDisplayTemplatesHtml');
}
getQueryParserTemplatesHtml() {
return this._invoke('getQueryParserTemplatesHtml');
}
getZoom() {
return this._invoke('getZoom');
}
getDefaultAnkiFieldTemplates() {
return this._invoke('getDefaultAnkiFieldTemplates');
}
getAnkiDeckNames() {
return this._invoke('getAnkiDeckNames');
}
getAnkiModelNames() {
return this._invoke('getAnkiModelNames');
}
getAnkiModelFieldNames(modelName) {
return this._invoke('getAnkiModelFieldNames', {modelName});
}
getDictionaryInfo() {
return this._invoke('getDictionaryInfo');
}
getDictionaryCounts(dictionaryNames, getTotal) {
return this._invoke('getDictionaryCounts', {dictionaryNames, getTotal});
}
purgeDatabase() {
return this._invoke('purgeDatabase');
}
getMedia(targets) {
return this._invoke('getMedia', {targets});
}
log(error, level, context) {
return this._invoke('log', {error, level, context});
}
logIndicatorClear() {
return this._invoke('logIndicatorClear');
}
modifySettings(targets, source) {
return this._invoke('modifySettings', {targets, source});
}
// Invoke functions with progress
importDictionaryArchive(archiveContent, details, onProgress) {
return this._invokeWithProgress('importDictionaryArchive', {archiveContent, details}, onProgress);
}
deleteDictionary(dictionaryName, onProgress) {
return this._invokeWithProgress('deleteDictionary', {dictionaryName}, onProgress);
}
// Utilities
_createActionPort(timeout=5000) {
return new Promise((resolve, reject) => {
let timer = null;
let portNameResolve;
let portNameReject;
const portNamePromise = new Promise((resolve2, reject2) => {
portNameResolve = resolve2;
portNameReject = reject2;
});
const onConnect = async (port) => {
try {
const portName = await portNamePromise;
if (port.name !== portName || timer === null) { return; }
} catch (e) {
return;
}
clearTimeout(timer);
timer = null;
chrome.runtime.onConnect.removeListener(onConnect);
resolve(port);
};
const onError = (e) => {
if (timer !== null) { if (timer !== null) {
clearTimeout(timer); clearTimeout(timer);
timer = null; timer = null;
} }
break; chrome.runtime.onConnect.removeListener(onConnect);
case 'progress': portNameReject(e);
reject(e);
};
timer = setTimeout(() => onError(new Error('Timeout')), timeout);
chrome.runtime.onConnect.addListener(onConnect);
this._invoke('createActionPort').then(portNameResolve, onError);
});
}
_invokeWithProgress(action, params, onProgress, timeout=5000) {
return new Promise((resolve, reject) => {
let timer = null;
let port = null;
if (typeof onProgress !== 'function') {
onProgress = () => {};
}
const onMessage = (message) => {
switch (message.type) {
case 'ack':
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
break;
case 'progress':
try {
onProgress(...message.data);
} catch (e) {
// NOP
}
break;
case 'complete':
cleanup();
resolve(message.data);
break;
case 'error':
cleanup();
reject(jsonToError(message.data));
break;
}
};
const onDisconnect = () => {
cleanup();
reject(new Error('Disconnected'));
};
const cleanup = () => {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
if (port !== null) {
port.onMessage.removeListener(onMessage);
port.onDisconnect.removeListener(onDisconnect);
port.disconnect();
port = null;
}
onProgress = null;
};
timer = setTimeout(() => {
cleanup();
reject(new Error('Timeout'));
}, timeout);
(async () => {
try { try {
onProgress(...message.data); port = await this._createActionPort(timeout);
port.onMessage.addListener(onMessage);
port.onDisconnect.addListener(onDisconnect);
port.postMessage({action, params});
} catch (e) { } catch (e) {
// NOP cleanup();
reject(e);
} finally {
action = null;
params = null;
} }
break; })();
case 'complete': });
cleanup(); }
resolve(message.data);
break;
case 'error':
cleanup();
reject(jsonToError(message.data));
break;
}
};
const onDisconnect = () => { _invoke(action, params={}) {
cleanup(); const data = {action, params};
reject(new Error('Disconnected')); return new Promise((resolve, reject) => {
}; try {
chrome.runtime.sendMessage(data, (response) => {
const cleanup = () => { this._checkLastError(chrome.runtime.lastError);
if (timer !== null) { if (response !== null && typeof response === 'object') {
clearTimeout(timer); if (typeof response.error !== 'undefined') {
timer = null; reject(jsonToError(response.error));
} } else {
if (port !== null) { resolve(response.result);
port.onMessage.removeListener(onMessage); }
port.onDisconnect.removeListener(onDisconnect); } else {
port.disconnect(); const message = response === null ? 'Unexpected null response' : `Unexpected response of type ${typeof response}`;
port = null; reject(new Error(`${message} (${JSON.stringify(data)})`));
} }
onProgress = null; });
}; } catch (e) {
reject(e);
timer = setTimeout(() => { yomichan.triggerOrphaned(e);
cleanup();
reject(new Error('Timeout'));
}, timeout);
(async () => {
try {
port = await _apiCreateActionPort(timeout);
port.onMessage.addListener(onMessage);
port.onDisconnect.addListener(onDisconnect);
port.postMessage({action, params});
} catch (e) {
cleanup();
reject(e);
} finally {
action = null;
params = null;
}
})();
});
}
function _apiInvoke(action, params={}) {
const data = {action, params};
return new Promise((resolve, reject) => {
try {
chrome.runtime.sendMessage(data, (response) => {
_apiCheckLastError(chrome.runtime.lastError);
if (response !== null && typeof response === 'object') {
if (typeof response.error !== 'undefined') {
reject(jsonToError(response.error));
} else {
resolve(response.result);
}
} else {
const message = response === null ? 'Unexpected null response' : `Unexpected response of type ${typeof response}`;
reject(new Error(`${message} (${JSON.stringify(data)})`));
} }
}); });
} catch (e) {
reject(e);
yomichan.triggerOrphaned(e);
} }
});
}
function _apiCheckLastError() { _checkLastError() {
// NOP
}
let _apiForwardLogsToBackendEnabled = false;
function apiForwardLogsToBackend() {
if (_apiForwardLogsToBackendEnabled) { return; }
_apiForwardLogsToBackendEnabled = true;
yomichan.on('log', async ({error, level, context}) => {
try {
await apiLog(errorToJson(error), level, context);
} catch (e) {
// NOP // NOP
} }
}); }
}
return new API();
})();

View File

@ -17,7 +17,7 @@
/* global /* global
* TemplateHandler * TemplateHandler
* apiGetDisplayTemplatesHtml * api
* jp * jp
*/ */
@ -29,7 +29,7 @@ class DisplayGenerator {
} }
async prepare() { async prepare() {
const html = await apiGetDisplayTemplatesHtml(); const html = await api.getDisplayTemplatesHtml();
this._templateHandler = new TemplateHandler(html); this._templateHandler = new TemplateHandler(html);
} }

View File

@ -22,15 +22,7 @@
* DisplayGenerator * DisplayGenerator
* MediaLoader * MediaLoader
* WindowScroll * WindowScroll
* apiAudioGetUri * api
* apiBroadcastTab
* apiDefinitionAdd
* apiDefinitionsAddable
* apiKanjiFind
* apiNoteView
* apiOptionsGet
* apiScreenshotGet
* apiTermsFind
* docRangeFromPoint * docRangeFromPoint
* docSentenceExtract * docSentenceExtract
*/ */
@ -49,7 +41,7 @@ class Display {
this.audioSystem = new AudioSystem({ this.audioSystem = new AudioSystem({
audioUriBuilder: { audioUriBuilder: {
getUri: async (definition, source, details) => { getUri: async (definition, source, details) => {
return await apiAudioGetUri(definition, source, details); return await api.audioGetUri(definition, source, details);
} }
}, },
useCache: true useCache: true
@ -212,7 +204,7 @@ class Display {
url: this.context.get('url') url: this.context.get('url')
}; };
const definitions = await apiKanjiFind(link.textContent, this.getOptionsContext()); const definitions = await api.kanjiFind(link.textContent, this.getOptionsContext());
this.setContent('kanji', {definitions, context}); this.setContent('kanji', {definitions, context});
} catch (error) { } catch (error) {
this.onError(error); this.onError(error);
@ -290,7 +282,7 @@ class Display {
try { try {
textSource.setEndOffset(this.options.scanning.length); textSource.setEndOffset(this.options.scanning.length);
({definitions, length} = await apiTermsFind(textSource.text(), {}, this.getOptionsContext())); ({definitions, length} = await api.termsFind(textSource.text(), {}, this.getOptionsContext()));
if (definitions.length === 0) { if (definitions.length === 0) {
return false; return false;
} }
@ -334,7 +326,7 @@ class Display {
onNoteView(e) { onNoteView(e) {
e.preventDefault(); e.preventDefault();
const link = e.currentTarget; const link = e.currentTarget;
apiNoteView(link.dataset.noteId); api.noteView(link.dataset.noteId);
} }
onKeyDown(e) { onKeyDown(e) {
@ -379,7 +371,7 @@ class Display {
} }
async updateOptions() { async updateOptions() {
this.options = await apiOptionsGet(this.getOptionsContext()); this.options = await api.optionsGet(this.getOptionsContext());
this.updateDocumentOptions(this.options); this.updateDocumentOptions(this.options);
this.updateTheme(this.options.general.popupTheme); this.updateTheme(this.options.general.popupTheme);
this.setCustomCss(this.options.general.customPopupCss); this.setCustomCss(this.options.general.customPopupCss);
@ -746,7 +738,7 @@ class Display {
noteTryView() { noteTryView() {
const button = this.viewerButtonFind(this.index); const button = this.viewerButtonFind(this.index);
if (button !== null && !button.classList.contains('disabled')) { if (button !== null && !button.classList.contains('disabled')) {
apiNoteView(button.dataset.noteId); api.noteView(button.dataset.noteId);
} }
} }
@ -763,7 +755,7 @@ class Display {
} }
const context = await this._getNoteContext(); const context = await this._getNoteContext();
const noteId = await apiDefinitionAdd(definition, mode, context, details, this.getOptionsContext()); const noteId = await api.definitionAdd(definition, mode, context, details, this.getOptionsContext());
if (noteId) { if (noteId) {
const index = this.definitions.indexOf(definition); const index = this.definitions.indexOf(definition);
const adderButton = this.adderButtonFind(index, mode); const adderButton = this.adderButtonFind(index, mode);
@ -857,7 +849,7 @@ class Display {
await promiseTimeout(1); // Wait for popup to be hidden. await promiseTimeout(1); // Wait for popup to be hidden.
const {format, quality} = this.options.anki.screenshot; const {format, quality} = this.options.anki.screenshot;
const dataUrl = await apiScreenshotGet({format, quality}); const dataUrl = await api.screenshotGet({format, quality});
if (!dataUrl || dataUrl.error) { return; } if (!dataUrl || dataUrl.error) { return; }
return {dataUrl, format}; return {dataUrl, format};
@ -871,7 +863,7 @@ class Display {
} }
setPopupVisibleOverride(visible) { setPopupVisibleOverride(visible) {
return apiBroadcastTab('popupSetVisibleOverride', {visible}); return api.broadcastTab('popupSetVisibleOverride', {visible});
} }
setSpinnerVisible(visible) { setSpinnerVisible(visible) {
@ -933,7 +925,7 @@ class Display {
async getDefinitionsAddable(definitions, modes) { async getDefinitionsAddable(definitions, modes) {
try { try {
const context = await this._getNoteContext(); const context = await this._getNoteContext();
return await apiDefinitionsAddable(definitions, modes, context, this.getOptionsContext()); return await api.definitionsAddable(definitions, modes, context, this.getOptionsContext());
} catch (e) { } catch (e) {
return []; return [];
} }

View File

@ -16,7 +16,7 @@
*/ */
/* global /* global
* apiInjectStylesheet * api
*/ */
const dynamicLoader = (() => { const dynamicLoader = (() => {
@ -45,7 +45,7 @@ const dynamicLoader = (() => {
} }
injectedStylesheets.set(id, null); injectedStylesheets.set(id, null);
await apiInjectStylesheet(type, value); await api.injectStylesheet(type, value);
return null; return null;
} }

View File

@ -16,7 +16,7 @@
*/ */
/* global /* global
* apiGetMedia * api
*/ */
class MediaLoader { class MediaLoader {
@ -84,7 +84,7 @@ class MediaLoader {
async _getMediaData(path, dictionaryName, cachedData) { async _getMediaData(path, dictionaryName, cachedData) {
const token = this._token; const token = this._token;
const data = (await apiGetMedia([{path, dictionaryName}]))[0]; const data = (await api.getMedia([{path, dictionaryName}]))[0];
if (token === this._token && data !== null) { if (token === this._token && data !== null) {
const contentArrayBuffer = this._base64ToArrayBuffer(data.content); const contentArrayBuffer = this._base64ToArrayBuffer(data.content);
const blob = new Blob([contentArrayBuffer], {type: data.mediaType}); const blob = new Blob([contentArrayBuffer], {type: data.mediaType});