Bug 1291642 - Part 3 - Update permission notifications to use checkbox in PopupNotifications. r?paolo
MozReview-Commit-ID: HptoY3dSHOj
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2489,180 +2489,161 @@ ContentPermissionPrompt.prototype = {
* @param aActions An array of actions of the form:
* [main action, secondary actions, ...]
* Actions are of the form { stringId, action, expireType, callback }
* Permission is granted if action is null or ALLOW_ACTION.
* @param aNotificationId The id of the PopupNotification.
* @param aAnchorId The id for the PopupNotification anchor.
* @param aOptions Options for the PopupNotification
*/
- _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aActions,
+ _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aAllowAction, aDenyAction,
aNotificationId, aAnchorId, aOptions) {
var browser = this._getBrowserForRequest(aRequest);
var chromeWin = browser.ownerGlobal;
var requestPrincipal = aRequest.principal;
- // Transform the prompt actions into PopupNotification actions.
- var popupNotificationActions = [];
- for (var i = 0; i < aActions.length; i++) {
- let promptAction = aActions[i];
-
- // Don't offer action in PB mode if the action remembers permission for more than a session.
- if (PrivateBrowsingUtils.isWindowPrivate(chromeWin) &&
- promptAction.expireType != Ci.nsIPermissionManager.EXPIRE_SESSION &&
- promptAction.action) {
- continue;
- }
-
- var action = {
- label: gBrowserBundle.GetStringFromName(promptAction.stringId),
- accessKey: gBrowserBundle.GetStringFromName(promptAction.stringId + ".accesskey"),
- callback: function() {
- if (promptAction.callback) {
- promptAction.callback();
- }
-
- // Remember permissions.
- if (promptAction.action) {
- Services.perms.addFromPrincipal(requestPrincipal, aPermission,
- promptAction.action, promptAction.expireType);
- }
-
- // Grant permission if action is null or ALLOW_ACTION.
- if (!promptAction.action || promptAction.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
- aRequest.allow();
- } else {
- aRequest.cancel();
- }
- },
- };
-
- popupNotificationActions.push(action);
- }
-
- var mainAction = popupNotificationActions.length ?
- popupNotificationActions[0] : null;
- var secondaryActions = popupNotificationActions.splice(1);
+ let mainAction = {
+ label: gBrowserBundle.GetStringFromName(aAllowAction.stringId),
+ accessKey: gBrowserBundle.GetStringFromName(aAllowAction.stringId + ".accesskey"),
+ callback: function(remember) {
+ if (aAllowAction.callback) {
+ aAllowAction.callback();
+ }
+
+ // Remember permissions.
+ if (remember) {
+ Services.perms.addFromPrincipal(requestPrincipal, aPermission,
+ Ci.nsIPermissionManager.ALLOW_ACTION, aAllowAction.expireType);
+ }
+
+ aRequest.allow();
+ },
+ };
+
+ let secondaryAction = {
+ label: gBrowserBundle.GetStringFromName(aDenyAction.stringId),
+ accessKey: gBrowserBundle.GetStringFromName(aDenyAction.stringId + ".accesskey"),
+ callback: function(remember) {
+ if (aDenyAction.callback) {
+ aDenyAction.callback();
+ }
+
+ // Remember permissions.
+ if (remember) {
+ Services.perms.addFromPrincipal(requestPrincipal, aPermission,
+ Ci.nsIPermissionManager.DENY_ACTION, aDenyAction.expireType);
+ }
+
+ aRequest.cancel();
+ },
+ };
// Only allow exactly one permission request here.
let types = aRequest.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
aRequest.cancel();
return undefined;
}
if (!aOptions)
aOptions = {};
aOptions.displayURI = requestPrincipal.URI;
aOptions.persistent = true;
return chromeWin.PopupNotifications.show(browser, aNotificationId, aMessage, aAnchorId,
- mainAction, secondaryActions, aOptions);
+ mainAction, [secondaryAction], aOptions);
},
_promptGeo : function(aRequest) {
var secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
-
- var message;
-
- // Share location action.
- var actions = [{
- stringId: "geolocation.shareLocation",
- action: null,
- expireType: null,
- callback: function() {
- secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION);
+ let browser = this._getBrowserForRequest(aRequest);
+ let chromeWin = browser.ownerGlobal;
+
+ let allowAction = {
+ stringId: "geolocation.allow",
+ callback: function(remember) {
+ if (remember) {
+ secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_ALWAYS_SHARE);
+ } else {
+ secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION);
+ }
},
- }];
+ };
+
+ let denyAction = {
+ stringId: "geolocation.dontAllow",
+ callback: function(remember) {
+ if (remember) {
+ secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_NEVER_SHARE);
+ }
+ },
+ };
let options = {
learnMoreURL: Services.urlFormatter.formatURLPref("browser.geolocation.warning.infoURL"),
};
+ let message;
+
if (aRequest.principal.URI.schemeIs("file")) {
message = gBrowserBundle.GetStringFromName("geolocation.shareWithFile2");
+ options.checkbox = { show: false };
} else {
message = gBrowserBundle.GetStringFromName("geolocation.shareWithSite2");
- // Always share location action.
- actions.push({
- stringId: "geolocation.alwaysShareLocation",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expireType: null,
- callback: function() {
- secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_ALWAYS_SHARE);
- },
- });
-
- // Never share location action.
- actions.push({
- stringId: "geolocation.neverShareLocation",
- action: Ci.nsIPermissionManager.DENY_ACTION,
- expireType: null,
- callback: function() {
- secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_NEVER_SHARE);
- },
- });
+
+ // Don't offer "always remember" action in PB mode
+ options.checkbox = {
+ show: !PrivateBrowsingUtils.isWindowPrivate(chromeWin)
+ };
}
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
- this._showPrompt(aRequest, message, "geo", actions, "geolocation",
+ this._showPrompt(aRequest, message, "geo", allowAction, denyAction, "geolocation",
"geo-notification-icon", options);
},
_promptWebNotifications : function(aRequest) {
+ let browser = this._getBrowserForRequest(aRequest);
+ let chromeWin = browser.ownerGlobal;
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
- var actions;
-
- var browser = this._getBrowserForRequest(aRequest);
- // Only show "allow for session" in PB mode, we don't
- // support "allow for session" in non-PB mode.
- if (PrivateBrowsingUtils.isBrowserPrivate(browser)) {
- actions = [
- {
- stringId: "webNotifications.receiveForSession",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
- callback: function() {},
- }
- ];
- } else {
- actions = [
- {
- stringId: "webNotifications.alwaysReceive",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expireType: null,
- callback: function() {},
- },
- {
- stringId: "webNotifications.neverShow",
- action: Ci.nsIPermissionManager.DENY_ACTION,
- expireType: null,
- callback: function() {},
- },
- ];
- }
-
- var options = {
+ let allowAction = { stringId: "webNotifications.allow" };
+
+ let denyAction = { stringId: "webNotifications.dontAllow" };
+
+ let options = {
+ checkbox: {
+ show: true,
+ checked: true
+ },
learnMoreURL:
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push",
eventCallback(type) {
if (type == "dismissed") {
// Bug 1259148: Hide the doorhanger icon. Unlike other permission
// doorhangers, the user can't restore the doorhanger using the icon
// in the location bar. Instead, the site will be notified that the
// doorhanger was dismissed.
this.remove();
aRequest.cancel();
}
},
};
- this._showPrompt(aRequest, message, "desktop-notification", actions,
+ // In PB mode, the "always remember" checkbox should only remember for the session
+ if (PrivateBrowsingUtils.isWindowPrivate(chromeWin)) {
+ allowAction.expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
+ denyAction.expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
+
+ options.checkbox.label =
+ gBrowserBundle.GetStringFromName("webNotifications.rememberForSession");
+ }
+
+ this._showPrompt(aRequest, message, "desktop-notification", allowAction, denyAction,
"web-notifications",
"web-notifications-notification-icon", options);
},
prompt: function CPP_prompt(request) {
// Only allow exactly one permission request here.
let types = request.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -366,31 +366,28 @@ pu.notifyButton.accesskey=D
puNotifyText=%S has been updated
puAlertTitle=%S Updated
puAlertText=Click here for details
# Geolocation UI
# LOCALIZATION NOTE (geolocation.shareLocation geolocation.alwaysShareLocation geolocation.neverShareLocation):
# If you're having trouble with the word Share, please use Allow and Block in your language.
-geolocation.shareLocation=Share Location
-geolocation.shareLocation.accesskey=a
-geolocation.alwaysShareLocation=Always Share Location
-geolocation.alwaysShareLocation.accesskey=A
-geolocation.neverShareLocation=Never Share Location
-geolocation.neverShareLocation.accesskey=N
+geolocation.allow=Allow location access
+geolocation.allow.accesskey=A
+geolocation.dontAllow=Don’t allow
+geolocation.dontAllow.accesskey=n
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
-webNotifications.receiveForSession=Receive for this session
-webNotifications.receiveForSession.accesskey=s
-webNotifications.alwaysReceive=Always Receive Notifications
-webNotifications.alwaysReceive.accesskey=A
-webNotifications.neverShow=Always Block Notifications
-webNotifications.neverShow.accesskey=N
+webNotifications.rememberForSession=Remember decision for this session
+webNotifications.allow=Allow notifications
+webNotifications.allow.accesskey=A
+webNotifications.dontAllow=Don’t allow
+webNotifications.dontAllow.accesskey=n
webNotifications.receiveFromSite=Would you like to receive notifications from this site?
# LOCALIZATION NOTE (webNotifications.upgradeTitle): When using native notifications on OS X, the title may be truncated around 32 characters.
webNotifications.upgradeTitle=Upgraded notifications
# LOCALIZATION NOTE (webNotifications.upgradeBody): When using native notifications on OS X, the body may be truncated around 100 characters in some views.
webNotifications.upgradeBody=You can now receive notifications from sites that are not currently loaded. Click to learn more.
# Phishing/Malware Notification Bar.
# LOCALIZATION NOTE (notADeceptiveSite, notAnAttack)
@@ -518,16 +515,20 @@ getUserMedia.shareApplication.label = Sh
getUserMedia.shareWindow.label = Share Selected Window
getUserMedia.shareSelectedItems.label = Share Selected Items
getUserMedia.always.label = Always Share
getUserMedia.always.accesskey = A
getUserMedia.denyRequest.label = Don’t Share
getUserMedia.denyRequest.accesskey = D
getUserMedia.never.label = Never Share
getUserMedia.never.accesskey = N
+# LOCALIZATION NOTE (getUserMedia.dontAllowHTTP, getUserMedia.dontAllowHTTPAudio, getUserMedia.dontAllowHTTPVideo) - %S is brandShortName
+getUserMedia.dontAllowHTTP=Your connection to this site is not secure. %S can not allow permanent access to your devices.
+getUserMedia.dontAllowHTTPAudio=Your connection to this site is not secure. %S can not allow permanent access to your microphone.
+getUserMedia.dontAllowHTTPVideo=Your connection to this site is not secure. %S can not allow permanent access to your camera.
getUserMedia.sharingMenu.label = Tabs sharing devices
getUserMedia.sharingMenu.accesskey = d
# LOCALIZATION NOTE (getUserMedia.sharingMenuCamera
# getUserMedia.sharingMenuMicrophone,
# getUserMedia.sharingMenuAudioCapture,
# getUserMedia.sharingMenuApplication,
# getUserMedia.sharingMenuScreen,
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -13,16 +13,20 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
+XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
+ return Services.strings.createBundle('chrome://branding/locale/brand.properties');
+});
+
this.webrtcUI = {
init: function () {
Services.obs.addObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished", false);
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
ppmm.addMessageListener("webrtc:UpdatingIndicators", this);
ppmm.addMessageListener("webrtc:UpdateGlobalIndicators", this);
@@ -312,53 +316,46 @@ function prompt(aBrowser, aRequest) {
// reject the action.
callback: function() {}
};
let secondaryActions = [
{
label: stringBundle.getString("getUserMedia.denyRequest.label"),
accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
- callback: function () {
+ callback: function (aRemember) {
denyRequest(notification.browser, aRequest);
+ if (aRemember) {
+ let perms = Services.perms;
+ if (audioDevices.length)
+ perms.add(uri, "microphone", perms.DENY_ACTION);
+ if (videoDevices.length)
+ perms.add(uri, "camera", perms.DENY_ACTION);
+ }
}
}
];
- // Bug 1037438: implement 'never' for screen sharing.
- if (!sharingScreen && !sharingAudio) {
- secondaryActions.push({
- label: stringBundle.getString("getUserMedia.never.label"),
- accessKey: stringBundle.getString("getUserMedia.never.accesskey"),
- callback: function () {
- denyRequest(notification.browser, aRequest);
- // Let someone save "Never" for http sites so that they can be stopped from
- // bothering you with doorhangers.
- let perms = Services.perms;
- if (audioDevices.length)
- perms.add(uri, "microphone", perms.DENY_ACTION);
- if (videoDevices.length)
- perms.add(uri, "camera", perms.DENY_ACTION);
- }
- });
- }
- if (aRequest.secure && !sharingScreen && !sharingAudio) {
- // Don't show the 'Always' action if the connection isn't secure, or for
- // screen/audio sharing (because we can't guess which window the user wants
- // to share without prompting).
- secondaryActions.unshift({
- label: stringBundle.getString("getUserMedia.always.label"),
- accessKey: stringBundle.getString("getUserMedia.always.accesskey"),
- callback: function () {
- mainAction.callback(true);
- }
- });
+ let productName = gBrandBundle.GetStringFromName("brandShortName");
+ let disabledInfo = stringBundle.getFormattedString("getUserMedia.dontAllowHTTP", [productName]);
+ if (audioDevices.length && !videoDevices.length) {
+ disabledInfo = stringBundle.getFormattedString("getUserMedia.dontAllowHTTPAudio", [productName]);
+ } else if (!audioDevices.length && videoDevices.length) {
+ disabledInfo = stringBundle.getFormattedString("getUserMedia.dontAllowHTTPVideo", [productName]);
}
let options = {
+ // Don't show the 'Always Remember' checkbox if the connection isn't secure, or for
+ // screen/audio sharing (because we can't guess which window the user wants
+ // to share without prompting).
+ checkbox: {
+ show: !sharingScreen && !sharingAudio,
+ disableMainAction: !aRequest.secure,
+ disabledInfo: disabledInfo
+ },
persistent: true,
eventCallback: function(aTopic, aNewBrowser) {
if (aTopic == "swapping")
return true;
let chromeDoc = this.browser.ownerDocument;
if (aTopic == "shown") {