|
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 |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 this.EXPORTED_SYMBOLS = [ "SitePermissions" ]; |
|
6 |
|
7 Components.utils.import("resource://gre/modules/Services.jsm"); |
|
8 |
|
9 let gStringBundle = |
|
10 Services.strings.createBundle("chrome://browser/locale/sitePermissions.properties"); |
|
11 |
|
12 this.SitePermissions = { |
|
13 |
|
14 UNKNOWN: Services.perms.UNKNOWN_ACTION, |
|
15 ALLOW: Services.perms.ALLOW_ACTION, |
|
16 BLOCK: Services.perms.DENY_ACTION, |
|
17 SESSION: Components.interfaces.nsICookiePermission.ACCESS_SESSION, |
|
18 |
|
19 /* Checks whether a UI for managing permissions should be exposed for a given |
|
20 * URI. This excludes file URIs, for instance, as they don't have a host, |
|
21 * even though nsIPermissionManager can still handle them. |
|
22 */ |
|
23 isSupportedURI: function (aURI) { |
|
24 return aURI.schemeIs("http") || aURI.schemeIs("https"); |
|
25 }, |
|
26 |
|
27 /* Returns an array of all permission IDs. |
|
28 */ |
|
29 listPermissions: function () { |
|
30 let array = Object.keys(gPermissionObject); |
|
31 array.sort((a, b) => { |
|
32 return this.getPermissionLabel(a).localeCompare(this.getPermissionLabel(b)); |
|
33 }); |
|
34 return array; |
|
35 }, |
|
36 |
|
37 /* Returns an array of permission states to be exposed to the user for a |
|
38 * permission with the given ID. |
|
39 */ |
|
40 getAvailableStates: function (aPermissionID) { |
|
41 if (aPermissionID in gPermissionObject && |
|
42 gPermissionObject[aPermissionID].states) |
|
43 return gPermissionObject[aPermissionID].states; |
|
44 |
|
45 if (this.getDefault(aPermissionID) == this.UNKNOWN) |
|
46 return [ SitePermissions.UNKNOWN, SitePermissions.ALLOW, SitePermissions.BLOCK ]; |
|
47 |
|
48 return [ SitePermissions.ALLOW, SitePermissions.BLOCK ]; |
|
49 }, |
|
50 |
|
51 /* Returns the default state of a particular permission. |
|
52 */ |
|
53 getDefault: function (aPermissionID) { |
|
54 if (aPermissionID in gPermissionObject && |
|
55 gPermissionObject[aPermissionID].getDefault) |
|
56 return gPermissionObject[aPermissionID].getDefault(); |
|
57 |
|
58 return this.UNKNOWN; |
|
59 }, |
|
60 |
|
61 /* Returns the state of a particular permission for a given URI. |
|
62 */ |
|
63 get: function (aURI, aPermissionID) { |
|
64 if (!this.isSupportedURI(aURI)) |
|
65 return this.UNKNOWN; |
|
66 |
|
67 let state; |
|
68 if (aPermissionID in gPermissionObject && |
|
69 gPermissionObject[aPermissionID].exactHostMatch) |
|
70 state = Services.perms.testExactPermission(aURI, aPermissionID); |
|
71 else |
|
72 state = Services.perms.testPermission(aURI, aPermissionID); |
|
73 return state; |
|
74 }, |
|
75 |
|
76 /* Sets the state of a particular permission for a given URI. |
|
77 */ |
|
78 set: function (aURI, aPermissionID, aState) { |
|
79 if (!this.isSupportedURI(aURI)) |
|
80 return; |
|
81 |
|
82 if (aState == this.UNKNOWN) { |
|
83 this.remove(aURI, aPermissionID); |
|
84 return; |
|
85 } |
|
86 |
|
87 Services.perms.add(aURI, aPermissionID, aState); |
|
88 |
|
89 if (aPermissionID in gPermissionObject && |
|
90 gPermissionObject[aPermissionID].onChange) |
|
91 gPermissionObject[aPermissionID].onChange(aURI, aState); |
|
92 }, |
|
93 |
|
94 /* Removes the saved state of a particular permission for a given URI. |
|
95 */ |
|
96 remove: function (aURI, aPermissionID) { |
|
97 if (!this.isSupportedURI(aURI)) |
|
98 return; |
|
99 |
|
100 Services.perms.remove(aURI.host, aPermissionID); |
|
101 |
|
102 if (aPermissionID in gPermissionObject && |
|
103 gPermissionObject[aPermissionID].onChange) |
|
104 gPermissionObject[aPermissionID].onChange(aURI, this.UNKNOWN); |
|
105 }, |
|
106 |
|
107 /* Returns the localized label for the permission with the given ID, to be |
|
108 * used in a UI for managing permissions. |
|
109 */ |
|
110 getPermissionLabel: function (aPermissionID) { |
|
111 return gStringBundle.GetStringFromName("permission." + aPermissionID + ".label"); |
|
112 }, |
|
113 |
|
114 /* Returns the localized label for the given permission state, to be used in |
|
115 * a UI for managing permissions. |
|
116 */ |
|
117 getStateLabel: function (aPermissionID, aState) { |
|
118 if (aPermissionID in gPermissionObject && |
|
119 gPermissionObject[aPermissionID].getStateLabel) { |
|
120 let label = gPermissionObject[aPermissionID].getStateLabel(aState); |
|
121 if (label) |
|
122 return label; |
|
123 } |
|
124 |
|
125 switch (aState) { |
|
126 case this.UNKNOWN: |
|
127 return gStringBundle.GetStringFromName("alwaysAsk"); |
|
128 case this.ALLOW: |
|
129 return gStringBundle.GetStringFromName("allow"); |
|
130 case this.SESSION: |
|
131 return gStringBundle.GetStringFromName("allowForSession"); |
|
132 case this.BLOCK: |
|
133 return gStringBundle.GetStringFromName("block"); |
|
134 default: |
|
135 throw new Error("unknown permission state"); |
|
136 } |
|
137 } |
|
138 }; |
|
139 |
|
140 let gPermissionObject = { |
|
141 /* Holds permission ID => options pairs. |
|
142 * |
|
143 * Supported options: |
|
144 * |
|
145 * - exactHostMatch |
|
146 * Allows sub domains to have their own permissions. |
|
147 * Defaults to false. |
|
148 * |
|
149 * - getDefault |
|
150 * Called to get the permission's default state. |
|
151 * Defaults to UNKNOWN, indicating that the user will be asked each time |
|
152 * a page asks for that permissions. |
|
153 * |
|
154 * - getStateLabel |
|
155 * Called to get the localized label for the given permission state, to be |
|
156 * used in a UI for managing permissions. May return null for states that |
|
157 * should use their default label. |
|
158 * |
|
159 * - onChange |
|
160 * Called when a permission state changes. |
|
161 * |
|
162 * - states |
|
163 * Array of permission states to be exposed to the user. |
|
164 * Defaults to ALLOW, BLOCK and the default state (see getDefault). |
|
165 */ |
|
166 |
|
167 "image": { |
|
168 getDefault: function () { |
|
169 return Services.prefs.getIntPref("permissions.default.image") == 2 ? |
|
170 SitePermissions.BLOCK : SitePermissions.ALLOW; |
|
171 } |
|
172 }, |
|
173 |
|
174 "cookie": { |
|
175 states: [ SitePermissions.ALLOW, SitePermissions.SESSION, SitePermissions.BLOCK ], |
|
176 getDefault: function () { |
|
177 if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == 2) |
|
178 return SitePermissions.BLOCK; |
|
179 |
|
180 if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == 2) |
|
181 return SitePermissions.SESSION; |
|
182 |
|
183 return SitePermissions.ALLOW; |
|
184 } |
|
185 }, |
|
186 |
|
187 "desktop-notification": {}, |
|
188 |
|
189 "camera": {}, |
|
190 "microphone": {}, |
|
191 |
|
192 "popup": { |
|
193 getDefault: function () { |
|
194 return Services.prefs.getBoolPref("dom.disable_open_during_load") ? |
|
195 SitePermissions.BLOCK : SitePermissions.ALLOW; |
|
196 } |
|
197 }, |
|
198 |
|
199 "install": { |
|
200 getDefault: function () { |
|
201 return Services.prefs.getBoolPref("xpinstall.whitelist.required") ? |
|
202 SitePermissions.BLOCK : SitePermissions.ALLOW; |
|
203 } |
|
204 }, |
|
205 |
|
206 "geo": { |
|
207 exactHostMatch: true |
|
208 }, |
|
209 |
|
210 "indexedDB": { |
|
211 states: [ SitePermissions.ALLOW, SitePermissions.UNKNOWN, SitePermissions.BLOCK ], |
|
212 getStateLabel: function (aState) { |
|
213 // indexedDB redefines nsIPermissionManager.UNKNOWN_ACTION (the default) |
|
214 // as "allow" and nsIPermissionManager.ALLOW_ACTION as "ask the user." |
|
215 switch (aState) { |
|
216 case SitePermissions.UNKNOWN: |
|
217 return gStringBundle.GetStringFromName("allow"); |
|
218 case SitePermissions.ALLOW: |
|
219 return gStringBundle.GetStringFromName("alwaysAsk"); |
|
220 default: |
|
221 return null; |
|
222 } |
|
223 }, |
|
224 onChange: function (aURI, aState) { |
|
225 if (aState == SitePermissions.ALLOW || aState == SitePermissions.BLOCK) |
|
226 Services.perms.remove(aURI.host, "indexedDB-unlimited"); |
|
227 } |
|
228 }, |
|
229 |
|
230 "fullscreen": {}, |
|
231 |
|
232 "pointerLock": { |
|
233 exactHostMatch: true |
|
234 } |
|
235 }; |