/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_ |