1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/passwordmgr/content/passwordManagerCommon.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,233 @@ 1.4 +// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/*** =================== INITIALISATION CODE =================== ***/ 1.11 + 1.12 +var kObserverService; 1.13 + 1.14 +// interface variables 1.15 +var passwordmanager = null; 1.16 + 1.17 +// password-manager lists 1.18 +var signons = []; 1.19 +var rejects = []; 1.20 +var deletedSignons = []; 1.21 +var deletedRejects = []; 1.22 + 1.23 +var signonsTree; 1.24 +var rejectsTree; 1.25 + 1.26 +var showingPasswords = false; 1.27 + 1.28 +function Startup() { 1.29 + // xpconnect to password manager interfaces 1.30 + passwordmanager = Components.classes["@mozilla.org/login-manager;1"] 1.31 + .getService(Components.interfaces.nsILoginManager); 1.32 + 1.33 + // be prepared to reload the display if anything changes 1.34 + kObserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); 1.35 + kObserverService.addObserver(signonReloadDisplay, "passwordmgr-storage-changed", false); 1.36 + 1.37 + signonsTree = document.getElementById("signonsTree"); 1.38 + rejectsTree = document.getElementById("rejectsTree"); 1.39 +} 1.40 + 1.41 +function Shutdown() { 1.42 + kObserverService.removeObserver(signonReloadDisplay, "passwordmgr-storage-changed"); 1.43 +} 1.44 + 1.45 +var signonReloadDisplay = { 1.46 + observe: function(subject, topic, data) { 1.47 + if (topic == "passwordmgr-storage-changed") { 1.48 + switch (data) { 1.49 + case "addLogin": 1.50 + case "modifyLogin": 1.51 + case "removeLogin": 1.52 + case "removeAllLogins": 1.53 + if (!signonsTree) { 1.54 + return; 1.55 + } 1.56 + signons.length = 0; 1.57 + LoadSignons(); 1.58 + // apply the filter if needed 1.59 + if (document.getElementById("filter") && document.getElementById("filter").value != "") { 1.60 + _filterPasswords(); 1.61 + } 1.62 + break; 1.63 + case "hostSavingEnabled": 1.64 + case "hostSavingDisabled": 1.65 + if (!rejectsTree) { 1.66 + return; 1.67 + } 1.68 + rejects.length = 0; 1.69 + if (lastRejectSortColumn == "hostname") { 1.70 + lastRejectSortAscending = !lastRejectSortAscending; // prevents sort from being reversed 1.71 + } 1.72 + LoadRejects(); 1.73 + break; 1.74 + } 1.75 + kObserverService.notifyObservers(null, "passwordmgr-dialog-updated", null); 1.76 + } 1.77 + } 1.78 +} 1.79 + 1.80 +/*** =================== GENERAL CODE =================== ***/ 1.81 + 1.82 +function DeleteAllFromTree(tree, view, table, deletedTable, removeButton, removeAllButton) { 1.83 + 1.84 + // remove all items from table and place in deleted table 1.85 + for (var i=0; i<table.length; i++) { 1.86 + deletedTable[deletedTable.length] = table[i]; 1.87 + } 1.88 + table.length = 0; 1.89 + 1.90 + // clear out selections 1.91 + view.selection.select(-1); 1.92 + 1.93 + // update the tree view and notify the tree 1.94 + view.rowCount = 0; 1.95 + 1.96 + var box = tree.treeBoxObject; 1.97 + box.rowCountChanged(0, -deletedTable.length); 1.98 + box.invalidate(); 1.99 + 1.100 + 1.101 + // disable buttons 1.102 + document.getElementById(removeButton).setAttribute("disabled", "true") 1.103 + document.getElementById(removeAllButton).setAttribute("disabled","true"); 1.104 +} 1.105 + 1.106 +function DeleteSelectedItemFromTree 1.107 + (tree, view, table, deletedTable, removeButton, removeAllButton) { 1.108 + 1.109 + // Turn off tree selection notifications during the deletion 1.110 + tree.view.selection.selectEventsSuppressed = true; 1.111 + 1.112 + // remove selected items from list (by setting them to null) and place in deleted list 1.113 + var selections = GetTreeSelections(tree); 1.114 + for (var s=selections.length-1; s>= 0; s--) { 1.115 + var i = selections[s]; 1.116 + deletedTable[deletedTable.length] = table[i]; 1.117 + table[i] = null; 1.118 + } 1.119 + 1.120 + // collapse list by removing all the null entries 1.121 + for (var j=0; j<table.length; j++) { 1.122 + if (table[j] == null) { 1.123 + var k = j; 1.124 + while ((k < table.length) && (table[k] == null)) { 1.125 + k++; 1.126 + } 1.127 + table.splice(j, k-j); 1.128 + view.rowCount -= k - j; 1.129 + tree.treeBoxObject.rowCountChanged(j, j - k); 1.130 + } 1.131 + } 1.132 + 1.133 + // update selection and/or buttons 1.134 + if (table.length) { 1.135 + // update selection 1.136 + var nextSelection = (selections[0] < table.length) ? selections[0] : table.length-1; 1.137 + tree.view.selection.select(nextSelection); 1.138 + tree.treeBoxObject.ensureRowIsVisible(nextSelection); 1.139 + } else { 1.140 + // disable buttons 1.141 + document.getElementById(removeButton).setAttribute("disabled", "true") 1.142 + document.getElementById(removeAllButton).setAttribute("disabled","true"); 1.143 + } 1.144 + tree.view.selection.selectEventsSuppressed = false; 1.145 +} 1.146 + 1.147 +function GetTreeSelections(tree) { 1.148 + var selections = []; 1.149 + var select = tree.view.selection; 1.150 + if (select) { 1.151 + var count = select.getRangeCount(); 1.152 + var min = new Object(); 1.153 + var max = new Object(); 1.154 + for (var i=0; i<count; i++) { 1.155 + select.getRangeAt(i, min, max); 1.156 + for (var k=min.value; k<=max.value; k++) { 1.157 + if (k != -1) { 1.158 + selections[selections.length] = k; 1.159 + } 1.160 + } 1.161 + } 1.162 + } 1.163 + return selections; 1.164 +} 1.165 + 1.166 +function SortTree(tree, view, table, column, lastSortColumn, lastSortAscending, updateSelection) { 1.167 + 1.168 + // remember which item was selected so we can restore it after the sort 1.169 + var selections = GetTreeSelections(tree); 1.170 + var selectedNumber = selections.length ? table[selections[0]].number : -1; 1.171 + 1.172 + // determine if sort is to be ascending or descending 1.173 + var ascending = (column == lastSortColumn) ? !lastSortAscending : true; 1.174 + 1.175 + // do the sort 1.176 + var compareFunc; 1.177 + if (ascending) { 1.178 + compareFunc = function compare(first, second) { 1.179 + return CompareLowerCase(first[column], second[column]); 1.180 + } 1.181 + } else { 1.182 + compareFunc = function compare(first, second) { 1.183 + return CompareLowerCase(second[column], first[column]); 1.184 + } 1.185 + } 1.186 + table.sort(compareFunc); 1.187 + 1.188 + // restore the selection 1.189 + var selectedRow = -1; 1.190 + if (selectedNumber>=0 && updateSelection) { 1.191 + for (var s=0; s<table.length; s++) { 1.192 + if (table[s].number == selectedNumber) { 1.193 + // update selection 1.194 + // note: we need to deselect before reselecting in order to trigger ...Selected() 1.195 + tree.view.selection.select(-1); 1.196 + tree.view.selection.select(s); 1.197 + selectedRow = s; 1.198 + break; 1.199 + } 1.200 + } 1.201 + } 1.202 + 1.203 + // display the results 1.204 + tree.treeBoxObject.invalidate(); 1.205 + if (selectedRow >= 0) { 1.206 + tree.treeBoxObject.ensureRowIsVisible(selectedRow) 1.207 + } 1.208 + 1.209 + return ascending; 1.210 +} 1.211 + 1.212 +/** 1.213 + * Case insensitive string comparator. 1.214 + */ 1.215 +function CompareLowerCase(first, second) { 1.216 + var firstLower, secondLower; 1.217 + 1.218 + // Are we sorting nsILoginInfo entries or just strings? 1.219 + if (first.hostname) { 1.220 + firstLower = first.hostname.toLowerCase(); 1.221 + secondLower = second.hostname.toLowerCase(); 1.222 + } else { 1.223 + firstLower = first.toLowerCase(); 1.224 + secondLower = second.toLowerCase(); 1.225 + } 1.226 + 1.227 + if (firstLower < secondLower) { 1.228 + return -1; 1.229 + } 1.230 + 1.231 + if (firstLower > secondLower) { 1.232 + return 1; 1.233 + } 1.234 + 1.235 + return 0; 1.236 +}