mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
JS -- Add listener for sandbox events only if there are some actions
* When no actions then set it to null instead of empty object * Even if a field has no actions, it needs to listen to events from the sandbox in order to be updated if an action changes something in it.
This commit is contained in:
parent
55f55f5859
commit
a5279897a7
13 changed files with 170 additions and 28 deletions
|
@ -1020,6 +1020,21 @@ class PDFDocument {
|
|||
);
|
||||
}
|
||||
|
||||
get hasJSActions() {
|
||||
return shadow(
|
||||
this,
|
||||
"hasJSActions",
|
||||
this.fieldObjects.then(fieldObjects => {
|
||||
return (
|
||||
fieldObjects !== null &&
|
||||
Object.values(fieldObjects).some(fieldObject =>
|
||||
fieldObject.some(object => object.actions !== null)
|
||||
)
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
get calculationOrderIds() {
|
||||
const acroForm = this.catalog.acroForm;
|
||||
if (!acroForm || !acroForm.has("CO")) {
|
||||
|
|
|
@ -525,6 +525,10 @@ class WorkerMessageHandler {
|
|||
return pdfManager.ensureDoc("fieldObjects");
|
||||
});
|
||||
|
||||
handler.on("HasJSActions", function (data) {
|
||||
return pdfManager.ensureDoc("hasJSActions");
|
||||
});
|
||||
|
||||
handler.on("GetCalculationOrderIds", function (data) {
|
||||
return pdfManager.ensureDoc("calculationOrderIds");
|
||||
});
|
||||
|
|
|
@ -43,6 +43,8 @@ import { AnnotationStorage } from "./annotation_storage.js";
|
|||
* for annotation icons. Include trailing slash.
|
||||
* @property {boolean} renderInteractiveForms
|
||||
* @property {Object} svgFactory
|
||||
* @property {boolean} [enableScripting]
|
||||
* @property {boolean} [hasJSActions]
|
||||
*/
|
||||
|
||||
class AnnotationElementFactory {
|
||||
|
@ -142,6 +144,8 @@ class AnnotationElement {
|
|||
this.renderInteractiveForms = parameters.renderInteractiveForms;
|
||||
this.svgFactory = parameters.svgFactory;
|
||||
this.annotationStorage = parameters.annotationStorage;
|
||||
this.enableScripting = parameters.enableScripting;
|
||||
this.hasJSActions = parameters.hasJSActions;
|
||||
|
||||
if (isRenderable) {
|
||||
this.container = this._createContainer(ignoreBorder);
|
||||
|
@ -507,7 +511,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
event.target.setSelectionRange(0, 0);
|
||||
});
|
||||
|
||||
if (this.data.actions) {
|
||||
if (this.enableScripting && this.hasJSActions) {
|
||||
element.addEventListener("updateFromSandbox", function (event) {
|
||||
const data = event.detail;
|
||||
if ("value" in data) {
|
||||
|
@ -517,21 +521,23 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
}
|
||||
});
|
||||
|
||||
for (const eventType of Object.keys(this.data.actions)) {
|
||||
switch (eventType) {
|
||||
case "Format":
|
||||
element.addEventListener("blur", function (event) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("dispatchEventInSandbox", {
|
||||
detail: {
|
||||
id,
|
||||
name: "Format",
|
||||
value: event.target.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
break;
|
||||
if (this.data.actions !== null) {
|
||||
for (const eventType of Object.keys(this.data.actions)) {
|
||||
switch (eventType) {
|
||||
case "Format":
|
||||
element.addEventListener("blur", function (event) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("dispatchEventInSandbox", {
|
||||
detail: {
|
||||
id,
|
||||
name: "Format",
|
||||
value: event.target.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1562,6 +1568,9 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @property {boolean} renderInteractiveForms
|
||||
* @property {boolean} [enableScripting] - Enable embedded script execution.
|
||||
* @property {boolean} [hasJSActions] - Some fields have JS actions.
|
||||
* The default value is `false`.
|
||||
*/
|
||||
|
||||
class AnnotationLayer {
|
||||
|
@ -1608,6 +1617,8 @@ class AnnotationLayer {
|
|||
svgFactory: new DOMSVGFactory(),
|
||||
annotationStorage:
|
||||
parameters.annotationStorage || new AnnotationStorage(),
|
||||
enableScripting: parameters.enableScripting,
|
||||
hasJSActions: parameters.hasJSActions,
|
||||
});
|
||||
if (element.isRenderable) {
|
||||
const rendered = element.render();
|
||||
|
|
|
@ -903,6 +903,14 @@ class PDFDocumentProxy {
|
|||
return this._transport.getFieldObjects();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<boolean>} A promise that is resolved with `true`
|
||||
* if some /AcroForm fields have JavaScript actions.
|
||||
*/
|
||||
hasJSActions() {
|
||||
return this._transport.hasJSActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<Array<string> | null>} A promise that is resolved with an
|
||||
* {Array<string>} containing IDs of annotations that have a calculation
|
||||
|
@ -2568,6 +2576,10 @@ class WorkerTransport {
|
|||
return this.messageHandler.sendWithPromise("GetFieldObjects", null);
|
||||
}
|
||||
|
||||
hasJSActions() {
|
||||
return this.messageHandler.sendWithPromise("HasJSActions", null);
|
||||
}
|
||||
|
||||
getCalculationOrderIds() {
|
||||
return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null);
|
||||
}
|
||||
|
|
|
@ -73,12 +73,14 @@ class Field extends PDFObject {
|
|||
// Private
|
||||
this._actions = Object.create(null);
|
||||
const doc = (this._document = data.doc);
|
||||
for (const [eventType, actions] of Object.entries(data.actions)) {
|
||||
// This code is running in a sandbox so it's safe to use Function
|
||||
this._actions[eventType] = actions.map(action =>
|
||||
// eslint-disable-next-line no-new-func
|
||||
Function("event", `with (this) {${action}}`).bind(doc)
|
||||
);
|
||||
if (data.actions !== null) {
|
||||
for (const [eventType, actions] of Object.entries(data.actions)) {
|
||||
// This code is running in a sandbox so it's safe to use Function
|
||||
this._actions[eventType] = actions.map(action =>
|
||||
// eslint-disable-next-line no-new-func
|
||||
Function("event", `with (this) {${action}}`).bind(doc)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue