diff -r 000000000000 -r 6474c204b198 webapprt/ContentPermission.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webapprt/ContentPermission.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,118 @@ +/* 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/. */ + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +const UNKNOWN_FAIL = ["geolocation", "desktop-notification"]; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://webapprt/modules/WebappRT.jsm"); + +function ContentPermission() {} + +ContentPermission.prototype = { + classID: Components.ID("{07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]), + + _getChromeWindow: function(aWindow) { + return aWindow + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow) + .QueryInterface(Ci.nsIDOMChromeWindow); + }, + + prompt: function(request) { + // Only allow exactly one permission request here. + let types = request.types.QueryInterface(Ci.nsIArray); + if (types.length != 1) { + request.cancel(); + return; + } + let perm = types.queryElementAt(0, Ci.nsIContentPermissionType); + + // Reuse any remembered permission preferences + let result = + Services.perms.testExactPermissionFromPrincipal(request.principal, + perm.type); + + // We used to use the name "geo" for the geolocation permission, now we're + // using "geolocation". We need to check both to support existing + // installations. + if ((result == Ci.nsIPermissionManager.UNKNOWN_ACTION || + result == Ci.nsIPermissionManager.PROMPT_ACTION) && + perm.type == "geolocation") { + let geoResult = Services.perms.testExactPermission(request.principal.URI, + "geo"); + // We override the result only if the "geo" permission was allowed or + // denied. + if (geoResult == Ci.nsIPermissionManager.ALLOW_ACTION || + geoResult == Ci.nsIPermissionManager.DENY_ACTION) { + result = geoResult; + } + } + + if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { + request.allow(); + return; + } else if (result == Ci.nsIPermissionManager.DENY_ACTION || + (result == Ci.nsIPermissionManager.UNKNOWN_ACTION && + UNKNOWN_FAIL.indexOf(perm.type) >= 0)) { + request.cancel(); + return; + } + + // Display a prompt at the top level + let {name} = WebappRT.localeManifest; + let requestingWindow = request.window.top; + let chromeWin = this._getChromeWindow(requestingWindow); + let bundle = Services.strings.createBundle("chrome://webapprt/locale/webapp.properties"); + + // Construct a prompt with share/don't and remember checkbox + let remember = {value: false}; + let choice = Services.prompt.confirmEx( + chromeWin, + bundle.formatStringFromName(perm.type + ".title", [name], 1), + bundle.GetStringFromName(perm.type + ".description"), + // Set both buttons to strings with the cancel button being default + Ci.nsIPromptService.BUTTON_POS_1_DEFAULT | + Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 | + Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1, + bundle.GetStringFromName(perm.type + ".allow"), + bundle.GetStringFromName(perm.type + ".deny"), + null, + bundle.GetStringFromName(perm.type + ".remember"), + remember); + + let action = Ci.nsIPermissionManager.ALLOW_ACTION; + if (choice != 0) { + action = Ci.nsIPermissionManager.DENY_ACTION; + } + + if (remember.value) { + // Persist the choice if the user wants to remember + Services.perms.addFromPrincipal(request.principal, perm.type, action); + } else { + // Otherwise allow the permission for the current session + Services.perms.addFromPrincipal(request.principal, perm.type, action, + Ci.nsIPermissionManager.EXPIRE_SESSION); + } + + // Trigger the selected choice + if (choice == 0) { + request.allow(); + } + else { + request.cancel(); + } + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermission]);