зеркало из https://github.com/mozilla/gecko-dev.git
829 строки
35 KiB
C++
829 строки
35 KiB
C++
/* -*- 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 "INativePlacesEventCallback.h"
|
|
#include "nsTArray.h"
|
|
#include "nsMaybeWeakPtr.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() = default;
|
|
|
|
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, bool aPartialRemoval, \
|
|
const nsACString& aGUID, uint16_t aReason, \
|
|
uint32_t aTransitionType) __VA_ARGS__;
|
|
|
|
// The internal version is used by query nodes.
|
|
#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL \
|
|
NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE()
|
|
|
|
// The external version is used by results.
|
|
#define NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL(...) \
|
|
NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE(__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 mozilla::places::INativePlacesEventCallback {
|
|
public:
|
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID)
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_NSINAVHISTORYRESULT
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult,
|
|
nsINavHistoryResult)
|
|
NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL(override)
|
|
|
|
void AddHistoryObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode,
|
|
int64_t aFolder);
|
|
void AddAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void AddMobilePrefsObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void RemoveHistoryObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode,
|
|
int64_t aFolder);
|
|
void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void RemoveMobilePrefsObserver(nsNavHistoryQueryResultNode* aNode);
|
|
void StopObserving();
|
|
|
|
nsresult OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime,
|
|
uint32_t aTransitionType, const nsACString& aGUID,
|
|
bool aHidden, uint32_t aVisitCount,
|
|
const nsAString& aLastKnownTitle);
|
|
|
|
public:
|
|
explicit nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot,
|
|
const RefPtr<nsNavHistoryQuery>& aQuery,
|
|
const RefPtr<nsNavHistoryQueryOptions>& aOptions);
|
|
|
|
RefPtr<nsNavHistoryContainerResultNode> mRootNode;
|
|
|
|
RefPtr<nsNavHistoryQuery> mQuery;
|
|
RefPtr<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;
|
|
|
|
// node observers
|
|
bool mIsHistoryObserver;
|
|
bool mIsBookmarkFolderObserver;
|
|
bool mIsAllBookmarksObserver;
|
|
bool mIsMobilePrefObserver;
|
|
|
|
typedef nsTArray<RefPtr<nsNavHistoryQueryResultNode> > QueryObserverList;
|
|
QueryObserverList mHistoryObservers;
|
|
QueryObserverList mAllBookmarksObservers;
|
|
QueryObserverList mMobilePrefObservers;
|
|
|
|
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);
|
|
|
|
void HandlePlacesEvent(const PlacesEventSequence& aEvents) override;
|
|
|
|
void OnMobilePrefChanged();
|
|
|
|
static void OnMobilePrefChangedCallback(const char* prefName, void* self);
|
|
|
|
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 query 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);
|
|
|
|
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);
|
|
|
|
virtual nsresult OnMobilePrefChanged(bool newValue) { return NS_OK; };
|
|
|
|
protected:
|
|
virtual ~nsNavHistoryResultNode() = default;
|
|
|
|
public:
|
|
nsNavHistoryResult* GetResult();
|
|
|
|
// 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;
|
|
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); \
|
|
}
|
|
|
|
#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, PRTime aTime,
|
|
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;
|
|
|
|
// mOriginalOptions is the options object used to _define_ this specific
|
|
// container node. It may differ from mOptions, that is the options used
|
|
// to _fill_ this container node, because mOptions may be modified by
|
|
// the direct parent of this container node, see SetAsParentOfNode. For
|
|
// example, if the parent has excludeItems, options will have it too, even if
|
|
// originally this object was not defined with that option.
|
|
RefPtr<nsNavHistoryQueryOptions> mOriginalOptions;
|
|
RefPtr<nsNavHistoryQueryOptions> mOptions;
|
|
|
|
void FillStats();
|
|
// Sets this container as parent of aNode, propagating the appropriate
|
|
// options.
|
|
void SetAsParentOfNode(nsNavHistoryResultNode* aNode);
|
|
nsresult ReverseUpdateStats(int32_t aAccessCountChange);
|
|
|
|
// Sorting methods.
|
|
typedef nsCOMArray<nsNavHistoryResultNode>::TComparatorFunc SortComparator;
|
|
virtual uint16_t GetSortType();
|
|
|
|
static SortComparator GetSortingComparator(uint16_t aSortType);
|
|
virtual void RecursiveSort(SortComparator aComparator);
|
|
uint32_t FindInsertionPoint(nsNavHistoryResultNode* aNode,
|
|
SortComparator aComparator, bool* aItemExists);
|
|
bool DoesChildNeedResorting(uint32_t aIndex, SortComparator aComparator);
|
|
|
|
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_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);
|
|
}
|
|
|
|
nsNavHistoryResultNode* FindChildByGuid(const nsACString& guid,
|
|
int32_t* nodeIndex);
|
|
|
|
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, PRTime aTime,
|
|
const nsACString& aQueryURI,
|
|
const RefPtr<nsNavHistoryQuery>& aQuery,
|
|
const RefPtr<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
|
|
|
|
virtual nsresult OnMobilePrefChanged(bool newValue) override;
|
|
|
|
bool CanExpand();
|
|
bool IsContainersQuery();
|
|
|
|
virtual nsresult OpenContainer() override;
|
|
|
|
NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL
|
|
|
|
nsresult OnItemAdded(int64_t aItemId, int64_t aParentId, int32_t aIndex,
|
|
uint16_t aItemType, nsIURI* aURI, PRTime aDateAdded,
|
|
const nsACString& aGUID, const nsACString& aParentGUID,
|
|
uint16_t aSource);
|
|
|
|
nsresult OnItemRemoved(int64_t aItemId, int64_t aParentFolder, int32_t aIndex,
|
|
uint16_t aItemType, nsIURI* aURI,
|
|
const nsACString& aGUID, const nsACString& aParentGUID,
|
|
uint16_t aSource);
|
|
|
|
// 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.
|
|
nsresult OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime,
|
|
uint32_t aTransitionType, bool aHidden, uint32_t* aAdded);
|
|
virtual void OnRemoving() override;
|
|
|
|
public:
|
|
RefPtr<nsNavHistoryQuery> mQuery;
|
|
uint32_t mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
|
|
bool mHasSearchTerms;
|
|
|
|
// safe options getter, ensures query is 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 RecursiveSort(SortComparator aComparator) override;
|
|
|
|
nsresult NotifyIfTagsChanged(nsIURI* aURI);
|
|
|
|
uint32_t mBatchChanges;
|
|
|
|
// Tracks transition type filters.
|
|
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
|
|
|
|
nsresult OnItemAdded(int64_t aItemId, int64_t aParentId, int32_t aIndex,
|
|
uint16_t aItemType, nsIURI* aURI, PRTime aDateAdded,
|
|
const nsACString& aGUID, const nsACString& aParentGUID,
|
|
uint16_t aSource);
|
|
nsresult OnItemRemoved(int64_t aItemId, int64_t aParentFolder, int32_t aIndex,
|
|
uint16_t aItemType, nsIURI* aURI,
|
|
const nsACString& aGUID, const nsACString& aParentGUID,
|
|
uint16_t aSource);
|
|
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) override {
|
|
*type = nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR;
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
#endif // nsNavHistoryResult_h_
|