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();
|
: clearGlobalCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
async #collectFieldObjects(name, fieldRef, promises, annotationGlobals) {
|
async #collectFieldObjects(
|
||||||
|
name,
|
||||||
|
fieldRef,
|
||||||
|
promises,
|
||||||
|
annotationGlobals,
|
||||||
|
visitedRefs
|
||||||
|
) {
|
||||||
const { xref } = this;
|
const { xref } = this;
|
||||||
|
|
||||||
if (!(fieldRef instanceof Ref)) {
|
if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
visitedRefs.put(fieldRef);
|
||||||
const field = await xref.fetchAsync(fieldRef);
|
const field = await xref.fetchAsync(fieldRef);
|
||||||
if (!(field instanceof Dict)) {
|
if (!(field instanceof Dict)) {
|
||||||
return;
|
return;
|
||||||
@ -1724,6 +1731,25 @@ class PDFDocument {
|
|||||||
if (field.has("T")) {
|
if (field.has("T")) {
|
||||||
const partName = stringToPDFString(await field.getAsync("T"));
|
const partName = stringToPDFString(await field.getAsync("T"));
|
||||||
name = name === "" ? partName : `${name}.${partName}`;
|
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)) {
|
if (!promises.has(name)) {
|
||||||
@ -1751,7 +1777,13 @@ class PDFDocument {
|
|||||||
const kids = await field.getAsync("Kids");
|
const kids = await field.getAsync("Kids");
|
||||||
if (Array.isArray(kids)) {
|
if (Array.isArray(kids)) {
|
||||||
for (const kid of 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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const visitedRefs = new RefSet();
|
||||||
const allFields = Object.create(null);
|
const allFields = Object.create(null);
|
||||||
const fieldPromises = new Map();
|
const fieldPromises = new Map();
|
||||||
for (const fieldRef of await acroForm.getAsync("Fields")) {
|
for (const fieldRef of await acroForm.getAsync("Fields")) {
|
||||||
@ -1776,7 +1809,8 @@ class PDFDocument {
|
|||||||
"",
|
"",
|
||||||
fieldRef,
|
fieldRef,
|
||||||
fieldPromises,
|
fieldPromises,
|
||||||
annotationGlobals
|
annotationGlobals,
|
||||||
|
visitedRefs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import {
|
import {
|
||||||
clearInput,
|
clearInput,
|
||||||
closePages,
|
closePages,
|
||||||
|
getAnnotationStorage,
|
||||||
getComputedStyleSelector,
|
getComputedStyleSelector,
|
||||||
getFirstSerialized,
|
getFirstSerialized,
|
||||||
getQuerySelector,
|
getQuerySelector,
|
||||||
@ -24,6 +25,7 @@ import {
|
|||||||
kbSelectAll,
|
kbSelectAll,
|
||||||
loadAndWait,
|
loadAndWait,
|
||||||
scrollIntoView,
|
scrollIntoView,
|
||||||
|
waitForEntryInStorage,
|
||||||
} from "./test_utils.mjs";
|
} from "./test_utils.mjs";
|
||||||
|
|
||||||
describe("Interaction", () => {
|
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];
|
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) {
|
function getEditors(page, kind) {
|
||||||
return page.evaluate(aKind => {
|
return page.evaluate(aKind => {
|
||||||
const elements = document.querySelectorAll(`.${aKind}Editor`);
|
const elements = document.querySelectorAll(`.${aKind}Editor`);
|
||||||
@ -398,6 +420,7 @@ export {
|
|||||||
clearInput,
|
clearInput,
|
||||||
closePages,
|
closePages,
|
||||||
dragAndDropAnnotation,
|
dragAndDropAnnotation,
|
||||||
|
getAnnotationStorage,
|
||||||
getComputedStyleSelector,
|
getComputedStyleSelector,
|
||||||
getEditorDimensions,
|
getEditorDimensions,
|
||||||
getEditors,
|
getEditors,
|
||||||
@ -427,6 +450,7 @@ export {
|
|||||||
scrollIntoView,
|
scrollIntoView,
|
||||||
serializeBitmapDimensions,
|
serializeBitmapDimensions,
|
||||||
waitForAnnotationEditorLayer,
|
waitForAnnotationEditorLayer,
|
||||||
|
waitForEntryInStorage,
|
||||||
waitForEvent,
|
waitForEvent,
|
||||||
waitForSelectedEditor,
|
waitForSelectedEditor,
|
||||||
waitForSerialized,
|
waitForSerialized,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user