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

[Editor] Make the text layer focusable before the editors (bug 1881746)

Keep the different layers in a constant order to avoid the use of a z-index
and a tab-index.
This commit is contained in:
Calixte Denizet 2024-03-11 17:03:44 +01:00
parent 0022310b9c
commit 1b00511301
14 changed files with 187 additions and 36 deletions

View file

@ -18,6 +18,7 @@ import {
closePages,
createPromise,
dragAndDropAnnotation,
firstPageOnTop,
getEditors,
getEditorSelector,
getFirstSerialized,
@ -39,6 +40,7 @@ import {
kbUndo,
loadAndWait,
scrollIntoView,
waitForAnnotationEditorLayer,
waitForEvent,
waitForSelectedEditor,
waitForSerialized,
@ -923,6 +925,7 @@ describe("FreeText Editor", () => {
let currentId = 0;
for (let step = 0; step < 3; step++) {
await firstPageOnTop(page);
const rect = await page.$eval(".annotationEditorLayer", el => {
// With Chrome something is wrong when serializing a DomRect,
// hence we extract the values and just return them.
@ -931,8 +934,8 @@ describe("FreeText Editor", () => {
});
const data = `Hello ${step}`;
const x = rect.x + 0.1 * rect.width;
const y = rect.y + 0.1 * rect.height;
const x = Math.max(rect.x + 0.1 * rect.width, 10);
const y = Math.max(rect.y + 0.1 * rect.height, 10);
await page.mouse.click(x, y);
await page.waitForSelector(getEditorSelector(currentId), {
visible: true,
@ -945,9 +948,12 @@ describe("FreeText Editor", () => {
`${getEditorSelector(currentId)} .overlay.enabled`
);
const promise = await waitForAnnotationEditorLayer(page);
await page.evaluate(() => {
document.getElementById("pageRotateCw").click();
});
await awaitPromise(promise);
currentId += 1;
await page.waitForSelector(
".page[data-page-number='1'] .canvasWrapper",

View file

@ -22,6 +22,8 @@ import {
getSerialized,
kbBigMoveLeft,
kbBigMoveUp,
kbFocusNext,
kbFocusPrevious,
kbSelectAll,
loadAndWait,
scrollIntoView,
@ -1556,4 +1558,52 @@ describe("Highlight Editor", () => {
);
});
});
describe("Text layer must have the focus before highlights", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
});
afterAll(async () => {
await closePages(pages);
});
it("must check the focus order", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.click("#editorHighlight");
await page.waitForSelector(".annotationEditorLayer.highlightEditing");
let rect = await getSpanRectFromText(page, 1, "Abstract");
let x = rect.x + rect.width / 2;
let y = rect.y + rect.height / 2;
await page.mouse.click(x, y, { count: 2, delay: 100 });
await page.waitForSelector(getEditorSelector(0));
rect = await getSpanRectFromText(page, 1, "Languages");
x = rect.x + rect.width / 2;
y = rect.y + rect.height / 2;
await page.mouse.click(x, y, { count: 2, delay: 100 });
await page.waitForSelector(getEditorSelector(1));
await page.focus(getEditorSelector(1));
await kbFocusPrevious(page);
await page.waitForFunction(
sel => document.querySelector(sel) === document.activeElement,
{},
`.page[data-page-number="1"] > .textLayer`
);
await kbFocusNext(page);
await page.waitForFunction(
sel => document.querySelector(sel) === document.activeElement,
{},
getEditorSelector(1)
);
})
);
});
});
});

View file

@ -318,9 +318,12 @@ async function scrollIntoView(page, selector) {
const handle = await page.evaluateHandle(
sel => [
new Promise(resolve => {
document
.getElementById("viewerContainer")
.addEventListener("scrollend", resolve, { once: true });
const container = document.getElementById("viewerContainer");
if (container.scrollHeight <= container.clientHeight) {
resolve();
return;
}
container.addEventListener("scrollend", resolve, { once: true });
const element = document.querySelector(sel);
element.scrollIntoView({ behavior: "instant", block: "start" });
}),
@ -330,6 +333,21 @@ async function scrollIntoView(page, selector) {
return awaitPromise(handle);
}
async function firstPageOnTop(page) {
const handle = await page.evaluateHandle(() => [
new Promise(resolve => {
const container = document.getElementById("viewerContainer");
if (container.scrollTop === 0 && container.scrollLeft === 0) {
resolve();
return;
}
container.addEventListener("scrollend", resolve, { once: true });
container.scrollTo(0, 0);
}),
]);
return awaitPromise(handle);
}
async function hover(page, selector) {
const rect = await page.$eval(selector, el => {
const { x, y, width, height } = el.getBoundingClientRect();
@ -461,12 +479,31 @@ async function kbDeleteLastWord(page) {
}
}
async function kbFocusNext(page) {
const handle = await createPromise(page, resolve => {
window.addEventListener("focusin", resolve, { once: true });
});
await page.keyboard.press("Tab");
await awaitPromise(handle);
}
async function kbFocusPrevious(page) {
const handle = await createPromise(page, resolve => {
window.addEventListener("focusin", resolve, { once: true });
});
await page.keyboard.down("Shift");
await page.keyboard.press("Tab");
await page.keyboard.up("Shift");
await awaitPromise(handle);
}
export {
awaitPromise,
clearInput,
closePages,
createPromise,
dragAndDropAnnotation,
firstPageOnTop,
getAnnotationStorage,
getComputedStyleSelector,
getEditorDimensions,
@ -484,6 +521,8 @@ export {
kbBigMoveUp,
kbCopy,
kbDeleteLastWord,
kbFocusNext,
kbFocusPrevious,
kbGoToBegin,
kbGoToEnd,
kbModifierDown,