--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -33,16 +33,30 @@ PLACES_FACTORY_SINGLETON_IMPLEMENTATION(
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
#define FEED_URI_ANNO NS_LITERAL_CSTRING("livemark/feedURI")
namespace {
+#define SKIP_TAGS(condition) ((condition) ? SkipTags : DontSkip)
+
+bool DontSkip(nsCOMPtr<nsINavBookmarkObserver> obs) { return false; }
+bool SkipTags(nsCOMPtr<nsINavBookmarkObserver> obs) {
+ bool skipTags = false;
+ (void) obs->GetSkipTags(&skipTags);
+ return skipTags;
+}
+bool SkipDescendants(nsCOMPtr<nsINavBookmarkObserver> obs) {
+ bool skipDescendantsOnItemRemoval = false;
+ (void) obs->GetSkipTags(&skipDescendantsOnItemRemoval);
+ return skipDescendantsOnItemRemoval;
+}
+
template<typename Method, typename DataType>
class AsyncGetBookmarksForURI : public AsyncStatementCallback
{
public:
AsyncGetBookmarksForURI(nsNavBookmarks* aBookmarksSvc,
Method aCallback,
const DataType& aData)
: mBookmarksSvc(aBookmarksSvc)
@@ -456,17 +470,16 @@ nsNavBookmarks::InsertBookmarkInDB(int64
NS_ENSURE_SUCCESS(rv, rv);
}
bookmark.parentGuid = aParentGuid;
bookmark.grandParentId = aGrandParentId;
return NS_OK;
}
-
NS_IMETHODIMP
nsNavBookmarks::InsertBookmark(int64_t aFolder,
nsIURI* aURI,
int32_t aIndex,
const nsACString& aTitle,
const nsACString& aGUID,
uint16_t aSource,
int64_t* aNewBookmarkId)
@@ -519,47 +532,48 @@ nsNavBookmarks::InsertBookmark(int64_t a
if (grandParentId != mTagsRoot) {
rv = history->UpdateFrecency(placeId);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemAdded(*aNewBookmarkId, aFolder, index, TYPE_BOOKMARK,
- aURI, title, dateAdded, guid, folderGuid, aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ SKIP_TAGS(grandParentId == mTagsRoot),
+ OnItemAdded(*aNewBookmarkId, aFolder, index,
+ TYPE_BOOKMARK, aURI, title, dateAdded,
+ guid, folderGuid, aSource));
// If the bookmark has been added to a tag container, notify all
// bookmark-folder result nodes which contain a bookmark for the new
// bookmark's url.
if (grandParentId == mTagsRoot) {
// Notify a tags change to all bookmarks for this URI.
nsTArray<BookmarkData> bookmarks;
rv = GetBookmarksForURI(aURI, bookmarks);
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
// Check that bookmarks doesn't include the current tag itemId.
MOZ_ASSERT(bookmarks[i].id != *aNewBookmarkId);
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemChanged(bookmarks[i].id,
- NS_LITERAL_CSTRING("tags"),
- false,
- EmptyCString(),
- bookmarks[i].lastModified,
- TYPE_BOOKMARK,
- bookmarks[i].parentId,
- bookmarks[i].guid,
- bookmarks[i].parentGuid,
- EmptyCString(),
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ DontSkip,
+ OnItemChanged(bookmarks[i].id,
+ NS_LITERAL_CSTRING("tags"),
+ false,
+ EmptyCString(),
+ bookmarks[i].lastModified,
+ TYPE_BOOKMARK,
+ bookmarks[i].parentId,
+ bookmarks[i].guid,
+ bookmarks[i].parentGuid,
+ EmptyCString(),
+ aSource));
}
}
return NS_OK;
}
NS_IMETHODIMP
@@ -627,49 +641,50 @@ nsNavBookmarks::RemoveItem(int64_t aItem
NS_ENSURE_SUCCESS(rv, rv);
}
// A broken url should not interrupt the removal process.
(void)NS_NewURI(getter_AddRefs(uri), bookmark.url);
// We cannot assert since some automated tests are checking this path.
NS_WARNING_ASSERTION(uri, "Invalid URI in RemoveItem");
}
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemRemoved(bookmark.id,
- bookmark.parentId,
- bookmark.position,
- bookmark.type,
- uri,
- bookmark.guid,
- bookmark.parentGuid,
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ SKIP_TAGS(bookmark.parentId == mTagsRoot ||
+ bookmark.grandParentId == mTagsRoot),
+ OnItemRemoved(bookmark.id,
+ bookmark.parentId,
+ bookmark.position,
+ bookmark.type,
+ uri,
+ bookmark.guid,
+ bookmark.parentGuid,
+ aSource));
if (bookmark.type == TYPE_BOOKMARK && bookmark.grandParentId == mTagsRoot &&
uri) {
// If the removed bookmark was child of a tag container, notify a tags
// change to all bookmarks for this URI.
nsTArray<BookmarkData> bookmarks;
rv = GetBookmarksForURI(uri, bookmarks);
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemChanged(bookmarks[i].id,
- NS_LITERAL_CSTRING("tags"),
- false,
- EmptyCString(),
- bookmarks[i].lastModified,
- TYPE_BOOKMARK,
- bookmarks[i].parentId,
- bookmarks[i].guid,
- bookmarks[i].parentGuid,
- EmptyCString(),
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ DontSkip,
+ OnItemChanged(bookmarks[i].id,
+ NS_LITERAL_CSTRING("tags"),
+ false,
+ EmptyCString(),
+ bookmarks[i].lastModified,
+ TYPE_BOOKMARK,
+ bookmarks[i].parentId,
+ bookmarks[i].guid,
+ bookmarks[i].parentGuid,
+ EmptyCString(),
+ aSource));
}
}
return NS_OK;
}
@@ -747,21 +762,21 @@ nsNavBookmarks::CreateContainerWithID(in
rv = InsertBookmarkInDB(-1, FOLDER, aParent, index,
title, dateAdded, 0, folderGuid, grandParentId,
nullptr, aSource, aNewFolder, guid);
NS_ENSURE_SUCCESS(rv, rv);
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemAdded(*aNewFolder, aParent, index, FOLDER,
- nullptr, title, dateAdded, guid, folderGuid,
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ SKIP_TAGS(aParent == mTagsRoot),
+ OnItemAdded(*aNewFolder, aParent, index, FOLDER,
+ nullptr, title, dateAdded, guid,
+ folderGuid, aSource));
*aIndex = index;
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::InsertSeparator(int64_t aParent,
@@ -804,21 +819,21 @@ nsNavBookmarks::InsertSeparator(int64_t
rv = InsertBookmarkInDB(-1, SEPARATOR, aParent, index, NullCString(), dateAdded,
0, folderGuid, grandParentId, nullptr, aSource,
aNewItemId, guid);
NS_ENSURE_SUCCESS(rv, rv);
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemAdded(*aNewItemId, aParent, index, TYPE_SEPARATOR,
- nullptr, NullCString(), dateAdded, guid, folderGuid,
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ DontSkip,
+ OnItemAdded(*aNewItemId, aParent, index, TYPE_SEPARATOR,
+ nullptr, NullCString(), dateAdded, guid,
+ folderGuid, aSource));
return NS_OK;
}
nsresult
nsNavBookmarks::GetLastChildId(int64_t aFolderId, int64_t* aItemId)
{
@@ -1110,50 +1125,50 @@ nsNavBookmarks::RemoveFolderChildren(int
NS_ENSURE_SUCCESS(rv, rv);
}
// A broken url should not interrupt the removal process.
(void)NS_NewURI(getter_AddRefs(uri), child.url);
// We cannot assert since some automated tests are checking this path.
NS_WARNING_ASSERTION(uri, "Invalid URI in RemoveFolderChildren");
}
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemRemoved(child.id,
- child.parentId,
- child.position,
- child.type,
- uri,
- child.guid,
- child.parentGuid,
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ ((child.grandParentId == mTagsRoot) ? SkipTags : SkipDescendants),
+ OnItemRemoved(child.id,
+ child.parentId,
+ child.position,
+ child.type,
+ uri,
+ child.guid,
+ child.parentGuid,
+ aSource));
if (child.type == TYPE_BOOKMARK && child.grandParentId == mTagsRoot &&
uri) {
// If the removed bookmark was a child of a tag container, notify all
// bookmark-folder result nodes which contain a bookmark for the removed
// bookmark's url.
nsTArray<BookmarkData> bookmarks;
rv = GetBookmarksForURI(uri, bookmarks);
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t i = 0; i < bookmarks.Length(); ++i) {
- NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
- nsINavBookmarkObserver,
- OnItemChanged(bookmarks[i].id,
- NS_LITERAL_CSTRING("tags"),
- false,
- EmptyCString(),
- bookmarks[i].lastModified,
- TYPE_BOOKMARK,
- bookmarks[i].parentId,
- bookmarks[i].guid,
- bookmarks[i].parentGuid,
- EmptyCString(),
- aSource));
+ NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
+ DontSkip,
+ OnItemChanged(bookmarks[i].id,
+ NS_LITERAL_CSTRING("tags"),
+ false,
+ EmptyCString(),
+ bookmarks[i].lastModified,
+ TYPE_BOOKMARK,
+ bookmarks[i].parentId,
+ bookmarks[i].guid,
+ bookmarks[i].parentGuid,
+ EmptyCString(),
+ aSource));
}
}
}
return NS_OK;
}
--- a/toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js
+++ b/toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js
@@ -1,27 +1,78 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that each nsINavBookmarksObserver method gets the correct input.
+Cu.import("resource://gre/modules/PromiseUtils.jsm");
+
+const GUID_RE = /^[a-zA-Z0-9\-_]{12}$/;
var gBookmarksObserver = {
expected: [],
+ setup(expected) {
+ this.expected = expected;
+ this.deferred = PromiseUtils.defer();
+ return this.deferred.promise;
+ },
validate: function (aMethodName, aArguments) {
do_check_eq(this.expected[0].name, aMethodName);
let args = this.expected.shift().args;
do_check_eq(aArguments.length, args.length);
for (let i = 0; i < aArguments.length; i++) {
- do_print(aMethodName + "(args[" + i + "]: " + args[i].name + ")");
- do_check_true(args[i].check(aArguments[i]));
+ do_check_true(args[i].check(aArguments[i]), aMethodName + "(args[" + i + "]: " + args[i].name + ")");
}
- if (this.expected.length == 0) {
- run_next_test();
+ if (this.expected.length === 0) {
+ this.deferred.resolve();
+ }
+ },
+
+ // nsINavBookmarkObserver
+ onBeginUpdateBatch() {
+ return this.validate("onBeginUpdateBatch", arguments);
+ },
+ onEndUpdateBatch() {
+ return this.validate("onEndUpdateBatch", arguments);
+ },
+ onItemAdded() {
+ return this.validate("onItemAdded", arguments);
+ },
+ onItemRemoved() {
+ return this.validate("onItemRemoved", arguments);
+ },
+ onItemChanged() {
+ return this.validate("onItemChanged", arguments);
+ },
+ onItemVisited() {
+ return this.validate("onItemVisited", arguments);
+ },
+ onItemMoved() {
+ return this.validate("onItemMoved", arguments);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
+};
+
+var gBookmarkSkipObserver = {
+ skipTags: true,
+ skipDescendantsOnItemRemoval: true,
+
+ expected: null,
+ setup(expected) {
+ this.expected = expected;
+ this.deferred = PromiseUtils.defer();
+ return this.deferred.promise;
+ },
+ validate: function (aMethodName) {
+ do_check_eq(this.expected.shift(), aMethodName);
+ if (this.expected.length === 0) {
+ this.deferred.resolve();
}
},
// nsINavBookmarkObserver
onBeginUpdateBatch() {
return this.validate("onBeginUpdateBatch", arguments);
},
onEndUpdateBatch() {
@@ -40,359 +91,550 @@ var gBookmarksObserver = {
return this.validate("onItemVisited", arguments);
},
onItemMoved() {
return this.validate("onItemMoved", arguments);
},
// nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
-}
+};
+
+
+add_task(function setup() {
+ PlacesUtils.bookmarks.addObserver(gBookmarksObserver, false);
+ PlacesUtils.bookmarks.addObserver(gBookmarkSkipObserver, false);
+});
-add_test(function batch() {
- gBookmarksObserver.expected = [
- { name: "onBeginUpdateBatch",
- args: [] },
- { name: "onEndUpdateBatch",
- args: [] },
- ];
+add_task(function* batch() {
+ let promise = Promise.all([
+ gBookmarksObserver.setup([
+ { name: "onBeginUpdateBatch",
+ args: [] },
+ { name: "onEndUpdateBatch",
+ args: [] },
+ ]),
+ gBookmarkSkipObserver.setup([
+ "onBeginUpdateBatch", "onEndUpdateBatch"
+ ])]);
PlacesUtils.bookmarks.runInBatchMode({
runBatched: function () {
// Nothing.
}
}, null);
+ yield promise;
});
-add_test(function onItemAdded_bookmark() {
+add_task(function* onItemAdded_bookmark() {
const TITLE = "Bookmark 1";
let uri = NetUtil.newURI("http://1.mozilla.org/");
- gBookmarksObserver.expected = [
- { name: "onItemAdded",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
- { name: "title", check: v => v === TITLE },
- { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemAdded"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "title", check: v => v === TITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
TITLE);
+ yield promise;
});
-add_test(function onItemAdded_separator() {
- gBookmarksObserver.expected = [
- { name: "onItemAdded",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "index", check: v => v === 1 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
- { name: "uri", check: v => v === null },
- { name: "title", check: v => v === null },
- { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
+add_task(function* onItemAdded_separator() {
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemAdded"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "index", check: v => v === 1 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
+ { name: "uri", check: v => v === null },
+ { name: "title", check: v => v === null },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX);
+ yield promise;
});
-add_test(function onItemAdded_folder() {
+add_task(function* onItemAdded_folder() {
const TITLE = "Folder 1";
- gBookmarksObserver.expected = [
- { name: "onItemAdded",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "index", check: v => v === 2 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
- { name: "uri", check: v => v === null },
- { name: "title", check: v => v === TITLE },
- { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemAdded"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "index", check: v => v === 2 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "title", check: v => v === TITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
TITLE,
PlacesUtils.bookmarks.DEFAULT_INDEX);
+ yield promise;
});
-add_test(function onItemChanged_title_bookmark() {
+add_task(function* onItemChanged_title_bookmark() {
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
- let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
const TITLE = "New title";
- gBookmarksObserver.expected = [
- { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "title" },
- { name: "isAnno", check: v => v === false },
- { name: "newValue", check: v => v === TITLE },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemChanged"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "title" },
+ { name: "isAnno", check: v => v === false },
+ { name: "newValue", check: v => v === TITLE },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
PlacesUtils.bookmarks.setItemTitle(id, TITLE);
+ yield promise;
});
-add_test(function onItemChanged_tags_bookmark() {
+add_task(function* onItemChanged_tags_bookmark() {
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
- const TITLE = "New title";
- const TAG = "tag"
- gBookmarksObserver.expected = [
- { name: "onItemAdded", // This is the tag folder.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
- { name: "uri", check: v => v === null },
- { name: "title", check: v => v === TAG },
- { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemAdded", // This is the tag.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
- { name: "title", check: v => v === null },
- { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemChanged",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "tags" },
- { name: "isAnno", check: v => v === false },
- { name: "newValue", check: v => v === "" },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemRemoved", // This is the tag.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemRemoved", // This is the tag folder.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
- { name: "uri", check: v => v === null },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemChanged",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "tags" },
- { name: "isAnno", check: v => v === false },
- { name: "newValue", check: v => v === "" },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
+ const TAG = "tag";
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemChanged", "onItemChanged"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemAdded", // This is the tag folder.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "title", check: v => v === TAG },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemAdded", // This is the tag.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "title", check: v => v === null },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemChanged",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "tags" },
+ { name: "isAnno", check: v => v === false },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved", // This is the tag.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved", // This is the tag folder.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.tagsFolderId },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemChanged",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "tags" },
+ { name: "isAnno", check: v => v === false },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
PlacesUtils.tagging.tagURI(uri, [TAG]);
PlacesUtils.tagging.untagURI(uri, [TAG]);
+ yield promise;
});
-add_test(function onItemMoved_bookmark() {
+add_task(function* onItemMoved_bookmark() {
+ let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemMoved", "onItemMoved"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemMoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "oldParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "oldIndex", check: v => v === 0 },
+ { name: "newParentId", check: v => v === PlacesUtils.toolbarFolderId },
+ { name: "newIndex", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemMoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "oldParentId", check: v => v === PlacesUtils.toolbarFolderId },
+ { name: "oldIndex", check: v => v === 0 },
+ { name: "newParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "newIndex", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
+ PlacesUtils.bookmarks.moveItem(id, PlacesUtils.toolbarFolderId, 0);
+ PlacesUtils.bookmarks.moveItem(id, PlacesUtils.unfiledBookmarksFolderId, 0);
+ yield promise;
+});
+
+add_task(function* onItemMoved_bookmark() {
+ let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
+ let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemVisited"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemVisited",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "visitId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "time", check: v => typeof(v) == "number" && v > 0 },
+ { name: "transitionType", check: v => v === PlacesUtils.history.TRANSITION_TYPED },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ ] },
+ ])]);
+ PlacesTestUtils.addVisits({ uri: uri, transition: TRANSITION_TYPED });
+ yield promise;
+});
+
+add_task(function* onItemRemoved_bookmark() {
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
- gBookmarksObserver.expected = [
- { name: "onItemMoved",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "oldParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "oldIndex", check: v => v === 0 },
- { name: "newParentId", check: v => v === PlacesUtils.toolbarFolderId },
- { name: "newIndex", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldParentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "newParentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemMoved",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "oldParentId", check: v => v === PlacesUtils.toolbarFolderId },
- { name: "oldIndex", check: v => v === 0 },
- { name: "newParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "newIndex", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldParentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "newParentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
- PlacesUtils.bookmarks.moveItem(id, PlacesUtils.toolbarFolderId, 0);
- PlacesUtils.bookmarks.moveItem(id, PlacesUtils.unfiledBookmarksFolderId, 0);
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemChanged", "onItemRemoved"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "" },
+ { name: "isAnno", check: v => v === true },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
+ PlacesUtils.bookmarks.removeItem(id);
+ yield promise;
});
-add_test(function onItemMoved_bookmark() {
+add_task(function* onItemRemoved_separator() {
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
- let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
- gBookmarksObserver.expected = [
- { name: "onItemVisited",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "visitId", check: v => typeof(v) == "number" && v > 0 },
- { name: "time", check: v => typeof(v) == "number" && v > 0 },
- { name: "transitionType", check: v => v === PlacesUtils.history.TRANSITION_TYPED },
- { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- ] },
- ];
- PlacesTestUtils.addVisits({ uri: uri, transition: TRANSITION_TYPED });
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemChanged", "onItemRemoved"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "" },
+ { name: "isAnno", check: v => v === true },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
+ { name: "uri", check: v => v === null },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
+ PlacesUtils.bookmarks.removeItem(id);
+ yield promise;
+});
+
+add_task(function* onItemRemoved_folder() {
+ let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemChanged", "onItemRemoved"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "" },
+ { name: "isAnno", check: v => v === true },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
+ PlacesUtils.bookmarks.removeItem(id);
+ yield promise;
});
-add_test(function onItemRemoved_bookmark() {
- let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
- let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
- gBookmarksObserver.expected = [
- { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "" },
- { name: "isAnno", check: v => v === true },
- { name: "newValue", check: v => v === "" },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemRemoved",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
- { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
- PlacesUtils.bookmarks.removeItem(id);
+add_task(function* onItemRemoved_folder_recursive() {
+ const TITLE = "Folder 3";
+ const BMTITLE = "Bookmark 1";
+ let uri = NetUtil.newURI("http://1.mozilla.org/");
+ let promise = Promise.all([
+ gBookmarkSkipObserver.setup([
+ "onItemAdded", "onItemAdded", "onItemAdded", "onItemAdded",
+ "onItemChanged", "onItemRemoved"
+ ]),
+ gBookmarksObserver.setup([
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "title", check: v => v === TITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "title", check: v => v === BMTITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) },
+ { name: "index", check: v => v === 1 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "title", check: v => v === TITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemAdded",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0), 1) },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "title", check: v => v === BMTITLE },
+ { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "property", check: v => v === "" },
+ { name: "isAnno", check: v => v === true },
+ { name: "newValue", check: v => v === "" },
+ { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "oldValue", check: v => typeof(v) == "string" },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 1 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK },
+ { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ { name: "onItemRemoved",
+ args: [
+ { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
+ { name: "index", check: v => v === 0 },
+ { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
+ { name: "uri", check: v => v === null },
+ { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) },
+ { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
+ ] },
+ ])]);
+ let folder = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
+ TITLE,
+ PlacesUtils.bookmarks.DEFAULT_INDEX);
+ PlacesUtils.bookmarks.insertBookmark(folder,
+ uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
+ BMTITLE);
+ let folder2 = PlacesUtils.bookmarks.createFolder(folder, TITLE,
+ PlacesUtils.bookmarks.DEFAULT_INDEX);
+ PlacesUtils.bookmarks.insertBookmark(folder2,
+ uri, PlacesUtils.bookmarks.DEFAULT_INDEX,
+ BMTITLE);
+
+ PlacesUtils.bookmarks.removeItem(folder);
+ yield promise;
});
-add_test(function onItemRemoved_separator() {
- let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
- gBookmarksObserver.expected = [
- { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "" },
- { name: "isAnno", check: v => v === true },
- { name: "newValue", check: v => v === "" },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemRemoved",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR },
- { name: "uri", check: v => v === null },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
- PlacesUtils.bookmarks.removeItem(id);
+add_task(function cleanup()
+{
+ PlacesUtils.bookmarks.removeObserver(gBookmarksObserver);
+ PlacesUtils.bookmarks.removeObserver(gBookmarkSkipObserver);
});
-
-add_test(function onItemRemoved_folder() {
- let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0);
- const TITLE = "Folder 2";
- gBookmarksObserver.expected = [
- { name: "onItemChanged", // This is an unfortunate effect of bug 653910.
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "property", check: v => v === "" },
- { name: "isAnno", check: v => v === true },
- { name: "newValue", check: v => v === "" },
- { name: "lastModified", check: v => typeof(v) == "number" && v > 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "oldValue", check: v => typeof(v) == "string" },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- { name: "onItemRemoved",
- args: [
- { name: "itemId", check: v => typeof(v) == "number" && v > 0 },
- { name: "parentId", check: v => typeof(v) == "number" && v > 0 },
- { name: "index", check: v => v === 0 },
- { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER },
- { name: "uri", check: v => v === null },
- { name: "guid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "parentGuid", check: v => typeof(v) == "string" && /^[a-zA-Z0-9\-_]{12}$/.test(v) },
- { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) },
- ] },
- ];
- PlacesUtils.bookmarks.removeItem(id);
-});
-
-function run_test() {
- PlacesUtils.bookmarks.addObserver(gBookmarksObserver, false);
- run_next_test();
-}
-
-do_register_cleanup(function () {
- PlacesUtils.bookmarks.removeObserver(gBookmarksObserver);
-});