diff --git a/browser/components/places/content/treeView.js b/browser/components/places/content/treeView.js index 6c4ec38a0bdc..a987904ad762 100644 --- a/browser/components/places/content/treeView.js +++ b/browser/components/places/content/treeView.js @@ -837,8 +837,8 @@ PlacesTreeView.prototype = { _getResourceForNode : function PTV_getResourceForNode(aNode) { - // XXXndeakin bug 380735, need to support day/host containers as well var uri = aNode.uri; + NS_ASSERT(uri, "if there is no uri, we can't persist the open state"); return uri ? PlacesUtils.RDF.GetResource(uri) : null; }, diff --git a/toolkit/components/places/src/nsNavHistory.cpp b/toolkit/components/places/src/nsNavHistory.cpp index 1ff2a2d23496..dc11349abc20 100644 --- a/toolkit/components/places/src/nsNavHistory.cpp +++ b/toolkit/components/places/src/nsNavHistory.cpp @@ -69,6 +69,7 @@ #include "prsystem.h" #include "prtime.h" #include "prprf.h" +#include "nsEscape.h" #include "mozIStorageService.h" #include "mozIStorageConnection.h" @@ -2035,7 +2036,8 @@ nsNavHistory::ExecuteQueries(nsINavHistoryQuery** aQueries, PRUint32 aQueryCount // it ANDed with the all the rest of the queries. nsresult -nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, +nsNavHistory::GetQueryResults(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aQueries, nsNavHistoryQueryOptions *aOptions, nsCOMArray* aResults) { @@ -2254,13 +2256,13 @@ nsNavHistory::GetQueryResults(const nsCOMArray& aQueries, // keyword searching with grouping: need intermediate filtered results nsCOMArray filteredResults; FilterResultSet(toplevel, &filteredResults, aQueries[0]->SearchTerms()); - rv = RecursiveGroup(filteredResults, groupings, groupCount, + rv = RecursiveGroup(aResultNode, filteredResults, groupings, groupCount, aResults); NS_ENSURE_SUCCESS(rv, rv); } } else { // group unfiltered results - rv = RecursiveGroup(toplevel, groupings, groupCount, aResults); + rv = RecursiveGroup(aResultNode, toplevel, groupings, groupCount, aResults); NS_ENSURE_SUCCESS(rv, rv); } } @@ -3571,7 +3573,8 @@ nsNavHistory::ResultsAsList(mozIStorageStatement* statement, // single level of grouping. nsresult -nsNavHistory::RecursiveGroup(const nsCOMArray& aSource, +nsNavHistory::RecursiveGroup(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, const PRUint16* aGroupingMode, PRUint32 aGroupCount, nsCOMArray* aDest) { @@ -3582,13 +3585,13 @@ nsNavHistory::RecursiveGroup(const nsCOMArray& aSource, nsresult rv; switch (aGroupingMode[0]) { case nsINavHistoryQueryOptions::GROUP_BY_DAY: - rv = GroupByDay(aSource, aDest); + rv = GroupByDay(aResultNode, aSource, aDest); break; case nsINavHistoryQueryOptions::GROUP_BY_HOST: - rv = GroupByHost(aSource, aDest, PR_FALSE); + rv = GroupByHost(aResultNode, aSource, aDest, PR_FALSE); break; case nsINavHistoryQueryOptions::GROUP_BY_DOMAIN: - rv = GroupByHost(aSource, aDest, PR_TRUE); + rv = GroupByHost(aResultNode, aSource, aDest, PR_TRUE); break; case nsINavHistoryQueryOptions::GROUP_BY_FOLDER: // not yet supported (this code path is not reached for simple bookmark @@ -3609,7 +3612,7 @@ nsNavHistory::RecursiveGroup(const nsCOMArray& aSource, nsNavHistoryContainerResultNode* container = curNode->GetAsContainer(); nsCOMArray temp(container->mChildren); container->mChildren.Clear(); - rv = RecursiveGroup(temp, &aGroupingMode[1], aGroupCount - 1, + rv = RecursiveGroup(aResultNode, temp, &aGroupingMode[1], aGroupCount - 1, &container->mChildren); NS_ENSURE_SUCCESS(rv, rv); } @@ -3631,13 +3634,45 @@ GetAgeInDays(PRTime aNormalizedNow, PRTime aDate) return ((aNormalizedNow - dateMidnight) / USECS_PER_DAY); } +const PRInt64 UNDEFINED_AGE_IN_DAYS = -1; + +// Create a urn (like +// urn:places-persist:place:group=0&group=1&sort=1&type=1,,%28local%20files%29) +// to be used to persist the open state of this container in localstore.rdf +nsresult +CreatePlacesPersistURN(nsNavHistoryQueryResultNode *aResultNode, + PRInt64 aAgeInDays, const nsCString& aTitle, nsCString& aURN) +{ + nsCAutoString uri; + nsresult rv = aResultNode->GetUri(uri); + NS_ENSURE_SUCCESS(rv, rv); + + aURN.Assign(NS_LITERAL_CSTRING("urn:places-persist:")); + aURN.Append(uri); + + aURN.Append(NS_LITERAL_CSTRING(",")); + if (aAgeInDays != UNDEFINED_AGE_IN_DAYS) + aURN.AppendInt(aAgeInDays); + + aURN.Append(NS_LITERAL_CSTRING(",")); + if (!aTitle.IsEmpty()) { + nsCAutoString escapedTitle; + PRBool success = NS_Escape(aTitle, escapedTitle, url_XAlphas); + NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); + aURN.Append(escapedTitle); + } + + return NS_OK; +} + // XXX todo // we should make "group by date" more flexible and extensible, in order // to allow extension developers to write better history sidebars and viewers // see bug #359346 // nsNavHistory::GroupByDay nsresult -nsNavHistory::GroupByDay(const nsCOMArray& aSource, +nsNavHistory::GroupByDay(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, nsCOMArray* aDest) { // 8 == today, yesterday, 2 ago, 3 ago, 4 ago, 5 ago, 6 ago, older than 6 @@ -3681,8 +3716,12 @@ nsNavHistory::GroupByDay(const nsCOMArray& aSource, curDateName = dateNames[ageInDays]; if (!dates[ageInDays]) { + nsCAutoString urn; + nsresult rv = CreatePlacesPersistURN(aResultNode, ageInDays, EmptyCString(), urn); + NS_ENSURE_SUCCESS(rv, rv); + // need to create an entry for this date - dates[ageInDays] = new nsNavHistoryContainerResultNode(EmptyCString(), + dates[ageInDays] = new nsNavHistoryContainerResultNode(urn, curDateName, EmptyCString(), nsNavHistoryResultNode::RESULT_TYPE_DAY, @@ -3719,7 +3758,8 @@ nsNavHistory::GroupByDay(const nsCOMArray& aSource, // we would only be charged the overhead of an empty string on each node. nsresult -nsNavHistory::GroupByHost(const nsCOMArray& aSource, +nsNavHistory::GroupByHost(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, nsCOMArray* aDest, PRBool aIsDomain) { @@ -3758,7 +3798,11 @@ nsNavHistory::GroupByHost(const nsCOMArray& aSource, nsCAutoString title; TitleForDomain(curHostName, title); - curTopGroup = new nsNavHistoryContainerResultNode(EmptyCString(), title, + nsCAutoString urn; + nsresult rv = CreatePlacesPersistURN(aResultNode, UNDEFINED_AGE_IN_DAYS, title, urn); + NS_ENSURE_SUCCESS(rv, rv); + + curTopGroup = new nsNavHistoryContainerResultNode(urn, title, EmptyCString(), nsNavHistoryResultNode::RESULT_TYPE_HOST, PR_TRUE, EmptyCString()); if (! curTopGroup) @@ -3766,7 +3810,8 @@ nsNavHistory::GroupByHost(const nsCOMArray& aSource, if (! hosts.Put(curHostName, curTopGroup)) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = aDest->AppendObject(curTopGroup); + + rv = aDest->AppendObject(curTopGroup); NS_ENSURE_SUCCESS(rv, rv); } if (! curTopGroup->mChildren.AppendObject(aSource[i])) diff --git a/toolkit/components/places/src/nsNavHistory.h b/toolkit/components/places/src/nsNavHistory.h index 7d000fca5f68..9ccfdd965026 100644 --- a/toolkit/components/places/src/nsNavHistory.h +++ b/toolkit/components/places/src/nsNavHistory.h @@ -247,7 +247,8 @@ public: // this actually executes a query and gives you results, it is used by // nsNavHistoryQueryResultNode - nsresult GetQueryResults(const nsCOMArray& aQueries, + nsresult GetQueryResults(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aQueries, nsNavHistoryQueryOptions *aOptions, nsCOMArray* aResults); @@ -299,7 +300,8 @@ public: static void DomainNameFromHostName(const nsCString& aHostName, nsACString& aDomainName); static PRTime NormalizeTime(PRUint32 aRelative, PRTime aOffset); - nsresult RecursiveGroup(const nsCOMArray& aSource, + nsresult RecursiveGroup(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, const PRUint16* aGroupingMode, PRUint32 aGroupCount, nsCOMArray* aDest); @@ -499,10 +501,12 @@ protected: nsresult SetPageTitleInternal(nsIURI* aURI, PRBool aIsUserTitle, const nsAString& aTitle); - nsresult GroupByDay(const nsCOMArray& aSource, - nsCOMArray* aDest); + nsresult GroupByDay(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, + nsCOMArray* aDest); - nsresult GroupByHost(const nsCOMArray& aSource, + nsresult GroupByHost(nsNavHistoryQueryResultNode *aResultNode, + const nsCOMArray& aSource, nsCOMArray* aDest, PRBool aIsDomain); diff --git a/toolkit/components/places/src/nsNavHistoryResult.cpp b/toolkit/components/places/src/nsNavHistoryResult.cpp index 0c010f6de8fe..4cbfe7aad33b 100644 --- a/toolkit/components/places/src/nsNavHistoryResult.cpp +++ b/toolkit/components/places/src/nsNavHistoryResult.cpp @@ -2120,7 +2120,7 @@ nsNavHistoryQueryResultNode::FillChildren() // get the results from the history service nsresult rv = VerifyQueriesParsed(); NS_ENSURE_SUCCESS(rv, rv); - rv = history->GetQueryResults(mQueries, mOptions, &mChildren); + rv = history->GetQueryResults(this, mQueries, mOptions, &mChildren); NS_ENSURE_SUCCESS(rv, rv); // it is important to call FillStats to fill in the parents on all @@ -2398,7 +2398,7 @@ nsNavHistoryQueryResultNode::OnVisit(nsIURI* aURI, PRInt64 aVisitId, nsCOMArray itemSource; if (! itemSource.AppendObject(addition)) return NS_ERROR_OUT_OF_MEMORY; - history->RecursiveGroup(itemSource, groupings, groupCount, &grouped); + history->RecursiveGroup(this, itemSource, groupings, groupCount, &grouped); } else { // no grouping if (! grouped.AppendObject(addition))