Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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/. */
6 #ifndef nsNavBookmarks_h_
7 #define nsNavBookmarks_h_
9 #include "nsINavBookmarksService.h"
10 #include "nsIAnnotationService.h"
11 #include "nsITransaction.h"
12 #include "nsNavHistory.h"
13 #include "nsToolkitCompsCID.h"
14 #include "nsCategoryCache.h"
15 #include "nsTHashtable.h"
16 #include "nsWeakReference.h"
17 #include "mozilla/Attributes.h"
18 #include "prtime.h"
20 class nsNavBookmarks;
21 class nsIOutputStream;
23 namespace mozilla {
24 namespace places {
26 enum BookmarkStatementId {
27 DB_FIND_REDIRECTED_BOOKMARK = 0
28 , DB_GET_BOOKMARKS_FOR_URI
29 };
31 struct BookmarkData {
32 int64_t id;
33 nsCString url;
34 nsCString title;
35 int32_t position;
36 int64_t placeId;
37 int64_t parentId;
38 int64_t grandParentId;
39 int32_t type;
40 nsCString serviceCID;
41 PRTime dateAdded;
42 PRTime lastModified;
43 nsCString guid;
44 nsCString parentGuid;
45 };
47 struct ItemVisitData {
48 BookmarkData bookmark;
49 int64_t visitId;
50 uint32_t transitionType;
51 PRTime time;
52 };
54 struct ItemChangeData {
55 BookmarkData bookmark;
56 nsCString property;
57 bool isAnnotation;
58 nsCString newValue;
59 };
61 typedef void (nsNavBookmarks::*ItemVisitMethod)(const ItemVisitData&);
62 typedef void (nsNavBookmarks::*ItemChangeMethod)(const ItemChangeData&);
64 class BookmarkKeyClass : public nsTrimInt64HashKey
65 {
66 public:
67 BookmarkKeyClass(const int64_t* aItemId)
68 : nsTrimInt64HashKey(aItemId)
69 , creationTime(PR_Now())
70 {
71 }
72 BookmarkKeyClass(const BookmarkKeyClass& aOther)
73 : nsTrimInt64HashKey(aOther)
74 , creationTime(PR_Now())
75 {
76 NS_NOTREACHED("Do not call me!");
77 }
78 BookmarkData bookmark;
79 PRTime creationTime;
80 };
82 enum BookmarkDate {
83 DATE_ADDED = 0
84 , LAST_MODIFIED
85 };
87 } // namespace places
88 } // namespace mozilla
90 class nsNavBookmarks MOZ_FINAL : public nsINavBookmarksService
91 , public nsINavHistoryObserver
92 , public nsIAnnotationObserver
93 , public nsIObserver
94 , public nsSupportsWeakReference
95 {
96 public:
97 NS_DECL_ISUPPORTS
98 NS_DECL_NSINAVBOOKMARKSSERVICE
99 NS_DECL_NSINAVHISTORYOBSERVER
100 NS_DECL_NSIANNOTATIONOBSERVER
101 NS_DECL_NSIOBSERVER
103 nsNavBookmarks();
105 /**
106 * Obtains the service's object.
107 */
108 static already_AddRefed<nsNavBookmarks> GetSingleton();
110 /**
111 * Initializes the service's object. This should only be called once.
112 */
113 nsresult Init();
115 static nsNavBookmarks* GetBookmarksService() {
116 if (!gBookmarksService) {
117 nsCOMPtr<nsINavBookmarksService> serv =
118 do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID);
119 NS_ENSURE_TRUE(serv, nullptr);
120 NS_ASSERTION(gBookmarksService,
121 "Should have static instance pointer now");
122 }
123 return gBookmarksService;
124 }
126 typedef mozilla::places::BookmarkData BookmarkData;
127 typedef mozilla::places::BookmarkKeyClass BookmarkKeyClass;
128 typedef mozilla::places::ItemVisitData ItemVisitData;
129 typedef mozilla::places::ItemChangeData ItemChangeData;
130 typedef mozilla::places::BookmarkStatementId BookmarkStatementId;
132 nsresult ResultNodeForContainer(int64_t aID,
133 nsNavHistoryQueryOptions* aOptions,
134 nsNavHistoryResultNode** aNode);
136 // Find all the children of a folder, using the given query and options.
137 // For each child, a ResultNode is created and added to |children|.
138 // The results are ordered by folder position.
139 nsresult QueryFolderChildren(int64_t aFolderId,
140 nsNavHistoryQueryOptions* aOptions,
141 nsCOMArray<nsNavHistoryResultNode>* children);
143 /**
144 * Turns aRow into a node and appends it to aChildren if it is appropriate to
145 * do so.
146 *
147 * @param aRow
148 * A Storage statement (in the case of synchronous execution) or row of
149 * a result set (in the case of asynchronous execution).
150 * @param aOptions
151 * The options of the parent folder node.
152 * @param aChildren
153 * The children of the parent folder node.
154 * @param aCurrentIndex
155 * The index of aRow within the results. When called on the first row,
156 * this should be set to -1.
157 */
158 nsresult ProcessFolderNodeRow(mozIStorageValueArray* aRow,
159 nsNavHistoryQueryOptions* aOptions,
160 nsCOMArray<nsNavHistoryResultNode>* aChildren,
161 int32_t& aCurrentIndex);
163 /**
164 * The async version of QueryFolderChildren.
165 *
166 * @param aNode
167 * The folder node that will receive the children.
168 * @param _pendingStmt
169 * The Storage pending statement that will be used to control async
170 * execution.
171 */
172 nsresult QueryFolderChildrenAsync(nsNavHistoryFolderResultNode* aNode,
173 int64_t aFolderId,
174 mozIStoragePendingStatement** _pendingStmt);
176 /**
177 * @return index of the new folder in aIndex, whether it was passed in or
178 * generated by autoincrement.
179 *
180 * @note If aFolder is -1, uses the autoincrement id for folder index.
181 * @note aTitle will be truncated to TITLE_LENGTH_MAX
182 */
183 nsresult CreateContainerWithID(int64_t aId, int64_t aParent,
184 const nsACString& aTitle,
185 bool aIsBookmarkFolder,
186 int32_t* aIndex,
187 const nsACString& aGUID,
188 int64_t* aNewFolder);
190 /**
191 * Fetches information about the specified id from the database.
192 *
193 * @param aItemId
194 * Id of the item to fetch information for.
195 * @param aBookmark
196 * BookmarkData to store the information.
197 */
198 nsresult FetchItemInfo(int64_t aItemId,
199 BookmarkData& _bookmark);
201 /**
202 * Notifies that a bookmark has been visited.
203 *
204 * @param aItemId
205 * The visited item id.
206 * @param aData
207 * Details about the new visit.
208 */
209 void NotifyItemVisited(const ItemVisitData& aData);
211 /**
212 * Notifies that a bookmark has changed.
213 *
214 * @param aItemId
215 * The changed item id.
216 * @param aData
217 * Details about the change.
218 */
219 void NotifyItemChanged(const ItemChangeData& aData);
221 /**
222 * Recursively builds an array of descendant folders inside a given folder.
223 *
224 * @param aFolderId
225 * The folder to fetch descendants from.
226 * @param aDescendantFoldersArray
227 * Output array to put descendant folders id.
228 */
229 nsresult GetDescendantFolders(int64_t aFolderId,
230 nsTArray<int64_t>& aDescendantFoldersArray);
232 private:
233 static nsNavBookmarks* gBookmarksService;
235 ~nsNavBookmarks();
237 /**
238 * Locates the root items in the bookmarks folder hierarchy assigning folder
239 * ids to the root properties that are exposed through the service interface.
240 */
241 nsresult ReadRoots();
243 nsresult AdjustIndices(int64_t aFolder,
244 int32_t aStartIndex,
245 int32_t aEndIndex,
246 int32_t aDelta);
248 /**
249 * Fetches properties of a folder.
250 *
251 * @param aFolderId
252 * Folder to count children for.
253 * @param _folderCount
254 * Number of children in the folder.
255 * @param _guid
256 * Unique id of the folder.
257 * @param _parentId
258 * Id of the parent of the folder.
259 *
260 * @throws If folder does not exist.
261 */
262 nsresult FetchFolderInfo(int64_t aFolderId,
263 int32_t* _folderCount,
264 nsACString& _guid,
265 int64_t* _parentId);
267 nsresult GetLastChildId(int64_t aFolder, int64_t* aItemId);
269 /**
270 * This is an handle to the Places database.
271 */
272 nsRefPtr<mozilla::places::Database> mDB;
274 int32_t mItemCount;
276 nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
278 int64_t mRoot;
279 int64_t mMenuRoot;
280 int64_t mTagsRoot;
281 int64_t mUnfiledRoot;
282 int64_t mToolbarRoot;
284 inline bool IsRoot(int64_t aFolderId) {
285 return aFolderId == mRoot || aFolderId == mMenuRoot ||
286 aFolderId == mTagsRoot || aFolderId == mUnfiledRoot ||
287 aFolderId == mToolbarRoot;
288 }
290 nsresult IsBookmarkedInDatabase(int64_t aBookmarkID, bool* aIsBookmarked);
292 nsresult SetItemDateInternal(enum mozilla::places::BookmarkDate aDateType,
293 int64_t aItemId,
294 PRTime aValue);
296 // Recursive method to build an array of folder's children
297 nsresult GetDescendantChildren(int64_t aFolderId,
298 const nsACString& aFolderGuid,
299 int64_t aGrandParentId,
300 nsTArray<BookmarkData>& aFolderChildrenArray);
302 enum ItemType {
303 BOOKMARK = TYPE_BOOKMARK,
304 FOLDER = TYPE_FOLDER,
305 SEPARATOR = TYPE_SEPARATOR,
306 };
308 /**
309 * Helper to insert a bookmark in the database.
310 *
311 * @param aItemId
312 * The itemId to insert, pass -1 to generate a new one.
313 * @param aPlaceId
314 * The placeId to which this bookmark refers to, pass nullptr for
315 * items that don't refer to an URI (eg. folders, separators, ...).
316 * @param aItemType
317 * The type of the new bookmark, see TYPE_* constants.
318 * @param aParentId
319 * The itemId of the parent folder.
320 * @param aIndex
321 * The position inside the parent folder.
322 * @param aTitle
323 * The title for the new bookmark.
324 * Pass a void string to set a NULL title.
325 * @param aDateAdded
326 * The date for the insertion.
327 * @param [optional] aLastModified
328 * The last modified date for the insertion.
329 * It defaults to aDateAdded.
330 *
331 * @return The new item id that has been inserted.
332 *
333 * @note This will also update last modified date of the parent folder.
334 */
335 nsresult InsertBookmarkInDB(int64_t aPlaceId,
336 enum ItemType aItemType,
337 int64_t aParentId,
338 int32_t aIndex,
339 const nsACString& aTitle,
340 PRTime aDateAdded,
341 PRTime aLastModified,
342 const nsACString& aParentGuid,
343 int64_t aGrandParentId,
344 nsIURI* aURI,
345 int64_t* _itemId,
346 nsACString& _guid);
348 /**
349 * TArray version of getBookmarksIdForURI for ease of use in C++ code.
350 * Pass in a reference to a TArray; it will get filled with the
351 * resulting list of bookmark IDs.
352 *
353 * @param aURI
354 * URI to get bookmarks for.
355 * @param aResult
356 * Array of bookmark ids.
357 * @param aSkipTags
358 * If true ids of tags-as-bookmarks entries will be excluded.
359 */
360 nsresult GetBookmarkIdsForURITArray(nsIURI* aURI,
361 nsTArray<int64_t>& aResult,
362 bool aSkipTags);
364 nsresult GetBookmarksForURI(nsIURI* aURI,
365 nsTArray<BookmarkData>& _bookmarks);
367 int64_t RecursiveFindRedirectedBookmark(int64_t aPlaceId);
369 static const int32_t kGetChildrenIndex_Position;
370 static const int32_t kGetChildrenIndex_Type;
371 static const int32_t kGetChildrenIndex_PlaceID;
372 static const int32_t kGetChildrenIndex_Guid;
374 class RemoveFolderTransaction MOZ_FINAL : public nsITransaction {
375 public:
376 RemoveFolderTransaction(int64_t aID) : mID(aID) {}
378 NS_DECL_ISUPPORTS
380 NS_IMETHOD DoTransaction() {
381 nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
382 NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
383 BookmarkData folder;
384 nsresult rv = bookmarks->FetchItemInfo(mID, folder);
385 // TODO (Bug 656935): store the BookmarkData struct instead.
386 mParent = folder.parentId;
387 mIndex = folder.position;
389 rv = bookmarks->GetItemTitle(mID, mTitle);
390 NS_ENSURE_SUCCESS(rv, rv);
392 return bookmarks->RemoveItem(mID);
393 }
395 NS_IMETHOD UndoTransaction() {
396 nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
397 NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
398 int64_t newFolder;
399 return bookmarks->CreateContainerWithID(mID, mParent, mTitle, true,
400 &mIndex, EmptyCString(), &newFolder);
401 }
403 NS_IMETHOD RedoTransaction() {
404 return DoTransaction();
405 }
407 NS_IMETHOD GetIsTransient(bool* aResult) {
408 *aResult = false;
409 return NS_OK;
410 }
412 NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aResult) {
413 *aResult = false;
414 return NS_OK;
415 }
417 private:
418 int64_t mID;
419 int64_t mParent;
420 nsCString mTitle;
421 int32_t mIndex;
422 };
424 // Used to enable and disable the observer notifications.
425 bool mCanNotify;
426 nsCategoryCache<nsINavBookmarkObserver> mCacheObservers;
428 // Tracks whether we are in batch mode.
429 // Note: this is only tracking bookmarks batches, not history ones.
430 bool mBatching;
432 /**
433 * Always call EnsureKeywordsHash() and check it for errors before actually
434 * using the hash. Internal keyword methods are already doing that.
435 */
436 nsresult EnsureKeywordsHash();
437 nsDataHashtable<nsTrimInt64HashKey, nsString> mBookmarkToKeywordHash;
438 bool mBookmarkToKeywordHashInitialized;
440 /**
441 * This function must be called every time a bookmark is removed.
442 *
443 * @param aURI
444 * Uri to test.
445 */
446 nsresult UpdateKeywordsHashForRemovedBookmark(int64_t aItemId);
448 /**
449 * Cache for the last fetched BookmarkData entries.
450 * This is used to speed up repeated requests to the same item id.
451 */
452 nsTHashtable<BookmarkKeyClass> mRecentBookmarksCache;
454 /**
455 * Tracks bookmarks in the cache critical path. Items should not be
456 * added to the cache till they are removed from this hash.
457 */
458 nsTHashtable<nsTrimInt64HashKey> mUncachableBookmarks;
459 };
461 #endif // nsNavBookmarks_h_