Bug 1323420 - Add a pref to control the close button on web permission prompts. r=past
authorNihanth Subramanya <nhnt11@gmail.com>
Mon, 16 Jan 2017 18:08:07 +0530
changeset 379648 0c698bfb1310af765951946cfb317e37471e1881
parent 379647 8396ed4c874f948d3b41fce7be5155cbfca1c15b
child 379649 fffe9c114f88be787f003cdfe3d997d7d56b3081
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspast
bugs1323420
milestone53.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 1323420 - Add a pref to control the close button on web permission prompts. r=past MozReview-Commit-ID: JHEY478q3C
browser/base/content/browser.js
browser/base/content/test/popupNotifications/browser_popupNotification_2.js
browser/modules/PermissionUI.jsm
browser/modules/webrtcUI.jsm
modules/libpref/init/all.js
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/modules/PopupNotifications.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6241,22 +6241,22 @@ var IndexedDBPromptHelper = {
         accessKey: gNavigatorBundle.getString("offlineApps.dontAllow.accesskey"),
         callback() {
           observer.observe(null, responseTopic,
                            Ci.nsIPermissionManager.DENY_ACTION);
         }
       }
     ];
 
-    PopupNotifications.show(browser, topic, message,
-                            this._notificationIcon, mainAction,
-                            secondaryActions, {
-                              persistent: true,
-                              hideClose: true,
-                            });
+    PopupNotifications.show(
+      browser, topic, message, this._notificationIcon, mainAction, secondaryActions,
+      {
+        persistent: true,
+        hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
+      });
   }
 };
 
 function CanCloseWindow() {
   // Avoid redundant calls to canClose from showing multiple
   // PermitUnload dialogs.
   if (Services.startup.shuttingDown || window.skipNextCanClose) {
     return true;
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
@@ -193,20 +193,42 @@ var tests = [
       checkPopup(popup, this.notifyObj);
       let notification = popup.childNodes[0];
       EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
     },
     onHidden(popup) {
       ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
       this.notification.remove();
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
+      ok(!this.notifyObj.secondaryActionClicked, "secondary action not clicked");
+    }
+  },
+  // Test that notification close button calls secondary action instead of
+  // dismissal callback if privacy.permissionPrompts.showCloseButton is set.
+  { id: "Test#10",
+    run() {
+      Preferences.set("privacy.permissionPrompts.showCloseButton", true);
+      this.notifyObj = new BasicNotification(this.id);
+      this.notification = showNotification(this.notifyObj);
+    },
+    onShown(popup) {
+      checkPopup(popup, this.notifyObj);
+      let notification = popup.childNodes[0];
+      EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
+    },
+    onHidden(popup) {
+      ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback not triggered");
+      ok(this.notifyObj.secondaryActionClicked, "secondary action clicked");
+      Preferences.reset("privacy.permissionPrompts.showCloseButton");
+      this.notification.remove();
+      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     }
   },
   // Test notification when chrome is hidden
-  { id: "Test#10",
+  { id: "Test#11",
     run() {
       window.locationbar.visible = false;
       this.notifyObj = new BasicNotification(this.id);
       this.notification = showNotification(this.notifyObj);
     },
     onShown(popup) {
       checkPopup(popup, this.notifyObj);
       is(popup.anchorNode.className, "tabbrowser-tab", "notification anchored to tab");
--- a/browser/modules/PermissionUI.jsm
+++ b/browser/modules/PermissionUI.jsm
@@ -336,19 +336,19 @@ this.PermissionPromptPrototype = {
                      popupNotificationActions[0] : null;
     let secondaryActions = popupNotificationActions.splice(1);
 
     let options = this.popupOptions;
 
     if (!options.hasOwnProperty("displayURI") || options.displayURI) {
       options.displayURI = this.principal.URI;
     }
-    // Permission prompts are always persistent and don't have a close button.
+    // Permission prompts are always persistent; the close button is controlled by a pref.
     options.persistent = true;
-    options.hideClose = true;
+    options.hideClose = !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton");
 
     this.onBeforeShow();
     chromeWin.PopupNotifications.show(this.browser,
                                       this.notificationID,
                                       this.message,
                                       this.anchorID,
                                       mainAction,
                                       secondaryActions,
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -439,17 +439,17 @@ function prompt(aBrowser, aRequest) {
   } else if (sharingAudio) {
     reasonForNoPermanentAllow = "getUserMedia.reasonForNoPermanentAllow.audio";
   } else if (!aRequest.secure) {
     reasonForNoPermanentAllow = "getUserMedia.reasonForNoPermanentAllow.insecure";
   }
 
   let options = {
     persistent: true,
-    hideClose: true,
+    hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
     checkbox: {
       label: stringBundle.getString("getUserMedia.remember"),
       checkedState: reasonForNoPermanentAllow ? {
         disableMainAction: true,
         warningLabel: stringBundle.getFormattedString(reasonForNoPermanentAllow,
                                                       [productName])
       } : undefined,
     },
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1215,16 +1215,20 @@ pref("content.sink.pending_event_mode", 
 // Disable popups from plugins by default
 //   0 = openAllowed
 //   1 = openControlled
 //   2 = openAbused
 pref("privacy.popups.disable_from_plugins", 2);
 
 // send "do not track" HTTP header, disabled by default
 pref("privacy.donottrackheader.enabled",    false);
+// If true, close buton will be shown on permission prompts
+// and for all PopupNotifications, the secondary action of
+// the popup will be called when the popup is dismissed.
+pref("privacy.permissionPrompts.showCloseButton", false);
 // Enforce tracking protection in all modes
 pref("privacy.trackingprotection.enabled",  false);
 // Enforce tracking protection in Private Browsing mode
 pref("privacy.trackingprotection.pbmode.enabled",  true);
 // Annotate channels based on the tracking protection list in all modes
 pref("privacy.trackingprotection.annotate_channels",  false);
 // Lower the priority of network loads for resources on the tracking protection list.
 // Note that this requires the privacy.trackingprotection.annotate_channels pref to be on in order to have any effect.
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -1008,17 +1008,17 @@ LoginManagerPrompter.prototype = {
       promptMsg,
       "password-notification-icon",
       mainAction,
       secondaryActions,
       {
         timeout: Date.now() + 10000,
         persistWhileVisible: true,
         passwordNotificationType: type,
-        hideClose: true,
+        hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
         eventCallback(topic) {
           switch (topic) {
             case "showing":
               currentNotification = this;
               chromeDoc.getElementById("password-notification-password")
                        .removeAttribute("focused");
               chromeDoc.getElementById("password-notification-username")
                        .removeAttribute("focused");
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -711,17 +711,22 @@ PopupNotifications.prototype = {
       if (popupnotification)
         gNotificationParents.set(popupnotification, popupnotification.parentNode);
       else
         popupnotification = doc.createElementNS(XUL_NS, "popupnotification");
 
       popupnotification.setAttribute("label", n.message);
       popupnotification.setAttribute("id", popupnotificationID);
       popupnotification.setAttribute("popupid", n.id);
-      popupnotification.setAttribute("closebuttoncommand", `PopupNotifications._dismiss(event, ${TELEMETRY_STAT_DISMISSAL_CLOSE_BUTTON});`);
+      if (Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton")) {
+        popupnotification.setAttribute("closebuttoncommand", "PopupNotifications._onButtonEvent(event, 'secondarybuttoncommand');");
+      }
+      else {
+        popupnotification.setAttribute("closebuttoncommand", `PopupNotifications._dismiss(event, ${TELEMETRY_STAT_DISMISSAL_CLOSE_BUTTON});`);
+      }
       if (n.mainAction) {
         popupnotification.setAttribute("buttonlabel", n.mainAction.label);
         popupnotification.setAttribute("buttonaccesskey", n.mainAction.accessKey);
         popupnotification.setAttribute("buttoncommand", "PopupNotifications._onButtonEvent(event, 'buttoncommand');");
         popupnotification.setAttribute("dropmarkerpopupshown", "PopupNotifications._onButtonEvent(event, 'dropmarkerpopupshown');");
         popupnotification.setAttribute("learnmoreclick", "PopupNotifications._onButtonEvent(event, 'learnmoreclick');");
         popupnotification.setAttribute("menucommand", "PopupNotifications._onMenuCommand(event);");
       } else {