Skip to content

Commit 94b4715

Browse files
committed
[JS] Use beforeinput event to trigger a keystroke event in the sandbox
- it aims to fix issue #14307; - this event has been added recently in Firefox and we can now use it; - fix few bugs in aform.js or in annotation_layer.js; - add some integration tests to test keystroke events (see `AFSpecial_Keystroke`); - make dispatchEvent in the quickjs sandbox async.
1 parent 922dac0 commit 94b4715

File tree

7 files changed

+219
-44
lines changed

7 files changed

+219
-44
lines changed

src/display/annotation_layer.js

+10-34
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ class WidgetAnnotationElement extends AnnotationElement {
780780
detail: {
781781
id: this.data.id,
782782
name: eventName,
783-
value: event.target.checked,
783+
value: valueGetter(event),
784784
},
785785
});
786786
});
@@ -923,8 +923,6 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
923923
const elementData = {
924924
userValue: null,
925925
formattedValue: null,
926-
beforeInputSelectionRange: null,
927-
beforeInputValue: null,
928926
};
929927

930928
if (this.data.multiLine) {
@@ -965,7 +963,6 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
965963
}
966964
// Reset the cursor position to the start of the field (issue 12359).
967965
event.target.scrollLeft = 0;
968-
elementData.beforeInputSelectionRange = null;
969966
};
970967

971968
if (this.enableScripting && this.hasJSActions) {
@@ -1007,7 +1004,6 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
10071004
// Even if the field hasn't any actions
10081005
// leaving it can still trigger some actions with Calculate
10091006
element.addEventListener("keydown", event => {
1010-
elementData.beforeInputValue = event.target.value;
10111007
// if the key is one of Escape, Enter or Tab
10121008
// then the data are committed
10131009
let commitKey = -1;
@@ -1039,9 +1035,9 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
10391035
const _blurListener = blurListener;
10401036
blurListener = null;
10411037
element.addEventListener("blur", event => {
1038+
elementData.userValue = event.target.value;
10421039
if (this._mouseState.isDown) {
10431040
// Focus out using the mouse: data are committed
1044-
elementData.userValue = event.target.value;
10451041
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
10461042
source: this,
10471043
detail: {
@@ -1057,42 +1053,22 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
10571053
}
10581054
_blurListener(event);
10591055
});
1060-
element.addEventListener("mousedown", event => {
1061-
elementData.beforeInputValue = event.target.value;
1062-
elementData.beforeInputSelectionRange = null;
1063-
});
1064-
element.addEventListener("keyup", event => {
1065-
// keyup is triggered after input
1066-
if (event.target.selectionStart === event.target.selectionEnd) {
1067-
elementData.beforeInputSelectionRange = null;
1068-
}
1069-
});
1070-
element.addEventListener("select", event => {
1071-
elementData.beforeInputSelectionRange = [
1072-
event.target.selectionStart,
1073-
event.target.selectionEnd,
1074-
];
1075-
});
10761056

10771057
if (this.data.actions?.Keystroke) {
1078-
// We should use beforeinput but this
1079-
// event isn't available in Firefox
1080-
element.addEventListener("input", event => {
1081-
let selStart = -1;
1082-
let selEnd = -1;
1083-
if (elementData.beforeInputSelectionRange) {
1084-
[selStart, selEnd] = elementData.beforeInputSelectionRange;
1085-
}
1058+
element.addEventListener("beforeinput", event => {
1059+
elementData.formattedValue = "";
1060+
const { data, target } = event;
1061+
const { value, selectionStart, selectionEnd } = target;
10861062
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
10871063
source: this,
10881064
detail: {
10891065
id,
10901066
name: "Keystroke",
1091-
value: elementData.beforeInputValue,
1092-
change: event.data,
1067+
value,
1068+
change: data,
10931069
willCommit: false,
1094-
selStart,
1095-
selEnd,
1070+
selStart: selectionStart,
1071+
selEnd: selectionEnd,
10961072
},
10971073
});
10981074
});

src/scripting_api/aform.js

+4-8
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,10 @@ class AForm {
466466

467467
const event = globalThis.event;
468468
const value = this.AFMergeChange(event);
469+
if (!value) {
470+
return;
471+
}
472+
469473
const checkers = new Map([
470474
["9", char => char >= "0" && char <= "9"],
471475
[
@@ -498,10 +502,6 @@ class AForm {
498502
return true;
499503
}
500504

501-
if (!value) {
502-
return;
503-
}
504-
505505
const err = `${GlobalConstants.IDS_INVALID_VALUE} = "${cMask}"`;
506506

507507
if (value.length > cMask.length) {
@@ -538,10 +538,6 @@ class AForm {
538538

539539
AFSpecial_Keystroke(psf) {
540540
const event = globalThis.event;
541-
if (!event.value) {
542-
return;
543-
}
544-
545541
psf = this.AFMakeNumber(psf);
546542

547543
let formatStr;

src/scripting_api/event.js

+8
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ class EventDispatcher {
151151
value: savedChange.value,
152152
selRange: [savedChange.selStart, savedChange.selEnd],
153153
});
154+
} else {
155+
// Entry is not valid (rc == false) and it's a commit
156+
// so just clear the field.
157+
source.obj._send({
158+
id: source.obj._id,
159+
value: "",
160+
selRange: [0, 0],
161+
});
154162
}
155163
}
156164
}

0 commit comments

Comments
 (0)