mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
Re-factor document.getElementsByName
lookups in the AnnotationLayer (issue 14003)
This replaces direct `document.getElementsByName` lookups with a helper method which: - Lets the AnnotationLayer use the data returned by the `PDFDocumentProxy.getFieldObjects` API-method, such that we can directly lookup only the necessary DOM elements. - Fallback to using `document.getElementsByName` as before, such that e.g. the standalone viewer components still work. Finally, to fix the problems reported in issue 14003, regardless of the code-path we now also enforce that the DOM elements found were actually created by the AnnotationLayer code. With these changes we'll thus be able to update form elements on all visible pages just as before, but we'll additionally update the AnnotationStorage for not-yet-rendered elements thus fixing a pre-existing bug.
This commit is contained in:
parent
8dc22f40c7
commit
6cba5509f2
6 changed files with 149 additions and 78 deletions
|
@ -33,6 +33,8 @@ import { SimpleLinkService } from "./pdf_link_service.js";
|
|||
* @property {IL10n} l10n - Localization service.
|
||||
* @property {boolean} [enableScripting]
|
||||
* @property {Promise<boolean>} [hasJSActionsPromise]
|
||||
* @property {Promise<Object<string, Array<Object>> | null>}
|
||||
* [fieldObjectsPromise]
|
||||
* @property {Object} [mouseState]
|
||||
*/
|
||||
|
||||
|
@ -51,6 +53,7 @@ class AnnotationLayerBuilder {
|
|||
l10n = NullL10n,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
fieldObjectsPromise = null,
|
||||
mouseState = null,
|
||||
}) {
|
||||
this.pageDiv = pageDiv;
|
||||
|
@ -63,6 +66,7 @@ class AnnotationLayerBuilder {
|
|||
this.annotationStorage = annotationStorage;
|
||||
this.enableScripting = enableScripting;
|
||||
this._hasJSActionsPromise = hasJSActionsPromise;
|
||||
this._fieldObjectsPromise = fieldObjectsPromise;
|
||||
this._mouseState = mouseState;
|
||||
|
||||
this.div = null;
|
||||
|
@ -75,46 +79,49 @@ class AnnotationLayerBuilder {
|
|||
* @returns {Promise<void>} A promise that is resolved when rendering of the
|
||||
* annotations is complete.
|
||||
*/
|
||||
render(viewport, intent = "display") {
|
||||
return Promise.all([
|
||||
this.pdfPage.getAnnotations({ intent }),
|
||||
this._hasJSActionsPromise,
|
||||
]).then(([annotations, hasJSActions = false]) => {
|
||||
if (this._cancelled || annotations.length === 0) {
|
||||
return;
|
||||
}
|
||||
async render(viewport, intent = "display") {
|
||||
const [annotations, hasJSActions = false, fieldObjects = null] =
|
||||
await Promise.all([
|
||||
this.pdfPage.getAnnotations({ intent }),
|
||||
this._hasJSActionsPromise,
|
||||
this._fieldObjectsPromise,
|
||||
]);
|
||||
|
||||
const parameters = {
|
||||
viewport: viewport.clone({ dontFlip: true }),
|
||||
div: this.div,
|
||||
annotations,
|
||||
page: this.pdfPage,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
renderForms: this.renderForms,
|
||||
linkService: this.linkService,
|
||||
downloadManager: this.downloadManager,
|
||||
annotationStorage: this.annotationStorage,
|
||||
enableScripting: this.enableScripting,
|
||||
hasJSActions,
|
||||
mouseState: this._mouseState,
|
||||
};
|
||||
if (this._cancelled || annotations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.div) {
|
||||
// If an annotationLayer already exists, refresh its children's
|
||||
// transformation matrices.
|
||||
AnnotationLayer.update(parameters);
|
||||
} else {
|
||||
// Create an annotation layer div and render the annotations
|
||||
// if there is at least one annotation.
|
||||
this.div = document.createElement("div");
|
||||
this.div.className = "annotationLayer";
|
||||
this.pageDiv.appendChild(this.div);
|
||||
parameters.div = this.div;
|
||||
const parameters = {
|
||||
viewport: viewport.clone({ dontFlip: true }),
|
||||
div: this.div,
|
||||
annotations,
|
||||
page: this.pdfPage,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
renderForms: this.renderForms,
|
||||
linkService: this.linkService,
|
||||
downloadManager: this.downloadManager,
|
||||
annotationStorage: this.annotationStorage,
|
||||
enableScripting: this.enableScripting,
|
||||
hasJSActions,
|
||||
fieldObjects,
|
||||
mouseState: this._mouseState,
|
||||
};
|
||||
|
||||
AnnotationLayer.render(parameters);
|
||||
this.l10n.translate(this.div);
|
||||
}
|
||||
});
|
||||
if (this.div) {
|
||||
// If an annotationLayer already exists, refresh its children's
|
||||
// transformation matrices.
|
||||
AnnotationLayer.update(parameters);
|
||||
} else {
|
||||
// Create an annotation layer div and render the annotations
|
||||
// if there is at least one annotation.
|
||||
this.div = document.createElement("div");
|
||||
this.div.className = "annotationLayer";
|
||||
this.pageDiv.appendChild(this.div);
|
||||
parameters.div = this.div;
|
||||
|
||||
AnnotationLayer.render(parameters);
|
||||
this.l10n.translate(this.div);
|
||||
}
|
||||
}
|
||||
|
||||
cancel() {
|
||||
|
@ -144,6 +151,8 @@ class DefaultAnnotationLayerFactory {
|
|||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
* @param {Object} [mouseState]
|
||||
* @param {Promise<Object<string, Array<Object>> | null>}
|
||||
* [fieldObjectsPromise]
|
||||
* @returns {AnnotationLayerBuilder}
|
||||
*/
|
||||
createAnnotationLayerBuilder(
|
||||
|
@ -155,7 +164,8 @@ class DefaultAnnotationLayerFactory {
|
|||
l10n = NullL10n,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
mouseState = null
|
||||
mouseState = null,
|
||||
fieldObjectsPromise = null
|
||||
) {
|
||||
return new AnnotationLayerBuilder({
|
||||
pageDiv,
|
||||
|
@ -167,6 +177,7 @@ class DefaultAnnotationLayerFactory {
|
|||
annotationStorage,
|
||||
enableScripting,
|
||||
hasJSActionsPromise,
|
||||
fieldObjectsPromise,
|
||||
mouseState,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1318,6 +1318,8 @@ class BaseViewer {
|
|||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
* @param {Object} [mouseState]
|
||||
* @param {Promise<Object<string, Array<Object>> | null>}
|
||||
* [fieldObjectsPromise]
|
||||
* @returns {AnnotationLayerBuilder}
|
||||
*/
|
||||
createAnnotationLayerBuilder(
|
||||
|
@ -1329,7 +1331,8 @@ class BaseViewer {
|
|||
l10n = NullL10n,
|
||||
enableScripting = null,
|
||||
hasJSActionsPromise = null,
|
||||
mouseState = null
|
||||
mouseState = null,
|
||||
fieldObjectsPromise = null
|
||||
) {
|
||||
return new AnnotationLayerBuilder({
|
||||
pageDiv,
|
||||
|
@ -1344,6 +1347,8 @@ class BaseViewer {
|
|||
enableScripting: enableScripting ?? this.enableScripting,
|
||||
hasJSActionsPromise:
|
||||
hasJSActionsPromise || this.pdfDocument?.hasJSActions(),
|
||||
fieldObjectsPromise:
|
||||
fieldObjectsPromise || this.pdfDocument?.getFieldObjects(),
|
||||
mouseState: mouseState || this._scriptingManager?.mouseState,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ class IPDFAnnotationLayerFactory {
|
|||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
* @param {Object} [mouseState]
|
||||
* @param {Promise<Object<string, Array<Object>> | null>}
|
||||
* [fieldObjectsPromise]
|
||||
* @returns {AnnotationLayerBuilder}
|
||||
*/
|
||||
createAnnotationLayerBuilder(
|
||||
|
@ -177,7 +179,8 @@ class IPDFAnnotationLayerFactory {
|
|||
l10n = undefined,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
mouseState = null
|
||||
mouseState = null,
|
||||
fieldObjectsPromise = null
|
||||
) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -675,7 +675,8 @@ class PDFPageView {
|
|||
this.l10n,
|
||||
/* enableScripting = */ null,
|
||||
/* hasJSActionsPromise = */ null,
|
||||
/* mouseState = */ null
|
||||
/* mouseState = */ null,
|
||||
/* fieldObjectsPromise = */ null
|
||||
);
|
||||
}
|
||||
this._renderAnnotationLayer();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue