Merge pull request #16433 from calixteman/bug1825002
For text widgets, get the text from the AP stream instead of from the format callback (bug 1825002)
This commit is contained in:
commit
839be801a0
@ -2461,6 +2461,10 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||||||
this.data.doNotScroll = this.hasFieldFlag(AnnotationFieldFlag.DONOTSCROLL);
|
this.data.doNotScroll = this.hasFieldFlag(AnnotationFieldFlag.DONOTSCROLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get hasTextContent() {
|
||||||
|
return !!this.appearance;
|
||||||
|
}
|
||||||
|
|
||||||
_getCombAppearance(
|
_getCombAppearance(
|
||||||
defaultAppearance,
|
defaultAppearance,
|
||||||
font,
|
font,
|
||||||
|
@ -1049,7 +1049,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
const storedData = storage.getValue(id, {
|
const storedData = storage.getValue(id, {
|
||||||
value: this.data.fieldValue,
|
value: this.data.fieldValue,
|
||||||
});
|
});
|
||||||
let textContent = storedData.formattedValue || storedData.value || "";
|
let textContent = storedData.value || "";
|
||||||
const maxLen = storage.getValue(id, {
|
const maxLen = storage.getValue(id, {
|
||||||
charLimit: this.data.maxLen,
|
charLimit: this.data.maxLen,
|
||||||
}).charLimit;
|
}).charLimit;
|
||||||
@ -1057,23 +1057,29 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
textContent = textContent.slice(0, maxLen);
|
textContent = textContent.slice(0, maxLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fieldFormattedValues =
|
||||||
|
storedData.formattedValue || this.data.textContent?.join("\n") || null;
|
||||||
|
if (fieldFormattedValues && this.data.comb) {
|
||||||
|
fieldFormattedValues = fieldFormattedValues.replaceAll(/\s+/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
const elementData = {
|
const elementData = {
|
||||||
userValue: textContent,
|
userValue: textContent,
|
||||||
formattedValue: null,
|
formattedValue: fieldFormattedValues,
|
||||||
lastCommittedValue: null,
|
lastCommittedValue: null,
|
||||||
commitKey: 1,
|
commitKey: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.data.multiLine) {
|
if (this.data.multiLine) {
|
||||||
element = document.createElement("textarea");
|
element = document.createElement("textarea");
|
||||||
element.textContent = textContent;
|
element.textContent = fieldFormattedValues ?? textContent;
|
||||||
if (this.data.doNotScroll) {
|
if (this.data.doNotScroll) {
|
||||||
element.style.overflowY = "hidden";
|
element.style.overflowY = "hidden";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
element = document.createElement("input");
|
element = document.createElement("input");
|
||||||
element.type = "text";
|
element.type = "text";
|
||||||
element.setAttribute("value", textContent);
|
element.setAttribute("value", fieldFormattedValues ?? textContent);
|
||||||
if (this.data.doNotScroll) {
|
if (this.data.doNotScroll) {
|
||||||
element.style.overflowX = "hidden";
|
element.style.overflowX = "hidden";
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,9 @@ class EventDispatcher {
|
|||||||
// errors in the case where a formatter is using one of those named
|
// errors in the case where a formatter is using one of those named
|
||||||
// actions (see #15818).
|
// actions (see #15818).
|
||||||
this._document.obj._initActions();
|
this._document.obj._initActions();
|
||||||
// Before running the Open event, we format all the fields
|
// Before running the Open event, we run the format callbacks but
|
||||||
// (see bug 1766987).
|
// without changing the value of the fields.
|
||||||
|
// Acrobat does the same thing.
|
||||||
this.formatAll();
|
this.formatAll();
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@ -232,13 +233,7 @@ class EventDispatcher {
|
|||||||
const event = (globalThis.event = new Event({}));
|
const event = (globalThis.event = new Event({}));
|
||||||
for (const source of Object.values(this._objects)) {
|
for (const source of Object.values(this._objects)) {
|
||||||
event.value = source.obj.value;
|
event.value = source.obj.value;
|
||||||
if (this.runActions(source, source, event, "Format")) {
|
this.runActions(source, source, event, "Format");
|
||||||
source.obj._send({
|
|
||||||
id: source.obj._id,
|
|
||||||
siblings: source.obj._siblings,
|
|
||||||
formattedValue: event.value?.toString?.(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createActionsMap, FieldType, getFieldType } from "./common.js";
|
import { createActionsMap, getFieldType } from "./common.js";
|
||||||
import { Color } from "./color.js";
|
import { Color } from "./color.js";
|
||||||
import { PDFObject } from "./pdf_object.js";
|
import { PDFObject } from "./pdf_object.js";
|
||||||
|
|
||||||
@ -247,29 +247,15 @@ class Field extends PDFObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === "") {
|
if (value === "" || typeof value !== "string") {
|
||||||
this._value = "";
|
this._originalValue = undefined;
|
||||||
} else if (typeof value === "string") {
|
|
||||||
switch (this._fieldType) {
|
|
||||||
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 _value = value.trim().replace(",", ".");
|
|
||||||
const number = parseFloat(_value);
|
|
||||||
this._value = !isNaN(number) ? number : 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
this._value = value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._value = value;
|
this._value = value;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._originalValue = value;
|
||||||
|
const _value = value.trim().replace(",", ".");
|
||||||
|
this._value = !isNaN(_value) ? parseFloat(_value) : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getValue() {
|
_getValue() {
|
||||||
|
@ -1897,4 +1897,70 @@ describe("Interaction", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("in bug1825002.pdf", () => {
|
||||||
|
let pages;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
pages = await loadAndWait("bug1825002.pdf", getSelector("23R"));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await closePages(pages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that a field has the correct formatted value", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = await page.$eval(getSelector("23R"), el => el.value);
|
||||||
|
expect(text)
|
||||||
|
.withContext(`In ${browserName}`)
|
||||||
|
.toEqual("ABCDEFGHIJKLMN");
|
||||||
|
|
||||||
|
await page.click(getSelector("23R"));
|
||||||
|
await page.waitForFunction(
|
||||||
|
`${getQuerySelector("23R")}.value !== "ABCDEFGHIJKLMN"`
|
||||||
|
);
|
||||||
|
|
||||||
|
text = await page.$eval(getSelector("23R"), el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("123,45.7A");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("must check that a field is empty", async () => {
|
||||||
|
await Promise.all(
|
||||||
|
pages.map(async ([browserName, page]) => {
|
||||||
|
await page.waitForFunction(
|
||||||
|
"window.PDFViewerApplication.scriptingReady === true"
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = await page.$eval(getSelector("26R"), el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("");
|
||||||
|
|
||||||
|
await page.click(getSelector("26R"));
|
||||||
|
await page.type(getSelector("26R"), "abcde", { delay: 10 });
|
||||||
|
|
||||||
|
await page.click(getSelector("23R"));
|
||||||
|
await page.waitForTimeout(10);
|
||||||
|
await page.click(getSelector("26R"));
|
||||||
|
|
||||||
|
await page.keyboard.down("Control");
|
||||||
|
await page.keyboard.press("A");
|
||||||
|
await page.keyboard.up("Control");
|
||||||
|
await page.keyboard.press("Backspace");
|
||||||
|
|
||||||
|
await page.click(getSelector("23R"));
|
||||||
|
await page.waitForTimeout(10);
|
||||||
|
|
||||||
|
text = await page.$eval(getSelector("26R"), el => el.value);
|
||||||
|
expect(text).withContext(`In ${browserName}`).toEqual("");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -591,3 +591,4 @@
|
|||||||
!issue16316.pdf
|
!issue16316.pdf
|
||||||
!issue14565.pdf
|
!issue14565.pdf
|
||||||
!multiline.pdf
|
!multiline.pdf
|
||||||
|
!bug1825002.pdf
|
||||||
|
BIN
test/pdfs/bug1825002.pdf
Executable file
BIN
test/pdfs/bug1825002.pdf
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user