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/. */
8 const { AppConstants } = ChromeUtils.importESModule(
9 "resource://gre/modules/AppConstants.sys.mjs"
12 const ToolkitProfileService = "@mozilla.org/toolkit/profile-service;1";
15 var gProfileManagerBundle;
17 var gDefaultProfileParent;
19 // The directory where the profile will be created.
22 // Text node to display the location and name of the profile to create.
25 // Called once when the wizard is opened.
26 function initWizard() {
28 gProfileService = C[ToolkitProfileService].getService(
29 I.nsIToolkitProfileService
31 gProfileManagerBundle = document.getElementById("bundle_profileManager");
33 gDefaultProfileParent = Services.dirsvc.get("DefProfRt", I.nsIFile);
35 // Initialize the profile location display.
36 gProfileDisplay = document.getElementById("profileDisplay").firstChild;
37 document.addEventListener("wizardfinish", onFinish);
39 .getElementById("explanation")
40 .addEventListener("pageshow", enableNextButton);
42 .getElementById("createProfile")
43 .addEventListener("pageshow", initSecondWizardPage);
44 setDisplayToDefaultFolder();
51 // Called every time the second wizard page is displayed.
52 function initSecondWizardPage() {
53 var profileName = document.getElementById("profileName");
57 // Initialize profile name validation.
58 checkCurrentInput(profileName.value);
100 var kSaltString = "";
101 for (var i = 0; i < 8; ++i) {
102 kSaltString += kSaltTable[Math.floor(Math.random() * kSaltTable.length)];
105 function saltName(aName) {
106 return kSaltString + "." + aName;
109 function setDisplayToDefaultFolder() {
110 var defaultProfileDir = gDefaultProfileParent.clone();
111 defaultProfileDir.append(
112 saltName(document.getElementById("profileName").value)
114 gProfileRoot = defaultProfileDir;
115 document.getElementById("useDefault").disabled = true;
118 function updateProfileDisplay() {
119 gProfileDisplay.data = gProfileRoot.path;
122 // Invoke a folder selection dialog for choosing the directory of profile storage.
123 function chooseProfileFolder() {
126 var dirChooser = C["@mozilla.org/filepicker;1"].createInstance(
131 gProfileManagerBundle.getString("chooseFolder"),
132 I.nsIFilePicker.modeGetFolder
134 dirChooser.appendFilters(I.nsIFilePicker.filterAll);
136 // default to the Profiles folder
137 dirChooser.displayDirectory = gDefaultProfileParent;
139 dirChooser.open(() => {
140 newProfileRoot = dirChooser.file;
142 // Disable the "Default Folder..." button when the default profile folder
143 // was selected manually in the File Picker.
144 document.getElementById("useDefault").disabled =
145 newProfileRoot.parent.equals(gDefaultProfileParent);
147 gProfileRoot = newProfileRoot;
148 updateProfileDisplay();
152 // Checks the current user input for validity and triggers an error message accordingly.
153 function checkCurrentInput(currentInput) {
154 let wizard = document.querySelector("wizard");
155 var finishButton = wizard.getButton("finish");
156 var finishText = document.getElementById("finishText");
159 var errorMessage = checkProfileName(currentInput);
162 finishText.className = "";
163 if (AppConstants.platform == "macosx") {
164 finishText.firstChild.data = gProfileManagerBundle.getString(
165 "profileFinishTextMac"
168 finishText.firstChild.data =
169 gProfileManagerBundle.getString("profileFinishText");
173 finishText.className = "error";
174 finishText.firstChild.data = errorMessage;
178 wizard.canAdvance = canAdvance;
179 finishButton.disabled = !canAdvance;
181 updateProfileDisplay();
186 function updateProfileName(aNewName) {
187 if (checkCurrentInput(aNewName)) {
188 gProfileRoot.leafName = saltName(aNewName);
189 updateProfileDisplay();
193 // Checks whether the given string is a valid profile name.
194 // Returns an error message describing the error in the name or "" when it's valid.
195 function checkProfileName(profileNameToCheck) {
196 // Check for emtpy profile name.
197 if (!/\S/.test(profileNameToCheck)) {
198 return gProfileManagerBundle.getString("profileNameEmpty");
201 // Check whether all characters in the profile name are allowed.
202 if (/([\\*:?<>|\/\"])/.test(profileNameToCheck)) {
203 return gProfileManagerBundle.getFormattedString("invalidChar", [RegExp.$1]);
206 // Check whether a profile with the same name already exists.
207 if (profileExists(profileNameToCheck)) {
208 return gProfileManagerBundle.getString("profileExists");
211 // profileNameToCheck is valid.
215 function profileExists(aName) {
216 for (let profile of gProfileService.profiles) {
217 if (profile.name.toLowerCase() == aName.toLowerCase()) {
225 // Called when the first wizard page is shown.
226 function enableNextButton() {
227 document.querySelector("wizard").canAdvance = true;
230 function onFinish(event) {
231 var profileName = document.getElementById("profileName").value;
234 // Create profile named profileName in profileRoot.
236 profile = gProfileService.createProfile(gProfileRoot, profileName);
238 var profileCreationFailed = gProfileManagerBundle.getString(
239 "profileCreationFailed"
241 var profileCreationFailedTitle = gProfileManagerBundle.getString(
242 "profileCreationFailedTitle"
244 Services.prompt.alert(
246 profileCreationFailedTitle,
247 profileCreationFailed + "\n" + e
250 event.preventDefault();
254 if (window.arguments && window.arguments[1]) {
255 // Add new profile to the list in the Profile Manager.
256 window.arguments[1].CreateProfile(profile);
258 // Use the newly created Profile.
259 var profileLock = profile.lock(null);
261 var dialogParams = window.arguments[0].QueryInterface(
262 I.nsIDialogParamBlock
264 dialogParams.objects.insertElementAt(profileLock, 0);