diff options
Diffstat (limited to 'ext')
| -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 | ||||
| -rw-r--r-- | ext/settings.html | 1 | ||||
| -rw-r--r-- | ext/welcome.html | 1 | 
5 files changed, 67 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'); diff --git a/ext/settings.html b/ext/settings.html index 9d2d9791..cd2376d6 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -3451,6 +3451,7 @@  <script src="/js/input/hotkey-util.js"></script>  <script src="/js/language/dictionary-database.js"></script>  <script src="/js/language/dictionary-importer.js"></script> +<script src="/js/language/dictionary-importer-media-loader.js"></script>  <script src="/js/language/sandbox/dictionary-data-util.js"></script>  <script src="/js/language/sandbox/japanese-util.js"></script>  <script src="/js/media/audio-system.js"></script> diff --git a/ext/welcome.html b/ext/welcome.html index 85022e2c..5c9f4469 100644 --- a/ext/welcome.html +++ b/ext/welcome.html @@ -409,6 +409,7 @@  <script src="/js/input/hotkey-util.js"></script>  <script src="/js/language/dictionary-database.js"></script>  <script src="/js/language/dictionary-importer.js"></script> +<script src="/js/language/dictionary-importer-media-loader.js"></script>  <script src="/js/media/media-util.js"></script>  <script src="/js/pages/settings/dictionary-controller.js"></script>  <script src="/js/pages/settings/dictionary-import-controller.js"></script> |