зеркало из https://github.com/mozilla/gecko-dev.git
Bug 911307 - Reflect changes to top sites immediately in about:newtab (part 1, Places patch). r=mak
This commit is contained in:
Родитель
d5f21696c4
Коммит
fabe6973a8
|
@ -2338,6 +2338,22 @@ nsDownloadManager::OnTitleChanged(nsIURI *aURI,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDownloadManager::OnFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDownloadManager::OnManyFrecenciesChanged()
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDownloadManager::OnDeleteURI(nsIURI *aURI,
|
nsDownloadManager::OnDeleteURI(nsIURI *aURI,
|
||||||
const nsACString& aGUID,
|
const nsACString& aGUID,
|
||||||
|
|
|
@ -941,6 +941,8 @@ Database::InitFunctions()
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = FixupURLFunction::create(mMainConn);
|
rv = FixupURLFunction::create(mMainConn);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = FrecencyNotificationFunction::create(mMainConn);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1185,7 +1185,10 @@ private:
|
||||||
if (aPlace.placeId) {
|
if (aPlace.placeId) {
|
||||||
stmt = mHistory->GetStatement(
|
stmt = mHistory->GetStatement(
|
||||||
"UPDATE moz_places "
|
"UPDATE moz_places "
|
||||||
"SET frecency = CALCULATE_FRECENCY(:page_id) "
|
"SET frecency = NOTIFY_FRECENCY("
|
||||||
|
"CALCULATE_FRECENCY(:page_id), "
|
||||||
|
"url, guid, hidden, last_visit_date"
|
||||||
|
") "
|
||||||
"WHERE id = :page_id"
|
"WHERE id = :page_id"
|
||||||
);
|
);
|
||||||
NS_ENSURE_STATE(stmt);
|
NS_ENSURE_STATE(stmt);
|
||||||
|
@ -1195,7 +1198,9 @@ private:
|
||||||
else {
|
else {
|
||||||
stmt = mHistory->GetStatement(
|
stmt = mHistory->GetStatement(
|
||||||
"UPDATE moz_places "
|
"UPDATE moz_places "
|
||||||
"SET frecency = CALCULATE_FRECENCY(id) "
|
"SET frecency = NOTIFY_FRECENCY("
|
||||||
|
"CALCULATE_FRECENCY(id), url, guid, hidden, last_visit_date"
|
||||||
|
") "
|
||||||
"WHERE url = :page_url"
|
"WHERE url = :page_url"
|
||||||
);
|
);
|
||||||
NS_ENSURE_STATE(stmt);
|
NS_ENSURE_STATE(stmt);
|
||||||
|
@ -2037,13 +2042,14 @@ History::InsertPlace(const VisitData& aPlace)
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("url"), aPlace.spec);
|
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("url"), aPlace.spec);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsString title = aPlace.title;
|
||||||
// Empty strings should have no title, just like nsNavHistory::SetPageTitle.
|
// Empty strings should have no title, just like nsNavHistory::SetPageTitle.
|
||||||
if (aPlace.title.IsEmpty()) {
|
if (title.IsEmpty()) {
|
||||||
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("title"));
|
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("title"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("title"),
|
title.Assign(StringHead(aPlace.title, TITLE_LENGTH_MAX));
|
||||||
StringHead(aPlace.title, TITLE_LENGTH_MAX));
|
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("title"), title);
|
||||||
}
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("typed"), aPlace.typed);
|
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("typed"), aPlace.typed);
|
||||||
|
@ -2065,6 +2071,13 @@ History::InsertPlace(const VisitData& aPlace)
|
||||||
rv = stmt->Execute();
|
rv = stmt->Execute();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Post an onFrecencyChanged observer notification.
|
||||||
|
const nsNavHistory* navHistory = nsNavHistory::GetConstHistoryService();
|
||||||
|
NS_ENSURE_STATE(navHistory);
|
||||||
|
navHistory->DispatchFrecencyChangedNotification(aPlace.spec, frecency, guid,
|
||||||
|
aPlace.hidden,
|
||||||
|
aPlace.visitTime);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -749,5 +749,63 @@ namespace places {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Frecency Changed Notification Function
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
nsresult
|
||||||
|
FrecencyNotificationFunction::create(mozIStorageConnection *aDBConn)
|
||||||
|
{
|
||||||
|
nsRefPtr<FrecencyNotificationFunction> function =
|
||||||
|
new FrecencyNotificationFunction();
|
||||||
|
nsresult rv = aDBConn->CreateFunction(
|
||||||
|
NS_LITERAL_CSTRING("notify_frecency"), 5, function
|
||||||
|
);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(
|
||||||
|
FrecencyNotificationFunction,
|
||||||
|
mozIStorageFunction
|
||||||
|
)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
FrecencyNotificationFunction::OnFunctionCall(mozIStorageValueArray *aArgs,
|
||||||
|
nsIVariant **_result)
|
||||||
|
{
|
||||||
|
uint32_t numArgs;
|
||||||
|
nsresult rv = aArgs->GetNumEntries(&numArgs);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
MOZ_ASSERT(numArgs == 5);
|
||||||
|
|
||||||
|
int32_t newFrecency = aArgs->AsInt32(0);
|
||||||
|
|
||||||
|
nsAutoCString spec;
|
||||||
|
rv = aArgs->GetUTF8String(1, spec);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsAutoCString guid;
|
||||||
|
rv = aArgs->GetUTF8String(2, guid);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
bool hidden = static_cast<bool>(aArgs->AsInt32(3));
|
||||||
|
PRTime lastVisitDate = static_cast<PRTime>(aArgs->AsInt64(4));
|
||||||
|
|
||||||
|
const nsNavHistory* navHistory = nsNavHistory::GetConstHistoryService();
|
||||||
|
NS_ENSURE_STATE(navHistory);
|
||||||
|
navHistory->DispatchFrecencyChangedNotification(spec, newFrecency, guid,
|
||||||
|
hidden, lastVisitDate);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWritableVariant> result =
|
||||||
|
do_CreateInstance("@mozilla.org/variant;1");
|
||||||
|
NS_ENSURE_STATE(result);
|
||||||
|
rv = result->SetAsInt32(newFrecency);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
NS_ADDREF(*_result = result);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace places
|
} // namespace places
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -280,6 +280,43 @@ public:
|
||||||
static nsresult create(mozIStorageConnection *aDBConn);
|
static nsresult create(mozIStorageConnection *aDBConn);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Frecency Changed Notification Function
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given place, posts a runnable to the main thread that calls
|
||||||
|
* onFrecencyChanged on nsNavHistory's nsINavHistoryObservers. The passed-in
|
||||||
|
* newFrecency value is returned unchanged.
|
||||||
|
*
|
||||||
|
* @param newFrecency
|
||||||
|
* The place's new frecency.
|
||||||
|
* @param url
|
||||||
|
* The place's URL.
|
||||||
|
* @param guid
|
||||||
|
* The place's GUID.
|
||||||
|
* @param hidden
|
||||||
|
* The place's hidden boolean.
|
||||||
|
* @param lastVisitDate
|
||||||
|
* The place's last visit date.
|
||||||
|
* @return newFrecency
|
||||||
|
*/
|
||||||
|
class FrecencyNotificationFunction MOZ_FINAL : public mozIStorageFunction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
NS_DECL_MOZISTORAGEFUNCTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the function with the specified database connection.
|
||||||
|
*
|
||||||
|
* @param aDBConn
|
||||||
|
* The database connection to register with.
|
||||||
|
*/
|
||||||
|
static nsresult create(mozIStorageConnection *aDBConn);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace places
|
} // namespace places
|
||||||
} // namespace storage
|
} // namespace storage
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,7 @@ interface nsINavHistoryResult : nsISupports
|
||||||
* DANGER! If you are in the middle of a batch transaction, there may be a
|
* DANGER! If you are in the middle of a batch transaction, there may be a
|
||||||
* database transaction active. You can still access the DB, but be careful.
|
* database transaction active. You can still access the DB, but be careful.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(45e2970b-9b00-4473-9938-39d6beaf4248)]
|
[scriptable, uuid(0f0f45b0-13a1-44ae-a0ab-c6046ec6d4da)]
|
||||||
interface nsINavHistoryObserver : nsISupports
|
interface nsINavHistoryObserver : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -675,6 +675,37 @@ interface nsINavHistoryObserver : nsISupports
|
||||||
in AString aPageTitle,
|
in AString aPageTitle,
|
||||||
in ACString aGUID);
|
in ACString aGUID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an individual page's frecency has changed.
|
||||||
|
*
|
||||||
|
* This is not called for pages whose frecencies change as the result of some
|
||||||
|
* large operation where some large or unknown number of frecencies change at
|
||||||
|
* once. Use onManyFrecenciesChanged to detect such changes.
|
||||||
|
*
|
||||||
|
* @param aURI
|
||||||
|
* The page's URI.
|
||||||
|
* @param aNewFrecency
|
||||||
|
* The page's new frecency.
|
||||||
|
* @param aGUID
|
||||||
|
* The page's GUID.
|
||||||
|
* @param aHidden
|
||||||
|
* True if the page is marked as hidden.
|
||||||
|
* @param aVisitDate
|
||||||
|
* The page's last visit date.
|
||||||
|
*/
|
||||||
|
void onFrecencyChanged(in nsIURI aURI,
|
||||||
|
in long aNewFrecency,
|
||||||
|
in ACString aGUID,
|
||||||
|
in boolean aHidden,
|
||||||
|
in PRTime aVisitDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the frecencies of many pages have changed at once.
|
||||||
|
*
|
||||||
|
* onFrecencyChanged is not called for each of those pages.
|
||||||
|
*/
|
||||||
|
void onManyFrecenciesChanged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removed by the user.
|
* Removed by the user.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2841,6 +2841,24 @@ nsNavBookmarks::OnTitleChanged(nsIURI* aURI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavBookmarks::OnFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavBookmarks::OnManyFrecenciesChanged()
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNavBookmarks::OnPageChanged(nsIURI* aURI,
|
nsNavBookmarks::OnPageChanged(nsIURI* aURI,
|
||||||
uint32_t aChangedAttribute,
|
uint32_t aChangedAttribute,
|
||||||
|
|
|
@ -535,6 +535,82 @@ nsNavHistory::NotifyTitleChange(nsIURI* aURI,
|
||||||
nsINavHistoryObserver, OnTitleChanged(aURI, aTitle, aGUID));
|
nsINavHistoryObserver, OnTitleChanged(aURI, aTitle, aGUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNavHistory::NotifyFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!aGUID.IsEmpty());
|
||||||
|
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
|
||||||
|
nsINavHistoryObserver,
|
||||||
|
OnFrecencyChanged(aURI, aNewFrecency, aGUID, aHidden,
|
||||||
|
aLastVisitDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNavHistory::NotifyManyFrecenciesChanged()
|
||||||
|
{
|
||||||
|
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
|
||||||
|
nsINavHistoryObserver,
|
||||||
|
OnManyFrecenciesChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class FrecencyNotification : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FrecencyNotification(const nsACString& aSpec,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
: mSpec(aSpec)
|
||||||
|
, mNewFrecency(aNewFrecency)
|
||||||
|
, mGUID(aGUID)
|
||||||
|
, mHidden(aHidden)
|
||||||
|
, mLastVisitDate(aLastVisitDate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD Run()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread");
|
||||||
|
nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
|
||||||
|
if (navHistory) {
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
(void)NS_NewURI(getter_AddRefs(uri), mSpec);
|
||||||
|
navHistory->NotifyFrecencyChanged(uri, mNewFrecency, mGUID, mHidden,
|
||||||
|
mLastVisitDate);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCString mSpec;
|
||||||
|
int32_t mNewFrecency;
|
||||||
|
nsCString mGUID;
|
||||||
|
bool mHidden;
|
||||||
|
PRTime mLastVisitDate;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNavHistory::DispatchFrecencyChangedNotification(const nsACString& aSpec,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate) const
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIRunnable> notif = new FrecencyNotification(aSpec, aNewFrecency,
|
||||||
|
aGUID, aHidden,
|
||||||
|
aLastVisitDate);
|
||||||
|
(void)NS_DispatchToMainThread(notif);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
nsNavHistory::GetDaysOfHistory() {
|
nsNavHistory::GetDaysOfHistory() {
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread");
|
MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread");
|
||||||
|
@ -928,32 +1004,68 @@ nsNavHistory::GetHasHistoryEntries(bool* aHasEntries)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class InvalidateAllFrecenciesCallback : public AsyncStatementCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InvalidateAllFrecenciesCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD HandleCompletion(uint16_t aReason)
|
||||||
|
{
|
||||||
|
if (aReason == REASON_FINISHED) {
|
||||||
|
nsNavHistory *navHistory = nsNavHistory::GetHistoryService();
|
||||||
|
NS_ENSURE_STATE(navHistory);
|
||||||
|
navHistory->NotifyManyFrecenciesChanged();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsNavHistory::invalidateFrecencies(const nsCString& aPlaceIdsQueryString)
|
nsNavHistory::invalidateFrecencies(const nsCString& aPlaceIdsQueryString)
|
||||||
{
|
{
|
||||||
// Exclude place: queries by setting their frecency to zero.
|
// Exclude place: queries by setting their frecency to zero.
|
||||||
nsAutoCString invalideFrecenciesSQLFragment(
|
nsCString invalidFrecenciesSQLFragment(
|
||||||
"UPDATE moz_places SET frecency = (CASE "
|
"UPDATE moz_places SET frecency = "
|
||||||
"WHEN url BETWEEN 'place:' AND 'place;' "
|
);
|
||||||
"THEN 0 "
|
if (!aPlaceIdsQueryString.IsEmpty())
|
||||||
"ELSE -1 "
|
invalidFrecenciesSQLFragment.AppendLiteral("NOTIFY_FRECENCY(");
|
||||||
"END) "
|
invalidFrecenciesSQLFragment.AppendLiteral(
|
||||||
|
"(CASE "
|
||||||
|
"WHEN url BETWEEN 'place:' AND 'place;' "
|
||||||
|
"THEN 0 "
|
||||||
|
"ELSE -1 "
|
||||||
|
"END) "
|
||||||
|
);
|
||||||
|
if (!aPlaceIdsQueryString.IsEmpty()) {
|
||||||
|
invalidFrecenciesSQLFragment.AppendLiteral(
|
||||||
|
", url, guid, hidden, last_visit_date) "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
invalidFrecenciesSQLFragment.AppendLiteral(
|
||||||
"WHERE frecency > 0 "
|
"WHERE frecency > 0 "
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!aPlaceIdsQueryString.IsEmpty()) {
|
if (!aPlaceIdsQueryString.IsEmpty()) {
|
||||||
invalideFrecenciesSQLFragment.AppendLiteral("AND id IN(");
|
invalidFrecenciesSQLFragment.AppendLiteral("AND id IN(");
|
||||||
invalideFrecenciesSQLFragment.Append(aPlaceIdsQueryString);
|
invalidFrecenciesSQLFragment.Append(aPlaceIdsQueryString);
|
||||||
invalideFrecenciesSQLFragment.AppendLiteral(")");
|
invalidFrecenciesSQLFragment.AppendLiteral(")");
|
||||||
}
|
}
|
||||||
|
nsRefPtr<InvalidateAllFrecenciesCallback> cb =
|
||||||
|
aPlaceIdsQueryString.IsEmpty() ? new InvalidateAllFrecenciesCallback()
|
||||||
|
: nullptr;
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageAsyncStatement> stmt = mDB->GetAsyncStatement(
|
nsCOMPtr<mozIStorageAsyncStatement> stmt = mDB->GetAsyncStatement(
|
||||||
invalideFrecenciesSQLFragment
|
invalidFrecenciesSQLFragment
|
||||||
);
|
);
|
||||||
NS_ENSURE_STATE(stmt);
|
NS_ENSURE_STATE(stmt);
|
||||||
|
|
||||||
nsCOMPtr<mozIStoragePendingStatement> ps;
|
nsCOMPtr<mozIStoragePendingStatement> ps;
|
||||||
nsresult rv = stmt->ExecuteAsync(nullptr, getter_AddRefs(ps));
|
nsresult rv = stmt->ExecuteAsync(cb, getter_AddRefs(ps));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -3078,6 +3190,30 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class DecayFrecencyCallback : public AsyncStatementTelemetryTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DecayFrecencyCallback()
|
||||||
|
: AsyncStatementTelemetryTimer(Telemetry::PLACES_IDLE_FRECENCY_DECAY_TIME_MS)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD HandleCompletion(uint16_t aReason)
|
||||||
|
{
|
||||||
|
(void)AsyncStatementTelemetryTimer::HandleCompletion(aReason);
|
||||||
|
if (aReason == REASON_FINISHED) {
|
||||||
|
nsNavHistory *navHistory = nsNavHistory::GetHistoryService();
|
||||||
|
NS_ENSURE_STATE(navHistory);
|
||||||
|
navHistory->NotifyManyFrecenciesChanged();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsNavHistory::DecayFrecency()
|
nsNavHistory::DecayFrecency()
|
||||||
{
|
{
|
||||||
|
@ -3115,8 +3251,7 @@ nsNavHistory::DecayFrecency()
|
||||||
deleteAdaptive.get()
|
deleteAdaptive.get()
|
||||||
};
|
};
|
||||||
nsCOMPtr<mozIStoragePendingStatement> ps;
|
nsCOMPtr<mozIStoragePendingStatement> ps;
|
||||||
nsRefPtr<AsyncStatementTelemetryTimer> cb =
|
nsRefPtr<DecayFrecencyCallback> cb = new DecayFrecencyCallback();
|
||||||
new AsyncStatementTelemetryTimer(Telemetry::PLACES_IDLE_FRECENCY_DECAY_TIME_MS);
|
|
||||||
rv = mDB->MainConn()->ExecuteAsync(stmts, ArrayLength(stmts), cb,
|
rv = mDB->MainConn()->ExecuteAsync(stmts, ArrayLength(stmts), cb,
|
||||||
getter_AddRefs(ps));
|
getter_AddRefs(ps));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -4312,7 +4447,9 @@ nsNavHistory::UpdateFrecency(int64_t aPlaceId)
|
||||||
{
|
{
|
||||||
nsCOMPtr<mozIStorageAsyncStatement> updateFrecencyStmt = mDB->GetAsyncStatement(
|
nsCOMPtr<mozIStorageAsyncStatement> updateFrecencyStmt = mDB->GetAsyncStatement(
|
||||||
"UPDATE moz_places "
|
"UPDATE moz_places "
|
||||||
"SET frecency = CALCULATE_FRECENCY(:page_id) "
|
"SET frecency = NOTIFY_FRECENCY("
|
||||||
|
"CALCULATE_FRECENCY(:page_id), url, guid, hidden, last_visit_date"
|
||||||
|
") "
|
||||||
"WHERE id = :page_id"
|
"WHERE id = :page_id"
|
||||||
);
|
);
|
||||||
NS_ENSURE_STATE(updateFrecencyStmt);
|
NS_ENSURE_STATE(updateFrecencyStmt);
|
||||||
|
@ -4345,6 +4482,31 @@ nsNavHistory::UpdateFrecency(int64_t aPlaceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class FixInvalidFrecenciesCallback : public AsyncStatementCallbackNotifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FixInvalidFrecenciesCallback()
|
||||||
|
: AsyncStatementCallbackNotifier(TOPIC_FRECENCY_UPDATED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD HandleCompletion(uint16_t aReason)
|
||||||
|
{
|
||||||
|
nsresult rv = AsyncStatementCallbackNotifier::HandleCompletion(aReason);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
if (aReason == REASON_FINISHED) {
|
||||||
|
nsNavHistory *navHistory = nsNavHistory::GetHistoryService();
|
||||||
|
NS_ENSURE_STATE(navHistory);
|
||||||
|
navHistory->NotifyManyFrecenciesChanged();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsNavHistory::FixInvalidFrecencies()
|
nsNavHistory::FixInvalidFrecencies()
|
||||||
{
|
{
|
||||||
|
@ -4355,8 +4517,8 @@ nsNavHistory::FixInvalidFrecencies()
|
||||||
);
|
);
|
||||||
NS_ENSURE_STATE(stmt);
|
NS_ENSURE_STATE(stmt);
|
||||||
|
|
||||||
nsRefPtr<AsyncStatementCallbackNotifier> callback =
|
nsRefPtr<FixInvalidFrecenciesCallback> callback =
|
||||||
new AsyncStatementCallbackNotifier(TOPIC_FRECENCY_UPDATED);
|
new FixInvalidFrecenciesCallback();
|
||||||
nsCOMPtr<mozIStoragePendingStatement> ps;
|
nsCOMPtr<mozIStoragePendingStatement> ps;
|
||||||
(void)stmt->ExecuteAsync(callback, getter_AddRefs(ps));
|
(void)stmt->ExecuteAsync(callback, getter_AddRefs(ps));
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,29 @@ public:
|
||||||
const nsString& title,
|
const nsString& title,
|
||||||
const nsACString& aGUID);
|
const nsACString& aGUID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires onFrecencyChanged event to nsINavHistoryService observers
|
||||||
|
*/
|
||||||
|
void NotifyFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires onManyFrecenciesChanged event to nsINavHistoryService observers
|
||||||
|
*/
|
||||||
|
void NotifyManyFrecenciesChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts a runnable to the main thread that calls NotifyFrecencyChanged.
|
||||||
|
*/
|
||||||
|
void DispatchFrecencyChangedNotification(const nsACString& aSpec,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate) const;
|
||||||
|
|
||||||
bool isBatching() {
|
bool isBatching() {
|
||||||
return mBatchLevel > 0;
|
return mBatchLevel > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2614,6 +2614,24 @@ nsNavHistoryQueryResultNode::OnTitleChanged(nsIURI* aURI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavHistoryQueryResultNode::OnFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavHistoryQueryResultNode::OnManyFrecenciesChanged()
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here, we can always live update by just deleting all occurrences of
|
* Here, we can always live update by just deleting all occurrences of
|
||||||
* the given URI.
|
* the given URI.
|
||||||
|
@ -4662,6 +4680,24 @@ nsNavHistoryResult::OnTitleChanged(nsIURI* aURI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavHistoryResult::OnFrecencyChanged(nsIURI* aURI,
|
||||||
|
int32_t aNewFrecency,
|
||||||
|
const nsACString& aGUID,
|
||||||
|
bool aHidden,
|
||||||
|
PRTime aLastVisitDate)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavHistoryResult::OnManyFrecenciesChanged()
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNavHistoryResult::OnDeleteURI(nsIURI *aURI,
|
nsNavHistoryResult::OnDeleteURI(nsIURI *aURI,
|
||||||
const nsACString& aGUID,
|
const nsACString& aGUID,
|
||||||
|
|
|
@ -64,6 +64,10 @@ private:
|
||||||
NS_DECL_NSINAVBOOKMARKOBSERVER \
|
NS_DECL_NSINAVBOOKMARKOBSERVER \
|
||||||
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
|
NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
|
||||||
const nsACString& aGUID); \
|
const nsACString& aGUID); \
|
||||||
|
NS_IMETHOD OnFrecencyChanged(nsIURI* aURI, int32_t aNewFrecency, \
|
||||||
|
const nsACString& aGUID, bool aHidden, \
|
||||||
|
PRTime aLastVisitDate); \
|
||||||
|
NS_IMETHOD OnManyFrecenciesChanged(); \
|
||||||
NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
|
NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
|
||||||
uint16_t aReason); \
|
uint16_t aReason); \
|
||||||
NS_IMETHOD OnClearHistory(); \
|
NS_IMETHOD OnClearHistory(); \
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each of these tests a path that triggers a frecency update. Together they
|
||||||
|
// hit all sites that update a frecency.
|
||||||
|
|
||||||
|
// InsertVisitedURIs::UpdateFrecency and History::InsertPlace
|
||||||
|
add_task(function test_InsertVisitedURIs_UpdateFrecency_and_History_InsertPlace() {
|
||||||
|
// InsertPlace is at the end of a path that UpdateFrecency is also on, so kill
|
||||||
|
// two birds with one stone and expect two notifications. Trigger the path by
|
||||||
|
// adding a download.
|
||||||
|
let uri = NetUtil.newURI("http://example.com/a");
|
||||||
|
Cc["@mozilla.org/browser/download-history;1"].
|
||||||
|
getService(Ci.nsIDownloadHistory).
|
||||||
|
addDownload(uri);
|
||||||
|
yield Promise.all([onFrecencyChanged(uri), onFrecencyChanged(uri)]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// nsNavHistory::UpdateFrecency
|
||||||
|
add_task(function test_nsNavHistory_UpdateFrecency() {
|
||||||
|
let bm = PlacesUtils.bookmarks;
|
||||||
|
let uri = NetUtil.newURI("http://example.com/b");
|
||||||
|
bm.insertBookmark(bm.unfiledBookmarksFolder, uri,
|
||||||
|
Ci.nsINavBookmarksService.DEFAULT_INDEX, "test");
|
||||||
|
yield onFrecencyChanged(uri);
|
||||||
|
});
|
||||||
|
|
||||||
|
// nsNavHistory::invalidateFrecencies for particular pages
|
||||||
|
add_task(function test_nsNavHistory_invalidateFrecencies_somePages() {
|
||||||
|
let uri = NetUtil.newURI("http://test-nsNavHistory-invalidateFrecencies-somePages.com/");
|
||||||
|
// Bookmarking the URI is enough to add it to moz_places, and importantly, it
|
||||||
|
// means that removePagesFromHost doesn't remove it from moz_places, so its
|
||||||
|
// frecency is able to be changed.
|
||||||
|
let bm = PlacesUtils.bookmarks;
|
||||||
|
bm.insertBookmark(bm.unfiledBookmarksFolder, uri,
|
||||||
|
Ci.nsINavBookmarksService.DEFAULT_INDEX, "test");
|
||||||
|
PlacesUtils.history.removePagesFromHost(uri.host, false);
|
||||||
|
yield onFrecencyChanged(uri);
|
||||||
|
});
|
||||||
|
|
||||||
|
// nsNavHistory::invalidateFrecencies for all pages
|
||||||
|
add_task(function test_nsNavHistory_invalidateFrecencies_allPages() {
|
||||||
|
PlacesUtils.history.removeAllPages();
|
||||||
|
yield onManyFrecenciesChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
// nsNavHistory::DecayFrecency and nsNavHistory::FixInvalidFrecencies
|
||||||
|
add_task(function test_nsNavHistory_DecayFrecency_and_nsNavHistory_FixInvalidFrecencies() {
|
||||||
|
// FixInvalidFrecencies is at the end of a path that DecayFrecency is also on,
|
||||||
|
// so expect two notifications. Trigger the path by making nsNavHistory
|
||||||
|
// observe the idle-daily notification.
|
||||||
|
PlacesUtils.history.QueryInterface(Ci.nsIObserver).
|
||||||
|
observe(null, "idle-daily", "");
|
||||||
|
yield Promise.all([onManyFrecenciesChanged(), onManyFrecenciesChanged()]);
|
||||||
|
});
|
||||||
|
|
||||||
|
function onFrecencyChanged(expectedURI) {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
let obs = new NavHistoryObserver();
|
||||||
|
obs.onFrecencyChanged =
|
||||||
|
(uri, newFrecency, guid, hidden, visitDate) => {
|
||||||
|
PlacesUtils.history.removeObserver(obs);
|
||||||
|
do_check_true(!!uri);
|
||||||
|
do_check_true(uri.equals(expectedURI));
|
||||||
|
deferred.resolve();
|
||||||
|
};
|
||||||
|
PlacesUtils.history.addObserver(obs, false);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onManyFrecenciesChanged() {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
let obs = new NavHistoryObserver();
|
||||||
|
obs.onManyFrecenciesChanged = () => {
|
||||||
|
PlacesUtils.history.removeObserver(obs);
|
||||||
|
do_check_true(true);
|
||||||
|
deferred.resolve();
|
||||||
|
};
|
||||||
|
PlacesUtils.history.addObserver(obs, false);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
|
@ -113,6 +113,7 @@ skip-if = true
|
||||||
[test_null_interfaces.js]
|
[test_null_interfaces.js]
|
||||||
[test_onItemChanged_tags.js]
|
[test_onItemChanged_tags.js]
|
||||||
[test_pageGuid_bookmarkGuid.js]
|
[test_pageGuid_bookmarkGuid.js]
|
||||||
|
[test_frecency_observers.js]
|
||||||
[test_placeURIs.js]
|
[test_placeURIs.js]
|
||||||
[test_PlacesUtils_asyncGetBookmarkIds.js]
|
[test_PlacesUtils_asyncGetBookmarkIds.js]
|
||||||
[test_PlacesUtils_lazyobservers.js]
|
[test_PlacesUtils_lazyobservers.js]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче