Skip to content

Commit

Permalink
[JS] Run the named actions before running the format when the file is…
Browse files Browse the repository at this point in the history
… open (issue mozilla#15818)

It's a follow-up of mozilla#14950: some format actions are ran when the document is open
but we must be sure we've everything ready for that, hence we have to run some
named actions before runnig the global format.
In playing with the form, I discovered that the blur event wasn't triggered when
JS called `setFocus` (because in such a case the mouse was never down). So I removed
the mouseState thing to just use the correct commitKey when blur is triggered by a
TAB key.
  • Loading branch information
calixteman committed Dec 13, 2022
1 parent 2d59604 commit 2ebf874
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 159 deletions.
23 changes: 11 additions & 12 deletions src/display/annotation_layer.js
Expand Up @@ -67,7 +67,6 @@ function getRectDims(rect) {
* @property {boolean} [enableScripting]
* @property {boolean} [hasJSActions]
* @property {Object} [fieldObjects]
* @property {Object} [mouseState]
*/

class AnnotationElementFactory {
Expand Down Expand Up @@ -177,7 +176,6 @@ class AnnotationElement {
this.enableScripting = parameters.enableScripting;
this.hasJSActions = parameters.hasJSActions;
this._fieldObjects = parameters.fieldObjects;
this._mouseState = parameters.mouseState;

if (isRenderable) {
this.container = this._createContainer(ignoreBorder);
Expand Down Expand Up @@ -1053,6 +1051,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
userValue: textContent,
formattedValue: null,
lastCommittedValue: null,
commitKey: 1,
};

if (this.data.multiLine) {
Expand Down Expand Up @@ -1114,6 +1113,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
target.value = elementData.userValue;
}
elementData.lastCommittedValue = target.value;
elementData.commitKey = 1;
});

element.addEventListener("updatefromsandbox", jsEvent => {
Expand Down Expand Up @@ -1178,8 +1178,9 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
// Even if the field hasn't any actions
// leaving it can still trigger some actions with Calculate
element.addEventListener("keydown", event => {
// if the key is one of Escape, Enter or Tab
// then the data are committed
elementData.commitKey = 1;
// If the key is one of Escape, Enter then the data are committed.
// If we've a Tab then data will be committed on blur.
let commitKey = -1;
if (event.key === "Escape") {
commitKey = 0;
Expand All @@ -1189,7 +1190,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
// (see issue #15627).
commitKey = 2;
} else if (event.key === "Tab") {
commitKey = 3;
elementData.commitKey = 3;
}
if (commitKey === -1) {
return;
Expand Down Expand Up @@ -1217,21 +1218,20 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
const _blurListener = blurListener;
blurListener = null;
element.addEventListener("blur", event => {
if (!event.relatedTarget) {
return;
}
const { value } = event.target;
elementData.userValue = value;
if (
this._mouseState.isDown &&
elementData.lastCommittedValue !== value
) {
// Focus out using the mouse: data are committed
if (elementData.lastCommittedValue !== value) {
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
source: this,
detail: {
id,
name: "Keystroke",
value,
willCommit: true,
commitKey: 1,
commitKey: elementData.commitKey,
selStart: event.target.selectionStart,
selEnd: event.target.selectionEnd,
},
Expand Down Expand Up @@ -2620,7 +2620,6 @@ class AnnotationLayer {
enableScripting: parameters.enableScripting,
hasJSActions: parameters.hasJSActions,
fieldObjects: parameters.fieldObjects,
mouseState: parameters.mouseState || { isDown: false },
});
if (element.isRenderable) {
const rendered = element.render();
Expand Down
42 changes: 24 additions & 18 deletions src/scripting_api/doc.js
Expand Up @@ -101,27 +101,33 @@ class Doc extends PDFObject {
this._disableSaving = false;
}

_initActions() {
const dontRun = new Set([
"WillClose",
"WillSave",
"DidSave",
"WillPrint",
"DidPrint",
"OpenAction",
]);
// When a pdf has just been opened it doesn't really make sense
// to save it: it's up to the user to decide if they want to do that.
// A pdf can contain an action /FooBar which will trigger a save
// even if there are no WillSave/DidSave (which are themselves triggered
// after a save).
this._disableSaving = true;
for (const actionName of this._actions.keys()) {
if (!dontRun.has(actionName)) {
this._runActions(actionName);
}
}
this._runActions("OpenAction");
this._disableSaving = false;
}

_dispatchDocEvent(name) {
if (name === "Open") {
const dontRun = new Set([
"WillClose",
"WillSave",
"DidSave",
"WillPrint",
"DidPrint",
"OpenAction",
]);
// When a pdf has just been opened it doesn't really make sense
// to save it: it's up to the user to decide if they want to do that.
// A pdf can contain an action /FooBar which will trigger a save
// even if there are no WillSave/DidSave (which are themselves triggered
// after a save).
this._disableSaving = true;
for (const actionName of this._actions.keys()) {
if (!dontRun.has(actionName)) {
this._runActions(actionName);
}
}
this._runActions("OpenAction");
this._disableSaving = false;
} else if (name === "WillPrint") {
Expand Down
5 changes: 5 additions & 0 deletions src/scripting_api/event.js
Expand Up @@ -91,6 +91,10 @@ class EventDispatcher {
if (id === "doc") {
const eventName = event.name;
if (eventName === "Open") {
// Initialize named actions before calling formatAll to avoid any
// errors in the case where a formatter is using one of those named
// actions (see #15818).
this._document.obj._initActions();
// Before running the Open event, we format all the fields
// (see bug 1766987).
this.formatAll();
Expand Down Expand Up @@ -264,6 +268,7 @@ class EventDispatcher {
value: "",
formattedValue: null,
selRange: [0, 0],
focus: true, // Stay in the field.
});
}
}
Expand Down

0 comments on commit 2ebf874

Please sign in to comment.