mirror of
https://github.com/zen-browser/pdf.js.git
synced 2025-07-09 09:45:42 +02:00
JS - Collect and execute actions at doc and pages level
* the goal is to execute actions like Open or OpenAction * can be tested with issue6106.pdf (auto-print) * once #12701 is merged, we can add page actions
This commit is contained in:
parent
142f131ee1
commit
1e2173f038
18 changed files with 829 additions and 125 deletions
26
src/scripting_api/common.js
Normal file
26
src/scripting_api/common.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
function createActionsMap(actions) {
|
||||
const actionsMap = new Map();
|
||||
if (actions) {
|
||||
for (const [eventType, actionsForEvent] of Object.entries(actions)) {
|
||||
actionsMap.set(eventType, actionsForEvent);
|
||||
}
|
||||
}
|
||||
return actionsMap;
|
||||
}
|
||||
|
||||
export { createActionsMap };
|
|
@ -13,6 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createActionsMap } from "./common.js";
|
||||
import { PDFObject } from "./pdf_object.js";
|
||||
import { PrintParams } from "./print_params.js";
|
||||
import { ZoomType } from "./constants.js";
|
||||
|
@ -88,6 +89,48 @@ class Doc extends PDFObject {
|
|||
|
||||
this._zoomType = ZoomType.none;
|
||||
this._zoom = data.zoom || 100;
|
||||
this._actions = createActionsMap(data.actions);
|
||||
this._globalEval = data.globalEval;
|
||||
}
|
||||
|
||||
_dispatchDocEvent(name) {
|
||||
if (name === "Open") {
|
||||
const dontRun = new Set([
|
||||
"WillClose",
|
||||
"WillSave",
|
||||
"DidSave",
|
||||
"WillPrint",
|
||||
"DidPrint",
|
||||
"OpenAction",
|
||||
]);
|
||||
for (const actionName of this._actions.keys()) {
|
||||
if (!dontRun.has(actionName)) {
|
||||
this._runActions(actionName);
|
||||
}
|
||||
}
|
||||
this._runActions("OpenAction");
|
||||
} else {
|
||||
this._runActions(name);
|
||||
}
|
||||
}
|
||||
|
||||
_dispatchPageEvent(name, action, pageNumber) {
|
||||
if (name === "PageOpen") {
|
||||
this._pageNum = pageNumber - 1;
|
||||
}
|
||||
|
||||
this._globalEval(action);
|
||||
}
|
||||
|
||||
_runActions(name) {
|
||||
if (!this._actions.has(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actions = this._actions.get(name);
|
||||
for (const action of actions) {
|
||||
this._globalEval(action);
|
||||
}
|
||||
}
|
||||
|
||||
_addField(name, field) {
|
||||
|
@ -954,7 +997,7 @@ class Doc extends PDFObject {
|
|||
nEnd = -1;
|
||||
}
|
||||
|
||||
this._send({ id: "print", start: nStart, end: nEnd });
|
||||
this._send({ command: "print", start: nStart, end: nEnd });
|
||||
}
|
||||
|
||||
removeDataObject() {
|
||||
|
|
|
@ -65,12 +65,28 @@ class EventDispatcher {
|
|||
dispatch(baseEvent) {
|
||||
const id = baseEvent.id;
|
||||
if (!(id in this._objects)) {
|
||||
let event;
|
||||
if (id === "doc" || id === "page") {
|
||||
event = globalThis.event = new Event(baseEvent);
|
||||
event.source = event.target = this._document.wrapped;
|
||||
event.name = baseEvent.name;
|
||||
}
|
||||
if (id === "doc") {
|
||||
this._document.obj._dispatchDocEvent(event.name);
|
||||
}
|
||||
if (id === "page") {
|
||||
this._document.obj._dispatchPageEvent(
|
||||
event.name,
|
||||
baseEvent.action,
|
||||
baseEvent.pageNumber
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const name = baseEvent.name.replace(" ", "");
|
||||
const source = this._objects[id];
|
||||
globalThis.event = new Event(baseEvent);
|
||||
const event = (globalThis.event = new Event(baseEvent));
|
||||
let savedChange;
|
||||
|
||||
if (source.obj._isButton()) {
|
||||
|
@ -156,7 +172,7 @@ class EventDispatcher {
|
|||
const first = this._calculationOrder[0];
|
||||
const source = this._objects[first];
|
||||
globalThis.event = new Event({});
|
||||
this.runCalculate(source, event);
|
||||
this.runCalculate(source, globalThis.event);
|
||||
}
|
||||
|
||||
runCalculate(source, event) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
import { Color } from "./color.js";
|
||||
import { createActionsMap } from "./common.js";
|
||||
import { PDFObject } from "./pdf_object.js";
|
||||
|
||||
class Field extends PDFObject {
|
||||
|
@ -72,7 +73,7 @@ class Field extends PDFObject {
|
|||
|
||||
// Private
|
||||
this._document = data.doc;
|
||||
this._actions = this._createActionsMap(data.actions);
|
||||
this._actions = createActionsMap(data.actions);
|
||||
|
||||
this._fillColor = data.fillColor || ["T"];
|
||||
this._strokeColor = data.strokeColor || ["G", 0];
|
||||
|
@ -133,16 +134,6 @@ class Field extends PDFObject {
|
|||
this._send({ id: this._id, focus: true });
|
||||
}
|
||||
|
||||
_createActionsMap(actions) {
|
||||
const actionsMap = new Map();
|
||||
if (actions) {
|
||||
for (const [eventType, actionsForEvent] of Object.entries(actions)) {
|
||||
actionsMap.set(eventType, actionsForEvent);
|
||||
}
|
||||
}
|
||||
return actionsMap;
|
||||
}
|
||||
|
||||
_isButton() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ function initSandbox(params) {
|
|||
const { data } = params;
|
||||
const doc = new Doc({
|
||||
send,
|
||||
globalEval,
|
||||
...data.docInfo,
|
||||
});
|
||||
const _document = { obj: doc, wrapped: new Proxy(doc, proxyHandler) };
|
||||
|
@ -67,16 +68,17 @@ function initSandbox(params) {
|
|||
const util = new Util({ externalCall });
|
||||
const aform = new AForm(doc, app, util);
|
||||
|
||||
for (const [name, objs] of Object.entries(data.objects)) {
|
||||
const obj = objs[0];
|
||||
obj.send = send;
|
||||
obj.globalEval = globalEval;
|
||||
obj.doc = _document.wrapped;
|
||||
obj.globalEval = globalEval;
|
||||
const field = new Field(obj);
|
||||
const wrapped = new Proxy(field, proxyHandler);
|
||||
doc._addField(name, wrapped);
|
||||
app._objects[obj.id] = { obj: field, wrapped };
|
||||
if (data.objects) {
|
||||
for (const [name, objs] of Object.entries(data.objects)) {
|
||||
const obj = objs[0];
|
||||
obj.send = send;
|
||||
obj.globalEval = globalEval;
|
||||
obj.doc = _document.wrapped;
|
||||
const field = new Field(obj);
|
||||
const wrapped = new Proxy(field, proxyHandler);
|
||||
doc._addField(name, wrapped);
|
||||
app._objects[obj.id] = { obj: field, wrapped };
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.event = null;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue