Skip to content

Commit

Permalink
Bug 1613620 - Provide an option to remove all logins at once from abo…
Browse files Browse the repository at this point in the history
…ut:logins. r=prathiksha,fluent-reviewers,sfoster,markh

Depends on D89078

Differential Revision: https://phabricator.services.mozilla.com/D91198
  • Loading branch information
TGiles committed Nov 17, 2020
1 parent b4428b8 commit 3b9709f
Show file tree
Hide file tree
Showing 79 changed files with 937 additions and 111 deletions.
1 change: 1 addition & 0 deletions browser/components/BrowserGlue.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ let JSWINDOWACTORS = {
AboutLoginsOpenPreferences: { wantUntrusted: true },
AboutLoginsOpenSite: { wantUntrusted: true },
AboutLoginsRecordTelemetryEvent: { wantUntrusted: true },
AboutLoginsRemoveAllLogins: { wantUntrusted: true },
AboutLoginsSortChanged: { wantUntrusted: true },
AboutLoginsSyncEnable: { wantUntrusted: true },
AboutLoginsSyncOptions: { wantUntrusted: true },
Expand Down
4 changes: 4 additions & 0 deletions browser/components/aboutlogins/AboutLoginsChild.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ class AboutLoginsChild extends JSWindowActorChild {
recordTelemetryEvent(event.detail);
break;
}
case "AboutLoginsRemoveAllLogins": {
this.sendAsyncMessage("AboutLogins:RemoveAllLogins");
break;
}
case "AboutLoginsSortChanged": {
this.sendAsyncMessage("AboutLogins:SortChanged", event.detail);
break;
Expand Down
7 changes: 7 additions & 0 deletions browser/components/aboutlogins/AboutLoginsParent.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ class AboutLoginsParent extends JSWindowActorParent {
fp.open(fpCallback);
break;
}
case "AboutLogins:RemoveAllLogins": {
Services.logins.removeAllUserFacingLogins();
break;
}
}
}

Expand Down Expand Up @@ -790,12 +794,14 @@ var AboutLogins = {
// authenticated. More diagnostics and error states can be handled
// by other more Sync-specific pages.
const loggedIn = state.status != UIState.STATUS_NOT_CONFIGURED;
const passwordSyncEnabled = state.syncEnabled && PASSWORD_SYNC_ENABLED;

return {
loggedIn,
email: state.email,
avatarURL: state.avatarURL,
fxAccountsEnabled: FXA_ENABLED,
passwordSyncEnabled,
};
},

Expand All @@ -815,6 +821,7 @@ var AboutLogins = {
onPasswordSyncEnabledPreferenceChange(data, previous, latest) {
Services.prefs.clearUserPref(SHOW_PASSWORD_SYNC_NOTIFICATION_PREF);
this.updatePasswordSyncNotificationState(this.getSyncState(), latest);
this.messageSubscribers("AboutLogins:SyncState", this.getSyncState());
},
};
var _AboutLogins = AboutLogins;
Expand Down
28 changes: 28 additions & 0 deletions browser/components/aboutlogins/content/aboutLogins.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<link rel="localization" href="browser/branding/brandings.ftl">
<link rel="localization" href="browser/aboutLogins.ftl">
<script type="module" src="chrome://browser/content/aboutlogins/components/confirmation-dialog.js"></script>
<script type="module" src="chrome://browser/content/aboutlogins/components/remove-logins-dialog.js"></script>
<script type="module" src="chrome://browser/content/aboutlogins/components/fxaccounts-button.js"></script>
<script type="module" src="chrome://browser/content/aboutlogins/components/login-filter.js"></script>
<script type="module" src="chrome://browser/content/aboutlogins/components/login-intro.js"></script>
Expand All @@ -37,6 +38,7 @@
<login-item></login-item>
<login-intro></login-intro>
<confirmation-dialog hidden></confirmation-dialog>
<remove-logins-dialog hidden></remove-logins-dialog>
<div id="master-password-required-overlay"></div>

<template id="confirmation-dialog-template">
Expand All @@ -61,6 +63,31 @@ <h1 class="title" id="title"></h1>
</div>
</template>

<template id="remove-logins-dialog-template">
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/remove-logins-dialog.css">
<div class="overlay">
<div class="container" role="dialog" aria-labelledby="title" aria-describedby="message">
<button class="dismiss-button" data-l10n-id="confirmation-dialog-dismiss-button">
<img class="dismiss-icon" src="chrome://global/skin/icons/close.svg"/>
</button>
<div class="content">
<img class="warning-icon" src="chrome://global/skin/icons/delete.svg"/>
<h1 class="title" id="title"></h1>
<p class="message" id="message"></p>
<div class="checkbox-wrapper">
<input id="confirmation-checkbox" type="checkbox" class="checkbox"></input>
<label for="confirmation-checkbox"></label>
</div>
</div>
<div class="buttons">
<button class="confirm-button danger-button"></button>
<button class="cancel-button" data-l10n-id="confirmation-dialog-cancel-button"></button>
</div>
</div>
</template>

<template id="fxaccounts-button-template">
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/common.css">
Expand Down Expand Up @@ -275,6 +302,7 @@ <h3 class="alert-title" data-l10n-id="about-logins-vulnerable-alert-title"></h3>
<button role="menuitem" class="menuitem-button menuitem-import-browser ghost-button" hidden data-supported-platforms="Win32,MacIntel" data-event-name="AboutLoginsImportFromBrowser" data-l10n-id="about-logins-menu-menuitem-import-from-another-browser"></button>
<button role="menuitem" class="menuitem-button menuitem-import-file ghost-button" data-event-name="AboutLoginsImportFromFile" data-l10n-id="about-logins-menu-menuitem-import-from-a-file"></button>
<button role="menuitem" class="menuitem-button menuitem-export ghost-button" data-event-name="AboutLoginsExportPasswordsDialog" data-l10n-id="about-logins-menu-menuitem-export-logins"></button>
<button role="menuitem" class="menuitem-button menuitem-remove-all-logins ghost-button" data-event-name="AboutLoginsRemoveAllLoginsDialog" data-l10n-id="about-logins-menu-menuitem-remove-all-logins"></button>
<hr role="separator" class="menuitem-separator"></hr>
<button role="menuitem" class="menuitem-button menuitem-preferences ghost-button" data-event-name="AboutLoginsOpenPreferences" data-l10n-id="menu-menuitem-preferences"></button>
<hr role="separator" class="menuitem-separator"></hr>
Expand Down
47 changes: 47 additions & 0 deletions browser/components/aboutlogins/content/aboutLogins.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ const gElements = {
loginIntro: document.querySelector("login-intro"),
loginItem: document.querySelector("login-item"),
loginFilter: document.querySelector("login-filter"),
menuButton: document.querySelector("menu-button"),
// removeAllLogins button is nested inside of menuButton
get removeAllButton() {
return this.menuButton.shadowRoot.querySelector(
".menuitem-remove-all-logins"
);
},
};

let numberOfLogins = 0;
Expand All @@ -23,6 +30,7 @@ function updateNoLogins() {
document.documentElement.classList.toggle("no-logins", numberOfLogins == 0);
gElements.loginList.classList.toggle("no-logins", numberOfLogins == 0);
gElements.loginItem.classList.toggle("no-logins", numberOfLogins == 0);
gElements.removeAllButton.disabled = numberOfLogins == 0;
}

function handleAllLogins(logins) {
Expand All @@ -31,9 +39,14 @@ function handleAllLogins(logins) {
updateNoLogins();
}

let fxaLoggedIn = null;
let passwordSyncEnabled = null;

function handleSyncState(syncState) {
gElements.fxAccountsButton.updateState(syncState);
gElements.loginIntro.updateState(syncState);
fxaLoggedIn = syncState.loggedIn;
passwordSyncEnabled = syncState.passwordSyncEnabled;
}

window.addEventListener("AboutLoginsChromeToContent", event => {
Expand Down Expand Up @@ -115,6 +128,40 @@ window.addEventListener("AboutLoginsChromeToContent", event => {
}
});

window.addEventListener("AboutLoginsRemoveAllLoginsDialog", () => {
let options = {};
if (fxaLoggedIn && passwordSyncEnabled) {
options.title = "about-logins-confirm-remove-all-sync-dialog-title";
options.message = "about-logins-confirm-remove-all-sync-dialog-message";
} else {
options.title = "about-logins-confirm-remove-all-dialog-title";
options.message = "about-logins-confirm-remove-all-dialog-message";
}
options.confirmCheckboxLabel =
"about-logins-confirm-remove-all-dialog-checkbox-label";
options.confirmButtonLabel =
"about-logins-confirm-remove-all-dialog-confirm-button";
options.count = numberOfLogins;

let dialog = document.querySelector("remove-logins-dialog");
let dialogPromise = dialog.show(options);
try {
dialogPromise.then(
() => {
let removeAllEvt = new CustomEvent("AboutLoginsRemoveAllLogins", {
bubbles: true,
});
window.dispatchEvent(removeAllEvt);
},
() => {}
);
} catch (e) {
if (e != undefined) {
throw e;
}
}
});

window.addEventListener("AboutLoginsExportPasswordsDialog", async event => {
recordTelemetryEvent({
object: "export",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
background-image: url("chrome://browser/skin/save.svg");
}

.menuitem-remove-all-logins {
background-image: url("chrome://global/skin/icons/delete.svg");
}

.menuitem-preferences {
background-image: url("chrome://global/skin/icons/settings.svg");
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ export default class MenuButton extends HTMLElement {
if (this._menu.hidden) {
this._showMenu();
}
if (successor.disabled) {
if (next) {
successor = items[activeItemIndex + 2];
} else {
successor = items[activeItemIndex - 2];
}
}
successor.focus();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* 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/. */

.overlay {
position: fixed;
z-index: 1;
inset: 0;
/* TODO: this color is used in the about:preferences overlay, but
why isn't it declared as a variable? */
background-color: rgba(0,0,0,0.5);
display: flex;
}

.container {
z-index: 2;
position: relative;
display: flex;
flex-direction: column;
min-width: 300px;
max-width: 660px;
min-height: 200px;
align-self: center;
margin-inline-start: calc(var(--sidebar-width) - 48px);
background-color: var(--in-content-page-background);
color: var(--in-content-text-color);
box-shadow: var(--shadow-30);
/* show a border in high contrast mode */
outline: 1px solid transparent;
}

.title {
grid-area: 1 / 2 / 2 / 8;
}

.message {
font-weight: 600;
grid-area: 2 / 2 / 3 / 8;
font-size: 1.25em;
}

label[for="confirmation-checkbox"] {
font-size: 1.25em;
}

.dismiss-button {
position: absolute;
top: 0;
inset-inline-end: 0;
min-width: 20px;
min-height: 20px;
margin: 16px;
padding: 0;
line-height: 0;
}

.dismiss-icon {
-moz-context-properties: fill, fill-opacity;
fill: currentColor;
fill-opacity: 0;
}

.warning-icon {
-moz-context-properties: fill;
fill: currentColor;
width: 32px;
height: 32px;
margin: 8px;
}

.content,
.buttons {
padding: 36px 48px;
padding-bottom: 24px;
}

.content {
display: grid;
grid-template-columns: 0.5fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 0.5fr 0.5fr 0.5fr;
}

.checkbox-wrapper {
display: flex;
grid-area: 3 / 2 / 4 / 8;
align-self: first baseline;
}

.warning-icon {
grid-area: 1 / 1 / 2 / 2;
}

.checkbox {
grid-area: 3 / 2 / 4 / 8;
font-size: 1.1em;
align-self: center;
}

.buttons {
display: flex;
justify-content: flex-end;
padding-block: 16px 32px;
padding-inline: 48px 0;
border-top: 1px solid var(--in-content-border-color);
margin-inline: 48px;
}

.buttons.macosx > .confirm-button {
order: 1;
}

.buttons > button {
min-width: 140px;
}
Loading

0 comments on commit 3b9709f

Please sign in to comment.