mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
Bug 461199 (Part 2) - Create an API for asynchronous isVisited checks that content/layout can use
Create a new API (IHistory) to check for the visitedness of a URI. r=mak r=bz sr=bsmedberg
This commit is contained in:
parent
467d507067
commit
94acf62a02
@ -64,6 +64,12 @@ EXPORTS = \
|
||||
mozAutoDocUpdate.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/dom
|
||||
|
||||
EXPORTS_mozilla/dom = \
|
||||
Link.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
mozSanitizingSerializer.cpp \
|
||||
nsAtomListUtils.cpp \
|
||||
|
111
docshell/base/IHistory.h
Normal file
111
docshell/base/IHistory.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=80:
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_IHistory_h_
|
||||
#define mozilla_IHistory_h_
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class Link;
|
||||
}
|
||||
|
||||
#define IHISTORY_IID \
|
||||
{0xaf27265d, 0x5672, 0x4d23, {0xa0, 0x75, 0x34, 0x8e, 0xb9, 0x73, 0x5a, 0x9a}}
|
||||
|
||||
class IHistory : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID)
|
||||
|
||||
/**
|
||||
* Registers the Link for notifications about the visited-ness of aURI.
|
||||
* Consumers should assume that the URI is unvisited after calling this, and
|
||||
* they will be notified if that state (unvisited) changes by having
|
||||
* SetLinkState called on themselves. This function is guaranteed to run to
|
||||
* completion before aLink is notified. After the node is notified, it will
|
||||
* be unregistered.
|
||||
*
|
||||
* @note SetLinkState must not call RegisterVisitedCallback or
|
||||
* UnregisterVisitedCallback.
|
||||
*
|
||||
* @pre aURI must not be null.
|
||||
* @pre aLink must not be null.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check.
|
||||
* @param aLink
|
||||
* The link to update whenever the history status changes. The
|
||||
* implementation will only hold onto a raw pointer, so if this
|
||||
* object should be destroyed, be sure to call
|
||||
* UnregisterVistedCallback first.
|
||||
*/
|
||||
NS_IMETHOD RegisterVisitedCallback(nsIURI *aURI, dom::Link *aLink) = 0;
|
||||
|
||||
/**
|
||||
* Unregisters a previously registered Link object. This must be called
|
||||
* before destroying the registered object.
|
||||
*
|
||||
* @pre aURI must not be null.
|
||||
* @pre aLink must not be null.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI that aLink was registered for.
|
||||
* @param aLink
|
||||
* The link object to unregister for aURI.
|
||||
*/
|
||||
NS_IMETHOD UnregisterVisitedCallback(nsIURI *aURI, dom::Link *aLink) = 0;
|
||||
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(IHistory, IHISTORY_IID)
|
||||
|
||||
#define NS_DECL_IHISTORY \
|
||||
NS_IMETHOD RegisterVisitedCallback(nsIURI *aURI, \
|
||||
mozilla::dom::Link *aContent); \
|
||||
NS_IMETHOD UnregisterVisitedCallback(nsIURI *aURI, \
|
||||
mozilla::dom::Link *aContent);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_IHistory_h_
|
@ -82,6 +82,12 @@ XPIDLSRCS = \
|
||||
|
||||
EXPORTS = nsDocShellLoadTypes.h
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
IHistory.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsDocShell.cpp \
|
||||
nsDocShellLoadInfo.cpp \
|
||||
|
@ -86,7 +86,11 @@
|
||||
{ 0xaf, 0x80, 0x00, 0xa0, 0x24, 0xff, 0xc0, 0x8c } }
|
||||
#define NS_DOCSHELL_CONTRACTID "@mozilla.org/docshell/html;1"
|
||||
|
||||
|
||||
/**
|
||||
* Contract ID to obtain the IHistory interface. This is a non-scriptable
|
||||
* interface used to interact with history in an asynchronous manner.
|
||||
*/
|
||||
#define NS_IHISTORY_CONTRACTID "@mozilla.org/browser/history;1"
|
||||
|
||||
/**
|
||||
* An observer service topic that can be listened to to catch creation
|
||||
|
286
toolkit/components/places/src/History.cpp
Normal file
286
toolkit/components/places/src/History.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "History.h"
|
||||
#include "nsNavHistory.h"
|
||||
|
||||
#include "mozilla/storage.h"
|
||||
#include "mozilla/dom/Link.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace places {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Anonymous Helpers
|
||||
|
||||
namespace {
|
||||
|
||||
class VisitedQuery : public mozIStorageStatementCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static nsresult Start(nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(aURI, "Don't pass a null URI!");
|
||||
|
||||
nsNavHistory* navHist = nsNavHistory::GetHistoryService();
|
||||
NS_ENSURE_TRUE(navHist, NS_ERROR_FAILURE);
|
||||
mozIStorageStatement* stmt = navHist->DBGetIsVisited();
|
||||
NS_ENSURE_STATE(stmt);
|
||||
|
||||
// Be sure to reset our statement!
|
||||
mozStorageStatementScoper scoper(stmt);
|
||||
nsCString spec;
|
||||
nsresult rv = aURI->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->BindUTF8StringParameter(0, spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<VisitedQuery> callback = new VisitedQuery(aURI);
|
||||
NS_ENSURE_TRUE(callback, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<mozIStoragePendingStatement> handle;
|
||||
return stmt->ExecuteAsync(callback, getter_AddRefs(handle));
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleResult(mozIStorageResultSet* aResults)
|
||||
{
|
||||
// If this method is called, we've gotten results, which means we have a
|
||||
// visit.
|
||||
mIsVisited = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleError(mozIStorageError* aError)
|
||||
{
|
||||
// mIsVisited is already set to false, and that's the assumption we will
|
||||
// make if an error occurred.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleCompletion(PRUint16 aReason)
|
||||
{
|
||||
if (mIsVisited) {
|
||||
History::GetService()->NotifyVisited(mURI);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
VisitedQuery(nsIURI* aURI)
|
||||
: mURI(aURI)
|
||||
, mIsVisited(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
bool mIsVisited;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
VisitedQuery,
|
||||
mozIStorageStatementCallback
|
||||
)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// History
|
||||
|
||||
History* History::gService = NULL;
|
||||
|
||||
History::History()
|
||||
{
|
||||
NS_ASSERTION(!gService, "Ruh-roh! This service has already been created!");
|
||||
gService = this;
|
||||
}
|
||||
|
||||
History::~History()
|
||||
{
|
||||
gService = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
History::NotifyVisited(nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(aURI, "Ruh-roh! A NULL URI was passed to us!");
|
||||
|
||||
// If the hash table has not been initialized, then we have nothing to notify
|
||||
// about.
|
||||
if (!mObservers.IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Additionally, if we have no observers for this URI, we have nothing to
|
||||
// notify about.
|
||||
KeyClass* key = mObservers.GetEntry(aURI);
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Walk through the array, and update each Link node.
|
||||
const ObserverArray& observers = key->array;
|
||||
ObserverArray::index_type len = observers.Length();
|
||||
for (ObserverArray::index_type i = 0; i < len; i++) {
|
||||
Link* link = observers[i];
|
||||
link->SetLinkState(eLinkState_Visited);
|
||||
NS_ASSERTION(len == observers.Length(),
|
||||
"Calling SetLinkState added or removed an observer!");
|
||||
}
|
||||
|
||||
// All the registered nodes can now be removed for this URI.
|
||||
mObservers.RemoveEntry(aURI);
|
||||
}
|
||||
|
||||
/* static */
|
||||
History*
|
||||
History::GetService()
|
||||
{
|
||||
if (gService) {
|
||||
return gService;
|
||||
}
|
||||
|
||||
nsCOMPtr<IHistory> service(do_GetService(NS_IHISTORY_CONTRACTID));
|
||||
NS_ABORT_IF_FALSE(service, "Cannot obtain IHistory service!");
|
||||
NS_ASSERTION(gService, "Our constructor was not run?!");
|
||||
|
||||
return gService;
|
||||
}
|
||||
|
||||
/* static */
|
||||
History*
|
||||
History::GetSingleton()
|
||||
{
|
||||
if (!gService) {
|
||||
gService = new History();
|
||||
NS_ENSURE_TRUE(gService, nsnull);
|
||||
}
|
||||
|
||||
NS_ADDREF(gService);
|
||||
return gService;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// IHistory
|
||||
|
||||
NS_IMETHODIMP
|
||||
History::RegisterVisitedCallback(nsIURI* aURI,
|
||||
Link* aLink)
|
||||
{
|
||||
NS_ASSERTION(aURI, "Must pass a non-null URI!");
|
||||
NS_ASSERTION(aLink, "Must pass a non-null Link object!");
|
||||
|
||||
// First, ensure that our hash table is setup.
|
||||
if (!mObservers.IsInitialized()) {
|
||||
NS_ENSURE_TRUE(mObservers.Init(), NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// Obtain our array of observers for this URI.
|
||||
KeyClass* key = mObservers.PutEntry(aURI);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_OUT_OF_MEMORY);
|
||||
ObserverArray& observers = key->array;
|
||||
|
||||
if (observers.IsEmpty()) {
|
||||
// We are the first Link node to ask about this URI, or there are no pending
|
||||
// Links wanting to know about this URI. Therefore, we should query the
|
||||
// database now.
|
||||
nsresult rv = VisitedQuery::Start(aURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Curses - unregister and return failure.
|
||||
(void)UnregisterVisitedCallback(aURI, aLink);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check that Links are not registered more than once for a given URI.
|
||||
// This will not catch a case where it is registered for two different URIs.
|
||||
NS_ASSERTION(!observers.Contains(aLink),
|
||||
"Already tracking this Link object!");
|
||||
|
||||
// Start tracking our Link.
|
||||
if (!observers.AppendElement(aLink)) {
|
||||
// Curses - unregister and return failure.
|
||||
(void)UnregisterVisitedCallback(aURI, aLink);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
History::UnregisterVisitedCallback(nsIURI* aURI,
|
||||
Link* aLink)
|
||||
{
|
||||
NS_ASSERTION(aURI, "Must pass a non-null URI!");
|
||||
NS_ASSERTION(aLink, "Must pass a non-null Link object!");
|
||||
|
||||
// Get the array, and remove the item from it.
|
||||
KeyClass* key = mObservers.GetEntry(aURI);
|
||||
if (!key) {
|
||||
NS_ERROR("Trying to unregister for a URI that wasn't registered!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
ObserverArray& observers = key->array;
|
||||
if (!observers.RemoveElement(aLink)) {
|
||||
NS_ERROR("Trying to unregister a node that wasn't registered!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// If the array is now empty, we should remove it from the hashtable.
|
||||
if (observers.IsEmpty()) {
|
||||
mObservers.RemoveEntry(aURI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
History,
|
||||
IHistory
|
||||
)
|
||||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
111
toolkit/components/places/src/History.h
Normal file
111
toolkit/components/places/src/History.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_places_History_h_
|
||||
#define mozilla_places_History_h_
|
||||
|
||||
#include "mozilla/IHistory.h"
|
||||
#include "mozilla/dom/Link.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsURIHashKey.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace places {
|
||||
|
||||
#define NS_HISTORYSERVICE_CID \
|
||||
{0x9fc91e65, 0x1475, 0x4353, {0x9b, 0x9a, 0x93, 0xd7, 0x6f, 0x5b, 0xd9, 0xb7}}
|
||||
|
||||
class History : public IHistory
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IHISTORY
|
||||
|
||||
History();
|
||||
|
||||
/**
|
||||
* Notifies about the visited status of a given URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to notify about.
|
||||
*/
|
||||
void NotifyVisited(nsIURI *aURI);
|
||||
|
||||
/**
|
||||
* Obtains a pointer to this service.
|
||||
*/
|
||||
static History *GetService();
|
||||
|
||||
/**
|
||||
* Obtains a pointer that has had AddRef called on it. Used by the service
|
||||
* manager only.
|
||||
*/
|
||||
static History *GetSingleton();
|
||||
|
||||
private:
|
||||
~History();
|
||||
|
||||
static History *gService;
|
||||
|
||||
typedef nsTArray<mozilla::dom::Link *> ObserverArray;
|
||||
|
||||
class KeyClass : public nsURIHashKey
|
||||
{
|
||||
public:
|
||||
KeyClass(const nsIURI *aURI)
|
||||
: nsURIHashKey(aURI)
|
||||
{
|
||||
}
|
||||
KeyClass(const KeyClass &aOther)
|
||||
: nsURIHashKey(aOther)
|
||||
{
|
||||
NS_NOTREACHED("Do not call me!");
|
||||
}
|
||||
ObserverArray array;
|
||||
};
|
||||
|
||||
nsTHashtable<KeyClass> mObservers;
|
||||
};
|
||||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_places_History_h_
|
@ -64,6 +64,7 @@ CPPSRCS = \
|
||||
nsPlacesModule.cpp \
|
||||
SQLFunctions.cpp \
|
||||
Helpers.cpp \
|
||||
History.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "nsPlacesMacros.h"
|
||||
#include "SQLFunctions.h"
|
||||
#include "Helpers.h"
|
||||
#include "History.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIAutoCompleteInput.h"
|
||||
@ -2800,6 +2801,9 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRTime aTime, nsIURI* aReferringURI,
|
||||
obsService->NotifyObservers(aURI, NS_LINK_VISITED_EVENT_TOPIC, nsnull);
|
||||
}
|
||||
|
||||
// Because we implement IHistory, we always have to notify about the visit.
|
||||
History::GetService()->NotifyVisited(aURI);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -236,6 +236,8 @@ public:
|
||||
mozIStorageStatement *DBGetTags() { return mDBGetTags; }
|
||||
PRInt64 GetTagsFolder();
|
||||
|
||||
mozIStorageStatement *DBGetIsVisited() { return mDBIsPageVisited; }
|
||||
|
||||
// Constants for the columns returned by the above statement
|
||||
// (in addition to the ones above).
|
||||
static const PRInt32 kGetInfoIndex_VisitDate;
|
||||
|
@ -6,8 +6,11 @@
|
||||
#include "nsNavHistory.h"
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsFaviconService.h"
|
||||
#include "History.h"
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
using namespace mozilla::places;
|
||||
|
||||
#define NS_NAVHISTORY_CLASSINFO \
|
||||
nsnull, nsnull, nsnull, \
|
||||
NS_CI_INTERFACE_GETTER_NAME(nsNavHistory), \
|
||||
@ -25,6 +28,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsNavBookmarks,
|
||||
nsNavBookmarks::GetSingleton)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsFaviconService,
|
||||
nsFaviconService::GetSingleton)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(History, History::GetSingleton)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAnnoProtocolHandler)
|
||||
|
||||
@ -74,6 +78,11 @@ static const nsModuleComponentInfo components[] =
|
||||
nsNavHistoryConstructor,
|
||||
NS_NAVHISTORY_CLASSINFO },
|
||||
|
||||
{ "Browser History",
|
||||
NS_HISTORYSERVICE_CID,
|
||||
NS_IHISTORY_CONTRACTID,
|
||||
HistoryConstructor },
|
||||
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(nsPlacesModule, components)
|
||||
|
@ -68,6 +68,10 @@ DIRS = \
|
||||
browser \
|
||||
$(NULL)
|
||||
|
||||
TOOL_DIRS = \
|
||||
cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs:: $(MOCHI_TESTS)
|
||||
|
53
toolkit/components/places/tests/cpp/Makefile.in
Normal file
53
toolkit/components/places/tests/cpp/Makefile.in
Normal file
@ -0,0 +1,53 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Places cpp unit test code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Shawn Wilsher <me@shawnwilsher.com> (Original author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
relativesrcdir = toolkit/components/places/tests/cpp
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = test_places
|
||||
|
||||
CPP_UNIT_TESTS = \
|
||||
test_IHistory.cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
119
toolkit/components/places/tests/cpp/mock_Link.h
Normal file
119
toolkit/components/places/tests/cpp/mock_Link.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is places test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This is a mock Link object which can be used in tests.
|
||||
*/
|
||||
|
||||
#ifndef mock_Link_h__
|
||||
#define mock_Link_h__
|
||||
|
||||
#include "mozilla/dom/Link.h"
|
||||
|
||||
class mock_Link : public mozilla::dom::Link
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
mock_Link(void (*aHandlerFunction)(nsLinkState),
|
||||
bool aRunNextTest = true)
|
||||
: mozilla::dom::Link()
|
||||
, mHandler(aHandlerFunction)
|
||||
, mRunNextTest(aRunNextTest)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetLinkState(nsLinkState aState)
|
||||
{
|
||||
// Notify our callback function.
|
||||
mHandler(aState);
|
||||
|
||||
// Run the next test if we are supposed to.
|
||||
if (mRunNextTest) {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// Finally, we must manually release ourselves.
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
|
||||
private:
|
||||
void (*mHandler)(nsLinkState);
|
||||
bool mRunNextTest;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
mock_Link,
|
||||
mozilla::dom::Link
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Needed Link Methods
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
Link::Link()
|
||||
: mLinkState(mozilla::dom::Link::defaultState)
|
||||
{
|
||||
}
|
||||
|
||||
nsLinkState
|
||||
Link::GetLinkState() const
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::GetLinkState");
|
||||
return eLinkState_Unknown; // suppress compiler warning
|
||||
}
|
||||
|
||||
void
|
||||
Link::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::SetLinkState");
|
||||
}
|
||||
|
||||
void
|
||||
Link::ResetLinkState()
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::ResetLinkState");
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mock_Link_h__
|
123
toolkit/components/places/tests/cpp/places_test_harness.h
Normal file
123
toolkit/components/places/tests/cpp/places_test_harness.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is places test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "TestHarness.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/IHistory.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static size_t gTotalTests = 0;
|
||||
static size_t gPassedTests = 0;
|
||||
|
||||
#define do_check_true(aCondition) \
|
||||
PR_BEGIN_MACRO \
|
||||
gTotalTests++; \
|
||||
if (aCondition) { \
|
||||
gPassedTests++; \
|
||||
} else { \
|
||||
fail("Expected true, got false at %s:%d!", __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define do_check_false(aCondition) \
|
||||
PR_BEGIN_MACRO \
|
||||
gTotalTests++; \
|
||||
if (!aCondition) { \
|
||||
gPassedTests++; \
|
||||
} else { \
|
||||
fail("Expected false, got true at %s:%d!", __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define do_check_success(aResult) \
|
||||
do_check_true(NS_SUCCEEDED(aResult))
|
||||
|
||||
struct Test
|
||||
{
|
||||
void (*func)(void);
|
||||
const char* const name;
|
||||
};
|
||||
#define TEST(aName) \
|
||||
{aName, #aName}
|
||||
|
||||
/**
|
||||
* Runs the next text.
|
||||
*/
|
||||
void run_next_test();
|
||||
|
||||
/**
|
||||
* To be used around asynchronous work.
|
||||
*/
|
||||
void do_test_pending();
|
||||
void do_test_finished();
|
||||
|
||||
/**
|
||||
* Adds a URI to the database.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add to the database.
|
||||
*/
|
||||
void
|
||||
addURI(nsIURI* aURI)
|
||||
{
|
||||
nsCOMPtr<nsINavHistoryService> hist =
|
||||
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
|
||||
|
||||
PRInt64 id;
|
||||
nsresult rv = hist->AddVisit(aURI, PR_Now(), nsnull,
|
||||
nsINavHistoryService::TRANSITION_LINK, PR_FALSE,
|
||||
0, &id);
|
||||
do_check_success(rv);
|
||||
}
|
||||
|
||||
already_AddRefed<IHistory>
|
||||
do_get_IHistory()
|
||||
{
|
||||
nsCOMPtr<IHistory> history = do_GetService(NS_IHISTORY_CONTRACTID);
|
||||
do_check_true(history);
|
||||
return history.forget();
|
||||
}
|
127
toolkit/components/places/tests/cpp/places_test_harness_tail.h
Normal file
127
toolkit/components/places/tests/cpp/places_test_harness_tail.h
Normal file
@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is places test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef TEST_NAME
|
||||
#error "Must #define TEST_NAME before including places_test_harness_tail.h"
|
||||
#endif
|
||||
|
||||
#ifndef TEST_FILE
|
||||
#error "Must #define TEST_FILE before include places_test_harness_tail.h"
|
||||
#endif
|
||||
|
||||
size_t gTestsIndex = 0;
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define SIZE_T "%Iu"
|
||||
#else
|
||||
#define SIZE_T "%zu"
|
||||
#endif
|
||||
|
||||
#define TEST_INFO_STR "TEST-INFO | (%s) | "
|
||||
|
||||
class RunNextTest : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
if (gTestsIndex < NS_ARRAY_LENGTH(gTests)) {
|
||||
do_test_pending();
|
||||
Test &test = gTests[gTestsIndex++];
|
||||
(void)fprintf(stderr, TEST_INFO_STR "Running %s.\n", TEST_FILE,
|
||||
test.name);
|
||||
test.func();
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
run_next_test()
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new RunNextTest();
|
||||
do_check_success(NS_DispatchToCurrentThread(event));
|
||||
}
|
||||
|
||||
size_t gPendingTests = 0;
|
||||
|
||||
void
|
||||
do_test_pending()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
gPendingTests++;
|
||||
}
|
||||
|
||||
void
|
||||
do_test_finished()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
NS_ASSERTION(gPendingTests > 0, "Invalid pending test count!");
|
||||
gPendingTests--;
|
||||
}
|
||||
|
||||
int
|
||||
main(int aArgc,
|
||||
char** aArgv)
|
||||
{
|
||||
ScopedXPCOM xpcom(TEST_NAME);
|
||||
|
||||
do_test_pending();
|
||||
run_next_test();
|
||||
|
||||
// Spin the event loop until we've run out of tests to run.
|
||||
while (gPendingTests) {
|
||||
(void)NS_ProcessNextEvent();
|
||||
}
|
||||
|
||||
// And let any other events finish before we quit.
|
||||
(void)NS_ProcessPendingEvents(nsnull);
|
||||
|
||||
// Check that we have passed all of our tests, and output accordingly.
|
||||
if (gPassedTests == gTotalTests) {
|
||||
passed(TEST_FILE);
|
||||
}
|
||||
|
||||
(void)fprintf(stderr, TEST_INFO_STR SIZE_T " of " SIZE_T " tests passed\n",
|
||||
TEST_FILE, gPassedTests, gTotalTests);
|
||||
|
||||
return gPassedTests == gTotalTests ? 0 : -1;
|
||||
}
|
270
toolkit/components/places/tests/cpp/test_IHistory.cpp
Normal file
270
toolkit/components/places/tests/cpp/test_IHistory.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is places test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "places_test_harness.h"
|
||||
|
||||
#include "mock_Link.h"
|
||||
using namespace mozilla::dom;
|
||||
|
||||
/**
|
||||
* This file tests the IHistory interface.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Helper Methods
|
||||
|
||||
void
|
||||
expect_visit(nsLinkState aState)
|
||||
{
|
||||
do_check_true(aState == eLinkState_Visited);
|
||||
}
|
||||
|
||||
void
|
||||
expect_no_visit(nsLinkState aState)
|
||||
{
|
||||
do_check_true(aState == eLinkState_Unvisited);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
new_test_uri()
|
||||
{
|
||||
// Create a unique spec.
|
||||
static PRInt32 specNumber = 0;
|
||||
nsCAutoString spec = NS_LITERAL_CSTRING("http://mozilla.org/");
|
||||
spec.AppendInt(specNumber++);
|
||||
|
||||
// Create the URI for the spec.
|
||||
nsCOMPtr<nsIURI> testURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(testURI), spec);
|
||||
do_check_success(rv);
|
||||
return testURI.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
// These variables are shared between part 1 and part 2 of the test. Part 2
|
||||
// sets the nsCOMPtr's to nsnull, freeing the reference.
|
||||
namespace test_unvisited_does_not_notify {
|
||||
nsCOMPtr<nsIURI> testURI;
|
||||
nsCOMPtr<Link> link;
|
||||
}
|
||||
void
|
||||
test_unvisted_does_not_notify_part1()
|
||||
{
|
||||
using namespace test_unvisited_does_not_notify;
|
||||
|
||||
// This test is done in two parts. The first part registers for a URI that
|
||||
// should not be visited. We then run another test that will also do a
|
||||
// lookup and will be notified. Since requests are answered in the order they
|
||||
// are requested (at least as long as the same URI isn't asked for later), we
|
||||
// will know that the Link was not notified.
|
||||
|
||||
// First, we need a test URI.
|
||||
testURI = new_test_uri();
|
||||
|
||||
// Create our test Link.
|
||||
link = new mock_Link(expect_no_visit);
|
||||
|
||||
// Now, register our Link to be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Run the next test.
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
void
|
||||
test_visited_notifies()
|
||||
{
|
||||
// First, we add our test URI to history.
|
||||
nsCOMPtr<nsIURI> testURI(new_test_uri());
|
||||
addURI(testURI);
|
||||
|
||||
// Create our test Link. The callback function will release the reference we
|
||||
// have on the Link.
|
||||
Link* link = new mock_Link(expect_visit);
|
||||
NS_ADDREF(link);
|
||||
|
||||
// Now, register our Link to be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
// Note: test will continue upon notification.
|
||||
}
|
||||
|
||||
void
|
||||
test_unvisted_does_not_notify_part2()
|
||||
{
|
||||
using namespace test_unvisited_does_not_notify;
|
||||
|
||||
// We would have had a failure at this point had the content node been told it
|
||||
// was visited. Therefore, it is safe to unregister our content node.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->UnregisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Clear the stored variables now.
|
||||
testURI = nsnull;
|
||||
link = nsnull;
|
||||
|
||||
// Run the next test.
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
void
|
||||
test_same_uri_notifies_both()
|
||||
{
|
||||
// First, we add our test URI to history.
|
||||
nsCOMPtr<nsIURI> testURI(new_test_uri());
|
||||
addURI(testURI);
|
||||
|
||||
// Create our two test Links. The callback function will release the
|
||||
// reference we have on the Links. Only the second Link should run the next
|
||||
// test!
|
||||
Link* link1 = new mock_Link(expect_visit, false);
|
||||
NS_ADDREF(link1);
|
||||
Link* link2 = new mock_Link(expect_visit);
|
||||
NS_ADDREF(link2);
|
||||
|
||||
// Now, register our Link to be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link1);
|
||||
do_check_success(rv);
|
||||
rv = history->RegisterVisitedCallback(testURI, link2);
|
||||
do_check_success(rv);
|
||||
|
||||
// Note: test will continue upon notification.
|
||||
}
|
||||
|
||||
void
|
||||
test_unregistered_visited_does_not_notify()
|
||||
{
|
||||
// This test must have a test that has a successful notification after it.
|
||||
// The Link would have been notified by now if we were buggy and notified
|
||||
// unregistered Links (due to request serialization).
|
||||
|
||||
nsCOMPtr<nsIURI> testURI(new_test_uri());
|
||||
nsCOMPtr<Link> link(new mock_Link(expect_no_visit));
|
||||
|
||||
// Now, register our Link to be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Unregister the Link.
|
||||
rv = history->UnregisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// And finally add a visit for the URI.
|
||||
addURI(testURI);
|
||||
|
||||
// If history tries to notify us, we'll either crash because the Link will
|
||||
// have been deleted (we are the only thing holding a reference to it), or our
|
||||
// expect_no_visit call back will produce a failure. Either way, the test
|
||||
// will be reported as a failure.
|
||||
|
||||
// Run the next test.
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
void
|
||||
test_new_visit_notifies_waiting_Link()
|
||||
{
|
||||
// Create our test Link. The callback function will release the reference we
|
||||
// have on the link.
|
||||
Link* link = new mock_Link(expect_visit);
|
||||
NS_ADDREF(link);
|
||||
|
||||
// Now, register our content node to be notified.
|
||||
nsCOMPtr<nsIURI> testURI(new_test_uri());
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Add ourselves to history.
|
||||
addURI(testURI);
|
||||
|
||||
// Note: test will continue upon notification.
|
||||
}
|
||||
|
||||
void
|
||||
test_RegisterVisitedCallback_returns_before_notifying()
|
||||
{
|
||||
// Add a URI so that it's already in history.
|
||||
nsCOMPtr<nsIURI> testURI(new_test_uri());
|
||||
addURI(testURI);
|
||||
|
||||
// Create our test Link.
|
||||
nsCOMPtr<Link> link(new mock_Link(expect_no_visit));
|
||||
|
||||
// Now, register our content node to be notified. It should not be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Remove ourselves as an observer. We would have failed if we had been
|
||||
// notified.
|
||||
rv = history->UnregisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Harness
|
||||
|
||||
/**
|
||||
* Note: for tests marked "Order Important!", please see the test for details.
|
||||
*/
|
||||
Test gTests[] = {
|
||||
TEST(test_unvisted_does_not_notify_part1), // Order Important!
|
||||
TEST(test_visited_notifies),
|
||||
TEST(test_unvisted_does_not_notify_part2), // Order Important!
|
||||
TEST(test_same_uri_notifies_both),
|
||||
TEST(test_unregistered_visited_does_not_notify), // Order Important!
|
||||
TEST(test_new_visit_notifies_waiting_Link),
|
||||
TEST(test_RegisterVisitedCallback_returns_before_notifying),
|
||||
};
|
||||
|
||||
const char* file = __FILE__;
|
||||
#define TEST_NAME "IHistory"
|
||||
#define TEST_FILE file
|
||||
#include "places_test_harness_tail.h"
|
Loading…
x
Reference in New Issue
Block a user