Bug 1323420 - Add a pref to control the close button on web permission prompts. r=past draft
authorNihanth Subramanya <nhnt11@gmail.com>
Mon, 16 Jan 2017 18:08:07 +0530
changeset 461322 f4b44cc4e145b29461c48bcff69c63eda68ed6b1
parent 461121 8eaf154b385bbe0ff06155294ccf7962aa2d3324
child 542298 034dd2ec5694174cbe2b1b5430d10a689efdcebd
push id41651
push usernhnt11@gmail.com
push dateMon, 16 Jan 2017 13:38:51 +0000
reviewerspast
bugs1323420
milestone53.0a1
Bug 1323420 - Add a pref to control the close button on web permission prompts. r=past MozReview-Commit-ID: 9hHQ5Jdhvg2
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/test/popupNotifications/browser_popupNotification_2.js
browser/modules/PermissionUI.jsm
browser/modules/webrtcUI.jsm
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/modules/PopupNotifications.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -514,16 +514,18 @@ pref("privacy.cpd.cookies",             
 pref("privacy.cpd.cache",                   true);
 pref("privacy.cpd.sessions",                true);
 pref("privacy.cpd.offlineApps",             false);
 pref("privacy.cpd.siteSettings",            false);
 pref("privacy.cpd.openWindows",             false);
 
 pref("privacy.history.custom",              false);
 
+pref("privacy.permissionPrompts.showCloseButton", false);
+
 // What default should we use for the time span in the sanitizer:
 // 0 - Clear everything
 // 1 - Last Hour
 // 2 - Last 2 Hours
 // 3 - Last 4 Hours
 // 4 - Today
 // 5 - Last 5 minutes
 // 6 - Last 24 hours
@@ -1574,9 +1576,9 @@ pref("services.sync.validation.enabled",
 
 // Preferences for the form autofill system extension
 pref("browser.formautofill.experimental", false);
 
 // Enable safebrowsing v4 tables (suffixed by "-proto") update.
 #ifdef NIGHTLY_BUILD
 pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
 pref("urlclassifier.phishTable", "goog-phish-shavar,goog-phish-proto,test-phish-simple");
-#endif
\ No newline at end of file
+#endif
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6206,22 +6206,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
@@ -335,19 +335,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
@@ -381,17 +381,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/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
@@ -707,17 +707,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(${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(${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 {