mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 737381 - The Firefox Migrator should use the new migration system. r=mak
This commit is contained in:
parent
904a38aeb8
commit
c2761a5f3b
@ -215,16 +215,15 @@ var MigrationWizard = {
|
||||
var dataSources = document.getElementById("dataSources");
|
||||
while (dataSources.hasChildNodes())
|
||||
dataSources.removeChild(dataSources.firstChild);
|
||||
|
||||
var bundle = document.getElementById("bundle");
|
||||
|
||||
|
||||
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", bundle.getString(itemID + "_" + this._source));
|
||||
checkbox.setAttribute("label",
|
||||
MigrationUtils.getLocalizedString(itemID + "_" + this._source));
|
||||
dataSources.appendChild(checkbox);
|
||||
if (!this._itemsFlags || this._itemsFlags & itemID)
|
||||
checkbox.checked = true;
|
||||
@ -274,13 +273,13 @@ var MigrationWizard = {
|
||||
return;
|
||||
}
|
||||
|
||||
var bundle = document.getElementById("brandBundle");
|
||||
var brandBundle = document.getElementById("brandBundle");
|
||||
// These strings don't exist when not using official branding. If that's
|
||||
// the case, just skip this page.
|
||||
try {
|
||||
var pageTitle = bundle.getString("homePageMigrationPageTitle");
|
||||
var pageDesc = bundle.getString("homePageMigrationDescription");
|
||||
var mainStr = bundle.getString("homePageSingleStartMain");
|
||||
var pageTitle = brandBundle.getString("homePageMigrationPageTitle");
|
||||
var pageDesc = brandBundle.getString("homePageMigrationDescription");
|
||||
var mainStr = brandBundle.getString("homePageSingleStartMain");
|
||||
}
|
||||
catch (e) {
|
||||
this._wiz.advance();
|
||||
@ -318,10 +317,9 @@ var MigrationWizard = {
|
||||
var oldHomePageURL = this._migrator.sourceHomePageURL;
|
||||
|
||||
if (oldHomePageURL && source) {
|
||||
var bundle2 = document.getElementById("bundle");
|
||||
var appName = bundle2.getString(source);
|
||||
var oldHomePageLabel = bundle.getFormattedString("homePageImport",
|
||||
[appName]);
|
||||
var appName = MigrationUtils.getLocalizedString(source);
|
||||
var oldHomePageLabel =
|
||||
brandBundle.getFormattedString("homePageImport", [appName]);
|
||||
var oldHomePage = document.getElementById("oldHomePage");
|
||||
oldHomePage.setAttribute("label", oldHomePageLabel);
|
||||
oldHomePage.setAttribute("value", oldHomePageURL);
|
||||
@ -372,8 +370,7 @@ var MigrationWizard = {
|
||||
var items = document.getElementById(aID);
|
||||
while (items.hasChildNodes())
|
||||
items.removeChild(items.firstChild);
|
||||
|
||||
var bundle = document.getElementById("bundle");
|
||||
|
||||
var brandBundle = document.getElementById("brandBundle");
|
||||
var itemID;
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
@ -382,7 +379,8 @@ var MigrationWizard = {
|
||||
var label = document.createElement("label");
|
||||
label.id = itemID + "_migrated";
|
||||
try {
|
||||
label.setAttribute("value", bundle.getString(itemID + "_" + this._source));
|
||||
label.setAttribute("value",
|
||||
MigrationUtils.getLocalizedString(itemID + "_" + this._source));
|
||||
items.appendChild(label);
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -51,7 +51,6 @@
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/migration/migration.js"/>
|
||||
|
||||
<stringbundle id="bundle" src="chrome://browser/locale/migration/migration.properties"/>
|
||||
<stringbundle id="brandBundle" src="chrome://branding/locale/brand.properties"/>
|
||||
|
||||
<wizardpage id="importSource" pageid="importSource" next="selectProfile"
|
||||
|
@ -20,7 +20,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/MigrationUtils.jsm");
|
||||
Cu.import("resource:///modules/MigrationUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
@ -176,7 +176,7 @@ function GetBookmarksResource(aProfileFolder) {
|
||||
return null;
|
||||
|
||||
return {
|
||||
type: Ci.nsIBrowserProfileMigrator.BOOKMARKS,
|
||||
type: MigrationUtils.resourceTypes.BOOKMARKS,
|
||||
|
||||
migrate: function(aCallback) {
|
||||
NetUtil.asyncFetch(bookmarksFile, MigrationUtils.wrapMigrateFunction(
|
||||
@ -227,7 +227,7 @@ function GetHistoryResource(aProfileFolder) {
|
||||
return null;
|
||||
|
||||
return {
|
||||
type: Ci.nsIBrowserProfileMigrator.HISTORY,
|
||||
type: MigrationUtils.resourceTypes.HISTORY,
|
||||
|
||||
migrate: function(aCallback) {
|
||||
let dbConn = Services.storage.openUnsharedDatabase(historyFile);
|
||||
@ -288,7 +288,7 @@ function GetCookiesResource(aProfileFolder) {
|
||||
return null;
|
||||
|
||||
return {
|
||||
type: Ci.nsIBrowserProfileMigrator.COOKIES,
|
||||
type: MigrationUtils.resourceTypes.COOKIES,
|
||||
|
||||
migrate: function(aCallback) {
|
||||
let dbConn = Services.storage.openUnsharedDatabase(cookiesFile);
|
||||
|
@ -4,452 +4,91 @@
|
||||
* version 2.0 (the "License"). You can obtain a copy of the License at
|
||||
* http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* Migrates from a Firefox profile in a lossy manner in order to clean up a user's profile. Data
|
||||
* is only migrated where the benefits outweigh the potential problems caused by importing
|
||||
* undesired/invalid configurations from the source profile.
|
||||
* Migrates from a Firefox profile in a lossy manner in order to clean up a
|
||||
* user's profile. Data is only migrated where the benefits outweigh the
|
||||
* potential problems caused by importing undesired/invalid configurations
|
||||
* from the source profile.
|
||||
*/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
const MIGRATOR = Ci.nsIBrowserProfileMigrator;
|
||||
|
||||
const LOCAL_FILE_CID = "@mozilla.org/file/local;1";
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
Components.utils.import("resource:///modules/MigrationUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
function FirefoxProfileMigrator()
|
||||
{
|
||||
// profD is not available when the migrator is run during startup so use ProfDS.
|
||||
this._paths.currentProfile = FileUtils.getDir("ProfDS", []);
|
||||
function FirefoxProfileMigrator() { }
|
||||
|
||||
FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype);
|
||||
|
||||
FirefoxProfileMigrator.prototype.getResources = function() {
|
||||
// Only allow migrating from the default (selected) profile since this will
|
||||
// be the only one returned by the toolkit profile service after bug 214675.
|
||||
let sourceProfile =
|
||||
Components.classes["@mozilla.org/toolkit/profile-service;1"]
|
||||
.getService(Components.interfaces.nsIToolkitProfileService)
|
||||
.selectedProfile;
|
||||
if (!sourceProfile)
|
||||
return null;
|
||||
|
||||
let sourceProfileDir = sourceProfile.rootDir;
|
||||
if (!sourceProfileDir || !sourceProfileDir.exists() ||
|
||||
!sourceProfileDir.isReadable())
|
||||
return null;
|
||||
|
||||
// Being a startup-only migrator, we can rely on
|
||||
// MigrationUtils.profileStartup being set.
|
||||
let currentProfileDir = MigrationUtils.profileStartup.directory;
|
||||
|
||||
// Surely data cannot be imported from the current profile.
|
||||
if (sourceProfileDir.equals(currentProfileDir))
|
||||
return null;
|
||||
|
||||
let getFileResource = function(aMigrationType, aFileNames) {
|
||||
let files = [];
|
||||
for (let fileName of aFileNames) {
|
||||
let file = sourceProfileDir.clone();
|
||||
file.append(fileName);
|
||||
|
||||
// File resources are monolithic. We don't make partial copies since
|
||||
// they are not expected to work alone.
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
files.push(file);
|
||||
}
|
||||
return {
|
||||
type: aMigrationType,
|
||||
migrate: function(aCallback) {
|
||||
for (let file of files) {
|
||||
file.copyTo(currentProfileDir, "");
|
||||
}
|
||||
aCallback(true);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let types = MigrationUtils.resourceTypes;
|
||||
let places = getFileResource(types.HISTORY, ["places.sqlite"]);
|
||||
let cookies = getFileResource(types.COOKIES, ["cookies.sqlite"]);
|
||||
let passwords = getFileResource(types.PASSWORDS,
|
||||
["signons.sqlite", "key3.db"]);
|
||||
let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]);
|
||||
let bookmarksBackups = getFileResource(types.OTHERDATA,
|
||||
[PlacesUtils.backups.profileRelativeFolderPath]);
|
||||
|
||||
return [r for each (r in [places, cookies, passwords, formData,
|
||||
bookmarksBackups]) if (r)];
|
||||
}
|
||||
|
||||
FirefoxProfileMigrator.prototype = {
|
||||
_paths: {
|
||||
bookmarks: null,
|
||||
cookies: null,
|
||||
currentProfile: null, // The currently running (destination) profile.
|
||||
encryptionKey: null,
|
||||
formData: null,
|
||||
history: null,
|
||||
passwords: null,
|
||||
},
|
||||
|
||||
_homepageURL : null,
|
||||
_replaceBookmarks : false,
|
||||
_sourceProfile: null,
|
||||
_profilesCache: null,
|
||||
|
||||
/**
|
||||
* Notify to observers to start migration
|
||||
*
|
||||
* @param aType
|
||||
* notification type such as MIGRATOR.BOOKMARKS
|
||||
*/
|
||||
_notifyStart : function Firefox_notifyStart(aType)
|
||||
{
|
||||
Services.obs.notifyObservers(null, "Migration:ItemBeforeMigrate", aType);
|
||||
this._pendingCount++;
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify observers that a migration error occured with an item
|
||||
*
|
||||
* @param aType
|
||||
* notification type such as MIGRATOR.BOOKMARKS
|
||||
*/
|
||||
_notifyError : function Firefox_notifyError(aType)
|
||||
{
|
||||
Services.obs.notifyObservers(null, "Migration:ItemError", aType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify to observers to finish migration for item
|
||||
* If all items are finished, it sends migration end notification.
|
||||
*
|
||||
* @param aType
|
||||
* notification type such as MIGRATOR.BOOKMARKS
|
||||
*/
|
||||
_notifyCompleted : function Firefox_notifyIfCompleted(aType)
|
||||
{
|
||||
Services.obs.notifyObservers(null, "Migration:ItemAfterMigrate", aType);
|
||||
if (--this._pendingCount == 0) {
|
||||
// All items are migrated, so we have to send end notification.
|
||||
Services.obs.notifyObservers(null, "Migration:Ended", null);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The directory used for bookmark backups
|
||||
* @return directory of the bookmark backups
|
||||
*/
|
||||
get _bookmarks_backup_folder()
|
||||
{
|
||||
let bookmarksBackupRelativePath = PlacesUtils.backups.profileRelativeFolderPath;
|
||||
let bookmarksBackupDir = this._sourceProfile.clone().QueryInterface(Ci.nsILocalFile);
|
||||
bookmarksBackupDir.appendRelativePath(bookmarksBackupRelativePath);
|
||||
return bookmarksBackupDir;
|
||||
},
|
||||
|
||||
/**
|
||||
* Migrating bookmark items
|
||||
*/
|
||||
_migrateBookmarks : function Firefox_migrateBookmarks()
|
||||
{
|
||||
this._notifyStart(MIGRATOR.BOOKMARKS);
|
||||
|
||||
try {
|
||||
let srcBackupsDir = this._bookmarks_backup_folder;
|
||||
let backupFolder = this._paths.currentProfile.clone();
|
||||
backupFolder.append(srcBackupsDir.leafName);
|
||||
if (!backupFolder.exists())
|
||||
srcBackupsDir.copyTo(this._paths.currentProfile, null);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
// Don't notify about backup migration errors since actual bookmarks are
|
||||
// migrated with history.
|
||||
} finally {
|
||||
this._notifyCompleted(MIGRATOR.BOOKMARKS);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Migrating history
|
||||
*/
|
||||
_migrateHistory : function Firefox_migrateHistory()
|
||||
{
|
||||
this._notifyStart(MIGRATOR.HISTORY);
|
||||
|
||||
try {
|
||||
// access sqlite3 database of history
|
||||
let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this._paths.history);
|
||||
file.copyTo(this._paths.currentProfile, null);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
this._notifyError(MIGRATOR.HISTORY);
|
||||
} finally {
|
||||
this._notifyCompleted(MIGRATOR.HISTORY);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Migrating cookies
|
||||
*
|
||||
* @note Cookie permissions are not migrated since they may be inadvertently set leading to
|
||||
* website login problems.
|
||||
*/
|
||||
_migrateCookies : function Firefox_migrateCookies()
|
||||
{
|
||||
this._notifyStart(MIGRATOR.COOKIES);
|
||||
|
||||
try {
|
||||
// Access sqlite3 database of cookies
|
||||
let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this._paths.cookies);
|
||||
file.copyTo(this._paths.currentProfile, null);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
this._notifyError(MIGRATOR.COOKIES);
|
||||
} finally {
|
||||
this._notifyCompleted(MIGRATOR.COOKIES);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Migrating passwords
|
||||
*/
|
||||
_migratePasswords : function Firefox_migratePasswords()
|
||||
{
|
||||
this._notifyStart(MIGRATOR.PASSWORDS);
|
||||
|
||||
try {
|
||||
// Access sqlite3 database of passwords
|
||||
let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this._paths.passwords);
|
||||
file.copyTo(this._paths.currentProfile, null);
|
||||
|
||||
let encryptionKey = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
encryptionKey.initWithPath(this._paths.encryptionKey);
|
||||
encryptionKey.copyTo(this._paths.currentProfile, null);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
this._notifyError(MIGRATOR.PASSWORDS);
|
||||
} finally {
|
||||
this._notifyCompleted(MIGRATOR.PASSWORDS);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Migrating form history (satchel)
|
||||
*/
|
||||
_migrateFormData : function Firefox_migrateFormData()
|
||||
{
|
||||
this._notifyStart(MIGRATOR.FORMDATA);
|
||||
|
||||
try {
|
||||
// Access sqlite3 database of form history.
|
||||
let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(this._paths.formData);
|
||||
file.copyTo(this._paths.currentProfile, null);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
this._notifyError(MIGRATOR.FORMDATA);
|
||||
} finally {
|
||||
this._notifyCompleted(MIGRATOR.FORMDATA);
|
||||
}
|
||||
},
|
||||
Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", {
|
||||
get: function() true
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* nsIBrowserProfileMigrator interface implementation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Let's migrate all items
|
||||
*
|
||||
* @param aItems
|
||||
* list of data items to migrate.
|
||||
* @param aStartup
|
||||
* non-null if called during startup.
|
||||
* @param aProfile
|
||||
* profile directory path to migrate from
|
||||
*/
|
||||
migrate : function Firefox_migrate(aItems, aStartup, aProfile)
|
||||
{
|
||||
if (aStartup) {
|
||||
this._replaceBookmarks = true;
|
||||
}
|
||||
|
||||
// Ensure that aProfile is not the current profile.
|
||||
if (this._paths.currentProfile.path === this._sourceProfile.path) {
|
||||
throw new Exception("Source and destination profiles are the same");
|
||||
return;
|
||||
}
|
||||
|
||||
Services.obs.notifyObservers(null, "Migration:Started", null);
|
||||
|
||||
// Reset pending count. If this count becomes 0, "Migration:Ended"
|
||||
// notification is sent
|
||||
this._pendingCount = 1;
|
||||
|
||||
if (aItems & MIGRATOR.HISTORY)
|
||||
this._migrateHistory();
|
||||
|
||||
if (aItems & MIGRATOR.COOKIES)
|
||||
this._migrateCookies();
|
||||
|
||||
if (aItems & MIGRATOR.BOOKMARKS)
|
||||
this._migrateBookmarks();
|
||||
|
||||
if (aItems & MIGRATOR.PASSWORDS)
|
||||
this._migratePasswords();
|
||||
|
||||
// The password manager encryption key must be copied before startup.
|
||||
if (aStartup) {
|
||||
aStartup.doStartup();
|
||||
}
|
||||
|
||||
if (aItems & MIGRATOR.FORMDATA)
|
||||
this._migrateFormData();
|
||||
|
||||
if (--this._pendingCount == 0) {
|
||||
// When async imports are immediately completed unfortunately,
|
||||
// this will be called.
|
||||
// Usually, this notification is sent by _notifyCompleted()
|
||||
Services.obs.notifyObservers(null, "Migration:Ended", null);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* return supported migration types
|
||||
*
|
||||
* @param aProfile
|
||||
* the profile path to migrate from
|
||||
* @param aDoingStartup
|
||||
* non-null if called during startup.
|
||||
* @return supported migration types
|
||||
*
|
||||
* @todo Bug 715315 - make sure source databases are not in-use
|
||||
*/
|
||||
getMigrateData: function Firefox_getMigrateData(aProfile, aDoingStartup)
|
||||
{
|
||||
this._sourceProfile = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
this._sourceProfile.initWithPath(aProfile);
|
||||
|
||||
let result = 0;
|
||||
|
||||
// Ensure that aProfile is not the current profile.
|
||||
if (this._paths.currentProfile.path === this._sourceProfile.path)
|
||||
return result;
|
||||
|
||||
if (!this._sourceProfile.exists() || !this._sourceProfile.isReadable()) {
|
||||
Cu.reportError("source profile directory doesn't exist or is not readable");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Migration initiated from the UI is not supported.
|
||||
if (!aDoingStartup)
|
||||
return result;
|
||||
|
||||
// Bookmark backups in JSON format
|
||||
try {
|
||||
let file = this._bookmarks_backup_folder;
|
||||
if (file.exists()) {
|
||||
this._paths.bookmarks = file.path;
|
||||
result += MIGRATOR.BOOKMARKS;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
// Bookmarks, history and favicons
|
||||
try {
|
||||
let file = this._sourceProfile.clone();
|
||||
file.append("places.sqlite");
|
||||
if (file.exists()) {
|
||||
this._paths.history = file.path;
|
||||
result += MIGRATOR.HISTORY;
|
||||
result |= MIGRATOR.BOOKMARKS;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
// Cookies
|
||||
try {
|
||||
let file = this._sourceProfile.clone();
|
||||
file.append("cookies.sqlite");
|
||||
if (file.exists()) {
|
||||
this._paths.cookies = file.path;
|
||||
result += MIGRATOR.COOKIES;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
// Passwords & encryption key
|
||||
try {
|
||||
let passwords = this._sourceProfile.clone();
|
||||
passwords.append("signons.sqlite");
|
||||
let encryptionKey = this._sourceProfile.clone();
|
||||
encryptionKey.append("key3.db");
|
||||
if (passwords.exists() && encryptionKey.exists()) {
|
||||
this._paths.passwords = passwords.path;
|
||||
this._paths.encryptionKey = encryptionKey.path;
|
||||
result += MIGRATOR.PASSWORDS;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
// Form data
|
||||
try {
|
||||
let file = this._sourceProfile.clone();
|
||||
file.append("formhistory.sqlite");
|
||||
if (file.exists()) {
|
||||
this._paths.formData = file.path;
|
||||
result += MIGRATOR.FORMDATA;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether we support migration of Firefox
|
||||
*
|
||||
* @return true if supported
|
||||
*/
|
||||
get sourceExists()
|
||||
{
|
||||
let userData = Services.dirsvc.get("DefProfRt", Ci.nsIFile).path;
|
||||
let result = 0;
|
||||
try {
|
||||
let userDataDir = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
|
||||
userDataDir.initWithPath(userData);
|
||||
if (!userDataDir.exists() || !userDataDir.isReadable())
|
||||
return false;
|
||||
|
||||
let profiles = this.sourceProfiles;
|
||||
if (profiles.length < 1)
|
||||
return false;
|
||||
// Check that we can get data from at least one profile since profile selection has not
|
||||
// happened yet.
|
||||
for (let i = 0; i < profiles.length; i++) {
|
||||
result = this.getMigrateData(profiles.queryElementAt(i, Ci.nsISupportsString), true);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
return result > 0;
|
||||
},
|
||||
|
||||
get sourceHasMultipleProfiles()
|
||||
{
|
||||
return this.sourceProfiles.length > 1;
|
||||
},
|
||||
|
||||
get sourceProfiles()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!this._profilesCache)
|
||||
{
|
||||
this._profilesCache = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
|
||||
.getService(Ci.nsIToolkitProfileService);
|
||||
// Only allow migrating from the default (selected) profile since this will be the only one
|
||||
// returned by the toolkit profile service after bug 214675 has landed.
|
||||
var profile = profileService.selectedProfile;
|
||||
if (profile.rootDir.path === this._paths.currentProfile.path)
|
||||
return null;
|
||||
|
||||
let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
str.data = profile.rootDir.path;
|
||||
this._profilesCache.appendElement(str, false);
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError("Error detecting Firefox profiles: " + e);
|
||||
}
|
||||
return this._profilesCache;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return home page URL
|
||||
*
|
||||
* @return home page URL
|
||||
*
|
||||
* @todo Bug 715348 will migrate preferences such as the homepage
|
||||
*/
|
||||
get sourceHomePageURL()
|
||||
{
|
||||
try {
|
||||
if (this._homepageURL)
|
||||
return this._homepageURL;
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIBrowserProfileMigrator
|
||||
]),
|
||||
|
||||
classDescription: "Firefox Profile Migrator",
|
||||
contractID: "@mozilla.org/profile/migrator;1?app=browser&type=firefox",
|
||||
classID: Components.ID("{91185366-ba97-4438-acba-48deaca63386}")
|
||||
};
|
||||
FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator";
|
||||
FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox";
|
||||
FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}");
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]);
|
||||
|
@ -20,6 +20,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
|
||||
let gMigrators = null;
|
||||
let gProfileStartup = null;
|
||||
let gMigrationBundle = null;
|
||||
|
||||
function getMigrationBundle() {
|
||||
if (!gMigrationBundle) {
|
||||
gMigrationBundle = Services.strings.createBundle(
|
||||
"chrome://browser/locale/migration/migration.properties");
|
||||
}
|
||||
return gMigrationBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared prototype for migrators, implementing nsIBrowserProfileMigrator.
|
||||
@ -224,9 +233,22 @@ let MigratorPrototype = {
|
||||
// For a single-profile source, check if any data is available.
|
||||
// For multiple-profiles source, make sure that at least one
|
||||
// profile is available.
|
||||
let profiles = this.sourceProfiles;
|
||||
return (!profiles && this.getResources("")) ||
|
||||
(profiles && profiles.length > 0);
|
||||
let exists = false;
|
||||
try {
|
||||
let profiles = this.sourceProfiles;
|
||||
if (!profiles) {
|
||||
let resources = this._getMaybeCachedResources("");
|
||||
if (resources && resources.length > 0)
|
||||
exists = true;
|
||||
}
|
||||
else {
|
||||
exists = profiles.length > 0;
|
||||
}
|
||||
}
|
||||
catch(ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
return exists;
|
||||
},
|
||||
|
||||
/*** PRIVATE STUFF - DO NOT OVERRIDE ***/
|
||||
@ -243,6 +265,16 @@ let MigratorPrototype = {
|
||||
};
|
||||
|
||||
let MigrationUtils = Object.freeze({
|
||||
resourceTypes: {
|
||||
SETTINGS: Ci.nsIBrowserProfileMigrator.SETTINGS,
|
||||
COOKIES: Ci.nsIBrowserProfileMigrator.COOKIES,
|
||||
HISTORY: Ci.nsIBrowserProfileMigrator.HISTORY,
|
||||
FORMDATA: Ci.nsIBrowserProfileMigrator.FORMDATA,
|
||||
PASSWORDS: Ci.nsIBrowserProfileMigrator.PASSWORDS,
|
||||
BOOKMARKS: Ci.nsIBrowserProfileMigrator.BOOKMARKS,
|
||||
OTHERDATA: Ci.nsIBrowserProfileMigrator.OTHERDATA
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for implementing simple asynchronous cases of migration resources'
|
||||
* |migrate(aCallback)| (see MigratorPrototype). If your |migrate| method
|
||||
@ -295,6 +327,34 @@ let MigrationUtils = Object.freeze({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a string from the migration bundle. Shorthand for
|
||||
* nsIStringBundle.GetStringFromName, if aReplacements isn't passed, or for
|
||||
* nsIStringBundle.formatStringFromName if it is.
|
||||
*
|
||||
* This method also takes care of "bumped" keys (See bug 737381 comment 8 for
|
||||
* details).
|
||||
*
|
||||
* @param aKey
|
||||
* The key of the string to retrieve.
|
||||
* @param aReplacemts
|
||||
* [optioanl] Array of replacements to run on the retrieved string.
|
||||
* @return the retrieved string.
|
||||
*
|
||||
* @see nsIStringBundle
|
||||
*/
|
||||
getLocalizedString: function MU_getLocalizedString(aKey, aReplacements) {
|
||||
const OVERRIDES = {
|
||||
"4_firefox": "4_firefox_history_and_bookmarks"
|
||||
};
|
||||
aKey = OVERRIDES[aKey] || aKey;
|
||||
|
||||
if (aReplacements === undefined)
|
||||
return getMigrationBundle().GetStringFromName(aKey);
|
||||
return getMigrationBundle().formatStringFromName(
|
||||
aKey, aReplacements, aReplacements.length);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for creating a folder for imported bookmarks from a particular
|
||||
* migration source. The folder is created at the end of the given folder.
|
||||
@ -311,13 +371,10 @@ let MigrationUtils = Object.freeze({
|
||||
*/
|
||||
createImportedBookmarksFolder:
|
||||
function MU_createImportedBookmarksFolder(aSourceNameStr, aParentId) {
|
||||
let bundle = Services.strings.createBundle(
|
||||
"chrome://browser/locale/migration/migration.properties");
|
||||
let sourceName = bundle.GetStringFromName("sourceName" + aSourceNameStr);
|
||||
let folderName = bundle.formatStringFromName("importedBookmarksFolder",
|
||||
[sourceName], 1);
|
||||
let source = this.getLocalizedString("sourceName" + aSourceNameStr);
|
||||
let label = this.getLocalizedString("importedBookmarksFolder", [source]);
|
||||
return PlacesUtils.bookmarks.createFolder(
|
||||
aParentId, folderName, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
aParentId, label, PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
},
|
||||
|
||||
get _migrators() gMigrators ? gMigrators : gMigrators = new Dict(),
|
||||
@ -455,5 +512,6 @@ let MigrationUtils = Object.freeze({
|
||||
finishMigration: function MU_finishMigration() {
|
||||
gMigrators = null;
|
||||
gProfileStartup = null;
|
||||
gMigrationBundle = null;
|
||||
}
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ importedSafariBookmarks=From Safari
|
||||
4_ie=Browsing History
|
||||
4_safari=Browsing History
|
||||
4_chrome=Browsing History
|
||||
4_firefox=Browsing History
|
||||
4_firefox_history_and_bookmarks=Browsing History and Bookmarks
|
||||
|
||||
8_ie=Saved Form History
|
||||
8_safari=Saved Form History
|
||||
@ -46,4 +46,4 @@ importedSafariBookmarks=From Safari
|
||||
64_ie=Other Data
|
||||
64_safari=Other Data
|
||||
64_chrome=Other Data
|
||||
|
||||
64_firefox=Bookmarks Backups
|
||||
|
Loading…
Reference in New Issue
Block a user