michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsNavHistory_h_ michael@0: #define nsNavHistory_h_ michael@0: michael@0: #include "nsINavHistoryService.h" michael@0: #include "nsPIPlacesDatabase.h" michael@0: #include "nsPIPlacesHistoryListenersNotifier.h" michael@0: #include "nsIBrowserHistory.h" michael@0: #include "nsINavBookmarksService.h" michael@0: #include "nsIFaviconService.h" michael@0: michael@0: #include "nsIObserverService.h" michael@0: #include "nsICollation.h" michael@0: #include "nsIStringBundle.h" michael@0: #include "nsITimer.h" michael@0: #include "nsMaybeWeakPtr.h" michael@0: #include "nsCategoryCache.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsToolkitCompsCID.h" michael@0: #include "nsURIHashKey.h" michael@0: #include "nsTHashtable.h" michael@0: michael@0: #include "nsNavHistoryResult.h" michael@0: #include "nsNavHistoryQuery.h" michael@0: #include "Database.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #define QUERYUPDATE_TIME 0 michael@0: #define QUERYUPDATE_SIMPLE 1 michael@0: #define QUERYUPDATE_COMPLEX 2 michael@0: #define QUERYUPDATE_COMPLEX_WITH_BOOKMARKS 3 michael@0: #define QUERYUPDATE_HOST 4 michael@0: michael@0: // Clamp title and URL to generously large, but not too large, length. michael@0: // See bug 319004 for details. michael@0: #define URI_LENGTH_MAX 65536 michael@0: #define TITLE_LENGTH_MAX 4096 michael@0: michael@0: // Microsecond timeout for "recent" events such as typed and bookmark following. michael@0: // If you typed it more than this time ago, it's not recent. michael@0: #define RECENT_EVENT_THRESHOLD PRTime((int64_t)15 * 60 * PR_USEC_PER_SEC) michael@0: michael@0: #ifdef MOZ_XUL michael@0: // Fired after autocomplete feedback has been updated. michael@0: #define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated" michael@0: #endif michael@0: michael@0: // Fired after frecency has been updated. michael@0: #define TOPIC_FRECENCY_UPDATED "places-frecency-updated" michael@0: michael@0: class mozIAnnotationService; michael@0: class nsNavHistory; michael@0: class QueryKeyValuePair; michael@0: class nsIEffectiveTLDService; michael@0: class nsIIDNService; michael@0: class PlacesSQLQueryBuilder; michael@0: class nsIAutoCompleteController; michael@0: michael@0: // nsNavHistory michael@0: michael@0: class nsNavHistory MOZ_FINAL : public nsSupportsWeakReference michael@0: , public nsINavHistoryService michael@0: , public nsIObserver michael@0: , public nsIBrowserHistory michael@0: , public nsPIPlacesDatabase michael@0: , public nsPIPlacesHistoryListenersNotifier michael@0: , public mozIStorageVacuumParticipant michael@0: { michael@0: friend class PlacesSQLQueryBuilder; michael@0: michael@0: public: michael@0: nsNavHistory(); michael@0: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSINAVHISTORYSERVICE michael@0: NS_DECL_NSIBROWSERHISTORY michael@0: NS_DECL_NSIOBSERVER michael@0: NS_DECL_NSPIPLACESDATABASE michael@0: NS_DECL_NSPIPLACESHISTORYLISTENERSNOTIFIER michael@0: NS_DECL_MOZISTORAGEVACUUMPARTICIPANT michael@0: michael@0: /** michael@0: * Obtains the nsNavHistory object. michael@0: */ michael@0: static already_AddRefed GetSingleton(); michael@0: michael@0: /** michael@0: * Initializes the nsNavHistory object. This should only be called once. michael@0: */ michael@0: nsresult Init(); michael@0: michael@0: /** michael@0: * Used by other components in the places directory such as the annotation michael@0: * service to get a reference to this history object. Returns a pointer to michael@0: * the service if it exists. Otherwise creates one. Returns nullptr on error. michael@0: */ michael@0: static nsNavHistory* GetHistoryService() michael@0: { michael@0: if (!gHistoryService) { michael@0: nsCOMPtr serv = michael@0: do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID); michael@0: NS_ENSURE_TRUE(serv, nullptr); michael@0: NS_ASSERTION(gHistoryService, "Should have static instance pointer now"); michael@0: } michael@0: return gHistoryService; michael@0: } michael@0: michael@0: /** michael@0: * Used by other components in the places directory to get a reference to a michael@0: * const version of this history object. michael@0: * michael@0: * @return A pointer to a const version of the service if it exists, michael@0: * nullptr otherwise. michael@0: */ michael@0: static const nsNavHistory* GetConstHistoryService() michael@0: { michael@0: const nsNavHistory* const history = gHistoryService; michael@0: return history; michael@0: } michael@0: michael@0: /** michael@0: * Fetches the database id and the GUID associated to the given URI. michael@0: * michael@0: * @param aURI michael@0: * The page to look for. michael@0: * @param _pageId michael@0: * Will be set to the database id associated with the page. michael@0: * If the page doesn't exist, this will be zero. michael@0: * @param _GUID michael@0: * Will be set to the unique id associated with the page. michael@0: * If the page doesn't exist, this will be empty. michael@0: * @note This DOES NOT check for bad URLs other than that they're nonempty. michael@0: */ michael@0: nsresult GetIdForPage(nsIURI* aURI, michael@0: int64_t* _pageId, nsCString& _GUID); michael@0: michael@0: /** michael@0: * Fetches the database id and the GUID associated to the given URI, creating michael@0: * a new database entry if one doesn't exist yet. michael@0: * michael@0: * @param aURI michael@0: * The page to look for or create. michael@0: * @param _pageId michael@0: * Will be set to the database id associated with the page. michael@0: * @param _GUID michael@0: * Will be set to the unique id associated with the page. michael@0: * @note This DOES NOT check for bad URLs other than that they're nonempty. michael@0: * @note This DOES NOT update frecency of the page. michael@0: */ michael@0: nsresult GetOrCreateIdForPage(nsIURI* aURI, michael@0: int64_t* _pageId, nsCString& _GUID); michael@0: michael@0: /** michael@0: * Asynchronously recalculates frecency for a given page. michael@0: * michael@0: * @param aPlaceId michael@0: * Place id to recalculate the frecency for. michael@0: * @note If the new frecency is a non-zero value it will also unhide the page, michael@0: * otherwise will reuse the old hidden value. michael@0: */ michael@0: nsresult UpdateFrecency(int64_t aPlaceId); michael@0: michael@0: /** michael@0: * Recalculates frecency for all pages requesting that (frecency < 0). Those michael@0: * may be generated: michael@0: * * After a "clear private data" michael@0: * * After removing visits michael@0: * * After migrating from older versions michael@0: */ michael@0: nsresult FixInvalidFrecencies(); michael@0: michael@0: /** michael@0: * Invalidate the frecencies of a list of places, so they will be recalculated michael@0: * at the first idle-daily notification. michael@0: * michael@0: * @param aPlacesIdsQueryString michael@0: * Query string containing list of places to be invalidated. If it's michael@0: * an empty string all places will be invalidated. michael@0: */ michael@0: nsresult invalidateFrecencies(const nsCString& aPlaceIdsQueryString); michael@0: michael@0: /** michael@0: * These functions return non-owning references to the locale-specific michael@0: * objects for places components. michael@0: */ michael@0: nsIStringBundle* GetBundle(); michael@0: nsIStringBundle* GetDateFormatBundle(); michael@0: nsICollation* GetCollation(); michael@0: void GetStringFromName(const char16_t* aName, nsACString& aResult); michael@0: void GetAgeInDaysString(int32_t aInt, const char16_t *aName, michael@0: nsACString& aResult); michael@0: void GetMonthName(int32_t aIndex, nsACString& aResult); michael@0: void GetMonthYear(int32_t aMonth, int32_t aYear, nsACString& aResult); michael@0: michael@0: // Returns whether history is enabled or not. michael@0: bool IsHistoryDisabled() { michael@0: return !mHistoryEnabled; michael@0: } michael@0: michael@0: // Constants for the columns returned by the above statement. michael@0: static const int32_t kGetInfoIndex_PageID; michael@0: static const int32_t kGetInfoIndex_URL; michael@0: static const int32_t kGetInfoIndex_Title; michael@0: static const int32_t kGetInfoIndex_RevHost; michael@0: static const int32_t kGetInfoIndex_VisitCount; michael@0: static const int32_t kGetInfoIndex_VisitDate; michael@0: static const int32_t kGetInfoIndex_FaviconURL; michael@0: static const int32_t kGetInfoIndex_ItemId; michael@0: static const int32_t kGetInfoIndex_ItemDateAdded; michael@0: static const int32_t kGetInfoIndex_ItemLastModified; michael@0: static const int32_t kGetInfoIndex_ItemParentId; michael@0: static const int32_t kGetInfoIndex_ItemTags; michael@0: static const int32_t kGetInfoIndex_Frecency; michael@0: static const int32_t kGetInfoIndex_Hidden; michael@0: static const int32_t kGetInfoIndex_Guid; michael@0: michael@0: int64_t GetTagsFolder(); michael@0: michael@0: // this actually executes a query and gives you results, it is used by michael@0: // nsNavHistoryQueryResultNode michael@0: nsresult GetQueryResults(nsNavHistoryQueryResultNode *aResultNode, michael@0: const nsCOMArray& aQueries, michael@0: nsNavHistoryQueryOptions *aOptions, michael@0: nsCOMArray* aResults); michael@0: michael@0: // Take a row of kGetInfoIndex_* columns and construct a ResultNode. michael@0: // The row must contain the full set of columns. michael@0: nsresult RowToResult(mozIStorageValueArray* aRow, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsNavHistoryResultNode** aResult); michael@0: nsresult QueryRowToResult(int64_t aItemId, const nsACString& aURI, michael@0: const nsACString& aTitle, michael@0: uint32_t aAccessCount, PRTime aTime, michael@0: const nsACString& aFavicon, michael@0: nsNavHistoryResultNode** aNode); michael@0: michael@0: nsresult VisitIdToResultNode(int64_t visitId, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsNavHistoryResultNode** aResult); michael@0: michael@0: nsresult BookmarkIdToResultNode(int64_t aBookmarkId, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsNavHistoryResultNode** aResult); michael@0: nsresult URIToResultNode(nsIURI* aURI, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsNavHistoryResultNode** aResult); michael@0: michael@0: // used by other places components to send history notifications (for example, michael@0: // when the favicon has changed) michael@0: void SendPageChangedNotification(nsIURI* aURI, uint32_t aChangedAttribute, michael@0: const nsAString& aValue, michael@0: const nsACString& aGUID); michael@0: michael@0: /** michael@0: * Returns current number of days stored in history. michael@0: */ michael@0: int32_t GetDaysOfHistory(); michael@0: michael@0: // used by query result nodes to update: see comment on body of CanLiveUpdateQuery michael@0: static uint32_t GetUpdateRequirements(const nsCOMArray& aQueries, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: bool* aHasSearchTerms); michael@0: bool EvaluateQueryForNode(const nsCOMArray& aQueries, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsNavHistoryResultNode* aNode); michael@0: michael@0: static nsresult AsciiHostNameFromHostString(const nsACString& aHostName, michael@0: nsACString& aAscii); michael@0: void DomainNameFromURI(nsIURI* aURI, michael@0: nsACString& aDomainName); michael@0: static PRTime NormalizeTime(uint32_t aRelative, PRTime aOffset); michael@0: michael@0: // Don't use these directly, inside nsNavHistory use UpdateBatchScoper, michael@0: // else use nsINavHistoryService::RunInBatchMode michael@0: nsresult BeginUpdateBatch(); michael@0: nsresult EndUpdateBatch(); michael@0: michael@0: // The level of batches' nesting, 0 when no batches are open. michael@0: int32_t mBatchLevel; michael@0: // Current active transaction for a batch. michael@0: mozStorageTransaction* mBatchDBTransaction; michael@0: michael@0: // better alternative to QueryStringToQueries (in nsNavHistoryQuery.cpp) michael@0: nsresult QueryStringToQueryArray(const nsACString& aQueryString, michael@0: nsCOMArray* aQueries, michael@0: nsNavHistoryQueryOptions** aOptions); michael@0: michael@0: typedef nsDataHashtable StringHash; michael@0: michael@0: /** michael@0: * Indicates if it is OK to notify history observers or not. michael@0: * michael@0: * @return true if it is OK to notify, false otherwise. michael@0: */ michael@0: bool canNotify() { return mCanNotify; } michael@0: michael@0: enum RecentEventFlags { michael@0: RECENT_TYPED = 1 << 0, // User typed in URL recently michael@0: RECENT_ACTIVATED = 1 << 1, // User tapped URL link recently michael@0: RECENT_BOOKMARKED = 1 << 2 // User bookmarked URL recently michael@0: }; michael@0: michael@0: /** michael@0: * Returns any recent activity done with a URL. michael@0: * @return Any recent events associated with this URI. Each bit is set michael@0: * according to RecentEventFlags enum values. michael@0: */ michael@0: uint32_t GetRecentFlags(nsIURI *aURI); michael@0: michael@0: /** michael@0: * Registers a TRANSITION_EMBED visit for the session. michael@0: * michael@0: * @param aURI michael@0: * URI of the page. michael@0: * @param aTime michael@0: * Visit time. Only the last registered visit time is retained. michael@0: */ michael@0: void registerEmbedVisit(nsIURI* aURI, int64_t aTime); michael@0: michael@0: /** michael@0: * Returns whether the specified url has a embed visit. michael@0: * michael@0: * @param aURI michael@0: * URI of the page. michael@0: * @return whether the page has a embed visit. michael@0: */ michael@0: bool hasEmbedVisit(nsIURI* aURI); michael@0: michael@0: /** michael@0: * Clears all registered embed visits. michael@0: */ michael@0: void clearEmbedVisits(); michael@0: michael@0: int32_t GetFrecencyAgedWeight(int32_t aAgeInDays) const michael@0: { michael@0: if (aAgeInDays <= mFirstBucketCutoffInDays) { michael@0: return mFirstBucketWeight; michael@0: } michael@0: if (aAgeInDays <= mSecondBucketCutoffInDays) { michael@0: return mSecondBucketWeight; michael@0: } michael@0: if (aAgeInDays <= mThirdBucketCutoffInDays) { michael@0: return mThirdBucketWeight; michael@0: } michael@0: if (aAgeInDays <= mFourthBucketCutoffInDays) { michael@0: return mFourthBucketWeight; michael@0: } michael@0: return mDefaultWeight; michael@0: } michael@0: michael@0: int32_t GetFrecencyBucketWeight(int32_t aBucketIndex) const michael@0: { michael@0: switch(aBucketIndex) { michael@0: case 1: michael@0: return mFirstBucketWeight; michael@0: case 2: michael@0: return mSecondBucketWeight; michael@0: case 3: michael@0: return mThirdBucketWeight; michael@0: case 4: michael@0: return mFourthBucketWeight; michael@0: default: michael@0: return mDefaultWeight; michael@0: } michael@0: } michael@0: michael@0: int32_t GetFrecencyTransitionBonus(int32_t aTransitionType, michael@0: bool aVisited) const michael@0: { michael@0: switch (aTransitionType) { michael@0: case nsINavHistoryService::TRANSITION_EMBED: michael@0: return mEmbedVisitBonus; michael@0: case nsINavHistoryService::TRANSITION_FRAMED_LINK: michael@0: return mFramedLinkVisitBonus; michael@0: case nsINavHistoryService::TRANSITION_LINK: michael@0: return mLinkVisitBonus; michael@0: case nsINavHistoryService::TRANSITION_TYPED: michael@0: return aVisited ? mTypedVisitBonus : mUnvisitedTypedBonus; michael@0: case nsINavHistoryService::TRANSITION_BOOKMARK: michael@0: return aVisited ? mBookmarkVisitBonus : mUnvisitedBookmarkBonus; michael@0: case nsINavHistoryService::TRANSITION_DOWNLOAD: michael@0: return mDownloadVisitBonus; michael@0: case nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT: michael@0: return mPermRedirectVisitBonus; michael@0: case nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY: michael@0: return mTempRedirectVisitBonus; michael@0: default: michael@0: // 0 == undefined (see bug #375777 for details) michael@0: NS_WARN_IF_FALSE(!aTransitionType, "new transition but no bonus for frecency"); michael@0: return mDefaultVisitBonus; michael@0: } michael@0: } michael@0: michael@0: int32_t GetNumVisitsForFrecency() const michael@0: { michael@0: return mNumVisitsForFrecency; michael@0: } michael@0: michael@0: /** michael@0: * Fires onVisit event to nsINavHistoryService observers michael@0: */ michael@0: void NotifyOnVisit(nsIURI* aURI, michael@0: int64_t aVisitID, michael@0: PRTime aTime, michael@0: int64_t referringVisitID, michael@0: int32_t aTransitionType, michael@0: const nsACString& aGUID, michael@0: bool aHidden); michael@0: michael@0: /** michael@0: * Fires onTitleChanged event to nsINavHistoryService observers michael@0: */ michael@0: void NotifyTitleChange(nsIURI* aURI, michael@0: const nsString& title, michael@0: const nsACString& aGUID); michael@0: michael@0: /** michael@0: * Fires onFrecencyChanged event to nsINavHistoryService observers michael@0: */ michael@0: void NotifyFrecencyChanged(nsIURI* aURI, michael@0: int32_t aNewFrecency, michael@0: const nsACString& aGUID, michael@0: bool aHidden, michael@0: PRTime aLastVisitDate); michael@0: michael@0: /** michael@0: * Fires onManyFrecenciesChanged event to nsINavHistoryService observers michael@0: */ michael@0: void NotifyManyFrecenciesChanged(); michael@0: michael@0: /** michael@0: * Posts a runnable to the main thread that calls NotifyFrecencyChanged. michael@0: */ michael@0: void DispatchFrecencyChangedNotification(const nsACString& aSpec, michael@0: int32_t aNewFrecency, michael@0: const nsACString& aGUID, michael@0: bool aHidden, michael@0: PRTime aLastVisitDate) const; michael@0: michael@0: bool isBatching() { michael@0: return mBatchLevel > 0; michael@0: } michael@0: michael@0: private: michael@0: ~nsNavHistory(); michael@0: michael@0: // used by GetHistoryService michael@0: static nsNavHistory *gHistoryService; michael@0: michael@0: protected: michael@0: michael@0: // Database handle. michael@0: nsRefPtr mDB; michael@0: michael@0: /** michael@0: * Decays frecency and inputhistory values. Runs on idle-daily. michael@0: */ michael@0: nsresult DecayFrecency(); michael@0: michael@0: nsresult CalculateFrecency(int64_t aPageID, int32_t aTyped, int32_t aVisitCount, nsAutoCString &aURL, int32_t *aFrecency); michael@0: nsresult CalculateFrecencyInternal(int64_t aPageID, int32_t aTyped, int32_t aVisitCount, bool aIsBookmarked, int32_t *aFrecency); michael@0: michael@0: nsresult RemovePagesInternal(const nsCString& aPlaceIdsQueryString); michael@0: nsresult CleanupPlacesOnVisitsDelete(const nsCString& aPlaceIdsQueryString); michael@0: michael@0: /** michael@0: * Loads all of the preferences that we use into member variables. michael@0: * michael@0: * @note If mPrefBranch is nullptr, this does nothing. michael@0: */ michael@0: void LoadPrefs(); michael@0: michael@0: /** michael@0: * Calculates and returns value for mCachedNow. michael@0: * This is an hack to avoid calling PR_Now() too often, as is the case when michael@0: * we're asked the ageindays of many history entries in a row. A timer is michael@0: * set which will clear our valid flag after a short timeout. michael@0: */ michael@0: PRTime GetNow(); michael@0: PRTime mCachedNow; michael@0: nsCOMPtr mExpireNowTimer; michael@0: /** michael@0: * Called when the cached now value is expired and needs renewal. michael@0: */ michael@0: static void expireNowTimerCallback(nsITimer* aTimer, void* aClosure); michael@0: michael@0: nsresult ConstructQueryString(const nsCOMArray& aQueries, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsCString& queryString, michael@0: bool& aParamsPresent, michael@0: StringHash& aAddParams); michael@0: michael@0: nsresult QueryToSelectClause(nsNavHistoryQuery* aQuery, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: int32_t aQueryIndex, michael@0: nsCString* aClause); michael@0: nsresult BindQueryClauseParameters(mozIStorageBaseStatement* statement, michael@0: int32_t aQueryIndex, michael@0: nsNavHistoryQuery* aQuery, michael@0: nsNavHistoryQueryOptions* aOptions); michael@0: michael@0: nsresult ResultsAsList(mozIStorageStatement* statement, michael@0: nsNavHistoryQueryOptions* aOptions, michael@0: nsCOMArray* aResults); michael@0: michael@0: void TitleForDomain(const nsCString& domain, nsACString& aTitle); michael@0: michael@0: nsresult FilterResultSet(nsNavHistoryQueryResultNode *aParentNode, michael@0: const nsCOMArray& aSet, michael@0: nsCOMArray* aFiltered, michael@0: const nsCOMArray& aQueries, michael@0: nsNavHistoryQueryOptions* aOptions); michael@0: michael@0: // observers michael@0: nsMaybeWeakPtrArray mObservers; michael@0: michael@0: // effective tld service michael@0: nsCOMPtr mTLDService; michael@0: nsCOMPtr mIDNService; michael@0: michael@0: // localization michael@0: nsCOMPtr mBundle; michael@0: nsCOMPtr mDateFormatBundle; michael@0: nsCOMPtr mCollation; michael@0: michael@0: // recent events michael@0: typedef nsDataHashtable RecentEventHash; michael@0: RecentEventHash mRecentTyped; michael@0: RecentEventHash mRecentLink; michael@0: RecentEventHash mRecentBookmark; michael@0: michael@0: // Embed visits tracking. michael@0: class VisitHashKey : public nsURIHashKey michael@0: { michael@0: public: michael@0: VisitHashKey(const nsIURI* aURI) michael@0: : nsURIHashKey(aURI) michael@0: { michael@0: } michael@0: VisitHashKey(const VisitHashKey& aOther) michael@0: : nsURIHashKey(aOther) michael@0: { michael@0: NS_NOTREACHED("Do not call me!"); michael@0: } michael@0: PRTime visitTime; michael@0: }; michael@0: michael@0: nsTHashtable mEmbedVisits; michael@0: michael@0: bool CheckIsRecentEvent(RecentEventHash* hashTable, michael@0: const nsACString& url); michael@0: void ExpireNonrecentEvents(RecentEventHash* hashTable); michael@0: michael@0: #ifdef MOZ_XUL michael@0: nsresult AutoCompleteFeedback(int32_t aIndex, michael@0: nsIAutoCompleteController *aController); michael@0: #endif michael@0: michael@0: // Whether history is enabled or not. michael@0: // Will mimic value of the places.history.enabled preference. michael@0: bool mHistoryEnabled; michael@0: michael@0: // Frecency preferences. michael@0: int32_t mNumVisitsForFrecency; michael@0: int32_t mFirstBucketCutoffInDays; michael@0: int32_t mSecondBucketCutoffInDays; michael@0: int32_t mThirdBucketCutoffInDays; michael@0: int32_t mFourthBucketCutoffInDays; michael@0: int32_t mFirstBucketWeight; michael@0: int32_t mSecondBucketWeight; michael@0: int32_t mThirdBucketWeight; michael@0: int32_t mFourthBucketWeight; michael@0: int32_t mDefaultWeight; michael@0: int32_t mEmbedVisitBonus; michael@0: int32_t mFramedLinkVisitBonus; michael@0: int32_t mLinkVisitBonus; michael@0: int32_t mTypedVisitBonus; michael@0: int32_t mBookmarkVisitBonus; michael@0: int32_t mDownloadVisitBonus; michael@0: int32_t mPermRedirectVisitBonus; michael@0: int32_t mTempRedirectVisitBonus; michael@0: int32_t mDefaultVisitBonus; michael@0: int32_t mUnvisitedBookmarkBonus; michael@0: int32_t mUnvisitedTypedBonus; michael@0: michael@0: // in nsNavHistoryQuery.cpp michael@0: nsresult TokensToQueries(const nsTArray& aTokens, michael@0: nsCOMArray* aQueries, michael@0: nsNavHistoryQueryOptions* aOptions); michael@0: michael@0: int64_t mTagsFolder; michael@0: michael@0: int32_t mDaysOfHistory; michael@0: int64_t mLastCachedStartOfDay; michael@0: int64_t mLastCachedEndOfDay; michael@0: michael@0: // Used to enable and disable the observer notifications michael@0: bool mCanNotify; michael@0: nsCategoryCache mCacheObservers; michael@0: }; michael@0: michael@0: michael@0: #define PLACES_URI_PREFIX "place:" michael@0: michael@0: /* Returns true if the given URI represents a history query. */ michael@0: inline bool IsQueryURI(const nsCString &uri) michael@0: { michael@0: return StringBeginsWith(uri, NS_LITERAL_CSTRING(PLACES_URI_PREFIX)); michael@0: } michael@0: michael@0: /* Extracts the query string from a query URI. */ michael@0: inline const nsDependentCSubstring QueryURIToQuery(const nsCString &uri) michael@0: { michael@0: NS_ASSERTION(IsQueryURI(uri), "should only be called for query URIs"); michael@0: return Substring(uri, NS_LITERAL_CSTRING(PLACES_URI_PREFIX).Length()); michael@0: } michael@0: michael@0: #endif // nsNavHistory_h_