diff options
Diffstat (limited to 'mobile/android/chrome/content/aboutLogins.js')
-rw-r--r-- | mobile/android/chrome/content/aboutLogins.js | 517 |
1 files changed, 0 insertions, 517 deletions
diff --git a/mobile/android/chrome/content/aboutLogins.js b/mobile/android/chrome/content/aboutLogins.js deleted file mode 100644 index b3d003875..000000000 --- a/mobile/android/chrome/content/aboutLogins.js +++ /dev/null @@ -1,517 +0,0 @@ -/* 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/. */ - -var Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils; - -Cu.import("resource://services-common/utils.js"); /*global: CommonUtils */ -Cu.import("resource://gre/modules/Messaging.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyGetter(window, "gChromeWin", () => - window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .QueryInterface(Ci.nsIDOMChromeWindow)); - -XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Snackbars.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Prompt", - "resource://gre/modules/Prompt.jsm"); - -var debug = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "AboutLogins"); - -var gStringBundle = Services.strings.createBundle("chrome://browser/locale/aboutLogins.properties"); - -function copyStringShowSnackbar(string, notifyString) { - try { - let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); - clipboard.copyString(string); - Snackbars.show(notifyString, Snackbars.LENGTH_LONG); - } catch (e) { - debug("Error copying from about:logins"); - Snackbars.show(gStringBundle.GetStringFromName("loginsDetails.copyFailed"), Snackbars.LENGTH_LONG); - } -} - -// Delay filtering while typing in MS -const FILTER_DELAY = 500; - -var Logins = { - _logins: [], - _filterTimer: null, - _selectedLogin: null, - - // Load the logins list, displaying interstitial UI (see - // #logins-list-loading-body) while loading. There are careful - // jank-avoiding measures taken in this function; be careful when - // modifying it! - // - // Returns a Promise that resolves to the list of logins, ordered by - // hostname. - _promiseLogins: function() { - let contentBody = document.getElementById("content-body"); - let emptyBody = document.getElementById("empty-body"); - let filterIcon = document.getElementById("filter-button"); - - let showSpinner = () => { - this._toggleListBody(true); - emptyBody.classList.add("hidden"); - }; - - let getAllLogins = () => { - let logins = []; - try { - logins = Services.logins.getAllLogins(); - } catch(e) { - // It's likely that the Master Password was not entered; give - // a hint to the next person. - throw new Error("Possible Master Password permissions error: " + e.toString()); - } - - logins.sort((a, b) => a.hostname.localeCompare(b.hostname)); - - return logins; - }; - - let hideSpinner = (logins) => { - this._toggleListBody(false); - - if (!logins.length) { - contentBody.classList.add("hidden"); - filterIcon.classList.add("hidden"); - emptyBody.classList.remove("hidden"); - } else { - contentBody.classList.remove("hidden"); - emptyBody.classList.add("hidden"); - } - - return logins; - }; - - // Return a promise that is resolved after a paint. - let waitForPaint = () => { - // We're changing 'display'. We need to wait for the new value to take - // effect; otherwise, we'll block and never paint a change. Since - // requestAnimationFrame callback is generally triggered *before* any - // style flush and layout, we wait for two animation frames. This - // approach was cribbed from - // https://dxr.mozilla.org/mozilla-central/rev/5abe3c4deab94270440422c850bbeaf512b1f38d/browser/base/content/browser-fullScreen.js?offset=0#469. - return new Promise(function(resolve, reject) { - requestAnimationFrame(() => { - requestAnimationFrame(() => { - resolve(); - }); - }); - }); - }; - - // getAllLogins janks the main-thread. We need to paint before that jank; - // by throwing the janky load onto the next tick, we paint the spinner; the - // spinner is CSS animated off-main-thread. - return Promise.resolve() - .then(showSpinner) - .then(waitForPaint) - .then(getAllLogins) - .then(hideSpinner); - }, - - // Reload the logins list, displaying interstitial UI while loading. - // Update the stored and displayed list upon completion. - _reloadList: function() { - this._promiseLogins() - .then((logins) => { - this._logins = logins; - this._loadList(logins); - }) - .catch((e) => { - // There's no way to recover from errors, sadly. Log and make - // it obvious that something is up. - this._logins = []; - debug("Failed to _reloadList!"); - Cu.reportError(e); - }); - }, - - _toggleListBody: function(isLoading) { - let contentBody = document.getElementById("content-body"); - let loadingBody = document.getElementById("logins-list-loading-body"); - - if (isLoading) { - contentBody.classList.add("hidden"); - loadingBody.classList.remove("hidden"); - } else { - loadingBody.classList.add("hidden"); - contentBody.classList.remove("hidden"); - } - }, - - init: function () { - window.addEventListener("popstate", this , false); - - Services.obs.addObserver(this, "passwordmgr-storage-changed", false); - document.getElementById("update-btn").addEventListener("click", this._onSaveEditLogin.bind(this), false); - document.getElementById("password-btn").addEventListener("click", this._onPasswordBtn.bind(this), false); - - let filterInput = document.getElementById("filter-input"); - let filterContainer = document.getElementById("filter-input-container"); - - filterInput.addEventListener("input", (event) => { - // Stop any in-progress filter timer - if (this._filterTimer) { - clearTimeout(this._filterTimer); - this._filterTimer = null; - } - - // Start a new timer - this._filterTimer = setTimeout(() => { - this._filter(event); - }, FILTER_DELAY); - }, 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) => { - // Stop any in-progress filter timer - if (this._filterTimer) { - clearTimeout(this._filterTimer); - this._filterTimer = null; - } - - filterInput.blur(); - filterInput.value = ""; - this._loadList(this._logins); - }, false); - - this._showList(); - - this._updatePasswordBtn(true); - - this._reloadList(); - }, - - uninit: function () { - Services.obs.removeObserver(this, "passwordmgr-storage-changed"); - window.removeEventListener("popstate", this, false); - }, - - _loadList: function (logins) { - let list = document.getElementById("logins-list"); - let newList = list.cloneNode(false); - - logins.forEach(login => { - let item = this._createItemForLogin(login); - newList.appendChild(item); - }); - - list.parentNode.replaceChild(newList, list); - }, - - _showList: function () { - let loginsListPage = document.getElementById("logins-list-page"); - loginsListPage.classList.remove("hidden"); - - let editLoginPage = document.getElementById("edit-login-page"); - editLoginPage.classList.add("hidden"); - - // If the Show/Hide password button has been flipped, reset it - if (this._isPasswordBtnInHideMode()) { - this._updatePasswordBtn(true); - } - }, - - _onPopState: function (event) { - // Called when back/forward is used to change the state of the page - if (event.state) { - this._showEditLoginDialog(event.state.id); - } else { - this._selectedLogin = null; - this._showList(); - } - }, - _showEditLoginDialog: function (login) { - let listPage = document.getElementById("logins-list-page"); - listPage.classList.add("hidden"); - - let editLoginPage = document.getElementById("edit-login-page"); - editLoginPage.classList.remove("hidden"); - - let usernameField = document.getElementById("username"); - usernameField.value = login.username; - let passwordField = document.getElementById("password"); - passwordField.value = login.password; - let domainField = document.getElementById("hostname"); - domainField.value = login.hostname; - - let img = document.getElementById("favicon"); - this._loadFavicon(img, login.hostname); - - let headerText = document.getElementById("edit-login-header-text"); - if (login.hostname && (login.hostname != "")) { - headerText.textContent = login.hostname; - } - else { - headerText.textContent = gStringBundle.GetStringFromName("editLogin.fallbackTitle"); - } - - passwordField.addEventListener("input", (event) => { - let newPassword = passwordField.value; - let updateBtn = document.getElementById("update-btn"); - - if (newPassword === "") { - updateBtn.disabled = true; - updateBtn.classList.add("disabled-btn"); - } else if ((newPassword !== "") && (updateBtn.disabled === true)) { - updateBtn.disabled = false; - updateBtn.classList.remove("disabled-btn"); - } - }, false); - }, - - _onSaveEditLogin: function() { - let newUsername = document.getElementById("username").value; - let newPassword = document.getElementById("password").value; - let newDomain = document.getElementById("hostname").value; - let origUsername = this._selectedLogin.username; - let origPassword = this._selectedLogin.password; - let origDomain = this._selectedLogin.hostname; - - try { - if ((newUsername === origUsername) && - (newPassword === origPassword) && - (newDomain === origDomain) ) { - Snackbars.show(gStringBundle.GetStringFromName("editLogin.saved1"), Snackbars.LENGTH_LONG); - this._showList(); - return; - } - - let logins = Services.logins.findLogins({}, origDomain, origDomain, null); - - for (let i = 0; i < logins.length; i++) { - if (logins[i].username == origUsername) { - let clone = logins[i].clone(); - clone.username = newUsername; - clone.password = newPassword; - clone.hostname = newDomain; - Services.logins.removeLogin(logins[i]); - Services.logins.addLogin(clone); - break; - } - } - } catch (e) { - Snackbars.show(gStringBundle.GetStringFromName("editLogin.couldNotSave"), Snackbars.LENGTH_LONG); - return; - } - Snackbars.show(gStringBundle.GetStringFromName("editLogin.saved1"), Snackbars.LENGTH_LONG); - this._showList(); - }, - - _onPasswordBtn: function () { - this._updatePasswordBtn(this._isPasswordBtnInHideMode()); - }, - - _updatePasswordBtn: function (aShouldShow) { - let passwordField = document.getElementById("password"); - let button = document.getElementById("password-btn"); - let show = gStringBundle.GetStringFromName("password-btn.show"); - let hide = gStringBundle.GetStringFromName("password-btn.hide"); - if (aShouldShow) { - passwordField.type = "password"; - button.textContent = show; - button.classList.remove("password-btn-hide"); - } else { - passwordField.type = "text"; - button.textContent= hide; - button.classList.add("password-btn-hide"); - } - }, - - _isPasswordBtnInHideMode: function () { - let button = document.getElementById("password-btn"); - return button.classList.contains("password-btn-hide"); - }, - - _showPassword: function(password) { - let passwordPrompt = new Prompt({ - window: window, - message: password, - buttons: [ - gStringBundle.GetStringFromName("loginsDialog.copy"), - gStringBundle.GetStringFromName("loginsDialog.cancel") ] - }).show((data) => { - switch (data.button) { - case 0: - // Corresponds to "Copy password" button. - copyStringShowSnackbar(password, gStringBundle.GetStringFromName("loginsDetails.passwordCopied")); - } - }); - }, - - _onLoginClick: function (event) { - let loginItem = event.currentTarget; - let login = loginItem.login; - if (!login) { - debug("No login!"); - return; - } - - let prompt = new Prompt({ - window: window, - }); - let menuItems = [ - { label: gStringBundle.GetStringFromName("loginsMenu.showPassword") }, - { label: gStringBundle.GetStringFromName("loginsMenu.copyPassword") }, - { label: gStringBundle.GetStringFromName("loginsMenu.copyUsername") }, - { label: gStringBundle.GetStringFromName("loginsMenu.editLogin") }, - { label: gStringBundle.GetStringFromName("loginsMenu.delete") } - ]; - - prompt.setSingleChoiceItems(menuItems); - prompt.show((data) => { - // Switch on indices of buttons, as they were added when creating login item. - switch (data.button) { - case 0: - this._showPassword(login.password); - break; - case 1: - copyStringShowSnackbar(login.password, gStringBundle.GetStringFromName("loginsDetails.passwordCopied")); - break; - case 2: - copyStringShowSnackbar(login.username, gStringBundle.GetStringFromName("loginsDetails.usernameCopied")); - break; - case 3: - this._selectedLogin = login; - this._showEditLoginDialog(login); - history.pushState({ id: login.guid }, document.title); - break; - case 4: - let confirmPrompt = new Prompt({ - window: window, - message: gStringBundle.GetStringFromName("loginsDialog.confirmDelete"), - buttons: [ - gStringBundle.GetStringFromName("loginsDialog.confirm"), - gStringBundle.GetStringFromName("loginsDialog.cancel") ] - }); - confirmPrompt.show((data) => { - switch (data.button) { - case 0: - // Corresponds to "confirm" button. - Services.logins.removeLogin(login); - } - }); - } - }); - }, - - _loadFavicon: function (aImg, aHostname) { - // Load favicon from cache. - Messaging.sendRequestForResult({ - type: "Favicon:CacheLoad", - url: aHostname, - }).then(function(faviconUrl) { - aImg.style.backgroundImage= "url('" + faviconUrl + "')"; - aImg.style.visibility = "visible"; - }, function(data) { - debug("Favicon cache failure : " + data); - aImg.style.visibility = "visible"; - }); - }, - - _createItemForLogin: function (login) { - let loginItem = document.createElement("div"); - - loginItem.setAttribute("loginID", login.guid); - loginItem.className = "login-item list-item"; - - loginItem.addEventListener("click", this, true); - - // Create item icon. - let img = document.createElement("div"); - img.className = "icon"; - - this._loadFavicon(img, login.hostname); - loginItem.appendChild(img); - - // Create item details. - let inner = document.createElement("div"); - inner.className = "inner"; - - let details = document.createElement("div"); - details.className = "details"; - inner.appendChild(details); - - let titlePart = document.createElement("div"); - titlePart.className = "hostname"; - titlePart.textContent = login.hostname; - details.appendChild(titlePart); - - let versionPart = document.createElement("div"); - versionPart.textContent = login.httpRealm; - versionPart.className = "realm"; - details.appendChild(versionPart); - - let descPart = document.createElement("div"); - descPart.textContent = login.username; - descPart.className = "username"; - inner.appendChild(descPart); - - loginItem.appendChild(inner); - loginItem.login = login; - return loginItem; - }, - - handleEvent: function (event) { - switch (event.type) { - case "popstate": { - this._onPopState(event); - break; - } - case "click": { - this._onLoginClick(event); - break; - } - } - }, - - observe: function (subject, topic, data) { - switch(topic) { - case "passwordmgr-storage-changed": { - this._reloadList(); - break; - } - } - }, - - _filter: function(event) { - let value = event.target.value.toLowerCase(); - 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); - } -}; - -window.addEventListener("load", Logins.init.bind(Logins), false); -window.addEventListener("unload", Logins.uninit.bind(Logins), false); |