diff --git a/mobile/android/chrome/content/aboutPasswords.js b/mobile/android/chrome/content/aboutPasswords.js index 910883dbab7..48636f00e2f 100644 --- a/mobile/android/chrome/content/aboutPasswords.js +++ b/mobile/android/chrome/content/aboutPasswords.js @@ -32,17 +32,52 @@ function copyStringAndToast(string, notifyString) { } let Passwords = { + _logins: [], + + _getLogins: function() { + let logins; + try { + logins = Services.logins.getAllLogins(); + } catch(e) { + // Master password was not entered + debug("Master password permissions error: " + e); + logins = []; + } + + logins.sort((a, b) => a.hostname.localeCompare(b.hostname)); + return this._logins = logins; + }, + init: function () { window.addEventListener("popstate", this , false); Services.obs.addObserver(this, "passwordmgr-storage-changed", false); - this._loadList(); + this._loadList(this._getLogins()); document.getElementById("copyusername-btn").addEventListener("click", this._copyUsername.bind(this), false); document.getElementById("copypassword-btn").addEventListener("click", this._copyPassword.bind(this), false); document.getElementById("details-header").addEventListener("click", this._openLink.bind(this), false); + let filterInput = document.getElementById("filter-input"); + let filterContainer = document.getElementById("filter-input-container"); + + filterInput.addEventListener("input", this._filter.bind(this), false); + filterInput.addEventListener("blur", (event) => { + filterContainer.setAttribute("hidden", true); + }); + + document.getElementById("filter-button").addEventListener("click", (event) => { + filterContainer.removeAttribute("hidden"); + filterInput.focus(); + }, false); + + document.getElementById("filter-clear").addEventListener("click", (event) => { + filterInput.blur(); + filterInput.value = ""; + this._loadList(this._logins); + }, false); + this._showList(); }, @@ -51,27 +86,16 @@ let Passwords = { window.removeEventListener("popstate", this, false); }, - _loadList: function () { - let logins; - try { - logins = Services.logins.getAllLogins(); - } catch(e) { - // Master password was not entered - debug("Master password permissions error: " + e); - return; - } - - logins.forEach(login => login.QueryInterface(Ci.nsILoginMetaInfo)); - - logins.sort((a, b) => a.hostname.localeCompare(b.hostname)); - - // Clear all content before filling the logins + _loadList: function (logins) { let list = document.getElementById("logins-list"); - list.innerHTML = ""; + let newList = list.cloneNode(false); + logins.forEach(login => { let item = this._createItemForLogin(login); - list.appendChild(item); + newList.appendChild(item); }); + + list.parentNode.replaceChild(newList, list); }, _showList: function () { @@ -158,7 +182,7 @@ let Passwords = { switch(topic) { case "passwordmgr-storage-changed": { // Reload passwords content. - this._loadList(); + this._loadList(this._getLogins()); break; } } @@ -217,6 +241,26 @@ let Passwords = { let url = clickEvent.currentTarget.getAttribute("link"); let BrowserApp = gChromeWin.BrowserApp; BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }); + }, + + _filter: function(event) { + let value = event.target.value; + let logins = this._logins.filter((login) => { + if (login.hostname.toLowerCase().indexOf(value) != -1) { + return true; + } + if (login.username && + login.username.toLowerCase().indexOf(value) != -1) { + return true; + } + if (login.httpRealm && + login.httpRealm.toLowerCase().indexOf(value) != -1) { + return true; + } + return false; + }); + + this._loadList(logins); } }; diff --git a/mobile/android/chrome/content/aboutPasswords.xhtml b/mobile/android/chrome/content/aboutPasswords.xhtml index 3de98259242..a799efaa60a 100644 --- a/mobile/android/chrome/content/aboutPasswords.xhtml +++ b/mobile/android/chrome/content/aboutPasswords.xhtml @@ -23,6 +23,9 @@
&aboutPasswords.title;
+
@@ -43,5 +46,9 @@ + diff --git a/mobile/android/themes/core/aboutPasswords.css b/mobile/android/themes/core/aboutPasswords.css index 18c81bbfa84..63ddbb23556 100644 --- a/mobile/android/themes/core/aboutPasswords.css +++ b/mobile/android/themes/core/aboutPasswords.css @@ -1,6 +1,10 @@ /* 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/. */ + +%filter substitution +%include defines.inc + .hidden { display: none; } @@ -30,3 +34,71 @@ /* hostname is not localized, so keep the margin on the left side */ margin-left: .67em; } + +.toolbar-buttons { + list-style: none; +} + +.toolbar-buttons > li { + background-position: center; + background-size: 32px 32px; + background-repeat: no-repeat; + height: 32px; + width: 32px; + margin: 0 15px; +} + +#filter-input-container { + position: fixed; + bottom: 0; + width: 100%; + padding: 10px 0; + display: flex; + background: @color_about_background@; + border-top: 2px solid @color_about_item_border@; +} + +#filter-input-container[hidden] { + display: none; +} + +#filter-input { + flex: 1; + padding: 5px; + -moz-margin-start: 10px; + border-radius: 3px; +} + +#filter-button { + background-image: url("resource://android/res/drawable-mdpi-v4/ab_search.png"); +} + +#filter-clear { + background-image: url("resource://android/res/drawable-mdpi-v4/close_edit_mode_light.png"); + background-position: center; + background-size: 12px 12px; + background-repeat: no-repeat; + height: 32px; + width: 32px; + margin: 0 5px; +} + +@media screen and (min-resolution: 1.25dppx) { + #filter-button { + background-image: url("resource://android/res/drawable-hdpi-v4/ab_search.png"); + } + + #filter-clear { + background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png"); + } +} + +@media screen and (min-resolution: 2dppx) { + #filter-button { + background-image: url("resource://android/res/drawable-xhdpi-v4/ab_search.png"); + } + + #filter-clear { + background-image: url("resource://android/res/drawable-hdpi-v4/close_edit_mode_light.png"); + } +} diff --git a/mobile/android/themes/core/jar.mn b/mobile/android/themes/core/jar.mn index 2df29526258..c66134cc015 100644 --- a/mobile/android/themes/core/jar.mn +++ b/mobile/android/themes/core/jar.mn @@ -36,7 +36,7 @@ chrome.jar: % override chrome://global/skin/netError.css chrome://browser/skin/netError.css #ifdef NIGHTLY_BUILD - skin/aboutPasswords.css (aboutPasswords.css) +* skin/aboutPasswords.css (aboutPasswords.css) #endif skin/images/search.png (images/search.png)