diff options
Diffstat (limited to 'browser/components/migration/content')
4 files changed, 754 insertions, 0 deletions
diff --git a/browser/components/migration/content/aboutWelcomeBack.xhtml b/browser/components/migration/content/aboutWelcomeBack.xhtml new file mode 100644 index 000000000..d9fdb6c2c --- /dev/null +++ b/browser/components/migration/content/aboutWelcomeBack.xhtml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +# 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/. +--> +<!DOCTYPE html [ + <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> + %htmlDTD; + <!ENTITY % netErrorDTD SYSTEM "chrome://global/locale/netError.dtd"> + %netErrorDTD; + <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> + %globalDTD; + <!ENTITY % restorepageDTD SYSTEM "chrome://browser/locale/aboutSessionRestore.dtd"> + %restorepageDTD; +]> + +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <head> + <title>&welcomeback2.tabtitle;</title> + <link rel="stylesheet" href="chrome://global/skin/in-content/info-pages.css" type="text/css" media="all"/> + <link rel="stylesheet" href="chrome://browser/skin/aboutWelcomeBack.css" type="text/css" media="all"/> + <link rel="icon" type="image/png" href="chrome://global/skin/icons/information-16.png"/> + + <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSessionRestore.js"/> + </head> + + <body dir="&locale.dir;"> + + <div class="container"> + + <div class="title"> + <h1 class="title-text">&welcomeback2.pageTitle;</h1> + </div> + + <div class="description"> + + <p>&welcomeback2.pageInfo1;</p> + <!-- Note a href in the anchor below is added by JS --> + <p>&welcomeback2.beforelink.pageInfo2;<a id="linkMoreTroubleshooting" target="_blank">&welcomeback2.link.pageInfo2;</a>&welcomeback2.afterlink.pageInfo2;</p> + + <div> + <div class="radioRestoreContainer"> + <input class="radioRestoreButton" id="radioRestoreAll" type="radio" + name="restore" checked="checked"/> + <label class="radioRestoreLabel" for="radioRestoreAll">&welcomeback2.label.restoreAll;</label> + </div> + + <div class="radioRestoreContainer"> + <input class="radioRestoreButton" id="radioRestoreChoose" type="radio" + name="restore"/> + <label class="radioRestoreLabel" for="radioRestoreChoose">&welcomeback2.label.restoreSome;</label> + </div> + </div> + </div> + + <div class="tree-container"> + <xul:tree id="tabList" flex="1" seltype="single" hidecolumnpicker="true" + onclick="onListClick(event);" onkeydown="onListKeyDown(event);" + _window_label="&restorepage.windowLabel;"> + <xul:treecols> + <xul:treecol cycler="true" id="restore" type="checkbox" label="&restorepage.restoreHeader;"/> + <xul:splitter class="tree-splitter"/> + <xul:treecol primary="true" id="title" label="&restorepage.listHeader;" flex="1"/> + </xul:treecols> + <xul:treechildren flex="1"/> + </xul:tree> + </div> + + <div class="button-container"> + <xul:button class="primary" + id="errorTryAgain" + label="&welcomeback2.restoreButton;" + accesskey="&welcomeback2.restoreButton.access;" + oncommand="restoreSession();"/> + </div> + + <input type="text" id="sessionData" style="display: none;"/> + + </div> + </body> +</html> diff --git a/browser/components/migration/content/extra-migration-strings.properties b/browser/components/migration/content/extra-migration-strings.properties new file mode 100644 index 000000000..208906b31 --- /dev/null +++ b/browser/components/migration/content/extra-migration-strings.properties @@ -0,0 +1,14 @@ +# Automigration undo notification. +# %1$S will be replaced with the name of the browser we imported from, %2$S will be replaced with brandShortName +automigration.undo.message.all = Pick up where you left off. We’ve imported these sites and your bookmarks, history and passwords from %1$S into %2$S. +automigration.undo.message.bookmarks = Pick up where you left off. We’ve imported these sites and your bookmarks from %1$S into %2$S. +automigration.undo.message.bookmarks.logins = Pick up where you left off. We’ve imported these sites and your bookmarks and passwords from %1$S into %2$S. +automigration.undo.message.bookmarks.visits = Pick up where you left off. We’ve imported these sites and your bookmarks and history from %1$S into %2$S. +automigration.undo.message.logins = Pick up where you left off. We’ve imported your passwords from %1$S into %2$S. +automigration.undo.message.logins.visits = Pick up where you left off. We’ve imported these sites and your history and passwords from %1$S into %2$S. +automigration.undo.message.visits = Pick up where you left off. We’ve imported these sites and your history from %1$S into %2$S. +automigration.undo.keep2.label = OK, Got it +automigration.undo.keep2.accesskey = O +automigration.undo.dontkeep2.label = No Thanks +automigration.undo.dontkeep2.accesskey = N +automigration.undo.unknownbrowser = Unknown Browser diff --git a/browser/components/migration/content/migration.js b/browser/components/migration/content/migration.js new file mode 100644 index 000000000..eb2175628 --- /dev/null +++ b/browser/components/migration/content/migration.js @@ -0,0 +1,549 @@ +/* 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/. */ + +"use strict"; + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + +const kIMig = Ci.nsIBrowserProfileMigrator; +const kIPStartup = Ci.nsIProfileStartup; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource:///modules/MigrationUtils.jsm"); + +var MigrationWizard = { /* exported MigrationWizard */ + _source: "", // Source Profile Migrator ContractID suffix + _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield) + _selectedProfile: null, // Selected Profile name to import from + _wiz: null, + _migrator: null, + _autoMigrate: null, + + init: function () + { + let os = Services.obs; + os.addObserver(this, "Migration:Started", false); + os.addObserver(this, "Migration:ItemBeforeMigrate", false); + os.addObserver(this, "Migration:ItemAfterMigrate", false); + os.addObserver(this, "Migration:ItemError", false); + os.addObserver(this, "Migration:Ended", false); + + this._wiz = document.documentElement; + + let args = window.arguments; + let entryPointId = args[0] || MigrationUtils.MIGRATION_ENTRYPOINT_UNKNOWN; + Services.telemetry.getHistogramById("FX_MIGRATION_ENTRY_POINT").add(entryPointId); + this.isInitialMigration = entryPointId == MigrationUtils.MIGRATION_ENTRYPOINT_FIRSTRUN; + + if (args.length > 1) { + this._source = args[1]; + this._migrator = args[2] instanceof kIMig ? args[2] : null; + this._autoMigrate = args[3].QueryInterface(kIPStartup); + this._skipImportSourcePage = args[4]; + if (this._migrator && args[5]) { + let sourceProfiles = this._migrator.sourceProfiles; + this._selectedProfile = sourceProfiles.find(profile => profile.id == args[5]); + } + + if (this._autoMigrate) { + // 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 () + { + var os = Components.classes["@mozilla.org/observer-service;1"] + .getService(Components.interfaces.nsIObserverService); + os.removeObserver(this, "Migration:Started"); + os.removeObserver(this, "Migration:ItemBeforeMigrate"); + os.removeObserver(this, "Migration:ItemAfterMigrate"); + os.removeObserver(this, "Migration:ItemError"); + os.removeObserver(this, "Migration:Ended"); + MigrationUtils.finishMigration(); + }, + + // 1 - Import Source + onImportSourcePageShow: function () + { + // Show warning message to close the selected browser when needed + function toggleCloseBrowserWarning() { + let visibility = "hidden"; + if (group.selectedItem.id != "nothing") { + let migrator = MigrationUtils.getMigrator(group.selectedItem.id); + visibility = migrator.sourceLocked ? "visible" : "hidden"; + } + document.getElementById("closeSourceBrowser").style.visibility = visibility; + } + this._wiz.canRewind = false; + + var selectedMigrator = null; + this._availableMigrators = []; + + // Figure out what source apps are are available to import from: + var group = document.getElementById("importSourceGroup"); + for (var i = 0; i < group.childNodes.length; ++i) { + var migratorKey = group.childNodes[i].id; + if (migratorKey != "nothing") { + var migrator = MigrationUtils.getMigrator(migratorKey); + if (migrator) { + // Save this as the first selectable item, if we don't already have + // one, or if it is the migrator that was passed to us. + if (!selectedMigrator || this._source == migratorKey) + selectedMigrator = group.childNodes[i]; + this._availableMigrators.push([migratorKey, migrator]); + } else { + // Hide this option + group.childNodes[i].hidden = true; + } + } + } + if (this.isInitialMigration) { + Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_BROWSER_COUNT") + .add(this._availableMigrators.length); + let defaultBrowser = MigrationUtils.getMigratorKeyForDefaultBrowser(); + // This will record 0 for unknown default browser IDs. + defaultBrowser = MigrationUtils.getSourceIdForTelemetry(defaultBrowser); + Services.telemetry.getHistogramById("FX_STARTUP_MIGRATION_EXISTING_DEFAULT_BROWSER") + .add(defaultBrowser); + } + + group.addEventListener("command", toggleCloseBrowserWarning); + + if (selectedMigrator) { + group.selectedItem = selectedMigrator; + toggleCloseBrowserWarning(); + } else { + // We didn't find a migrator, notify the user + document.getElementById("noSources").hidden = false; + + this._wiz.canAdvance = false; + + document.getElementById("importBookmarks").hidden = true; + document.getElementById("importAll").hidden = true; + } + + // Advance to the next page if the caller told us to. + if (this._migrator && this._skipImportSourcePage) { + this._wiz.advance(); + this._wiz.canRewind = false; + } + }, + + onImportSourcePageAdvanced: function () + { + var newSource = document.getElementById("importSourceGroup").selectedItem.id; + + if (newSource == "nothing") { + // Need to do telemetry here because we're closing the dialog before we get to + // do actual migration. For actual migration, this doesn't happen until after + // migration takes place. + Services.telemetry.getHistogramById("FX_MIGRATION_SOURCE_BROWSER") + .add(MigrationUtils.getSourceIdForTelemetry("nothing")); + document.documentElement.cancel(); + return false; + } + + if (!this._migrator || (newSource != this._source)) { + // Create the migrator for the selected source. + this._migrator = MigrationUtils.getMigrator(newSource); + + this._itemsFlags = kIMig.ALL; + this._selectedProfile = null; + } + this._source = newSource; + + // check for more than one source profile + var sourceProfiles = this._migrator.sourceProfiles; + if (this._skipImportSourcePage) { + this._wiz.currentPage.next = "homePageImport"; + } + else if (sourceProfiles && sourceProfiles.length > 1) { + this._wiz.currentPage.next = "selectProfile"; + } + else { + if (this._autoMigrate) + this._wiz.currentPage.next = "homePageImport"; + else + this._wiz.currentPage.next = "importItems"; + + if (sourceProfiles && sourceProfiles.length == 1) + this._selectedProfile = sourceProfiles[0]; + else + this._selectedProfile = null; + } + return undefined; + }, + + // 2 - [Profile Selection] + onSelectProfilePageShow: function () + { + // Disabling this for now, since we ask about import sources in automigration + // too and don't want to disable the back button + // if (this._autoMigrate) + // document.documentElement.getButton("back").disabled = true; + + var profiles = document.getElementById("profiles"); + while (profiles.hasChildNodes()) + profiles.removeChild(profiles.firstChild); + + // Note that this block is still reached even if the user chose 'From File' + // and we canceled the dialog. When that happens, _migrator will be null. + if (this._migrator) { + var sourceProfiles = this._migrator.sourceProfiles; + + for (let profile of sourceProfiles) { + var item = document.createElement("radio"); + item.id = profile.id; + item.setAttribute("label", profile.name); + profiles.appendChild(item); + } + } + + profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild; + }, + + onSelectProfilePageRewound: function () + { + var profiles = document.getElementById("profiles"); + this._selectedProfile = this._migrator.sourceProfiles.find( + profile => profile.id == profiles.selectedItem.id + ) || null; + }, + + onSelectProfilePageAdvanced: function () + { + var profiles = document.getElementById("profiles"); + this._selectedProfile = this._migrator.sourceProfiles.find( + profile => profile.id == profiles.selectedItem.id + ) || null; + + // If we're automigrating or just doing bookmarks don't show the item selection page + if (this._autoMigrate) + this._wiz.currentPage.next = "homePageImport"; + }, + + // 3 - ImportItems + onImportItemsPageShow: function () + { + var dataSources = document.getElementById("dataSources"); + while (dataSources.hasChildNodes()) + dataSources.removeChild(dataSources.firstChild); + + var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); + for (var i = 0; i < 16; ++i) { + var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0; + if (itemID > 0) { + var checkbox = document.createElement("checkbox"); + checkbox.id = itemID; + checkbox.setAttribute("label", + MigrationUtils.getLocalizedString(itemID + "_" + this._source)); + dataSources.appendChild(checkbox); + if (!this._itemsFlags || this._itemsFlags & itemID) + checkbox.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.localName == "checkbox" && checkbox.checked) + this._itemsFlags |= parseInt(checkbox.id); + } + }, + + onImportItemCommand: function () + { + var items = document.getElementById("dataSources"); + var checkboxes = items.getElementsByTagName("checkbox"); + + var oneChecked = false; + for (var i = 0; i < checkboxes.length; ++i) { + if (checkboxes[i].checked) { + oneChecked = true; + break; + } + } + + this._wiz.canAdvance = oneChecked; + }, + + // 4 - Home Page Selection + onHomePageMigrationPageShow: function () + { + // only want this on the first run + if (!this._autoMigrate) { + this._wiz.advance(); + return; + } + + var brandBundle = document.getElementById("brandBundle"); + var pageTitle, pageDesc, mainStr; + // These strings don't exist when not using official branding. If that's + // the case, just skip this page. + try { + pageTitle = brandBundle.getString("homePageMigrationPageTitle"); + pageDesc = brandBundle.getString("homePageMigrationDescription"); + mainStr = brandBundle.getString("homePageSingleStartMain"); + } + catch (e) { + this._wiz.advance(); + return; + } + + document.getElementById("homePageImport").setAttribute("label", pageTitle); + document.getElementById("homePageImportDesc").setAttribute("value", pageDesc); + + this._wiz._adjustWizardHeader(); + + var singleStart = document.getElementById("homePageSingleStart"); + singleStart.setAttribute("label", mainStr); + singleStart.setAttribute("value", "DEFAULT"); + + var appName = MigrationUtils.getBrowserName(this._source); + + // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places + this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); + + var oldHomePageURL = this._migrator.sourceHomePageURL; + + if (oldHomePageURL && appName) { + var oldHomePageLabel = + brandBundle.getFormattedString("homePageImport", [appName]); + var oldHomePage = document.getElementById("oldHomePage"); + oldHomePage.setAttribute("label", oldHomePageLabel); + oldHomePage.setAttribute("value", oldHomePageURL); + oldHomePage.removeAttribute("hidden"); + } + 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 { + var radioGroup = document.getElementById("homePageRadiogroup"); + + this._newHomePage = radioGroup.selectedItem.value; + } catch (ex) {} + }, + + // 5 - Migrating + onMigratingPageShow: function () + { + this._wiz.getButton("cancel").disabled = true; + this._wiz.canRewind = false; + this._wiz.canAdvance = false; + + // When automigrating, show all of the data that can be received from this source. + if (this._autoMigrate) + this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); + + this._listItems("migratingItems"); + setTimeout(() => this.onMigratingMigrate(), 0); + }, + + onMigratingMigrate: function () + { + this._migrator.migrate(this._itemsFlags, this._autoMigrate, this._selectedProfile); + + Services.telemetry.getHistogramById("FX_MIGRATION_SOURCE_BROWSER") + .add(MigrationUtils.getSourceIdForTelemetry(this._source)); + if (!this._autoMigrate) { + let hist = Services.telemetry.getKeyedHistogramById("FX_MIGRATION_USAGE"); + let exp = 0; + let items = this._itemsFlags; + while (items) { + if (items & 1) { + hist.add(this._source, exp); + } + items = items >> 1; + exp++; + } + } + }, + + _listItems: function (aID) + { + var items = document.getElementById(aID); + while (items.hasChildNodes()) + items.removeChild(items.firstChild); + + var itemID; + for (var i = 0; i < 16; ++i) { + itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0; + if (itemID > 0) { + var label = document.createElement("label"); + label.id = itemID + "_migrated"; + try { + label.setAttribute("value", + MigrationUtils.getLocalizedString(itemID + "_" + this._source)); + 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. + break; + } + } + } + }, + + observe: function (aSubject, aTopic, aData) + { + var label; + switch (aTopic) { + case "Migration:Started": + break; + case "Migration:ItemBeforeMigrate": + label = document.getElementById(aData + "_migrated"); + if (label) + label.setAttribute("style", "font-weight: bold"); + break; + case "Migration:ItemAfterMigrate": + label = document.getElementById(aData + "_migrated"); + if (label) + label.removeAttribute("style"); + break; + case "Migration:Ended": + if (this.isInitialMigration) { + // Ensure errors in reporting data recency do not affect the rest of the migration. + try { + this.reportDataRecencyTelemetry(); + } catch (ex) { + Cu.reportError(ex); + } + } + if (this._autoMigrate) { + let hasImportedHomepage = !!(this._newHomePage && this._newHomePage != "DEFAULT"); + Services.telemetry.getKeyedHistogramById("FX_MIGRATION_IMPORTED_HOMEPAGE") + .add(this._source, hasImportedHomepage); + if (this._newHomePage) { + try { + // set homepage properly + var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefService); + var prefBranch = prefSvc.getBranch(null); + + if (this._newHomePage == "DEFAULT") { + prefBranch.clearUserPref("browser.startup.homepage"); + } + else { + var str = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(Components.interfaces.nsISupportsString); + str.data = this._newHomePage; + prefBranch.setComplexValue("browser.startup.homepage", + Components.interfaces.nsISupportsString, + str); + } + + var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties); + var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile); + prefFile.append("prefs.js"); + prefSvc.savePrefFile(prefFile); + } catch (ex) { + dump(ex); + } + } + + // We're done now. + this._wiz.canAdvance = true; + this._wiz.advance(); + + setTimeout(close, 5000); + } + else { + this._wiz.canAdvance = true; + var nextButton = this._wiz.getButton("next"); + nextButton.click(); + } + break; + case "Migration:ItemError": + let type = "undefined"; + let numericType = parseInt(aData); + switch (numericType) { + case Ci.nsIBrowserProfileMigrator.SETTINGS: + type = "settings"; + break; + case Ci.nsIBrowserProfileMigrator.COOKIES: + type = "cookies"; + break; + case Ci.nsIBrowserProfileMigrator.HISTORY: + type = "history"; + break; + case Ci.nsIBrowserProfileMigrator.FORMDATA: + type = "form data"; + break; + case Ci.nsIBrowserProfileMigrator.PASSWORDS: + type = "passwords"; + break; + case Ci.nsIBrowserProfileMigrator.BOOKMARKS: + type = "bookmarks"; + break; + case Ci.nsIBrowserProfileMigrator.OTHERDATA: + type = "misc. data"; + break; + } + Cc["@mozilla.org/consoleservice;1"] + .getService(Ci.nsIConsoleService) + .logStringMessage("some " + type + " did not successfully migrate."); + Services.telemetry.getKeyedHistogramById("FX_MIGRATION_ERRORS") + .add(this._source, Math.log2(numericType)); + break; + } + }, + + onDonePageShow: function () + { + this._wiz.getButton("cancel").disabled = true; + this._wiz.canRewind = false; + this._listItems("doneItems"); + }, + + reportDataRecencyTelemetry() { + let histogram = Services.telemetry.getKeyedHistogramById("FX_STARTUP_MIGRATION_DATA_RECENCY"); + let lastUsedPromises = []; + for (let [key, migrator] of this._availableMigrators) { + // No block-scoped let in for...of loop conditions, so get the source: + let localKey = key; + lastUsedPromises.push(migrator.getLastUsedDate().then(date => { + const ONE_YEAR = 24 * 365; + let diffInHours = Math.round((Date.now() - date) / (60 * 60 * 1000)); + if (diffInHours > ONE_YEAR) { + diffInHours = ONE_YEAR; + } + histogram.add(localKey, diffInHours); + return [localKey, diffInHours]; + })); + } + Promise.all(lastUsedPromises).then(migratorUsedTimeDiff => { + // Sort low to high. + migratorUsedTimeDiff.sort(([keyA, diffA], [keyB, diffB]) => diffA - diffB); /* eslint no-unused-vars: off */ + let usedMostRecentBrowser = migratorUsedTimeDiff.length && this._source == migratorUsedTimeDiff[0][0]; + let usedRecentBrowser = + Services.telemetry.getKeyedHistogramById("FX_STARTUP_MIGRATION_USED_RECENT_BROWSER"); + usedRecentBrowser.add(this._source, usedMostRecentBrowser); + }); + }, +}; diff --git a/browser/components/migration/content/migration.xul b/browser/components/migration/content/migration.xul new file mode 100644 index 000000000..e85091002 --- /dev/null +++ b/browser/components/migration/content/migration.xul @@ -0,0 +1,109 @@ +<?xml version="1.0"?> +# 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/. + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE dialog SYSTEM "chrome://browser/locale/migration/migration.dtd" > + +<wizard id="migrationWizard" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + windowtype="Browser:MigrationWizard" + title="&migrationWizard.title;" + onload="MigrationWizard.init()" + onunload="MigrationWizard.uninit()" + style="width: 40em;" + buttons="accept,cancel" + branded="true"> + + <script type="application/javascript" src="chrome://browser/content/migration/migration.js"/> + + <stringbundle id="brandBundle" src="chrome://branding/locale/brand.properties"/> + + <wizardpage id="importSource" pageid="importSource" next="selectProfile" + label="&importSource.title;" + onpageadvanced="return MigrationWizard.onImportSourcePageAdvanced();"> +#ifdef XP_WIN + <description id="importAll" control="importSourceGroup">&importFrom.label;</description> +#else + <description id="importAll" control="importSourceGroup">&importFromUnix.label;</description> +#endif + <description id="importBookmarks" control="importSourceGroup" hidden="true">&importFromBookmarks.label;</description> + + <radiogroup id="importSourceGroup" align="start"> +# NB: if you add items to this list, please also assign them a unique migrator ID in MigrationUtils.jsm + <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/> +#ifdef XP_WIN + <radio id="edge" label="&importFromEdge.label;" accesskey="&importFromEdge.accesskey;"/> + <radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/> + <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> + <radio id="chromium" label="&importFromChromium.label;" accesskey="&importFromChromium.accesskey;"/> + <radio id="canary" label="&importFromCanary.label;" accesskey="&importFromCanary.accesskey;"/> + <radio id="360se" label="&importFrom360se.label;" accesskey="&importFrom360se.accesskey;"/> +#elifdef XP_MACOSX + <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> + <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> + <radio id="chromium" label="&importFromChromium.label;" accesskey="&importFromChromium.accesskey;"/> + <radio id="canary" label="&importFromCanary.label;" accesskey="&importFromCanary.accesskey;"/> +#elifdef XP_UNIX + <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> + <radio id="chromium" label="&importFromChromium.label;" accesskey="&importFromChromium.accesskey;"/> +#endif + <radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/> + </radiogroup> + <label id="noSources" hidden="true">&noMigrationSources.label;</label> + <spacer flex="1"/> + <description class="header" id="closeSourceBrowser" style="visibility:hidden">&closeSourceBrowser.label;</description> + </wizardpage> + + <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;" + next="importItems" + onpageshow="return MigrationWizard.onSelectProfilePageShow();" + onpagerewound="return MigrationWizard.onSelectProfilePageRewound();" + onpageadvanced="return MigrationWizard.onSelectProfilePageAdvanced();"> + <description control="profiles">&selectProfile.label;</description> + + <radiogroup id="profiles" align="left"/> + </wizardpage> + + <wizardpage id="importItems" pageid="importItems" label="&importItems.title;" + next="homePageImport" + onpageshow="return MigrationWizard.onImportItemsPageShow();" + onpagerewound="return MigrationWizard.onImportItemsPageRewound();" + onpageadvanced="return MigrationWizard.onImportItemsPageAdvanced();" + oncommand="MigrationWizard.onImportItemCommand();"> + <description control="dataSources">&importItems.label;</description> + + <vbox id="dataSources" style="overflow: auto; -moz-appearance: listbox" align="left" flex="1" role="group"/> + </wizardpage> + + <wizardpage id="homePageImport" pageid="homePageImport" + next="migrating" + onpageshow="return MigrationWizard.onHomePageMigrationPageShow();" + onpageadvanced="return MigrationWizard.onHomePageMigrationPageAdvanced();"> + + <description id="homePageImportDesc" control="homePageRadioGroup"/> + <radiogroup id="homePageRadiogroup"> + <radio id="homePageSingleStart" selected="true" /> + <radio id="oldHomePage" hidden="true" /> + </radiogroup> + </wizardpage> + + <wizardpage id="migrating" pageid="migrating" label="&migrating.title;" + next="done" + onpageshow="MigrationWizard.onMigratingPageShow();"> + <description control="migratingItems">&migrating.label;</description> + + <vbox id="migratingItems" style="overflow: auto;" align="left" role="group"/> + </wizardpage> + + <wizardpage id="done" pageid="done" label="&done.title;" + onpageshow="MigrationWizard.onDonePageShow();"> + <description control="doneItems">&done.label;</description> + + <vbox id="doneItems" style="overflow: auto;" align="left" role="group"/> + </wizardpage> + +</wizard> + |