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/. */
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
12 #ifndef nsNavHistoryResult_h_
13 #define nsNavHistoryResult_h_
15 #include "INativePlacesEventCallback.h"
16 #include "nsCOMArray.h"
18 #include "nsMaybeWeakPtr.h"
19 #include "nsInterfaceHashtable.h"
20 #include "nsINavHistoryService.h"
21 #include "nsTHashMap.h"
22 #include "nsCycleCollectionParticipant.h"
23 #include "mozIStoragePendingStatement.h"
27 class nsNavHistoryQuery
;
28 class nsNavHistoryQueryOptions
;
30 class nsNavHistoryContainerResultNode
;
31 class nsNavHistoryFolderResultNode
;
32 class nsNavHistoryQueryResultNode
;
35 * hashkey wrapper using int64_t KeyType
37 * @see nsTHashtable::EntryType for specification
39 * This just truncates the 64-bit int to a 32-bit one for using a hash number.
40 * It is used for bookmark folder IDs, which should be way less than 2^32.
42 class nsTrimInt64HashKey
: public PLDHashEntryHdr
{
44 using KeyType
= const int64_t&;
45 using KeyTypePointer
= const int64_t*;
47 explicit nsTrimInt64HashKey(KeyTypePointer aKey
) : mValue(*aKey
) {}
48 nsTrimInt64HashKey(const nsTrimInt64HashKey
& toCopy
)
49 : mValue(toCopy
.mValue
) {}
50 ~nsTrimInt64HashKey() = default;
52 KeyType
GetKey() const { return mValue
; }
53 bool KeyEquals(KeyTypePointer aKey
) const { return *aKey
== mValue
; }
55 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
56 static PLDHashNumber
HashKey(KeyTypePointer aKey
) {
57 return static_cast<uint32_t>((*aKey
) & UINT32_MAX
);
59 enum { ALLOW_MEMMOVE
= true };
67 // nsNavHistory creates this object and fills in mChildren (by getting
68 // it through GetTopLevel()). Then FilledAllResults() is called to finish
69 // object initialization.
71 #define NS_NAVHISTORYRESULT_IID \
73 0x455d1d40, 0x1b9b, 0x40e6, { \
74 0xa6, 0x41, 0x8b, 0xb7, 0xe8, 0x82, 0x23, 0x87 \
78 class nsNavHistoryResult final
79 : public nsSupportsWeakReference
,
80 public nsINavHistoryResult
,
81 public mozilla::places::INativePlacesEventCallback
{
83 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID
)
85 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
86 NS_DECL_NSINAVHISTORYRESULT
87 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult
,
90 void AddHistoryObserver(nsNavHistoryQueryResultNode
* aNode
);
91 void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode
* aNode
,
92 const nsACString
& aFolderGUID
);
93 void AddAllBookmarksObserver(nsNavHistoryQueryResultNode
* aNode
);
94 void AddMobilePrefsObserver(nsNavHistoryQueryResultNode
* aNode
);
95 void RemoveHistoryObserver(nsNavHistoryQueryResultNode
* aNode
);
96 void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode
* aNode
,
97 const nsACString
& aFolderGUID
);
98 void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode
* aNode
);
99 void RemoveMobilePrefsObserver(nsNavHistoryQueryResultNode
* aNode
);
100 void StopObserving();
101 void EnsureIsObservingBookmarks();
103 nsresult
OnVisit(nsIURI
* aURI
, int64_t aVisitId
, PRTime aTime
,
104 uint32_t aTransitionType
, const nsACString
& aGUID
,
105 bool aHidden
, uint32_t aVisitCount
,
106 const nsAString
& aLastKnownTitle
, int64_t aFrecency
);
108 void OnIconChanged(nsIURI
* aURI
, nsIURI
* aFaviconURI
,
109 const nsACString
& aGUID
);
111 explicit nsNavHistoryResult(nsNavHistoryContainerResultNode
* aRoot
,
112 const RefPtr
<nsNavHistoryQuery
>& aQuery
,
113 const RefPtr
<nsNavHistoryQueryOptions
>& aOptions
);
115 RefPtr
<nsNavHistoryContainerResultNode
> mRootNode
;
117 RefPtr
<nsNavHistoryQuery
> mQuery
;
118 RefPtr
<nsNavHistoryQueryOptions
> mOptions
;
120 // One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to
121 // mOptions.sortingMode, but may be overridden if the user clicks on one of
123 uint16_t mSortingMode
;
124 // If root node is closed and we try to apply a sortingMode, it would not
125 // work. So we will apply it when the node will be reopened and populated.
126 // This var states the fact we need to apply sortingMode in such a situation.
127 bool mNeedsToApplySortingMode
;
130 bool mIsHistoryObserver
;
131 bool mIsBookmarksObserver
;
132 bool mIsMobilePrefObserver
;
134 using QueryObserverList
= nsTArray
<RefPtr
<nsNavHistoryQueryResultNode
>>;
135 QueryObserverList mHistoryObservers
;
136 QueryObserverList mAllBookmarksObservers
;
137 QueryObserverList mMobilePrefObservers
;
139 using FolderObserverList
= nsTArray
<RefPtr
<nsNavHistoryFolderResultNode
>>;
140 nsTHashMap
<nsCStringHashKey
, FolderObserverList
*> mBookmarkFolderObservers
;
141 FolderObserverList
* BookmarkFolderObserversForGUID(
142 const nsACString
& aFolderGUID
, bool aCreate
);
144 using ContainerObserverList
=
145 nsTArray
<RefPtr
<nsNavHistoryContainerResultNode
>>;
147 void RecursiveExpandCollapse(nsNavHistoryContainerResultNode
* aContainer
,
150 void InvalidateTree();
152 nsMaybeWeakPtrArray
<nsINavHistoryResultObserver
> mObservers
;
153 bool mSuppressNotifications
;
155 // Tracks whether observers for history details were added.
156 bool mIsHistoryDetailsObserver
;
157 // Tracks whether any result observer is interested in history details
159 bool mObserversWantHistoryDetails
;
161 * Updates mObserversWantHistoryDetails when observers are added/removed.
162 * @returns Whether we started observing for history changes.
164 bool UpdateHistoryDetailsObservers();
165 // Whether NodeHistoryDetailsChanged can be skipped.
166 bool CanSkipHistoryDetailsNotifications() const;
168 ContainerObserverList mRefreshParticipants
;
169 void requestRefresh(nsNavHistoryContainerResultNode
* aContainer
);
171 void HandlePlacesEvent(const PlacesEventSequence
& aEvents
) override
;
173 // Optimisation: refreshing containers is much faster than incremental
174 // updates when handling multiple Page_removed events.
175 bool IsBulkPageRemovedEvent(const PlacesEventSequence
& aEvents
);
177 void OnMobilePrefChanged();
179 bool IsBatching() const { return mBatchInProgress
> 0; };
181 static void OnMobilePrefChangedCallback(const char* prefName
, void* self
);
184 virtual ~nsNavHistoryResult();
187 // Number of batch processes currently running. IsBatching() returns true if
188 // this value is greater than or equal to 1. Also, when this value changes to
189 // 1 from 0, batching() in nsINavHistoryResultObserver is called with
190 // parameter as true, when changes to 0, that means finishing all batch
191 // processes, batching() is called with false.
192 uint32_t mBatchInProgress
;
194 // Stop all observers upon unlinking.
195 void StopObservingOnUnlink();
198 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult
, NS_NAVHISTORYRESULT_IID
)
200 // nsNavHistoryResultNode
202 // This is the base class for every node in a result set. The result itself
203 // is a node (nsNavHistoryResult inherits from this), as well as every
204 // leaf and branch on the tree.
206 #define NS_NAVHISTORYRESULTNODE_IID \
208 0x54b61d38, 0x57c1, 0x11da, { \
209 0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e \
213 // These are all the simple getters, they can be used for the result node
214 // implementation and all subclasses. More complex are GetIcon, GetParent
215 // (which depends on the definition of container result node), and GetUri
216 // (which is overridded for lazy construction for some containers).
217 #define NS_IMPLEMENT_SIMPLE_RESULTNODE \
218 NS_IMETHOD GetTitle(nsACString& aTitle) override { \
222 NS_IMETHOD GetAccessCount(uint32_t* aAccessCount) override { \
223 *aAccessCount = mAccessCount; \
226 NS_IMETHOD GetTime(PRTime* aTime) override { \
230 NS_IMETHOD GetIndentLevel(int32_t* aIndentLevel) override { \
231 *aIndentLevel = mIndentLevel; \
234 NS_IMETHOD GetBookmarkIndex(int32_t* aIndex) override { \
235 *aIndex = mBookmarkIndex; \
238 NS_IMETHOD GetDateAdded(PRTime* aDateAdded) override { \
239 *aDateAdded = mDateAdded; \
242 NS_IMETHOD GetLastModified(PRTime* aLastModified) override { \
243 *aLastModified = mLastModified; \
246 NS_IMETHOD GetItemId(int64_t* aId) override { \
251 // This is used by the base classes instead of
252 // NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
253 // need to redefine GetType and GetUri rather than forwarding them. This
254 // implements all the simple getters instead of forwarding because they are so
255 // short and we can save a virtual function call.
257 // (GetUri is redefined only by QueryResultNode and FolderResultNode because
258 // the query might not necessarily be parsed. The rest just return the node's
260 #define NS_FORWARD_COMMON_RESULTNODE_TO_BASE \
261 NS_IMPLEMENT_SIMPLE_RESULTNODE \
262 NS_IMETHOD GetIcon(nsACString& aIcon) override { \
263 return nsNavHistoryResultNode::GetIcon(aIcon); \
265 NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) override { \
266 return nsNavHistoryResultNode::GetParent(aParent); \
268 NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) override { \
269 return nsNavHistoryResultNode::GetParentResult(aResult); \
271 NS_IMETHOD GetTags(nsAString& aTags) override { \
272 return nsNavHistoryResultNode::GetTags(aTags); \
274 NS_IMETHOD GetPageGuid(nsACString& aPageGuid) override { \
275 return nsNavHistoryResultNode::GetPageGuid(aPageGuid); \
277 NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) override { \
278 return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); \
280 NS_IMETHOD GetVisitId(int64_t* aVisitId) override { \
281 return nsNavHistoryResultNode::GetVisitId(aVisitId); \
283 NS_IMETHOD GetVisitType(uint32_t* aVisitType) override { \
284 return nsNavHistoryResultNode::GetVisitType(aVisitType); \
287 class nsNavHistoryResultNode
: public nsINavHistoryResultNode
{
289 nsNavHistoryResultNode(const nsACString
& aURI
, const nsACString
& aTitle
,
290 uint32_t aAccessCount
, PRTime aTime
);
292 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID
)
294 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
295 NS_DECL_CYCLE_COLLECTION_CLASS(nsNavHistoryResultNode
)
297 NS_IMPLEMENT_SIMPLE_RESULTNODE
298 NS_IMETHOD
GetIcon(nsACString
& aIcon
) override
;
299 NS_IMETHOD
GetParent(nsINavHistoryContainerResultNode
** aParent
) override
;
300 NS_IMETHOD
GetParentResult(nsINavHistoryResult
** aResult
) override
;
301 NS_IMETHOD
GetType(uint32_t* type
) override
{
302 *type
= nsNavHistoryResultNode::RESULT_TYPE_URI
;
305 NS_IMETHOD
GetUri(nsACString
& aURI
) override
{
309 NS_IMETHOD
GetTags(nsAString
& aTags
) override
;
310 NS_IMETHOD
GetPageGuid(nsACString
& aPageGuid
) override
;
311 NS_IMETHOD
GetBookmarkGuid(nsACString
& aBookmarkGuid
) override
;
312 NS_IMETHOD
GetVisitId(int64_t* aVisitId
) override
;
313 NS_IMETHOD
GetVisitType(uint32_t* aVisitType
) override
;
315 virtual void OnRemoving();
317 nsresult
OnItemKeywordChanged(int64_t aItemId
, const nsACString
& aKeyword
);
318 nsresult
OnItemTagsChanged(int64_t aItemId
, const nsAString
& aURL
,
319 const nsAString
& aTags
);
320 nsresult
OnItemTimeChanged(int64_t aItemId
, const nsACString
& aGUID
,
321 PRTime aDateAdded
, PRTime aLastModified
);
322 nsresult
OnItemTitleChanged(int64_t aItemId
, const nsACString
& aGUID
,
323 const nsACString
& aTitle
, PRTime aLastModified
);
324 nsresult
OnItemUrlChanged(int64_t aItemId
, const nsACString
& aGUID
,
325 const nsACString
& aURL
, PRTime aLastModified
);
327 virtual nsresult
OnMobilePrefChanged(bool newValue
) { return NS_OK
; };
329 nsresult
OnVisitsRemoved();
332 virtual ~nsNavHistoryResultNode() = default;
335 nsNavHistoryResult
* GetResult();
336 void SetTags(const nsAString
& aTags
);
341 return type
== nsINavHistoryResultNode::RESULT_TYPE_QUERY
||
342 type
== nsINavHistoryResultNode::RESULT_TYPE_FOLDER
||
343 type
== nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT
;
349 return type
== nsINavHistoryResultNode::RESULT_TYPE_URI
;
352 bool IsFolderOrShortcut() {
355 return type
== nsINavHistoryResultNode::RESULT_TYPE_FOLDER
||
356 type
== nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT
;
362 return type
== nsINavHistoryResultNode::RESULT_TYPE_QUERY
;
368 return type
== nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR
;
371 nsNavHistoryContainerResultNode
* GetAsContainer() {
372 NS_ASSERTION(IsContainer(), "Not a container");
373 return reinterpret_cast<nsNavHistoryContainerResultNode
*>(this);
375 nsNavHistoryFolderResultNode
* GetAsFolder() {
376 NS_ASSERTION(IsFolderOrShortcut(), "Not a folder");
377 return reinterpret_cast<nsNavHistoryFolderResultNode
*>(this);
379 nsNavHistoryQueryResultNode
* GetAsQuery() {
380 NS_ASSERTION(IsQuery(), "Not a query");
381 return reinterpret_cast<nsNavHistoryQueryResultNode
*>(this);
384 RefPtr
<nsNavHistoryContainerResultNode
> mParent
;
385 nsCString mURI
; // not necessarily valid for containers, call GetUri
388 uint32_t mAccessCount
;
390 int32_t mBookmarkIndex
;
394 PRTime mLastModified
;
396 // The indent level of this node. The root node will have a value of -1. The
397 // root's children will have a value of 0, and so on.
398 int32_t mIndentLevel
;
400 // Frecency of the page. Valid only for URI nodes.
403 // Hidden status of the page. Valid only for URI nodes.
406 // Transition type used when this node represents a single visit.
407 uint32_t mTransitionType
;
409 // Unique Id of the page.
412 // Unique Id of the bookmark.
413 nsCString mBookmarkGuid
;
416 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResultNode
,
417 NS_NAVHISTORYRESULTNODE_IID
)
419 // nsNavHistoryContainerResultNode
421 // This is the base class for all nodes that can have children. It is
422 // overridden for nodes that are dynamically populated such as queries and
423 // folders. It is used directly for simple containers such as host groups
426 // derived classes each provide their own implementation of has children and
427 // forward the rest to us using this macro
428 #define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN \
429 NS_IMETHOD GetState(uint16_t* _state) override { \
430 return nsNavHistoryContainerResultNode::GetState(_state); \
432 NS_IMETHOD GetContainerOpen(bool* aContainerOpen) override { \
433 return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); \
435 NS_IMETHOD SetContainerOpen(bool aContainerOpen) override { \
436 return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); \
438 NS_IMETHOD GetChildCount(uint32_t* aChildCount) override { \
439 return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); \
441 NS_IMETHOD GetChild(uint32_t index, nsINavHistoryResultNode** _retval) \
443 return nsNavHistoryContainerResultNode::GetChild(index, _retval); \
445 NS_IMETHOD GetChildIndex(nsINavHistoryResultNode* aNode, uint32_t* _retval) \
447 return nsNavHistoryContainerResultNode::GetChildIndex(aNode, _retval); \
450 #define NS_NAVHISTORYCONTAINERRESULTNODE_IID \
452 0x6e3bf8d3, 0x22aa, 0x4065, { \
453 0x86, 0xbc, 0x37, 0x46, 0xb5, 0xb3, 0x2c, 0xe8 \
457 class nsNavHistoryContainerResultNode
458 : public nsNavHistoryResultNode
,
459 public nsINavHistoryContainerResultNode
{
461 nsNavHistoryContainerResultNode(const nsACString
& aURI
,
462 const nsACString
& aTitle
, PRTime aTime
,
463 uint32_t aContainerType
,
464 nsNavHistoryQueryOptions
* aOptions
);
466 virtual nsresult
Refresh();
468 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID
)
470 NS_DECL_ISUPPORTS_INHERITED
471 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsNavHistoryContainerResultNode
,
472 nsNavHistoryResultNode
)
473 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
474 NS_IMETHOD
GetType(uint32_t* type
) override
{
475 *type
= mContainerType
;
478 NS_IMETHOD
GetUri(nsACString
& aURI
) override
{
482 NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE
485 virtual void OnRemoving() override
;
487 nsresult
OnVisitsRemoved(nsIURI
* aURI
);
489 bool AreChildrenVisible();
491 // Overridded by descendents to populate.
492 virtual nsresult
OpenContainer();
493 nsresult
CloseContainer(bool aSuppressNotifications
= false);
495 virtual nsresult
OpenContainerAsync();
497 // This points to the result that owns this container. All containers have
498 // their result pointer set so we can quickly get to the result without having
499 // to walk the tree. Yet, this also saves us from storing a million pointers
500 // for every leaf node to the result.
501 RefPtr
<nsNavHistoryResult
> mResult
;
503 // For example, RESULT_TYPE_QUERY. Query and Folder results override GetType
504 // so this is not used, but is still kept in sync.
505 uint32_t mContainerType
;
507 // When there are children, this stores the open state in the tree
508 // this is set to the default in the constructor.
511 // Filled in by the result type generator in nsNavHistory.
512 nsCOMArray
<nsNavHistoryResultNode
> mChildren
;
514 // mOriginalOptions is the options object used to _define_ this specific
515 // container node. It may differ from mOptions, that is the options used
516 // to _fill_ this container node, because mOptions may be modified by
517 // the direct parent of this container node, see SetAsParentOfNode. For
518 // example, if the parent has excludeItems, options will have it too, even if
519 // originally this object was not defined with that option.
520 RefPtr
<nsNavHistoryQueryOptions
> mOriginalOptions
;
521 RefPtr
<nsNavHistoryQueryOptions
> mOptions
;
524 // Sets this container as parent of aNode, propagating the appropriate
526 void SetAsParentOfNode(nsNavHistoryResultNode
* aNode
);
529 using SortComparator
= nsCOMArray
<nsNavHistoryResultNode
>::TComparatorFunc
;
530 virtual uint16_t GetSortType();
532 static SortComparator
GetSortingComparator(uint16_t aSortType
);
533 virtual void RecursiveSort(SortComparator aComparator
);
534 int32_t FindInsertionPoint(nsNavHistoryResultNode
* aNode
,
535 SortComparator aComparator
, bool* aItemExists
);
536 bool DoesChildNeedResorting(int32_t aIndex
, SortComparator aComparator
);
538 static int32_t SortComparison_StringLess(const nsAString
& a
,
541 static int32_t SortComparison_Bookmark(nsNavHistoryResultNode
* a
,
542 nsNavHistoryResultNode
* b
);
543 static int32_t SortComparison_TitleLess(nsNavHistoryResultNode
* a
,
544 nsNavHistoryResultNode
* b
);
545 static int32_t SortComparison_TitleGreater(nsNavHistoryResultNode
* a
,
546 nsNavHistoryResultNode
* b
);
547 static int32_t SortComparison_DateLess(nsNavHistoryResultNode
* a
,
548 nsNavHistoryResultNode
* b
);
549 static int32_t SortComparison_DateGreater(nsNavHistoryResultNode
* a
,
550 nsNavHistoryResultNode
* b
);
551 static int32_t SortComparison_URILess(nsNavHistoryResultNode
* a
,
552 nsNavHistoryResultNode
* b
);
553 static int32_t SortComparison_URIGreater(nsNavHistoryResultNode
* a
,
554 nsNavHistoryResultNode
* b
);
555 static int32_t SortComparison_VisitCountLess(nsNavHistoryResultNode
* a
,
556 nsNavHistoryResultNode
* b
);
557 static int32_t SortComparison_VisitCountGreater(nsNavHistoryResultNode
* a
,
558 nsNavHistoryResultNode
* b
);
559 static int32_t SortComparison_DateAddedLess(nsNavHistoryResultNode
* a
,
560 nsNavHistoryResultNode
* b
);
561 static int32_t SortComparison_DateAddedGreater(nsNavHistoryResultNode
* a
,
562 nsNavHistoryResultNode
* b
);
563 static int32_t SortComparison_LastModifiedLess(nsNavHistoryResultNode
* a
,
564 nsNavHistoryResultNode
* b
);
565 static int32_t SortComparison_LastModifiedGreater(nsNavHistoryResultNode
* a
,
566 nsNavHistoryResultNode
* b
);
567 static int32_t SortComparison_TagsLess(nsNavHistoryResultNode
* a
,
568 nsNavHistoryResultNode
* b
);
569 static int32_t SortComparison_TagsGreater(nsNavHistoryResultNode
* a
,
570 nsNavHistoryResultNode
* b
);
571 static int32_t SortComparison_FrecencyLess(nsNavHistoryResultNode
* a
,
572 nsNavHistoryResultNode
* b
);
573 static int32_t SortComparison_FrecencyGreater(nsNavHistoryResultNode
* a
,
574 nsNavHistoryResultNode
* b
);
576 // finding children: THESE DO NOT ADDREF
577 nsNavHistoryResultNode
* FindChildByURI(const nsACString
& aSpec
,
578 uint32_t* aNodeIndex
);
579 void FindChildrenByURI(const nsCString
& aSpec
,
580 nsCOMArray
<nsNavHistoryResultNode
>* aMatches
);
581 // returns the index of the given node, -1 if not found
582 int32_t FindChild(nsNavHistoryResultNode
* aNode
) {
583 return mChildren
.IndexOf(aNode
);
586 nsNavHistoryResultNode
* FindChildByGuid(const nsACString
& guid
,
589 nsNavHistoryResultNode
* FindChildById(int64_t aItemId
, int32_t* aNodeIndex
);
591 nsresult
InsertChildAt(nsNavHistoryResultNode
* aNode
, int32_t aIndex
);
592 nsresult
InsertSortedChild(nsNavHistoryResultNode
* aNode
,
593 bool aIgnoreDuplicates
= false);
594 bool EnsureItemPosition(int32_t aIndex
);
596 nsresult
RemoveChildAt(int32_t aIndex
);
598 void RecursiveFindURIs(bool aOnlyOne
,
599 nsNavHistoryContainerResultNode
* aContainer
,
600 const nsCString
& aSpec
,
601 nsCOMArray
<nsNavHistoryResultNode
>* aMatches
);
602 bool UpdateURIs(bool aRecursive
, bool aOnlyOne
, bool aUpdateSort
,
603 const nsCString
& aSpec
,
604 nsresult (*aCallback
)(nsNavHistoryResultNode
*, const void*,
605 const nsNavHistoryResult
*),
606 const void* aClosure
);
607 nsresult
ChangeTitles(nsIURI
* aURI
, const nsACString
& aNewTitle
,
608 bool aRecursive
, bool aOnlyOne
);
611 virtual ~nsNavHistoryContainerResultNode();
613 enum AsyncCanceledState
{ NOT_CANCELED
, CANCELED
, CANCELED_RESTART_NEEDED
};
615 void CancelAsyncOpen(bool aRestart
);
616 nsresult
NotifyOnStateChange(uint16_t aOldState
);
618 nsCOMPtr
<mozIStoragePendingStatement
> mAsyncPendingStmt
;
619 AsyncCanceledState mAsyncCanceledState
;
622 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryContainerResultNode
,
623 NS_NAVHISTORYCONTAINERRESULTNODE_IID
)
625 // nsNavHistoryQueryResultNode
627 // Overridden container type for complex queries over history and/or
628 // bookmarks. This keeps itself in sync by listening to history and
629 // bookmark notifications.
631 class nsNavHistoryQueryResultNode final
632 : public nsNavHistoryContainerResultNode
,
633 public nsINavHistoryQueryResultNode
{
635 nsNavHistoryQueryResultNode(const nsACString
& aTitle
, PRTime aTime
,
636 const nsACString
& aQueryURI
,
637 const RefPtr
<nsNavHistoryQuery
>& aQuery
,
638 const RefPtr
<nsNavHistoryQueryOptions
>& aOptions
);
640 NS_DECL_ISUPPORTS_INHERITED
641 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
642 NS_IMETHOD
GetType(uint32_t* type
) override
{
643 *type
= nsNavHistoryResultNode::RESULT_TYPE_QUERY
;
646 NS_IMETHOD
GetUri(nsACString
& aURI
) override
; // does special lazy creation
647 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
648 NS_IMETHOD
GetHasChildren(bool* aHasChildren
) override
;
649 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
651 virtual nsresult
OnMobilePrefChanged(bool newValue
) override
;
654 bool IsContainersQuery();
656 virtual nsresult
OpenContainer() override
;
658 nsresult
OnItemAdded(int64_t aItemId
, int64_t aParentId
, int32_t aIndex
,
659 uint16_t aItemType
, nsIURI
* aURI
, PRTime aDateAdded
,
660 const nsACString
& aGUID
, const nsACString
& aParentGUID
,
662 nsresult
OnItemRemoved(int64_t aItemId
, int64_t aParentFolder
, int32_t aIndex
,
663 uint16_t aItemType
, nsIURI
* aURI
,
664 const nsACString
& aGUID
, const nsACString
& aParentGUID
,
666 nsresult
OnItemMoved(int64_t aFolder
, int32_t aOldIndex
, int32_t aNewIndex
,
667 uint16_t aItemType
, const nsACString
& aGUID
,
668 const nsACString
& aOldParentGUID
,
669 const nsACString
& aNewParentGUID
, uint16_t aSource
,
670 const nsACString
& aURI
);
671 nsresult
OnItemTagsChanged(int64_t aItemId
, const nsAString
& aURL
,
672 const nsAString
& aTags
);
673 nsresult
OnItemTimeChanged(int64_t aItemId
, const nsACString
& aGUID
,
674 PRTime aDateAdded
, PRTime aLastModified
);
675 nsresult
OnItemTitleChanged(int64_t aItemId
, const nsACString
& aGUID
,
676 const nsACString
& aTitle
, PRTime aLastModified
);
677 nsresult
OnItemUrlChanged(int64_t aItemId
, const nsACString
& aGUID
,
678 const nsACString
& aURL
, PRTime aLastModified
);
680 // The internal version has an output aAdded parameter, it is incremented by
681 // query nodes when the visited uri belongs to them. If no such query exists,
682 // the history result creates a new query node dynamically.
683 nsresult
OnVisit(nsIURI
* aURI
, int64_t aVisitId
, PRTime aTime
,
684 uint32_t aTransitionType
, const nsACString
& aGUID
,
685 bool aHidden
, uint32_t aVisitCount
,
686 const nsAString
& aLastKnownTitle
, int64_t aFrecency
,
688 nsresult
OnTitleChanged(nsIURI
* aURI
, const nsAString
& aPageTitle
,
689 const nsACString
& aGUID
);
690 nsresult
OnClearHistory();
691 nsresult
OnPageRemovedFromStore(nsIURI
* aURI
, const nsACString
& aGUID
,
693 nsresult
OnPageRemovedVisits(nsIURI
* aURI
, bool aPartialRemoval
,
694 const nsACString
& aGUID
, uint16_t aReason
,
695 uint32_t aTransitionType
);
697 virtual void OnRemoving() override
;
699 nsresult
OnBeginUpdateBatch();
700 nsresult
OnEndUpdateBatch();
703 RefPtr
<nsNavHistoryQuery
> mQuery
;
704 bool mHasSearchTerms
;
705 uint32_t mLiveUpdate
; // one of QUERYUPDATE_* in nsNavHistory.h
707 // safe options getter, ensures query is parsed
708 nsNavHistoryQueryOptions
* Options();
710 // this indicates whether the query contents are valid, they don't go away
711 // after the container is closed until a notification comes in
714 nsresult
FillChildren();
715 void ClearChildren(bool unregister
);
716 nsresult
Refresh() override
;
718 virtual uint16_t GetSortType() override
;
719 virtual void RecursiveSort(SortComparator aComparator
) override
;
721 uint32_t mBatchChanges
;
723 // Tracks transition type filters.
724 nsTArray
<uint32_t> mTransitions
;
727 virtual ~nsNavHistoryQueryResultNode();
730 // nsNavHistoryFolderResultNode
732 // Overridden container type for bookmark folders. It will keep the contents
733 // of the folder in sync with the bookmark service.
735 class nsNavHistoryFolderResultNode final
736 : public nsNavHistoryContainerResultNode
,
737 public nsINavHistoryQueryResultNode
,
738 public mozilla::places::WeakAsyncStatementCallback
{
740 nsNavHistoryFolderResultNode(int64_t aItemId
, const nsACString
& aBookmarkGuid
,
741 int64_t aTargetFolderItemId
,
742 const nsACString
& aTargetFolderGuid
,
743 const nsACString
& aTitle
,
744 nsNavHistoryQueryOptions
* aOptions
);
746 NS_DECL_ISUPPORTS_INHERITED
747 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
748 NS_IMETHOD
GetType(uint32_t* type
) override
{
749 if (mTargetFolderItemId
!= mItemId
) {
750 *type
= nsNavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT
;
752 *type
= nsNavHistoryResultNode::RESULT_TYPE_FOLDER
;
756 NS_IMETHOD
GetUri(nsACString
& aURI
) override
;
757 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
758 NS_IMETHOD
GetHasChildren(bool* aHasChildren
) override
;
759 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
761 virtual nsresult
OpenContainer() override
;
763 virtual nsresult
OpenContainerAsync() override
;
764 NS_DECL_ASYNCSTATEMENTCALLBACK
766 nsresult
OnItemAdded(int64_t aItemId
, int64_t aParentFolder
, int32_t aIndex
,
767 uint16_t aItemType
, nsIURI
* aURI
, PRTime aDateAdded
,
768 const nsACString
& aGUID
, const nsACString
& aParentGUID
,
769 uint16_t aSource
, const nsACString
& aTitle
,
770 const nsAString
& aTags
, int64_t aFrecency
, bool aHidden
,
771 uint32_t aVisitCount
, PRTime aLastVisitDate
,
772 int64_t aTargetFolderItemId
,
773 const nsACString
& aTargetFolderGuid
,
774 const nsACString
& aTargetFolderTitle
);
775 nsresult
OnItemRemoved(int64_t aItemId
, int64_t aParentFolder
, int32_t aIndex
,
776 uint16_t aItemType
, nsIURI
* aURI
,
777 const nsACString
& aGUID
, const nsACString
& aParentGUID
,
779 nsresult
OnItemMoved(int64_t aItemId
, int32_t aOldIndex
, int32_t aNewIndex
,
780 uint16_t aItemType
, const nsACString
& aGUID
,
781 const nsACString
& aOldParentGUID
,
782 const nsACString
& aNewParentGUID
, uint16_t aSource
,
783 const nsACString
& aURI
, const nsACString
& aTitle
,
784 const nsAString
& aTags
, int64_t aFrecency
, bool aHidden
,
785 uint32_t aVisitCount
, PRTime aLastVisitDate
,
787 nsresult
OnItemVisited(nsIURI
* aURI
, int64_t aVisitId
, PRTime aTime
,
790 virtual void OnRemoving() override
;
792 // this indicates whether the folder contents are valid, they don't go away
793 // after the container is closed until a notification comes in
796 // If the node is generated from a place:folder=X query, this is the target
797 // folder id and GUID. For regular folder nodes, they are set to the same
798 // values as mItemId and mBookmarkGuid. For more complex queries, they are set
799 // to -1/an empty string.
800 int64_t mTargetFolderItemId
;
801 nsCString mTargetFolderGuid
;
803 nsresult
FillChildren();
804 void ClearChildren(bool aUnregister
);
805 nsresult
Refresh() override
;
807 bool StartIncrementalUpdate();
808 void ReindexRange(int32_t aStartIndex
, int32_t aEndIndex
, int32_t aDelta
);
810 nsresult
OnBeginUpdateBatch();
811 nsresult
OnEndUpdateBatch();
814 virtual ~nsNavHistoryFolderResultNode();
817 nsresult
OnChildrenFilled();
818 void EnsureRegisteredAsFolderObserver();
819 nsresult
FillChildrenAsync();
821 bool mIsRegisteredFolderObserver
;
822 int32_t mAsyncBookmarkIndex
;
825 // nsNavHistorySeparatorResultNode
827 // Separator result nodes do not hold any data.
828 class nsNavHistorySeparatorResultNode
: public nsNavHistoryResultNode
{
830 nsNavHistorySeparatorResultNode();
832 NS_IMETHOD
GetType(uint32_t* type
) override
{
833 *type
= nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR
;
838 #endif // nsNavHistoryResult_h_