Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef nsNavHistory_h_ |
michael@0 | 7 | #define nsNavHistory_h_ |
michael@0 | 8 | |
michael@0 | 9 | #include "nsINavHistoryService.h" |
michael@0 | 10 | #include "nsPIPlacesDatabase.h" |
michael@0 | 11 | #include "nsPIPlacesHistoryListenersNotifier.h" |
michael@0 | 12 | #include "nsIBrowserHistory.h" |
michael@0 | 13 | #include "nsINavBookmarksService.h" |
michael@0 | 14 | #include "nsIFaviconService.h" |
michael@0 | 15 | |
michael@0 | 16 | #include "nsIObserverService.h" |
michael@0 | 17 | #include "nsICollation.h" |
michael@0 | 18 | #include "nsIStringBundle.h" |
michael@0 | 19 | #include "nsITimer.h" |
michael@0 | 20 | #include "nsMaybeWeakPtr.h" |
michael@0 | 21 | #include "nsCategoryCache.h" |
michael@0 | 22 | #include "nsNetCID.h" |
michael@0 | 23 | #include "nsToolkitCompsCID.h" |
michael@0 | 24 | #include "nsURIHashKey.h" |
michael@0 | 25 | #include "nsTHashtable.h" |
michael@0 | 26 | |
michael@0 | 27 | #include "nsNavHistoryResult.h" |
michael@0 | 28 | #include "nsNavHistoryQuery.h" |
michael@0 | 29 | #include "Database.h" |
michael@0 | 30 | #include "mozilla/Attributes.h" |
michael@0 | 31 | |
michael@0 | 32 | #define QUERYUPDATE_TIME 0 |
michael@0 | 33 | #define QUERYUPDATE_SIMPLE 1 |
michael@0 | 34 | #define QUERYUPDATE_COMPLEX 2 |
michael@0 | 35 | #define QUERYUPDATE_COMPLEX_WITH_BOOKMARKS 3 |
michael@0 | 36 | #define QUERYUPDATE_HOST 4 |
michael@0 | 37 | |
michael@0 | 38 | // Clamp title and URL to generously large, but not too large, length. |
michael@0 | 39 | // See bug 319004 for details. |
michael@0 | 40 | #define URI_LENGTH_MAX 65536 |
michael@0 | 41 | #define TITLE_LENGTH_MAX 4096 |
michael@0 | 42 | |
michael@0 | 43 | // Microsecond timeout for "recent" events such as typed and bookmark following. |
michael@0 | 44 | // If you typed it more than this time ago, it's not recent. |
michael@0 | 45 | #define RECENT_EVENT_THRESHOLD PRTime((int64_t)15 * 60 * PR_USEC_PER_SEC) |
michael@0 | 46 | |
michael@0 | 47 | #ifdef MOZ_XUL |
michael@0 | 48 | // Fired after autocomplete feedback has been updated. |
michael@0 | 49 | #define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated" |
michael@0 | 50 | #endif |
michael@0 | 51 | |
michael@0 | 52 | // Fired after frecency has been updated. |
michael@0 | 53 | #define TOPIC_FRECENCY_UPDATED "places-frecency-updated" |
michael@0 | 54 | |
michael@0 | 55 | class mozIAnnotationService; |
michael@0 | 56 | class nsNavHistory; |
michael@0 | 57 | class QueryKeyValuePair; |
michael@0 | 58 | class nsIEffectiveTLDService; |
michael@0 | 59 | class nsIIDNService; |
michael@0 | 60 | class PlacesSQLQueryBuilder; |
michael@0 | 61 | class nsIAutoCompleteController; |
michael@0 | 62 | |
michael@0 | 63 | // nsNavHistory |
michael@0 | 64 | |
michael@0 | 65 | class nsNavHistory MOZ_FINAL : public nsSupportsWeakReference |
michael@0 | 66 | , public nsINavHistoryService |
michael@0 | 67 | , public nsIObserver |
michael@0 | 68 | , public nsIBrowserHistory |
michael@0 | 69 | , public nsPIPlacesDatabase |
michael@0 | 70 | , public nsPIPlacesHistoryListenersNotifier |
michael@0 | 71 | , public mozIStorageVacuumParticipant |
michael@0 | 72 | { |
michael@0 | 73 | friend class PlacesSQLQueryBuilder; |
michael@0 | 74 | |
michael@0 | 75 | public: |
michael@0 | 76 | nsNavHistory(); |
michael@0 | 77 | |
michael@0 | 78 | NS_DECL_THREADSAFE_ISUPPORTS |
michael@0 | 79 | NS_DECL_NSINAVHISTORYSERVICE |
michael@0 | 80 | NS_DECL_NSIBROWSERHISTORY |
michael@0 | 81 | NS_DECL_NSIOBSERVER |
michael@0 | 82 | NS_DECL_NSPIPLACESDATABASE |
michael@0 | 83 | NS_DECL_NSPIPLACESHISTORYLISTENERSNOTIFIER |
michael@0 | 84 | NS_DECL_MOZISTORAGEVACUUMPARTICIPANT |
michael@0 | 85 | |
michael@0 | 86 | /** |
michael@0 | 87 | * Obtains the nsNavHistory object. |
michael@0 | 88 | */ |
michael@0 | 89 | static already_AddRefed<nsNavHistory> GetSingleton(); |
michael@0 | 90 | |
michael@0 | 91 | /** |
michael@0 | 92 | * Initializes the nsNavHistory object. This should only be called once. |
michael@0 | 93 | */ |
michael@0 | 94 | nsresult Init(); |
michael@0 | 95 | |
michael@0 | 96 | /** |
michael@0 | 97 | * Used by other components in the places directory such as the annotation |
michael@0 | 98 | * service to get a reference to this history object. Returns a pointer to |
michael@0 | 99 | * the service if it exists. Otherwise creates one. Returns nullptr on error. |
michael@0 | 100 | */ |
michael@0 | 101 | static nsNavHistory* GetHistoryService() |
michael@0 | 102 | { |
michael@0 | 103 | if (!gHistoryService) { |
michael@0 | 104 | nsCOMPtr<nsINavHistoryService> serv = |
michael@0 | 105 | do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID); |
michael@0 | 106 | NS_ENSURE_TRUE(serv, nullptr); |
michael@0 | 107 | NS_ASSERTION(gHistoryService, "Should have static instance pointer now"); |
michael@0 | 108 | } |
michael@0 | 109 | return gHistoryService; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | /** |
michael@0 | 113 | * Used by other components in the places directory to get a reference to a |
michael@0 | 114 | * const version of this history object. |
michael@0 | 115 | * |
michael@0 | 116 | * @return A pointer to a const version of the service if it exists, |
michael@0 | 117 | * nullptr otherwise. |
michael@0 | 118 | */ |
michael@0 | 119 | static const nsNavHistory* GetConstHistoryService() |
michael@0 | 120 | { |
michael@0 | 121 | const nsNavHistory* const history = gHistoryService; |
michael@0 | 122 | return history; |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | /** |
michael@0 | 126 | * Fetches the database id and the GUID associated to the given URI. |
michael@0 | 127 | * |
michael@0 | 128 | * @param aURI |
michael@0 | 129 | * The page to look for. |
michael@0 | 130 | * @param _pageId |
michael@0 | 131 | * Will be set to the database id associated with the page. |
michael@0 | 132 | * If the page doesn't exist, this will be zero. |
michael@0 | 133 | * @param _GUID |
michael@0 | 134 | * Will be set to the unique id associated with the page. |
michael@0 | 135 | * If the page doesn't exist, this will be empty. |
michael@0 | 136 | * @note This DOES NOT check for bad URLs other than that they're nonempty. |
michael@0 | 137 | */ |
michael@0 | 138 | nsresult GetIdForPage(nsIURI* aURI, |
michael@0 | 139 | int64_t* _pageId, nsCString& _GUID); |
michael@0 | 140 | |
michael@0 | 141 | /** |
michael@0 | 142 | * Fetches the database id and the GUID associated to the given URI, creating |
michael@0 | 143 | * a new database entry if one doesn't exist yet. |
michael@0 | 144 | * |
michael@0 | 145 | * @param aURI |
michael@0 | 146 | * The page to look for or create. |
michael@0 | 147 | * @param _pageId |
michael@0 | 148 | * Will be set to the database id associated with the page. |
michael@0 | 149 | * @param _GUID |
michael@0 | 150 | * Will be set to the unique id associated with the page. |
michael@0 | 151 | * @note This DOES NOT check for bad URLs other than that they're nonempty. |
michael@0 | 152 | * @note This DOES NOT update frecency of the page. |
michael@0 | 153 | */ |
michael@0 | 154 | nsresult GetOrCreateIdForPage(nsIURI* aURI, |
michael@0 | 155 | int64_t* _pageId, nsCString& _GUID); |
michael@0 | 156 | |
michael@0 | 157 | /** |
michael@0 | 158 | * Asynchronously recalculates frecency for a given page. |
michael@0 | 159 | * |
michael@0 | 160 | * @param aPlaceId |
michael@0 | 161 | * Place id to recalculate the frecency for. |
michael@0 | 162 | * @note If the new frecency is a non-zero value it will also unhide the page, |
michael@0 | 163 | * otherwise will reuse the old hidden value. |
michael@0 | 164 | */ |
michael@0 | 165 | nsresult UpdateFrecency(int64_t aPlaceId); |
michael@0 | 166 | |
michael@0 | 167 | /** |
michael@0 | 168 | * Recalculates frecency for all pages requesting that (frecency < 0). Those |
michael@0 | 169 | * may be generated: |
michael@0 | 170 | * * After a "clear private data" |
michael@0 | 171 | * * After removing visits |
michael@0 | 172 | * * After migrating from older versions |
michael@0 | 173 | */ |
michael@0 | 174 | nsresult FixInvalidFrecencies(); |
michael@0 | 175 | |
michael@0 | 176 | /** |
michael@0 | 177 | * Invalidate the frecencies of a list of places, so they will be recalculated |
michael@0 | 178 | * at the first idle-daily notification. |
michael@0 | 179 | * |
michael@0 | 180 | * @param aPlacesIdsQueryString |
michael@0 | 181 | * Query string containing list of places to be invalidated. If it's |
michael@0 | 182 | * an empty string all places will be invalidated. |
michael@0 | 183 | */ |
michael@0 | 184 | nsresult invalidateFrecencies(const nsCString& aPlaceIdsQueryString); |
michael@0 | 185 | |
michael@0 | 186 | /** |
michael@0 | 187 | * These functions return non-owning references to the locale-specific |
michael@0 | 188 | * objects for places components. |
michael@0 | 189 | */ |
michael@0 | 190 | nsIStringBundle* GetBundle(); |
michael@0 | 191 | nsIStringBundle* GetDateFormatBundle(); |
michael@0 | 192 | nsICollation* GetCollation(); |
michael@0 | 193 | void GetStringFromName(const char16_t* aName, nsACString& aResult); |
michael@0 | 194 | void GetAgeInDaysString(int32_t aInt, const char16_t *aName, |
michael@0 | 195 | nsACString& aResult); |
michael@0 | 196 | void GetMonthName(int32_t aIndex, nsACString& aResult); |
michael@0 | 197 | void GetMonthYear(int32_t aMonth, int32_t aYear, nsACString& aResult); |
michael@0 | 198 | |
michael@0 | 199 | // Returns whether history is enabled or not. |
michael@0 | 200 | bool IsHistoryDisabled() { |
michael@0 | 201 | return !mHistoryEnabled; |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | // Constants for the columns returned by the above statement. |
michael@0 | 205 | static const int32_t kGetInfoIndex_PageID; |
michael@0 | 206 | static const int32_t kGetInfoIndex_URL; |
michael@0 | 207 | static const int32_t kGetInfoIndex_Title; |
michael@0 | 208 | static const int32_t kGetInfoIndex_RevHost; |
michael@0 | 209 | static const int32_t kGetInfoIndex_VisitCount; |
michael@0 | 210 | static const int32_t kGetInfoIndex_VisitDate; |
michael@0 | 211 | static const int32_t kGetInfoIndex_FaviconURL; |
michael@0 | 212 | static const int32_t kGetInfoIndex_ItemId; |
michael@0 | 213 | static const int32_t kGetInfoIndex_ItemDateAdded; |
michael@0 | 214 | static const int32_t kGetInfoIndex_ItemLastModified; |
michael@0 | 215 | static const int32_t kGetInfoIndex_ItemParentId; |
michael@0 | 216 | static const int32_t kGetInfoIndex_ItemTags; |
michael@0 | 217 | static const int32_t kGetInfoIndex_Frecency; |
michael@0 | 218 | static const int32_t kGetInfoIndex_Hidden; |
michael@0 | 219 | static const int32_t kGetInfoIndex_Guid; |
michael@0 | 220 | |
michael@0 | 221 | int64_t GetTagsFolder(); |
michael@0 | 222 | |
michael@0 | 223 | // this actually executes a query and gives you results, it is used by |
michael@0 | 224 | // nsNavHistoryQueryResultNode |
michael@0 | 225 | nsresult GetQueryResults(nsNavHistoryQueryResultNode *aResultNode, |
michael@0 | 226 | const nsCOMArray<nsNavHistoryQuery>& aQueries, |
michael@0 | 227 | nsNavHistoryQueryOptions *aOptions, |
michael@0 | 228 | nsCOMArray<nsNavHistoryResultNode>* aResults); |
michael@0 | 229 | |
michael@0 | 230 | // Take a row of kGetInfoIndex_* columns and construct a ResultNode. |
michael@0 | 231 | // The row must contain the full set of columns. |
michael@0 | 232 | nsresult RowToResult(mozIStorageValueArray* aRow, |
michael@0 | 233 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 234 | nsNavHistoryResultNode** aResult); |
michael@0 | 235 | nsresult QueryRowToResult(int64_t aItemId, const nsACString& aURI, |
michael@0 | 236 | const nsACString& aTitle, |
michael@0 | 237 | uint32_t aAccessCount, PRTime aTime, |
michael@0 | 238 | const nsACString& aFavicon, |
michael@0 | 239 | nsNavHistoryResultNode** aNode); |
michael@0 | 240 | |
michael@0 | 241 | nsresult VisitIdToResultNode(int64_t visitId, |
michael@0 | 242 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 243 | nsNavHistoryResultNode** aResult); |
michael@0 | 244 | |
michael@0 | 245 | nsresult BookmarkIdToResultNode(int64_t aBookmarkId, |
michael@0 | 246 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 247 | nsNavHistoryResultNode** aResult); |
michael@0 | 248 | nsresult URIToResultNode(nsIURI* aURI, |
michael@0 | 249 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 250 | nsNavHistoryResultNode** aResult); |
michael@0 | 251 | |
michael@0 | 252 | // used by other places components to send history notifications (for example, |
michael@0 | 253 | // when the favicon has changed) |
michael@0 | 254 | void SendPageChangedNotification(nsIURI* aURI, uint32_t aChangedAttribute, |
michael@0 | 255 | const nsAString& aValue, |
michael@0 | 256 | const nsACString& aGUID); |
michael@0 | 257 | |
michael@0 | 258 | /** |
michael@0 | 259 | * Returns current number of days stored in history. |
michael@0 | 260 | */ |
michael@0 | 261 | int32_t GetDaysOfHistory(); |
michael@0 | 262 | |
michael@0 | 263 | // used by query result nodes to update: see comment on body of CanLiveUpdateQuery |
michael@0 | 264 | static uint32_t GetUpdateRequirements(const nsCOMArray<nsNavHistoryQuery>& aQueries, |
michael@0 | 265 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 266 | bool* aHasSearchTerms); |
michael@0 | 267 | bool EvaluateQueryForNode(const nsCOMArray<nsNavHistoryQuery>& aQueries, |
michael@0 | 268 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 269 | nsNavHistoryResultNode* aNode); |
michael@0 | 270 | |
michael@0 | 271 | static nsresult AsciiHostNameFromHostString(const nsACString& aHostName, |
michael@0 | 272 | nsACString& aAscii); |
michael@0 | 273 | void DomainNameFromURI(nsIURI* aURI, |
michael@0 | 274 | nsACString& aDomainName); |
michael@0 | 275 | static PRTime NormalizeTime(uint32_t aRelative, PRTime aOffset); |
michael@0 | 276 | |
michael@0 | 277 | // Don't use these directly, inside nsNavHistory use UpdateBatchScoper, |
michael@0 | 278 | // else use nsINavHistoryService::RunInBatchMode |
michael@0 | 279 | nsresult BeginUpdateBatch(); |
michael@0 | 280 | nsresult EndUpdateBatch(); |
michael@0 | 281 | |
michael@0 | 282 | // The level of batches' nesting, 0 when no batches are open. |
michael@0 | 283 | int32_t mBatchLevel; |
michael@0 | 284 | // Current active transaction for a batch. |
michael@0 | 285 | mozStorageTransaction* mBatchDBTransaction; |
michael@0 | 286 | |
michael@0 | 287 | // better alternative to QueryStringToQueries (in nsNavHistoryQuery.cpp) |
michael@0 | 288 | nsresult QueryStringToQueryArray(const nsACString& aQueryString, |
michael@0 | 289 | nsCOMArray<nsNavHistoryQuery>* aQueries, |
michael@0 | 290 | nsNavHistoryQueryOptions** aOptions); |
michael@0 | 291 | |
michael@0 | 292 | typedef nsDataHashtable<nsCStringHashKey, nsCString> StringHash; |
michael@0 | 293 | |
michael@0 | 294 | /** |
michael@0 | 295 | * Indicates if it is OK to notify history observers or not. |
michael@0 | 296 | * |
michael@0 | 297 | * @return true if it is OK to notify, false otherwise. |
michael@0 | 298 | */ |
michael@0 | 299 | bool canNotify() { return mCanNotify; } |
michael@0 | 300 | |
michael@0 | 301 | enum RecentEventFlags { |
michael@0 | 302 | RECENT_TYPED = 1 << 0, // User typed in URL recently |
michael@0 | 303 | RECENT_ACTIVATED = 1 << 1, // User tapped URL link recently |
michael@0 | 304 | RECENT_BOOKMARKED = 1 << 2 // User bookmarked URL recently |
michael@0 | 305 | }; |
michael@0 | 306 | |
michael@0 | 307 | /** |
michael@0 | 308 | * Returns any recent activity done with a URL. |
michael@0 | 309 | * @return Any recent events associated with this URI. Each bit is set |
michael@0 | 310 | * according to RecentEventFlags enum values. |
michael@0 | 311 | */ |
michael@0 | 312 | uint32_t GetRecentFlags(nsIURI *aURI); |
michael@0 | 313 | |
michael@0 | 314 | /** |
michael@0 | 315 | * Registers a TRANSITION_EMBED visit for the session. |
michael@0 | 316 | * |
michael@0 | 317 | * @param aURI |
michael@0 | 318 | * URI of the page. |
michael@0 | 319 | * @param aTime |
michael@0 | 320 | * Visit time. Only the last registered visit time is retained. |
michael@0 | 321 | */ |
michael@0 | 322 | void registerEmbedVisit(nsIURI* aURI, int64_t aTime); |
michael@0 | 323 | |
michael@0 | 324 | /** |
michael@0 | 325 | * Returns whether the specified url has a embed visit. |
michael@0 | 326 | * |
michael@0 | 327 | * @param aURI |
michael@0 | 328 | * URI of the page. |
michael@0 | 329 | * @return whether the page has a embed visit. |
michael@0 | 330 | */ |
michael@0 | 331 | bool hasEmbedVisit(nsIURI* aURI); |
michael@0 | 332 | |
michael@0 | 333 | /** |
michael@0 | 334 | * Clears all registered embed visits. |
michael@0 | 335 | */ |
michael@0 | 336 | void clearEmbedVisits(); |
michael@0 | 337 | |
michael@0 | 338 | int32_t GetFrecencyAgedWeight(int32_t aAgeInDays) const |
michael@0 | 339 | { |
michael@0 | 340 | if (aAgeInDays <= mFirstBucketCutoffInDays) { |
michael@0 | 341 | return mFirstBucketWeight; |
michael@0 | 342 | } |
michael@0 | 343 | if (aAgeInDays <= mSecondBucketCutoffInDays) { |
michael@0 | 344 | return mSecondBucketWeight; |
michael@0 | 345 | } |
michael@0 | 346 | if (aAgeInDays <= mThirdBucketCutoffInDays) { |
michael@0 | 347 | return mThirdBucketWeight; |
michael@0 | 348 | } |
michael@0 | 349 | if (aAgeInDays <= mFourthBucketCutoffInDays) { |
michael@0 | 350 | return mFourthBucketWeight; |
michael@0 | 351 | } |
michael@0 | 352 | return mDefaultWeight; |
michael@0 | 353 | } |
michael@0 | 354 | |
michael@0 | 355 | int32_t GetFrecencyBucketWeight(int32_t aBucketIndex) const |
michael@0 | 356 | { |
michael@0 | 357 | switch(aBucketIndex) { |
michael@0 | 358 | case 1: |
michael@0 | 359 | return mFirstBucketWeight; |
michael@0 | 360 | case 2: |
michael@0 | 361 | return mSecondBucketWeight; |
michael@0 | 362 | case 3: |
michael@0 | 363 | return mThirdBucketWeight; |
michael@0 | 364 | case 4: |
michael@0 | 365 | return mFourthBucketWeight; |
michael@0 | 366 | default: |
michael@0 | 367 | return mDefaultWeight; |
michael@0 | 368 | } |
michael@0 | 369 | } |
michael@0 | 370 | |
michael@0 | 371 | int32_t GetFrecencyTransitionBonus(int32_t aTransitionType, |
michael@0 | 372 | bool aVisited) const |
michael@0 | 373 | { |
michael@0 | 374 | switch (aTransitionType) { |
michael@0 | 375 | case nsINavHistoryService::TRANSITION_EMBED: |
michael@0 | 376 | return mEmbedVisitBonus; |
michael@0 | 377 | case nsINavHistoryService::TRANSITION_FRAMED_LINK: |
michael@0 | 378 | return mFramedLinkVisitBonus; |
michael@0 | 379 | case nsINavHistoryService::TRANSITION_LINK: |
michael@0 | 380 | return mLinkVisitBonus; |
michael@0 | 381 | case nsINavHistoryService::TRANSITION_TYPED: |
michael@0 | 382 | return aVisited ? mTypedVisitBonus : mUnvisitedTypedBonus; |
michael@0 | 383 | case nsINavHistoryService::TRANSITION_BOOKMARK: |
michael@0 | 384 | return aVisited ? mBookmarkVisitBonus : mUnvisitedBookmarkBonus; |
michael@0 | 385 | case nsINavHistoryService::TRANSITION_DOWNLOAD: |
michael@0 | 386 | return mDownloadVisitBonus; |
michael@0 | 387 | case nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT: |
michael@0 | 388 | return mPermRedirectVisitBonus; |
michael@0 | 389 | case nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY: |
michael@0 | 390 | return mTempRedirectVisitBonus; |
michael@0 | 391 | default: |
michael@0 | 392 | // 0 == undefined (see bug #375777 for details) |
michael@0 | 393 | NS_WARN_IF_FALSE(!aTransitionType, "new transition but no bonus for frecency"); |
michael@0 | 394 | return mDefaultVisitBonus; |
michael@0 | 395 | } |
michael@0 | 396 | } |
michael@0 | 397 | |
michael@0 | 398 | int32_t GetNumVisitsForFrecency() const |
michael@0 | 399 | { |
michael@0 | 400 | return mNumVisitsForFrecency; |
michael@0 | 401 | } |
michael@0 | 402 | |
michael@0 | 403 | /** |
michael@0 | 404 | * Fires onVisit event to nsINavHistoryService observers |
michael@0 | 405 | */ |
michael@0 | 406 | void NotifyOnVisit(nsIURI* aURI, |
michael@0 | 407 | int64_t aVisitID, |
michael@0 | 408 | PRTime aTime, |
michael@0 | 409 | int64_t referringVisitID, |
michael@0 | 410 | int32_t aTransitionType, |
michael@0 | 411 | const nsACString& aGUID, |
michael@0 | 412 | bool aHidden); |
michael@0 | 413 | |
michael@0 | 414 | /** |
michael@0 | 415 | * Fires onTitleChanged event to nsINavHistoryService observers |
michael@0 | 416 | */ |
michael@0 | 417 | void NotifyTitleChange(nsIURI* aURI, |
michael@0 | 418 | const nsString& title, |
michael@0 | 419 | const nsACString& aGUID); |
michael@0 | 420 | |
michael@0 | 421 | /** |
michael@0 | 422 | * Fires onFrecencyChanged event to nsINavHistoryService observers |
michael@0 | 423 | */ |
michael@0 | 424 | void NotifyFrecencyChanged(nsIURI* aURI, |
michael@0 | 425 | int32_t aNewFrecency, |
michael@0 | 426 | const nsACString& aGUID, |
michael@0 | 427 | bool aHidden, |
michael@0 | 428 | PRTime aLastVisitDate); |
michael@0 | 429 | |
michael@0 | 430 | /** |
michael@0 | 431 | * Fires onManyFrecenciesChanged event to nsINavHistoryService observers |
michael@0 | 432 | */ |
michael@0 | 433 | void NotifyManyFrecenciesChanged(); |
michael@0 | 434 | |
michael@0 | 435 | /** |
michael@0 | 436 | * Posts a runnable to the main thread that calls NotifyFrecencyChanged. |
michael@0 | 437 | */ |
michael@0 | 438 | void DispatchFrecencyChangedNotification(const nsACString& aSpec, |
michael@0 | 439 | int32_t aNewFrecency, |
michael@0 | 440 | const nsACString& aGUID, |
michael@0 | 441 | bool aHidden, |
michael@0 | 442 | PRTime aLastVisitDate) const; |
michael@0 | 443 | |
michael@0 | 444 | bool isBatching() { |
michael@0 | 445 | return mBatchLevel > 0; |
michael@0 | 446 | } |
michael@0 | 447 | |
michael@0 | 448 | private: |
michael@0 | 449 | ~nsNavHistory(); |
michael@0 | 450 | |
michael@0 | 451 | // used by GetHistoryService |
michael@0 | 452 | static nsNavHistory *gHistoryService; |
michael@0 | 453 | |
michael@0 | 454 | protected: |
michael@0 | 455 | |
michael@0 | 456 | // Database handle. |
michael@0 | 457 | nsRefPtr<mozilla::places::Database> mDB; |
michael@0 | 458 | |
michael@0 | 459 | /** |
michael@0 | 460 | * Decays frecency and inputhistory values. Runs on idle-daily. |
michael@0 | 461 | */ |
michael@0 | 462 | nsresult DecayFrecency(); |
michael@0 | 463 | |
michael@0 | 464 | nsresult CalculateFrecency(int64_t aPageID, int32_t aTyped, int32_t aVisitCount, nsAutoCString &aURL, int32_t *aFrecency); |
michael@0 | 465 | nsresult CalculateFrecencyInternal(int64_t aPageID, int32_t aTyped, int32_t aVisitCount, bool aIsBookmarked, int32_t *aFrecency); |
michael@0 | 466 | |
michael@0 | 467 | nsresult RemovePagesInternal(const nsCString& aPlaceIdsQueryString); |
michael@0 | 468 | nsresult CleanupPlacesOnVisitsDelete(const nsCString& aPlaceIdsQueryString); |
michael@0 | 469 | |
michael@0 | 470 | /** |
michael@0 | 471 | * Loads all of the preferences that we use into member variables. |
michael@0 | 472 | * |
michael@0 | 473 | * @note If mPrefBranch is nullptr, this does nothing. |
michael@0 | 474 | */ |
michael@0 | 475 | void LoadPrefs(); |
michael@0 | 476 | |
michael@0 | 477 | /** |
michael@0 | 478 | * Calculates and returns value for mCachedNow. |
michael@0 | 479 | * This is an hack to avoid calling PR_Now() too often, as is the case when |
michael@0 | 480 | * we're asked the ageindays of many history entries in a row. A timer is |
michael@0 | 481 | * set which will clear our valid flag after a short timeout. |
michael@0 | 482 | */ |
michael@0 | 483 | PRTime GetNow(); |
michael@0 | 484 | PRTime mCachedNow; |
michael@0 | 485 | nsCOMPtr<nsITimer> mExpireNowTimer; |
michael@0 | 486 | /** |
michael@0 | 487 | * Called when the cached now value is expired and needs renewal. |
michael@0 | 488 | */ |
michael@0 | 489 | static void expireNowTimerCallback(nsITimer* aTimer, void* aClosure); |
michael@0 | 490 | |
michael@0 | 491 | nsresult ConstructQueryString(const nsCOMArray<nsNavHistoryQuery>& aQueries, |
michael@0 | 492 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 493 | nsCString& queryString, |
michael@0 | 494 | bool& aParamsPresent, |
michael@0 | 495 | StringHash& aAddParams); |
michael@0 | 496 | |
michael@0 | 497 | nsresult QueryToSelectClause(nsNavHistoryQuery* aQuery, |
michael@0 | 498 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 499 | int32_t aQueryIndex, |
michael@0 | 500 | nsCString* aClause); |
michael@0 | 501 | nsresult BindQueryClauseParameters(mozIStorageBaseStatement* statement, |
michael@0 | 502 | int32_t aQueryIndex, |
michael@0 | 503 | nsNavHistoryQuery* aQuery, |
michael@0 | 504 | nsNavHistoryQueryOptions* aOptions); |
michael@0 | 505 | |
michael@0 | 506 | nsresult ResultsAsList(mozIStorageStatement* statement, |
michael@0 | 507 | nsNavHistoryQueryOptions* aOptions, |
michael@0 | 508 | nsCOMArray<nsNavHistoryResultNode>* aResults); |
michael@0 | 509 | |
michael@0 | 510 | void TitleForDomain(const nsCString& domain, nsACString& aTitle); |
michael@0 | 511 | |
michael@0 | 512 | nsresult FilterResultSet(nsNavHistoryQueryResultNode *aParentNode, |
michael@0 | 513 | const nsCOMArray<nsNavHistoryResultNode>& aSet, |
michael@0 | 514 | nsCOMArray<nsNavHistoryResultNode>* aFiltered, |
michael@0 | 515 | const nsCOMArray<nsNavHistoryQuery>& aQueries, |
michael@0 | 516 | nsNavHistoryQueryOptions* aOptions); |
michael@0 | 517 | |
michael@0 | 518 | // observers |
michael@0 | 519 | nsMaybeWeakPtrArray<nsINavHistoryObserver> mObservers; |
michael@0 | 520 | |
michael@0 | 521 | // effective tld service |
michael@0 | 522 | nsCOMPtr<nsIEffectiveTLDService> mTLDService; |
michael@0 | 523 | nsCOMPtr<nsIIDNService> mIDNService; |
michael@0 | 524 | |
michael@0 | 525 | // localization |
michael@0 | 526 | nsCOMPtr<nsIStringBundle> mBundle; |
michael@0 | 527 | nsCOMPtr<nsIStringBundle> mDateFormatBundle; |
michael@0 | 528 | nsCOMPtr<nsICollation> mCollation; |
michael@0 | 529 | |
michael@0 | 530 | // recent events |
michael@0 | 531 | typedef nsDataHashtable<nsCStringHashKey, int64_t> RecentEventHash; |
michael@0 | 532 | RecentEventHash mRecentTyped; |
michael@0 | 533 | RecentEventHash mRecentLink; |
michael@0 | 534 | RecentEventHash mRecentBookmark; |
michael@0 | 535 | |
michael@0 | 536 | // Embed visits tracking. |
michael@0 | 537 | class VisitHashKey : public nsURIHashKey |
michael@0 | 538 | { |
michael@0 | 539 | public: |
michael@0 | 540 | VisitHashKey(const nsIURI* aURI) |
michael@0 | 541 | : nsURIHashKey(aURI) |
michael@0 | 542 | { |
michael@0 | 543 | } |
michael@0 | 544 | VisitHashKey(const VisitHashKey& aOther) |
michael@0 | 545 | : nsURIHashKey(aOther) |
michael@0 | 546 | { |
michael@0 | 547 | NS_NOTREACHED("Do not call me!"); |
michael@0 | 548 | } |
michael@0 | 549 | PRTime visitTime; |
michael@0 | 550 | }; |
michael@0 | 551 | |
michael@0 | 552 | nsTHashtable<VisitHashKey> mEmbedVisits; |
michael@0 | 553 | |
michael@0 | 554 | bool CheckIsRecentEvent(RecentEventHash* hashTable, |
michael@0 | 555 | const nsACString& url); |
michael@0 | 556 | void ExpireNonrecentEvents(RecentEventHash* hashTable); |
michael@0 | 557 | |
michael@0 | 558 | #ifdef MOZ_XUL |
michael@0 | 559 | nsresult AutoCompleteFeedback(int32_t aIndex, |
michael@0 | 560 | nsIAutoCompleteController *aController); |
michael@0 | 561 | #endif |
michael@0 | 562 | |
michael@0 | 563 | // Whether history is enabled or not. |
michael@0 | 564 | // Will mimic value of the places.history.enabled preference. |
michael@0 | 565 | bool mHistoryEnabled; |
michael@0 | 566 | |
michael@0 | 567 | // Frecency preferences. |
michael@0 | 568 | int32_t mNumVisitsForFrecency; |
michael@0 | 569 | int32_t mFirstBucketCutoffInDays; |
michael@0 | 570 | int32_t mSecondBucketCutoffInDays; |
michael@0 | 571 | int32_t mThirdBucketCutoffInDays; |
michael@0 | 572 | int32_t mFourthBucketCutoffInDays; |
michael@0 | 573 | int32_t mFirstBucketWeight; |
michael@0 | 574 | int32_t mSecondBucketWeight; |
michael@0 | 575 | int32_t mThirdBucketWeight; |
michael@0 | 576 | int32_t mFourthBucketWeight; |
michael@0 | 577 | int32_t mDefaultWeight; |
michael@0 | 578 | int32_t mEmbedVisitBonus; |
michael@0 | 579 | int32_t mFramedLinkVisitBonus; |
michael@0 | 580 | int32_t mLinkVisitBonus; |
michael@0 | 581 | int32_t mTypedVisitBonus; |
michael@0 | 582 | int32_t mBookmarkVisitBonus; |
michael@0 | 583 | int32_t mDownloadVisitBonus; |
michael@0 | 584 | int32_t mPermRedirectVisitBonus; |
michael@0 | 585 | int32_t mTempRedirectVisitBonus; |
michael@0 | 586 | int32_t mDefaultVisitBonus; |
michael@0 | 587 | int32_t mUnvisitedBookmarkBonus; |
michael@0 | 588 | int32_t mUnvisitedTypedBonus; |
michael@0 | 589 | |
michael@0 | 590 | // in nsNavHistoryQuery.cpp |
michael@0 | 591 | nsresult TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens, |
michael@0 | 592 | nsCOMArray<nsNavHistoryQuery>* aQueries, |
michael@0 | 593 | nsNavHistoryQueryOptions* aOptions); |
michael@0 | 594 | |
michael@0 | 595 | int64_t mTagsFolder; |
michael@0 | 596 | |
michael@0 | 597 | int32_t mDaysOfHistory; |
michael@0 | 598 | int64_t mLastCachedStartOfDay; |
michael@0 | 599 | int64_t mLastCachedEndOfDay; |
michael@0 | 600 | |
michael@0 | 601 | // Used to enable and disable the observer notifications |
michael@0 | 602 | bool mCanNotify; |
michael@0 | 603 | nsCategoryCache<nsINavHistoryObserver> mCacheObservers; |
michael@0 | 604 | }; |
michael@0 | 605 | |
michael@0 | 606 | |
michael@0 | 607 | #define PLACES_URI_PREFIX "place:" |
michael@0 | 608 | |
michael@0 | 609 | /* Returns true if the given URI represents a history query. */ |
michael@0 | 610 | inline bool IsQueryURI(const nsCString &uri) |
michael@0 | 611 | { |
michael@0 | 612 | return StringBeginsWith(uri, NS_LITERAL_CSTRING(PLACES_URI_PREFIX)); |
michael@0 | 613 | } |
michael@0 | 614 | |
michael@0 | 615 | /* Extracts the query string from a query URI. */ |
michael@0 | 616 | inline const nsDependentCSubstring QueryURIToQuery(const nsCString &uri) |
michael@0 | 617 | { |
michael@0 | 618 | NS_ASSERTION(IsQueryURI(uri), "should only be called for query URIs"); |
michael@0 | 619 | return Substring(uri, NS_LITERAL_CSTRING(PLACES_URI_PREFIX).Length()); |
michael@0 | 620 | } |
michael@0 | 621 | |
michael@0 | 622 | #endif // nsNavHistory_h_ |