/* 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"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/turn-on-scheduled-backups.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/turn-off-scheduled-backups.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/restore-from-backup.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/enable-backup-encryption.mjs"; // eslint-disable-next-line import/no-unassigned-import import "chrome://browser/content/backup/disable-backup-encryption.mjs"; /** * The widget for managing the BackupService that is embedded within the main * document of about:settings / about:preferences. */ export default class BackupSettings extends MozLitElement { #placeholderIconURL = "chrome://global/skin/icons/page-portrait.svg"; static properties = { backupServiceState: { type: Object }, recoveryErrorCode: { type: Number }, recoveryInProgress: { type: Boolean }, _enableEncryptionTypeAttr: { type: String }, }; static get queries() { return { scheduledBackupsButtonEl: "#backup-toggle-scheduled-button", changePasswordButtonEl: "#backup-change-password-button", disableBackupEncryptionEl: "disable-backup-encryption", disableBackupEncryptionDialogEl: "#disable-backup-encryption-dialog", enableBackupEncryptionEl: "enable-backup-encryption", enableBackupEncryptionDialogEl: "#enable-backup-encryption-dialog", turnOnScheduledBackupsDialogEl: "#turn-on-scheduled-backups-dialog", turnOnScheduledBackupsEl: "turn-on-scheduled-backups", turnOffScheduledBackupsEl: "turn-off-scheduled-backups", turnOffScheduledBackupsDialogEl: "#turn-off-scheduled-backups-dialog", restoreFromBackupEl: "restore-from-backup", restoreFromBackupButtonEl: "#backup-toggle-restore-button", restoreFromBackupDescriptionEl: "#backup-restore-description", restoreFromBackupDialogEl: "#restore-from-backup-dialog", sensitiveDataCheckboxInputEl: "#backup-sensitive-data-checkbox-input", passwordControlsEl: "#backup-password-controls", lastBackupLocationInputEl: "#last-backup-location", lastBackupFileNameEl: "#last-backup-filename", lastBackupDateEl: "#last-backup-date", backupLocationShowButtonEl: "#backup-location-show", backupLocationEditButtonEl: "#backup-location-edit", scheduledBackupsDescriptionEl: "#scheduled-backups-description", }; } /** * Creates a BackupPreferences instance and sets the initial default * state. */ constructor() { super(); this.backupServiceState = { backupDirPath: "", backupFileToRestore: null, backupFileInfo: null, defaultParent: { fileName: "", path: "", iconURL: "", }, encryptionEnabled: false, scheduledBackupsEnabled: false, lastBackupDate: null, lastBackupFileName: "", supportBaseLink: "", }; this.recoveryInProgress = false; this.recoveryErrorCode = 0; this._enableEncryptionTypeAttr = ""; } /** * 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 }) ); this.addEventListener("dialogCancel", this); this.addEventListener("getBackupFileInfo", this); this.addEventListener("restoreFromBackupConfirm", this); this.addEventListener("restoreFromBackupChooseFile", this); } handleEvent(event) { switch (event.type) { case "dialogCancel": if (this.turnOnScheduledBackupsDialogEl.open) { this.turnOnScheduledBackupsDialogEl.close(); } else if (this.turnOffScheduledBackupsDialogEl.open) { this.turnOffScheduledBackupsDialogEl.close(); } else if (this.restoreFromBackupDialogEl.open) { this.restoreFromBackupDialogEl.close(); } else if (this.disableBackupEncryptionDialogEl.open) { this.disableBackupEncryptionDialogEl.close(); } else if (this.enableBackupEncryptionDialogEl.open) { this.enableBackupEncryptionDialogEl.close(); } break; case "restoreFromBackupConfirm": this.dispatchEvent( new CustomEvent("BackupUI:RestoreFromBackupFile", { bubbles: true, composed: true, detail: { backupFile: event.detail.backupFile, backupPassword: event.detail.backupPassword, }, }) ); break; case "restoreFromBackupChooseFile": this.dispatchEvent( new CustomEvent("BackupUI:RestoreFromBackupChooseFile", { bubbles: true, composed: true, }) ); break; case "getBackupFileInfo": this.dispatchEvent( new CustomEvent("BackupUI:GetBackupFileInfo", { bubbles: true, composed: true, detail: { backupFile: event.detail.backupFile, }, }) ); break; } } handleShowScheduledBackups() { if ( !this.backupServiceState.scheduledBackupsEnabled && this.turnOnScheduledBackupsDialogEl ) { this.turnOnScheduledBackupsDialogEl.showModal(); } else if ( this.backupServiceState.scheduledBackupsEnabled && this.turnOffScheduledBackupsDialogEl ) { this.turnOffScheduledBackupsDialogEl.showModal(); } } async handleToggleBackupEncryption(event) { event.preventDefault(); // Checkbox was unchecked, meaning encryption is already enabled and should be disabled. let toggledToDisable = !event.target.checked && this.backupServiceState.encryptionEnabled; if (toggledToDisable && this.disableBackupEncryptionDialogEl) { this.disableBackupEncryptionDialogEl.showModal(); } else { this._enableEncryptionTypeAttr = "set-password"; await this.updateComplete; this.enableBackupEncryptionDialogEl.showModal(); } } async handleChangePassword() { if (this.enableBackupEncryptionDialogEl) { this._enableEncryptionTypeAttr = "change-password"; await this.updateComplete; this.enableBackupEncryptionDialogEl.showModal(); } } scheduledBackupsDescriptionTemplate() { return html`
`; } turnOnScheduledBackupsDialogTemplate() { let { fileName, path, iconURL } = this.backupServiceState.defaultParent; return html` `; } turnOffScheduledBackupsDialogTemplate() { return html` `; } restoreFromBackupDialogTemplate() { let { backupFilePath, backupFileToRestore, backupFileInfo } = this.backupServiceState; return html` `; } restoreFromBackupTemplate() { let descriptionL10nID = this.backupServiceState.scheduledBackupsEnabled ? "settings-data-backup-scheduled-backups-on-restore-description" : "settings-data-backup-scheduled-backups-off-restore-description"; let restoreButtonL10nID = this.backupServiceState.scheduledBackupsEnabled ? "settings-data-backup-scheduled-backups-on-restore-choose" : "settings-data-backup-scheduled-backups-off-restore-choose"; return html`
${this.restoreFromBackupDialogTemplate()}
`; } handleShowRestoreDialog() { if (this.restoreFromBackupDialogEl) { this.restoreFromBackupDialogEl.showModal(); } } handleShowBackupLocation() { this.dispatchEvent( new CustomEvent("BackupUI:ShowBackupLocation", { bubbles: true, }) ); } handleEditBackupLocation() { this.dispatchEvent( new CustomEvent("BackupUI:EditBackupLocation", { bubbles: true, }) ); } enableBackupEncryptionDialogTemplate() { return html` `; } disableBackupEncryptionDialogTemplate() { return html` `; } lastBackupInfoTemplate() { // The lastBackupDate is stored in preferences, which only accepts // 32-bit signed values, so we automatically divide it by 1000 before // storing it. We need to re-multiply it by 1000 to get Fluent to render // the right time. let backupDateArgs = { date: this.backupServiceState.lastBackupDate * 1000, }; let backupFileNameArgs = { fileName: this.backupServiceState.lastBackupFileName, }; return html`
`; } backupLocationTemplate() { let iconURL = this.backupServiceState.defaultParent.iconURL || this.#placeholderIconURL; let { backupDirPath } = this.backupServiceState; return html`
`; } sensitiveDataTemplate() { return html`
${this.backupServiceState.encryptionEnabled ? html`` : null}
`; } updated() { if (this.backupServiceState.scheduledBackupsEnabled) { let input = this.lastBackupLocationInputEl; input.setSelectionRange(input.value.length, input.value.length); } } render() { let scheduledBackupsEnabledL10nID = this.backupServiceState .scheduledBackupsEnabled ? "settings-data-backup-scheduled-backups-on" : "settings-data-backup-scheduled-backups-off"; return html` ${this.turnOnScheduledBackupsDialogTemplate()} ${this.turnOffScheduledBackupsDialogTemplate()} ${this.enableBackupEncryptionDialogTemplate()} ${this.disableBackupEncryptionDialogTemplate()}
${this.backupServiceState.scheduledBackupsEnabled ? null : this.scheduledBackupsDescriptionTemplate()}
${this.backupServiceState.lastBackupDate ? this.lastBackupInfoTemplate() : null} ${this.backupServiceState.scheduledBackupsEnabled ? this.backupLocationTemplate() : null} ${this.backupServiceState.scheduledBackupsEnabled ? this.sensitiveDataTemplate() : null}
${this.restoreFromBackupTemplate()} `; } } customElements.define("backup-settings", BackupSettings);