Bug 1315228 - add a popupIconClass option to popup notifications so that the microphone and screensharing icons can be set without hacks, r=paolo.
authorFlorian Quèze <florian@queze.net>
Wed, 09 Nov 2016 15:32:49 +0100
changeset 367006 41e192bec53699a83c3002bb374c13909f6d6135
parent 367005 0675eb15b778409550d77a77324695a7350d6586
child 367007 c17531742f635bcb7bac22ba9e80c23afd7d49b5
push id1369
push userjlorenzo@mozilla.com
push dateMon, 27 Feb 2017 14:59:41 +0000
treeherdermozilla-release@d75a1dba431f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspaolo
bugs1315228
milestone52.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 1315228 - add a popupIconClass option to popup notifications so that the microphone and screensharing icons can be set without hacks, r=paolo.
browser/base/content/test/webrtc/browser_devices_get_user_media.js
browser/modules/webrtcUI.jsm
browser/themes/shared/notification-icons.inc.css
toolkit/content/widgets/notification.xml
toolkit/modules/PopupNotifications.jsm
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media.js
@@ -19,18 +19,19 @@ var gTests = [
     let promise = promisePopupNotificationShown("webRTC-shareDevices");
     yield promiseRequestDevice(true, true);
     yield promise;
     yield expectObserverCalled("getUserMedia:request");
 
     is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
        "webRTC-shareDevices-notification-icon", "anchored to device icon");
     checkDeviceSelectors(true, true);
-    is(PopupNotifications.panel.firstChild.getAttribute("popupid"),
-       "webRTC-shareDevices", "panel using devices icon");
+    let iconclass =
+      PopupNotifications.panel.firstChild.getAttribute("iconclass");
+    ok(iconclass.includes("camera-icon"), "panel using devices icon");
 
     let indicator = promiseIndicatorWindow();
     yield promiseMessage("ok", () => {
       PopupNotifications.panel.firstChild.button.click();
     });
     yield expectObserverCalled("getUserMedia:response:allow");
     yield expectObserverCalled("recording-device-events");
     is((yield getMediaCaptureState()), "CameraAndMicrophone",
@@ -48,18 +49,19 @@ var gTests = [
     let promise = promisePopupNotificationShown("webRTC-shareDevices");
     yield promiseRequestDevice(true);
     yield promise;
     yield expectObserverCalled("getUserMedia:request");
 
     is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
        "webRTC-shareMicrophone-notification-icon", "anchored to mic icon");
     checkDeviceSelectors(true);
-    is(PopupNotifications.panel.firstChild.getAttribute("popupid"),
-       "webRTC-shareMicrophone", "panel using microphone icon");
+    let iconclass =
+      PopupNotifications.panel.firstChild.getAttribute("iconclass");
+    ok(iconclass.includes("microphone-icon"), "panel using microphone icon");
 
     let indicator = promiseIndicatorWindow();
     yield promiseMessage("ok", () => {
       PopupNotifications.panel.firstChild.button.click();
     });
     yield expectObserverCalled("getUserMedia:response:allow");
     yield expectObserverCalled("recording-device-events");
     is((yield getMediaCaptureState()), "Microphone",
@@ -77,18 +79,19 @@ var gTests = [
     let promise = promisePopupNotificationShown("webRTC-shareDevices");
     yield promiseRequestDevice(false, true);
     yield promise;
     yield expectObserverCalled("getUserMedia:request");
 
     is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
        "webRTC-shareDevices-notification-icon", "anchored to device icon");
     checkDeviceSelectors(false, true);
-    is(PopupNotifications.panel.firstChild.getAttribute("popupid"),
-       "webRTC-shareDevices", "panel using devices icon");
+    let iconclass =
+      PopupNotifications.panel.firstChild.getAttribute("iconclass");
+    ok(iconclass.includes("camera-icon"), "panel using devices icon");
 
     let indicator = promiseIndicatorWindow();
     yield promiseMessage("ok", () => {
       PopupNotifications.panel.firstChild.button.click();
     });
     yield expectObserverCalled("getUserMedia:response:allow");
     yield expectObserverCalled("recording-device-events");
     is((yield getMediaCaptureState()), "Camera", "expected camera to be shared");
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -358,27 +358,16 @@ function prompt(aBrowser, aRequest) {
 
   let options = {
     eventCallback: function(aTopic, aNewBrowser) {
       if (aTopic == "swapping")
         return true;
 
       let chromeDoc = this.browser.ownerDocument;
 
-      if (aTopic == "shown") {
-        let popupId = "Devices";
-        if (requestTypes.length == 1 && (requestTypes[0] == "Microphone" ||
-                                         requestTypes[0] == "AudioCapture"))
-          popupId = "Microphone";
-        if (requestTypes.includes("Screen"))
-          popupId = "Screen";
-        chromeDoc.getElementById("webRTC-shareDevices-notification")
-                 .setAttribute("popupid", "webRTC-share" + popupId);
-      }
-
       // Clean-up video streams of screensharing previews.
       if ((aTopic == "dismissed" || aTopic == "removed") &&
           requestTypes.includes("Screen")) {
         let video = chromeDoc.getElementById("webRTC-previewVideo");
         video.deviceId = undefined;
         if (video.stream) {
           video.stream.getTracks().forEach(t => t.stop());
           video.stream = null;
@@ -666,21 +655,29 @@ function prompt(aBrowser, aRequest) {
         mm.sendAsyncMessage("webrtc:Allow", {callID: aRequest.callID,
                                              windowID: aRequest.windowID,
                                              devices: allowedDevices});
       };
       return false;
     }
   };
 
-  let anchorId = "webRTC-shareDevices-notification-icon";
-  if (requestTypes.length == 1 && requestTypes[0] == "Microphone")
-    anchorId = "webRTC-shareMicrophone-notification-icon";
+  let iconType = "Devices";
+  if (requestTypes.length == 1 && (requestTypes[0] == "Microphone" ||
+                                   requestTypes[0] == "AudioCapture"))
+    iconType = "Microphone";
   if (requestTypes.includes("Screen"))
-    anchorId = "webRTC-shareScreen-notification-icon";
+    iconType = "Screen";
+  let anchorId = "webRTC-share" + iconType + "-notification-icon";
+
+  let iconClass = iconType.toLowerCase();
+  if (iconClass == "devices")
+    iconClass = "camera";
+  options.popupIconClass = iconClass + "-icon";
+
   notification =
     chromeWin.PopupNotifications.show(aBrowser, "webRTC-shareDevices", message,
                                       anchorId, mainAction, secondaryActions,
                                       options);
   notification.callID = aRequest.callID;
 }
 
 function removePrompt(aBrowser, aCallId) {
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -108,18 +108,17 @@
 .login-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#login);
 }
 
 .popup-notification-icon[popupid="password"] {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#login-detailed);
 }
 
-.camera-icon,
-.popup-notification-icon[popupid="webRTC-shareDevices"] {
+.camera-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#camera);
 }
 
 .camera-icon.in-use {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#camera-sharing);
 }
 
 .camera-icon.blocked-permission-icon {
@@ -133,21 +132,20 @@
 .microphone-icon.in-use {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone-sharing);
 }
 
 .microphone-icon.blocked-permission-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone-blocked);
 }
 
-.popup-notification-icon[popupid="webRTC-shareMicrophone"] {
+.popup-notification-icon.microphone-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#microphone-detailed);
 }
 
-.popup-notification-icon[popupid="webRTC-shareScreen"],
 .screen-icon {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#screen);
 }
 
 .screen-icon.in-use {
   list-style-image: url(chrome://browser/skin/notification-icons.svg#screen-sharing);
 }
 
--- a/toolkit/content/widgets/notification.xml
+++ b/toolkit/content/widgets/notification.xml
@@ -484,17 +484,17 @@
       </method>
     </implementation>
   </binding>
 
   <binding id="popup-notification">
     <content>
       <xul:vbox>
         <xul:image class="popup-notification-icon"
-                   xbl:inherits="popupid,src=icon"/>
+                   xbl:inherits="popupid,src=icon,class=iconclass"/>
       </xul:vbox>
       <xul:vbox class="popup-notification-body" xbl:inherits="popupid">
         <xul:hbox align="start">
           <xul:vbox flex="1">
             <xul:label class="popup-notification-origin header"
                        xbl:inherits="value=origin,tooltiptext=origin"
                        crop="center"/>
             <xul:description class="popup-notification-description"
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -367,16 +367,21 @@ PopupNotifications.prototype = {
    *                         (optional) An object that allows you to customize
    *                         the notification state when the checkbox is not checked.
    *                         Has the same attributes as checkedState.
    *        hideNotNow:  If true, indicates that the 'Not Now' menuitem should
    *                     not be shown. If 'Not Now' is hidden, it needs to be
    *                     replaced by another 'do nothing' item, so providing at
    *                     least one secondary action is required; and one of the
    *                     actions needs to have the 'dismiss' property set to true.
+   *        popupIconClass:
+   *                     A string. A class (or space separated list of classes)
+   *                     that will be applied to the icon in the popup so that
+   *                     several notifications using the same panel can use
+   *                     different icons.
    *        popupIconURL:
    *                     A string. URL of the image to be displayed in the popup.
    *                     Normally specified in CSS using list-style-image and the
    *                     .popup-notification-icon[popupid=...] selector.
    *        learnMoreURL:
    *                     A string URL. Setting this property will make the
    *                     prompt display a "Learn More" link that, when clicked,
    *                     opens the URL in a new tab.
@@ -678,16 +683,20 @@ PopupNotifications.prototype = {
         popupnotification.removeAttribute("buttonaccesskey");
         popupnotification.removeAttribute("buttoncommand");
         popupnotification.removeAttribute("buttonpopupshown");
         popupnotification.removeAttribute("learnmoreclick");
         popupnotification.removeAttribute("menucommand");
         popupnotification.removeAttribute("closeitemcommand");
       }
 
+      if (n.options.popupIconClass) {
+        let classes = "popup-notification-icon " + n.options.popupIconClass;
+        popupnotification.setAttribute("iconclass", classes);
+      }
       if (n.options.popupIconURL)
         popupnotification.setAttribute("icon", n.options.popupIconURL);
 
       if (n.options.learnMoreURL)
         popupnotification.setAttribute("learnmoreurl", n.options.learnMoreURL);
       else
         popupnotification.removeAttribute("learnmoreurl");