toolkit/components/places/nsNavHistoryResult.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /**
michael@0 7 * The definitions of objects that make up a history query result set. This file
michael@0 8 * should only be included by nsNavHistory.h, include that if you want these
michael@0 9 * classes.
michael@0 10 */
michael@0 11
michael@0 12 #ifndef nsNavHistoryResult_h_
michael@0 13 #define nsNavHistoryResult_h_
michael@0 14
michael@0 15 #include "nsTArray.h"
michael@0 16 #include "nsInterfaceHashtable.h"
michael@0 17 #include "nsDataHashtable.h"
michael@0 18 #include "nsCycleCollectionParticipant.h"
michael@0 19 #include "mozilla/storage.h"
michael@0 20 #include "Helpers.h"
michael@0 21
michael@0 22 class nsNavHistory;
michael@0 23 class nsNavHistoryQuery;
michael@0 24 class nsNavHistoryQueryOptions;
michael@0 25
michael@0 26 class nsNavHistoryContainerResultNode;
michael@0 27 class nsNavHistoryFolderResultNode;
michael@0 28 class nsNavHistoryQueryResultNode;
michael@0 29
michael@0 30 /**
michael@0 31 * hashkey wrapper using int64_t KeyType
michael@0 32 *
michael@0 33 * @see nsTHashtable::EntryType for specification
michael@0 34 *
michael@0 35 * This just truncates the 64-bit int to a 32-bit one for using a hash number.
michael@0 36 * It is used for bookmark folder IDs, which should be way less than 2^32.
michael@0 37 */
michael@0 38 class nsTrimInt64HashKey : public PLDHashEntryHdr
michael@0 39 {
michael@0 40 public:
michael@0 41 typedef const int64_t& KeyType;
michael@0 42 typedef const int64_t* KeyTypePointer;
michael@0 43
michael@0 44 nsTrimInt64HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
michael@0 45 nsTrimInt64HashKey(const nsTrimInt64HashKey& toCopy) : mValue(toCopy.mValue) { }
michael@0 46 ~nsTrimInt64HashKey() { }
michael@0 47
michael@0 48 KeyType GetKey() const { return mValue; }
michael@0 49 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
michael@0 50
michael@0 51 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
michael@0 52 static PLDHashNumber HashKey(KeyTypePointer aKey)
michael@0 53 { return static_cast<uint32_t>((*aKey) & UINT32_MAX); }
michael@0 54 enum { ALLOW_MEMMOVE = true };
michael@0 55
michael@0 56 private:
michael@0 57 const int64_t mValue;
michael@0 58 };
michael@0 59
michael@0 60
michael@0 61 // Declare methods for implementing nsINavBookmarkObserver
michael@0 62 // and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap)
michael@0 63 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
michael@0 64 NS_DECL_NSINAVBOOKMARKOBSERVER \
michael@0 65 NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
michael@0 66 const nsACString& aGUID); \
michael@0 67 NS_IMETHOD OnFrecencyChanged(nsIURI* aURI, int32_t aNewFrecency, \
michael@0 68 const nsACString& aGUID, bool aHidden, \
michael@0 69 PRTime aLastVisitDate); \
michael@0 70 NS_IMETHOD OnManyFrecenciesChanged(); \
michael@0 71 NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
michael@0 72 uint16_t aReason); \
michael@0 73 NS_IMETHOD OnClearHistory(); \
michael@0 74 NS_IMETHOD OnPageChanged(nsIURI *aURI, uint32_t aChangedAttribute, \
michael@0 75 const nsAString &aNewValue, \
michael@0 76 const nsACString &aGUID); \
michael@0 77 NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \
michael@0 78 const nsACString& aGUID, uint16_t aReason, \
michael@0 79 uint32_t aTransitionType);
michael@0 80
michael@0 81 // The internal version has an output aAdded parameter, it is incremented by
michael@0 82 // query nodes when the visited uri belongs to them. If no such query exists,
michael@0 83 // the history result creates a new query node dynamically.
michael@0 84 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL \
michael@0 85 NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
michael@0 86 NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
michael@0 87 int64_t aSessionId, int64_t aReferringId, \
michael@0 88 uint32_t aTransitionType, const nsACString& aGUID, \
michael@0 89 bool aHidden, uint32_t* aAdded);
michael@0 90
michael@0 91 // The external version is used by results.
michael@0 92 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL \
michael@0 93 NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
michael@0 94 NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
michael@0 95 int64_t aSessionId, int64_t aReferringId, \
michael@0 96 uint32_t aTransitionType, const nsACString& aGUID, \
michael@0 97 bool aHidden);
michael@0 98
michael@0 99 // nsNavHistoryResult
michael@0 100 //
michael@0 101 // nsNavHistory creates this object and fills in mChildren (by getting
michael@0 102 // it through GetTopLevel()). Then FilledAllResults() is called to finish
michael@0 103 // object initialization.
michael@0 104
michael@0 105 #define NS_NAVHISTORYRESULT_IID \
michael@0 106 { 0x455d1d40, 0x1b9b, 0x40e6, { 0xa6, 0x41, 0x8b, 0xb7, 0xe8, 0x82, 0x23, 0x87 } }
michael@0 107
michael@0 108 class nsNavHistoryResult : public nsSupportsWeakReference,
michael@0 109 public nsINavHistoryResult,
michael@0 110 public nsINavBookmarkObserver,
michael@0 111 public nsINavHistoryObserver
michael@0 112 {
michael@0 113 public:
michael@0 114 static nsresult NewHistoryResult(nsINavHistoryQuery** aQueries,
michael@0 115 uint32_t aQueryCount,
michael@0 116 nsNavHistoryQueryOptions* aOptions,
michael@0 117 nsNavHistoryContainerResultNode* aRoot,
michael@0 118 bool aBatchInProgress,
michael@0 119 nsNavHistoryResult** result);
michael@0 120
michael@0 121 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID)
michael@0 122
michael@0 123 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 124 NS_DECL_NSINAVHISTORYRESULT
michael@0 125 NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL
michael@0 126 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult, nsINavHistoryResult)
michael@0 127
michael@0 128 void AddHistoryObserver(nsNavHistoryQueryResultNode* aNode);
michael@0 129 void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
michael@0 130 void AddAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
michael@0 131 void RemoveHistoryObserver(nsNavHistoryQueryResultNode* aNode);
michael@0 132 void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
michael@0 133 void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
michael@0 134 void StopObserving();
michael@0 135
michael@0 136 public:
michael@0 137 // two-stage init, use NewHistoryResult to construct
michael@0 138 nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot);
michael@0 139 virtual ~nsNavHistoryResult();
michael@0 140 nsresult Init(nsINavHistoryQuery** aQueries,
michael@0 141 uint32_t aQueryCount,
michael@0 142 nsNavHistoryQueryOptions *aOptions);
michael@0 143
michael@0 144 nsRefPtr<nsNavHistoryContainerResultNode> mRootNode;
michael@0 145
michael@0 146 nsCOMArray<nsINavHistoryQuery> mQueries;
michael@0 147 nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
michael@0 148
michael@0 149 // One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to mOptions.sortingMode,
michael@0 150 // but may be overridden if the user clicks on one of the columns.
michael@0 151 uint16_t mSortingMode;
michael@0 152 // If root node is closed and we try to apply a sortingMode, it would not
michael@0 153 // work. So we will apply it when the node will be reopened and populated.
michael@0 154 // This var states the fact we need to apply sortingMode in such a situation.
michael@0 155 bool mNeedsToApplySortingMode;
michael@0 156
michael@0 157 // The sorting annotation to be used for in SORT_BY_ANNOTATION_* modes
michael@0 158 nsCString mSortingAnnotation;
michael@0 159
michael@0 160 // node observers
michael@0 161 bool mIsHistoryObserver;
michael@0 162 bool mIsBookmarkFolderObserver;
michael@0 163 bool mIsAllBookmarksObserver;
michael@0 164
michael@0 165 typedef nsTArray< nsRefPtr<nsNavHistoryQueryResultNode> > QueryObserverList;
michael@0 166 QueryObserverList mHistoryObservers;
michael@0 167 QueryObserverList mAllBookmarksObservers;
michael@0 168
michael@0 169 typedef nsTArray< nsRefPtr<nsNavHistoryFolderResultNode> > FolderObserverList;
michael@0 170 nsDataHashtable<nsTrimInt64HashKey, FolderObserverList*> mBookmarkFolderObservers;
michael@0 171 FolderObserverList* BookmarkFolderObserversForId(int64_t aFolderId, bool aCreate);
michael@0 172
michael@0 173 typedef nsTArray< nsRefPtr<nsNavHistoryContainerResultNode> > ContainerObserverList;
michael@0 174
michael@0 175 void RecursiveExpandCollapse(nsNavHistoryContainerResultNode* aContainer,
michael@0 176 bool aExpand);
michael@0 177
michael@0 178 void InvalidateTree();
michael@0 179
michael@0 180 bool mBatchInProgress;
michael@0 181
michael@0 182 nsMaybeWeakPtrArray<nsINavHistoryResultObserver> mObservers;
michael@0 183 bool mSuppressNotifications;
michael@0 184
michael@0 185 ContainerObserverList mRefreshParticipants;
michael@0 186 void requestRefresh(nsNavHistoryContainerResultNode* aContainer);
michael@0 187 };
michael@0 188
michael@0 189 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)
michael@0 190
michael@0 191 // nsNavHistoryResultNode
michael@0 192 //
michael@0 193 // This is the base class for every node in a result set. The result itself
michael@0 194 // is a node (nsNavHistoryResult inherits from this), as well as every
michael@0 195 // leaf and branch on the tree.
michael@0 196
michael@0 197 #define NS_NAVHISTORYRESULTNODE_IID \
michael@0 198 {0x54b61d38, 0x57c1, 0x11da, {0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e}}
michael@0 199
michael@0 200 // These are all the simple getters, they can be used for the result node
michael@0 201 // implementation and all subclasses. More complex are GetIcon, GetParent
michael@0 202 // (which depends on the definition of container result node), and GetUri
michael@0 203 // (which is overridded for lazy construction for some containers).
michael@0 204 #define NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
michael@0 205 NS_IMETHOD GetTitle(nsACString& aTitle) \
michael@0 206 { aTitle = mTitle; return NS_OK; } \
michael@0 207 NS_IMETHOD GetAccessCount(uint32_t* aAccessCount) \
michael@0 208 { *aAccessCount = mAccessCount; return NS_OK; } \
michael@0 209 NS_IMETHOD GetTime(PRTime* aTime) \
michael@0 210 { *aTime = mTime; return NS_OK; } \
michael@0 211 NS_IMETHOD GetIndentLevel(int32_t* aIndentLevel) \
michael@0 212 { *aIndentLevel = mIndentLevel; return NS_OK; } \
michael@0 213 NS_IMETHOD GetBookmarkIndex(int32_t* aIndex) \
michael@0 214 { *aIndex = mBookmarkIndex; return NS_OK; } \
michael@0 215 NS_IMETHOD GetDateAdded(PRTime* aDateAdded) \
michael@0 216 { *aDateAdded = mDateAdded; return NS_OK; } \
michael@0 217 NS_IMETHOD GetLastModified(PRTime* aLastModified) \
michael@0 218 { *aLastModified = mLastModified; return NS_OK; }
michael@0 219
michael@0 220 #define NS_IMPLEMENT_SIMPLE_RESULTNODE \
michael@0 221 NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
michael@0 222 NS_IMETHOD GetItemId(int64_t* aId) \
michael@0 223 { *aId = mItemId; return NS_OK; }
michael@0 224
michael@0 225 // This is used by the base classes instead of
michael@0 226 // NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
michael@0 227 // need to redefine GetType and GetUri rather than forwarding them. This
michael@0 228 // implements all the simple getters instead of forwarding because they are so
michael@0 229 // short and we can save a virtual function call.
michael@0 230 //
michael@0 231 // (GetUri is redefined only by QueryResultNode and FolderResultNode because
michael@0 232 // the queries might not necessarily be parsed. The rest just return the node's
michael@0 233 // buffer.)
michael@0 234 #define NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \
michael@0 235 NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
michael@0 236 NS_IMETHOD GetIcon(nsACString& aIcon) \
michael@0 237 { return nsNavHistoryResultNode::GetIcon(aIcon); } \
michael@0 238 NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) \
michael@0 239 { return nsNavHistoryResultNode::GetParent(aParent); } \
michael@0 240 NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) \
michael@0 241 { return nsNavHistoryResultNode::GetParentResult(aResult); } \
michael@0 242 NS_IMETHOD GetTags(nsAString& aTags) \
michael@0 243 { return nsNavHistoryResultNode::GetTags(aTags); } \
michael@0 244 NS_IMETHOD GetPageGuid(nsACString& aPageGuid) \
michael@0 245 { return nsNavHistoryResultNode::GetPageGuid(aPageGuid); } \
michael@0 246 NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) \
michael@0 247 { return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); }
michael@0 248
michael@0 249 #define NS_FORWARD_COMMON_RESULTNODE_TO_BASE \
michael@0 250 NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \
michael@0 251 NS_IMETHOD GetItemId(int64_t* aId) \
michael@0 252 { *aId = mItemId; return NS_OK; }
michael@0 253
michael@0 254 class nsNavHistoryResultNode : public nsINavHistoryResultNode
michael@0 255 {
michael@0 256 public:
michael@0 257 nsNavHistoryResultNode(const nsACString& aURI, const nsACString& aTitle,
michael@0 258 uint32_t aAccessCount, PRTime aTime,
michael@0 259 const nsACString& aIconURI);
michael@0 260 virtual ~nsNavHistoryResultNode() {}
michael@0 261
michael@0 262 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID)
michael@0 263
michael@0 264 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 265 NS_DECL_CYCLE_COLLECTION_CLASS(nsNavHistoryResultNode)
michael@0 266
michael@0 267 NS_IMPLEMENT_SIMPLE_RESULTNODE
michael@0 268 NS_IMETHOD GetIcon(nsACString& aIcon);
michael@0 269 NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent);
michael@0 270 NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult);
michael@0 271 NS_IMETHOD GetType(uint32_t* type)
michael@0 272 { *type = nsNavHistoryResultNode::RESULT_TYPE_URI; return NS_OK; }
michael@0 273 NS_IMETHOD GetUri(nsACString& aURI)
michael@0 274 { aURI = mURI; return NS_OK; }
michael@0 275 NS_IMETHOD GetTags(nsAString& aTags);
michael@0 276 NS_IMETHOD GetPageGuid(nsACString& aPageGuid);
michael@0 277 NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid);
michael@0 278
michael@0 279 virtual void OnRemoving();
michael@0 280
michael@0 281 // Called from result's onItemChanged, see also bookmark observer declaration in
michael@0 282 // nsNavHistoryFolderResultNode
michael@0 283 NS_IMETHOD OnItemChanged(int64_t aItemId,
michael@0 284 const nsACString &aProperty,
michael@0 285 bool aIsAnnotationProperty,
michael@0 286 const nsACString &aValue,
michael@0 287 PRTime aNewLastModified,
michael@0 288 uint16_t aItemType,
michael@0 289 int64_t aParentId,
michael@0 290 const nsACString& aGUID,
michael@0 291 const nsACString& aParentGUID);
michael@0 292
michael@0 293 public:
michael@0 294
michael@0 295 nsNavHistoryResult* GetResult();
michael@0 296 nsNavHistoryQueryOptions* GetGeneratingOptions();
michael@0 297
michael@0 298 // These functions test the type. We don't use a virtual function since that
michael@0 299 // would take a vtable slot for every one of (potentially very many) nodes.
michael@0 300 // Note that GetType() already has a vtable slot because its on the iface.
michael@0 301 bool IsTypeContainer(uint32_t type) {
michael@0 302 return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
michael@0 303 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
michael@0 304 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
michael@0 305 }
michael@0 306 bool IsContainer() {
michael@0 307 uint32_t type;
michael@0 308 GetType(&type);
michael@0 309 return IsTypeContainer(type);
michael@0 310 }
michael@0 311 static bool IsTypeURI(uint32_t type) {
michael@0 312 return type == nsINavHistoryResultNode::RESULT_TYPE_URI;
michael@0 313 }
michael@0 314 bool IsURI() {
michael@0 315 uint32_t type;
michael@0 316 GetType(&type);
michael@0 317 return IsTypeURI(type);
michael@0 318 }
michael@0 319 static bool IsTypeFolder(uint32_t type) {
michael@0 320 return type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
michael@0 321 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
michael@0 322 }
michael@0 323 bool IsFolder() {
michael@0 324 uint32_t type;
michael@0 325 GetType(&type);
michael@0 326 return IsTypeFolder(type);
michael@0 327 }
michael@0 328 static bool IsTypeQuery(uint32_t type) {
michael@0 329 return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY;
michael@0 330 }
michael@0 331 bool IsQuery() {
michael@0 332 uint32_t type;
michael@0 333 GetType(&type);
michael@0 334 return IsTypeQuery(type);
michael@0 335 }
michael@0 336 bool IsSeparator() {
michael@0 337 uint32_t type;
michael@0 338 GetType(&type);
michael@0 339 return type == nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR;
michael@0 340 }
michael@0 341 nsNavHistoryContainerResultNode* GetAsContainer() {
michael@0 342 NS_ASSERTION(IsContainer(), "Not a container");
michael@0 343 return reinterpret_cast<nsNavHistoryContainerResultNode*>(this);
michael@0 344 }
michael@0 345 nsNavHistoryFolderResultNode* GetAsFolder() {
michael@0 346 NS_ASSERTION(IsFolder(), "Not a folder");
michael@0 347 return reinterpret_cast<nsNavHistoryFolderResultNode*>(this);
michael@0 348 }
michael@0 349 nsNavHistoryQueryResultNode* GetAsQuery() {
michael@0 350 NS_ASSERTION(IsQuery(), "Not a query");
michael@0 351 return reinterpret_cast<nsNavHistoryQueryResultNode*>(this);
michael@0 352 }
michael@0 353
michael@0 354 nsRefPtr<nsNavHistoryContainerResultNode> mParent;
michael@0 355 nsCString mURI; // not necessarily valid for containers, call GetUri
michael@0 356 nsCString mTitle;
michael@0 357 nsString mTags;
michael@0 358 bool mAreTagsSorted;
michael@0 359 uint32_t mAccessCount;
michael@0 360 int64_t mTime;
michael@0 361 nsCString mFaviconURI;
michael@0 362 int32_t mBookmarkIndex;
michael@0 363 int64_t mItemId;
michael@0 364 int64_t mFolderId;
michael@0 365 PRTime mDateAdded;
michael@0 366 PRTime mLastModified;
michael@0 367
michael@0 368 // The indent level of this node. The root node will have a value of -1. The
michael@0 369 // root's children will have a value of 0, and so on.
michael@0 370 int32_t mIndentLevel;
michael@0 371
michael@0 372 // Frecency of the page. Valid only for URI nodes.
michael@0 373 int32_t mFrecency;
michael@0 374
michael@0 375 // Hidden status of the page. Valid only for URI nodes.
michael@0 376 bool mHidden;
michael@0 377
michael@0 378 // Transition type used when this node represents a single visit.
michael@0 379 uint32_t mTransitionType;
michael@0 380
michael@0 381 // Unique Id of the page.
michael@0 382 nsCString mPageGuid;
michael@0 383
michael@0 384 // Unique Id of the bookmark.
michael@0 385 nsCString mBookmarkGuid;
michael@0 386 };
michael@0 387
michael@0 388 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResultNode, NS_NAVHISTORYRESULTNODE_IID)
michael@0 389
michael@0 390
michael@0 391 // nsNavHistoryContainerResultNode
michael@0 392 //
michael@0 393 // This is the base class for all nodes that can have children. It is
michael@0 394 // overridden for nodes that are dynamically populated such as queries and
michael@0 395 // folders. It is used directly for simple containers such as host groups
michael@0 396 // in history views.
michael@0 397
michael@0 398 // derived classes each provide their own implementation of has children and
michael@0 399 // forward the rest to us using this macro
michael@0 400 #define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY \
michael@0 401 NS_IMETHOD GetState(uint16_t* _state) \
michael@0 402 { return nsNavHistoryContainerResultNode::GetState(_state); } \
michael@0 403 NS_IMETHOD GetContainerOpen(bool *aContainerOpen) \
michael@0 404 { return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); } \
michael@0 405 NS_IMETHOD SetContainerOpen(bool aContainerOpen) \
michael@0 406 { return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); } \
michael@0 407 NS_IMETHOD GetChildCount(uint32_t *aChildCount) \
michael@0 408 { return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \
michael@0 409 NS_IMETHOD GetChild(uint32_t index, nsINavHistoryResultNode **_retval) \
michael@0 410 { return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \
michael@0 411 NS_IMETHOD GetChildIndex(nsINavHistoryResultNode* aNode, uint32_t* _retval) \
michael@0 412 { return nsNavHistoryContainerResultNode::GetChildIndex(aNode, _retval); } \
michael@0 413 NS_IMETHOD FindNodeByDetails(const nsACString& aURIString, PRTime aTime, \
michael@0 414 int64_t aItemId, bool aRecursive, \
michael@0 415 nsINavHistoryResultNode** _retval) \
michael@0 416 { return nsNavHistoryContainerResultNode::FindNodeByDetails(aURIString, aTime, aItemId, \
michael@0 417 aRecursive, _retval); }
michael@0 418
michael@0 419 #define NS_NAVHISTORYCONTAINERRESULTNODE_IID \
michael@0 420 { 0x6e3bf8d3, 0x22aa, 0x4065, { 0x86, 0xbc, 0x37, 0x46, 0xb5, 0xb3, 0x2c, 0xe8 } }
michael@0 421
michael@0 422 class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode,
michael@0 423 public nsINavHistoryContainerResultNode
michael@0 424 {
michael@0 425 public:
michael@0 426 nsNavHistoryContainerResultNode(
michael@0 427 const nsACString& aURI, const nsACString& aTitle,
michael@0 428 const nsACString& aIconURI, uint32_t aContainerType,
michael@0 429 bool aReadOnly, nsNavHistoryQueryOptions* aOptions);
michael@0 430 nsNavHistoryContainerResultNode(
michael@0 431 const nsACString& aURI, const nsACString& aTitle,
michael@0 432 PRTime aTime,
michael@0 433 const nsACString& aIconURI, uint32_t aContainerType,
michael@0 434 bool aReadOnly, nsNavHistoryQueryOptions* aOptions);
michael@0 435
michael@0 436 virtual nsresult Refresh();
michael@0 437 virtual ~nsNavHistoryContainerResultNode();
michael@0 438
michael@0 439 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID)
michael@0 440
michael@0 441 NS_DECL_ISUPPORTS_INHERITED
michael@0 442 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
michael@0 443 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
michael@0 444 NS_IMETHOD GetType(uint32_t* type)
michael@0 445 { *type = mContainerType; return NS_OK; }
michael@0 446 NS_IMETHOD GetUri(nsACString& aURI)
michael@0 447 { aURI = mURI; return NS_OK; }
michael@0 448 NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE
michael@0 449
michael@0 450 public:
michael@0 451
michael@0 452 virtual void OnRemoving();
michael@0 453
michael@0 454 bool AreChildrenVisible();
michael@0 455
michael@0 456 // Overridded by descendents to populate.
michael@0 457 virtual nsresult OpenContainer();
michael@0 458 nsresult CloseContainer(bool aSuppressNotifications = false);
michael@0 459
michael@0 460 virtual nsresult OpenContainerAsync();
michael@0 461
michael@0 462 // This points to the result that owns this container. All containers have
michael@0 463 // their result pointer set so we can quickly get to the result without having
michael@0 464 // to walk the tree. Yet, this also saves us from storing a million pointers
michael@0 465 // for every leaf node to the result.
michael@0 466 nsRefPtr<nsNavHistoryResult> mResult;
michael@0 467
michael@0 468 // For example, RESULT_TYPE_QUERY. Query and Folder results override GetType
michael@0 469 // so this is not used, but is still kept in sync.
michael@0 470 uint32_t mContainerType;
michael@0 471
michael@0 472 // When there are children, this stores the open state in the tree
michael@0 473 // this is set to the default in the constructor.
michael@0 474 bool mExpanded;
michael@0 475
michael@0 476 // Filled in by the result type generator in nsNavHistory.
michael@0 477 nsCOMArray<nsNavHistoryResultNode> mChildren;
michael@0 478
michael@0 479 bool mChildrenReadOnly;
michael@0 480
michael@0 481 nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
michael@0 482
michael@0 483 void FillStats();
michael@0 484 nsresult ReverseUpdateStats(int32_t aAccessCountChange);
michael@0 485
michael@0 486 // Sorting methods.
michael@0 487 typedef nsCOMArray<nsNavHistoryResultNode>::nsCOMArrayComparatorFunc SortComparator;
michael@0 488 virtual uint16_t GetSortType();
michael@0 489 virtual void GetSortingAnnotation(nsACString& aSortingAnnotation);
michael@0 490
michael@0 491 static SortComparator GetSortingComparator(uint16_t aSortType);
michael@0 492 virtual void RecursiveSort(const char* aData,
michael@0 493 SortComparator aComparator);
michael@0 494 uint32_t FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator,
michael@0 495 const char* aData, bool* aItemExists);
michael@0 496 bool DoesChildNeedResorting(uint32_t aIndex, SortComparator aComparator,
michael@0 497 const char* aData);
michael@0 498
michael@0 499 static int32_t SortComparison_StringLess(const nsAString& a, const nsAString& b);
michael@0 500
michael@0 501 static int32_t SortComparison_Bookmark(nsNavHistoryResultNode* a,
michael@0 502 nsNavHistoryResultNode* b,
michael@0 503 void* closure);
michael@0 504 static int32_t SortComparison_TitleLess(nsNavHistoryResultNode* a,
michael@0 505 nsNavHistoryResultNode* b,
michael@0 506 void* closure);
michael@0 507 static int32_t SortComparison_TitleGreater(nsNavHistoryResultNode* a,
michael@0 508 nsNavHistoryResultNode* b,
michael@0 509 void* closure);
michael@0 510 static int32_t SortComparison_DateLess(nsNavHistoryResultNode* a,
michael@0 511 nsNavHistoryResultNode* b,
michael@0 512 void* closure);
michael@0 513 static int32_t SortComparison_DateGreater(nsNavHistoryResultNode* a,
michael@0 514 nsNavHistoryResultNode* b,
michael@0 515 void* closure);
michael@0 516 static int32_t SortComparison_URILess(nsNavHistoryResultNode* a,
michael@0 517 nsNavHistoryResultNode* b,
michael@0 518 void* closure);
michael@0 519 static int32_t SortComparison_URIGreater(nsNavHistoryResultNode* a,
michael@0 520 nsNavHistoryResultNode* b,
michael@0 521 void* closure);
michael@0 522 static int32_t SortComparison_VisitCountLess(nsNavHistoryResultNode* a,
michael@0 523 nsNavHistoryResultNode* b,
michael@0 524 void* closure);
michael@0 525 static int32_t SortComparison_VisitCountGreater(nsNavHistoryResultNode* a,
michael@0 526 nsNavHistoryResultNode* b,
michael@0 527 void* closure);
michael@0 528 static int32_t SortComparison_KeywordLess(nsNavHistoryResultNode* a,
michael@0 529 nsNavHistoryResultNode* b,
michael@0 530 void* closure);
michael@0 531 static int32_t SortComparison_KeywordGreater(nsNavHistoryResultNode* a,
michael@0 532 nsNavHistoryResultNode* b,
michael@0 533 void* closure);
michael@0 534 static int32_t SortComparison_AnnotationLess(nsNavHistoryResultNode* a,
michael@0 535 nsNavHistoryResultNode* b,
michael@0 536 void* closure);
michael@0 537 static int32_t SortComparison_AnnotationGreater(nsNavHistoryResultNode* a,
michael@0 538 nsNavHistoryResultNode* b,
michael@0 539 void* closure);
michael@0 540 static int32_t SortComparison_DateAddedLess(nsNavHistoryResultNode* a,
michael@0 541 nsNavHistoryResultNode* b,
michael@0 542 void* closure);
michael@0 543 static int32_t SortComparison_DateAddedGreater(nsNavHistoryResultNode* a,
michael@0 544 nsNavHistoryResultNode* b,
michael@0 545 void* closure);
michael@0 546 static int32_t SortComparison_LastModifiedLess(nsNavHistoryResultNode* a,
michael@0 547 nsNavHistoryResultNode* b,
michael@0 548 void* closure);
michael@0 549 static int32_t SortComparison_LastModifiedGreater(nsNavHistoryResultNode* a,
michael@0 550 nsNavHistoryResultNode* b,
michael@0 551 void* closure);
michael@0 552 static int32_t SortComparison_TagsLess(nsNavHistoryResultNode* a,
michael@0 553 nsNavHistoryResultNode* b,
michael@0 554 void* closure);
michael@0 555 static int32_t SortComparison_TagsGreater(nsNavHistoryResultNode* a,
michael@0 556 nsNavHistoryResultNode* b,
michael@0 557 void* closure);
michael@0 558 static int32_t SortComparison_FrecencyLess(nsNavHistoryResultNode* a,
michael@0 559 nsNavHistoryResultNode* b,
michael@0 560 void* closure);
michael@0 561 static int32_t SortComparison_FrecencyGreater(nsNavHistoryResultNode* a,
michael@0 562 nsNavHistoryResultNode* b,
michael@0 563 void* closure);
michael@0 564
michael@0 565 // finding children: THESE DO NOT ADDREF
michael@0 566 nsNavHistoryResultNode* FindChildURI(nsIURI* aURI, uint32_t* aNodeIndex)
michael@0 567 {
michael@0 568 nsAutoCString spec;
michael@0 569 if (NS_FAILED(aURI->GetSpec(spec)))
michael@0 570 return nullptr;
michael@0 571 return FindChildURI(spec, aNodeIndex);
michael@0 572 }
michael@0 573 nsNavHistoryResultNode* FindChildURI(const nsACString& aSpec,
michael@0 574 uint32_t* aNodeIndex);
michael@0 575 // returns the index of the given node, -1 if not found
michael@0 576 int32_t FindChild(nsNavHistoryResultNode* aNode)
michael@0 577 { return mChildren.IndexOf(aNode); }
michael@0 578
michael@0 579 nsresult InsertChildAt(nsNavHistoryResultNode* aNode, int32_t aIndex,
michael@0 580 bool aIsTemporary = false);
michael@0 581 nsresult InsertSortedChild(nsNavHistoryResultNode* aNode,
michael@0 582 bool aIsTemporary = false,
michael@0 583 bool aIgnoreDuplicates = false);
michael@0 584 bool EnsureItemPosition(uint32_t aIndex);
michael@0 585
michael@0 586 nsresult RemoveChildAt(int32_t aIndex, bool aIsTemporary = false);
michael@0 587
michael@0 588 void RecursiveFindURIs(bool aOnlyOne,
michael@0 589 nsNavHistoryContainerResultNode* aContainer,
michael@0 590 const nsCString& aSpec,
michael@0 591 nsCOMArray<nsNavHistoryResultNode>* aMatches);
michael@0 592 bool UpdateURIs(bool aRecursive, bool aOnlyOne, bool aUpdateSort,
michael@0 593 const nsCString& aSpec,
michael@0 594 nsresult (*aCallback)(nsNavHistoryResultNode*, const void*,
michael@0 595 const nsNavHistoryResult*),
michael@0 596 const void* aClosure);
michael@0 597 nsresult ChangeTitles(nsIURI* aURI, const nsACString& aNewTitle,
michael@0 598 bool aRecursive, bool aOnlyOne);
michael@0 599
michael@0 600 protected:
michael@0 601
michael@0 602 enum AsyncCanceledState {
michael@0 603 NOT_CANCELED, CANCELED, CANCELED_RESTART_NEEDED
michael@0 604 };
michael@0 605
michael@0 606 void CancelAsyncOpen(bool aRestart);
michael@0 607 nsresult NotifyOnStateChange(uint16_t aOldState);
michael@0 608
michael@0 609 nsCOMPtr<mozIStoragePendingStatement> mAsyncPendingStmt;
michael@0 610 AsyncCanceledState mAsyncCanceledState;
michael@0 611 };
michael@0 612
michael@0 613 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryContainerResultNode,
michael@0 614 NS_NAVHISTORYCONTAINERRESULTNODE_IID)
michael@0 615
michael@0 616 // nsNavHistoryQueryResultNode
michael@0 617 //
michael@0 618 // Overridden container type for complex queries over history and/or
michael@0 619 // bookmarks. This keeps itself in sync by listening to history and
michael@0 620 // bookmark notifications.
michael@0 621
michael@0 622 class nsNavHistoryQueryResultNode : public nsNavHistoryContainerResultNode,
michael@0 623 public nsINavHistoryQueryResultNode
michael@0 624 {
michael@0 625 public:
michael@0 626 nsNavHistoryQueryResultNode(const nsACString& aTitle,
michael@0 627 const nsACString& aIconURI,
michael@0 628 const nsACString& aQueryURI);
michael@0 629 nsNavHistoryQueryResultNode(const nsACString& aTitle,
michael@0 630 const nsACString& aIconURI,
michael@0 631 const nsCOMArray<nsNavHistoryQuery>& aQueries,
michael@0 632 nsNavHistoryQueryOptions* aOptions);
michael@0 633 nsNavHistoryQueryResultNode(const nsACString& aTitle,
michael@0 634 const nsACString& aIconURI,
michael@0 635 PRTime aTime,
michael@0 636 const nsCOMArray<nsNavHistoryQuery>& aQueries,
michael@0 637 nsNavHistoryQueryOptions* aOptions);
michael@0 638
michael@0 639 virtual ~nsNavHistoryQueryResultNode();
michael@0 640
michael@0 641 NS_DECL_ISUPPORTS_INHERITED
michael@0 642 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
michael@0 643 NS_IMETHOD GetType(uint32_t* type)
michael@0 644 { *type = nsNavHistoryResultNode::RESULT_TYPE_QUERY; return NS_OK; }
michael@0 645 NS_IMETHOD GetUri(nsACString& aURI); // does special lazy creation
michael@0 646 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY
michael@0 647 NS_IMETHOD GetHasChildren(bool* aHasChildren);
michael@0 648 NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly)
michael@0 649 { return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); }
michael@0 650 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
michael@0 651
michael@0 652 bool CanExpand();
michael@0 653 bool IsContainersQuery();
michael@0 654
michael@0 655 virtual nsresult OpenContainer();
michael@0 656
michael@0 657 NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL
michael@0 658 virtual void OnRemoving();
michael@0 659
michael@0 660 public:
michael@0 661 // this constructs lazily mURI from mQueries and mOptions, call
michael@0 662 // VerifyQueriesSerialized either this or mQueries/mOptions should be valid
michael@0 663 nsresult VerifyQueriesSerialized();
michael@0 664
michael@0 665 // these may be constructed lazily from mURI, call VerifyQueriesParsed
michael@0 666 // either this or mURI should be valid
michael@0 667 nsCOMArray<nsNavHistoryQuery> mQueries;
michael@0 668 uint32_t mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
michael@0 669 bool mHasSearchTerms;
michael@0 670 nsresult VerifyQueriesParsed();
michael@0 671
michael@0 672 // safe options getter, ensures queries are parsed
michael@0 673 nsNavHistoryQueryOptions* Options();
michael@0 674
michael@0 675 // this indicates whether the query contents are valid, they don't go away
michael@0 676 // after the container is closed until a notification comes in
michael@0 677 bool mContentsValid;
michael@0 678
michael@0 679 nsresult FillChildren();
michael@0 680 void ClearChildren(bool unregister);
michael@0 681 nsresult Refresh();
michael@0 682
michael@0 683 virtual uint16_t GetSortType();
michael@0 684 virtual void GetSortingAnnotation(nsACString& aSortingAnnotation);
michael@0 685 virtual void RecursiveSort(const char* aData,
michael@0 686 SortComparator aComparator);
michael@0 687
michael@0 688 nsCOMPtr<nsIURI> mRemovingURI;
michael@0 689 nsresult NotifyIfTagsChanged(nsIURI* aURI);
michael@0 690
michael@0 691 uint32_t mBatchChanges;
michael@0 692
michael@0 693 // Tracks transition type filters shared by all mQueries.
michael@0 694 nsTArray<uint32_t> mTransitions;
michael@0 695 };
michael@0 696
michael@0 697
michael@0 698 // nsNavHistoryFolderResultNode
michael@0 699 //
michael@0 700 // Overridden container type for bookmark folders. It will keep the contents
michael@0 701 // of the folder in sync with the bookmark service.
michael@0 702
michael@0 703 class nsNavHistoryFolderResultNode : public nsNavHistoryContainerResultNode,
michael@0 704 public nsINavHistoryQueryResultNode,
michael@0 705 public mozilla::places::AsyncStatementCallback
michael@0 706 {
michael@0 707 public:
michael@0 708 nsNavHistoryFolderResultNode(const nsACString& aTitle,
michael@0 709 nsNavHistoryQueryOptions* options,
michael@0 710 int64_t aFolderId);
michael@0 711
michael@0 712 virtual ~nsNavHistoryFolderResultNode();
michael@0 713
michael@0 714 NS_DECL_ISUPPORTS_INHERITED
michael@0 715 NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID
michael@0 716 NS_IMETHOD GetType(uint32_t* type) {
michael@0 717 if (mQueryItemId != -1) {
michael@0 718 *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
michael@0 719 } else {
michael@0 720 *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER;
michael@0 721 }
michael@0 722 return NS_OK;
michael@0 723 }
michael@0 724 NS_IMETHOD GetUri(nsACString& aURI);
michael@0 725 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY
michael@0 726 NS_IMETHOD GetHasChildren(bool* aHasChildren);
michael@0 727 NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly);
michael@0 728 NS_IMETHOD GetItemId(int64_t *aItemId);
michael@0 729 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
michael@0 730
michael@0 731 virtual nsresult OpenContainer();
michael@0 732
michael@0 733 virtual nsresult OpenContainerAsync();
michael@0 734 NS_DECL_ASYNCSTATEMENTCALLBACK
michael@0 735
michael@0 736 // This object implements a bookmark observer interface without deriving from
michael@0 737 // the bookmark observers. This is called from the result's actual observer
michael@0 738 // and it knows all observers are FolderResultNodes
michael@0 739 NS_DECL_NSINAVBOOKMARKOBSERVER
michael@0 740
michael@0 741 virtual void OnRemoving();
michael@0 742
michael@0 743 // this indicates whether the folder contents are valid, they don't go away
michael@0 744 // after the container is closed until a notification comes in
michael@0 745 bool mContentsValid;
michael@0 746
michael@0 747 // If the node is generated from a place:folder=X query, this is the query's
michael@0 748 // itemId.
michael@0 749 int64_t mQueryItemId;
michael@0 750
michael@0 751 nsresult FillChildren();
michael@0 752 void ClearChildren(bool aUnregister);
michael@0 753 nsresult Refresh();
michael@0 754
michael@0 755 bool StartIncrementalUpdate();
michael@0 756 void ReindexRange(int32_t aStartIndex, int32_t aEndIndex, int32_t aDelta);
michael@0 757
michael@0 758 nsNavHistoryResultNode* FindChildById(int64_t aItemId,
michael@0 759 uint32_t* aNodeIndex);
michael@0 760
michael@0 761 private:
michael@0 762
michael@0 763 nsresult OnChildrenFilled();
michael@0 764 void EnsureRegisteredAsFolderObserver();
michael@0 765 nsresult FillChildrenAsync();
michael@0 766
michael@0 767 bool mIsRegisteredFolderObserver;
michael@0 768 int32_t mAsyncBookmarkIndex;
michael@0 769 };
michael@0 770
michael@0 771 // nsNavHistorySeparatorResultNode
michael@0 772 //
michael@0 773 // Separator result nodes do not hold any data.
michael@0 774 class nsNavHistorySeparatorResultNode : public nsNavHistoryResultNode
michael@0 775 {
michael@0 776 public:
michael@0 777 nsNavHistorySeparatorResultNode();
michael@0 778
michael@0 779 NS_IMETHOD GetType(uint32_t* type)
michael@0 780 { *type = nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR; return NS_OK; }
michael@0 781 };
michael@0 782
michael@0 783 #endif // nsNavHistoryResult_h_

mercurial