Coverage Report

Created: 2018-09-25 14:53

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