diff options
Diffstat (limited to 'ext/js')
-rw-r--r-- | ext/js/language/dictionary-importer-media-loader.js | 57 | ||||
-rw-r--r-- | ext/js/language/dictionary-importer.js | 41 | ||||
-rw-r--r-- | ext/js/pages/settings/dictionary-import-controller.js | 4 |
3 files changed, 65 insertions, 37 deletions
diff --git a/ext/js/language/dictionary-importer-media-loader.js b/ext/js/language/dictionary-importer-media-loader.js new file mode 100644 index 00000000..bbcc5476 --- /dev/null +++ b/ext/js/language/dictionary-importer-media-loader.js @@ -0,0 +1,57 @@ +/* + * Copyright (C) 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 + * MediaUtil + */ + +/** + * Class used for loading and validating media during the dictionary import process. + */ +class DictionaryImporterMediaLoader { + /** + * Attempts to load an image using a base64 encoded content and a media type + * and returns its resolution. + * @param mediaType The media type for the image content. + * @param content The binary content for the image, encoded in base64. + * @returns A Promise which resolves with {width, height} on success, + * otherwise an error is thrown. + */ + getImageResolution(mediaType, content) { + return new Promise((resolve, reject) => { + const image = new Image(); + const eventListeners = new EventListenerCollection(); + const cleanup = () => { + image.removeAttribute('src'); + URL.revokeObjectURL(url); + eventListeners.removeAllEventListeners(); + }; + eventListeners.addEventListener(image, 'load', () => { + const {naturalWidth: width, naturalHeight: height} = image; + cleanup(); + resolve({width, height}); + }, false); + eventListeners.addEventListener(image, 'error', () => { + cleanup(); + reject(new Error('Image failed to load')); + }, false); + const blob = MediaUtil.createBlobFromBase64Content(content, mediaType); + const url = URL.createObjectURL(blob); + image.src = url; + }); + } +} diff --git a/ext/js/language/dictionary-importer.js b/ext/js/language/dictionary-importer.js index 27b3c44e..b931c929 100644 --- a/ext/js/language/dictionary-importer.js +++ b/ext/js/language/dictionary-importer.js @@ -22,11 +22,12 @@ */ class DictionaryImporter { - constructor() { + constructor(mediaLoader) { + this._mediaLoader = mediaLoader; this._schemas = new Map(); } - async importDictionary(dictionaryDatabase, archiveSource, details, onProgress) { + async importDictionary(dictionaryDatabase, archiveContent, details, onProgress) { if (!dictionaryDatabase) { throw new Error('Invalid database'); } @@ -37,7 +38,7 @@ class DictionaryImporter { const hasOnProgress = (typeof onProgress === 'function'); // Read archive - const archive = await JSZip.loadAsync(archiveSource); + const archive = await JSZip.loadAsync(archiveContent); // Read and validate index const indexFileName = 'index.json'; @@ -469,7 +470,7 @@ class DictionaryImporter { let width; let height; try { - ({width, height} = await this._getImageResolution(mediaType, content)); + ({width, height} = await this._mediaLoader.getImageResolution(mediaType, content)); } catch (e) { throw createError('Could not load image'); } @@ -502,36 +503,4 @@ class DictionaryImporter { } return await response.json(); } - - /** - * Attempts to load an image using a base64 encoded content and a media type - * and returns its resolution. - * @param mediaType The media type for the image content. - * @param content The binary content for the image, encoded in base64. - * @returns A Promise which resolves with {width, height} on success, - * otherwise an error is thrown. - */ - _getImageResolution(mediaType, content) { - return new Promise((resolve, reject) => { - const image = new Image(); - const eventListeners = new EventListenerCollection(); - const cleanup = () => { - image.removeAttribute('src'); - URL.revokeObjectURL(url); - eventListeners.removeAllEventListeners(); - }; - eventListeners.addEventListener(image, 'load', () => { - const {naturalWidth: width, naturalHeight: height} = image; - cleanup(); - resolve({width, height}); - }, false); - eventListeners.addEventListener(image, 'error', () => { - cleanup(); - reject(new Error('Image failed to load')); - }, false); - const blob = MediaUtil.createBlobFromBase64Content(content, mediaType); - const url = URL.createObjectURL(blob); - image.src = url; - }); - } } diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js index db9a1a50..128e18cb 100644 --- a/ext/js/pages/settings/dictionary-import-controller.js +++ b/ext/js/pages/settings/dictionary-import-controller.js @@ -19,6 +19,7 @@ * DictionaryController * DictionaryDatabase * DictionaryImporter + * DictionaryImporterMediaLoader */ class DictionaryImportController { @@ -184,7 +185,8 @@ class DictionaryImportController { async _importDictionary(file, importDetails, onProgress) { const dictionaryDatabase = await this._getPreparedDictionaryDatabase(); try { - const dictionaryImporter = new DictionaryImporter(); + const dictionaryImporterMediaLoader = new DictionaryImporterMediaLoader(); + const dictionaryImporter = new DictionaryImporter(dictionaryImporterMediaLoader); const archiveContent = await this._readFile(file); const {result, errors} = await dictionaryImporter.importDictionary(dictionaryDatabase, archiveContent, importDetails, onProgress); yomichan.api.triggerDatabaseUpdated('dictionary', 'import'); |