Revision control

Copy as Markdown

Other Tools

/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const NS_PROFILE_MIGRATOR_CONTRACTID =
"@mozilla.org/profile/migrator;1?app=suite&type=";
var MigrationWizard = {
_source: "", // Source Profile Migrator ContractID suffix
_itemsFlags: Ci.nsISuiteProfileMigrator.ALL, // Selected Import Data Sources
_selectedProfile: null, // Selected Profile name to import from
_wiz: null, // Shortcut to the wizard
_migrator: null, // The actual profile migrator.
_autoMigrate: null, // Whether or not we are actually migrating.
_singleItem: false, // Are we choosing just to import a single
// item into the current profile?
_newHomePage: null, // Are we setting a new home page - what to?
init: function() {
Services.obs.addObserver(this, "Migration:Started");
Services.obs.addObserver(this, "Migration:ItemBeforeMigrate");
Services.obs.addObserver(this, "Migration:ItemAfterMigrate");
Services.obs.addObserver(this, "Migration:Ended");
Services.obs.addObserver(this, "Migration:Progress");
this._wiz = document.documentElement;
this._wiz.canRewind = false;
if ("arguments" in window) {
if ("arguments" in window && window.arguments[0] == "bookmarks") {
this._singleItem = true;
this._itemsFlags = Ci.nsISuiteProfileMigrator.BOOKMARKS;
document.getElementById("fromFile").hidden = false;
document.getElementById("importBookmarks").hidden = false;
document.getElementById("importAll").hidden = true;
}
else if (window.arguments.length > 1) {
this._source = window.arguments[0];
this._migrator =
window.arguments[1] instanceof Ci.nsISuiteProfileMigrator ?
window.arguments[1] : null;
this._autoMigrate = window.arguments[2]
.QueryInterface(Ci.nsIProfileStartup);
// Show the "nothing" option in the automigrate case to provide an
// easily identifiable way to avoid migration and create a new profile.
document.getElementById("nothing").hidden = false;
}
}
this.onImportSourcePageShow();
},
uninit: function() {
Services.obs.removeObserver(this, "Migration:Started");
Services.obs.removeObserver(this, "Migration:ItemBeforeMigrate");
Services.obs.removeObserver(this, "Migration:ItemAfterMigrate");
Services.obs.removeObserver(this, "Migration:Ended");
Services.obs.removeObserver(this, "Migration:Progress");
},
// 1 - Import Source
onImportSourcePageShow: function() {
// Figure out what source apps are are available to import from:
var group = document.getElementById("importSourceGroup");
var firstSelectable = null;
for (var i = 0; i < group.childNodes.length; ++i) {
var suffix = group.childNodes[i].id;
if (suffix != "nothing" && suffix != "fromFile") {
var contractID = NS_PROFILE_MIGRATOR_CONTRACTID + suffix;
var migrator = null;
if (contractID in Cc) {
migrator = Cc[contractID]
.createInstance(Ci.nsISuiteProfileMigrator);
} else {
dump("*** invalid contractID =" + contractID + "\n");
// This is an invalid contract id, therefore hide this element
// and allow things to continue - that way we should be able to
// copy with anything happening.
group.childNodes[i].hidden = true;
break;
}
// Ensure that we only allow import selections for profile
// migrators that support the requested action.
if (!migrator.sourceExists ||
!(migrator.supportedItems & this._itemsFlags)) {
group.childNodes[i].hidden = true;
break;
}
if (!firstSelectable && !group.childNodes[i].disabled &&
!group.childNodes[i].hidden) {
firstSelectable = group.childNodes[i];
}
}
}
if (this._source) {
// Somehow the Profile Migrator got confused, and gave us a migrate source
// that doesn't actually exist. This could be because of a bogus registry
// state. Set the _source property to null so the first visible item in
// the list is selected instead.
if (document.getElementById(this._source).hidden)
this._source = null;
}
group.selectedItem = this._source ?
document.getElementById(this._source) : firstSelectable;
},
onImportSourcePageAdvanced: function() {
var newSource = document.getElementById("importSourceGroup").value;
if (newSource == "nothing" || newSource == "fromFile") {
if (newSource == "fromFile") {
window.opener.fromFile = true;
}
document.documentElement.cancel();
// Don't let the wizard migrate to the next page event though we've
// called cancel - cancel may not get processed first.
return false;
}
if (!this._migrator || newSource != this._source) {
// Create the migrator for the selected source.
var contractID = NS_PROFILE_MIGRATOR_CONTRACTID + newSource;
this._migrator = Cc[contractID]
.createInstance(Ci.nsISuiteProfileMigrator);
this._selectedProfile = null;
}
this._source = newSource;
// check for more than one source profile
if (this._migrator.sourceHasMultipleProfiles)
this._wiz.currentPage.next = "selectProfile";
else {
if (this._autoMigrate)
this._wiz.currentPage.next = "homePageImport";
else if (this._singleItem)
this._wiz.currentPage.next = "migrating";
else
this._wiz.currentPage.next = "importItems";
var sourceProfiles = this._migrator.sourceProfiles;
if (sourceProfiles && sourceProfiles.length == 1) {
this._selectedProfile = sourceProfiles
.queryElementAt(0, Ci.nsISupportsString).data;
}
else
this._selectedProfile = "";
}
return true;
},
// 2 - [Profile Selection]
onSelectProfilePageShow: function() {
var profiles = document.getElementById("profiles");
while (profiles.hasChildNodes())
profiles.lastChild.remove();
var sourceProfiles = this._migrator.sourceProfiles;
var count = sourceProfiles.length;
for (var i = 0; i < count; ++i) {
var item = document.createElement("radio");
item.id = sourceProfiles.queryElementAt(i, Ci.nsISupportsString).data;
item.setAttribute("label", item.id);
profiles.appendChild(item);
}
profiles.selectedItem = this._selectedProfile ?
document.getElementById(this._selectedProfile) : profiles.firstChild;
},
onSelectProfilePageAdvanced: function() {
this._selectedProfile = document.getElementById("profiles").selectedItem.id;
// If we're automigrating or just doing bookmarks don't show the item
// selection page
if (this._autoMigrate)
this._wiz.currentPage.next = "homePageImport";
else if (this._singleItem)
this._wiz.currentPage.next = "migrating"
},
// 3 - ImportItems
onImportItemsPageShow: function() {
var dataSources = document.getElementById("dataSources");
while (dataSources.hasChildNodes())
dataSources.lastChild.remove();
var bundle = document.getElementById("bundle");
var items = this._migrator.getMigrateData(this._selectedProfile,
this._autoMigrate);
for (var i = 0; i < 16; ++i) {
var itemID = items & (1 << i);
if (itemID) {
var checkbox = document.createElement("checkbox");
checkbox.id = itemID;
try {
checkbox.setAttribute("label",
bundle.getString(itemID + "_" + this._source));
}
catch (ex) {
checkbox.setAttribute("label",
bundle.getString(itemID + "_generic"));
}
dataSources.appendChild(checkbox);
if (this._itemsFlags & itemID)
checkbox.setAttribute("checked", true);
}
}
},
onImportItemsPageRewound: function() {
this._wiz.canAdvance = true;
this.onImportItemsPageAdvanced();
},
onImportItemsPageAdvanced: function() {
var dataSources = document.getElementById("dataSources");
this._itemsFlags = 0;
for (var i = 0; i < dataSources.childNodes.length; ++i) {
var checkbox = dataSources.childNodes[i];
if (checkbox.checked)
this._itemsFlags |= checkbox.id;
}
},
onImportItemCommand: function(aEvent) {
this._wiz.canAdvance = document
.getElementById("dataSources")
.getElementsByAttribute("checked", "true").item(0) != null;
},
// 4 - Home Page Selection
onHomePageMigrationPageShow: function() {
// only want this on the first run
if (!this._autoMigrate) {
this._wiz.advance();
return;
}
var bundle = document.getElementById("bundle");
var pageTitle = bundle.getString("homePageMigrationPageTitle");
var pageDesc = bundle.getString("homePageMigrationDescription");
document.getElementById("homePageImport").setAttribute("label", pageTitle);
document.getElementById("homePageImportDesc")
.setAttribute("value", pageDesc);
this._wiz._adjustWizardHeader();
var homePageStart = document.getElementById("homePageStart");
// Find out if the target profile already has a homepage or not
var mainStr = this.targetHasHomePageURL() ?
bundle.getString("homePageStartCurrent") :
bundle.getString("homePageStartDefault");
homePageStart.setAttribute("label", mainStr);
var source = null;
if (this._source != "") {
source = "sourceName" + this._source;
}
var availableItems = this._migrator.getMigrateData(this._selectedProfile,
this._autoMigrate);
if (source && (availableItems & Ci.nsISuiteProfileMigrator.HOMEPAGEDATA)) {
var appName = document.getElementById("bundle").getString(source);
var oldHomePageLabel = bundle.getFormattedString("homePageImport",
[appName]);
var oldHomePage = document.getElementById("oldHomePage");
oldHomePage.setAttribute("label", oldHomePageLabel);
oldHomePage.setAttribute("value", "source");
oldHomePage.removeAttribute("hidden");
oldHomePage.focus();
document.getElementById("homePageRadioGroup").selectedItem = oldHomePage;
}
else {
// if we don't have at least two options, just advance
this._wiz.advance();
}
},
onHomePageMigrationPageAdvanced: function() {
// we might not have a selectedItem if we're in fallback mode
try {
this._newHomePage = document.getElementById("homePageRadioGroup")
.value;
} catch(ex) {}
},
// 5 - Migrating
onMigratingPageShow: function() {
this._wiz.getButton("cancel").disabled = true;
this._wiz.canRewind = false;
this._wiz.canAdvance = false;
// When migrating a profile on startup, show all of the data that can be
// received from this source, but exclude home pages if the user didn't
// want to migrate it.
if (this._autoMigrate) {
this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile,
this._autoMigrate);
if (!this._newHomePage)
this._itemsFlags &= ~Ci.nsISuiteProfileMigrator.HOMEPAGEDATA;
}
this._listItems("migratingItems");
setTimeout(this.onMigratingMigrate, 0, this);
},
onMigratingMigrate: function(aOuter) {
aOuter._migrator.migrate(aOuter._itemsFlags,
aOuter._autoMigrate,
aOuter._selectedProfile);
},
_listItems: function(aID) {
var items = document.getElementById(aID);
while (items.hasChildNodes())
items.lastChild.remove();
var bundle = document.getElementById("bundle");
var itemID;
for (var x = 1; x < Ci.nsISuiteProfileMigrator.ALL;
x = x << 1) {
if (x & this._itemsFlags) {
var label = document.createElement("label");
label.id = x + "_migrated";
try {
label.setAttribute("value",
bundle.stringBundle
.GetStringFromName(x + "_"+ this._source));
label.setAttribute("class", "migration-pending");
items.appendChild(label);
}
catch (ex) {
try {
label.setAttribute("value", bundle.getString(x + "_generic"));
label.setAttribute("class", "migration-pending");
items.appendChild(label);
}
catch (e) {
// if the block above throws, we've enumerated all the import
// data types we currently support and are now just wasting time.
break;
}
}
}
}
},
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "Migration:Progress":
document.getElementById("progressBar").value = aData;
break;
case "Migration:Started":
break;
case "Migration:ItemBeforeMigrate":
var label = document.getElementById(aData + "_migrated");
if (label)
label.setAttribute("class", "migration-in-progress");
break;
case "Migration:ItemAfterMigrate":
var label = document.getElementById(aData + "_migrated");
if (label)
label.setAttribute("class", "migration-finished");
break;
case "Migration:Ended":
// We're done now.
this._wiz.canAdvance = true;
this._wiz.advance();
if (this._autoMigrate)
setTimeout(close, 5000);
break;
}
},
onDonePageShow: function() {
this._wiz.getButton("cancel").disabled = true;
this._wiz.canRewind = false;
this._listItems("doneItems");
},
targetHasHomePageURL: function() {
var targetPrefsFile = this._autoMigrate.directory;
targetPrefsFile.append("prefs.js");
// If the target prefs file doesn't exist, then we can't have a
// homepage set in the target profile.
if (!targetPrefsFile.exists())
return false;
Services.prefs.resetPrefs();
Services.prefs.readUserPrefsFromFile(targetPrefsFile);
return Services.prefs.prefHasUserValue("browser.startup.homepage");
}
};