Merge pull request #12106 from calixteman/storage

Add an annotation storage in order to save annotation data in acroforms
This commit is contained in:
Tim van der Meij 2020-07-24 23:49:37 +02:00 committed by GitHub
commit bf539deada
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 152 additions and 7 deletions

View File

@ -509,7 +509,7 @@ class Annotation {
}); });
} }
getOperatorList(evaluator, task, renderForms) { getOperatorList(evaluator, task, renderForms, annotationStorage) {
if (!this.appearance) { if (!this.appearance) {
return Promise.resolve(new OperatorList()); return Promise.resolve(new OperatorList());
} }
@ -877,13 +877,18 @@ class WidgetAnnotation extends Annotation {
return !!(this.data.fieldFlags & flag); return !!(this.data.fieldFlags & flag);
} }
getOperatorList(evaluator, task, renderForms) { getOperatorList(evaluator, task, renderForms, annotationStorage) {
// Do not render form elements on the canvas when interactive forms are // Do not render form elements on the canvas when interactive forms are
// enabled. The display layer is responsible for rendering them instead. // enabled. The display layer is responsible for rendering them instead.
if (renderForms) { if (renderForms) {
return Promise.resolve(new OperatorList()); return Promise.resolve(new OperatorList());
} }
return super.getOperatorList(evaluator, task, renderForms); return super.getOperatorList(
evaluator,
task,
renderForms,
annotationStorage
);
} }
} }
@ -920,9 +925,14 @@ class TextWidgetAnnotation extends WidgetAnnotation {
this.data.maxLen !== null; this.data.maxLen !== null;
} }
getOperatorList(evaluator, task, renderForms) { getOperatorList(evaluator, task, renderForms, annotationStorage) {
if (renderForms || this.appearance) { if (renderForms || this.appearance) {
return super.getOperatorList(evaluator, task, renderForms); return super.getOperatorList(
evaluator,
task,
renderForms,
annotationStorage
);
} }
const operatorList = new OperatorList(); const operatorList = new OperatorList();

View File

@ -238,7 +238,14 @@ class Page {
}); });
} }
getOperatorList({ handler, sink, task, intent, renderInteractiveForms }) { getOperatorList({
handler,
sink,
task,
intent,
renderInteractiveForms,
annotationStorage,
}) {
const contentStreamPromise = this.pdfManager.ensure( const contentStreamPromise = this.pdfManager.ensure(
this, this,
"getContentStream" "getContentStream"
@ -301,7 +308,12 @@ class Page {
if (isAnnotationRenderable(annotation, intent)) { if (isAnnotationRenderable(annotation, intent)) {
opListPromises.push( opListPromises.push(
annotation annotation
.getOperatorList(partialEvaluator, task, renderInteractiveForms) .getOperatorList(
partialEvaluator,
task,
renderInteractiveForms,
annotationStorage
)
.catch(function (reason) { .catch(function (reason) {
warn( warn(
"getOperatorList - ignoring annotation data during " + "getOperatorList - ignoring annotation data during " +

View File

@ -532,6 +532,7 @@ class WorkerMessageHandler {
task, task,
intent: data.intent, intent: data.intent,
renderInteractiveForms: data.renderInteractiveForms, renderInteractiveForms: data.renderInteractiveForms,
annotationStorage: data.annotationStorage,
}) })
.then( .then(
function (operatorListInfo) { function (operatorListInfo) {

View File

@ -140,6 +140,7 @@ class AnnotationElement {
this.imageResourcesPath = parameters.imageResourcesPath; this.imageResourcesPath = parameters.imageResourcesPath;
this.renderInteractiveForms = parameters.renderInteractiveForms; this.renderInteractiveForms = parameters.renderInteractiveForms;
this.svgFactory = parameters.svgFactory; this.svgFactory = parameters.svgFactory;
this.annotationStorage = parameters.annotationStorage;
if (isRenderable) { if (isRenderable) {
this.container = this._createContainer(ignoreBorder); this.container = this._createContainer(ignoreBorder);
@ -1450,6 +1451,7 @@ class AnnotationLayer {
imageResourcesPath: parameters.imageResourcesPath || "", imageResourcesPath: parameters.imageResourcesPath || "",
renderInteractiveForms: parameters.renderInteractiveForms || false, renderInteractiveForms: parameters.renderInteractiveForms || false,
svgFactory: new DOMSVGFactory(), svgFactory: new DOMSVGFactory(),
annotationStorage: parameters.annotationStorage,
}); });
if (element.isRenderable) { if (element.isRenderable) {
parameters.div.appendChild(element.render()); parameters.div.appendChild(element.render());

View File

@ -0,0 +1,57 @@
/* Copyright 2020 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class AnnotationStorage {
constructor() {
this._storage = {};
}
/**
* Get the value for a given key if it exists
* or store and return the default value
*
* @public
* @memberof AnnotationStorage
* @param {string} key
* @param {Object} defaultValue
* @returns {Object}
*/
getOrCreateValue(key, defaultValue) {
if (key in this._storage) {
return this._storage[key];
}
this._storage[key] = defaultValue;
return defaultValue;
}
/**
* Set the value for a given key
*
* @public
* @memberof AnnotationStorage
* @param {string} key
* @param {Object} value
*/
setValue(key, value) {
this._storage[key] = value;
}
getAll() {
return this._storage;
}
}
export { AnnotationStorage };

View File

@ -48,6 +48,7 @@ import {
} from "./display_utils.js"; } from "./display_utils.js";
import { FontFaceObject, FontLoader } from "./font_loader.js"; import { FontFaceObject, FontLoader } from "./font_loader.js";
import { NodeCanvasFactory, NodeCMapReaderFactory } from "./node_utils.js"; import { NodeCanvasFactory, NodeCMapReaderFactory } from "./node_utils.js";
import { AnnotationStorage } from "./annotation_storage.js";
import { apiCompatibilityParams } from "./api_compatibility.js"; import { apiCompatibilityParams } from "./api_compatibility.js";
import { CanvasGraphics } from "./canvas.js"; import { CanvasGraphics } from "./canvas.js";
import { GlobalWorkerOptions } from "./worker_options.js"; import { GlobalWorkerOptions } from "./worker_options.js";
@ -576,6 +577,14 @@ class PDFDocumentProxy {
constructor(pdfInfo, transport) { constructor(pdfInfo, transport) {
this._pdfInfo = pdfInfo; this._pdfInfo = pdfInfo;
this._transport = transport; this._transport = transport;
this._annotationStorage = new AnnotationStorage();
}
/**
* @type {AnnotationStorage} Storage for annotation data in forms.
*/
get annotationStorage() {
return this._annotationStorage;
} }
/** /**
@ -1004,6 +1013,7 @@ class PDFPageProxy {
imageLayer = null, imageLayer = null,
canvasFactory = null, canvasFactory = null,
background = null, background = null,
annotationStorage = null,
}) { }) {
if (this._stats) { if (this._stats) {
this._stats.time("Overall"); this._stats.time("Overall");
@ -1048,6 +1058,7 @@ class PDFPageProxy {
pageIndex: this._pageIndex, pageIndex: this._pageIndex,
intent: renderingIntent, intent: renderingIntent,
renderInteractiveForms: renderInteractiveForms === true, renderInteractiveForms: renderInteractiveForms === true,
annotationStorage,
}); });
} }

View File

@ -0,0 +1,42 @@
/* Copyright 2020 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AnnotationStorage } from "../../src/display/annotation_storage.js";
describe("AnnotationStorage", function () {
describe("GetOrCreateValue", function () {
it("should get and set a new value in the annotation storage", function (done) {
const annotationStorage = new AnnotationStorage();
let value = annotationStorage.getOrCreateValue("123A", "hello world");
expect(value).toEqual("hello world");
// the second argument is the default value to use
// if the key isn't in the storage
value = annotationStorage.getOrCreateValue("123A", "an other string");
expect(value).toEqual("hello world");
done();
});
});
describe("SetValue", function () {
it("should set a new value in the annotation storage", function (done) {
const annotationStorage = new AnnotationStorage();
annotationStorage.setValue("123A", "an other string");
const value = annotationStorage.getAll()["123A"];
expect(value).toEqual("an other string");
done();
});
});
});

View File

@ -7,6 +7,7 @@
"spec_files": [ "spec_files": [
"annotation_spec.js", "annotation_spec.js",
"annotation_storage_spec.js",
"api_spec.js", "api_spec.js",
"bidi_spec.js", "bidi_spec.js",
"cff_parser_spec.js", "cff_parser_spec.js",

View File

@ -49,6 +49,7 @@ function initializePDFJS(callback) {
"pdfjs/display/fetch_stream.js", "pdfjs/display/fetch_stream.js",
"pdfjs/shared/is_node.js", "pdfjs/shared/is_node.js",
"pdfjs-test/unit/annotation_spec.js", "pdfjs-test/unit/annotation_spec.js",
"pdfjs-test/unit/annotation_storage_spec.js",
"pdfjs-test/unit/api_spec.js", "pdfjs-test/unit/api_spec.js",
"pdfjs-test/unit/bidi_spec.js", "pdfjs-test/unit/bidi_spec.js",
"pdfjs-test/unit/cff_parser_spec.js", "pdfjs-test/unit/cff_parser_spec.js",

View File

@ -38,6 +38,7 @@ class AnnotationLayerBuilder {
pdfPage, pdfPage,
linkService, linkService,
downloadManager, downloadManager,
annotationStorage,
imageResourcesPath = "", imageResourcesPath = "",
renderInteractiveForms = false, renderInteractiveForms = false,
l10n = NullL10n, l10n = NullL10n,
@ -49,6 +50,7 @@ class AnnotationLayerBuilder {
this.imageResourcesPath = imageResourcesPath; this.imageResourcesPath = imageResourcesPath;
this.renderInteractiveForms = renderInteractiveForms; this.renderInteractiveForms = renderInteractiveForms;
this.l10n = l10n; this.l10n = l10n;
this.annotationStorage = annotationStorage;
this.div = null; this.div = null;
this._cancelled = false; this._cancelled = false;
@ -73,6 +75,7 @@ class AnnotationLayerBuilder {
renderInteractiveForms: this.renderInteractiveForms, renderInteractiveForms: this.renderInteractiveForms,
linkService: this.linkService, linkService: this.linkService,
downloadManager: this.downloadManager, downloadManager: this.downloadManager,
annotationStorage: this.annotationStorage,
}; };
if (this.div) { if (this.div) {
@ -124,6 +127,7 @@ class DefaultAnnotationLayerFactory {
createAnnotationLayerBuilder( createAnnotationLayerBuilder(
pageDiv, pageDiv,
pdfPage, pdfPage,
annotationStorage,
imageResourcesPath = "", imageResourcesPath = "",
renderInteractiveForms = false, renderInteractiveForms = false,
l10n = NullL10n l10n = NullL10n
@ -135,6 +139,7 @@ class DefaultAnnotationLayerFactory {
renderInteractiveForms, renderInteractiveForms,
linkService: new SimpleLinkService(), linkService: new SimpleLinkService(),
l10n, l10n,
annotationStorage,
}); });
} }
} }

View File

@ -1164,6 +1164,7 @@ class BaseViewer {
renderInteractiveForms, renderInteractiveForms,
linkService: this.linkService, linkService: this.linkService,
downloadManager: this.downloadManager, downloadManager: this.downloadManager,
annotationStorage: this.pdfDocument.annotationStorage,
l10n, l10n,
}); });
} }

View File

@ -53,6 +53,7 @@ function composePage(pdfDocument, pageNumber, size, printContainer) {
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }), viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
intent: "print", intent: "print",
annotationStorage: pdfDocument.annotationStorage.getAll(),
}; };
return pdfPage.render(renderContext).promise; return pdfPage.render(renderContext).promise;
}) })

View File

@ -49,6 +49,7 @@ function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) {
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }), viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
intent: "print", intent: "print",
annotationStorage: pdfDocument.annotationStorage.getAll(),
}; };
return pdfPage.render(renderContext).promise; return pdfPage.render(renderContext).promise;
}) })