Skip to content

Commit

Permalink
Merge pull request #17719 from calixteman/bug1881692
Browse files Browse the repository at this point in the history
[Editor] In caret browsing mode, get the caret position in the text layer (bug 1881692)
  • Loading branch information
calixteman authored Feb 23, 2024
2 parents 101e8ef + bb19cf9 commit b8b8f1a
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 5 deletions.
63 changes: 63 additions & 0 deletions test/integration/highlight_editor_spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
})
);
});
});
});
6 changes: 6 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ const PDFViewerApplication = {
params.get("highlighteditorcolors")
);
}
if (params.has("supportscaretbrowsingmode")) {
AppOptions.set(
"supportsCaretBrowsingMode",
params.get("supportscaretbrowsingmode") === "true"
);
}
}
},

Expand Down
28 changes: 23 additions & 5 deletions web/caret_browsing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit b8b8f1a

Please sign in to comment.