Wed, 31 Dec 2014 07:53:36 +0100
Correct small whitespace inconsistency, lost while renaming variables.
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/. */
5 const Cc = Components.classes;
6 const Ci = Components.interfaces;
7 const Cu = Components.utils;
9 const kIMig = Ci.nsIBrowserProfileMigrator;
10 const kIPStartup = Ci.nsIProfileStartup;
12 Cu.import("resource:///modules/MigrationUtils.jsm");
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,
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);
32 this._wiz = document.documentElement;
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];
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 }
49 this.onImportSourcePageShow();
50 },
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 },
64 // 1 - Import Source
65 onImportSourcePageShow: function ()
66 {
67 this._wiz.canRewind = false;
69 var selectedMigrator = null;
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 }
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;
95 this._wiz.canAdvance = false;
97 document.getElementById("importBookmarks").hidden = true;
98 document.getElementById("importAll").hidden = true;
99 }
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 },
108 onImportSourcePageAdvanced: function ()
109 {
110 var newSource = document.getElementById("importSourceGroup").selectedItem.id;
112 if (newSource == "nothing") {
113 document.documentElement.cancel();
114 return false;
115 }
117 if (!this._migrator || (newSource != this._source)) {
118 // Create the migrator for the selected source.
119 this._migrator = MigrationUtils.getMigrator(newSource);
121 this._itemsFlags = kIMig.ALL;
122 this._selectedProfile = null;
123 }
124 this._source = newSource;
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";
137 if (sourceProfiles && sourceProfiles.length == 1)
138 this._selectedProfile = sourceProfiles[0];
139 else
140 this._selectedProfile = "";
141 }
142 },
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;
152 var profiles = document.getElementById("profiles");
153 while (profiles.hasChildNodes())
154 profiles.removeChild(profiles.firstChild);
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 }
168 profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile) : profiles.firstChild;
169 },
171 onSelectProfilePageRewound: function ()
172 {
173 var profiles = document.getElementById("profiles");
174 this._selectedProfile = profiles.selectedItem.id;
175 },
177 onSelectProfilePageAdvanced: function ()
178 {
179 var profiles = document.getElementById("profiles");
180 this._selectedProfile = profiles.selectedItem.id;
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 },
187 // 3 - ImportItems
188 onImportItemsPageShow: function ()
189 {
190 var dataSources = document.getElementById("dataSources");
191 while (dataSources.hasChildNodes())
192 dataSources.removeChild(dataSources.firstChild);
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 },
209 onImportItemsPageRewound: function ()
210 {
211 this._wiz.canAdvance = true;
212 this.onImportItemsPageAdvanced();
213 },
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 },
226 onImportItemCommand: function (aEvent)
227 {
228 var items = document.getElementById("dataSources");
229 var checkboxes = items.getElementsByTagName("checkbox");
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 }
239 this._wiz.canAdvance = oneChecked;
240 },
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 }
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 }
264 document.getElementById("homePageImport").setAttribute("label", pageTitle);
265 document.getElementById("homePageImportDesc").setAttribute("value", pageDesc);
267 this._wiz._adjustWizardHeader();
269 var singleStart = document.getElementById("homePageSingleStart");
270 singleStart.setAttribute("label", mainStr);
271 singleStart.setAttribute("value", "DEFAULT");
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 }
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);
292 var oldHomePageURL = this._migrator.sourceHomePageURL;
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 },
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");
315 this._newHomePage = radioGroup.selectedItem.value;
316 } catch(ex) {}
317 },
319 // 5 - Migrating
320 onMigratingPageShow: function ()
321 {
322 this._wiz.getButton("cancel").disabled = true;
323 this._wiz.canRewind = false;
324 this._wiz.canAdvance = false;
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);
330 this._listItems("migratingItems");
331 setTimeout(this.onMigratingMigrate, 0, this);
332 },
334 onMigratingMigrate: function (aOuter)
335 {
336 aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile);
337 },
339 _listItems: function (aID)
340 {
341 var items = document.getElementById(aID);
342 while (items.hasChildNodes())
343 items.removeChild(items.firstChild);
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 },
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);
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 }
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 }
412 // We're done now.
413 this._wiz.canAdvance = true;
414 this._wiz.advance();
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 },
456 onDonePageShow: function ()
457 {
458 this._wiz.getButton("cancel").disabled = true;
459 this._wiz.canRewind = false;
460 this._listItems("doneItems");
461 }
462 };