1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/nsNavHistoryResult.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,783 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/** 1.10 + * The definitions of objects that make up a history query result set. This file 1.11 + * should only be included by nsNavHistory.h, include that if you want these 1.12 + * classes. 1.13 + */ 1.14 + 1.15 +#ifndef nsNavHistoryResult_h_ 1.16 +#define nsNavHistoryResult_h_ 1.17 + 1.18 +#include "nsTArray.h" 1.19 +#include "nsInterfaceHashtable.h" 1.20 +#include "nsDataHashtable.h" 1.21 +#include "nsCycleCollectionParticipant.h" 1.22 +#include "mozilla/storage.h" 1.23 +#include "Helpers.h" 1.24 + 1.25 +class nsNavHistory; 1.26 +class nsNavHistoryQuery; 1.27 +class nsNavHistoryQueryOptions; 1.28 + 1.29 +class nsNavHistoryContainerResultNode; 1.30 +class nsNavHistoryFolderResultNode; 1.31 +class nsNavHistoryQueryResultNode; 1.32 + 1.33 +/** 1.34 + * hashkey wrapper using int64_t KeyType 1.35 + * 1.36 + * @see nsTHashtable::EntryType for specification 1.37 + * 1.38 + * This just truncates the 64-bit int to a 32-bit one for using a hash number. 1.39 + * It is used for bookmark folder IDs, which should be way less than 2^32. 1.40 + */ 1.41 +class nsTrimInt64HashKey : public PLDHashEntryHdr 1.42 +{ 1.43 +public: 1.44 + typedef const int64_t& KeyType; 1.45 + typedef const int64_t* KeyTypePointer; 1.46 + 1.47 + nsTrimInt64HashKey(KeyTypePointer aKey) : mValue(*aKey) { } 1.48 + nsTrimInt64HashKey(const nsTrimInt64HashKey& toCopy) : mValue(toCopy.mValue) { } 1.49 + ~nsTrimInt64HashKey() { } 1.50 + 1.51 + KeyType GetKey() const { return mValue; } 1.52 + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } 1.53 + 1.54 + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } 1.55 + static PLDHashNumber HashKey(KeyTypePointer aKey) 1.56 + { return static_cast<uint32_t>((*aKey) & UINT32_MAX); } 1.57 + enum { ALLOW_MEMMOVE = true }; 1.58 + 1.59 +private: 1.60 + const int64_t mValue; 1.61 +}; 1.62 + 1.63 + 1.64 +// Declare methods for implementing nsINavBookmarkObserver 1.65 +// and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap) 1.66 +#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \ 1.67 + NS_DECL_NSINAVBOOKMARKOBSERVER \ 1.68 + NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \ 1.69 + const nsACString& aGUID); \ 1.70 + NS_IMETHOD OnFrecencyChanged(nsIURI* aURI, int32_t aNewFrecency, \ 1.71 + const nsACString& aGUID, bool aHidden, \ 1.72 + PRTime aLastVisitDate); \ 1.73 + NS_IMETHOD OnManyFrecenciesChanged(); \ 1.74 + NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \ 1.75 + uint16_t aReason); \ 1.76 + NS_IMETHOD OnClearHistory(); \ 1.77 + NS_IMETHOD OnPageChanged(nsIURI *aURI, uint32_t aChangedAttribute, \ 1.78 + const nsAString &aNewValue, \ 1.79 + const nsACString &aGUID); \ 1.80 + NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \ 1.81 + const nsACString& aGUID, uint16_t aReason, \ 1.82 + uint32_t aTransitionType); 1.83 + 1.84 +// The internal version has an output aAdded parameter, it is incremented by 1.85 +// query nodes when the visited uri belongs to them. If no such query exists, 1.86 +// the history result creates a new query node dynamically. 1.87 +#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL \ 1.88 + NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \ 1.89 + NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \ 1.90 + int64_t aSessionId, int64_t aReferringId, \ 1.91 + uint32_t aTransitionType, const nsACString& aGUID, \ 1.92 + bool aHidden, uint32_t* aAdded); 1.93 + 1.94 +// The external version is used by results. 1.95 +#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL \ 1.96 + NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \ 1.97 + NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \ 1.98 + int64_t aSessionId, int64_t aReferringId, \ 1.99 + uint32_t aTransitionType, const nsACString& aGUID, \ 1.100 + bool aHidden); 1.101 + 1.102 +// nsNavHistoryResult 1.103 +// 1.104 +// nsNavHistory creates this object and fills in mChildren (by getting 1.105 +// it through GetTopLevel()). Then FilledAllResults() is called to finish 1.106 +// object initialization. 1.107 + 1.108 +#define NS_NAVHISTORYRESULT_IID \ 1.109 + { 0x455d1d40, 0x1b9b, 0x40e6, { 0xa6, 0x41, 0x8b, 0xb7, 0xe8, 0x82, 0x23, 0x87 } } 1.110 + 1.111 +class nsNavHistoryResult : public nsSupportsWeakReference, 1.112 + public nsINavHistoryResult, 1.113 + public nsINavBookmarkObserver, 1.114 + public nsINavHistoryObserver 1.115 +{ 1.116 +public: 1.117 + static nsresult NewHistoryResult(nsINavHistoryQuery** aQueries, 1.118 + uint32_t aQueryCount, 1.119 + nsNavHistoryQueryOptions* aOptions, 1.120 + nsNavHistoryContainerResultNode* aRoot, 1.121 + bool aBatchInProgress, 1.122 + nsNavHistoryResult** result); 1.123 + 1.124 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID) 1.125 + 1.126 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.127 + NS_DECL_NSINAVHISTORYRESULT 1.128 + NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL 1.129 + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult, nsINavHistoryResult) 1.130 + 1.131 + void AddHistoryObserver(nsNavHistoryQueryResultNode* aNode); 1.132 + void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder); 1.133 + void AddAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode); 1.134 + void RemoveHistoryObserver(nsNavHistoryQueryResultNode* aNode); 1.135 + void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder); 1.136 + void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode); 1.137 + void StopObserving(); 1.138 + 1.139 +public: 1.140 + // two-stage init, use NewHistoryResult to construct 1.141 + nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot); 1.142 + virtual ~nsNavHistoryResult(); 1.143 + nsresult Init(nsINavHistoryQuery** aQueries, 1.144 + uint32_t aQueryCount, 1.145 + nsNavHistoryQueryOptions *aOptions); 1.146 + 1.147 + nsRefPtr<nsNavHistoryContainerResultNode> mRootNode; 1.148 + 1.149 + nsCOMArray<nsINavHistoryQuery> mQueries; 1.150 + nsCOMPtr<nsNavHistoryQueryOptions> mOptions; 1.151 + 1.152 + // One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to mOptions.sortingMode, 1.153 + // but may be overridden if the user clicks on one of the columns. 1.154 + uint16_t mSortingMode; 1.155 + // If root node is closed and we try to apply a sortingMode, it would not 1.156 + // work. So we will apply it when the node will be reopened and populated. 1.157 + // This var states the fact we need to apply sortingMode in such a situation. 1.158 + bool mNeedsToApplySortingMode; 1.159 + 1.160 + // The sorting annotation to be used for in SORT_BY_ANNOTATION_* modes 1.161 + nsCString mSortingAnnotation; 1.162 + 1.163 + // node observers 1.164 + bool mIsHistoryObserver; 1.165 + bool mIsBookmarkFolderObserver; 1.166 + bool mIsAllBookmarksObserver; 1.167 + 1.168 + typedef nsTArray< nsRefPtr<nsNavHistoryQueryResultNode> > QueryObserverList; 1.169 + QueryObserverList mHistoryObservers; 1.170 + QueryObserverList mAllBookmarksObservers; 1.171 + 1.172 + typedef nsTArray< nsRefPtr<nsNavHistoryFolderResultNode> > FolderObserverList; 1.173 + nsDataHashtable<nsTrimInt64HashKey, FolderObserverList*> mBookmarkFolderObservers; 1.174 + FolderObserverList* BookmarkFolderObserversForId(int64_t aFolderId, bool aCreate); 1.175 + 1.176 + typedef nsTArray< nsRefPtr<nsNavHistoryContainerResultNode> > ContainerObserverList; 1.177 + 1.178 + void RecursiveExpandCollapse(nsNavHistoryContainerResultNode* aContainer, 1.179 + bool aExpand); 1.180 + 1.181 + void InvalidateTree(); 1.182 + 1.183 + bool mBatchInProgress; 1.184 + 1.185 + nsMaybeWeakPtrArray<nsINavHistoryResultObserver> mObservers; 1.186 + bool mSuppressNotifications; 1.187 + 1.188 + ContainerObserverList mRefreshParticipants; 1.189 + void requestRefresh(nsNavHistoryContainerResultNode* aContainer); 1.190 +}; 1.191 + 1.192 +NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID) 1.193 + 1.194 +// nsNavHistoryResultNode 1.195 +// 1.196 +// This is the base class for every node in a result set. The result itself 1.197 +// is a node (nsNavHistoryResult inherits from this), as well as every 1.198 +// leaf and branch on the tree. 1.199 + 1.200 +#define NS_NAVHISTORYRESULTNODE_IID \ 1.201 + {0x54b61d38, 0x57c1, 0x11da, {0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e}} 1.202 + 1.203 +// These are all the simple getters, they can be used for the result node 1.204 +// implementation and all subclasses. More complex are GetIcon, GetParent 1.205 +// (which depends on the definition of container result node), and GetUri 1.206 +// (which is overridded for lazy construction for some containers). 1.207 +#define NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \ 1.208 + NS_IMETHOD GetTitle(nsACString& aTitle) \ 1.209 + { aTitle = mTitle; return NS_OK; } \ 1.210 + NS_IMETHOD GetAccessCount(uint32_t* aAccessCount) \ 1.211 + { *aAccessCount = mAccessCount; return NS_OK; } \ 1.212 + NS_IMETHOD GetTime(PRTime* aTime) \ 1.213 + { *aTime = mTime; return NS_OK; } \ 1.214 + NS_IMETHOD GetIndentLevel(int32_t* aIndentLevel) \ 1.215 + { *aIndentLevel = mIndentLevel; return NS_OK; } \ 1.216 + NS_IMETHOD GetBookmarkIndex(int32_t* aIndex) \ 1.217 + { *aIndex = mBookmarkIndex; return NS_OK; } \ 1.218 + NS_IMETHOD GetDateAdded(PRTime* aDateAdded) \ 1.219 + { *aDateAdded = mDateAdded; return NS_OK; } \ 1.220 + NS_IMETHOD GetLastModified(PRTime* aLastModified) \ 1.221 + { *aLastModified = mLastModified; return NS_OK; } 1.222 + 1.223 +#define NS_IMPLEMENT_SIMPLE_RESULTNODE \ 1.224 + NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \ 1.225 + NS_IMETHOD GetItemId(int64_t* aId) \ 1.226 + { *aId = mItemId; return NS_OK; } 1.227 + 1.228 +// This is used by the base classes instead of 1.229 +// NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they 1.230 +// need to redefine GetType and GetUri rather than forwarding them. This 1.231 +// implements all the simple getters instead of forwarding because they are so 1.232 +// short and we can save a virtual function call. 1.233 +// 1.234 +// (GetUri is redefined only by QueryResultNode and FolderResultNode because 1.235 +// the queries might not necessarily be parsed. The rest just return the node's 1.236 +// buffer.) 1.237 +#define NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \ 1.238 + NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \ 1.239 + NS_IMETHOD GetIcon(nsACString& aIcon) \ 1.240 + { return nsNavHistoryResultNode::GetIcon(aIcon); } \ 1.241 + NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) \ 1.242 + { return nsNavHistoryResultNode::GetParent(aParent); } \ 1.243 + NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) \ 1.244 + { return nsNavHistoryResultNode::GetParentResult(aResult); } \ 1.245 + NS_IMETHOD GetTags(nsAString& aTags) \ 1.246 + { return nsNavHistoryResultNode::GetTags(aTags); } \ 1.247 + NS_IMETHOD GetPageGuid(nsACString& aPageGuid) \ 1.248 + { return nsNavHistoryResultNode::GetPageGuid(aPageGuid); } \ 1.249 + NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) \ 1.250 + { return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); } 1.251 + 1.252 +#define NS_FORWARD_COMMON_RESULTNODE_TO_BASE \ 1.253 + NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \ 1.254 + NS_IMETHOD GetItemId(int64_t* aId) \ 1.255 + { *aId = mItemId; return NS_OK; } 1.256 + 1.257 +class nsNavHistoryResultNode : public nsINavHistoryResultNode 1.258 +{ 1.259 +public: 1.260 + nsNavHistoryResultNode(const nsACString& aURI, const nsACString& aTitle, 1.261 + uint32_t aAccessCount, PRTime aTime, 1.262 + const nsACString& aIconURI); 1.263 + virtual ~nsNavHistoryResultNode() {} 1.264 + 1.265 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID) 1.266 + 1.267 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.268 + NS_DECL_CYCLE_COLLECTION_CLASS(nsNavHistoryResultNode) 1.269 + 1.270 + NS_IMPLEMENT_SIMPLE_RESULTNODE 1.271 + NS_IMETHOD GetIcon(nsACString& aIcon); 1.272 + NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent); 1.273 + NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult); 1.274 + NS_IMETHOD GetType(uint32_t* type) 1.275 + { *type = nsNavHistoryResultNode::RESULT_TYPE_URI; return NS_OK; } 1.276 + NS_IMETHOD GetUri(nsACString& aURI) 1.277 + { aURI = mURI; return NS_OK; } 1.278 + NS_IMETHOD GetTags(nsAString& aTags); 1.279 + NS_IMETHOD GetPageGuid(nsACString& aPageGuid); 1.280 + NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid); 1.281 + 1.282 + virtual void OnRemoving(); 1.283 + 1.284 + // Called from result's onItemChanged, see also bookmark observer declaration in 1.285 + // nsNavHistoryFolderResultNode 1.286 + NS_IMETHOD OnItemChanged(int64_t aItemId, 1.287 + const nsACString &aProperty, 1.288 + bool aIsAnnotationProperty, 1.289 + const nsACString &aValue, 1.290 + PRTime aNewLastModified, 1.291 + uint16_t aItemType, 1.292 + int64_t aParentId, 1.293 + const nsACString& aGUID, 1.294 + const nsACString& aParentGUID); 1.295 + 1.296 +public: 1.297 + 1.298 + nsNavHistoryResult* GetResult(); 1.299 + nsNavHistoryQueryOptions* GetGeneratingOptions(); 1.300 + 1.301 + // These functions test the type. We don't use a virtual function since that 1.302 + // would take a vtable slot for every one of (potentially very many) nodes. 1.303 + // Note that GetType() already has a vtable slot because its on the iface. 1.304 + bool IsTypeContainer(uint32_t type) { 1.305 + return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY || 1.306 + type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER || 1.307 + type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT; 1.308 + } 1.309 + bool IsContainer() { 1.310 + uint32_t type; 1.311 + GetType(&type); 1.312 + return IsTypeContainer(type); 1.313 + } 1.314 + static bool IsTypeURI(uint32_t type) { 1.315 + return type == nsINavHistoryResultNode::RESULT_TYPE_URI; 1.316 + } 1.317 + bool IsURI() { 1.318 + uint32_t type; 1.319 + GetType(&type); 1.320 + return IsTypeURI(type); 1.321 + } 1.322 + static bool IsTypeFolder(uint32_t type) { 1.323 + return type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER || 1.324 + type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT; 1.325 + } 1.326 + bool IsFolder() { 1.327 + uint32_t type; 1.328 + GetType(&type); 1.329 + return IsTypeFolder(type); 1.330 + } 1.331 + static bool IsTypeQuery(uint32_t type) { 1.332 + return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY; 1.333 + } 1.334 + bool IsQuery() { 1.335 + uint32_t type; 1.336 + GetType(&type); 1.337 + return IsTypeQuery(type); 1.338 + } 1.339 + bool IsSeparator() { 1.340 + uint32_t type; 1.341 + GetType(&type); 1.342 + return type == nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR; 1.343 + } 1.344 + nsNavHistoryContainerResultNode* GetAsContainer() { 1.345 + NS_ASSERTION(IsContainer(), "Not a container"); 1.346 + return reinterpret_cast<nsNavHistoryContainerResultNode*>(this); 1.347 + } 1.348 + nsNavHistoryFolderResultNode* GetAsFolder() { 1.349 + NS_ASSERTION(IsFolder(), "Not a folder"); 1.350 + return reinterpret_cast<nsNavHistoryFolderResultNode*>(this); 1.351 + } 1.352 + nsNavHistoryQueryResultNode* GetAsQuery() { 1.353 + NS_ASSERTION(IsQuery(), "Not a query"); 1.354 + return reinterpret_cast<nsNavHistoryQueryResultNode*>(this); 1.355 + } 1.356 + 1.357 + nsRefPtr<nsNavHistoryContainerResultNode> mParent; 1.358 + nsCString mURI; // not necessarily valid for containers, call GetUri 1.359 + nsCString mTitle; 1.360 + nsString mTags; 1.361 + bool mAreTagsSorted; 1.362 + uint32_t mAccessCount; 1.363 + int64_t mTime; 1.364 + nsCString mFaviconURI; 1.365 + int32_t mBookmarkIndex; 1.366 + int64_t mItemId; 1.367 + int64_t mFolderId; 1.368 + PRTime mDateAdded; 1.369 + PRTime mLastModified; 1.370 + 1.371 + // The indent level of this node. The root node will have a value of -1. The 1.372 + // root's children will have a value of 0, and so on. 1.373 + int32_t mIndentLevel; 1.374 + 1.375 + // Frecency of the page. Valid only for URI nodes. 1.376 + int32_t mFrecency; 1.377 + 1.378 + // Hidden status of the page. Valid only for URI nodes. 1.379 + bool mHidden; 1.380 + 1.381 + // Transition type used when this node represents a single visit. 1.382 + uint32_t mTransitionType; 1.383 + 1.384 + // Unique Id of the page. 1.385 + nsCString mPageGuid; 1.386 + 1.387 + // Unique Id of the bookmark. 1.388 + nsCString mBookmarkGuid; 1.389 +}; 1.390 + 1.391 +NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResultNode, NS_NAVHISTORYRESULTNODE_IID) 1.392 + 1.393 + 1.394 +// nsNavHistoryContainerResultNode 1.395 +// 1.396 +// This is the base class for all nodes that can have children. It is 1.397 +// overridden for nodes that are dynamically populated such as queries and 1.398 +// folders. It is used directly for simple containers such as host groups 1.399 +// in history views. 1.400 + 1.401 +// derived classes each provide their own implementation of has children and 1.402 +// forward the rest to us using this macro 1.403 +#define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY \ 1.404 + NS_IMETHOD GetState(uint16_t* _state) \ 1.405 + { return nsNavHistoryContainerResultNode::GetState(_state); } \ 1.406 + NS_IMETHOD GetContainerOpen(bool *aContainerOpen) \ 1.407 + { return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); } \ 1.408 + NS_IMETHOD SetContainerOpen(bool aContainerOpen) \ 1.409 + { return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); } \ 1.410 + NS_IMETHOD GetChildCount(uint32_t *aChildCount) \ 1.411 + { return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \ 1.412 + NS_IMETHOD GetChild(uint32_t index, nsINavHistoryResultNode **_retval) \ 1.413 + { return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \ 1.414 + NS_IMETHOD GetChildIndex(nsINavHistoryResultNode* aNode, uint32_t* _retval) \ 1.415 + { return nsNavHistoryContainerResultNode::GetChildIndex(aNode, _retval); } \ 1.416 + NS_IMETHOD FindNodeByDetails(const nsACString& aURIString, PRTime aTime, \ 1.417 + int64_t aItemId, bool aRecursive, \ 1.418 + nsINavHistoryResultNode** _retval) \ 1.419 + { return nsNavHistoryContainerResultNode::FindNodeByDetails(aURIString, aTime, aItemId, \ 1.420 + aRecursive, _retval); } 1.421 + 1.422 +#define NS_NAVHISTORYCONTAINERRESULTNODE_IID \ 1.423 + { 0x6e3bf8d3, 0x22aa, 0x4065, { 0x86, 0xbc, 0x37, 0x46, 0xb5, 0xb3, 0x2c, 0xe8 } } 1.424 + 1.425 +class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode, 1.426 + public nsINavHistoryContainerResultNode 1.427 +{ 1.428 +public: 1.429 + nsNavHistoryContainerResultNode( 1.430 + const nsACString& aURI, const nsACString& aTitle, 1.431 + const nsACString& aIconURI, uint32_t aContainerType, 1.432 + bool aReadOnly, nsNavHistoryQueryOptions* aOptions); 1.433 + nsNavHistoryContainerResultNode( 1.434 + const nsACString& aURI, const nsACString& aTitle, 1.435 + PRTime aTime, 1.436 + const nsACString& aIconURI, uint32_t aContainerType, 1.437 + bool aReadOnly, nsNavHistoryQueryOptions* aOptions); 1.438 + 1.439 + virtual nsresult Refresh(); 1.440 + virtual ~nsNavHistoryContainerResultNode(); 1.441 + 1.442 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID) 1.443 + 1.444 + NS_DECL_ISUPPORTS_INHERITED 1.445 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode) 1.446 + NS_FORWARD_COMMON_RESULTNODE_TO_BASE 1.447 + NS_IMETHOD GetType(uint32_t* type) 1.448 + { *type = mContainerType; return NS_OK; } 1.449 + NS_IMETHOD GetUri(nsACString& aURI) 1.450 + { aURI = mURI; return NS_OK; } 1.451 + NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE 1.452 + 1.453 +public: 1.454 + 1.455 + virtual void OnRemoving(); 1.456 + 1.457 + bool AreChildrenVisible(); 1.458 + 1.459 + // Overridded by descendents to populate. 1.460 + virtual nsresult OpenContainer(); 1.461 + nsresult CloseContainer(bool aSuppressNotifications = false); 1.462 + 1.463 + virtual nsresult OpenContainerAsync(); 1.464 + 1.465 + // This points to the result that owns this container. All containers have 1.466 + // their result pointer set so we can quickly get to the result without having 1.467 + // to walk the tree. Yet, this also saves us from storing a million pointers 1.468 + // for every leaf node to the result. 1.469 + nsRefPtr<nsNavHistoryResult> mResult; 1.470 + 1.471 + // For example, RESULT_TYPE_QUERY. Query and Folder results override GetType 1.472 + // so this is not used, but is still kept in sync. 1.473 + uint32_t mContainerType; 1.474 + 1.475 + // When there are children, this stores the open state in the tree 1.476 + // this is set to the default in the constructor. 1.477 + bool mExpanded; 1.478 + 1.479 + // Filled in by the result type generator in nsNavHistory. 1.480 + nsCOMArray<nsNavHistoryResultNode> mChildren; 1.481 + 1.482 + bool mChildrenReadOnly; 1.483 + 1.484 + nsCOMPtr<nsNavHistoryQueryOptions> mOptions; 1.485 + 1.486 + void FillStats(); 1.487 + nsresult ReverseUpdateStats(int32_t aAccessCountChange); 1.488 + 1.489 + // Sorting methods. 1.490 + typedef nsCOMArray<nsNavHistoryResultNode>::nsCOMArrayComparatorFunc SortComparator; 1.491 + virtual uint16_t GetSortType(); 1.492 + virtual void GetSortingAnnotation(nsACString& aSortingAnnotation); 1.493 + 1.494 + static SortComparator GetSortingComparator(uint16_t aSortType); 1.495 + virtual void RecursiveSort(const char* aData, 1.496 + SortComparator aComparator); 1.497 + uint32_t FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator, 1.498 + const char* aData, bool* aItemExists); 1.499 + bool DoesChildNeedResorting(uint32_t aIndex, SortComparator aComparator, 1.500 + const char* aData); 1.501 + 1.502 + static int32_t SortComparison_StringLess(const nsAString& a, const nsAString& b); 1.503 + 1.504 + static int32_t SortComparison_Bookmark(nsNavHistoryResultNode* a, 1.505 + nsNavHistoryResultNode* b, 1.506 + void* closure); 1.507 + static int32_t SortComparison_TitleLess(nsNavHistoryResultNode* a, 1.508 + nsNavHistoryResultNode* b, 1.509 + void* closure); 1.510 + static int32_t SortComparison_TitleGreater(nsNavHistoryResultNode* a, 1.511 + nsNavHistoryResultNode* b, 1.512 + void* closure); 1.513 + static int32_t SortComparison_DateLess(nsNavHistoryResultNode* a, 1.514 + nsNavHistoryResultNode* b, 1.515 + void* closure); 1.516 + static int32_t SortComparison_DateGreater(nsNavHistoryResultNode* a, 1.517 + nsNavHistoryResultNode* b, 1.518 + void* closure); 1.519 + static int32_t SortComparison_URILess(nsNavHistoryResultNode* a, 1.520 + nsNavHistoryResultNode* b, 1.521 + void* closure); 1.522 + static int32_t SortComparison_URIGreater(nsNavHistoryResultNode* a, 1.523 + nsNavHistoryResultNode* b, 1.524 + void* closure); 1.525 + static int32_t SortComparison_VisitCountLess(nsNavHistoryResultNode* a, 1.526 + nsNavHistoryResultNode* b, 1.527 + void* closure); 1.528 + static int32_t SortComparison_VisitCountGreater(nsNavHistoryResultNode* a, 1.529 + nsNavHistoryResultNode* b, 1.530 + void* closure); 1.531 + static int32_t SortComparison_KeywordLess(nsNavHistoryResultNode* a, 1.532 + nsNavHistoryResultNode* b, 1.533 + void* closure); 1.534 + static int32_t SortComparison_KeywordGreater(nsNavHistoryResultNode* a, 1.535 + nsNavHistoryResultNode* b, 1.536 + void* closure); 1.537 + static int32_t SortComparison_AnnotationLess(nsNavHistoryResultNode* a, 1.538 + nsNavHistoryResultNode* b, 1.539 + void* closure); 1.540 + static int32_t SortComparison_AnnotationGreater(nsNavHistoryResultNode* a, 1.541 + nsNavHistoryResultNode* b, 1.542 + void* closure); 1.543 + static int32_t SortComparison_DateAddedLess(nsNavHistoryResultNode* a, 1.544 + nsNavHistoryResultNode* b, 1.545 + void* closure); 1.546 + static int32_t SortComparison_DateAddedGreater(nsNavHistoryResultNode* a, 1.547 + nsNavHistoryResultNode* b, 1.548 + void* closure); 1.549 + static int32_t SortComparison_LastModifiedLess(nsNavHistoryResultNode* a, 1.550 + nsNavHistoryResultNode* b, 1.551 + void* closure); 1.552 + static int32_t SortComparison_LastModifiedGreater(nsNavHistoryResultNode* a, 1.553 + nsNavHistoryResultNode* b, 1.554 + void* closure); 1.555 + static int32_t SortComparison_TagsLess(nsNavHistoryResultNode* a, 1.556 + nsNavHistoryResultNode* b, 1.557 + void* closure); 1.558 + static int32_t SortComparison_TagsGreater(nsNavHistoryResultNode* a, 1.559 + nsNavHistoryResultNode* b, 1.560 + void* closure); 1.561 + static int32_t SortComparison_FrecencyLess(nsNavHistoryResultNode* a, 1.562 + nsNavHistoryResultNode* b, 1.563 + void* closure); 1.564 + static int32_t SortComparison_FrecencyGreater(nsNavHistoryResultNode* a, 1.565 + nsNavHistoryResultNode* b, 1.566 + void* closure); 1.567 + 1.568 + // finding children: THESE DO NOT ADDREF 1.569 + nsNavHistoryResultNode* FindChildURI(nsIURI* aURI, uint32_t* aNodeIndex) 1.570 + { 1.571 + nsAutoCString spec; 1.572 + if (NS_FAILED(aURI->GetSpec(spec))) 1.573 + return nullptr; 1.574 + return FindChildURI(spec, aNodeIndex); 1.575 + } 1.576 + nsNavHistoryResultNode* FindChildURI(const nsACString& aSpec, 1.577 + uint32_t* aNodeIndex); 1.578 + // returns the index of the given node, -1 if not found 1.579 + int32_t FindChild(nsNavHistoryResultNode* aNode) 1.580 + { return mChildren.IndexOf(aNode); } 1.581 + 1.582 + nsresult InsertChildAt(nsNavHistoryResultNode* aNode, int32_t aIndex, 1.583 + bool aIsTemporary = false); 1.584 + nsresult InsertSortedChild(nsNavHistoryResultNode* aNode, 1.585 + bool aIsTemporary = false, 1.586 + bool aIgnoreDuplicates = false); 1.587 + bool EnsureItemPosition(uint32_t aIndex); 1.588 + 1.589 + nsresult RemoveChildAt(int32_t aIndex, bool aIsTemporary = false); 1.590 + 1.591 + void RecursiveFindURIs(bool aOnlyOne, 1.592 + nsNavHistoryContainerResultNode* aContainer, 1.593 + const nsCString& aSpec, 1.594 + nsCOMArray<nsNavHistoryResultNode>* aMatches); 1.595 + bool UpdateURIs(bool aRecursive, bool aOnlyOne, bool aUpdateSort, 1.596 + const nsCString& aSpec, 1.597 + nsresult (*aCallback)(nsNavHistoryResultNode*, const void*, 1.598 + const nsNavHistoryResult*), 1.599 + const void* aClosure); 1.600 + nsresult ChangeTitles(nsIURI* aURI, const nsACString& aNewTitle, 1.601 + bool aRecursive, bool aOnlyOne); 1.602 + 1.603 +protected: 1.604 + 1.605 + enum AsyncCanceledState { 1.606 + NOT_CANCELED, CANCELED, CANCELED_RESTART_NEEDED 1.607 + }; 1.608 + 1.609 + void CancelAsyncOpen(bool aRestart); 1.610 + nsresult NotifyOnStateChange(uint16_t aOldState); 1.611 + 1.612 + nsCOMPtr<mozIStoragePendingStatement> mAsyncPendingStmt; 1.613 + AsyncCanceledState mAsyncCanceledState; 1.614 +}; 1.615 + 1.616 +NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryContainerResultNode, 1.617 + NS_NAVHISTORYCONTAINERRESULTNODE_IID) 1.618 + 1.619 +// nsNavHistoryQueryResultNode 1.620 +// 1.621 +// Overridden container type for complex queries over history and/or 1.622 +// bookmarks. This keeps itself in sync by listening to history and 1.623 +// bookmark notifications. 1.624 + 1.625 +class nsNavHistoryQueryResultNode : public nsNavHistoryContainerResultNode, 1.626 + public nsINavHistoryQueryResultNode 1.627 +{ 1.628 +public: 1.629 + nsNavHistoryQueryResultNode(const nsACString& aTitle, 1.630 + const nsACString& aIconURI, 1.631 + const nsACString& aQueryURI); 1.632 + nsNavHistoryQueryResultNode(const nsACString& aTitle, 1.633 + const nsACString& aIconURI, 1.634 + const nsCOMArray<nsNavHistoryQuery>& aQueries, 1.635 + nsNavHistoryQueryOptions* aOptions); 1.636 + nsNavHistoryQueryResultNode(const nsACString& aTitle, 1.637 + const nsACString& aIconURI, 1.638 + PRTime aTime, 1.639 + const nsCOMArray<nsNavHistoryQuery>& aQueries, 1.640 + nsNavHistoryQueryOptions* aOptions); 1.641 + 1.642 + virtual ~nsNavHistoryQueryResultNode(); 1.643 + 1.644 + NS_DECL_ISUPPORTS_INHERITED 1.645 + NS_FORWARD_COMMON_RESULTNODE_TO_BASE 1.646 + NS_IMETHOD GetType(uint32_t* type) 1.647 + { *type = nsNavHistoryResultNode::RESULT_TYPE_QUERY; return NS_OK; } 1.648 + NS_IMETHOD GetUri(nsACString& aURI); // does special lazy creation 1.649 + NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY 1.650 + NS_IMETHOD GetHasChildren(bool* aHasChildren); 1.651 + NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly) 1.652 + { return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); } 1.653 + NS_DECL_NSINAVHISTORYQUERYRESULTNODE 1.654 + 1.655 + bool CanExpand(); 1.656 + bool IsContainersQuery(); 1.657 + 1.658 + virtual nsresult OpenContainer(); 1.659 + 1.660 + NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL 1.661 + virtual void OnRemoving(); 1.662 + 1.663 +public: 1.664 + // this constructs lazily mURI from mQueries and mOptions, call 1.665 + // VerifyQueriesSerialized either this or mQueries/mOptions should be valid 1.666 + nsresult VerifyQueriesSerialized(); 1.667 + 1.668 + // these may be constructed lazily from mURI, call VerifyQueriesParsed 1.669 + // either this or mURI should be valid 1.670 + nsCOMArray<nsNavHistoryQuery> mQueries; 1.671 + uint32_t mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h 1.672 + bool mHasSearchTerms; 1.673 + nsresult VerifyQueriesParsed(); 1.674 + 1.675 + // safe options getter, ensures queries are parsed 1.676 + nsNavHistoryQueryOptions* Options(); 1.677 + 1.678 + // this indicates whether the query contents are valid, they don't go away 1.679 + // after the container is closed until a notification comes in 1.680 + bool mContentsValid; 1.681 + 1.682 + nsresult FillChildren(); 1.683 + void ClearChildren(bool unregister); 1.684 + nsresult Refresh(); 1.685 + 1.686 + virtual uint16_t GetSortType(); 1.687 + virtual void GetSortingAnnotation(nsACString& aSortingAnnotation); 1.688 + virtual void RecursiveSort(const char* aData, 1.689 + SortComparator aComparator); 1.690 + 1.691 + nsCOMPtr<nsIURI> mRemovingURI; 1.692 + nsresult NotifyIfTagsChanged(nsIURI* aURI); 1.693 + 1.694 + uint32_t mBatchChanges; 1.695 + 1.696 + // Tracks transition type filters shared by all mQueries. 1.697 + nsTArray<uint32_t> mTransitions; 1.698 +}; 1.699 + 1.700 + 1.701 +// nsNavHistoryFolderResultNode 1.702 +// 1.703 +// Overridden container type for bookmark folders. It will keep the contents 1.704 +// of the folder in sync with the bookmark service. 1.705 + 1.706 +class nsNavHistoryFolderResultNode : public nsNavHistoryContainerResultNode, 1.707 + public nsINavHistoryQueryResultNode, 1.708 + public mozilla::places::AsyncStatementCallback 1.709 +{ 1.710 +public: 1.711 + nsNavHistoryFolderResultNode(const nsACString& aTitle, 1.712 + nsNavHistoryQueryOptions* options, 1.713 + int64_t aFolderId); 1.714 + 1.715 + virtual ~nsNavHistoryFolderResultNode(); 1.716 + 1.717 + NS_DECL_ISUPPORTS_INHERITED 1.718 + NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID 1.719 + NS_IMETHOD GetType(uint32_t* type) { 1.720 + if (mQueryItemId != -1) { 1.721 + *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT; 1.722 + } else { 1.723 + *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER; 1.724 + } 1.725 + return NS_OK; 1.726 + } 1.727 + NS_IMETHOD GetUri(nsACString& aURI); 1.728 + NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY 1.729 + NS_IMETHOD GetHasChildren(bool* aHasChildren); 1.730 + NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly); 1.731 + NS_IMETHOD GetItemId(int64_t *aItemId); 1.732 + NS_DECL_NSINAVHISTORYQUERYRESULTNODE 1.733 + 1.734 + virtual nsresult OpenContainer(); 1.735 + 1.736 + virtual nsresult OpenContainerAsync(); 1.737 + NS_DECL_ASYNCSTATEMENTCALLBACK 1.738 + 1.739 + // This object implements a bookmark observer interface without deriving from 1.740 + // the bookmark observers. This is called from the result's actual observer 1.741 + // and it knows all observers are FolderResultNodes 1.742 + NS_DECL_NSINAVBOOKMARKOBSERVER 1.743 + 1.744 + virtual void OnRemoving(); 1.745 + 1.746 + // this indicates whether the folder contents are valid, they don't go away 1.747 + // after the container is closed until a notification comes in 1.748 + bool mContentsValid; 1.749 + 1.750 + // If the node is generated from a place:folder=X query, this is the query's 1.751 + // itemId. 1.752 + int64_t mQueryItemId; 1.753 + 1.754 + nsresult FillChildren(); 1.755 + void ClearChildren(bool aUnregister); 1.756 + nsresult Refresh(); 1.757 + 1.758 + bool StartIncrementalUpdate(); 1.759 + void ReindexRange(int32_t aStartIndex, int32_t aEndIndex, int32_t aDelta); 1.760 + 1.761 + nsNavHistoryResultNode* FindChildById(int64_t aItemId, 1.762 + uint32_t* aNodeIndex); 1.763 + 1.764 +private: 1.765 + 1.766 + nsresult OnChildrenFilled(); 1.767 + void EnsureRegisteredAsFolderObserver(); 1.768 + nsresult FillChildrenAsync(); 1.769 + 1.770 + bool mIsRegisteredFolderObserver; 1.771 + int32_t mAsyncBookmarkIndex; 1.772 +}; 1.773 + 1.774 +// nsNavHistorySeparatorResultNode 1.775 +// 1.776 +// Separator result nodes do not hold any data. 1.777 +class nsNavHistorySeparatorResultNode : public nsNavHistoryResultNode 1.778 +{ 1.779 +public: 1.780 + nsNavHistorySeparatorResultNode(); 1.781 + 1.782 + NS_IMETHOD GetType(uint32_t* type) 1.783 + { *type = nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR; return NS_OK; } 1.784 +}; 1.785 + 1.786 +#endif // nsNavHistoryResult_h_