diff --git a/src/display/annotation_storage.js b/src/display/annotation_storage.js index 9999f3b52..91cdc6240 100644 --- a/src/display/annotation_storage.js +++ b/src/display/annotation_storage.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { objectFromMap, shadow, unreachable } from "../shared/util.js"; +import { shadow, unreachable } from "../shared/util.js"; import { AnnotationEditor } from "./editor/editor.js"; import { MurmurHash3_64 } from "../shared/murmurhash3.js"; @@ -41,6 +41,17 @@ class AnnotationStorage { this.onSetModified = null; this.onResetModified = null; this.onAnnotationEditor = null; + + if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) { + // For testing purposes. + Object.defineProperty(this, "_setValues", { + value: obj => { + for (const [key, val] of Object.entries(obj)) { + this.setValue(key, val); + } + }, + }); + } } /** @@ -128,22 +139,6 @@ class AnnotationStorage { return this.#storage.has(key); } - /** - * @returns {Object | null} - */ - getAll() { - return this.#storage.size > 0 ? objectFromMap(this.#storage) : null; - } - - /** - * @param {Object} obj - */ - setAll(obj) { - for (const [key, val] of Object.entries(obj)) { - this.setValue(key, val); - } - } - get size() { return this.#storage.size; } @@ -278,6 +273,10 @@ class AnnotationStorage { hash: ids.join(","), }); } + + [Symbol.iterator]() { + return this.#storage.entries(); + } } /** diff --git a/src/display/metadata.js b/src/display/metadata.js index 9c62bed94..1760afb97 100644 --- a/src/display/metadata.js +++ b/src/display/metadata.js @@ -13,15 +13,13 @@ * limitations under the License. */ -import { objectFromMap } from "../shared/util.js"; - class Metadata { - #metadataMap; + #map; #data; constructor({ parsedData, rawData }) { - this.#metadataMap = parsedData; + this.#map = parsedData; this.#data = rawData; } @@ -30,15 +28,11 @@ class Metadata { } get(name) { - return this.#metadataMap.get(name) ?? null; + return this.#map.get(name) ?? null; } - getAll() { - return objectFromMap(this.#metadataMap); - } - - has(name) { - return this.#metadataMap.has(name); + [Symbol.iterator]() { + return this.#map.entries(); } } diff --git a/src/display/optional_content_config.js b/src/display/optional_content_config.js index b31bd526e..27c59340f 100644 --- a/src/display/optional_content_config.js +++ b/src/display/optional_content_config.js @@ -15,7 +15,6 @@ import { info, - objectFromMap, RenderingIntentFlag, unreachable, warn, @@ -301,10 +300,6 @@ class OptionalContentConfig { return [...this.#groups.keys()]; } - getGroups() { - return this.#groups.size > 0 ? objectFromMap(this.#groups) : null; - } - getGroup(id) { return this.#groups.get(id) || null; } @@ -320,6 +315,10 @@ class OptionalContentConfig { } return (this.#cachedGetHash = hash.hexdigest()); } + + [Symbol.iterator]() { + return this.#groups.entries(); + } } export { OptionalContentConfig }; diff --git a/src/shared/util.js b/src/shared/util.js index 013bdfffa..76380843a 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -578,16 +578,6 @@ function objectSize(obj) { return Object.keys(obj).length; } -// Ensure that the returned Object has a `null` prototype; hence why -// `Object.fromEntries(...)` is not used. -function objectFromMap(map) { - const obj = Object.create(null); - for (const [key, value] of map) { - obj[key] = value; - } - return obj; -} - // Checks the endianness of the platform. function isLittleEndian() { const buffer8 = new Uint8Array(4); @@ -1313,7 +1303,6 @@ export { LINE_FACTOR, MathClamp, normalizeUnicode, - objectFromMap, objectSize, OPS, PageActionEventType, diff --git a/test/driver.js b/test/driver.js index 56fc71891..946147106 100644 --- a/test/driver.js +++ b/test/driver.js @@ -738,7 +738,7 @@ class Driver { await page.getAnnotations({ intent: "display" }); } } - doc.annotationStorage.setAll(task.annotationStorage); + doc.annotationStorage._setValues(task.annotationStorage); const data = await doc.saveDocument(); await loadingTask.destroy(); @@ -919,7 +919,7 @@ class Driver { pageColors = null; if (task.annotationStorage) { - task.pdfDoc.annotationStorage.setAll(task.annotationStorage); + task.pdfDoc.annotationStorage._setValues(task.annotationStorage); } let textLayerCanvas, annotationLayerCanvas, annotationLayerContext; diff --git a/test/unit/annotation_storage_spec.js b/test/unit/annotation_storage_spec.js index a736309cc..4c162da1b 100644 --- a/test/unit/annotation_storage_spec.js +++ b/test/unit/annotation_storage_spec.js @@ -59,7 +59,7 @@ describe("AnnotationStorage", function () { it("should set a new value in the annotation storage", function () { const annotationStorage = new AnnotationStorage(); annotationStorage.setValue("123A", { value: "an other string" }); - const value = annotationStorage.getAll()["123A"].value; + const { value } = annotationStorage.getRawValue("123A"); expect(value).toEqual("an other string"); }); diff --git a/test/unit/metadata_spec.js b/test/unit/metadata_spec.js index 4d1aeabeb..5360f8ab0 100644 --- a/test/unit/metadata_spec.js +++ b/test/unit/metadata_spec.js @@ -16,8 +16,6 @@ import { Metadata } from "../../src/display/metadata.js"; import { MetadataParser } from "../../src/core/metadata_parser.js"; -const emptyObj = Object.create(null); - function createMetadata(data) { const metadataParser = new MetadataParser(data); return new Metadata(metadataParser.serializable); @@ -33,13 +31,10 @@ describe("metadata", function () { ""; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual("Foo bar baz"); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ "dc:title": "Foo bar baz" }); + expect([...metadata]).toEqual([["dc:title", "Foo bar baz"]]); }); it("should repair and handle invalid metadata", function () { @@ -51,13 +46,10 @@ describe("metadata", function () { ""; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual("PDF&"); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ "dc:title": "PDF&" }); + expect([...metadata]).toEqual([["dc:title", "PDF&"]]); }); it("should repair and handle invalid metadata (bug 1424938)", function () { @@ -94,19 +86,16 @@ describe("metadata", function () { ""; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual( "L'Odissee thématique logo Odisséé - décembre 2008.pub" ); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ - "dc:creator": ["ODIS"], - "dc:title": "L'Odissee thématique logo Odisséé - décembre 2008.pub", - "xap:creatortool": "PDFCreator Version 0.9.6", - }); + expect([...metadata].sort()).toEqual([ + ["dc:creator", ["ODIS"]], + ["dc:title", "L'Odissee thématique logo Odisséé - décembre 2008.pub"], + ["xap:creatortool", "PDFCreator Version 0.9.6"], + ]); }); it("should gracefully handle incomplete tags (issue 8884)", function () { @@ -137,7 +126,7 @@ describe("metadata", function () { ''; const metadata = createMetadata(data); - expect(metadata.getAll()).toEqual(emptyObj); + expect([...metadata]).toEqual([]); }); it('should gracefully handle "junk" before the actual metadata (issue 10395)', function () { @@ -168,26 +157,23 @@ describe("metadata", function () { ''; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual(""); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ - "dc:creator": [""], - "dc:description": "", - "dc:format": "application/pdf", - "dc:subject": [], - "dc:title": "", - "pdf:keywords": "", - "pdf:pdfversion": "1.7", - "pdf:producer": "PDFKit.NET 4.0.102.0", - "xap:createdate": "2018-12-27T13:50:36-08:00", - "xap:creatortool": "", - "xap:metadatadate": "2018-12-27T13:50:38-08:00", - "xap:modifydate": "2018-12-27T13:50:38-08:00", - }); + expect([...metadata].sort()).toEqual([ + ["dc:creator", [""]], + ["dc:description", ""], + ["dc:format", "application/pdf"], + ["dc:subject", []], + ["dc:title", ""], + ["pdf:keywords", ""], + ["pdf:pdfversion", "1.7"], + ["pdf:producer", "PDFKit.NET 4.0.102.0"], + ["xap:createdate", "2018-12-27T13:50:36-08:00"], + ["xap:creatortool", ""], + ["xap:metadatadate", "2018-12-27T13:50:38-08:00"], + ["xap:modifydate", "2018-12-27T13:50:38-08:00"], + ]); }); it('should correctly handle metadata containing "&apos" (issue 10407)', function () { @@ -200,13 +186,10 @@ describe("metadata", function () { ""; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual("'Foo bar baz'"); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ "dc:title": "'Foo bar baz'" }); + expect([...metadata]).toEqual([["dc:title", "'Foo bar baz'"]]); }); it("should gracefully handle unbalanced end tags (issue 10410)", function () { @@ -229,7 +212,7 @@ describe("metadata", function () { ''; const metadata = createMetadata(data); - expect(metadata.getAll()).toEqual(emptyObj); + expect([...metadata]).toEqual([]); }); it("should not be vulnerable to the billion laughs attack", function () { @@ -258,12 +241,9 @@ describe("metadata", function () { ""; const metadata = createMetadata(data); - expect(metadata.has("dc:title")).toBeTruthy(); - expect(metadata.has("dc:qux")).toBeFalsy(); - expect(metadata.get("dc:title")).toEqual("a&lol9;b"); expect(metadata.get("dc:qux")).toEqual(null); - expect(metadata.getAll()).toEqual({ "dc:title": "a&lol9;b" }); + expect([...metadata]).toEqual([["dc:title", "a&lol9;b"]]); }); });