Skip to content

Commit

Permalink
Bug 1820229 - Stub out a button in the URL bar for translations; r=no…
Browse files Browse the repository at this point in the history
…rdzilla,desktop-theme-reviewers,flod,Itiel

This code is untested since it's stubbing out functionality, which will
eventually use PageActions to open up a popup. The final code with the
popup will get tested, but for now rely on the existing test behavior,
without asserting new behavior.

Differential Revision: https://phabricator.services.mozilla.com/D173196
  • Loading branch information
gregtatum committed Mar 23, 2023
1 parent 94ee0e7 commit 5fbf34f
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 15 deletions.
2 changes: 2 additions & 0 deletions browser/base/content/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ ChromeUtils.defineESModuleGetters(this, {
TabsSetupFlowManager:
"resource:///modules/firefox-view-tabs-setup-manager.sys.mjs",
TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs",
TranslationsParent: "resource://gre/actors/TranslationsParent.sys.mjs",
UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
UrlbarInput: "resource:///modules/UrlbarInput.sys.mjs",
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
Expand Down Expand Up @@ -5363,6 +5364,7 @@ var XULBrowserWindow = {
CFRPageActions.updatePageActions(gBrowser.selectedBrowser);

AboutReaderParent.updateReaderButton(gBrowser.selectedBrowser);
TranslationsParent.updateButtonFromLocationChange(gBrowser.selectedBrowser);

PictureInPicture.updateUrlbarToggle(gBrowser.selectedBrowser);

Expand Down
1 change: 1 addition & 0 deletions browser/base/content/browser.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<link rel="localization" href="toolkit/printing/printUI.ftl"/>
<link rel="localization" href="browser/tabbrowser.ftl"/>
<link rel="localization" href="preview/firefoxSuggest.ftl"/>
<link rel="localization" href="locales-preview/translations.ftl"/>
<link rel="localization" href="browser/toolbarContextMenu.ftl"/>
<link rel="localization" href="browser/screenshots.ftl"/>
<link rel="localization" href="browser/firefoxView.ftl"/>
Expand Down
8 changes: 8 additions & 0 deletions browser/base/content/navigator-toolbox.inc.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,14 @@
<image id="picture-in-picture-button-icon"
class="urlbar-icon"/>
</hbox>
<hbox id="translations-button"
class="urlbar-page-action"
role="button"
data-l10n-id="urlbar-translations-button"
hidden="true"
onclick="TranslationsParent.urlBarButtonClick(event);">
<image class="urlbar-icon"/>
</hbox>
<toolbarbutton id="urlbar-zoom-button"
onclick="FullZoom.reset(); FullZoom.resetScalingZoom();"
tooltip="dynamic-shortcut-tooltip"
Expand Down
7 changes: 7 additions & 0 deletions browser/locales-preview/translations.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# 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/.

# The button for "Firefox Translations" in the url bar.
urlbar-translations-button =
.tooltiptext = { -translations-brand-name }
1 change: 1 addition & 0 deletions browser/locales/jar.mn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
preview/firefoxSuggest.ftl (../components/urlbar/content/firefoxSuggest.ftl)
preview/identityCredentialNotification.ftl (../components/credentialmanager/identityCredentialNotification.ftl)
locales-preview/migrationWizard.ftl (../locales-preview/migrationWizard.ftl)
locales-preview/translations.ftl (../locales-preview/translations.ftl)
browser (%browser/**/*.ftl)

@[email protected]:
Expand Down
6 changes: 6 additions & 0 deletions browser/themes/shared/icons/translations.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions browser/themes/shared/jar.inc.mn
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
skin/classic/browser/sync.svg (../shared/icons/sync.svg)
skin/classic/browser/synced-tabs.svg (../shared/icons/synced-tabs.svg)
skin/classic/browser/tab.svg (../shared/icons/tab.svg)
skin/classic/browser/translations.svg (../shared/icons/translations.svg)
skin/classic/browser/thumb-down.svg (../shared/icons/thumb-down.svg)
skin/classic/browser/topsites.svg (../shared/icons/topsites.svg)
skin/classic/browser/trending.svg (../shared/icons/trending.svg)
Expand Down
11 changes: 11 additions & 0 deletions browser/themes/shared/urlbar-searchbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,17 @@
transform: scaleX(-1);
}

/* Translations button */

#translations-button > .urlbar-icon {
list-style-image: url(chrome://browser/skin/translations.svg);
}

#translations-button[translationsactive] > .urlbar-icon {
fill: var(--toolbar-field-icon-fill-attention);
fill-opacity: 1;
}

/* Zoom button */

#urlbar-zoom-button {
Expand Down
4 changes: 4 additions & 0 deletions modules/libpref/init/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -3788,6 +3788,10 @@ pref("browser.translations.logLevel", "Error");
// and the full page translations uses HTML. Set this pref to true to use the HTML
// translation behavior on about:translations. Requires a page refresh.
pref("browser.translations.useHTML", false);
// Normally there is a UI to ask the user to translate a page, this pref makes it
// so that the page automatically performs a translation if one is detected as being
// required.
pref("browser.translations.autoTranslate", false);

// When a user cancels this number of authentication dialogs coming from
// a single web page in a row, all following authentication dialogs will
Expand Down
104 changes: 94 additions & 10 deletions toolkit/components/translations/actors/TranslationsChild.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ XPCOMUtils.defineLazyGetter(lazy, "console", () => {
});
});

XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"autoTranslatePagePref",
"browser.translations.autoTranslate"
);

export class LanguageIdEngine {
/** @type {Worker} */
#languageIdWorker;
Expand Down Expand Up @@ -417,6 +423,14 @@ export class TranslationsChild extends JSWindowActorChild {
*/
translatedDoc = null;

/**
* The matched language tags for the page. Used to find a default language pair for
* translations.
*
* @type {null | { appLangTag: string, docLangTag: string }}
* */
#langTags = null;

/**
* @returns {Promise<ArrayBuffer>}
*/
Expand Down Expand Up @@ -480,23 +494,49 @@ export class TranslationsChild extends JSWindowActorChild {
null,
"Event: " + event.type
);
if (event.type === "DOMContentLoaded") {
this.innerWindowId = this.contentWindow.windowGlobalChild.innerWindowId;
this.maybeTranslateDocument();
switch (event.type) {
case "DOMContentLoaded":
this.innerWindowId = this.contentWindow.windowGlobalChild.innerWindowId;
this.maybeOfferTranslation();
break;
case "pagehide":
lazy.console.log(
"pagehide",
this.contentWindow.location,
this.#langTags
);
this.reportLangTagsToParent(null);
break;
}
}

async maybeTranslateDocument() {
/**
* This is used to conditionally add the translations button.
* @param {null | { appLangTag: string, docLangTag: string }} langTags
*/
reportLangTagsToParent(langTags) {
this.sendAsyncMessage("Translations:ReportLangTags", {
langTags,
});
}

/**
* Determine if the page should be translated by checking the App's languages and
* comparing it to the reported language of the page. If we can translate the page,
* then return the language pair.
*
* @returns {Promise<null | { appLangTag: string, docLangTag: string }>}
*/
async getLangTagsForTranslation() {
const { href } = this.contentWindow.location;
if (
!href.startsWith("http://") &&
!href.startsWith("https://") &&
!href.startsWith("file:///")
) {
return;
return null;
}

const translationsStart = this.docShell.now();
let appLangTag = new Intl.Locale(Services.locale.appLocaleAsBCP47).language;
let docLangTag;

Expand All @@ -513,7 +553,7 @@ export class TranslationsChild extends JSWindowActorChild {
message
);
lazy.console.log(message, this.contentWindow.location.href);
return;
return null;
}

if (appLangTag === docLangTag) {
Expand All @@ -525,7 +565,7 @@ export class TranslationsChild extends JSWindowActorChild {
message
);
lazy.console.log(message, this.contentWindow.location.href);
return;
return null;
}

// There is no reason to look at supported languages if the engine is already in
Expand All @@ -534,7 +574,7 @@ export class TranslationsChild extends JSWindowActorChild {
// TODO - This is wrong for non-bidirectional translation pairs.
const supportedLanguages = await this.getSupportedLanguages();
if (this.#isDestroyed) {
return;
return null;
}
if (
!supportedLanguages.some(({ langTag }) => langTag === appLangTag) ||
Expand All @@ -547,10 +587,45 @@ export class TranslationsChild extends JSWindowActorChild {
message
);
lazy.console.log(message, supportedLanguages);
return;
return null;
}
}
return { appLangTag, docLangTag };
}

/**
* Deduce the language tags on the page, and either:
* 1. Show an offer to translate.
* 2. Auto-translate.
* 3. Do nothing.
*/
async maybeOfferTranslation() {
const translationsStart = this.docShell.now();
const langTags = await this.getLangTagsForTranslation();

this.#langTags = langTags;
this.reportLangTagsToParent(langTags);

if (langTags && lazy.autoTranslatePagePref) {
this.translatePage(langTags, translationsStart);
}
}

/**
* Load the translation engine and translate the page.
*
* @param {{docLangTag: string, appLangTag: string}} langTags
* @param {number} [translationsStart]
* @returns {Promise<void>}
*/
async translatePage(
{ docLangTag, appLangTag },
translationsStart = this.docShell.now()
) {
if (this.translatedDoc) {
lazy.console.warn("This page was already translated.");
return;
}
try {
const engineLoadStart = this.docShell.now();

Expand Down Expand Up @@ -641,6 +716,15 @@ export class TranslationsChild extends JSWindowActorChild {
case "Translations:IsMocked":
this.#isTranslationsEngineMocked = message.data;
break;
case "Translations:TranslatePage":
if (!this.#langTags) {
lazy.console.warn(
"Attempting to translate a page, but no language tags were present."
);
break;
}
this.translatePage(this.#langTags);
break;
default:
lazy.console.warn("Unknown message.");
}
Expand Down
Loading

0 comments on commit 5fbf34f

Please sign in to comment.