Bug 662806 - nsINavHistoryObserver: pass GUID to onPageChanged.

r=philikon sr=rstrong
This commit is contained in:
Marco Bonardo 2011-06-30 22:06:56 +02:00
parent f7be880d3b
commit e1678f1592
19 changed files with 318 additions and 276 deletions

View File

@ -1888,8 +1888,10 @@ nsDownloadManager::OnClearHistory()
}
NS_IMETHODIMP
nsDownloadManager::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
const nsAString &aValue)
nsDownloadManager::OnPageChanged(nsIURI *aURI,
PRUint32 aChangedAttribute,
const nsAString& aNewValue,
const nsACString &aGUID)
{
return NS_OK;
}

View File

@ -120,7 +120,7 @@ FetchPageInfo(StatementCache<mozIStorageStatement>& aStmtCache,
nsCOMPtr<mozIStorageStatement> stmt =
aStmtCache.GetCachedStatement(NS_LITERAL_CSTRING(
"SELECT h.id, h.favicon_id, "
"SELECT h.id, h.favicon_id, h.guid, "
"(") + redirectedBookmarksFragment + NS_LITERAL_CSTRING(") "
"FROM moz_places h WHERE h.url = :page_url"
));
@ -142,19 +142,20 @@ FetchPageInfo(StatementCache<mozIStorageStatement>& aStmtCache,
rv = stmt->GetInt64(0, &_page.id);
NS_ENSURE_SUCCESS(rv, rv);
PRBool isNull;
stmt->GetIsNull(1, &isNull);
rv = stmt->GetIsNull(1, &isNull);
NS_ENSURE_SUCCESS(rv, rv);
// favicon_id can be NULL.
if (!isNull) {
rv = stmt->GetInt64(1, &_page.iconId);
NS_ENSURE_SUCCESS(rv, rv);
}
stmt->GetIsNull(2, &isNull);
rv = stmt->GetUTF8String(2, _page.guid);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->GetIsNull(3, &isNull);
NS_ENSURE_SUCCESS(rv, rv);
// The page could not be bookmarked.
if (!isNull) {
rv = stmt->GetUTF8String(2, _page.bookmarkedSpec);
rv = stmt->GetUTF8String(3, _page.bookmarkedSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -807,6 +808,10 @@ AsyncAssociateIconToPage::Run()
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
// Get the new id and GUID.
rv = FetchPageInfo(mFaviconSvc->mSyncStatements, mPage);
NS_ENSURE_SUCCESS(rv, rv);
mIcon.status |= ICON_STATUS_ASSOCIATED;
}
// Otherwise just associate the icon to the page, if needed.
@ -959,7 +964,7 @@ NotifyIconObservers::Run()
rv = NS_NewURI(getter_AddRefs(pageURI), mPage.spec);
NS_ENSURE_SUCCESS(rv, rv);
mFaviconSvc->SendFaviconNotifications(pageURI, iconURI);
mFaviconSvc->SendFaviconNotifications(pageURI, iconURI, mPage.guid);
// If the page is bookmarked and the bookmarked url is different from the
// updated one, start a new task to update its icon as well.

View File

@ -102,6 +102,7 @@ struct PageData
, canAddToHistory(true)
, iconId(0)
{
guid.SetIsVoid(PR_TRUE);
}
PRInt64 id;
@ -110,6 +111,7 @@ struct PageData
nsString revHost;
bool canAddToHistory; // False for disabled history and unsupported schemas.
PRInt64 iconId;
nsCString guid;
};
/**

View File

@ -256,16 +256,92 @@ nsFaviconService::SetFaviconUrlForPage(nsIURI* aPageURI, nsIURI* aFaviconURI)
NS_ENSURE_ARG(aPageURI);
NS_ENSURE_ARG(aFaviconURI);
if (mFaviconsExpirationRunning)
// If we are about to expire all favicons, don't bother setting a new one.
if (mFaviconsExpirationRunning) {
return NS_OK;
}
PRBool hasData;
nsresult rv = SetFaviconUrlForPageInternal(aPageURI, aFaviconURI, &hasData);
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
if (history->InPrivateBrowsingMode()) {
return NS_OK;
}
nsresult rv;
PRInt64 iconId = -1;
PRBool hasData = PR_FALSE;
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetIconInfo);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResult = PR_FALSE;
if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
// We already have an entry for this icon, just get its stats.
rv = stmt->GetInt64(0, &iconId);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 dataSize;
rv = stmt->GetInt32(1, &dataSize);
NS_ENSURE_SUCCESS(rv, rv);
if (dataSize > 0) {
hasData = PR_TRUE;
}
}
}
mozStorageTransaction transaction(mDBConn, PR_FALSE);
if (iconId == -1) {
// We did not find any entry for this icon, so create a new one.
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBInsertIcon);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("icon_id"));
NS_ENSURE_SUCCESS(rv, rv);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("data"));
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("mime_type"));
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("expiration"));
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(getInfoStmt, mDBGetIconInfo);
rv = URIBinder::Bind(getInfoStmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResult;
rv = getInfoStmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(hasResult, "hasResult is false but the call succeeded?");
iconId = getInfoStmt->AsInt64(0);
}
}
// Now, link our icon entry with the page.
PRInt64 pageId;
nsCAutoString guid;
rv = history->GetOrCreateIdForPage(aPageURI, &pageId, guid);
NS_ENSURE_SUCCESS(rv, rv);
// send favicon change notifications if the URL has any data
if (hasData)
SendFaviconNotifications(aPageURI, aFaviconURI);
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBSetPageFavicon);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), pageId);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("icon_id"), iconId);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
// Send favicon change notifications only if the icon has any data.
if (hasData) {
SendFaviconNotifications(aPageURI, aFaviconURI, guid);
}
return NS_OK;
}
@ -284,115 +360,18 @@ nsFaviconService::GetDefaultFavicon(nsIURI** _retval)
return mDefaultIcon->Clone(_retval);
}
// nsFaviconService::SetFaviconUrlForPageInternal
//
// This creates a new entry in the favicon table if necessary and tells the
// history service to associate the given favicon ID with the given URI. We
// don't want to update the history table directly since that may involve
// creating a new row in the history table, which should only be done by
// history.
//
// This sets aHasData if there was already icon data for this favicon. Used
// to know if we should try reloading.
//
// Does NOT send out notifications. Caller should send out notifications
// if the favicon has data.
nsresult
nsFaviconService::SetFaviconUrlForPageInternal(nsIURI* aPageURI,
nsIURI* aFaviconURI,
PRBool* aHasData)
{
nsresult rv;
PRInt64 iconId = -1;
*aHasData = PR_FALSE;
nsNavHistory* historyService = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(historyService, NS_ERROR_OUT_OF_MEMORY);
if (historyService->InPrivateBrowsingMode())
return NS_OK;
mozStorageTransaction transaction(mDBConn, PR_FALSE);
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetIconInfo);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResult = PR_FALSE;
if (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
// We already have an entry for this icon, just get the stats
rv = stmt->GetInt64(0, &iconId);
NS_ENSURE_SUCCESS(rv, rv);
// see if this icon has data already
PRInt32 dataSize;
rv = stmt->GetInt32(1, &dataSize);
NS_ENSURE_SUCCESS(rv, rv);
if (dataSize > 0)
*aHasData = PR_TRUE;
}
}
if (iconId == -1) {
// We did not find any entry, so create a new one
// not-binded params are automatically nullified by mozStorage
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBInsertIcon);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("icon_id"));
NS_ENSURE_SUCCESS(rv, rv);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(getInfoStmt, mDBGetIconInfo);
rv = URIBinder::Bind(getInfoStmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResult;
rv = getInfoStmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(hasResult, "hasResult is false but the call succeeded?");
iconId = getInfoStmt->AsInt64(0);
}
}
// now link our icon entry with the page
PRInt64 pageId;
rv = historyService->GetUrlIdFor(aPageURI, &pageId, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBSetPageFavicon);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), pageId);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("icon_id"), iconId);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
// nsFaviconService::SendFaviconNotifications
//
// Call to send out favicon changed notifications. Should only be called
// when you know there is data loaded for the favicon.
void
nsFaviconService::SendFaviconNotifications(nsIURI* aPageURI,
nsIURI* aFaviconURI)
nsIURI* aFaviconURI,
const nsACString& aGUID)
{
nsCAutoString faviconSpec;
nsNavHistory* historyService = nsNavHistory::GetHistoryService();
if (historyService && NS_SUCCEEDED(aFaviconURI->GetSpec(faviconSpec))) {
historyService->SendPageChangedNotification(aPageURI,
nsINavHistoryObserver::ATTRIBUTE_FAVICON,
NS_ConvertUTF8toUTF16(faviconSpec));
nsNavHistory* history = nsNavHistory::GetHistoryService();
if (history && NS_SUCCEEDED(aFaviconURI->GetSpec(faviconSpec))) {
history->SendPageChangedNotification(aPageURI,
nsINavHistoryObserver::ATTRIBUTE_FAVICON,
NS_ConvertUTF8toUTF16(faviconSpec),
aGUID);
}
}

View File

@ -144,7 +144,18 @@ public:
*/
nsresult FinalizeStatements();
void SendFaviconNotifications(nsIURI* aPage, nsIURI* aFaviconURI);
/**
* Call to send out favicon changed notifications. Should only be called
* when there is data loaded for the favicon.
* @param aPageURI
* The URI of the page to notify about.
* @param aFaviconURI
* The moz-anno:favicon URI of the icon.
* @param aGUID
* The unique ID associated with the page.
*/
void SendFaviconNotifications(nsIURI* aPageURI, nsIURI* aFaviconURI,
const nsACString& aGUID);
/**
* This cache should be used only for background thread statements.

View File

@ -809,7 +809,7 @@ interface nsINavHistoryResult : nsISupports
* 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.
*/
[scriptable, uuid(b02e6e42-9ef1-4b89-9ea3-aae29244fcef)]
[scriptable, uuid(c837f6ba-6ad7-4810-a425-8ce29e05d17e)]
interface nsINavHistoryObserver : nsISupports
{
/**
@ -928,20 +928,27 @@ interface nsINavHistoryObserver : nsISupports
void onClearHistory();
/**
* A page has had some attribute on it changed. Note that for TYPED and
* HIDDEN, the page may not necessarily have been added yet.
* onPageChanged attribute indicating that favicon has been updated.
* aNewValue parameter will be set to the new favicon URI string.
*/
const unsigned long ATTRIBUTE_FAVICON = 3;
/**
* An attribute of this page changed.
*
* @param aURI
* The URI of the page on which an attribute changed.
* @param aWhat
* The attribute whose value changed.
* @param aValue
* The attribute's new value.
* The URI of the page on which an attribute changed.
* @param aChangedAttribute
* The attribute whose value changed. See ATTRIBUTE_* constants.
* @param aNewValue
* The attribute's new value.
* @param aGUID
* The unique ID associated with the page.
*/
const unsigned long ATTRIBUTE_FAVICON = 3; // favicon updated, aString = favicon annotation URI
void onPageChanged(in nsIURI aURI,
in unsigned long aWhat,
in AString aValue);
in unsigned long aChangedAttribute,
in AString aNewValue,
in ACString aGUID);
/**
* Called when some visits of an history entry are expired.

View File

@ -967,11 +967,11 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder,
mozStorageTransaction transaction(mDBConn, PR_FALSE);
PRInt64 placeId;
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
// If the URI is unknown, this will create a new entry.
nsresult rv = history->GetUrlIdFor(aURI, &placeId, PR_TRUE);
PRInt64 placeId;
nsCAutoString placeGuid;
nsresult rv = history->GetOrCreateIdForPage(aURI, &placeId, placeGuid);
NS_ENSURE_SUCCESS(rv, rv);
// Get the correct index for insertion. This also ensures the parent exists.
@ -2424,7 +2424,8 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIURI* aURI, nsIURI** _retval)
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
PRInt64 placeId;
nsresult rv = history->GetUrlIdFor(aURI, &placeId, PR_FALSE);
nsCAutoString placeGuid;
nsresult rv = history->GetIdForPage(aURI, &placeId, placeGuid);
NS_ENSURE_SUCCESS(rv, rv);
if (!placeId) {
// This URI is unknown, just return null.
@ -2466,11 +2467,11 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI* aNewURI)
mozStorageTransaction transaction(mDBConn, PR_FALSE);
// This will create a new page if one doesn't exist.
PRInt64 newPlaceId;
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->GetUrlIdFor(aNewURI, &newPlaceId, PR_TRUE);
PRInt64 newPlaceId;
nsCAutoString newPlaceGuid;
rv = history->GetOrCreateIdForPage(aNewURI, &newPlaceId, newPlaceGuid);
NS_ENSURE_SUCCESS(rv, rv);
if (!newPlaceId)
return NS_ERROR_INVALID_ARG;
@ -3080,8 +3081,9 @@ nsNavBookmarks::OnDeleteURI(nsIURI* aURI,
#ifdef DEBUG
nsNavHistory* history = nsNavHistory::GetHistoryService();
PRInt64 placeId;
nsCAutoString placeGuid;
NS_ABORT_IF_FALSE(
history && NS_SUCCEEDED(history->GetUrlIdFor(aURI, &placeId, PR_FALSE)) && !placeId,
history && NS_SUCCEEDED(history->GetIdForPage(aURI, &placeId, placeGuid)) && !placeId,
"OnDeleteURI was notified for a page that still exists?"
);
#endif
@ -3109,17 +3111,19 @@ nsNavBookmarks::OnTitleChanged(nsIURI* aURI,
NS_IMETHODIMP
nsNavBookmarks::OnPageChanged(nsIURI* aURI, PRUint32 aWhat,
const nsAString& aValue)
nsNavBookmarks::OnPageChanged(nsIURI* aURI,
PRUint32 aChangedAttribute,
const nsAString& aNewValue,
const nsACString& aGUID)
{
nsresult rv;
if (aWhat == nsINavHistoryObserver::ATTRIBUTE_FAVICON) {
if (aChangedAttribute == nsINavHistoryObserver::ATTRIBUTE_FAVICON) {
ItemChangeData changeData;
rv = aURI->GetSpec(changeData.bookmark.url);
NS_ENSURE_SUCCESS(rv, rv);
changeData.property = NS_LITERAL_CSTRING("favicon");
changeData.isAnnotation = PR_FALSE;
changeData.newValue = NS_ConvertUTF16toUTF8(aValue);
changeData.newValue = NS_ConvertUTF16toUTF8(aNewValue);
changeData.bookmark.lastModified = 0;
changeData.bookmark.type = TYPE_BOOKMARK;

View File

@ -1691,48 +1691,50 @@ nsNavHistory::MigrateV11Up(mozIStorageConnection *aDBConn)
return NS_OK;
}
// nsNavHistory::GetUrlIdFor
//
// Called by the bookmarks and annotation services, this function returns the
// ID of the row for the given URL, optionally creating one if it doesn't
// exist. A newly created entry will have no visits.
//
// If aAutoCreate is false and the item doesn't exist, the entry ID will be
// zero.
//
// This DOES NOT check for bad URLs other than that they're nonempty.
nsresult
nsNavHistory::GetUrlIdFor(nsIURI* aURI, PRInt64* aEntryID,
PRBool aAutoCreate)
nsNavHistory::GetIdForPage(nsIURI* aURI,
PRInt64* _pageId,
nsCString& _GUID)
{
*aEntryID = 0;
{
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetURLPageInfo);
nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
*_pageId = 0;
PRBool hasEntry = PR_FALSE;
rv = stmt->ExecuteStep(&hasEntry);
NS_ENSURE_SUCCESS(rv, rv);
DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetURLPageInfo);
nsresult rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
if (hasEntry)
return stmt->GetInt64(kGetInfoIndex_PageID, aEntryID);
PRBool hasEntry = PR_FALSE;
rv = stmt->ExecuteStep(&hasEntry);
NS_ENSURE_SUCCESS(rv, rv);
if (hasEntry) {
rv = stmt->GetInt64(kGetInfoIndex_PageID, _pageId);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->GetUTF8String(5, _GUID);
NS_ENSURE_SUCCESS(rv, rv);
}
if (aAutoCreate) {
// create a new hidden, untyped, unvisited entry
nsAutoString voidString;
voidString.SetIsVoid(PR_TRUE);
nsCAutoString guid;
return InternalAddNewPage(aURI, voidString, PR_TRUE, PR_FALSE, 0, PR_TRUE, aEntryID, guid);
}
// Doesn't exist: don't do anything, entry ID was already set to 0 above
return NS_OK;
}
nsresult
nsNavHistory::GetOrCreateIdForPage(nsIURI* aURI,
PRInt64* _pageId,
nsCString& _GUID)
{
nsresult rv = GetIdForPage(aURI, _pageId, _GUID);
NS_ENSURE_SUCCESS(rv, rv);
if (*_pageId == 0) {
// Create a new hidden, untyped and unvisited entry.
nsAutoString voidString;
voidString.SetIsVoid(PR_TRUE);
rv = InternalAddNewPage(aURI, voidString, PR_TRUE, PR_FALSE, 0, PR_TRUE,
_pageId, _GUID);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
// nsNavHistory::InternalAddNewPage
//
@ -4277,7 +4279,8 @@ nsNavHistory::RemovePages(nsIURI **aURIs, PRUint32 aLength, PRBool aDoBatchNotif
nsCString deletePlaceIdsQueryString;
for (PRUint32 i = 0; i < aLength; i++) {
PRInt64 placeId;
rv = GetUrlIdFor(aURIs[i], &placeId, PR_FALSE);
nsCAutoString guid;
rv = GetIdForPage(aURIs[i], &placeId, guid);
NS_ENSURE_SUCCESS(rv, rv);
if (placeId != 0) {
if (!deletePlaceIdsQueryString.IsEmpty())
@ -6673,11 +6676,15 @@ nsNavHistory::URIToResultNode(nsIURI* aURI,
}
void
nsNavHistory::SendPageChangedNotification(nsIURI* aURI, PRUint32 aWhat,
const nsAString& aValue)
nsNavHistory::SendPageChangedNotification(nsIURI* aURI,
PRUint32 aChangedAttribute,
const nsAString& aNewValue,
const nsACString& aGUID)
{
MOZ_ASSERT(!aGUID.IsEmpty());
NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver, OnPageChanged(aURI, aWhat, aValue));
nsINavHistoryObserver,
OnPageChanged(aURI, aChangedAttribute, aNewValue, aGUID));
}
// nsNavHistory::TitleForDomain

View File

@ -236,11 +236,35 @@ public:
}
/**
* Returns the database ID for the given URI, or 0 if not found and autoCreate
* is false.
* Fetches the database id and the GUID associated to the given URI.
*
* @param aURI
* The page to look for.
* @param _pageId
* Will be set to the database id associated with the page.
* If the page doesn't exist, this will be zero.
* @param _GUID
* Will be set to the unique id associated with the page.
* If the page doesn't exist, this will be empty.
* @note This DOES NOT check for bad URLs other than that they're nonempty.
*/
nsresult GetUrlIdFor(nsIURI* aURI, PRInt64* aEntryID,
PRBool aAutoCreate);
nsresult GetIdForPage(nsIURI* aURI,
PRInt64* _pageId, nsCString& _GUID);
/**
* Fetches the database id and the GUID associated to the given URI, creating
* a new database entry if one doesn't exist yet.
*
* @param aURI
* The page to look for or create.
* @param _pageId
* Will be set to the database id associated with the page.
* @param _GUID
* Will be set to the unique id associated with the page.
* @note This DOES NOT check for bad URLs other than that they're nonempty.
*/
nsresult GetOrCreateIdForPage(nsIURI* aURI,
PRInt64* _pageId, nsCString& _GUID);
nsresult UpdateFrecency(PRInt64 aPlaceId);
@ -336,8 +360,9 @@ public:
// used by other places components to send history notifications (for example,
// when the favicon has changed)
void SendPageChangedNotification(nsIURI* aURI, PRUint32 aWhat,
const nsAString& aValue);
void SendPageChangedNotification(nsIURI* aURI, PRUint32 aChangedAttribute,
const nsAString& aValue,
const nsACString& aGUID);
/**
* Returns current number of days stored in history.

View File

@ -3063,7 +3063,7 @@ nsNavHistoryQueryResultNode::OnTitleChanged(nsIURI* aURI,
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnBeforeDeleteURI(nsIURI *aURI,
nsNavHistoryQueryResultNode::OnBeforeDeleteURI(nsIURI* aURI,
const nsACString& aGUID,
PRUint16 aReason)
{
@ -3075,7 +3075,7 @@ nsNavHistoryQueryResultNode::OnBeforeDeleteURI(nsIURI *aURI,
* the given URI.
*/
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnDeleteURI(nsIURI *aURI,
nsNavHistoryQueryResultNode::OnDeleteURI(nsIURI* aURI,
const nsACString& aGUID,
PRUint16 aReason)
{
@ -3144,22 +3144,23 @@ static nsresult setFaviconCallback(
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
const nsAString &aValue)
nsNavHistoryQueryResultNode::OnPageChanged(nsIURI* aURI,
PRUint32 aChangedAttribute,
const nsAString& aNewValue,
const nsACString& aGUID)
{
nsCAutoString spec;
nsresult rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
switch (aWhat) {
switch (aChangedAttribute) {
case nsINavHistoryObserver::ATTRIBUTE_FAVICON: {
NS_ConvertUTF16toUTF8 newFavicon(aValue);
PRBool onlyOneEntry = (mOptions->ResultType() ==
nsINavHistoryQueryOptions::RESULTS_AS_URI ||
mOptions->ResultType() ==
nsINavHistoryQueryOptions::RESULTS_AS_TAG_CONTENTS);
rv = UpdateURIs(PR_TRUE, onlyOneEntry, PR_FALSE, spec, setFaviconCallback,
&newFavicon);
&NS_ConvertUTF16toUTF8(aNewValue));
NS_ENSURE_SUCCESS(rv, rv);
break;
}
@ -5170,10 +5171,12 @@ nsNavHistoryResult::OnClearHistory()
NS_IMETHODIMP
nsNavHistoryResult::OnPageChanged(nsIURI *aURI,
PRUint32 aWhat, const nsAString &aValue)
nsNavHistoryResult::OnPageChanged(nsIURI* aURI,
PRUint32 aChangedAttribute,
const nsAString& aValue,
const nsACString& aGUID)
{
ENUMERATE_HISTORY_OBSERVERS(OnPageChanged(aURI, aWhat, aValue));
ENUMERATE_HISTORY_OBSERVERS(OnPageChanged(aURI, aChangedAttribute, aValue, aGUID));
return NS_OK;
}

View File

@ -107,8 +107,9 @@ private:
NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
PRUint16 aReason); \
NS_IMETHOD OnClearHistory(); \
NS_IMETHOD OnPageChanged(nsIURI *aURI, PRUint32 aWhat, \
const nsAString &aValue); \
NS_IMETHOD OnPageChanged(nsIURI *aURI, PRUint32 aChangedAttribute, \
const nsAString &aNewValue, \
const nsACString &aGUID); \
NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \
const nsACString& aGUID, PRUint16 aReason);

View File

@ -55,9 +55,9 @@ function test() {
// Create and add history observer.
var historyObserver = {
visitCount: Array(),
onBeginUpdateBatch: function() {},
onEndUpdateBatch: function() {},
onVisit: function(aURI, aVisitID, aTime, aSessionID, aReferringID,
onBeginUpdateBatch: function () {},
onEndUpdateBatch: function () {},
onVisit: function (aURI, aVisitID, aTime, aSessionID, aReferringID,
aTransitionType) {
info("Received onVisit: " + aURI.spec);
if (aURI.spec in this.visitCount)
@ -65,12 +65,12 @@ function test() {
else
this.visitCount[aURI.spec] = 1;
},
onTitleChanged: function(aURI, aPageTitle) {},
onBeforeDeleteURI: function(aURI) {},
onDeleteURI: function(aURI) {},
onClearHistory: function() {},
onPageChanged: function(aURI, aWhat, aValue) {},
onDeleteVisits: function() {},
onTitleChanged: function () {},
onBeforeDeleteURI: function () {},
onDeleteURI: function () {},
onClearHistory: function () {},
onPageChanged: function () {},
onDeleteVisits: function () {},
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
};
hs.addObserver(historyObserver, false);

View File

@ -48,19 +48,19 @@ function DummyObserver() {
DummyObserver.prototype = {
// history observer
onBeginUpdateBatch: function() {},
onEndUpdateBatch: function() {},
onVisit: function(aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) {
onBeginUpdateBatch: function () {},
onEndUpdateBatch: function () {},
onVisit: function (aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) {
let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.notifyObservers(null, "dummy-observer-visited", null);
},
onTitleChanged: function(aURI, aPageTitle) {},
onBeforeDeleteURI: function(aURI) {},
onDeleteURI: function(aURI) {},
onClearHistory: function() {},
onPageChanged: function(aURI, aWhat, aValue) {},
onDeleteVisits: function(aURI, aVisitTime) {},
onTitleChanged: function () {},
onBeforeDeleteURI: function () {},
onDeleteURI: function () {},
onClearHistory: function () {},
onPageChanged: function () {},
onDeleteVisits: function () {},
// bookmark observer
//onBeginUpdateBatch: function() {},

View File

@ -61,19 +61,15 @@ var observer = {
dump("onVisit: " + aURI.spec + "\n");
confirm_results();
},
onTitleChanged: function(aURI, aPageTitle) {},
onBeforeDeleteURI: function(aURI) {},
onDeleteURI: function(aURI) {},
onClearHistory: function() {},
onPageChanged: function(aURI, aWhat, aValue) {},
onDeleteVisits: function() {},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsINavHistoryObserver) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
onTitleChanged: function () {},
onBeforeDeleteURI: function () {},
onDeleteURI: function () {},
onClearHistory: function () {},
onPageChanged: function () {},
onDeleteVisits: function () {},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsINavHistoryObserver
])
};
histsvc.addObserver(observer, false);

View File

@ -161,10 +161,12 @@ var historyObserver = {
onClearHistory: function() {},
onDeleteVisits: function() {},
onPageChanged: function historyObserver_onPageChanged(pageURI, what, value) {
onPageChanged: function historyObserver_onPageChanged(pageURI, what, value, guid) {
if (what != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON)
return;
do_check_guid_for_uri(pageURI, guid);
if (pageURI.equals(tests[currentTestIndex].pageURI)) {
tests[currentTestIndex].check();
currentTestIndex++;

View File

@ -143,7 +143,7 @@ let historyObserver = {
onClearHistory: function() {},
onDeleteVisits: function() {},
onPageChanged: function historyObserver_onPageChanged(pageURI, what, value) {
onPageChanged: function historyObserver_onPageChanged(pageURI, what, value, guid) {
if (what != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON)
return;
@ -151,6 +151,8 @@ let historyObserver = {
//dump_table("moz_places");
//dump_table("moz_favicons");
do_check_guid_for_uri(pageURI, guid);
// Ensure we have been called by the last test.
do_check_true(pageURI.equals(NetUtil.newURI("http://testfinal.bar/")));

View File

@ -126,3 +126,24 @@ add_test(function test_onTitleChanged() {
let title = "test-title";
PlacesUtils.history.setPageTitle(testuri, title);
});
add_test(function test_onPageChanged() {
onNotify(function onPageChanged(aURI, aChangedAttribute, aNewValue, aGUID) {
do_check_eq(aChangedAttribute, Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON);
do_check_true(aURI.equals(testuri));
do_check_eq(aNewValue, iconurl);
do_check_guid_for_uri(aURI, aGUID);
run_next_test();
});
let [testuri] = add_visit();
let iconurl = "file:///favicon-normal32.png";
let data = readFileData(do_get_file("favicon-normal32.png"));
PlacesUtils.favicons.setFaviconData(NetUtil.newURI(iconurl),
data, data.length, "image/png",
Number.MAX_VALUE);
PlacesUtils.favicons.setFaviconUrlForPage(testuri, NetUtil.newURI(iconurl));
});

View File

@ -100,25 +100,15 @@ var observer = {
if (this._visitCount == gVisits.length)
do_test_finished();
},
onTitleChanged: function(aURI, aPageTitle) {
},
onBeforeDeleteURI: function(aURI) {
},
onDeleteURI: function(aURI) {
},
onClearHistory: function() {
},
onPageChanged: function(aURI, aWhat, aValue) {
},
onDeleteVisits: function() {
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsINavHistoryObserver) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
onTitleChanged: function () {},
onBeforeDeleteURI: function () {},
onDeleteURI: function () {},
onClearHistory: function () {},
onPageChanged: function () {},
onDeleteVisits: function () {},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsINavHistoryObserver
])
};
histsvc.addObserver(observer, false);

View File

@ -57,43 +57,28 @@ function Observer()
Observer.prototype =
{
checked: false,
onBeginUpdateBatch: function() {
},
onEndUpdateBatch: function() {
},
onVisit: function(aURI, aVisitID, aTime, aSessionId, aReferringId,
aTransitionType, _added)
{
},
onTitleChanged: function(aURI, aPageTable)
{
},
onBeforeDeleteURI: function(aURI, aGUID)
onBeginUpdateBatch: function () {},
onEndUpdateBatch: function () {},
onVisit: function () {},
onTitleChanged: function () {},
onBeforeDeleteURI: function (aURI, aGUID)
{
this.removedURI = aURI;
this.removedGUID = aGUID;
do_check_guid_for_uri(aURI, aGUID);
},
onDeleteURI: function(aURI, aGUID)
onDeleteURI: function (aURI, aGUID)
{
do_check_false(this.checked);
do_check_true(this.removedURI.equals(aURI));
do_check_eq(this.removedGUID, aGUID);
this.checked = true;
},
onPageChanged: function(aURI, aWhat, aValue)
{
},
onDeleteVisits: function()
{
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsINavHistoryObserver) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
onPageChanged: function () {},
onDeleteVisits: function () {},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsINavHistoryObserver
])
};
////////////////////////////////////////////////////////////////////////////////