Skip to content

Commit 584902d

Browse files
committed
Add an annotation storage in order to save annotation data in acroforms
1 parent d69fb44 commit 584902d

13 files changed

+152
-7
lines changed

src/core/annotation.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ class Annotation {
509509
});
510510
}
511511

512-
getOperatorList(evaluator, task, renderForms) {
512+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
513513
if (!this.appearance) {
514514
return Promise.resolve(new OperatorList());
515515
}
@@ -877,13 +877,18 @@ class WidgetAnnotation extends Annotation {
877877
return !!(this.data.fieldFlags & flag);
878878
}
879879

880-
getOperatorList(evaluator, task, renderForms) {
880+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
881881
// Do not render form elements on the canvas when interactive forms are
882882
// enabled. The display layer is responsible for rendering them instead.
883883
if (renderForms) {
884884
return Promise.resolve(new OperatorList());
885885
}
886-
return super.getOperatorList(evaluator, task, renderForms);
886+
return super.getOperatorList(
887+
evaluator,
888+
task,
889+
renderForms,
890+
annotationStorage
891+
);
887892
}
888893
}
889894

@@ -920,9 +925,14 @@ class TextWidgetAnnotation extends WidgetAnnotation {
920925
this.data.maxLen !== null;
921926
}
922927

923-
getOperatorList(evaluator, task, renderForms) {
928+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
924929
if (renderForms || this.appearance) {
925-
return super.getOperatorList(evaluator, task, renderForms);
930+
return super.getOperatorList(
931+
evaluator,
932+
task,
933+
renderForms,
934+
annotationStorage
935+
);
926936
}
927937

928938
const operatorList = new OperatorList();

src/core/document.js

+14-2
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,14 @@ class Page {
238238
});
239239
}
240240

241-
getOperatorList({ handler, sink, task, intent, renderInteractiveForms }) {
241+
getOperatorList({
242+
handler,
243+
sink,
244+
task,
245+
intent,
246+
renderInteractiveForms,
247+
annotationStorage,
248+
}) {
242249
const contentStreamPromise = this.pdfManager.ensure(
243250
this,
244251
"getContentStream"
@@ -301,7 +308,12 @@ class Page {
301308
if (isAnnotationRenderable(annotation, intent)) {
302309
opListPromises.push(
303310
annotation
304-
.getOperatorList(partialEvaluator, task, renderInteractiveForms)
311+
.getOperatorList(
312+
partialEvaluator,
313+
task,
314+
renderInteractiveForms,
315+
annotationStorage
316+
)
305317
.catch(function (reason) {
306318
warn(
307319
"getOperatorList - ignoring annotation data during " +

src/core/worker.js

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ class WorkerMessageHandler {
532532
task,
533533
intent: data.intent,
534534
renderInteractiveForms: data.renderInteractiveForms,
535+
annotationStorage: data.annotationStorage,
535536
})
536537
.then(
537538
function (operatorListInfo) {

src/display/annotation_layer.js

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class AnnotationElement {
140140
this.imageResourcesPath = parameters.imageResourcesPath;
141141
this.renderInteractiveForms = parameters.renderInteractiveForms;
142142
this.svgFactory = parameters.svgFactory;
143+
this.annotationStorage = parameters.annotationStorage;
143144

144145
if (isRenderable) {
145146
this.container = this._createContainer(ignoreBorder);
@@ -1450,6 +1451,7 @@ class AnnotationLayer {
14501451
imageResourcesPath: parameters.imageResourcesPath || "",
14511452
renderInteractiveForms: parameters.renderInteractiveForms || false,
14521453
svgFactory: new DOMSVGFactory(),
1454+
annotationStorage: parameters.annotationStorage,
14531455
});
14541456
if (element.isRenderable) {
14551457
parameters.div.appendChild(element.render());

src/display/annotation_storage.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* Copyright 2020 Mozilla Foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
class AnnotationStorage {
17+
constructor() {
18+
this._storage = {};
19+
}
20+
21+
/**
22+
* Get the value for a given key if it exists
23+
* or store and return the default value
24+
*
25+
* @public
26+
* @memberof AnnotationStorage
27+
* @param {string} key
28+
* @param {Object} defaultValue
29+
* @returns {Object}
30+
*/
31+
getOrCreateValue(key, defaultValue) {
32+
if (key in this._storage) {
33+
return this._storage[key];
34+
}
35+
36+
this._storage[key] = defaultValue;
37+
return defaultValue;
38+
}
39+
40+
/**
41+
* Set the value for a given key
42+
*
43+
* @public
44+
* @memberof AnnotationStorage
45+
* @param {string} key
46+
* @param {Object} value
47+
*/
48+
setValue(key, value) {
49+
this._storage[key] = value;
50+
}
51+
52+
getAll() {
53+
return this._storage;
54+
}
55+
}
56+
57+
export { AnnotationStorage };

src/display/api.js

+11
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
} from "./display_utils.js";
4949
import { FontFaceObject, FontLoader } from "./font_loader.js";
5050
import { NodeCanvasFactory, NodeCMapReaderFactory } from "./node_utils.js";
51+
import { AnnotationStorage } from "./annotation_storage.js";
5152
import { apiCompatibilityParams } from "./api_compatibility.js";
5253
import { CanvasGraphics } from "./canvas.js";
5354
import { GlobalWorkerOptions } from "./worker_options.js";
@@ -576,6 +577,14 @@ class PDFDocumentProxy {
576577
constructor(pdfInfo, transport) {
577578
this._pdfInfo = pdfInfo;
578579
this._transport = transport;
580+
this._annotationStorage = new AnnotationStorage();
581+
}
582+
583+
/**
584+
* @type {AnnotationStorage} Storage for annotation data in forms.
585+
*/
586+
get annotationStorage() {
587+
return this._annotationStorage;
579588
}
580589

581590
/**
@@ -1004,6 +1013,7 @@ class PDFPageProxy {
10041013
imageLayer = null,
10051014
canvasFactory = null,
10061015
background = null,
1016+
annotationStorage = null,
10071017
}) {
10081018
if (this._stats) {
10091019
this._stats.time("Overall");
@@ -1048,6 +1058,7 @@ class PDFPageProxy {
10481058
pageIndex: this._pageIndex,
10491059
intent: renderingIntent,
10501060
renderInteractiveForms: renderInteractiveForms === true,
1061+
annotationStorage,
10511062
});
10521063
}
10531064

test/unit/annotation_storage_spec.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* Copyright 2020 Mozilla Foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
import { AnnotationStorage } from "../../src/display/annotation_storage.js";
17+
18+
describe("AnnotationStorage", function () {
19+
describe("GetOrCreateValue", function () {
20+
it("should get and set a new value in the annotation storage", function (done) {
21+
const annotationStorage = new AnnotationStorage();
22+
let value = annotationStorage.getOrCreateValue("123A", "hello world");
23+
expect(value).toEqual("hello world");
24+
25+
// the second argument is the default value to use
26+
// if the key isn't in the storage
27+
value = annotationStorage.getOrCreateValue("123A", "an other string");
28+
expect(value).toEqual("hello world");
29+
done();
30+
});
31+
});
32+
33+
describe("SetValue", function () {
34+
it("should set a new value in the annotation storage", function (done) {
35+
const annotationStorage = new AnnotationStorage();
36+
annotationStorage.setValue("123A", "an other string");
37+
const value = annotationStorage.getAll()["123A"];
38+
expect(value).toEqual("an other string");
39+
done();
40+
});
41+
});
42+
});

test/unit/clitests.json

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
"spec_files": [
99
"annotation_spec.js",
10+
"annotation_storage_spec.js",
1011
"api_spec.js",
1112
"bidi_spec.js",
1213
"cff_parser_spec.js",

test/unit/jasmine-boot.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ function initializePDFJS(callback) {
4949
"pdfjs/display/fetch_stream.js",
5050
"pdfjs/shared/is_node.js",
5151
"pdfjs-test/unit/annotation_spec.js",
52+
"pdfjs-test/unit/annotation_storage_spec.js",
5253
"pdfjs-test/unit/api_spec.js",
5354
"pdfjs-test/unit/bidi_spec.js",
5455
"pdfjs-test/unit/cff_parser_spec.js",

web/annotation_layer_builder.js

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class AnnotationLayerBuilder {
3838
pdfPage,
3939
linkService,
4040
downloadManager,
41+
annotationStorage,
4142
imageResourcesPath = "",
4243
renderInteractiveForms = false,
4344
l10n = NullL10n,
@@ -49,6 +50,7 @@ class AnnotationLayerBuilder {
4950
this.imageResourcesPath = imageResourcesPath;
5051
this.renderInteractiveForms = renderInteractiveForms;
5152
this.l10n = l10n;
53+
this.annotationStorage = annotationStorage;
5254

5355
this.div = null;
5456
this._cancelled = false;
@@ -73,6 +75,7 @@ class AnnotationLayerBuilder {
7375
renderInteractiveForms: this.renderInteractiveForms,
7476
linkService: this.linkService,
7577
downloadManager: this.downloadManager,
78+
annotationStorage: this.annotationStorage,
7679
};
7780

7881
if (this.div) {
@@ -124,6 +127,7 @@ class DefaultAnnotationLayerFactory {
124127
createAnnotationLayerBuilder(
125128
pageDiv,
126129
pdfPage,
130+
annotationStorage,
127131
imageResourcesPath = "",
128132
renderInteractiveForms = false,
129133
l10n = NullL10n
@@ -135,6 +139,7 @@ class DefaultAnnotationLayerFactory {
135139
renderInteractiveForms,
136140
linkService: new SimpleLinkService(),
137141
l10n,
142+
annotationStorage,
138143
});
139144
}
140145
}

web/base_viewer.js

+1
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,7 @@ class BaseViewer {
11641164
renderInteractiveForms,
11651165
linkService: this.linkService,
11661166
downloadManager: this.downloadManager,
1167+
annotationStorage: this.pdfDocument.annotationStorage,
11671168
l10n,
11681169
});
11691170
}

web/firefox_print_service.js

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ function composePage(pdfDocument, pageNumber, size, printContainer) {
5353
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
5454
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
5555
intent: "print",
56+
annotationStorage: pdfDocument.annotationStorage.getAll(),
5657
};
5758
return pdfPage.render(renderContext).promise;
5859
})

web/pdf_print_service.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) {
4949
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
5050
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
5151
intent: "print",
52+
annotationStorage: pdfDocument.annotationStorage.getAll(),
5253
};
5354
return pdfPage.render(renderContext).promise;
5455
})

0 commit comments

Comments
 (0)