|
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 const nsIPermissionManager = Components.interfaces.nsIPermissionManager; |
|
7 const nsICookiePermission = Components.interfaces.nsICookiePermission; |
|
8 |
|
9 const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions"; |
|
10 |
|
11 function Permission(host, rawHost, type, capability) |
|
12 { |
|
13 this.host = host; |
|
14 this.rawHost = rawHost; |
|
15 this.type = type; |
|
16 this.capability = capability; |
|
17 } |
|
18 |
|
19 var gPermissionManager = { |
|
20 _type : "", |
|
21 _permissions : [], |
|
22 _pm : Components.classes["@mozilla.org/permissionmanager;1"] |
|
23 .getService(Components.interfaces.nsIPermissionManager), |
|
24 _bundle : null, |
|
25 _tree : null, |
|
26 |
|
27 _view: { |
|
28 _rowCount: 0, |
|
29 get rowCount() |
|
30 { |
|
31 return this._rowCount; |
|
32 }, |
|
33 getCellText: function (aRow, aColumn) |
|
34 { |
|
35 if (aColumn.id == "siteCol") |
|
36 return gPermissionManager._permissions[aRow].rawHost; |
|
37 else if (aColumn.id == "statusCol") |
|
38 return gPermissionManager._permissions[aRow].capability; |
|
39 return ""; |
|
40 }, |
|
41 |
|
42 isSeparator: function(aIndex) { return false; }, |
|
43 isSorted: function() { return false; }, |
|
44 isContainer: function(aIndex) { return false; }, |
|
45 setTree: function(aTree){}, |
|
46 getImageSrc: function(aRow, aColumn) {}, |
|
47 getProgressMode: function(aRow, aColumn) {}, |
|
48 getCellValue: function(aRow, aColumn) {}, |
|
49 cycleHeader: function(column) {}, |
|
50 getRowProperties: function(row){ return ""; }, |
|
51 getColumnProperties: function(column){ return ""; }, |
|
52 getCellProperties: function(row,column){ |
|
53 if (column.element.getAttribute("id") == "siteCol") |
|
54 return "ltr"; |
|
55 |
|
56 return ""; |
|
57 } |
|
58 }, |
|
59 |
|
60 _getCapabilityString: function (aCapability) |
|
61 { |
|
62 var stringKey = null; |
|
63 switch (aCapability) { |
|
64 case nsIPermissionManager.ALLOW_ACTION: |
|
65 stringKey = "can"; |
|
66 break; |
|
67 case nsIPermissionManager.DENY_ACTION: |
|
68 stringKey = "cannot"; |
|
69 break; |
|
70 case nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY: |
|
71 stringKey = "canAccessFirstParty"; |
|
72 break; |
|
73 case nsICookiePermission.ACCESS_SESSION: |
|
74 stringKey = "canSession"; |
|
75 break; |
|
76 } |
|
77 return this._bundle.getString(stringKey); |
|
78 }, |
|
79 |
|
80 addPermission: function (aCapability) |
|
81 { |
|
82 var textbox = document.getElementById("url"); |
|
83 var host = textbox.value.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme |
|
84 try { |
|
85 var ioService = Components.classes["@mozilla.org/network/io-service;1"] |
|
86 .getService(Components.interfaces.nsIIOService); |
|
87 var uri = ioService.newURI("http://"+host, null, null); |
|
88 host = uri.host; |
|
89 } catch(ex) { |
|
90 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] |
|
91 .getService(Components.interfaces.nsIPromptService); |
|
92 var message = this._bundle.getString("invalidURI"); |
|
93 var title = this._bundle.getString("invalidURITitle"); |
|
94 promptService.alert(window, title, message); |
|
95 return; |
|
96 } |
|
97 |
|
98 var capabilityString = this._getCapabilityString(aCapability); |
|
99 |
|
100 // check whether the permission already exists, if not, add it |
|
101 var exists = false; |
|
102 for (var i = 0; i < this._permissions.length; ++i) { |
|
103 if (this._permissions[i].rawHost == host) { |
|
104 // Avoid calling the permission manager if the capability settings are |
|
105 // the same. Otherwise allow the call to the permissions manager to |
|
106 // update the listbox for us. |
|
107 exists = this._permissions[i].capability == capabilityString; |
|
108 break; |
|
109 } |
|
110 } |
|
111 |
|
112 if (!exists) { |
|
113 host = (host.charAt(0) == ".") ? host.substring(1,host.length) : host; |
|
114 var uri = ioService.newURI("http://" + host, null, null); |
|
115 this._pm.add(uri, this._type, aCapability); |
|
116 } |
|
117 textbox.value = ""; |
|
118 textbox.focus(); |
|
119 |
|
120 // covers a case where the site exists already, so the buttons don't disable |
|
121 this.onHostInput(textbox); |
|
122 |
|
123 // enable "remove all" button as needed |
|
124 document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0; |
|
125 }, |
|
126 |
|
127 onHostInput: function (aSiteField) |
|
128 { |
|
129 document.getElementById("btnSession").disabled = !aSiteField.value; |
|
130 document.getElementById("btnBlock").disabled = !aSiteField.value; |
|
131 document.getElementById("btnAllow").disabled = !aSiteField.value; |
|
132 }, |
|
133 |
|
134 onWindowKeyPress: function (aEvent) |
|
135 { |
|
136 if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE) |
|
137 window.close(); |
|
138 }, |
|
139 |
|
140 onHostKeyPress: function (aEvent) |
|
141 { |
|
142 if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN) |
|
143 document.getElementById("btnAllow").click(); |
|
144 }, |
|
145 |
|
146 onLoad: function () |
|
147 { |
|
148 this._bundle = document.getElementById("bundlePreferences"); |
|
149 var params = window.arguments[0]; |
|
150 this.init(params); |
|
151 }, |
|
152 |
|
153 init: function (aParams) |
|
154 { |
|
155 if (this._type) { |
|
156 // reusing an open dialog, clear the old observer |
|
157 this.uninit(); |
|
158 } |
|
159 |
|
160 this._type = aParams.permissionType; |
|
161 this._manageCapability = aParams.manageCapability; |
|
162 |
|
163 var permissionsText = document.getElementById("permissionsText"); |
|
164 while (permissionsText.hasChildNodes()) |
|
165 permissionsText.removeChild(permissionsText.firstChild); |
|
166 permissionsText.appendChild(document.createTextNode(aParams.introText)); |
|
167 |
|
168 document.title = aParams.windowTitle; |
|
169 |
|
170 document.getElementById("btnBlock").hidden = !aParams.blockVisible; |
|
171 document.getElementById("btnSession").hidden = !aParams.sessionVisible; |
|
172 document.getElementById("btnAllow").hidden = !aParams.allowVisible; |
|
173 |
|
174 var urlFieldVisible = (aParams.blockVisible || aParams.sessionVisible || aParams.allowVisible); |
|
175 |
|
176 var urlField = document.getElementById("url"); |
|
177 urlField.value = aParams.prefilledHost; |
|
178 urlField.hidden = !urlFieldVisible; |
|
179 |
|
180 this.onHostInput(urlField); |
|
181 |
|
182 var urlLabel = document.getElementById("urlLabel"); |
|
183 urlLabel.hidden = !urlFieldVisible; |
|
184 |
|
185 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
186 .getService(Components.interfaces.nsIObserverService); |
|
187 os.notifyObservers(null, NOTIFICATION_FLUSH_PERMISSIONS, this._type); |
|
188 os.addObserver(this, "perm-changed", false); |
|
189 |
|
190 this._loadPermissions(); |
|
191 |
|
192 urlField.focus(); |
|
193 }, |
|
194 |
|
195 uninit: function () |
|
196 { |
|
197 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
198 .getService(Components.interfaces.nsIObserverService); |
|
199 os.removeObserver(this, "perm-changed"); |
|
200 }, |
|
201 |
|
202 observe: function (aSubject, aTopic, aData) |
|
203 { |
|
204 if (aTopic == "perm-changed") { |
|
205 var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); |
|
206 if (aData == "added") { |
|
207 this._addPermissionToList(permission); |
|
208 ++this._view._rowCount; |
|
209 this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1); |
|
210 // Re-do the sort, since we inserted this new item at the end. |
|
211 gTreeUtils.sort(this._tree, this._view, this._permissions, |
|
212 this._permissionsComparator, |
|
213 this._lastPermissionSortColumn, |
|
214 this._lastPermissionSortAscending); |
|
215 } |
|
216 else if (aData == "changed") { |
|
217 for (var i = 0; i < this._permissions.length; ++i) { |
|
218 if (this._permissions[i].host == permission.host) { |
|
219 this._permissions[i].capability = this._getCapabilityString(permission.capability); |
|
220 break; |
|
221 } |
|
222 } |
|
223 // Re-do the sort, if the status changed from Block to Allow |
|
224 // or vice versa, since if we're sorted on status, we may no |
|
225 // longer be in order. |
|
226 if (this._lastPermissionSortColumn.id == "statusCol") { |
|
227 gTreeUtils.sort(this._tree, this._view, this._permissions, |
|
228 this._permissionsComparator, |
|
229 this._lastPermissionSortColumn, |
|
230 this._lastPermissionSortAscending); |
|
231 } |
|
232 this._tree.treeBoxObject.invalidate(); |
|
233 } |
|
234 // No UI other than this window causes this method to be sent a "deleted" |
|
235 // notification, so we don't need to implement it since Delete is handled |
|
236 // directly by the Permission Removal handlers. If that ever changes, those |
|
237 // implementations will have to move into here. |
|
238 } |
|
239 }, |
|
240 |
|
241 onPermissionSelected: function () |
|
242 { |
|
243 var hasSelection = this._tree.view.selection.count > 0; |
|
244 var hasRows = this._tree.view.rowCount > 0; |
|
245 document.getElementById("removePermission").disabled = !hasRows || !hasSelection; |
|
246 document.getElementById("removeAllPermissions").disabled = !hasRows; |
|
247 }, |
|
248 |
|
249 onPermissionDeleted: function () |
|
250 { |
|
251 if (!this._view.rowCount) |
|
252 return; |
|
253 var removedPermissions = []; |
|
254 gTreeUtils.deleteSelectedItems(this._tree, this._view, this._permissions, removedPermissions); |
|
255 for (var i = 0; i < removedPermissions.length; ++i) { |
|
256 var p = removedPermissions[i]; |
|
257 this._pm.remove(p.host, p.type); |
|
258 } |
|
259 document.getElementById("removePermission").disabled = !this._permissions.length; |
|
260 document.getElementById("removeAllPermissions").disabled = !this._permissions.length; |
|
261 }, |
|
262 |
|
263 onAllPermissionsDeleted: function () |
|
264 { |
|
265 if (!this._view.rowCount) |
|
266 return; |
|
267 var removedPermissions = []; |
|
268 gTreeUtils.deleteAll(this._tree, this._view, this._permissions, removedPermissions); |
|
269 for (var i = 0; i < removedPermissions.length; ++i) { |
|
270 var p = removedPermissions[i]; |
|
271 this._pm.remove(p.host, p.type); |
|
272 } |
|
273 document.getElementById("removePermission").disabled = true; |
|
274 document.getElementById("removeAllPermissions").disabled = true; |
|
275 }, |
|
276 |
|
277 onPermissionKeyPress: function (aEvent) |
|
278 { |
|
279 if (aEvent.keyCode == 46) |
|
280 this.onPermissionDeleted(); |
|
281 }, |
|
282 |
|
283 _lastPermissionSortColumn: "", |
|
284 _lastPermissionSortAscending: false, |
|
285 _permissionsComparator : function (a, b) |
|
286 { |
|
287 return a.toLowerCase().localeCompare(b.toLowerCase()); |
|
288 }, |
|
289 |
|
290 |
|
291 onPermissionSort: function (aColumn) |
|
292 { |
|
293 this._lastPermissionSortAscending = gTreeUtils.sort(this._tree, |
|
294 this._view, |
|
295 this._permissions, |
|
296 aColumn, |
|
297 this._permissionsComparator, |
|
298 this._lastPermissionSortColumn, |
|
299 this._lastPermissionSortAscending); |
|
300 this._lastPermissionSortColumn = aColumn; |
|
301 }, |
|
302 |
|
303 _loadPermissions: function () |
|
304 { |
|
305 this._tree = document.getElementById("permissionsTree"); |
|
306 this._permissions = []; |
|
307 |
|
308 // load permissions into a table |
|
309 var count = 0; |
|
310 var enumerator = this._pm.enumerator; |
|
311 while (enumerator.hasMoreElements()) { |
|
312 var nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission); |
|
313 this._addPermissionToList(nextPermission); |
|
314 } |
|
315 |
|
316 this._view._rowCount = this._permissions.length; |
|
317 |
|
318 // sort and display the table |
|
319 this._tree.treeBoxObject.view = this._view; |
|
320 this.onPermissionSort("rawHost", false); |
|
321 |
|
322 // disable "remove all" button if there are none |
|
323 document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0; |
|
324 }, |
|
325 |
|
326 _addPermissionToList: function (aPermission) |
|
327 { |
|
328 if (aPermission.type == this._type && |
|
329 (!this._manageCapability || |
|
330 (aPermission.capability == this._manageCapability))) { |
|
331 |
|
332 var host = aPermission.host; |
|
333 var capabilityString = this._getCapabilityString(aPermission.capability); |
|
334 var p = new Permission(host, |
|
335 (host.charAt(0) == ".") ? host.substring(1,host.length) : host, |
|
336 aPermission.type, |
|
337 capabilityString); |
|
338 this._permissions.push(p); |
|
339 } |
|
340 }, |
|
341 |
|
342 setHost: function (aHost) |
|
343 { |
|
344 document.getElementById("url").value = aHost; |
|
345 } |
|
346 }; |
|
347 |
|
348 function setHost(aHost) |
|
349 { |
|
350 gPermissionManager.setHost(aHost); |
|
351 } |
|
352 |
|
353 function initWithParams(aParams) |
|
354 { |
|
355 gPermissionManager.init(aParams); |
|
356 } |
|
357 |