gecko-dev/webapprt/ContentPermission.js

119 lines
4.4 KiB
JavaScript

/* 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 rquest 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]);