Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / browser / components / preferences / permissions.js
blob5b16d1510520b3bb0a2c56323368b3b90acb4a30
1 # -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
13 # License.
15 # The Original Code is the Firefox Preferences System.
17 # The Initial Developer of the Original Code is
18 # Ben Goodger.
19 # Portions created by the Initial Developer are Copyright (C) 2005
20 # the Initial Developer. All Rights Reserved.
22 # Contributor(s):
23 # Ben Goodger <ben@mozilla.org>
24 # Blake Ross <firefox@blakeross.com>
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
38 # ***** END LICENSE BLOCK *****
40 const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
41 const nsICookiePermission = Components.interfaces.nsICookiePermission;
43 function Permission(host, rawHost, type, capability, perm)
45 this.host = host;
46 this.rawHost = rawHost;
47 this.type = type;
48 this.capability = capability;
49 this.perm = perm;
52 var gPermissionManager = {
53 _type : "",
54 _permissions : [],
55 _pm : Components.classes["@mozilla.org/permissionmanager;1"]
56 .getService(Components.interfaces.nsIPermissionManager),
57 _bundle : null,
58 _tree : null,
60 _view: {
61 _rowCount: 0,
62 get rowCount()
64 return this._rowCount;
66 getCellText: function (aRow, aColumn)
68 if (aColumn.id == "siteCol")
69 return gPermissionManager._permissions[aRow].rawHost;
70 else if (aColumn.id == "statusCol")
71 return gPermissionManager._permissions[aRow].capability;
72 return "";
75 isSeparator: function(aIndex) { return false; },
76 isSorted: function() { return false; },
77 isContainer: function(aIndex) { return false; },
78 setTree: function(aTree){},
79 getImageSrc: function(aRow, aColumn) {},
80 getProgressMode: function(aRow, aColumn) {},
81 getCellValue: function(aRow, aColumn) {},
82 cycleHeader: function(column) {},
83 getRowProperties: function(row,prop){},
84 getColumnProperties: function(column,prop){},
85 getCellProperties: function(row,column,prop){}
88 _getCapabilityString: function (aCapability)
90 var stringKey = null;
91 switch (aCapability) {
92 case nsIPermissionManager.ALLOW_ACTION:
93 stringKey = "can";
94 break;
95 case nsIPermissionManager.DENY_ACTION:
96 stringKey = "cannot";
97 break;
98 case nsICookiePermission.ACCESS_SESSION:
99 stringKey = "canSession";
100 break;
102 return this._bundle.getString(stringKey);
105 addPermission: function (aCapability)
107 var textbox = document.getElementById("url");
108 var host = textbox.value.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme
109 try {
110 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
111 .getService(Components.interfaces.nsIIOService);
112 var uri = ioService.newURI("http://"+host, null, null);
113 host = uri.host;
114 } catch(ex) {
115 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
116 .getService(Components.interfaces.nsIPromptService);
117 var message = this._bundle.getString("invalidURI");
118 var title = this._bundle.getString("invalidURITitle");
119 promptService.alert(window, title, message);
120 return;
123 var capabilityString = this._getCapabilityString(aCapability);
125 // check whether the permission already exists, if not, add it
126 var exists = false;
127 for (var i = 0; i < this._permissions.length; ++i) {
128 if (this._permissions[i].rawHost == host) {
129 // Avoid calling the permission manager if the capability settings are
130 // the same. Otherwise allow the call to the permissions manager to
131 // update the listbox for us.
132 exists = this._permissions[i].perm == aCapability;
133 break;
137 if (!exists) {
138 host = (host.charAt(0) == ".") ? host.substring(1,host.length) : host;
139 var uri = ioService.newURI("http://" + host, null, null);
140 this._pm.add(uri, this._type, aCapability);
142 textbox.value = "";
143 textbox.focus();
145 // covers a case where the site exists already, so the buttons don't disable
146 this.onHostInput(textbox);
148 // enable "remove all" button as needed
149 document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
152 onHostInput: function (aSiteField)
154 document.getElementById("btnSession").disabled = !aSiteField.value;
155 document.getElementById("btnBlock").disabled = !aSiteField.value;
156 document.getElementById("btnAllow").disabled = !aSiteField.value;
159 onHostKeyPress: function (aEvent)
161 if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
162 document.getElementById("btnAllow").click();
165 onLoad: function ()
167 this._bundle = document.getElementById("bundlePreferences");
168 var params = window.arguments[0];
169 this.init(params);
172 init: function (aParams)
174 if (this._type) {
175 // reusing an open dialog, clear the old observer
176 this.uninit();
179 this._type = aParams.permissionType;
180 this._manageCapability = aParams.manageCapability;
182 var permissionsText = document.getElementById("permissionsText");
183 while (permissionsText.hasChildNodes())
184 permissionsText.removeChild(permissionsText.firstChild);
185 permissionsText.appendChild(document.createTextNode(aParams.introText));
187 document.title = aParams.windowTitle;
189 document.getElementById("btnBlock").hidden = !aParams.blockVisible;
190 document.getElementById("btnSession").hidden = !aParams.sessionVisible;
191 document.getElementById("btnAllow").hidden = !aParams.allowVisible;
193 var urlFieldVisible = (aParams.blockVisible || aParams.sessionVisible || aParams.allowVisible);
195 var urlField = document.getElementById("url");
196 urlField.value = aParams.prefilledHost;
197 urlField.hidden = !urlFieldVisible;
199 this.onHostInput(urlField);
201 var urlLabel = document.getElementById("urlLabel");
202 urlLabel.hidden = !urlFieldVisible;
204 var os = Components.classes["@mozilla.org/observer-service;1"]
205 .getService(Components.interfaces.nsIObserverService);
206 os.addObserver(this, "perm-changed", false);
208 if (this._type == "install") {
209 var enumerator = this._pm.enumerator;
210 if (!enumerator.hasMoreElements())
211 this._updatePermissions();
214 this._loadPermissions();
216 urlField.focus();
219 uninit: function ()
221 var os = Components.classes["@mozilla.org/observer-service;1"]
222 .getService(Components.interfaces.nsIObserverService);
223 os.removeObserver(this, "perm-changed");
226 observe: function (aSubject, aTopic, aData)
228 if (aTopic == "perm-changed") {
229 var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission);
230 if (aData == "added") {
231 this._addPermissionToList(permission);
232 ++this._view._rowCount;
233 this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1);
234 // Re-do the sort, since we inserted this new item at the end.
235 gTreeUtils.sort(this._tree, this._view, this._permissions,
236 this._lastPermissionSortColumn,
237 this._lastPermissionSortAscending);
239 else if (aData == "changed") {
240 for (var i = 0; i < this._permissions.length; ++i) {
241 if (this._permissions[i].host == permission.host) {
242 this._permissions[i].capability = this._getCapabilityString(permission.capability);
243 break;
246 // Re-do the sort, if the status changed from Block to Allow
247 // or vice versa, since if we're sorted on status, we may no
248 // longer be in order.
249 if (this._lastPermissionSortColumn.id == "statusCol") {
250 gTreeUtils.sort(this._tree, this._view, this._permissions,
251 this._lastPermissionSortColumn,
252 this._lastPermissionSortAscending);
254 this._tree.treeBoxObject.invalidate();
256 // No UI other than this window causes this method to be sent a "deleted"
257 // notification, so we don't need to implement it since Delete is handled
258 // directly by the Permission Removal handlers. If that ever changes, those
259 // implementations will have to move into here.
263 onPermissionSelected: function ()
265 var hasSelection = this._tree.view.selection.count > 0;
266 var hasRows = this._tree.view.rowCount > 0;
267 document.getElementById("removePermission").disabled = !hasRows || !hasSelection;
268 document.getElementById("removeAllPermissions").disabled = !hasRows;
271 onPermissionDeleted: function ()
273 if (!this._view.rowCount)
274 return;
275 var removedPermissions = [];
276 gTreeUtils.deleteSelectedItems(this._tree, this._view, this._permissions, removedPermissions);
277 for (var i = 0; i < removedPermissions.length; ++i) {
278 var p = removedPermissions[i];
279 this._pm.remove(p.host, p.type);
281 document.getElementById("removePermission").disabled = !this._permissions.length;
282 document.getElementById("removeAllPermissions").disabled = !this._permissions.length;
285 onAllPermissionsDeleted: function ()
287 if (!this._view.rowCount)
288 return;
289 var removedPermissions = [];
290 gTreeUtils.deleteAll(this._tree, this._view, this._permissions, removedPermissions);
291 for (var i = 0; i < removedPermissions.length; ++i) {
292 var p = removedPermissions[i];
293 this._pm.remove(p.host, p.type);
295 document.getElementById("removePermission").disabled = true;
296 document.getElementById("removeAllPermissions").disabled = true;
299 onPermissionKeyPress: function (aEvent)
301 if (aEvent.keyCode == 46)
302 this.onPermissionDeleted();
305 _lastPermissionSortColumn: "",
306 _lastPermissionSortAscending: false,
308 onPermissionSort: function (aColumn)
310 this._lastPermissionSortAscending = gTreeUtils.sort(this._tree,
311 this._view,
312 this._permissions,
313 aColumn,
314 this._lastPermissionSortColumn,
315 this._lastPermissionSortAscending);
316 this._lastPermissionSortColumn = aColumn;
319 _loadPermissions: function ()
321 this._tree = document.getElementById("permissionsTree");
322 this._permissions = [];
324 // load permissions into a table
325 var count = 0;
326 var enumerator = this._pm.enumerator;
327 while (enumerator.hasMoreElements()) {
328 var nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
329 this._addPermissionToList(nextPermission);
332 this._view._rowCount = this._permissions.length;
334 // sort and display the table
335 this._tree.treeBoxObject.view = this._view;
336 this.onPermissionSort("rawHost", false);
338 // disable "remove all" button if there are none
339 document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
342 _addPermissionToList: function (aPermission)
344 if (aPermission.type == this._type &&
345 (!this._manageCapability ||
346 (aPermission.capability == this._manageCapability))) {
348 var host = aPermission.host;
349 var capabilityString = this._getCapabilityString(aPermission.capability);
350 var p = new Permission(host,
351 (host.charAt(0) == ".") ? host.substring(1,host.length) : host,
352 aPermission.type,
353 capabilityString,
354 aPermission.capability);
355 this._permissions.push(p);
359 _updatePermissions: function ()
361 try {
362 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
363 .getService(Components.interfaces.nsIIOService);
364 var pbi = Components.classes["@mozilla.org/preferences-service;1"]
365 .getService(Components.interfaces.nsIPrefBranch2);
366 var prefList = [["xpinstall.whitelist.add", nsIPermissionManager.ALLOW_ACTION],
367 ["xpinstall.whitelist.add.103", nsIPermissionManager.ALLOW_ACTION],
368 ["xpinstall.blacklist.add", nsIPermissionManager.DENY_ACTION]];
370 for (var i = 0; i < prefList.length; ++i) {
371 try {
372 // this pref is a comma-delimited list of hosts
373 var hosts = pbi.getCharPref(prefList[i][0]);
374 } catch(ex) {
375 continue;
378 if (!hosts)
379 continue;
381 hostList = hosts.split(",");
382 var capability = prefList[i][1];
383 for (var j = 0; j < hostList.length; ++j) {
384 // trim leading and trailing spaces
385 var host = hostList[j].replace(/^\s*/,"").replace(/\s*$/,"");
386 try {
387 var uri = ioService.newURI("http://" + host, null, null);
388 this._pm.add(uri, this._type, capability);
389 } catch(ex) { }
391 pbi.setCharPref(prefList[i][0], "");
393 } catch(ex) { }
396 setHost: function (aHost)
398 document.getElementById("url").value = aHost;
402 function setHost(aHost)
404 gPermissionManager.setHost(aHost);
407 function initWithParams(aParams)
409 gPermissionManager.init(aParams);