Bug 1174468 - Show Yandex.Translate attribution when Yandex engine is selected. r=felipc
authorIaroslav Sheptykin <yarik.sheptykin@googlemail.com>
Mon, 20 Jul 2015 06:54:00 -0400
changeset 254117 bfa0f07aeccb1cb52fbb0503ef2002ad345c2f17
parent 254116 b787fd6ee92bb0096f5cf439c061c9e1ea644bdf
child 254118 19bdfb755eebb79704eda17585583849433aea84
push id29089
push userryanvm@gmail.com
push dateWed, 22 Jul 2015 20:29:27 +0000
treeherdermozilla-central@7abecce35aca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipc
bugs1174468
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1174468 - Show Yandex.Translate attribution when Yandex engine is selected. r=felipc
browser/components/preferences/content.js
browser/components/preferences/content.xul
browser/components/preferences/in-content/content.js
browser/components/preferences/in-content/content.xul
browser/components/translation/Translation.jsm
browser/components/translation/test/browser_translation_yandex.js
browser/components/translation/translation-infobar.xml
browser/locales/en-US/chrome/browser/translation.dtd
--- a/browser/components/preferences/content.js
+++ b/browser/components/preferences/content.js
@@ -13,16 +13,21 @@ var gContentPane = {
       menulist.value = FontBuilder.readFontSelection(menulist);
     }
 
     // Show translation preferences if we may:
     const prefName = "browser.translation.ui.show";
     if (Services.prefs.getBoolPref(prefName)) {
       let row = document.getElementById("translationBox");
       row.removeAttribute("hidden");
+      // Showing attribution only for Bing Translator.
+      Components.utils.import("resource:///modules/translation/Translation.jsm");
+      if (Translation.translationEngine == "bing") {
+        document.getElementById("bingAttribution").removeAttribute("hidden");
+      }
     }
 
     let drmInfoURL =
       Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content";
     document.getElementById("playDRMContentLink").setAttribute("href", drmInfoURL);
     let emeUIEnabled = Services.prefs.getBoolPref("browser.eme.ui.enabled");
     // Force-disable/hide on WinXP:
     if (navigator.platform.toLowerCase().startsWith("win")) {
--- a/browser/components/preferences/content.xul
+++ b/browser/components/preferences/content.xul
@@ -158,21 +158,23 @@
                     oncommand="gContentPane.showLanguages();"/>
           </row>
           <row id="translationBox" hidden="true">
             <hbox align="center">
               <checkbox id="translate" preference="browser.translation.detectLanguage"
                         label="&translateWebPages.label;." accesskey="&translateWebPages.accesskey;"
                         onsyncfrompreference="return gContentPane.updateButtons('translateButton',
                                               'browser.translation.detectLanguage');"/>
-              <label>&translation.options.attribution.beforeLogo;</label>
-              <image id="translationAttributionImage" aria-label="Microsoft Translator"
-                     onclick="gContentPane.openTranslationProviderAttribution()"
-                     src="chrome://browser/content/microsoft-translator-attribution.png"/>
-              <label>&translation.options.attribution.afterLogo;</label>
+              <hbox id="bingAttribution" hidden="true">
+                <label>&translation.options.attribution.beforeLogo;</label>
+                <image id="translationAttributionImage" aria-label="Microsoft Translator"
+                       onclick="gContentPane.openTranslationProviderAttribution()"
+                       src="chrome://browser/content/microsoft-translator-attribution.png"/>
+                <label>&translation.options.attribution.afterLogo;</label>
+              </hbox>
             </hbox>
             <button id="translateButton" label="&translateExceptions.label;"
                     oncommand="gContentPane.showTranslationExceptions();"
                     accesskey="&translateExceptions.accesskey;"/>
           </row>
         </rows>
       </grid>
 
--- a/browser/components/preferences/in-content/content.js
+++ b/browser/components/preferences/in-content/content.js
@@ -18,16 +18,21 @@ var gContentPane = {
       menulist.value = FontBuilder.readFontSelection(menulist);
     }
 
     // Show translation preferences if we may:
     const prefName = "browser.translation.ui.show";
     if (Services.prefs.getBoolPref(prefName)) {
       let row = document.getElementById("translationBox");
       row.removeAttribute("hidden");
+      // Showing attribution only for Bing Translator.
+      Components.utils.import("resource:///modules/translation/Translation.jsm");
+      if (Translation.translationEngine == "bing") {
+        document.getElementById("bingAttribution").removeAttribute("hidden");
+      }
     }
 
     setEventListener("font.language.group", "change",
       gContentPane._rebuildFonts);
     setEventListener("popupPolicyButton", "command",
       gContentPane.showPopupExceptions);
     setEventListener("advancedFonts", "command",
       gContentPane.configureFonts);
--- a/browser/components/preferences/in-content/content.xul
+++ b/browser/components/preferences/in-content/content.xul
@@ -155,19 +155,21 @@
   </hbox>
 
   <hbox id="translationBox" hidden="true">
     <hbox align="center" flex="1">
       <checkbox id="translate" preference="browser.translation.detectLanguage"
                 label="&translateWebPages.label;." accesskey="&translateWebPages.accesskey;"
                 onsyncfrompreference="return gContentPane.updateButtons('translateButton',
                                               'browser.translation.detectLanguage');"/>
-      <label>&translation.options.attribution.beforeLogo;</label>
-      <separator orient="vertical" class="thin"/>
-      <image id="translationAttributionImage" aria-label="Microsoft Translator"
-             src="chrome://browser/content/microsoft-translator-attribution.png"/>
-      <separator orient="vertical" class="thin"/>
-      <label>&translation.options.attribution.afterLogo;</label>
+      <hbox id="bingAttribution" hidden="true">
+        <label>&translation.options.attribution.beforeLogo;</label>
+        <separator orient="vertical" class="thin"/>
+        <image id="translationAttributionImage" aria-label="Microsoft Translator"
+               src="chrome://browser/content/microsoft-translator-attribution.png"/>
+        <separator orient="vertical" class="thin"/>
+        <label>&translation.options.attribution.afterLogo;</label>
+      </hbox>
     </hbox>
     <button id="translateButton" label="&translateExceptions.label;"
             accesskey="&translateExceptions.accesskey;"/>
   </hbox>
 </groupbox>
--- a/browser/components/translation/Translation.jsm
+++ b/browser/components/translation/Translation.jsm
@@ -79,20 +79,44 @@ this.Translation = {
 
     trUI.showURLBarIcon();
 
     if (trUI.shouldShowInfoBar(aBrowser.currentURI))
       trUI.showTranslationInfoBar();
   },
 
   openProviderAttribution: function() {
+    let attribution = this.supportedEngines[this.translationEngine];
     Cu.import("resource:///modules/RecentWindow.jsm");
-    RecentWindow.getMostRecentBrowserWindow().openUILinkIn(
-      "http://aka.ms/MicrosoftTranslatorAttribution", "tab");
-  }
+    RecentWindow.getMostRecentBrowserWindow().openUILinkIn(attribution, "tab");
+  },
+
+  /**
+   * The list of translation engines and their attributions.
+   */
+  supportedEngines: {
+    "bing"    : "http://aka.ms/MicrosoftTranslatorAttribution",
+    "yandex"  : "http://translate.yandex.com/"
+  },
+
+  /**
+   * Fallback engine (currently Bing Translator) if the preferences seem
+   * confusing.
+   */
+  get defaultEngine() {
+    return this.supportedEngines.keys[0];
+  },
+
+  /**
+   * Returns the name of the preferred translation engine.
+   */
+  get translationEngine() {
+    let engine = Services.prefs.getCharPref("browser.translation.engine");
+    return Object.keys(this.supportedEngines).includes(engine) ? engine : this.defaultEngine;
+  },
 };
 
 /* TranslationUI objects keep the information related to translation for
  * a specific browser.  This object is passed to the translation
  * infobar so that it can initialize itself.  The properties exposed to
  * the infobar are:
  * - detectedLanguage, code of the language detected on the web page.
  * - state, the state in which the infobar should be displayed
--- a/browser/components/translation/test/browser_translation_yandex.js
+++ b/browser/components/translation/test/browser_translation_yandex.js
@@ -3,28 +3,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Test the Yandex Translator client against a mock Yandex service, yandex.sjs.
 
 "use strict";
 
 const kEnginePref = "browser.translation.engine";
 const kApiKeyPref = "browser.translation.yandex.apiKeyOverride";
+const kShowUIPref = "browser.translation.ui.show";
 
 const {YandexTranslator} = Cu.import("resource:///modules/translation/YandexTranslator.jsm", {});
 const {TranslationDocument} = Cu.import("resource:///modules/translation/TranslationDocument.jsm", {});
 const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
+const {Translation} = Cu.import("resource:///modules/translation/Translation.jsm", {});
 
 add_task(function* setup() {
   Services.prefs.setCharPref(kEnginePref, "yandex");
   Services.prefs.setCharPref(kApiKeyPref, "yandexValidKey");
+  Services.prefs.setBoolPref(kShowUIPref, true);
 
   registerCleanupFunction(function () {
     Services.prefs.clearUserPref(kEnginePref);
     Services.prefs.clearUserPref(kApiKeyPref);
+    Services.prefs.clearUserPref(kShowUIPref);
   });
 });
 
 /**
  * Ensure that the translation engine behaives as expected when translating
  * a sample page.
  */
 add_task(function* test_yandex_translation() {
@@ -41,16 +45,48 @@ add_task(function* test_yandex_translati
   let result = yield client.translate();
 
   Assert.ok(result, "There should be a result.");
 
   gBrowser.removeTab(tab);
 });
 
 /**
+ * Ensure that Yandex.Translate is propertly attributed.
+ */
+add_task(function* test_yandex_attribution() {
+  // Loading the fixture page.
+  let url = constructFixtureURL("bug1022725-fr.html");
+  let tab = yield promiseTestPageLoad(url);
+
+  info("Show an info bar saying the current page is in French");
+  let notif = showTranslationUI(tab, "fr");
+  let attribution = notif._getAnonElt("translationEngine").selectedIndex;
+  Assert.equal(attribution, 1, "Yandex attribution should be shown.");
+
+  gBrowser.removeTab(tab);
+});
+
+
+add_task(function* test_preference_attribution() {
+
+    let prefUrl = "about:preferences#content";
+    let tab = yield promiseTestPageLoad(prefUrl);
+
+    let browser = gBrowser.getBrowserForTab(tab);
+    let win = browser.contentWindow;
+    let bingAttribution = win.document.getElementById("bingAttribution");
+    ok(bingAttribution, "Bing attribution should exist.");
+    ok(bingAttribution.hidden, "Bing attribution should be hidden.");
+
+    gBrowser.removeTab(tab);
+
+});
+
+/**
  * A helper function for constructing a URL to a page stored in the
  * local fixture folder.
  *
  * @param filename  Name of a fixture file.
  */
 function constructFixtureURL(filename){
   // Deduce the Mochitest server address in use from a pref that was pre-processed.
   let server = Services.prefs.getCharPref("browser.translation.yandex.translateURLOverride")
@@ -74,8 +110,17 @@ function promiseTestPageLoad(url) {
     if (browser.currentURI.spec == "about:blank")
       return;
     info("Page loaded: " + browser.currentURI.spec);
     browser.removeEventListener("load", listener, true);
     deferred.resolve(tab);
   }, true);
   return deferred.promise;
 }
+
+function showTranslationUI(tab, aDetectedLanguage) {
+  let browser = gBrowser.selectedBrowser;
+  Translation.documentStateReceived(browser, {state: Translation.STATE_OFFER,
+                                              originalShown: true,
+                                              detectedLanguage: aDetectedLanguage});
+  let ui = browser.translationUI;
+  return ui.notificationBox.getNotificationWithValue("translation");
+}
--- a/browser/components/translation/translation-infobar.xml
+++ b/browser/components/translation/translation-infobar.xml
@@ -122,22 +122,27 @@
               <xul:menuitem anonid="neverForSite"
                             oncommand="document.getBindingParent(this).neverForSite();"
                             label="&translation.options.neverForSite.label;"
                             accesskey="&translation.options.neverForSite.accesskey;"/>
               <xul:menuseparator/>
               <xul:menuitem oncommand="openPreferences('paneContent');"
                             label="&translation.options.preferences.label;"
                             accesskey="&translation.options.preferences.accesskey;"/>
-              <xul:menuitem class="translation-attribution subviewbutton panel-subview-footer"
+              <xul:menuitem class="subviewbutton panel-subview-footer"
                             oncommand="document.getBindingParent(this).openProviderAttribution();">
-                <xul:label>&translation.options.attribution.beforeLogo;</xul:label>
-                <xul:image src="chrome://browser/content/microsoft-translator-attribution.png"
-                           aria-label="Microsoft Translator"/>
-                <xul:label>&translation.options.attribution.afterLogo;</xul:label>
+                <xul:deck anonid="translationEngine" selectedIndex="0">
+                  <xul:hbox class="translation-attribution">
+                    <xul:label>&translation.options.attribution.beforeLogo;</xul:label>
+                    <xul:image src="chrome://browser/content/microsoft-translator-attribution.png"
+                               aria-label="Microsoft Translator"/>
+                    <xul:label>&translation.options.attribution.afterLogo;</xul:label>
+                  </xul:hbox>
+                  <xul:label class="translation-attribution">&translation.options.attribution.yandexTranslate;</xul:label>
+                </xul:deck>
               </xul:menuitem>
             </xul:menupopup>
           </xul:button>
 
         </xul:hbox>
         <xul:toolbarbutton ondblclick="event.stopPropagation();"
                            anonid="closeButton"
                            class="messageCloseButton close-icon tabbable"
@@ -210,16 +215,23 @@
               toLanguage.appendItem(name, code);
 
             if (aTranslation.translatedTo)
               toLanguage.value = aTranslation.translatedTo;
 
             if (aTranslation.state)
               this.state = aTranslation.state;
 
+            // Show attribution for the preferred translator.
+            let engineIndex = Object.keys(Translation.supportedEngines)
+              .indexOf(Translation.translationEngine);
+            if (engineIndex != -1) {
+              this._getAnonElt('translationEngine').selectedIndex = engineIndex;
+            }
+
             const kWelcomePref = "browser.translation.ui.welcomeMessageShown";
             if (Services.prefs.prefHasUserValue(kWelcomePref) ||
                 this.translation.browser != gBrowser.selectedBrowser)
               return;
 
             this.addEventListener("transitionend", function onShown() {
               this.removeEventListener("transitionend", onShown);
 
--- a/browser/locales/en-US/chrome/browser/translation.dtd
+++ b/browser/locales/en-US/chrome/browser/translation.dtd
@@ -59,8 +59,17 @@
 
 <!-- LOCALIZATION NOTE (translation.options.attribution.beforeLogo,
   -                     translation.options.attribution.afterLogo):
   -  These 2 strings are displayed before and after a 'Microsoft Translator'
   -  logo.
   -->
 <!ENTITY translation.options.attribution.beforeLogo "Translations by">
 <!ENTITY translation.options.attribution.afterLogo "">
+
+<!-- LOCALIZATION NOTE (translation.options.attribution.poweredByYandex,
+                        translation.options.attribution.beforeLogo,
+  -                     translation.options.attribution.afterLogo):
+  -  translation.options.attribution.poweredByYandex is displayed instead of
+  -  the other two strings when yandex translation engine is preferred by the
+  -  user.
+  -->
+<!ENTITY translation.options.attribution.yandexTranslate "Powered by Yandex.Translate">