From b6fcb523c5040334c8395f94ddb17df57d5f4dfb Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Fri, 21 Nov 2025 14:52:04 +0100 Subject: [PATCH] [Editor] Allow to save an edited comment in using CTRL+Enter shortcut. --- test/integration/comment_spec.mjs | 59 +++++++++++++++++++++++++++++++ web/alt_text_manager.js | 9 +++++ web/comment_manager.js | 9 +++++ web/new_alt_text_manager.js | 9 +++++ 4 files changed, 86 insertions(+) diff --git a/test/integration/comment_spec.mjs b/test/integration/comment_spec.mjs index ed67f006ae785..9770724cc7324 100644 --- a/test/integration/comment_spec.mjs +++ b/test/integration/comment_spec.mjs @@ -15,6 +15,7 @@ import { awaitPromise, + clearInput, closePages, createPromise, dragAndDrop, @@ -851,4 +852,62 @@ describe("Comment", () => { ); }); }); + + describe("Save a comment in using CTRL+Enter", () => { + let pages; + + beforeEach(async () => { + pages = await loadAndWait( + "comments.pdf", + ".annotationEditorLayer", + "page-fit", + null, + { enableComment: true } + ); + }); + + afterEach(async () => { + await closePages(pages); + }); + + it("must check that the comment is saved", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + const commentButtonSelector = `[data-annotation-id="612R"] + button.annotationCommentButton`; + await waitAndClick(page, commentButtonSelector); + const commentPopupSelector = "#commentPopup"; + const editButtonSelector = `${commentPopupSelector} button.commentPopupEdit`; + await waitAndClick(page, editButtonSelector); + + const textInputSelector = "#commentManagerTextInput"; + await page.waitForSelector(textInputSelector, { + visible: true, + }); + await clearInput(page, textInputSelector, true); + const comment = "Comment saved using CTRL+Enter"; + await page.type(textInputSelector, comment); + await page.focus(textInputSelector); + + await page.keyboard.down("Control"); + await page.keyboard.press("Enter"); + await page.keyboard.up("Control"); + + await page.waitForSelector("#commentManagerDialog", { + visible: false, + }); + + await page.hover(commentButtonSelector); + await page.waitForSelector(commentPopupSelector, { + visible: true, + }); + const popupTextSelector = `${commentPopupSelector} .commentPopupText`; + const popupText = await page.evaluate( + selector => document.querySelector(selector).textContent, + popupTextSelector + ); + expect(popupText).withContext(`In ${browserName}`).toEqual(comment); + }) + ); + }); + }); }); diff --git a/web/alt_text_manager.js b/web/alt_text_manager.js index 9245d42d6c23f..d3ddac8e7ee2a 100644 --- a/web/alt_text_manager.js +++ b/web/alt_text_manager.js @@ -87,6 +87,15 @@ class AltTextManager { saveButton.addEventListener("click", this.#save.bind(this)); optionDescription.addEventListener("change", onUpdateUIState); optionDecorative.addEventListener("change", onUpdateUIState); + textarea.addEventListener("keydown", e => { + if ( + (e.ctrlKey || e.metaKey) && + e.key === "Enter" && + !saveButton.disabled + ) { + this.#save(); + } + }); this.#overlayManager.register(dialog); } diff --git a/web/comment_manager.js b/web/comment_manager.js index eaff727bdb22c..d01f06611da4c 100644 --- a/web/comment_manager.js +++ b/web/comment_manager.js @@ -723,6 +723,15 @@ class CommentDialog { textInput.addEventListener("input", () => { saveButton.disabled = textInput.value === this.#previousText; }); + textInput.addEventListener("keydown", e => { + if ( + (e.ctrlKey || e.metaKey) && + e.key === "Enter" && + !saveButton.disabled + ) { + this.#save(); + } + }); // Make the dialog draggable. let pointerMoveAC; diff --git a/web/new_alt_text_manager.js b/web/new_alt_text_manager.js index d9554b7798aa9..5d461bb25dcb1 100644 --- a/web/new_alt_text_manager.js +++ b/web/new_alt_text_manager.js @@ -141,6 +141,15 @@ class NewAltTextManager { textarea.addEventListener("input", () => { this.#toggleTitleAndDisclaimer(); }); + textarea.addEventListener("keydown", e => { + if ( + (e.ctrlKey || e.metaKey) && + e.key === "Enter" && + !saveButton.disabled + ) { + this.#save(); + } + }); eventBus._on("enableguessalttext", ({ value }) => { this.#toggleGuessAltText(value, /* isInitial = */ false);