diff --git a/src/core/annotation.js b/src/core/annotation.js index 2db3b26ef..f1b82f7e0 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -348,9 +348,10 @@ class Annotation { } isHidden(annotationStorage) { - const data = annotationStorage && annotationStorage[this.data.id]; - if (data && "hidden" in data) { - return data.hidden; + const storageEntry = + annotationStorage && annotationStorage.get(this.data.id); + if (storageEntry && storageEntry.hidden !== undefined) { + return storageEntry.hidden; } return this._hasFlag(this.flags, AnnotationFlag.HIDDEN); } @@ -1206,8 +1207,11 @@ class WidgetAnnotation extends Annotation { } async save(evaluator, task, annotationStorage) { - const value = - annotationStorage[this.data.id] && annotationStorage[this.data.id].value; + if (!annotationStorage) { + return null; + } + const storageEntry = annotationStorage.get(this.data.id); + const value = storageEntry && storageEntry.value; if (value === this.data.fieldValue || value === undefined) { return null; } @@ -1289,8 +1293,8 @@ class WidgetAnnotation extends Annotation { if (!annotationStorage || isPassword) { return null; } - let value = - annotationStorage[this.data.id] && annotationStorage[this.data.id].value; + const storageEntry = annotationStorage.get(this.data.id); + let value = storageEntry && storageEntry.value; if (value === undefined) { // The annotation hasn't been rendered so use the appearance return null; @@ -1769,9 +1773,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } if (annotationStorage) { - const value = - annotationStorage[this.data.id] && - annotationStorage[this.data.id].value; + const storageEntry = annotationStorage.get(this.data.id); + const value = storageEntry && storageEntry.value; if (value === undefined) { return super.getOperatorList( evaluator, @@ -1826,8 +1829,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } async _saveCheckbox(evaluator, task, annotationStorage) { - const value = - annotationStorage[this.data.id] && annotationStorage[this.data.id].value; + if (!annotationStorage) { + return null; + } + const storageEntry = annotationStorage.get(this.data.id); + const value = storageEntry && storageEntry.value; if (value === undefined) { return null; } @@ -1869,8 +1875,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } async _saveRadioButton(evaluator, task, annotationStorage) { - const value = - annotationStorage[this.data.id] && annotationStorage[this.data.id].value; + if (!annotationStorage) { + return null; + } + const storageEntry = annotationStorage.get(this.data.id); + const value = storageEntry && storageEntry.value; if (value === undefined) { return null; } diff --git a/src/display/annotation_storage.js b/src/display/annotation_storage.js index ae30af211..5af4cf59a 100644 --- a/src/display/annotation_storage.js +++ b/src/display/annotation_storage.js @@ -91,10 +91,7 @@ class AnnotationStorage { } getAll() { - if (this._storage.size === 0) { - return null; - } - return objectFromEntries(this._storage); + return this._storage.size > 0 ? objectFromEntries(this._storage) : null; } get size() { @@ -121,6 +118,14 @@ class AnnotationStorage { } } } + + /** + * PLEASE NOTE: Only intended for usage within the API itself. + * @ignore + */ + get serializable() { + return this._storage.size > 0 ? this._storage : null; + } } export { AnnotationStorage }; diff --git a/src/display/api.js b/src/display/api.js index 925e73a4a..d3a9d6362 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -1214,7 +1214,7 @@ class PDFPageProxy { pageIndex: this._pageIndex, intent: renderingIntent, renderInteractiveForms: renderInteractiveForms === true, - annotationStorage: annotationStorage?.getAll() || null, + annotationStorage: annotationStorage?.serializable || null, }); } @@ -2613,7 +2613,7 @@ class WorkerTransport { return this.messageHandler .sendWithPromise("SaveDocument", { numPages: this._numPages, - annotationStorage: annotationStorage?.getAll() || null, + annotationStorage: annotationStorage?.serializable || null, filename: this._fullReader?.filename ?? null, }) .finally(() => { diff --git a/test/unit/annotation_spec.js b/test/unit/annotation_spec.js index fb2a17875..0ff9cd69b 100644 --- a/test/unit/annotation_spec.js +++ b/test/unit/annotation_spec.js @@ -1672,9 +1672,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "test\\print" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "test\\print" }); + return annotation._getAppearance( partialEvaluator, task, @@ -1709,9 +1709,11 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "こんにちは世界の" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { + value: "こんにちは世界の", + }); + return annotation._getAppearance( partialEvaluator, task, @@ -1756,7 +1758,8 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; + const annotationStorage = new Map(); + return annotation.getOperatorList( partialEvaluator, task, @@ -1797,9 +1800,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "test (print)" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "test (print)" }); + return annotation._getAppearance( partialEvaluator, task, @@ -1834,9 +1837,11 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "こんにちは世界の" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { + value: "こんにちは世界の", + }); + return annotation._getAppearance( partialEvaluator, task, @@ -1873,9 +1878,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "mypassword" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "mypassword" }); + return annotation._getAppearance( partialEvaluator, task, @@ -1906,13 +1911,13 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "a aa aaa aaaa aaaaa aaaaaa " + "pneumonoultramicroscopicsilicovolcanoconiosis", - }; + }); + return annotation._getAppearance( partialEvaluator, task, @@ -1954,9 +1959,11 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "こんにちは世界の" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { + value: "こんにちは世界の", + }); + return annotation._getAppearance( partialEvaluator, task, @@ -2014,9 +2021,8 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r" + "Aliquam vitae felis ac lectus bibendum ultricies quis non diam.\n" + @@ -2026,7 +2032,8 @@ describe("annotation", function () { "Nulla consectetur, ligula in tincidunt placerat, " + "velit augue consectetur orci, sed mattis libero nunc ut massa.\r" + "Etiam facilisis tempus interdum.", - }; + }); + return annotation._getAppearance( partialEvaluator, task, @@ -2058,9 +2065,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "aa(aa)a\\" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "aa(aa)a\\" }); + return annotation._getAppearance( partialEvaluator, task, @@ -2101,9 +2108,11 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "こんにちは世界の" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { + value: "こんにちは世界の", + }); + return annotation._getAppearance( partialEvaluator, task, @@ -2138,8 +2147,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: "hello world" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "hello world" }); + return annotation.save(partialEvaluator, task, annotationStorage); }, done.fail) .then(data => { @@ -2270,8 +2280,11 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: "こんにちは世界の" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { + value: "こんにちは世界の", + }); + return annotation.save(partialEvaluator, task, annotationStorage); }, done.fail) .then(data => { @@ -2440,8 +2453,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return annotation.getOperatorList( partialEvaluator, task, @@ -2498,8 +2512,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.getOperatorList( @@ -2523,8 +2538,9 @@ describe("annotation", function () { return annotation; }, done.fail) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: false }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: false }); + return annotation.getOperatorList( partialEvaluator, task, @@ -2581,8 +2597,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.getOperatorList( @@ -2606,8 +2623,9 @@ describe("annotation", function () { return annotation; }) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return annotation.getOperatorList( partialEvaluator, task, @@ -2665,7 +2683,8 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; + const annotationStorage = new Map(); + return annotation.getOperatorList( partialEvaluator, task, @@ -2713,8 +2732,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.save(partialEvaluator, task, annotationStorage), @@ -2732,8 +2752,9 @@ describe("annotation", function () { return annotation; }, done.fail) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: false }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: false }); + return annotation.save(partialEvaluator, task, annotationStorage); }, done.fail) .then(data => { @@ -2875,8 +2896,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.getOperatorList( @@ -2900,8 +2922,9 @@ describe("annotation", function () { return annotation; }, done.fail) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: false }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: false }); + return annotation.getOperatorList( partialEvaluator, task, @@ -2959,7 +2982,8 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; + const annotationStorage = new Map(); + return annotation.getOperatorList( partialEvaluator, task, @@ -3018,8 +3042,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.save(partialEvaluator, task, annotationStorage), @@ -3044,8 +3069,9 @@ describe("annotation", function () { return annotation; }, done.fail) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: false }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: false }); + return annotation.save(partialEvaluator, task, annotationStorage); }, done.fail) .then(data => { @@ -3089,8 +3115,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: true }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: true }); + return Promise.all([ annotation, annotation.save(partialEvaluator, task, annotationStorage), @@ -3130,7 +3157,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - return annotation.save(partialEvaluator, task, {}); + const annotationStorage = new Map(); + + return annotation.save(partialEvaluator, task, annotationStorage); }) .then(data => { expect(data).toEqual(null); @@ -3535,9 +3564,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const id = annotation.data.id; - const annotationStorage = {}; - annotationStorage[id] = { value: "a value" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "a value" }); + return annotation._getAppearance( partialEvaluator, task, @@ -3571,8 +3600,9 @@ describe("annotation", function () { idFactoryMock ) .then(annotation => { - const annotationStorage = {}; - annotationStorage[annotation.data.id] = { value: "C" }; + const annotationStorage = new Map(); + annotationStorage.set(annotation.data.id, { value: "C" }); + return annotation.save(partialEvaluator, task, annotationStorage); }, done.fail) .then(data => {