tor-browser

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

commit 75259352201f05beaca3f1d8dc56c0b582d60a21
parent 57d3feae5d6f71d9b7aa0e05b9f2e516ce662d2c
Author: Erik Nordin <enordin@mozilla.com>
Date:   Tue, 23 Dec 2025 16:05:28 +0000

Bug 1992233 - Part 1/3: Add Source Section Clear Button r=translations-reviewers,fluent-reviewers,bolsson,gregtatum

This commit adds the actions column and clear button to the source section
of the about:translations page. This introduces the new UI element sonly,
ensuring that the pre-existing lofic is consistent, especially resizing.

At this point, the button is always shown and has no functionality.
Subsequent commits will add the show/hide/click logic as well as tests.

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

Diffstat:
Mtoolkit/components/translations/content/about-translations.css | 59++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mtoolkit/components/translations/content/about-translations.html | 8++++++++
Mtoolkit/components/translations/content/about-translations.mjs | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/locales/en-US/toolkit/about/aboutTranslations.ftl | 4++++
4 files changed, 112 insertions(+), 7 deletions(-)

diff --git a/toolkit/components/translations/content/about-translations.css b/toolkit/components/translations/content/about-translations.css @@ -27,6 +27,9 @@ --AT-content-width: calc(var(--AT-section-height) * 4.5); --AT-content-max: calc(100vw - var(--AT-viewport-padding) * 2); + + --AT-square-button-large: calc(var(--size-item-large) + var(--space-small)); + --AT-square-button-small: var(--size-item-large); } body { @@ -36,7 +39,7 @@ body { align-items: flex-start; visibility: hidden; margin: 0; - row-gap: var(--space-xlarge); + row-gap: var(--space-xxlarge); padding: var(--AT-page-padding-block-start) var(--AT-viewport-padding) var(--AT-page-padding-block-end); } @@ -84,12 +87,23 @@ body { margin: 0; } -#about-translations-swap-languages-button[type~="icon"]::part(button) { - width: var(--size-item-xlarge); - height: var(--size-item-xlarge); - transform: rotate(90deg) scaleX(-1); - background-image: url("chrome://global/skin/icons/arrows-updown.svg"); - background-size: var(--size-item-medium); +#about-translations-swap-languages-button { + align-self: center; + + &[type~="icon"]::part(button) { + width: var(--AT-square-button-large); + height: var(--AT-square-button-large); + transform: rotate(90deg) scaleX(-1); + background-image: url("chrome://global/skin/icons/arrows-updown.svg"); + background-size: var(--size-item-medium); + } +} + +#about-translations-clear-button[type~="icon"]::part(button) { + width: var(--AT-square-button-small); + height: var(--AT-square-button-small); + background-image: url("chrome://global/skin/icons/close.svg"); + background-size: var(--size-item-small); } #about-translations-source-section, @@ -98,6 +112,20 @@ body { min-height: var(--AT-section-height); } +#about-translations-source-section { + display: grid; + grid-template-columns: 1fr auto; + background-color: var(--background-color-box); + border: 1px solid var(--border-color); + border-radius: var(--border-radius-medium); + overflow: hidden; + + &.focus-section { + outline: var(--focus-outline); + outline-offset: -1px; + } +} + #about-translations-target-section { background-color: var(--background-color-box); border: 1px solid var(--border-color); @@ -118,6 +146,23 @@ body { resize: none; } +#about-translations-source-textarea { + border: none; + border-radius: 0; + background-color: transparent; + padding-inline-end: var(--space-xsmall); + + &:focus-visible { + outline: none; + } +} + +#about-translations-source-actions { + padding: var(--space-xsmall); + min-width: var(--AT-square-button-small); + background-color: transparent; +} + #about-translations-target-textarea { border: none; border-radius: 0; diff --git a/toolkit/components/translations/content/about-translations.html b/toolkit/components/translations/content/about-translations.html @@ -120,6 +120,14 @@ data-l10n-id="about-translations-input-placeholder" spellcheck="false" ></textarea> + <div id="about-translations-source-actions"> + <moz-button + id="about-translations-clear-button" + type="ghost icon" + data-l10n-id="about-translations-clear-button" + tabindex="-1" + ></moz-button> + </div> </div> <div id="about-translations-empty-section"></div> <div id="about-translations-target-section"> diff --git a/toolkit/components/translations/content/about-translations.mjs b/toolkit/components/translations/content/about-translations.mjs @@ -196,6 +196,8 @@ class AboutTranslations { * mainUserInterface: HTMLElement, * sourceLanguageSelector: HTMLSelectElement, * sourceSection: HTMLElement, + * sourceSectionActionsColumn: HTMLElement, + * sourceSectionClearButton: HTMLElement, * sourceSectionTextArea: HTMLTextAreaElement, * swapLanguagesButton: HTMLElement, * targetLanguageSelector: HTMLSelectElement, @@ -234,6 +236,12 @@ class AboutTranslations { sourceSection: /** @type {HTMLElement} */ ( document.getElementById("about-translations-source-section") ), + sourceSectionActionsColumn: /** @type {HTMLElement} */ ( + document.getElementById("about-translations-source-actions") + ), + sourceSectionClearButton: /** @type {HTMLElement} */ ( + document.getElementById("about-translations-clear-button") + ), sourceSectionTextArea: /** @type {HTMLTextAreaElement} */ ( document.getElementById("about-translations-source-textarea") ), @@ -362,6 +370,7 @@ class AboutTranslations { copyButton, learnMoreLink, sourceLanguageSelector, + sourceSectionActionsColumn, sourceSectionTextArea, swapLanguagesButton, targetLanguageSelector, @@ -375,7 +384,16 @@ class AboutTranslations { "input", this.#onSourceLanguageInput ); + sourceSectionActionsColumn.addEventListener( + "pointerdown", + this.#onSourceSectionActionsPointerDown + ); sourceSectionTextArea.addEventListener("input", this.#onSourceTextInput); + sourceSectionTextArea.addEventListener( + "focus", + this.#onSourceTextAreaFocus + ); + sourceSectionTextArea.addEventListener("blur", this.#onSourceTextAreaBlur); swapLanguagesButton.addEventListener("click", this.#onSwapLanguagesButton); targetLanguageSelector.addEventListener( "input", @@ -443,6 +461,36 @@ class AboutTranslations { }; /** + * Handles pointerdown events within the source section's actions column. + * + * Clicking empty space within the column should behave as though the + * textarea was clicked, but clicking the clear button should preserve + * the default behavior. + */ + #onSourceSectionActionsPointerDown = event => { + if (event.target?.closest?.("#about-translations-clear-button")) { + return; + } + + event.preventDefault(); + this.elements.sourceSectionTextArea.focus(); + }; + + /** + * Handles focusing the source section by outlining the entire section. + */ + #onSourceTextAreaFocus = () => { + this.elements.sourceSection.classList.add("focus-section"); + }; + + /** + * Handles blur events on the source section's text area. + */ + #onSourceTextAreaBlur = () => { + this.elements.sourceSection.classList.remove("focus-section"); + }; + + /** * Handles pointerdown events within the target section's actions row. * * Clicking empty space within the actions row should behave as though diff --git a/toolkit/locales/en-US/toolkit/about/aboutTranslations.ftl b/toolkit/locales/en-US/toolkit/about/aboutTranslations.ftl @@ -59,3 +59,7 @@ about-translations-translating-message = Translating… # source and target languages, reversing the direction of translation. about-translations-swap-languages = .title = Swap languages + +# The title attribute for the button that clears the source text area. +about-translations-clear-button = + .title = Clear source text