Start using Iterator.prototype.join in the code-base

This is an upcoming JavaScript feature, which helps avoid creating intermediate Arrays in some cases; see https://github.com/tc39/proposal-iterator-join

Firefox implemented this in [bug 2004803](https://bugzilla.mozilla.org/show_bug.cgi?id=2004803), and it was enabled by default in [bug 2047995](https://bugzilla.mozilla.org/show_bug.cgi?id=2047995).

This patch changes two Objects to Maps, in the XFA-parsing respectively the find-implementation, to make use of the new feature.
This commit is contained in:
Jonas Jenwald 2026-07-16 19:00:34 +02:00
parent 16290afa3b
commit 9a7335d26b
5 changed files with 48 additions and 37 deletions

View File

@ -1280,13 +1280,13 @@ class PDFDocument {
if (!streams) {
return null;
}
const data = Object.create(null);
const data = new Map();
for (const [key, stream] of streams) {
if (!stream) {
continue;
}
try {
data[key] = stringToUTF8String(stream.getString());
data.set(key, stringToUTF8String(stream.getString()));
} catch {
warn("XFA - Invalid utf-8 string.");
return null;

View File

@ -132,10 +132,7 @@ class XFAFactory {
}
static _createDocument(data) {
if (!data["/xdp:xdp"]) {
return data["xdp:xdp"];
}
return Object.values(data).join("");
return !data.get("/xdp:xdp") ? data.get("xdp:xdp") : data.values().join("");
}
static getRichTextAsHtml(rc) {

View File

@ -1159,6 +1159,14 @@ if (
};
}
// TODO: Remove this once `Iterator.prototype.join` is generally available.
if (typeof Iterator.prototype.join !== "function") {
// eslint-disable-next-line no-extend-native
Iterator.prototype.join = function (separator) {
return [...this].join(separator);
};
}
export {
_isValidExplicitDest,
AbortException,

View File

@ -82,7 +82,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
factory.setFonts([]);
expect(await factory.getNumPages()).toEqual(2);
@ -168,7 +168,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -202,7 +202,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -256,7 +256,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
factory.setFonts([]);
expect(await factory.getNumPages()).toEqual(1);
@ -330,7 +330,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -372,7 +372,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -414,7 +414,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -457,7 +457,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -511,7 +511,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -555,7 +555,9 @@ describe("XFAFactory", function () {
let factory, pages, a;
// A valid, and complete, URL.
factory = new XFAFactory({ "xdp:xdp": getXml("https://www.example.com/") });
factory = new XFAFactory(
new Map([["xdp:xdp", getXml("https://www.example.com/")]])
);
expect(await factory.getNumPages()).toEqual(1);
pages = await factory.getPages();
a = searchHtmlNode(pages, "name", "a");
@ -563,7 +565,9 @@ describe("XFAFactory", function () {
expect(a.attributes.href).toEqual("https://www.example.com/");
// A valid, but incomplete, URL.
factory = new XFAFactory({ "xdp:xdp": getXml("www.example.com/") });
factory = new XFAFactory(
new Map([["xdp:xdp", getXml("www.example.com/")]])
);
expect(await factory.getNumPages()).toEqual(1);
pages = await factory.getPages();
a = searchHtmlNode(pages, "name", "a");
@ -571,7 +575,9 @@ describe("XFAFactory", function () {
expect(a.attributes.href).toEqual("http://www.example.com/");
// A valid email-address.
factory = new XFAFactory({ "xdp:xdp": getXml("mailto:test@example.com") });
factory = new XFAFactory(
new Map([["xdp:xdp", getXml("mailto:test@example.com")]])
);
expect(await factory.getNumPages()).toEqual(1);
pages = await factory.getPages();
a = searchHtmlNode(pages, "name", "a");
@ -579,7 +585,7 @@ describe("XFAFactory", function () {
expect(a.attributes.href).toEqual("mailto:test@example.com");
// Not a valid URL.
factory = new XFAFactory({ "xdp:xdp": getXml("qwerty/") });
factory = new XFAFactory(new Map([["xdp:xdp", getXml("qwerty/")]]));
expect(await factory.getNumPages()).toEqual(1);
pages = await factory.getPages();
a = searchHtmlNode(pages, "name", "a");
@ -629,7 +635,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);
@ -675,7 +681,7 @@ describe("XFAFactory", function () {
</xfa:datasets>
</xdp:xdp>
`;
const factory = new XFAFactory({ "xdp:xdp": xml });
const factory = new XFAFactory(new Map([["xdp:xdp", xml]]));
expect(await factory.getNumPages()).toEqual(1);

View File

@ -28,20 +28,20 @@ const FindState = {
PENDING: 3,
};
const CHARACTERS_TO_NORMALIZE = {
"\u2010": "-", // Hyphen
"\u2018": "'", // Left single quotation mark
"\u2019": "'", // Right single quotation mark
"\u201A": "'", // Single low-9 quotation mark
"\u201B": "'", // Single high-reversed-9 quotation mark
"\u201C": '"', // Left double quotation mark
"\u201D": '"', // Right double quotation mark
"\u201E": '"', // Double low-9 quotation mark
"\u201F": '"', // Double high-reversed-9 quotation mark
"\u00BC": "1/4", // Vulgar fraction one quarter
"\u00BD": "1/2", // Vulgar fraction one half
"\u00BE": "3/4", // Vulgar fraction three quarters
};
const CHARACTERS_TO_NORMALIZE = new Map([
["\u2010", "-"], // Hyphen
["\u2018", "'"], // Left single quotation mark
["\u2019", "'"], // Right single quotation mark
["\u201A", "'"], // Single low-9 quotation mark
["\u201B", "'"], // Single high-reversed-9 quotation mark
["\u201C", '"'], // Left double quotation mark
["\u201D", '"'], // Right double quotation mark
["\u201E", '"'], // Double low-9 quotation mark
["\u201F", '"'], // Double high-reversed-9 quotation mark
["\u00BC", "1/4"], // Vulgar fraction one quarter
["\u00BD", "1/2"], // Vulgar fraction one half
["\u00BE", "3/4"], // Vulgar fraction three quarters
]);
// These diacritics aren't considered as combining diacritics
// when searching in a document:
@ -121,7 +121,7 @@ function normalize(text, options = {}) {
normalizationRegex = withSyllablesRegExp;
} else {
// Compile the regular expression for text normalization once.
const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join("");
const replace = CHARACTERS_TO_NORMALIZE.keys().join("");
const toNormalizeWithNFKC = getNormalizeWithNFKC();
// 3040-309F: Hiragana
@ -206,7 +206,7 @@ function normalize(text, options = {}) {
i -= shiftOrigin;
if (p1) {
// Maybe fractions or quotations mark...
const replacement = CHARACTERS_TO_NORMALIZE[p1];
const replacement = CHARACTERS_TO_NORMALIZE.get(p1);
const jj = replacement.length;
for (let j = 1; j < jj; j++) {
positions.push(i - shift + j, shift - j);