From c16599cc1db7d9e43fe31f5ec08b585120240ffd Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 5 Nov 2008 16:01:07 -0800 Subject: [PATCH] Bug 460353: app caches should be per iframe, not per toplevel browsing context. r=dcamp, r+sr=jst --- content/base/public/nsContentUtils.h | 8 +- content/base/src/nsContentSink.cpp | 207 +++++++----------- content/base/src/nsContentSink.h | 11 +- content/base/src/nsContentUtils.cpp | 19 +- docshell/base/nsDocShell.cpp | 43 ++-- dom/src/base/nsGlobalWindow.cpp | 13 +- dom/src/offline/nsDOMOfflineResourceList.cpp | 13 +- dom/src/offline/nsDOMOfflineResourceList.h | 4 +- .../offline/460353_iframe_nomanifest.html | 9 + .../offline/460353_iframe_ownmanifest.html | 37 ++++ .../offline/460353_iframe_samemanifest.html | 21 ++ dom/tests/mochitest/ajax/offline/Makefile.in | 4 + .../mochitest/ajax/offline/foreign2.html | 4 +- .../ajax/offline/test_bug460353.html | 113 ++++++++++ .../ajax/offline/test_offlineMode.html | 2 +- netwerk/cache/src/nsDiskCacheDeviceSQL.cpp | 2 +- uriloader/prefetch/nsOfflineCacheUpdate.cpp | 10 +- 17 files changed, 312 insertions(+), 208 deletions(-) create mode 100644 dom/tests/mochitest/ajax/offline/460353_iframe_nomanifest.html create mode 100644 dom/tests/mochitest/ajax/offline/460353_iframe_ownmanifest.html create mode 100644 dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html create mode 100644 dom/tests/mochitest/ajax/offline/test_bug460353.html diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 87554288b0b4..0ce4699fa8f3 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1241,14 +1241,14 @@ public: static nsIAtom* IsNamedItem(nsIContent* aContent); /** - * Get the application manifest URI for this context. The manifest URI + * Get the application manifest URI for this document. The manifest URI * is specified in the manifest= attribute of the root element of the - * toplevel window. + * document. * - * @param aWindow The context to check. + * @param aDocument The document that lists the manifest. * @param aURI The manifest URI. */ - static void GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI); + static void GetOfflineAppManifest(nsIDocument *aDocument, nsIURI **aURI); /** * Check whether an application should be allowed to use offline APIs. diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp index 6156849d6cea..0f0bdf1082ee 100644 --- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -878,10 +878,11 @@ nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey) nsresult nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, nsIURI *aManifestURI, - PRBool aIsTopDocument, PRBool aFetchedWithHTTPGetOrEquiv, CacheSelectionAction *aAction) { + nsresult rv; + *aAction = CACHE_SELECTION_NONE; nsCOMPtr applicationCacheDocument = @@ -889,14 +890,9 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, NS_ASSERTION(applicationCacheDocument, "mDocument must implement nsIApplicationCacheContainer."); - nsresult rv; - - // We might decide on a new application cache... - nsCOMPtr applicationCache = aLoadApplicationCache; - - if (applicationCache) { + if (aLoadApplicationCache) { nsCAutoString groupID; - rv = applicationCache->GetGroupID(groupID); + rv = aLoadApplicationCache->GetGroupID(groupID); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr groupURI; @@ -908,34 +904,37 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, NS_ENSURE_SUCCESS(rv, rv); if (!equal) { - // This is a foreign entry, mark it as such. If this is a - // toplevel load, force a reload to avoid loading the foreign - // entry. The next attempt will not choose this cache entry - // (because it has been marked foreign). + // This is a foreign entry, mark it as such and force a reload to avoid + // loading the foreign entry. The next attempt will not choose this + // cache entry (because it has been marked foreign). nsCAutoString cachekey; rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey); NS_ENSURE_SUCCESS(rv, rv); - rv = applicationCache->MarkEntry(cachekey, - nsIApplicationCache::ITEM_FOREIGN); + rv = aLoadApplicationCache->MarkEntry(cachekey, + nsIApplicationCache::ITEM_FOREIGN); NS_ENSURE_SUCCESS(rv, rv); - if (aIsTopDocument) { - *aAction = CACHE_SELECTION_RELOAD; - } - - return NS_OK; + *aAction = CACHE_SELECTION_RELOAD; } + else { + // The http manifest attribute URI is equal to the manifest URI of + // the cache the document was loaded from - associate the document with + // that cache and invoke the cache update process. +#ifdef NS_DEBUG + nsCAutoString docURISpec, clientID; + mDocumentURI->GetAsciiSpec(docURISpec); + aLoadApplicationCache->GetClientID(clientID); + SINK_TRACE(gContentSinkLogModuleInfo, SINK_TRACE_CALLS, + ("Selection: assigning app cache %s to document %s", clientID.get(), docURISpec.get())); +#endif - if (aIsTopDocument) { - // This is a top level document and the http manifest attribute - // URI is equal to the manifest URI of the cache the document - // was loaded from - associate the document with that cache and - // invoke the cache update process. - rv = applicationCacheDocument->SetApplicationCache(applicationCache); + rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache); NS_ENSURE_SUCCESS(rv, rv); + // Document will be added as implicit entry to the cache as part of + // the update process. *aAction = CACHE_SELECTION_UPDATE; } } @@ -947,51 +946,12 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, if (!aFetchedWithHTTPGetOrEquiv) { // The document was not loaded using HTTP GET or equivalent // method. The spec says to run the cache selection algorithm w/o - // the manifest specified but we can just do return NS_OK here. - - return NS_OK; - } - - // If there is an existing application cache for this manifest, - // associate it with the document. - nsCAutoString manifestURISpec; - rv = aManifestURI->GetAsciiSpec(manifestURISpec); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr appCacheService = - do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID); - if (!appCacheService) { - // No application cache service, nothing to do here. - return NS_OK; - } - - rv = appCacheService->GetActiveCache(manifestURISpec, - getter_AddRefs(applicationCache)); - NS_ENSURE_SUCCESS(rv, rv); - - if (applicationCache) { - rv = applicationCacheDocument->SetApplicationCache(applicationCache); - NS_ENSURE_SUCCESS(rv, rv); + // the manifest specified. + *aAction = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST; } else { - // XXX bug 443023: if there is already a scheduled update or - // update in progress we have to add this document as - // an implicit entry. - } - - // Always do an update in this case - *aAction = CACHE_SELECTION_UPDATE; - } - - if (applicationCache) { - // We are now associated with an application cache. This item - // should be marked as an implicit entry. - nsCAutoString cachekey; - rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey); - if (NS_SUCCEEDED(rv)) { - rv = applicationCache->MarkEntry(cachekey, - nsIApplicationCache::ITEM_IMPLICIT); - NS_ENSURE_SUCCESS(rv, rv); + // Always do an update in this case + *aAction = CACHE_SELECTION_UPDATE; } } @@ -1000,39 +960,44 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, nsresult nsContentSink::SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache, - PRBool aIsTopDocument, nsIURI **aManifestURI, CacheSelectionAction *aAction) { *aManifestURI = nsnull; *aAction = CACHE_SELECTION_NONE; - if (!aIsTopDocument || !aLoadApplicationCache) { - return NS_OK; - } - nsresult rv; - // The document was loaded from an application cache, use that - // application cache as the document's application cache. - nsCOMPtr applicationCacheDocument = - do_QueryInterface(mDocument); - NS_ASSERTION(applicationCacheDocument, - "mDocument must implement nsIApplicationCacheContainer."); + if (aLoadApplicationCache) { + // The document was loaded from an application cache, use that + // application cache as the document's application cache. + nsCOMPtr applicationCacheDocument = + do_QueryInterface(mDocument); + NS_ASSERTION(applicationCacheDocument, + "mDocument must implement nsIApplicationCacheContainer."); - rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache); - NS_ENSURE_SUCCESS(rv, rv); +#ifdef NS_DEBUG + nsCAutoString docURISpec, clientID; + mDocumentURI->GetAsciiSpec(docURISpec); + aLoadApplicationCache->GetClientID(clientID); + SINK_TRACE(gContentSinkLogModuleInfo, SINK_TRACE_CALLS, + ("Selection, no manifest: assigning app cache %s to document %s", clientID.get(), docURISpec.get())); +#endif - // Return the uri and invoke the update process for the selected - // application cache. - nsCAutoString groupID; - rv = aLoadApplicationCache->GetGroupID(groupID); - NS_ENSURE_SUCCESS(rv, rv); + rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache); + NS_ENSURE_SUCCESS(rv, rv); - rv = NS_NewURI(aManifestURI, groupID); - NS_ENSURE_SUCCESS(rv, rv); + // Return the uri and invoke the update process for the selected + // application cache. + nsCAutoString groupID; + rv = aLoadApplicationCache->GetGroupID(groupID); + NS_ENSURE_SUCCESS(rv, rv); - *aAction = CACHE_SELECTION_UPDATE; + rv = NS_NewURI(aManifestURI, groupID); + NS_ENSURE_SUCCESS(rv, rv); + + *aAction = CACHE_SELECTION_UPDATE; + } return NS_OK; } @@ -1070,26 +1035,11 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement) return; } - // The manifest attribute is handled differently if the document is - // not toplevel. - nsCOMPtr window = mDocument->GetWindow(); - if (!window) - return; - nsCOMPtr parent; - window->GetParent(getter_AddRefs(parent)); - PRBool isTop = (parent == window); - CacheSelectionAction action = CACHE_SELECTION_NONE; nsCOMPtr manifestURI; if (manifestSpec.IsEmpty()) { - rv = SelectDocAppCacheNoManifest(applicationCache, - isTop, - getter_AddRefs(manifestURI), - &action); - if (NS_FAILED(rv)) { - return; - } + action = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST; } else { nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI), @@ -1102,25 +1052,35 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement) // Documents must list a manifest from the same origin rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE); if (NS_FAILED(rv)) { - return; + action = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST; } + else { + // Only continue if the document has permission to use offline APIs. + if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) { + return; + } - // Only continue if the document has permission to use offline APIs. - if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) { - return; + PRBool fetchedWithHTTPGetOrEquiv = PR_FALSE; + nsCOMPtr httpChannel(do_QueryInterface(mDocument->GetChannel())); + if (httpChannel) { + nsCAutoString method; + rv = httpChannel->GetRequestMethod(method); + if (NS_SUCCEEDED(rv)) + fetchedWithHTTPGetOrEquiv = method.Equals("GET"); + } + + rv = SelectDocAppCache(applicationCache, manifestURI, + fetchedWithHTTPGetOrEquiv, &action); + if (NS_FAILED(rv)) { + return; + } } + } - PRBool fetchedWithHTTPGetOrEquiv = PR_FALSE; - nsCOMPtr httpChannel(do_QueryInterface(mDocument->GetChannel())); - if (httpChannel) { - nsCAutoString method; - rv = httpChannel->GetRequestMethod(method); - if (NS_SUCCEEDED(rv)) - fetchedWithHTTPGetOrEquiv = method.Equals("GET"); - } - - rv = SelectDocAppCache(applicationCache, manifestURI, isTop, - fetchedWithHTTPGetOrEquiv, &action); + if (action == CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST) { + rv = SelectDocAppCacheNoManifest(applicationCache, + getter_AddRefs(manifestURI), + &action); if (NS_FAILED(rv)) { return; } @@ -1129,7 +1089,7 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement) switch (action) { case CACHE_SELECTION_NONE: - return; + break; case CACHE_SELECTION_UPDATE: { nsCOMPtr updateService = do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID); @@ -1143,13 +1103,16 @@ nsContentSink::ProcessOfflineManifest(nsIContent *aElement) case CACHE_SELECTION_RELOAD: { // This situation occurs only for toplevel documents, see bottom // of SelectDocAppCache method. - NS_ASSERTION(isTop, "Should only reload toplevel documents!"); nsCOMPtr webNav = do_QueryInterface(mDocShell); webNav->Stop(nsIWebNavigation::STOP_ALL); webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE); break; } + default: + NS_ASSERTION(PR_FALSE, + "Cache selection algorithm didn't decide on proper action"); + break; } } diff --git a/content/base/src/nsContentSink.h b/content/base/src/nsContentSink.h index f2c8c38bdbb5..9b7ca1ca642c 100644 --- a/content/base/src/nsContentSink.h +++ b/content/base/src/nsContentSink.h @@ -167,7 +167,10 @@ protected: // document. In this case, the document is marked as foreign in // the cache it was loaded from and must be reloaded from the // correct cache (the one it specifies). - CACHE_SELECTION_RELOAD = 2 + CACHE_SELECTION_RELOAD = 2, + + // Some conditions require we must reselect the cache without the manifest + CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST = 3 }; nsresult Init(nsIDocument* aDoc, nsIURI* aURI, @@ -206,8 +209,6 @@ protected: // any. // @param aManifestURI // The manifest URI listed in the document. - // @param aIsTopDocument - // TRUE if this is a toplevel document. // @param aFetchedWithHTTPGetOrEquiv // TRUE if this was fetched using the HTTP GET method. // @param aAction @@ -215,7 +216,6 @@ protected: // by the calling function. nsresult SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache, nsIURI *aManifestURI, - PRBool aIsTopDocument, PRBool aFetchedWithHTTPGetOrEquiv, CacheSelectionAction *aAction); @@ -228,8 +228,6 @@ protected: // @param aLoadApplicationCache // The application cache from which the load originated, if // any. - // @param aIsTopDocument - // TRUE if this is a toplevel document. // @param aManifestURI // Out parameter, returns the manifest URI of the cache that // was selected. @@ -237,7 +235,6 @@ protected: // Out parameter, returns the action that should be performed // by the calling function. nsresult SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache, - PRBool aIsTopDocument, nsIURI **aManifestURI, CacheSelectionAction *aAction); diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 1a127741e61c..79d161691105 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -798,22 +798,9 @@ nsContentUtils::IsHTMLWhitespace(PRUnichar aChar) /* static */ void -nsContentUtils::GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI) +nsContentUtils::GetOfflineAppManifest(nsIDocument *aDocument, nsIURI **aURI) { - nsCOMPtr top; - aWindow->GetTop(getter_AddRefs(top)); - if (!top) { - return; - } - - nsCOMPtr topDOMDocument; - top->GetDocument(getter_AddRefs(topDOMDocument)); - nsCOMPtr topDoc = do_QueryInterface(topDOMDocument); - if (!topDoc) { - return; - } - - nsCOMPtr docElement = topDoc->GetRootContent(); + nsCOMPtr docElement = aDocument->GetRootContent(); if (!docElement) { return; } @@ -828,7 +815,7 @@ nsContentUtils::GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI) } nsContentUtils::NewURIWithDocumentCharset(aURI, manifestSpec, - topDoc, topDoc->GetBaseURI()); + aDocument, aDocument->GetBaseURI()); } /* static */ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index e43b1679dad4..f365094e1cb5 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -468,17 +468,10 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer))) { *aSink = nsnull; - // Return the toplevel document as an - // nsIApplicationCacheContainer. - - nsCOMPtr rootItem; - GetSameTypeRootTreeItem(getter_AddRefs(rootItem)); - nsCOMPtr rootDocShell = do_QueryInterface(rootItem); - if (!rootDocShell) - return NS_ERROR_NO_INTERFACE; + // Return application cache associated with this docshell, if any nsCOMPtr contentViewer; - rootDocShell->GetContentViewer(getter_AddRefs(contentViewer)); + GetContentViewer(getter_AddRefs(contentViewer)); if (!contentViewer) return NS_ERROR_NO_INTERFACE; @@ -488,6 +481,11 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) if (!domDoc) return NS_ERROR_NO_INTERFACE; +#if defined(PR_LOGGING) && defined(DEBUG) + PR_LOG(gDocShellLog, PR_LOG_DEBUG, + ("nsDocShell[%p]: returning app cache container %p", + this, domDoc.get())); +#endif return domDoc->QueryInterface(aIID, aSink); } else if (aIID.Equals(NS_GET_IID(nsIPrompt)) && @@ -5115,7 +5113,7 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, if (result == NS_ERROR_NOT_IMPLEMENTED) { // when there is no GlobalHistory3, or it doesn't implement // AddToplevelRedirect, we fall back to GlobalHistory2. Just notify - // that the redirecting page was a redirect so it will be link colored + // that the redirecting page was a rePdirect so it will be link colored // but not visible. nsCOMPtr oldURI; aOldChannel->GetURI(getter_AddRefs(oldURI)); @@ -7338,15 +7336,6 @@ nsDocShell::GetInheritedPrincipal(PRBool aConsiderCurrentDocument) PRBool nsDocShell::ShouldCheckAppCache(nsIURI *aURI) { - // Toplevel document loads in domains with the offline-app - // permission should check for an associated application - // cache. - nsCOMPtr root; - GetSameTypeRootTreeItem(getter_AddRefs(root)); - if (root != this) { - return PR_FALSE; - } - nsCOMPtr offlineService = do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID); if (!offlineService) { @@ -7420,16 +7409,12 @@ nsDocShell::DoURILoad(nsIURI * aURI, nsCOMPtr appCacheChannel = do_QueryInterface(channel); if (appCacheChannel) { - // Toplevel document loads should not inherit application - // caches - nsCOMPtr root; - GetSameTypeRootTreeItem(getter_AddRefs(root)); - if (root == this) { - appCacheChannel->SetInheritApplicationCache(PR_FALSE); - // And loads with the correct permissions should check - // for a matching application cache. - appCacheChannel->SetChooseApplicationCache(ShouldCheckAppCache(aURI)); - } + // Any document load should not inherit application cache. + appCacheChannel->SetInheritApplicationCache(PR_FALSE); + + // Loads with the correct permissions should check for a matching + // application cache. + appCacheChannel->SetChooseApplicationCache(ShouldCheckAppCache(aURI)); } // Make sure to give the caller a channel if we managed to create one diff --git a/dom/src/base/nsGlobalWindow.cpp b/dom/src/base/nsGlobalWindow.cpp index e7f7141e514f..a82d5fb10df9 100644 --- a/dom/src/base/nsGlobalWindow.cpp +++ b/dom/src/base/nsGlobalWindow.cpp @@ -2861,19 +2861,14 @@ nsGlobalWindow::GetApplicationCache(nsIDOMOfflineResourceList **aApplicationCach nsresult rv = webNav->GetCurrentURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr doc = do_QueryInterface(mDocument); nsCOMPtr manifestURI; - nsContentUtils::GetOfflineAppManifest(GetOuterWindowInternal(), - getter_AddRefs(manifestURI)); - - PRBool isToplevel; - nsCOMPtr parentWindow; - GetParent(getter_AddRefs(parentWindow)); - isToplevel = (parentWindow.get() == static_cast(GetOuterWindowInternal())); + nsContentUtils::GetOfflineAppManifest(doc, getter_AddRefs(manifestURI)); nsDOMOfflineResourceList* applicationCache = - new nsDOMOfflineResourceList(isToplevel, manifestURI, uri, this); + new nsDOMOfflineResourceList(manifestURI, uri, this); - if (!applicationCache) + if (!applicationCache) return NS_ERROR_OUT_OF_MEMORY; mApplicationCache = applicationCache; diff --git a/dom/src/offline/nsDOMOfflineResourceList.cpp b/dom/src/offline/nsDOMOfflineResourceList.cpp index f96170fbd85b..acfb059e7aea 100644 --- a/dom/src/offline/nsDOMOfflineResourceList.cpp +++ b/dom/src/offline/nsDOMOfflineResourceList.cpp @@ -154,12 +154,10 @@ NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMOfflineResourceList) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMOfflineResourceList) -nsDOMOfflineResourceList::nsDOMOfflineResourceList(PRBool aToplevel, - nsIURI *aManifestURI, +nsDOMOfflineResourceList::nsDOMOfflineResourceList(nsIURI *aManifestURI, nsIURI *aDocumentURI, nsIDOMWindow *aWindow) : mInitialized(PR_FALSE) - , mToplevel(aToplevel) , mManifestURI(aManifestURI) , mDocumentURI(aDocumentURI) , mCachedKeys(nsnull) @@ -536,10 +534,6 @@ nsDOMOfflineResourceList::SwapCache() return NS_ERROR_DOM_SECURITY_ERR; } - if (!mToplevel) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - nsCOMPtr serv = do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -893,11 +887,6 @@ nsDOMOfflineResourceList::SendEvent(const nsAString &aEventName, nsIDOMEventListener *aListener, const nsCOMArray &aListeners) { - // Only toplevel windows get application cache events. - if (!mToplevel) { - return NS_OK; - } - if (!aListener && aListeners.Count() == 0) { return NS_OK; } diff --git a/dom/src/offline/nsDOMOfflineResourceList.h b/dom/src/offline/nsDOMOfflineResourceList.h index 1c0b5d348d16..188f859330e5 100644 --- a/dom/src/offline/nsDOMOfflineResourceList.h +++ b/dom/src/offline/nsDOMOfflineResourceList.h @@ -76,8 +76,7 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMOfflineResourceList, nsIDOMOfflineResourceList) - nsDOMOfflineResourceList(PRBool aToplevel, - nsIURI* aManifestURI, + nsDOMOfflineResourceList(nsIURI* aManifestURI, nsIURI* aDocumentURI, nsIDOMWindow* aWindow); virtual ~nsDOMOfflineResourceList(); @@ -109,7 +108,6 @@ private: void ClearCachedKeys(); PRBool mInitialized; - PRBool mToplevel; nsCOMPtr mManifestURI; // AsciiSpec of mManifestURI diff --git a/dom/tests/mochitest/ajax/offline/460353_iframe_nomanifest.html b/dom/tests/mochitest/ajax/offline/460353_iframe_nomanifest.html new file mode 100644 index 000000000000..75b297bbd2bd --- /dev/null +++ b/dom/tests/mochitest/ajax/offline/460353_iframe_nomanifest.html @@ -0,0 +1,9 @@ + + +Bug 460353, iframe with no manifest reference + + + + This is an iframe without a manifest reference + + diff --git a/dom/tests/mochitest/ajax/offline/460353_iframe_ownmanifest.html b/dom/tests/mochitest/ajax/offline/460353_iframe_ownmanifest.html new file mode 100644 index 000000000000..9109040783d3 --- /dev/null +++ b/dom/tests/mochitest/ajax/offline/460353_iframe_ownmanifest.html @@ -0,0 +1,37 @@ + + +Bug 460353, iframe with a different manifest reference + + + + + + This is an iframe with a different manifest reference + + diff --git a/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html b/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html new file mode 100644 index 000000000000..556789792bed --- /dev/null +++ b/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html @@ -0,0 +1,21 @@ + + +Bug 460353, iframe with a different manifest reference + + + + + + This is an iframe with the same manifest reference + + diff --git a/dom/tests/mochitest/ajax/offline/Makefile.in b/dom/tests/mochitest/ajax/offline/Makefile.in index 1b777ed79859..6214daa6b2c9 100644 --- a/dom/tests/mochitest/ajax/offline/Makefile.in +++ b/dom/tests/mochitest/ajax/offline/Makefile.in @@ -63,6 +63,10 @@ _TEST_FILES = \ 445544_part2.html \ 445544.cacheManifest \ 445544.cacheManifest^headers^ \ + test_bug460353.html \ + 460353_iframe_nomanifest.html \ + 460353_iframe_ownmanifest.html \ + 460353_iframe_samemanifest.html \ test_obsolete.html \ obsolete.html \ badManifestMagic.cacheManifest \ diff --git a/dom/tests/mochitest/ajax/offline/foreign2.html b/dom/tests/mochitest/ajax/offline/foreign2.html index d82e0f944524..7638418d90b5 100644 --- a/dom/tests/mochitest/ajax/offline/foreign2.html +++ b/dom/tests/mochitest/ajax/offline/foreign2.html @@ -17,7 +17,7 @@ function manifestUpdated() var foreign2cache = appCacheService.chooseApplicationCache( "http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html"); - OfflineTest.ok(foreign2cache, "Foreign 2 cache present, choosed for foreign2.html"); + OfflineTest.ok(foreign2cache, "Foreign 2 cache present, chosen for foreign2.html"); OfflineTest.is(foreign2cache.groupID, "http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest") var foreign1cache = appCacheService.getActiveCache( @@ -44,7 +44,7 @@ function onLoaded() foreign1cache = appCacheService.chooseApplicationCache( "http://localhost:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html"); - OfflineTest.ok(!foreign1cache, "foreign2.html not choosed from foreign1 cache"); + OfflineTest.ok(!foreign1cache, "foreign2.html not chosen from foreign1 cache"); try { diff --git a/dom/tests/mochitest/ajax/offline/test_bug460353.html b/dom/tests/mochitest/ajax/offline/test_bug460353.html new file mode 100644 index 000000000000..f96d55677e23 --- /dev/null +++ b/dom/tests/mochitest/ajax/offline/test_bug460353.html @@ -0,0 +1,113 @@ + + +Bug 460353 + + + + + + + + + + + + + + + diff --git a/dom/tests/mochitest/ajax/offline/test_offlineMode.html b/dom/tests/mochitest/ajax/offline/test_offlineMode.html index 8453133ee721..bee14e858f0e 100644 --- a/dom/tests/mochitest/ajax/offline/test_offlineMode.html +++ b/dom/tests/mochitest/ajax/offline/test_offlineMode.html @@ -121,7 +121,7 @@ function finalize() OfflineTest.is(gGotExplicitVersion, 1, "Explicit entry loaded"); OfflineTest.todo(gGotImplicitVersion == 1, "Bug 461325 - Implicit entry loaded"); OfflineTest.is(gGotDynamicVersion, 1, "Dynamic entry loaded"); - OfflineTest.todo(gGotOnError, "Got onerror event invoked by implicit page load in offline mode"); + OfflineTest.ok(gGotOnError, "Got onerror event invoked by implicit page load in offline mode"); OfflineTest.teardown(); OfflineTest.finish(); diff --git a/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp b/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp index 11ef1dcd8b83..92df0ac2c003 100644 --- a/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp +++ b/netwerk/cache/src/nsDiskCacheDeviceSQL.cpp @@ -1881,7 +1881,7 @@ nsOfflineCacheDevice::AddNamespace(const nsCString &clientID, rv = ns->GetItemType(&itemType); NS_ENSURE_SUCCESS(rv, rv); - LOG(("nsOfflineCacheDevice::AddNamespace [cid=%s, ns=%s, type=%d]", + LOG(("nsOfflineCacheDevice::AddNamespace [cid=%s, ns=%s, data=%s, type=%d]", PromiseFlatCString(clientID).get(), namespaceSpec.get(), data.get(), itemType)); diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.cpp b/uriloader/prefetch/nsOfflineCacheUpdate.cpp index 87d306c7702f..118021e1706f 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp @@ -1720,6 +1720,8 @@ nsOfflineCacheUpdate::AssociateDocument(nsIDOMDocument *aDocument) NS_ENSURE_SUCCESS(rv, rv); if (!existingCache) { + LOG(("Update %p: associating app cache %s to document %p", this, mClientID.get(), aDocument)); + rv = container->SetApplicationCache(mApplicationCache); NS_ENSURE_SUCCESS(rv, rv); } @@ -2241,8 +2243,10 @@ nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI, PRBool equals; rv = manifestURI->Equals(aManifestURI, &equals); if (equals) { - if (aDocument) + if (aDocument) { + LOG(("Document %p added to update %p", aDocument, update.get())); update->AddDocument(aDocument); + } NS_ADDREF(*aUpdate = update); return NS_OK; } @@ -2258,8 +2262,10 @@ nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI, rv = update->Init(aManifestURI, aDocumentURI); NS_ENSURE_SUCCESS(rv, rv); - if (aDocument) + if (aDocument) { + LOG(("First document %p added to update %p", aDocument, update.get())); update->AddDocument(aDocument); + } rv = update->Schedule(); NS_ENSURE_SUCCESS(rv, rv);