forked from mirrors/gecko-dev
Bug 1893277 - build initial UI for turning on scheduled backups. r=backup-reviewers,firefox-desktop-core-reviewers ,fluent-reviewers,mconley
backup-settings changes: - adds a new button in the Backup section of about:preferences / about:settings - shows the turn on dialog after pressing the button Turn on dialog behaviour (implemented): - pressing the cancel will close the dialog - pressing the confirm button will set the pref browser.backup.scheduled.enabled=true and close the dialog - pressing the passwords checkbox will show more options Turn on dialog behaviour (not implemented): - requiring a password for the backup (see Bug 1895981) - modifying the save location and showing a file picker (see Bug 1895943) Other changes: - tests for backup-settings and the turn on dialog - Storybook template for the turn on dialog Lo-fi Figma designs: https://www.figma.com/design/vNbX4c0ws0L1qr0mxpKvsW/Fx-Backup?node-id=147-4558&t=PYLY0QMN1n8GR9vW-0 Differential Revision: https://phabricator.services.mozilla.com/D209769
This commit is contained in:
parent
421acc9093
commit
a39846bf34
18 changed files with 721 additions and 13 deletions
|
|
@ -3052,6 +3052,8 @@ pref("browser.mailto.prompt.os", true);
|
|||
|
||||
// Pref to initialize the BackupService soon after startup.
|
||||
pref("browser.backup.enabled", true);
|
||||
// Pref to control whether scheduled backups run or not.
|
||||
pref("browser.backup.scheduled.enabled", false);
|
||||
// Pref to control the visibility of the backup section in about:preferences
|
||||
pref("browser.backup.preferences.ui.enabled", false);
|
||||
// The number of SQLite database pages to backup per step.
|
||||
|
|
|
|||
|
|
@ -439,6 +439,7 @@ let JSWINDOWACTORS = {
|
|||
esModuleURI: "resource:///actors/BackupUIChild.sys.mjs",
|
||||
events: {
|
||||
"BackupUI:InitWidget": { wantUntrusted: true },
|
||||
"BackupUI:ScheduledBackupsConfirm": { wantUntrusted: true },
|
||||
},
|
||||
},
|
||||
matches: ["about:preferences*", "about:settings*"],
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
import * as DefaultBackupResources from "resource:///modules/backup/BackupResources.sys.mjs";
|
||||
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||
|
||||
const SCHEDULED_BACKUPS_ENABLED_PREF_NAME = "browser.backup.scheduled.enabled";
|
||||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "logConsole", function () {
|
||||
|
|
@ -33,6 +35,19 @@ ChromeUtils.defineLazyGetter(lazy, "ZipWriter", () =>
|
|||
Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter", "open")
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"scheduledBackupsPref",
|
||||
SCHEDULED_BACKUPS_ENABLED_PREF_NAME,
|
||||
false,
|
||||
function onUpdateScheduledBackups(_pref, _prevVal, newVal) {
|
||||
let bs = BackupService.get();
|
||||
if (bs) {
|
||||
bs.onUpdateScheduledBackups(newVal);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* The BackupService class orchestrates the scheduling and creation of profile
|
||||
* backups. It also does most of the heavy lifting for the restoration of a
|
||||
|
|
@ -94,7 +109,11 @@ export class BackupService extends EventTarget {
|
|||
*
|
||||
* @type {object}
|
||||
*/
|
||||
#_state = { backupInProgress: false };
|
||||
#_state = {
|
||||
backupFilePath: "Documents", // TODO: make save location configurable (bug 1895943)
|
||||
backupInProgress: false,
|
||||
scheduledBackupsEnabled: lazy.scheduledBackupsPref,
|
||||
};
|
||||
|
||||
/**
|
||||
* A Promise that will resolve once the postRecovery steps are done. It will
|
||||
|
|
@ -844,6 +863,35 @@ export class BackupService extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets browser.backup.scheduled.enabled to true or false.
|
||||
*
|
||||
* @param { boolean } shouldEnableScheduledBackups true if scheduled backups should be enabled. Else, false.
|
||||
*/
|
||||
setScheduledBackups(shouldEnableScheduledBackups) {
|
||||
Services.prefs.setBoolPref(
|
||||
SCHEDULED_BACKUPS_ENABLED_PREF_NAME,
|
||||
shouldEnableScheduledBackups
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates scheduledBackupsEnabled in the backup service state. Should be called every time
|
||||
* the value for browser.backup.scheduled.enabled changes.
|
||||
*
|
||||
* @param {boolean} isScheduledBackupsEnabled True if scheduled backups are enabled. Else false.
|
||||
*/
|
||||
onUpdateScheduledBackups(isScheduledBackupsEnabled) {
|
||||
if (this.#_state.scheduledBackupsEnabled != isScheduledBackupsEnabled) {
|
||||
lazy.logConsole.debug(
|
||||
"Updating scheduled backups",
|
||||
isScheduledBackupsEnabled
|
||||
);
|
||||
this.#_state.scheduledBackupsEnabled = isScheduledBackupsEnabled;
|
||||
this.stateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Take measurements of the current profile state for Telemetry.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -13,20 +13,24 @@ export class BackupUIChild extends JSWindowActorChild {
|
|||
#inittedWidgets = new WeakSet();
|
||||
|
||||
/**
|
||||
* Handles BackupUI:InitWidget custom events fired by widgets that want to
|
||||
* register with BackupUIChild. Firing this event sends a message to the
|
||||
* parent to request the BackupService state which will result in a
|
||||
* `backupServiceState` property of the widget to be set when that state is
|
||||
* received. Subsequent state updates will also cause that state property to
|
||||
* be set.
|
||||
* Handles custom events fired by widgets that want to register with
|
||||
* BackupUIChild.
|
||||
*
|
||||
* @param {Event} event
|
||||
* The BackupUI:InitWidget custom event that the widget fired.
|
||||
* The custom event that the widget fired.
|
||||
*/
|
||||
handleEvent(event) {
|
||||
/**
|
||||
* BackupUI:InitWidget sends a message to the parent to request the BackupService state
|
||||
* which will result in a `backupServiceState` property of the widget to be set when that
|
||||
* state is received. Subsequent state updates will also cause that state property to
|
||||
* be set.
|
||||
*/
|
||||
if (event.type == "BackupUI:InitWidget") {
|
||||
this.#inittedWidgets.add(event.target);
|
||||
this.sendAsyncMessage("RequestState");
|
||||
} else if (event.type == "BackupUI:ScheduledBackupsConfirm") {
|
||||
this.sendAsyncMessage("ScheduledBackupsConfirm");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ export class BackupUIParent extends JSWindowActorParent {
|
|||
receiveMessage(message) {
|
||||
if (message.name == "RequestState") {
|
||||
this.sendState();
|
||||
} else if (message.name == "ScheduledBackupsConfirm") {
|
||||
this.#bs.setScheduledBackups(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
7
browser/components/backup/content/backup-settings.css
Normal file
7
browser/components/backup/content/backup-settings.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#turn-on-scheduled-backups-dialog {
|
||||
width: 27.8rem;
|
||||
}
|
||||
|
|
@ -5,6 +5,9 @@
|
|||
import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://browser/content/backup/turn-on-scheduled-backups.mjs";
|
||||
|
||||
/**
|
||||
* The widget for managing the BackupService that is embedded within the main
|
||||
* document of about:settings / about:preferences.
|
||||
|
|
@ -14,14 +17,24 @@ export default class BackupSettings extends MozLitElement {
|
|||
backupServiceState: { type: Object },
|
||||
};
|
||||
|
||||
static get queries() {
|
||||
return {
|
||||
scheduledBackupsButtonEl: "#backup-toggle-scheduled-button",
|
||||
turnOnScheduledBackupsDialogEl: "#turn-on-scheduled-backups-dialog",
|
||||
turnOnScheduledBackupsEl: "turn-on-scheduled-backups",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BackupSettings instance and sets the initial default
|
||||
* Creates a BackupPreferences instance and sets the initial default
|
||||
* state.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.backupServiceState = {
|
||||
backupFilePath: "Documents", // TODO: make save location configurable (bug 1895943)
|
||||
backupInProgress: false,
|
||||
scheduledBackupsEnabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -34,13 +47,68 @@ export default class BackupSettings extends MozLitElement {
|
|||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
|
||||
this.addEventListener("scheduledBackupsCancel", this);
|
||||
this.addEventListener("scheduledBackupsConfirm", this);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "scheduledBackupsConfirm":
|
||||
this.turnOnScheduledBackupsDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:ScheduledBackupsConfirm", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "scheduledBackupsCancel":
|
||||
this.turnOnScheduledBackupsDialogEl.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleShowScheduledBackups() {
|
||||
if (
|
||||
!this.backupServiceState.scheduledBackupsEnabled &&
|
||||
this.turnOnScheduledBackupsDialogEl
|
||||
) {
|
||||
this.turnOnScheduledBackupsDialogEl.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
turnOnScheduledBackupsDialogTemplate() {
|
||||
return html`<dialog id="turn-on-scheduled-backups-dialog">
|
||||
<turn-on-scheduled-backups
|
||||
.backupFilePath=${this.backupServiceState.backupFilePath}
|
||||
></turn-on-scheduled-backups>
|
||||
</dialog>`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<div>
|
||||
Backup in progress:
|
||||
${this.backupServiceState.backupInProgress ? "Yes" : "No"}
|
||||
</div>`;
|
||||
return html`<link
|
||||
rel="stylesheet"
|
||||
href="chrome://browser/skin/preferences/preferences.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="chrome://browser/content/backup/backup-settings.css"
|
||||
/>
|
||||
<div id="scheduled-backups">
|
||||
<div>
|
||||
Backup in progress:
|
||||
${this.backupServiceState.backupInProgress ? "Yes" : "No"}
|
||||
</div>
|
||||
|
||||
${this.turnOnScheduledBackupsDialogTemplate()}
|
||||
|
||||
<moz-button
|
||||
id="backup-toggle-scheduled-button"
|
||||
@click=${this.handleShowScheduledBackups}
|
||||
data-l10n-id="settings-data-backup-toggle"
|
||||
></moz-button>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
import { html } from "lit.all.mjs";
|
||||
import "./backup-settings.mjs";
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
|
||||
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Backup/Backup Settings",
|
||||
component: "backup-settings",
|
||||
|
|
@ -19,13 +22,17 @@ const Template = ({ backupServiceState }) => html`
|
|||
export const BackingUpNotInProgress = Template.bind({});
|
||||
BackingUpNotInProgress.args = {
|
||||
backupServiceState: {
|
||||
backupFilePath: "Documents",
|
||||
backupInProgress: false,
|
||||
scheduledBackupsEnabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const BackingUpInProgress = Template.bind({});
|
||||
BackingUpInProgress.args = {
|
||||
backupServiceState: {
|
||||
backupFilePath: "Documents",
|
||||
backupInProgress: true,
|
||||
scheduledBackupsEnabled: false,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
109
browser/components/backup/content/turn-on-scheduled-backups.css
Normal file
109
browser/components/backup/content/turn-on-scheduled-backups.css
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@import url("chrome://global/skin/in-content/common.css");
|
||||
|
||||
:host {
|
||||
--margin-inline-start-checkbox-content: calc(var(--checkbox-margin-inline) + var(--checkbox-size));
|
||||
}
|
||||
|
||||
#backup-turn-on-scheduled-wrapper {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"content"
|
||||
"button-group";
|
||||
grid-template-rows: auto auto auto;
|
||||
line-height: 1.5;
|
||||
|
||||
#backup-turn-on-scheduled-header {
|
||||
grid-area: header;
|
||||
font-size: var(--font-size-large);
|
||||
font-weight: var(--font-weight);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& fieldset {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#backup-turn-on-scheduled-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-area: content;
|
||||
margin-block-start: var(--space-small);
|
||||
margin-block-end: var(--space-large);
|
||||
row-gap: var(--space-large);
|
||||
}
|
||||
|
||||
#all-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: var(--space-xlarge);
|
||||
}
|
||||
|
||||
#backup-location-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: var(--space-xsmall);
|
||||
|
||||
#backup-location-filepicker {
|
||||
display: flex;
|
||||
column-gap: var(--space-small);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#backup-location-filepicker-input {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
#sensitive-data-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: var(--space-large);
|
||||
|
||||
#sensitive-data-checkbox-label {
|
||||
display: flex;
|
||||
gap: var(--checkbox-margin-inline);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#sensitive-data-checkbox-label > input {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#sensitive-data-checkbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: var(--space-xsmall);
|
||||
}
|
||||
|
||||
#sensitive-data-checkbox > span {
|
||||
margin-inline-start: var(--margin-inline-start-checkbox-content);
|
||||
}
|
||||
}
|
||||
|
||||
#passwords {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-inline-start: var(--margin-inline-start-checkbox-content);
|
||||
|
||||
& > #new-password-label, #repeat-password-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
& > #new-password-label > input, #repeat-password-label > input {
|
||||
margin-inline-start: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
#backup-turn-on-scheduled-button-group {
|
||||
grid-area: button-group;
|
||||
}
|
||||
}
|
||||
212
browser/components/backup/content/turn-on-scheduled-backups.mjs
Normal file
212
browser/components/backup/content/turn-on-scheduled-backups.mjs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/* 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/. */
|
||||
|
||||
import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
/**
|
||||
* The widget for showing available options when users want to turn on
|
||||
* scheduled backups.
|
||||
*/
|
||||
export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
static properties = {
|
||||
backupFilePath: { type: String },
|
||||
showPasswordOptions: { type: Boolean, reflect: true },
|
||||
};
|
||||
|
||||
static get queries() {
|
||||
return {
|
||||
cancelButtonEl: "#backup-turn-on-scheduled-cancel-button",
|
||||
confirmButtonEl: "#backup-turn-on-scheduled-confirm-button",
|
||||
passwordOptionsCheckboxEl: "#sensitive-data-checkbox-input",
|
||||
passwordOptionsExpandedEl: "#passwords",
|
||||
recommendedFolderInputEl: "#backup-location-filepicker-input",
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.backupFilePath = null;
|
||||
this.showPasswordOptions = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
|
||||
* DOM, which registers with BackupUIChild for BackupService state updates.
|
||||
*/
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleChooseLocation() {
|
||||
// TODO: show file picker (bug 1895943)
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("scheduledBackupsCancel", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.showPasswordOptions = false;
|
||||
this.passwordOptionsCheckboxEl.checked = false;
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
/**
|
||||
* TODO:
|
||||
* We should pass save location to BackupUIParent here (bug 1895943).
|
||||
* If encryption is enabled via this dialog, ensure a password is set and pass it to BackupUIParent (bug 1895981).
|
||||
* Before confirmation, verify passwords match and FxA format rules (bug 1896772).
|
||||
*/
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("scheduledBackupsConfirm", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.showPasswordOptions = false;
|
||||
this.passwordOptionsCheckboxEl.checked = false;
|
||||
}
|
||||
|
||||
handleTogglePasswordOptions() {
|
||||
this.showPasswordOptions = this.passwordOptionsCheckboxEl?.checked;
|
||||
}
|
||||
|
||||
allOptionsTemplate() {
|
||||
return html`
|
||||
<fieldset id="all-controls">
|
||||
<fieldset id="backup-location-controls">
|
||||
<label
|
||||
id="backup-location-label"
|
||||
for="backup-location-filepicker-input"
|
||||
data-l10n-id="turn-on-scheduled-backups-location-label"
|
||||
></label>
|
||||
<!-- TODO: show folder icon (bug 1895943) -->
|
||||
<div id="backup-location-filepicker">
|
||||
<input
|
||||
id="backup-location-filepicker-input"
|
||||
type="text"
|
||||
readonly
|
||||
data-l10n-id="turn-on-scheduled-backups-location-default-folder"
|
||||
data-l10n-args=${JSON.stringify({
|
||||
recommendedFolder: this.backupFilePath,
|
||||
})}
|
||||
data-l10n-attrs="value"
|
||||
/>
|
||||
<moz-button
|
||||
id="backup-location-filepicker-button"
|
||||
@click=${this.handleChooseLocation}
|
||||
data-l10n-id="turn-on-scheduled-backups-location-choose-button"
|
||||
aria-controls="backup-location-filepicker-input"
|
||||
></moz-button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="sensitive-data-controls">
|
||||
<div id="sensitive-data-checkbox">
|
||||
<label
|
||||
id="sensitive-data-checkbox-label"
|
||||
for="sensitive-data-checkbox-input"
|
||||
aria-controls="passwords"
|
||||
aria-expanded=${this.showPasswordOptions}
|
||||
>
|
||||
<input
|
||||
id="sensitive-data-checkbox-input"
|
||||
value=${this.showPasswordOptions}
|
||||
@click=${this.handleTogglePasswordOptions}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
id="sensitive-data-checkbox-span"
|
||||
data-l10n-id="turn-on-scheduled-backups-encryption-label"
|
||||
></span>
|
||||
</label>
|
||||
<span
|
||||
class="text-deemphasized"
|
||||
data-l10n-id="turn-on-scheduled-backups-encryption-description"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
${this.showPasswordOptions ? this.passwordOptionsTemplate() : null}
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
`;
|
||||
}
|
||||
|
||||
passwordOptionsTemplate() {
|
||||
return html`
|
||||
<fieldset id="passwords">
|
||||
<label id="new-password-label" for="new-password-input">
|
||||
<span id="new-password-span" data-l10n-id="turn-on-scheduled-backups-encryption-create-password-label"></span>
|
||||
<input type="password" id="new-password-input"/>
|
||||
</label>
|
||||
<label id="repeat-password-label" for="repeat-password-input">
|
||||
<span id="repeat-password-span" data-l10n-id="turn-on-scheduled-backups-encryption-repeat-password-label"></span>
|
||||
<input type="password" id="repeat-password-input"/>
|
||||
</label>
|
||||
</fieldset>
|
||||
</fieldset>`;
|
||||
}
|
||||
|
||||
contentTemplate() {
|
||||
return html`
|
||||
<div
|
||||
id="backup-turn-on-scheduled-wrapper"
|
||||
aria-labelledby="backup-turn-on-scheduled-header"
|
||||
aria-describedby="backup-turn-on-scheduled-description"
|
||||
>
|
||||
<h1
|
||||
id="backup-turn-on-scheduled-header"
|
||||
data-l10n-id="turn-on-scheduled-backups-header"
|
||||
></h1>
|
||||
<main id="backup-turn-on-scheduled-content">
|
||||
<div id="backup-turn-on-scheduled-description">
|
||||
<span
|
||||
id="backup-turn-on-scheduled-description-span"
|
||||
data-l10n-id="turn-on-scheduled-backups-description"
|
||||
></span>
|
||||
<a
|
||||
id="backup-turn-on-scheduled-learn-more-link"
|
||||
is="moz-support-link"
|
||||
support-page="todo-backup"
|
||||
data-l10n-id="turn-on-scheduled-backups-support-link"
|
||||
></a>
|
||||
</div>
|
||||
${this.allOptionsTemplate()}
|
||||
</main>
|
||||
|
||||
<moz-button-group id="backup-turn-on-scheduled-button-group">
|
||||
<moz-button
|
||||
id="backup-turn-on-scheduled-cancel-button"
|
||||
@click=${this.handleCancel}
|
||||
data-l10n-id="turn-on-scheduled-backups-cancel-button"
|
||||
></moz-button>
|
||||
<moz-button
|
||||
id="backup-turn-on-scheduled-confirm-button"
|
||||
@click=${this.handleConfirm}
|
||||
type="primary"
|
||||
data-l10n-id="turn-on-scheduled-backups-confirm-button"
|
||||
></moz-button>
|
||||
</moz-button-group>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="chrome://browser/content/backup/turn-on-scheduled-backups.css"
|
||||
/>
|
||||
${this.contentTemplate()}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("turn-on-scheduled-backups", TurnOnScheduledBackups);
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* 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/. */
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { html } from "lit.all.mjs";
|
||||
import "chrome://global/content/elements/moz-card.mjs";
|
||||
import "./turn-on-scheduled-backups.mjs";
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
|
||||
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Backup/Turn On Scheduled Backups",
|
||||
component: "turn-on-scheduled-backups",
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
const Template = ({ backupFilePath }) => html`
|
||||
<moz-card style="width: 27.8rem;">
|
||||
<turn-on-scheduled-backups
|
||||
.backupFilePath=${backupFilePath}
|
||||
></turn-on-scheduled-backups>
|
||||
</moz-card>
|
||||
`;
|
||||
|
||||
export const RecommendedFolder = Template.bind({});
|
||||
RecommendedFolder.args = {
|
||||
backupFilePath: "Documents",
|
||||
};
|
||||
|
|
@ -8,4 +8,7 @@ browser.jar:
|
|||
content/browser/backup/debug.js (content/debug.js)
|
||||
#endif
|
||||
content/browser/backup/BackupManifest.1.schema.json (content/BackupManifest.1.schema.json)
|
||||
content/browser/backup/backup-settings.css (content/backup-settings.css)
|
||||
content/browser/backup/backup-settings.mjs (content/backup-settings.mjs)
|
||||
content/browser/backup/turn-on-scheduled-backups.css (content/turn-on-scheduled-backups.css)
|
||||
content/browser/backup/turn-on-scheduled-backups.mjs (content/turn-on-scheduled-backups.mjs)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
prefs = [
|
||||
"browser.backup.enabled=true",
|
||||
"browser.backup.preferences.ui.enabled=true",
|
||||
"browser.backup.scheduled.enabled=false",
|
||||
]
|
||||
|
||||
["browser_settings.js"]
|
||||
|
|
|
|||
|
|
@ -38,3 +38,51 @@ add_task(async function test_preferences_visibility() {
|
|||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that the turn on scheduled backups dialog can set
|
||||
* browser.backup.scheduled.enabled to true from the settings page.
|
||||
*/
|
||||
add_task(async function test_turn_on_scheduled_backups_confirm() {
|
||||
await BrowserTestUtils.withNewTab("about:preferences", async browser => {
|
||||
let settings = browser.contentDocument.querySelector("backup-settings");
|
||||
|
||||
await settings.updateComplete;
|
||||
|
||||
let turnOnButton = settings.scheduledBackupsButtonEl;
|
||||
|
||||
Assert.ok(
|
||||
turnOnButton,
|
||||
"Button to turn on scheduled backups should be found"
|
||||
);
|
||||
|
||||
turnOnButton.click();
|
||||
|
||||
await settings.updateComplete;
|
||||
|
||||
let turnOnScheduledBackups = settings.turnOnScheduledBackupsEl;
|
||||
|
||||
Assert.ok(
|
||||
turnOnScheduledBackups,
|
||||
"turn-on-scheduled-backups should be found"
|
||||
);
|
||||
|
||||
let confirmButton = turnOnScheduledBackups.confirmButtonEl;
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"scheduledBackupsConfirm"
|
||||
);
|
||||
|
||||
Assert.ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
confirmButton.click();
|
||||
|
||||
await promise;
|
||||
await settings.updateComplete;
|
||||
|
||||
let scheduledPrefVal = Services.prefs.getBoolPref(
|
||||
"browser.backup.scheduled.enabled"
|
||||
);
|
||||
Assert.ok(scheduledPrefVal, "Scheduled backups pref should be true");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
[DEFAULT]
|
||||
prefs = [
|
||||
"browser.backup.scheduled.enabled=false",
|
||||
]
|
||||
skip-if = ["os == 'android'"]
|
||||
|
||||
["test_backup_settings.html"]
|
||||
|
||||
["test_turn_on_scheduled_backups.html"]
|
||||
|
|
|
|||
|
|
@ -31,6 +31,41 @@
|
|||
|
||||
settings.remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that the dialog for turning on scheduled backups can be displayed
|
||||
* from settings, or hidden if cancelled.
|
||||
*/
|
||||
add_task(async function test_turnOnScheduledBackupsDialog() {
|
||||
let settings = document.getElementById("test-backup-settings");
|
||||
settings.backupServiceState = {
|
||||
scheduledBackupsEnabled: false,
|
||||
}
|
||||
|
||||
await settings.updateComplete;
|
||||
|
||||
let turnOnButton = settings.scheduledBackupsButtonEl;
|
||||
let dialog = settings.turnOnScheduledBackupsDialogEl;
|
||||
|
||||
ok(turnOnButton, "Button to turn on scheduled backups should be found");
|
||||
ok(!dialog.open, "Dialog should not be open");
|
||||
|
||||
turnOnButton.click();
|
||||
await settings.updateComplete;
|
||||
|
||||
ok(dialog?.open, "Dialog should be open");
|
||||
|
||||
let turnOnScheduledBackups = dialog.querySelector("turn-on-scheduled-backups");
|
||||
ok(turnOnScheduledBackups, "turn-on-scheduled-backups should be found");
|
||||
|
||||
let cancelButton = turnOnScheduledBackups.shadowRoot.getElementById("backup-turn-on-scheduled-cancel-button");
|
||||
ok(cancelButton, "Cancel button should be found");
|
||||
|
||||
cancelButton.click();
|
||||
await settings.updateComplete;
|
||||
|
||||
ok(!dialog.open, "Dialog should not be open");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests for the turn-on-scheduled-backups component</title>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script
|
||||
src="chrome://browser/content/backup/turn-on-scheduled-backups.mjs"
|
||||
type="module"
|
||||
></script>
|
||||
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
|
||||
const { BrowserTestUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/BrowserTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests that adding a turn-on-scheduled-backups element to the DOM causes it to
|
||||
* fire a BackupUI:InitWidget event.
|
||||
*/
|
||||
add_task(async function test_initWidget() {
|
||||
let turnOnScheduledBackups = document.createElement("turn-on-scheduled-backups");
|
||||
let content = document.getElementById("content");
|
||||
|
||||
let sawInitWidget = BrowserTestUtils.waitForEvent(content, "BackupUI:InitWidget");
|
||||
content.appendChild(turnOnScheduledBackups);
|
||||
await sawInitWidget;
|
||||
ok(true, "Saw BackupUI:InitWidget");
|
||||
|
||||
turnOnScheduledBackups.remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that pressing the confirm button will dispatch the expected events.
|
||||
*/
|
||||
add_task(async function test_confirm() {
|
||||
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
|
||||
let confirmButton = turnOnScheduledBackups.confirmButtonEl;
|
||||
|
||||
ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "scheduledBackupsConfirm");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
await promise;
|
||||
ok(true, "Detected event after selecting the confirm button");
|
||||
})
|
||||
|
||||
/**
|
||||
* Tests that pressing the cancel button will dispatch the expected events.
|
||||
*/
|
||||
add_task(async function test_cancel() {
|
||||
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
|
||||
let cancelButton = turnOnScheduledBackups.cancelButtonEl;
|
||||
|
||||
ok(cancelButton, "Cancel button should be found");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "scheduledBackupsCancel");
|
||||
|
||||
cancelButton.click()
|
||||
|
||||
await promise;
|
||||
ok(true, "Detected event after selecting the cancel button");
|
||||
})
|
||||
|
||||
/**
|
||||
* Tests that selecting the checkbox for enabling backup encryption will show more
|
||||
* options to configure the password needed for encryption.
|
||||
*/
|
||||
add_task(async function test_expandedPasswords() {
|
||||
let turnOnScheduledBackups = document.getElementById("test-turn-on-scheduled-backups");
|
||||
let passwordsCheckbox = turnOnScheduledBackups.passwordOptionsCheckboxEl;
|
||||
|
||||
ok(passwordsCheckbox, "Passwords checkbox should be found");
|
||||
ok(!turnOnScheduledBackups.passwordOptionsExpandedEl, "Passwords expanded options should not be found");
|
||||
|
||||
passwordsCheckbox.click();
|
||||
await turnOnScheduledBackups.updateComplete;
|
||||
|
||||
ok(turnOnScheduledBackups.passwordOptionsExpandedEl, "Passwords expanded options should be found");
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<turn-on-scheduled-backups id="test-turn-on-scheduled-backups"></turn-on-scheduled-backups>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,3 +3,33 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
settings-data-backup-header = Backup
|
||||
settings-data-backup-toggle = Manage backup
|
||||
|
||||
## These strings are displayed in a modal when users want to turn on scheduled backups.
|
||||
|
||||
turn-on-scheduled-backups-header = Turn on backup
|
||||
turn-on-scheduled-backups-description = { -brand-short-name } will create a snapshot of your data every 60 minutes. You can restore it if there’s a problem or you get a new device.
|
||||
turn-on-scheduled-backups-support-link = What will be backed up?
|
||||
|
||||
# "Location" refers to the save location or a folder where users want backups stored.
|
||||
turn-on-scheduled-backups-location-label = Location
|
||||
# Variables:
|
||||
# $recommendedFolder (String) - Name of the recommended folder for saving backups
|
||||
turn-on-scheduled-backups-location-default-folder =
|
||||
.value = { $recommendedFolder } (recommended)
|
||||
turn-on-scheduled-backups-location-choose-button =
|
||||
{ PLATFORM() ->
|
||||
[macos] Choose…
|
||||
*[other] Browse…
|
||||
}
|
||||
|
||||
turn-on-scheduled-backups-encryption-label = Back up your sensitive data
|
||||
turn-on-scheduled-backups-encryption-description = Back up your passwords, payment methods, and cookies with encryption.
|
||||
turn-on-scheduled-backups-encryption-create-password-label = Password
|
||||
# Users will be prompted to re-type a password, to ensure that the password is entered correctly.
|
||||
turn-on-scheduled-backups-encryption-repeat-password-label = Repeat password
|
||||
|
||||
turn-on-scheduled-backups-cancel-button = Cancel
|
||||
turn-on-scheduled-backups-confirm-button = Turn on backup
|
||||
|
||||
##
|
||||
|
|
|
|||
Loading…
Reference in a new issue