diff --git a/mozilla/browser/components/places/content/places.js b/mozilla/browser/components/places/content/places.js index cf61c6d93fd..f3c67c8ec61 100755 --- a/mozilla/browser/components/places/content/places.js +++ b/mozilla/browser/components/places/content/places.js @@ -39,9 +39,6 @@ const PREF_PLACES_GROUPING_GENERIC = "browser.places.grouping.generic"; const PREF_PLACES_GROUPING_BOOKMARK = "browser.places.grouping.bookmark"; // Default Search Queries -const QUERY_MONTH_HISTORY = "place:&group=2&sort=1&type=1"; -const QUERY_DAY_HISTORY = "place:&beginTimeRef=1&endTimeRef=2&sort=4&type=1"; -const QUERY_BOOKMARKS_MENU = "place:&folders=3&group=3"; const INDEX_HISTORY = 0; const INDEX_BOOKMARKS = 1; diff --git a/mozilla/browser/components/places/public/Makefile.in b/mozilla/browser/components/places/public/Makefile.in index 6878f5ff269..1e729168643 100644 --- a/mozilla/browser/components/places/public/Makefile.in +++ b/mozilla/browser/components/places/public/Makefile.in @@ -51,8 +51,8 @@ XPIDLSRCS = \ nsIFaviconService.idl \ nsINavHistoryService.idl \ nsINavBookmarksService.idl \ - nsIBookmarksContainer.idl \ nsILivemarkService.idl \ + nsIRemoteContainer.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/mozilla/browser/components/places/public/nsIBookmarksContainer.idl b/mozilla/browser/components/places/public/nsIBookmarksContainer.idl deleted file mode 100755 index 422be72517e..00000000000 --- a/mozilla/browser/components/places/public/nsIBookmarksContainer.idl +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Places. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Annie Sullivan (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsISupports.idl" - -interface nsIURI; - -/** - * The Bookmarks Container interface provides a base class - * for services that want to provide containers for bookmarks. - * Some examples of possible services are the livemarks service and - * the filesystem. Containers are implemented as bookmarked folders. - */ - -[scriptable, uuid(45bf2020-9683-498c-9638-f08130c4151d)] -interface nsIBookmarksContainer : nsISupports -{ - - /** - * Called when the given container is about to be shown, - * so that the service can populate the container if necessary. - * @returns true if the data for the node has changed, false otherwise. - * @param container The folderId of the bookmark folder - * representing the container. - */ - boolean onContainerOpening(in PRInt64 container); - - /** - * Called when the given container has just been hidden, - * so that the service can do any necessary cleanup. - * @param container The folderId of the bookmark folder - * representing the container. - */ - void onContainerClosed(in PRInt64 container); - - /** - * Called when the given container is about to be deleted, so - * that the service can do any necessary cleanup. - * Called BEFORE the container is deleted, so that the service - * can still reference it. - * @param container The folderId of the bookmark folder - * representing the container to be deleted. - */ - void onContainerRemoving(in PRInt64 container); - - /** - * Called when the given container has just been moved, in case - * the service needs to do any bookkeeping. - * Called AFTER the container has been moved, so the service can - * get the new URI. - * @param container The folderId of the bookmark folder - * representing the container to be moved. - * @param newFolder The folderId of the new parent folder - * for the container. - * @param newIndex The index the container will be inserted at, - * or -1 for append. - */ - void onContainerMoved(in PRInt64 container, - in PRInt64 newFolder, in PRInt32 newIndex); - - /** - * Returns true if containers of this type should not expose UI for - * inserting, moving, or deleting children. - */ - readonly attribute boolean childrenReadOnly; -}; diff --git a/mozilla/browser/components/places/public/nsILivemarkService.idl b/mozilla/browser/components/places/public/nsILivemarkService.idl index 130425fbe71..d0b818cfd5d 100755 --- a/mozilla/browser/components/places/public/nsILivemarkService.idl +++ b/mozilla/browser/components/places/public/nsILivemarkService.idl @@ -37,12 +37,12 @@ * ***** END LICENSE BLOCK ***** */ #include "nsISupports.idl" -#include "nsIBookmarksContainer.idl" +#include "nsIRemoteContainer.idl" interface nsIURI; [scriptable, uuid(b1257934-86cf-4143-8386-734ac352b6ba)] -interface nsILivemarkService : nsIBookmarksContainer +interface nsILivemarkService : nsIRemoteContainer { /** * Creates a new livemark diff --git a/mozilla/browser/components/places/public/nsINavHistoryService.idl b/mozilla/browser/components/places/public/nsINavHistoryService.idl index 1784aeea6f0..6dc89225d24 100644 --- a/mozilla/browser/components/places/public/nsINavHistoryService.idl +++ b/mozilla/browser/components/places/public/nsINavHistoryService.idl @@ -42,6 +42,8 @@ interface nsIFile; interface nsINavHistoryContainerResultNode; +interface nsINavHistoryQueryResultNode; +interface nsINavHistoryFolderResultNode; interface nsINavHistoryQuery; interface nsINavHistoryQueryOptions; interface nsITransactionManager; @@ -58,15 +60,20 @@ interface nsINavHistoryResultNode : nsISupports readonly attribute nsINavHistoryContainerResultNode parent; /** - * Identifies the type of this node. + * Identifies the type of this node. This node can then be QI-ed to the + * corresponding specialized result node interface. The remote_container one + * is a little weird, it is a temportary folder generated by the remote + * container API. Note that bookmark folders can also be filled by the + * remote container API (these are the entrypoints for the API) and may + * have a remote container type as well. */ - const PRUint32 RESULT_TYPE_URI = 0; - const PRUint32 RESULT_TYPE_VISIT = 1; - const PRUint32 RESULT_TYPE_FULL_VISIT = 2; - const PRUint32 RESULT_TYPE_HOST = 3; - const PRUint32 RESULT_TYPE_DAY = 4; - const PRUint32 RESULT_TYPE_QUERY = 5; - const PRUint32 RESULT_TYPE_FOLDER = 6; + const PRUint32 RESULT_TYPE_URI = 0; // nsINavHistoryURIResultNode + const PRUint32 RESULT_TYPE_VISIT = 1; // nsINavHistoryVisitResultNode + const PRUint32 RESULT_TYPE_FULL_VISIT = 2; // nsINavHistoryFullVisitResultNode + const PRUint32 RESULT_TYPE_HOST = 3; // nsINavHistoryContainerResultNode + const PRUint32 RESULT_TYPE_REMOTE_CONTAINER = 4; // nsINavHistoryContainerResultNode + const PRUint32 RESULT_TYPE_QUERY = 5; // nsINavHistoryQueryResultNode + const PRUint32 RESULT_TYPE_FOLDER = 6; // nsINavHistoryFolderResultNode readonly attribute PRUint32 type; /** @@ -233,6 +240,97 @@ interface nsINavHistoryContainerResultNode : nsINavHistoryResultNode * been called to override it, and true for non-folder nodes. */ readonly attribute boolean childrenReadOnly; + + // -------------------------------------------------------------------------- + // Remote container + + /** + * This is a string representing the remote container API service that is + * responsible for this container. It is empty if there is none. This can + * be set for bookmark folders which have been registered, and also for + * RESULT_TYPE_REMOTE_CONTAINER nodes which have been dynamically generated + * by the remote container API. + */ + readonly attribute AUTF8String remoteContainerType; + + /** + * Appends a full visit node to this container and returns it. For the remote + * container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * @see nsINavHistoryURIResultNode for parameters. + */ + nsINavHistoryURIResultNode appendURINode( + in AUTF8String aTitle, in PRUint32 aAccessCount, in PRTime aTime, + in AUTF8String aIconURI, in AUTF8String aURI); + + /** + * Appends a full visit node to this container and returns it. For the remote + * container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * @see nsINavHistoryVisitResultNode for parameters. + */ + nsINavHistoryVisitResultNode appendVisitNode( + in AUTF8String aTitle, in PRUint32 aAccessCount, in PRTime aTime, + in AUTF8String aIconURI, in AUTF8String aURI, in PRInt64 aSession); + + /** + * Appends a full visit node to this container and returns it. For the remote + * container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * @see nsINavHistoryFullVisitResultNode for parameters. + */ + nsINavHistoryFullVisitResultNode appendFullVisitNode( + in AUTF8String aTitle, in PRUint32 aAccessCount, in PRTime aTime, + in AUTF8String aIconURI, in AUTF8String aURI, in PRInt64 aSession, + in PRInt64 aVisitId, in PRInt64 aReferringVisitId, + in PRInt32 aTransitionType); + + /** + * Appends a container node to this container and returns it. For the remote + * container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * aContainerType should be either RESULT_TYPE_HOST or + * RESULT_TYPE_REMOTE_CONTAINER. When type is remote container you must + * specify a remote container type, otherwise, the remote container type must + * be null. Use appendQueryNode and appendFolderNode for the other container + * types. + */ + nsINavHistoryContainerResultNode appendContainerNode( + in AUTF8String aTitle, in AUTF8String aIconURI, in PRUint32 aContainerType, + in AUTF8String aRemoteContainerType); + + /** + * Appends a query node to this container and returns it. For the remote + * container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * Normally you should supply an empty string for IconURI and it will take + * the default query icon for the current theme. + */ + nsINavHistoryQueryResultNode appendQueryNode( + in AUTF8String aTitle, in AUTF8String aIconURI, in AUTF8String aQueryString); + + /** + * Appends a bookmark folder node to this container and returns it. For the + * remote container API. TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening() + * ONLY, and only for non-bookmark-folder containers. + * + * All container attributes will come from the boomkarks service for this + * folder. + */ + nsINavHistoryFolderResultNode appendFolderNode(in PRInt64 aFolderId); + + /** + * Clears all children of this container. For the remote container API. + * TO BE CALLED FROM nsIRemoteContainer::OnContainerOpening and + * nsIRemoteContainer::OnContainerClosed ONLY, and valid only for + * non-bookmark-folder containers. + */ + void clearContents(); }; @@ -635,13 +733,6 @@ interface nsINavHistoryQuery : nsISupports [scriptable, uuid(25fd4de4-33b0-475e-a63d-2bcb1d123e0d)] interface nsINavHistoryQueryOptions : nsISupports { - /** - * Grouping by day. The results will be an array of nsINavHistoryResults with - * type = RESULT_TYPE_DAY, one for each day where there are results. These - * will have children of corresponding to the search results of that day. - */ - const PRUint32 GROUP_BY_DAY = 0; - /** * Groping by exact host. The results will be an array of nsINavHistoryResults * with type = RESULT_TYPE_HOST, one for each unique host (for example, @@ -709,12 +800,9 @@ interface nsINavHistoryQueryOptions : nsISupports /** * The grouping mode to be used for this query. - * Grouping mode is an array of GROUP_BY_* values that specifies the structure - * of the tree you want. For example, an array consisting of - * [GROUP_BY_DAY, GROUP_BY_DOMAIN] will give you a tree whose first level is - * a list of days, and whose second level is a list of domains, and whose - * third level is a list of pages in those domains. If you don't want a tree, - * you can specify an empty array. + * Grouping mode is an array of GROUP_BY_* values that specifies the + * structure of the tree you want. If you don't want grouping, you can + * specify an empty array. */ void getGroupingMode(out PRUint32 groupCount, [retval,array,size_is(groupCount)] out PRUint32 groupingMode); diff --git a/mozilla/browser/components/places/public/nsIRemoteContainer.idl b/mozilla/browser/components/places/public/nsIRemoteContainer.idl new file mode 100644 index 00000000000..9a7d1698634 --- /dev/null +++ b/mozilla/browser/components/places/public/nsIRemoteContainer.idl @@ -0,0 +1,141 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Places. + * + * The Initial Developer of the Original Code is + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Annie Sullivan (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIURI; +interface nsINavHistoryContainerResultNode; +interface nsINavHistoryQueryOptions; + +/** + * The Remote Container interface provides a base class for services that want + * to provide containers for bookmarks. Some examples of possible services are + * the livemarks service and the filesystem. + * + * There are two primary modes of operation: container services might create + * actual bookmarks, or they might fill containers on the fly as needed. The + * livemarks service, for example, queries the feed from time to time and + * creates actual bookmarks in the folder corresponding to the feed. This way + * the items are persistent even if the user is offline, and can be searched. + * In this mode, the service just looks for moves and deletes to update the + * corresponding bookkeeping information. It can use the normal population + * method provided by the bookmark service and need not do any work for the + * onContainerOpen message. + * + * Such a bookmark-based container service might listen for onContainerOpening + * notifications messages to see whether + + * + * Persistent bookmarks are not appropriate for more short-lived data, such as + * the filesystem interface. In this case, the service can fill result nodes + * directly into the container when it is being opened. It can use the property + * bag on every result node to store data associated with each item, such as + * full path on disk. It would create additional containers for each folder, + * resgistered to its service. These dynamic containers are not bookmark + * folders in contrast to the initial item. + */ + +[scriptable, uuid(45bf2020-9683-498c-9638-f08130c4151d)] +interface nsIRemoteContainer : nsISupports +{ + + /** + * Called when the given container is about to be populated so that the + * service can populate the container if necessary. + * + * @param container The container node for the container being opened. + * If the node type is a bookmarks container, you can + * QI it to nsINavHistoryFolderResultNode and access the + * folder ID, etc. Note that all result nodes implement + * a property bag if you need to store state. + * @param options The options used to generate this query. Containers + * should follow these when possible, for example, + * whether to expand queries, etc. Implementations should + * use this when possible if adding query and folder nodes + * to the container. DO NOT MODIFY THIS VALUE. + */ + void onContainerOpening(in nsINavHistoryContainerResultNode container, + in nsINavHistoryQueryOptions options); + + /** + * Called when the given container has just been hidden so that the service + * can do any necessary cleanup. This is NOT guaranteed to get called. In + * particular, if the query just goes away (like the user switched views on + * the places page) you will not get this call. This only happens when the + * container itself goes from the open state to the closed state. A serviced + * with large numbers of dynamically populated items might use this to do + * some cleanup so those items don't hang around + * + * @param container The container node of the container being closed. The + * service need not worry about removing any created nodes, + * they will be automatically removed when this call + * completes. + */ + void onContainerClosed(in nsINavHistoryContainerResultNode container); + + /** + * Called when the given container is about to be deleted, so + * that the service can do any necessary cleanup. + * Called BEFORE the container is deleted, so that the service + * can still reference it. + * @param container The folderId of the bookmark folder + * representing the container to be deleted. + */ + void onContainerRemoving(in PRInt64 container); + + /** + * Called when the given container has just been moved, in case + * the service needs to do any bookkeeping. + * Called AFTER the container has been moved, so the service can + * get the new URI. + * @param container The folderId of the bookmark folder + * representing the container to be moved. + * @param newFolder The folderId of the new parent folder + * for the container. + * @param newIndex The index the container will be inserted at, + * or -1 for append. + */ + void onContainerMoved(in PRInt64 container, + in PRInt64 newFolder, in PRInt32 newIndex); + + /** + * Returns true if containers of this type should not expose UI for + * inserting, moving, or deleting children. + */ + readonly attribute boolean childrenReadOnly; +}; diff --git a/mozilla/browser/components/places/src/nsLivemarkService.cpp b/mozilla/browser/components/places/src/nsLivemarkService.cpp index 604ba7b6449..7dda00cae22 100755 --- a/mozilla/browser/components/places/src/nsLivemarkService.cpp +++ b/mozilla/browser/components/places/src/nsLivemarkService.cpp @@ -39,6 +39,7 @@ #include "nsLivemarkService.h" #include "nsIServiceManager.h" #include "nsNavBookmarks.h" +#include "nsNavHistoryResult.h" #include "nsIAnnotationService.h" #include "nsNetUtil.h" #include "rdf.h" @@ -95,7 +96,7 @@ nsLivemarkService::~nsLivemarkService() mTimer = nsnull; } // Cancel any pending loads - for (PRInt32 i = 0; i < mLivemarks.Length(); ++i) { + for (PRUint32 i = 0; i < mLivemarks.Length(); ++i) { LivemarkInfo *li = mLivemarks[i]; if (li->loadGroup) { li->loadGroup->Cancel(NS_BINDING_ABORTED); @@ -105,7 +106,7 @@ nsLivemarkService::~nsLivemarkService() NS_IMPL_ISUPPORTS2(nsLivemarkService, nsILivemarkService, - nsIBookmarksContainer) + nsIRemoteContainer) nsresult nsLivemarkService::Init() @@ -186,7 +187,7 @@ nsLivemarkService::Init() &pLivemarks); NS_ENSURE_SUCCESS(rv, rv); - for (PRInt32 i = 0; i < numLivemarks; ++i) { + for (PRUint32 i = 0; i < numLivemarks; ++i) { // Get the feed URI from the annotation. nsAutoString feedURIString; @@ -198,26 +199,24 @@ nsLivemarkService::Init() rv = NS_NewURI(getter_AddRefs(feedURI), NS_ConvertUTF16toUTF8(feedURIString)); NS_ENSURE_SUCCESS(rv, rv); - // Use QueryStringToQueries() to get the folderId from the place:uri. - // (It ends up in folders[0]) + // Use QueryStringToQueryArray() to get the folderId from the place:uri. + // (It ends up in folders[0] since we know that this place: uri was + // generated by the bookmark service to uniquely identify the folder) nsCAutoString folderQueryString; rv = pLivemarks[i]->GetSpec(folderQueryString); NS_ENSURE_SUCCESS(rv, rv); - PRUint32 resultCount; - nsINavHistoryQuery** queries = nsnull; - nsCOMPtr options; - rv = History()->QueryStringToQueries(folderQueryString, - &queries, - &resultCount, - getter_AddRefs(options)); - NS_ENSURE_SUCCESS(rv, rv); - PRUint32 folderCount; - PRInt64 *folders = nsnull; - rv = queries[0]->GetFolders(&folderCount, &folders); + + nsCOMArray queries; + nsCOMPtr options; + rv = History()->QueryStringToQueryArray(folderQueryString, &queries, + getter_AddRefs(options)); NS_ENSURE_SUCCESS(rv, rv); + if (queries.Count() != 1 || queries[0]->Folders().Length() != 1) + continue; // invalid folder URI (should identify exactly one folder) // Create the livemark and add it to the list. - LivemarkInfo *li = new LivemarkInfo(folders[0], pLivemarks[i], feedURI); + LivemarkInfo *li = new LivemarkInfo(queries[0]->Folders()[0], + pLivemarks[i], feedURI); NS_ENSURE_TRUE(li, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(mLivemarks.AppendElement(li), NS_ERROR_OUT_OF_MEMORY); } @@ -283,17 +282,18 @@ nsLivemarkService::CreateLivemark(PRInt64 aFolder, NS_IMETHODIMP -nsLivemarkService::OnContainerOpening(PRInt64 aContainer, PRBool * _result) +nsLivemarkService::OnContainerOpening( + nsINavHistoryContainerResultNode* container, + nsINavHistoryQueryOptions* options) { // Nothing to do here since the containers are filled in // as the livemarks are loaded through FireTimer(). - *_result = PR_FALSE; return NS_OK; } NS_IMETHODIMP -nsLivemarkService::OnContainerClosed(PRInt64 aContainer) +nsLivemarkService::OnContainerClosed(nsINavHistoryContainerResultNode* container) { // Nothing to clean up return NS_OK; @@ -308,7 +308,7 @@ nsLivemarkService::OnContainerRemoving(PRInt64 aContainer) // Find the livemark id in the list of livemarks. PRInt32 lmIndex = -1; PRInt32 i; - for (i = 0; i < mLivemarks.Length(); i++) { + for (i = 0; i < PRInt32(mLivemarks.Length()); i++) { if (mLivemarks[i]->folderId == aContainer) { lmIndex = i; break; @@ -332,7 +332,7 @@ nsLivemarkService::OnContainerRemoving(PRInt64 aContainer) // If not, remove the annotations for the feed. PRBool stillInUse = PR_FALSE; PRBool urisEqual = PR_FALSE; - for (i = 0; i < mLivemarks.Length(); i++) { + for (i = 0; i < PRInt32(mLivemarks.Length()); i++) { if (i != lmIndex && (NS_OK == mLivemarks[i]->feedURI->Equals(removedItem->feedURI, &urisEqual)) && urisEqual) { @@ -369,7 +369,7 @@ nsLivemarkService::OnContainerMoved(PRInt64 aContainer, // Find the livemark in the list. PRInt32 index = -1; - for (PRInt32 i = 0; i < mLivemarks.Length(); i++) { + for (PRInt32 i = 0; i < PRInt32(mLivemarks.Length()); i++) { if (mLivemarks[i]->folderId == aContainer) { index = i; break; @@ -436,7 +436,7 @@ nsLivemarkService::FireTimer(nsITimer* aTimer, void* aClosure) if (!lmks) return; // Go through all of the livemarks, and check if each needs to be updated. - for (PRInt32 i = 0; i < lmks->mLivemarks.Length(); i++) { + for (PRUint32 i = 0; i < lmks->mLivemarks.Length(); i++) { lmks->UpdateLivemarkChildren(i); } } diff --git a/mozilla/browser/components/places/src/nsLivemarkService.h b/mozilla/browser/components/places/src/nsLivemarkService.h index 13b114faf06..8cf8237e0a1 100755 --- a/mozilla/browser/components/places/src/nsLivemarkService.h +++ b/mozilla/browser/components/places/src/nsLivemarkService.h @@ -52,7 +52,7 @@ class nsLivemarkService : public nsILivemarkService { public: NS_DECL_ISUPPORTS - NS_DECL_NSIBOOKMARKSCONTAINER + NS_DECL_NSIREMOTECONTAINER NS_DECL_NSILIVEMARKSERVICE nsLivemarkService(); diff --git a/mozilla/browser/components/places/src/nsNavBookmarks.cpp b/mozilla/browser/components/places/src/nsNavBookmarks.cpp index f7bf23b2e5b..145d45f2978 100644 --- a/mozilla/browser/components/places/src/nsNavBookmarks.cpp +++ b/mozilla/browser/components/places/src/nsNavBookmarks.cpp @@ -43,7 +43,7 @@ #include "nsIServiceManager.h" #include "nsNetUtil.h" #include "nsIAnnotationService.h" -#include "nsIBookmarksContainer.h" +#include "nsIRemoteContainer.h" const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ItemChild = 0; const PRInt32 nsNavBookmarks::kFindBookmarksIndex_FolderChild = 1; @@ -719,12 +719,12 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolder) { // If this is a container bookmark, try to notify its service. nsresult rv; - nsAutoString folderType; + nsCAutoString folderType; rv = GetFolderType(aFolder, folderType); NS_ENSURE_SUCCESS(rv, rv); if (folderType.Length() > 0) { // There is a type associated with this folder; it's a livemark. - nsCOMPtr bmcServ = do_GetService(NS_ConvertUTF16toUTF8(folderType).get()); + nsCOMPtr bmcServ = do_GetService(folderType.get()); if (bmcServ) { rv = bmcServ->OnContainerRemoving(aFolder); if (NS_FAILED(rv)) @@ -796,16 +796,16 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolder) nsTArray folderChildren; { mozStorageStatementScoper scope(mDBGetFolderChildren); - rv = mDBGetChildren->BindInt64Parameter(0, aFolder); + rv = mDBGetFolderChildren->BindInt64Parameter(0, aFolder); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBGetChildren->BindInt32Parameter(1, 0); + rv = mDBGetFolderChildren->BindInt32Parameter(1, 0); NS_ENSURE_SUCCESS(rv, rv); - rv = mDBGetChildren->BindInt32Parameter(2, PR_INT32_MAX); + rv = mDBGetFolderChildren->BindInt32Parameter(2, PR_INT32_MAX); NS_ENSURE_SUCCESS(rv, rv); PRBool more; - while (NS_SUCCEEDED(rv = mDBGetChildren->ExecuteStep(&more)) && more) { - folderChildren.AppendElement(mDBGetChildren->AsInt64(kGetChildrenIndex_FolderChild)); + while (NS_SUCCEEDED(rv = mDBGetFolderChildren->ExecuteStep(&more)) && more) { + folderChildren.AppendElement(mDBGetFolderChildren->AsInt64(kGetChildrenIndex_FolderChild)); } } @@ -944,10 +944,23 @@ nsNavBookmarks::MoveFolder(PRInt64 aFolder, PRInt64 aNewParent, PRInt32 aIndex) rv = transaction.Commit(); NS_ENSURE_SUCCESS(rv, rv); + // notify bookmark observers ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver, OnFolderMoved(aFolder, parent, oldIndex, aNewParent, newIndex)) + // notify remote container provider if there is one + nsCAutoString type; + rv = GetFolderType(aFolder, type); + NS_ENSURE_SUCCESS(rv, rv); + if (! type.IsEmpty()) { + nsCOMPtr container = + do_GetService(type.get(), &rv); + if (NS_SUCCEEDED(rv)) { + rv = container->OnContainerMoved(aFolder, aNewParent, newIndex); + NS_ENSURE_SUCCESS(rv, rv); + } + } return NS_OK; } @@ -1051,7 +1064,7 @@ nsNavBookmarks::GetFolderTitle(PRInt64 aFolder, nsAString &aTitle) nsresult -nsNavBookmarks::GetFolderType(PRInt64 aFolder, nsAString &aType) +nsNavBookmarks::GetFolderType(PRInt64 aFolder, nsACString &aType) { mozStorageStatementScoper scope(mDBGetFolderInfo); nsresult rv = mDBGetFolderInfo->BindInt64Parameter(0, aFolder); @@ -1065,7 +1078,7 @@ nsNavBookmarks::GetFolderType(PRInt64 aFolder, nsAString &aType) return NS_ERROR_INVALID_ARG; } - return mDBGetFolderInfo->GetString(kGetFolderInfoIndex_Type, aType); + return mDBGetFolderInfo->GetUTF8String(kGetFolderInfoIndex_Type, aType); } nsresult @@ -1090,19 +1103,10 @@ nsNavBookmarks::ResultNodeForFolder(PRInt64 aID, nsCAutoString title; rv = mDBGetFolderInfo->GetUTF8String(kGetFolderInfoIndex_Title, title); - if (folderType.IsEmpty()) { - *aNode = new nsNavHistoryFolderResultNode(title, 0, 0, aOptions, aID); - if (! *aNode) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aNode); - } else { - // a container API thing - // FIXME(brettw) - //NS_NOTREACHED("FIXME: Not implemented"); - *aNode = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; - } - + *aNode = new nsNavHistoryFolderResultNode(title, aOptions, aID, folderType); + if (! *aNode) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*aNode); return NS_OK; } @@ -1118,7 +1122,7 @@ nsNavBookmarks::GetFolderURI(PRInt64 aFolder, nsIURI **aURI) // correct string here. // // If you change this, change IsSimpleFolderURI which detects this string. - nsCAutoString spec("place:folders="); + nsCAutoString spec("place:folder="); spec.AppendInt(aFolder); spec.AppendLiteral("&group=3"); // GROUP_BY_FOLDER return NS_NewURI(aURI, spec); @@ -1127,15 +1131,15 @@ nsNavBookmarks::GetFolderURI(PRInt64 aFolder, nsIURI **aURI) NS_IMETHODIMP nsNavBookmarks::GetFolderReadonly(PRInt64 aFolder, PRBool *aResult) { - // Ask the folder's nsIBookmarksContainer for the readonly property. + // Ask the folder's nsIRemoteContainer for the readonly property. *aResult = PR_FALSE; - nsAutoString type; + nsCAutoString type; nsresult rv = GetFolderType(aFolder, type); NS_ENSURE_SUCCESS(rv, rv); if (!type.IsEmpty()) { - nsCOMPtr container = - do_GetService(NS_ConvertUTF16toUTF8(type).get(), &rv); + nsCOMPtr container = + do_GetService(type.get(), &rv); if (NS_SUCCEEDED(rv)) { rv = container->GetChildrenReadOnly(aResult); NS_ENSURE_SUCCESS(rv, rv); diff --git a/mozilla/browser/components/places/src/nsNavBookmarks.h b/mozilla/browser/components/places/src/nsNavBookmarks.h index cc14e1ca7c1..7a20ef35e15 100644 --- a/mozilla/browser/components/places/src/nsNavBookmarks.h +++ b/mozilla/browser/components/places/src/nsNavBookmarks.h @@ -96,7 +96,7 @@ private: PRInt32 aStartIndex, PRInt32 aEndIndex, PRInt32 aDelta); PRInt32 FolderCount(PRInt64 aFolder); - nsresult GetFolderType(PRInt64 aFolder, nsAString &aType); + nsresult GetFolderType(PRInt64 aFolder, nsACString &aType); // remove me when there is better query initialization nsNavHistory* History() { return nsNavHistory::GetHistoryService(); } diff --git a/mozilla/browser/components/places/src/nsNavHistory.cpp b/mozilla/browser/components/places/src/nsNavHistory.cpp index 327e73e1cc4..c51a9396ddd 100644 --- a/mozilla/browser/components/places/src/nsNavHistory.cpp +++ b/mozilla/browser/components/places/src/nsNavHistory.cpp @@ -120,8 +120,8 @@ static PRInt32 GetTLDType(const nsCString& aHostTail); static void GetUnreversedHostname(const nsString& aBackward, nsAString& aForward); static PRBool IsNumericHostName(const nsCString& aHost); -static PRInt64 GetSimpleBookmarksQueryFolder(nsINavHistoryQuery** aQueries, - PRUint32 aQueryCount); +static PRInt64 GetSimpleBookmarksQueryFolder( + const nsCOMArray& aQueries); static void ParseSearchQuery(const nsString& aQuery, nsStringArray* aTerms); inline void ReverseString(const nsString& aInput, nsAString& aReversed) @@ -1192,16 +1192,17 @@ nsNavHistory::NormalizeTime(PRUint32 aRelative, PRTime aOffset) // change operations as simple instead of complex. PRUint32 -nsNavHistory::GetUpdateRequirements(nsCOMArray* aQueries, +nsNavHistory::GetUpdateRequirements(const nsCOMArray& aQueries, nsNavHistoryQueryOptions* aOptions, PRBool* aHasSearchTerms) { - NS_ASSERTION(aQueries->Count() > 0, "Must have at least one query"); + NS_ASSERTION(aQueries.Count() > 0, "Must have at least one query"); // first check if there are search terms *aHasSearchTerms = PR_FALSE; - for (PRInt32 i = 0; i < aQueries->Count(); i ++) { - (*aQueries)[i]->GetHasSearchTerms(aHasSearchTerms); + PRInt32 i; + for (i = 0; i < aQueries.Count(); i ++) { + aQueries[i]->GetHasSearchTerms(aHasSearchTerms); if (*aHasSearchTerms) break; } @@ -1213,13 +1214,8 @@ nsNavHistory::GetUpdateRequirements(nsCOMArray* aQueries, return QUERYUPDATE_COMPLEX; PRBool nonTimeBasedItems = PR_FALSE; - for (i = 0; i < aQueries->Count(); i ++) { - nsresult rv; - nsCOMPtr query = do_QueryInterface((*aQueries)[i], &rv); - if (NS_FAILED(rv)) { - NS_NOTREACHED("Query is not one of our query objects!"); - return QUERYUPDATE_COMPLEX; - } + for (i = 0; i < aQueries.Count(); i ++) { + nsNavHistoryQuery* query = aQueries[i]; if (query->Folders().Length() > 0 || query->OnlyBookmarked()) { return QUERYUPDATE_COMPLEX_WITH_BOOKMARKS; @@ -1232,7 +1228,7 @@ nsNavHistory::GetUpdateRequirements(nsCOMArray* aQueries, nonTimeBasedItems = PR_TRUE; } - if (aQueries->Count() == 1 && ! nonTimeBasedItems) + if (aQueries.Count() == 1 && ! nonTimeBasedItems) return QUERYUPDATE_TIME; return QUERYUPDATE_SIMPLE; } @@ -1253,21 +1249,16 @@ nsNavHistory::GetUpdateRequirements(nsCOMArray* aQueries, // Returns true if node matches the query, false if not. PRBool -nsNavHistory::EvaluateQueryForNode(nsCOMArray* aQueries, +nsNavHistory::EvaluateQueryForNode(const nsCOMArray& aQueries, nsNavHistoryQueryOptions* aOptions, nsNavHistoryURIResultNode* aNode) { // lazily created from the node's string when we need to match URIs nsCOMPtr nodeUri; - nsresult rv; - for (PRInt32 i = 0; i < aQueries->Count(); i ++) { + for (PRInt32 i = 0; i < aQueries.Count(); i ++) { PRBool hasIt; - nsCOMPtr query = do_QueryInterface((*aQueries)[i], &rv); - if (NS_FAILED(rv)) { - NS_NOTREACHED("Query is not one of ours."); - return PR_FALSE; - } + nsCOMPtr query = aQueries[i]; // --- begin time --- query->GetHasBeginTime(&hasIt); @@ -1294,7 +1285,7 @@ nsNavHistory::EvaluateQueryForNode(nsCOMArray* aQueries, nsCOMArray inputSet; inputSet.AppendObject(aNode); nsCOMArray filteredSet; - rv = FilterResultSet(inputSet, &filteredSet, query->SearchTerms()); + nsresult rv = FilterResultSet(inputSet, &filteredSet, query->SearchTerms()); if (NS_FAILED(rv)) continue; if (! filteredSet.Count()) @@ -1336,7 +1327,7 @@ nsNavHistory::EvaluateQueryForNode(nsCOMArray* aQueries, if (! query->UriIsPrefix()) { // easy case: the URI is an exact match PRBool equals; - rv = query->Uri()->Equals(nodeUri, &equals); + nsresult rv = query->Uri()->Equals(nodeUri, &equals); NS_ENSURE_SUCCESS(rv, rv); if (! equals) continue; @@ -1640,21 +1631,33 @@ nsNavHistory::ExecuteQueries(nsINavHistoryQuery** aQueries, PRUint32 aQueryCount nsCOMPtr options = do_QueryInterface(aOptions); NS_ENSURE_TRUE(options, NS_ERROR_INVALID_ARG); + // concrete queries array + nsCOMArray queries; + for (PRUint32 i = 0; i < aQueryCount; i ++) { + nsCOMPtr query = do_QueryInterface(aQueries[i], &rv); + NS_ENSURE_SUCCESS(rv, rv); + queries.AppendObject(query); + } + // root node nsRefPtr rootNode; - PRInt64 folderId = GetSimpleBookmarksQueryFolder(aQueries, aQueryCount); + PRInt64 folderId = GetSimpleBookmarksQueryFolder(queries); if (folderId) { // In the simple case where we're just querying children of a single bookmark // folder, we can more efficiently generate results. - rootNode = new nsNavHistoryFolderResultNode(EmptyCString(), 0, 0, - options, folderId); + nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); + NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY); + nsCOMPtr tempRootNode; + rv = bookmarks->ResultNodeForFolder(folderId, options, + getter_AddRefs(tempRootNode)); + NS_ENSURE_SUCCESS(rv, rv); + rootNode = tempRootNode->GetAsContainer(); } else { // complex query - rootNode = new nsNavHistoryQueryResultNode(options, - EmptyCString(), 0, 0, EmptyCString(), - aQueries, aQueryCount, options); + rootNode = new nsNavHistoryQueryResultNode(EmptyCString(), EmptyCString(), + queries, options); + NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY); } - NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY); // result object nsRefPtr result; @@ -1688,7 +1691,7 @@ nsNavHistory::ExecuteQueries(nsINavHistoryQuery** aQueries, PRUint32 aQueryCount // it ANDed with the all the rest of the queries. nsresult -nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, +nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, nsNavHistoryQueryOptions *aOptions, nsCOMArray* aResults) { @@ -1843,15 +1846,13 @@ nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, for (i = 0; i < aQueries.Count(); i ++) { PRInt32 clauseParameters = 0; rv = BindQueryClauseParameters(statement, numParameters, - NS_CONST_CAST(nsINavHistoryQuery*, aQueries[i]), - &clauseParameters); + aQueries[i], &clauseParameters); NS_ENSURE_SUCCESS(rv, rv); numParameters += clauseParameters; } PRBool hasSearchTerms; - rv = NS_CONST_CAST(nsINavHistoryQuery*, - aQueries[0])->GetHasSearchTerms(&hasSearchTerms); + rv = aQueries[0]->GetHasSearchTerms(&hasSearchTerms); NS_ENSURE_SUCCESS(rv, rv); PRUint32 groupCount; @@ -1868,37 +1869,26 @@ nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, rv = ResultsAsList(statement, aOptions, &toplevel); NS_ENSURE_SUCCESS(rv, rv); - /* FIXME(brettw) if (hasSearchTerms) { // keyword search - nsAutoString searchTerms; - NS_CONST_CAST(nsINavHistoryQuery*, aQueries[0]) - ->GetSearchTerms(searchTerms); if (groupCount == 0) { - FilterResultSet(toplevel, result->GetTopLevel(), searchTerms); + // keyword search with no grouping: can filter directly into the result + FilterResultSet(toplevel, aResults, aQueries[0]->SearchTerms()); } else { + // keyword searching with grouping: need intermediate filtered results nsCOMArray filteredResults; - FilterResultSet(toplevel, &filteredResults, searchTerms); + FilterResultSet(toplevel, &filteredResults, aQueries[0]->SearchTerms()); rv = RecursiveGroup(filteredResults, groupings, groupCount, - result->GetTopLevel()); + aResults); NS_ENSURE_SUCCESS(rv, rv); } - } else */{ + } else { // group unfiltered results rv = RecursiveGroup(toplevel, groupings, groupCount, aResults); NS_ENSURE_SUCCESS(rv, rv); } } - /* - nsNavHistoryContainerResultNode::SortComparator comparator = - nsNavHistoryContainerResultNode::GetSortingComparator( - sortingMode); - if (sortingMode) - nsNavHistoryContainerResultNode::RecursiveSortArray( - aResults, mCollation, comparator); - */ - // automatically expand things that were expanded before // FIXME(brettw) //if (gExpandedItems.Count() > 0) @@ -2526,7 +2516,7 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic, // no way for those to fail. nsresult -nsNavHistory::QueryToSelectClause(nsINavHistoryQuery* aQuery, // const +nsNavHistory::QueryToSelectClause(nsNavHistoryQuery* aQuery, // const PRInt32 aStartParameter, nsCString* aClause, PRInt32* aParamCount, @@ -2559,7 +2549,7 @@ nsNavHistory::QueryToSelectClause(nsINavHistoryQuery* aQuery, // const // search terms FIXME // only bookmarked - if (NS_SUCCEEDED(aQuery->GetOnlyBookmarked(&hasIt)) && hasIt) { + if (aQuery->OnlyBookmarked()) { if (! aClause->IsEmpty()) *aClause += NS_LITERAL_CSTRING(" AND "); @@ -2602,15 +2592,12 @@ nsNavHistory::QueryToSelectClause(nsINavHistoryQuery* aQuery, // const if (! aClause->IsEmpty()) *aClause += NS_LITERAL_CSTRING(" AND "); - PRBool uriIsPrefix; - aQuery->GetUriIsPrefix(&uriIsPrefix); - nsCAutoString paramString; parameterString(aStartParameter + *aParamCount, paramString); (*aParamCount) ++; nsCAutoString match; - if (uriIsPrefix) { + if (aQuery->UriIsPrefix()) { // Prefix: want something of the form SUBSTR(h.url, 0, length(?1)) = ?1 *aClause += NS_LITERAL_CSTRING("SUBSTR(h.url, 0, LENGTH(") + paramString + NS_LITERAL_CSTRING(")) = ") + paramString; @@ -2625,14 +2612,11 @@ nsNavHistory::QueryToSelectClause(nsINavHistoryQuery* aQuery, // const if (! aClause->IsEmpty()) *aClause += NS_LITERAL_CSTRING(" AND "); if (hasIt) { - PRBool notAnnotation; - aQuery->GetAnnotationIsNot(¬Annotation); - nsCAutoString paramString; parameterString(aStartParameter + *aParamCount, paramString); (*aParamCount) ++; - if (notAnnotation) + if (aQuery->AnnotationIsNot()) aClause->AppendLiteral("NOT "); aClause->AppendLiteral("EXISTS (SELECT anno_id FROM moz_anno anno WHERE anno.page = h.id AND anno.name = "); aClause->Append(paramString); @@ -2655,7 +2639,7 @@ nsNavHistory::QueryToSelectClause(nsINavHistoryQuery* aQuery, // const nsresult nsNavHistory::BindQueryClauseParameters(mozIStorageStatement* statement, PRInt32 aStartParameter, - nsINavHistoryQuery* aQuery, // const + nsNavHistoryQuery* aQuery, // const PRInt32* aParamCount) { nsresult rv; @@ -2665,11 +2649,8 @@ nsNavHistory::BindQueryClauseParameters(mozIStorageStatement* statement, // begin time if (NS_SUCCEEDED(aQuery->GetHasBeginTime(&hasIt)) && hasIt) { - PRTime time; - aQuery->GetBeginTime(&time); - PRUint32 timeReference; - aQuery->GetBeginTimeReference(&timeReference); - time = NormalizeTime(timeReference, time); + PRTime time = NormalizeTime(aQuery->BeginTimeReference(), + aQuery->BeginTime()); rv = statement->BindInt64Parameter(aStartParameter + *aParamCount, time); NS_ENSURE_SUCCESS(rv, rv); (*aParamCount) ++; @@ -2677,11 +2658,8 @@ nsNavHistory::BindQueryClauseParameters(mozIStorageStatement* statement, // end time if (NS_SUCCEEDED(aQuery->GetHasEndTime(&hasIt)) && hasIt) { - PRTime time; - aQuery->GetEndTime(&time); - PRUint32 timeReference; - aQuery->GetEndTimeReference(&timeReference); - time = NormalizeTime(timeReference, time); + PRTime time = NormalizeTime(aQuery->EndTimeReference(), + aQuery->EndTime()); rv = statement->BindInt64Parameter(aStartParameter + *aParamCount, time); NS_ENSURE_SUCCESS(rv, rv); (*aParamCount) ++; @@ -2693,14 +2671,10 @@ nsNavHistory::BindQueryClauseParameters(mozIStorageStatement* statement, // domain (see GetReversedHostname for more info on reversed host names) if (NS_SUCCEEDED(aQuery->GetHasDomain(&hasIt)) && hasIt) { - nsCAutoString domain; - aQuery->GetDomain(domain); nsString revDomain; - GetReversedHostname(NS_ConvertUTF8toUTF16(domain), revDomain); + GetReversedHostname(NS_ConvertUTF8toUTF16(aQuery->Domain()), revDomain); - PRBool domainIsHost = PR_FALSE; - aQuery->GetDomainIsHost(&domainIsHost); - if (domainIsHost) { + if (aQuery->DomainIsHost()) { rv = statement->BindStringParameter(aStartParameter + *aParamCount, revDomain); NS_ENSURE_SUCCESS(rv, rv); (*aParamCount) ++; @@ -2722,21 +2696,15 @@ nsNavHistory::BindQueryClauseParameters(mozIStorageStatement* statement, // URI if (NS_SUCCEEDED(aQuery->GetHasUri(&hasIt)) && hasIt) { - nsCOMPtr uri; - rv = aQuery->GetUri(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); // if (hasUri) then it should be valid - BindStatementURI(statement, aStartParameter + *aParamCount, uri); + BindStatementURI(statement, aStartParameter + *aParamCount, aQuery->Uri()); (*aParamCount) ++; } // annotation aQuery->GetHasAnnotation(&hasIt); if (hasIt) { - nsCAutoString annotationName; - aQuery->GetAnnotation(annotationName); rv = statement->BindUTF8StringParameter(aStartParameter + *aParamCount, - annotationName); + aQuery->Annotation()); NS_ENSURE_SUCCESS(rv, rv); } @@ -2791,9 +2759,6 @@ nsNavHistory::RecursiveGroup(const nsCOMArray& aSource, nsresult rv; switch (aGroupingMode[0]) { - case nsINavHistoryQueryOptions::GROUP_BY_DAY: - rv = GroupByDay(aSource, aDest); - break; case nsINavHistoryQueryOptions::GROUP_BY_HOST: rv = GroupByHost(aSource, aDest, PR_FALSE); break; @@ -2825,18 +2790,6 @@ nsNavHistory::RecursiveGroup(const nsCOMArray& aSource, } -// nsNavHistory::GroupByDay -// -// FIXME TODO IMPLEMENT ME (or maybe we don't care about this?) - -nsresult -nsNavHistory::GroupByDay(const nsCOMArray& aSource, - nsCOMArray* aDest) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - - // nsNavHistory::GroupByHost // // OPTIMIZATION: This parses the URI of each node that is coming in. This @@ -2892,7 +2845,7 @@ nsNavHistory::GroupByHost(const nsCOMArray& aSource, TitleForDomain(curHostName, title); curTopGroup = new nsNavHistoryContainerResultNode(title, EmptyCString(), - nsNavHistoryResultNode::RESULT_TYPE_HOST); + nsNavHistoryResultNode::RESULT_TYPE_HOST, PR_TRUE, EmptyCString()); if (! curTopGroup) return NS_ERROR_OUT_OF_MEMORY; @@ -2955,29 +2908,28 @@ nsNavHistory::FilterResultSet(const nsCOMArray& aSet, } */ - /* FIXME(brettw) for (PRInt32 termIndex = 0; termIndex < terms.Count(); termIndex ++) { PRBool termFound = PR_FALSE; // title and URL if (CaseInsensitiveFindInReadable(*terms[termIndex], NS_ConvertUTF8toUTF16(aSet[nodeIndex]->mTitle)) || - CaseInsensitiveFindInReadable(*terms[termIndex], - NS_ConvertUTF8toUTF16(aSet[nodeIndex]->mUrl))) + (aSet[nodeIndex]->IsURI() && + CaseInsensitiveFindInReadable(*terms[termIndex], + NS_ConvertUTF8toUTF16(aSet[nodeIndex]->GetAsURI()->mURI)))) termFound = PR_TRUE; // searchable annotations - if (! termFound) { + /*if (! termFound) { for (PRInt32 annotIndex = 0; annotIndex < curAnnotations.Count(); annotIndex ++) { if (CaseInsensitiveFindInReadable(*terms[termIndex], *curAnnotations[annotIndex])) termFound = PR_TRUE; } - } + }*/ if (! termFound) { allTermsFound = PR_FALSE; break; } } - */ if (allTermsFound) aFiltered->AppendObject(aSet[nodeIndex]); } @@ -3077,41 +3029,8 @@ nsNavHistory::RowToResult(mozIStorageValueArray* aRow, NS_ENSURE_SUCCESS(rv, rv); if (IsQueryURI(url)) { - nsINavHistoryQuery** queries; - PRUint32 queryCount; - nsCOMPtr subIOptions; - rv = QueryStringToQueries(url, &queries, &queryCount, - getter_AddRefs(subIOptions)); - if (NS_FAILED(rv)) { - // This was a query that did not parse, what do we do? We don't want to - // return failure since that will kill the whole query process. Instead - // make a query node with the query as a string. This way we have a valid - // node for the user to manipulate, but it will never populate since the - // query string is invalid. - *aResult = new nsNavHistoryQueryResultNode(aOptions, title, accessCount, - time, favicon, url); - } else { - nsCOMPtr subOptions = - do_QueryInterface(subIOptions, &rv); - NS_ASSERTION(NS_SUCCEEDED(rv), "Options must be our concrete ones"); - PRInt64 folderId = GetSimpleBookmarksQueryFolder(queries, queryCount); - if (folderId) { - // simple bookmarks folder, magically generate a bookmarks folder node - *aResult = new nsNavHistoryFolderResultNode(title, 0, 0, - subOptions, folderId); - } else { - // regular query - *aResult = new nsNavHistoryQueryResultNode(subOptions, title, 0, - 0, EmptyCString(), - queries, queryCount, - subOptions); - } - nsMemory::Free(queries); - } - if (! *aResult) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*aResult); - return NS_OK; + // special case "place:" URIs: turn them into containers + return QueryRowToResult(url, title, accessCount, time, favicon, aResult); } else if (aOptions->ResultType() == nsNavHistoryQueryOptions::RESULTS_AS_URI) { *aResult = new nsNavHistoryURIResultNode(title, accessCount, time, favicon, url); @@ -3164,6 +3083,54 @@ nsNavHistory::RowToResult(mozIStorageValueArray* aRow, } +// nsNavHistory::QueryRowToResult +// +// Called by RowToResult when the URI is a place: URI to generate the proper +// folder or query node. + +nsresult +nsNavHistory::QueryRowToResult(const nsACString& aURI, const nsACString& aTitle, + PRUint32 aAccessCount, PRTime aTime, + const nsACString& aFavicon, + nsNavHistoryResultNode** aNode) +{ + nsCOMArray queries; + nsCOMPtr options; + nsresult rv = QueryStringToQueryArray(aURI, &queries, + getter_AddRefs(options)); + if (NS_FAILED(rv)) { + // This was a query that did not parse, what do we do? We don't want to + // return failure since that will kill the whole query process. Instead + // make a query node with the query as a string. This way we have a valid + // node for the user to manipulate that will look like a query, but it will + // never populate since the query string is invalid. + *aNode = new nsNavHistoryQueryResultNode(aTitle, aFavicon, aURI); + if (! *aNode) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*aNode); + } else { + PRInt64 folderId = GetSimpleBookmarksQueryFolder(queries); + if (folderId) { + // simple bookmarks folder, magically generate a bookmarks folder node + nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); + NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY); + + // this addrefs for us + rv = bookmarks->ResultNodeForFolder(folderId, options, aNode); + NS_ENSURE_SUCCESS(rv, rv); + } else { + // regular query + *aNode = new nsNavHistoryQueryResultNode(aTitle, EmptyCString(), + queries, options); + if (! *aNode) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*aNode); + } + } + return NS_OK; +} + + // nsNavHistory::VisitIdToResultNode // // Used by the query results to create new nodes on the fly when @@ -3473,13 +3440,12 @@ PRBool IsNumericHostName(const nsCString& aHost) // Returns the folder ID if it is a simple folder query, 0 if not. static PRInt64 -GetSimpleBookmarksQueryFolder(nsINavHistoryQuery** aQueries, PRUint32 aQueryCount) +GetSimpleBookmarksQueryFolder(const nsCOMArray& aQueries) { - if (aQueryCount != 1) + if (aQueries.Count() != 1) return 0; - nsresult rv; - nsCOMPtr query = do_QueryInterface(aQueries[0], &rv); + nsNavHistoryQuery* query = aQueries[0]; if (query->Folders().Length() != 1) return 0; diff --git a/mozilla/browser/components/places/src/nsNavHistory.h b/mozilla/browser/components/places/src/nsNavHistory.h index 0df85827a0a..b640bf70689 100644 --- a/mozilla/browser/components/places/src/nsNavHistory.h +++ b/mozilla/browser/components/places/src/nsNavHistory.h @@ -200,7 +200,7 @@ public: // this actually executes a query and gives you results, it is used by // nsNavHistoryQueryResultNode - nsresult GetQueryResults(const nsCOMArray& aQueries, + nsresult GetQueryResults(const nsCOMArray& aQueries, nsNavHistoryQueryOptions *aOptions, nsCOMArray* aResults); @@ -209,6 +209,10 @@ public: nsresult RowToResult(mozIStorageValueArray* aRow, nsNavHistoryQueryOptions* aOptions, nsNavHistoryResultNode** aResult); + nsresult QueryRowToResult(const nsACString& aURI, const nsACString& aTitle, + PRUint32 aAccessCount, PRTime aTime, + const nsACString& aFavicon, + nsNavHistoryResultNode** aNode); nsresult VisitIdToResultNode(PRInt64 visitId, nsNavHistoryQueryOptions* aOptions, @@ -233,10 +237,10 @@ public: static const char kAnnotationPreviousEncoding[]; // used by query result nodes to update: see comment on body of CanLiveUpdateQuery - static PRUint32 GetUpdateRequirements(nsCOMArray* aQueries, + static PRUint32 GetUpdateRequirements(const nsCOMArray& aQueries, nsNavHistoryQueryOptions* aOptions, PRBool* aHasSearchTerms); - PRBool EvaluateQueryForNode(nsCOMArray* aQueries, + PRBool EvaluateQueryForNode(const nsCOMArray& aQueries, nsNavHistoryQueryOptions* aOptions, nsNavHistoryURIResultNode* aNode); @@ -249,6 +253,11 @@ public: const PRUint32* aGroupingMode, PRUint32 aGroupCount, nsCOMArray* aDest); + // better alternative to QueryStringToQueries (in nsNavHistoryQuery.cpp) + nsresult QueryStringToQueryArray(const nsACString& aQueryString, + nsCOMArray* aQueries, + nsNavHistoryQueryOptions** aOptions); + private: ~nsNavHistory(); @@ -319,14 +328,14 @@ protected: nsCOMPtr mExpireNowTimer; static void expireNowTimerCallback(nsITimer* aTimer, void* aClosure); - nsresult QueryToSelectClause(nsINavHistoryQuery* aQuery, + nsresult QueryToSelectClause(nsNavHistoryQuery* aQuery, PRInt32 aStartParameter, nsCString* aClause, PRInt32* aParamCount, const nsACString& aCommonConditions); nsresult BindQueryClauseParameters(mozIStorageStatement* statement, PRInt32 aStartParameter, - nsINavHistoryQuery* aQuery, + nsNavHistoryQuery* aQuery, PRInt32* aParamCount); nsresult ResultsAsList(mozIStorageStatement* statement, @@ -337,8 +346,6 @@ protected: nsresult SetPageTitleInternal(nsIURI* aURI, PRBool aIsUserTitle, const nsAString& aTitle); - nsresult GroupByDay(const nsCOMArray& aSource, - nsCOMArray* aDest); nsresult GroupByHost(const nsCOMArray& aSource, nsCOMArray* aDest, PRBool aIsDomain); @@ -413,7 +420,7 @@ protected: // in nsNavHistoryQuery.cpp nsresult TokensToQueries(const nsTArray& aTokens, - nsCOMArray* aQueries, + nsCOMArray* aQueries, nsNavHistoryQueryOptions* aOptions); // Transaction Manager diff --git a/mozilla/browser/components/places/src/nsNavHistoryQuery.cpp b/mozilla/browser/components/places/src/nsNavHistoryQuery.cpp index 298590d2d52..5444c6d10b2 100644 --- a/mozilla/browser/components/places/src/nsNavHistoryQuery.cpp +++ b/mozilla/browser/components/places/src/nsNavHistoryQuery.cpp @@ -141,7 +141,7 @@ static void SetOptionsKeyUint32(const nsCString& aValue, #define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked" #define QUERYKEY_DOMAIN_IS_HOST "domainIsHost" #define QUERYKEY_DOMAIN "domain" -#define QUERYKEY_FOLDERS "folders" +#define QUERYKEY_FOLDER "folder" #define QUERYKEY_NOTANNOTATION "!annotation" #define QUERYKEY_ANNOTATION "annotation" #define QUERYKEY_URI "uri" @@ -175,7 +175,11 @@ inline void AppendInt64(nsACString& str, PRInt64 i) str.Append(tmp); } + // nsNavHistory::QueryStringToQueries +// +// From C++ places code, you should use QueryStringToQueryArray, this is +// the harder-to-use XPCOM version. NS_IMETHODIMP nsNavHistory::QueryStringToQueries(const nsACString& aQueryString, @@ -183,9 +187,42 @@ nsNavHistory::QueryStringToQueries(const nsACString& aQueryString, PRUint32* aResultCount, nsINavHistoryQueryOptions** aOptions) { - nsresult rv; *aQueries = nsnull; *aResultCount = 0; + nsCOMPtr options; + nsCOMArray queries; + nsresult rv = QueryStringToQueryArray(aQueryString, &queries, + getter_AddRefs(options)); + NS_ENSURE_SUCCESS(rv, rv); + + *aResultCount = queries.Count(); + if (queries.Count() > 0) { + // convert COM array to raw + *aQueries = NS_STATIC_CAST(nsINavHistoryQuery**, + nsMemory::Alloc(sizeof(nsINavHistoryQuery*) * queries.Count())); + NS_ENSURE_TRUE(*aQueries, NS_ERROR_OUT_OF_MEMORY); + for (PRInt32 i = 0; i < queries.Count(); i ++) { + (*aQueries)[i] = queries[i]; + NS_ADDREF((*aQueries)[i]); + } + } + NS_ADDREF(*aOptions = options); + return NS_OK; +} + + +// nsNavHistory::QueryStringToQueryArray +// +// An internal version of QueryStringToQueries that fills a COM array for +// ease-of-use. + +nsresult +nsNavHistory::QueryStringToQueryArray(const nsACString& aQueryString, + nsCOMArray* aQueries, + nsNavHistoryQueryOptions** aOptions) +{ + nsresult rv; + aQueries->Clear(); *aOptions = nsnull; nsRefPtr options(new nsNavHistoryQueryOptions()); @@ -196,30 +233,14 @@ nsNavHistory::QueryStringToQueries(const nsACString& aQueryString, rv = TokenizeQueryString(aQueryString, &tokens); NS_ENSURE_SUCCESS(rv, rv); - nsCOMArray queries; - rv = TokensToQueries(tokens, &queries, options); + rv = TokensToQueries(tokens, aQueries, options); + if (NS_FAILED(rv)) { + NS_WARNING("Unable to parse the query string: "); + NS_WARNING(PromiseFlatCString(aQueryString).get()); + } NS_ENSURE_SUCCESS(rv, rv); - NS_STATIC_CAST(nsRefPtr, options).swap(*aOptions); - *aResultCount = queries.Count(); - if (queries.Count() == 0) { - // need to special-case 0 queries since we don't allocate an array - *aQueries = nsnull; - return NS_OK; - } - - // convert COM array to raw - *aQueries = NS_STATIC_CAST(nsINavHistoryQuery**, - nsMemory::Alloc(sizeof(nsINavHistoryQuery*) * queries.Count())); - if (! *aQueries) - return NS_ERROR_OUT_OF_MEMORY; - for (PRInt32 i = 0; i < queries.Count(); i ++) { - (*aQueries)[i] = queries[i]; - NS_ADDREF((*aQueries)[i]); - } - NS_ADDREF(*aOptions = options); - return NS_OK; } @@ -352,7 +373,7 @@ nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries, query->GetFolders(&folderCount, &folders); for (PRUint32 i = 0; i < folderCount; ++i) { AppendAmpersandIfNonempty(aQueryString); - aQueryString += NS_LITERAL_CSTRING(QUERYKEY_FOLDERS "="); + aQueryString += NS_LITERAL_CSTRING(QUERYKEY_FOLDER "="); AppendInt64(aQueryString, folders[0]); } } @@ -465,7 +486,7 @@ TokenizeQueryString(const nsACString& aQuery, nsresult nsNavHistory::TokensToQueries(const nsTArray& aTokens, - nsCOMArray* aQueries, + nsCOMArray* aQueries, nsNavHistoryQueryOptions* aOptions) { nsresult rv; @@ -475,7 +496,7 @@ nsNavHistory::TokensToQueries(const nsTArray& aTokens, nsTArray groups; nsTArray folders; - nsCOMPtr query(new nsNavHistoryQuery()); + nsCOMPtr query(new nsNavHistoryQuery()); if (! query) return NS_ERROR_OUT_OF_MEMORY; if (! aQueries->AppendObject(query)) @@ -522,7 +543,7 @@ nsNavHistory::TokensToQueries(const nsTArray& aTokens, NS_ENSURE_SUCCESS(rv, rv); // folders: FIXME use folder name??? - } else if (kvp.key.EqualsLiteral(QUERYKEY_FOLDERS)) { + } else if (kvp.key.EqualsLiteral(QUERYKEY_FOLDER)) { PRInt64 folder; if (PR_sscanf(kvp.value.get(), "%lld", &folder) == 1) { NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY); diff --git a/mozilla/browser/components/places/src/nsNavHistoryQuery.h b/mozilla/browser/components/places/src/nsNavHistoryQuery.h index d729ec71de0..5a562fe4e64 100644 --- a/mozilla/browser/components/places/src/nsNavHistoryQuery.h +++ b/mozilla/browser/components/places/src/nsNavHistoryQuery.h @@ -77,6 +77,8 @@ public: const nsCString& Domain() { return mDomain; } PRBool UriIsPrefix() { return mUriIsPrefix; } nsIURI* Uri() { return mUri; } // NOT AddRef-ed! + PRBool AnnotationIsNot() { return mAnnotationIsNot; } + const nsCString& Annotation() { return mAnnotation; } const nsTArray& Folders() const { return mFolders; } private: diff --git a/mozilla/browser/components/places/src/nsNavHistoryResult.cpp b/mozilla/browser/components/places/src/nsNavHistoryResult.cpp index d0692370bb5..23394377bce 100755 --- a/mozilla/browser/components/places/src/nsNavHistoryResult.cpp +++ b/mozilla/browser/components/places/src/nsNavHistoryResult.cpp @@ -52,6 +52,7 @@ #include "nsILocale.h" #include "nsILocaleService.h" #include "nsILocalFile.h" +#include "nsIRemoteContainer.h" #include "nsIServiceManager.h" #include "nsISupportsPrimitives.h" #include "nsITreeColumns.h" @@ -162,6 +163,45 @@ nsNavHistoryResultNode::GetResult() } +// nsNavHistoryResultNode::GetGeneratingOptions +// +// Searches up the tree for the closest node that has an options structure. +// This will tell us the options that were used to generate this node. +// +// Be careful, this function walks up the tree, so it can not be used when +// result nodes are created because they have no parent. Only call this +// function after the tree has been built. + +nsNavHistoryQueryOptions* +nsNavHistoryResultNode::GetGeneratingOptions() +{ + if (! mParent) { + // When we have no parent, it either means we haven't built the tree yet, + // in which case calling this function is a bug, or this node is the root + // of the tree. When we are the root of the tree, our own options are the + // generating options, and we know we are either a query of a folder node. + if (IsFolder()) + return GetAsFolder()->mOptions; + else if (IsQuery()) + return GetAsQuery()->mOptions; + NS_NOTREACHED("Can't find a generating node for this container, perhaps FillStats has not been called on this tree yet?"); + return nsnull; + } + + nsNavHistoryContainerResultNode* cur = mParent; + while (cur) { + if (cur->IsFolder()) + return cur->GetAsFolder()->mOptions; + else if (cur->IsQuery()) + return cur->GetAsQuery()->mOptions; + cur = cur->mParent; + } + // we should always find a folder or query node as an ancestor + NS_NOTREACHED("Can't find a generating node for this container, the tree seemes corrupted."); + return nsnull; +} + + // nsNavHistoryURIResultNode *************************************************** NS_IMPL_ISUPPORTS_INHERITED1(nsNavHistoryURIResultNode, @@ -216,32 +256,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsNavHistoryContainerResultNode, nsNavHistoryResultNode, nsINavHistoryContainerResultNode) -nsNavHistoryContainerResultNode::nsNavHistoryContainerResultNode( - const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, - const nsACString& aIconURI, PRUint32 aContainerType, PRBool aReadOnly) : - nsNavHistoryResultNode(aTitle, aAccessCount, aTime, aIconURI), - mResult(nsnull), - mContainerType(aContainerType), - mExpanded(PR_FALSE), - mChildrenReadOnly(aReadOnly) -{ -} - nsNavHistoryContainerResultNode::nsNavHistoryContainerResultNode( const nsACString& aTitle, const nsACString& aIconURI, - PRUint32 aContainerType) : + PRUint32 aContainerType, PRBool aReadOnly, + const nsACString& aRemoteContainerType) : nsNavHistoryResultNode(aTitle, 0, 0, aIconURI), mResult(nsnull), mContainerType(aContainerType), mExpanded(PR_FALSE), - mChildrenReadOnly(PR_TRUE) + mChildrenReadOnly(aReadOnly), + mRemoteContainerType(aRemoteContainerType) { - // The container type must be a host or day. This constructor is used when - // we are grouping and want to create host or day containers. Therefore, you - // can't use it with folder or query containers. - NS_ASSERTION(aContainerType == nsNavHistoryResultNode::RESULT_TYPE_HOST || - aContainerType == nsNavHistoryResultNode::RESULT_TYPE_DAY, - "You are passing in a container type that isn't valid"); } @@ -312,6 +337,9 @@ nsNavHistoryContainerResultNode::SetContainerOpen(PRBool aContainerOpen) // nsNavHistoryContainerResultNode::OpenContainer +// +// This handles the generic container case. Other container types should +// override this to do their own handling. nsresult nsNavHistoryContainerResultNode::OpenContainer() @@ -320,6 +348,20 @@ nsNavHistoryContainerResultNode::OpenContainer() NS_ASSERTION(! mExpanded, "Container must be expanded to close it"); mExpanded = PR_TRUE; + if (! mRemoteContainerType.IsEmpty()) { + // remote container API may want to fill us + nsCOMPtr remote = do_GetService(mRemoteContainerType.get(), &rv); + if (NS_SUCCEEDED(rv)) { + remote->OnContainerOpening(this, GetGeneratingOptions()); + } else { + NS_WARNING("Unable to get remote container for "); + NS_WARNING(mRemoteContainerType.get()); + } + PRInt32 oldAccessCount = mAccessCount; + FillStats(); + ReverseUpdateStats(mAccessCount - oldAccessCount); + } + nsNavHistoryResult* result = GetResult(); NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); rv = result->RefreshVisibleSection(this); @@ -336,9 +378,17 @@ nsNavHistoryContainerResultNode::CloseContainer() NS_ASSERTION(mExpanded, "Container must be expanded to close it"); mExpanded = PR_FALSE; + nsresult rv; + if (! mRemoteContainerType.IsEmpty()) { + // notify remote containers that we are closing + nsCOMPtr remote = do_GetService(mRemoteContainerType.get(), &rv); + if (NS_SUCCEEDED(rv)) + remote->OnContainerClosed(this); + } + nsNavHistoryResult* result = GetResult(); NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); - nsresult rv = result->RefreshVisibleSection(this); + rv = result->RefreshVisibleSection(this); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } @@ -691,9 +741,6 @@ PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_URILess( nsNavHistoryURIResultNode* aURI = a->GetAsURI(); nsNavHistoryURIResultNode* bURI = b->GetAsURI(); value = aURI->mURI.Compare(bURI->mURI.get()); - } else if (aType == nsNavHistoryResultNode::RESULT_TYPE_DAY) { - // date nodes use date (skip conflict resolution because it uses date too) - return ComparePRTime(a->mTime, b->mTime); } else { // for everything else, use title (= host name) nsICollation* collation = NS_STATIC_CAST(nsICollation*, closure); @@ -1079,6 +1126,20 @@ nsNavHistoryContainerResultNode::RemoveChildAt(PRInt32 aIndex, } +// nsNavHistoryContainerResultNode::CanRemoteContainersChange +// +// Returns true if remote containers can manipulate the contents of this +// container. This is false for folders and queries, true for everything +// else. + +PRBool +nsNavHistoryContainerResultNode::CanRemoteContainersChange() +{ + return (mContainerType != nsNavHistoryResultNode::RESULT_TYPE_FOLDER && + mContainerType != nsNavHistoryResultNode::RESULT_TYPE_QUERY); +} + + // nsNavHistoryContainerResultNode::GetHasChildren // // Complex containers (folders and queries) will override this. Here, we @@ -1131,27 +1192,233 @@ nsNavHistoryContainerResultNode::GetChildrenReadOnly(PRBool *aChildrenReadOnly) return NS_OK; } + +// nsNavHistoryContainerResultNode::GetRemoteContainerType + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::GetRemoteContainerType( + nsACString& aRemoteContainerType) +{ + aRemoteContainerType = mRemoteContainerType; + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendURINode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendURINode( + const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, + const nsACString& aIconURI, const nsACString& aURI, + nsINavHistoryURIResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + nsRefPtr result = + new nsNavHistoryURIResultNode(aTitle, aAccessCount, aTime, aIconURI, aURI); + NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendVisitNode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendVisitNode( + const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, + const nsACString& aIconURI, const nsACString& aURI, PRInt64 aSession, + nsINavHistoryVisitResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + nsRefPtr result = + new nsNavHistoryVisitResultNode(aTitle, aAccessCount, aTime, + aIconURI, aURI, aSession); + NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendFullVisitNode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendFullVisitNode( + const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, + const nsACString& aIconURI, const nsACString& aURI, PRInt64 aSession, + PRInt64 aVisitId, PRInt64 aReferringVisitId, PRInt32 aTransitionType, + nsINavHistoryFullVisitResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + nsRefPtr result = + new nsNavHistoryFullVisitResultNode(aTitle, aAccessCount, aTime, + aIconURI, aURI, aSession, + aVisitId, aReferringVisitId, + aTransitionType); + NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendContainerNode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendContainerNode( + const nsACString& aTitle, const nsACString& aIconURI, + PRUint32 aContainerType, const nsACString& aRemoteContainerType, + nsINavHistoryContainerResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + if (! IsTypeContainer(aContainerType) || IsTypeFolder(aContainerType) || + IsTypeQuery(aContainerType)) + return NS_ERROR_INVALID_ARG; // not proper container type + if (aContainerType == nsNavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER && + aRemoteContainerType.IsEmpty()) + return NS_ERROR_INVALID_ARG; // remote containers must have r.c. type + if (aContainerType != nsNavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER && + ! aRemoteContainerType.IsEmpty()) + return NS_ERROR_INVALID_ARG; // non-remote containers must NOT have r.c. type + + nsRefPtr result = + new nsNavHistoryContainerResultNode(aTitle, aIconURI, aContainerType, + PR_TRUE, aRemoteContainerType); + NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendQueryNode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendQueryNode( + const nsACString& aTitle, const nsACString& aIconURI, + const nsACString& aQueryString, nsINavHistoryQueryResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + nsRefPtr result = + new nsNavHistoryQueryResultNode(aTitle, aIconURI, aQueryString); + NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::AppendFolderNode + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::AppendFolderNode( + PRInt64 aFolderId, nsINavHistoryFolderResultNode** _retval) +{ + *_retval = nsnull; + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService(); + NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY); + + // create the node, it will be addrefed for us + nsRefPtr result; + nsresult rv = bookmarks->ResultNodeForFolder(aFolderId, + GetGeneratingOptions(), + getter_AddRefs(result)); + NS_ENSURE_SUCCESS(rv, rv); + + // append to our list + if (! mChildren.AppendObject(result)) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval = result->GetAsFolder()); + return NS_OK; +} + + +// nsNavHistoryContainerResultNode::ClearContents +// +// Used by the remote container API to clear this container + +NS_IMETHODIMP +nsNavHistoryContainerResultNode::ClearContents() +{ + if (mRemoteContainerType.IsEmpty() || ! CanRemoteContainersChange()) + return NS_ERROR_INVALID_ARG; // we must be a remote container + + // we know if CanRemoteContainersChange() then we are a regular container + // and not a query or folder, so clearing doesn't need anything else to + // happen (like unregistering observers). Also, since this should only + // happen when the container is closed, we don't need to redraw the screen. + mChildren.Clear(); + + PRUint32 oldAccessCount = mAccessCount; + mAccessCount = 0; + mTime = 0; + ReverseUpdateStats(-oldAccessCount); + return NS_OK; +} + + // nsNavHistoryQueryResultNode ************************************************* // // HOW QUERY UPDATING WORKS // // Queries are different than bookmark folders in that we can not always -// do dynamic updates (easily) and updates are more expensive. +// do dynamic updates (easily) and updates are more expensive. Therefore, +// we do NOT query if we are not open and want to see if we have any children +// (for drawing a twisty) and always assume we will. // -// +// When the container is opened, we execute the query and register the +// listeners. Like bookmark folders, we stay registered even when closed, +// and clear ourselves as soon as a message comes in. This lets us respond +// quickly if the user closes and reopens the container. +// +// We try to handle the most common notifications for the most common query +// types dynamically, that is, figuring out what should happen in response +// to a message without doing a requery. For complex changes or complex +// queries, we give up and requery. NS_IMPL_ISUPPORTS_INHERITED1(nsNavHistoryQueryResultNode, nsNavHistoryContainerResultNode, nsINavHistoryQueryResultNode) nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode( - nsNavHistoryQueryOptions* aGeneratingOptions, - const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, - const nsACString& aIconURI, const nsACString& aQueryURI) : - nsNavHistoryContainerResultNode(aTitle, aAccessCount, aTime, aIconURI, + const nsACString& aTitle, const nsACString& aIconURI, + const nsACString& aQueryURI) : + nsNavHistoryContainerResultNode(aTitle, aIconURI, nsNavHistoryResultNode::RESULT_TYPE_QUERY, - PR_TRUE), - mGeneratingOptions(aGeneratingOptions), + PR_TRUE, EmptyCString()), mQueryURI(aQueryURI), mHasSearchTerms(PR_FALSE), mContentsValid(PR_FALSE), @@ -1163,26 +1430,27 @@ nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode( } nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode( - nsNavHistoryQueryOptions* aGeneratingOptions, - const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, - const nsACString& aIconURI, nsINavHistoryQuery** aQueries, - PRUint32 aQueryCount, nsNavHistoryQueryOptions* aOptions) : - nsNavHistoryContainerResultNode(aTitle, aAccessCount, aTime, aIconURI, + const nsACString& aTitle, const nsACString& aIconURI, + const nsCOMArray& aQueries, + nsNavHistoryQueryOptions* aOptions) : + nsNavHistoryContainerResultNode(aTitle, aIconURI, nsNavHistoryResultNode::RESULT_TYPE_QUERY, - PR_TRUE), - mGeneratingOptions(aGeneratingOptions), + PR_TRUE, EmptyCString()), + mQueries(aQueries), + mOptions(aOptions), mContentsValid(PR_FALSE), mBatchInProgress(PR_FALSE) { - NS_ASSERTION(aQueryCount > 0, "Must have at least one query"); + NS_ASSERTION(aQueries.Count() > 0, "Must have at least one query"); + /* for (PRUint32 i = 0; i < aQueryCount; i ++) mQueries.AppendObject(aQueries[i]); aOptions->Clone(getter_AddRefs(mOptions)); - +*/ nsNavHistory* history = nsNavHistory::GetHistoryService(); NS_ASSERTION(history, "History service missing"); - mLiveUpdate = history->GetUpdateRequirements(&mQueries, mOptions, + mLiveUpdate = history->GetUpdateRequirements(mQueries, mOptions, &mHasSearchTerms); // queries have special icons if not otherwise set @@ -1200,7 +1468,8 @@ nsNavHistoryQueryResultNode::nsNavHistoryQueryResultNode( PRBool nsNavHistoryQueryResultNode::CanExpand() { - if (mGeneratingOptions->ExpandQueries()) + nsNavHistoryQueryOptions* options = GetGeneratingOptions(); + if (options && options->ExpandQueries()) return PR_TRUE; if (mResult && mResult->mRootNode == this) return PR_TRUE; @@ -1233,13 +1502,18 @@ nsNavHistoryQueryResultNode::OnRemoving() nsresult nsNavHistoryQueryResultNode::OpenContainer() { + NS_ASSERTION(! mExpanded, "Container must be expanded to close it"); if (! CanExpand()) return NS_OK; if (! mContentsValid) { nsresult rv = FillChildren(); NS_ENSURE_SUCCESS(rv, rv); } - return nsNavHistoryContainerResultNode::OpenContainer(); + + mExpanded = PR_TRUE; + nsNavHistoryResult* result = GetResult(); + NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); + return result->RefreshVisibleSection(this); } @@ -1329,31 +1603,11 @@ nsNavHistoryQueryResultNode::VerifyQueriesParsed() nsNavHistory* history = nsNavHistory::GetHistoryService(); NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY); - nsINavHistoryQuery** queries; - PRUint32 queryCount; - nsCOMPtr options; - nsresult rv = history->QueryStringToQueries(mQueryURI, &queries, &queryCount, - getter_AddRefs(options)); + nsresult rv = history->QueryStringToQueryArray(mQueryURI, &mQueries, + getter_AddRefs(mOptions)); NS_ENSURE_SUCCESS(rv, rv); - mOptions = do_QueryInterface(options, &rv); // need concrete pointer - if (NS_FAILED(rv)) { - nsMemory::Free(queries); - return rv; - } - // Copy the individual queries into our array. At the same time, note if - // we have any bookmark components so we know whether to pay attention to - // bookmark notifications. - for (PRUint32 i = 0; i < queryCount; i ++) { - if (! mQueries.AppendObject(queries[i])) { - nsMemory::Free(queries); - mQueries.Clear(); - return NS_ERROR_OUT_OF_MEMORY; - } - } - nsMemory::Free(queries); - - mLiveUpdate = history->GetUpdateRequirements(&mQueries, mOptions, + mLiveUpdate = history->GetUpdateRequirements(mQueries, mOptions, &mHasSearchTerms); return NS_OK; } @@ -1726,7 +1980,7 @@ nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId, rv = history->VisitIdToResultNode(aVisitId, mOptions, getter_AddRefs(addition)); NS_ENSURE_SUCCESS(rv, rv); - if (! history->EvaluateQueryForNode(&mQueries, mOptions, + if (! history->EvaluateQueryForNode(mQueries, mOptions, addition->GetAsURI())) return NS_OK; // don't need to include in our query break; @@ -2051,11 +2305,11 @@ NS_IMPL_ISUPPORTS_INHERITED2(nsNavHistoryFolderResultNode, nsINavHistoryFolderResultNode) nsNavHistoryFolderResultNode::nsNavHistoryFolderResultNode( - const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, - nsNavHistoryQueryOptions* aOptions, PRInt64 aFolderId) : - nsNavHistoryContainerResultNode(aTitle, aAccessCount, aTime, EmptyCString(), + const nsACString& aTitle, nsNavHistoryQueryOptions* aOptions, + PRInt64 aFolderId, const nsACString& aRemoteContainerType) : + nsNavHistoryContainerResultNode(aTitle, EmptyCString(), nsNavHistoryResultNode::RESULT_TYPE_FOLDER, - PR_FALSE), + PR_FALSE, aRemoteContainerType), mContentsValid(PR_FALSE), mOptions(aOptions), mFolderId(aFolderId) @@ -2104,11 +2358,28 @@ nsNavHistoryFolderResultNode::OnRemoving() nsresult nsNavHistoryFolderResultNode::OpenContainer() { + NS_ASSERTION(! mExpanded, "Container must be expanded to close it"); + nsresult rv; + if (! mRemoteContainerType.IsEmpty()) { + // remote container API may want to change the bookmarks for this folder. + nsCOMPtr remote = do_GetService(mRemoteContainerType.get(), &rv); + if (NS_SUCCEEDED(rv)) { + remote->OnContainerOpening(NS_STATIC_CAST(nsINavHistoryFolderResultNode*, this), + mOptions); + } else { + NS_WARNING("Unable to get remote container for "); + NS_WARNING(mRemoteContainerType.get()); + } + } + if (! mContentsValid) { - nsresult rv = FillChildren(); + rv = FillChildren(); NS_ENSURE_SUCCESS(rv, rv); } - return nsNavHistoryContainerResultNode::OpenContainer(); + mExpanded = PR_TRUE; + nsNavHistoryResult* result = GetResult(); + NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); + return result->RefreshVisibleSection(this); } @@ -2734,11 +3005,9 @@ nsNavHistoryResult::ComputeShowSessions() return; // not date sorting PRUint32 groupCount; - const PRUint32* groups = mOptions->GroupingMode(&groupCount); - for (PRUint32 i = 0; i < groupCount; i ++) { - if (groups[i] != nsINavHistoryQueryOptions::GROUP_BY_DAY) - return; // non-time-based grouping - } + mOptions->GroupingMode(&groupCount); + if (groupCount > 0) + return; mShowSessions = PR_TRUE; } diff --git a/mozilla/browser/components/places/src/nsNavHistoryResult.h b/mozilla/browser/components/places/src/nsNavHistoryResult.h index a02e8198d39..3b672c3afae 100644 --- a/mozilla/browser/components/places/src/nsNavHistoryResult.h +++ b/mozilla/browser/components/places/src/nsNavHistoryResult.h @@ -53,6 +53,7 @@ class nsNavHistory; class nsNavHistoryResult; class nsIDateTimeFormat; class nsIWritablePropertyBag; +class nsNavHistoryQuery; class nsNavHistoryQueryOptions; class nsNavHistoryContainerResultNode; @@ -167,13 +168,14 @@ public: public: nsNavHistoryResult* GetResult(); + nsNavHistoryQueryOptions* GetGeneratingOptions(); // These functions test the type. We don't use a virtual function since that // would take a vtable slot for every one of (potentially very many) nodes. // Note that GetType() already has a vtable slot because its on the iface. PRBool IsTypeContainer(PRUint32 type) { return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST || - type == nsINavHistoryResultNode::RESULT_TYPE_DAY || + type == nsINavHistoryResultNode::RESULT_TYPE_REMOTE_CONTAINER || type == nsINavHistoryResultNode::RESULT_TYPE_QUERY || type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER); } @@ -184,10 +186,10 @@ public: } static PRBool IsTypeQuerySubcontainer(PRUint32 type) { // Tests containers that are inside queries that really belong to the query - // itself, and is used when recursively updating a query. This include host - // and day containers, but doesn't include other queries and folders. - return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST || - type == nsINavHistoryResultNode::RESULT_TYPE_DAY); + // itself, and is used when recursively updating a query. This currently + // includes only host containers, but may be extended to support things + // like days or other criteria. It doesn't include other queries and folders. + return (type == nsINavHistoryResultNode::RESULT_TYPE_HOST); } PRBool IsQuerySubcontainer() { PRUint32 type; @@ -371,17 +373,31 @@ public: NS_IMETHOD GetChild(PRUint32 index, nsINavHistoryResultNode **_retval) \ { return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \ NS_IMETHOD GetChildrenReadOnly(PRBool *aChildrenReadOnly) \ - { return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); } + { return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); } \ + NS_IMETHOD GetRemoteContainerType(nsACString& aRemoteContainerType) \ + { return nsNavHistoryContainerResultNode::GetRemoteContainerType(aRemoteContainerType); } \ + NS_IMETHOD AppendURINode(const nsACString& aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString& aIconURI, const nsACString & aURI, nsINavHistoryURIResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendURINode(aTitle, aAccessCount, aTime, aIconURI, aURI, _retval); } \ + NS_IMETHOD AppendVisitNode(const nsACString & aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString & aIconURI, const nsACString & aURI, PRInt64 aSession, nsINavHistoryVisitResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendVisitNode(aTitle, aAccessCount, aTime, aIconURI, aURI, aSession, _retval); } \ + NS_IMETHOD AppendFullVisitNode(const nsACString & aTitle, PRUint32 aAccessCount, PRTime aTime, const nsACString & aIconURI, const nsACString & aURI, PRInt64 aSession, PRInt64 aVisitId, PRInt64 aReferringVisitId, PRInt32 aTransitionType, nsINavHistoryFullVisitResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendFullVisitNode(aTitle, aAccessCount, aTime, aIconURI, aURI, aSession, aVisitId, aReferringVisitId, aTransitionType, _retval); } \ + NS_IMETHOD AppendContainerNode(const nsACString & aTitle, const nsACString & aIconURI, PRUint32 aContainerType, const nsACString & aRemoteContainerType, nsINavHistoryContainerResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendContainerNode(aTitle, aIconURI, aContainerType, aRemoteContainerType, _retval); } \ + NS_IMETHOD AppendQueryNode(const nsACString & aTitle, const nsACString & aIconURI, const nsACString & aQueryString, nsINavHistoryQueryResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendQueryNode(aTitle, aIconURI, aQueryString, _retval); } \ + NS_IMETHOD AppendFolderNode(PRInt64 aFolderId, nsINavHistoryFolderResultNode **_retval) \ + { return nsNavHistoryContainerResultNode::AppendFolderNode(aFolderId, _retval); } \ + NS_IMETHOD ClearContents() \ + { return nsNavHistoryContainerResultNode::ClearContents(); } class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode, public nsINavHistoryContainerResultNode { public: - nsNavHistoryContainerResultNode(const nsACString& aTitle, PRUint32 aAccessCount, - PRTime aTime, const nsACString& aIconURI, PRUint32 aContainerType, - PRBool aReadOnly); nsNavHistoryContainerResultNode(const nsACString& aTitle, - const nsACString& aIconURI, PRUint32 aContainerType); + const nsACString& aIconURI, PRUint32 aContainerType, + PRBool aReadOnly, const nsACString& aRemoteContainerType); NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE @@ -397,7 +413,7 @@ public: // overridded by descendents to populate virtual nsresult OpenContainer(); - virtual nsresult CloseContainer(); + nsresult CloseContainer(); // this points to the result that owns this container. All containers have // their result pointer set so we can quickly get to the result without having @@ -405,8 +421,8 @@ public: // for every leaf node to the result. nsNavHistoryResult* mResult; - // for example, RESULT_TYPE_HOST or RESULT_TYPE_DAY. Query and Folder results - // override GetType so this is not used, but is still kept in sync. + // for example, RESULT_TYPE_HOST. Query and Folder results override GetType + // so this is not used, but is still kept in sync. PRUint32 mContainerType; // when there are children, this stores the open state in the tree @@ -418,6 +434,11 @@ public: PRBool mChildrenReadOnly; + // ID of a remote container interface that we can use GetService to get. + // This is empty to indicate there is no remote container service for this + // container (the common case). + nsCString mRemoteContainerType; + void FillStats(); void ReverseUpdateStats(PRInt32 aAccessCountChange); @@ -472,6 +493,8 @@ public: nsresult ReplaceChildURIAt(PRUint32 aIndex, nsNavHistoryURIResultNode* aNode); nsresult RemoveChildAt(PRInt32 aIndex, PRBool aIsTemporary = PR_FALSE); + + PRBool CanRemoteContainersChange(); }; @@ -485,14 +508,12 @@ class nsNavHistoryQueryResultNode : public nsNavHistoryContainerResultNode, public nsINavHistoryQueryResultNode { public: - nsNavHistoryQueryResultNode(nsNavHistoryQueryOptions* aGeneratingOptions, - const nsACString& aTitle, PRUint32 aAccessCount, - PRTime aTime, const nsACString& aIconURI, + nsNavHistoryQueryResultNode(const nsACString& aTitle, + const nsACString& aIconURI, const nsACString& aQueryURI); - nsNavHistoryQueryResultNode(nsNavHistoryQueryOptions* aGeneratingOptions, - const nsACString& aTitle, PRUint32 aAccessCount, - PRTime aTime, const nsACString& aIconURI, - nsINavHistoryQuery** aQueries, PRUint32 aQueryCount, + nsNavHistoryQueryResultNode(const nsACString& aTitle, + const nsACString& aIconURI, + const nsCOMArray& aQueries, nsNavHistoryQueryOptions* aOptions); NS_DECL_ISUPPORTS_INHERITED @@ -511,13 +532,6 @@ public: virtual void OnRemoving(); public: - // These are the options that caused this node to be generated. For just - // running queries directly, this node will be the root of the result and - // mGeneratingOptions will be the same as mOptions. When queries are in - // bookmark folders, this it the options structure used to generate the - // bookmarks tree. It tells us, for example, if we should expand ourselves. - nsCOMPtr mGeneratingOptions; - // this may be constructedlazily from mQueries and mOptions, call VerifyQueriesSerialized // either this or mQueries/mOptions should be valid nsCString mQueryURI; @@ -525,7 +539,7 @@ public: // these may be constructed lazily from mQueryURI, call VerifyQueriesParsed // either this or mQueryURI should be valid - nsCOMArray mQueries; + nsCOMArray mQueries; nsCOMPtr mOptions; PRUint32 mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h PRBool mHasSearchTerms; @@ -561,9 +575,10 @@ class nsNavHistoryFolderResultNode : public nsNavHistoryContainerResultNode, public nsINavHistoryFolderResultNode { public: - nsNavHistoryFolderResultNode(const nsACString& aTitle, PRUint32 aAccessCount, - PRTime aTime, nsNavHistoryQueryOptions* options, - PRInt64 aFolderId); + nsNavHistoryFolderResultNode(const nsACString& aTitle, + nsNavHistoryQueryOptions* options, + PRInt64 aFolderId, + const nsACString& aRemoteContainerType); NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_RESULTNODE_TO_BASE_EXCEPT_GETTYPE