Merge pull request #20977 from calixteman/bug2026037

Use non-breakable spaces in options for the choice widget (bug 2026037)
This commit is contained in:
calixteman 2026-03-26 23:55:49 +01:00 committed by GitHub
commit a9e439bce1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 4 deletions

View File

@ -2139,10 +2139,18 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
}
});
const fixDisplayValue = (option, value) => {
const newValue = value.replaceAll(" ", "\u00A0");
option.textContent = newValue;
if (newValue !== value) {
option.setAttribute("display-value", value);
}
};
// Insert the options into the choice field.
for (const option of this.data.options) {
const optionElement = document.createElement("option");
optionElement.textContent = option.displayValue;
fixDisplayValue(optionElement, option.displayValue);
optionElement.value = option.exportValue;
if (storedData.value.includes(option.exportValue)) {
optionElement.setAttribute("selected", true);
@ -2185,7 +2193,8 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
const getItems = event => {
const options = event.target.options;
return Array.prototype.map.call(options, option => ({
displayValue: option.textContent,
displayValue:
option.getAttribute("display-value") || option.textContent,
exportValue: option.value,
}));
};
@ -2239,7 +2248,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
const { index, displayValue, exportValue } = event.detail.insert;
const selectChild = selectElement.children[index];
const optionElement = document.createElement("option");
optionElement.textContent = displayValue;
fixDisplayValue(optionElement, displayValue);
optionElement.value = exportValue;
if (selectChild) {
@ -2261,7 +2270,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
for (const item of items) {
const { displayValue, exportValue } = item;
const optionElement = document.createElement("option");
optionElement.textContent = displayValue;
fixDisplayValue(optionElement, displayValue);
optionElement.value = exportValue;
selectElement.append(optionElement);
}

View File

@ -920,4 +920,50 @@ a dynamic compiler for JavaScript based on our`);
);
});
});
describe("bug 2026037", () => {
let pages;
beforeEach(async () => {
pages = await loadAndWait("bug2026037.pdf", getAnnotationSelector("22R"));
});
afterEach(async () => {
await closePages(pages);
});
it("must check that spaces in a choice option display value are preserved", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
// The option's displayValue contains multiple consecutive spaces
// ("A B"). Browsers collapse spaces in textContent, so the
// fix stores the original in a "display-value" attribute and uses
// non-breaking spaces (\u00A0) in textContent.
const displayAttr = await page.$eval(
`${getSelector("22R")} option`,
el => el.getAttribute("display-value")
);
expect(displayAttr)
.withContext(`In ${browserName}`)
.toEqual("A B");
const textContent = await page.$eval(
`${getSelector("22R")} option`,
el => el.textContent
);
expect(textContent)
.withContext(`In ${browserName}`)
.toEqual("A\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0B");
const exportValue = await page.$eval(
`${getSelector("22R")} option`,
el => el.value
);
expect(exportValue)
.withContext(`In ${browserName}`)
.toEqual("a b");
})
);
});
});
});

View File

@ -893,3 +893,4 @@
!text_rise_eol_bug.pdf
!hello_world_rotated.pdf
!bug2025674.pdf
!bug2026037.pdf

BIN
test/pdfs/bug2026037.pdf Executable file

Binary file not shown.