diff --git a/mozilla/toolkit/components/places/public/nsITaggingService.idl b/mozilla/toolkit/components/places/public/nsITaggingService.idl index cbf048f18bf..de99adc33df 100644 --- a/mozilla/toolkit/components/places/public/nsITaggingService.idl +++ b/mozilla/toolkit/components/places/public/nsITaggingService.idl @@ -91,3 +91,9 @@ interface nsITaggingService : nsISupports */ readonly attribute nsIVariant allTags; }; + +%{C++ + +#define TAGGING_SERVICE_CID "@mozilla.org/browser/tagging-service;1" + +%} diff --git a/mozilla/toolkit/components/places/src/nsNavHistory.cpp b/mozilla/toolkit/components/places/src/nsNavHistory.cpp index 2ff53615267..3e2756ae99f 100644 --- a/mozilla/toolkit/components/places/src/nsNavHistory.cpp +++ b/mozilla/toolkit/components/places/src/nsNavHistory.cpp @@ -69,6 +69,9 @@ #include "prtime.h" #include "prprf.h" #include "nsEscape.h" +#include "nsITaggingService.h" +#include "nsIVariant.h" +#include "nsVariant.h" #include "mozIStorageService.h" #include "mozIStorageConnection.h" @@ -4096,6 +4099,45 @@ nsNavHistory::GroupByHost(nsNavHistoryQueryResultNode *aResultNode, return NS_OK; } +PRBool +nsNavHistory::URIHasTag(nsIURI* aURI, const nsAString& aTag) +{ + nsresult rv; + nsCOMPtr tagService = + do_GetService(TAGGING_SERVICE_CID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr tagsV; + rv = tagService->GetTagsForURI(aURI, getter_AddRefs(tagsV)); + NS_ENSURE_SUCCESS(rv, rv); + + // confirm that type is array, and has elements + // (data type is different for empty array) + PRUint16 dataType; + tagsV->GetDataType(&dataType); + if (dataType != nsIDataType::VTYPE_ARRAY) + return PR_FALSE; + + // get tags as array + PRUint16 type; + nsIID iid; + PRUint32 count; + PRUnichar** tags; + rv = tagsV->GetAsArray(&type, &iid, &count, (void**)&tags); + NS_ENSURE_SUCCESS(rv, rv); + + for (PRUint32 i = 0; i < count; i++) { + nsAutoString tag(tags[i]); + PRInt32 position = Compare(tag, aTag, nsCaseInsensitiveStringComparator()); + if (position == 0) { + nsMemory::Free(tags); + return PR_TRUE; + } + } + nsMemory::Free(tags); + return PR_FALSE; +} + // nsNavHistory::FilterResultSet // @@ -4161,6 +4203,7 @@ nsNavHistory::FilterResultSet(nsNavHistoryQueryResultNode* aParentNode, if (terms.Count() == 0) { allTermsFound = PR_TRUE; } else { + for (PRInt32 termIndex = 0; termIndex < terms.Count(); termIndex ++) { PRBool termFound = PR_FALSE; // title and URL @@ -4170,6 +4213,7 @@ nsNavHistory::FilterResultSet(nsNavHistoryQueryResultNode* aParentNode, CaseInsensitiveFindInReadable(*terms[termIndex], NS_ConvertUTF8toUTF16(aSet[nodeIndex]->mURI)))) termFound = PR_TRUE; + // searchable annotations /*if (! termFound) { for (PRInt32 annotIndex = 0; annotIndex < curAnnotations.Count(); annotIndex ++) { @@ -4178,7 +4222,16 @@ nsNavHistory::FilterResultSet(nsNavHistoryQueryResultNode* aParentNode, termFound = PR_TRUE; } }*/ - if (! termFound) { + + // search tags + if (!termFound) { + nsCOMPtr itemURI; + rv = NS_NewURI(getter_AddRefs(itemURI), aSet[nodeIndex]->mURI); + NS_ENSURE_SUCCESS(rv, rv); + termFound = URIHasTag(itemURI, *terms[termIndex]); + } + + if (!termFound) { allTermsFound = PR_FALSE; break; } diff --git a/mozilla/toolkit/components/places/src/nsNavHistory.h b/mozilla/toolkit/components/places/src/nsNavHistory.h index 792a0745ae0..b128b4ee237 100644 --- a/mozilla/toolkit/components/places/src/nsNavHistory.h +++ b/mozilla/toolkit/components/places/src/nsNavHistory.h @@ -511,6 +511,8 @@ protected: nsCOMArray* aDest, PRBool aIsDomain); + PRBool URIHasTag(nsIURI* aURI, const nsAString& aTag); + nsresult FilterResultSet(nsNavHistoryQueryResultNode *aParentNode, const nsCOMArray& aSet, nsCOMArray* aFiltered, diff --git a/mozilla/toolkit/components/places/tests/bookmarks/test_395101.js b/mozilla/toolkit/components/places/tests/bookmarks/test_395101.js new file mode 100644 index 00000000000..50d04f69a05 --- /dev/null +++ b/mozilla/toolkit/components/places/tests/bookmarks/test_395101.js @@ -0,0 +1,115 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dietrich Ayala + * + * 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 ***** */ + +// Get bookmark service +try { + var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService); +} catch(ex) { + do_throw("Could not get nav-bookmarks-service\n"); +} + +// Get history service +try { + var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService); +} catch(ex) { + do_throw("Could not get history service\n"); +} + +// Get tagging service +try { + var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"]. + getService(Ci.nsITaggingService); +} catch(ex) { + do_throw("Could not get tagging service\n"); +} + +// get bookmarks root id +var root = bmsvc.bookmarksRoot; + +// main +function run_test() { + // test searching for tagged bookmarks + + // test folder + var folder = bmsvc.createFolder(root, "bug 395101 test", bmsvc.DEFAULT_INDEX); + + // create a bookmark + var testURI = uri("http://a1.com"); + var b1 = bmsvc.insertBookmark(folder, testURI, + bmsvc.DEFAULT_INDEX, "1 title"); + + // tag the bookmarked URI + tagssvc.tagURI(testURI, ["elephant", "walrus", "giraffe", "turkey", "hiPPo", "BABOON", "alf"]); + + // search for the bookmark, using a tag + var query = histsvc.getNewQuery(); + query.searchTerms = "elephant"; + var options = histsvc.getNewQueryOptions(); + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; + query.setFolders([folder], 1); + + var result = histsvc.executeQuery(query, options); + var rootNode = result.root; + rootNode.containerOpen = true; + + do_check_eq(rootNode.childCount, 1); + do_check_eq(rootNode.getChild(0).itemId, b1); + + // only exact matches + query.searchTerms = "wal"; + var result = histsvc.executeQuery(query, options); + var rootNode = result.root; + rootNode.containerOpen = true; + do_check_eq(rootNode.childCount, 0); + + // case insensitive search term + query.searchTerms = "WALRUS"; + var result = histsvc.executeQuery(query, options); + var rootNode = result.root; + rootNode.containerOpen = true; + do_check_eq(rootNode.childCount, 1); + do_check_eq(rootNode.getChild(0).itemId, b1); + + // case insensitive tag + query.searchTerms = "baboon"; + var result = histsvc.executeQuery(query, options); + var rootNode = result.root; + rootNode.containerOpen = true; + do_check_eq(rootNode.childCount, 1); + do_check_eq(rootNode.getChild(0).itemId, b1); +}