From 8ba83e73fa88175a46b842fe0f1f0f8bec9b9ba8 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 11 Feb 2026 22:37:49 +0100 Subject: [PATCH] Start using `Response.prototype.bytes()` in the code-base In all cases where we currently use `Response.prototype.arrayBuffer()` the result is immediately wrapped in a `Uint8Array`, which can be avoided by instead using the newer `Response.prototype.bytes()` method; see https://developer.mozilla.org/en-US/docs/Web/API/Response/bytes --- src/core/core_utils.js | 2 +- src/display/cmap_reader_factory.js | 6 ++---- src/display/display_utils.js | 7 ++++++- src/display/standard_fontdata_factory.js | 3 +-- src/display/wasm_factory.js | 3 +-- src/shared/util.js | 12 ++++++++++++ test/unit/test_utils.js | 3 +-- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/core/core_utils.js b/src/core/core_utils.js index f3218ac61..5980a51f2 100644 --- a/src/core/core_utils.js +++ b/src/core/core_utils.js @@ -129,7 +129,7 @@ async function fetchBinaryData(url) { `Failed to fetch file "${url}" with "${response.statusText}".` ); } - return new Uint8Array(await response.arrayBuffer()); + return response.bytes(); } /** diff --git a/src/display/cmap_reader_factory.js b/src/display/cmap_reader_factory.js index 5246fbb23..748bf8812 100644 --- a/src/display/cmap_reader_factory.js +++ b/src/display/cmap_reader_factory.js @@ -64,11 +64,9 @@ class DOMCMapReaderFactory extends BaseCMapReaderFactory { async _fetch(url) { const data = await fetchData( url, - /* type = */ this.isCompressed ? "arraybuffer" : "text" + /* type = */ this.isCompressed ? "bytes" : "text" ); - return data instanceof ArrayBuffer - ? new Uint8Array(data) - : stringToBytes(data); + return data instanceof Uint8Array ? data : stringToBytes(data); } } diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 16181b3e5..c8f66a97d 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -48,6 +48,8 @@ async function fetchData(url, type = "text") { return response.arrayBuffer(); case "blob": return response.blob(); + case "bytes": + return response.bytes(); case "json": return response.json(); } @@ -58,7 +60,7 @@ async function fetchData(url, type = "text") { return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open("GET", url, /* async = */ true); - request.responseType = type; + request.responseType = type === "bytes" ? "arraybuffer" : type; request.onreadystatechange = () => { if (request.readyState !== XMLHttpRequest.DONE) { @@ -66,6 +68,9 @@ async function fetchData(url, type = "text") { } if (request.status === 200 || request.status === 0) { switch (type) { + case "bytes": + resolve(new Uint8Array(request.response)); + return; case "arraybuffer": case "blob": case "json": diff --git a/src/display/standard_fontdata_factory.js b/src/display/standard_fontdata_factory.js index bfd8af3c0..15cdfdd23 100644 --- a/src/display/standard_fontdata_factory.js +++ b/src/display/standard_fontdata_factory.js @@ -57,8 +57,7 @@ class DOMStandardFontDataFactory extends BaseStandardFontDataFactory { * @ignore */ async _fetch(url) { - const data = await fetchData(url, /* type = */ "arraybuffer"); - return new Uint8Array(data); + return fetchData(url, /* type = */ "bytes"); } } diff --git a/src/display/wasm_factory.js b/src/display/wasm_factory.js index 297e8e0e3..cc889e101 100644 --- a/src/display/wasm_factory.js +++ b/src/display/wasm_factory.js @@ -55,8 +55,7 @@ class DOMWasmFactory extends BaseWasmFactory { * @ignore */ async _fetch(url) { - const data = await fetchData(url, /* type = */ "arraybuffer"); - return new Uint8Array(data); + return fetchData(url, /* type = */ "bytes"); } } diff --git a/src/shared/util.js b/src/shared/util.js index ccbc2f56a..039efa7d6 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -1248,6 +1248,18 @@ if ( }; } +// See https://developer.mozilla.org/en-US/docs/Web/API/Response/bytes#browser_compatibility +if ( + typeof PDFJSDev !== "undefined" && + !PDFJSDev.test("SKIP_BABEL") && + typeof Response.prototype.bytes !== "function" +) { + Response.prototype.bytes = async function () { + return new Uint8Array(await this.arrayBuffer()); + }; +} + +// TODO: Remove this once Safari 17.4 is the lowest supported version. if ( typeof PDFJSDev !== "undefined" && !PDFJSDev.test("SKIP_BABEL") && diff --git a/test/unit/test_utils.js b/test/unit/test_utils.js index 15b5fce06..5d59c8f21 100644 --- a/test/unit/test_utils.js +++ b/test/unit/test_utils.js @@ -41,8 +41,7 @@ class DefaultFileReaderFactory { if (isNodeJS) { return fetchDataNode(params.path); } - const data = await fetchDataDOM(params.path, /* type = */ "arraybuffer"); - return new Uint8Array(data); + return fetchDataDOM(params.path, /* type = */ "bytes"); } }