mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out changeset d2693e86769d (bug 482911) due to crashes on Mac xpcshell tests. r=orange.
This commit is contained in:
parent
4dbc4331f0
commit
98c2fd10a7
@ -163,3 +163,20 @@ GetProfilePath(nsIProfileStartup* aStartup, nsCOMPtr<nsIFile>& aProfileDir)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
ImportDefaultBookmarks()
|
||||
{
|
||||
nsCOMPtr<nsIPlacesImportExportService> importer =
|
||||
do_GetService(NS_PLACESIMPORTEXPORTSERVICE_CONTRACTID);
|
||||
NS_ENSURE_STATE(importer);
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService = mozilla::services::GetIOService();
|
||||
NS_ENSURE_STATE(ioService);
|
||||
nsCOMPtr<nsIURI> bookmarksURI;
|
||||
nsresult rv = ioService->NewURI(DEFAULT_BOOKMARKS, nsnull, nsnull,
|
||||
getter_AddRefs(bookmarksURI));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return importer->ImportHTMLFromURI(bookmarksURI, true);
|
||||
}
|
||||
|
@ -99,5 +99,10 @@ void GetMigrateDataFromArray(MigrationData* aDataArray,
|
||||
// this is already cloned, modify it to your heart's content
|
||||
void GetProfilePath(nsIProfileStartup* aStartup, nsCOMPtr<nsIFile>& aProfileDir);
|
||||
|
||||
/**
|
||||
* Imports default bookmarks to the profile.
|
||||
*/
|
||||
nsresult ImportDefaultBookmarks();
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1398,6 +1398,11 @@ nsIEProfileMigrator::CopyFavoritesBatched(bool aReplace)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
// If importing defaults fails for whatever reason, let the import process
|
||||
// continue.
|
||||
DebugOnly<nsresult> rv = ImportDefaultBookmarks();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
|
||||
|
||||
// Locate the Links toolbar folder, we want to replace the Personal Toolbar
|
||||
// content with Favorites in this folder.
|
||||
// On versions minor or equal to IE6 the folder name is stored in the
|
||||
|
@ -974,6 +974,11 @@ nsSafariProfileMigrator::CopyBookmarksBatched(bool aReplace)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
// If importing defaults fails for whatever reason, let the import process
|
||||
// continue.
|
||||
DebugOnly<nsresult> rv = ImportDefaultBookmarks();
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to import default bookmarks");
|
||||
|
||||
// In replace mode we are merging at the top level.
|
||||
folder = bookmarksMenuFolderId;
|
||||
}
|
||||
|
@ -62,9 +62,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
|
||||
"resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
|
||||
"resource:///modules/KeywordURLResetPrompter.jsm");
|
||||
|
||||
@ -231,6 +228,10 @@ BrowserGlue.prototype = {
|
||||
// no longer needed, since history was initialized completely.
|
||||
Services.obs.removeObserver(this, "places-database-locked");
|
||||
this._isPlacesLockedObserver = false;
|
||||
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
break;
|
||||
case "places-database-locked":
|
||||
this._isPlacesDatabaseLocked = true;
|
||||
@ -256,6 +257,13 @@ BrowserGlue.prototype = {
|
||||
// Customization has finished, we don't need the customizer anymore.
|
||||
delete this._distributionCustomizer;
|
||||
break;
|
||||
case "bookmarks-restore-success":
|
||||
case "bookmarks-restore-failed":
|
||||
Services.obs.removeObserver(this, "bookmarks-restore-success");
|
||||
Services.obs.removeObserver(this, "bookmarks-restore-failed");
|
||||
if (topic == "bookmarks-restore-success" && data == "html-initial")
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
break;
|
||||
case "browser-glue-test": // used by tests
|
||||
if (data == "post-update-notification") {
|
||||
if (Services.prefs.prefHasUserValue("app.update.postupdate"))
|
||||
@ -280,9 +288,6 @@ BrowserGlue.prototype = {
|
||||
keywordURI);
|
||||
}
|
||||
break;
|
||||
case "initial-migration":
|
||||
this._initialMigrationPerformed = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -985,9 +990,18 @@ BrowserGlue.prototype = {
|
||||
// If the database is corrupt or has been newly created we should
|
||||
// import bookmarks.
|
||||
var dbStatus = PlacesUtils.history.databaseStatus;
|
||||
var importBookmarks = !this._initialMigrationPerformed &&
|
||||
(dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE ||
|
||||
dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT);
|
||||
var importBookmarks = dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE ||
|
||||
dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT;
|
||||
|
||||
if (dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE) {
|
||||
// If the database has just been created, but we already have any
|
||||
// bookmark, this is not the initial import. This can happen after a
|
||||
// migration from a different browser since migrators run before us.
|
||||
// In such a case we should not import, unless some pref has been set.
|
||||
if (PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarksMenuFolderId, 0) != -1 ||
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0) != -1)
|
||||
importBookmarks = false;
|
||||
}
|
||||
|
||||
// Check if user or an extension has required to import bookmarks.html
|
||||
var importBookmarksHTML = false;
|
||||
@ -1044,9 +1058,6 @@ BrowserGlue.prototype = {
|
||||
// delayed till the import operations has finished. Not doing so would
|
||||
// cause them to be overwritten by the newly imported bookmarks.
|
||||
if (!importBookmarks) {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}
|
||||
else {
|
||||
@ -1080,28 +1091,25 @@ BrowserGlue.prototype = {
|
||||
}
|
||||
|
||||
if (bookmarksURI) {
|
||||
// Add an import observer. It will ensure that smart bookmarks are
|
||||
// created once the operation is complete.
|
||||
Services.obs.addObserver(this, "bookmarks-restore-success", false);
|
||||
Services.obs.addObserver(this, "bookmarks-restore-failed", false);
|
||||
|
||||
// Import from bookmarks.html file.
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromURL(bookmarksURI.spec, true, (function (success) {
|
||||
if (success) {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
// Ensure that smart bookmarks are created once the operation is
|
||||
// complete.
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}
|
||||
else {
|
||||
Cu.reportError("Bookmarks.html file could be corrupt.");
|
||||
}
|
||||
}).bind(this));
|
||||
var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
importer.importHTMLFromURI(bookmarksURI, true /* overwrite existing */);
|
||||
} catch (err) {
|
||||
// Report the error, but ignore it.
|
||||
Cu.reportError("Bookmarks.html file could be corrupt. " + err);
|
||||
Services.obs.removeObserver(this, "bookmarks-restore-success");
|
||||
Services.obs.removeObserver(this, "bookmarks-restore-failed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
Cu.reportError("Unable to find bookmarks.html file.");
|
||||
}
|
||||
|
||||
// Reset preferences, so we won't try to import again at next run
|
||||
if (importBookmarksHTML)
|
||||
|
@ -400,9 +400,10 @@ var PlacesOrganizer = {
|
||||
Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||
if (fp.fileURL) {
|
||||
Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
BookmarkHTMLUtils.importFromURL(fp.fileURL.spec, false);
|
||||
if (fp.file) {
|
||||
var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
importer.importHTMLFromFile(fp.file, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -57,8 +57,8 @@ function run_test() {
|
||||
- export as json, import, test
|
||||
*/
|
||||
|
||||
// import the importer
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
// get places import/export service
|
||||
var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].getService(Ci.nsIPlacesImportExportService);
|
||||
|
||||
// avoid creating the places smart folder during tests
|
||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
|
||||
@ -83,14 +83,8 @@ function run_test() {
|
||||
// 2. run the test-suite
|
||||
// Note: we do not empty the db before this import to catch bugs like 380999
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(bookmarksFileOld, true, after_import);
|
||||
importer.importHTMLFromFile(bookmarksFileOld, true);
|
||||
} catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
|
||||
}
|
||||
|
||||
function after_import(success) {
|
||||
if (!success) {
|
||||
do_throw("Couldn't import legacy bookmarks file.");
|
||||
}
|
||||
populate();
|
||||
validate();
|
||||
|
||||
@ -101,8 +95,6 @@ function after_import(success) {
|
||||
// 3. import bookmarks.exported.json
|
||||
// 4. run the test-suite
|
||||
try {
|
||||
var jsonFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
jsonFile.append("bookmarks.exported.json");
|
||||
PlacesUtils.backups.saveBookmarksToJSONFile(jsonFile);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
LOG("exported json");
|
||||
|
@ -55,7 +55,6 @@ var ps = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var ies = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
@ -73,14 +72,8 @@ function run_test() {
|
||||
// import bookmarks from corrupt file
|
||||
var corruptBookmarksFile = do_get_file("bookmarks.corrupt.html");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(corruptBookmarksFile, true, after_import);
|
||||
ies.importHTMLFromFile(corruptBookmarksFile, true);
|
||||
} catch(ex) { do_throw("couldn't import corrupt bookmarks file: " + ex); }
|
||||
}
|
||||
|
||||
function after_import(success) {
|
||||
if (!success) {
|
||||
do_throw("Couldn't import corrupt bookmarks file.");
|
||||
}
|
||||
|
||||
// Check that every bookmark is correct
|
||||
// Corrupt bookmarks should not have been imported
|
||||
@ -112,16 +105,14 @@ function after_import(success) {
|
||||
|
||||
// Import bookmarks
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(bookmarksFile, true, before_database_check);
|
||||
ies.importHTMLFromFile(bookmarksFile, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
});
|
||||
}
|
||||
|
||||
function before_database_check(success) {
|
||||
// Check that every bookmark is correct
|
||||
database_check();
|
||||
|
||||
waitForAsyncUpdates(do_test_finished);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -36,8 +36,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
/**
|
||||
* Tests the bookmarks-restore-* nsIObserver notifications after restoring
|
||||
* bookmarks from JSON and HTML. See bug 470314.
|
||||
@ -136,14 +134,10 @@ var tests = [
|
||||
run: function () {
|
||||
this.file = createFile("bookmarks-test_restoreNotification.html");
|
||||
addBookmarks();
|
||||
exporter.exportHTMLToFile(this.file);
|
||||
importer.exportHTMLToFile(this.file);
|
||||
remove_all_bookmarks();
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
|
||||
if (!success) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, false);
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
@ -160,11 +154,7 @@ var tests = [
|
||||
run: function () {
|
||||
this.file = createFile("bookmarks-test_restoreNotification.init.html");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
|
||||
if (!success) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, false);
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
@ -182,12 +172,8 @@ var tests = [
|
||||
this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
this.file.append("this file doesn't exist because nobody created it");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, false, function (success) {
|
||||
print("callback");
|
||||
if (success) {
|
||||
do_throw(" Restore should have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, false);
|
||||
do_throw(" Restore should have failed");
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
@ -202,14 +188,10 @@ var tests = [
|
||||
run: function () {
|
||||
this.file = createFile("bookmarks-test_restoreNotification.init.html");
|
||||
addBookmarks();
|
||||
exporter.exportHTMLToFile(this.file);
|
||||
importer.exportHTMLToFile(this.file);
|
||||
remove_all_bookmarks();
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
|
||||
if (!success) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, true);
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
@ -226,11 +208,7 @@ var tests = [
|
||||
run: function () {
|
||||
this.file = createFile("bookmarks-test_restoreNotification.init.html");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
|
||||
if (!success) {
|
||||
do_throw(" Restore should not have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, true);
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(" Restore should not have failed");
|
||||
@ -248,15 +226,13 @@ var tests = [
|
||||
this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
|
||||
this.file.append("this file doesn't exist because nobody created it");
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(this.file, true, function (success) {
|
||||
if (success) {
|
||||
do_throw(" Restore should have failed");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(this.file, true);
|
||||
do_throw(" Restore should have failed");
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
// nsIObserver that observes bookmarks-restore-begin.
|
||||
@ -305,7 +281,7 @@ var successAndFailedObserver = {
|
||||
do_check_eq(test.folderId, null);
|
||||
|
||||
remove_all_bookmarks();
|
||||
do_execute_soon(doNextTest);
|
||||
doNextTest();
|
||||
}
|
||||
};
|
||||
|
||||
@ -318,7 +294,7 @@ var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
var obssvc = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
|
||||
var exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -99,11 +99,9 @@ let gBookmarksFileOld;
|
||||
// Places bookmarks.html file pointer.
|
||||
let gBookmarksFileNew;
|
||||
|
||||
let exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
let importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
|
||||
getService(Ci.nsIPlacesImportExportService);
|
||||
|
||||
Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
|
||||
|
||||
function run_test()
|
||||
{
|
||||
run_next_test();
|
||||
@ -133,26 +131,22 @@ add_test(function setup() {
|
||||
// 2. run the test-suite
|
||||
// Note: we do not empty the db before this import to catch bugs like 380999
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileOld, true, function(success) {
|
||||
if (success) {
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
// Prepare for next tests.
|
||||
try {
|
||||
exporter.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
do_throw("couldn't import legacy bookmarks file.");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(gBookmarksFileOld, true);
|
||||
} catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
// Prepare for next tests.
|
||||
try {
|
||||
importer.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_import_new()
|
||||
@ -162,21 +156,17 @@ add_test(function test_import_new()
|
||||
// 2. run the test-suite
|
||||
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
|
||||
if (success) {
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
do_throw("couldn't import the exported file.");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(gBookmarksFileNew, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_emptytitle_export()
|
||||
@ -190,50 +180,42 @@ add_test(function test_emptytitle_export()
|
||||
// 5. run the test-suite
|
||||
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
|
||||
if (success) {
|
||||
const NOTITLE_URL = "http://notitle.mozilla.org/";
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI(NOTITLE_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"");
|
||||
test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
|
||||
|
||||
try {
|
||||
exporter.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
remove_all_bookmarks();
|
||||
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
|
||||
if (success) {
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
test_bookmarks.unfiled.pop();
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
try {
|
||||
exporter.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
do_throw("couldn't import the exported file.");
|
||||
}
|
||||
});
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
} else {
|
||||
do_throw("couldn't import the exported file.");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(gBookmarksFileNew, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
const NOTITLE_URL = "http://notitle.mozilla.org/";
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI(NOTITLE_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"");
|
||||
test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
|
||||
|
||||
try {
|
||||
importer.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
remove_all_bookmarks();
|
||||
|
||||
try {
|
||||
importer.importHTMLFromFile(gBookmarksFileNew, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
test_bookmarks.unfiled.pop();
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
try {
|
||||
importer.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_import_ontop()
|
||||
@ -247,33 +229,23 @@ add_test(function test_import_ontop()
|
||||
// 4. run the test-suite
|
||||
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
|
||||
if (success) {
|
||||
try {
|
||||
exporter.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true, function(success) {
|
||||
if (success) {
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
do_throw("couldn't import the exported file.");
|
||||
}
|
||||
});
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
} else {
|
||||
do_throw("couldn't import the exported file.");
|
||||
}
|
||||
});
|
||||
importer.importHTMLFromFile(gBookmarksFileNew, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
try {
|
||||
importer.exportHTMLToFile(gBookmarksFileNew);
|
||||
} catch(ex) { do_throw("couldn't export to file: " + ex); }
|
||||
try {
|
||||
importer.importHTMLFromFile(gBookmarksFileNew, true);
|
||||
} catch(ex) { do_throw("couldn't import the exported file: " + ex); }
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
testImportedBookmarks();
|
||||
|
||||
waitForAsyncUpdates(function () {
|
||||
remove_all_bookmarks();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function testImportedBookmarks()
|
||||
|
@ -29,15 +29,14 @@ function run_test() {
|
||||
do_check_eq(PlacesUtils.history.databaseStatus,
|
||||
PlacesUtils.history.DATABASE_STATUS_CREATE);
|
||||
|
||||
//A migrator would run before nsBrowserGlue Places initialization, so mimic
|
||||
//that behavior adding a bookmark and notifying the migration.
|
||||
// A migrator would run before nsBrowserGlue, so we mimic that behavior
|
||||
// adding a bookmark.
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.bookmarksMenuFolder, uri("http://mozilla.org/"),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "migrated");
|
||||
|
||||
// Initialize nsBrowserGlue.
|
||||
let bg = Cc["@mozilla.org/browser/browserglue;1"].
|
||||
getService(Ci.nsIObserver);
|
||||
bg.observe(null, "initial-migration", null)
|
||||
getService(Ci.nsIBrowserGlue);
|
||||
|
||||
let bookmarksObserver = {
|
||||
onBeginUpdateBatch: function() {},
|
||||
|
@ -17,16 +17,6 @@ const TOPICDATA_FORCE_PLACES_INIT = "force-places-init";
|
||||
let bg = Cc["@mozilla.org/browser/browserglue;1"].
|
||||
getService(Ci.nsIBrowserGlue);
|
||||
|
||||
function waitForImportAndSmartBookmarks(aCallback) {
|
||||
Services.obs.addObserver(function waitImport() {
|
||||
Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
|
||||
// Delay to test eventual smart bookmarks creation.
|
||||
do_execute_soon(function () {
|
||||
waitForAsyncUpdates(aCallback);
|
||||
});
|
||||
}, "bookmarks-restore-success", false);
|
||||
}
|
||||
|
||||
let gTests = [
|
||||
|
||||
// This test must be the first one.
|
||||
@ -76,20 +66,19 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces().
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been imported, and a smart bookmark has been
|
||||
// created.
|
||||
itemId = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been imported, and a smart bookmark has been
|
||||
// created.
|
||||
itemId = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
||||
function test_import_noSmartBookmarks()
|
||||
@ -109,20 +98,19 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces().
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
||||
function test_import_autoExport_updatedSmartBookmarks()
|
||||
@ -143,21 +131,20 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces()
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
// Check preferences have been reverted.
|
||||
Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId, 0);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
// Check preferences have been reverted.
|
||||
Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
||||
function test_import_autoExport_oldSmartBookmarks()
|
||||
@ -178,22 +165,21 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces()
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
// Check preferences have been reverted.
|
||||
Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been imported, but smart bookmarks have not
|
||||
// been created.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(itemId), "example");
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
// Check preferences have been reverted.
|
||||
Services.prefs.setBoolPref(PREF_AUTO_EXPORT_HTML, false);
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
||||
function test_restore()
|
||||
@ -212,21 +198,19 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces()
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been restored.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_true(itemId > 0);
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been restored.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_true(itemId > 0);
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
|
||||
|
||||
run_next_test();
|
||||
},
|
||||
|
||||
function test_restore_import()
|
||||
@ -246,21 +230,20 @@ let gTests = [
|
||||
|
||||
// Force nsBrowserGlue::_initPlaces()
|
||||
print("Simulate Places init");
|
||||
waitForImportAndSmartBookmarks(function () {
|
||||
// Check bookmarks.html has been restored.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_true(itemId > 0);
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
bg.QueryInterface(Ci.nsIObserver).observe(null,
|
||||
TOPIC_BROWSERGLUE_TEST,
|
||||
TOPICDATA_FORCE_PLACES_INIT);
|
||||
|
||||
// Check bookmarks.html has been restored.
|
||||
itemId =
|
||||
PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.toolbarFolderId,
|
||||
SMART_BOOKMARKS_ON_TOOLBAR);
|
||||
do_check_true(itemId > 0);
|
||||
// Check preferences have been reverted.
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
|
||||
do_check_false(Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
];
|
||||
|
@ -364,15 +364,6 @@ function run_test() {
|
||||
}
|
||||
catch(ex) {}
|
||||
|
||||
waitForImportAndSmartBookmarks(next_test);
|
||||
}
|
||||
|
||||
function waitForImportAndSmartBookmarks(aCallback) {
|
||||
Services.obs.addObserver(function waitImport() {
|
||||
Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
|
||||
// Delay to test eventual smart bookmarks creation.
|
||||
do_execute_soon(function () {
|
||||
waitForAsyncUpdates(aCallback);
|
||||
});
|
||||
}, "bookmarks-restore-success", false);
|
||||
// Kick-off tests.
|
||||
next_test();
|
||||
}
|
||||
|
@ -1,775 +0,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/. */
|
||||
|
||||
const EXPORTED_SYMBOLS = [ "BookmarkHTMLUtils" ];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
const Container_Normal = 0;
|
||||
const Container_Toolbar = 1;
|
||||
const Container_Menu = 2;
|
||||
const Container_Unfiled = 3;
|
||||
const Container_Places = 4;
|
||||
|
||||
const RESTORE_BEGIN_NSIOBSERVER_TOPIC = "bookmarks-restore-begin";
|
||||
const RESTORE_SUCCESS_NSIOBSERVER_TOPIC = "bookmarks-restore-success";
|
||||
const RESTORE_FAILED_NSIOBSERVER_TOPIC = "bookmarks-restore-failed";
|
||||
const RESTORE_NSIOBSERVER_DATA = "html";
|
||||
const RESTORE_INITIAL_NSIOBSERVER_DATA = "html-initial";
|
||||
|
||||
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
|
||||
const DESCRIPTION_ANNO = "bookmarkProperties/description";
|
||||
const POST_DATA_ANNO = "bookmarkProperties/POSTData";
|
||||
|
||||
let serialNumber = 0; // for favicons
|
||||
|
||||
let BookmarkHTMLUtils = Object.freeze({
|
||||
importFromURL: function importFromFile(aUrlString,
|
||||
aInitialImport,
|
||||
aCallback) {
|
||||
let importer = new BookmarkImporter(aInitialImport);
|
||||
importer.importFromURL(aUrlString, aCallback);
|
||||
},
|
||||
|
||||
importFromFile: function importFromFile(aLocalFile,
|
||||
aInitialImport,
|
||||
aCallback) {
|
||||
let importer = new BookmarkImporter(aInitialImport);
|
||||
importer.importFromFile(aLocalFile, aCallback);
|
||||
},
|
||||
});
|
||||
|
||||
function Frame(aFrameId) {
|
||||
this.containerId = aFrameId;
|
||||
|
||||
/**
|
||||
* How many <dl>s have been nested. Each frame/container should start
|
||||
* with a heading, and is then followed by a <dl>, <ul>, or <menu>. When
|
||||
* that list is complete, then it is the end of this container and we need
|
||||
* to pop back up one level for new items. If we never get an open tag for
|
||||
* one of these things, we should assume that the container is empty and
|
||||
* that things we find should be siblings of it. Normally, these <dl>s won't
|
||||
* be nested so this will be 0 or 1.
|
||||
*/
|
||||
this.containerNesting = 0;
|
||||
|
||||
/**
|
||||
* when we find a heading tag, it actually affects the title of the NEXT
|
||||
* container in the list. This stores that heading tag and whether it was
|
||||
* special. 'consumeHeading' resets this._
|
||||
*/
|
||||
this.lastContainerType = Container_Normal;
|
||||
|
||||
/**
|
||||
* this contains the text from the last begin tag until now. It is reset
|
||||
* at every begin tag. We can check it when we see a </a>, or </h3>
|
||||
* to see what the text content of that node should be.
|
||||
*/
|
||||
this.previousText = "";
|
||||
|
||||
/**
|
||||
* true when we hit a <dd>, which contains the description for the preceding
|
||||
* <a> tag. We can't just check for </dd> like we can for </a> or </h3>
|
||||
* because if there is a sub-folder, it is actually a child of the <dd>
|
||||
* because the tag is never explicitly closed. If this is true and we see a
|
||||
* new open tag, that means to commit the description to the previous
|
||||
* bookmark.
|
||||
*
|
||||
* Additional weirdness happens when the previous <dt> tag contains a <h3>:
|
||||
* this means there is a new folder with the given description, and whose
|
||||
* children are contained in the following <dl> list.
|
||||
*
|
||||
* This is handled in openContainer(), which commits previous text if
|
||||
* necessary.
|
||||
*/
|
||||
this.inDescription = false;
|
||||
|
||||
/**
|
||||
* contains the URL of the previous bookmark created. This is used so that
|
||||
* when we encounter a <dd>, we know what bookmark to associate the text with.
|
||||
* This is cleared whenever we hit a <h3>, so that we know NOT to save this
|
||||
* with a bookmark, but to keep it until
|
||||
*/
|
||||
this.previousLink = null; // nsIURI
|
||||
|
||||
/**
|
||||
* contains the URL of the previous livemark, so that when the link ends,
|
||||
* and the livemark title is known, we can create it.
|
||||
*/
|
||||
this.previousFeed = null; // nsIURI
|
||||
|
||||
/**
|
||||
* Contains the id of an imported, or newly created bookmark.
|
||||
*/
|
||||
this.previousId = 0;
|
||||
|
||||
/**
|
||||
* Contains the date-added and last-modified-date of an imported item.
|
||||
* Used to override the values set by insertBookmark, createFolder, etc.
|
||||
*/
|
||||
this.previousDateAdded = 0;
|
||||
this.previousLastModifiedDate = 0;
|
||||
}
|
||||
|
||||
function BookmarkImporter(aInitialImport) {
|
||||
this._isImportDefaults = aInitialImport;
|
||||
this._frames = new Array();
|
||||
this._frames.push(new Frame(PlacesUtils.bookmarksMenuFolderId));
|
||||
}
|
||||
|
||||
BookmarkImporter.prototype = {
|
||||
|
||||
_safeTrim: function safeTrim(aStr) {
|
||||
return aStr ? aStr.trim() : aStr;
|
||||
},
|
||||
|
||||
get _curFrame() {
|
||||
return this._frames[this._frames.length - 1];
|
||||
},
|
||||
|
||||
get _previousFrame() {
|
||||
return this._frames[this._frames.length - 2];
|
||||
},
|
||||
|
||||
/**
|
||||
* This is called when there is a new folder found. The folder takes the
|
||||
* name from the previous frame's heading.
|
||||
*/
|
||||
_newFrame: function newFrame() {
|
||||
let containerId = -1;
|
||||
let frame = this._curFrame;
|
||||
let containerTitle = frame.previousText;
|
||||
frame.previousText = "";
|
||||
let containerType = frame.lastContainerType;
|
||||
|
||||
switch (containerType) {
|
||||
case Container_Normal:
|
||||
// append a new folder
|
||||
containerId =
|
||||
PlacesUtils.bookmarks.createFolder(frame.containerId,
|
||||
containerTitle,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
break;
|
||||
case Container_Places:
|
||||
containerId = PlacesUtils.placesRootId;
|
||||
break;
|
||||
case Container_Menu:
|
||||
containerId = PlacesUtils.bookmarksMenuFolderId;
|
||||
break;
|
||||
case Container_Unfiled:
|
||||
containerId = PlacesUtils.unfiledBookmarksFolderId;
|
||||
break;
|
||||
case Container_Toolbar:
|
||||
containerId = PlacesUtils.toolbarFolderId;
|
||||
break;
|
||||
default:
|
||||
// NOT REACHED
|
||||
throw new Error("Unreached");
|
||||
}
|
||||
|
||||
if (frame.previousDateAdded > 0) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.setItemDateAdded(containerId, frame.previousDateAdded);
|
||||
} catch(e) {
|
||||
}
|
||||
frame.previousDateAdded = 0;
|
||||
}
|
||||
if (frame.previousLastModifiedDate > 0) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.setItemLastModified(containerId, frame.previousLastModifiedDate);
|
||||
} catch(e) {
|
||||
}
|
||||
// don't clear last-modified, in case there's a description
|
||||
}
|
||||
|
||||
frame.previousId = containerId;
|
||||
|
||||
this._frames.push(new Frame(containerId));
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles <H1>. We check for the attribute PLACES_ROOT and reset the
|
||||
* container id if it's found. Otherwise, the default bookmark menu
|
||||
* root is assumed and imported things will go into the bookmarks menu.
|
||||
*/
|
||||
_handleHead1Begin: function handleHead1Begin(aElt) {
|
||||
if (this._frames.length > 1) {
|
||||
return;
|
||||
}
|
||||
if (aElt.hasAttribute("places_root")) {
|
||||
this._curFrame.containerId = PlacesUtils.placesRootId;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called for h2,h3,h4,h5,h6. This just stores the correct information in
|
||||
* the current frame; the actual new frame corresponding to the container
|
||||
* associated with the heading will be created when the tag has been closed
|
||||
* and we know the title (we don't know to create a new folder or to merge
|
||||
* with an existing one until we have the title).
|
||||
*/
|
||||
_handleHeadBegin: function handleHeadBegin(aElt) {
|
||||
let frame = this._curFrame;
|
||||
|
||||
// after a heading, a previous bookmark is not applicable (for example, for
|
||||
// the descriptions contained in a <dd>). Neither is any previous head type
|
||||
frame.previousLink = null;
|
||||
frame.lastContainerType = Container_Normal;
|
||||
|
||||
// It is syntactically possible for a heading to appear after another heading
|
||||
// but before the <dl> that encloses that folder's contents. This should not
|
||||
// happen in practice, as the file will contain "<dl></dl>" sequence for
|
||||
// empty containers.
|
||||
//
|
||||
// Just to be on the safe side, if we encounter
|
||||
// <h3>FOO</h3>
|
||||
// <h3>BAR</h3>
|
||||
// <dl>...content 1...</dl>
|
||||
// <dl>...content 2...</dl>
|
||||
// we'll pop the stack when we find the h3 for BAR, treating that as an
|
||||
// implicit ending of the FOO container. The output will be FOO and BAR as
|
||||
// siblings. If there's another <dl> following (as in "content 2"), those
|
||||
// items will be treated as further siblings of FOO and BAR
|
||||
if (frame.containerNesting == 0) {
|
||||
this._frames.pop();
|
||||
}
|
||||
|
||||
// We have to check for some attributes to see if this is a "special"
|
||||
// folder, which will have different creation rules when the end tag is
|
||||
// processed.
|
||||
if (aElt.hasAttribute("personal_toolbar_folder")) {
|
||||
if (this._isImportDefaults) {
|
||||
frame.lastContainerType = Container_Toolbar;
|
||||
}
|
||||
} else if (aElt.hasAttribute("bookmarks_menu")) {
|
||||
if (this._isImportDefaults) {
|
||||
frame.lastContainerType = Container_Menu;
|
||||
}
|
||||
} else if (aElt.hasAttribute("unfiled_bookmarks_folder")) {
|
||||
if (this._isImportDefaults) {
|
||||
frame.lastContainerType = Container_Unfiled;
|
||||
}
|
||||
} else if (aElt.hasAttribute("places_root")) {
|
||||
if (this._isImportDefaults) {
|
||||
frame.lastContainerType = Container_Places;
|
||||
}
|
||||
} else {
|
||||
let addDate = aElt.getAttribute("add_date");
|
||||
if (addDate) {
|
||||
frame.previousDateAdded =
|
||||
this._convertImportedDateToInternalDate(addDate);
|
||||
}
|
||||
let modDate = aElt.getAttribute("last_modified");
|
||||
if (modDate) {
|
||||
frame.previousLastModifiedDate =
|
||||
this._convertImportedDateToInternalDate(modDate);
|
||||
}
|
||||
}
|
||||
this._curFrame.previousText = "";
|
||||
},
|
||||
|
||||
/*
|
||||
* Handles "<a" tags by creating a new bookmark. The title of the bookmark
|
||||
* will be the text content, which will be stuffed in previousText for us
|
||||
* and which will be saved by handleLinkEnd
|
||||
*/
|
||||
_handleLinkBegin: function handleLinkBegin(aElt) {
|
||||
let frame = this._curFrame;
|
||||
|
||||
// Make sure that the feed URIs from previous frames are emptied.
|
||||
frame.previousFeed = null;
|
||||
// Make sure that the bookmark id from previous frames are emptied.
|
||||
frame.previousId = 0;
|
||||
// mPreviousText will hold link text, clear it.
|
||||
frame.previousText = "";
|
||||
|
||||
// Get the attributes we care about.
|
||||
let href = this._safeTrim(aElt.getAttribute("href"));
|
||||
let feedUrl = this._safeTrim(aElt.getAttribute("feedurl"));
|
||||
let icon = this._safeTrim(aElt.getAttribute("icon"));
|
||||
let iconUri = this._safeTrim(aElt.getAttribute("icon_uri"));
|
||||
let lastCharset = this._safeTrim(aElt.getAttribute("last_charset"));
|
||||
let keyword = this._safeTrim(aElt.getAttribute("shortcuturl"));
|
||||
let postData = this._safeTrim(aElt.getAttribute("post_data"));
|
||||
let webPanel = this._safeTrim(aElt.getAttribute("web_panel"));
|
||||
let micsumGenURI = this._safeTrim(aElt.getAttribute("micsum_gen_uri"));
|
||||
let generatedTitle = this._safeTrim(aElt.getAttribute("generated_title"));
|
||||
let dateAdded = this._safeTrim(aElt.getAttribute("add_date"));
|
||||
let lastModified = this._safeTrim(aElt.getAttribute("last_modified"));
|
||||
|
||||
// For feeds, get the feed URL. If it is invalid, mPreviousFeed will be
|
||||
// NULL and we'll create it as a normal bookmark.
|
||||
if (feedUrl) {
|
||||
frame.previousFeed = NetUtil.newURI(feedUrl);
|
||||
}
|
||||
|
||||
// Ignore <a> tags that have no href.
|
||||
if (href) {
|
||||
// Save the address if it's valid. Note that we ignore errors if this is a
|
||||
// feed since href is optional for them.
|
||||
try {
|
||||
frame.previousLink = NetUtil.newURI(href);
|
||||
} catch(e) {
|
||||
if (!frame.previousFeed) {
|
||||
frame.previousLink = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
frame.previousLink = null;
|
||||
// The exception is for feeds, where the href is an optional component
|
||||
// indicating the source web site.
|
||||
if (!frame.previousFeed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Save bookmark's last modified date.
|
||||
if (lastModified) {
|
||||
frame.previousLastModifiedDate =
|
||||
this._convertImportedDateToInternalDate(lastModified);
|
||||
}
|
||||
|
||||
// If this is a live bookmark, we will handle it in HandleLinkEnd(), so we
|
||||
// can skip bookmark creation.
|
||||
if (frame.previousFeed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the bookmark. The title is unknown for now, we will set it later.
|
||||
try {
|
||||
frame.previousId =
|
||||
PlacesUtils.bookmarks.insertBookmark(frame.containerId,
|
||||
frame.previousLink,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"");
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the date added value, if we have it.
|
||||
if (dateAdded) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.setItemDateAdded(frame.previousId,
|
||||
this._convertImportedDateToInternalDate(dateAdded));
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Save the favicon.
|
||||
if (icon || iconUri) {
|
||||
let iconUriObject;
|
||||
try {
|
||||
iconUriObject = NetUtil.newURI(iconUri);
|
||||
} catch(e) {
|
||||
}
|
||||
if (icon || iconUriObject) {
|
||||
try {
|
||||
this._setFaviconForURI(frame.previousLink, iconUriObject, icon);
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the keyword.
|
||||
if (keyword) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.setKeywordForBookmark(frame.previousId, keyword);
|
||||
if (postData) {
|
||||
PlacesUtils.annotations.setItemAnnotation(frame.previousId,
|
||||
POST_DATA_ANNO,
|
||||
postData,
|
||||
0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set load-in-sidebar annotation for the bookmark.
|
||||
if (webPanel && webPanel.toLowerCase() == "true") {
|
||||
try {
|
||||
PlacesUtils.annotations.setItemAnnotation(frame.previousId,
|
||||
LOAD_IN_SIDEBAR_ANNO,
|
||||
1,
|
||||
0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Import last charset.
|
||||
if (lastCharset) {
|
||||
try {
|
||||
PlacesUtils.history.setCharsetForURI(frame.previousLink, lastCharset);
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_handleContainerBegin: function handleContainerBegin() {
|
||||
this._curFrame.containerNesting++;
|
||||
},
|
||||
|
||||
/**
|
||||
* Our "indent" count has decreased, and when we hit 0 that means that this
|
||||
* container is complete and we need to pop back to the outer frame. Never
|
||||
* pop the toplevel frame
|
||||
*/
|
||||
_handleContainerEnd: function handleContainerEnd() {
|
||||
let frame = this._curFrame;
|
||||
if (frame.containerNesting > 0)
|
||||
frame.containerNesting --;
|
||||
if (this._frames.length > 1 && frame.containerNesting == 0) {
|
||||
// we also need to re-set the imported last-modified date here. Otherwise
|
||||
// the addition of items will override the imported field.
|
||||
let prevFrame = this._previousFrame;
|
||||
if (prevFrame.previousLastModifiedDate > 0) {
|
||||
PlacesUtils.bookmarks.setItemLastModified(frame.containerId,
|
||||
prevFrame.previousLastModifiedDate);
|
||||
}
|
||||
this._frames.pop();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the new frame for this heading now that we know the name of the
|
||||
* container (tokens since the heading open tag will have been placed in
|
||||
* previousText).
|
||||
*/
|
||||
_handleHeadEnd: function handleHeadEnd() {
|
||||
this._newFrame();
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the title for the given bookmark.
|
||||
*/
|
||||
_handleLinkEnd: function handleLinkEnd() {
|
||||
let frame = this._curFrame;
|
||||
frame.previousText = frame.previousText.trim();
|
||||
|
||||
try {
|
||||
if (frame.previousFeed) {
|
||||
// The is a live bookmark. We create it here since in HandleLinkBegin we
|
||||
// don't know the title.
|
||||
PlacesUtils.livemarks.addLivemark({
|
||||
"title": frame.previousText,
|
||||
"parentId": frame.containerId,
|
||||
"index": PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"feedURI": frame.previousFeed,
|
||||
"siteURI": frame.previousLink,
|
||||
});
|
||||
} else if (frame.previousLink) {
|
||||
// This is a common bookmark.
|
||||
PlacesUtils.bookmarks.setItemTitle(frame.previousId,
|
||||
frame.previousText);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
|
||||
// Set last modified date as the last change.
|
||||
if (frame.previousId > 0 && frame.previousLastModifiedDate > 0) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.setItemLastModified(frame.previousId,
|
||||
frame.previousLastModifiedDate);
|
||||
} catch(e) {
|
||||
}
|
||||
// Note: don't clear previousLastModifiedDate, because if this item has a
|
||||
// description, we'll need to set it again.
|
||||
}
|
||||
|
||||
frame.previousText = "";
|
||||
|
||||
},
|
||||
|
||||
_openContainer: function openContainer(aElt) {
|
||||
if (aElt.namespaceURI != "http://www.w3.org/1999/xhtml") {
|
||||
return;
|
||||
}
|
||||
switch(aElt.localName) {
|
||||
case "h1":
|
||||
this._handleHead1Begin(aElt);
|
||||
break;
|
||||
case "h2":
|
||||
case "h3":
|
||||
case "h4":
|
||||
case "h5":
|
||||
case "h6":
|
||||
this._handleHeadBegin(aElt);
|
||||
break;
|
||||
case "a":
|
||||
this._handleLinkBegin(aElt);
|
||||
break;
|
||||
case "dl":
|
||||
case "ul":
|
||||
case "menu":
|
||||
this._handleContainerBegin();
|
||||
break;
|
||||
case "dd":
|
||||
this._curFrame.inDescription = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_closeContainer: function closeContainer(aElt) {
|
||||
let frame = this._curFrame;
|
||||
|
||||
// see the comment for the definition of inDescription. Basically, we commit
|
||||
// any text in previousText to the description of the node/folder if there
|
||||
// is any.
|
||||
if (frame.inDescription) {
|
||||
// NOTE ES5 trim trims more than the previous C++ trim.
|
||||
frame.previousText = frame.previousText.trim(); // important
|
||||
if (frame.previousText) {
|
||||
|
||||
let itemId = !frame.previousLink ? frame.containerId
|
||||
: frame.previousId;
|
||||
|
||||
try {
|
||||
if (!PlacesUtils.annotations.itemHasAnnotation(itemId, DESCRIPTION_ANNO)) {
|
||||
PlacesUtils.annotations.setItemAnnotation(itemId,
|
||||
DESCRIPTION_ANNO,
|
||||
frame.previousText,
|
||||
0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
frame.previousText = "";
|
||||
|
||||
// Set last-modified a 2nd time for all items with descriptions
|
||||
// we need to set last-modified as the *last* step in processing
|
||||
// any item type in the bookmarks.html file, so that we do
|
||||
// not overwrite the imported value. for items without descriptions,
|
||||
// setting this value after setting the item title is that
|
||||
// last point at which we can save this value before it gets reset.
|
||||
// for items with descriptions, it must set after that point.
|
||||
// however, at the point at which we set the title, there's no way
|
||||
// to determine if there will be a description following,
|
||||
// so we need to set the last-modified-date at both places.
|
||||
|
||||
let lastModified;
|
||||
if (!frame.previousLink) {
|
||||
lastModified = this._previousFrame.previousLastModifiedDate;
|
||||
} else {
|
||||
lastModified = frame.previousLastModifiedDate;
|
||||
}
|
||||
|
||||
if (itemId > 0 && lastModified > 0) {
|
||||
PlacesUtils.bookmarks.setItemLastModified(itemId, lastModified);
|
||||
}
|
||||
}
|
||||
frame.inDescription = false;
|
||||
}
|
||||
|
||||
if (aElt.namespaceURI != "http://www.w3.org/1999/xhtml") {
|
||||
return;
|
||||
}
|
||||
switch(aElt.localName) {
|
||||
case "dl":
|
||||
case "ul":
|
||||
case "menu":
|
||||
this._handleContainerEnd();
|
||||
break;
|
||||
case "dt":
|
||||
break;
|
||||
case "h1":
|
||||
// ignore
|
||||
break;
|
||||
case "h2":
|
||||
case "h3":
|
||||
case "h4":
|
||||
case "h5":
|
||||
case "h6":
|
||||
this._handleHeadEnd();
|
||||
break;
|
||||
case "a":
|
||||
this._handleLinkEnd();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_appendText: function appendText(str) {
|
||||
this._curFrame.previousText += str;
|
||||
},
|
||||
|
||||
/**
|
||||
* data is a string that is a data URI for the favicon. Our job is to
|
||||
* decode it and store it in the favicon service.
|
||||
*
|
||||
* When aIconURI is non-null, we will use that as the URI of the favicon
|
||||
* when storing in the favicon service.
|
||||
*
|
||||
* When aIconURI is null, we have to make up a URI for this favicon so that
|
||||
* it can be stored in the service. The real one will be set the next time
|
||||
* the user visits the page. Our made up one should get expired when the
|
||||
* page no longer references it.
|
||||
*/
|
||||
_setFaviconForURI: function setFaviconForURI(aPageURI, aIconURI, aData) {
|
||||
// if the input favicon URI is a chrome: URI, then we just save it and don't
|
||||
// worry about data
|
||||
if (aIconURI) {
|
||||
if (aIconURI.scheme == "chrome") {
|
||||
PlacesUtils.favicons.setFaviconUrlForPage(aPageURI, aIconURI);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// some bookmarks have placeholder URIs that contain just "data:"
|
||||
// ignore these
|
||||
if (aData.length <= 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
let faviconURI;
|
||||
if (aIconURI) {
|
||||
faviconURI = aIconURI;
|
||||
} else {
|
||||
// make up favicon URL
|
||||
let faviconSpec = "http://www.mozilla.org/2005/made-up-favicon/"
|
||||
+ serialNumber
|
||||
+ "-"
|
||||
+ new Date().getTime();
|
||||
faviconURI = NetUtil.newURI(faviconSpec);
|
||||
serialNumber++;
|
||||
}
|
||||
|
||||
// save the favicon data
|
||||
// This could fail if the favicon is bigger than defined limit, in such a
|
||||
// case data will not be saved to the db but we will still continue.
|
||||
PlacesUtils.favicons.setFaviconDataFromDataURL(faviconURI, aData, 0);
|
||||
|
||||
PlacesUtils.favicons.setFaviconUrlForPage(aPageURI, faviconURI);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a string date in seconds to an int date in microseconds
|
||||
*/
|
||||
_convertImportedDateToInternalDate: function convertImportedDateToInternalDate(aDate) {
|
||||
if (aDate && !isNaN(aDate)) {
|
||||
return parseInt(aDate) * 1000000; // in bookmarks.html this value is in seconds, not microseconds
|
||||
} else {
|
||||
return Date.now();
|
||||
}
|
||||
},
|
||||
|
||||
runBatched: function runBatched(aDoc) {
|
||||
if (!aDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isImportDefaults) {
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarksMenuFolderId);
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.toolbarFolderId);
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
}
|
||||
|
||||
let current = aDoc;
|
||||
let next;
|
||||
for (;;) {
|
||||
switch (current.nodeType) {
|
||||
case Ci.nsIDOMNode.ELEMENT_NODE:
|
||||
this._openContainer(current);
|
||||
break;
|
||||
case Ci.nsIDOMNode.TEXT_NODE:
|
||||
this._appendText(current.data);
|
||||
break;
|
||||
}
|
||||
if ((next = current.firstChild)) {
|
||||
current = next;
|
||||
continue;
|
||||
}
|
||||
for (;;) {
|
||||
if (current.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
|
||||
this._closeContainer(current);
|
||||
}
|
||||
if (current == aDoc) {
|
||||
return;
|
||||
}
|
||||
if ((next = current.nextSibling)) {
|
||||
current = next;
|
||||
break;
|
||||
}
|
||||
current = current.parentNode;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_walkTreeForImport: function walkTreeForImport(aDoc) {
|
||||
PlacesUtils.bookmarks.runInBatchMode(this, aDoc);
|
||||
},
|
||||
|
||||
_notifyObservers: function notifyObservers(topic) {
|
||||
Services.obs.notifyObservers(null,
|
||||
topic,
|
||||
this._isImportDefaults ?
|
||||
RESTORE_INITIAL_NSIOBSERVER_DATA :
|
||||
RESTORE_NSIOBSERVER_DATA);
|
||||
},
|
||||
|
||||
importFromURL: function importFromURL(aUrlString, aCallback) {
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.onload = (function onload() {
|
||||
try {
|
||||
this._walkTreeForImport(xhr.responseXML);
|
||||
this._notifyObservers(RESTORE_SUCCESS_NSIOBSERVER_TOPIC);
|
||||
if (aCallback) {
|
||||
try {
|
||||
aCallback(true);
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
this._notifyObservers(RESTORE_FAILED_NSIOBSERVER_TOPIC);
|
||||
if (aCallback) {
|
||||
try {
|
||||
aCallback(false);
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}).bind(this);
|
||||
xhr.onabort = xhr.onerror = xhr.ontimeout = (function handleFail() {
|
||||
this._notifyObservers(RESTORE_FAILED_NSIOBSERVER_TOPIC);
|
||||
if (aCallback) {
|
||||
try {
|
||||
aCallback(false);
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
}).bind(this);
|
||||
this._notifyObservers(RESTORE_BEGIN_NSIOBSERVER_TOPIC);
|
||||
try {
|
||||
xhr.open("GET", aUrlString);
|
||||
xhr.responseType = "document";
|
||||
xhr.overrideMimeType("text/html");
|
||||
xhr.send();
|
||||
} catch (e) {
|
||||
this._notifyObservers(RESTORE_FAILED_NSIOBSERVER_TOPIC);
|
||||
if (aCallback) {
|
||||
try {
|
||||
aCallback(false);
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
importFromFile: function importFromFile(aLocalFile, aCallback) {
|
||||
let url = NetUtil.newURI(aLocalFile);
|
||||
this.importFromURL(url.spec, aCallback);
|
||||
},
|
||||
|
||||
};
|
@ -445,5 +445,64 @@ AsyncStatementTelemetryTimer::HandleCompletion(PRUint16 aReason)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is a temporary converter used by nsPlacesImportExportService until
|
||||
// bug 482911 completes its js rewrite.
|
||||
jsval
|
||||
livemarkInfoToJSVal(PRInt64 aId,
|
||||
const nsACString& aGUID,
|
||||
const nsAString& aTitle,
|
||||
PRInt64 aParentId,
|
||||
PRInt32 aIndex,
|
||||
nsCOMPtr<nsIURI>& aFeedURI,
|
||||
nsCOMPtr<nsIURI>& aSiteURI)
|
||||
{
|
||||
nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
|
||||
NS_ENSURE_TRUE(xpc, JSVAL_NULL);
|
||||
|
||||
nsAXPCNativeCallContext *ncc;
|
||||
nsresult rv = xpc->GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
|
||||
JSContext *cx = nsnull;
|
||||
rv = ncc->GetJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
|
||||
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
NS_ENSURE_TRUE(obj, JSVAL_NULL);
|
||||
|
||||
jsval id;
|
||||
NS_ENSURE_TRUE(JS_NewNumberValue(cx, double(aId), &id), JSVAL_NULL);
|
||||
|
||||
JSString* guid = JS_NewStringCopyN(cx, PromiseFlatCString(aGUID).get(),
|
||||
aGUID.Length());
|
||||
NS_ENSURE_TRUE(guid, JSVAL_NULL);
|
||||
|
||||
JSString* title = JS_NewUCStringCopyN(cx, PromiseFlatString(aTitle).get(),
|
||||
aTitle.Length());
|
||||
NS_ENSURE_TRUE(title, JSVAL_NULL);
|
||||
|
||||
jsval parentId;
|
||||
NS_ENSURE_TRUE(JS_NewNumberValue(cx, double(aParentId), &parentId), JSVAL_NULL);
|
||||
|
||||
jsval feedURI;
|
||||
rv = nsContentUtils::WrapNative(cx, JS_GetGlobalForScopeChain(cx),
|
||||
NS_ISUPPORTS_CAST(nsIURI*, aFeedURI), &feedURI);
|
||||
NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
|
||||
|
||||
jsval siteURI;
|
||||
rv = nsContentUtils::WrapNative(cx, JS_GetGlobalForScopeChain(cx),
|
||||
NS_ISUPPORTS_CAST(nsIURI*, aSiteURI), &siteURI);
|
||||
NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
|
||||
|
||||
if (!JS_DefineProperty(cx, obj, "id", id, NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "guid", STRING_TO_JSVAL(guid), NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "title", STRING_TO_JSVAL(title), NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "parentId", parentId, NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "index", INT_TO_JSVAL(aIndex), NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "feedURI", feedURI, NULL, NULL, JSPROP_ENUMERATE) ||
|
||||
!JS_DefineProperty(cx, obj, "siteURI", siteURI, NULL, NULL, JSPROP_ENUMERATE)) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
return OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
||||
|
@ -297,6 +297,15 @@ private:
|
||||
const TimeStamp mStart;
|
||||
};
|
||||
|
||||
jsval
|
||||
livemarkInfoToJSVal(PRInt64 aId,
|
||||
const nsACString& aGUID,
|
||||
const nsAString& aTitle,
|
||||
PRInt64 aParentId,
|
||||
PRInt32 aIndex,
|
||||
nsCOMPtr<nsIURI>& aFeedURI,
|
||||
nsCOMPtr<nsIURI>& aSiteURI);
|
||||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -92,7 +92,7 @@ CPPSRCS = \
|
||||
SQLFunctions.cpp \
|
||||
Helpers.cpp \
|
||||
History.cpp \
|
||||
nsPlacesExportService.cpp \
|
||||
nsPlacesImportExportService.cpp \
|
||||
AsyncFaviconHelpers.cpp \
|
||||
PlaceInfo.cpp \
|
||||
VisitInfo.cpp \
|
||||
@ -123,7 +123,6 @@ endif
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
PlacesDBUtils.jsm \
|
||||
BookmarkHTMLUtils.jsm \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_PP_JS_MODULES = \
|
||||
|
@ -85,7 +85,7 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
||||
const MIN_TRANSACTIONS_FOR_BATCH = 5;
|
||||
|
||||
// The RESTORE_*_NSIOBSERVER_TOPIC constants should match the #defines of the
|
||||
// same names in browser/components/places/src/nsPlacesExportService.cpp
|
||||
// same names in browser/components/places/src/nsPlacesImportExportService.cpp
|
||||
const RESTORE_BEGIN_NSIOBSERVER_TOPIC = "bookmarks-restore-begin";
|
||||
const RESTORE_SUCCESS_NSIOBSERVER_TOPIC = "bookmarks-restore-success";
|
||||
const RESTORE_FAILED_NSIOBSERVER_TOPIC = "bookmarks-restore-failed";
|
||||
|
@ -41,15 +41,34 @@ interface nsILocalFile;
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* The PlacesImportExport interface provides methods for exporting Places data.
|
||||
* The word "Import" is in the name for legacy reasons and was kept to avoid
|
||||
* disrupting potential extension code using the export part. The new importer
|
||||
* lives in BookmarkHTMLUtils.jsm.
|
||||
* The PlacesImportExport interface provides methods for importing
|
||||
* and exporting Places data.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(47a4a09e-c708-4e68-b2f2-664d982ce026)]
|
||||
[scriptable, uuid(08f4626e-af3f-4e84-bd01-cf09175c4f94)]
|
||||
interface nsIPlacesImportExportService: nsISupports
|
||||
{
|
||||
/**
|
||||
* Loads the given bookmarks.html file and replaces it with the current
|
||||
* bookmarks hierarchy (if aIsInitialImport is true) or appends it
|
||||
* (if aIsInitialImport is false).
|
||||
*
|
||||
* Three nsIObserverService notifications are fired as a result of the
|
||||
* import. "bookmarks-restore-begin" is fired just before the import is
|
||||
* started. "bookmarks-restore-success" is fired right after the
|
||||
* bookmarks are successfully imported. "bookmarks-restore-failed" is
|
||||
* fired right after a failure occurs when importing the bookmarks.
|
||||
* Observers will be passed through their data parameters either "html"
|
||||
* if aIsInitialImport is false or "html-initial" if aIsInitialImport is
|
||||
* true. The observer subject will be null.
|
||||
*/
|
||||
void importHTMLFromFile(in nsILocalFile aFile, in boolean aIsInitialImport);
|
||||
|
||||
/**
|
||||
* Same thing as importHTMLFromFile, but takes a URI instead
|
||||
*/
|
||||
void importHTMLFromURI(in nsIURI aURI, in boolean aIsInitialImport);
|
||||
|
||||
/**
|
||||
* Saves the current bookmarks hierarchy to a bookmarks.html file.
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
2459
toolkit/components/places/nsPlacesImportExportService.cpp
Normal file
2459
toolkit/components/places/nsPlacesImportExportService.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
#ifndef nsPlacesExportService_h_
|
||||
#define nsPlacesExportService_h_
|
||||
#ifndef nsPlacesImportExportService_h__
|
||||
#define nsPlacesImportExportService_h__
|
||||
|
||||
#include "nsIPlacesImportExportService.h"
|
||||
|
||||
@ -13,17 +13,19 @@
|
||||
#include "nsINavBookmarksService.h"
|
||||
#include "nsIChannel.h"
|
||||
|
||||
class nsPlacesExportService : public nsIPlacesImportExportService
|
||||
class nsPlacesImportExportService : public nsIPlacesImportExportService,
|
||||
public nsINavHistoryBatchCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPLACESIMPORTEXPORTSERVICE
|
||||
nsPlacesExportService();
|
||||
NS_DECL_NSINAVHISTORYBATCHCALLBACK
|
||||
nsPlacesImportExportService();
|
||||
|
||||
/**
|
||||
* Obtains the service's object.
|
||||
*/
|
||||
static nsPlacesExportService* GetSingleton();
|
||||
static nsPlacesImportExportService* GetSingleton();
|
||||
|
||||
/**
|
||||
* Initializes the service's object. This should only be called once.
|
||||
@ -31,8 +33,8 @@ class nsPlacesExportService : public nsIPlacesImportExportService
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
static nsPlacesExportService* gExportService;
|
||||
virtual ~nsPlacesExportService();
|
||||
static nsPlacesImportExportService* gImportExportService;
|
||||
virtual ~nsPlacesImportExportService();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIFaviconService> mFaviconService;
|
||||
@ -41,6 +43,13 @@ class nsPlacesExportService : public nsIPlacesImportExportService
|
||||
nsCOMPtr<nsINavHistoryService> mHistoryService;
|
||||
nsCOMPtr<mozIAsyncLivemarks> mLivemarkService;
|
||||
|
||||
nsCOMPtr<nsIChannel> mImportChannel;
|
||||
bool mIsImportDefaults;
|
||||
|
||||
nsresult ImportHTMLFromFileInternal(nsILocalFile* aFile, bool aAllowRootChanges,
|
||||
PRInt64 aFolder, bool aIsImportDefaults);
|
||||
nsresult ImportHTMLFromURIInternal(nsIURI* aURI, bool aAllowRootChanges,
|
||||
PRInt64 aFolder, bool aIsImportDefaults);
|
||||
nsresult WriteContainer(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput);
|
||||
nsresult WriteContainerHeader(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput);
|
||||
nsresult WriteTitle(nsINavHistoryResultNode* aItem, nsIOutputStream* aOutput);
|
||||
@ -60,4 +69,4 @@ class nsPlacesExportService : public nsIPlacesImportExportService
|
||||
}
|
||||
};
|
||||
|
||||
#endif // nsPlacesExportService_h_
|
||||
#endif // nsPlacesImportExportService_h__
|
@ -6,7 +6,7 @@
|
||||
#include "nsNavHistory.h"
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsFaviconService.h"
|
||||
#include "nsPlacesExportService.h"
|
||||
#include "nsPlacesImportExportService.h"
|
||||
#include "History.h"
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
@ -24,8 +24,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsNavBookmarks,
|
||||
nsNavBookmarks::GetSingleton)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsFaviconService,
|
||||
nsFaviconService::GetSingleton)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsPlacesExportService,
|
||||
nsPlacesExportService::GetSingleton)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsPlacesImportExportService,
|
||||
nsPlacesImportExportService::GetSingleton)
|
||||
#ifdef MOZ_ANDROID_HISTORY
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsAndroidHistory, nsAndroidHistory::GetSingleton)
|
||||
#else
|
||||
@ -57,7 +57,7 @@ const mozilla::Module::CIDEntry kPlacesCIDs[] = {
|
||||
#else
|
||||
{ &kNS_HISTORYSERVICE_CID, false, NULL, HistoryConstructor },
|
||||
#endif
|
||||
{ &kNS_PLACESIMPORTEXPORTSERVICE_CID, false, NULL, nsPlacesExportServiceConstructor },
|
||||
{ &kNS_PLACESIMPORTEXPORTSERVICE_CID, false, NULL, nsPlacesImportExportServiceConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user