diff --git a/test/integration/stamp_editor_spec.mjs b/test/integration/stamp_editor_spec.mjs index c947d934003ad0..c1b90b4dc08e81 100644 --- a/test/integration/stamp_editor_spec.mjs +++ b/test/integration/stamp_editor_spec.mjs @@ -1050,6 +1050,50 @@ describe("Stamp Editor", () => { tooltipSelector ); expect(tooltipText).toEqual("Hello World"); + + // Click on the Review button. + await page.click(buttonSelector); + await page.waitForSelector("#newAltTextDialog", { visible: true }); + await page.click("#newAltTextCreateAutomaticallyButton"); + await page.click("#newAltTextCancel"); + await page.waitForSelector("#newAltTextDialog", { visible: false }); + } + }); + + it("must check the new alt text flow (part 2)", async () => { + // Run sequentially to avoid clipboard issues. + for (const [, page] of pages) { + await switchToStamp(page); + + // Add an image. + await copyImage(page, "../images/firefox_logo.png", 0); + const editorSelector = getEditorSelector(0); + await page.waitForSelector(editorSelector); + await waitForSerialized(page, 1); + + // Wait for the dialog to be visible. + await page.waitForSelector("#newAltTextDialog", { visible: true }); + + // Wait for the spinner to be visible. + await page.waitForSelector("#newAltTextDescriptionContainer.loading"); + + // Check we've the disclaimer. + await page.waitForSelector("#newAltTextDisclaimer", { visible: true }); + + // Click in the textarea in order to stop the guessing. + await page.click("#newAltTextDescriptionTextarea"); + await page.waitForFunction(() => + document + .getElementById("newAltTextTitle") + .textContent.startsWith("Add ") + ); + + // Check we haven't the disclaimer. + await page.waitForSelector("#newAltTextDisclaimer", { visible: false }); + + // Click on the Not Now button. + await page.click("#newAltTextNotNow"); + await page.waitForSelector("#newAltTextDialog", { visible: false }); } }); }); diff --git a/web/annotation_editor_layer_builder.css b/web/annotation_editor_layer_builder.css index aea5879b895277..1c55dfd88a986f 100644 --- a/web/annotation_editor_layer_builder.css +++ b/web/annotation_editor_layer_builder.css @@ -990,6 +990,10 @@ gap: 4px; font-size: 11px; + &.noDisclaimer { + visibility: hidden; + } + &::before { content: ""; display: inline-block; diff --git a/web/new_alt_text_manager.js b/web/new_alt_text_manager.js index 42567161cb191e..611b41e5f27951 100644 --- a/web/new_alt_text_manager.js +++ b/web/new_alt_text_manager.js @@ -40,6 +40,8 @@ class NewAltTextManager { #guessedAltText; + #hasAI = false; + #isEditing = null; #imagePreview; @@ -128,16 +130,16 @@ class NewAltTextManager { textarea.addEventListener("focus", () => { this.#wasAILoading = this.#isAILoading; this.#toggleLoading(false); + this.#toggleTitleAndDisclaimer(); }); textarea.addEventListener("blur", () => { - if (textarea.value) { - return; + this.#toggleTitleAndDisclaimer(); + if (!textarea.value) { + this.#toggleLoading(this.#wasAILoading); } - this.#toggleLoading(this.#wasAILoading); }); textarea.addEventListener("input", () => { - this.#toggleTitle(); - this.#toggleDisclaimer(); + this.#toggleTitleAndDisclaimer(); }); eventBus._on("enableguessalttext", ({ value }) => { @@ -169,18 +171,6 @@ class NewAltTextManager { this.#dialog.classList.toggle("error", value); } - #toggleTitle() { - const isEditing = this.#isAILoading || !!this.#textarea.value; - if (this.#isEditing === isEditing) { - return; - } - this.#isEditing = isEditing; - this.#title.setAttribute( - "data-l10n-id", - `pdfjs-editor-new-alt-text-dialog-${isEditing ? "edit" : "add"}-label` - ); - } - async #toggleGuessAltText(value, isInitial = false) { if (!this.#uiManager) { return; @@ -197,8 +187,7 @@ class NewAltTextManager { } else { this.#toggleLoading(false); this.#isAILoading = false; - this.#toggleTitle(); - this.#toggleDisclaimer(); + this.#toggleTitleAndDisclaimer(); } } @@ -208,19 +197,34 @@ class NewAltTextManager { } #toggleAI(value) { + if (!this.#uiManager || this.#hasAI === value) { + return; + } + this.#hasAI = value; this.#dialog.classList.toggle("noAi", !value); - this.#toggleTitle(); + this.#toggleTitleAndDisclaimer(); } - #toggleDisclaimer(value = null) { - if (!this.#uiManager) { + #toggleTitleAndDisclaimer() { + // Disclaimer is visible when the AI is loading or the user didn't change + // the guessed alt text. + const visible = + this.#isAILoading || + (this.#guessedAltText && this.#guessedAltText === this.#textarea.value); + this.#disclaimer.classList.toggle("noDisclaimer", !visible); + + // The title changes depending if the text area is empty or not. + const isEditing = this.#isAILoading || !!this.#textarea.value; + if (this.#isEditing === isEditing) { return; } - const hidden = - value === null - ? !this.#guessedAltText || this.#guessedAltText !== this.#textarea.value - : !value; - this.#disclaimer.classList.toggle("hidden", hidden); + this.#isEditing = isEditing; + this.#title.setAttribute( + "data-l10n-id", + isEditing + ? "pdfjs-editor-new-alt-text-dialog-edit-label" + : "pdfjs-editor-new-alt-text-dialog-add-label" + ); } async #mlGuessAltText(isInitial) { @@ -243,14 +247,11 @@ class NewAltTextManager { if (this.#previousAltText === null && this.#guessedAltText) { // We have a guessed alt text and the user didn't change it. this.#addAltText(this.#guessedAltText); - this.#toggleDisclaimer(); - this.#toggleTitle(); return; } this.#toggleLoading(true); - this.#toggleTitle(); - this.#toggleDisclaimer(true); + this.#toggleTitleAndDisclaimer(); let hasError = false; try { @@ -277,8 +278,7 @@ class NewAltTextManager { if (hasError && this.#uiManager) { this.#toggleError(true); - this.#toggleTitle(); - this.#toggleDisclaimer(); + this.#toggleTitleAndDisclaimer(); } } @@ -287,6 +287,7 @@ class NewAltTextManager { return; } this.#textarea.value = altText; + this.#toggleTitleAndDisclaimer(); } #setProgress() {