summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/palemoon/app/profile/palemoon.js1
-rw-r--r--application/palemoon/base/content/browser-fullScreen.js3
-rw-r--r--application/palemoon/base/content/browser-plugins.js20
-rw-r--r--application/palemoon/base/content/browser.js10
-rw-r--r--application/palemoon/base/content/pageinfo/pageInfo.js3
-rw-r--r--application/palemoon/base/content/pageinfo/permissions.js4
-rw-r--r--application/palemoon/base/content/urlbarBindings.xml20
-rw-r--r--application/palemoon/components/nsBrowserGlue.js160
-rw-r--r--application/palemoon/components/preferences/aboutPermissions.js151
-rw-r--r--application/palemoon/components/preferences/aboutPermissions.xul5
-rw-r--r--application/palemoon/components/preferences/advanced.js49
-rw-r--r--application/palemoon/components/preferences/cookies.js7
-rw-r--r--application/palemoon/components/preferences/handlers.xml2
-rw-r--r--application/palemoon/components/preferences/jar.mn6
-rw-r--r--application/palemoon/components/preferences/permissions.js308
-rw-r--r--application/palemoon/components/preferences/permissions.xul36
-rw-r--r--application/palemoon/components/preferences/security.js16
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/browser.properties4
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/preferences/aboutPermissions.dtd2
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/preferences/permissions.dtd8
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties2
-rw-r--r--application/palemoon/modules/PopupNotifications.jsm66
-rw-r--r--application/palemoon/modules/webrtcUI.jsm130
-rw-r--r--application/palemoon/themes/linux/Push-16.pngbin0 -> 606 bytes
-rw-r--r--application/palemoon/themes/linux/Push-64.pngbin0 -> 8056 bytes
-rw-r--r--application/palemoon/themes/linux/browser.css21
-rw-r--r--application/palemoon/themes/linux/jar.mn4
-rw-r--r--application/palemoon/themes/linux/notification-16.pngbin610 -> 0 bytes
-rw-r--r--application/palemoon/themes/linux/notification-64.pngbin3373 -> 0 bytes
-rw-r--r--application/palemoon/themes/linux/preferences/aboutPermissions.css2
-rw-r--r--application/palemoon/themes/linux/web-notifications-icon.svg15
-rw-r--r--application/palemoon/themes/linux/web-notifications-tray.svg23
-rw-r--r--application/palemoon/themes/osx/Push-16.pngbin0 -> 312 bytes
-rw-r--r--application/palemoon/themes/osx/Push-64.pngbin0 -> 8490 bytes
-rw-r--r--application/palemoon/themes/osx/browser.css17
-rw-r--r--application/palemoon/themes/osx/jar.mn4
-rw-r--r--application/palemoon/themes/osx/notification-16.pngbin610 -> 0 bytes
-rw-r--r--application/palemoon/themes/osx/notification-64.pngbin3373 -> 0 bytes
-rw-r--r--application/palemoon/themes/osx/preferences/aboutPermissions.css2
-rw-r--r--application/palemoon/themes/osx/web-notifications-icon.svg15
-rw-r--r--application/palemoon/themes/osx/web-notifications-tray.svg23
-rw-r--r--application/palemoon/themes/windows/Push-16.pngbin0 -> 704 bytes
-rw-r--r--application/palemoon/themes/windows/Push-64.pngbin0 -> 8388 bytes
-rw-r--r--application/palemoon/themes/windows/browser.css13
-rw-r--r--application/palemoon/themes/windows/jar.mn4
-rw-r--r--application/palemoon/themes/windows/notification-16.pngbin610 -> 0 bytes
-rw-r--r--application/palemoon/themes/windows/notification-64.pngbin3373 -> 0 bytes
-rw-r--r--application/palemoon/themes/windows/preferences/aboutPermissions.css2
-rw-r--r--application/palemoon/themes/windows/web-notifications-icon.svg15
-rw-r--r--application/palemoon/themes/windows/web-notifications-tray.svg23
-rw-r--r--security/nss/lib/softoken/sftkpwd.c4
-rw-r--r--toolkit/themes/linux/global/inContentUI.css41
-rw-r--r--toolkit/themes/linux/global/jar.mn1
-rw-r--r--toolkit/themes/osx/global/inContentUI.css144
-rw-r--r--toolkit/themes/osx/global/jar.mn1
-rw-r--r--toolkit/themes/windows/global/inContentUI.css159
-rw-r--r--toolkit/themes/windows/global/jar.mn1
57 files changed, 1170 insertions, 377 deletions
diff --git a/application/palemoon/app/profile/palemoon.js b/application/palemoon/app/profile/palemoon.js
index ee4a95d38..20919eca4 100644
--- a/application/palemoon/app/profile/palemoon.js
+++ b/application/palemoon/app/profile/palemoon.js
@@ -756,6 +756,7 @@ pref("goanna.handlerService.allowRegisterFromDifferentHost", false);
pref("browser.geolocation.warning.infoURL", "http://www.palemoon.org/info-url/geolocation.shtml");
pref("browser.mixedcontent.warning.infoURL", "http://www.palemoon.org/info-url/mixedcontent.shtml");
+pref("browser.push.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/push/");
pref("browser.EULA.version", 3);
pref("browser.rights.version", 3);
diff --git a/application/palemoon/base/content/browser-fullScreen.js b/application/palemoon/base/content/browser-fullScreen.js
index 400340e77..73b10ae85 100644
--- a/application/palemoon/base/content/browser-fullScreen.js
+++ b/application/palemoon/base/content/browser-fullScreen.js
@@ -354,11 +354,10 @@ var FullScreen = {
"fullscreen",
Services.perms.ALLOW_ACTION,
Services.perms.EXPIRE_SESSION);
- let host = uri.host;
var onFullscreenchange = function onFullscreenchange(event) {
if (event.target == document && document.mozFullScreenElement == null) {
// The chrome document has left fullscreen. Remove the temporary permission grant.
- Services.perms.remove(host, "fullscreen");
+ Services.perms.remove(uri, "fullscreen");
document.removeEventListener("mozfullscreenchange", onFullscreenchange);
}
}
diff --git a/application/palemoon/base/content/browser-plugins.js b/application/palemoon/base/content/browser-plugins.js
index 769ac6d8a..838268203 100644
--- a/application/palemoon/base/content/browser-plugins.js
+++ b/application/palemoon/base/content/browser-plugins.js
@@ -470,28 +470,12 @@ var gPluginHandler = {
}
},
- // Match the behaviour of nsPermissionManager
- _getHostFromPrincipal: function PH_getHostFromPrincipal(principal) {
- if (!principal.URI || principal.URI.schemeIs("moz-nullprincipal")) {
- return "(null)";
- }
-
- try {
- if (principal.URI.host)
- return principal.URI.host;
- } catch (e) {}
-
- return principal.origin;
- },
-
_makeCenterActions: function PH_makeCenterActions(notification) {
let contentWindow = notification.browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let principal = contentWindow.document.nodePrincipal;
- // This matches the behavior of nsPermssionManager, used for display purposes only
- let principalHost = this._getHostFromPrincipal(principal);
let centerActions = [];
let pluginsFound = new Set();
@@ -517,11 +501,11 @@ var gPluginHandler = {
let permissionObj = Services.perms.
getPermissionObject(principal, pluginInfo.permissionString, false);
if (permissionObj) {
- pluginInfo.pluginPermissionHost = permissionObj.host;
+ pluginInfo.pluginPermissionPrePath = permissionObj.principal.originNoSuffix;
pluginInfo.pluginPermissionType = permissionObj.expireType;
}
else {
- pluginInfo.pluginPermissionHost = principalHost;
+ pluginInfo.pluginPermissionPrePath = principal.originNoSuffix;
pluginInfo.pluginPermissionType = undefined;
}
diff --git a/application/palemoon/base/content/browser.js b/application/palemoon/base/content/browser.js
index c9f0aa4aa..556e7a2b7 100644
--- a/application/palemoon/base/content/browser.js
+++ b/application/palemoon/base/content/browser.js
@@ -83,14 +83,8 @@ this.__defineSetter__("AddonManager", function (val) {
return this.AddonManager = val;
});
-this.__defineGetter__("PluralForm", function() {
- Cu.import("resource://gre/modules/PluralForm.jsm");
- return this.PluralForm;
-});
-this.__defineSetter__("PluralForm", function (val) {
- delete this.PluralForm;
- return this.PluralForm = val;
-});
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+ "resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
"resource:///modules/AboutHomeUtils.jsm");
diff --git a/application/palemoon/base/content/pageinfo/pageInfo.js b/application/palemoon/base/content/pageinfo/pageInfo.js
index 83f0ddb91..6b02bc370 100644
--- a/application/palemoon/base/content/pageinfo/pageInfo.js
+++ b/application/palemoon/base/content/pageinfo/pageInfo.js
@@ -1112,8 +1112,9 @@ var imagePermissionObserver = {
var row = getSelectedRow(imageTree);
var item = gImageView.data[row][COL_IMAGE_NODE];
var url = gImageView.data[row][COL_IMAGE_ADDRESS];
- if (makeURI(url).host == permission.host)
+ if (permission.matchesURI(makeURI(url), true)) {
makeBlockImage(url);
+ }
}
}
}
diff --git a/application/palemoon/base/content/pageinfo/permissions.js b/application/palemoon/base/content/pageinfo/permissions.js
index 2fa0cc303..68261ce6e 100644
--- a/application/palemoon/base/content/pageinfo/permissions.js
+++ b/application/palemoon/base/content/pageinfo/permissions.js
@@ -98,7 +98,7 @@ var permissionObserver = {
if (aTopic == "perm-changed") {
var permission = aSubject.QueryInterface(
Components.interfaces.nsIPermission);
- if (permission.host == gPermURI.host) {
+ if (permission.matchesURI(gPermURI, true)) {
if (permission.type in gPermObj)
initRow(permission.type);
else if (permission.type.startsWith("plugin"))
@@ -119,7 +119,7 @@ function onLoadPermission(principal)
gPermURI = uri;
gPermPrincipal = principal;
var hostText = document.getElementById("hostText");
- hostText.value = gPermURI.host;
+ hostText.value = gPermURI.prePath;
for (var i in gPermObj)
initRow(i);
diff --git a/application/palemoon/base/content/urlbarBindings.xml b/application/palemoon/base/content/urlbarBindings.xml
index bf59ea164..4a6cfeee5 100644
--- a/application/palemoon/base/content/urlbarBindings.xml
+++ b/application/palemoon/base/content/urlbarBindings.xml
@@ -1356,8 +1356,8 @@
return;
}
- let host = gPluginHandler._getHostFromPrincipal(this.notification.browser.contentWindow.document.nodePrincipal);
- this._setupDescription("pluginActivateMultiple.message", null, host);
+ let prePath = this.notification.browser.contentWindow.document.nodePrincipal.URI.prePath;
+ this._setupDescription("pluginActivateMultiple.message", null, prePath);
var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox");
@@ -1396,7 +1396,7 @@
<method name="_setupSingleState">
<body><![CDATA[
var action = this.notification.options.centerActions[0];
- var host = action.pluginPermissionHost;
+ var prePath = action.pluginPermissionPrePath;
let label, linkLabel, linkUrl, button1, button2;
@@ -1491,7 +1491,7 @@
Cu.reportError(Error("Unexpected blocklist state"));
}
}
- this._setupDescription(label, action.pluginName, host);
+ this._setupDescription(label, action.pluginName, prePath);
this._setupLink(linkLabel, action.detailsLink);
this._primaryButton.label = gNavigatorBundle.getString(button1.label);
@@ -1512,7 +1512,7 @@
<method name="_setupDescription">
<parameter name="baseString" />
<parameter name="pluginName" /> <!-- null for the multiple-plugin case -->
- <parameter name="host" />
+ <parameter name="prePath" />
<body><![CDATA[
var bsn = this._brandShortName;
var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
@@ -1520,17 +1520,17 @@
span.removeChild(span.lastChild);
}
- var args = ["__host__", this._brandShortName];
+ var args = ["__prepath__", this._brandShortName];
if (pluginName) {
args.unshift(pluginName);
}
var bases = gNavigatorBundle.getFormattedString(baseString, args).
- split("__host__", 2);
+ split("__prepath__", 2);
span.appendChild(document.createTextNode(bases[0]));
- var hostSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em");
- hostSpan.appendChild(document.createTextNode(host));
- span.appendChild(hostSpan);
+ var prePathSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em");
+ prePathSpan.appendChild(document.createTextNode(prePath));
+ span.appendChild(prePathSpan);
span.appendChild(document.createTextNode(bases[1] + " "));
]]></body>
</method>
diff --git a/application/palemoon/components/nsBrowserGlue.js b/application/palemoon/components/nsBrowserGlue.js
index 225cddd52..6563df4e6 100644
--- a/application/palemoon/components/nsBrowserGlue.js
+++ b/application/palemoon/components/nsBrowserGlue.js
@@ -39,6 +39,9 @@ Cu.import("resource://gre/modules/Services.jsm");
["DateTimePickerHelper", "resource://gre/modules/DateTimePickerHelper.jsm"],
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
+XPCOMUtils.defineLazyServiceGetter(this, "AlertsService",
+ "@mozilla.org/alerts-service;1", "nsIAlertsService");
+
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
@@ -825,16 +828,6 @@ BrowserGlue.prototype = {
if (actions.indexOf("showAlert") == -1)
return;
- let notifier;
- try {
- notifier = Cc["@mozilla.org/alerts-service;1"].
- getService(Ci.nsIAlertsService);
- }
- catch (e) {
- // nsIAlertsService is not available for this platform
- return;
- }
-
let title = getNotifyString({propName: "alertTitle",
stringName: "puAlertTitle",
stringParams: [appName]});
@@ -856,10 +849,11 @@ BrowserGlue.prototype = {
try {
// This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot
// be displayed per the idl.
- notifier.showAlertNotification(null, title, text,
- true, url, clickCallback);
+ AlertsService.showAlertNotification(null, title, text,
+ true, url, clickCallback);
}
catch (e) {
+ Cu.reportError(e);
}
},
@@ -1191,7 +1185,7 @@ BrowserGlue.prototype = {
},
_migrateUI: function BG__migrateUI() {
- const UI_VERSION = 15;
+ const UI_VERSION = 17;
const BROWSER_DOCURL = "chrome://browser/content/browser.xul#";
let currentUIVersion = 0;
try {
@@ -1386,6 +1380,10 @@ BrowserGlue.prototype = {
}
}
+ if (currentUIVersion < 17) {
+ this._notifyNotificationsUpgrade();
+ }
+
if (this._dirty)
this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
@@ -1396,6 +1394,52 @@ BrowserGlue.prototype = {
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
},
+ _hasExistingNotificationPermission: function BG__hasExistingNotificationPermission() {
+ let enumerator = Services.perms.enumerator;
+ while (enumerator.hasMoreElements()) {
+ let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
+ if (permission.type == "desktop-notification") {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _notifyNotificationsUpgrade: function BG__notifyNotificationsUpgrade() {
+ if (!this._hasExistingNotificationPermission()) {
+ return;
+ }
+ function clickCallback(subject, topic, data) {
+ if (topic != "alertclickcallback")
+ return;
+ let win = RecentWindow.getMostRecentBrowserWindow();
+ win.openUILinkIn(data, "tab");
+ }
+ // Show the application icon for XUL notifications. We assume system-level
+ // notifications will include their own icon.
+ let imageURL = this._hasSystemAlertsService() ? "" :
+ "chrome://branding/content/about-logo.png";
+ let title = gBrowserBundle.GetStringFromName("webNotifications.upgradeTitle");
+ let text = gBrowserBundle.GetStringFromName("webNotifications.upgradeBody");
+ let url = Services.urlFormatter.formatURLPref("browser.push.warning.infoURL");
+
+ try {
+ AlertsService.showAlertNotification(imageURL, title, text,
+ true, url, clickCallback);
+ }
+ catch (e) {
+ Cu.reportError(e);
+ }
+ },
+
+ _hasSystemAlertsService: function() {
+ try {
+ return !!Cc["@mozilla.org/system-alerts-service;1"].getService(
+ Ci.nsIAlertsService);
+ } catch (e) {}
+ return false;
+ },
+
_getPersist: function BG__getPersist(aSource, aProperty) {
var target = this._dataSource.GetTarget(aSource, aProperty, true);
if (target instanceof Ci.nsIRDFLiteral)
@@ -1645,6 +1689,16 @@ ContentPermissionPrompt.prototype = {
return chromeWin;
},
+ _getBrowserForRequest: function (aRequest) {
+ let requestingWindow = aRequest.window.top;
+ // find the requesting browser or iframe
+ let browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .chromeEventHandler;
+ return browser;
+ },
+
/**
* Show a permission prompt.
*
@@ -1809,30 +1863,49 @@ ContentPermissionPrompt.prototype = {
var message = browserBundle.formatStringFromName("webNotifications.showFromSite",
[requestingURI.host], 1);
- var actions = [
- {
- stringId: "webNotifications.showForSession",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
- callback: function() {},
- },
- {
- stringId: "webNotifications.alwaysShow",
- action: Ci.nsIPermissionManager.ALLOW_ACTION,
- expireType: null,
- callback: function() {},
- },
- {
- stringId: "webNotifications.neverShow",
- action: Ci.nsIPermissionManager.DENY_ACTION,
- expireType: null,
- callback: function() {},
- },
- ];
+ 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.showForSession",
+ action: Ci.nsIPermissionManager.ALLOW_ACTION,
+ expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
+ callback: function() {},
+ },
+ ];
+ } else {
+ actions = [
+ {
+ stringId: "webNotifications.showForSession",
+ action: Ci.nsIPermissionManager.ALLOW_ACTION,
+ expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
+ callback: function() {},
+ },
+ {
+ stringId: "webNotifications.alwaysShow",
+ action: Ci.nsIPermissionManager.ALLOW_ACTION,
+ expireType: null,
+ callback: function() {},
+ },
+ {
+ stringId: "webNotifications.neverShow",
+ action: Ci.nsIPermissionManager.DENY_ACTION,
+ expireType: null,
+ callback: function() {},
+ },
+ ];
+ }
+ var options = {
+ learnMoreURL: Services.urlFormatter.formatURLPref("browser.push.warning.infoURL"),
+ };
this._showPrompt(aRequest, message, "desktop-notification", actions,
"web-notifications",
- "web-notifications-notification-icon", null);
+ "web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
@@ -1875,7 +1948,6 @@ ContentPermissionPrompt.prototype = {
},
prompt: function CPP_prompt(request) {
-
// Only allow exactly one permission rquest here.
let types = request.types.QueryInterface(Ci.nsIArray);
if (types.length != 1) {
@@ -1921,15 +1993,15 @@ ContentPermissionPrompt.prototype = {
// Show the prompt.
switch (perm.type) {
- case "geolocation":
- this._promptGeo(request);
- break;
- case "desktop-notification":
- this._promptWebNotifications(request);
- break;
- case "pointerLock":
- this._promptPointerLock(request, autoAllow);
- break;
+ case "geolocation":
+ this._promptGeo(request);
+ break;
+ case "desktop-notification":
+ this._promptWebNotifications(request);
+ break;
+ case "pointerLock":
+ this._promptPointerLock(request, autoAllow);
+ break;
}
},
diff --git a/application/palemoon/components/preferences/aboutPermissions.js b/application/palemoon/components/preferences/aboutPermissions.js
index 31b48f88e..531bb061f 100644
--- a/application/palemoon/components/preferences/aboutPermissions.js
+++ b/application/palemoon/components/preferences/aboutPermissions.js
@@ -2,17 +2,25 @@
* 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/. */
+"use strict";
+
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cu = Components.utils;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PluralForm.jsm");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+ "resource://gre/modules/PluralForm.jsm");
+
+var gSecMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+
var gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
@@ -22,7 +30,7 @@ var gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"].
clone(true);
var gSitesStmt = gPlacesDatabase.createAsyncStatement(
- "SELECT get_unreversed_host(rev_host) AS host " +
+ "SELECT url " +
"FROM moz_places " +
"WHERE rev_host > '.' " +
"AND visit_count > 0 " +
@@ -54,14 +62,11 @@ const MASTER_PASSWORD_MESSAGE = "User canceled master password entry";
const TEST_EXACT_PERM_TYPES = ["desktop-notification", "geo", "pointerLock"];
/**
- * Site object represents a single site, uniquely identified by a host.
+ * Site object represents a single site, uniquely identified by a principal.
*/
-function Site(host) {
- this.host = host;
+function Site(principal) {
+ this.principal = principal;
this.listitem = null;
-
- this.httpURI = NetUtil.newURI("http://" + this.host);
- this.httpsURI = NetUtil.newURI("https://" + this.host);
}
Site.prototype = {
@@ -83,16 +88,10 @@ Site.prototype = {
}
}
- // Try to find favicon for both URIs, but always prefer the https favicon.
- gFaviconService.getFaviconURLForPage(this.httpsURI, function(aURI) {
+ // Get the favicon for the origin
+ gFaviconService.getFaviconURLForPage(this.principal.URI, function (aURI) {
if (aURI) {
invokeCallback(aURI);
- } else {
- gFaviconService.getFaviconURLForPage(this.httpURI, function(aURI) {
- if (aURI) {
- invokeCallback(aURI);
- }
- });
}
}.bind(this));
},
@@ -104,7 +103,9 @@ Site.prototype = {
* A function that takes the visit count (a number) as a parameter.
*/
getVisitCount: function Site_getVisitCount(aCallback) {
- let rev_host = this.host.split("").reverse().join("") + ".";
+ // XXX This won't be a very reliable system, as it will count both http: and https: visits
+ // Unfortunately, I don't think that there is a much better way to do it right now.
+ let rev_host = this.principal.URI.host.split("").reverse().join("") + ".";
gVisitStmt.params.rev_host = rev_host;
gVisitStmt.executeAsync({
handleResult: function(aResults) {
@@ -147,9 +148,9 @@ Site.prototype = {
let permissionValue;
if (TEST_EXACT_PERM_TYPES.indexOf(aType) == -1) {
- permissionValue = Services.perms.testPermission(this.httpURI, aType);
+ permissionValue = Services.perms.testPermissionFromPrincipal(this.principal, aType);
} else {
- permissionValue = Services.perms.testExactPermission(this.httpURI, aType);
+ permissionValue = Services.perms.testExactPermissionFromPrincipal(this.principal, aType);
}
aResultObj.value = permissionValue;
@@ -187,9 +188,7 @@ Site.prototype = {
}
}
- // Using httpURI is kind of bogus, but the permission manager stores
- // the permission for the host, so the right thing happens in the end.
- Services.perms.add(this.httpURI, aType, aPerm);
+ Services.perms.addFromPrincipal(this.principal, aType, aPerm);
},
/**
@@ -200,7 +199,7 @@ Site.prototype = {
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
*/
clearPermission: function Site_clearPermission(aType) {
- Services.perms.remove(this.host, aType);
+ Services.perms.removeFromPrincipal(this.principal, aType);
},
/**
@@ -210,11 +209,9 @@ Site.prototype = {
*/
get logins() {
try {
- let httpLogins = Services.logins.findLogins(
- {}, this.httpURI.prePath, "", "");
- let httpsLogins = Services.logins.findLogins(
- {}, this.httpsURI.prePath, "", "");
- return httpLogins.concat(httpsLogins);
+ let logins = Services.logins.findLogins({},
+ this.principal.originNoSuffix, "", "");
+ return logins;
} catch (e) {
if (!e.message.includes(MASTER_PASSWORD_MESSAGE)) {
Cu.reportError("AboutPermissions: " + e);
@@ -227,8 +224,7 @@ Site.prototype = {
// Only say that login saving is blocked if it is blocked for both
// http and https.
try {
- return Services.logins.getLoginSavingEnabled(this.httpURI.prePath) &&
- Services.logins.getLoginSavingEnabled(this.httpsURI.prePath);
+ return Services.logins.getLoginSavingEnabled(this.principal.originNoSuffix);
} catch (e) {
if (!e.message.includes(MASTER_PASSWORD_MESSAGE)) {
Cu.reportError("AboutPermissions: " + e);
@@ -239,8 +235,7 @@ Site.prototype = {
set loginSavingEnabled(isEnabled) {
try {
- Services.logins.setLoginSavingEnabled(this.httpURI.prePath, isEnabled);
- Services.logins.setLoginSavingEnabled(this.httpsURI.prePath, isEnabled);
+ Services.logins.setLoginSavingEnabled(this.principal.originNoSuffix, isEnabled);
} catch (e) {
if (!e.message.includes(MASTER_PASSWORD_MESSAGE)) {
Cu.reportError("AboutPermissions: " + e);
@@ -279,7 +274,11 @@ Site.prototype = {
* Removes all data from the browser corresponding to the site.
*/
forgetSite: function Site_forgetSite() {
- ForgetAboutSite.removeDataFromDomain(this.host)
+ // XXX This removes data for an entire domain, rather than just
+ // an origin. This may produce confusing results, as data will
+ // be cleared for the http:// as well as the https:// domain
+ // if you try to forget the https:// site.
+ ForgetAboutSite.removeDataFromDomain(this.principal.URI.host)
.catch(Cu.reportError);
}
}
@@ -461,10 +460,18 @@ var AboutPermissions = {
LIST_BUILD_DELAY: 100, // delay between intervals
/**
- * Stores a mapping of host strings to Site objects.
+ * Stores a mapping of origin strings to Site objects.
*/
_sites: {},
+ /**
+ * Using a getter for sitesFilter to avoid races with tests.
+ */
+ get sitesFilter () {
+ delete this.sitesFilter;
+ return this.sitesFilter = document.getElementById("sites-filter");
+ },
+
sitesList: null,
_selectedSite: null,
@@ -721,9 +728,9 @@ var AboutPermissions = {
break;
}
let permission = aSubject.QueryInterface(Ci.nsIPermission);
- // We can't compare selectedSite.host and permission.host here because
- // we need to handle the case where a parent domain was changed in
- // a way that affects the subdomain.
+ // We can't compare selectedSite.principal and permission.principal here
+ // because we need to handle the case where a parent domain was changed
+ // in a way that affects the subdomain.
if (this._supportedPermissions.indexOf(permission.type) != -1) {
this.updatePermission(permission.type);
}
@@ -798,8 +805,11 @@ var AboutPermissions = {
AboutPermissions.startSitesListBatch();
let row;
while (row = aResults.getNextRow()) {
- let host = row.getResultByName("host");
- AboutPermissions.addHost(host);
+ let spec = row.getResultByName("url");
+ let uri = NetUtil.newURI(spec);
+ let principal = gSecMan.getNoAppCodebasePrincipal(uri);
+
+ AboutPermissions.addPrincipal(principal);
}
AboutPermissions.endSitesListBatch();
},
@@ -853,7 +863,8 @@ var AboutPermissions = {
// i.e.: "chrome://weave" (Sync)
if (!aLogin.hostname.startsWith(schemeChrome + ":")) {
let uri = NetUtil.newURI(aLogin.hostname);
- this.addHost(uri.host);
+ let principal = gSecMan.getNoAppCodebasePrincipal(uri);
+ this.addPrincipal(principal);
}
} catch (e) {
Cu.reportError("AboutPermissions: " + e);
@@ -869,7 +880,8 @@ var AboutPermissions = {
// i.e.: "chrome://weave" (Sync)
if (!aHostname.startsWith(schemeChrome + ":")) {
let uri = NetUtil.newURI(aHostname);
- this.addHost(uri.host);
+ let principal = gSecMan.getNoAppCodebasePrincipal(uri);
+ this.addPrincipal(principal);
}
} catch (e) {
Cu.reportError("AboutPermissions: " + e);
@@ -887,7 +899,7 @@ var AboutPermissions = {
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
// Only include sites with exceptions set for supported permission types.
if (this._supportedPermissions.indexOf(permission.type) != -1) {
- this.addHost(permission.host);
+ this.addPrincipal(permission.principal);
}
itemCnt++;
}
@@ -898,15 +910,15 @@ var AboutPermissions = {
/**
* Creates a new Site and adds it to _sites if it's not already there.
*
- * @param aHost
- * A host string.
+ * @param aPrincipal
+ * A principal.
*/
- addHost: function(aHost) {
- if (aHost in this._sites) {
+ addPrincipal: function(aPrincipal) {
+ if (aPrincipal.origin in this._sites) {
return;
}
- let site = new Site(aHost);
- this._sites[aHost] = site;
+ let site = new Site(aPrincipal);
+ this._sites[aPrincipal.origin] = site;
this.addToSitesList(site);
},
@@ -919,7 +931,7 @@ var AboutPermissions = {
addToSitesList: function(aSite) {
let item = document.createElement("richlistitem");
item.setAttribute("class", "site");
- item.setAttribute("value", aSite.host);
+ item.setAttribute("value", aSite.principal.origin);
aSite.getFavicon(function(aURL) {
item.setAttribute("favicon", aURL);
@@ -927,9 +939,8 @@ var AboutPermissions = {
aSite.listitem = item;
// Make sure to only display relevant items when list is filtered.
- let filterValue =
- document.getElementById("sites-filter").value.toLowerCase();
- item.collapsed = aSite.host.toLowerCase().indexOf(filterValue) == -1;
+ let filterValue = this.sitesFilter.value.toLowerCase();
+ item.collapsed = aSite.principal.origin.toLowerCase().indexOf(filterValue) == -1;
(this._listFragment || this.sitesList).appendChild(item);
},
@@ -951,8 +962,7 @@ var AboutPermissions = {
*/
filterSitesList: function() {
let siteItems = this.sitesList.children;
- let filterValue =
- document.getElementById("sites-filter").value.toLowerCase();
+ let filterValue = this.sitesFilter.value.toLowerCase();
if (filterValue == "") {
for (let i = 0, iLen = siteItems.length; i < iLen; i++) {
@@ -983,9 +993,9 @@ var AboutPermissions = {
* The host string corresponding to the site to delete.
*/
deleteFromSitesList: function(aHost) {
- for (let host in this._sites) {
- let site = this._sites[host];
- if (site.host.hasRootDomain(aHost)) {
+ for (let origin in this._sites) {
+ let site = this._sites[origin];
+ if (site.principal.URI.host.hasRootDomain(aHost)) {
if (site == this._selectedSite) {
// Replace site-specific interface with "All Sites" interface.
this.sitesList.selectedItem =
@@ -993,7 +1003,7 @@ var AboutPermissions = {
}
this.sitesList.removeChild(site.listitem);
- delete this._sites[site.host];
+ delete this._sites[site.principal.origin];
}
}
},
@@ -1009,9 +1019,9 @@ var AboutPermissions = {
return;
}
- let host = event.target.value;
- let site = this._selectedSite = this._sites[host];
- document.getElementById("site-label").value = host;
+ let origin = event.target.value;
+ let site = this._selectedSite = this._sites[origin];
+ document.getElementById("site-label").value = origin;
document.getElementById("header-deck").selectedPanel =
document.getElementById("site-header");
@@ -1245,19 +1255,19 @@ var AboutPermissions = {
* Opens password manager dialog.
*/
managePasswords: function() {
- let selectedHost = "";
+ let selectedOrigin = "";
if (this._selectedSite) {
- selectedHost = this._selectedSite.host;
+ selectedOrigin = this._selectedSite.principal.URI.prePath;
}
let win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
if (win) {
- win.setFilter(selectedHost);
+ win.setFilter(selectedOrigin);
win.focus();
} else {
window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
"Toolkit:PasswordManager", "",
- {filterString : selectedHost});
+ {filterString : selectedOrigin});
}
},
@@ -1313,10 +1323,12 @@ var AboutPermissions = {
* Opens cookie manager dialog.
*/
manageCookies: function() {
+ // Cookies are stored by-host, and thus we filter the cookie window
+ // using only the host of the selected principal's origin
let selectedHost = "";
let selectedDomain = "";
if (this._selectedSite) {
- selectedHost = this._selectedSite.host;
+ selectedHost = this._selectedSite.principal.URI.host;
selectedDomain = this.domainFromHost(selectedHost);
}
@@ -1328,6 +1340,13 @@ var AboutPermissions = {
window.openDialog("chrome://browser/content/preferences/cookies.xul",
"Browser:Cookies", "", {filterString : selectedDomain});
}
+ },
+
+ /**
+ * Focusses the filter box.
+ */
+ focusFilterBox: function() {
+ this.sitesFilter.focus();
}
}
diff --git a/application/palemoon/components/preferences/aboutPermissions.xul b/application/palemoon/components/preferences/aboutPermissions.xul
index bd5a205c7..c099161f2 100644
--- a/application/palemoon/components/preferences/aboutPermissions.xul
+++ b/application/palemoon/components/preferences/aboutPermissions.xul
@@ -25,6 +25,10 @@
<script type="application/javascript"
src="chrome://browser/content/preferences/aboutPermissions.js"/>
+ <keyset>
+ <key key="&focusSearch.key;" modifiers="accel" oncommand="AboutPermissions.focusFilterBox();"/>
+ </keyset>
+
<hbox flex="1" id="permissions-header">
<label id="permissions-pagetitle">&permissionsManager.title;</label>
</hbox>
@@ -390,7 +394,6 @@
</hbox>
</vbox>
</hbox>
-
</vbox>
</hbox>
diff --git a/application/palemoon/components/preferences/advanced.js b/application/palemoon/components/preferences/advanced.js
index 429a0c419..0803496fe 100644
--- a/application/palemoon/components/preferences/advanced.js
+++ b/application/palemoon/components/preferences/advanced.js
@@ -8,6 +8,7 @@ Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
+Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
var gAdvancedPane = {
_inited: false,
@@ -377,7 +378,7 @@ var gAdvancedPane = {
},
// XXX: duplicated in browser.js
- _getOfflineAppUsage: function (host, groups)
+ _getOfflineAppUsage: function (perm, groups)
{
var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
getService(Components.interfaces.nsIApplicationCacheService);
@@ -390,7 +391,7 @@ var gAdvancedPane = {
var usage = 0;
for (var i = 0; i < groups.length; i++) {
var uri = ios.newURI(groups[i], null, null);
- if (uri.asciiHost == host) {
+ if (perm.matchesURI(uri, true)) {
var cache = cacheService.getActiveCache(groups[i]);
usage += cache.usage;
}
@@ -427,9 +428,9 @@ var gAdvancedPane = {
var row = document.createElement("listitem");
row.id = "";
row.className = "offlineapp";
- row.setAttribute("host", perm.host);
+ row.setAttribute("origin", perm.principal.origin);
var converted = DownloadUtils.
- convertByteUnits(this._getOfflineAppUsage(perm.host, groups));
+ convertByteUnits(this._getOfflineAppUsage(perm, groups));
row.setAttribute("usage",
bundle.getFormattedString("offlineAppUsage",
converted));
@@ -453,7 +454,8 @@ var gAdvancedPane = {
{
var list = document.getElementById("offlineAppsList");
var item = list.selectedItem;
- var host = item.getAttribute("host");
+ var origin = item.getAttribute("origin");
+ var principal = BrowserUtils.principalFromOrigin(origin);
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
@@ -462,35 +464,34 @@ var gAdvancedPane = {
var bundle = document.getElementById("bundlePreferences");
var title = bundle.getString("offlineAppRemoveTitle");
- var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [host]);
+ var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [principal.URI.prePath]);
var confirm = bundle.getString("offlineAppRemoveConfirm");
var result = prompts.confirmEx(window, title, prompt, flags, confirm,
null, null, null, {});
if (result != 0)
return;
- // clear offline cache entries
- var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
- getService(Components.interfaces.nsIApplicationCacheService);
- var ios = Components.classes["@mozilla.org/network/io-service;1"].
- getService(Components.interfaces.nsIIOService);
- var groups = cacheService.getGroups();
- for (var i = 0; i < groups.length; i++) {
- var uri = ios.newURI(groups[i], null, null);
- if (uri.asciiHost == host) {
+ // get the permission
+ var pm = Components.classes["@mozilla.org/permissionmanager;1"]
+ .getService(Components.interfaces.nsIPermissionManager);
+ var perm = pm.getPermissionObject(principal, "offline-app");
+ if (perm) {
+ // clear offline cache entries
+ try {
+ var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
+ getService(Components.interfaces.nsIApplicationCacheService);
+ var groups = cacheService.getGroups();
+ for (var i = 0; i < groups.length; i++) {
+ var uri = Services.io.newURI(groups[i], null, null);
+ if (perm.matchesURI(uri, true)) {
var cache = cacheService.getActiveCache(groups[i]);
cache.discard();
+ }
}
- }
-
- // remove the permission
- var pm = Components.classes["@mozilla.org/permissionmanager;1"]
- .getService(Components.interfaces.nsIPermissionManager);
- pm.remove(host, "offline-app",
- Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
- pm.remove(host, "offline-app",
- Components.interfaces.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
+ } catch (e) {}
+ pm.removePermission(perm);
+ }
list.removeChild(item);
gAdvancedPane.offlineAppSelected();
this.updateActualAppCacheSize();
diff --git a/application/palemoon/components/preferences/cookies.js b/application/palemoon/components/preferences/cookies.js
index 543aeb186..4ef30d48e 100644
--- a/application/palemoon/components/preferences/cookies.js
+++ b/application/palemoon/components/preferences/cookies.js
@@ -732,8 +732,13 @@ var gCookiesWindow = {
},
onCookieKeyPress: function (aEvent) {
- if (aEvent.keyCode == 46)
+ if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE
+#ifdef XP_MACOSX
+ || aEvent.keyCode == KeyEvent.DOM_VK_BACK_SPACE
+#endif
+ ) {
this.deleteCookie();
+ }
},
_lastSortProperty : "",
diff --git a/application/palemoon/components/preferences/handlers.xml b/application/palemoon/components/preferences/handlers.xml
index d60792803..5fb915cee 100644
--- a/application/palemoon/components/preferences/handlers.xml
+++ b/application/palemoon/components/preferences/handlers.xml
@@ -72,7 +72,7 @@
extends="chrome://global/content/bindings/listbox.xml#listitem">
<content>
<children>
- <xul:listcell xbl:inherits="label=host"/>
+ <xul:listcell xbl:inherits="label=origin"/>
<xul:listcell xbl:inherits="label=usage"/>
</children>
</content>
diff --git a/application/palemoon/components/preferences/jar.mn b/application/palemoon/components/preferences/jar.mn
index a27784305..798a2dae4 100644
--- a/application/palemoon/components/preferences/jar.mn
+++ b/application/palemoon/components/preferences/jar.mn
@@ -15,7 +15,7 @@ browser.jar:
* content/browser/preferences/applicationManager.js
* content/browser/preferences/colors.xul
* content/browser/preferences/cookies.xul
- content/browser/preferences/cookies.js
+* content/browser/preferences/cookies.js
content/browser/preferences/content.xul
content/browser/preferences/content.js
* content/browser/preferences/connection.xul
@@ -28,8 +28,8 @@ browser.jar:
content/browser/preferences/languages.js
* content/browser/preferences/main.xul
content/browser/preferences/main.js
-* content/browser/preferences/permissions.xul
- content/browser/preferences/permissions.js
+ content/browser/preferences/permissions.xul
+* content/browser/preferences/permissions.js
* content/browser/preferences/preferences.xul
content/browser/preferences/privacy.xul
content/browser/preferences/privacy.js
diff --git a/application/palemoon/components/preferences/permissions.js b/application/palemoon/components/preferences/permissions.js
index 785e26d5e..4b1bf41b2 100644
--- a/application/palemoon/components/preferences/permissions.js
+++ b/application/palemoon/components/preferences/permissions.js
@@ -3,38 +3,40 @@
* 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/. */
+Components.utils.import("resource://gre/modules/Services.jsm");
+
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
const nsICookiePermission = Components.interfaces.nsICookiePermission;
const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions";
-function Permission(host, rawHost, type, capability, perm)
+function Permission(principal, type, capability)
{
- this.host = host;
- this.rawHost = rawHost;
+ this.principal = principal;
+ this.origin = principal.origin;
this.type = type;
this.capability = capability;
- this.perm = perm;
}
var gPermissionManager = {
- _type : "",
- _permissions : [],
- _pm : Components.classes["@mozilla.org/permissionmanager;1"]
- .getService(Components.interfaces.nsIPermissionManager),
- _bundle : null,
- _tree : null,
-
+ _type : "",
+ _permissions : [],
+ _permissionsToAdd : new Map(),
+ _permissionsToDelete : new Map(),
+ _bundle : null,
+ _tree : null,
+ _observerRemoved : false,
+
_view: {
_rowCount: 0,
- get rowCount()
- {
- return this._rowCount;
+ get rowCount()
+ {
+ return this._rowCount;
},
getCellText: function (aRow, aColumn)
{
if (aColumn.id == "siteCol")
- return gPermissionManager._permissions[aRow].rawHost;
+ return gPermissionManager._permissions[aRow].origin;
else if (aColumn.id == "statusCol")
return gPermissionManager._permissions[aRow].capability;
return "";
@@ -57,7 +59,7 @@ var gPermissionManager = {
return "";
}
},
-
+
_getCapabilityString: function (aCapability)
{
var stringKey = null;
@@ -77,44 +79,66 @@ var gPermissionManager = {
}
return this._bundle.getString(stringKey);
},
-
+
addPermission: function (aCapability)
{
var textbox = document.getElementById("url");
- var host = textbox.value.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme
+ var input_url = textbox.value.replace(/^\s*/, ""); // trim any leading space
+ let principal;
try {
- var ioService = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var uri = ioService.newURI("http://"+host, null, null);
- host = uri.host;
+ // The origin accessor on the principal object will throw if the
+ // principal doesn't have a canonical origin representation. This will
+ // help catch cases where the URI parser parsed something like
+ // `localhost:8080` as having the scheme `localhost`, rather than being
+ // an invalid URI. A canonical origin representation is required by the
+ // permission manager for storage, so this won't prevent any valid
+ // permissions from being entered by the user.
+ let uri;
+ try {
+ uri = Services.io.newURI(input_url, null, null);
+ principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
+ // If we have ended up with an unknown scheme, the following will throw.
+ principal.origin;
+ } catch(ex) {
+ uri = Services.io.newURI("http://" + input_url, null, null);
+ principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
+ // If we have ended up with an unknown scheme, the following will throw.
+ principal.origin;
+ }
} catch(ex) {
- var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
var message = this._bundle.getString("invalidURI");
var title = this._bundle.getString("invalidURITitle");
- promptService.alert(window, title, message);
+ Services.prompt.alert(window, title, message);
return;
}
var capabilityString = this._getCapabilityString(aCapability);
// check whether the permission already exists, if not, add it
- var exists = false;
+ let permissionExists = false;
+ let capabilityExists = false;
for (var i = 0; i < this._permissions.length; ++i) {
- if (this._permissions[i].rawHost == host) {
- // Avoid calling the permission manager if the capability settings are
- // the same. Otherwise allow the call to the permissions manager to
- // update the listbox for us.
- exists = this._permissions[i].perm == aCapability;
+ if (this._permissions[i].principal.equals(principal)) {
+ permissionExists = true;
+ capabilityExists = this._permissions[i].capability == capabilityString;
+ if (!capabilityExists) {
+ this._permissions[i].capability = capabilityString;
+ }
break;
}
}
- if (!exists) {
- host = (host.charAt(0) == ".") ? host.substring(1,host.length) : host;
- var uri = ioService.newURI("http://" + host, null, null);
- this._pm.add(uri, this._type, aCapability);
+
+ let permissionParams = {principal: principal, type: this._type, capability: aCapability};
+ if (!permissionExists) {
+ this._permissionsToAdd.set(principal.origin, permissionParams);
+ this._addPermission(permissionParams);
+ }
+ else if (!capabilityExists) {
+ this._permissionsToAdd.set(principal.origin, permissionParams);
+ this._handleCapabilityChange();
}
+
textbox.value = "";
textbox.focus();
@@ -124,14 +148,58 @@ var gPermissionManager = {
// enable "remove all" button as needed
document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
},
-
+
+ _removePermission: function(aPermission)
+ {
+ this._removePermissionFromList(aPermission.principal);
+
+ // If this permission was added during this session, let's remove
+ // it from the pending adds list to prevent calls to the
+ // permission manager.
+ let isNewPermission = this._permissionsToAdd.delete(aPermission.principal.origin);
+
+ if (!isNewPermission) {
+ this._permissionsToDelete.set(aPermission.principal.origin, aPermission);
+ }
+
+ },
+
+ _handleCapabilityChange: function ()
+ {
+ // Re-do the sort, if the status changed from Block to Allow
+ // or vice versa, since if we're sorted on status, we may no
+ // longer be in order.
+ if (this._lastPermissionSortColumn == "statusCol") {
+ this._resortPermissions();
+ }
+ this._tree.treeBoxObject.invalidate();
+ },
+
+ _addPermission: function(aPermission)
+ {
+ this._addPermissionToList(aPermission);
+ ++this._view._rowCount;
+ this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1);
+ // Re-do the sort, since we inserted this new item at the end.
+ this._resortPermissions();
+ },
+
+ _resortPermissions: function()
+ {
+ gTreeUtils.sort(this._tree, this._view, this._permissions,
+ this._lastPermissionSortColumn,
+ this._permissionsComparator,
+ this._lastPermissionSortColumn,
+ !this._lastPermissionSortAscending); // keep sort direction
+ },
+
onHostInput: function (aSiteField)
{
document.getElementById("btnSession").disabled = !aSiteField.value;
document.getElementById("btnBlock").disabled = !aSiteField.value;
document.getElementById("btnAllow").disabled = !aSiteField.value;
},
-
+
onWindowKeyPress: function (aEvent)
{
if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
@@ -143,14 +211,14 @@ var gPermissionManager = {
if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
document.getElementById("btnAllow").click();
},
-
+
onLoad: function ()
{
this._bundle = document.getElementById("bundlePreferences");
var params = window.arguments[0];
this.init(params);
},
-
+
init: function (aParams)
{
if (this._type) {
@@ -160,14 +228,14 @@ var gPermissionManager = {
this._type = aParams.permissionType;
this._manageCapability = aParams.manageCapability;
-
+
var permissionsText = document.getElementById("permissionsText");
while (permissionsText.hasChildNodes())
permissionsText.removeChild(permissionsText.firstChild);
permissionsText.appendChild(document.createTextNode(aParams.introText));
document.title = aParams.windowTitle;
-
+
document.getElementById("btnBlock").hidden = !aParams.blockVisible;
document.getElementById("btnSession").hidden = !aParams.sessionVisible;
document.getElementById("btnAllow").hidden = !aParams.allowVisible;
@@ -183,64 +251,64 @@ var gPermissionManager = {
var urlLabel = document.getElementById("urlLabel");
urlLabel.hidden = !urlFieldVisible;
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.notifyObservers(null, NOTIFICATION_FLUSH_PERMISSIONS, this._type);
- os.addObserver(this, "perm-changed", false);
+ let treecols = document.getElementsByTagName("treecols")[0];
+ treecols.addEventListener("click", event => {
+ if (event.target.nodeName != "treecol" || event.button != 0) {
+ return;
+ }
+
+ let sortField = event.target.getAttribute("data-field-name");
+ if (!sortField) {
+ return;
+ }
+
+ gPermissionManager.onPermissionSort(sortField);
+ });
+
+ Services.obs.notifyObservers(null, NOTIFICATION_FLUSH_PERMISSIONS, this._type);
+ Services.obs.addObserver(this, "perm-changed", false);
this._loadPermissions();
-
+
urlField.focus();
},
-
+
uninit: function ()
{
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.removeObserver(this, "perm-changed");
+ if (!this._observerRemoved) {
+ Services.obs.removeObserver(this, "perm-changed");
+
+ this._observerRemoved = true;
+ }
},
-
+
observe: function (aSubject, aTopic, aData)
{
if (aTopic == "perm-changed") {
var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission);
+
+ // Ignore unrelated permission types.
+ if (permission.type != this._type)
+ return;
+
if (aData == "added") {
- this._addPermissionToList(permission);
- ++this._view._rowCount;
- this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1);
- // Re-do the sort, since we inserted this new item at the end.
- gTreeUtils.sort(this._tree, this._view, this._permissions,
- this._lastPermissionSortColumn,
- this._permissionsComparator,
- this._lastPermissionSortColumn,
- !this._lastPermissionSortAscending); // keep sort direction
+ this._addPermission(permission);
}
else if (aData == "changed") {
for (var i = 0; i < this._permissions.length; ++i) {
- if (this._permissions[i].host == permission.host) {
+ if (permission.matches(this._permissions[i].principal, true)) {
this._permissions[i].capability = this._getCapabilityString(permission.capability);
break;
}
}
- // Re-do the sort, if the status changed from Block to Allow
- // or vice versa, since if we're sorted on status, we may no
- // longer be in order.
- if (this._lastPermissionSortColumn == "statusCol") {
- gTreeUtils.sort(this._tree, this._view, this._permissions,
- this._lastPermissionSortColumn,
- this._permissionsComparator,
- this._lastPermissionSortColumn,
- !this._lastPermissionSortAscending); // keep sort direction
- }
- this._tree.treeBoxObject.invalidate();
+ this._handleCapabilityChange();
+ }
+ else if (aData == "deleted") {
+ this._removePermissionFromList(permission.principal);
}
- // No UI other than this window causes this method to be sent a "deleted"
- // notification, so we don't need to implement it since Delete is handled
- // directly by the Permission Removal handlers. If that ever changes, those
- // implementations will have to move into here.
}
},
-
+
onPermissionSelected: function ()
{
var hasSelection = this._tree.view.selection.count > 0;
@@ -257,8 +325,8 @@ var gPermissionManager = {
gTreeUtils.deleteSelectedItems(this._tree, this._view, this._permissions, removedPermissions);
for (var i = 0; i < removedPermissions.length; ++i) {
var p = removedPermissions[i];
- this._pm.remove(p.host, p.type);
- }
+ this._removePermission(p);
+ }
document.getElementById("removePermission").disabled = !this._permissions.length;
document.getElementById("removeAllPermissions").disabled = !this._permissions.length;
},
@@ -271,18 +339,23 @@ var gPermissionManager = {
gTreeUtils.deleteAll(this._tree, this._view, this._permissions, removedPermissions);
for (var i = 0; i < removedPermissions.length; ++i) {
var p = removedPermissions[i];
- this._pm.remove(p.host, p.type);
- }
+ this._removePermission(p);
+ }
document.getElementById("removePermission").disabled = true;
document.getElementById("removeAllPermissions").disabled = true;
},
-
+
onPermissionKeyPress: function (aEvent)
{
- if (aEvent.keyCode == 46)
+ if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE
+#ifdef XP_MACOSX
+ || aEvent.keyCode == KeyEvent.DOM_VK_BACK_SPACE
+#endif
+ ) {
this.onPermissionDeleted();
+ }
},
-
+
_lastPermissionSortColumn: "",
_lastPermissionSortAscending: false,
_permissionsComparator : function (a, b)
@@ -293,16 +366,34 @@ var gPermissionManager = {
onPermissionSort: function (aColumn)
{
- this._lastPermissionSortAscending = gTreeUtils.sort(this._tree,
- this._view,
+ this._lastPermissionSortAscending = gTreeUtils.sort(this._tree,
+ this._view,
this._permissions,
aColumn,
this._permissionsComparator,
- this._lastPermissionSortColumn,
+ this._lastPermissionSortColumn,
this._lastPermissionSortAscending);
this._lastPermissionSortColumn = aColumn;
},
-
+
+ onApplyChanges: function()
+ {
+ // Stop observing permission changes since we are about
+ // to write out the pending adds/deletes and don't need
+ // to update the UI
+ this.uninit();
+
+ for (let permissionParams of this._permissionsToAdd.values()) {
+ Services.perms.addFromPrincipal(permissionParams.principal, permissionParams.type, permissionParams.capability);
+ }
+
+ for (let p of this._permissionsToDelete.values()) {
+ Services.perms.removeFromPrincipal(p.principal, p.type);
+ }
+
+ window.close();
+ },
+
_loadPermissions: function ()
{
this._tree = document.getElementById("permissionsTree");
@@ -310,48 +401,59 @@ var gPermissionManager = {
// load permissions into a table
var count = 0;
- var enumerator = this._pm.enumerator;
+ var enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
var nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
this._addPermissionToList(nextPermission);
}
-
+
this._view._rowCount = this._permissions.length;
// sort and display the table
this._tree.view = this._view;
- this.onPermissionSort("rawHost");
+ this.onPermissionSort("origin");
// disable "remove all" button if there are none
document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
},
-
+
_addPermissionToList: function (aPermission)
{
if (aPermission.type == this._type &&
(!this._manageCapability ||
(aPermission.capability == this._manageCapability))) {
- var host = aPermission.host;
+ var principal = aPermission.principal;
var capabilityString = this._getCapabilityString(aPermission.capability);
- var p = new Permission(host,
- (host.charAt(0) == ".") ? host.substring(1,host.length) : host,
+ var p = new Permission(principal,
aPermission.type,
- capabilityString,
- aPermission.capability);
+ capabilityString);
this._permissions.push(p);
- }
+ }
},
-
- setHost: function (aHost)
+
+ _removePermissionFromList: function (aPrincipal)
+ {
+ for (let i = 0; i < this._permissions.length; ++i) {
+ if (this._permissions[i].principal.equals(aPrincipal)) {
+ this._permissions.splice(i, 1);
+ this._view._rowCount--;
+ this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, -1);
+ this._tree.treeBoxObject.invalidate();
+ break;
+ }
+ }
+ },
+
+ setOrigin: function (aOrigin)
{
- document.getElementById("url").value = aHost;
+ document.getElementById("url").value = aOrigin;
}
};
-function setHost(aHost)
+function setOrigin(aOrigin)
{
- gPermissionManager.setHost(aHost);
+ gPermissionManager.setOrigin(aOrigin);
}
function initWithParams(aParams)
diff --git a/application/palemoon/components/preferences/permissions.xul b/application/palemoon/components/preferences/permissions.xul
index fd550e8f7..33806cc27 100644
--- a/application/palemoon/components/preferences/permissions.xul
+++ b/application/palemoon/components/preferences/permissions.xul
@@ -1,12 +1,12 @@
<?xml version="1.0"?>
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# 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/.
+<!-- -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -->
+<!-- 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/. -->
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://browser/locale/preferences/permissions.dtd" >
@@ -35,7 +35,7 @@
<separator class="thin"/>
<label id="urlLabel" control="url" value="&address.label;" accesskey="&address.accesskey;"/>
<hbox align="start">
- <textbox id="url" flex="1"
+ <textbox id="url" flex="1"
oninput="gPermissionManager.onHostInput(event.target);"
onkeypress="gPermissionManager.onHostKeyPress(event);"/>
</hbox>
@@ -54,30 +54,32 @@
onselect="gPermissionManager.onPermissionSelected();">
<treecols>
<treecol id="siteCol" label="&treehead.sitename.label;" flex="3"
- onclick="gPermissionManager.onPermissionSort('rawHost');" persist="width"/>
+ data-field-name="origin" persist="width"/>
<splitter class="tree-splitter"/>
<treecol id="statusCol" label="&treehead.status.label;" flex="1"
- onclick="gPermissionManager.onPermissionSort('capability');" persist="width"/>
+ data-field-name="capability" persist="width"/>
</treecols>
<treechildren/>
</tree>
</vbox>
- <hbox align="end">
- <hbox class="actionButtons" flex="1">
+ <vbox>
+ <hbox class="actionButtons" align="left" flex="1">
<button id="removePermission" disabled="true"
accesskey="&removepermission.accesskey;"
icon="remove" label="&removepermission.label;"
oncommand="gPermissionManager.onPermissionDeleted();"/>
<button id="removeAllPermissions"
icon="clear" label="&removeallpermissions.label;"
- accesskey="&removeallpermissions.accesskey;"
+ accesskey="&removeallpermissions.accesskey;"
oncommand="gPermissionManager.onAllPermissionsDeleted();"/>
- <spacer flex="1"/>
-#ifndef XP_MACOSX
+ </hbox>
+ <spacer flex="1"/>
+ <hbox class="actionButtons" align="right" flex="1">
<button oncommand="close();" icon="close"
- label="&button.close.label;" accesskey="&button.close.accesskey;"/>
-#endif
+ label="&button.cancel.label;" accesskey="&button.cancel.accesskey;" />
+ <button id="btnApplyChanges" oncommand="gPermissionManager.onApplyChanges();" icon="save"
+ label="&button.ok.label;" accesskey="&button.ok.accesskey;"/>
</hbox>
<resizer type="window" dir="bottomend"/>
- </hbox>
+ </vbox>
</window>
diff --git a/application/palemoon/components/preferences/security.js b/application/palemoon/components/preferences/security.js
index 56664bf66..9d5f302a2 100644
--- a/application/palemoon/components/preferences/security.js
+++ b/application/palemoon/components/preferences/security.js
@@ -131,9 +131,21 @@ var gSecurityPane = {
*/
showPasswordExceptions: function ()
{
+ let bundlePrefs = document.getElementById("bundlePreferences");
+ let params = {
+ blockVisible: true,
+ sessionVisible: false,
+ allowVisible: false,
+ hideStatusColumn: true,
+ prefilledHost: "",
+ permissionType: "login-saving",
+ windowTitle: bundlePrefs.getString("savedLoginsExceptions_title"),
+ introText: bundlePrefs.getString("savedLoginsExceptions_desc")
+ };
+
document.documentElement.openWindow("Toolkit:PasswordManagerExceptions",
- "chrome://passwordmgr/content/passwordManagerExceptions.xul",
- "", null);
+ "chrome://browser/content/preferences/permissions.xul",
+ null, params);
},
/**
diff --git a/application/palemoon/locales/en-US/chrome/browser/browser.properties b/application/palemoon/locales/en-US/chrome/browser/browser.properties
index bf363d103..2468f3c48 100644
--- a/application/palemoon/locales/en-US/chrome/browser/browser.properties
+++ b/application/palemoon/locales/en-US/chrome/browser/browser.properties
@@ -304,6 +304,10 @@ webNotifications.alwaysShow.accesskey=A
webNotifications.neverShow=Always Block Notifications
webNotifications.neverShow.accesskey=N
webNotifications.showFromSite=Would you like to show notifications from %S?
+# 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.
# Pointer lock UI
diff --git a/application/palemoon/locales/en-US/chrome/browser/preferences/aboutPermissions.dtd b/application/palemoon/locales/en-US/chrome/browser/preferences/aboutPermissions.dtd
index ff1da3dd0..9e36520c8 100644
--- a/application/palemoon/locales/en-US/chrome/browser/preferences/aboutPermissions.dtd
+++ b/application/palemoon/locales/en-US/chrome/browser/preferences/aboutPermissions.dtd
@@ -54,3 +54,5 @@
<!ENTITY fullscreen.label "Fullscreen">
<!ENTITY pointerLock.label "Hide the Mouse Pointer">
+
+<!ENTITY focusSearch.key "f">
diff --git a/application/palemoon/locales/en-US/chrome/browser/preferences/permissions.dtd b/application/palemoon/locales/en-US/chrome/browser/preferences/permissions.dtd
index f6a9c466c..e61228b76 100644
--- a/application/palemoon/locales/en-US/chrome/browser/preferences/permissions.dtd
+++ b/application/palemoon/locales/en-US/chrome/browser/preferences/permissions.dtd
@@ -3,7 +3,7 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY window.title "Exceptions">
-<!ENTITY window.width "36em">
+<!ENTITY window.width "45em">
<!ENTITY treehead.sitename.label "Site">
<!ENTITY treehead.status.label "Status">
@@ -21,6 +21,8 @@
<!ENTITY allow.accesskey "A">
<!ENTITY windowClose.key "w">
-<!ENTITY button.close.label "Close">
-<!ENTITY button.close.accesskey "C">
+<!ENTITY button.cancel.label "Cancel">
+<!ENTITY button.cancel.accesskey "C">
+<!ENTITY button.ok.label "Save Changes">
+<!ENTITY button.ok.accesskey "S">
diff --git a/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties b/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties
index 356922982..3eebbcbec 100644
--- a/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -23,6 +23,8 @@ popuppermissionstext=You can specify which websites are allowed to open pop-up w
popuppermissionstitle=Allowed Sites - Pop-ups
invalidURI=Please enter a valid hostname
invalidURITitle=Invalid Hostname Entered
+savedLoginsExceptions_title=Exceptions - Saved Logins
+savedLoginsExceptions_desc=Logins for the following sites will not be saved:
#### Master Password
diff --git a/application/palemoon/modules/PopupNotifications.jsm b/application/palemoon/modules/PopupNotifications.jsm
index 15c8915ed..0cb970230 100644
--- a/application/palemoon/modules/PopupNotifications.jsm
+++ b/application/palemoon/modules/PopupNotifications.jsm
@@ -12,6 +12,7 @@ const NOTIFICATION_EVENT_DISMISSED = "dismissed";
const NOTIFICATION_EVENT_REMOVED = "removed";
const NOTIFICATION_EVENT_SHOWING = "showing";
const NOTIFICATION_EVENT_SHOWN = "shown";
+const NOTIFICATION_EVENT_SWAPPING = "swapping";
const ICON_SELECTOR = ".notification-anchor-icon";
const ICON_ATTRIBUTE_SHOWING = "showing";
@@ -237,9 +238,23 @@ PopupNotifications.prototype = {
* tabs)
* "removed": notification has been removed (due to
* location change or user action)
+ * "showing": notification is about to be shown
+ * (this can be fired multiple times as
+ * notifications are dismissed and re-shown)
* "shown": notification has been shown (this can be fired
* multiple times as notifications are dismissed
* and re-shown)
+ * "swapping": the docshell of the browser that created
+ * the notification is about to be swapped to
+ * another browser. A second parameter contains
+ * the browser that is receiving the docshell,
+ * so that the event callback can transfer stuff
+ * specific to this notification.
+ * If the callback returns true, the notification
+ * will be moved to the new browser.
+ * If the callback isn't implemented, returns false,
+ * or doesn't return any value, the notification
+ * will be removed.
* neverShow: Indicate that no popup should be shown for this
* notification. Useful for just showing the anchor icon.
* removeOnDismissal:
@@ -829,13 +844,60 @@ PopupNotifications.prototype = {
this._update(notifications, anchor);
},
- _fireCallback: function PopupNotifications_fireCallback(n, event) {
+ _swapBrowserNotifications: function PopupNotifications_swapBrowserNoficications(ourBrowser, otherBrowser) {
+ // When swaping browser docshells (e.g. dragging tab to new window) we need
+ // to update our notification map.
+
+ let ourNotifications = this._getNotificationsForBrowser(ourBrowser);
+ let other = otherBrowser.ownerDocument.defaultView.PopupNotifications;
+ if (!other) {
+ if (ourNotifications.length > 0)
+ Cu.reportError("unable to swap notifications: otherBrowser doesn't support notifications");
+ return;
+ }
+ let otherNotifications = other._getNotificationsForBrowser(otherBrowser);
+ if (ourNotifications.length < 1 && otherNotifications.length < 1) {
+ // No notification to swap.
+ return;
+ }
+
+ otherNotifications = otherNotifications.filter(n => {
+ if (this._fireCallback(n, NOTIFICATION_EVENT_SWAPPING, ourBrowser)) {
+ n.browser = ourBrowser;
+ n.owner = this;
+ return true;
+ }
+ other._fireCallback(n, NOTIFICATION_EVENT_REMOVED);
+ return false;
+ });
+
+ ourNotifications = ourNotifications.filter(n => {
+ if (this._fireCallback(n, NOTIFICATION_EVENT_SWAPPING, otherBrowser)) {
+ n.browser = otherBrowser;
+ n.owner = other;
+ return true;
+ }
+ this._fireCallback(n, NOTIFICATION_EVENT_REMOVED);
+ return false;
+ });
+
+ this._setNotificationsForBrowser(otherBrowser, ourNotifications);
+ other._setNotificationsForBrowser(ourBrowser, otherNotifications);
+
+ if (otherNotifications.length > 0)
+ this._update(otherNotifications, otherNotifications[0].anchorElement);
+ if (ourNotifications.length > 0)
+ other._update(ourNotifications, ourNotifications[0].anchorElement);
+ },
+
+ _fireCallback: function PopupNotifications_fireCallback(n, event, ...args) {
try {
if (n.options.eventCallback)
- n.options.eventCallback.call(n, event);
+ return n.options.eventCallback.call(n, event, ...args);
} catch (error) {
Cu.reportError(error);
}
+ return undefined;
},
_onPopupHidden: function PopupNotifications_onPopupHidden(event) {
diff --git a/application/palemoon/modules/webrtcUI.jsm b/application/palemoon/modules/webrtcUI.jsm
index c957bfd9a..819ca181f 100644
--- a/application/palemoon/modules/webrtcUI.jsm
+++ b/application/palemoon/modules/webrtcUI.jsm
@@ -11,9 +11,11 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PluralForm.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+ "resource://gre/modules/PluralForm.jsm");
+
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
"@mozilla.org/mediaManagerService;1",
"nsIMediaManagerService");
@@ -128,62 +130,14 @@ function prompt(aWindowID, aCallID, aAudioRequested, aVideoRequested, aDevices)
let message = stringBundle.getFormattedString("getUserMedia.share" + requestType + ".message",
[ host ]);
- function listDevices(menupopup, devices) {
- while (menupopup.lastChild)
- menupopup.removeChild(menupopup.lastChild);
-
- let deviceIndex = 0;
- for (let device of devices) {
- addDeviceToList(menupopup, device.name, deviceIndex);
- deviceIndex++;
- }
- }
-
- function addDeviceToList(menupopup, deviceName, deviceIndex) {
- let menuitem = chromeDoc.createElement("menuitem");
- menuitem.setAttribute("value", deviceIndex);
- menuitem.setAttribute("label", deviceName);
- menuitem.setAttribute("tooltiptext", deviceName);
- menupopup.appendChild(menuitem);
- }
-
- chromeDoc.getElementById("webRTC-selectCamera").hidden = !videoDevices.length;
- chromeDoc.getElementById("webRTC-selectMicrophone").hidden = !audioDevices.length;
-
- let camMenupopup = chromeDoc.getElementById("webRTC-selectCamera-menupopup");
- let micMenupopup = chromeDoc.getElementById("webRTC-selectMicrophone-menupopup");
- listDevices(camMenupopup, videoDevices);
- listDevices(micMenupopup, audioDevices);
- if (requestType == "CameraAndMicrophone") {
- addDeviceToList(camMenupopup, stringBundle.getString("getUserMedia.noVideo.label"), "-1");
- addDeviceToList(micMenupopup, stringBundle.getString("getUserMedia.noAudio.label"), "-1");
- }
-
let mainAction = {
label: PluralForm.get(requestType == "CameraAndMicrophone" ? 2 : 1,
stringBundle.getString("getUserMedia.shareSelectedDevices.label")),
accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
- callback: function () {
- let allowedDevices = Cc["@mozilla.org/supports-array;1"]
- .createInstance(Ci.nsISupportsArray);
- if (videoDevices.length) {
- let videoDeviceIndex = chromeDoc.getElementById("webRTC-selectCamera-menulist").value;
- if (videoDeviceIndex != "-1")
- allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
- }
- if (audioDevices.length) {
- let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
- if (audioDeviceIndex != "-1")
- allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
- }
-
- if (allowedDevices.Count() == 0) {
- denyRequest(aCallID);
- return;
- }
-
- Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
- }
+ // The real callback will be set during the "showing" event. The
+ // empty function here is so that PopupNotifications.show doesn't
+ // reject the action.
+ callback: function() {}
};
let secondaryActions = [{
@@ -194,7 +148,72 @@ function prompt(aWindowID, aCallID, aAudioRequested, aVideoRequested, aDevices)
}
}];
- let options = null;
+ let options = {
+ eventCallback: function(aTopic, aNewBrowser) {
+ if (aTopic == "swapping")
+ return true;
+
+ if (aTopic != "showing")
+ return false;
+
+ let chromeDoc = this.browser.ownerDocument;
+
+ function listDevices(menupopup, devices) {
+ while (menupopup.lastChild)
+ menupopup.removeChild(menupopup.lastChild);
+
+ let deviceIndex = 0;
+ for (let device of devices) {
+ addDeviceToList(menupopup, device.name, deviceIndex);
+ deviceIndex++;
+ }
+ }
+
+ function addDeviceToList(menupopup, deviceName, deviceIndex) {
+ let menuitem = chromeDoc.createElement("menuitem");
+ menuitem.setAttribute("value", deviceIndex);
+ menuitem.setAttribute("label", deviceName);
+ menuitem.setAttribute("tooltiptext", deviceName);
+ menupopup.appendChild(menuitem);
+ }
+
+ chromeDoc.getElementById("webRTC-selectCamera").hidden = !videoDevices.length;
+ chromeDoc.getElementById("webRTC-selectMicrophone").hidden = !audioDevices.length;
+
+ let camMenupopup = chromeDoc.getElementById("webRTC-selectCamera-menupopup");
+ let micMenupopup = chromeDoc.getElementById("webRTC-selectMicrophone-menupopup");
+ listDevices(camMenupopup, videoDevices);
+ listDevices(micMenupopup, audioDevices);
+ if (requestType == "CameraAndMicrophone") {
+ let stringBundle = chromeDoc.defaultView.gNavigatorBundle;
+ addDeviceToList(camMenupopup, stringBundle.getString("getUserMedia.noVideo.label"), "-1");
+ addDeviceToList(micMenupopup, stringBundle.getString("getUserMedia.noAudio.label"), "-1");
+ }
+
+ this.mainAction.callback = function() {
+ let allowedDevices = Cc["@mozilla.org/supports-array;1"]
+ .createInstance(Ci.nsISupportsArray);
+ if (videoDevices.length) {
+ let videoDeviceIndex = chromeDoc.getElementById("webRTC-selectCamera-menulist").value;
+ if (videoDeviceIndex != "-1")
+ allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
+ }
+ if (audioDevices.length) {
+ let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
+ if (audioDeviceIndex != "-1")
+ allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
+ }
+
+ if (allowedDevices.Count() == 0) {
+ denyRequest(aCallID);
+ return;
+ }
+
+ Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
+ };
+ return true;
+ }
+ };
chromeWin.PopupNotifications.show(browser, "webRTC-shareDevices", message,
"webRTC-shareDevices-notification-icon", mainAction,
@@ -254,7 +273,8 @@ function showBrowserSpecificIndicator(aBrowser) {
}];
let options = {
hideNotNow: true,
- dismissed: true
+ dismissed: true,
+ eventCallback: function(aTopic) aTopic == "swapping"
};
chromeWin.PopupNotifications.show(aBrowser, "webRTC-sharingDevices", message,
"webRTC-sharingDevices-notification-icon", mainAction,
diff --git a/application/palemoon/themes/linux/Push-16.png b/application/palemoon/themes/linux/Push-16.png
new file mode 100644
index 000000000..082b17781
--- /dev/null
+++ b/application/palemoon/themes/linux/Push-16.png
Binary files differ
diff --git a/application/palemoon/themes/linux/Push-64.png b/application/palemoon/themes/linux/Push-64.png
new file mode 100644
index 000000000..6e09ab9c3
--- /dev/null
+++ b/application/palemoon/themes/linux/Push-64.png
Binary files differ
diff --git a/application/palemoon/themes/linux/browser.css b/application/palemoon/themes/linux/browser.css
index 4f4964db8..131a63a90 100644
--- a/application/palemoon/themes/linux/browser.css
+++ b/application/palemoon/themes/linux/browser.css
@@ -1169,6 +1169,10 @@ toolbar[iconsize="small"] #webrtc-status-button {
list-style-image: url(chrome://browser/skin/Geolocation-64.png);
}
+.popup-notification-icon[popupid="push"] {
+ list-style-image: url(chrome://browser/skin/Push-64.png);
+}
+
.popup-notification-icon[popupid="xpinstall-disabled"],
.popup-notification-icon[popupid="addon-progress"],
.popup-notification-icon[popupid="addon-install-cancelled"],
@@ -1288,6 +1292,10 @@ toolbar[iconsize="small"] #webrtc-status-button {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
+#push-notification-icon {
+ list-style-image: url(chrome://browser/skin/Push-16.png);
+}
+
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
@@ -1374,7 +1382,18 @@ toolbar[iconsize="small"] #webrtc-status-button {
.web-notifications-notification-icon,
#web-notifications-notification-icon {
- list-style-image: url(chrome://browser/skin/notification-16.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
}
#pointerLock-notification-icon {
diff --git a/application/palemoon/themes/linux/jar.mn b/application/palemoon/themes/linux/jar.mn
index 7e67d0129..3c2ac406e 100644
--- a/application/palemoon/themes/linux/jar.mn
+++ b/application/palemoon/themes/linux/jar.mn
@@ -36,8 +36,6 @@ browser.jar:
skin/classic/browser/mixed-content-blocked-64.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
- skin/classic/browser/notification-16.png
- skin/classic/browser/notification-64.png
* skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png
@@ -54,6 +52,8 @@ browser.jar:
skin/classic/browser/Toolbar.png
skin/classic/browser/Toolbar-small.png
skin/classic/browser/urlbar-arrow.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
#ifdef MOZ_WEBRTC
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
diff --git a/application/palemoon/themes/linux/notification-16.png b/application/palemoon/themes/linux/notification-16.png
deleted file mode 100644
index 6b2df7341..000000000
--- a/application/palemoon/themes/linux/notification-16.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/linux/notification-64.png b/application/palemoon/themes/linux/notification-64.png
deleted file mode 100644
index a01d0ab77..000000000
--- a/application/palemoon/themes/linux/notification-64.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/linux/preferences/aboutPermissions.css b/application/palemoon/themes/linux/preferences/aboutPermissions.css
index 406568831..224c88018 100644
--- a/application/palemoon/themes/linux/preferences/aboutPermissions.css
+++ b/application/palemoon/themes/linux/preferences/aboutPermissions.css
@@ -90,7 +90,7 @@
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.pref-icon[type="desktop-notification"] {
- list-style-image: url(chrome://browser/skin/notification-64.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="install"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
diff --git a/application/palemoon/themes/linux/web-notifications-icon.svg b/application/palemoon/themes/linux/web-notifications-icon.svg
new file mode 100644
index 000000000..f7186c727
--- /dev/null
+++ b/application/palemoon/themes/linux/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="64" height="64" viewBox="0 0 64 64">
+ <defs>
+ <style>
+ .icon {
+ fill: #a6a6a6;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path d="M57,48 L46,48 L46,60.016 L32.482,48 L7,48 C5.343,48 4,46.657 4,45 L4,11.031 C4,9.374 5.343,8.031 7,8.031 L57,8.031 C58.657,8.031 60,9.374 60,11.031 L60,45 C60,46.657 58.657,48 57,48 ZM36,16.031 C36,14.927 35.105,14.031 34,14.031 L30,14.031 C28.895,14.031 28,14.927 28,16.031 L28,30.031 C28,31.136 28.895,32.031 30,32.031 L34,32.031 C35.105,32.031 36,31.136 36,30.031 L36,16.031 ZM36,37.5 C36,36.672 35.328,36 34.5,36 L29.5,36 C28.672,36 28,36.672 28,37.5 L28,40.5 C28,41.328 28.672,42 29.5,42 L34.5,42 C35.328,42 36,41.328 36,40.5 L36,37.5 Z" class="icon"/>
+</svg>
diff --git a/application/palemoon/themes/linux/web-notifications-tray.svg b/application/palemoon/themes/linux/web-notifications-tray.svg
new file mode 100644
index 000000000..314026a10
--- /dev/null
+++ b/application/palemoon/themes/linux/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="16" viewBox="0 0 96 32">
+ <defs>
+ <style>
+ .style-icon-notification {
+ fill: #666666;
+ }
+ .style-icon-notification.hover {
+ fill: #808080;
+ }
+ .style-icon-notification.active {
+ fill: #4d4d4d;
+ }
+ </style>
+ <path id="shape-notifcations-push" d="M27,23.969 L24,23.969 L24,29.977 L17.241,23.969 L5,23.969 C3.343,23.969 2,22.626 2,20.969 L2,6.969 C2,5.312 3.343,3.969 5,3.969 L27,3.969 C28.657,3.969 30,5.312 30,6.969 L30,20.969 C30,22.626 28.657,23.969 27,23.969 ZM18,8.969 C18,7.864 17.105,6.969 16,6.969 C14.895,6.969 14,7.864 14,8.969 L14,13.969 C14,15.073 14.895,15.969 16,15.969 C17.105,15.969 18,15.073 18,13.969 L18,8.969 ZM16.5,17.969 L15.5,17.969 C14.672,17.969 14,18.640 14,19.469 C14,20.297 14.672,20.969 15.5,20.969 L16.5,20.969 C17.328,20.969 18,20.297 18,19.469 C18,18.640 17.328,17.969 16.5,17.969 Z"/>
+ </defs>
+ <use xlink:href="#shape-notifcations-push" class="style-icon-notification"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(32)" class="style-icon-notification hover"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(64)" class="style-icon-notification active"/>
+</svg>
diff --git a/application/palemoon/themes/osx/Push-16.png b/application/palemoon/themes/osx/Push-16.png
new file mode 100644
index 000000000..54ef8f8ea
--- /dev/null
+++ b/application/palemoon/themes/osx/Push-16.png
Binary files differ
diff --git a/application/palemoon/themes/osx/Push-64.png b/application/palemoon/themes/osx/Push-64.png
new file mode 100644
index 000000000..099b9c76f
--- /dev/null
+++ b/application/palemoon/themes/osx/Push-64.png
Binary files differ
diff --git a/application/palemoon/themes/osx/browser.css b/application/palemoon/themes/osx/browser.css
index 8d709d8e1..58443fa76 100644
--- a/application/palemoon/themes/osx/browser.css
+++ b/application/palemoon/themes/osx/browser.css
@@ -1975,6 +1975,10 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
}
+#push-notification-icon {
+ list-style-image: url(chrome://browser/skin/Push-16.png);
+}
+
#addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
}
@@ -2061,7 +2065,18 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
.web-notifications-notification-icon,
#web-notifications-notification-icon {
- list-style-image: url(chrome://browser/skin/notification-16.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
}
#pointerLock-notification-icon {
diff --git a/application/palemoon/themes/osx/jar.mn b/application/palemoon/themes/osx/jar.mn
index 186cd8a75..a085c5f81 100644
--- a/application/palemoon/themes/osx/jar.mn
+++ b/application/palemoon/themes/osx/jar.mn
@@ -41,8 +41,6 @@ browser.jar:
skin/classic/browser/mixed-content-blocked-64.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
- skin/classic/browser/notification-16.png
- skin/classic/browser/notification-64.png
skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png
@@ -70,6 +68,8 @@ browser.jar:
skin/classic/browser/urlbar-history-dropmarker.png
skin/classic/browser/webapps-16.png
skin/classic/browser/webapps-64.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
diff --git a/application/palemoon/themes/osx/notification-16.png b/application/palemoon/themes/osx/notification-16.png
deleted file mode 100644
index 6b2df7341..000000000
--- a/application/palemoon/themes/osx/notification-16.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/osx/notification-64.png b/application/palemoon/themes/osx/notification-64.png
deleted file mode 100644
index a01d0ab77..000000000
--- a/application/palemoon/themes/osx/notification-64.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/osx/preferences/aboutPermissions.css b/application/palemoon/themes/osx/preferences/aboutPermissions.css
index cfb941bbb..a97e71e04 100644
--- a/application/palemoon/themes/osx/preferences/aboutPermissions.css
+++ b/application/palemoon/themes/osx/preferences/aboutPermissions.css
@@ -93,7 +93,7 @@
list-style-image: url(chrome://global/skin/icons/question-64.png);
}
.pref-icon[type="desktop-notification"] {
- list-style-image: url(chrome://browser/skin/notification-64.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="install"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
diff --git a/application/palemoon/themes/osx/web-notifications-icon.svg b/application/palemoon/themes/osx/web-notifications-icon.svg
new file mode 100644
index 000000000..f7186c727
--- /dev/null
+++ b/application/palemoon/themes/osx/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="64" height="64" viewBox="0 0 64 64">
+ <defs>
+ <style>
+ .icon {
+ fill: #a6a6a6;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path d="M57,48 L46,48 L46,60.016 L32.482,48 L7,48 C5.343,48 4,46.657 4,45 L4,11.031 C4,9.374 5.343,8.031 7,8.031 L57,8.031 C58.657,8.031 60,9.374 60,11.031 L60,45 C60,46.657 58.657,48 57,48 ZM36,16.031 C36,14.927 35.105,14.031 34,14.031 L30,14.031 C28.895,14.031 28,14.927 28,16.031 L28,30.031 C28,31.136 28.895,32.031 30,32.031 L34,32.031 C35.105,32.031 36,31.136 36,30.031 L36,16.031 ZM36,37.5 C36,36.672 35.328,36 34.5,36 L29.5,36 C28.672,36 28,36.672 28,37.5 L28,40.5 C28,41.328 28.672,42 29.5,42 L34.5,42 C35.328,42 36,41.328 36,40.5 L36,37.5 Z" class="icon"/>
+</svg>
diff --git a/application/palemoon/themes/osx/web-notifications-tray.svg b/application/palemoon/themes/osx/web-notifications-tray.svg
new file mode 100644
index 000000000..314026a10
--- /dev/null
+++ b/application/palemoon/themes/osx/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="16" viewBox="0 0 96 32">
+ <defs>
+ <style>
+ .style-icon-notification {
+ fill: #666666;
+ }
+ .style-icon-notification.hover {
+ fill: #808080;
+ }
+ .style-icon-notification.active {
+ fill: #4d4d4d;
+ }
+ </style>
+ <path id="shape-notifcations-push" d="M27,23.969 L24,23.969 L24,29.977 L17.241,23.969 L5,23.969 C3.343,23.969 2,22.626 2,20.969 L2,6.969 C2,5.312 3.343,3.969 5,3.969 L27,3.969 C28.657,3.969 30,5.312 30,6.969 L30,20.969 C30,22.626 28.657,23.969 27,23.969 ZM18,8.969 C18,7.864 17.105,6.969 16,6.969 C14.895,6.969 14,7.864 14,8.969 L14,13.969 C14,15.073 14.895,15.969 16,15.969 C17.105,15.969 18,15.073 18,13.969 L18,8.969 ZM16.5,17.969 L15.5,17.969 C14.672,17.969 14,18.640 14,19.469 C14,20.297 14.672,20.969 15.5,20.969 L16.5,20.969 C17.328,20.969 18,20.297 18,19.469 C18,18.640 17.328,17.969 16.5,17.969 Z"/>
+ </defs>
+ <use xlink:href="#shape-notifcations-push" class="style-icon-notification"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(32)" class="style-icon-notification hover"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(64)" class="style-icon-notification active"/>
+</svg>
diff --git a/application/palemoon/themes/windows/Push-16.png b/application/palemoon/themes/windows/Push-16.png
new file mode 100644
index 000000000..d710e7336
--- /dev/null
+++ b/application/palemoon/themes/windows/Push-16.png
Binary files differ
diff --git a/application/palemoon/themes/windows/Push-64.png b/application/palemoon/themes/windows/Push-64.png
new file mode 100644
index 000000000..27fecb858
--- /dev/null
+++ b/application/palemoon/themes/windows/Push-64.png
Binary files differ
diff --git a/application/palemoon/themes/windows/browser.css b/application/palemoon/themes/windows/browser.css
index 1c51accae..3d519ba85 100644
--- a/application/palemoon/themes/windows/browser.css
+++ b/application/palemoon/themes/windows/browser.css
@@ -2548,7 +2548,18 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
.web-notifications-notification-icon,
#web-notifications-notification-icon {
- list-style-image: url(chrome://browser/skin/notification-16.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
}
#pointerLock-notification-icon {
diff --git a/application/palemoon/themes/windows/jar.mn b/application/palemoon/themes/windows/jar.mn
index a66714b13..8c0d9a5cc 100644
--- a/application/palemoon/themes/windows/jar.mn
+++ b/application/palemoon/themes/windows/jar.mn
@@ -42,8 +42,6 @@ browser.jar:
skin/classic/browser/mixed-content-blocked-64.png
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
- skin/classic/browser/notification-16.png
- skin/classic/browser/notification-64.png
skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png)
@@ -72,6 +70,8 @@ browser.jar:
skin/classic/browser/urlbar-history-dropmarker.png
skin/classic/browser/webapps-16.png
skin/classic/browser/webapps-64.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
diff --git a/application/palemoon/themes/windows/notification-16.png b/application/palemoon/themes/windows/notification-16.png
deleted file mode 100644
index 6b2df7341..000000000
--- a/application/palemoon/themes/windows/notification-16.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/windows/notification-64.png b/application/palemoon/themes/windows/notification-64.png
deleted file mode 100644
index a01d0ab77..000000000
--- a/application/palemoon/themes/windows/notification-64.png
+++ /dev/null
Binary files differ
diff --git a/application/palemoon/themes/windows/preferences/aboutPermissions.css b/application/palemoon/themes/windows/preferences/aboutPermissions.css
index d9db6ccbf..73b8d6e14 100644
--- a/application/palemoon/themes/windows/preferences/aboutPermissions.css
+++ b/application/palemoon/themes/windows/preferences/aboutPermissions.css
@@ -93,7 +93,7 @@
list-style-image: url(chrome://global/skin/icons/question-48.png);
}
.pref-icon[type="desktop-notification"] {
- list-style-image: url(chrome://browser/skin/notification-64.png);
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
}
.pref-icon[type="install"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-48.png);
diff --git a/application/palemoon/themes/windows/web-notifications-icon.svg b/application/palemoon/themes/windows/web-notifications-icon.svg
new file mode 100644
index 000000000..f7186c727
--- /dev/null
+++ b/application/palemoon/themes/windows/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="64" height="64" viewBox="0 0 64 64">
+ <defs>
+ <style>
+ .icon {
+ fill: #a6a6a6;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path d="M57,48 L46,48 L46,60.016 L32.482,48 L7,48 C5.343,48 4,46.657 4,45 L4,11.031 C4,9.374 5.343,8.031 7,8.031 L57,8.031 C58.657,8.031 60,9.374 60,11.031 L60,45 C60,46.657 58.657,48 57,48 ZM36,16.031 C36,14.927 35.105,14.031 34,14.031 L30,14.031 C28.895,14.031 28,14.927 28,16.031 L28,30.031 C28,31.136 28.895,32.031 30,32.031 L34,32.031 C35.105,32.031 36,31.136 36,30.031 L36,16.031 ZM36,37.5 C36,36.672 35.328,36 34.5,36 L29.5,36 C28.672,36 28,36.672 28,37.5 L28,40.5 C28,41.328 28.672,42 29.5,42 L34.5,42 C35.328,42 36,41.328 36,40.5 L36,37.5 Z" class="icon"/>
+</svg>
diff --git a/application/palemoon/themes/windows/web-notifications-tray.svg b/application/palemoon/themes/windows/web-notifications-tray.svg
new file mode 100644
index 000000000..314026a10
--- /dev/null
+++ b/application/palemoon/themes/windows/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="16" viewBox="0 0 96 32">
+ <defs>
+ <style>
+ .style-icon-notification {
+ fill: #666666;
+ }
+ .style-icon-notification.hover {
+ fill: #808080;
+ }
+ .style-icon-notification.active {
+ fill: #4d4d4d;
+ }
+ </style>
+ <path id="shape-notifcations-push" d="M27,23.969 L24,23.969 L24,29.977 L17.241,23.969 L5,23.969 C3.343,23.969 2,22.626 2,20.969 L2,6.969 C2,5.312 3.343,3.969 5,3.969 L27,3.969 C28.657,3.969 30,5.312 30,6.969 L30,20.969 C30,22.626 28.657,23.969 27,23.969 ZM18,8.969 C18,7.864 17.105,6.969 16,6.969 C14.895,6.969 14,7.864 14,8.969 L14,13.969 C14,15.073 14.895,15.969 16,15.969 C17.105,15.969 18,15.073 18,13.969 L18,8.969 ZM16.5,17.969 L15.5,17.969 C14.672,17.969 14,18.640 14,19.469 C14,20.297 14.672,20.969 15.5,20.969 L16.5,20.969 C17.328,20.969 18,20.297 18,19.469 C18,18.640 17.328,17.969 16.5,17.969 Z"/>
+ </defs>
+ <use xlink:href="#shape-notifcations-push" class="style-icon-notification"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(32)" class="style-icon-notification hover"/>
+ <use xlink:href="#shape-notifcations-push" transform="translate(64)" class="style-icon-notification active"/>
+</svg>
diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c
index 68f6e4152..0b8c91bfd 100644
--- a/security/nss/lib/softoken/sftkpwd.c
+++ b/security/nss/lib/softoken/sftkpwd.c
@@ -273,7 +273,7 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len);
param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt,
- 30000);
+ 1);
if (param == NULL) {
rv = SECFailure;
goto loser;
@@ -444,7 +444,7 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
RNG_GenerateGlobalRandomBytes(saltData, prfLength);
/* initialize our pkcs5 parameter */
- param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 30000);
+ param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 1);
if (param == NULL) {
rv = SECFailure;
goto loser;
diff --git a/toolkit/themes/linux/global/inContentUI.css b/toolkit/themes/linux/global/inContentUI.css
new file mode 100644
index 000000000..afcef9274
--- /dev/null
+++ b/toolkit/themes/linux/global/inContentUI.css
@@ -0,0 +1,41 @@
+/* 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/. */
+
+/*
+ * The default namespace for this file is XUL. Be sure to prefix rules that
+ * are applicable to both XUL and HTML with '*|'.
+ */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* Page background */
+*|*:root {
+ -moz-appearance: none;
+ padding: 18px;
+ background-color: Window;
+ background-image: /* Texture */
+ url("chrome://global/skin/inContentUI/background-texture.png");
+ color: WindowText;
+}
+
+/* Use the new in-content colors for #contentAreaDownloadsView. After landing
+ of bug 989469 the colors can be moved to *|*:root */
+*|*#contentAreaDownloadsView {
+ background: #f1f1f1;
+ color: #424e5a;
+}
+
+html|html {
+ font: message-box;
+}
+
+/* Content */
+*|*.main-content {
+ /* Needed to allow the radius to clip the inner content, see bug 595656 */
+ overflow: hidden;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+ border: 1px solid ThreeDShadow;
+ border-radius: 5px;
+}
diff --git a/toolkit/themes/linux/global/jar.mn b/toolkit/themes/linux/global/jar.mn
index b0d0b9ddb..0efc8c5cf 100644
--- a/toolkit/themes/linux/global/jar.mn
+++ b/toolkit/themes/linux/global/jar.mn
@@ -16,6 +16,7 @@ toolkit.jar:
skin/classic/global/findBar.css
skin/classic/global/global.css
skin/classic/global/groupbox.css
+ skin/classic/global/inContentUI.css
skin/classic/global/listbox.css
skin/classic/global/menu.css
skin/classic/global/menulist.css
diff --git a/toolkit/themes/osx/global/inContentUI.css b/toolkit/themes/osx/global/inContentUI.css
new file mode 100644
index 000000000..17e2e6ae3
--- /dev/null
+++ b/toolkit/themes/osx/global/inContentUI.css
@@ -0,0 +1,144 @@
+/* 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/. */
+
+%include shared.inc
+
+/*
+ * The default namespace for this file is XUL. Be sure to prefix rules that
+ * are applicable to both XUL and HTML with '*|'.
+ */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* Page background */
+*|*:root {
+ -moz-appearance: none;
+ padding: 18px;
+ background-image: /* Texture */
+ url("chrome://global/skin/inContentUI/background-texture.png"),
+ /* Gradient */
+ linear-gradient(#ADB5C2, #BFC6D1);
+}
+
+/* Use the new in-content colors for #contentAreaDownloadsView. After landing
+ of bug 989469 the colors can be moved to *|*:root */
+*|*#contentAreaDownloadsView {
+ background: #f1f1f1;
+ color: #424e5a;
+}
+
+html|html {
+ font: message-box;
+}
+
+/* Content */
+*|*.main-content {
+ /* Needed to allow the radius to clip the inner content, see bug 595656 */
+ overflow: hidden;
+ background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.25) 50%, rgba(255, 255, 255, 0.05));
+ border: 1px solid rgba(50, 65, 92, 0.4);
+ border-radius: 5px;
+}
+
+/* Buttons */
+*|button,
+menulist,
+colorpicker[type="button"] {
+ -moz-appearance: none;
+ padding: 1px 4px;
+ min-width: 60px;
+ border-radius: 3px;
+ border: 1px solid rgba(60,73,97,0.5);
+ box-shadow: inset 0 1px rgba(255,255,255,0.25), 0 1px rgba(255,255,255,0.25);
+ background-color: transparent;
+ background-image: linear-gradient(rgba(255,255,255,0.45), rgba(255,255,255,0.2));
+ background-clip: padding-box;
+ color: #252F3B;
+ text-shadow: @loweredShadow@;
+}
+
+button:-moz-focusring > .button-box,
+menulist:-moz-focusring:not([open="true"]) > .menulist-label-box,
+colorpicker[type="button"]:-moz-focusring:not([open="true"]) > .colorpicker-button-colorbox {
+ outline: 1px dotted #252F3B;
+}
+
+html|button[disabled],
+button[disabled="true"],
+menulist[disabled="true"],
+colorpicker[type="button"][disabled="true"] {
+ opacity: 0.8;
+ color: #505050;
+}
+
+html|button:not([disabled]):active:hover,
+button:not([disabled="true"]):active:hover,
+menulist[open="true"]:not([disabled="true"]),
+colorpicker[type="button"][open="true"]:not([disabled="true"]) {
+ box-shadow: inset 0 1px 3px rgba(0,0,0,.2), 0 1px rgba(255,255,255,0.25);
+ background-image: linear-gradient(rgba(45,54,71,0.3), rgba(45,54,71,0.1));
+ border-color: rgba(60,73,97,0.7);
+}
+
+menulist {
+ -moz-padding-end: 0;
+ margin-left: 5px;
+ margin-right: 5px;
+}
+
+/* Tweak margins so the focus ring is in the right place. */
+menulist > .menulist-label-box {
+ -moz-margin-end: 3px;
+ margin-top: 1px;
+}
+
+menulist > .menulist-label-box > .menulist-label {
+ margin-top: 0px !important;
+ margin-bottom: 0px !important;
+}
+
+menulist > .menulist-dropmarker {
+ -moz-appearance: none;
+ display: -moz-box;
+ background: transparent;
+ border: none;
+ -moz-border-start: 1px solid rgba(60,73,97,0.5);
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+colorpicker[type="button"] {
+ margin: 1px 5px 2px 5px;
+ padding: 3px;
+ height: 25px;
+}
+
+spinbuttons {
+ -moz-appearance: none;
+}
+
+spinbuttons > .spinbuttons-box > .spinbuttons-button {
+ min-width: 12px;
+}
+
+.spinbuttons-button > .button-box > .button-text {
+ display: none;
+}
+
+.spinbuttons-button[disabled="true"] > .button-box > .button-icon {
+ opacity: 0.5;
+}
+
+spinbuttons > .spinbuttons-box > .spinbuttons-up {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
+ border-bottom-width: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+spinbuttons > .spinbuttons-box > .spinbuttons-down {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
diff --git a/toolkit/themes/osx/global/jar.mn b/toolkit/themes/osx/global/jar.mn
index 79bb062ab..9407ccee5 100644
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -21,6 +21,7 @@ toolkit.jar:
* skin/classic/global/findBar.css
* skin/classic/global/global.css
skin/classic/global/groupbox.css
+* skin/classic/global/inContentUI.css
skin/classic/global/linkTree.css
skin/classic/global/listbox.css
skin/classic/global/menu.css
diff --git a/toolkit/themes/windows/global/inContentUI.css b/toolkit/themes/windows/global/inContentUI.css
new file mode 100644
index 000000000..a3bca7b06
--- /dev/null
+++ b/toolkit/themes/windows/global/inContentUI.css
@@ -0,0 +1,159 @@
+/* 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/. */
+
+/*
+ * The default namespace for this file is XUL. Be sure to prefix rules that
+ * are applicable to both XUL and HTML with '*|'.
+ */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* Page background */
+*|*:root {
+ -moz-appearance: none;
+ padding: 18px;
+ background-repeat: repeat;
+ color: -moz-dialogText;
+ background-color: -moz-dialog;
+ background-image: /* Texture */
+ url("chrome://global/skin/inContentUI/background-texture.png");
+}
+
+html|html {
+ font: message-box;
+}
+
+@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
+ (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
+ *|*:root {
+ color: #000;
+ background-color: #CCD9EA;
+ }
+}
+
+@media (-moz-windows-glass) {
+ *|*:root {
+ /* Blame shorlander for this monstrosity. */
+ background-image: /* Side gradients */
+ linear-gradient(to right,
+ rgba(255,255,255,0.2), transparent 40%,
+ transparent 60%, rgba(255,255,255,0.2)),
+ /* Aero-style light beams */
+ -moz-linear-gradient(left 32deg,
+ /* First light beam */
+ transparent 19.5%, rgba(255,255,255,0.1) 20%,
+ rgba(255,255,255,0.1) 21.5%, rgba(255,255,255,0.2) 22%,
+ rgba(255,255,255,0.2) 25.5%, rgba(255,255,255,0.1) 26%,
+ rgba(255,255,255,0.1) 27.5%, transparent 28%,
+ /* Second light beam */
+ transparent 49.5%, rgba(255,255,255,0.1) 50%,
+ rgba(255,255,255,0.1) 52.5%, rgba(255,255,255,0.2) 53%,
+ rgba(255,255,255,0.2) 54.5%, rgba(255,255,255,0.1) 55%,
+ rgba(255,255,255,0.1) 57.5%, transparent 58%,
+ /* Third light beam */
+ transparent 87%, rgba(255,255,255,0.2) 90%),
+ /* Texture */
+ url("chrome://global/skin/inContentUI/background-texture.png");
+ }
+}
+
+/* Use the new in-content colors for #contentAreaDownloadsView. After landing
+ of bug 989469 the colors can be moved to *|*:root */
+*|*#contentAreaDownloadsView {
+ background: #f1f1f1;
+ color: #424e5a;
+}
+
+/* Content */
+*|*.main-content {
+ /* Needed to allow the radius to clip the inner content, see bug 595656 */
+ overflow: hidden;
+ background-color: rgba(255, 255, 255, 0.35);
+ background-image: linear-gradient(rgba(255, 255, 255, 0),
+ rgba(255, 255, 255, 0.75));
+ border: 1px solid #C3CEDF;
+}
+
+%ifdef XP_WIN
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+%endif
+ *|*.main-content {
+ border-radius: 5px;
+ }
+%ifdef XP_WIN
+}
+%endif
+
+@media (-moz-windows-glass) {
+ /* Buttons */
+ *|button,
+ menulist,
+ colorpicker[type="button"] {
+ -moz-appearance: none;
+ color: black;
+ padding: 0 5px;
+ background: linear-gradient(rgba(251, 252, 253, 0.95), transparent 49%,
+ rgba(211, 212, 213, 0.45) 51%, rgba(225, 226, 229, 0.3));
+ background-clip: padding-box;
+ border-radius: 3px;
+ border: 1px solid rgba(31, 64, 100, 0.4);
+ border-top-color: rgba(31, 64, 100, 0.3);
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25) inset,
+ 0 0 2px 1px rgba(255, 255, 255, 0.25) inset;
+ }
+
+ menulist {
+ -moz-padding-end: 0;
+ }
+
+ colorpicker[type="button"]:-moz-focusring:not([open="true"]) > .colorpicker-button-colorbox {
+ outline: 1px dotted ThreeDDarkShadow;
+ }
+
+ html|button[disabled],
+ button[disabled="true"],
+ menulist[disabled="true"],
+ colorpicker[type="button"][disabled="true"] {
+ -moz-border-top-colors: rgba(31, 64, 100, 0.3) !important;
+ -moz-border-right-colors: rgba(31, 64, 100, 0.4) !important;
+ -moz-border-bottom-colors: rgba(31, 64, 100, 0.4) !important;
+ -moz-border-left-colors: rgba(31, 64, 100, 0.4) !important;
+ opacity: 0.8;
+ color: #505050;
+ }
+
+ html|button:not([disabled]):active:hover,
+ button:not([disabled="true"]):active:hover,
+ menulist[open="true"]:not([disabled="true"]),
+ colorpicker[type="button"][open="true"]:not([disabled="true"]) {
+ background-color: rgba(61, 76, 92, 0.2);
+ border-color: rgba(39, 53, 68, 0.5);
+ box-shadow: 0 0 3px 1px rgba(39, 53, 68, 0.2) inset;
+ }
+
+ button > .button-box {
+ padding: 1px !important;
+ }
+
+ spinbuttons > .spinbuttons-box > .spinbuttons-button {
+ border-radius: 0;
+ padding: 0 4px;
+ }
+
+ spinbuttons > .spinbuttons-box > .spinbuttons-up {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
+ border-bottom-width: 0;
+ }
+
+ spinbuttons > .spinbuttons-box > .spinbuttons-down {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
+ }
+}
+
+colorpicker[type="button"] {
+ margin: 1px 5px 2px 5px;
+ padding: 3px;
+ height: 25px;
+}
diff --git a/toolkit/themes/windows/global/jar.mn b/toolkit/themes/windows/global/jar.mn
index a6ccbd71d..8c5d5de5a 100644
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -27,6 +27,7 @@ toolkit.jar:
skin/classic/global/console/itemSelected.png (console/itemSelected.png)
skin/classic/global/findBar.css
* skin/classic/global/global.css
+* skin/classic/global/inContentUI.css
skin/classic/global/listbox.css
skin/classic/global/netError.css
skin/classic/global/numberbox.css