Merge pull request #14869 from calixteman/14862
[JS] Fix few bugs present in the pdf for issue #14862
This commit is contained in:
commit
8135d7ccf6
@ -1518,7 +1518,8 @@ class WidgetAnnotation extends Annotation {
|
|||||||
const storageEntry = annotationStorage
|
const storageEntry = annotationStorage
|
||||||
? annotationStorage.get(this.data.id)
|
? annotationStorage.get(this.data.id)
|
||||||
: undefined;
|
: undefined;
|
||||||
let value = storageEntry && storageEntry.value;
|
let value =
|
||||||
|
storageEntry && (storageEntry.formattedValue || storageEntry.value);
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
if (!this._hasValueFromXFA || this.appearance) {
|
if (!this._hasValueFromXFA || this.appearance) {
|
||||||
// The annotation hasn't been rendered so use the appearance.
|
// The annotation hasn't been rendered so use the appearance.
|
||||||
@ -1981,7 +1982,7 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||||||
return {
|
return {
|
||||||
id: this.data.id,
|
id: this.data.id,
|
||||||
value: this.data.fieldValue,
|
value: this.data.fieldValue,
|
||||||
defaultValue: this.data.defaultFieldValue,
|
defaultValue: this.data.defaultFieldValue || "",
|
||||||
multiline: this.data.multiLine,
|
multiline: this.data.multiLine,
|
||||||
password: this.hasFieldFlag(AnnotationFieldFlag.PASSWORD),
|
password: this.hasFieldFlag(AnnotationFieldFlag.PASSWORD),
|
||||||
charLimit: this.data.maxLen,
|
charLimit: this.data.maxLen,
|
||||||
|
@ -297,6 +297,110 @@ class AnnotationElement {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _commonActions() {
|
||||||
|
const setColor = (jsName, styleName, event) => {
|
||||||
|
const color = event.detail[jsName];
|
||||||
|
event.target.style[styleName] = ColorConverters[`${color[0]}_HTML`](
|
||||||
|
color.slice(1)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return shadow(this, "_commonActions", {
|
||||||
|
display: event => {
|
||||||
|
const hidden = event.detail.display % 2 === 1;
|
||||||
|
event.target.style.visibility = hidden ? "hidden" : "visible";
|
||||||
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
|
hidden,
|
||||||
|
print: event.detail.display === 0 || event.detail.display === 3,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
print: event => {
|
||||||
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
|
print: event.detail.print,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hidden: event => {
|
||||||
|
event.target.style.visibility = event.detail.hidden
|
||||||
|
? "hidden"
|
||||||
|
: "visible";
|
||||||
|
this.annotationStorage.setValue(this.data.id, {
|
||||||
|
hidden: event.detail.hidden,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
focus: event => {
|
||||||
|
setTimeout(() => event.target.focus({ preventScroll: false }), 0);
|
||||||
|
},
|
||||||
|
userName: event => {
|
||||||
|
// tooltip
|
||||||
|
event.target.title = event.detail.userName;
|
||||||
|
},
|
||||||
|
readonly: event => {
|
||||||
|
if (event.detail.readonly) {
|
||||||
|
event.target.setAttribute("readonly", "");
|
||||||
|
} else {
|
||||||
|
event.target.removeAttribute("readonly");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: event => {
|
||||||
|
if (event.detail.required) {
|
||||||
|
event.target.setAttribute("required", "");
|
||||||
|
} else {
|
||||||
|
event.target.removeAttribute("required");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bgColor: event => {
|
||||||
|
setColor("bgColor", "backgroundColor", event);
|
||||||
|
},
|
||||||
|
fillColor: event => {
|
||||||
|
setColor("fillColor", "backgroundColor", event);
|
||||||
|
},
|
||||||
|
fgColor: event => {
|
||||||
|
setColor("fgColor", "color", event);
|
||||||
|
},
|
||||||
|
textColor: event => {
|
||||||
|
setColor("textColor", "color", event);
|
||||||
|
},
|
||||||
|
borderColor: event => {
|
||||||
|
setColor("borderColor", "borderColor", event);
|
||||||
|
},
|
||||||
|
strokeColor: event => {
|
||||||
|
setColor("strokeColor", "borderColor", event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_dispatchEventFromSandbox(actions, jsEvent) {
|
||||||
|
const commonActions = this._commonActions;
|
||||||
|
for (const name of Object.keys(jsEvent.detail)) {
|
||||||
|
const action = actions[name] || commonActions[name];
|
||||||
|
if (action) {
|
||||||
|
action(jsEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_setDefaultPropertiesFromJS(element) {
|
||||||
|
if (!this.enableScripting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some properties may have been updated thanks to JS.
|
||||||
|
const storedData = this.annotationStorage.getRawValue(this.data.id);
|
||||||
|
if (!storedData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const commonActions = this._commonActions;
|
||||||
|
for (const [actionName, detail] of Object.entries(storedData)) {
|
||||||
|
const action = commonActions[actionName];
|
||||||
|
if (action) {
|
||||||
|
action({ detail, target: element });
|
||||||
|
// The action has been consumed: no need to keep it.
|
||||||
|
delete storedData[actionName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create quadrilaterals from the annotation's quadpoints.
|
* Create quadrilaterals from the annotation's quadpoints.
|
||||||
*
|
*
|
||||||
@ -657,7 +761,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||||||
switch (field.type) {
|
switch (field.type) {
|
||||||
case "text": {
|
case "text": {
|
||||||
const value = field.defaultValue || "";
|
const value = field.defaultValue || "";
|
||||||
storage.setValue(id, { value, valueAsString: value });
|
storage.setValue(id, { value });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "checkbox":
|
case "checkbox":
|
||||||
@ -794,85 +898,6 @@ class WidgetAnnotationElement extends AnnotationElement {
|
|||||||
? "transparent"
|
? "transparent"
|
||||||
: Util.makeHexColor(color[0], color[1], color[2]);
|
: Util.makeHexColor(color[0], color[1], color[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_dispatchEventFromSandbox(actions, jsEvent) {
|
|
||||||
const setColor = (jsName, styleName, event) => {
|
|
||||||
const color = event.detail[jsName];
|
|
||||||
event.target.style[styleName] = ColorConverters[`${color[0]}_HTML`](
|
|
||||||
color.slice(1)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const commonActions = {
|
|
||||||
display: event => {
|
|
||||||
const hidden = event.detail.display % 2 === 1;
|
|
||||||
event.target.style.visibility = hidden ? "hidden" : "visible";
|
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
|
||||||
hidden,
|
|
||||||
print: event.detail.display === 0 || event.detail.display === 3,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
print: event => {
|
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
|
||||||
print: event.detail.print,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hidden: event => {
|
|
||||||
event.target.style.visibility = event.detail.hidden
|
|
||||||
? "hidden"
|
|
||||||
: "visible";
|
|
||||||
this.annotationStorage.setValue(this.data.id, {
|
|
||||||
hidden: event.detail.hidden,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
focus: event => {
|
|
||||||
setTimeout(() => event.target.focus({ preventScroll: false }), 0);
|
|
||||||
},
|
|
||||||
userName: event => {
|
|
||||||
// tooltip
|
|
||||||
event.target.title = event.detail.userName;
|
|
||||||
},
|
|
||||||
readonly: event => {
|
|
||||||
if (event.detail.readonly) {
|
|
||||||
event.target.setAttribute("readonly", "");
|
|
||||||
} else {
|
|
||||||
event.target.removeAttribute("readonly");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
required: event => {
|
|
||||||
if (event.detail.required) {
|
|
||||||
event.target.setAttribute("required", "");
|
|
||||||
} else {
|
|
||||||
event.target.removeAttribute("required");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bgColor: event => {
|
|
||||||
setColor("bgColor", "backgroundColor", event);
|
|
||||||
},
|
|
||||||
fillColor: event => {
|
|
||||||
setColor("fillColor", "backgroundColor", event);
|
|
||||||
},
|
|
||||||
fgColor: event => {
|
|
||||||
setColor("fgColor", "color", event);
|
|
||||||
},
|
|
||||||
textColor: event => {
|
|
||||||
setColor("textColor", "color", event);
|
|
||||||
},
|
|
||||||
borderColor: event => {
|
|
||||||
setColor("borderColor", "borderColor", event);
|
|
||||||
},
|
|
||||||
strokeColor: event => {
|
|
||||||
setColor("strokeColor", "borderColor", event);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const name of Object.keys(jsEvent.detail)) {
|
|
||||||
const action = actions[name] || commonActions[name];
|
|
||||||
if (action) {
|
|
||||||
action(jsEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||||
@ -909,12 +934,12 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
// from parsing the elements correctly for the reference tests.
|
// from parsing the elements correctly for the reference tests.
|
||||||
const storedData = storage.getValue(id, {
|
const storedData = storage.getValue(id, {
|
||||||
value: this.data.fieldValue,
|
value: this.data.fieldValue,
|
||||||
valueAsString: this.data.fieldValue,
|
|
||||||
});
|
});
|
||||||
const textContent = storedData.valueAsString || storedData.value || "";
|
const textContent = storedData.formattedValue || storedData.value || "";
|
||||||
const elementData = {
|
const elementData = {
|
||||||
userValue: null,
|
userValue: null,
|
||||||
formattedValue: null,
|
formattedValue: null,
|
||||||
|
valueOnFocus: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.data.multiLine) {
|
if (this.data.multiLine) {
|
||||||
@ -944,14 +969,15 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
element.addEventListener("resetform", event => {
|
element.addEventListener("resetform", event => {
|
||||||
const defaultValue = this.data.defaultFieldValue || "";
|
const defaultValue = this.data.defaultFieldValue ?? "";
|
||||||
element.value = elementData.userValue = defaultValue;
|
element.value = elementData.userValue = defaultValue;
|
||||||
delete elementData.formattedValue;
|
elementData.formattedValue = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
let blurListener = event => {
|
let blurListener = event => {
|
||||||
if (elementData.formattedValue) {
|
const { formattedValue } = elementData;
|
||||||
event.target.value = elementData.formattedValue;
|
if (formattedValue !== null && formattedValue !== undefined) {
|
||||||
|
event.target.value = formattedValue;
|
||||||
}
|
}
|
||||||
// Reset the cursor position to the start of the field (issue 12359).
|
// Reset the cursor position to the start of the field (issue 12359).
|
||||||
event.target.scrollLeft = 0;
|
event.target.scrollLeft = 0;
|
||||||
@ -962,32 +988,33 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
if (elementData.userValue) {
|
if (elementData.userValue) {
|
||||||
event.target.value = elementData.userValue;
|
event.target.value = elementData.userValue;
|
||||||
}
|
}
|
||||||
|
elementData.valueOnFocus = event.target.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
element.addEventListener("updatefromsandbox", jsEvent => {
|
element.addEventListener("updatefromsandbox", jsEvent => {
|
||||||
const actions = {
|
const actions = {
|
||||||
value(event) {
|
value(event) {
|
||||||
elementData.userValue = event.detail.value || "";
|
elementData.userValue = event.detail.value ?? "";
|
||||||
storage.setValue(id, { value: elementData.userValue.toString() });
|
storage.setValue(id, { value: elementData.userValue.toString() });
|
||||||
if (!elementData.formattedValue) {
|
|
||||||
event.target.value = elementData.userValue;
|
event.target.value = elementData.userValue;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
valueAsString(event) {
|
formattedValue(event) {
|
||||||
elementData.formattedValue = event.detail.valueAsString || "";
|
const { formattedValue } = event.detail;
|
||||||
if (event.target !== document.activeElement) {
|
elementData.formattedValue = formattedValue;
|
||||||
|
if (
|
||||||
|
formattedValue !== null &&
|
||||||
|
formattedValue !== undefined &&
|
||||||
|
event.target !== document.activeElement
|
||||||
|
) {
|
||||||
// Input hasn't the focus so display formatted string
|
// Input hasn't the focus so display formatted string
|
||||||
event.target.value = elementData.formattedValue;
|
event.target.value = formattedValue;
|
||||||
}
|
}
|
||||||
storage.setValue(id, {
|
storage.setValue(id, {
|
||||||
formattedValue: elementData.formattedValue,
|
formattedValue,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
selRange(event) {
|
selRange(event) {
|
||||||
const [selStart, selEnd] = event.detail.selRange;
|
event.target.setSelectionRange(...event.detail.selRange);
|
||||||
if (selStart >= 0 && selEnd < event.target.value.length) {
|
|
||||||
event.target.setSelectionRange(selStart, selEnd);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this._dispatchEventFromSandbox(actions, jsEvent);
|
this._dispatchEventFromSandbox(actions, jsEvent);
|
||||||
@ -1009,14 +1036,18 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
if (commitKey === -1) {
|
if (commitKey === -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const { value } = event.target;
|
||||||
|
if (elementData.valueOnFocus === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Save the entered value
|
// Save the entered value
|
||||||
elementData.userValue = event.target.value;
|
elementData.userValue = value;
|
||||||
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
||||||
source: this,
|
source: this,
|
||||||
detail: {
|
detail: {
|
||||||
id,
|
id,
|
||||||
name: "Keystroke",
|
name: "Keystroke",
|
||||||
value: event.target.value,
|
value,
|
||||||
willCommit: true,
|
willCommit: true,
|
||||||
commitKey,
|
commitKey,
|
||||||
selStart: event.target.selectionStart,
|
selStart: event.target.selectionStart,
|
||||||
@ -1027,15 +1058,16 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
const _blurListener = blurListener;
|
const _blurListener = blurListener;
|
||||||
blurListener = null;
|
blurListener = null;
|
||||||
element.addEventListener("blur", event => {
|
element.addEventListener("blur", event => {
|
||||||
elementData.userValue = event.target.value;
|
const { value } = event.target;
|
||||||
if (this._mouseState.isDown) {
|
elementData.userValue = value;
|
||||||
|
if (this._mouseState.isDown && elementData.valueOnFocus !== value) {
|
||||||
// Focus out using the mouse: data are committed
|
// Focus out using the mouse: data are committed
|
||||||
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
||||||
source: this,
|
source: this,
|
||||||
detail: {
|
detail: {
|
||||||
id,
|
id,
|
||||||
name: "Keystroke",
|
name: "Keystroke",
|
||||||
value: event.target.value,
|
value,
|
||||||
willCommit: true,
|
willCommit: true,
|
||||||
commitKey: 1,
|
commitKey: 1,
|
||||||
selStart: event.target.selectionStart,
|
selStart: event.target.selectionStart,
|
||||||
@ -1048,19 +1080,56 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
|
|
||||||
if (this.data.actions?.Keystroke) {
|
if (this.data.actions?.Keystroke) {
|
||||||
element.addEventListener("beforeinput", event => {
|
element.addEventListener("beforeinput", event => {
|
||||||
elementData.formattedValue = "";
|
|
||||||
const { data, target } = event;
|
const { data, target } = event;
|
||||||
const { value, selectionStart, selectionEnd } = target;
|
const { value, selectionStart, selectionEnd } = target;
|
||||||
|
|
||||||
|
let selStart = selectionStart,
|
||||||
|
selEnd = selectionEnd;
|
||||||
|
|
||||||
|
switch (event.inputType) {
|
||||||
|
// https://rawgit.com/w3c/input-events/v1/index.html#interface-InputEvent-Attributes
|
||||||
|
case "deleteWordBackward": {
|
||||||
|
const match = value
|
||||||
|
.substring(0, selectionStart)
|
||||||
|
.match(/\w*[^\w]*$/);
|
||||||
|
if (match) {
|
||||||
|
selStart -= match[0].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "deleteWordForward": {
|
||||||
|
const match = value
|
||||||
|
.substring(selectionStart)
|
||||||
|
.match(/^[^\w]*\w*/);
|
||||||
|
if (match) {
|
||||||
|
selEnd += match[0].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "deleteContentBackward":
|
||||||
|
if (selectionStart === selectionEnd) {
|
||||||
|
selStart -= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "deleteContentForward":
|
||||||
|
if (selectionStart === selectionEnd) {
|
||||||
|
selEnd += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We handle the event ourselves.
|
||||||
|
event.preventDefault();
|
||||||
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
||||||
source: this,
|
source: this,
|
||||||
detail: {
|
detail: {
|
||||||
id,
|
id,
|
||||||
name: "Keystroke",
|
name: "Keystroke",
|
||||||
value,
|
value,
|
||||||
change: data,
|
change: data || "",
|
||||||
willCommit: false,
|
willCommit: false,
|
||||||
selStart: selectionStart,
|
selStart,
|
||||||
selEnd: selectionEnd,
|
selEnd,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1104,6 +1173,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
|
|
||||||
this._setTextStyle(element);
|
this._setTextStyle(element);
|
||||||
this._setBackgroundColor(element);
|
this._setBackgroundColor(element);
|
||||||
|
this._setDefaultPropertiesFromJS(element);
|
||||||
|
|
||||||
this.container.appendChild(element);
|
this.container.appendChild(element);
|
||||||
return this.container;
|
return this.container;
|
||||||
@ -1213,6 +1283,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._setBackgroundColor(element);
|
this._setBackgroundColor(element);
|
||||||
|
this._setDefaultPropertiesFromJS(element);
|
||||||
|
|
||||||
this.container.appendChild(element);
|
this.container.appendChild(element);
|
||||||
return this.container;
|
return this.container;
|
||||||
@ -1300,6 +1371,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._setBackgroundColor(element);
|
this._setBackgroundColor(element);
|
||||||
|
this._setDefaultPropertiesFromJS(element);
|
||||||
|
|
||||||
this.container.appendChild(element);
|
this.container.appendChild(element);
|
||||||
return this.container;
|
return this.container;
|
||||||
@ -1322,6 +1394,8 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
|
|||||||
container.title = this.data.alternativeText;
|
container.title = this.data.alternativeText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._setDefaultPropertiesFromJS(container);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1534,6 +1608,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._setBackgroundColor(selectElement);
|
this._setBackgroundColor(selectElement);
|
||||||
|
this._setDefaultPropertiesFromJS(selectElement);
|
||||||
|
|
||||||
this.container.appendChild(selectElement);
|
this.container.appendChild(selectElement);
|
||||||
return this.container;
|
return this.container;
|
||||||
|
@ -50,6 +50,18 @@ class AnnotationStorage {
|
|||||||
return Object.assign(defaultValue, value);
|
return Object.assign(defaultValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value for a given key.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @memberof AnnotationStorage
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getRawValue(key) {
|
||||||
|
return this._storage.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value for a given key
|
* Set the value for a given key
|
||||||
*
|
*
|
||||||
|
@ -434,7 +434,7 @@ class App extends PDFObject {
|
|||||||
oDoc = null,
|
oDoc = null,
|
||||||
oCheckbox = null
|
oCheckbox = null
|
||||||
) {
|
) {
|
||||||
if (typeof cMsg === "object") {
|
if (cMsg && typeof cMsg === "object") {
|
||||||
nType = cMsg.nType;
|
nType = cMsg.nType;
|
||||||
cMsg = cMsg.cMsg;
|
cMsg = cMsg.cMsg;
|
||||||
}
|
}
|
||||||
@ -580,7 +580,7 @@ class App extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response(cQuestion, cTitle = "", cDefault = "", bPassword = "", cLabel = "") {
|
response(cQuestion, cTitle = "", cDefault = "", bPassword = "", cLabel = "") {
|
||||||
if (typeof cQuestion === "object") {
|
if (cQuestion && typeof cQuestion === "object") {
|
||||||
cDefault = cQuestion.cDefault;
|
cDefault = cQuestion.cDefault;
|
||||||
cQuestion = cQuestion.cQuestion;
|
cQuestion = cQuestion.cQuestion;
|
||||||
}
|
}
|
||||||
@ -590,7 +590,7 @@ class App extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setInterval(cExpr, nMilliseconds = 0) {
|
setInterval(cExpr, nMilliseconds = 0) {
|
||||||
if (typeof cExpr === "object") {
|
if (cExpr && typeof cExpr === "object") {
|
||||||
nMilliseconds = cExpr.nMilliseconds || 0;
|
nMilliseconds = cExpr.nMilliseconds || 0;
|
||||||
cExpr = cExpr.cExpr;
|
cExpr = cExpr.cExpr;
|
||||||
}
|
}
|
||||||
@ -609,7 +609,7 @@ class App extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTimeOut(cExpr, nMilliseconds = 0) {
|
setTimeOut(cExpr, nMilliseconds = 0) {
|
||||||
if (typeof cExpr === "object") {
|
if (cExpr && typeof cExpr === "object") {
|
||||||
nMilliseconds = cExpr.nMilliseconds || 0;
|
nMilliseconds = cExpr.nMilliseconds || 0;
|
||||||
cExpr = cExpr.cExpr;
|
cExpr = cExpr.cExpr;
|
||||||
}
|
}
|
||||||
|
@ -820,8 +820,8 @@ class Doc extends PDFObject {
|
|||||||
/* Not implemented */
|
/* Not implemented */
|
||||||
}
|
}
|
||||||
|
|
||||||
getField(cName) {
|
_getField(cName) {
|
||||||
if (typeof cName === "object") {
|
if (cName && typeof cName === "object") {
|
||||||
cName = cName.cName;
|
cName = cName.cName;
|
||||||
}
|
}
|
||||||
if (typeof cName !== "string") {
|
if (typeof cName !== "string") {
|
||||||
@ -859,6 +859,14 @@ class Doc extends PDFObject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getField(cName) {
|
||||||
|
const field = this._getField(cName);
|
||||||
|
if (!field) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return field.wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
_getChildren(fieldName) {
|
_getChildren(fieldName) {
|
||||||
// Children of foo.bar are foo.bar.oof, foo.bar.rab
|
// Children of foo.bar are foo.bar.oof, foo.bar.rab
|
||||||
// but not foo.bar.oof.FOO.
|
// but not foo.bar.oof.FOO.
|
||||||
@ -889,7 +897,7 @@ class Doc extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNthFieldName(nIndex) {
|
getNthFieldName(nIndex) {
|
||||||
if (typeof nIndex === "object") {
|
if (nIndex && typeof nIndex === "object") {
|
||||||
nIndex = nIndex.nIndex;
|
nIndex = nIndex.nIndex;
|
||||||
}
|
}
|
||||||
if (typeof nIndex !== "number") {
|
if (typeof nIndex !== "number") {
|
||||||
@ -1027,7 +1035,7 @@ class Doc extends PDFObject {
|
|||||||
bAnnotations = true,
|
bAnnotations = true,
|
||||||
printParams = null
|
printParams = null
|
||||||
) {
|
) {
|
||||||
if (typeof bUI === "object") {
|
if (bUI && typeof bUI === "object") {
|
||||||
nStart = bUI.nStart;
|
nStart = bUI.nStart;
|
||||||
nEnd = bUI.nEnd;
|
nEnd = bUI.nEnd;
|
||||||
bSilent = bUI.bSilent;
|
bSilent = bUI.bSilent;
|
||||||
@ -1103,30 +1111,52 @@ class Doc extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetForm(aFields = null) {
|
resetForm(aFields = null) {
|
||||||
if (aFields && !Array.isArray(aFields) && typeof aFields === "object") {
|
// Handle the case resetForm({ aFields: ... })
|
||||||
|
if (aFields && typeof aFields === "object") {
|
||||||
aFields = aFields.aFields;
|
aFields = aFields.aFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aFields && !Array.isArray(aFields)) {
|
||||||
|
aFields = [aFields];
|
||||||
|
}
|
||||||
|
|
||||||
let mustCalculate = false;
|
let mustCalculate = false;
|
||||||
|
let fieldsToReset;
|
||||||
if (aFields) {
|
if (aFields) {
|
||||||
|
fieldsToReset = [];
|
||||||
for (const fieldName of aFields) {
|
for (const fieldName of aFields) {
|
||||||
if (!fieldName) {
|
if (!fieldName) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const field = this.getField(fieldName);
|
if (typeof fieldName !== "string") {
|
||||||
|
// In Acrobat if a fieldName is not a string all the fields are reset.
|
||||||
|
fieldsToReset = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const field = this._getField(fieldName);
|
||||||
if (!field) {
|
if (!field) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
field.value = field.defaultValue;
|
fieldsToReset.push(field);
|
||||||
field.valueAsString = field.value;
|
|
||||||
mustCalculate = true;
|
mustCalculate = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (!fieldsToReset) {
|
||||||
|
fieldsToReset = this._fields.values();
|
||||||
mustCalculate = this._fields.size !== 0;
|
mustCalculate = this._fields.size !== 0;
|
||||||
for (const field of this._fields.values()) {
|
|
||||||
field.value = field.defaultValue;
|
|
||||||
field.valueAsString = field.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const field of fieldsToReset) {
|
||||||
|
field.obj.value = field.obj.defaultValue;
|
||||||
|
this._send({
|
||||||
|
id: field.obj._id,
|
||||||
|
value: field.obj.defaultValue,
|
||||||
|
formattedValue: null,
|
||||||
|
selRange: [0, 0],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mustCalculate) {
|
if (mustCalculate) {
|
||||||
this.calculateNow();
|
this.calculateNow();
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ class EventDispatcher {
|
|||||||
this._objects = objects;
|
this._objects = objects;
|
||||||
|
|
||||||
this._document.obj._eventDispatcher = this;
|
this._document.obj._eventDispatcher = this;
|
||||||
|
this._isCalculating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeChange(event) {
|
mergeChange(event) {
|
||||||
@ -129,24 +130,37 @@ class EventDispatcher {
|
|||||||
return;
|
return;
|
||||||
case "Action":
|
case "Action":
|
||||||
this.runActions(source, source, event, name);
|
this.runActions(source, source, event, name);
|
||||||
if (this._document.obj.calculate) {
|
|
||||||
this.runCalculate(source, event);
|
this.runCalculate(source, event);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.runActions(source, source, event, name);
|
this.runActions(source, source, event, name);
|
||||||
|
|
||||||
if (name === "Keystroke") {
|
if (name !== "Keystroke") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.rc) {
|
if (event.rc) {
|
||||||
if (event.willCommit) {
|
if (event.willCommit) {
|
||||||
this.runValidation(source, event);
|
this.runValidation(source, event);
|
||||||
} else if (
|
} else {
|
||||||
event.change !== savedChange.change ||
|
const value = (source.obj.value = this.mergeChange(event));
|
||||||
|
let selStart, selEnd;
|
||||||
|
if (
|
||||||
event.selStart !== savedChange.selStart ||
|
event.selStart !== savedChange.selStart ||
|
||||||
event.selEnd !== savedChange.selEnd
|
event.selEnd !== savedChange.selEnd
|
||||||
) {
|
) {
|
||||||
source.wrapped.value = this.mergeChange(event);
|
// Selection has been changed by the script so apply the changes.
|
||||||
|
selStart = event.selStart;
|
||||||
|
selEnd = event.selEnd;
|
||||||
|
} else {
|
||||||
|
selEnd = selStart = savedChange.selStart + event.change.length;
|
||||||
|
}
|
||||||
|
source.obj._send({
|
||||||
|
id: source.obj._id,
|
||||||
|
value,
|
||||||
|
selRange: [selStart, selEnd],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (!event.willCommit) {
|
} else if (!event.willCommit) {
|
||||||
source.obj._send({
|
source.obj._send({
|
||||||
@ -160,30 +174,40 @@ class EventDispatcher {
|
|||||||
source.obj._send({
|
source.obj._send({
|
||||||
id: source.obj._id,
|
id: source.obj._id,
|
||||||
value: "",
|
value: "",
|
||||||
|
formattedValue: null,
|
||||||
selRange: [0, 0],
|
selRange: [0, 0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
runValidation(source, event) {
|
runValidation(source, event) {
|
||||||
const hasRan = this.runActions(source, source, event, "Validate");
|
const didValidateRun = this.runActions(source, source, event, "Validate");
|
||||||
if (event.rc) {
|
if (event.rc) {
|
||||||
if (hasRan) {
|
|
||||||
source.wrapped.value = event.value;
|
|
||||||
source.wrapped.valueAsString = event.value;
|
|
||||||
} else {
|
|
||||||
source.obj.value = event.value;
|
source.obj.value = event.value;
|
||||||
source.obj.valueAsString = event.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._document.obj.calculate) {
|
|
||||||
this.runCalculate(source, event);
|
this.runCalculate(source, event);
|
||||||
|
|
||||||
|
const savedValue = (event.value = source.obj.value);
|
||||||
|
let formattedValue = null;
|
||||||
|
|
||||||
|
if (this.runActions(source, source, event, "Format")) {
|
||||||
|
formattedValue = event.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.value = source.obj.value;
|
source.obj._send({
|
||||||
this.runActions(source, source, event, "Format");
|
id: source.obj._id,
|
||||||
source.wrapped.valueAsString = event.value;
|
value: savedValue,
|
||||||
|
formattedValue,
|
||||||
|
});
|
||||||
|
event.value = savedValue;
|
||||||
|
} else if (didValidateRun) {
|
||||||
|
// The value is not valid.
|
||||||
|
source.obj._send({
|
||||||
|
id: source.obj._id,
|
||||||
|
value: "",
|
||||||
|
formattedValue: null,
|
||||||
|
selRange: [0, 0],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,17 +222,42 @@ class EventDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateNow() {
|
calculateNow() {
|
||||||
if (!this._calculationOrder) {
|
// This function can be called by a JS script (doc.calculateNow()).
|
||||||
|
// If !this._calculationOrder then there is nothing to calculate.
|
||||||
|
// _isCalculating is here to prevent infinite recursion with calculateNow.
|
||||||
|
// If !this._document.obj.calculate then the script doesn't want to have
|
||||||
|
// a calculate.
|
||||||
|
|
||||||
|
if (
|
||||||
|
!this._calculationOrder ||
|
||||||
|
this._isCalculating ||
|
||||||
|
!this._document.obj.calculate
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this._isCalculating = true;
|
||||||
const first = this._calculationOrder[0];
|
const first = this._calculationOrder[0];
|
||||||
const source = this._objects[first];
|
const source = this._objects[first];
|
||||||
globalThis.event = new Event({});
|
globalThis.event = new Event({});
|
||||||
|
|
||||||
|
try {
|
||||||
this.runCalculate(source, globalThis.event);
|
this.runCalculate(source, globalThis.event);
|
||||||
|
} catch (error) {
|
||||||
|
this._isCalculating = false;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isCalculating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
runCalculate(source, event) {
|
runCalculate(source, event) {
|
||||||
if (!this._calculationOrder) {
|
// _document.obj.calculate is equivalent to doc.calculate and can be
|
||||||
|
// changed by a script to allow a future calculate or not.
|
||||||
|
// This function is either called by calculateNow or when an action
|
||||||
|
// is triggered (in this case we cannot be currently calculating).
|
||||||
|
// So there are no need to check for _isCalculating because it has
|
||||||
|
// been already done in calculateNow.
|
||||||
|
if (!this._calculationOrder || !this._document.obj.calculate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,31 +267,43 @@ class EventDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this._document.obj.calculate) {
|
if (!this._document.obj.calculate) {
|
||||||
// An action may have changed calculate value.
|
// An action could have changed calculate value.
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.value = null;
|
event.value = null;
|
||||||
const target = this._objects[targetId];
|
const target = this._objects[targetId];
|
||||||
|
let savedValue = target.obj.value;
|
||||||
this.runActions(source, target, event, "Calculate");
|
this.runActions(source, target, event, "Calculate");
|
||||||
if (!event.rc) {
|
if (!event.rc) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.value !== null) {
|
if (event.value !== null) {
|
||||||
target.wrapped.value = event.value;
|
// A new value has been calculated so set it.
|
||||||
|
target.obj.value = event.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.value = target.obj.value;
|
event.value = target.obj.value;
|
||||||
this.runActions(target, target, event, "Validate");
|
this.runActions(target, target, event, "Validate");
|
||||||
if (!event.rc) {
|
if (!event.rc) {
|
||||||
|
if (target.obj.value !== savedValue) {
|
||||||
|
target.wrapped.value = savedValue;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.value = target.obj.value;
|
savedValue = event.value = target.obj.value;
|
||||||
this.runActions(target, target, event, "Format");
|
let formattedValue = null;
|
||||||
if (event.value !== null) {
|
if (this.runActions(target, target, event, "Format")) {
|
||||||
target.wrapped.valueAsString = event.value;
|
formattedValue = event.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target.obj._send({
|
||||||
|
id: target.obj._id,
|
||||||
|
value: savedValue,
|
||||||
|
formattedValue,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,6 @@ class Field extends PDFObject {
|
|||||||
|
|
||||||
this._globalEval = data.globalEval;
|
this._globalEval = data.globalEval;
|
||||||
this._appObjects = data.appObjects;
|
this._appObjects = data.appObjects;
|
||||||
|
|
||||||
this.valueAsString = data.valueAsString || this._value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentValueIndices() {
|
get currentValueIndices() {
|
||||||
@ -252,14 +250,11 @@ class Field extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get valueAsString() {
|
get valueAsString() {
|
||||||
if (this._valueAsString === undefined) {
|
return (this._value ?? "").toString();
|
||||||
this._valueAsString = this._value ? this._value.toString() : "";
|
|
||||||
}
|
|
||||||
return this._valueAsString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set valueAsString(val) {
|
set valueAsString(_) {
|
||||||
this._valueAsString = val ? val.toString() : "";
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
browseForFileToSubmit() {
|
browseForFileToSubmit() {
|
||||||
@ -376,7 +371,9 @@ class Field extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._children === null) {
|
if (this._children === null) {
|
||||||
this._children = this._document.obj._getChildren(this._fieldPath);
|
this._children = this._document.obj
|
||||||
|
._getChildren(this._fieldPath)
|
||||||
|
.map(child => child.wrapped);
|
||||||
}
|
}
|
||||||
return this._children;
|
return this._children;
|
||||||
}
|
}
|
||||||
@ -481,7 +478,7 @@ class Field extends PDFObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_reset() {
|
_reset() {
|
||||||
this.value = this.valueAsString = this.defaultValue;
|
this.value = this.defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_runActions(event) {
|
_runActions(event) {
|
||||||
|
@ -120,8 +120,8 @@ function initSandbox(params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const wrapped = new Proxy(field, proxyHandler);
|
const wrapped = new Proxy(field, proxyHandler);
|
||||||
doc._addField(name, wrapped);
|
|
||||||
const _object = { obj: field, wrapped };
|
const _object = { obj: field, wrapped };
|
||||||
|
doc._addField(name, _object);
|
||||||
for (const object of objs) {
|
for (const object of objs) {
|
||||||
appObjects[object.id] = _object;
|
appObjects[object.id] = _object;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ describe("Interaction", () => {
|
|||||||
await page.click("[data-annotation-id='402R']");
|
await page.click("[data-annotation-id='402R']");
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
["16", "22", "19", "05", "27"].map(id =>
|
["16", "22", "19", "05"].map(id =>
|
||||||
page.waitForFunction(
|
page.waitForFunction(
|
||||||
`document.querySelector("#\\\\34 ${id}R").value === ""`
|
`document.querySelector("#\\\\34 ${id}R").value === ""`
|
||||||
)
|
)
|
||||||
@ -256,11 +256,14 @@ describe("Interaction", () => {
|
|||||||
text = await page.$eval("#\\34 05R", el => el.value);
|
text = await page.$eval("#\\34 05R", el => el.value);
|
||||||
expect(text).toEqual("");
|
expect(text).toEqual("");
|
||||||
|
|
||||||
const sum = await page.$eval("#\\34 27R", el => el.value);
|
|
||||||
expect(sum).toEqual("");
|
|
||||||
|
|
||||||
checked = await page.$eval("#\\34 49R", el => el.checked);
|
checked = await page.$eval("#\\34 49R", el => el.checked);
|
||||||
expect(checked).toEqual(false);
|
expect(checked).toEqual(false);
|
||||||
|
|
||||||
|
const visibility = await page.$eval(
|
||||||
|
"#\\34 27R",
|
||||||
|
el => getComputedStyle(el).visibility
|
||||||
|
);
|
||||||
|
expect(visibility).toEqual("hidden");
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -992,7 +995,7 @@ describe("Interaction", () => {
|
|||||||
await clearInput(page, "#\\33 0R");
|
await clearInput(page, "#\\33 0R");
|
||||||
|
|
||||||
await page.focus("#\\32 9R");
|
await page.focus("#\\32 9R");
|
||||||
await page.type("#\\32 9R", "12A");
|
await page.type("#\\32 9R", "12A", { delay: 100 });
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
`document.querySelector("#\\\\32 9R").value !== "12A"`
|
`document.querySelector("#\\\\32 9R").value !== "12A"`
|
||||||
);
|
);
|
||||||
@ -1001,7 +1004,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("12");
|
expect(text).withContext(`In ${browserName}`).toEqual("12");
|
||||||
|
|
||||||
await page.focus("#\\32 9R");
|
await page.focus("#\\32 9R");
|
||||||
await page.type("#\\32 9R", "34");
|
await page.type("#\\32 9R", "34", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='30R']");
|
await page.click("[data-annotation-id='30R']");
|
||||||
|
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
@ -1012,7 +1015,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("");
|
expect(text).withContext(`In ${browserName}`).toEqual("");
|
||||||
|
|
||||||
await page.focus("#\\32 9R");
|
await page.focus("#\\32 9R");
|
||||||
await page.type("#\\32 9R", "12345");
|
await page.type("#\\32 9R", "12345", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='30R']");
|
await page.click("[data-annotation-id='30R']");
|
||||||
|
|
||||||
text = await page.$eval(`#\\32 9R`, el => el.value);
|
text = await page.$eval(`#\\32 9R`, el => el.value);
|
||||||
@ -1049,7 +1052,7 @@ describe("Interaction", () => {
|
|||||||
await clearInput(page, "#\\33 0R");
|
await clearInput(page, "#\\33 0R");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "(123) 456A");
|
await page.type("#\\33 0R", "(123) 456A", { delay: 100 });
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
`document.querySelector("#\\\\33 0R").value !== "(123) 456A"`
|
`document.querySelector("#\\\\33 0R").value !== "(123) 456A"`
|
||||||
);
|
);
|
||||||
@ -1058,7 +1061,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("(123) 456");
|
expect(text).withContext(`In ${browserName}`).toEqual("(123) 456");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "-789");
|
await page.type("#\\33 0R", "-789", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='29R']");
|
await page.click("[data-annotation-id='29R']");
|
||||||
|
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
@ -1069,7 +1072,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("");
|
expect(text).withContext(`In ${browserName}`).toEqual("");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "(123) 456-7890");
|
await page.type("#\\33 0R", "(123) 456-7890", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='29R']");
|
await page.click("[data-annotation-id='29R']");
|
||||||
|
|
||||||
text = await page.$eval(`#\\33 0R`, el => el.value);
|
text = await page.$eval(`#\\33 0R`, el => el.value);
|
||||||
@ -1108,7 +1111,7 @@ describe("Interaction", () => {
|
|||||||
await clearInput(page, "#\\33 0R");
|
await clearInput(page, "#\\33 0R");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "123A");
|
await page.type("#\\33 0R", "123A", { delay: 100 });
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
`document.querySelector("#\\\\33 0R").value !== "123A"`
|
`document.querySelector("#\\\\33 0R").value !== "123A"`
|
||||||
);
|
);
|
||||||
@ -1117,7 +1120,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("123");
|
expect(text).withContext(`In ${browserName}`).toEqual("123");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "-456");
|
await page.type("#\\33 0R", "-456", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='29R']");
|
await page.click("[data-annotation-id='29R']");
|
||||||
|
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
@ -1128,7 +1131,7 @@ describe("Interaction", () => {
|
|||||||
expect(text).withContext(`In ${browserName}`).toEqual("");
|
expect(text).withContext(`In ${browserName}`).toEqual("");
|
||||||
|
|
||||||
await page.focus("#\\33 0R");
|
await page.focus("#\\33 0R");
|
||||||
await page.type("#\\33 0R", "123-4567");
|
await page.type("#\\33 0R", "123-4567", { delay: 100 });
|
||||||
await page.click("[data-annotation-id='29R']");
|
await page.click("[data-annotation-id='29R']");
|
||||||
|
|
||||||
text = await page.$eval(`#\\33 0R`, el => el.value);
|
text = await page.$eval(`#\\33 0R`, el => el.value);
|
||||||
@ -1137,4 +1140,166 @@ describe("Interaction", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("in issue14862.pdf", () => {
|
||||||
|
let pages;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
pages = await loadAndWait("issue14862.pdf", "#\\32 7R");
|
||||||
|
pages.map(async ([, page]) => {
|
||||||
|
page.on("dialog", async dialog => {
|
||||||
|
await dialog.dismiss();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await closePages(pages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must convert input in uppercase", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.type("#\\32 7R", "Hello", { delay: 100 });
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 7R").value !== "Hello"`
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HELLO");
|
||||||
|
|
||||||
|
await page.type("#\\32 7R", " world", { delay: 100 });
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 7R").value !== "HELLO world"`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HELLO WORLD");
|
||||||
|
|
||||||
|
await page.keyboard.press("Backspace");
|
||||||
|
await page.keyboard.press("Backspace");
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 7R").value !== "HELLO WORLD"`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HELLO WOR");
|
||||||
|
|
||||||
|
await page.type("#\\32 7R", "12.dL", { delay: 100 });
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 7R").value !== "HELLO WOR"`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HELLO WORDL");
|
||||||
|
|
||||||
|
await page.type("#\\32 7R", " ", { delay: 100 });
|
||||||
|
|
||||||
|
await page.keyboard.down("Control");
|
||||||
|
await page.keyboard.press("Backspace");
|
||||||
|
await page.keyboard.up("Control");
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 7R").value !== "HELLO WORDL "`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HELLO ");
|
||||||
|
|
||||||
|
await page.$eval("#\\32 7R", el => {
|
||||||
|
// Select LL
|
||||||
|
el.selectionStart = 2;
|
||||||
|
el.selectionEnd = 4;
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.keyboard.press("a");
|
||||||
|
text = await page.$eval("#\\32 7R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("HEAO ");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that an infinite loop is not triggered", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.type("#\\32 8R", "Hello", { delay: 100 });
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 8R").value !== "123"`
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = await page.$eval("#\\32 8R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("Hello123");
|
||||||
|
|
||||||
|
// The action will trigger a calculateNow which itself
|
||||||
|
// will trigger a resetForm (inducing a calculateNow) and a
|
||||||
|
// calculateNow.
|
||||||
|
await page.click("[data-annotation-id='31R']");
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 8R").value !== "Hello123"`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Without preventing against infinite loop the field is empty.
|
||||||
|
text = await page.$eval("#\\32 8R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("123");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("in issue14705.pdf", () => {
|
||||||
|
let pages;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
pages = await loadAndWait("issue14705.pdf", "#\\32 9R");
|
||||||
|
pages.map(async ([, page]) => {
|
||||||
|
page.on("dialog", async dialog => {
|
||||||
|
await dialog.dismiss();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await closePages(pages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that field value is correctly updated", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.type("#\\32 9R", "Hello World", { delay: 100 });
|
||||||
|
await page.click("#\\32 7R");
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 9R").value !== "Hello World"`
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = await page.$eval("#\\32 9R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("checked");
|
||||||
|
|
||||||
|
await page.click("#\\32 7R");
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
`document.querySelector("#\\\\32 9R").value !== "checked"`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval("#\\32 9R", el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("unchecked");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
2
test/pdfs/.gitignore
vendored
2
test/pdfs/.gitignore
vendored
@ -520,3 +520,5 @@
|
|||||||
!issue14502.pdf
|
!issue14502.pdf
|
||||||
!issue13211.pdf
|
!issue13211.pdf
|
||||||
!issue14627.pdf
|
!issue14627.pdf
|
||||||
|
!issue14862.pdf
|
||||||
|
!issue14705.pdf
|
||||||
|
BIN
test/pdfs/issue14705.pdf
Normal file
BIN
test/pdfs/issue14705.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/issue14862.pdf
Executable file
BIN
test/pdfs/issue14862.pdf
Executable file
Binary file not shown.
@ -1320,7 +1320,7 @@ describe("api", function () {
|
|||||||
{
|
{
|
||||||
id: "25R",
|
id: "25R",
|
||||||
value: "",
|
value: "",
|
||||||
defaultValue: null,
|
defaultValue: "",
|
||||||
multiline: false,
|
multiline: false,
|
||||||
password: false,
|
password: false,
|
||||||
charLimit: null,
|
charLimit: null,
|
||||||
|
@ -89,7 +89,7 @@ describe("Scripting", function () {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
const number = 123;
|
const number = 123;
|
||||||
const expected = (((number - 1) * number) / 2).toString();
|
const expected = ((number - 1) * number) / 2;
|
||||||
const refId = getId();
|
const refId = getId();
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@ -120,7 +120,8 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.has(refId)).toEqual(true);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
expect(send_queue.get(refId)).toEqual({
|
expect(send_queue.get(refId)).toEqual({
|
||||||
id: refId,
|
id: refId,
|
||||||
valueAsString: expected,
|
value: expected,
|
||||||
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -406,6 +407,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refId)).toEqual({
|
expect(send_queue.get(refId)).toEqual({
|
||||||
id: refId,
|
id: refId,
|
||||||
value: "hella",
|
value: "hella",
|
||||||
|
selRange: [5, 5],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -478,7 +480,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refId1)).toEqual({
|
expect(send_queue.get(refId1)).toEqual({
|
||||||
id: refId1,
|
id: refId1,
|
||||||
value: "world",
|
value: "world",
|
||||||
valueAsString: "world",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -799,7 +801,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refId)).toEqual({
|
expect(send_queue.get(refId)).toEqual({
|
||||||
id: refId,
|
id: refId,
|
||||||
value: "123456.789",
|
value: "123456.789",
|
||||||
valueAsString: "123456.789",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -978,7 +980,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refId)).toEqual({
|
expect(send_queue.get(refId)).toEqual({
|
||||||
id: refId,
|
id: refId,
|
||||||
value: "321",
|
value: "321",
|
||||||
valueAsString: "321",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1076,7 +1078,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refIds[3])).toEqual({
|
expect(send_queue.get(refIds[3])).toEqual({
|
||||||
id: refIds[3],
|
id: refIds[3],
|
||||||
value: 1,
|
value: 1,
|
||||||
valueAsString: "1",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
@ -1089,7 +1091,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refIds[3])).toEqual({
|
expect(send_queue.get(refIds[3])).toEqual({
|
||||||
id: refIds[3],
|
id: refIds[3],
|
||||||
value: 3,
|
value: 3,
|
||||||
valueAsString: "3",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
@ -1102,7 +1104,7 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.get(refIds[3])).toEqual({
|
expect(send_queue.get(refIds[3])).toEqual({
|
||||||
id: refIds[3],
|
id: refIds[3],
|
||||||
value: 6,
|
value: 6,
|
||||||
valueAsString: "6",
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1137,7 +1139,8 @@ describe("Scripting", function () {
|
|||||||
selStart: 0,
|
selStart: 0,
|
||||||
selEnd: 0,
|
selEnd: 0,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
id: refId,
|
id: refId,
|
||||||
@ -1148,7 +1151,8 @@ describe("Scripting", function () {
|
|||||||
selStart: 1,
|
selStart: 1,
|
||||||
selEnd: 1,
|
selEnd: 1,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
id: refId,
|
id: refId,
|
||||||
@ -1159,7 +1163,8 @@ describe("Scripting", function () {
|
|||||||
selStart: 2,
|
selStart: 2,
|
||||||
selEnd: 2,
|
selEnd: 2,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
id: refId,
|
id: refId,
|
||||||
@ -1187,7 +1192,8 @@ describe("Scripting", function () {
|
|||||||
selStart: 3,
|
selStart: 3,
|
||||||
selEnd: 3,
|
selEnd: 3,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
|
|
||||||
await sandbox.dispatchEventInSandbox({
|
await sandbox.dispatchEventInSandbox({
|
||||||
id: refId,
|
id: refId,
|
||||||
@ -1200,7 +1206,8 @@ describe("Scripting", function () {
|
|||||||
expect(send_queue.has(refId)).toEqual(true);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
expect(send_queue.get(refId)).toEqual({
|
expect(send_queue.get(refId)).toEqual({
|
||||||
id: refId,
|
id: refId,
|
||||||
valueAsString: "3F?0",
|
value: "3F?0",
|
||||||
|
formattedValue: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1242,7 +1249,8 @@ describe("Scripting", function () {
|
|||||||
selStart: i,
|
selStart: i,
|
||||||
selEnd: i,
|
selEnd: i,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
value += change;
|
value += change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,7 +1309,8 @@ describe("Scripting", function () {
|
|||||||
selStart: i,
|
selStart: i,
|
||||||
selEnd: i,
|
selEnd: i,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
value += change;
|
value += change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,7 +1369,8 @@ describe("Scripting", function () {
|
|||||||
selStart: i,
|
selStart: i,
|
||||||
selEnd: i,
|
selEnd: i,
|
||||||
});
|
});
|
||||||
expect(send_queue.has(refId)).toEqual(false);
|
expect(send_queue.has(refId)).toEqual(true);
|
||||||
|
send_queue.delete(refId);
|
||||||
value += change;
|
value += change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user