From 0331374241a55415cbae37d386f47da428ede3db Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 3 Sep 2021 22:33:58 -0400 Subject: Dictionary media import improvements (#1926) * Add base64ToArrayBuffer to StringUtil * Remove unnecessary media-util.js import * Run async requirements in serial rather than parallel * Update API.getMedia handler to convert ArrayBuffer content to base64 * Rename getImageResolution to getImageDetails * Change parameter order of getImageDetails * Pre-process and store media as an ArrayBuffer * Remove MediaUtil.createBlobFromBase64Content * Fix Anki media injection --- ext/js/language/dictionary-importer-media-loader.js | 19 +++++++------------ ext/js/language/dictionary-importer.js | 9 +++------ ext/js/language/dictionary-worker-handler.js | 2 +- ext/js/language/dictionary-worker-media-loader.js | 16 +++++++--------- ext/js/language/dictionary-worker.js | 13 +++++++------ 5 files changed, 25 insertions(+), 34 deletions(-) (limited to 'ext/js/language') diff --git a/ext/js/language/dictionary-importer-media-loader.js b/ext/js/language/dictionary-importer-media-loader.js index bbcc5476..27ddde34 100644 --- a/ext/js/language/dictionary-importer-media-loader.js +++ b/ext/js/language/dictionary-importer-media-loader.js @@ -15,23 +15,17 @@ * along with this program. If not, see . */ -/* 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. + * Attempts to load an image using an ArrayBuffer and a media type to return details about it. + * @param content The binary content for the image, encoded as an ArrayBuffer. * @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. + * @returns A Promise which resolves with {content, width, height} on success, otherwise an error is thrown. */ - getImageResolution(mediaType, content) { + getImageDetails(content, mediaType, transfer) { return new Promise((resolve, reject) => { const image = new Image(); const eventListeners = new EventListenerCollection(); @@ -42,14 +36,15 @@ class DictionaryImporterMediaLoader { }; eventListeners.addEventListener(image, 'load', () => { const {naturalWidth: width, naturalHeight: height} = image; + if (Array.isArray(transfer)) { transfer.push(content); } cleanup(); - resolve({width, height}); + resolve({content, width, height}); }, false); eventListeners.addEventListener(image, 'error', () => { cleanup(); reject(new Error('Image failed to load')); }, false); - const blob = MediaUtil.createBlobFromBase64Content(content, mediaType); + const blob = new Blob([content], {type: 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 98cddf76..5629e197 100644 --- a/ext/js/language/dictionary-importer.js +++ b/ext/js/language/dictionary-importer.js @@ -328,13 +328,10 @@ class DictionaryImporter { const media = new Map(); const context = {archive, media}; - const promises = []; for (const requirement of requirements) { - promises.push(this._resolveAsyncRequirement(context, requirement)); + await this._resolveAsyncRequirement(context, requirement); } - await Promise.all(promises); - return { media: [...media.values()] }; @@ -425,7 +422,7 @@ class DictionaryImporter { } // Load file content - const content = await file.async('base64'); + let content = await file.async('arraybuffer'); const mediaType = MediaUtil.getImageMediaTypeFromFileName(path); if (mediaType === null) { throw createError('Could not determine media type for image'); @@ -435,7 +432,7 @@ class DictionaryImporter { let width; let height; try { - ({width, height} = await this._mediaLoader.getImageResolution(mediaType, content)); + ({content, width, height} = await this._mediaLoader.getImageDetails(content, mediaType)); } catch (e) { throw createError('Could not load image'); } diff --git a/ext/js/language/dictionary-worker-handler.js b/ext/js/language/dictionary-worker-handler.js index 1d6b4aab..3ce744f9 100644 --- a/ext/js/language/dictionary-worker-handler.js +++ b/ext/js/language/dictionary-worker-handler.js @@ -44,7 +44,7 @@ class DictionaryWorkerHandler { case 'getDictionaryCounts': this._onMessageWithProgress(params, this._getDictionaryCounts.bind(this)); break; - case 'getImageResolution.response': + case 'getImageDetails.response': this._mediaLoader.handleMessage(params); break; } diff --git a/ext/js/language/dictionary-worker-media-loader.js b/ext/js/language/dictionary-worker-media-loader.js index 90ee513f..25f8de72 100644 --- a/ext/js/language/dictionary-worker-media-loader.js +++ b/ext/js/language/dictionary-worker-media-loader.js @@ -45,21 +45,19 @@ class DictionaryWorkerMediaLoader { } /** - * Attempts to load an image using a base64 encoded content and a media type - * and returns its resolution. + * Attempts to load an image using an ArrayBuffer and a media type to return details about it. + * @param content The binary content for the image, encoded as an ArrayBuffer. * @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. + * @returns A Promise which resolves with {content, width, height} on success, otherwise an error is thrown. */ - getImageResolution(mediaType, content) { + getImageDetails(content, mediaType) { return new Promise((resolve, reject) => { const id = generateId(16); this._requests.set(id, {resolve, reject}); self.postMessage({ - action: 'getImageResolution', - params: {id, mediaType, content} - }); + action: 'getImageDetails', + params: {id, content, mediaType} + }, [content]); }); } } diff --git a/ext/js/language/dictionary-worker.js b/ext/js/language/dictionary-worker.js index 92faa3dc..be94c397 100644 --- a/ext/js/language/dictionary-worker.js +++ b/ext/js/language/dictionary-worker.js @@ -85,8 +85,8 @@ class DictionaryWorker { case 'progress': this._onMessageProgress(params, details.onProgress); break; - case 'getImageResolution': - this._onMessageGetImageResolution(params, details.worker); + case 'getImageDetails': + this._onMessageGetImageDetails(params, details.worker); break; } } @@ -115,16 +115,17 @@ class DictionaryWorker { onProgress(...args); } - async _onMessageGetImageResolution(params, worker) { - const {id, mediaType, content} = params; + async _onMessageGetImageDetails(params, worker) { + const {id, content, mediaType} = params; + const transfer = []; let response; try { - const result = await this._dictionaryImporterMediaLoader.getImageResolution(mediaType, content); + const result = await this._dictionaryImporterMediaLoader.getImageDetails(content, mediaType, transfer); response = {id, result}; } catch (e) { response = {id, error: serializeError(e)}; } - worker.postMessage({action: 'getImageResolution.response', params: response}); + worker.postMessage({action: 'getImageDetails.response', params: response}, transfer); } _formatimportDictionaryResult(result) { -- cgit v1.2.3