1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-20 15:18:08 +02:00

Make tagged images visible for screen readers (bug 1708040)

The idea is to insert a span in the text layer with an aria-role set to img
and use the bounding box provided by the attribute field in the tag dict in
order to have non-null dimensions for the image to make it "visible".
This commit is contained in:
Calixte Denizet 2024-09-04 16:45:09 +02:00
parent 4b906ad0a8
commit ddba096191
12 changed files with 240 additions and 10 deletions

View file

@ -241,4 +241,44 @@ describe("accessibility", () => {
);
});
});
describe("Figure in the content stream", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("bug1708040.pdf", ".textLayer");
});
afterAll(async () => {
await closePages(pages);
});
it("must check that an image is correctly inserted in the text layer", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
expect(await isStructTreeVisible(page))
.withContext(`In ${browserName}`)
.toBeTrue();
const spanId = await page.evaluate(() => {
const el = document.querySelector(
`.structTree span[role="figure"]`
);
return el.getAttribute("aria-owns") || null;
});
expect(spanId).withContext(`In ${browserName}`).not.toBeNull();
const ariaLabel = await page.evaluate(id => {
const img = document.querySelector(`#${id} > span[role="img"]`);
return img.getAttribute("aria-label");
}, spanId);
expect(ariaLabel)
.withContext(`In ${browserName}`)
.toEqual("A logo of a fox and a globe");
})
);
});
});
});

View file

@ -2053,4 +2053,51 @@ describe("Highlight Editor", () => {
);
});
});
describe("Free Highlight with an image in the struct tree", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait(
"bug1708040.pdf",
".annotationEditorLayer",
null,
null,
{ highlightEditorColors: "red=#AB0000" }
);
});
afterAll(async () => {
await closePages(pages);
});
it("must check that it's possible to draw on an image in a struct tree", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await switchToHighlight(page);
const rect = await getRect(page, `.textLayer span[role="img"]`);
const x = rect.x + rect.width / 2;
const y = rect.y + rect.height / 2;
const clickHandle = await waitForPointerUp(page);
await page.mouse.move(x, y);
await page.mouse.down();
await page.mouse.move(rect.x - 1, rect.y - 1);
await page.mouse.up();
await awaitPromise(clickHandle);
await page.waitForSelector(getEditorSelector(0));
const usedColor = await page.evaluate(() => {
const highlight = document.querySelector(
`.page[data-page-number = "1"] .canvasWrapper > svg.highlight`
);
return highlight.getAttribute("fill");
});
expect(usedColor).withContext(`In ${browserName}`).toEqual("#AB0000");
})
);
});
});
});

View file

@ -664,3 +664,4 @@
!issue18561.pdf
!highlights.pdf
!highlight.pdf
!bug1708040.pdf

BIN
test/pdfs/bug1708040.pdf Executable file

Binary file not shown.

View file

@ -3807,11 +3807,13 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`)
role: "Figure",
children: [{ type: "content", id: "p406R_mc11" }],
alt: "d h c s logo",
bbox: [57.75, 676, 133.35, 752],
},
{
role: "Figure",
children: [{ type: "content", id: "p406R_mc1" }],
alt: "Great Seal of the State of California",
bbox: [481.5, 678, 544.5, 741],
},
{
role: "P",

View file

@ -107,4 +107,48 @@ describe("struct tree", function () {
await loadingTask.destroy();
});
});
it("parses structure with a figure and its bounding box", async function () {
const filename = "bug1708040.pdf";
const params = buildGetDocumentParams(filename);
const loadingTask = getDocument(params);
const doc = await loadingTask.promise;
const page = await doc.getPage(1);
const struct = await page.getStructTree();
equalTrees(
{
children: [
{
role: "Document",
children: [
{
role: "Sect",
children: [
{
role: "P",
children: [{ type: "content", id: "p21R_mc0" }],
lang: "EN-US",
},
{
role: "P",
children: [{ type: "content", id: "p21R_mc1" }],
lang: "EN-US",
},
{
role: "Figure",
children: [{ type: "content", id: "p21R_mc2" }],
alt: "A logo of a fox and a globe\u0000",
bbox: [72, 287.782, 456, 695.032],
},
],
},
],
},
],
role: "Root",
},
struct
);
await loadingTask.destroy();
});
});