From 709d89420edc930d4011eadc5e3686a38a956dbe Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 14 Nov 2023 12:54:21 +0100 Subject: [PATCH] Re-factor how the `GenericL10n` class fetches localization-data - Re-factor the existing `fetchData` helper function such that it can fetch more types of data, and it now supports "arraybuffer", "json", and "text". This only needed minor adjustments in the `DOMCMapReaderFactory` and `DOMStandardFontDataFactory` classes.[1] - Expose the `fetchData` helper function in the API, such that the viewer is able to access it. - Use the `fetchData` helper function in the `GenericL10n` class, since this should allow fetching of localization-data even if the default viewer is run in an environment without support for the Fetch API. --- [1] While testing this I also noticed a minor inconsistency when handling standard font-data on the worker-thread. --- src/core/evaluator.js | 2 +- src/display/display_utils.js | 48 +++++++++++++++++++++++++----------- src/pdf.js | 2 ++ test/unit/pdf_spec.js | 2 ++ web/genericl10n.js | 9 ++++--- web/pdfjs.js | 2 ++ 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 5e86ea5e2aaf4..41081c5f4e3ef 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -425,7 +425,7 @@ class PartialEvaluator { `fetchStandardFontData: failed to fetch file "${url}" with "${response.statusText}".` ); } else { - data = await response.arrayBuffer(); + data = new Uint8Array(await response.arrayBuffer()); } } else { // Get the data on the main-thread instead. diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 4b535b73e5664..2ec31ca8e2490 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -387,7 +387,7 @@ class DOMCanvasFactory extends BaseCanvasFactory { } } -async function fetchData(url, asTypedArray = false) { +async function fetchData(url, type = "text") { if ( (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) || isValidFetchUrl(url, document.baseURI) @@ -396,29 +396,35 @@ async function fetchData(url, asTypedArray = false) { if (!response.ok) { throw new Error(response.statusText); } - return asTypedArray - ? new Uint8Array(await response.arrayBuffer()) - : stringToBytes(await response.text()); + switch (type) { + case "arraybuffer": + return response.arrayBuffer(); + case "json": + return response.json(); + } + return response.text(); } // The Fetch API is not supported. return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); - request.open("GET", url, /* asTypedArray = */ true); + request.open("GET", url, /* async = */ true); + request.responseType = type; - if (asTypedArray) { - request.responseType = "arraybuffer"; - } request.onreadystatechange = () => { if (request.readyState !== XMLHttpRequest.DONE) { return; } if (request.status === 200 || request.status === 0) { let data; - if (asTypedArray && request.response) { - data = new Uint8Array(request.response); - } else if (!asTypedArray && request.responseText) { - data = stringToBytes(request.responseText); + switch (type) { + case "arraybuffer": + case "json": + data = request.response; + break; + default: + data = request.responseText; + break; } if (data) { resolve(data); @@ -437,8 +443,17 @@ class DOMCMapReaderFactory extends BaseCMapReaderFactory { * @ignore */ _fetchData(url, compressionType) { - return fetchData(url, /* asTypedArray = */ this.isCompressed).then(data => { - return { cMapData: data, compressionType }; + return fetchData( + url, + /* type = */ this.isCompressed ? "arraybuffer" : "text" + ).then(data => { + return { + cMapData: + data instanceof ArrayBuffer + ? new Uint8Array(data) + : stringToBytes(data), + compressionType, + }; }); } } @@ -448,7 +463,9 @@ class DOMStandardFontDataFactory extends BaseStandardFontDataFactory { * @ignore */ _fetchData(url) { - return fetchData(url, /* asTypedArray = */ true); + return fetchData(url, /* type = */ "arraybuffer").then(data => { + return new Uint8Array(data); + }); } } @@ -993,6 +1010,7 @@ export { DOMFilterFactory, DOMStandardFontDataFactory, DOMSVGFactory, + fetchData, getColorValues, getCurrentTransform, getCurrentTransformInverse, diff --git a/src/pdf.js b/src/pdf.js index cc8d6af5872a2..6c88794e8ad16 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -54,6 +54,7 @@ import { } from "./display/api.js"; import { DOMSVGFactory, + fetchData, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, @@ -92,6 +93,7 @@ export { createValidAbsoluteUrl, DOMSVGFactory, FeatureTest, + fetchData, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, diff --git a/test/unit/pdf_spec.js b/test/unit/pdf_spec.js index d647f5ced7313..c7fd117cd4eb6 100644 --- a/test/unit/pdf_spec.js +++ b/test/unit/pdf_spec.js @@ -44,6 +44,7 @@ import { } from "../../src/display/api.js"; import { DOMSVGFactory, + fetchData, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, @@ -78,6 +79,7 @@ const expectedAPI = Object.freeze({ createValidAbsoluteUrl, DOMSVGFactory, FeatureTest, + fetchData, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, diff --git a/web/genericl10n.js b/web/genericl10n.js index 05ac48209d9ee..ec68b7f12a8f1 100644 --- a/web/genericl10n.js +++ b/web/genericl10n.js @@ -17,6 +17,7 @@ import { FluentBundle, FluentResource } from "fluent-bundle"; import { DOMLocalization } from "fluent-dom"; +import { fetchData } from "pdfjs-lib"; import { L10n } from "./l10n.js"; /** @@ -71,8 +72,8 @@ class GenericL10n extends L10n { return null; } const url = new URL(path, baseURL); - const data = await fetch(url); - const text = await data.text(); + const text = await fetchData(url, /* type = */ "text"); + const resource = new FluentResource(text); const bundle = new FluentBundle(lang); const errors = bundle.addResource(resource); @@ -84,8 +85,8 @@ class GenericL10n extends L10n { static async #getPaths() { const { href } = document.querySelector(`link[type="application/l10n"]`); - const data = await fetch(href); - const paths = await data.json(); + const paths = await fetchData(href, /* type = */ "json"); + return { baseURL: href.replace(/[^/]*$/, "") || "./", paths }; } } diff --git a/web/pdfjs.js b/web/pdfjs.js index 30da7c8d6bd1a..a8b8b215bb350 100644 --- a/web/pdfjs.js +++ b/web/pdfjs.js @@ -35,6 +35,7 @@ const { createValidAbsoluteUrl, DOMSVGFactory, FeatureTest, + fetchData, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, @@ -80,6 +81,7 @@ export { createValidAbsoluteUrl, DOMSVGFactory, FeatureTest, + fetchData, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl,