move the offline cache update logic from the content sink and prefetch service into an nsOfflineCacheUpdate object. bug=388839, r=biesi, sr=jst

This commit is contained in:
dcamp@mozilla.com 2007-07-24 22:35:39 -07:00
Родитель 319fc3fbe1
Коммит e6fea393ca
21 изменённых файлов: 1744 добавлений и 299 удалений

Просмотреть файл

@ -45,6 +45,7 @@
#include "nsContentSink.h"
#include "nsScriptLoader.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsICSSLoader.h"
#include "nsStyleConsts.h"
#include "nsStyleLinkElement.h"
@ -72,7 +73,8 @@
#include "nsICache.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsIOfflineCacheSession.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIDOMLoadStatus.h"
#include "nsICookieService.h"
#include "nsIPrompt.h"
#include "nsServiceManagerUtils.h"
@ -679,14 +681,12 @@ nsContentSink::ProcessLink(nsIContent* aElement,
PRBool hasPrefetch = (linkTypes.IndexOf(NS_LITERAL_STRING("prefetch")) != -1);
// prefetch href if relation is "next" or "prefetch"
if (hasPrefetch || linkTypes.IndexOf(NS_LITERAL_STRING("next")) != -1) {
PrefetchHref(aHref, aElement, hasPrefetch, PR_FALSE);
PrefetchHref(aHref, aElement, hasPrefetch);
}
// fetch href into the offline cache if relation is "offline-resource"
if (linkTypes.IndexOf(NS_LITERAL_STRING("offline-resource")) != -1) {
AddOfflineResource(aHref);
if (mSaveOfflineResources)
PrefetchHref(aHref, aElement, PR_TRUE, PR_TRUE);
AddOfflineResource(aHref, aElement);
}
// is it a stylesheet link?
@ -771,8 +771,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
void
nsContentSink::PrefetchHref(const nsAString &aHref,
nsIContent *aSource,
PRBool aExplicit,
PRBool aOffline)
PRBool aExplicit)
{
//
// SECURITY CHECK: disable prefetching from mailnews!
@ -816,45 +815,13 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
mDocumentBaseURI);
if (uri) {
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
if (aOffline)
prefetchService->PrefetchURIForOfflineUse(uri,
mDocumentURI,
domNode,
aExplicit);
else
prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
prefetchService->PrefetchURI(uri, mDocumentURI, domNode, aExplicit);
}
}
}
nsresult
nsContentSink::GetOfflineCacheSession(nsIOfflineCacheSession **aSession)
{
if (!mOfflineCacheSession) {
nsresult rv;
nsCOMPtr<nsICacheService> serv =
do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICacheSession> session;
rv = serv->CreateSession("HTTP-offline",
nsICache::STORE_OFFLINE,
nsICache::STREAM_BASED,
getter_AddRefs(session));
NS_ENSURE_SUCCESS(rv, rv);
mOfflineCacheSession =
do_QueryInterface(session, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ADDREF(*aSession = mOfflineCacheSession);
return NS_OK;
}
nsresult
nsContentSink::AddOfflineResource(const nsAString &aHref)
nsContentSink::AddOfflineResource(const nsAString &aHref, nsIContent *aSource)
{
PRBool match;
nsresult rv;
@ -863,17 +830,8 @@ nsContentSink::AddOfflineResource(const nsAString &aHref)
if (!innerURI)
return NS_ERROR_FAILURE;
nsCAutoString ownerHost;
rv = innerURI->GetHostPort(ownerHost);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString ownerSpec;
rv = mDocumentURI->GetSpec(ownerSpec);
NS_ENSURE_SUCCESS(rv, rv);
if (!mHaveOfflineResources) {
mHaveOfflineResources = PR_TRUE;
mSaveOfflineResources = PR_FALSE;
// only let http and https urls add offline resources
nsresult rv = innerURI->SchemeIs("http", &match);
@ -886,18 +844,29 @@ nsContentSink::AddOfflineResource(const nsAString &aHref)
return NS_OK;
}
nsCOMPtr<nsIOfflineCacheSession> session;
rv = GetOfflineCacheSession(getter_AddRefs(session));
// create updater
mOfflineCacheUpdate =
do_CreateInstance(NS_OFFLINECACHEUPDATE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// we're going to replace the list, clear it out
rv = session->SetOwnedKeys(ownerHost, ownerSpec, 0, nsnull);
nsCAutoString ownerDomain;
rv = innerURI->GetHostPort(ownerDomain);
NS_ENSURE_SUCCESS(rv, rv);
mSaveOfflineResources = PR_TRUE;
nsCAutoString ownerSpec;
rv = mDocumentURI->GetSpec(ownerSpec);
NS_ENSURE_SUCCESS(rv, rv);
rv = mOfflineCacheUpdate->Init(PR_FALSE, ownerDomain,
ownerSpec, mDocumentURI);
NS_ENSURE_SUCCESS(rv, rv);
// Kick off this update when the document is done loading
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(mDocument);
mOfflineCacheUpdate->ScheduleOnDocumentStop(doc);
}
if (!mSaveOfflineResources) return NS_OK;
if (!mOfflineCacheUpdate) return NS_OK;
const nsACString &charset = mDocument->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
@ -906,38 +875,9 @@ nsContentSink::AddOfflineResource(const nsAString &aHref)
mDocumentBaseURI);
NS_ENSURE_SUCCESS(rv, rv);
// only http and https urls can be marked as offline resources
rv = uri->SchemeIs("http", &match);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aSource);
if (!match) {
rv = uri->SchemeIs("https", &match);
NS_ENSURE_SUCCESS(rv, rv);
if (!match)
return NS_OK;
}
nsCAutoString spec;
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIOfflineCacheSession> offlineCacheSession;
rv = GetOfflineCacheSession(getter_AddRefs(offlineCacheSession));
NS_ENSURE_SUCCESS(rv, rv);
// url fragments aren't used in cache keys
nsCAutoString::const_iterator specStart, specEnd;
spec.BeginReading(specStart);
spec.EndReading(specEnd);
if (FindCharInReadable('#', specStart, specEnd)) {
spec.BeginReading(specEnd);
offlineCacheSession->AddOwnedKey(ownerHost, ownerSpec,
Substring(specEnd, specStart));
} else {
offlineCacheSession->AddOwnedKey(ownerHost, ownerSpec, spec);
}
return NS_OK;
return mOfflineCacheUpdate->AddURI(uri, domNode);
}
void

Просмотреть файл

@ -75,7 +75,7 @@ class nsIContent;
class nsIViewManager;
class nsNodeInfoManager;
class nsScriptLoader;
class nsIOfflineCacheSession;
class nsIOfflineCacheUpdate;
#ifdef NS_DEBUG
@ -168,9 +168,8 @@ protected:
const nsSubstring& aMedia);
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
PRBool aExplicit, PRBool aOffline);
nsresult GetOfflineCacheSession(nsIOfflineCacheSession **aSession);
nsresult AddOfflineResource(const nsAString &aHref);
PRBool aExplicit);
nsresult AddOfflineResource(const nsAString &aHref, nsIContent *aSource);
void ScrollToRef();
nsresult RefreshIfEnabled(nsIViewManager* vm);
@ -262,7 +261,7 @@ protected:
PRPackedBool mNotifyOnTimer;
// For saving <link rel="offline-resource"> links
nsCOMPtr<nsIOfflineCacheSession> mOfflineCacheSession;
nsCOMPtr<nsIOfflineCacheUpdate> mOfflineCacheUpdate;
// Have we already called BeginUpdate for this set of content changes?
PRUint8 mBeganUpdate : 1;
@ -278,8 +277,6 @@ protected:
PRUint8 mDeferredLayoutStart : 1;
// true if an <link rel="offline-resource"> nodes have been encountered.
PRUint8 mHaveOfflineResources : 1;
// true if offline-resource links should be saved to the offline cache
PRUint8 mSaveOfflineResources : 1;
// If true, we deferred notifications until sheets load
PRUint8 mDeferredFlushTags : 1;

Просмотреть файл

@ -3005,16 +3005,14 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
nsAutoString hrefVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchHref(hrefVal, element, hasPrefetch, PR_FALSE);
PrefetchHref(hrefVal, element, hasPrefetch);
}
}
if (linkTypes.IndexOf(NS_LITERAL_STRING("offline-resource")) != -1) {
nsAutoString hrefVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
AddOfflineResource(hrefVal);
if (mSaveOfflineResources)
PrefetchHref(hrefVal, element, PR_TRUE, PR_TRUE);
AddOfflineResource(hrefVal, element);
}
}
}

Просмотреть файл

@ -60,6 +60,7 @@ REQUIRES = xpcom \
js \
shistory \
necko \
nkcache \
gfx \
content \
layout \

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsOSHelperAppService.h"
#include "nsExternalProtocolHandler.h"
#include "nsPrefetchService.h"
#include "nsOfflineCacheUpdate.h"
#include "nsHandlerAppImpl.h"
// session history
@ -100,6 +101,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsOSHelperAppService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlockedExternalProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefetchService, Init)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheUpdateService,
nsOfflineCacheUpdateService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLocalHandlerApp)
#if defined(XP_MAC) || defined(XP_MACOSX)
@ -205,6 +209,10 @@ static const nsModuleComponentInfo gDocShellModuleInfo[] = {
nsBlockedExternalProtocolHandlerConstructor, },
{ NS_PREFETCHSERVICE_CLASSNAME, NS_PREFETCHSERVICE_CID, NS_PREFETCHSERVICE_CONTRACTID,
nsPrefetchServiceConstructor, },
{ NS_OFFLINECACHEUPDATESERVICE_CLASSNAME, NS_OFFLINECACHEUPDATESERVICE_CID, NS_OFFLINECACHEUPDATESERVICE_CONTRACTID,
nsOfflineCacheUpdateServiceConstructor, },
{ NS_OFFLINECACHEUPDATE_CLASSNAME, NS_OFFLINECACHEUPDATE_CID, NS_OFFLINECACHEUPDATE_CONTRACTID,
nsOfflineCacheUpdateConstructor, },
{ "Local Application Handler App", NS_LOCALHANDLERAPP_CID,
NS_LOCALHANDLERAPP_CONTRACTID, nsLocalHandlerAppConstructor, },
#if defined(XP_MAC) || defined(XP_MACOSX)

Просмотреть файл

@ -66,6 +66,7 @@ REQUIRES = xpcom \
java \
locale \
uriloader \
prefetch \
xuldoc \
webshell \
view \

Просмотреть файл

@ -154,6 +154,7 @@ NS_INTERFACE_MAP_BEGIN(nsDOMOfflineLoadStatusList)
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadStatusList)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIOfflineCacheUpdateObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(LoadStatusList)
NS_INTERFACE_MAP_END
@ -185,114 +186,31 @@ nsDOMOfflineLoadStatusList::Init()
nsresult rv = mURI->GetHostPort(mHostPort);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICacheService> serv =
do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
nsCOMPtr<nsIOfflineCacheUpdateService> cacheUpdateService =
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICacheSession> session;
rv = serv->CreateSession("HTTP-offline",
nsICache::STORE_OFFLINE,
nsICache::STREAM_BASED,
getter_AddRefs(session));
PRUint32 numUpdates;
rv = cacheUpdateService->GetNumUpdates(&numUpdates);
NS_ENSURE_SUCCESS(rv, rv);
mCacheSession = do_QueryInterface(session, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// get the current list of loads from the prefetch queue
nsCOMPtr<nsIPrefetchService> prefetchService =
do_GetService(NS_PREFETCHSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> e;
rv = prefetchService->EnumerateQueue(PR_FALSE, PR_TRUE, getter_AddRefs(e));
NS_ENSURE_SUCCESS(rv, rv);
PRBool more;
while (NS_SUCCEEDED(rv = e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIDOMLoadStatus> status;
rv = e->GetNext(getter_AddRefs(status));
for (PRUint32 i = 0; i < numUpdates; i++) {
nsCOMPtr<nsIOfflineCacheUpdate> cacheUpdate;
rv = cacheUpdateService->GetUpdate(i, getter_AddRefs(cacheUpdate));
NS_ENSURE_SUCCESS(rv, rv);
PRBool shouldInclude;
rv = ShouldInclude(status, &shouldInclude);
rv = WatchUpdate(cacheUpdate);
NS_ENSURE_SUCCESS(rv, rv);
if (!shouldInclude) {
continue;
}
nsDOMOfflineLoadStatus *wrapper = new nsDOMOfflineLoadStatus(status);
if (!wrapper) return NS_ERROR_OUT_OF_MEMORY;
mItems.AppendObject(wrapper);
}
NS_ENSURE_SUCCESS(rv, rv);
// watch for changes in the prefetch queue
// watch for new offline cache updates
nsCOMPtr<nsIObserverService> observerServ =
do_GetService("@mozilla.org/observer-service;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = observerServ->AddObserver(this, "offline-load-requested", PR_TRUE);
rv = observerServ->AddObserver(this, "offline-cache-update-added", PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
rv = observerServ->AddObserver(this, "offline-load-completed", PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsDOMOfflineLoadStatusList::ShouldInclude(nsIDOMLoadStatus *aStatus,
PRBool *aShouldInclude)
{
*aShouldInclude = PR_FALSE;
nsAutoString uriStr;
nsresult rv = aStatus->GetUri(uriStr);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriStr);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString hostport;
rv = uri->GetHostPort(hostport);
NS_ENSURE_SUCCESS(rv, rv);
if (hostport != mHostPort)
return NS_OK;
// Check that the URL is owned by this domain
nsCAutoString spec;
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> source;
rv = aStatus->GetSource(getter_AddRefs(source));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString ownerURI;
if (source) {
// Came from a <link> element, check that it's owned by this URI
rv = mURI->GetSpec(ownerURI);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// Didn't come from a <link> element, check that it's owned by
// resource list (no owner URI)
ownerURI.Truncate();
}
PRBool owned;
rv = mCacheSession->KeyIsOwned(mHostPort, ownerURI, spec, &owned);
NS_ENSURE_SUCCESS(rv, rv);
if (!owned) {
return NS_OK;
}
*aShouldInclude = PR_TRUE;
return NS_OK;
}
@ -312,6 +230,45 @@ nsDOMOfflineLoadStatusList::FindWrapper(nsIDOMLoadStatus *aStatus,
return nsnull;
}
nsresult
nsDOMOfflineLoadStatusList::WatchUpdate(nsIOfflineCacheUpdate *aUpdate)
{
nsCAutoString owner;
nsresult rv = aUpdate->GetUpdateDomain(owner);
NS_ENSURE_SUCCESS(rv, rv);
if (owner != mHostPort) {
// This update doesn't belong to us
return NS_OK;
}
PRUint32 numItems;
rv = aUpdate->GetCount(&numItems);
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < numItems; i++) {
nsCOMPtr<nsIDOMLoadStatus> status;
rv = aUpdate->Item(i, getter_AddRefs(status));
NS_ENSURE_SUCCESS(rv, rv);
nsDOMOfflineLoadStatus *wrapper = new nsDOMOfflineLoadStatus(status);
if (!wrapper) return NS_ERROR_OUT_OF_MEMORY;
mItems.AppendObject(wrapper);
rv = SendLoadEvent(NS_LITERAL_STRING(LOADREQUESTED_STR),
mLoadRequestedEventListeners,
wrapper);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ENSURE_SUCCESS(rv, rv);
rv = aUpdate->AddObserver(this, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
//
// nsDOMOfflineLoadStatusList::nsIDOMLoadStatusList
//
@ -508,39 +465,32 @@ nsDOMOfflineLoadStatusList::Observe(nsISupports *aSubject,
const PRUnichar *aData)
{
nsresult rv;
if (!strcmp(aTopic, "offline-load-requested")) {
nsCOMPtr<nsIDOMLoadStatus> status = do_QueryInterface(aSubject);
if (status) {
PRBool shouldInclude;
rv = ShouldInclude(status, &shouldInclude);
NS_ENSURE_SUCCESS(rv, rv);
if (!shouldInclude) return NS_OK;
nsDOMOfflineLoadStatus *wrapper = new nsDOMOfflineLoadStatus(status);
if (!wrapper) return NS_ERROR_OUT_OF_MEMORY;
mItems.AppendObject(wrapper);
rv = SendLoadEvent(NS_LITERAL_STRING(LOADREQUESTED_STR),
mLoadRequestedEventListeners,
wrapper);
if (!strcmp(aTopic, "offline-cache-update-added")) {
nsCOMPtr<nsIOfflineCacheUpdate> update = do_QueryInterface(aSubject);
if (update) {
rv = WatchUpdate(update);
NS_ENSURE_SUCCESS(rv, rv);
}
} else if (!strcmp(aTopic, "offline-load-completed")) {
nsCOMPtr<nsIDOMLoadStatus> status = do_QueryInterface(aSubject);
if (status) {
PRUint32 index;
nsCOMPtr<nsIDOMLoadStatus> wrapper = FindWrapper(status, &index);
if (wrapper) {
mItems.RemoveObjectAt(index);
}
rv = SendLoadEvent(NS_LITERAL_STRING(LOADCOMPLETED_STR),
mLoadCompletedEventListeners,
wrapper);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
//
// nsDOMLoadStatusList::nsIOfflineCacheUpdateObserver
//
NS_IMETHODIMP
nsDOMOfflineLoadStatusList::ItemCompleted(nsIDOMLoadStatus *aItem)
{
PRUint32 index;
nsCOMPtr<nsIDOMLoadStatus> wrapper = FindWrapper(aItem, &index);
if (wrapper) {
mItems.RemoveObjectAt(index);
nsresult rv = SendLoadEvent(NS_LITERAL_STRING(LOADCOMPLETED_STR),
mLoadCompletedEventListeners,
wrapper);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;

Просмотреть файл

@ -43,7 +43,7 @@
#include "nsIDOMLoadStatus.h"
#include "nsIDOMLoadStatusEvent.h"
#include "nsIDOMLoadStatusList.h"
#include "nsIOfflineCacheSession.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsIURI.h"
@ -59,6 +59,7 @@ class nsDOMOfflineLoadStatus;
class nsDOMOfflineLoadStatusList : public nsIDOMLoadStatusList,
public nsIDOMEventTarget,
public nsIObserver,
public nsIOfflineCacheUpdateObserver,
public nsSupportsWeakReference
{
public:
@ -66,6 +67,7 @@ public:
NS_DECL_NSIDOMLOADSTATUSLIST
NS_DECL_NSIDOMEVENTTARGET
NS_DECL_NSIOBSERVER
NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
nsDOMOfflineLoadStatusList(nsIURI *aURI);
virtual ~nsDOMOfflineLoadStatusList();
@ -73,8 +75,7 @@ public:
nsresult Init();
private :
nsresult ShouldInclude (nsIDOMLoadStatus *aStatus,
PRBool *aInclude);
nsresult WatchUpdate (nsIOfflineCacheUpdate *aUpdate);
nsIDOMLoadStatus *FindWrapper (nsIDOMLoadStatus *aStatus,
PRUint32 *aIndex);
void NotifyEventListeners(const nsCOMArray<nsIDOMEventListener>& aListeners,
@ -89,7 +90,6 @@ private :
nsCOMPtr<nsIURI> mURI;
nsCOMArray<nsIDOMLoadStatus> mItems;
nsCString mHostPort;
nsCOMPtr<nsIOfflineCacheSession> mCacheSession;
nsCOMPtr<nsIScriptContext> mScriptContext;

Просмотреть файл

@ -46,6 +46,8 @@
#include "nsICacheSession.h"
#include "nsICacheService.h"
#include "nsIOfflineCacheSession.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIDOMLoadStatus.h"
#include "nsAutoPtr.h"
#include "nsContentUtils.h"
@ -165,16 +167,6 @@ nsDOMOfflineResourceList::Add(const nsAString& aURI)
rv = NS_NewURI(getter_AddRefs(requestedURI), aURI);
NS_ENSURE_SUCCESS(rv, rv);
// only http/https urls will work offline
PRBool match;
rv = requestedURI->SchemeIs("http", &match);
NS_ENSURE_SUCCESS(rv, rv);
if (!match) {
rv = requestedURI->SchemeIs("https", &match);
NS_ENSURE_SUCCESS(rv, rv);
if (!match) return NS_ERROR_DOM_BAD_URI;
}
PRUint32 length;
rv = GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
@ -185,23 +177,20 @@ nsDOMOfflineResourceList::Add(const nsAString& aURI)
ClearCachedKeys();
nsCAutoString key;
rv = GetCacheKey(requestedURI, key);
nsCOMPtr<nsIOfflineCacheUpdate> update =
do_CreateInstance(NS_OFFLINECACHEUPDATE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mCacheSession->AddOwnedKey(mHostPort,
NS_LITERAL_CSTRING(""),
key);
rv = update->Init(PR_TRUE, mHostPort, NS_LITERAL_CSTRING(""), mURI);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrefetchService> prefetchService =
do_GetService(NS_PREFETCHSERVICE_CONTRACTID, &rv);
rv = update->AddURI(requestedURI, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
return prefetchService->PrefetchURIForOfflineUse(requestedURI,
mURI,
nsnull,
PR_TRUE);
rv = update->Schedule();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
@ -254,28 +243,17 @@ nsDOMOfflineResourceList::Refresh()
nsresult rv = Init();
NS_ENSURE_SUCCESS(rv, rv);
rv = CacheKeys();
nsCOMPtr<nsIOfflineCacheUpdate> update =
do_CreateInstance(NS_OFFLINECACHEUPDATE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// try to start fetching it now, but it's not fatal if it fails
nsCOMPtr<nsIPrefetchService> prefetchService =
do_GetService(NS_PREFETCHSERVICE_CONTRACTID, &rv);
rv = update->Init(PR_FALSE, mHostPort, NS_LITERAL_CSTRING(""), mURI);
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < gCachedKeysCount; i++) {
// this will fail if the URI is not absolute
nsCOMPtr<nsIURI> requestedURI;
nsresult rv = NS_NewURI(getter_AddRefs(requestedURI), gCachedKeys[i]);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->Schedule();
NS_ENSURE_SUCCESS(rv, rv);
rv = prefetchService->PrefetchURIForOfflineUse(requestedURI,
mURI,
nsnull,
PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
return rv;
}
nsresult

Просмотреть файл

@ -104,10 +104,6 @@ function run_test()
load_completed,
false);
// The <link rel="offline-resource"> should already be in the queue
ok(navigator.pendingOfflineLoads.length == 2,
"<link rel=\"offline-resource\"> loads should already be in the queue");
for (var i = 0; i < navigator.pendingOfflineLoads.length; i++) {
var load = navigator.pendingOfflineLoads[i];
check_load_added(navigator.pendingOfflineLoads[i]);

Просмотреть файл

@ -40,7 +40,7 @@
#include "nsISupports.idl"
#include "nsICache.idl"
[scriptable, uuid(e9581d9f-3c0c-4722-8d2b-3d18f8d41299)]
[scriptable, uuid(0058c32b-0d93-4cf8-a561-e6f749c8a7b1)]
interface nsIOfflineCacheSession : nsISupports
{
/**
@ -66,6 +66,26 @@ interface nsIOfflineCacheSession : nsISupports
* the domain.
*/
/**
* Gets the list of owner domains in the cache.
*
* @param count The number of domains returned
* @param uris The domains that own resources in the cache
*/
void getOwnerDomains(out unsigned long count,
[array, size_is(count)]out string domains);
/**
* Gets the list of owner URIs associated with a domain.
*
* @param ownerDomain The domain to query
* @param count The number of uris returned
* @param uris The uris in this domain that own resources
*/
void getOwnerURIs(in ACString ownerDomain,
out unsigned long count,
[array, size_is(count)]out string uris);
/**
* Sets the resources owned by a given domain/URI pair.
*

43
netwerk/cache/src/nsCacheService.cpp поставляемый
Просмотреть файл

@ -830,6 +830,49 @@ nsCacheService::IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy storagePo
return PR_FALSE;
}
nsresult nsCacheService::GetOfflineOwnerDomains(nsCacheSession * session,
PRUint32 * count,
char *** domains)
{
#ifdef NECKO_OFFLINE_CACHE
if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
return NS_ERROR_NOT_AVAILABLE;
if (!gService->mOfflineDevice) {
nsresult rv = gService->CreateOfflineDevice();
if (NS_FAILED(rv)) return rv;
}
return gService->mOfflineDevice->GetOwnerDomains(session->ClientID()->get(),
count, domains);
#else // !NECKO_OFFLINE_CACHE
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
nsresult nsCacheService::GetOfflineOwnerURIs(nsCacheSession * session,
const nsACString & ownerDomain,
PRUint32 * count,
char *** uris)
{
#ifdef NECKO_OFFLINE_CACHE
if (session->StoragePolicy() != nsICache::STORE_OFFLINE)
return NS_ERROR_NOT_AVAILABLE;
if (!gService->mOfflineDevice) {
nsresult rv = gService->CreateOfflineDevice();
if (NS_FAILED(rv)) return rv;
}
return gService->mOfflineDevice->GetOwnerURIs(session->ClientID()->get(),
ownerDomain, count, uris);
#else // !NECKO_OFFLINE_CACHE
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
nsresult
nsCacheService::SetOfflineOwnedKeys(nsCacheSession * session,
const nsACString & ownerDomain,

8
netwerk/cache/src/nsCacheService.h поставляемый
Просмотреть файл

@ -98,6 +98,14 @@ public:
PRBool * result);
static nsresult GetOfflineOwnerDomains(nsCacheSession * session,
PRUint32 * count,
char *** domains);
static nsresult GetOfflineOwnerURIs(nsCacheSession * session,
const nsACString & ownerDomain,
PRUint32 * count,
char *** uris);
static nsresult SetOfflineOwnedKeys(nsCacheSession * session,
const nsACString & ownerDomain,
const nsACString & ownerUri,

13
netwerk/cache/src/nsCacheSession.cpp поставляемый
Просмотреть файл

@ -136,6 +136,19 @@ NS_IMETHODIMP nsCacheSession::IsStorageEnabled(PRBool *result)
return nsCacheService::IsStorageEnabledForPolicy(StoragePolicy(), result);
}
NS_IMETHODIMP nsCacheSession::GetOwnerDomains(PRUint32 * count,
char *** domains)
{
return nsCacheService::GetOfflineOwnerDomains(this, count, domains);
}
NS_IMETHODIMP nsCacheSession::GetOwnerURIs(const nsACString & domain,
PRUint32 * count,
char *** uris)
{
return nsCacheService::GetOfflineOwnerURIs(this, domain, count, uris);
}
NS_IMETHODIMP nsCacheSession::SetOwnedKeys(const nsACString & domain,
const nsACString & uri,
PRUint32 count,

106
netwerk/cache/src/nsDiskCacheDeviceSQL.cpp поставляемый
Просмотреть файл

@ -789,7 +789,9 @@ nsOfflineCacheDevice::Init()
StatementSql ( mStatement_AddOwnership, "INSERT INTO moz_cache_owners (ClientID, Domain, URI, Key) VALUES (?, ?, ?, ?);" ),
StatementSql ( mStatement_CheckOwnership, "SELECT Key From moz_cache_owners WHERE ClientID = ? AND Domain = ? AND URI = ? AND Key = ?;" ),
StatementSql ( mStatement_ListOwned, "SELECT Key FROM moz_cache_owners WHERE ClientID = ? AND Domain = ? AND URI = ?;" ),
StatementSql ( mStatement_DeleteUnowned, "DELETE FROM moz_cache WHERE rowid IN (SELECT moz_cache.rowid FROM moz_cache LEFT OUTER JOIN moz_cache_owners ON (moz_cache.ClientID = moz_cache_owners.ClientID AND moz_cache.Key = moz_cache_owners.Key) WHERE moz_cache.ClientID = ? AND moz_cache_owners.Domain ISNULL);" ),
StatementSql ( mStatement_ListOwnerDomains, "SELECT DISTINCT Domain FROM moz_cache_owners WHERE ClientID = ?;"),
StatementSql ( mStatement_ListOwnerURIs, "SELECT DISTINCT URI FROM moz_cache_owners WHERE ClientID = ? AND Domain = ?;"),
StatementSql ( mStatement_DeleteUnowned, "DELETE FROM moz_cache WHERE rowid IN (SELECT moz_cache.rowid FROM moz_cache LEFT OUTER JOIN moz_cache_owners ON (moz_cache.ClientID = moz_cache_owners.ClientID AND moz_cache.Key = moz_cache_owners.Key) WHERE moz_cache.ClientID = ? AND moz_cache_owners.Domain ISNULL);" )
};
for (PRUint32 i=0; i<NS_ARRAY_LENGTH(prepared); ++i)
{
@ -1251,6 +1253,77 @@ nsOfflineCacheDevice::EvictEntries(const char *clientID)
return NS_OK;
}
nsresult
nsOfflineCacheDevice::RunSimpleQuery(mozIStorageStatement * statement,
PRUint32 resultIndex,
PRUint32 * count,
char *** values)
{
PRBool hasRows;
nsresult rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsCString> valArray;
while (hasRows)
{
PRUint32 length;
valArray.AppendElement(
nsDependentCString(statement->AsSharedUTF8String(resultIndex, &length)));
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
}
*count = valArray.Length();
char **ret = static_cast<char **>(NS_Alloc(*count * sizeof(char*)));
if (!ret) return NS_ERROR_OUT_OF_MEMORY;
for (PRUint32 i = 0; i < *count; i++) {
ret[i] = NS_strdup(valArray[i].get());
if (!ret[i]) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, ret);
return NS_ERROR_OUT_OF_MEMORY;
}
}
*values = ret;
return NS_OK;
}
nsresult
nsOfflineCacheDevice::GetOwnerDomains(const char * clientID,
PRUint32 * count,
char *** domains)
{
LOG(("nsOfflineCacheDevice::GetOwnerDomains [cid=%s]\n", clientID));
AutoResetStatement statement(mStatement_ListOwnerDomains);
nsresult rv = statement->BindUTF8StringParameter(
0, nsDependentCString(clientID));
NS_ENSURE_SUCCESS(rv, rv);
return RunSimpleQuery(mStatement_ListOwnerDomains, 0, count, domains);
}
nsresult
nsOfflineCacheDevice::GetOwnerURIs(const char * clientID,
const nsACString & ownerDomain,
PRUint32 * count,
char *** domains)
{
LOG(("nsOfflineCacheDevice::GetOwnerURIs [cid=%s]\n", clientID));
AutoResetStatement statement(mStatement_ListOwnerURIs);
nsresult rv = statement->BindUTF8StringParameter(
0, nsDependentCString(clientID));
rv = statement->BindUTF8StringParameter(
1, ownerDomain);
NS_ENSURE_SUCCESS(rv, rv);
return RunSimpleQuery(mStatement_ListOwnerURIs, 0, count, domains);
}
nsresult
nsOfflineCacheDevice::SetOwnedKeys(const char * clientID,
const nsACString & ownerDomain,
@ -1305,36 +1378,7 @@ nsOfflineCacheDevice::GetOwnedKeys(const char * clientID,
rv |= statement->BindUTF8StringParameter(2, ownerURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasRows;
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsCString> keyArray;
while (hasRows)
{
PRUint32 length;
keyArray.AppendElement(
nsDependentCString(statement->AsSharedUTF8String(0, &length)));
rv = statement->ExecuteStep(&hasRows);
NS_ENSURE_SUCCESS(rv, rv);
}
*count = keyArray.Length();
char **ret = static_cast<char **>(NS_Alloc(*count * sizeof(char*)));
if (!ret) return NS_ERROR_OUT_OF_MEMORY;
for (PRUint32 i = 0; i < *count; i++) {
ret[i] = NS_strdup(keyArray[i].get());
if (!ret[i]) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, ret);
return NS_ERROR_OUT_OF_MEMORY;
}
}
*keys = ret;
return NS_OK;
return RunSimpleQuery(mStatement_ListOwned, 0, count, keys);
}
nsresult

13
netwerk/cache/src/nsDiskCacheDeviceSQL.h поставляемый
Просмотреть файл

@ -86,6 +86,13 @@ public:
/* Entry ownership */
nsresult GetOwnerDomains(const char * clientID,
PRUint32 * count,
char *** domains);
nsresult GetOwnerURIs(const char * clientID,
const nsACString & ownerDomain,
PRUint32 * count,
char *** uris);
nsresult SetOwnedKeys(const char * clientID,
const nsACString & ownerDomain,
const nsACString & ownerUrl,
@ -135,6 +142,10 @@ private:
nsresult DeleteData(nsCacheEntry *entry);
nsresult EnableEvictionObserver();
nsresult DisableEvictionObserver();
nsresult RunSimpleQuery(mozIStorageStatement *statment,
PRUint32 resultIndex,
PRUint32 * count,
char *** values);
nsCOMPtr<mozIStorageConnection> mDB;
nsCOMPtr<mozIStorageStatement> mStatement_CacheSize;
@ -152,6 +163,8 @@ private:
nsCOMPtr<mozIStorageStatement> mStatement_CheckOwnership;
nsCOMPtr<mozIStorageStatement> mStatement_DeleteUnowned;
nsCOMPtr<mozIStorageStatement> mStatement_ListOwned;
nsCOMPtr<mozIStorageStatement> mStatement_ListOwnerDomains;
nsCOMPtr<mozIStorageStatement> mStatement_ListOwnerURIs;
nsCOMPtr<nsILocalFile> mCacheDirectory;
PRUint32 mCacheCapacity;

Просмотреть файл

@ -57,9 +57,12 @@ REQUIRES = xpcom \
CPPSRCS = \
nsPrefetchService.cpp \
nsOfflineCacheUpdate.cpp \
$(NULL)
XPIDLSRCS = \
nsIPrefetchService.idl \
nsIOfflineCacheUpdate.idl \
$(NULL)
EXPORTS = \
nsCPrefetchService.h \

Просмотреть файл

@ -55,4 +55,37 @@
{0xbe, 0x83, 0xa8, 0x1b, 0x7c, 0x0f, 0x63, 0xbf} \
}
/**
* nsOfflineCacheUpdateService : nsIOfflineCacheUpdateService
*/
#define NS_OFFLINECACHEUPDATESERVICE_CLASSNAME \
"nsOfflineCacheUpdateService"
#define NS_OFFLINECACHEUPDATESERVICE_CONTRACTID \
"@mozilla.org/offlinecacheupdate-service;1"
#define NS_OFFLINECACHEUPDATESERVICE_CID \
{ /* ec06f3fc-70db-4ecd-94e0-a6e91ca44d8a */ \
0xec06f3fc, \
0x70db, \
0x4ecd , \
{0x94, 0xe0, 0xa6, 0xe9, 0x1c, 0xa4, 0x4d, 0x8a} \
}
/**
* nsOfflineCacheUpdate : nsIOfflineCacheUpdate
*/
#define NS_OFFLINECACHEUPDATE_CLASSNAME \
"nsOfflineCacheUpdate"
#define NS_OFFLINECACHEUPDATE_CONTRACTID \
"@mozilla.org/offlinecacheupdate;1"
#define NS_OFFLINECACHEUPDATE_CID \
{ /* e56f5e01-c7cc-4675-a9d7-b8f1e4127295 */ \
0xe56f5e01, \
0xc7cc, \
0x4675, \
{0xa9, 0xd7, 0xb8, 0xf1, 0xe4, 0x12, 0x72, 0x95} \
}
#endif // !nsCPrefetchService_h__

Просмотреть файл

@ -0,0 +1,159 @@
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dave Camp <dcamp@mozilla.com>
*
* 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 "nsISupports.idl"
interface nsIURI;
interface nsIDOMNode;
interface nsIDOMDocument;
interface nsIDOMLoadStatus;
[scriptable, uuid(e0785ebb-b3a1-426a-a70e-be2b923e973e)]
interface nsIOfflineCacheUpdateObserver : nsISupports {
/**
* An item has finished loading.
*
* @param aItem load status for the item that completed.
*/
void itemCompleted(in nsIDOMLoadStatus aItem);
};
/**
* An nsIOfflineCacheUpdate is used to update a domain's offline resources.
* It can be used to perform partial or complete updates.
*
* Each update object maintains a list of nsIDOMLoadStatus items for the
* resources it is updating. The list of these items will be available
* after the object is scheduled.
*
* One update object will be updating at a time. The active object will
* load its items one by one, sending itemCompleted() to any registered
* observers.
*/
[scriptable, uuid(7dc06ede-1098-4384-b95e-65525ab254c9)]
interface nsIOfflineCacheUpdate : nsISupports {
/**
* The domain being updated, and the domain that will own any URIs added
* with this update.
*/
readonly attribute ACString updateDomain;
/**
* The URI that will own any URIs added by this update
*/
readonly attribute ACString ownerURI;
/**
* Initialize the update.
*
* @param aPartialUpdate
* TRUE if the update should just update the URIs given to it,
* FALSE if all URLs for the owner domain should be added.
* @param aUpdateDomain
* The domain which is being updated, and which will own any
* URIs added.
* @param aOwnerURI
* The owner URI for any URIs added.
* @param aReferrerURI
* The page that is requesting the update.
*/
void init(in boolean aPartialUpdate,
in ACString aUpdateDomain,
in ACString aOwnerURI,
in nsIURI aReferrerURI);
/**
* Add a URI to the offline cache as part of the update.
*
* @param aURI
* The URI to add.
* @param aSource
* The DOM node (<link> tag) associated with this node (for
* implementing nsIDOMLoadStatus).
*/
void addURI(in nsIURI aURI, in nsIDOMNode aSource);
/**
* Add the update to the offline update queue. An offline-cache-update-added
* event will be sent to the observer service.
*/
void schedule();
/**
* Request that the update be scheduled when a document finishes loading.
*
* @param aDocument
* When this document finishes loading, the update will be scheduled.
*/
void scheduleOnDocumentStop(in nsIDOMDocument aDocument);
/**
* Access to the list of items in the update.
*/
readonly attribute unsigned long count;
nsIDOMLoadStatus item(in unsigned long index);
/**
* Observe loads that are added to the update.
*
* @param aObserver
* object that notifications will be sent to.
* @param aHoldWeak
* TRUE if you want the update to hold a weak reference to the
* observer, FALSE for a strong reference.
*/
void addObserver(in nsIOfflineCacheUpdateObserver aObserver,
in boolean aHoldWeak);
/**
* Remove an observer from the update.
*
* @param aObserver
* the observer to remove.
*/
void removeObserver(in nsIOfflineCacheUpdateObserver aObserver);
};
[scriptable, uuid(f99ca10f-5cde-4966-b845-433f2921a201)]
interface nsIOfflineCacheUpdateService : nsISupports {
/**
* Access to the list of cache updates that have been scheduled.
*/
readonly attribute unsigned long numUpdates;
nsIOfflineCacheUpdate getUpdate(in unsigned long index);
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,182 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dave Camp <dcamp@mozilla.com>
*
* 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 nsOfflineCacheUpdate_h__
#define nsOfflineCacheUpdate_h__
#include "nsIOfflineCacheUpdate.h"
#include "nsAutoPtr.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsICacheService.h"
#include "nsIChannelEventSink.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNode.h"
#include "nsIDOMLoadStatus.h"
#include "nsIInterfaceRequestor.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsIOfflineCacheSession.h"
#include "nsIPrefetchService.h"
#include "nsIRequestObserver.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
#include "nsIWebProgressListener.h"
#include "nsRefPtrHashtable.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWeakReference.h"
class nsOfflineCacheUpdate;
class nsOfflineCacheUpdateItem : public nsIDOMLoadStatus
, public nsIStreamListener
, public nsIInterfaceRequestor
, public nsIChannelEventSink
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMLOADSTATUS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
nsOfflineCacheUpdateItem(nsOfflineCacheUpdate *aUpdate,
nsIURI *aURI,
nsIURI *aReferrerURI,
nsIDOMNode *aSource);
~nsOfflineCacheUpdateItem();
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mReferrerURI;
nsCOMPtr<nsIWeakReference> mSource;
nsresult OpenChannel();
nsresult Cancel();
private:
nsOfflineCacheUpdate* mUpdate;
nsCOMPtr<nsIChannel> mChannel;
PRUint16 mState;
PRInt32 mBytesRead;
};
class nsOfflineCacheUpdate : public nsIOfflineCacheUpdate
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOFFLINECACHEUPDATE
nsOfflineCacheUpdate();
~nsOfflineCacheUpdate();
nsresult Init();
nsresult Begin();
nsresult Cancel();
void LoadCompleted();
private:
nsresult ProcessNextURI();
nsresult AddOwnedItems(const nsACString &aOwnerURI);
nsresult AddDomainItems();
nsresult NotifyAdded(nsOfflineCacheUpdateItem *aItem);
nsresult NotifyCompleted(nsOfflineCacheUpdateItem *aItem);
nsresult Finish();
enum {
STATE_UNINITIALIZED,
STATE_INITIALIZED,
STATE_RUNNING,
STATE_CANCELLED,
STATE_FINISHED
} mState;
PRBool mAddedItems;
PRBool mPartialUpdate;
nsCString mUpdateDomain;
nsCString mOwnerURI;
nsCOMPtr<nsIURI> mReferrerURI;
nsCOMPtr<nsIOfflineCacheSession> mCacheSession;
nsCOMPtr<nsIObserverService> mObserverService;
/* Items being updated */
nsTArray<nsRefPtr<nsOfflineCacheUpdateItem> > mItems;
/* Clients watching this update for changes */
nsCOMArray<nsIWeakReference> mWeakObservers;
nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
};
class nsOfflineCacheUpdateService : public nsIOfflineCacheUpdateService
, public nsIWebProgressListener
, public nsIObserver
, public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOFFLINECACHEUPDATESERVICE
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIOBSERVER
nsOfflineCacheUpdateService();
~nsOfflineCacheUpdateService();
nsresult Init();
nsresult Schedule(nsOfflineCacheUpdate *aUpdate);
nsresult ScheduleOnDocumentStop(nsOfflineCacheUpdate *aUpdate,
nsIDOMDocument *aDocument);
nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
static nsOfflineCacheUpdateService *GetInstance();
private:
nsresult ProcessNextUpdate();
nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates;
nsRefPtrHashtable<nsVoidPtrHashKey, nsOfflineCacheUpdate> mDocUpdates;
PRBool mDisabled;
PRBool mUpdateRunning;
};
#endif