tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 580540cbec4f4dc49864ea96d575f9c89092e4b1
parent ffc2589ee135246568c4fb813952977f50cad773
Author: Erik Nordin <enordin@mozilla.com>
Date:   Tue, 23 Dec 2025 16:05:28 +0000

Bug 1992232 - Part 5/6: Implement Copy Button Enabled States r=translations-reviewers,gregtatum

This commit introduces the logic for when the target-section copy button
should be enabled or disabled on the about:translations page.

At this point the button has no functionality when clicked.
This will be added in the next commit.

Differential Revision: https://phabricator.services.mozilla.com/D276137

Diffstat:
Mtoolkit/components/translations/content/about-translations.mjs | 25+++++++++++++++++++++++--
Mtoolkit/components/translations/tests/browser/browser.toml | 2++
Atoolkit/components/translations/tests/browser/browser_about_translations_copy_button_enabled_states.js | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/components/translations/tests/browser/shared-head.js | 14++++++++++++++
4 files changed, 226 insertions(+), 2 deletions(-)

diff --git a/toolkit/components/translations/content/about-translations.mjs b/toolkit/components/translations/content/about-translations.mjs @@ -739,6 +739,23 @@ class AboutTranslations { } /** + * Updates the enabled state of the copy button. + * + * @param {boolean} shouldEnable + */ + #setCopyButtonEnabled(shouldEnable) { + const { copyButton } = this.elements; + + copyButton.disabled = !shouldEnable; + + const eventName = shouldEnable + ? "AboutTranslationsTest:CopyButtonEnabled" + : "AboutTranslationsTest:CopyButtonDisabled"; + + document.dispatchEvent(new CustomEvent(eventName)); + } + + /** * If the currently selected language pair is determined to be swappable, * swaps the active source language with the active target language, * and moves the translated output to be the new source text. @@ -830,8 +847,11 @@ class AboutTranslations { * Sets the value of the target <textarea>. * * @param {string} value + * @param {object} [options] + * @param {boolean} [options.isTranslationResult=false] + * True if the value is the result of a translation request, otherwise false. */ - #setTargetText(value) { + #setTargetText(value, { isTranslationResult = false } = {}) { this.elements.targetSectionTextArea.value = value; if (!value) { @@ -842,6 +862,7 @@ class AboutTranslations { this.#updateTargetScriptDirection(); this.#ensureSectionHeightsMatch({ scheduleCallback: false }); + this.#setCopyButtonEnabled(Boolean(value) && isTranslationResult); } /** @@ -1151,7 +1172,7 @@ class AboutTranslations { } ); - this.#setTargetText(translatedText); + this.#setTargetText(translatedText, { isTranslationResult: true }); this.#updateSwapLanguagesButtonEnabledState(); document.dispatchEvent( new CustomEvent("AboutTranslationsTest:TranslationComplete", { diff --git a/toolkit/components/translations/tests/browser/browser.toml b/toolkit/components/translations/tests/browser/browser.toml @@ -24,6 +24,8 @@ support-files = [ "translations-text-cleaning.html", ] +["browser_about_translations_copy_button_enabled_states.js"] + ["browser_about_translations_debounce.js"] skip-if = [ "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'", # Bug 1821461 diff --git a/toolkit/components/translations/tests/browser/browser_about_translations_copy_button_enabled_states.js b/toolkit/components/translations/tests/browser/browser_about_translations_copy_button_enabled_states.js @@ -0,0 +1,187 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const languagePairs = [ + { fromLang: "en", toLang: "fr" }, + { fromLang: "fr", toLang: "en" }, + { fromLang: "en", toLang: "de" }, + { fromLang: "de", toLang: "en" }, +]; + +add_task( + async function test_copy_button_disabled_until_translation_completes() { + const { aboutTranslationsTestUtils, cleanup } = await openAboutTranslations( + { + languagePairs, + autoDownloadFromRemoteSettings: false, + } + ); + + await aboutTranslationsTestUtils.setSourceLanguageSelectorValue("en"); + await aboutTranslationsTestUtils.setTargetLanguageSelectorValue("fr"); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [ + AboutTranslationsTestUtils.Events.TranslationRequested, + { translationId: 1 }, + ], + [AboutTranslationsTestUtils.Events.ShowTranslatingPlaceholder], + ], + unexpected: [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + }, + async () => { + await aboutTranslationsTestUtils.setSourceTextAreaValue("Hello world"); + } + ); + + await aboutTranslationsTestUtils.assertTranslatingPlaceholder(); + await aboutTranslationsTestUtils.assertCopyButton({ enabled: false }); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [ + AboutTranslationsTestUtils.Events.TranslationComplete, + { translationId: 1 }, + ], + [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + ], + }, + async () => { + await aboutTranslationsTestUtils.resolveDownloads(1); + } + ); + + await aboutTranslationsTestUtils.assertCopyButton({ enabled: true }); + + await aboutTranslationsTestUtils.assertTranslatedText({ + sourceLanguage: "en", + targetLanguage: "fr", + sourceText: "Hello world", + }); + + await cleanup(); + } +); + +add_task(async function test_copy_button_disables_when_translation_cleared() { + const { aboutTranslationsTestUtils, cleanup } = await openAboutTranslations({ + languagePairs, + autoDownloadFromRemoteSettings: false, + }); + + await aboutTranslationsTestUtils.setSourceLanguageSelectorValue("en"); + await aboutTranslationsTestUtils.setTargetLanguageSelectorValue("fr"); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [ + AboutTranslationsTestUtils.Events.TranslationRequested, + { translationId: 1 }, + ], + [AboutTranslationsTestUtils.Events.ShowTranslatingPlaceholder], + ], + unexpected: [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + }, + async () => { + await aboutTranslationsTestUtils.setSourceTextAreaValue("Hello again"); + } + ); + + await aboutTranslationsTestUtils.assertTranslatingPlaceholder(); + await aboutTranslationsTestUtils.assertCopyButton({ enabled: false }); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [ + AboutTranslationsTestUtils.Events.TranslationComplete, + { translationId: 1 }, + ], + [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + ], + }, + async () => { + await aboutTranslationsTestUtils.resolveDownloads(1); + } + ); + + await aboutTranslationsTestUtils.assertCopyButton({ enabled: true }); + + await aboutTranslationsTestUtils.assertTranslatedText({ + sourceLanguage: "en", + targetLanguage: "fr", + sourceText: "Hello again", + }); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [AboutTranslationsTestUtils.Events.CopyButtonDisabled], + [ + AboutTranslationsTestUtils.Events.TranslationRequested, + { translationId: 2 }, + ], + [AboutTranslationsTestUtils.Events.ShowTranslatingPlaceholder], + ], + unexpected: [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + }, + async () => { + await aboutTranslationsTestUtils.setTargetLanguageSelectorValue("de"); + } + ); + + await aboutTranslationsTestUtils.assertTranslatingPlaceholder(); + await aboutTranslationsTestUtils.assertCopyButton({ enabled: false }); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [ + AboutTranslationsTestUtils.Events.TranslationComplete, + { translationId: 2 }, + ], + [AboutTranslationsTestUtils.Events.CopyButtonEnabled], + ], + }, + async () => { + await aboutTranslationsTestUtils.resolveDownloads(1); + } + ); + + await aboutTranslationsTestUtils.assertCopyButton({ enabled: true }); + + await aboutTranslationsTestUtils.assertTranslatedText({ + sourceLanguage: "en", + targetLanguage: "de", + sourceText: "Hello again", + }); + + await aboutTranslationsTestUtils.assertEvents( + { + expected: [ + [AboutTranslationsTestUtils.Events.CopyButtonDisabled], + [AboutTranslationsTestUtils.Events.ClearTargetText], + ], + unexpected: [ + AboutTranslationsTestUtils.Events.CopyButtonEnabled, + AboutTranslationsTestUtils.Events.TranslationRequested, + ], + }, + async () => { + await aboutTranslationsTestUtils.setTargetLanguageSelectorValue(""); + } + ); + + await aboutTranslationsTestUtils.assertTargetTextArea({ + showsPlaceholder: true, + }); + await aboutTranslationsTestUtils.assertCopyButton({ enabled: false }); + + await cleanup(); +}); diff --git a/toolkit/components/translations/tests/browser/shared-head.js b/toolkit/components/translations/tests/browser/shared-head.js @@ -4108,6 +4108,20 @@ class AboutTranslationsTestUtils { static TranslationComplete = "AboutTranslationsTest:TranslationComplete"; /** + * Event fired when the copy button becomes enabled. + * + * @type {string} + */ + static CopyButtonEnabled = "AboutTranslationsTest:CopyButtonEnabled"; + + /** + * Event fired when the copy button becomes disabled. + * + * @type {string} + */ + static CopyButtonDisabled = "AboutTranslationsTest:CopyButtonDisabled"; + + /** * Event fired when the page layout changes. * * @type {string}