Merge pull request #17719 from calixteman/bug1881692

[Editor] In caret browsing mode, get the caret position in the text layer (bug 1881692)
This commit is contained in:
calixteman 2024-02-23 17:11:51 +01:00 committed by GitHub
commit b8b8f1af66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 5 deletions

View File

@ -1030,4 +1030,67 @@ describe("Highlight Editor", () => {
);
});
});
describe("Highlight and caret browsing", () => {
let pages;
beforeAll(async () => {
pages = await loadAndWait(
"tracemonkey.pdf",
".annotationEditorLayer",
null,
null,
{
highlightEditorColors: "red=#AB0000",
supportsCaretBrowsingMode: true,
}
);
});
afterAll(async () => {
await closePages(pages);
});
it("must check that the caret can move a highlighted text", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await page.click("#editorHighlight");
await page.waitForSelector(".annotationEditorLayer.highlightEditing");
const rect = await getSpanRectFromText(page, 1, "Abstract");
const x = rect.x + rect.width / 2;
const y = rect.y + rect.height / 2;
await page.mouse.click(x, y, { count: 2 });
await page.waitForSelector(`${getEditorSelector(0)}`);
await page.keyboard.press("Escape");
await page.waitForSelector(
`${getEditorSelector(0)}:not(.selectedEditor)`
);
await page.evaluate(() => {
const text =
"Dynamic languages such as JavaScript are more difficult to com-";
for (const el of document.querySelectorAll(
`.page[data-page-number="${1}"] > .textLayer > span`
)) {
if (el.textContent === text) {
window.getSelection().setPosition(el.firstChild, 1);
break;
}
}
});
await page.keyboard.press("ArrowUp");
const [text, offset] = await page.evaluate(() => {
const selection = window.getSelection();
return [selection.anchorNode.textContent, selection.anchorOffset];
});
expect(text).withContext(`In ${browserName}`).toEqual("Abstract");
expect(offset).withContext(`In ${browserName}`).toEqual(1);
})
);
});
});
});

View File

@ -329,6 +329,12 @@ const PDFViewerApplication = {
params.get("highlighteditorcolors")
);
}
if (params.has("supportscaretbrowsingmode")) {
AppOptions.set(
"supportsCaretBrowsingMode",
params.get("supportscaretbrowsingmode") === "true"
);
}
}
},

View File

@ -130,11 +130,29 @@ class CaretBrowsingMode {
}
const midY = rect.y + rect.height / 2;
const caretPosition = CaretBrowsingMode.#caretPositionFromPoint(
caretX,
midY
);
if (caretPosition.offsetNode?.parentElement !== element) {
let caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY);
let parentElement = caretPosition.offsetNode?.parentElement;
if (parentElement && parentElement !== element) {
// There is an element on top of the one in the text layer, so we
// need to hide all the elements (except the one in the text layer)
// at this position in order to get the correct caret position.
const elementsAtPoint = document.elementsFromPoint(caretX, midY);
const savedVisibilities = [];
for (const el of elementsAtPoint) {
if (el === element) {
break;
}
const { style } = el;
savedVisibilities.push([el, style.visibility]);
style.visibility = "hidden";
}
caretPosition = CaretBrowsingMode.#caretPositionFromPoint(caretX, midY);
parentElement = caretPosition.offsetNode?.parentElement;
for (const [el, visibility] of savedVisibilities) {
el.style.visibility = visibility;
}
}
if (parentElement !== element) {
// The element targeted by caretPositionFromPoint isn't in the text
// layer.
if (select) {