|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Cc = Components.classes; |
|
6 const Ci = Components.interfaces; |
|
7 const Cu = Components.utils; |
|
8 |
|
9 const UNKNOWN_FAIL = ["geolocation", "desktop-notification"]; |
|
10 |
|
11 Cu.import("resource://gre/modules/Services.jsm"); |
|
12 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
13 Cu.import("resource://webapprt/modules/WebappRT.jsm"); |
|
14 |
|
15 function ContentPermission() {} |
|
16 |
|
17 ContentPermission.prototype = { |
|
18 classID: Components.ID("{07ef5b2e-88fb-47bd-8cec-d3b0bef11ac4}"), |
|
19 QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]), |
|
20 |
|
21 _getChromeWindow: function(aWindow) { |
|
22 return aWindow |
|
23 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
24 .getInterface(Ci.nsIWebNavigation) |
|
25 .QueryInterface(Ci.nsIDocShellTreeItem) |
|
26 .rootTreeItem |
|
27 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
28 .getInterface(Ci.nsIDOMWindow) |
|
29 .QueryInterface(Ci.nsIDOMChromeWindow); |
|
30 }, |
|
31 |
|
32 prompt: function(request) { |
|
33 // Only allow exactly one permission request here. |
|
34 let types = request.types.QueryInterface(Ci.nsIArray); |
|
35 if (types.length != 1) { |
|
36 request.cancel(); |
|
37 return; |
|
38 } |
|
39 let perm = types.queryElementAt(0, Ci.nsIContentPermissionType); |
|
40 |
|
41 // Reuse any remembered permission preferences |
|
42 let result = |
|
43 Services.perms.testExactPermissionFromPrincipal(request.principal, |
|
44 perm.type); |
|
45 |
|
46 // We used to use the name "geo" for the geolocation permission, now we're |
|
47 // using "geolocation". We need to check both to support existing |
|
48 // installations. |
|
49 if ((result == Ci.nsIPermissionManager.UNKNOWN_ACTION || |
|
50 result == Ci.nsIPermissionManager.PROMPT_ACTION) && |
|
51 perm.type == "geolocation") { |
|
52 let geoResult = Services.perms.testExactPermission(request.principal.URI, |
|
53 "geo"); |
|
54 // We override the result only if the "geo" permission was allowed or |
|
55 // denied. |
|
56 if (geoResult == Ci.nsIPermissionManager.ALLOW_ACTION || |
|
57 geoResult == Ci.nsIPermissionManager.DENY_ACTION) { |
|
58 result = geoResult; |
|
59 } |
|
60 } |
|
61 |
|
62 if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { |
|
63 request.allow(); |
|
64 return; |
|
65 } else if (result == Ci.nsIPermissionManager.DENY_ACTION || |
|
66 (result == Ci.nsIPermissionManager.UNKNOWN_ACTION && |
|
67 UNKNOWN_FAIL.indexOf(perm.type) >= 0)) { |
|
68 request.cancel(); |
|
69 return; |
|
70 } |
|
71 |
|
72 // Display a prompt at the top level |
|
73 let {name} = WebappRT.localeManifest; |
|
74 let requestingWindow = request.window.top; |
|
75 let chromeWin = this._getChromeWindow(requestingWindow); |
|
76 let bundle = Services.strings.createBundle("chrome://webapprt/locale/webapp.properties"); |
|
77 |
|
78 // Construct a prompt with share/don't and remember checkbox |
|
79 let remember = {value: false}; |
|
80 let choice = Services.prompt.confirmEx( |
|
81 chromeWin, |
|
82 bundle.formatStringFromName(perm.type + ".title", [name], 1), |
|
83 bundle.GetStringFromName(perm.type + ".description"), |
|
84 // Set both buttons to strings with the cancel button being default |
|
85 Ci.nsIPromptService.BUTTON_POS_1_DEFAULT | |
|
86 Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0 | |
|
87 Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_1, |
|
88 bundle.GetStringFromName(perm.type + ".allow"), |
|
89 bundle.GetStringFromName(perm.type + ".deny"), |
|
90 null, |
|
91 bundle.GetStringFromName(perm.type + ".remember"), |
|
92 remember); |
|
93 |
|
94 let action = Ci.nsIPermissionManager.ALLOW_ACTION; |
|
95 if (choice != 0) { |
|
96 action = Ci.nsIPermissionManager.DENY_ACTION; |
|
97 } |
|
98 |
|
99 if (remember.value) { |
|
100 // Persist the choice if the user wants to remember |
|
101 Services.perms.addFromPrincipal(request.principal, perm.type, action); |
|
102 } else { |
|
103 // Otherwise allow the permission for the current session |
|
104 Services.perms.addFromPrincipal(request.principal, perm.type, action, |
|
105 Ci.nsIPermissionManager.EXPIRE_SESSION); |
|
106 } |
|
107 |
|
108 // Trigger the selected choice |
|
109 if (choice == 0) { |
|
110 request.allow(); |
|
111 } |
|
112 else { |
|
113 request.cancel(); |
|
114 } |
|
115 } |
|
116 }; |
|
117 |
|
118 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermission]); |