|
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 file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Cc = Components.classes; |
|
6 const Ci = Components.interfaces; |
|
7 const Cu = Components.utils; |
|
8 |
|
9 const kIMig = Ci.nsIBrowserProfileMigrator; |
|
10 const kIPStartup = Ci.nsIProfileStartup; |
|
11 |
|
12 Cu.import("resource:///modules/MigrationUtils.jsm"); |
|
13 |
|
14 var MigrationWizard = { |
|
15 _source: "", // Source Profile Migrator ContractID suffix |
|
16 _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield) |
|
17 _selectedProfile: null, // Selected Profile name to import from |
|
18 _wiz: null, |
|
19 _migrator: null, |
|
20 _autoMigrate: null, |
|
21 |
|
22 init: function () |
|
23 { |
|
24 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
25 .getService(Components.interfaces.nsIObserverService); |
|
26 os.addObserver(this, "Migration:Started", false); |
|
27 os.addObserver(this, "Migration:ItemBeforeMigrate", false); |
|
28 os.addObserver(this, "Migration:ItemAfterMigrate", false); |
|
29 os.addObserver(this, "Migration:ItemError", false); |
|
30 os.addObserver(this, "Migration:Ended", false); |
|
31 |
|
32 this._wiz = document.documentElement; |
|
33 |
|
34 if ("arguments" in window && window.arguments.length > 1) { |
|
35 this._source = window.arguments[0]; |
|
36 this._migrator = window.arguments[1] instanceof kIMig ? |
|
37 window.arguments[1] : null; |
|
38 this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup); |
|
39 this._skipImportSourcePage = window.arguments[3]; |
|
40 |
|
41 if (this._autoMigrate) { |
|
42 // Show the "nothing" option in the automigrate case to provide an |
|
43 // easily identifiable way to avoid migration and create a new profile. |
|
44 var nothing = document.getElementById("nothing"); |
|
45 nothing.hidden = false; |
|
46 } |
|
47 } |
|
48 |
|
49 this.onImportSourcePageShow(); |
|
50 }, |
|
51 |
|
52 uninit: function () |
|
53 { |
|
54 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
55 .getService(Components.interfaces.nsIObserverService); |
|
56 os.removeObserver(this, "Migration:Started"); |
|
57 os.removeObserver(this, "Migration:ItemBeforeMigrate"); |
|
58 os.removeObserver(this, "Migration:ItemAfterMigrate"); |
|
59 os.removeObserver(this, "Migration:ItemError"); |
|
60 os.removeObserver(this, "Migration:Ended"); |
|
61 MigrationUtils.finishMigration(); |
|
62 }, |
|
63 |
|
64 // 1 - Import Source |
|
65 onImportSourcePageShow: function () |
|
66 { |
|
67 this._wiz.canRewind = false; |
|
68 |
|
69 var selectedMigrator = null; |
|
70 |
|
71 // Figure out what source apps are are available to import from: |
|
72 var group = document.getElementById("importSourceGroup"); |
|
73 for (var i = 0; i < group.childNodes.length; ++i) { |
|
74 var migratorKey = group.childNodes[i].id; |
|
75 if (migratorKey != "nothing") { |
|
76 var migrator = MigrationUtils.getMigrator(migratorKey); |
|
77 if (migrator) { |
|
78 // Save this as the first selectable item, if we don't already have |
|
79 // one, or if it is the migrator that was passed to us. |
|
80 if (!selectedMigrator || this._source == migratorKey) |
|
81 selectedMigrator = group.childNodes[i]; |
|
82 } else { |
|
83 // Hide this option |
|
84 group.childNodes[i].hidden = true; |
|
85 } |
|
86 } |
|
87 } |
|
88 |
|
89 if (selectedMigrator) |
|
90 group.selectedItem = selectedMigrator; |
|
91 else { |
|
92 // We didn't find a migrator, notify the user |
|
93 document.getElementById("noSources").hidden = false; |
|
94 |
|
95 this._wiz.canAdvance = false; |
|
96 |
|
97 document.getElementById("importBookmarks").hidden = true; |
|
98 document.getElementById("importAll").hidden = true; |
|
99 } |
|
100 |
|
101 // Advance to the next page if the caller told us to. |
|
102 if (this._migrator && this._skipImportSourcePage) { |
|
103 this._wiz.advance(); |
|
104 this._wiz.canRewind = false; |
|
105 } |
|
106 }, |
|
107 |
|
108 onImportSourcePageAdvanced: function () |
|
109 { |
|
110 var newSource = document.getElementById("importSourceGroup").selectedItem.id; |
|
111 |
|
112 if (newSource == "nothing") { |
|
113 document.documentElement.cancel(); |
|
114 return false; |
|
115 } |
|
116 |
|
117 if (!this._migrator || (newSource != this._source)) { |
|
118 // Create the migrator for the selected source. |
|
119 this._migrator = MigrationUtils.getMigrator(newSource); |
|
120 |
|
121 this._itemsFlags = kIMig.ALL; |
|
122 this._selectedProfile = null; |
|
123 } |
|
124 this._source = newSource; |
|
125 |
|
126 // check for more than one source profile |
|
127 var sourceProfiles = this._migrator.sourceProfiles; |
|
128 if (sourceProfiles && sourceProfiles.length > 1) { |
|
129 this._wiz.currentPage.next = "selectProfile"; |
|
130 } |
|
131 else { |
|
132 if (this._autoMigrate) |
|
133 this._wiz.currentPage.next = "homePageImport"; |
|
134 else |
|
135 this._wiz.currentPage.next = "importItems"; |
|
136 |
|
137 if (sourceProfiles && sourceProfiles.length == 1) |
|
138 this._selectedProfile = sourceProfiles[0]; |
|
139 else |
|
140 this._selectedProfile = ""; |
|
141 } |
|
142 }, |
|
143 |
|
144 // 2 - [Profile Selection] |
|
145 onSelectProfilePageShow: function () |
|
146 { |
|
147 // Disabling this for now, since we ask about import sources in automigration |
|
148 // too and don't want to disable the back button |
|
149 // if (this._autoMigrate) |
|
150 // document.documentElement.getButton("back").disabled = true; |
|
151 |
|
152 var profiles = document.getElementById("profiles"); |
|
153 while (profiles.hasChildNodes()) |
|
154 profiles.removeChild(profiles.firstChild); |
|
155 |
|
156 // Note that this block is still reached even if the user chose 'From File' |
|
157 // and we canceled the dialog. When that happens, _migrator will be null. |
|
158 if (this._migrator) { |
|
159 var sourceProfiles = this._migrator.sourceProfiles; |
|
160 for (var i = 0; i < sourceProfiles.length; ++i) { |
|
161 var item = document.createElement("radio"); |
|
162 item.id = sourceProfiles[i]; |
|
163 item.setAttribute("label", sourceProfiles[i]); |
|
164 profiles.appendChild(item); |
|
165 } |
|
166 } |
|
167 |
|
168 profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile) : profiles.firstChild; |
|
169 }, |
|
170 |
|
171 onSelectProfilePageRewound: function () |
|
172 { |
|
173 var profiles = document.getElementById("profiles"); |
|
174 this._selectedProfile = profiles.selectedItem.id; |
|
175 }, |
|
176 |
|
177 onSelectProfilePageAdvanced: function () |
|
178 { |
|
179 var profiles = document.getElementById("profiles"); |
|
180 this._selectedProfile = profiles.selectedItem.id; |
|
181 |
|
182 // If we're automigrating or just doing bookmarks don't show the item selection page |
|
183 if (this._autoMigrate) |
|
184 this._wiz.currentPage.next = "homePageImport"; |
|
185 }, |
|
186 |
|
187 // 3 - ImportItems |
|
188 onImportItemsPageShow: function () |
|
189 { |
|
190 var dataSources = document.getElementById("dataSources"); |
|
191 while (dataSources.hasChildNodes()) |
|
192 dataSources.removeChild(dataSources.firstChild); |
|
193 |
|
194 var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); |
|
195 for (var i = 0; i < 16; ++i) { |
|
196 var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0; |
|
197 if (itemID > 0) { |
|
198 var checkbox = document.createElement("checkbox"); |
|
199 checkbox.id = itemID; |
|
200 checkbox.setAttribute("label", |
|
201 MigrationUtils.getLocalizedString(itemID + "_" + this._source)); |
|
202 dataSources.appendChild(checkbox); |
|
203 if (!this._itemsFlags || this._itemsFlags & itemID) |
|
204 checkbox.checked = true; |
|
205 } |
|
206 } |
|
207 }, |
|
208 |
|
209 onImportItemsPageRewound: function () |
|
210 { |
|
211 this._wiz.canAdvance = true; |
|
212 this.onImportItemsPageAdvanced(); |
|
213 }, |
|
214 |
|
215 onImportItemsPageAdvanced: function () |
|
216 { |
|
217 var dataSources = document.getElementById("dataSources"); |
|
218 this._itemsFlags = 0; |
|
219 for (var i = 0; i < dataSources.childNodes.length; ++i) { |
|
220 var checkbox = dataSources.childNodes[i]; |
|
221 if (checkbox.localName == "checkbox" && checkbox.checked) |
|
222 this._itemsFlags |= parseInt(checkbox.id); |
|
223 } |
|
224 }, |
|
225 |
|
226 onImportItemCommand: function (aEvent) |
|
227 { |
|
228 var items = document.getElementById("dataSources"); |
|
229 var checkboxes = items.getElementsByTagName("checkbox"); |
|
230 |
|
231 var oneChecked = false; |
|
232 for (var i = 0; i < checkboxes.length; ++i) { |
|
233 if (checkboxes[i].checked) { |
|
234 oneChecked = true; |
|
235 break; |
|
236 } |
|
237 } |
|
238 |
|
239 this._wiz.canAdvance = oneChecked; |
|
240 }, |
|
241 |
|
242 // 4 - Home Page Selection |
|
243 onHomePageMigrationPageShow: function () |
|
244 { |
|
245 // only want this on the first run |
|
246 if (!this._autoMigrate) { |
|
247 this._wiz.advance(); |
|
248 return; |
|
249 } |
|
250 |
|
251 var brandBundle = document.getElementById("brandBundle"); |
|
252 // These strings don't exist when not using official branding. If that's |
|
253 // the case, just skip this page. |
|
254 try { |
|
255 var pageTitle = brandBundle.getString("homePageMigrationPageTitle"); |
|
256 var pageDesc = brandBundle.getString("homePageMigrationDescription"); |
|
257 var mainStr = brandBundle.getString("homePageSingleStartMain"); |
|
258 } |
|
259 catch (e) { |
|
260 this._wiz.advance(); |
|
261 return; |
|
262 } |
|
263 |
|
264 document.getElementById("homePageImport").setAttribute("label", pageTitle); |
|
265 document.getElementById("homePageImportDesc").setAttribute("value", pageDesc); |
|
266 |
|
267 this._wiz._adjustWizardHeader(); |
|
268 |
|
269 var singleStart = document.getElementById("homePageSingleStart"); |
|
270 singleStart.setAttribute("label", mainStr); |
|
271 singleStart.setAttribute("value", "DEFAULT"); |
|
272 |
|
273 var source = null; |
|
274 switch (this._source) { |
|
275 case "ie": |
|
276 source = "sourceNameIE"; |
|
277 break; |
|
278 case "safari": |
|
279 source = "sourceNameSafari"; |
|
280 break; |
|
281 case "chrome": |
|
282 source = "sourceNameChrome"; |
|
283 break; |
|
284 case "firefox": |
|
285 source = "sourceNameFirefox"; |
|
286 break; |
|
287 } |
|
288 |
|
289 // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places |
|
290 this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); |
|
291 |
|
292 var oldHomePageURL = this._migrator.sourceHomePageURL; |
|
293 |
|
294 if (oldHomePageURL && source) { |
|
295 var appName = MigrationUtils.getLocalizedString(source); |
|
296 var oldHomePageLabel = |
|
297 brandBundle.getFormattedString("homePageImport", [appName]); |
|
298 var oldHomePage = document.getElementById("oldHomePage"); |
|
299 oldHomePage.setAttribute("label", oldHomePageLabel); |
|
300 oldHomePage.setAttribute("value", oldHomePageURL); |
|
301 oldHomePage.removeAttribute("hidden"); |
|
302 } |
|
303 else { |
|
304 // if we don't have at least two options, just advance |
|
305 this._wiz.advance(); |
|
306 } |
|
307 }, |
|
308 |
|
309 onHomePageMigrationPageAdvanced: function () |
|
310 { |
|
311 // we might not have a selectedItem if we're in fallback mode |
|
312 try { |
|
313 var radioGroup = document.getElementById("homePageRadiogroup"); |
|
314 |
|
315 this._newHomePage = radioGroup.selectedItem.value; |
|
316 } catch(ex) {} |
|
317 }, |
|
318 |
|
319 // 5 - Migrating |
|
320 onMigratingPageShow: function () |
|
321 { |
|
322 this._wiz.getButton("cancel").disabled = true; |
|
323 this._wiz.canRewind = false; |
|
324 this._wiz.canAdvance = false; |
|
325 |
|
326 // When automigrating, show all of the data that can be received from this source. |
|
327 if (this._autoMigrate) |
|
328 this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); |
|
329 |
|
330 this._listItems("migratingItems"); |
|
331 setTimeout(this.onMigratingMigrate, 0, this); |
|
332 }, |
|
333 |
|
334 onMigratingMigrate: function (aOuter) |
|
335 { |
|
336 aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile); |
|
337 }, |
|
338 |
|
339 _listItems: function (aID) |
|
340 { |
|
341 var items = document.getElementById(aID); |
|
342 while (items.hasChildNodes()) |
|
343 items.removeChild(items.firstChild); |
|
344 |
|
345 var brandBundle = document.getElementById("brandBundle"); |
|
346 var itemID; |
|
347 for (var i = 0; i < 16; ++i) { |
|
348 var itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0; |
|
349 if (itemID > 0) { |
|
350 var label = document.createElement("label"); |
|
351 label.id = itemID + "_migrated"; |
|
352 try { |
|
353 label.setAttribute("value", |
|
354 MigrationUtils.getLocalizedString(itemID + "_" + this._source)); |
|
355 items.appendChild(label); |
|
356 } |
|
357 catch (e) { |
|
358 // if the block above throws, we've enumerated all the import data types we |
|
359 // currently support and are now just wasting time, break. |
|
360 break; |
|
361 } |
|
362 } |
|
363 } |
|
364 }, |
|
365 |
|
366 observe: function (aSubject, aTopic, aData) |
|
367 { |
|
368 switch (aTopic) { |
|
369 case "Migration:Started": |
|
370 break; |
|
371 case "Migration:ItemBeforeMigrate": |
|
372 var label = document.getElementById(aData + "_migrated"); |
|
373 if (label) |
|
374 label.setAttribute("style", "font-weight: bold"); |
|
375 break; |
|
376 case "Migration:ItemAfterMigrate": |
|
377 var label = document.getElementById(aData + "_migrated"); |
|
378 if (label) |
|
379 label.removeAttribute("style"); |
|
380 break; |
|
381 case "Migration:Ended": |
|
382 if (this._autoMigrate) { |
|
383 if (this._newHomePage) { |
|
384 try { |
|
385 // set homepage properly |
|
386 var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] |
|
387 .getService(Components.interfaces.nsIPrefService); |
|
388 var prefBranch = prefSvc.getBranch(null); |
|
389 |
|
390 if (this._newHomePage == "DEFAULT") { |
|
391 prefBranch.clearUserPref("browser.startup.homepage"); |
|
392 } |
|
393 else { |
|
394 var str = Components.classes["@mozilla.org/supports-string;1"] |
|
395 .createInstance(Components.interfaces.nsISupportsString); |
|
396 str.data = this._newHomePage; |
|
397 prefBranch.setComplexValue("browser.startup.homepage", |
|
398 Components.interfaces.nsISupportsString, |
|
399 str); |
|
400 } |
|
401 |
|
402 var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] |
|
403 .getService(Components.interfaces.nsIProperties); |
|
404 var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile); |
|
405 prefFile.append("prefs.js"); |
|
406 prefSvc.savePrefFile(prefFile); |
|
407 } catch(ex) { |
|
408 dump(ex); |
|
409 } |
|
410 } |
|
411 |
|
412 // We're done now. |
|
413 this._wiz.canAdvance = true; |
|
414 this._wiz.advance(); |
|
415 |
|
416 setTimeout(close, 5000); |
|
417 } |
|
418 else { |
|
419 this._wiz.canAdvance = true; |
|
420 var nextButton = this._wiz.getButton("next"); |
|
421 nextButton.click(); |
|
422 } |
|
423 break; |
|
424 case "Migration:ItemError": |
|
425 var type = "undefined"; |
|
426 switch (parseInt(aData)) { |
|
427 case Ci.nsIBrowserProfileMigrator.SETTINGS: |
|
428 type = "settings"; |
|
429 break; |
|
430 case Ci.nsIBrowserProfileMigrator.COOKIES: |
|
431 type = "cookies"; |
|
432 break; |
|
433 case Ci.nsIBrowserProfileMigrator.HISTORY: |
|
434 type = "history"; |
|
435 break; |
|
436 case Ci.nsIBrowserProfileMigrator.FORMDATA: |
|
437 type = "form data"; |
|
438 break; |
|
439 case Ci.nsIBrowserProfileMigrator.PASSWORDS: |
|
440 type = "passwords"; |
|
441 break; |
|
442 case Ci.nsIBrowserProfileMigrator.BOOKMARKS: |
|
443 type = "bookmarks"; |
|
444 break; |
|
445 case Ci.nsIBrowserProfileMigrator.OTHERDATA: |
|
446 type = "misc. data"; |
|
447 break; |
|
448 } |
|
449 Cc["@mozilla.org/consoleservice;1"] |
|
450 .getService(Ci.nsIConsoleService) |
|
451 .logStringMessage("some " + type + " did not successfully migrate."); |
|
452 break; |
|
453 } |
|
454 }, |
|
455 |
|
456 onDonePageShow: function () |
|
457 { |
|
458 this._wiz.getButton("cancel").disabled = true; |
|
459 this._wiz.canRewind = false; |
|
460 this._listItems("doneItems"); |
|
461 } |
|
462 }; |