[JS] Correctly format field with numbers (bug 1811694, bug 1811510)

In PR #15757, a value is automatically converted into a number when it's possible
but the case of numbers like "000123" has been overlooked and their format must
be preserved.
When a script is doing something like "foo.value + bar.value" and the values are
numbers then "foo.value" must return a number but the displayed value must be what
the user entered or what a script set, so this patch is just adding a a field
_orginalValue in order to track the value has it has defined.
Some people are used to use a comma as decimal separator, hence it must be considered
when a value is parsed into a number.
This patch is fixing a regression introduced by #15757.
This commit is contained in:
Calixte Denizet 2023-01-26 13:04:48 +01:00
parent 1b1ebf6a77
commit 6f4d037a8e
8 changed files with 95 additions and 9 deletions

View File

@ -249,7 +249,8 @@ class EventDispatcher {
this.runCalculate(source, event);
const savedValue = (event.value = source.obj.value);
const savedValue = source.obj._getValue();
event.value = source.obj.value;
let formattedValue = null;
if (this.runActions(source, source, event, "Format")) {

View File

@ -251,14 +251,19 @@ class Field extends PDFObject {
this._value = "";
} else if (typeof value === "string") {
switch (this._fieldType) {
case FieldType.none:
this._value = !isNaN(value) ? parseFloat(value) : value;
case FieldType.none: {
this._originalValue = value;
const _value = value.trim().replace(",", ".");
this._value = !isNaN(_value) ? parseFloat(_value) : value;
break;
}
case FieldType.number:
case FieldType.percent:
const number = parseFloat(value);
case FieldType.percent: {
const _value = value.trim().replace(",", ".");
const number = parseFloat(_value);
this._value = !isNaN(number) ? number : 0;
break;
}
default:
this._value = value;
}
@ -267,6 +272,10 @@ class Field extends PDFObject {
}
}
_getValue() {
return this._originalValue ?? this.value;
}
_setChoiceValue(value) {
if (this.multipleSelection) {
if (!Array.isArray(value)) {

View File

@ -63,7 +63,7 @@ class ProxyHandler {
typeof old !== "function"
) {
const data = { id: obj._id };
data[prop] = obj[prop];
data[prop] = prop === "value" ? obj._getValue() : obj[prop];
// send the updated value to the other side
if (!obj._siblings) {

View File

@ -1780,4 +1780,78 @@ describe("Interaction", () => {
);
});
});
describe("in bug1811694.pdf", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("bug1811694.pdf", getSelector("25R"));
});
afterAll(async () => {
await closePages(pages);
});
it("must check that a field value with a number isn't changed", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.waitForFunction(
"window.PDFViewerApplication.scriptingReady === true"
);
await page.click(getSelector("25R"));
await page.type(getSelector("25R"), "00000000123", { delay: 10 });
let text = await page.$eval(getSelector("25R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("00000000123");
await page.click(getSelector("26R"));
await page.waitForTimeout(10);
text = await page.$eval(getSelector("25R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("00000000123");
})
);
});
});
describe("in bug1811510.pdf", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("bug1811510.pdf", getSelector("22R"));
});
afterAll(async () => {
await closePages(pages);
});
it("must check that a field value with a number with a comma has the correct value", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.waitForFunction(
"window.PDFViewerApplication.scriptingReady === true"
);
let text = await page.$eval(getSelector("22R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("5,25");
await page.$eval(getSelector("31R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("5,25");
await page.click(getSelector("22R"));
await page.waitForTimeout(10);
text = await page.$eval(getSelector("22R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("5,25");
await page.click(getSelector("31R"));
await page.waitForTimeout(10);
text = await page.$eval(getSelector("31R"), el => el.value);
expect(text).withContext(`In ${browserName}`).toEqual("5.25");
})
);
});
});
});

View File

@ -568,3 +568,5 @@
!issue15815.pdf
!issue15818.pdf
!autoprint.pdf
!bug1811694.pdf
!bug1811510.pdf

BIN
test/pdfs/bug1811510.pdf Executable file

Binary file not shown.

BIN
test/pdfs/bug1811694.pdf Executable file

Binary file not shown.

View File

@ -346,7 +346,7 @@ describe("Scripting", function () {
expect(send_queue.has(refId)).toEqual(true);
expect(send_queue.get(refId)).toEqual({
id: refId,
value: 123,
value: "123",
});
});
@ -826,7 +826,7 @@ describe("Scripting", function () {
expect(send_queue.get(refId)).toEqual({
id: refId,
siblings: null,
value: 123456.789,
value: "123456.789",
formattedValue: null,
});
});
@ -1006,7 +1006,7 @@ describe("Scripting", function () {
expect(send_queue.get(refId)).toEqual({
id: refId,
siblings: null,
value: 321,
value: "321",
formattedValue: null,
});
});