mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Work-in-progress for places UI. Allow the backend to filter results based on item type, and provide a way to ask for a result rooted at a given bookmark folder. NPOB, will be reviewed by ben/brettw before being turned on.
This commit is contained in:
parent
4d3b10b817
commit
b1ce141d0e
@ -41,6 +41,7 @@ var PlacesPage = {
|
||||
_topWindow: null,
|
||||
_topDocument: null,
|
||||
_populators: { },
|
||||
_bmsvc : null,
|
||||
};
|
||||
|
||||
PlacesPage.init = function PP_init() {
|
||||
@ -66,6 +67,7 @@ PlacesPage.init = function PP_init() {
|
||||
|
||||
const NH = Ci.nsINavHistory;
|
||||
const NHQO = Ci.nsINavHistoryQueryOptions;
|
||||
const TV = Ci.nsITreeView;
|
||||
var places =
|
||||
Cc["@mozilla.org/browser/nav-history;1"].getService(NH);
|
||||
var query = places.getNewQuery();
|
||||
@ -75,12 +77,15 @@ PlacesPage.init = function PP_init() {
|
||||
options.setSortingMode(NHQO.SORT_BY_NONE);
|
||||
options.setResultType(NHQO.RESULT_TYPE_URL);
|
||||
var result = places.executeQuery(query, options);
|
||||
result.QueryInterface(Ci.nsITreeView);
|
||||
result.QueryInterface(TV);
|
||||
var placeContent = document.getElementById("placeContent");
|
||||
placeContent.view = result;
|
||||
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
|
||||
document.getElementById("placesList").view = bmsvc.bookmarks.QueryInterface(Ci.nsITreeView);
|
||||
const BS = Ci.nsINavBookmarksService;
|
||||
this._bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(BS);
|
||||
var children = this._bmsvc.getFolderChildren(this._bmsvc.placesRoot,
|
||||
BS.FOLDER_CHILDREN);
|
||||
document.getElementById("placesList").view = children.QueryInterface(TV);
|
||||
|
||||
this._showPlacesUI();
|
||||
};
|
||||
@ -200,3 +205,13 @@ PlacesPage.openLinkInCurrentWindow = function PP_openLinkInCurrentWindow() {
|
||||
this._topWindow.loadURI(placeContent.selectedURL, null, null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a place folder is selected in the left pane.
|
||||
*/
|
||||
PlacesPage.placeSelected = function PP_placeSelected(event) {
|
||||
var resultView = event.target.view;
|
||||
resultView.QueryInterface(Components.interfaces.nsINavHistoryResult);
|
||||
|
||||
var folder = resultView.nodeForTreeIndex(resultView.selection.currentIndex);
|
||||
document.getElementById("placeContent").view = this._bmsvc.getFolderChildren(folder.folderId, Components.interfaces.nsINavBookmarksService.ALL_CHILDREN);
|
||||
};
|
||||
|
@ -103,7 +103,8 @@
|
||||
<hbox flex="1" id="placesView">
|
||||
<vbox flex="1">
|
||||
<tree id="placesList" class="placesTree" flex="1"
|
||||
hidecolumnpicker="true" context="placesContext">
|
||||
hidecolumnpicker="true" context="placesContext"
|
||||
onselect="PlacesPage.placeSelected(event);">
|
||||
<treecols>
|
||||
<treecol id="title" flex="1" primary="true" hideheader="true"/>
|
||||
</treecols>
|
||||
|
@ -150,16 +150,41 @@ interface nsINavBookmarkObserver : nsISupports
|
||||
[scriptable, uuid(5feca204-b735-40e8-921f-8b057eedffe2)]
|
||||
interface nsINavBookmarksService : nsISupports
|
||||
{
|
||||
/**
|
||||
* The folder ID of the Places root.
|
||||
*/
|
||||
readonly attribute PRInt64 placesRoot;
|
||||
|
||||
/**
|
||||
* The folder ID of the bookmarks root.
|
||||
*/
|
||||
readonly attribute PRInt64 bookmarksRoot;
|
||||
|
||||
/**
|
||||
* The folder ID of the personal toolbar root.
|
||||
*/
|
||||
readonly attribute PRInt64 toolbarRoot;
|
||||
|
||||
/**
|
||||
* A query result containing the bookmarks folder tree.
|
||||
* XXX get rid of me
|
||||
*/
|
||||
readonly attribute nsINavHistoryResult bookmarks;
|
||||
|
||||
/**
|
||||
* These flags can be OR'd together and passed to getFolderChildren to
|
||||
* specify the types of children returned.
|
||||
*/
|
||||
const PRUint32 ALL_CHILDREN = 0;
|
||||
const PRUint32 ITEM_CHILDREN = 1;
|
||||
const PRUint32 FOLDER_CHILDREN = 2;
|
||||
const PRUint32 QUERY_CHILDREN = 4;
|
||||
|
||||
/**
|
||||
* A query result containing only the children of the given folder.
|
||||
*/
|
||||
nsINavHistoryResult getFolderChildren(in PRInt64 folder, in PRUint32 flags);
|
||||
|
||||
/**
|
||||
* Inserts a child item into the given folder.
|
||||
* @param folder The id of the parent folder
|
||||
|
@ -64,6 +64,12 @@ interface nsINavHistoryResultNode : nsISupports
|
||||
*/
|
||||
readonly attribute AUTF8String url;
|
||||
|
||||
/**
|
||||
* ID of the folder corresponding to this node.
|
||||
* Only valid for RESULT_TYPE_FOLDER nodes, 0 for all other types.
|
||||
*/
|
||||
readonly attribute PRInt64 folderId;
|
||||
|
||||
/**
|
||||
* Title of the web page, or name of the host.
|
||||
*/
|
||||
@ -304,6 +310,12 @@ interface nsINavHistoryQuery : nsISupports
|
||||
*/
|
||||
attribute AString domain;
|
||||
readonly attribute boolean hasDomain;
|
||||
|
||||
/**
|
||||
* Limit results to items that are in all of the given folders.
|
||||
*/
|
||||
// void setFolders([const,array, size_is(folderCount)] in PRInt64 folders,
|
||||
// in PRUint32 folderCount);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -64,6 +64,12 @@ interface nsINavHistoryResultNode : nsISupports
|
||||
*/
|
||||
readonly attribute AUTF8String url;
|
||||
|
||||
/**
|
||||
* ID of the folder corresponding to this node.
|
||||
* Only valid for RESULT_TYPE_FOLDER nodes, 0 for all other types.
|
||||
*/
|
||||
readonly attribute PRInt64 folderId;
|
||||
|
||||
/**
|
||||
* Title of the web page, or name of the host.
|
||||
*/
|
||||
@ -304,6 +310,12 @@ interface nsINavHistoryQuery : nsISupports
|
||||
*/
|
||||
attribute AString domain;
|
||||
readonly attribute boolean hasDomain;
|
||||
|
||||
/**
|
||||
* Limit results to items that are in all of the given folders.
|
||||
*/
|
||||
// void setFolders([const,array, size_is(folderCount)] in PRInt64 folders,
|
||||
// in PRUint32 folderCount);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,11 @@ nsNavBookmarks::Init()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mRoot = 0;
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT id, name FROM moz_bookmarks_containers WHERE id = ?1"),
|
||||
getter_AddRefs(mDBGetFolderInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRoot = mBookmarksRoot = mToolbarRoot = 0;
|
||||
{
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT folder_child FROM moz_bookmarks_assoc WHERE parent IS NULL"),
|
||||
@ -111,15 +115,44 @@ nsNavBookmarks::Init()
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString buffer;
|
||||
|
||||
if (mRoot) {
|
||||
// Locate the bookmarks and toolbar folders
|
||||
buffer.AssignLiteral("SELECT folder_child FROM moz_bookmarks_assoc a JOIN moz_bookmarks_containers c ON a.folder_child = c.id WHERE c.name = ?1 AND a.parent = ");
|
||||
buffer.AppendInt(mRoot);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> locateChild;
|
||||
rv = dbConn->CreateStatement(buffer, getter_AddRefs(locateChild));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = locateChild->BindStringParameter(0, NS_LITERAL_STRING("Bookmarks"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool results;
|
||||
rv = locateChild->ExecuteStep(&results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (results) {
|
||||
mBookmarksRoot = locateChild->AsInt64(0);
|
||||
}
|
||||
rv = locateChild->Reset();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = locateChild->BindStringParameter(0, NS_LITERAL_STRING("Personal Toolbar Folder"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = locateChild->ExecuteStep(&results);
|
||||
if (results) {
|
||||
mToolbarRoot = locateChild->AsInt64(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mRoot) {
|
||||
// Create the root container
|
||||
// Create the root Places container
|
||||
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_containers (name) VALUES (NULL)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dbConn->GetLastInsertRowID(&mRoot);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(mRoot != 0, "row id must be non-zero!");
|
||||
|
||||
nsCAutoString buffer;
|
||||
buffer.AssignLiteral("INSERT INTO moz_bookmarks_assoc (folder_child) VALUES(");
|
||||
buffer.AppendInt(mRoot);
|
||||
buffer.AppendLiteral(")");
|
||||
@ -127,20 +160,54 @@ nsNavBookmarks::Init()
|
||||
rv = dbConn->ExecuteSimpleSQL(buffer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (!mBookmarksRoot) {
|
||||
CreateFolder(mRoot, NS_LITERAL_STRING("Bookmarks"), 0, &mBookmarksRoot);
|
||||
NS_ASSERTION(mBookmarksRoot != 0, "row id must be non-zero!");
|
||||
}
|
||||
if (!mToolbarRoot) {
|
||||
CreateFolder(mRoot, NS_LITERAL_STRING("Personal Toolbar Folder"), 1,
|
||||
&mToolbarRoot);
|
||||
NS_ASSERTION(mToolbarRoot != 0, "row id must be non-zero!");
|
||||
}
|
||||
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT a.* FROM moz_bookmarks_assoc a, moz_history h WHERE h.url = ?1 AND a.item_child = h.id"),
|
||||
getter_AddRefs(mDBFindURIBookmarks));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This gigantic statement constructs a result where the first columns exactly match
|
||||
// those returned by mDBGetVisitPageInfo, and additionally contains columns for
|
||||
// position, item_child, and folder_child from moz_bookmarks_assoc, and name from
|
||||
// moz_bookmarks_containers. The end result is a list of all folder and item children
|
||||
// for a given folder id, sorted by position.
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT h.id, h.url, h.title, h.visit_count, MAX(fullv.visit_date), h.rev_host, a.position, a.item_child, a.folder_child, null FROM moz_bookmarks_assoc a JOIN moz_history h ON a.item_child = h.id LEFT JOIN moz_historyvisit v ON h.id = v.page_id LEFT JOIN moz_historyvisit fullv ON h.id = fullv.page_id WHERE a.parent = ?1 GROUP BY h.id UNION ALL SELECT null, null, null, null, null, null, a.position, a.item_child, a.folder_child, c.name FROM moz_bookmarks_assoc a JOIN moz_bookmarks_containers c ON c.id = a.folder_child WHERE a.parent = ?1 ORDER BY a.position"),
|
||||
// Construct a result where the first columns exactly match those returned by
|
||||
// mDBGetVisitPageInfo, and additionally contains columns for position,
|
||||
// item_child, and folder_child from moz_bookmarks_assoc. This selects only
|
||||
// _item_ children which are in moz_history.
|
||||
NS_NAMED_LITERAL_CSTRING(selectItemChildren,
|
||||
"SELECT h.id, h.url, h.title, h.visit_count, MAX(fullv.visit_date), h.rev_host, a.position, a.item_child, a.folder_child, null FROM moz_bookmarks_assoc a JOIN moz_history h ON a.item_child = h.id LEFT JOIN moz_historyvisit v ON h.id = v.page_id LEFT JOIN moz_historyvisit fullv ON h.id = fullv.page_id WHERE a.parent = ?1 GROUP BY h.id");
|
||||
|
||||
// Construct a result where the first columns are padded out to the width
|
||||
// of mDBGetVisitPageInfo, containing additional columns for position,
|
||||
// item_child, and folder_child from moz_bookmarks_assoc, and name from
|
||||
// moz_bookmarks_containers. This selects only _folder_ children which are
|
||||
// in moz_bookmarks_containers.
|
||||
NS_NAMED_LITERAL_CSTRING(selectFolderChildren,
|
||||
"SELECT null, null, null, null, null, null, a.position, a.item_child, a.folder_child, c.name FROM moz_bookmarks_assoc a JOIN moz_bookmarks_containers c ON c.id = a.folder_child WHERE a.parent = ?1");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(orderByPosition, " ORDER BY a.position");
|
||||
|
||||
// Select all children of a given folder, sorted by position
|
||||
rv = dbConn->CreateStatement(selectItemChildren +
|
||||
NS_LITERAL_CSTRING(" UNION ALL ") +
|
||||
selectFolderChildren + orderByPosition,
|
||||
getter_AddRefs(mDBGetChildren));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Returns only the item children in a folder
|
||||
rv = dbConn->CreateStatement(selectItemChildren + orderByPosition,
|
||||
getter_AddRefs(mDBGetItemChildren));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Returns only the folder children in a folder
|
||||
rv = dbConn->CreateStatement(selectFolderChildren + orderByPosition,
|
||||
getter_AddRefs(mDBGetFolderChildren));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT COUNT(*) FROM moz_bookmarks_assoc WHERE parent = ?1"),
|
||||
getter_AddRefs(mDBFolderCount));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -174,12 +241,26 @@ nsNavBookmarks::AdjustIndices(PRInt64 aFolder,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetBookmarksRoot(PRInt64 *aRoot)
|
||||
nsNavBookmarks::GetPlacesRoot(PRInt64 *aRoot)
|
||||
{
|
||||
*aRoot = mRoot;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetBookmarksRoot(PRInt64 *aRoot)
|
||||
{
|
||||
*aRoot = mBookmarksRoot;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetToolbarRoot(PRInt64 *aRoot)
|
||||
{
|
||||
*aRoot = mToolbarRoot;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::InsertItem(PRInt64 aFolder, nsIURI *aItem, PRInt32 aIndex)
|
||||
{
|
||||
@ -287,9 +368,9 @@ nsNavBookmarks::CreateFolder(PRInt64 aParent, const nsAString &aName,
|
||||
nsresult rv = AdjustIndices(aParent, index, -1, 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_containers (name) VALUES (") +
|
||||
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_containers (name) VALUES (\"") +
|
||||
NS_ConvertUTF16toUTF8(aName) +
|
||||
NS_LITERAL_CSTRING(")"));
|
||||
NS_LITERAL_CSTRING("\")"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 child;
|
||||
@ -508,13 +589,14 @@ nsNavBookmarks::GetFolderTitle(PRInt64 aFolder, nsAString &aTitle)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavFolderResultNode::BuildChildren()
|
||||
nsNavFolderResultNode::BuildChildren(PRUint32 aOptions)
|
||||
{
|
||||
if (mBuiltChildren) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = nsNavBookmarks::sInstance->FillFolderChildren(this);
|
||||
nsresult rv = nsNavBookmarks::sInstance->QueryFolderChildren(mID, aOptions,
|
||||
&mChildren);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mBuiltChildren = PR_TRUE;
|
||||
@ -523,15 +605,26 @@ nsNavFolderResultNode::BuildChildren()
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::ResultNodeForFolder(PRInt64 aID,
|
||||
const nsString &aTitle,
|
||||
nsNavHistoryResultNode **aNode)
|
||||
{
|
||||
mozStorageStatementScoper scope(mDBGetFolderInfo);
|
||||
mDBGetFolderInfo->BindInt64Parameter(0, aID);
|
||||
|
||||
PRBool results;
|
||||
nsresult rv = mDBGetFolderInfo->ExecuteStep(&results);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(results, "ResultNodeForFolder expects a valid folder id");
|
||||
|
||||
nsAutoString title;
|
||||
rv = mDBGetFolderInfo->GetString(kGetFolderInfoIndex_Title, title);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsNavFolderResultNode *node = new nsNavFolderResultNode();
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
node->mID = aID;
|
||||
node->mType = nsINavHistoryResultNode::RESULT_TYPE_FOLDER;
|
||||
node->mTitle = aTitle;
|
||||
node->mTitle = title;
|
||||
node->mAccessCount = 0;
|
||||
node->mTime = 0;
|
||||
|
||||
@ -554,8 +647,7 @@ nsNavBookmarks::GetBookmarks(nsINavHistoryResult **aResult)
|
||||
|
||||
// Fill the result with a single result node for the bookmarks root.
|
||||
nsCOMPtr<nsNavHistoryResultNode> topNode;
|
||||
rv = ResultNodeForFolder(mRoot, NS_LITERAL_STRING("Bookmarks"),
|
||||
getter_AddRefs(topNode));
|
||||
rv = ResultNodeForFolder(mRoot, getter_AddRefs(topNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_TRUE(result->GetTopLevel()->AppendObject(topNode),
|
||||
@ -567,35 +659,88 @@ nsNavBookmarks::GetBookmarks(nsINavHistoryResult **aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::FillFolderChildren(nsNavFolderResultNode *aNode)
|
||||
NS_IMETHODIMP
|
||||
nsNavBookmarks::GetFolderChildren(PRInt64 aFolder, PRUint32 aOptions,
|
||||
nsINavHistoryResult **aChildren)
|
||||
{
|
||||
NS_ASSERTION(aNode->mChildren.Count() == 0, "already have child nodes");
|
||||
*aChildren = nsnull;
|
||||
|
||||
mozStorageStatementScoper scope(mDBGetChildren);
|
||||
mozStorageTransaction transaction(DBConn(), PR_FALSE);
|
||||
nsRefPtr<nsNavHistoryResult> result = History()->NewHistoryResult();
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = mDBGetChildren->BindInt64Parameter(0, aNode->mID);
|
||||
result->SetBookmarkOptions(aOptions);
|
||||
|
||||
nsresult rv = QueryFolderChildren(aFolder, aOptions, result->GetTopLevel());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMArray<nsNavHistoryResultNode>* children = &aNode->mChildren;
|
||||
result->FilledAllResults();
|
||||
|
||||
PRBool results;
|
||||
while (NS_SUCCEEDED(mDBGetChildren->ExecuteStep(&results)) && results) {
|
||||
nsCOMPtr<nsNavHistoryResultNode> node;
|
||||
if (mDBGetChildren->IsNull(kGetChildrenIndex_FolderChild)) {
|
||||
rv = History()->RowToResult(mDBGetChildren, PR_FALSE, getter_AddRefs(node));
|
||||
} else {
|
||||
PRInt64 folder = mDBGetChildren->AsInt64(kGetChildrenIndex_FolderChild);
|
||||
nsAutoString title;
|
||||
mDBGetChildren->GetString(kGetChildrenIndex_FolderTitle, title);
|
||||
rv = ResultNodeForFolder(folder, title, getter_AddRefs(node));
|
||||
}
|
||||
NS_STATIC_CAST(nsRefPtr<nsINavHistoryResult>, result).swap(*aChildren);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(children->AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
|
||||
// Special flag OR'd with *_CHILDREN to specify that we do _not_ want to
|
||||
// build children for folders.
|
||||
|
||||
#define BUILD_CHILDREN_NO_RECURSE (1 << 31)
|
||||
|
||||
nsresult
|
||||
nsNavBookmarks::QueryFolderChildren(PRInt64 aFolder, PRUint32 aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aChildren)
|
||||
{
|
||||
mozStorageTransaction transaction(DBConn(), PR_FALSE);
|
||||
PRBool noRecurse = (aOptions & BUILD_CHILDREN_NO_RECURSE) != 0;
|
||||
aOptions &= ~BUILD_CHILDREN_NO_RECURSE;
|
||||
|
||||
mozIStorageStatement *statement;
|
||||
if (aOptions == ALL_CHILDREN ||
|
||||
aOptions == (ITEM_CHILDREN | FOLDER_CHILDREN)) {
|
||||
statement = mDBGetChildren;
|
||||
} else if (aOptions == ITEM_CHILDREN) {
|
||||
statement = mDBGetItemChildren;
|
||||
} else if (aOptions == FOLDER_CHILDREN) {
|
||||
statement = mDBGetFolderChildren;
|
||||
} else {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
mozStorageStatementScoper scope(statement);
|
||||
|
||||
rv = statement->BindInt64Parameter(0, aFolder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool results;
|
||||
while (NS_SUCCEEDED(statement->ExecuteStep(&results)) && results) {
|
||||
PRBool isFolder = !statement->IsNull(kGetChildrenIndex_FolderChild);
|
||||
nsCOMPtr<nsNavHistoryResultNode> node;
|
||||
if (isFolder) {
|
||||
PRInt64 folder = statement->AsInt64(kGetChildrenIndex_FolderChild);
|
||||
rv = ResultNodeForFolder(folder, getter_AddRefs(node));
|
||||
} else {
|
||||
rv = History()->RowToResult(statement, PR_FALSE, getter_AddRefs(node));
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(aChildren->AppendObject(node), NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
// Now build children for any folder children we just created. This is
|
||||
// pretty cheap (only go down 1 level) and allows us to know whether
|
||||
// to draw a twisty.
|
||||
if (!noRecurse) {
|
||||
for (PRInt32 i = 0; i < aChildren->Count(); ++i) {
|
||||
nsNavHistoryResultNode *child = (*aChildren)[i];
|
||||
if (child->Type() == nsINavHistoryResultNode::RESULT_TYPE_FOLDER) {
|
||||
rv = child->BuildChildren(aOptions | BUILD_CHILDREN_NO_RECURSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return transaction.Commit();
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
nsNavFolderResultNode() : nsNavHistoryResultNode(),
|
||||
mBuiltChildren(PR_FALSE) { }
|
||||
|
||||
virtual nsresult BuildChildren();
|
||||
virtual nsresult BuildChildren(PRUint32 aOptions);
|
||||
|
||||
private:
|
||||
friend class nsNavBookmarks;
|
||||
@ -84,10 +84,11 @@ private:
|
||||
nsresult AdjustIndices(PRInt64 aFolder,
|
||||
PRInt32 aStartIndex, PRInt32 aEndIndex,
|
||||
PRInt32 aDelta);
|
||||
nsresult ResultNodeForFolder(PRInt64 aFolder, const nsString &aTitle,
|
||||
nsresult ResultNodeForFolder(PRInt64 aFolder,
|
||||
nsNavHistoryResultNode **aNode);
|
||||
nsresult FillFolderChildren(nsNavFolderResultNode *aNode);
|
||||
PRInt32 FolderCount(PRInt64 aFolder);
|
||||
nsresult QueryFolderChildren(PRInt64 aFolder, PRUint32 aOptions,
|
||||
nsCOMArray<nsNavHistoryResultNode>* aChildren);
|
||||
|
||||
nsNavHistory* History() { return nsNavHistory::GetHistoryService(); }
|
||||
|
||||
@ -98,13 +99,16 @@ private:
|
||||
|
||||
nsCOMArray<nsINavBookmarkObserver> mObservers;
|
||||
PRInt64 mRoot;
|
||||
PRInt64 mBookmarksRoot;
|
||||
PRInt64 mToolbarRoot;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetFolderInfo; // kGetFolderInfoIndex_* results
|
||||
static const PRInt32 kGetFolderInfoIndex_FolderID;
|
||||
static const PRInt32 kGetFolderInfoIndex_Title;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetChildren; // kGetInfoIndex_* results + kGetChildrenIndex_* results
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetItemChildren;
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetFolderChildren;
|
||||
static const PRInt32 kGetChildrenIndex_Position;
|
||||
static const PRInt32 kGetChildrenIndex_ItemChild;
|
||||
static const PRInt32 kGetChildrenIndex_FolderChild;
|
||||
|
@ -3312,6 +3312,13 @@ NS_IMETHODIMP nsNavHistoryResultNode::GetUrl(nsACString& aUrl)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute PRInt64 folderId; */
|
||||
NS_IMETHODIMP nsNavHistoryResultNode::GetFolderId(PRInt64 *aID)
|
||||
{
|
||||
*aID = mType == RESULT_TYPE_FOLDER ? mID : 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute string title; */
|
||||
NS_IMETHODIMP nsNavHistoryResultNode::GetTitle(nsAString& aTitle)
|
||||
{
|
||||
@ -3491,7 +3498,9 @@ nsNavHistoryResult::nsNavHistoryResult(nsNavHistory* aHistoryService,
|
||||
nsIStringBundle* aHistoryBundle)
|
||||
: mBundle(aHistoryBundle), mHistoryService(aHistoryService),
|
||||
mCollapseDuplicates(PR_TRUE),
|
||||
mTimesIncludeDates(PR_TRUE), mCurrentSort(nsINavHistoryQueryOptions::SORT_BY_NONE)
|
||||
mTimesIncludeDates(PR_TRUE),
|
||||
mCurrentSort(nsINavHistoryQueryOptions::SORT_BY_NONE),
|
||||
mBookmarkOptions(nsINavBookmarksService::ALL_CHILDREN)
|
||||
{
|
||||
}
|
||||
|
||||
@ -3548,16 +3557,21 @@ nsNavHistoryResult::FilledAllResults()
|
||||
nsresult
|
||||
nsNavHistoryResult::BuildChildrenFor(nsNavHistoryResultNode *aNode)
|
||||
{
|
||||
nsresult rv = aNode->BuildChildren();
|
||||
nsresult rv = aNode->BuildChildren(mBookmarkOptions);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
FillTreeStats(aNode, aNode->mIndentLevel);
|
||||
|
||||
PRInt32 flatIndex = aNode->mFlatIndex + 1;
|
||||
for (PRInt32 i = 0; i < aNode->mChildren.Count(); ++i) {
|
||||
// XXX inefficient, need to be able to InsertElementsAt from nsCOMArray!
|
||||
mAllElements.InsertElementAt(aNode->mChildren[i],
|
||||
aNode->mFlatIndex + 1 + i);
|
||||
nsNavHistoryResultNode *child = aNode->mChildren[i];
|
||||
|
||||
// XXX inefficient, need to be able to insert multiple items at once
|
||||
mAllElements.InsertElementAt(child, flatIndex++);
|
||||
for (PRInt32 j = 0; j < child->mChildren.Count(); ++j) {
|
||||
mAllElements.InsertElementAt(child->mChildren[j], flatIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
FillTreeStats(aNode, aNode->mIndentLevel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4235,9 +4249,7 @@ NS_IMETHODIMP nsNavHistoryResult::IsContainerEmpty(PRInt32 index, PRBool *_retva
|
||||
if (index < 0 || index >= mVisibleElements.Count())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsNavHistoryResultNode *node = VisibleElementAt(index);
|
||||
*_retval = (node->mType != nsINavHistoryResultNode::RESULT_TYPE_FOLDER &&
|
||||
node->mChildren.Count() == 0);
|
||||
*_retval = (VisibleElementAt(index)->mChildren.Count() == 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -117,12 +117,15 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINAVHISTORYRESULTNODE
|
||||
|
||||
// Generate the children for this node.
|
||||
virtual nsresult BuildChildren(PRUint32 aOptions) { return NS_OK; }
|
||||
|
||||
// Non-XPCOM member accessors
|
||||
PRInt32 Type() const { return mType; }
|
||||
|
||||
protected:
|
||||
virtual ~nsNavHistoryResultNode() {}
|
||||
|
||||
// Generate the children for this node.
|
||||
virtual nsresult BuildChildren() { return NS_OK; }
|
||||
|
||||
// parent of this element, NULL if no parent. Filled in by FillAllElements
|
||||
// in the result set.
|
||||
nsNavHistoryResultNode* mParent;
|
||||
@ -185,6 +188,8 @@ public:
|
||||
|
||||
nsresult BuildChildrenFor(nsNavHistoryResultNode *aNode);
|
||||
|
||||
void SetBookmarkOptions(PRUint32 aOptions) { mBookmarkOptions = aOptions; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINAVHISTORYRESULT
|
||||
NS_DECL_NSITREEVIEW
|
||||
@ -231,6 +236,9 @@ protected:
|
||||
// keep track of sorting state
|
||||
PRUint32 mCurrentSort;
|
||||
|
||||
// bookmark types for this result (nsINavBookmarksService::*_CHILDREN)
|
||||
PRUint32 mBookmarkOptions;
|
||||
|
||||
void FillTreeStats(nsNavHistoryResultNode* aResult, PRInt32 aLevel);
|
||||
void InitializeVisibleList();
|
||||
void RebuildList();
|
||||
|
@ -137,19 +137,9 @@ var root = bmsvc.bookmarksRoot;
|
||||
|
||||
// add some bookmarks and folders
|
||||
|
||||
bmsvc.insertItem(root, uri("http://www.mozilla.org/"), 0);
|
||||
if (observer._itemAdded.spec != "http://www.mozilla.org/" ||
|
||||
observer._itemAddedFolder != root || observer._itemAddedIndex != 0) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.setItemTitle(uri("http://www.mozilla.org/"), "Mozilla.org");
|
||||
if (observer._itemChanged.spec != "http://www.mozilla.org/" ||
|
||||
observer._itemChangedProperty != "title") {
|
||||
dump("setItemTitle notification FAILED\n");
|
||||
}
|
||||
bmsvc.insertItem(root, uri("http://google.com/"), -1);
|
||||
if (observer._itemAdded.spec != "http://google.com/" ||
|
||||
observer._itemAddedFolder != root || observer._itemAddedIndex != 1) {
|
||||
observer._itemAddedFolder != root || observer._itemAddedIndex != 0) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.setItemTitle(uri("http://google.com/"), "Google");
|
||||
@ -157,32 +147,69 @@ if (observer._itemChanged.spec != "http://google.com/" ||
|
||||
observer._itemChangedProperty != "title") {
|
||||
dump("setItemTitle notification FAILED\n");
|
||||
}
|
||||
bmsvc.removeItem(root, uri("http://www.mozilla.org/"));
|
||||
if (observer._itemRemoved.spec != "http://www.mozilla.org/" ||
|
||||
observer._itemRemovedFolder != root || observer._itemRemovedIndex != 0) {
|
||||
dump("removeItem notification FAILED\n");
|
||||
|
||||
var workFolder = bmsvc.createFolder(root, "Work", 1);
|
||||
if (observer._folderAdded != workFolder ||
|
||||
observer._folderAddedParent != root ||
|
||||
observer._folderAddedIndex != 1) {
|
||||
dump("createFolder notification FAILED\n");
|
||||
}
|
||||
bmsvc.insertItem(root, uri("http://www.mozilla.org/"), -1);
|
||||
if (observer._itemAdded.spec != "http://www.mozilla.org/" ||
|
||||
observer._itemAddedFolder != root || observer._itemAddedIndex != 1) {
|
||||
bmsvc.insertItem(workFolder, uri("http://developer.mozilla.org/"), 0);
|
||||
if (observer._itemAdded.spec != "http://developer.mozilla.org/" ||
|
||||
observer._itemAddedFolder != workFolder || observer._itemAddedIndex != 0) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.setItemTitle(uri("http://developer.mozilla.org/"), "DevMo");
|
||||
if (observer._itemChanged.spec != "http://developer.mozilla.org/" ||
|
||||
observer._itemChangedProperty != "title") {
|
||||
dump("setItemTitle notification FAILED\n");
|
||||
}
|
||||
bmsvc.insertItem(workFolder, uri("http://msdn.microsoft.com/"), -1);
|
||||
if (observer._itemAdded.spec != "http://msdn.microsoft.com/" ||
|
||||
observer._itemAddedFolder != workFolder || observer._itemAddedIndex != 1) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.setItemTitle(uri("http://msdn.microsoft.com/"), "MSDN");
|
||||
if (observer._itemChanged.spec != "http://msdn.microsoft.com/" ||
|
||||
observer._itemChangedProperty != "title") {
|
||||
dump("setItemTitle notification FAILED\n");
|
||||
}
|
||||
bmsvc.removeItem(workFolder, uri("http://developer.mozilla.org/"));
|
||||
if (observer._itemRemoved.spec != "http://developer.mozilla.org/" ||
|
||||
observer._itemRemovedFolder != workFolder ||
|
||||
observer._itemRemovedIndex != 0) {
|
||||
dump("removeItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.insertItem(workFolder, uri("http://developer.mozilla.org/"), -1);
|
||||
if (observer._itemAdded.spec != "http://developer.mozilla.org/" ||
|
||||
observer._itemAddedFolder != workFolder || observer._itemAddedIndex != 1) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
var homeFolder = bmsvc.createFolder(root, "Home", -1);
|
||||
if (observer._folderAdded != homeFolder ||
|
||||
observer._folderAddedParent != root || observer._folderAddedIndex != 2) {
|
||||
dump("createFolder notification FAILED\n");
|
||||
}
|
||||
bmsvc.insertItem(homeFolder, uri("http://espn.com/"), 0);
|
||||
if (observer._itemAdded.spec != "http://espn.com/" ||
|
||||
observer._itemAddedFolder != homeFolder || observer._itemAddedIndex != 0) {
|
||||
dump("insertItem notification FAILED\n");
|
||||
}
|
||||
bmsvc.setItemTitle(uri("http://espn.com/"), "ESPN");
|
||||
if (observer._itemChanged.spec != "http://espn.com/" ||
|
||||
observer._itemChangedProperty != "title") {
|
||||
dump("setItemTitle notification FAILED\n");
|
||||
}
|
||||
|
||||
/// EXPECTED TABLE RESULTS
|
||||
/// EXPECTED TABLE RESULTS FIXME
|
||||
/// moz_bookmarks_assoc:
|
||||
/// item_child folder_child parent position
|
||||
/// ---------- ------------ ------ --------
|
||||
/// 1
|
||||
/// 2 1 0
|
||||
/// 1 1 1
|
||||
///
|
||||
/// moz_history:
|
||||
/// id url
|
||||
/// -- ------------------------
|
||||
/// 1 http://www.mozilla.org/
|
||||
/// 2 http://google.com/
|
||||
///
|
||||
/// moz_bookmarks_containers:
|
||||
/// id
|
||||
/// --
|
||||
// 1
|
||||
|
Loading…
Reference in New Issue
Block a user