Bug 1444149 - Include addon name and icon in New Tab doorhanger r?aswan draft
authorMark Striemer <mstriemer@mozilla.com>
Fri, 09 Mar 2018 15:23:01 -0600
changeset 765584 91f83d5c44a4301835570a47e95fcf6ae1bb1946
parent 765057 b93a9c630a0c9ce75b5fc1a0ab91f3a9adbbab87
child 765585 2f1066199f2279da88d4bc686e4f715de4ebb8be
child 765586 02f48dad8ac61a1a639e6c5d04883244d2696a93
push id102111
push userbmo:mstriemer@mozilla.com
push dateFri, 09 Mar 2018 21:55:47 +0000
reviewersaswan
bugs1444149
milestone60.0a1
Bug 1444149 - Include addon name and icon in New Tab doorhanger r?aswan MozReview-Commit-ID: 2Mpn1iKVPbF
browser/components/customizableui/content/panelUI.inc.xul
browser/components/extensions/ext-url-overrides.js
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/shared/customizableui/panelUI.inc.css
toolkit/locales/en-US/chrome/global/extensions.properties
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -711,14 +711,12 @@
                      buttonlabel="&newTabControlled.keepButton.label;"
                      buttonaccesskey="&newTabControlled.keepButton.accesskey;"
                      secondarybuttonlabel="&newTabControlled.restoreButton.label;"
                      secondarybuttonaccesskey="&newTabControlled.restoreButton.accesskey;"
                      closebuttonhidden="true"
                      dropmarkerhidden="true"
                      checkboxhidden="true">
     <popupnotificationcontent orient="vertical">
-      <description id="extension-new-tab-notification-description">
-        &newTabControlled.message;
-      </description>
+      <description id="extension-new-tab-notification-description"/>
     </popupnotificationcontent>
   </popupnotification>
 </panel>
--- a/browser/components/extensions/ext-url-overrides.js
+++ b/browser/components/extensions/ext-url-overrides.js
@@ -1,35 +1,55 @@
 /* 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/. */
 /* import-globals-from ext-browser.js */
 
 "use strict";
 
+ChromeUtils.defineModuleGetter(this, "AddonManager",
+                               "resource://gre/modules/AddonManager.jsm");
+ChromeUtils.defineModuleGetter(this, "BrowserUtils",
+                               "resource://gre/modules/BrowserUtils.jsm");
+ChromeUtils.defineModuleGetter(this, "CustomizableUI",
+                               "resource:///modules/CustomizableUI.jsm");
 ChromeUtils.defineModuleGetter(this, "ExtensionSettingsStore",
                                "resource://gre/modules/ExtensionSettingsStore.jsm");
-ChromeUtils.defineModuleGetter(this, "AddonManager",
-                               "resource://gre/modules/AddonManager.jsm");
-ChromeUtils.defineModuleGetter(this, "CustomizableUI",
-                               "resource:///modules/CustomizableUI.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 const STORE_TYPE = "url_overrides";
 const NEW_TAB_SETTING_NAME = "newTabURL";
 const NEW_TAB_CONFIRMED_TYPE = "newTabNotification";
 
+XPCOMUtils.defineLazyGetter(this, "strBundle", function() {
+  return Services.strings.createBundle("chrome://global/locale/extensions.properties");
+});
+
 function userWasNotified(extensionId) {
   let setting = ExtensionSettingsStore.getSetting(NEW_TAB_CONFIRMED_TYPE, extensionId);
   return setting && setting.value;
 }
 
+function getAddonDetails(doc, addon) {
+  const defaultIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
+
+  let image = doc.createElement("image");
+  image.setAttribute("src", addon.iconURL || defaultIcon);
+  image.classList.add("extension-controlled-icon");
+
+  let addonDetails = doc.createDocumentFragment();
+  addonDetails.appendChild(image);
+  addonDetails.appendChild(doc.createTextNode(" " + addon.name));
+
+  return addonDetails;
+}
+
 function replaceUrlInTab(gBrowser, tab, url) {
   let loaded = new Promise(resolve => {
     windowTracker.addListener("progress", {
       onLocationChange(browser, webProgress, request, locationURI, flags) {
         if (webProgress.isTopLevel
             && browser.ownerGlobal.gBrowser.getTabForBrowser(browser) == tab
             && locationURI.spec == url) {
           windowTracker.removeListener(this);
@@ -53,31 +73,40 @@ async function handleNewTabOpened() {
   if (!item || !item.id || userWasNotified(item.id)) {
     return;
   }
 
   // Find the elements we need.
   let win = windowTracker.getCurrentWindow({});
   let doc = win.document;
   let panel = doc.getElementById("extension-notification-panel");
+  let addon = await AddonManager.getAddonByID(item.id);
+
+  let description = doc.getElementById("extension-new-tab-notification-description");
+  while (description.firstChild) {
+    description.firstChild.remove();
+  }
+  let message = strBundle.GetStringFromName("newTabControlled.message");
+  let addonDetails = getAddonDetails(doc, addon);
+  description.appendChild(
+    BrowserUtils.getLocalizedFragment(doc, message, addonDetails));
 
   // Setup the command handler.
   let handleCommand = async (event) => {
     if (event.originalTarget.getAttribute("anonid") == "button") {
       // Main action is to keep changes.
       await ExtensionSettingsStore.addSetting(
         item.id, NEW_TAB_CONFIRMED_TYPE, item.id, true, () => false);
     } else {
       // Secondary action is to restore settings. Disabling an add-on should remove
       // the tabs that it has open, but we want to open the new New Tab in this tab.
       //   1. Replace the tab's URL with about:blank, wait for it to change
       //   2. Now that this tab isn't associated with the add-on, disable the add-on
       //   3. Replace the tab's URL with the new New Tab URL
       ExtensionSettingsStore.removeSetting(NEW_TAB_CONFIRMED_TYPE, item.id);
-      let addon = await AddonManager.getAddonByID(item.id);
       let gBrowser = win.gBrowser;
       let tab = gBrowser.selectedTab;
       await replaceUrlInTab(gBrowser, tab, "about:blank");
       Services.obs.addObserver({
         async observe() {
           await replaceUrlInTab(gBrowser, tab, aboutNewTabService.newTabURL);
           handleNewTabOpened();
           Services.obs.removeObserver(this, "newtab-url-changed");
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -968,22 +968,22 @@ you can use these alternative items. Oth
 <!ENTITY updateRestart.message2 "After a quick restart, &brandShorterName; will restore all your open tabs and windows that are not in Private Browsing mode.">
 <!ENTITY updateRestart.header.message2 "Restart to update &brandShorterName;.">
 <!ENTITY updateRestart.acceptButton.label "Restart and Restore">
 <!ENTITY updateRestart.acceptButton.accesskey "R">
 <!ENTITY updateRestart.cancelButton.label "Not Now">
 <!ENTITY updateRestart.cancelButton.accesskey "N">
 <!ENTITY updateRestart.panelUI.label2 "Restart to update &brandShorterName;">
 
-<!ENTITY newTabControlled.message "An extension has changed the page you see when you open a New Tab. You can restore your settings if you do not want this change.">
+<!-- newTabControlled.message is in toolkit/locales/en-US/chrome/global/extensions.properties -->
 <!ENTITY newTabControlled.header.message "Your New Tab has changed.">
 <!ENTITY newTabControlled.keepButton.label "Keep Changes">
 <!ENTITY newTabControlled.keepButton.accesskey "K">
-<!ENTITY newTabControlled.restoreButton.label "Restore Settings">
-<!ENTITY newTabControlled.restoreButton.accesskey "R">
+<!ENTITY newTabControlled.restoreButton.label "Disable Extension">
+<!ENTITY newTabControlled.restoreButton.accesskey "D">
 
 <!ENTITY pageActionButton.tooltip "Page actions">
 <!ENTITY pageAction.addToUrlbar.label "Add to Address Bar">
 <!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar">
 <!ENTITY pageAction.allowInUrlbar.label "Show in Address Bar">
 <!ENTITY pageAction.disallowInUrlbar.label "Don’t Show in Address Bar">
 <!ENTITY pageAction.manageExtension.label "Manage Extension…">
 
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -328,16 +328,22 @@ panelview:not([mainview]) .toolbarbutton
   font-size: 1.3em;
   font-weight: lighter;
 }
 
 #extension-new-tab-notification-description {
   margin-bottom: 0;
 }
 
+#extension-new-tab-notification-description > .extension-controlled-icon {
+  height: 16px;
+  width: 16px;
+  vertical-align: bottom;
+}
+
 #extension-new-tab-notification > .popup-notification-body-container > .popup-notification-body > .popup-notification-warning,
 #extension-new-tab-notification > .popup-notification-body-container > .popup-notification-icon {
   display: none;
 }
 /* END notification popups for extension controlled content */
 
 #appMenu-popup > .panel-arrowcontainer > .panel-arrowcontent,
 panel[photon] > .panel-arrowcontainer > .panel-arrowcontent {
--- a/toolkit/locales/en-US/chrome/global/extensions.properties
+++ b/toolkit/locales/en-US/chrome/global/extensions.properties
@@ -24,8 +24,11 @@ uninstall.confirmation.title = Uninstall
 
 #LOCALIZATION NOTE (uninstall.confirmation.message) %S is the name of the extension which is about to be uninstalled.
 uninstall.confirmation.message = The extension “%S” is requesting to be uninstalled. What would you like to do?
 
 uninstall.confirmation.button-0.label = Uninstall
 uninstall.confirmation.button-1.label = Keep Installed
 
 saveaspdf.saveasdialog.title = Save As
+
+#LOCALIZATION NOTE (newTabControlled.message) %S is the icon and name of the extension which updated the New Tab page.
+newTabControlled.message = An extension, %S, changed the page you see when you open a new tab.