mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
Merge pull request #15237 from calixteman/annotation_a11y
[Annotations] Add some aria-owns in the text layer to link to annotations (bug 1780375)
This commit is contained in:
commit
6b4c2464ad
23 changed files with 436 additions and 246 deletions
|
@ -32,6 +32,7 @@ async function runTests(results) {
|
|||
"find_spec.js",
|
||||
"freetext_editor_spec.js",
|
||||
"ink_editor_spec.js",
|
||||
"a11y_spec.js",
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -66,4 +66,44 @@ describe("accessibility", () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Annotation", () => {
|
||||
let pages;
|
||||
|
||||
beforeAll(async () => {
|
||||
pages = await loadAndWait(
|
||||
"tracemonkey_a11y.pdf",
|
||||
".textLayer .endOfContent"
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
function getSpans(page) {
|
||||
return page.evaluate(() => {
|
||||
const elements = document.querySelectorAll(
|
||||
`.textLayer span[aria-owns]:not([role="presentation"])`
|
||||
);
|
||||
const results = [];
|
||||
for (const element of elements) {
|
||||
results.push(element.innerText);
|
||||
}
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
it("must check that some spans are linked to some annotations thanks to aria-owns", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
const spanContents = await getSpans(page);
|
||||
|
||||
expect(spanContents)
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual(["Languages", "@intel.com", "Abstract", "Introduction"]);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
const {
|
||||
closePages,
|
||||
editorPrefix,
|
||||
getEditorSelector,
|
||||
getSelectedEditors,
|
||||
loadAndWait,
|
||||
} = require("./test_utils.js");
|
||||
|
@ -51,9 +51,9 @@ describe("Editor", () => {
|
|||
|
||||
const data = "Hello PDF.js World !!";
|
||||
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||
await page.type(`${editorPrefix}0 .internal`, data);
|
||||
await page.type(`${getEditorSelector(0)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(`${editorPrefix}0`, el => {
|
||||
const editorRect = await page.$eval(getEditorSelector(0), el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return {
|
||||
x,
|
||||
|
@ -73,7 +73,7 @@ describe("Editor", () => {
|
|||
.withContext(`In ${browserName}`)
|
||||
.toEqual(1);
|
||||
|
||||
const content = await page.$eval(`${editorPrefix}0`, el =>
|
||||
const content = await page.$eval(getEditorSelector(0), el =>
|
||||
el.innerText.trimEnd()
|
||||
);
|
||||
expect(content).withContext(`In ${browserName}`).toEqual(data);
|
||||
|
@ -84,7 +84,7 @@ describe("Editor", () => {
|
|||
it("must copy/paste", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
const editorRect = await page.$eval(`${editorPrefix}0`, el => {
|
||||
const editorRect = await page.$eval(getEditorSelector(0), el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
});
|
||||
|
@ -107,11 +107,11 @@ describe("Editor", () => {
|
|||
.withContext(`In ${browserName}`)
|
||||
.toEqual(2);
|
||||
|
||||
const content = await page.$eval(`${editorPrefix}0`, el =>
|
||||
const content = await page.$eval(getEditorSelector(0), el =>
|
||||
el.innerText.trimEnd()
|
||||
);
|
||||
|
||||
let pastedContent = await page.$eval(`${editorPrefix}1`, el =>
|
||||
let pastedContent = await page.$eval(getEditorSelector(1), el =>
|
||||
el.innerText.trimEnd()
|
||||
);
|
||||
|
||||
|
@ -131,7 +131,7 @@ describe("Editor", () => {
|
|||
.withContext(`In ${browserName}`)
|
||||
.toEqual(3);
|
||||
|
||||
pastedContent = await page.$eval(`${editorPrefix}2`, el =>
|
||||
pastedContent = await page.$eval(getEditorSelector(2), el =>
|
||||
el.innerText.trimEnd()
|
||||
);
|
||||
expect(pastedContent)
|
||||
|
@ -155,7 +155,7 @@ describe("Editor", () => {
|
|||
for (const n of [0, 1, 2]) {
|
||||
const hasEditor = await page.evaluate(sel => {
|
||||
return !!document.querySelector(sel);
|
||||
}, `${editorPrefix}${n}`);
|
||||
}, getEditorSelector(n));
|
||||
|
||||
expect(hasEditor).withContext(`In ${browserName}`).toEqual(false);
|
||||
}
|
||||
|
@ -177,9 +177,9 @@ describe("Editor", () => {
|
|||
|
||||
const data = "Hello PDF.js World !!";
|
||||
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||
await page.type(`${editorPrefix}3 .internal`, data);
|
||||
await page.type(`${getEditorSelector(3)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(`${editorPrefix}3`, el => {
|
||||
const editorRect = await page.$eval(getEditorSelector(3), el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
});
|
||||
|
@ -205,7 +205,7 @@ describe("Editor", () => {
|
|||
|
||||
let hasEditor = await page.evaluate(sel => {
|
||||
return !!document.querySelector(sel);
|
||||
}, `${editorPrefix}4`);
|
||||
}, getEditorSelector(4));
|
||||
|
||||
expect(hasEditor).withContext(`In ${browserName}`).toEqual(true);
|
||||
|
||||
|
@ -215,7 +215,7 @@ describe("Editor", () => {
|
|||
|
||||
hasEditor = await page.evaluate(sel => {
|
||||
return !!document.querySelector(sel);
|
||||
}, `${editorPrefix}4`);
|
||||
}, getEditorSelector(4));
|
||||
|
||||
expect(hasEditor).withContext(`In ${browserName}`).toEqual(false);
|
||||
|
||||
|
@ -227,7 +227,7 @@ describe("Editor", () => {
|
|||
|
||||
let length = await page.evaluate(sel => {
|
||||
return document.querySelectorAll(sel).length;
|
||||
}, `${editorPrefix}5, ${editorPrefix}6`);
|
||||
}, `${getEditorSelector(5)}, ${getEditorSelector(6)}`);
|
||||
expect(length).withContext(`In ${browserName}`).toEqual(2);
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
|
@ -238,7 +238,7 @@ describe("Editor", () => {
|
|||
|
||||
length = await page.evaluate(sel => {
|
||||
return document.querySelectorAll(sel).length;
|
||||
}, `${editorPrefix}5, ${editorPrefix}6`);
|
||||
}, `${getEditorSelector(5)}, ${getEditorSelector(6)}`);
|
||||
expect(length).withContext(`In ${browserName}`).toEqual(0);
|
||||
})
|
||||
);
|
||||
|
@ -273,7 +273,7 @@ describe("Editor", () => {
|
|||
stacksRect.x + stacksRect.width + 1,
|
||||
stacksRect.y + stacksRect.height / 2
|
||||
);
|
||||
await page.type(`${editorPrefix}7 .internal`, data);
|
||||
await page.type(`${getEditorSelector(7)} .internal`, data);
|
||||
|
||||
// Commit.
|
||||
await page.keyboard.press("Escape");
|
||||
|
@ -283,9 +283,9 @@ describe("Editor", () => {
|
|||
return span?.getAttribute("aria-owns") || null;
|
||||
});
|
||||
|
||||
expect(ariaOwns)
|
||||
expect(ariaOwns.endsWith("_7-editor"))
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual(`${editorPrefix}7-editor`.slice(1));
|
||||
.toEqual(true);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -308,9 +308,9 @@ describe("Editor", () => {
|
|||
|
||||
const data = "Hello PDF.js World !!";
|
||||
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||
await page.type(`${editorPrefix}8 .internal`, data);
|
||||
await page.type(`${getEditorSelector(8)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(`${editorPrefix}8`, el => {
|
||||
const editorRect = await page.$eval(getEditorSelector(8), el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
});
|
||||
|
@ -385,9 +385,9 @@ describe("Editor", () => {
|
|||
rect.x + (i + 1) * 100,
|
||||
rect.y + (i + 1) * 100
|
||||
);
|
||||
await page.type(`${editorPrefix}${i} .internal`, data);
|
||||
await page.type(`${getEditorSelector(i)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(`${editorPrefix}${i}`, el => {
|
||||
const editorRect = await page.$eval(getEditorSelector(i), el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return {
|
||||
x,
|
||||
|
|
|
@ -73,19 +73,17 @@ function getComputedStyleSelector(id) {
|
|||
return `getComputedStyle(${getQuerySelector(id)})`;
|
||||
}
|
||||
exports.getComputedStyleSelector = getComputedStyleSelector;
|
||||
|
||||
const editorPrefix = "#pdfjs_internal_editor_";
|
||||
exports.editorPrefix = editorPrefix;
|
||||
exports.getEditorSelector = n => `#pdfjs_internal_editor_${n}`;
|
||||
|
||||
function getSelectedEditors(page) {
|
||||
return page.evaluate(prefix => {
|
||||
return page.evaluate(() => {
|
||||
const elements = document.querySelectorAll(".selectedEditor");
|
||||
const results = [];
|
||||
for (const { id } of elements) {
|
||||
results.push(parseInt(id.slice(prefix.length)));
|
||||
results.push(parseInt(id.split("_").at(-1)));
|
||||
}
|
||||
results.sort();
|
||||
return results;
|
||||
}, editorPrefix.slice(1));
|
||||
});
|
||||
}
|
||||
exports.getSelectedEditors = getSelectedEditors;
|
||||
|
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
|
@ -534,3 +534,4 @@
|
|||
!bug1675139.pdf
|
||||
!issue15092.pdf
|
||||
!bug1782186.pdf
|
||||
!tracemonkey_a11y.pdf
|
||||
|
|
BIN
test/pdfs/tracemonkey_a11y.pdf
Normal file
BIN
test/pdfs/tracemonkey_a11y.pdf
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue