new-profile-card.mjs (3299B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { html } from "chrome://global/content/vendor/lit.all.mjs"; 6 import { EditProfileCard } from "chrome://browser/content/profiles/edit-profile-card.mjs"; 7 // eslint-disable-next-line import/no-unassigned-import 8 import "chrome://global/content/elements/moz-support-link.mjs"; 9 10 const DEFAULT_THEME_ID = "default-theme@mozilla.org"; 11 const TEN_MINUTES_IN_MS = 10 * 60 * 1000; 12 13 /** 14 * Element used for updating a profile's name, theme, and avatar. 15 */ 16 export class NewProfileCard extends EditProfileCard { 17 async init() { 18 if (this.initialized) { 19 return; 20 } 21 22 let { currentProfile, profiles, profileCreated, themes, isInAutomation } = 23 await RPMSendQuery("Profiles:GetNewProfileContent"); 24 25 if (isInAutomation) { 26 this.updateNameDebouncer.timeout = 50; 27 } 28 29 if (!isInAutomation) { 30 this.maybeRedirectExistingProfile(profileCreated); 31 } 32 33 this.setProfile(currentProfile); 34 this.profiles = profiles; 35 this.themes = themes; 36 37 await Promise.all([ 38 this.setInitialInput(), 39 this.setRandomTheme(isInAutomation), 40 ]); 41 } 42 43 /** 44 * To avoid accidental data loss caused by the no-confirmation delete 45 * button, if the profile is more than 10 minutes old, redirect to 46 * about:editprofile instead. 47 * 48 * Extracted into a helper function to simplify testing. 49 * 50 * @param {number} profileCreated 51 * Profile creation timestamp (milliseconds since epoch). 52 */ 53 maybeRedirectExistingProfile(profileCreated) { 54 if (Date.now() - TEN_MINUTES_IN_MS > profileCreated) { 55 window.removeEventListener("beforeunload", this); 56 window.location.replace("about:editprofile"); 57 } 58 } 59 60 async setRandomTheme(isInAutomation) { 61 if (this.profile.themeId !== DEFAULT_THEME_ID) { 62 return; 63 } 64 65 let possibleThemes = this.themes; 66 if (isInAutomation) { 67 possibleThemes = possibleThemes.filter(t => t.useInAutomation); 68 } 69 let newTheme = 70 possibleThemes[Math.floor(Math.random() * possibleThemes.length)]; 71 await super.updateTheme(newTheme.id); 72 } 73 74 async setInitialInput() { 75 if (RPMGetBoolPref("browser.profiles.profile-name.updated", false)) { 76 return; 77 } 78 79 await this.getUpdateComplete(); 80 81 this.nameInput.value = ""; 82 } 83 84 onDeleteClick() { 85 window.removeEventListener("beforeunload", this); 86 RPMSendAsyncMessage("Profiles:DeleteProfile"); 87 } 88 89 headerTemplate() { 90 return html`<div> 91 <h1 data-l10n-id="new-profile-page-header"></h1> 92 <p> 93 <span data-l10n-id="new-profile-page-header-description"></span> 94 <a 95 is="moz-support-link" 96 support-page="profile-management" 97 data-l10n-id="new-profile-page-learn-more" 98 ></a> 99 </p> 100 </div>`; 101 } 102 103 nameInputTemplate() { 104 return html`<input 105 type="text" 106 id="profile-name" 107 size="64" 108 aria-errormessage="error-message" 109 data-l10n-id="new-profile-page-input-placeholder" 110 .value=${this.profile.name} 111 @input=${super.handleInputEvent} 112 />`; 113 } 114 } 115 116 customElements.define("new-profile-card", NewProfileCard);