diff options
Diffstat (limited to 'ext/mixed/js/api.js')
-rw-r--r-- | ext/mixed/js/api.js | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js deleted file mode 100644 index d37b091a..00000000 --- a/ext/mixed/js/api.js +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2016-2021 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -/* global - * CrossFrameAPI - */ - -const api = (() => { - class API { - constructor() { - this._forwardLogsToBackendEnabled = false; - this._crossFrame = new CrossFrameAPI(); - } - - get crossFrame() { - return this._crossFrame; - } - - prepare() { - this._crossFrame.prepare(); - } - - forwardLogsToBackend() { - if (this._forwardLogsToBackendEnabled) { return; } - this._forwardLogsToBackendEnabled = true; - - yomichan.on('log', async ({error, level, context}) => { - try { - await this.log(serializeError(error), level, context); - } catch (e) { - // NOP - } - }); - } - - // Invoke functions - - optionsGet(optionsContext) { - return this._invoke('optionsGet', {optionsContext}); - } - - optionsGetFull() { - return this._invoke('optionsGetFull'); - } - - 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}); - } - - isAnkiConnected() { - return this._invoke('isAnkiConnected'); - } - - getAnkiConnectVersion() { - return this._invoke('getAnkiConnectVersion'); - } - - addAnkiNote(note) { - return this._invoke('addAnkiNote', {note}); - } - - getAnkiNoteInfo(notes) { - return this._invoke('getAnkiNoteInfo', {notes}); - } - - injectAnkiNoteMedia(timestamp, definitionDetails, audioDetails, screenshotDetails, clipboardDetails) { - return this._invoke('injectAnkiNoteMedia', {timestamp, definitionDetails, audioDetails, screenshotDetails, clipboardDetails}); - } - - noteView(noteId) { - return this._invoke('noteView', {noteId}); - } - - suspendAnkiCardsForNote(noteId) { - return this._invoke('suspendAnkiCardsForNote', {noteId}); - } - - getExpressionAudioInfoList(source, expression, reading, details) { - return this._invoke('getExpressionAudioInfoList', {source, expression, reading, details}); - } - - commandExec(command, params) { - return this._invoke('commandExec', {command, params}); - } - - 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}); - } - - getStylesheetContent(url) { - return this._invoke('getStylesheetContent', {url}); - } - - getEnvironmentInfo() { - return this._invoke('getEnvironmentInfo'); - } - - clipboardGet() { - return this._invoke('clipboardGet'); - } - - getDisplayTemplatesHtml() { - return this._invoke('getDisplayTemplatesHtml'); - } - - getZoom() { - return this._invoke('getZoom'); - } - - getDefaultAnkiFieldTemplates() { - return this._invoke('getDefaultAnkiFieldTemplates'); - } - - 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}); - } - - getSettings(targets) { - return this._invoke('getSettings', {targets}); - } - - setAllSettings(value, source) { - return this._invoke('setAllSettings', {value, source}); - } - - getOrCreateSearchPopup(details) { - return this._invoke('getOrCreateSearchPopup', isObject(details) ? details : {}); - } - - isTabSearchPopup(tabId) { - return this._invoke('isTabSearchPopup', {tabId}); - } - - triggerDatabaseUpdated(type, cause) { - return this._invoke('triggerDatabaseUpdated', {type, cause}); - } - - testMecab() { - return this._invoke('testMecab', {}); - } - - // Utilities - - _createActionPort(timeout=5000) { - return new Promise((resolve, reject) => { - let timer = null; - const portDetails = deferPromise(); - - const onConnect = async (port) => { - try { - const {name: expectedName, id: expectedId} = await portDetails.promise; - const {name, id} = JSON.parse(port.name); - if (name !== expectedName || id !== expectedId || 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); - portDetails.reject(e); - reject(e); - }; - - timer = setTimeout(() => onError(new Error('Timeout')), timeout); - - chrome.runtime.onConnect.addListener(onConnect); - this._invoke('createActionPort').then(portDetails.resolve, onError); - }); - } - - _invokeWithProgress(action, params, onProgress, timeout=5000) { - return new Promise((resolve, reject) => { - let port = null; - - if (typeof onProgress !== 'function') { - onProgress = () => {}; - } - - const onMessage = (message) => { - switch (message.type) { - case 'progress': - try { - onProgress(...message.data); - } catch (e) { - // NOP - } - break; - case 'complete': - cleanup(); - resolve(message.data); - break; - case 'error': - cleanup(); - reject(deserializeError(message.data)); - break; - } - }; - - const onDisconnect = () => { - cleanup(); - reject(new Error('Disconnected')); - }; - - const cleanup = () => { - if (port !== null) { - port.onMessage.removeListener(onMessage); - port.onDisconnect.removeListener(onDisconnect); - port.disconnect(); - port = null; - } - onProgress = null; - }; - - (async () => { - try { - port = await this._createActionPort(timeout); - port.onMessage.addListener(onMessage); - port.onDisconnect.addListener(onDisconnect); - - // Chrome has a maximum message size that can be sent, so longer messages must be fragmented. - const messageString = JSON.stringify({action, params}); - const fragmentSize = 1e7; // 10 MB - for (let i = 0, ii = messageString.length; i < ii; i += fragmentSize) { - const data = messageString.substring(i, i + fragmentSize); - port.postMessage({action: 'fragment', data}); - } - port.postMessage({action: 'invoke'}); - } catch (e) { - cleanup(); - reject(e); - } finally { - action = null; - params = null; - } - })(); - }); - } - - _invoke(action, params={}) { - const data = {action, params}; - return new Promise((resolve, reject) => { - try { - yomichan.sendMessage(data, (response) => { - this._checkLastError(chrome.runtime.lastError); - if (response !== null && typeof response === 'object') { - if (typeof response.error !== 'undefined') { - reject(deserializeError(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); - } - }); - } - - _checkLastError() { - // NOP - } - } - - // eslint-disable-next-line no-shadow - const api = new API(); - api.prepare(); - return api; -})(); |