diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index 1b180ac8f52160..8636fbbd52d792 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -906,13 +906,11 @@ class AnnotationEditorUIManager { #addKeyboardManager() { // The keyboard events are caught at the container level in order to be able // to execute some callbacks even if the current page doesn't have focus. - window.addEventListener("keydown", this.#boundKeydown, { capture: true }); + window.addEventListener("keydown", this.#boundKeydown); } #removeKeyboardManager() { - window.removeEventListener("keydown", this.#boundKeydown, { - capture: true, - }); + window.removeEventListener("keydown", this.#boundKeydown); } #addCopyPasteListeners() { diff --git a/test/integration/freetext_editor_spec.mjs b/test/integration/freetext_editor_spec.mjs index 412167f518a0b7..4a801f38a27b45 100644 --- a/test/integration/freetext_editor_spec.mjs +++ b/test/integration/freetext_editor_spec.mjs @@ -2981,4 +2981,66 @@ describe("FreeText Editor", () => { ); }); }); + + describe("Avoid to steal keyboard events", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("empty.pdf", ".annotationEditorLayer"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check the keyboard event is limited to the input", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + await switchToFreeText(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. + const { x, y } = el.getBoundingClientRect(); + return { x, y }; + }); + + const data = "Hello PDF.js World !!"; + await page.mouse.click(rect.x + 100, rect.y + 100); + await page.waitForSelector(getEditorSelector(0), { + visible: true, + }); + await page.type(`${getEditorSelector(0)} .internal`, data); + + // Commit. + await page.keyboard.press("Escape"); + await page.waitForSelector( + `${getEditorSelector(0)} .overlay.enabled` + ); + + await page.focus("#pageNumber"); + const promise = page.evaluate( + () => + new Promise(resolve => { + document + .getElementById("pageNumber") + .addEventListener("keyup", resolve, { once: true }); + }) + ); + await page.keyboard.press("Backspace"); + await promise; + + let content = await page.$eval("#pageNumber", el => + el.innerText.trimEnd() + ); + expect(content).withContext(`In ${browserName}`).toEqual(""); + + content = await page.$eval(getEditorSelector(0), el => + el.innerText.trimEnd() + ); + expect(content).withContext(`In ${browserName}`).toEqual(data); + }) + ); + }); + }); }); diff --git a/web/pdf_find_bar.js b/web/pdf_find_bar.js index ebdd817fb3ce4f..dc96e9dc05e0b5 100644 --- a/web/pdf_find_bar.js +++ b/web/pdf_find_bar.js @@ -51,16 +51,21 @@ class PDFFindBar { this.findField.addEventListener("input", () => { this.dispatchEvent(""); }); + this.findField.addEventListener("keydown", e => { + e.stopPropagation(); + }); this.bar.addEventListener("keydown", e => { switch (e.keyCode) { case 13: // Enter if (e.target === this.findField) { this.dispatchEvent("again", e.shiftKey); + e.stopPropagation(); } break; case 27: // Escape this.close(); + e.stopPropagation(); break; } }); diff --git a/web/toolbar.js b/web/toolbar.js index 516cc096bcb09f..35bf6b8dd4b26d 100644 --- a/web/toolbar.js +++ b/web/toolbar.js @@ -170,6 +170,9 @@ class Toolbar { pageNumber.addEventListener("click", function () { this.select(); }); + pageNumber.addEventListener("keydown", event => { + event.stopPropagation(); + }); pageNumber.addEventListener("change", function () { self.eventBus.dispatch("pagenumberchanged", { source: self,