diff options
47 files changed, 669 insertions, 313 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..750295c2a 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, @@ -534,10 +541,12 @@ var AboutPermissions = { Services.prefs.addObserver("dom.webnotifications.enabled", this, false); Services.prefs.addObserver("xpinstall.whitelist.required", this, false); Services.prefs.addObserver("geo.enabled", this, false); + Services.prefs.addObserver("dom.push.enabled", this, false); Services.prefs.addObserver("dom.indexedDB.enabled", this, false); Services.prefs.addObserver("plugins.click_to_play", this, false); Services.prefs.addObserver("full-screen-api.enabled", this, false); Services.prefs.addObserver("full-screen-api.pointer-lock.enabled", this, false); + Services.prefs.addObserver("dom.push.enabled", this, false); Services.prefs.addObserver("permissions.places-sites-limit", this, false); Services.obs.addObserver(this, "perm-changed", false); @@ -686,10 +695,12 @@ var AboutPermissions = { Services.prefs.removeObserver("dom.webnotifications.enabled", this, false); Services.prefs.removeObserver("xpinstall.whitelist.required", this, false); Services.prefs.removeObserver("geo.enabled", this, false); + Services.prefs.removeObserver("dom.push.enabled", this, false); Services.prefs.removeObserver("dom.indexedDB.enabled", this, false); Services.prefs.removeObserver("plugins.click_to_play", this, false); Services.prefs.removeObserver("full-screen-api.enabled", this, false); Services.prefs.removeObserver("full-screen-api.pointer-lock.enabled", this, false); + Services.prefs.removeObserver("dom.push.enabled", this, false); Services.prefs.removeObserver("permissions.places-sites-limit", this, false); Services.obs.removeObserver(this, "perm-changed"); @@ -721,9 +732,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 +809,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 +867,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 +884,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 +903,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 +914,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 +935,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 +943,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 +966,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 +997,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 +1007,7 @@ var AboutPermissions = { } this.sitesList.removeChild(site.listitem); - delete this._sites[site.host]; + delete this._sites[site.principal.origin]; } } }, @@ -1009,9 +1023,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 +1259,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 +1327,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 +1344,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..8f559b0e0 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); } - // 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..9d0e0c43a 100644 --- a/application/palemoon/components/preferences/permissions.xul +++ b/application/palemoon/components/preferences/permissions.xul @@ -1,9 +1,9 @@ <?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"?> @@ -54,16 +54,16 @@ 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;" @@ -72,12 +72,14 @@ icon="clear" label="&removeallpermissions.label;" 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/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/modules/webrtcUI.jsm b/application/palemoon/modules/webrtcUI.jsm index c957bfd9a..9427fc630 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"); diff --git a/application/palemoon/themes/linux/Push-16.png b/application/palemoon/themes/linux/Push-16.png Binary files differnew file mode 100644 index 000000000..082b17781 --- /dev/null +++ b/application/palemoon/themes/linux/Push-16.png diff --git a/application/palemoon/themes/linux/Push-64.png b/application/palemoon/themes/linux/Push-64.png Binary files differnew file mode 100644 index 000000000..6e09ab9c3 --- /dev/null +++ b/application/palemoon/themes/linux/Push-64.png 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 Binary files differdeleted file mode 100644 index 6b2df7341..000000000 --- a/application/palemoon/themes/linux/notification-16.png +++ /dev/null diff --git a/application/palemoon/themes/linux/notification-64.png b/application/palemoon/themes/linux/notification-64.png Binary files differdeleted file mode 100644 index a01d0ab77..000000000 --- a/application/palemoon/themes/linux/notification-64.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..54ef8f8ea --- /dev/null +++ b/application/palemoon/themes/osx/Push-16.png diff --git a/application/palemoon/themes/osx/Push-64.png b/application/palemoon/themes/osx/Push-64.png Binary files differnew file mode 100644 index 000000000..099b9c76f --- /dev/null +++ b/application/palemoon/themes/osx/Push-64.png 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 Binary files differdeleted file mode 100644 index 6b2df7341..000000000 --- a/application/palemoon/themes/osx/notification-16.png +++ /dev/null diff --git a/application/palemoon/themes/osx/notification-64.png b/application/palemoon/themes/osx/notification-64.png Binary files differdeleted file mode 100644 index a01d0ab77..000000000 --- a/application/palemoon/themes/osx/notification-64.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..d710e7336 --- /dev/null +++ b/application/palemoon/themes/windows/Push-16.png diff --git a/application/palemoon/themes/windows/Push-64.png b/application/palemoon/themes/windows/Push-64.png Binary files differnew file mode 100644 index 000000000..27fecb858 --- /dev/null +++ b/application/palemoon/themes/windows/Push-64.png 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 Binary files differdeleted file mode 100644 index 6b2df7341..000000000 --- a/application/palemoon/themes/windows/notification-16.png +++ /dev/null diff --git a/application/palemoon/themes/windows/notification-64.png b/application/palemoon/themes/windows/notification-64.png Binary files differdeleted file mode 100644 index a01d0ab77..000000000 --- a/application/palemoon/themes/windows/notification-64.png +++ /dev/null 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> |