diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-05-14 10:50:01 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-05-14 10:50:01 +0200 |
commit | e9dd029f5d00590e1a53e63b0ab805110a10b54c (patch) | |
tree | 1126ca5dda925a62be3dc12c99c90e953d08afcf /application/palemoon/components | |
parent | 9d6a7ae25d7f5da855a8f8df884de483b4e2a538 (diff) | |
parent | 36b8fd734f590eb726ca2e50f8d1ff9cc968b8e1 (diff) | |
download | UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.gz UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.lz UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.xz UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.zip |
Merge branch 'master' into Basilisk-release
Diffstat (limited to 'application/palemoon/components')
19 files changed, 632 insertions, 493 deletions
diff --git a/application/palemoon/components/about/AboutRedirector.cpp b/application/palemoon/components/about/AboutRedirector.cpp index d52b873b9..27f6540b2 100644 --- a/application/palemoon/components/about/AboutRedirector.cpp +++ b/application/palemoon/components/about/AboutRedirector.cpp @@ -137,8 +137,13 @@ AboutRedirector::NewChannel(nsIURI* aURI, for (int i = 0; i < kRedirTotal; i++) { if (!strcmp(path.get(), kRedirMap[i].id)) { nsCOMPtr<nsIChannel> tempChannel; - rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), - nullptr, nullptr, getter_AddRefs(tempChannel)); + nsCOMPtr<nsIURI> tempURI; + rv = NS_NewURI(getter_AddRefs(tempURI), + nsDependentCString(kRedirMap[i].url)); + NS_ENSURE_SUCCESS(rv, rv); + rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), + tempURI, + aLoadInfo); NS_ENSURE_SUCCESS(rv, rv); tempChannel->SetOriginalURI(aURI); diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js index 46e867068..054f0405f 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js @@ -41,22 +41,6 @@ const DOWNLOAD_VIEW_SUPPORTED_COMMANDS = const NOT_AVAILABLE = Number.MAX_VALUE; /** - * Download a URL. - * - * @param aURL - * the url to download (nsIURI object) - * @param [optional] aFileName - * the destination file name - */ -function DownloadURL(aURL, aFileName) { - // For private browsing, try to get document out of the most recent browser - // window, or provide our own if there's no browser window. - let browserWin = RecentWindow.getMostRecentBrowserWindow(); - let initiatingDoc = browserWin ? browserWin.document : document; - saveURL(aURL, aFileName, null, true, true, undefined, initiatingDoc); -} - -/** * A download element shell is responsible for handling the commands and the * displayed data for a single download view element. The download element * could represent either a past download (for which we get data from places) or @@ -654,7 +638,10 @@ DownloadElementShell.prototype = { // In future we may try to download into the same original target uri, when // we have it. Though that requires verifying the path is still valid and // may surprise the user if he wants to be requested every time. - DownloadURL(this.downloadURI, this.getDownloadMetaData().fileName); + let browserWin = RecentWindow.getMostRecentBrowserWindow(); + let initiatingDoc = browserWin ? browserWin.document : document; + DownloadURL(this.downloadURI, this.getDownloadMetaData().fileName, + initiatingDoc); }, /* nsIController */ @@ -1407,16 +1394,11 @@ DownloadsPlacesView.prototype = { _copySelectedDownloadsToClipboard: function DPV__copySelectedDownloadsToClipboard() { - let selectedElements = this._richlistbox.selectedItems; - // Tycho: let urls = [e._shell.downloadURI for each (e in selectedElements)]; - let urls = []; - - for each (e in selectedElements) { - urls.push(e._shell.downloadURI); - } + let urls = [for (element of this._richlistbox.selectedItems) + element._shell.downloadURI]; Cc["@mozilla.org/widget/clipboardhelper;1"]. - getService(Ci.nsIClipboardHelper).copyString(urls.join("\n"), document); + getService(Ci.nsIClipboardHelper).copyString(urls.join("\n")); }, _getURLFromClipboardData: function DPV__getURLFromClipboardData() { @@ -1450,10 +1432,16 @@ DownloadsPlacesView.prototype = { _downloadURLFromClipboard: function DPV__downloadURLFromClipboard() { let [url, name] = this._getURLFromClipboardData(); - DownloadURL(url, name); + let browserWin = RecentWindow.getMostRecentBrowserWindow(); + let initiatingDoc = browserWin ? browserWin.document : document; + DownloadURL(url, name, initiatingDoc); }, doCommand: function DPV_doCommand(aCommand) { + // Commands may be invoked with keyboard shortcuts even if disabled. + if (!this.isCommandEnabled(aCommand)) { + return; + } switch (aCommand) { case "cmd_copy": this._copySelectedDownloadsToClipboard(); @@ -1504,6 +1492,11 @@ DownloadsPlacesView.prototype = { else contextMenu.removeAttribute("state"); + if (state == nsIDM.DOWNLOAD_DOWNLOADING) { + // The resumable property of a download may change at any time, so + // ensure we update the related command now. + goUpdateCommand("downloadsCmd_pauseResume"); + } return true; }, @@ -1594,10 +1587,16 @@ DownloadsPlacesView.prototype = { if (dt.mozGetDataAt("application/x-moz-file", 0)) return; - let name = { }; - let url = Services.droppedLinkHandler.dropLink(aEvent, name); - if (url) - DownloadURL(url, name.value); + let links = Services.droppedLinkHandler.dropLinks(aEvent); + if (!links.length) + return; + let browserWin = RecentWindow.getMostRecentBrowserWindow(); + let initiatingDoc = browserWin ? browserWin.document : document; + for (let link of links) { + if (link.url.startsWith("about:")) + continue; + DownloadURL(link.url, link.name, initiatingDoc); + } } }; diff --git a/application/palemoon/components/downloads/content/downloads.js b/application/palemoon/components/downloads/content/downloads.js index 0412344bc..833d7d72f 100644 --- a/application/palemoon/components/downloads/content/downloads.js +++ b/application/palemoon/components/downloads/content/downloads.js @@ -507,8 +507,7 @@ const DownloadsPanel = { let uri = NetUtil.newURI(url); DownloadsCommon.log("Pasted URL seems valid. Starting download."); - saveURL(uri.spec, name || uri.spec, null, true, true, - undefined, document); + DownloadURL(uri.spec, name, document); } catch (ex) {} }, diff --git a/application/palemoon/components/downloads/content/indicator.js b/application/palemoon/components/downloads/content/indicator.js index e6a5bd012..1a2175a92 100644 --- a/application/palemoon/components/downloads/content/indicator.js +++ b/application/palemoon/components/downloads/content/indicator.js @@ -548,15 +548,18 @@ const DownloadsIndicatorView = { if (dt.mozGetDataAt("application/x-moz-file", 0)) return; - let name = {}; - let url = browserDragAndDrop.drop(aEvent, name); - if (url) { - if (url.startsWith("about:")) { - return; - } - - let sourceDoc = dt.mozSourceNode ? dt.mozSourceNode.ownerDocument : document; - saveURL(url, name.value, null, true, true, null, sourceDoc); + let links = browserDragAndDrop.dropLinks(aEvent); + if (!links.length) + return; + let sourceDoc = dt.mozSourceNode ? dt.mozSourceNode.ownerDocument : document; + let handled = false; + for (let link of links) { + if (link.url.startsWith("about:")) + continue; + saveURL(link.url, link.name, null, true, true, null, sourceDoc); + handled = true; + } + if (handled) { aEvent.preventDefault(); } }, diff --git a/application/palemoon/components/feeds/FeedWriter.js b/application/palemoon/components/feeds/FeedWriter.js index cbb146564..2ae31dffa 100644 --- a/application/palemoon/components/feeds/FeedWriter.js +++ b/application/palemoon/components/feeds/FeedWriter.js @@ -1173,7 +1173,7 @@ FeedWriter.prototype = { var secman = Cc["@mozilla.org/scriptsecuritymanager;1"]. getService(Ci.nsIScriptSecurityManager); - this._feedPrincipal = secman.getSimpleCodebasePrincipal(this._feedURI); + this._feedPrincipal = secman.createCodebasePrincipal(this._feedURI, {}); LOG("Subscribe Preview: feed uri = " + this._window.location.href); diff --git a/application/palemoon/components/nsBrowserGlue.js b/application/palemoon/components/nsBrowserGlue.js index 225cddd52..aa24d88ef 100644 --- a/application/palemoon/components/nsBrowserGlue.js +++ b/application/palemoon/components/nsBrowserGlue.js @@ -13,7 +13,11 @@ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -// Define Lazy Module Gitters +// Define Lazy Service Getters +XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", + "@mozilla.org/alerts-service;1", "nsIAlertsService"); + +// Define Lazy Module Getters [ ["AddonManager", "resource://gre/modules/AddonManager.jsm"], ["NetUtil", "resource://gre/modules/NetUtil.jsm"], @@ -37,8 +41,19 @@ Cu.import("resource://gre/modules/Services.jsm"); ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"], ["AutoCompletePopup", "resource:///modules/AutoCompletePopup.jsm"], ["DateTimePickerHelper", "resource://gre/modules/DateTimePickerHelper.jsm"], + ["ShellService", "resource:///modules/ShellService.jsm"], ].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); +// Define Lazy Getters + +XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() { + return Services.strings.createBundle('chrome://branding/locale/brand.properties'); +}); + +XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() { + return Services.strings.createBundle('chrome://browser/locale/browser.properties'); +}); + const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; @@ -460,9 +475,7 @@ BrowserGlue.prototype = { if (!win) return; - let productName = Services.strings - .createBundle("chrome://branding/locale/brand.properties") - .GetStringFromName("brandFullName"); + let productName = gBrandBundle.GetStringFromName("brandFullName"); let message = win.gNavigatorBundle.getFormattedString("slowStartup.message", [productName]); let buttons = [ @@ -559,17 +572,17 @@ BrowserGlue.prototype = { } // Perform default browser checking. - var shell; - try { - shell = Components.classes["@mozilla.org/browser/shell-service;1"] - .getService(Components.interfaces.nsIShellService); - } catch (e) { } - if (shell) { -#ifdef DEBUG - let shouldCheck = false; -#else - let shouldCheck = shell.shouldCheckDefaultBrowser; -#endif + if (ShellService) { + let shouldCheck = ShellService.shouldCheckDefaultBrowser; + + const skipDefaultBrowserCheck = + Services.prefs.getBoolPref("browser.shell.skipDefaultBrowserCheckOnFirstRun") && + Services.prefs.getBoolPref("browser.shell.skipDefaultBrowserCheck"); + + const usePromptLimit = false; + let promptCount = + usePromptLimit ? Services.prefs.getIntPref("browser.shell.defaultBrowserCheckCount") : 0; + let willRecoverSession = false; try { let ss = Cc["@mozilla.org/browser/sessionstartup;1"]. @@ -579,9 +592,25 @@ BrowserGlue.prototype = { } catch (ex) { /* never mind; suppose SessionStore is broken */ } - let isDefault = shell.isDefaultBrowser(true, false); // startup check, check all assoc + // startup check, check all assoc + let isDefault = false; + let isDefaultError = false; + try { + isDefault = ShellService.isDefaultBrowser(true, false); + } catch (ex) { + isDefaultError = true; + } - if (shouldCheck && !isDefault && !willRecoverSession) { + if (isDefault) { + let now = (Math.floor(Date.now() / 1000)).toString(); + Services.prefs.setCharPref("browser.shell.mostRecentDateSetAsDefault", now); + } + + let willPrompt = shouldCheck && !isDefault && !willRecoverSession; + + // Skip the "Set Default Browser" check during first-run or after the + // browser has been run a few times. + if (willPrompt) { Services.tm.mainThread.dispatch(function() { var win = this.getMostRecentBrowserWindow(); var brandBundle = win.document.getElementById("bundle_brand"); @@ -610,9 +639,9 @@ BrowserGlue.prototype = { claimAllTypes = (parseFloat(version) < 6.2); } catch (ex) { } #endif - shell.setDefaultBrowser(claimAllTypes, false); + ShellService.setDefaultBrowser(claimAllTypes, false); } - shell.shouldCheckDefaultBrowser = checkEveryTime.value; + ShellService.shouldCheckDefaultBrowser = checkEveryTime.value; }.bind(this), Ci.nsIThread.DISPATCH_NORMAL); } } @@ -693,9 +722,8 @@ BrowserGlue.prototype = { let prompt = Services.prompt; let quitBundle = Services.strings.createBundle("chrome://browser/locale/quitDialog.properties"); - let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); - let appName = brandBundle.GetStringFromName("brandShortName"); + let appName = gBrandBundle.GetStringFromName("brandShortName"); let quitDialogTitle = quitBundle.formatStringFromName("quitDialogTitle", [appName], 1); let neverAskText = quitBundle.GetStringFromName("neverAsk2"); @@ -772,9 +800,7 @@ BrowserGlue.prototype = { var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]. getService(Ci.nsIURLFormatter); - var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); - var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); - var appName = brandBundle.GetStringFromName("brandShortName"); + var appName = gBrandBundle.GetStringFromName("brandShortName"); function getNotifyString(aPropData) { var propValue = update.getProperty(aPropData.propName); @@ -782,11 +808,11 @@ BrowserGlue.prototype = { if (aPropData.prefName) propValue = formatter.formatURLPref(aPropData.prefName); else if (aPropData.stringParams) - propValue = browserBundle.formatStringFromName(aPropData.stringName, - aPropData.stringParams, - aPropData.stringParams.length); + propValue = gBrowserBundle.formatStringFromName(aPropData.stringName, + aPropData.stringParams, + aPropData.stringParams.length); else - propValue = browserBundle.GetStringFromName(aPropData.stringName); + propValue = gBrowserBundle.GetStringFromName(aPropData.stringName); } return propValue; } @@ -825,16 +851,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 +872,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); } }, @@ -1156,8 +1173,7 @@ BrowserGlue.prototype = { * Show the notificationBox for a locked places database. */ _showPlacesLockedNotificationBox: function BG__showPlacesLockedNotificationBox() { - var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); - var applicationName = brandBundle.GetStringFromName("brandShortName"); + var applicationName = gBrandBundle.GetStringFromName("brandShortName"); var placesBundle = Services.strings.createBundle("chrome://browser/locale/places/places.properties"); var title = placesBundle.GetStringFromName("lockPrompt.title"); var text = placesBundle.formatStringFromName("lockPrompt.text", [applicationName], 1); @@ -1191,7 +1207,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 +1402,10 @@ BrowserGlue.prototype = { } } + if (currentUIVersion < 17) { + this._notifyNotificationsUpgrade(); + } + if (this._dirty) this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush(); @@ -1396,6 +1416,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 +1711,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. * @@ -1665,8 +1741,6 @@ ContentPermissionPrompt.prototype = { popup.remove(); } - var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); - var requestingWindow = aRequest.window.top; var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject; var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document); @@ -1692,8 +1766,8 @@ ContentPermissionPrompt.prototype = { } var action = { - label: browserBundle.GetStringFromName(promptAction.stringId), - accessKey: browserBundle.GetStringFromName(promptAction.stringId + ".accesskey"), + label: gBrowserBundle.GetStringFromName(promptAction.stringId), + accessKey: gBrowserBundle.GetStringFromName(promptAction.stringId + ".accesskey"), callback: function() { if (promptAction.callback) { promptAction.callback(); @@ -1752,7 +1826,6 @@ ContentPermissionPrompt.prototype = { }, _promptGeo : function(aRequest) { - var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); var requestingURI = aRequest.principal.URI; var message; @@ -1768,11 +1841,11 @@ ContentPermissionPrompt.prototype = { }]; if (requestingURI.schemeIs("file")) { - message = browserBundle.formatStringFromName("geolocation.shareWithFile", - [requestingURI.path], 1); + message = gBrowserBundle.formatStringFromName("geolocation.shareWithFile", + [requestingURI.path], 1); } else { - message = browserBundle.formatStringFromName("geolocation.shareWithSite", - [requestingURI.host], 1); + message = gBrowserBundle.formatStringFromName("geolocation.shareWithSite", + [requestingURI.host], 1); // Always share location action. actions.push({ stringId: "geolocation.alwaysShareLocation", @@ -1803,47 +1876,63 @@ ContentPermissionPrompt.prototype = { }, _promptWebNotifications : function(aRequest) { - var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); var requestingURI = aRequest.principal.URI; - var message = browserBundle.formatStringFromName("webNotifications.showFromSite", - [requestingURI.host], 1); + var message = gBrowserBundle.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) { - - let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); let requestingURI = aRequest.principal.URI; let originString = requestingURI.schemeIs("file") ? requestingURI.path : requestingURI.host; - let message = browserBundle.formatStringFromName(autoAllow ? - "pointerLock.autoLock.title2" : "pointerLock.title2", - [originString], 1); + let message = gBrowserBundle.formatStringFromName(autoAllow ? + "pointerLock.autoLock.title2" : "pointerLock.title2", + [originString], 1); // If this is an autoAllow info prompt, offer no actions. // _showPrompt() will allow the request when it's dismissed. let actions = []; @@ -1875,7 +1964,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 +2009,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/places/content/editBookmarkOverlay.js b/application/palemoon/components/places/content/editBookmarkOverlay.js index 43645cc73..69d7d32eb 100644 --- a/application/palemoon/components/places/content/editBookmarkOverlay.js +++ b/application/palemoon/components/places/content/editBookmarkOverlay.js @@ -12,6 +12,7 @@ var gEditItemOverlay = { _uris: [], _tags: [], _allTags: [], + _keyword: null, _multiEdit: false, _itemType: -1, _readOnly: false, @@ -139,9 +140,8 @@ var gEditItemOverlay = { this._itemType = PlacesUtils.bookmarks.getItemType(this._itemId); if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) { this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._itemId); - this._initTextField("keywordField", - PlacesUtils.bookmarks - .getKeywordForBookmark(this._itemId)); + this._keyword = PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId); + this._initTextField("keywordField", this._keyword); this._element("loadInSidebarCheckbox").checked = PlacesUtils.annotations.itemHasAnnotation(this._itemId, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO); @@ -610,9 +610,13 @@ var gEditItemOverlay = { }, onKeywordFieldBlur: function EIO_onKeywordFieldBlur() { - var keyword = this._element("keywordField").value; - if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) { - var txn = new PlacesEditBookmarkKeywordTransaction(this._itemId, keyword); + let oldKeyword = this._keyword; + let keyword = this._keyword = this._element("keywordField").value; + if (keyword != oldKeyword) { + let txn = new PlacesEditBookmarkKeywordTransaction(this._itemId, + keyword, + null, + oldKeyword); PlacesUtils.transactionManager.doTransaction(txn); } }, @@ -1004,9 +1008,8 @@ var gEditItemOverlay = { } break; case "keyword": - this._initTextField("keywordField", - PlacesUtils.bookmarks - .getKeywordForBookmark(this._itemId)); + this._keyword = PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId); + this._initTextField("keywordField", this._keyword); break; case PlacesUIUtils.DESCRIPTION_ANNO: this._initTextField("descriptionField", diff --git a/application/palemoon/components/preferences/aboutPermissions.js b/application/palemoon/components/preferences/aboutPermissions.js index 31b48f88e..9fb12d081 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); } } @@ -419,31 +418,6 @@ var PermissionDefaults = { Services.prefs.setBoolPref("dom.indexedDB.enabled", value); }, - get fullscreen() { - if (!Services.prefs.getBoolPref("full-screen-api.enabled")) { - return this.DENY; - } - // We always ask for permission to fullscreen with a specific site, - // so there is no global ALLOW. - return this.UNKNOWN; - }, - set fullscreen(aValue) { - let value = (aValue != this.DENY); - Services.prefs.setBoolPref("full-screen-api.enabled", value); - }, - - get pointerLock() { - if (!Services.prefs.getBoolPref("full-screen-api.pointer-lock.enabled")) { - return this.DENY; - } - // We always ask for permission to hide the mouse pointer - // with a specific site, so there is no global ALLOW. - return this.UNKNOWN; - }, - set pointerLock(aValue) { - let value = (aValue != this.DENY); - Services.prefs.setBoolPref("full-screen-api.pointer-lock.enabled", value); - }, } /** @@ -461,10 +435,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, @@ -482,14 +464,12 @@ var AboutPermissions = { * Potential future additions: "sts/use", "sts/subd" */ _supportedPermissions: ["password", "image", "popup", "cookie", - "desktop-notification", "install", "geo", "indexedDB", - "fullscreen", "pointerLock"], + "desktop-notification", "install", "geo", "indexedDB"], /** * Permissions that don't have a global "Allow" option. */ - _noGlobalAllow: ["desktop-notification", "geo", "indexedDB", "fullscreen", - "pointerLock"], + _noGlobalAllow: ["desktop-notification", "geo", "indexedDB"], /** * Permissions that don't have a global "Deny" option. @@ -536,8 +516,6 @@ var AboutPermissions = { Services.prefs.addObserver("geo.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("permissions.places-sites-limit", this, false); Services.obs.addObserver(this, "perm-changed", false); @@ -688,8 +666,6 @@ var AboutPermissions = { Services.prefs.removeObserver("geo.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("permissions.places-sites-limit", this, false); Services.obs.removeObserver(this, "perm-changed"); @@ -721,9 +697,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 +774,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 +832,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 +849,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 +868,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 +879,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 +900,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 +908,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 +931,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 +962,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 +972,7 @@ var AboutPermissions = { } this.sitesList.removeChild(site.listitem); - delete this._sites[site.host]; + delete this._sites[site.principal.origin]; } } }, @@ -1009,9 +988,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 +1224,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 +1292,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 +1309,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..56d6cfbbf 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> @@ -332,65 +336,6 @@ <vbox id="plugins-box"/> </vbox> </hbox> - - <!-- Fullscreen --> - <hbox id="fullscreen-pref-item" - class="pref-item" align="top"> - <image class="pref-icon" type="fullscreen"/> - <vbox> - <hbox> - <label class="pref-title" value="&fullscreen.label;"/> - <label id="fullscreen-default" class="pref-default" value="*"/> - </hbox> - <hbox align="center"> - <menulist id="fullscreen-menulist" - class="pref-menulist" - type="fullscreen" - oncommand="AboutPermissions.onPermissionCommand(event, false);"> - <menupopup> - <menuitem id="fullscreen-0" value="0" label="&permission.alwaysAsk;"/> - <menuitem id="fullscreen-1" value="1" label="&permission.allow;"/> - <menuitem id="fullscreen-2" value="2" label="&permission.block;"/> - </menupopup> - </menulist> - <button id="fullscreen-set-default" - class="pref-set-default" - label="&permission.default;" - type="fullscreen" - oncommand="AboutPermissions.onPermissionCommand(event, true);"/> - </hbox> - </vbox> - </hbox> - - <!-- PointerLock --> - <hbox id="pointerLock-pref-item" - class="pref-item" align="top"> - <image class="pref-icon" type="pointerLock"/> - <vbox> - <hbox> - <label class="pref-title" value="&pointerLock.label;"/> - <label id="pointerLock-default" class="pref-default" value="*"/> - </hbox> - <hbox> - <menulist id="pointerLock-menulist" - class="pref-menulist" - type="pointerLock" - oncommand="AboutPermissions.onPermissionCommand(event, false);"> - <menupopup> - <menuitem id="pointerLock-0" value="0" label="&permission.alwaysAsk;"/> - <menuitem id="pointerLock-1" value="1" label="&permission.allow;"/> - <menuitem id="pointerLock-2" value="2" label="&permission.block;"/> - </menupopup> - </menulist> - <button id="pointerLock-set-default" - class="pref-set-default" - label="&permission.default;" - type="pointerLock" - oncommand="AboutPermissions.onPermissionCommand(event, true);"/> - </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/content.js b/application/palemoon/components/preferences/content.js index 0775c6270..5ae84c2f7 100644 --- a/application/palemoon/components/preferences/content.js +++ b/application/palemoon/components/preferences/content.js @@ -38,33 +38,11 @@ var gContentPane = { */ updateMSE: function () { - var checkboxMSENFR = document.getElementById('videoMSENFR'); var checkboxMSEMP4 = document.getElementById('videoMSEMP4'); var checkboxMSEWebM = document.getElementById('videoMSEWebM'); var preference = document.getElementById('media.mediasource.enabled'); - checkboxMSENFR.disabled = preference.value != true; checkboxMSEMP4.disabled = preference.value != true; checkboxMSEWebM.disabled = preference.value != true; - // Check and disable WebM if necessary - if (preference.value == true) { - this.updateMSEWebM(); - } - }, - - /** - * Utility function to enable/disable the checkbox for MSE+WebM depending - * on the value of media.mediasource.format-reader. - */ - updateMSEWebM: function () - { - var checkboxMSEWebM = document.getElementById('videoMSEWebM'); - var preference = document.getElementById('media.mediasource.format-reader'); - checkboxMSEWebM.disabled = preference.value == true; - if (preference.value == true) { - // Switch off incompatible format - Services.prefs.setBoolPref('media.mediasource.webm.enabled', false); - checkboxMSEWebM.checked = false; - } }, // BEGIN UI CODE diff --git a/application/palemoon/components/preferences/content.xul b/application/palemoon/components/preferences/content.xul index 22b6ce229..23d942e45 100644 --- a/application/palemoon/components/preferences/content.xul +++ b/application/palemoon/components/preferences/content.xul @@ -33,10 +33,7 @@ onchange="gContentPane._rebuildFonts();"/> <!-- VIDEO --> - <preference id="media.mediasource.enabled" name="media.mediasource.enabled" type="bool" - onchange="gContentPane.updateMSE();" /> - <preference id="media.mediasource.format-reader" name="media.mediasource.format-reader" type="bool" - onchange="gContentPane.updateMSEWebM();" /> + <preference id="media.mediasource.enabled" name="media.mediasource.enabled" type="bool"/> <preference id="media.mediasource.mp4.enabled" name="media.mediasource.mp4.enabled" type="bool"/> <preference id="media.mediasource.webm.enabled" name="media.mediasource.webm.enabled" type="bool"/> @@ -163,8 +160,6 @@ <checkbox id="videoMSE" preference="media.mediasource.enabled" label="&videoMSE.label;" accesskey="&videoMSE.accesskey;" onsyncfrompreference="gContentPane.updateMSE();"/> - <checkbox class="indent" id="videoMSENFR" preference="media.mediasource.format-reader" - label="&videoMSENFR.label;" accesskey="&videoMSENFR.accesskey;"/> <checkbox class="indent" id="videoMSEMP4" preference="media.mediasource.mp4.enabled" label="&videoMSEMP4.label;" accesskey="&videoMSEMP4.accesskey;"/> <checkbox class="indent" id="videoMSEWebM" preference="media.mediasource.webm.enabled" 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/components/sessionstore/SessionStore.jsm b/application/palemoon/components/sessionstore/SessionStore.jsm index f7c495be8..4f95f10a7 100644 --- a/application/palemoon/components/sessionstore/SessionStore.jsm +++ b/application/palemoon/components/sessionstore/SessionStore.jsm @@ -1951,7 +1951,13 @@ var SessionStoreInternal = { // userTypedValue. if (browser.userTypedValue) { tabData.userTypedValue = browser.userTypedValue; - tabData.userTypedClear = browser.userTypedClear; + // We always used to keep track of the loading state as an integer, where + // '0' indicated the user had typed since the last load (or no load was + // ongoing), and any positive value indicated we had started a load since + // the last time the user typed in the URL bar. Mimic this to keep the + // session store representation in sync, even though we now represent this + // more explicitly: + tabData.userTypedClear = browser.didStartLoadSinceLastUserTyping() ? 1 : 0; } else { delete tabData.userTypedValue; delete tabData.userTypedClear; @@ -2079,7 +2085,7 @@ var SessionStoreInternal = { } catch (ex) { debug(ex); } // POSTDATA is tricky - especially since some extensions don't get it right - if (aEntry.owner) { + if (aEntry.triggeringPrincipal) { // Not catching anything specific here, just possible errors // from writeCompoundObject and the like. try { @@ -2088,19 +2094,19 @@ var SessionStoreInternal = { var pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe); pipe.init(false, false, 0, 0xffffffff, null); binaryStream.setOutputStream(pipe.outputStream); - binaryStream.writeCompoundObject(aEntry.owner, Ci.nsISupports, true); + binaryStream.writeCompoundObject(aEntry.triggeringPrincipal, Ci.nsIPrincipal, true); binaryStream.close(); // Now we want to read the data from the pipe's input end and encode it. var scriptableStream = Cc["@mozilla.org/binaryinputstream;1"]. createInstance(Ci.nsIBinaryInputStream); scriptableStream.setInputStream(pipe.inputStream); - var ownerBytes = + var triggeringPrincipalBytes = scriptableStream.readByteArray(scriptableStream.available()); // We can stop doing base64 encoding once our serialization into JSON // is guaranteed to handle all chars in strings, including embedded // nulls. - entry.owner_b64 = btoa(String.fromCharCode.apply(null, ownerBytes)); + entry.triggeringPrincipal_b64 = btoa(String.fromCharCode.apply(null, triggeringPrincipalBytes)); } catch (ex) { debug(ex); } } @@ -3394,16 +3400,24 @@ var SessionStoreInternal = { } } - if (aEntry.owner_b64) { - var ownerInput = Cc["@mozilla.org/io/string-input-stream;1"]. - createInstance(Ci.nsIStringInputStream); - var binaryData = atob(aEntry.owner_b64); - ownerInput.setData(binaryData, binaryData.length); + // The field aEntry.owner_b64 got renamed to aEntry.triggeringPricipal_b64 in + // Bug 1286472. To remain backward compatible we still have to support that + // field for a few cycles before we can remove it within Bug 1289785. + if (aEntry.owner_b64) { + aEntry.triggeringPrincipal_b64 = aEntry.owner_b64; + delete aEntry.owner_b64; + } + + if (aEntry.triggeringPrincipal_b64) { + var triggeringPrincipalInput = Cc["@mozilla.org/io/string-input-stream;1"]. + createInstance(Ci.nsIStringInputStream); + var binaryData = atob(aEntry.triggeringPrincipal_b64); + triggeringPrincipalInput.setData(binaryData, binaryData.length); var binaryStream = Cc["@mozilla.org/binaryinputstream;1"]. createInstance(Ci.nsIObjectInputStream); - binaryStream.setInputStream(ownerInput); + binaryStream.setInputStream(triggeringPrincipalInput); try { // Catch possible deserialization exceptions - shEntry.owner = binaryStream.readObject(true); + shEntry.triggeringPrincipal = binaryStream.readObject(true); } catch (ex) { debug(ex); } } |