summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/nsNavHistoryResult.h
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/nsNavHistoryResult.h')
-rw-r--r--toolkit/components/places/nsNavHistoryResult.h782
1 files changed, 782 insertions, 0 deletions
diff --git a/toolkit/components/places/nsNavHistoryResult.h b/toolkit/components/places/nsNavHistoryResult.h
new file mode 100644
index 000000000..fffe2bf13
--- /dev/null
+++ b/toolkit/components/places/nsNavHistoryResult.h
@@ -0,0 +1,782 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * The definitions of objects that make up a history query result set. This file
+ * should only be included by nsNavHistory.h, include that if you want these
+ * classes.
+ */
+
+#ifndef nsNavHistoryResult_h_
+#define nsNavHistoryResult_h_
+
+#include "nsTArray.h"
+#include "nsInterfaceHashtable.h"
+#include "nsDataHashtable.h"
+#include "nsCycleCollectionParticipant.h"
+#include "mozilla/storage.h"
+#include "Helpers.h"
+
+class nsNavHistory;
+class nsNavHistoryQuery;
+class nsNavHistoryQueryOptions;
+
+class nsNavHistoryContainerResultNode;
+class nsNavHistoryFolderResultNode;
+class nsNavHistoryQueryResultNode;
+
+/**
+ * hashkey wrapper using int64_t KeyType
+ *
+ * @see nsTHashtable::EntryType for specification
+ *
+ * This just truncates the 64-bit int to a 32-bit one for using a hash number.
+ * It is used for bookmark folder IDs, which should be way less than 2^32.
+ */
+class nsTrimInt64HashKey : public PLDHashEntryHdr
+{
+public:
+ typedef const int64_t& KeyType;
+ typedef const int64_t* KeyTypePointer;
+
+ explicit nsTrimInt64HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
+ nsTrimInt64HashKey(const nsTrimInt64HashKey& toCopy) : mValue(toCopy.mValue) { }
+ ~nsTrimInt64HashKey() { }
+
+ KeyType GetKey() const { return mValue; }
+ bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
+
+ static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
+ static PLDHashNumber HashKey(KeyTypePointer aKey)
+ { return static_cast<uint32_t>((*aKey) & UINT32_MAX); }
+ enum { ALLOW_MEMMOVE = true };
+
+private:
+ const int64_t mValue;
+};
+
+
+// Declare methods for implementing nsINavBookmarkObserver
+// and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap)
+#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE(...) \
+ NS_DECL_NSINAVBOOKMARKOBSERVER \
+ NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
+ const nsACString& aGUID) __VA_ARGS__; \
+ NS_IMETHOD OnFrecencyChanged(nsIURI* aURI, int32_t aNewFrecency, \
+ const nsACString& aGUID, bool aHidden, \
+ PRTime aLastVisitDate) __VA_ARGS__; \
+ NS_IMETHOD OnManyFrecenciesChanged() __VA_ARGS__; \
+ NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
+ uint16_t aReason) __VA_ARGS__; \
+ NS_IMETHOD OnClearHistory() __VA_ARGS__; \
+ NS_IMETHOD OnPageChanged(nsIURI *aURI, uint32_t aChangedAttribute, \
+ const nsAString &aNewValue, \
+ const nsACString &aGUID) __VA_ARGS__; \
+ NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \
+ const nsACString& aGUID, uint16_t aReason, \
+ uint32_t aTransitionType) __VA_ARGS__;
+
+// The internal version has an output aAdded parameter, it is incremented by
+// query nodes when the visited uri belongs to them. If no such query exists,
+// the history result creates a new query node dynamically.
+#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL \
+ NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE() \
+ NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
+ int64_t aSessionId, int64_t aReferringId, \
+ uint32_t aTransitionType, const nsACString& aGUID, \
+ bool aHidden, uint32_t* aAdded);
+
+// The external version is used by results.
+#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL(...) \
+ NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE(__VA_ARGS__) \
+ NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
+ int64_t aSessionId, int64_t aReferringId, \
+ uint32_t aTransitionType, const nsACString& aGUID, \
+ bool aHidden, uint32_t aVisitCount, uint32_t aTyped) __VA_ARGS__;
+
+// nsNavHistoryResult
+//
+// nsNavHistory creates this object and fills in mChildren (by getting
+// it through GetTopLevel()). Then FilledAllResults() is called to finish
+// object initialization.
+
+#define NS_NAVHISTORYRESULT_IID \
+ { 0x455d1d40, 0x1b9b, 0x40e6, { 0xa6, 0x41, 0x8b, 0xb7, 0xe8, 0x82, 0x23, 0x87 } }
+
+class nsNavHistoryResult final : public nsSupportsWeakReference,
+ public nsINavHistoryResult,
+ public nsINavBookmarkObserver,
+ public nsINavHistoryObserver
+{
+public:
+ static nsresult NewHistoryResult(nsINavHistoryQuery** aQueries,
+ uint32_t aQueryCount,
+ nsNavHistoryQueryOptions* aOptions,
+ nsNavHistoryContainerResultNode* aRoot,
+ bool aBatchInProgress,
+ nsNavHistoryResult** result);
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID)
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_NSINAVHISTORYRESULT
+ NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL(override)
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult, nsINavHistoryResult)
+
+ void AddHistoryObserver(nsNavHistoryQueryResultNode* aNode);
+ void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
+ void AddAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
+ void RemoveHistoryObserver(nsNavHistoryQueryResultNode* aNode);
+ void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
+ void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
+ void StopObserving();
+
+public:
+ // two-stage init, use NewHistoryResult to construct
+ explicit nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot);
+ nsresult Init(nsINavHistoryQuery** aQueries,
+ uint32_t aQueryCount,
+ nsNavHistoryQueryOptions *aOptions);
+
+ RefPtr<nsNavHistoryContainerResultNode> mRootNode;
+
+ nsCOMArray<nsINavHistoryQuery> mQueries;
+ nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
+
+ // One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to mOptions.sortingMode,
+ // but may be overridden if the user clicks on one of the columns.
+ uint16_t mSortingMode;
+ // If root node is closed and we try to apply a sortingMode, it would not
+ // work. So we will apply it when the node will be reopened and populated.
+ // This var states the fact we need to apply sortingMode in such a situation.
+ bool mNeedsToApplySortingMode;
+
+ // The sorting annotation to be used for in SORT_BY_ANNOTATION_* modes
+ nsCString mSortingAnnotation;
+
+ // node observers
+ bool mIsHistoryObserver;
+ bool mIsBookmarkFolderObserver;
+ bool mIsAllBookmarksObserver;
+
+ typedef nsTArray< RefPtr<nsNavHistoryQueryResultNode> > QueryObserverList;
+ QueryObserverList mHistoryObservers;
+ QueryObserverList mAllBookmarksObservers;
+
+ typedef nsTArray< RefPtr<nsNavHistoryFolderResultNode> > FolderObserverList;
+ nsDataHashtable<nsTrimInt64HashKey, FolderObserverList*> mBookmarkFolderObservers;
+ FolderObserverList* BookmarkFolderObserversForId(int64_t aFolderId, bool aCreate);
+
+ typedef nsTArray< RefPtr<nsNavHistoryContainerResultNode> > ContainerObserverList;
+
+ void RecursiveExpandCollapse(nsNavHistoryContainerResultNode* aContainer,
+ bool aExpand);
+
+ void InvalidateTree();
+
+ bool mBatchInProgress;
+
+ nsMaybeWeakPtrArray<nsINavHistoryResultObserver> mObservers;
+ bool mSuppressNotifications;
+
+ ContainerObserverList mRefreshParticipants;
+ void requestRefresh(nsNavHistoryContainerResultNode* aContainer);
+
+protected:
+ virtual ~nsNavHistoryResult();
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)
+
+// nsNavHistoryResultNode
+//
+// This is the base class for every node in a result set. The result itself
+// is a node (nsNavHistoryResult inherits from this), as well as every
+// leaf and branch on the tree.
+
+#define NS_NAVHISTORYRESULTNODE_IID \
+ {0x54b61d38, 0x57c1, 0x11da, {0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e}}
+
+// These are all the simple getters, they can be used for the result node
+// implementation and all subclasses. More complex are GetIcon, GetParent
+// (which depends on the definition of container result node), and GetUri
+// (which is overridded for lazy construction for some containers).
+#define NS_IMPLEMENT_SIMPLE_RESULTNODE \
+ NS_IMETHOD GetTitle(nsACString& aTitle) override \
+ { aTitle = mTitle; return NS_OK; } \
+ NS_IMETHOD GetAccessCount(uint32_t* aAccessCount) override \
+ { *aAccessCount = mAccessCount; return NS_OK; } \
+ NS_IMETHOD GetTime(PRTime* aTime) override \
+ { *aTime = mTime; return NS_OK; } \
+ NS_IMETHOD GetIndentLevel(int32_t* aIndentLevel) override \
+ { *aIndentLevel = mIndentLevel; return NS_OK; } \
+ NS_IMETHOD GetBookmarkIndex(int32_t* aIndex) override \
+ { *aIndex = mBookmarkIndex; return NS_OK; } \
+ NS_IMETHOD GetDateAdded(PRTime* aDateAdded) override \
+ { *aDateAdded = mDateAdded; return NS_OK; } \
+ NS_IMETHOD GetLastModified(PRTime* aLastModified) override \
+ { *aLastModified = mLastModified; return NS_OK; } \
+ NS_IMETHOD GetItemId(int64_t* aId) override \
+ { *aId = mItemId; return NS_OK; }
+
+// This is used by the base classes instead of
+// NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
+// need to redefine GetType and GetUri rather than forwarding them. This
+// implements all the simple getters instead of forwarding because they are so
+// short and we can save a virtual function call.
+//
+// (GetUri is redefined only by QueryResultNode and FolderResultNode because
+// the queries might not necessarily be parsed. The rest just return the node's
+// buffer.)
+#define NS_FORWARD_COMMON_RESULTNODE_TO_BASE \
+ NS_IMPLEMENT_SIMPLE_RESULTNODE \
+ NS_IMETHOD GetIcon(nsACString& aIcon) override \
+ { return nsNavHistoryResultNode::GetIcon(aIcon); } \
+ NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) override \
+ { return nsNavHistoryResultNode::GetParent(aParent); } \
+ NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) override \
+ { return nsNavHistoryResultNode::GetParentResult(aResult); } \
+ NS_IMETHOD GetTags(nsAString& aTags) override \
+ { return nsNavHistoryResultNode::GetTags(aTags); } \
+ NS_IMETHOD GetPageGuid(nsACString& aPageGuid) override \
+ { return nsNavHistoryResultNode::GetPageGuid(aPageGuid); } \
+ NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) override \
+ { return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); } \
+ NS_IMETHOD GetVisitId(int64_t* aVisitId) override \
+ { return nsNavHistoryResultNode::GetVisitId(aVisitId); } \
+ NS_IMETHOD GetFromVisitId(int64_t* aFromVisitId) override \
+ { return nsNavHistoryResultNode::GetFromVisitId(aFromVisitId); } \
+ NS_IMETHOD GetVisitType(uint32_t* aVisitType) override \
+ { return nsNavHistoryResultNode::GetVisitType(aVisitType); }
+
+class nsNavHistoryResultNode : public nsINavHistoryResultNode
+{
+public:
+ nsNavHistoryResultNode(const nsACString& aURI, const nsACString& aTitle,
+ uint32_t aAccessCount, PRTime aTime,
+ const nsACString& aIconURI);
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID)
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsNavHistoryResultNode)
+
+ NS_IMPLEMENT_SIMPLE_RESULTNODE
+ NS_IMETHOD GetIcon(nsACString& aIcon) override;
+ NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) override;
+ NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) override;
+ NS_IMETHOD GetType(uint32_t* type) override
+ { *type = nsNavHistoryResultNode::RESULT_TYPE_URI; return NS_OK; }
+ NS_IMETHOD GetUri(nsACString& aURI) override
+ { aURI = mURI; return NS_OK; }
+ NS_IMETHOD GetTags(nsAString& aTags) override;
+ NS_IMETHOD GetPageGuid(nsACString& aPageGuid) override;
+ NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) override;
+ NS_IMETHOD GetVisitId(int64_t* aVisitId) override;
+ NS_IMETHOD GetFromVisitId(int64_t* aFromVisitId) override;
+ NS_IMETHOD GetVisitType(uint32_t* aVisitType) override;
+
+ virtual void OnRemoving();
+
+ // Called from result's onItemChanged, see also bookmark observer declaration in
+ // nsNavHistoryFolderResultNode
+ NS_IMETHOD OnItemChanged(int64_t aItemId,
+ const nsACString &aProperty,
+ bool aIsAnnotationProperty,
+ const nsACString &aValue,
+ PRTime aNewLastModified,
+ uint16_t aItemType,
+ int64_t aParentId,
+ const nsACString& aGUID,
+ const nsACString& aParentGUID,
+ const nsACString &aOldValue,
+ uint16_t aSource);
+
+protected:
+ virtual ~nsNavHistoryResultNode() {}
+
+public:
+
+ nsNavHistoryResult* GetResult();
+ nsNavHistoryQueryOptions* GetGeneratingOptions();
+
+ // These functions test the type. We don't use a virtual function since that
+ // would take a vtable slot for every one of (potentially very many) nodes.
+ // Note that GetType() already has a vtable slot because its on the iface.
+ bool IsTypeContainer(uint32_t type) {
+ return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
+ type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
+ type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
+ }
+ bool IsContainer() {
+ uint32_t type;
+ GetType(&type);
+ return IsTypeContainer(type);
+ }
+ static bool IsTypeURI(uint32_t type) {
+ return type == nsINavHistoryResultNode::RESULT_TYPE_URI;
+ }
+ bool IsURI() {
+ uint32_t type;
+ GetType(&type);
+ return IsTypeURI(type);
+ }
+ static bool IsTypeFolder(uint32_t type) {
+ return type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
+ type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
+ }
+ bool IsFolder() {
+ uint32_t type;
+ GetType(&type);
+ return IsTypeFolder(type);
+ }
+ static bool IsTypeQuery(uint32_t type) {
+ return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY;
+ }
+ bool IsQuery() {
+ uint32_t type;
+ GetType(&type);
+ return IsTypeQuery(type);
+ }
+ bool IsSeparator() {
+ uint32_t type;
+ GetType(&type);
+ return type == nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR;
+ }
+ nsNavHistoryContainerResultNode* GetAsContainer() {
+ NS_ASSERTION(IsContainer(), "Not a container");
+ return reinterpret_cast<nsNavHistoryContainerResultNode*>(this);
+ }
+ nsNavHistoryFolderResultNode* GetAsFolder() {
+ NS_ASSERTION(IsFolder(), "Not a folder");
+ return reinterpret_cast<nsNavHistoryFolderResultNode*>(this);
+ }
+ nsNavHistoryQueryResultNode* GetAsQuery() {
+ NS_ASSERTION(IsQuery(), "Not a query");
+ return reinterpret_cast<nsNavHistoryQueryResultNode*>(this);
+ }
+
+ RefPtr<nsNavHistoryContainerResultNode> mParent;
+ nsCString mURI; // not necessarily valid for containers, call GetUri
+ nsCString mTitle;
+ nsString mTags;
+ bool mAreTagsSorted;
+ uint32_t mAccessCount;
+ int64_t mTime;
+ nsCString mFaviconURI;
+ int32_t mBookmarkIndex;
+ int64_t mItemId;
+ int64_t mFolderId;
+ int64_t mVisitId;
+ int64_t mFromVisitId;
+ PRTime mDateAdded;
+ PRTime mLastModified;
+
+ // The indent level of this node. The root node will have a value of -1. The
+ // root's children will have a value of 0, and so on.
+ int32_t mIndentLevel;
+
+ // Frecency of the page. Valid only for URI nodes.
+ int32_t mFrecency;
+
+ // Hidden status of the page. Valid only for URI nodes.
+ bool mHidden;
+
+ // Transition type used when this node represents a single visit.
+ uint32_t mTransitionType;
+
+ // Unique Id of the page.
+ nsCString mPageGuid;
+
+ // Unique Id of the bookmark.
+ nsCString mBookmarkGuid;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResultNode, NS_NAVHISTORYRESULTNODE_IID)
+
+
+// nsNavHistoryContainerResultNode
+//
+// This is the base class for all nodes that can have children. It is
+// overridden for nodes that are dynamically populated such as queries and
+// folders. It is used directly for simple containers such as host groups
+// in history views.
+
+// derived classes each provide their own implementation of has children and
+// forward the rest to us using this macro
+#define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN \
+ NS_IMETHOD GetState(uint16_t* _state) override \
+ { return nsNavHistoryContainerResultNode::GetState(_state); } \
+ NS_IMETHOD GetContainerOpen(bool *aContainerOpen) override \
+ { return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); } \
+ NS_IMETHOD SetContainerOpen(bool aContainerOpen) override \
+ { return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); } \
+ NS_IMETHOD GetChildCount(uint32_t *aChildCount) override \
+ { return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \
+ NS_IMETHOD GetChild(uint32_t index, nsINavHistoryResultNode **_retval) override \
+ { return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \
+ NS_IMETHOD GetChildIndex(nsINavHistoryResultNode* aNode, uint32_t* _retval) override \
+ { return nsNavHistoryContainerResultNode::GetChildIndex(aNode, _retval); } \
+ NS_IMETHOD FindNodeByDetails(const nsACString& aURIString, PRTime aTime, \
+ int64_t aItemId, bool aRecursive, \
+ nsINavHistoryResultNode** _retval) override \
+ { return nsNavHistoryContainerResultNode::FindNodeByDetails(aURIString, aTime, aItemId, \
+ aRecursive, _retval); }
+
+#define NS_NAVHISTORYCONTAINERRESULTNODE_IID \
+ { 0x6e3bf8d3, 0x22aa, 0x4065, { 0x86, 0xbc, 0x37, 0x46, 0xb5, 0xb3, 0x2c, 0xe8 } }
+
+class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode,
+ public nsINavHistoryContainerResultNode
+{
+public:
+ nsNavHistoryContainerResultNode(
+ const nsACString& aURI, const nsACString& aTitle,
+ const nsACString& aIconURI, uint32_t aContainerType,
+ nsNavHistoryQueryOptions* aOptions);
+ nsNavHistoryContainerResultNode(
+ const nsACString& aURI, const nsACString& aTitle,
+ PRTime aTime,
+ const nsACString& aIconURI, uint32_t aContainerType,
+ nsNavHistoryQueryOptions* aOptions);
+
+ virtual nsresult Refresh();
+
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID)
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
+ NS_FORWARD_COMMON_RESULTNODE_TO_BASE
+ NS_IMETHOD GetType(uint32_t* type) override
+ { *type = mContainerType; return NS_OK; }
+ NS_IMETHOD GetUri(nsACString& aURI) override
+ { aURI = mURI; return NS_OK; }
+ NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE
+
+public:
+
+ virtual void OnRemoving() override;
+
+ bool AreChildrenVisible();
+
+ // Overridded by descendents to populate.
+ virtual nsresult OpenContainer();
+ nsresult CloseContainer(bool aSuppressNotifications = false);
+
+ virtual nsresult OpenContainerAsync();
+
+ // This points to the result that owns this container. All containers have
+ // their result pointer set so we can quickly get to the result without having
+ // to walk the tree. Yet, this also saves us from storing a million pointers
+ // for every leaf node to the result.
+ RefPtr<nsNavHistoryResult> mResult;
+
+ // For example, RESULT_TYPE_QUERY. Query and Folder results override GetType
+ // so this is not used, but is still kept in sync.
+ uint32_t mContainerType;
+
+ // When there are children, this stores the open state in the tree
+ // this is set to the default in the constructor.
+ bool mExpanded;
+
+ // Filled in by the result type generator in nsNavHistory.
+ nsCOMArray<nsNavHistoryResultNode> mChildren;
+
+ nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
+
+ void FillStats();
+ nsresult ReverseUpdateStats(int32_t aAccessCountChange);
+
+ // Sorting methods.
+ typedef nsCOMArray<nsNavHistoryResultNode>::nsCOMArrayComparatorFunc SortComparator;
+ virtual uint16_t GetSortType();
+ virtual void GetSortingAnnotation(nsACString& aSortingAnnotation);
+
+ static SortComparator GetSortingComparator(uint16_t aSortType);
+ virtual void RecursiveSort(const char* aData,
+ SortComparator aComparator);
+ uint32_t FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator,
+ const char* aData, bool* aItemExists);
+ bool DoesChildNeedResorting(uint32_t aIndex, SortComparator aComparator,
+ const char* aData);
+
+ static int32_t SortComparison_StringLess(const nsAString& a, const nsAString& b);
+
+ static int32_t SortComparison_Bookmark(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_TitleLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_TitleGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_DateLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_DateGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_URILess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_URIGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_VisitCountLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_VisitCountGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_KeywordLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_KeywordGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_AnnotationLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_AnnotationGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_DateAddedLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_DateAddedGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_LastModifiedLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_LastModifiedGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_TagsLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_TagsGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_FrecencyLess(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+ static int32_t SortComparison_FrecencyGreater(nsNavHistoryResultNode* a,
+ nsNavHistoryResultNode* b,
+ void* closure);
+
+ // finding children: THESE DO NOT ADDREF
+ nsNavHistoryResultNode* FindChildURI(const nsACString& aSpec,
+ uint32_t* aNodeIndex);
+ // returns the index of the given node, -1 if not found
+ int32_t FindChild(nsNavHistoryResultNode* aNode)
+ { return mChildren.IndexOf(aNode); }
+
+ nsresult InsertChildAt(nsNavHistoryResultNode* aNode, int32_t aIndex);
+ nsresult InsertSortedChild(nsNavHistoryResultNode* aNode,
+ bool aIgnoreDuplicates = false);
+ bool EnsureItemPosition(uint32_t aIndex);
+
+ nsresult RemoveChildAt(int32_t aIndex);
+
+ void RecursiveFindURIs(bool aOnlyOne,
+ nsNavHistoryContainerResultNode* aContainer,
+ const nsCString& aSpec,
+ nsCOMArray<nsNavHistoryResultNode>* aMatches);
+ bool UpdateURIs(bool aRecursive, bool aOnlyOne, bool aUpdateSort,
+ const nsCString& aSpec,
+ nsresult (*aCallback)(nsNavHistoryResultNode*, const void*,
+ const nsNavHistoryResult*),
+ const void* aClosure);
+ nsresult ChangeTitles(nsIURI* aURI, const nsACString& aNewTitle,
+ bool aRecursive, bool aOnlyOne);
+
+protected:
+ virtual ~nsNavHistoryContainerResultNode();
+
+ enum AsyncCanceledState {
+ NOT_CANCELED, CANCELED, CANCELED_RESTART_NEEDED
+ };
+
+ void CancelAsyncOpen(bool aRestart);
+ nsresult NotifyOnStateChange(uint16_t aOldState);
+
+ nsCOMPtr<mozIStoragePendingStatement> mAsyncPendingStmt;
+ AsyncCanceledState mAsyncCanceledState;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryContainerResultNode,
+ NS_NAVHISTORYCONTAINERRESULTNODE_IID)
+
+// nsNavHistoryQueryResultNode
+//
+// Overridden container type for complex queries over history and/or
+// bookmarks. This keeps itself in sync by listening to history and
+// bookmark notifications.
+
+class nsNavHistoryQueryResultNode final : public nsNavHistoryContainerResultNode,
+ public nsINavHistoryQueryResultNode,
+ public nsINavBookmarkObserver
+{
+public:
+ nsNavHistoryQueryResultNode(const nsACString& aTitle,
+ const nsACString& aIconURI,
+ const nsACString& aQueryURI);
+ nsNavHistoryQueryResultNode(const nsACString& aTitle,
+ const nsACString& aIconURI,
+ const nsCOMArray<nsNavHistoryQuery>& aQueries,
+ nsNavHistoryQueryOptions* aOptions);
+ nsNavHistoryQueryResultNode(const nsACString& aTitle,
+ const nsACString& aIconURI,
+ PRTime aTime,
+ const nsCOMArray<nsNavHistoryQuery>& aQueries,
+ nsNavHistoryQueryOptions* aOptions);
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_FORWARD_COMMON_RESULTNODE_TO_BASE
+ NS_IMETHOD GetType(uint32_t* type) override
+ { *type = nsNavHistoryResultNode::RESULT_TYPE_QUERY; return NS_OK; }
+ NS_IMETHOD GetUri(nsACString& aURI) override; // does special lazy creation
+ NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
+ NS_IMETHOD GetHasChildren(bool* aHasChildren) override;
+ NS_DECL_NSINAVHISTORYQUERYRESULTNODE
+
+ bool CanExpand();
+ bool IsContainersQuery();
+
+ virtual nsresult OpenContainer() override;
+
+ NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL
+ virtual void OnRemoving() override;
+
+public:
+ // this constructs lazily mURI from mQueries and mOptions, call
+ // VerifyQueriesSerialized either this or mQueries/mOptions should be valid
+ nsresult VerifyQueriesSerialized();
+
+ // these may be constructed lazily from mURI, call VerifyQueriesParsed
+ // either this or mURI should be valid
+ nsCOMArray<nsNavHistoryQuery> mQueries;
+ uint32_t mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
+ bool mHasSearchTerms;
+ nsresult VerifyQueriesParsed();
+
+ // safe options getter, ensures queries are parsed
+ nsNavHistoryQueryOptions* Options();
+
+ // this indicates whether the query contents are valid, they don't go away
+ // after the container is closed until a notification comes in
+ bool mContentsValid;
+
+ nsresult FillChildren();
+ void ClearChildren(bool unregister);
+ nsresult Refresh() override;
+
+ virtual uint16_t GetSortType() override;
+ virtual void GetSortingAnnotation(nsACString& aSortingAnnotation) override;
+ virtual void RecursiveSort(const char* aData,
+ SortComparator aComparator) override;
+
+ nsresult NotifyIfTagsChanged(nsIURI* aURI);
+
+ uint32_t mBatchChanges;
+
+ // Tracks transition type filters shared by all mQueries.
+ nsTArray<uint32_t> mTransitions;
+
+protected:
+ virtual ~nsNavHistoryQueryResultNode();
+};
+
+
+// nsNavHistoryFolderResultNode
+//
+// Overridden container type for bookmark folders. It will keep the contents
+// of the folder in sync with the bookmark service.
+
+class nsNavHistoryFolderResultNode final : public nsNavHistoryContainerResultNode,
+ public nsINavHistoryQueryResultNode,
+ public nsINavBookmarkObserver,
+ public mozilla::places::WeakAsyncStatementCallback
+{
+public:
+ nsNavHistoryFolderResultNode(const nsACString& aTitle,
+ nsNavHistoryQueryOptions* options,
+ int64_t aFolderId);
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_FORWARD_COMMON_RESULTNODE_TO_BASE
+ NS_IMETHOD GetType(uint32_t* type) override {
+ if (mTargetFolderItemId != mItemId) {
+ *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
+ } else {
+ *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER;
+ }
+ return NS_OK;
+ }
+ NS_IMETHOD GetUri(nsACString& aURI) override;
+ NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN
+ NS_IMETHOD GetHasChildren(bool* aHasChildren) override;
+ NS_DECL_NSINAVHISTORYQUERYRESULTNODE
+
+ virtual nsresult OpenContainer() override;
+
+ virtual nsresult OpenContainerAsync() override;
+ NS_DECL_ASYNCSTATEMENTCALLBACK
+
+ // This object implements a bookmark observer interface. This is called from the
+ // result's actual observer and it knows all observers are FolderResultNodes
+ NS_DECL_NSINAVBOOKMARKOBSERVER
+
+ virtual void OnRemoving() override;
+
+ // this indicates whether the folder contents are valid, they don't go away
+ // after the container is closed until a notification comes in
+ bool mContentsValid;
+
+ // If the node is generated from a place:folder=X query, this is the target
+ // folder id and GUID. For regular folder nodes, they are set to the same
+ // values as mItemId and mBookmarkGuid. For more complex queries, they are set
+ // to -1/an empty string.
+ int64_t mTargetFolderItemId;
+ nsCString mTargetFolderGuid;
+
+ nsresult FillChildren();
+ void ClearChildren(bool aUnregister);
+ nsresult Refresh() override;
+
+ bool StartIncrementalUpdate();
+ void ReindexRange(int32_t aStartIndex, int32_t aEndIndex, int32_t aDelta);
+
+ nsNavHistoryResultNode* FindChildById(int64_t aItemId,
+ uint32_t* aNodeIndex);
+
+protected:
+ virtual ~nsNavHistoryFolderResultNode();
+
+private:
+
+ nsresult OnChildrenFilled();
+ void EnsureRegisteredAsFolderObserver();
+ nsresult FillChildrenAsync();
+
+ bool mIsRegisteredFolderObserver;
+ int32_t mAsyncBookmarkIndex;
+};
+
+// nsNavHistorySeparatorResultNode
+//
+// Separator result nodes do not hold any data.
+class nsNavHistorySeparatorResultNode : public nsNavHistoryResultNode
+{
+public:
+ nsNavHistorySeparatorResultNode();
+
+ NS_IMETHOD GetType(uint32_t* type)
+ { *type = nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR; return NS_OK; }
+};
+
+#endif // nsNavHistoryResult_h_