| |
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 const C = Components.classes; |
| |
6 const I = Components.interfaces; |
| |
7 |
| |
8 const ToolkitProfileService = "@mozilla.org/toolkit/profile-service;1"; |
| |
9 |
| |
10 var gProfileService; |
| |
11 var gProfileManagerBundle; |
| |
12 |
| |
13 var gDefaultProfileParent; |
| |
14 var gOldProfileName; |
| |
15 |
| |
16 // The directory where the profile will be created. |
| |
17 var gProfileRoot; |
| |
18 |
| |
19 // Text node to display the location and name of the profile to create. |
| |
20 var gProfileDisplay; |
| |
21 |
| |
22 // Called once when the wizard is opened. |
| |
23 function initWizard() |
| |
24 { |
| |
25 try { |
| |
26 gProfileService = C[ToolkitProfileService].getService(I.nsIToolkitProfileService); |
| |
27 gProfileManagerBundle = document.getElementById("bundle_profileManager"); |
| |
28 |
| |
29 var dirService = C["@mozilla.org/file/directory_service;1"].getService(I.nsIProperties); |
| |
30 gDefaultProfileParent = dirService.get("DefProfRt", I.nsIFile); |
| |
31 |
| |
32 gOldProfileName = document.getElementById("profileName").value; |
| |
33 |
| |
34 // Initialize the profile location display. |
| |
35 gProfileDisplay = document.getElementById("profileDisplay").firstChild; |
| |
36 setDisplayToDefaultFolder(); |
| |
37 } |
| |
38 catch(e) { |
| |
39 window.close(); |
| |
40 throw (e); |
| |
41 } |
| |
42 } |
| |
43 |
| |
44 // Called every time the second wizard page is displayed. |
| |
45 function initSecondWizardPage() |
| |
46 { |
| |
47 var profileName = document.getElementById("profileName"); |
| |
48 profileName.select(); |
| |
49 profileName.focus(); |
| |
50 |
| |
51 // Initialize profile name validation. |
| |
52 checkCurrentInput(profileName.value); |
| |
53 } |
| |
54 |
| |
55 const kSaltTable = [ |
| |
56 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', |
| |
57 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', |
| |
58 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' ]; |
| |
59 |
| |
60 var kSaltString = ""; |
| |
61 for (var i = 0; i < 8; ++i) { |
| |
62 kSaltString += kSaltTable[Math.floor(Math.random() * kSaltTable.length)]; |
| |
63 } |
| |
64 |
| |
65 |
| |
66 function saltName(aName) |
| |
67 { |
| |
68 return kSaltString + "." + aName; |
| |
69 } |
| |
70 |
| |
71 function setDisplayToDefaultFolder() |
| |
72 { |
| |
73 var defaultProfileDir = gDefaultProfileParent.clone(); |
| |
74 defaultProfileDir.append(saltName(document.getElementById("profileName").value)); |
| |
75 gProfileRoot = defaultProfileDir; |
| |
76 document.getElementById("useDefault").disabled = true; |
| |
77 } |
| |
78 |
| |
79 function updateProfileDisplay() |
| |
80 { |
| |
81 gProfileDisplay.data = gProfileRoot.path; |
| |
82 } |
| |
83 |
| |
84 // Invoke a folder selection dialog for choosing the directory of profile storage. |
| |
85 function chooseProfileFolder() |
| |
86 { |
| |
87 var newProfileRoot; |
| |
88 |
| |
89 var dirChooser = C["@mozilla.org/filepicker;1"].createInstance(I.nsIFilePicker); |
| |
90 dirChooser.init(window, gProfileManagerBundle.getString("chooseFolder"), |
| |
91 I.nsIFilePicker.modeGetFolder); |
| |
92 dirChooser.appendFilters(I.nsIFilePicker.filterAll); |
| |
93 |
| |
94 // default to the Profiles folder |
| |
95 dirChooser.displayDirectory = gDefaultProfileParent; |
| |
96 |
| |
97 dirChooser.show(); |
| |
98 newProfileRoot = dirChooser.file; |
| |
99 |
| |
100 // Disable the "Default Folder..." button when the default profile folder |
| |
101 // was selected manually in the File Picker. |
| |
102 document.getElementById("useDefault").disabled = |
| |
103 (newProfileRoot.parent.equals(gDefaultProfileParent)); |
| |
104 |
| |
105 gProfileRoot = newProfileRoot; |
| |
106 updateProfileDisplay(); |
| |
107 } |
| |
108 |
| |
109 // Checks the current user input for validity and triggers an error message accordingly. |
| |
110 function checkCurrentInput(currentInput) |
| |
111 { |
| |
112 var finishButton = document.documentElement.getButton("finish"); |
| |
113 var finishText = document.getElementById("finishText"); |
| |
114 var canAdvance; |
| |
115 |
| |
116 var errorMessage = checkProfileName(currentInput); |
| |
117 |
| |
118 if (!errorMessage) { |
| |
119 finishText.className = ""; |
| |
120 #ifndef XP_MACOSX |
| |
121 finishText.firstChild.data = gProfileManagerBundle.getString("profileFinishText"); |
| |
122 #else |
| |
123 finishText.firstChild.data = gProfileManagerBundle.getString("profileFinishTextMac"); |
| |
124 #endif |
| |
125 canAdvance = true; |
| |
126 } |
| |
127 else { |
| |
128 finishText.className = "error"; |
| |
129 finishText.firstChild.data = errorMessage; |
| |
130 canAdvance = false; |
| |
131 } |
| |
132 |
| |
133 document.documentElement.canAdvance = canAdvance; |
| |
134 finishButton.disabled = !canAdvance; |
| |
135 |
| |
136 updateProfileDisplay(); |
| |
137 } |
| |
138 |
| |
139 function updateProfileName(aNewName) { |
| |
140 checkCurrentInput(aNewName); |
| |
141 |
| |
142 var re = new RegExp("^[a-z0-9]{8}\\." + |
| |
143 gOldProfileName.replace(/[|^$()\[\]{}\\+?.*]/g, "\\$&") |
| |
144 + '$'); |
| |
145 |
| |
146 if (re.test(gProfileRoot.leafName)) { |
| |
147 gProfileRoot.leafName = saltName(aNewName); |
| |
148 updateProfileDisplay(); |
| |
149 } |
| |
150 gOldProfileName = aNewName; |
| |
151 } |
| |
152 |
| |
153 // Checks whether the given string is a valid profile name. |
| |
154 // Returns an error message describing the error in the name or "" when it's valid. |
| |
155 function checkProfileName(profileNameToCheck) |
| |
156 { |
| |
157 // Check for emtpy profile name. |
| |
158 if (!/\S/.test(profileNameToCheck)) |
| |
159 return gProfileManagerBundle.getString("profileNameEmpty"); |
| |
160 |
| |
161 // Check whether all characters in the profile name are allowed. |
| |
162 if (/([\\*:?<>|\/\"])/.test(profileNameToCheck)) |
| |
163 return gProfileManagerBundle.getFormattedString("invalidChar", [RegExp.$1]); |
| |
164 |
| |
165 // Check whether a profile with the same name already exists. |
| |
166 if (profileExists(profileNameToCheck)) |
| |
167 return gProfileManagerBundle.getString("profileExists"); |
| |
168 |
| |
169 // profileNameToCheck is valid. |
| |
170 return ""; |
| |
171 } |
| |
172 |
| |
173 function profileExists(aName) |
| |
174 { |
| |
175 var profiles = gProfileService.profiles; |
| |
176 while (profiles.hasMoreElements()) { |
| |
177 var profile = profiles.getNext().QueryInterface(I.nsIToolkitProfile); |
| |
178 if (profile.name.toLowerCase() == aName.toLowerCase()) |
| |
179 return true; |
| |
180 } |
| |
181 |
| |
182 return false; |
| |
183 } |
| |
184 |
| |
185 // Called when the first wizard page is shown. |
| |
186 function enableNextButton() |
| |
187 { |
| |
188 document.documentElement.canAdvance = true; |
| |
189 } |
| |
190 |
| |
191 function onFinish() |
| |
192 { |
| |
193 var profileName = document.getElementById("profileName").value; |
| |
194 var profile; |
| |
195 |
| |
196 // Create profile named profileName in profileRoot. |
| |
197 try { |
| |
198 profile = gProfileService.createProfile(gProfileRoot, profileName); |
| |
199 } |
| |
200 catch (e) { |
| |
201 var profileCreationFailed = |
| |
202 gProfileManagerBundle.getString("profileCreationFailed"); |
| |
203 var profileCreationFailedTitle = |
| |
204 gProfileManagerBundle.getString("profileCreationFailedTitle"); |
| |
205 var promptService = C["@mozilla.org/embedcomp/prompt-service;1"]. |
| |
206 getService(I.nsIPromptService); |
| |
207 promptService.alert(window, profileCreationFailedTitle, |
| |
208 profileCreationFailed + "\n" + e); |
| |
209 |
| |
210 return false; |
| |
211 } |
| |
212 |
| |
213 // window.opener is false if the Create Profile Wizard was opened from the |
| |
214 // command line. |
| |
215 if (window.opener) { |
| |
216 // Add new profile to the list in the Profile Manager. |
| |
217 window.opener.CreateProfile(profile); |
| |
218 } |
| |
219 else { |
| |
220 // Use the newly created Profile. |
| |
221 var profileLock = profile.lock(null); |
| |
222 |
| |
223 var dialogParams = window.arguments[0].QueryInterface(I.nsIDialogParamBlock); |
| |
224 dialogParams.objects.insertElementAt(profileLock, 0, false); |
| |
225 } |
| |
226 |
| |
227 // Exit the wizard. |
| |
228 return true; |
| |
229 } |