summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/nsNavBookmarks.h
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/nsNavBookmarks.h')
-rw-r--r--toolkit/components/places/nsNavBookmarks.h445
1 files changed, 445 insertions, 0 deletions
diff --git a/toolkit/components/places/nsNavBookmarks.h b/toolkit/components/places/nsNavBookmarks.h
new file mode 100644
index 000000000..d5cc3b5b7
--- /dev/null
+++ b/toolkit/components/places/nsNavBookmarks.h
@@ -0,0 +1,445 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsNavBookmarks_h_
+#define nsNavBookmarks_h_
+
+#include "nsINavBookmarksService.h"
+#include "nsIAnnotationService.h"
+#include "nsITransaction.h"
+#include "nsNavHistory.h"
+#include "nsToolkitCompsCID.h"
+#include "nsCategoryCache.h"
+#include "nsTHashtable.h"
+#include "nsWeakReference.h"
+#include "mozilla/Attributes.h"
+#include "prtime.h"
+
+class nsNavBookmarks;
+
+namespace mozilla {
+namespace places {
+
+ enum BookmarkStatementId {
+ DB_FIND_REDIRECTED_BOOKMARK = 0
+ , DB_GET_BOOKMARKS_FOR_URI
+ };
+
+ struct BookmarkData {
+ int64_t id;
+ nsCString url;
+ nsCString title;
+ int32_t position;
+ int64_t placeId;
+ int64_t parentId;
+ int64_t grandParentId;
+ int32_t type;
+ nsCString serviceCID;
+ PRTime dateAdded;
+ PRTime lastModified;
+ nsCString guid;
+ nsCString parentGuid;
+ };
+
+ struct ItemVisitData {
+ BookmarkData bookmark;
+ int64_t visitId;
+ uint32_t transitionType;
+ PRTime time;
+ };
+
+ struct ItemChangeData {
+ BookmarkData bookmark;
+ nsCString property;
+ bool isAnnotation;
+ nsCString newValue;
+ nsCString oldValue;
+ };
+
+ typedef void (nsNavBookmarks::*ItemVisitMethod)(const ItemVisitData&);
+ typedef void (nsNavBookmarks::*ItemChangeMethod)(const ItemChangeData&);
+
+ enum BookmarkDate {
+ DATE_ADDED = 0
+ , LAST_MODIFIED
+ };
+
+} // namespace places
+} // namespace mozilla
+
+class nsNavBookmarks final : public nsINavBookmarksService
+ , public nsINavHistoryObserver
+ , public nsIAnnotationObserver
+ , public nsIObserver
+ , public nsSupportsWeakReference
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSINAVBOOKMARKSSERVICE
+ NS_DECL_NSINAVHISTORYOBSERVER
+ NS_DECL_NSIANNOTATIONOBSERVER
+ NS_DECL_NSIOBSERVER
+
+ nsNavBookmarks();
+
+ /**
+ * Obtains the service's object.
+ */
+ static already_AddRefed<nsNavBookmarks> GetSingleton();
+
+ /**
+ * Initializes the service's object. This should only be called once.
+ */
+ nsresult Init();
+
+ static nsNavBookmarks* GetBookmarksService() {
+ if (!gBookmarksService) {
+ nsCOMPtr<nsINavBookmarksService> serv =
+ do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID);
+ NS_ENSURE_TRUE(serv, nullptr);
+ NS_ASSERTION(gBookmarksService,
+ "Should have static instance pointer now");
+ }
+ return gBookmarksService;
+ }
+
+ typedef mozilla::places::BookmarkData BookmarkData;
+ typedef mozilla::places::ItemVisitData ItemVisitData;
+ typedef mozilla::places::ItemChangeData ItemChangeData;
+ typedef mozilla::places::BookmarkStatementId BookmarkStatementId;
+
+ nsresult ResultNodeForContainer(int64_t aID,
+ nsNavHistoryQueryOptions* aOptions,
+ nsNavHistoryResultNode** aNode);
+
+ // Find all the children of a folder, using the given query and options.
+ // For each child, a ResultNode is created and added to |children|.
+ // The results are ordered by folder position.
+ nsresult QueryFolderChildren(int64_t aFolderId,
+ nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* children);
+
+ /**
+ * Turns aRow into a node and appends it to aChildren if it is appropriate to
+ * do so.
+ *
+ * @param aRow
+ * A Storage statement (in the case of synchronous execution) or row of
+ * a result set (in the case of asynchronous execution).
+ * @param aOptions
+ * The options of the parent folder node.
+ * @param aChildren
+ * The children of the parent folder node.
+ * @param aCurrentIndex
+ * The index of aRow within the results. When called on the first row,
+ * this should be set to -1.
+ */
+ nsresult ProcessFolderNodeRow(mozIStorageValueArray* aRow,
+ nsNavHistoryQueryOptions* aOptions,
+ nsCOMArray<nsNavHistoryResultNode>* aChildren,
+ int32_t& aCurrentIndex);
+
+ /**
+ * The async version of QueryFolderChildren.
+ *
+ * @param aNode
+ * The folder node that will receive the children.
+ * @param _pendingStmt
+ * The Storage pending statement that will be used to control async
+ * execution.
+ */
+ nsresult QueryFolderChildrenAsync(nsNavHistoryFolderResultNode* aNode,
+ int64_t aFolderId,
+ mozIStoragePendingStatement** _pendingStmt);
+
+ /**
+ * @return index of the new folder in aIndex, whether it was passed in or
+ * generated by autoincrement.
+ *
+ * @note If aFolder is -1, uses the autoincrement id for folder index.
+ * @note aTitle will be truncated to TITLE_LENGTH_MAX
+ */
+ nsresult CreateContainerWithID(int64_t aId, int64_t aParent,
+ const nsACString& aTitle,
+ bool aIsBookmarkFolder,
+ int32_t* aIndex,
+ const nsACString& aGUID,
+ uint16_t aSource,
+ int64_t* aNewFolder);
+
+ /**
+ * Fetches information about the specified id from the database.
+ *
+ * @param aItemId
+ * Id of the item to fetch information for.
+ * @param aBookmark
+ * BookmarkData to store the information.
+ */
+ nsresult FetchItemInfo(int64_t aItemId,
+ BookmarkData& _bookmark);
+
+ /**
+ * Notifies that a bookmark has been visited.
+ *
+ * @param aItemId
+ * The visited item id.
+ * @param aData
+ * Details about the new visit.
+ */
+ void NotifyItemVisited(const ItemVisitData& aData);
+
+ /**
+ * Notifies that a bookmark has changed.
+ *
+ * @param aItemId
+ * The changed item id.
+ * @param aData
+ * Details about the change.
+ */
+ void NotifyItemChanged(const ItemChangeData& aData);
+
+ /**
+ * Recursively builds an array of descendant folders inside a given folder.
+ *
+ * @param aFolderId
+ * The folder to fetch descendants from.
+ * @param aDescendantFoldersArray
+ * Output array to put descendant folders id.
+ */
+ nsresult GetDescendantFolders(int64_t aFolderId,
+ nsTArray<int64_t>& aDescendantFoldersArray);
+
+ static const int32_t kGetChildrenIndex_Guid;
+ static const int32_t kGetChildrenIndex_Position;
+ static const int32_t kGetChildrenIndex_Type;
+ static const int32_t kGetChildrenIndex_PlaceID;
+
+ static mozilla::Atomic<int64_t> sLastInsertedItemId;
+ static void StoreLastInsertedId(const nsACString& aTable,
+ const int64_t aLastInsertedId);
+
+private:
+ static nsNavBookmarks* gBookmarksService;
+
+ ~nsNavBookmarks();
+
+ /**
+ * Checks whether or not aFolderId points to a live bookmark.
+ *
+ * @param aFolderId
+ * the item-id of the folder to check.
+ * @return true if aFolderId points to live bookmarks, false otherwise.
+ */
+ bool IsLivemark(int64_t aFolderId);
+
+ /**
+ * Locates the root items in the bookmarks folder hierarchy assigning folder
+ * ids to the root properties that are exposed through the service interface.
+ */
+ nsresult ReadRoots();
+
+ nsresult AdjustIndices(int64_t aFolder,
+ int32_t aStartIndex,
+ int32_t aEndIndex,
+ int32_t aDelta);
+
+ /**
+ * Fetches properties of a folder.
+ *
+ * @param aFolderId
+ * Folder to count children for.
+ * @param _folderCount
+ * Number of children in the folder.
+ * @param _guid
+ * Unique id of the folder.
+ * @param _parentId
+ * Id of the parent of the folder.
+ *
+ * @throws If folder does not exist.
+ */
+ nsresult FetchFolderInfo(int64_t aFolderId,
+ int32_t* _folderCount,
+ nsACString& _guid,
+ int64_t* _parentId);
+
+ nsresult GetLastChildId(int64_t aFolder, int64_t* aItemId);
+
+ /**
+ * This is an handle to the Places database.
+ */
+ RefPtr<mozilla::places::Database> mDB;
+
+ int32_t mItemCount;
+
+ nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
+
+ int64_t mRoot;
+ int64_t mMenuRoot;
+ int64_t mTagsRoot;
+ int64_t mUnfiledRoot;
+ int64_t mToolbarRoot;
+ int64_t mMobileRoot;
+
+ inline bool IsRoot(int64_t aFolderId) {
+ return aFolderId == mRoot || aFolderId == mMenuRoot ||
+ aFolderId == mTagsRoot || aFolderId == mUnfiledRoot ||
+ aFolderId == mToolbarRoot || aFolderId == mMobileRoot;
+ }
+
+ nsresult IsBookmarkedInDatabase(int64_t aBookmarkID, bool* aIsBookmarked);
+
+ nsresult SetItemDateInternal(enum mozilla::places::BookmarkDate aDateType,
+ int64_t aItemId,
+ PRTime aValue);
+
+ // Recursive method to build an array of folder's children
+ nsresult GetDescendantChildren(int64_t aFolderId,
+ const nsACString& aFolderGuid,
+ int64_t aGrandParentId,
+ nsTArray<BookmarkData>& aFolderChildrenArray);
+
+ enum ItemType {
+ BOOKMARK = TYPE_BOOKMARK,
+ FOLDER = TYPE_FOLDER,
+ SEPARATOR = TYPE_SEPARATOR,
+ };
+
+ /**
+ * Helper to insert a bookmark in the database.
+ *
+ * @param aItemId
+ * The itemId to insert, pass -1 to generate a new one.
+ * @param aPlaceId
+ * The placeId to which this bookmark refers to, pass nullptr for
+ * items that don't refer to an URI (eg. folders, separators, ...).
+ * @param aItemType
+ * The type of the new bookmark, see TYPE_* constants.
+ * @param aParentId
+ * The itemId of the parent folder.
+ * @param aIndex
+ * The position inside the parent folder.
+ * @param aTitle
+ * The title for the new bookmark.
+ * Pass a void string to set a NULL title.
+ * @param aDateAdded
+ * The date for the insertion.
+ * @param [optional] aLastModified
+ * The last modified date for the insertion.
+ * It defaults to aDateAdded.
+ *
+ * @return The new item id that has been inserted.
+ *
+ * @note This will also update last modified date of the parent folder.
+ */
+ nsresult InsertBookmarkInDB(int64_t aPlaceId,
+ enum ItemType aItemType,
+ int64_t aParentId,
+ int32_t aIndex,
+ const nsACString& aTitle,
+ PRTime aDateAdded,
+ PRTime aLastModified,
+ const nsACString& aParentGuid,
+ int64_t aGrandParentId,
+ nsIURI* aURI,
+ uint16_t aSource,
+ int64_t* _itemId,
+ nsACString& _guid);
+
+ /**
+ * TArray version of getBookmarksIdForURI for ease of use in C++ code.
+ * Pass in a reference to a TArray; it will get filled with the
+ * resulting list of bookmark IDs.
+ *
+ * @param aURI
+ * URI to get bookmarks for.
+ * @param aResult
+ * Array of bookmark ids.
+ * @param aSkipTags
+ * If true ids of tags-as-bookmarks entries will be excluded.
+ */
+ nsresult GetBookmarkIdsForURITArray(nsIURI* aURI,
+ nsTArray<int64_t>& aResult,
+ bool aSkipTags);
+
+ nsresult GetBookmarksForURI(nsIURI* aURI,
+ nsTArray<BookmarkData>& _bookmarks);
+
+ int64_t RecursiveFindRedirectedBookmark(int64_t aPlaceId);
+
+ class RemoveFolderTransaction final : public nsITransaction {
+ public:
+ RemoveFolderTransaction(int64_t aID, uint16_t aSource)
+ : mID(aID)
+ , mSource(aSource)
+ {}
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD DoTransaction() override {
+ nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
+ NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
+ BookmarkData folder;
+ nsresult rv = bookmarks->FetchItemInfo(mID, folder);
+ // TODO (Bug 656935): store the BookmarkData struct instead.
+ mParent = folder.parentId;
+ mIndex = folder.position;
+
+ rv = bookmarks->GetItemTitle(mID, mTitle);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return bookmarks->RemoveItem(mID, mSource);
+ }
+
+ NS_IMETHOD UndoTransaction() override {
+ nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
+ NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
+ int64_t newFolder;
+ return bookmarks->CreateContainerWithID(mID, mParent, mTitle, true,
+ &mIndex, EmptyCString(),
+ mSource, &newFolder);
+ }
+
+ NS_IMETHOD RedoTransaction() override {
+ return DoTransaction();
+ }
+
+ NS_IMETHOD GetIsTransient(bool* aResult) override {
+ *aResult = false;
+ return NS_OK;
+ }
+
+ NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aResult) override {
+ *aResult = false;
+ return NS_OK;
+ }
+
+ private:
+ ~RemoveFolderTransaction() {}
+
+ int64_t mID;
+ uint16_t mSource;
+ MOZ_INIT_OUTSIDE_CTOR int64_t mParent;
+ nsCString mTitle;
+ MOZ_INIT_OUTSIDE_CTOR int32_t mIndex;
+ };
+
+ // Used to enable and disable the observer notifications.
+ bool mCanNotify;
+ nsCategoryCache<nsINavBookmarkObserver> mCacheObservers;
+
+ // Tracks whether we are in batch mode.
+ // Note: this is only tracking bookmarks batches, not history ones.
+ bool mBatching;
+
+ /**
+ * This function must be called every time a bookmark is removed.
+ *
+ * @param aURI
+ * Uri to test.
+ */
+ nsresult UpdateKeywordsForRemovedBookmark(const BookmarkData& aBookmark);
+};
+
+#endif // nsNavBookmarks_h_