Bug 1870300 - Add SelectTranslationsPanel class r=translations-reviewers,fluent-reviewers,desktop-theme-reviewers,bolsson,gregtatum,emilio

Adds a new class for SelectTranslationsPanel.

Differential Revision: https://phabricator.services.mozilla.com/D200502
This commit is contained in:
Erik Nordin 2024-02-23 21:30:34 +00:00
parent d80cf90364
commit 9957890189
9 changed files with 330 additions and 4 deletions

View File

@ -358,7 +358,8 @@
<menuitem id="context-searchselect-private"
oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms, true, this.principal, this.csp, event);"/>
<menuitem id="context-translate-selection"
data-l10n-id="main-context-menu-translate-selection"/>
data-l10n-id="main-context-menu-translate-selection"
oncommand="SelectTranslationsPanel.open(event);"/>
<menuseparator id="frame-sep"/>
<menu id="frame" data-l10n-id="main-context-menu-frame">

View File

@ -182,6 +182,11 @@ XPCOMUtils.defineLazyScriptGetter(
"gPermissionPanel",
"chrome://browser/content/browser-sitePermissionPanel.js"
);
XPCOMUtils.defineLazyScriptGetter(
this,
"SelectTranslationsPanel",
"chrome://browser/content/translations/selectTranslationsPanel.js"
);
XPCOMUtils.defineLazyScriptGetter(
this,
"TranslationsPanel",

View File

@ -496,6 +496,7 @@
#include ../../components/controlcenter/content/permissionPanel.inc.xhtml
#include ../../components/controlcenter/content/protectionsPanel.inc.xhtml
#include ../../components/downloads/content/downloadsPanel.inc.xhtml
#include ../../components/translations/content/selectTranslationsPanel.inc.xhtml
#include ../../components/translations/content/translationsPanel.inc.xhtml
#include browser-allTabsMenu.inc.xhtml

View File

@ -0,0 +1,102 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html:template id="template-select-translations-panel">
<panel id="select-translations-panel"
class="panel-no-padding translations-panel"
type="arrow"
role="alertdialog"
noautofocus="true"
aria-labelledby="translations-panel-header"
orient="vertical">
<panelmultiview id="select-translations-panel-multiview" mainViewId="select-translations-panel-view-default">
<panelview id="select-translations-panel-view-default"
class="PanelUI-subView translations-panel-view"
role="document"
mainview-with-header="true"
has-custom-header="true">
<hbox class="panel-header select-translations-panel-header">
<html:h1 class="translations-panel-header-wrapper">
<html:span id="select-translations-panel-header" data-l10n-id="select-translations-panel-header">
</html:span>
</html:h1>
<hbox class="translations-panel-beta">
<image id="select-translations-panel-beta-icon"
class="translations-panel-beta-icon">
</image>
</hbox>
<toolbarbutton id="select-translations-panel-settings"
class="panel-info-button translations-panel-settings-gear-icon"
data-l10n-id="translations-panel-settings-button"
closemenu="none" />
</hbox>
<vbox class="select-translations-panel-content">
<hbox id="select-translations-panel-lang-selection">
<vbox flex="1">
<label id="select-translations-panel-from-label"
class="select-translations-panel-label"
data-l10n-id="select-translations-panel-from-label">
</label>
<menulist id="select-translations-panel-from"
flex="1"
value="detect"
size="large"
data-l10n-id="translations-panel-choose-language"
aria-labelledby="translations-panel-from-label">
<menupopup id="select-translations-panel-from-menupopup"
class="translations-panel-language-menupopup-from">
<!-- The list of <menuitem> will be dynamically inserted. -->
</menupopup>
</menulist>
</vbox>
<vbox flex="1">
<label id="select-translations-panel-to-label"
class="select-translations-panel-label"
data-l10n-id="select-translations-panel-to-label">
</label>
<menulist id="select-translations-panel-to"
flex="1"
value="detect"
size="large"
data-l10n-id="translations-panel-choose-language"
aria-labelledby="translations-panel-to-label">
<menupopup id="select-translations-panel-to-menupopup"
class="translations-panel-language-menupopup-to">
<!-- The list of <menuitem> will be dynamically inserted. -->
</menupopup>
</menulist>
</vbox>
</hbox>
</vbox>
<vbox class="select-translations-panel-content">
<html:textarea id="select-translations-panel-translation-area"
data-l10n-id="select-translations-panel-placeholder-text"
readonly="true"
tabindex="0">
</html:textarea>
</vbox>
<hbox class="select-translations-panel-content">
<button id="select-translations-panel-copy-button"
class="footer-button select-translations-panel-button select-translations-panel-copy-button"
data-l10n-id="select-translations-panel-copy-button">
</button>
</hbox>
<html:moz-button-group class="panel-footer translations-panel-footer">
<button id="select-translations-panel-translate-full-page-button"
class="footer-button select-translations-panel-button"
data-l10n-id="select-translations-panel-translate-full-page-button">
</button>
<button id="select-translations-panel-done-button"
class="footer-button select-translations-panel-button"
data-l10n-id="select-translations-panel-done-button"
default="true"
oncommand = "SelectTranslationsPanel.close()">
</button>
</html:moz-button-group>
</panelview>
</panelmultiview>
</panel>
</html:template>

View File

@ -0,0 +1,141 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env mozilla/browser-window */
/**
* This singleton class controls the Translations popup panel.
*/
var SelectTranslationsPanel = new (class {
/** @type {Console?} */
#console;
/**
* Lazily get a console instance. Note that this script is loaded in very early to
* the browser loading process, and may run before the console is available. In
* this case the console will return as `undefined`.
*
* @returns {Console | void}
*/
get console() {
if (!this.#console) {
try {
this.#console = console.createInstance({
maxLogLevelPref: "browser.translations.logLevel",
prefix: "Translations",
});
} catch {
// The console may not be initialized yet.
}
}
return this.#console;
}
/**
* Where the lazy elements are stored.
*
* @type {Record<string, Element>?}
*/
#lazyElements;
/**
* Lazily creates the dom elements, and lazily selects them.
*
* @returns {Record<string, Element>}
*/
get elements() {
if (!this.#lazyElements) {
// Lazily turn the template into a DOM element.
/** @type {HTMLTemplateElement} */
const wrapper = document.getElementById(
"template-select-translations-panel"
);
const panel = wrapper.content.firstElementChild;
const settingsButton = document.getElementById(
"translations-panel-settings"
);
wrapper.replaceWith(wrapper.content);
// Lazily select the elements.
this.#lazyElements = {
panel,
settingsButton,
};
/**
* Define a getter on #lazyElements that gets the element by an id
* or class name.
*/
const getter = (name, discriminator) => {
let element;
Object.defineProperty(this.#lazyElements, name, {
get: () => {
if (!element) {
if (discriminator[0] === ".") {
// Lookup by class
element = document.querySelector(discriminator);
} else {
// Lookup by id
element = document.getElementById(discriminator);
}
}
if (!element) {
throw new Error(
`Could not find "${name}" at "#${discriminator}".`
);
}
return element;
},
});
};
// Getters by id
getter("betaIcon", "select-translations-panel-beta-icon");
getter("copyButton", "select-translations-panel-copy-button");
getter("doneButton", "select-translations-panel-done-button");
getter("fromLabel", "select-translations-panel-from-label");
getter("fromMenuList", "select-translations-panel-from");
getter("header", "select-translations-panel-header");
getter("multiview", "select-translations-panel-multiview");
getter("textArea", "select-translations-panel-translation-area");
getter("toLabel", "select-translations-panel-to-label");
getter("toMenuList", "select-translations-panel-to");
getter(
"translateFullPageButton",
"select-translations-panel-translate-full-page-button"
);
}
return this.#lazyElements;
}
/**
* Close the Select Translations Panel.
*/
close() {
PanelMultiView.hidePopup(this.elements.panel);
}
/**
* Open the Select Translations Panel.
*/
async open(event) {
// TODO(Bug 1878721) Rework the logic of where to open the panel.
//
// For the moment, the Select Translations panel opens at the
// AppMenu Button, but it will eventually need to open near
// to the selected content.
const appMenuButton = document.getElementById("PanelUI-menu-button");
const { panel, textArea } = this.elements;
panel.addEventListener("popupshown", () => textArea.focus(), {
once: true,
});
await PanelMultiView.openPopup(panel, appMenuButton, {
position: "bottomright topright",
triggerEvent: event,
}).catch(error => this.console?.error(error));
}
})();

View File

@ -27,7 +27,8 @@
<hbox class="translations-panel-beta">
<image class="translations-panel-beta-icon"></image>
</hbox>
<toolbarbutton id="translations-panel-settings" class="panel-info-button"
<toolbarbutton id="translations-panel-settings"
class="panel-info-button translations-panel-settings-gear-icon"
data-l10n-id="translations-panel-settings-button"
closemenu="none"
oncommand="TranslationsPanel.openSettingsPopup(this)"/>

View File

@ -3,4 +3,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
browser.jar:
content/browser/translations/selectTranslationsPanel.js (content/selectTranslationsPanel.js)
content/browser/translations/translationsPanel.js (content/translationsPanel.js)

View File

@ -28,3 +28,24 @@ main-context-menu-translate-link-text =
# $language (string) - The localized display name of the target language
main-context-menu-translate-link-text-to-language =
.label = Translate Link Text to { $language }
# Text displayed in the select translations panel header.
select-translations-panel-header = Translation
# Text displayed above the from-language dropdown menu.
select-translations-panel-from-label = From
# Text displayed above the to-language dropdown menu.
select-translations-panel-to-label = To
# Text displayed on the copy button.
select-translations-panel-copy-button = Copy
# Text displayed on the done button.
select-translations-panel-done-button = Done
# Text displayed on translate-full-page button.
select-translations-panel-translate-full-page-button = Translate full page
# Text displayed as a placeholder in the translated text area.
select-translations-panel-placeholder-text = Translated text will appear here.

View File

@ -46,7 +46,7 @@ h1.translations-panel-header-wrapper {
line-height: 1.6;
}
#translations-panel-settings > image {
.translations-panel-settings-gear-icon > image {
/* Override the panel-info-button with a gear icon. */
list-style-image: url(chrome://global/skin/icons/settings.svg);
}
@ -54,7 +54,6 @@ h1.translations-panel-header-wrapper {
.translations-panel-content {
padding: var(--arrowpanel-padding);
padding-block-end: 8px;
gap: var(--arrowpanel-padding);
}
#translations-panel-lang-selection > label {
@ -116,3 +115,57 @@ h1.translations-panel-header-wrapper {
border-radius: 4px;
padding: 12px;
}
.select-translations-panel-button {
align-items: center;
justify-content: center;
margin-inline: 0;
}
.select-translations-panel-content {
padding: var(--arrowpanel-padding);
padding-block: 4px;
}
.select-translations-panel-copy-button {
background-color: transparent;
font: message-box;
font-weight: var(--font-weight-bold);
&::before {
content: url(chrome://global/skin/icons/edit-copy.svg);
fill: currentColor;
margin-inline-end: 5px;
-moz-context-properties: fill;
}
}
.select-translations-panel-header {
padding: var(--arrowpanel-padding);
text-align: initial;
}
.select-translations-panel-label {
margin-inline: 2px;
}
#select-translations-panel-lang-selection {
gap: 6px;
}
#select-translations-panel-translation-area {
background-color: transparent;
border: none;
border-radius: 4px;
height: 8em;
margin-inline: 5px;
outline: 2px solid var(--arrowpanel-dimmed);
overflow: auto;
padding: 4px;
resize: none;
/* This manual focus styling may no longer be needed after Bug 1881256 lands.
https://bugzilla.mozilla.org/show_bug.cgi?id=1881256 */
&:focus {
outline: var(--focus-outline);
outline-offset: var(--focus-outline-offset);
}
}