michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: const kIMig = Ci.nsIBrowserProfileMigrator; michael@0: const kIPStartup = Ci.nsIProfileStartup; michael@0: michael@0: Cu.import("resource:///modules/MigrationUtils.jsm"); michael@0: michael@0: var MigrationWizard = { michael@0: _source: "", // Source Profile Migrator ContractID suffix michael@0: _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield) michael@0: _selectedProfile: null, // Selected Profile name to import from michael@0: _wiz: null, michael@0: _migrator: null, michael@0: _autoMigrate: null, michael@0: michael@0: init: function () michael@0: { michael@0: var os = Components.classes["@mozilla.org/observer-service;1"] michael@0: .getService(Components.interfaces.nsIObserverService); michael@0: os.addObserver(this, "Migration:Started", false); michael@0: os.addObserver(this, "Migration:ItemBeforeMigrate", false); michael@0: os.addObserver(this, "Migration:ItemAfterMigrate", false); michael@0: os.addObserver(this, "Migration:ItemError", false); michael@0: os.addObserver(this, "Migration:Ended", false); michael@0: michael@0: this._wiz = document.documentElement; michael@0: michael@0: if ("arguments" in window && window.arguments.length > 1) { michael@0: this._source = window.arguments[0]; michael@0: this._migrator = window.arguments[1] instanceof kIMig ? michael@0: window.arguments[1] : null; michael@0: this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup); michael@0: this._skipImportSourcePage = window.arguments[3]; michael@0: michael@0: if (this._autoMigrate) { michael@0: // Show the "nothing" option in the automigrate case to provide an michael@0: // easily identifiable way to avoid migration and create a new profile. michael@0: var nothing = document.getElementById("nothing"); michael@0: nothing.hidden = false; michael@0: } michael@0: } michael@0: michael@0: this.onImportSourcePageShow(); michael@0: }, michael@0: michael@0: uninit: function () michael@0: { michael@0: var os = Components.classes["@mozilla.org/observer-service;1"] michael@0: .getService(Components.interfaces.nsIObserverService); michael@0: os.removeObserver(this, "Migration:Started"); michael@0: os.removeObserver(this, "Migration:ItemBeforeMigrate"); michael@0: os.removeObserver(this, "Migration:ItemAfterMigrate"); michael@0: os.removeObserver(this, "Migration:ItemError"); michael@0: os.removeObserver(this, "Migration:Ended"); michael@0: MigrationUtils.finishMigration(); michael@0: }, michael@0: michael@0: // 1 - Import Source michael@0: onImportSourcePageShow: function () michael@0: { michael@0: this._wiz.canRewind = false; michael@0: michael@0: var selectedMigrator = null; michael@0: michael@0: // Figure out what source apps are are available to import from: michael@0: var group = document.getElementById("importSourceGroup"); michael@0: for (var i = 0; i < group.childNodes.length; ++i) { michael@0: var migratorKey = group.childNodes[i].id; michael@0: if (migratorKey != "nothing") { michael@0: var migrator = MigrationUtils.getMigrator(migratorKey); michael@0: if (migrator) { michael@0: // Save this as the first selectable item, if we don't already have michael@0: // one, or if it is the migrator that was passed to us. michael@0: if (!selectedMigrator || this._source == migratorKey) michael@0: selectedMigrator = group.childNodes[i]; michael@0: } else { michael@0: // Hide this option michael@0: group.childNodes[i].hidden = true; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (selectedMigrator) michael@0: group.selectedItem = selectedMigrator; michael@0: else { michael@0: // We didn't find a migrator, notify the user michael@0: document.getElementById("noSources").hidden = false; michael@0: michael@0: this._wiz.canAdvance = false; michael@0: michael@0: document.getElementById("importBookmarks").hidden = true; michael@0: document.getElementById("importAll").hidden = true; michael@0: } michael@0: michael@0: // Advance to the next page if the caller told us to. michael@0: if (this._migrator && this._skipImportSourcePage) { michael@0: this._wiz.advance(); michael@0: this._wiz.canRewind = false; michael@0: } michael@0: }, michael@0: michael@0: onImportSourcePageAdvanced: function () michael@0: { michael@0: var newSource = document.getElementById("importSourceGroup").selectedItem.id; michael@0: michael@0: if (newSource == "nothing") { michael@0: document.documentElement.cancel(); michael@0: return false; michael@0: } michael@0: michael@0: if (!this._migrator || (newSource != this._source)) { michael@0: // Create the migrator for the selected source. michael@0: this._migrator = MigrationUtils.getMigrator(newSource); michael@0: michael@0: this._itemsFlags = kIMig.ALL; michael@0: this._selectedProfile = null; michael@0: } michael@0: this._source = newSource; michael@0: michael@0: // check for more than one source profile michael@0: var sourceProfiles = this._migrator.sourceProfiles; michael@0: if (sourceProfiles && sourceProfiles.length > 1) { michael@0: this._wiz.currentPage.next = "selectProfile"; michael@0: } michael@0: else { michael@0: if (this._autoMigrate) michael@0: this._wiz.currentPage.next = "homePageImport"; michael@0: else michael@0: this._wiz.currentPage.next = "importItems"; michael@0: michael@0: if (sourceProfiles && sourceProfiles.length == 1) michael@0: this._selectedProfile = sourceProfiles[0]; michael@0: else michael@0: this._selectedProfile = ""; michael@0: } michael@0: }, michael@0: michael@0: // 2 - [Profile Selection] michael@0: onSelectProfilePageShow: function () michael@0: { michael@0: // Disabling this for now, since we ask about import sources in automigration michael@0: // too and don't want to disable the back button michael@0: // if (this._autoMigrate) michael@0: // document.documentElement.getButton("back").disabled = true; michael@0: michael@0: var profiles = document.getElementById("profiles"); michael@0: while (profiles.hasChildNodes()) michael@0: profiles.removeChild(profiles.firstChild); michael@0: michael@0: // Note that this block is still reached even if the user chose 'From File' michael@0: // and we canceled the dialog. When that happens, _migrator will be null. michael@0: if (this._migrator) { michael@0: var sourceProfiles = this._migrator.sourceProfiles; michael@0: for (var i = 0; i < sourceProfiles.length; ++i) { michael@0: var item = document.createElement("radio"); michael@0: item.id = sourceProfiles[i]; michael@0: item.setAttribute("label", sourceProfiles[i]); michael@0: profiles.appendChild(item); michael@0: } michael@0: } michael@0: michael@0: profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile) : profiles.firstChild; michael@0: }, michael@0: michael@0: onSelectProfilePageRewound: function () michael@0: { michael@0: var profiles = document.getElementById("profiles"); michael@0: this._selectedProfile = profiles.selectedItem.id; michael@0: }, michael@0: michael@0: onSelectProfilePageAdvanced: function () michael@0: { michael@0: var profiles = document.getElementById("profiles"); michael@0: this._selectedProfile = profiles.selectedItem.id; michael@0: michael@0: // If we're automigrating or just doing bookmarks don't show the item selection page michael@0: if (this._autoMigrate) michael@0: this._wiz.currentPage.next = "homePageImport"; michael@0: }, michael@0: michael@0: // 3 - ImportItems michael@0: onImportItemsPageShow: function () michael@0: { michael@0: var dataSources = document.getElementById("dataSources"); michael@0: while (dataSources.hasChildNodes()) michael@0: dataSources.removeChild(dataSources.firstChild); michael@0: michael@0: var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); michael@0: for (var i = 0; i < 16; ++i) { michael@0: var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0; michael@0: if (itemID > 0) { michael@0: var checkbox = document.createElement("checkbox"); michael@0: checkbox.id = itemID; michael@0: checkbox.setAttribute("label", michael@0: MigrationUtils.getLocalizedString(itemID + "_" + this._source)); michael@0: dataSources.appendChild(checkbox); michael@0: if (!this._itemsFlags || this._itemsFlags & itemID) michael@0: checkbox.checked = true; michael@0: } michael@0: } michael@0: }, michael@0: michael@0: onImportItemsPageRewound: function () michael@0: { michael@0: this._wiz.canAdvance = true; michael@0: this.onImportItemsPageAdvanced(); michael@0: }, michael@0: michael@0: onImportItemsPageAdvanced: function () michael@0: { michael@0: var dataSources = document.getElementById("dataSources"); michael@0: this._itemsFlags = 0; michael@0: for (var i = 0; i < dataSources.childNodes.length; ++i) { michael@0: var checkbox = dataSources.childNodes[i]; michael@0: if (checkbox.localName == "checkbox" && checkbox.checked) michael@0: this._itemsFlags |= parseInt(checkbox.id); michael@0: } michael@0: }, michael@0: michael@0: onImportItemCommand: function (aEvent) michael@0: { michael@0: var items = document.getElementById("dataSources"); michael@0: var checkboxes = items.getElementsByTagName("checkbox"); michael@0: michael@0: var oneChecked = false; michael@0: for (var i = 0; i < checkboxes.length; ++i) { michael@0: if (checkboxes[i].checked) { michael@0: oneChecked = true; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: this._wiz.canAdvance = oneChecked; michael@0: }, michael@0: michael@0: // 4 - Home Page Selection michael@0: onHomePageMigrationPageShow: function () michael@0: { michael@0: // only want this on the first run michael@0: if (!this._autoMigrate) { michael@0: this._wiz.advance(); michael@0: return; michael@0: } michael@0: michael@0: var brandBundle = document.getElementById("brandBundle"); michael@0: // These strings don't exist when not using official branding. If that's michael@0: // the case, just skip this page. michael@0: try { michael@0: var pageTitle = brandBundle.getString("homePageMigrationPageTitle"); michael@0: var pageDesc = brandBundle.getString("homePageMigrationDescription"); michael@0: var mainStr = brandBundle.getString("homePageSingleStartMain"); michael@0: } michael@0: catch (e) { michael@0: this._wiz.advance(); michael@0: return; michael@0: } michael@0: michael@0: document.getElementById("homePageImport").setAttribute("label", pageTitle); michael@0: document.getElementById("homePageImportDesc").setAttribute("value", pageDesc); michael@0: michael@0: this._wiz._adjustWizardHeader(); michael@0: michael@0: var singleStart = document.getElementById("homePageSingleStart"); michael@0: singleStart.setAttribute("label", mainStr); michael@0: singleStart.setAttribute("value", "DEFAULT"); michael@0: michael@0: var source = null; michael@0: switch (this._source) { michael@0: case "ie": michael@0: source = "sourceNameIE"; michael@0: break; michael@0: case "safari": michael@0: source = "sourceNameSafari"; michael@0: break; michael@0: case "chrome": michael@0: source = "sourceNameChrome"; michael@0: break; michael@0: case "firefox": michael@0: source = "sourceNameFirefox"; michael@0: break; michael@0: } michael@0: michael@0: // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places michael@0: this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); michael@0: michael@0: var oldHomePageURL = this._migrator.sourceHomePageURL; michael@0: michael@0: if (oldHomePageURL && source) { michael@0: var appName = MigrationUtils.getLocalizedString(source); michael@0: var oldHomePageLabel = michael@0: brandBundle.getFormattedString("homePageImport", [appName]); michael@0: var oldHomePage = document.getElementById("oldHomePage"); michael@0: oldHomePage.setAttribute("label", oldHomePageLabel); michael@0: oldHomePage.setAttribute("value", oldHomePageURL); michael@0: oldHomePage.removeAttribute("hidden"); michael@0: } michael@0: else { michael@0: // if we don't have at least two options, just advance michael@0: this._wiz.advance(); michael@0: } michael@0: }, michael@0: michael@0: onHomePageMigrationPageAdvanced: function () michael@0: { michael@0: // we might not have a selectedItem if we're in fallback mode michael@0: try { michael@0: var radioGroup = document.getElementById("homePageRadiogroup"); michael@0: michael@0: this._newHomePage = radioGroup.selectedItem.value; michael@0: } catch(ex) {} michael@0: }, michael@0: michael@0: // 5 - Migrating michael@0: onMigratingPageShow: function () michael@0: { michael@0: this._wiz.getButton("cancel").disabled = true; michael@0: this._wiz.canRewind = false; michael@0: this._wiz.canAdvance = false; michael@0: michael@0: // When automigrating, show all of the data that can be received from this source. michael@0: if (this._autoMigrate) michael@0: this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); michael@0: michael@0: this._listItems("migratingItems"); michael@0: setTimeout(this.onMigratingMigrate, 0, this); michael@0: }, michael@0: michael@0: onMigratingMigrate: function (aOuter) michael@0: { michael@0: aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile); michael@0: }, michael@0: michael@0: _listItems: function (aID) michael@0: { michael@0: var items = document.getElementById(aID); michael@0: while (items.hasChildNodes()) michael@0: items.removeChild(items.firstChild); michael@0: michael@0: var brandBundle = document.getElementById("brandBundle"); michael@0: var itemID; michael@0: for (var i = 0; i < 16; ++i) { michael@0: var itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0; michael@0: if (itemID > 0) { michael@0: var label = document.createElement("label"); michael@0: label.id = itemID + "_migrated"; michael@0: try { michael@0: label.setAttribute("value", michael@0: MigrationUtils.getLocalizedString(itemID + "_" + this._source)); michael@0: items.appendChild(label); michael@0: } michael@0: catch (e) { michael@0: // if the block above throws, we've enumerated all the import data types we michael@0: // currently support and are now just wasting time, break. michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: }, michael@0: michael@0: observe: function (aSubject, aTopic, aData) michael@0: { michael@0: switch (aTopic) { michael@0: case "Migration:Started": michael@0: break; michael@0: case "Migration:ItemBeforeMigrate": michael@0: var label = document.getElementById(aData + "_migrated"); michael@0: if (label) michael@0: label.setAttribute("style", "font-weight: bold"); michael@0: break; michael@0: case "Migration:ItemAfterMigrate": michael@0: var label = document.getElementById(aData + "_migrated"); michael@0: if (label) michael@0: label.removeAttribute("style"); michael@0: break; michael@0: case "Migration:Ended": michael@0: if (this._autoMigrate) { michael@0: if (this._newHomePage) { michael@0: try { michael@0: // set homepage properly michael@0: var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] michael@0: .getService(Components.interfaces.nsIPrefService); michael@0: var prefBranch = prefSvc.getBranch(null); michael@0: michael@0: if (this._newHomePage == "DEFAULT") { michael@0: prefBranch.clearUserPref("browser.startup.homepage"); michael@0: } michael@0: else { michael@0: var str = Components.classes["@mozilla.org/supports-string;1"] michael@0: .createInstance(Components.interfaces.nsISupportsString); michael@0: str.data = this._newHomePage; michael@0: prefBranch.setComplexValue("browser.startup.homepage", michael@0: Components.interfaces.nsISupportsString, michael@0: str); michael@0: } michael@0: michael@0: var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] michael@0: .getService(Components.interfaces.nsIProperties); michael@0: var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile); michael@0: prefFile.append("prefs.js"); michael@0: prefSvc.savePrefFile(prefFile); michael@0: } catch(ex) { michael@0: dump(ex); michael@0: } michael@0: } michael@0: michael@0: // We're done now. michael@0: this._wiz.canAdvance = true; michael@0: this._wiz.advance(); michael@0: michael@0: setTimeout(close, 5000); michael@0: } michael@0: else { michael@0: this._wiz.canAdvance = true; michael@0: var nextButton = this._wiz.getButton("next"); michael@0: nextButton.click(); michael@0: } michael@0: break; michael@0: case "Migration:ItemError": michael@0: var type = "undefined"; michael@0: switch (parseInt(aData)) { michael@0: case Ci.nsIBrowserProfileMigrator.SETTINGS: michael@0: type = "settings"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.COOKIES: michael@0: type = "cookies"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.HISTORY: michael@0: type = "history"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.FORMDATA: michael@0: type = "form data"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.PASSWORDS: michael@0: type = "passwords"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.BOOKMARKS: michael@0: type = "bookmarks"; michael@0: break; michael@0: case Ci.nsIBrowserProfileMigrator.OTHERDATA: michael@0: type = "misc. data"; michael@0: break; michael@0: } michael@0: Cc["@mozilla.org/consoleservice;1"] michael@0: .getService(Ci.nsIConsoleService) michael@0: .logStringMessage("some " + type + " did not successfully migrate."); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: onDonePageShow: function () michael@0: { michael@0: this._wiz.getButton("cancel").disabled = true; michael@0: this._wiz.canRewind = false; michael@0: this._listItems("doneItems"); michael@0: } michael@0: };