From 902e3022cee991a1191a6f7dc0809d8b28568086 Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Tue, 23 Jun 2009 01:00:51 +0200 Subject: [PATCH] Bug 492884 - getMostRecentFolderForFeedURI should use the livemarks service instead of annos directly, r=dietrich --- .../places/public/nsILivemarkService.idl | 12 ++- .../places/src/nsLivemarkService.js | 12 +++ toolkit/components/places/src/utils.js | 50 +++++++--- ...livemarkService_getLivemarkIdForFeedURI.js | 99 +++++++++++++++++++ 4 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 toolkit/components/places/tests/unit/test_livemarkService_getLivemarkIdForFeedURI.js diff --git a/toolkit/components/places/public/nsILivemarkService.idl b/toolkit/components/places/public/nsILivemarkService.idl index 8d22ea57e76..2c4f453f126 100644 --- a/toolkit/components/places/public/nsILivemarkService.idl +++ b/toolkit/components/places/public/nsILivemarkService.idl @@ -43,7 +43,7 @@ interface nsIURI; interface nsINavBookmarksService; -[scriptable, uuid(2c08ab79-7f9b-40f3-8d04-540b5857b211)] +[scriptable, uuid(62a5fe00-d85c-4a63-aef7-176d8f1b189d)] interface nsILivemarkService : nsISupports { /** @@ -95,6 +95,16 @@ interface nsILivemarkService : nsISupports */ boolean isLivemark(in long long folder); + /** + * Determines whether the feed URI is a currently registered livemark. + * + * @param aFeedURI + * Feed URI to look for. + * + * @returns the found livemark folder id, or -1 if nothing was found. + */ + long long getLivemarkIdForFeedURI(in nsIURI aFeedURI); + /** * Gets the URI of the website associated with a livemark container. * diff --git a/toolkit/components/places/src/nsLivemarkService.js b/toolkit/components/places/src/nsLivemarkService.js index f40b0b3ae7c..107496c0d2a 100644 --- a/toolkit/components/places/src/nsLivemarkService.js +++ b/toolkit/components/places/src/nsLivemarkService.js @@ -393,6 +393,18 @@ LivemarkService.prototype = { return false; }, + getLivemarkIdForFeedURI: function LS_getLivemarkIdForFeedURI(aFeedURI) { + if (!(aFeedURI instanceof Ci.nsIURI)) + throw Cr.NS_ERROR_INVALID_ARG; + + for (var i = 0; i < this._livemarks.length; ++i) { + if (this._livemarks[i].feedURI.equals(aFeedURI)) + return this._livemarks[i].folderId; + } + + return -1; + }, + _ensureLivemark: function LS__ensureLivemark(aFolderId) { if (!this.isLivemark(aFolderId)) throw Cr.NS_ERROR_INVALID_ARG; diff --git a/toolkit/components/places/src/utils.js b/toolkit/components/places/src/utils.js index c7a0ce9deb0..501d01ef91f 100644 --- a/toolkit/components/places/src/utils.js +++ b/toolkit/components/places/src/utils.js @@ -1001,38 +1001,60 @@ var PlacesUtils = { /** * Get the most recently added/modified bookmark for a URL, excluding items - * under tag or livemark containers. -1 is returned if no item is found. + * under tag or livemark containers. + * + * @param aURI + * nsIURI of the page we will look for. + * @returns itemId of the found bookmark, or -1 if nothing is found. */ getMostRecentBookmarkForURI: function PU_getMostRecentBookmarkForURI(aURI) { var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {}); for (var i = 0; i < bmkIds.length; i++) { // Find the first folder which isn't a tag container - var bk = bmkIds[i]; - var parentId = this.bookmarks.getFolderIdForItem(bk); - if (parentId == this.unfiledBookmarksFolderId) - return bk; + var itemId = bmkIds[i]; + var parentId = this.bookmarks.getFolderIdForItem(itemId); + // Optimization: if this is a direct child of a root we don't need to + // check if its grandparent is a tag. + if (parentId == this.unfiledBookmarksFolderId || + parentId == this.toolbarFolderId || + parentId == this.bookmarksMenuFolderId) + return itemId; var grandparentId = this.bookmarks.getFolderIdForItem(parentId); if (grandparentId != this.tagsFolderId && !this.itemIsLivemark(parentId)) - return bk; + return itemId; } return -1; }, /** - * TODO: this should use the livemark service's cache of folder ids (bug 492884). + * Get the most recent folder item id for a feed URI. + * + * @param aURI + * nsIURI of the feed we will look for. + * @returns folder item id of the found livemark, or -1 if nothing is found. */ getMostRecentFolderForFeedURI: - function PU_getMostRecentFolderForFeedURI(aURI) { - var feedSpec = aURI.spec - var annosvc = this.annotations; - var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {}); - for (var i = 0; i < livemarks.length; i++) { - if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec) - return livemarks[i]; + function PU_getMostRecentFolderForFeedURI(aFeedURI) { + // If the Livemark service hasn't yet been initialized then + // use the annotations service directly to avoid instanciating + // it on startup. (bug 398300) + if (this.__lookupGetter__("livemarks")) { + var feedSpec = aFeedURI.spec + var annosvc = this.annotations; + var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {}); + for (var i = 0; i < livemarks.length; i++) { + if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec) + return livemarks[i]; + } } + else { + // If the livemark service has already been instanciated, use it. + return this.livemarks.getLivemarkIdForFeedURI(aFeedURI); + } + return -1; }, diff --git a/toolkit/components/places/tests/unit/test_livemarkService_getLivemarkIdForFeedURI.js b/toolkit/components/places/tests/unit/test_livemarkService_getLivemarkIdForFeedURI.js new file mode 100644 index 00000000000..9b286963808 --- /dev/null +++ b/toolkit/components/places/tests/unit/test_livemarkService_getLivemarkIdForFeedURI.js @@ -0,0 +1,99 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Places unit test code. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Marco Bonardo + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const LMANNO_FEEDURI = "livemark/feedURI"; + +Components.utils.import("resource://gre/modules/utils.js"); +var PU = PlacesUtils; +var bs = PU.bookmarks; +var as = PU.annotations; + +/** + * Creates a fake livemark without using the livemark service. + * + * @param aParentId + * folder where we will create the livemark. + * @param aTitle + * title for the livemark. + * @param aSiteURI + * siteURI, currently unused. + * @param aFeedURI + * feed URI for the livemark. + * @param aIndex + * index of the new folder inside parent. + * + * @returns the new folder id. + */ +function createFakeLivemark(aParentId, aTitle, aSiteURI, aFeedURI, aIndex) { + var folderId = bs.createFolder(aParentId, aTitle, aIndex); + bs.setFolderReadonly(folderId, true); + + // Add an annotation to map the folder id to the livemark feed URI. + as.setItemAnnotation(folderId, LMANNO_FEEDURI, aFeedURI.spec, + 0, as.EXPIRE_NEVER); + return folderId; +} + +// main +function run_test() { + var feedURI = uri("http://example.com/rss.xml"); + + // Create a fake livemark, and use getMostRecentFolderForFeedURI before + // livemark service is initialized. + var fakeLivemarkId = createFakeLivemark(bs.bookmarksMenuFolder, "foo", + uri("http://example.com/"), + feedURI, bs.DEFAULT_INDEX); + do_check_eq(PU.getMostRecentFolderForFeedURI(feedURI), fakeLivemarkId); + + bs.removeItem(fakeLivemarkId); + do_check_eq(PU.getMostRecentFolderForFeedURI(feedURI), -1); + + // Create livemark service and repeat the test. + var ls = PU.livemarks; + var livemarkId = ls.createLivemarkFolderOnly(bs.bookmarksMenuFolder, "foo", + uri("http://example.com/"), + feedURI, bs.DEFAULT_INDEX); + + do_check_eq(ls.getLivemarkIdForFeedURI(feedURI), livemarkId); + do_check_eq(PU.getMostRecentFolderForFeedURI(feedURI), livemarkId); + + bs.removeItem(livemarkId); + do_check_eq(ls.getLivemarkIdForFeedURI(feedURI), -1); + do_check_eq(PU.getMostRecentFolderForFeedURI(feedURI), -1); +}