Merge pull request #17271 from calixteman/maif
Get the field name from its parent when it doesn't have one when collecting fields (bug 1864136)
This commit is contained in:
commit
787d092ecb
@ -1711,12 +1711,19 @@ class PDFDocument {
|
||||
: clearGlobalCaches();
|
||||
}
|
||||
|
||||
async #collectFieldObjects(name, fieldRef, promises, annotationGlobals) {
|
||||
async #collectFieldObjects(
|
||||
name,
|
||||
fieldRef,
|
||||
promises,
|
||||
annotationGlobals,
|
||||
visitedRefs
|
||||
) {
|
||||
const { xref } = this;
|
||||
|
||||
if (!(fieldRef instanceof Ref)) {
|
||||
if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {
|
||||
return;
|
||||
}
|
||||
visitedRefs.put(fieldRef);
|
||||
const field = await xref.fetchAsync(fieldRef);
|
||||
if (!(field instanceof Dict)) {
|
||||
return;
|
||||
@ -1724,6 +1731,25 @@ class PDFDocument {
|
||||
if (field.has("T")) {
|
||||
const partName = stringToPDFString(await field.getAsync("T"));
|
||||
name = name === "" ? partName : `${name}.${partName}`;
|
||||
} else {
|
||||
let obj = field;
|
||||
while (true) {
|
||||
obj = obj.getRaw("Parent");
|
||||
if (obj instanceof Ref) {
|
||||
if (visitedRefs.has(obj)) {
|
||||
break;
|
||||
}
|
||||
obj = await xref.fetchAsync(obj);
|
||||
}
|
||||
if (!(obj instanceof Dict)) {
|
||||
break;
|
||||
}
|
||||
if (obj.has("T")) {
|
||||
const partName = stringToPDFString(await obj.getAsync("T"));
|
||||
name = name === "" ? partName : `${name}.${partName}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!promises.has(name)) {
|
||||
@ -1751,7 +1777,13 @@ class PDFDocument {
|
||||
const kids = await field.getAsync("Kids");
|
||||
if (Array.isArray(kids)) {
|
||||
for (const kid of kids) {
|
||||
await this.#collectFieldObjects(name, kid, promises, annotationGlobals);
|
||||
await this.#collectFieldObjects(
|
||||
name,
|
||||
kid,
|
||||
promises,
|
||||
annotationGlobals,
|
||||
visitedRefs
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1769,6 +1801,7 @@ class PDFDocument {
|
||||
return null;
|
||||
}
|
||||
|
||||
const visitedRefs = new RefSet();
|
||||
const allFields = Object.create(null);
|
||||
const fieldPromises = new Map();
|
||||
for (const fieldRef of await acroForm.getAsync("Fields")) {
|
||||
@ -1776,7 +1809,8 @@ class PDFDocument {
|
||||
"",
|
||||
fieldRef,
|
||||
fieldPromises,
|
||||
annotationGlobals
|
||||
annotationGlobals,
|
||||
visitedRefs
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
import {
|
||||
clearInput,
|
||||
closePages,
|
||||
getAnnotationStorage,
|
||||
getComputedStyleSelector,
|
||||
getFirstSerialized,
|
||||
getQuerySelector,
|
||||
@ -24,6 +25,7 @@ import {
|
||||
kbSelectAll,
|
||||
loadAndWait,
|
||||
scrollIntoView,
|
||||
waitForEntryInStorage,
|
||||
} from "./test_utils.mjs";
|
||||
|
||||
describe("Interaction", () => {
|
||||
@ -2225,4 +2227,58 @@ describe("Interaction", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Radio button without T value", () => {
|
||||
let pages;
|
||||
let otherPages;
|
||||
|
||||
beforeAll(async () => {
|
||||
otherPages = await Promise.all(
|
||||
global.integrationSessions.map(async session =>
|
||||
session.browser.newPage()
|
||||
)
|
||||
);
|
||||
pages = await loadAndWait("bug1860602.pdf", getSelector("22R"));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await closePages(pages);
|
||||
await Promise.all(otherPages.map(page => page.close()));
|
||||
});
|
||||
|
||||
it("must check that only one radio is selected", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page], i) => {
|
||||
await page.waitForFunction(
|
||||
"window.PDFViewerApplication.scriptingReady === true"
|
||||
);
|
||||
await scrollIntoView(page, getSelector("22R"));
|
||||
|
||||
await page.click(getSelector("25R"));
|
||||
await waitForEntryInStorage(page, "25R", { value: true });
|
||||
|
||||
let storage = await getAnnotationStorage(page);
|
||||
expect(storage)
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual({
|
||||
"22R": { value: false },
|
||||
"25R": { value: true },
|
||||
"28R": { value: false },
|
||||
});
|
||||
|
||||
await page.click(getSelector("22R"));
|
||||
await waitForEntryInStorage(page, "22R", { value: true });
|
||||
|
||||
storage = await getAnnotationStorage(page);
|
||||
expect(storage)
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual({
|
||||
"22R": { value: true },
|
||||
"25R": { value: false },
|
||||
"28R": { value: false },
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -176,6 +176,28 @@ async function getFirstSerialized(page, filter = undefined) {
|
||||
return (await getSerialized(page, filter))[0];
|
||||
}
|
||||
|
||||
function getAnnotationStorage(page) {
|
||||
return page.evaluate(() =>
|
||||
Object.fromEntries(
|
||||
window.PDFViewerApplication.pdfDocument.annotationStorage.serializable.map?.entries() ||
|
||||
[]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function waitForEntryInStorage(page, key, value) {
|
||||
return page.waitForFunction(
|
||||
(k, v) => {
|
||||
const { map } =
|
||||
window.PDFViewerApplication.pdfDocument.annotationStorage.serializable;
|
||||
return map && JSON.stringify(map.get(k)) === v;
|
||||
},
|
||||
{},
|
||||
key,
|
||||
JSON.stringify(value)
|
||||
);
|
||||
}
|
||||
|
||||
function getEditors(page, kind) {
|
||||
return page.evaluate(aKind => {
|
||||
const elements = document.querySelectorAll(`.${aKind}Editor`);
|
||||
@ -398,6 +420,7 @@ export {
|
||||
clearInput,
|
||||
closePages,
|
||||
dragAndDropAnnotation,
|
||||
getAnnotationStorage,
|
||||
getComputedStyleSelector,
|
||||
getEditorDimensions,
|
||||
getEditors,
|
||||
@ -427,6 +450,7 @@ export {
|
||||
scrollIntoView,
|
||||
serializeBitmapDimensions,
|
||||
waitForAnnotationEditorLayer,
|
||||
waitForEntryInStorage,
|
||||
waitForEvent,
|
||||
waitForSelectedEditor,
|
||||
waitForSerialized,
|
||||
|
Loading…
Reference in New Issue
Block a user