diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc
index 84540b459fc6..37603234564e 100644
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -387,7 +387,7 @@
onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
onpopupshowing="BookmarkingUI.onMainMenuPopupShowing(event);
if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.menuGuid}`);"
tooltip="bhTooltip" popupsinherittooltip="true">
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.toolbarGuid}`);"/>
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.unfiledGuid}`);"/>
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.mobileGuid}`);"/>
diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js
index 8a5ece9d5010..ed52678fb95f 100644
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -998,8 +998,6 @@ var PlacesMenuDNDHandler = {
* toolbar.
*/
var PlacesToolbarHelper = {
- _place: "place:folder=TOOLBAR",
-
get _viewElt() {
return document.getElementById("PlacesToolbar");
},
@@ -1030,7 +1028,7 @@ var PlacesToolbarHelper = {
return;
}
- new PlacesToolbar(this._place);
+ new PlacesToolbar(`place:parent=${PlacesUtils.bookmarks.toolbarGuid}`);
},
handleEvent(event) {
@@ -1335,7 +1333,7 @@ var BookmarkingUI = {
if (node.parentNode._placesView)
return;
- new PlacesMenu(event, "place:folder=BOOKMARKS_MENU", {
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.menuGuid}`, {
extraClasses: {
entry: "subviewbutton",
footer: "panel-subview-footer"
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index 74d1c07615e8..8e454cff2997 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1130,7 +1130,7 @@
placespopup="true"
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
- new PlacesMenu(event, 'place:folder=TOOLBAR',
+ new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.toolbarGuid}`,
PlacesUIUtils.getViewForNode(this.parentNode.parentNode).options);">
diff --git a/browser/components/places/content/bookmarksSidebar.js b/browser/components/places/content/bookmarksSidebar.js
index 290a97f19ae8..3b59c1815b42 100644
--- a/browser/components/places/content/bookmarksSidebar.js
+++ b/browser/components/places/content/bookmarksSidebar.js
@@ -21,10 +21,7 @@ function searchBookmarks(aSearchString) {
tree.place = tree.place;
else
tree.applyFilter(aSearchString,
- [PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.toolbarFolderId,
- PlacesUtils.mobileFolderId]);
+ PlacesUtils.bookmarks.userContentRoots);
}
window.addEventListener("SidebarFocused",
diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js
index a9202ec5eea7..be526cf533a9 100644
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -753,10 +753,7 @@ var PlacesSearchBox = {
_folders: [],
get folders() {
if (this._folders.length == 0) {
- this._folders.push(PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.toolbarFolderId,
- PlacesUtils.mobileFolderId);
+ this._folders = PlacesUtils.bookmarks.userContentRoots;
}
return this._folders;
},
@@ -931,10 +928,7 @@ var PlacesQueryBuilder = {
break;
case "bookmarks":
filterCollection = "bookmarks";
- folders.push(PlacesUtils.bookmarksMenuFolderId,
- PlacesUtils.toolbarFolderId,
- PlacesUtils.unfiledBookmarksFolderId,
- PlacesUtils.mobileFolderId);
+ folders = PlacesUtils.bookmarks.userContentRoots;
break;
case "downloads":
filterCollection = "downloads";
diff --git a/browser/components/places/content/tree.xml b/browser/components/places/content/tree.xml
index 1948890c4543..bc425dde47dc 100644
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -92,7 +92,7 @@
query.searchTerms = filterString;
if (folderRestrict) {
- query.setFolders(folderRestrict, folderRestrict.length);
+ query.setParents(folderRestrict, folderRestrict.length);
options.queryType = options.QUERY_TYPE_BOOKMARKS;
}
diff --git a/toolkit/components/places/Database.cpp b/toolkit/components/places/Database.cpp
index 73502f36ea55..21d4e283605e 100644
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -107,12 +107,6 @@
#define LMANNO_FEEDURI "livemark/feedURI"
#define LMANNO_SITEURI "livemark/siteURI"
-#define ROOT_GUID "root________"
-#define MENU_ROOT_GUID "menu________"
-#define TOOLBAR_ROOT_GUID "toolbar_____"
-#define UNFILED_ROOT_GUID "unfiled_____"
-#define TAGS_ROOT_GUID "tags________"
-#define MOBILE_ROOT_GUID "mobile______"
// This is no longer used & obsolete except for during migration.
// Note: it may still be found in older places databases.
#define MOBILE_ROOT_ANNO "mobile/bookmarksRoot"
diff --git a/toolkit/components/places/nsINavHistoryService.idl b/toolkit/components/places/nsINavHistoryService.idl
index cdf2244a6346..89aa937e23f7 100644
--- a/toolkit/components/places/nsINavHistoryService.idl
+++ b/toolkit/components/places/nsINavHistoryService.idl
@@ -956,16 +956,16 @@ interface nsINavHistoryQuery : nsISupports
/**
* Limit results to items that are in all of the given folders.
*/
- void getFolders([optional] out unsigned long count,
- [retval,array,size_is(count)] out long long folders);
- readonly attribute unsigned long folderCount;
+ void getParents([optional] out unsigned long aGuidCount,
+ [retval,array,size_is(aGuidCount)] out string aGuids);
+ readonly attribute unsigned long parentCount;
/**
* This is not recursive so results will be returned from the first level of
* that folder.
*/
- void setFolders([const,array, size_is(folderCount)] in long long folders,
- in unsigned long folderCount);
+ void setParents([array, size_is(aGuidCount)] in string aGuids,
+ in unsigned long aGuidCount);
/**
* Creates a new query item with the same parameters of this one.
diff --git a/toolkit/components/places/nsNavBookmarks.cpp b/toolkit/components/places/nsNavBookmarks.cpp
index 64ea616c2987..9e2cdd207640 100644
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -1112,6 +1112,80 @@ nsNavBookmarks::FetchItemInfo(int64_t aItemId,
return NS_OK;
}
+
+nsresult
+nsNavBookmarks::FetchItemInfo(const nsCString& aGUID,
+ BookmarkData& _bookmark)
+{
+ // LEFT JOIN since not all bookmarks have an associated place.
+ nsCOMPtr stmt = mDB->GetStatement(
+ "SELECT b.id, h.url, b.title, b.position, b.fk, b.parent, b.type, "
+ "b.dateAdded, b.lastModified, t.guid, t.parent, "
+ "b.syncStatus "
+ "FROM moz_bookmarks b "
+ "LEFT JOIN moz_bookmarks t ON t.id = b.parent "
+ "LEFT JOIN moz_places h ON h.id = b.fk "
+ "WHERE b.guid = :item_guid"
+ );
+ NS_ENSURE_STATE(stmt);
+ mozStorageStatementScoper scoper(stmt);
+
+ nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("item_guid"), aGUID);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ _bookmark.guid = aGUID;
+
+ bool hasResult;
+ rv = stmt->ExecuteStep(&hasResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!hasResult) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ rv = stmt->GetInt64(0, &_bookmark.id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = stmt->GetUTF8String(1, _bookmark.url);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool isNull;
+ rv = stmt->GetIsNull(2, &isNull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isNull) {
+ rv = stmt->GetUTF8String(2, _bookmark.title);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ rv = stmt->GetInt32(3, &_bookmark.position);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(4, &_bookmark.placeId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(5, &_bookmark.parentId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt32(6, &_bookmark.type);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(7, reinterpret_cast(&_bookmark.dateAdded));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(8, reinterpret_cast(&_bookmark.lastModified));
+ NS_ENSURE_SUCCESS(rv, rv);
+ // Getting properties of the root would show no parent.
+ rv = stmt->GetIsNull(9, &isNull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isNull) {
+ rv = stmt->GetUTF8String(9, _bookmark.parentGuid);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = stmt->GetInt64(10, &_bookmark.grandParentId);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ else {
+ _bookmark.grandParentId = -1;
+ }
+ rv = stmt->GetInt32(11, &_bookmark.syncStatus);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+
nsresult
nsNavBookmarks::SetItemDateInternal(enum BookmarkDate aDateType,
int64_t aSyncChangeDelta,
@@ -1500,12 +1574,12 @@ nsNavBookmarks::GetBookmarkURI(int64_t aItemId,
nsresult
-nsNavBookmarks::ResultNodeForContainer(int64_t aItemId,
+nsNavBookmarks::ResultNodeForContainer(const nsCString& aGUID,
nsNavHistoryQueryOptions* aOptions,
nsNavHistoryResultNode** aNode)
{
BookmarkData bookmark;
- nsresult rv = FetchItemInfo(aItemId, bookmark);
+ nsresult rv = FetchItemInfo(aGUID, bookmark);
NS_ENSURE_SUCCESS(rv, rv);
if (bookmark.type == TYPE_FOLDER) { // TYPE_FOLDER
@@ -2087,9 +2161,9 @@ nsNavBookmarks::OnPageChanged(nsIURI* aURI,
NS_ENSURE_SUCCESS(rv, rv);
RefPtr queryObj = do_QueryObject(query);
- if (queryObj->Folders().Length() == 1) {
+ if (queryObj->Parents().Length() == 1) {
// Fetch missing data.
- rv = FetchItemInfo(queryObj->Folders()[0], changeData.bookmark);
+ rv = FetchItemInfo(queryObj->Parents()[0], changeData.bookmark);
NS_ENSURE_SUCCESS(rv, rv);
NotifyItemChanged(changeData);
}
diff --git a/toolkit/components/places/nsNavBookmarks.h b/toolkit/components/places/nsNavBookmarks.h
index 06bfadb2eb01..b99507b84304 100644
--- a/toolkit/components/places/nsNavBookmarks.h
+++ b/toolkit/components/places/nsNavBookmarks.h
@@ -121,7 +121,7 @@ public:
nsresult GetBookmarkURI(int64_t aItemId, nsIURI** _URI);
- nsresult ResultNodeForContainer(int64_t aID,
+ nsresult ResultNodeForContainer(const nsCString& aGUID,
nsNavHistoryQueryOptions* aOptions,
nsNavHistoryResultNode** aNode);
@@ -177,6 +177,17 @@ public:
BookmarkData& _bookmark);
/**
+ * Fetches information about the specified GUID from the database.
+ *
+ * @param aGUID
+ * GUID of the item to fetch information for.
+ * @param aBookmark
+ * BookmarkData to store the information.
+ */
+ nsresult FetchItemInfo(const nsCString &aGUID,
+ BookmarkData& _bookmark);
+
+/**
* Notifies that a bookmark has been visited.
*
* @param aItemId
diff --git a/toolkit/components/places/nsNavHistory.cpp b/toolkit/components/places/nsNavHistory.cpp
index 37307d6b6e3b..ab6c0355e0dc 100644
--- a/toolkit/components/places/nsNavHistory.cpp
+++ b/toolkit/components/places/nsNavHistory.cpp
@@ -191,8 +191,8 @@ NS_IMPL_CI_INTERFACE_GETTER(nsNavHistory,
namespace {
-static int64_t GetSimpleBookmarksQueryFolder(const RefPtr& aQuery,
- const RefPtr& aOptions);
+static nsCString GetSimpleBookmarksQueryParent(const RefPtr& aQuery,
+ const RefPtr& aOptions);
static void ParseSearchTermsFromQuery(const RefPtr& aQuery,
nsTArray* aTerms);
@@ -1041,14 +1041,14 @@ nsNavHistory::ExecuteQuery(nsINavHistoryQuery *aQuery,
// Create the root node.
RefPtr rootNode;
- int64_t folderId = GetSimpleBookmarksQueryFolder(query, options);
- if (folderId) {
+ nsCString folderGuid = GetSimpleBookmarksQueryParent(query, options);
+ if (!folderGuid.IsEmpty()) {
// In the simple case where we're just querying children of a single
// bookmark folder, we can more efficiently generate results.
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
RefPtr tempRootNode;
- nsresult rv = bookmarks->ResultNodeForContainer(folderId, options,
+ nsresult rv = bookmarks->ResultNodeForContainer(folderGuid, options,
getter_AddRefs(tempRootNode));
if (NS_SUCCEEDED(rv)) {
rootNode = tempRootNode->GetAsContainer();
@@ -1130,7 +1130,7 @@ bool IsOptimizableHistoryQuery(const RefPtr& aQuery,
if (aQuery->AnnotationIsNot() || !aQuery->Annotation().IsEmpty())
return false;
- if (aQuery->Folders().Length() > 0)
+ if (aQuery->Parents().Length() > 0)
return false;
if (aQuery->Tags().Length() > 0)
@@ -1694,17 +1694,17 @@ PlacesSQLQueryBuilder::SelectAsRoots()
mAddParams.Put(NS_LITERAL_CSTRING("MobileBookmarksFolderTitle"), mobileTitle);
mobileString = NS_LITERAL_CSTRING(","
- "(null, 'place:folder=MOBILE_BOOKMARKS', :MobileBookmarksFolderTitle, null, null, null, "
+ "(null, 'place:parent=" MOBILE_ROOT_GUID "', :MobileBookmarksFolderTitle, null, null, null, "
"null, null, 0, 0, null, null, null, null, '" MOBILE_BOOKMARKS_VIRTUAL_GUID "', null) ");
}
mQueryString = NS_LITERAL_CSTRING(
"SELECT * FROM ("
- "VALUES(null, 'place:folder=TOOLBAR', :BookmarksToolbarFolderTitle, null, null, null, "
+ "VALUES(null, 'place:parent=" TOOLBAR_ROOT_GUID "', :BookmarksToolbarFolderTitle, null, null, null, "
"null, null, 0, 0, null, null, null, null, 'toolbar____v', null), "
- "(null, 'place:folder=BOOKMARKS_MENU', :BookmarksMenuFolderTitle, null, null, null, "
+ "(null, 'place:parent=" MENU_ROOT_GUID "', :BookmarksMenuFolderTitle, null, null, null, "
"null, null, 0, 0, null, null, null, null, 'menu_______v', null), "
- "(null, 'place:folder=UNFILED_BOOKMARKS', :OtherBookmarksFolderTitle, null, null, null, "
+ "(null, 'place:parent=" UNFILED_ROOT_GUID "', :OtherBookmarksFolderTitle, null, null, null, "
"null, null, 0, 0, null, null, null, null, 'unfiled___v', null) ") +
mobileString + NS_LITERAL_CSTRING(")");
@@ -2767,21 +2767,23 @@ nsNavHistory::QueryToSelectClause(const RefPtr& aQuery,
.Str(")");
}
- // folders
- const nsTArray& folders = aQuery->Folders();
- if (folders.Length() > 0) {
+ // parents
+ const nsTArray& parents = aQuery->Parents();
+ if (parents.Length() > 0) {
aOptions->SetQueryType(nsNavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS);
clause.Condition("b.parent IN( "
"WITH RECURSIVE parents(id) AS ( "
- "VALUES ");
- for (uint32_t i = 0; i < folders.Length(); ++i) {
- nsPrintfCString param("(:parent%d_)", i);
+ "SELECT id FROM moz_bookmarks WHERE GUID IN (");
+
+ for (uint32_t i = 0; i < parents.Length(); ++i) {
+ nsPrintfCString param(":parentguid%d_", i);
clause.Param(param.get());
- if (i < folders.Length() - 1) {
+ if (i < parents.Length() - 1) {
clause.Str(",");
}
}
- clause.Str( "UNION ALL "
+ clause.Str( ") "
+ "UNION ALL "
"SELECT b2.id "
"FROM moz_bookmarks b2 "
"JOIN parents p ON b2.parent = p.id "
@@ -2917,11 +2919,11 @@ nsNavHistory::BindQueryClauseParameters(mozIStorageBaseStatement* statement,
NS_ENSURE_SUCCESS(rv, rv);
}
- // folders
- const nsTArray& folders = aQuery->Folders();
- for (uint32_t i = 0; i < folders.Length(); ++i) {
- nsPrintfCString paramName("parent%d_", i);
- rv = statement->BindInt64ByName(paramName, folders[i]);
+ // parents
+ const nsTArray& parents = aQuery->Parents();
+ for (uint32_t i = 0; i < parents.Length(); ++i) {
+ nsPrintfCString paramName("parentguid%d_", i);
+ rv = statement->BindUTF8StringByName(paramName, parents[i]);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -3350,21 +3352,19 @@ nsNavHistory::QueryRowToResult(int64_t itemId,
// handle it later.
if (NS_SUCCEEDED(rv)) {
// Check if this is a folder shortcut, so we can take a faster path.
- int64_t targetFolderId = GetSimpleBookmarksQueryFolder(queryObj, optionsObj);
- if (targetFolderId) {
+ nsCString targetFolderGuid = GetSimpleBookmarksQueryParent(queryObj, optionsObj);
+ if (!targetFolderGuid.IsEmpty()) {
nsNavBookmarks *bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
- rv = bookmarks->ResultNodeForContainer(targetFolderId, optionsObj,
+ rv = bookmarks->ResultNodeForContainer(targetFolderGuid, optionsObj,
getter_AddRefs(resultNode));
// If this failed the shortcut is pointing to nowhere, let the error pass
// and handle it later.
if (NS_SUCCEEDED(rv)) {
// At this point the node is set up like a regular folder node. Here
// we make the necessary change to make it a folder shortcut.
- resultNode->GetAsFolder()->mTargetFolderItemId = targetFolderId;
resultNode->mItemId = itemId;
- nsAutoCString targetFolderGuid(resultNode->GetAsFolder()->mBookmarkGuid);
resultNode->mBookmarkGuid = aBookmarkGuid;
resultNode->GetAsFolder()->mTargetFolderGuid = targetFolderGuid;
@@ -3629,7 +3629,7 @@ nsNavHistory::GetMonthYear(const PRExplodedTime& aTime, nsACString& aResult)
namespace {
-// GetSimpleBookmarksQueryFolder
+// GetSimpleBookmarksQueryParent
//
// Determines if this is a simple bookmarks query for a
// folder with no other constraints. In these common cases, we can more
@@ -3639,33 +3639,33 @@ namespace {
// bookmark items, folders and separators.
//
// Returns the folder ID if it is a simple folder query, 0 if not.
-static int64_t
-GetSimpleBookmarksQueryFolder(const RefPtr& aQuery,
+static nsCString
+GetSimpleBookmarksQueryParent(const RefPtr& aQuery,
const RefPtr& aOptions)
{
- if (aQuery->Folders().Length() != 1)
- return 0;
+ if (aQuery->Parents().Length() != 1)
+ return EmptyCString();
bool hasIt;
if (NS_SUCCEEDED(aQuery->GetHasBeginTime(&hasIt)) && hasIt)
- return 0;
+ return EmptyCString();
if (NS_SUCCEEDED(aQuery->GetHasEndTime(&hasIt)) && hasIt)
- return 0;
+ return EmptyCString();
if (!aQuery->Domain().IsVoid())
- return 0;
+ return EmptyCString();
if (aQuery->Uri())
- return 0;
+ return EmptyCString();
if (!aQuery->SearchTerms().IsEmpty())
- return 0;
+ return EmptyCString();
if (aQuery->Tags().Length() > 0)
- return 0;
+ return EmptyCString();
if (aOptions->MaxResults() > 0)
- return 0;
+ return EmptyCString();
// Don't care about onlyBookmarked flag, since specifying a bookmark
// folder is inferring onlyBookmarked.
- return aQuery->Folders()[0];
+ return aQuery->Parents()[0];
}
diff --git a/toolkit/components/places/nsNavHistory.h b/toolkit/components/places/nsNavHistory.h
index 753960ca9865..e3127ccee751 100644
--- a/toolkit/components/places/nsNavHistory.h
+++ b/toolkit/components/places/nsNavHistory.h
@@ -65,6 +65,13 @@
// The guid of the mobile bookmarks virtual query.
#define MOBILE_BOOKMARKS_VIRTUAL_GUID "mobile____v"
+#define ROOT_GUID "root________"
+#define MENU_ROOT_GUID "menu________"
+#define TOOLBAR_ROOT_GUID "toolbar_____"
+#define UNFILED_ROOT_GUID "unfiled_____"
+#define TAGS_ROOT_GUID "tags________"
+#define MOBILE_ROOT_GUID "mobile______"
+
class nsIAutoCompleteController;
class nsIEffectiveTLDService;
class nsIIDNService;
diff --git a/toolkit/components/places/nsNavHistoryQuery.cpp b/toolkit/components/places/nsNavHistoryQuery.cpp
index 58b7f18d4ad2..36b91e5b7604 100644
--- a/toolkit/components/places/nsNavHistoryQuery.cpp
+++ b/toolkit/components/places/nsNavHistoryQuery.cpp
@@ -110,7 +110,7 @@ static void SetOptionsKeyUint32(const nsCString& aValue,
#define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked"
#define QUERYKEY_DOMAIN_IS_HOST "domainIsHost"
#define QUERYKEY_DOMAIN "domain"
-#define QUERYKEY_FOLDER "folder"
+#define QUERYKEY_PARENT "parent"
#define QUERYKEY_NOTANNOTATION "!annotation"
#define QUERYKEY_ANNOTATION "annotation"
#define QUERYKEY_URI "uri"
@@ -155,93 +155,6 @@ inline void AppendInt64(nsACString& str, int64_t i)
str.Append(tmp);
}
-namespace PlacesFolderConversion {
- #define PLACES_ROOT_FOLDER "PLACES_ROOT"
- #define BOOKMARKS_MENU_FOLDER "BOOKMARKS_MENU"
- #define TAGS_FOLDER "TAGS"
- #define UNFILED_BOOKMARKS_FOLDER "UNFILED_BOOKMARKS"
- #define TOOLBAR_FOLDER "TOOLBAR"
- #define MOBILE_BOOKMARKS_FOLDER "MOBILE_BOOKMARKS"
-
- /**
- * Converts a folder name to a folder id.
- *
- * @param aName
- * The name of the folder to convert to a folder id.
- * @returns the folder id if aName is a recognizable name, -1 otherwise.
- */
- inline int64_t DecodeFolder(const nsCString &aName)
- {
- nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
- NS_ENSURE_TRUE(bs, false);
- int64_t folderID = -1;
-
- if (aName.EqualsLiteral(PLACES_ROOT_FOLDER))
- (void)bs->GetPlacesRoot(&folderID);
- else if (aName.EqualsLiteral(BOOKMARKS_MENU_FOLDER))
- (void)bs->GetBookmarksMenuFolder(&folderID);
- else if (aName.EqualsLiteral(TAGS_FOLDER))
- (void)bs->GetTagsFolder(&folderID);
- else if (aName.EqualsLiteral(UNFILED_BOOKMARKS_FOLDER))
- (void)bs->GetUnfiledBookmarksFolder(&folderID);
- else if (aName.EqualsLiteral(TOOLBAR_FOLDER))
- (void)bs->GetToolbarFolder(&folderID);
- else if (aName.EqualsLiteral(MOBILE_BOOKMARKS_FOLDER))
- (void)bs->GetMobileFolder(&folderID);
-
- return folderID;
- }
-
- /**
- * Converts a folder id to a named constant, or a string representation of the
- * folder id if there is no named constant for the folder, and appends it to
- * aQuery.
- *
- * @param aQuery
- * The string to append the folder string to. This is generally a
- * query string, but could really be anything.
- * @param aFolderID
- * The folder ID to convert to the proper named constant.
- */
- inline nsresult AppendFolder(nsCString &aQuery, int64_t aFolderID)
- {
- nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
- NS_ENSURE_STATE(bs);
- int64_t folderID = -1;
-
- if (NS_SUCCEEDED(bs->GetPlacesRoot(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(PLACES_ROOT_FOLDER);
- }
- else if (NS_SUCCEEDED(bs->GetBookmarksMenuFolder(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(BOOKMARKS_MENU_FOLDER);
- }
- else if (NS_SUCCEEDED(bs->GetTagsFolder(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(TAGS_FOLDER);
- }
- else if (NS_SUCCEEDED(bs->GetUnfiledBookmarksFolder(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(UNFILED_BOOKMARKS_FOLDER);
- }
- else if (NS_SUCCEEDED(bs->GetToolbarFolder(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(TOOLBAR_FOLDER);
- }
- else if (NS_SUCCEEDED(bs->GetMobileFolder(&folderID)) &&
- aFolderID == folderID) {
- aQuery.AppendLiteral(MOBILE_BOOKMARKS_FOLDER);
- }
- else {
- // It wasn't one of our named constants, so just convert it to a string.
- aQuery.AppendInt(aFolderID);
- }
-
- return NS_OK;
- }
-} // namespace PlacesFolderConversion
-
NS_IMETHODIMP
nsNavHistory::QueryStringToQuery(const nsACString& aQueryString,
nsINavHistoryQuery** _query,
@@ -386,13 +299,12 @@ nsNavHistory::QueryToQueryString(nsINavHistoryQuery *aQuery,
queryString.Append(escaped);
}
- // folders
- const nsTArray& folders = query->Folders();
- for (uint32_t i = 0; i < folders.Length(); ++i) {
+ // parents
+ const nsTArray& parents = query->Parents();
+ for (uint32_t i = 0; i < parents.Length(); ++i) {
AppendAmpersandIfNonempty(queryString);
- queryString += NS_LITERAL_CSTRING(QUERYKEY_FOLDER "=");
- nsresult rv = PlacesFolderConversion::AppendFolder(queryString, folders[i]);
- NS_ENSURE_SUCCESS(rv, rv);
+ queryString += NS_LITERAL_CSTRING(QUERYKEY_PARENT "=");
+ queryString += parents[i];
}
// tags
@@ -552,7 +464,7 @@ nsNavHistory::TokensToQuery(const nsTArray& aTokens,
if (aTokens.Length() == 0)
return NS_OK;
- nsTArray folders;
+ nsTArray parents;
nsTArray tags;
nsTArray transitions;
for (uint32_t i = 0; i < aTokens.Length(); i ++) {
@@ -612,20 +524,11 @@ nsNavHistory::TokensToQuery(const nsTArray& aTokens,
rv = aQuery->SetDomain(unescapedDomain);
NS_ENSURE_SUCCESS(rv, rv);
- // folders
- } else if (kvp.key.EqualsLiteral(QUERYKEY_FOLDER)) {
- int64_t folder;
- if (PR_sscanf(kvp.value.get(), "%lld", &folder) == 1) {
- NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY);
- } else {
- folder = PlacesFolderConversion::DecodeFolder(kvp.value);
- if (folder != -1)
- NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY);
- else
- NS_WARNING("folders value in query is invalid, ignoring");
- }
+ // parent folders (guids)
+ } else if (kvp.key.EqualsLiteral(QUERYKEY_PARENT)) {
+ NS_ENSURE_TRUE(parents.AppendElement(kvp.value), NS_ERROR_OUT_OF_MEMORY);
- // uri
+ // uri
} else if (kvp.key.EqualsLiteral(QUERYKEY_URI)) {
nsAutoCString unescapedUri(kvp.value);
NS_UnescapeURL(unescapedUri); // modifies input
@@ -733,8 +636,10 @@ nsNavHistory::TokensToQuery(const nsTArray& aTokens,
}
}
- if (folders.Length() != 0)
- aQuery->SetFolders(folders.Elements(), folders.Length());
+ if (parents.Length() != 0) {
+ rv = aQuery->SetParents(parents);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
if (tags.Length() > 0) {
rv = aQuery->SetTags(tags);
@@ -799,7 +704,7 @@ nsNavHistoryQuery::nsNavHistoryQuery(const nsNavHistoryQuery& aOther)
mDomainIsHost(aOther.mDomainIsHost), mDomain(aOther.mDomain),
mUri(aOther.mUri), mAnnotationIsNot(aOther.mAnnotationIsNot),
mAnnotation(aOther.mAnnotation),
- mFolders(aOther.mFolders),
+ mParents(aOther.mParents),
mTags(aOther.mTags), mTagsAreNot(aOther.mTagsAreNot),
mTransitions(aOther.mTransitions)
{
@@ -1131,37 +1036,39 @@ NS_IMETHODIMP nsNavHistoryQuery::SetTagsAreNot(bool aTagsAreNot)
return NS_OK;
}
-NS_IMETHODIMP nsNavHistoryQuery::GetFolders(uint32_t *aCount,
- int64_t **aFolders)
+NS_IMETHODIMP nsNavHistoryQuery::GetParents(uint32_t *aGuidCount,
+ char ***aGuids)
{
- uint32_t count = mFolders.Length();
- int64_t *folders = nullptr;
+ uint32_t count = mParents.Length();
+ char **guids = nullptr;
if (count > 0) {
- folders = static_cast
- (moz_xmalloc(count * sizeof(int64_t)));
- NS_ENSURE_TRUE(folders, NS_ERROR_OUT_OF_MEMORY);
+ guids = static_cast
+ (moz_xmalloc(count * sizeof(char*)));
+ NS_ENSURE_TRUE(guids, NS_ERROR_OUT_OF_MEMORY);
for (uint32_t i = 0; i < count; ++i) {
- folders[i] = mFolders[i];
+ guids[i] = ToNewCString(mParents[i]);
}
}
- *aCount = count;
- *aFolders = folders;
+ *aGuidCount = count;
+ *aGuids = guids;
return NS_OK;
}
-NS_IMETHODIMP nsNavHistoryQuery::GetFolderCount(uint32_t *aCount)
+NS_IMETHODIMP nsNavHistoryQuery::GetParentCount(uint32_t *aGuidCount)
{
- *aCount = mFolders.Length();
+ *aGuidCount = mParents.Length();
return NS_OK;
}
-NS_IMETHODIMP nsNavHistoryQuery::SetFolders(const int64_t *aFolders,
- uint32_t aFolderCount)
+NS_IMETHODIMP nsNavHistoryQuery::SetParents(const char** aGuids,
+ uint32_t aGuidCount)
{
- if (!mFolders.ReplaceElementsAt(0, mFolders.Length(),
- aFolders, aFolderCount)) {
- return NS_ERROR_OUT_OF_MEMORY;
+ mParents.Clear();
+ for (size_t i = 0; i < aGuidCount; i++) {
+ if (!mParents.AppendElement(aGuids[i])) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
}
return NS_OK;
diff --git a/toolkit/components/places/nsNavHistoryQuery.h b/toolkit/components/places/nsNavHistoryQuery.h
index 5a96e716d1ef..c5e791afd33c 100644
--- a/toolkit/components/places/nsNavHistoryQuery.h
+++ b/toolkit/components/places/nsNavHistoryQuery.h
@@ -45,7 +45,14 @@ public:
nsIURI* Uri() { return mUri; } // NOT AddRef-ed!
bool AnnotationIsNot() { return mAnnotationIsNot; }
const nsCString& Annotation() { return mAnnotation; }
- const nsTArray& Folders() const { return mFolders; }
+ const nsTArray& Parents() { return mParents; }
+ nsresult SetParents(const nsTArray& aParents)
+ {
+ if (!mParents.ReplaceElementsAt(0, mParents.Length(), aParents))
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+ }
+
const nsTArray& Tags() const { return mTags; }
nsresult SetTags(const nsTArray& aTags)
{
@@ -85,7 +92,7 @@ protected:
nsCOMPtr mUri;
bool mAnnotationIsNot;
nsCString mAnnotation;
- nsTArray mFolders;
+ nsTArray mParents;
nsTArray mTags;
bool mTagsAreNot;
nsTArray mTransitions;
diff --git a/toolkit/components/places/nsNavHistoryResult.cpp b/toolkit/components/places/nsNavHistoryResult.cpp
index 5f431e9c0ec0..6ce374e558ce 100644
--- a/toolkit/components/places/nsNavHistoryResult.cpp
+++ b/toolkit/components/places/nsNavHistoryResult.cpp
@@ -99,7 +99,7 @@ getUpdateRequirements(const RefPtr& aQuery,
bool nonTimeBasedItems = false;
bool domainBasedItems = false;
- if (aQuery->Folders().Length() > 0 ||
+ if (aQuery->Parents().Length() > 0 ||
aQuery->OnlyBookmarked() ||
aQuery->Tags().Length() > 0 ||
(aOptions->QueryType() == nsINavHistoryQueryOptions::QUERY_TYPE_BOOKMARKS &&
@@ -3218,14 +3218,14 @@ NS_IMETHODIMP
nsNavHistoryFolderResultNode::GetQuery(nsINavHistoryQuery** _query)
{
// get the query object
- nsCOMPtr query;
- nsNavHistory* history = nsNavHistory::GetHistoryService();
- NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
- nsresult rv = history->GetNewQuery(getter_AddRefs(query));
- NS_ENSURE_SUCCESS(rv, rv);
+ RefPtr query = new nsNavHistoryQuery();
+ nsTArray parents;
// query just has the folder ID set and nothing else
- rv = query->SetFolders(&mTargetFolderItemId, 1);
+ if (!parents.AppendElement(mTargetFolderGuid)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ nsresult rv = query->SetParents(parents);
NS_ENSURE_SUCCESS(rv, rv);
query.forget(_query);
@@ -3678,7 +3678,7 @@ nsNavHistoryFolderResultNode::OnItemAdded(int64_t aItemId,
else if (aItemType == nsINavBookmarksService::TYPE_FOLDER) {
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
- rv = bookmarks->ResultNodeForContainer(aItemId,
+ rv = bookmarks->ResultNodeForContainer(PromiseFlatCString(aGUID),
new nsNavHistoryQueryOptions(),
getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
diff --git a/toolkit/components/places/tests/queries/test_queryMultipleFolder.js b/toolkit/components/places/tests/queries/test_queryMultipleFolder.js
index 0d12cf761d7a..1229227c4771 100644
--- a/toolkit/components/places/tests/queries/test_queryMultipleFolder.js
+++ b/toolkit/components/places/tests/queries/test_queryMultipleFolder.js
@@ -3,16 +3,19 @@
"use strict";
-add_task(async function test_queryMultipleFolders() {
+var folderIds = [];
+var folderGuids = [];
+var bookmarkGuids = [];
+
+add_task(async function setup() {
// adding bookmarks in the folders
- let folderIds = [];
- let bookmarkIds = [];
for (let i = 0; i < 3; ++i) {
let folder = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
title: `Folder${i}`
});
+ folderGuids.push(folder.guid);
folderIds.push(await PlacesUtils.promiseItemId(folder.guid));
for (let j = 0; j < 7; ++j) {
@@ -21,10 +24,12 @@ add_task(async function test_queryMultipleFolders() {
url: `http://Bookmark${i}_${j}.com`,
title: ""
});
- bookmarkIds.push(await PlacesUtils.promiseItemId(bm.guid));
+ bookmarkGuids.push(bm.guid);
}
}
+});
+add_task(async function test_queryMultipleFolders_ids() {
// using queryStringToQuery
let query = {}, options = {};
let maxResults = 20;
@@ -36,7 +41,7 @@ add_task(async function test_queryMultipleFolders() {
Assert.equal(resultLength, maxResults);
for (let i = 0; i < resultLength; ++i) {
let node = rootNode.getChild(i);
- Assert.equal(bookmarkIds[i], node.itemId, node.uri);
+ Assert.equal(bookmarkGuids[i], node.bookmarkGuid, node.uri);
}
rootNode.containerOpen = false;
@@ -52,7 +57,40 @@ add_task(async function test_queryMultipleFolders() {
Assert.equal(resultLength, maxResults);
for (let i = 0; i < resultLength; ++i) {
let node = rootNode.getChild(i);
- Assert.equal(bookmarkIds[i], node.itemId, node.uri);
+ Assert.equal(bookmarkGuids[i], node.bookmarkGuid, node.uri);
+ }
+ rootNode.containerOpen = false;
+});
+
+add_task(async function test_queryMultipleFolders_guids() {
+ // using queryStringToQuery
+ let query = {}, options = {};
+ let maxResults = 20;
+ let queryString = `place:${folderGuids.map((guid) => "parent=" + guid).join("&")}&sort=5&maxResults=${maxResults}`;
+ PlacesUtils.history.queryStringToQuery(queryString, query, options);
+ let rootNode = PlacesUtils.history.executeQuery(query.value, options.value).root;
+ rootNode.containerOpen = true;
+ let resultLength = rootNode.childCount;
+ Assert.equal(resultLength, maxResults);
+ for (let i = 0; i < resultLength; ++i) {
+ let node = rootNode.getChild(i);
+ Assert.equal(bookmarkGuids[i], node.bookmarkGuid, node.uri);
+ }
+ rootNode.containerOpen = false;
+
+ // using getNewQuery and getNewQueryOptions
+ query = PlacesUtils.history.getNewQuery();
+ options = PlacesUtils.history.getNewQueryOptions();
+ query.setParents(folderGuids, folderGuids.length);
+ options.sortingMode = options.SORT_BY_URI_ASCENDING;
+ options.maxResults = maxResults;
+ rootNode = PlacesUtils.history.executeQuery(query, options).root;
+ rootNode.containerOpen = true;
+ resultLength = rootNode.childCount;
+ Assert.equal(resultLength, maxResults);
+ for (let i = 0; i < resultLength; ++i) {
+ let node = rootNode.getChild(i);
+ Assert.equal(bookmarkGuids[i], node.bookmarkGuid, node.uri);
}
rootNode.containerOpen = false;
});