diff options
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/background/backend.js | 16 | ||||
| -rw-r--r-- | ext/js/data/sandbox/string-util.js | 15 | ||||
| -rw-r--r-- | ext/js/language/dictionary-importer-media-loader.js | 19 | ||||
| -rw-r--r-- | ext/js/language/dictionary-importer.js | 9 | ||||
| -rw-r--r-- | ext/js/language/dictionary-worker-handler.js | 2 | ||||
| -rw-r--r-- | ext/js/language/dictionary-worker-media-loader.js | 16 | ||||
| -rw-r--r-- | ext/js/language/dictionary-worker.js | 13 | ||||
| -rw-r--r-- | ext/js/media/media-loader.js | 5 | ||||
| -rw-r--r-- | ext/js/media/media-util.js | 16 | 
9 files changed, 57 insertions, 54 deletions
| diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index dea67091..8e05ee68 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -31,6 +31,7 @@   * PermissionsUtil   * ProfileConditionsUtil   * RequestBuilder + * StringUtil   * Translator   * wanakana   */ @@ -621,7 +622,7 @@ class Backend {      }      async _onApiGetMedia({targets}) { -        return await this._dictionaryDatabase.getMedia(targets); +        return await this._getNormalizedDictionaryDatabaseMedia(targets);      }      _onApiLog({error, level, context}) { @@ -1847,7 +1848,7 @@ class Backend {              detailsList.push(details);              detailsMap.set(key, details);          } -        const mediaList = await this._dictionaryDatabase.getMedia(targets); +        const mediaList = await this._getNormalizedDictionaryDatabaseMedia(targets);          for (const media of mediaList) {              const {dictionary, path} = media; @@ -2283,4 +2284,15 @@ class Backend {          return await this._injectScript(file, tab.id, frameId);      } + +    async _getNormalizedDictionaryDatabaseMedia(targets) { +        const results = await this._dictionaryDatabase.getMedia(targets); +        for (const item of results) { +            const {content} = item; +            if (content instanceof ArrayBuffer) { +                item.content = StringUtil.arrayBufferToBase64(content); +            } +        } +        return results; +    }  } diff --git a/ext/js/data/sandbox/string-util.js b/ext/js/data/sandbox/string-util.js index 37e021c9..b523c39d 100644 --- a/ext/js/data/sandbox/string-util.js +++ b/ext/js/data/sandbox/string-util.js @@ -58,4 +58,19 @@ class StringUtil {              return binary;          }      } + +    /** +     * Converts a base64 string to an ArrayBuffer. +     * @param content The binary content string encoded in base64. +     * @returns A new `ArrayBuffer` object corresponding to the specified content. +     */ +    static base64ToArrayBuffer(content) { +        const binaryContent = atob(content); +        const length = binaryContent.length; +        const array = new Uint8Array(length); +        for (let i = 0; i < length; ++i) { +            array[i] = binaryContent.charCodeAt(i); +        } +        return array.buffer; +    }  } 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 <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. +     * 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) { diff --git a/ext/js/media/media-loader.js b/ext/js/media/media-loader.js index 7dafc2a3..8c7e356c 100644 --- a/ext/js/media/media-loader.js +++ b/ext/js/media/media-loader.js @@ -16,7 +16,7 @@   */  /* global - * MediaUtil + * StringUtil   */  class MediaLoader { @@ -86,7 +86,8 @@ class MediaLoader {          const token = this._token;          const data = (await yomichan.api.getMedia([{path, dictionary}]))[0];          if (token === this._token && data !== null) { -            const blob = MediaUtil.createBlobFromBase64Content(data.content, data.mediaType); +            const buffer = StringUtil.base64ToArrayBuffer(data.content); +            const blob = new Blob([buffer], {type: data.mediaType});              const url = URL.createObjectURL(blob);              cachedData.data = data;              cachedData.url = url; diff --git a/ext/js/media/media-util.js b/ext/js/media/media-util.js index f783038a..11172c5c 100644 --- a/ext/js/media/media-util.js +++ b/ext/js/media/media-util.js @@ -129,20 +129,4 @@ class MediaUtil {                  return null;          }      } - -    /** -     * Creates a new `Blob` object from a base64 string of content. -     * @param content The binary content string encoded in base64. -     * @param mediaType The type of the media. -     * @returns A new `Blob` object corresponding to the specified content. -     */ -    static createBlobFromBase64Content(content, mediaType) { -        const binaryContent = atob(content); -        const length = binaryContent.length; -        const array = new Uint8Array(length); -        for (let i = 0; i < length; ++i) { -            array[i] = binaryContent.charCodeAt(i); -        } -        return new Blob([array.buffer], {type: mediaType}); -    }  } |