diff --git a/src/display/editor/stamp.js b/src/display/editor/stamp.js index fc4f6e41c68bb..0381f475651ed 100644 --- a/src/display/editor/stamp.js +++ b/src/display/editor/stamp.js @@ -133,9 +133,52 @@ class StampEditor extends AnnotationEditor { ) { this._editToolbar.hide(); this._uiManager.editAltText(this, /* firstTime = */ true); - } else { - this.div.focus(); + return; } + + if ( + !this._uiManager.useNewAltTextWhenAddingImage && + this._uiManager.useNewAltTextFlow && + this.#bitmap + ) { + // The alt-text dialog isn't opened but we still want to guess the alt + // text. + this.mlGuessAltText(); + } + + this.div.focus(); + } + + async mlGuessAltText(imageData = null, updateAltTextData = true) { + if (this.hasAltTextData()) { + return null; + } + + const { mlManager } = this._uiManager; + if (!mlManager || !(await mlManager.isEnabledFor("altText"))) { + return null; + } + const { data, width, height } = + imageData || + this.copyCanvas(null, /* createImageData = */ true).imageData; + const response = await mlManager.guess({ + name: "altText", + request: { + data, + width, + height, + channels: data.length / (width * height), + }, + }); + if (!response || response.error || !response.output) { + return null; + } + const altText = response.output; + await this.setGuessedAltText(altText); + if (updateAltTextData && !this.hasAltTextData()) { + this.altTextData = { alt: altText, decorative: false }; + } + return altText; } #getBitmap() { @@ -370,6 +413,13 @@ class StampEditor extends AnnotationEditor { } copyCanvas(maxDimension, createImageData = false) { + if (!maxDimension) { + // TODO: get this value from Firefox + // (https://bugzilla.mozilla.org/show_bug.cgi?id=1908184) + // It's the maximum dimension that the AI can handle. + maxDimension = 224; + } + const { width: bitmapWidth, height: bitmapHeight } = this.#bitmap; const canvas = document.createElement("canvas"); diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index a45f3647144f0..436dc0c4d6f41 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -856,18 +856,6 @@ class AnnotationEditorUIManager { } } - hasMLManager() { - return !!this.#mlManager; - } - - async mlGuess(data) { - return this.#mlManager?.guess(data) || null; - } - - async isMLEnabledFor(name) { - return !!(await this.#mlManager?.isEnabledFor(name)); - } - get mlManager() { return this.#mlManager; } diff --git a/web/new_alt_text_manager.js b/web/new_alt_text_manager.js index 9f372bda59359..a89ac4575b054 100644 --- a/web/new_alt_text_manager.js +++ b/web/new_alt_text_manager.js @@ -240,29 +240,17 @@ class NewAltTextManager { let hasError = false; try { - const { width, height, data } = this.#imageData; - - // Take a reference on the current editor, as it can be set to null (if - // the dialog is closed before the end of the guess). - // But in case we've an alt-text, we want to set it on the editor. - const editor = this.#currentEditor; - // When calling #mlGuessAltText we don't wait for it, so we must take care // that the alt text dialog can have been closed before the response is. - const response = await this.#uiManager.mlGuess({ - name: "altText", - request: { - data, - width, - height, - channels: data.length / (width * height), - }, - }); - if (!response || response.error || !response.output) { + + const altText = await this.#currentEditor.mlGuessAltText( + this.#imageData, + /* updateAltTextData = */ false + ); + if (altText === null) { throw new Error("No valid response from the AI service."); } - const altText = (this.#guessedAltText = response.output); - await editor.setGuessedAltText(altText); + this.#guessedAltText = altText; this.#wasAILoading = this.#isAILoading; if (this.#isAILoading) { this.#addAltText(altText);