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