|
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 } |