author | Matthew Noorenberghe <mozilla@noorenberghe.ca> |
Mon, 21 Sep 2015 14:19:28 -0700 | |
changeset 263706 | e4e3a8b66db489efcf3a87e3c954614ed1b2b9ff |
parent 263705 | b59d92a6d64b0d740cbf7d4e067ed3cdcecf8cc9 |
child 263707 | 65b643d6e5f35e20c456efc4aa0e9ef4ba7c74a7 |
push id | 65396 |
push user | cbook@mozilla.com |
push date | Tue, 22 Sep 2015 10:50:42 +0000 |
treeherder | mozilla-inbound@9a5faeebdcb5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Dolske, rchtara |
bugs | 1121291 |
milestone | 44.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/components/passwordmgr/content/passwordManager.js +++ b/toolkit/components/passwordmgr/content/passwordManager.js @@ -1,26 +1,23 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /*** =================== SAVED SIGNONS CODE =================== ***/ var kSignonBundle; -var showingPasswords = false; var dateFormatter = new Intl.DateTimeFormat(undefined, { day: "numeric", month: "short", year: "numeric" }); var dateAndTimeFormatter = new Intl.DateTimeFormat(undefined, { day: "numeric", month: "short", year: "numeric", hour: "numeric", minute: "numeric" }); function SignonsStartup() { kSignonBundle = document.getElementById("signonBundle"); - document.getElementById("togglePasswords").label = kSignonBundle.getString("showPasswords"); - document.getElementById("togglePasswords").accessKey = kSignonBundle.getString("showPasswordsAccessKey"); document.getElementById("signonsIntro").textContent = kSignonBundle.getString("loginsDescriptionAll"); let treecols = document.getElementsByTagName("treecols")[0]; treecols.addEventListener("click", HandleTreeColumnClick.bind(null, SignonColumnSort)); LoadSignons(); // filter the table if requested by caller @@ -74,19 +71,24 @@ var signonsTreeView = { return dateFormatter.format(time); case "timesUsedCol": return signon.timesUsed; default: return ""; } }, isEditable : function(row, col) { - if (col.id == "userCol" || col.id == "passwordCol") { + if (col.id == "userCol") { return true; } + + if (col.id == "passwordCol") { + return masterPasswordLogin(); + } + return false; }, isSeparator : function(index) { return false; }, isSorted : function() { return false; }, isContainer : function(index) { return false; }, cycleHeader : function(column) {}, getRowProperties : function(row) { return ""; }, getColumnProperties : function(column) { return ""; }, @@ -123,38 +125,36 @@ var signonsTreeView = { }; function LoadSignons() { // loads signons into table try { signons = passwordmanager.getAllLogins(); } catch (e) { - signons = []; + window.close(); + return; } signons.forEach(login => login.QueryInterface(Components.interfaces.nsILoginMetaInfo)); signonsTreeView.rowCount = signons.length; // sort and display the table signonsTree.view = signonsTreeView; // The sort column didn't change. SortTree (called by // SignonColumnSort) assumes we want to toggle the sort // direction but here we don't so we have to trick it lastSignonSortAscending = !lastSignonSortAscending; SignonColumnSort(lastSignonSortColumn); // disable "remove all signons" button if there are no signons var element = document.getElementById("removeAllSignons"); - var toggle = document.getElementById("togglePasswords"); if (signons.length == 0) { element.setAttribute("disabled","true"); - toggle.setAttribute("disabled","true"); } else { element.removeAttribute("disabled"); - toggle.removeAttribute("disabled"); } return true; } function SignonSelected() { var selections = GetTreeSelections(signonsTree); if (selections.length) { @@ -186,44 +186,16 @@ function DeleteAllSignons() { var syncNeeded = (signonsTreeView._filterSet.length != 0); DeleteAllFromTree(signonsTree, signonsTreeView, signonsTreeView._filterSet.length ? signonsTreeView._filterSet : signons, deletedSignons, "removeSignon", "removeAllSignons"); FinalizeSignonDeletions(syncNeeded); Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED_ALL").add(1); } -function TogglePasswordVisible() { - if (showingPasswords || masterPasswordLogin(AskUserShowPasswords)) { - showingPasswords = !showingPasswords; - document.getElementById("togglePasswords").label = kSignonBundle.getString(showingPasswords ? "hidePasswords" : "showPasswords"); - document.getElementById("togglePasswords").accessKey = kSignonBundle.getString(showingPasswords ? "hidePasswordsAccessKey" : "showPasswordsAccessKey"); - document.getElementById("passwordCol").hidden = !showingPasswords; - _filterPasswords(); - } - - // Notify observers that the password visibility toggling is - // completed. (Mostly useful for tests) - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .notifyObservers(null, "passwordmgr-password-toggle-complete", null); - Services.telemetry.getHistogramById("PWMGR_MANAGE_VISIBILITY_TOGGLED").add(showingPasswords); -} - -function AskUserShowPasswords() { - var prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); - var dummy = { value: false }; - - // Confirm the user wants to display passwords - return prompter.confirmEx(window, - null, - kSignonBundle.getString("noMasterPasswordPrompt"), prompter.STD_YES_NO_BUTTONS, - null, null, null, null, dummy) == 0; // 0=="Yes" button -} - function FinalizeSignonDeletions(syncNeeded) { for (var s=0; s<deletedSignons.length; s++) { passwordmanager.removeLogin(deletedSignons[s]); Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED").add(1); } // If the deletion has been performed in a filtered view, reflect the deletion in the unfiltered table. // See bug 405389. if (syncNeeded) { @@ -327,17 +299,17 @@ function SignonMatchesFilter(aSignon, aF if (aSignon.hostname.toLowerCase().indexOf(aFilterValue) != -1) return true; if (aSignon.username && aSignon.username.toLowerCase().indexOf(aFilterValue) != -1) return true; if (aSignon.httpRealm && aSignon.httpRealm.toLowerCase().indexOf(aFilterValue) != -1) return true; - if (showingPasswords && aSignon.password && + if (Services.logins.isLoggedIn && aSignon.password && aSignon.password.toLowerCase().indexOf(aFilterValue) != -1) return true; return false; } function FilterPasswords(aFilterValue, view) { aFilterValue = aFilterValue.toLowerCase(); @@ -383,19 +355,18 @@ function _filterPasswords() // if the view is not empty then select the first item if (signonsTreeView.rowCount > 0) signonsTreeView.selection.select(0); document.getElementById("signonsIntro").textContent = kSignonBundle.getString("loginsDescriptionFiltered"); } function CopyPassword() { - // Don't copy passwords if we aren't already showing the passwords & a master - // password hasn't been entered. - if (!showingPasswords && !masterPasswordLogin()) + // Don't copy passwords if a master password hasn't been entered. + if (!masterPasswordLogin()) return; // Copy selected signon's password to clipboard var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]. getService(Components.interfaces.nsIClipboardHelper); var row = document.getElementById("signonsTree").currentIndex; var password = signonsTreeView.getCellText(row, {id : "passwordCol" }); clipboard.copyString(password); Services.telemetry.getHistogramById("PWMGR_MANAGE_COPIED_PASSWORD").add(1); @@ -438,23 +409,17 @@ function UpdateContextMenu() { if (signonsTreeView.getCellText(selectedRow, { id: "userCol" }) != "") { menuItems.get("context-copyusername").removeAttribute("disabled"); } else { menuItems.get("context-copyusername").setAttribute("disabled", "true"); } menuItems.get("context-editusername").removeAttribute("disabled"); menuItems.get("context-copypassword").removeAttribute("disabled"); - - // Disable "Edit Password" if the password column isn't showing. - if (!document.getElementById("passwordCol").hidden) { - menuItems.get("context-editpassword").removeAttribute("disabled"); - } else { - menuItems.get("context-editpassword").setAttribute("disabled", "true"); - } + menuItems.get("context-editpassword").removeAttribute("disabled"); } function masterPasswordLogin(noPasswordCallback) { // This doesn't harm if passwords are not encrypted var tokendb = Components.classes["@mozilla.org/security/pk11tokendb;1"] .createInstance(Components.interfaces.nsIPK11TokenDB); var token = tokendb.getInternalKeyToken();
--- a/toolkit/components/passwordmgr/content/passwordManager.xul +++ b/toolkit/components/passwordmgr/content/passwordManager.xul @@ -77,19 +77,18 @@ ignoreincolumnpicker="true" sortDirection="ascending"/> <splitter class="tree-splitter"/> <treecol id="userCol" label="&treehead.username.label;" flex="25" ignoreincolumnpicker="true" data-field-name="username" persist="width"/> <splitter class="tree-splitter"/> <treecol id="passwordCol" label="&treehead.password.label;" flex="15" - ignoreincolumnpicker="true" - data-field-name="password" persist="width" - hidden="true"/> + data-field-name="password" persist="width hidden" + type="password"/> <splitter class="tree-splitter"/> <treecol id="timeCreatedCol" label="&treehead.timeCreated.label;" flex="10" data-field-name="timeCreated" persist="width hidden" hidden="true"/> <splitter class="tree-splitter"/> <treecol id="timeLastUsedCol" label="&treehead.timeLastUsed.label;" flex="20" data-field-name="timeLastUsed" persist="width hidden"/> <splitter class="tree-splitter"/> @@ -112,18 +111,16 @@ label="&removeall.label;" accesskey="&removeall.accesskey;" oncommand="DeleteAllSignons();"/> <spacer flex="1"/> #if defined(MOZ_BUILD_APP_IS_BROWSER) && defined(XP_WIN) <button accesskey="&import.accesskey;" label="&import.label;" oncommand="OpenMigrator();"/> #endif - <button id="togglePasswords" - oncommand="TogglePasswordVisible();"/> </hbox> </vbox> <hbox align="end"> <hbox class="actionButtons" flex="1"> <spacer flex="1"/> #ifndef XP_MACOSX <button oncommand="close();" icon="close" label="&closebutton.label;" accesskey="&closebutton.accesskey;"/>
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_contextmenu.js +++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_contextmenu.js @@ -45,28 +45,27 @@ function test() { assertMenuitemEnabled("copypassword", false); assertMenuitemEnabled("editpassword", false); info("Select the first row (with an empty username)"); selection.select(0); assertMenuitemEnabled("copyusername", false, "empty username"); assertMenuitemEnabled("editusername", true); assertMenuitemEnabled("copypassword", true); - assertMenuitemEnabled("editpassword", false, "password column hidden"); + assertMenuitemEnabled("editpassword", true); info("Clear the selection"); selection.clearSelection(); assertMenuitemEnabled("copyusername", false); assertMenuitemEnabled("editusername", false); assertMenuitemEnabled("copypassword", false); assertMenuitemEnabled("editpassword", false); info("Select the third row and making the password column visible"); selection.select(2); - doc.getElementById("passwordCol").hidden = false; assertMenuitemEnabled("copyusername", true); assertMenuitemEnabled("editusername", true); assertMenuitemEnabled("copypassword", true); assertMenuitemEnabled("editpassword", true, "password column visible"); menuitem.doCommand(); } function assertMenuitemEnabled(idSuffix, expected, reason = "") { @@ -75,17 +74,16 @@ function test() { is(actual, expected, idSuffix + " should be " + (expected ? "enabled" : "disabled") + (reason ? ": " + reason : "")); } function cleanUp() { Services.ww.registerNotification(function (aSubject, aTopic, aData) { Services.ww.unregisterNotification(arguments.callee); Services.logins.removeAllLogins(); - doc.getElementById("passwordCol").hidden = true; finish(); }); pwmgrdlg.close(); } function testPassword() { info("Testing Copy Password"); waitForClipboard("coded", function copyPassword() {
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js +++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js @@ -27,21 +27,16 @@ function synthesizeDblClickOnCell(aTree, let rect = tbo.getCoordsForCellItem(row, aTree.columns[column], "text"); let x = rect.x + rect.width / 2; let y = rect.y + rect.height / 2; // Simulate the double click. EventUtils.synthesizeMouse(aTree.body, x, y, { clickCount: 2 }, aTree.ownerDocument.defaultView); } -function* togglePasswords() { - pwmgrdlg.document.querySelector("#togglePasswords").doCommand(); - yield new Promise(resolve => waitForFocus(resolve, pwmgrdlg)); -} - function* editUsernamePromises(site, oldUsername, newUsername) { is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found"); let login = Services.logins.findLogins({}, site, "", "")[0]; is(login.username, oldUsername, "Correct username saved"); is(getUsername(0), oldUsername, "Correct username shown"); synthesizeDblClickOnCell(signonsTree, 1, 0); yield ContentTaskUtils.waitForCondition(() => signonsTree.getAttribute("editing"), "Waiting for editing"); @@ -109,19 +104,17 @@ add_task(function* test_setup() { }, pwmgrdlg); }); }); add_task(function* test_edit_multiple_logins() { function* testLoginChange(site, oldUsername, oldPassword, newUsername, newPassword) { addLogin(site, oldUsername, oldPassword); yield* editUsernamePromises(site, oldUsername, newUsername); - yield* togglePasswords(); yield* editPasswordPromises(site, oldPassword, newPassword); - yield* togglePasswords(); } yield* testLoginChange("http://c.tn/", "userC", "passC", "usernameC", "passwordC"); yield* testLoginChange("http://b.tn/", "userB", "passB", "usernameB", "passwordB"); yield* testLoginChange("http://a.tn/", "userA", "passA", "usernameA", "passwordA"); pwmgrdlg.close(); });
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_sort.js +++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_sort.js @@ -62,45 +62,16 @@ function test() { let doc = pwmgrdlg.document; let win = doc.defaultView; let sTree = doc.getElementById("signonsTree"); let filter = doc.getElementById("filter"); let siteCol = doc.getElementById("siteCol"); let userCol = doc.getElementById("userCol"); let passwordCol = doc.getElementById("passwordCol"); - let toggleCalls = 0; - function toggleShowPasswords(func) { - let toggleButton = doc.getElementById("togglePasswords"); - let showMode = (toggleCalls++ % 2) == 0; - - // only watch for a confirmation dialog every other time being called - if (showMode) { - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") - Services.ww.unregisterNotification(arguments.callee); - else if (aTopic == "domwindowopened") { - let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget); - SimpleTest.waitForFocus(function() { - EventUtils.sendKey("RETURN", win); - }, win); - } - }); - } - - Services.obs.addObserver(function (aSubject, aTopic, aData) { - if (aTopic == "passwordmgr-password-toggle-complete") { - Services.obs.removeObserver(arguments.callee, aTopic); - func(); - } - }, "passwordmgr-password-toggle-complete", false); - - EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win); - } - function clickCol(col) { EventUtils.synthesizeMouse(col, 20, 1, {}, win); setTimeout(runNextTest, 0); } function setFilter(string) { filter.value = string; filter.doCommand(); @@ -197,12 +168,11 @@ function test() { pwmgr.removeAllLogins(); finish(); }); pwmgrdlg.close(); } } - // Toggle Show Passwords to display Password column, then start tests - toggleShowPasswords(runNextTest); + runNextTest(); } }
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js +++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js @@ -52,98 +52,44 @@ function test() { let view = tree.view; is(filter.value, "", "Filter box should initially be empty"); is(view.rowCount, 10, "There should be 10 passwords initially"); // Prepare a set of tests // filter: the text entered in the filter search box // count: the number of logins which should match the respective filter - // count2: the number of logins which should match the respective filter - // if the passwords are being shown as well - // Note: if a test doesn't have count2 set, count is used instead. let tests = [ - {filter: "pass", count: 0, count2: 4}, + {filter: "pass", count: 4}, {filter: "", count: 10}, // test clearing the filter {filter: "moz", count: 7}, {filter: "mozi", count: 7}, {filter: "mozil", count: 7}, {filter: "mozill", count: 7}, {filter: "mozilla", count: 7}, - {filter: "mozilla.com", count: 1, count2: 2}, + {filter: "mozilla.com", count: 2}, {filter: "user", count: 4}, {filter: "user ", count: 1}, {filter: " user", count: 2}, {filter: "http", count: 10}, {filter: "https", count: 1}, - {filter: "secret", count: 0, count2: 2}, + {filter: "secret", count: 2}, {filter: "secret!", count: 0}, ]; - let toggleCalls = 0; - function toggleShowPasswords(func) { - let toggleButton = doc.getElementById("togglePasswords"); - let showMode = (toggleCalls++ % 2) == 0; - - // only watch for a confirmation dialog every other time being called - if (showMode) { - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") - Services.ww.unregisterNotification(arguments.callee); - else if (aTopic == "domwindowopened") { - let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget); - SimpleTest.waitForFocus(function() { - EventUtils.sendKey("RETURN", win); - }, win); - } - }); - } - - Services.obs.addObserver(function (aSubject, aTopic, aData) { - if (aTopic == "passwordmgr-password-toggle-complete") { - Services.obs.removeObserver(arguments.callee, aTopic); - func(); - } - }, "passwordmgr-password-toggle-complete", false); - - EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win); - } - - function runTests(mode, endFunction) { + function runTests(endFunction) { let testCounter = 0; function setFilter(string) { filter.value = string; filter.doCommand(); } function runOneTest(test) { - function tester() { - is(view.rowCount, expected, expected + " logins should match '" + test.filter + "'"); - } - - let expected; - switch (mode) { - case 1: // without showing passwords - expected = test.count; - break; - case 2: // showing passwords - expected = ("count2" in test) ? test.count2 : test.count; - break; - case 3: // toggle - expected = test.count; - tester(); - toggleShowPasswords(function () { - expected = ("count2" in test) ? test.count2 : test.count; - tester(); - toggleShowPasswords(proceed); - }); - return; - } - tester(); + is(view.rowCount, test.count, test.count + " logins should match '" + test.filter + "'"); proceed(); } function proceed() { // run the next test if necessary or proceed with the tests if (testCounter != tests.length) runNextTest(); else @@ -155,29 +101,17 @@ function test() { setFilter(test.filter); setTimeout(runOneTest, 0, test); } runNextTest(); } function step1() { - runTests(1, step2); - } - - function step2() { - toggleShowPasswords(function() { - runTests(2, step3); - }); - } - - function step3() { - toggleShowPasswords(function() { - runTests(3, lastStep); - }); + runTests(lastStep); } function lastStep() { // cleanup Services.ww.registerNotification(function (aSubject, aTopic, aData) { // unregister ourself Services.ww.unregisterNotification(arguments.callee);
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -8637,21 +8637,16 @@ "description": "Accumulates how the password management interface was opened. (0=Preferences, 1=Page Info)" }, "PWMGR_MANAGE_SORTED": { "expires_in_version": "never", "keyed": true, "kind": "count", "description": "Reports the column that logins are sorted by" }, - "PWMGR_MANAGE_VISIBILITY_TOGGLED": { - "expires_in_version": "never", - "kind": "boolean", - "description": "Whether the visibility of passwords was toggled (0=Hide, 1=Show)" - }, "PWMGR_NUM_PASSWORDS_PER_HOSTNAME": { "expires_in_version": "never", "kind": "linear", "high": 21, "n_buckets" : 20, "description": "The number of passwords per hostname" }, "PWMGR_NUM_SAVED_PASSWORDS": {
--- a/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties +++ b/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties @@ -42,21 +42,16 @@ passwordChangeTitle = Confirm Password C # String is the username for the login. updatePasswordMsg = Would you like to update the saved password for "%S"? updatePasswordMsgNoUser = Would you like to update the saved password? notifyBarUpdateButtonText = Update Password notifyBarUpdateButtonAccessKey = U notifyBarDontChangeButtonText = Don't Change notifyBarDontChangeButtonAccessKey = D userSelectText = Please confirm which user you are changing the password for -hidePasswords=Hide Passwords -hidePasswordsAccessKey=P -showPasswords=Show Passwords -showPasswordsAccessKey=P -noMasterPasswordPrompt=Are you sure you wish to show your passwords? removeAllPasswordsPrompt=Are you sure you wish to remove all passwords? removeAllPasswordsTitle=Remove all passwords removeLoginPrompt=Are you sure you wish to remove this login? removeLoginTitle=Remove login loginsDescriptionAll=Logins for the following sites are stored on your computer: loginsDescriptionFiltered=The following logins match your search: # LOCALIZATION NOTE (loginHostAge): # This is used to show the context menu login items with their age.