1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/preferences/permissions.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,357 @@ 1.4 +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +const nsIPermissionManager = Components.interfaces.nsIPermissionManager; 1.10 +const nsICookiePermission = Components.interfaces.nsICookiePermission; 1.11 + 1.12 +const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions"; 1.13 + 1.14 +function Permission(host, rawHost, type, capability) 1.15 +{ 1.16 + this.host = host; 1.17 + this.rawHost = rawHost; 1.18 + this.type = type; 1.19 + this.capability = capability; 1.20 +} 1.21 + 1.22 +var gPermissionManager = { 1.23 + _type : "", 1.24 + _permissions : [], 1.25 + _pm : Components.classes["@mozilla.org/permissionmanager;1"] 1.26 + .getService(Components.interfaces.nsIPermissionManager), 1.27 + _bundle : null, 1.28 + _tree : null, 1.29 + 1.30 + _view: { 1.31 + _rowCount: 0, 1.32 + get rowCount() 1.33 + { 1.34 + return this._rowCount; 1.35 + }, 1.36 + getCellText: function (aRow, aColumn) 1.37 + { 1.38 + if (aColumn.id == "siteCol") 1.39 + return gPermissionManager._permissions[aRow].rawHost; 1.40 + else if (aColumn.id == "statusCol") 1.41 + return gPermissionManager._permissions[aRow].capability; 1.42 + return ""; 1.43 + }, 1.44 + 1.45 + isSeparator: function(aIndex) { return false; }, 1.46 + isSorted: function() { return false; }, 1.47 + isContainer: function(aIndex) { return false; }, 1.48 + setTree: function(aTree){}, 1.49 + getImageSrc: function(aRow, aColumn) {}, 1.50 + getProgressMode: function(aRow, aColumn) {}, 1.51 + getCellValue: function(aRow, aColumn) {}, 1.52 + cycleHeader: function(column) {}, 1.53 + getRowProperties: function(row){ return ""; }, 1.54 + getColumnProperties: function(column){ return ""; }, 1.55 + getCellProperties: function(row,column){ 1.56 + if (column.element.getAttribute("id") == "siteCol") 1.57 + return "ltr"; 1.58 + 1.59 + return ""; 1.60 + } 1.61 + }, 1.62 + 1.63 + _getCapabilityString: function (aCapability) 1.64 + { 1.65 + var stringKey = null; 1.66 + switch (aCapability) { 1.67 + case nsIPermissionManager.ALLOW_ACTION: 1.68 + stringKey = "can"; 1.69 + break; 1.70 + case nsIPermissionManager.DENY_ACTION: 1.71 + stringKey = "cannot"; 1.72 + break; 1.73 + case nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY: 1.74 + stringKey = "canAccessFirstParty"; 1.75 + break; 1.76 + case nsICookiePermission.ACCESS_SESSION: 1.77 + stringKey = "canSession"; 1.78 + break; 1.79 + } 1.80 + return this._bundle.getString(stringKey); 1.81 + }, 1.82 + 1.83 + addPermission: function (aCapability) 1.84 + { 1.85 + var textbox = document.getElementById("url"); 1.86 + var host = textbox.value.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme 1.87 + try { 1.88 + var ioService = Components.classes["@mozilla.org/network/io-service;1"] 1.89 + .getService(Components.interfaces.nsIIOService); 1.90 + var uri = ioService.newURI("http://"+host, null, null); 1.91 + host = uri.host; 1.92 + } catch(ex) { 1.93 + var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] 1.94 + .getService(Components.interfaces.nsIPromptService); 1.95 + var message = this._bundle.getString("invalidURI"); 1.96 + var title = this._bundle.getString("invalidURITitle"); 1.97 + promptService.alert(window, title, message); 1.98 + return; 1.99 + } 1.100 + 1.101 + var capabilityString = this._getCapabilityString(aCapability); 1.102 + 1.103 + // check whether the permission already exists, if not, add it 1.104 + var exists = false; 1.105 + for (var i = 0; i < this._permissions.length; ++i) { 1.106 + if (this._permissions[i].rawHost == host) { 1.107 + // Avoid calling the permission manager if the capability settings are 1.108 + // the same. Otherwise allow the call to the permissions manager to 1.109 + // update the listbox for us. 1.110 + exists = this._permissions[i].capability == capabilityString; 1.111 + break; 1.112 + } 1.113 + } 1.114 + 1.115 + if (!exists) { 1.116 + host = (host.charAt(0) == ".") ? host.substring(1,host.length) : host; 1.117 + var uri = ioService.newURI("http://" + host, null, null); 1.118 + this._pm.add(uri, this._type, aCapability); 1.119 + } 1.120 + textbox.value = ""; 1.121 + textbox.focus(); 1.122 + 1.123 + // covers a case where the site exists already, so the buttons don't disable 1.124 + this.onHostInput(textbox); 1.125 + 1.126 + // enable "remove all" button as needed 1.127 + document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0; 1.128 + }, 1.129 + 1.130 + onHostInput: function (aSiteField) 1.131 + { 1.132 + document.getElementById("btnSession").disabled = !aSiteField.value; 1.133 + document.getElementById("btnBlock").disabled = !aSiteField.value; 1.134 + document.getElementById("btnAllow").disabled = !aSiteField.value; 1.135 + }, 1.136 + 1.137 + onWindowKeyPress: function (aEvent) 1.138 + { 1.139 + if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE) 1.140 + window.close(); 1.141 + }, 1.142 + 1.143 + onHostKeyPress: function (aEvent) 1.144 + { 1.145 + if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN) 1.146 + document.getElementById("btnAllow").click(); 1.147 + }, 1.148 + 1.149 + onLoad: function () 1.150 + { 1.151 + this._bundle = document.getElementById("bundlePreferences"); 1.152 + var params = window.arguments[0]; 1.153 + this.init(params); 1.154 + }, 1.155 + 1.156 + init: function (aParams) 1.157 + { 1.158 + if (this._type) { 1.159 + // reusing an open dialog, clear the old observer 1.160 + this.uninit(); 1.161 + } 1.162 + 1.163 + this._type = aParams.permissionType; 1.164 + this._manageCapability = aParams.manageCapability; 1.165 + 1.166 + var permissionsText = document.getElementById("permissionsText"); 1.167 + while (permissionsText.hasChildNodes()) 1.168 + permissionsText.removeChild(permissionsText.firstChild); 1.169 + permissionsText.appendChild(document.createTextNode(aParams.introText)); 1.170 + 1.171 + document.title = aParams.windowTitle; 1.172 + 1.173 + document.getElementById("btnBlock").hidden = !aParams.blockVisible; 1.174 + document.getElementById("btnSession").hidden = !aParams.sessionVisible; 1.175 + document.getElementById("btnAllow").hidden = !aParams.allowVisible; 1.176 + 1.177 + var urlFieldVisible = (aParams.blockVisible || aParams.sessionVisible || aParams.allowVisible); 1.178 + 1.179 + var urlField = document.getElementById("url"); 1.180 + urlField.value = aParams.prefilledHost; 1.181 + urlField.hidden = !urlFieldVisible; 1.182 + 1.183 + this.onHostInput(urlField); 1.184 + 1.185 + var urlLabel = document.getElementById("urlLabel"); 1.186 + urlLabel.hidden = !urlFieldVisible; 1.187 + 1.188 + var os = Components.classes["@mozilla.org/observer-service;1"] 1.189 + .getService(Components.interfaces.nsIObserverService); 1.190 + os.notifyObservers(null, NOTIFICATION_FLUSH_PERMISSIONS, this._type); 1.191 + os.addObserver(this, "perm-changed", false); 1.192 + 1.193 + this._loadPermissions(); 1.194 + 1.195 + urlField.focus(); 1.196 + }, 1.197 + 1.198 + uninit: function () 1.199 + { 1.200 + var os = Components.classes["@mozilla.org/observer-service;1"] 1.201 + .getService(Components.interfaces.nsIObserverService); 1.202 + os.removeObserver(this, "perm-changed"); 1.203 + }, 1.204 + 1.205 + observe: function (aSubject, aTopic, aData) 1.206 + { 1.207 + if (aTopic == "perm-changed") { 1.208 + var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); 1.209 + if (aData == "added") { 1.210 + this._addPermissionToList(permission); 1.211 + ++this._view._rowCount; 1.212 + this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1); 1.213 + // Re-do the sort, since we inserted this new item at the end. 1.214 + gTreeUtils.sort(this._tree, this._view, this._permissions, 1.215 + this._permissionsComparator, 1.216 + this._lastPermissionSortColumn, 1.217 + this._lastPermissionSortAscending); 1.218 + } 1.219 + else if (aData == "changed") { 1.220 + for (var i = 0; i < this._permissions.length; ++i) { 1.221 + if (this._permissions[i].host == permission.host) { 1.222 + this._permissions[i].capability = this._getCapabilityString(permission.capability); 1.223 + break; 1.224 + } 1.225 + } 1.226 + // Re-do the sort, if the status changed from Block to Allow 1.227 + // or vice versa, since if we're sorted on status, we may no 1.228 + // longer be in order. 1.229 + if (this._lastPermissionSortColumn.id == "statusCol") { 1.230 + gTreeUtils.sort(this._tree, this._view, this._permissions, 1.231 + this._permissionsComparator, 1.232 + this._lastPermissionSortColumn, 1.233 + this._lastPermissionSortAscending); 1.234 + } 1.235 + this._tree.treeBoxObject.invalidate(); 1.236 + } 1.237 + // No UI other than this window causes this method to be sent a "deleted" 1.238 + // notification, so we don't need to implement it since Delete is handled 1.239 + // directly by the Permission Removal handlers. If that ever changes, those 1.240 + // implementations will have to move into here. 1.241 + } 1.242 + }, 1.243 + 1.244 + onPermissionSelected: function () 1.245 + { 1.246 + var hasSelection = this._tree.view.selection.count > 0; 1.247 + var hasRows = this._tree.view.rowCount > 0; 1.248 + document.getElementById("removePermission").disabled = !hasRows || !hasSelection; 1.249 + document.getElementById("removeAllPermissions").disabled = !hasRows; 1.250 + }, 1.251 + 1.252 + onPermissionDeleted: function () 1.253 + { 1.254 + if (!this._view.rowCount) 1.255 + return; 1.256 + var removedPermissions = []; 1.257 + gTreeUtils.deleteSelectedItems(this._tree, this._view, this._permissions, removedPermissions); 1.258 + for (var i = 0; i < removedPermissions.length; ++i) { 1.259 + var p = removedPermissions[i]; 1.260 + this._pm.remove(p.host, p.type); 1.261 + } 1.262 + document.getElementById("removePermission").disabled = !this._permissions.length; 1.263 + document.getElementById("removeAllPermissions").disabled = !this._permissions.length; 1.264 + }, 1.265 + 1.266 + onAllPermissionsDeleted: function () 1.267 + { 1.268 + if (!this._view.rowCount) 1.269 + return; 1.270 + var removedPermissions = []; 1.271 + gTreeUtils.deleteAll(this._tree, this._view, this._permissions, removedPermissions); 1.272 + for (var i = 0; i < removedPermissions.length; ++i) { 1.273 + var p = removedPermissions[i]; 1.274 + this._pm.remove(p.host, p.type); 1.275 + } 1.276 + document.getElementById("removePermission").disabled = true; 1.277 + document.getElementById("removeAllPermissions").disabled = true; 1.278 + }, 1.279 + 1.280 + onPermissionKeyPress: function (aEvent) 1.281 + { 1.282 + if (aEvent.keyCode == 46) 1.283 + this.onPermissionDeleted(); 1.284 + }, 1.285 + 1.286 + _lastPermissionSortColumn: "", 1.287 + _lastPermissionSortAscending: false, 1.288 + _permissionsComparator : function (a, b) 1.289 + { 1.290 + return a.toLowerCase().localeCompare(b.toLowerCase()); 1.291 + }, 1.292 + 1.293 + 1.294 + onPermissionSort: function (aColumn) 1.295 + { 1.296 + this._lastPermissionSortAscending = gTreeUtils.sort(this._tree, 1.297 + this._view, 1.298 + this._permissions, 1.299 + aColumn, 1.300 + this._permissionsComparator, 1.301 + this._lastPermissionSortColumn, 1.302 + this._lastPermissionSortAscending); 1.303 + this._lastPermissionSortColumn = aColumn; 1.304 + }, 1.305 + 1.306 + _loadPermissions: function () 1.307 + { 1.308 + this._tree = document.getElementById("permissionsTree"); 1.309 + this._permissions = []; 1.310 + 1.311 + // load permissions into a table 1.312 + var count = 0; 1.313 + var enumerator = this._pm.enumerator; 1.314 + while (enumerator.hasMoreElements()) { 1.315 + var nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission); 1.316 + this._addPermissionToList(nextPermission); 1.317 + } 1.318 + 1.319 + this._view._rowCount = this._permissions.length; 1.320 + 1.321 + // sort and display the table 1.322 + this._tree.treeBoxObject.view = this._view; 1.323 + this.onPermissionSort("rawHost", false); 1.324 + 1.325 + // disable "remove all" button if there are none 1.326 + document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0; 1.327 + }, 1.328 + 1.329 + _addPermissionToList: function (aPermission) 1.330 + { 1.331 + if (aPermission.type == this._type && 1.332 + (!this._manageCapability || 1.333 + (aPermission.capability == this._manageCapability))) { 1.334 + 1.335 + var host = aPermission.host; 1.336 + var capabilityString = this._getCapabilityString(aPermission.capability); 1.337 + var p = new Permission(host, 1.338 + (host.charAt(0) == ".") ? host.substring(1,host.length) : host, 1.339 + aPermission.type, 1.340 + capabilityString); 1.341 + this._permissions.push(p); 1.342 + } 1.343 + }, 1.344 + 1.345 + setHost: function (aHost) 1.346 + { 1.347 + document.getElementById("url").value = aHost; 1.348 + } 1.349 +}; 1.350 + 1.351 +function setHost(aHost) 1.352 +{ 1.353 + gPermissionManager.setHost(aHost); 1.354 +} 1.355 + 1.356 +function initWithParams(aParams) 1.357 +{ 1.358 + gPermissionManager.init(aParams); 1.359 +} 1.360 +