2009-07-30 Michael Nordman <michaeln@google.com>
Reviewed by Darin Fisher.
https://bugs.webkit.org/show_bug.cgi?id=27821
ApplicationCacheHost refactoring.
1) Better encapsulate the interfaces between webcore common code
and the appcache system within a new class ApplicationCacheHost.
2) Use that interface throughout the loader system, replacing inline appcache logic.
3) Implement the interface in terms of webcore's appcache system.
4) Add the new files to various makefiles.
5) Implement protocolHostAndPortAreEqual() in KURLGoogle.cpp
No new features, no new tests. The existing layout tests all pass.
* GNUmakefile.am:
* WebCore.base.exp:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
* html/HTMLHtmlElement.cpp:
(WebCore::HTMLHtmlElement::insertedIntoDocument):
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::DocumentLoader):
(WebCore::DocumentLoader::~DocumentLoader):
(WebCore::DocumentLoader::mainReceivedError):
(WebCore::DocumentLoader::detachFromFrame):
(WebCore::DocumentLoader::setPrimaryLoadComplete):
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::applicationCacheHost):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::canCachePageContainingThisFrame):
(WebCore::FrameLoader::logCanCacheFrameDecision):
(WebCore::FrameLoader::loadResourceSynchronously):
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::didReceiveResponse):
(WebCore::MainResourceLoader::didReceiveData):
(WebCore::MainResourceLoader::didFinishLoading):
(WebCore::MainResourceLoader::didFail):
(WebCore::MainResourceLoader::load):
* loader/MainResourceLoader.h:
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::load):
(WebCore::ResourceLoader::willSendRequest):
(WebCore::ResourceLoader::didReceiveResponse):
(WebCore::ResourceLoader::didFail):
* loader/ResourceLoader.h:
* loader/appcache/ApplicationCacheGroup.cpp:
(WebCore::ApplicationCacheGroup::selectCache):
(WebCore::ApplicationCacheGroup::selectCacheWithoutManifestURL):
(WebCore::ApplicationCacheGroup::finishedLoadingMainResource):
(WebCore::ApplicationCacheGroup::failedLoadingMainResource):
(WebCore::ApplicationCacheGroup::disassociateDocumentLoader):
(WebCore::ApplicationCacheGroup::update):
(WebCore::ApplicationCacheGroup::didFinishLoadingManifest):
(WebCore::ApplicationCacheGroup::manifestNotFound):
(WebCore::ApplicationCacheGroup::checkIfLoadIsComplete):
(WebCore::ApplicationCacheGroup::startLoadingEntry):
(WebCore::ApplicationCacheGroup::associateDocumentLoaderWithCache):
(WebCore::CallCacheListenerTask::create):
(WebCore::CallCacheListenerTask::performTask):
(WebCore::CallCacheListenerTask::CallCacheListenerTask):
(WebCore::ApplicationCacheGroup::postListenerTask):
* loader/appcache/ApplicationCacheGroup.h:
* loader/appcache/ApplicationCacheHost.cpp: Added.
* loader/appcache/ApplicationCacheHost.h: Added.
* loader/appcache/ApplicationCacheStorage.cpp:
(WebCore::ApplicationCacheStorage::transferApplicationCache):
* loader/appcache/ApplicationCacheStorage.h:
* loader/appcache/DOMApplicationCache.cpp:
(WebCore::DOMApplicationCache::DOMApplicationCache):
(WebCore::DOMApplicationCache::disconnectFrame):
(WebCore::DOMApplicationCache::applicationCacheHost):
(WebCore::DOMApplicationCache::status):
(WebCore::DOMApplicationCache::update):
(WebCore::DOMApplicationCache::swapCache):
(WebCore::DOMApplicationCache::addEventListener):
(WebCore::DOMApplicationCache::removeEventListener):
(WebCore::DOMApplicationCache::dispatchEvent):
(WebCore::DOMApplicationCache::callListener):
(WebCore::DOMApplicationCache::toEventName):
(WebCore::DOMApplicationCache::toEventType):
* loader/appcache/DOMApplicationCache.h:
(WebCore::DOMApplicationCache::):
(WebCore::DOMApplicationCache::setAttributeEventListener):
(WebCore::DOMApplicationCache::getAttributeEventListener):
(WebCore::DOMApplicationCache::clearAttributeEventListener):
(WebCore::DOMApplicationCache::callEventListener):
(WebCore::DOMApplicationCache::setOnchecking):
(WebCore::DOMApplicationCache::onchecking):
(WebCore::DOMApplicationCache::setOnerror):
(WebCore::DOMApplicationCache::onerror):
(WebCore::DOMApplicationCache::setOnnoupdate):
(WebCore::DOMApplicationCache::onnoupdate):
(WebCore::DOMApplicationCache::setOndownloading):
(WebCore::DOMApplicationCache::ondownloading):
(WebCore::DOMApplicationCache::setOnprogress):
(WebCore::DOMApplicationCache::onprogress):
(WebCore::DOMApplicationCache::setOnupdateready):
(WebCore::DOMApplicationCache::onupdateready):
(WebCore::DOMApplicationCache::setOncached):
(WebCore::DOMApplicationCache::oncached):
(WebCore::DOMApplicationCache::setOnobsolete):
(WebCore::DOMApplicationCache::onobsolete):
(WebCore::DOMApplicationCache::~DOMApplicationCache):
* platform/KURLGoogle.cpp:
(WebCore::protocolHostAndPortAreEqual):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@46609 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index ffe49a3..49ff658 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,119 @@
+2009-07-30 Michael Nordman <michaeln@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=27821
+
+ ApplicationCacheHost refactoring.
+
+ 1) Better encapsulate the interfaces between webcore common code
+ and the appcache system within a new class ApplicationCacheHost.
+
+ 2) Use that interface throughout the loader system, replacing inline appcache logic.
+
+ 3) Implement the interface in terms of webcore's appcache system.
+
+ 4) Add the new files to various makefiles.
+
+ 5) Implement protocolHostAndPortAreEqual() in KURLGoogle.cpp
+
+ No new features, no new tests. The existing layout tests all pass.
+
+ * GNUmakefile.am:
+ * WebCore.base.exp:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * html/HTMLHtmlElement.cpp:
+ (WebCore::HTMLHtmlElement::insertedIntoDocument):
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::DocumentLoader):
+ (WebCore::DocumentLoader::~DocumentLoader):
+ (WebCore::DocumentLoader::mainReceivedError):
+ (WebCore::DocumentLoader::detachFromFrame):
+ (WebCore::DocumentLoader::setPrimaryLoadComplete):
+ * loader/DocumentLoader.h:
+ (WebCore::DocumentLoader::applicationCacheHost):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::canCachePageContainingThisFrame):
+ (WebCore::FrameLoader::logCanCacheFrameDecision):
+ (WebCore::FrameLoader::loadResourceSynchronously):
+ * loader/MainResourceLoader.cpp:
+ (WebCore::MainResourceLoader::didReceiveResponse):
+ (WebCore::MainResourceLoader::didReceiveData):
+ (WebCore::MainResourceLoader::didFinishLoading):
+ (WebCore::MainResourceLoader::didFail):
+ (WebCore::MainResourceLoader::load):
+ * loader/MainResourceLoader.h:
+ * loader/ResourceLoader.cpp:
+ (WebCore::ResourceLoader::load):
+ (WebCore::ResourceLoader::willSendRequest):
+ (WebCore::ResourceLoader::didReceiveResponse):
+ (WebCore::ResourceLoader::didFail):
+ * loader/ResourceLoader.h:
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::selectCache):
+ (WebCore::ApplicationCacheGroup::selectCacheWithoutManifestURL):
+ (WebCore::ApplicationCacheGroup::finishedLoadingMainResource):
+ (WebCore::ApplicationCacheGroup::failedLoadingMainResource):
+ (WebCore::ApplicationCacheGroup::disassociateDocumentLoader):
+ (WebCore::ApplicationCacheGroup::update):
+ (WebCore::ApplicationCacheGroup::didFinishLoadingManifest):
+ (WebCore::ApplicationCacheGroup::manifestNotFound):
+ (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete):
+ (WebCore::ApplicationCacheGroup::startLoadingEntry):
+ (WebCore::ApplicationCacheGroup::associateDocumentLoaderWithCache):
+ (WebCore::CallCacheListenerTask::create):
+ (WebCore::CallCacheListenerTask::performTask):
+ (WebCore::CallCacheListenerTask::CallCacheListenerTask):
+ (WebCore::ApplicationCacheGroup::postListenerTask):
+ * loader/appcache/ApplicationCacheGroup.h:
+ * loader/appcache/ApplicationCacheHost.cpp: Added.
+ * loader/appcache/ApplicationCacheHost.h: Added.
+ * loader/appcache/ApplicationCacheStorage.cpp:
+ (WebCore::ApplicationCacheStorage::transferApplicationCache):
+ * loader/appcache/ApplicationCacheStorage.h:
+ * loader/appcache/DOMApplicationCache.cpp:
+ (WebCore::DOMApplicationCache::DOMApplicationCache):
+ (WebCore::DOMApplicationCache::disconnectFrame):
+ (WebCore::DOMApplicationCache::applicationCacheHost):
+ (WebCore::DOMApplicationCache::status):
+ (WebCore::DOMApplicationCache::update):
+ (WebCore::DOMApplicationCache::swapCache):
+ (WebCore::DOMApplicationCache::addEventListener):
+ (WebCore::DOMApplicationCache::removeEventListener):
+ (WebCore::DOMApplicationCache::dispatchEvent):
+ (WebCore::DOMApplicationCache::callListener):
+ (WebCore::DOMApplicationCache::toEventName):
+ (WebCore::DOMApplicationCache::toEventType):
+ * loader/appcache/DOMApplicationCache.h:
+ (WebCore::DOMApplicationCache::):
+ (WebCore::DOMApplicationCache::setAttributeEventListener):
+ (WebCore::DOMApplicationCache::getAttributeEventListener):
+ (WebCore::DOMApplicationCache::clearAttributeEventListener):
+ (WebCore::DOMApplicationCache::callEventListener):
+ (WebCore::DOMApplicationCache::setOnchecking):
+ (WebCore::DOMApplicationCache::onchecking):
+ (WebCore::DOMApplicationCache::setOnerror):
+ (WebCore::DOMApplicationCache::onerror):
+ (WebCore::DOMApplicationCache::setOnnoupdate):
+ (WebCore::DOMApplicationCache::onnoupdate):
+ (WebCore::DOMApplicationCache::setOndownloading):
+ (WebCore::DOMApplicationCache::ondownloading):
+ (WebCore::DOMApplicationCache::setOnprogress):
+ (WebCore::DOMApplicationCache::onprogress):
+ (WebCore::DOMApplicationCache::setOnupdateready):
+ (WebCore::DOMApplicationCache::onupdateready):
+ (WebCore::DOMApplicationCache::setOncached):
+ (WebCore::DOMApplicationCache::oncached):
+ (WebCore::DOMApplicationCache::setOnobsolete):
+ (WebCore::DOMApplicationCache::onobsolete):
+ (WebCore::DOMApplicationCache::~DOMApplicationCache):
+ * platform/KURLGoogle.cpp:
+ (WebCore::protocolHostAndPortAreEqual):
+
2009-07-30 Chris Fleizach <cfleizach@apple.com>
Reviewed by Darin Adler.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index add35aa..f3c4fa3c 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -2006,6 +2006,8 @@
WebCore/loader/appcache/ApplicationCache.h \
WebCore/loader/appcache/ApplicationCacheGroup.cpp \
WebCore/loader/appcache/ApplicationCacheGroup.h \
+ WebCore/loader/appcache/ApplicationCacheHost.cpp \
+ WebCore/loader/appcache/ApplicationCacheHost.h \
WebCore/loader/appcache/ApplicationCacheResource.cpp \
WebCore/loader/appcache/ApplicationCacheResource.h \
WebCore/loader/appcache/ApplicationCacheStorage.cpp \
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index 8d395b4..96d193e 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -443,7 +443,7 @@
__ZN7WebCore22createFragmentFromTextEPNS_5RangeERKNS_6StringE
__ZN7WebCore22externalRepresentationEPNS_12RenderObjectE
__ZN7WebCore23ApplicationCacheStorage14setMaximumSizeEx
-__ZN7WebCore23ApplicationCacheStorage16storeCopyOfCacheERKNS_6StringEPNS_16ApplicationCacheE
+__ZN7WebCore23ApplicationCacheStorage24transferApplicationCacheERKNS_6StringEPNS_20ApplicationCacheHostE
__ZN7WebCore23ApplicationCacheStorage17setCacheDirectoryERKNS_6StringE
__ZN7WebCore23ApplicationCacheStorage18vacuumDatabaseFileEv
__ZN7WebCore23ApplicationCacheStorage5emptyEv
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 7b26421..0dade31 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1425,6 +1425,8 @@
'loader/appcache/ApplicationCache.h',
'loader/appcache/ApplicationCacheGroup.cpp',
'loader/appcache/ApplicationCacheGroup.h',
+ 'loader/appcache/ApplicationCacheHost.cpp',
+ 'loader/appcache/ApplicationCacheHost.h',
'loader/appcache/ApplicationCacheResource.cpp',
'loader/appcache/ApplicationCacheResource.h',
'loader/appcache/ApplicationCacheStorage.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 43a91e8..edcf25d 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1513,6 +1513,7 @@
inspector/JavaScriptProfile.h \
inspector/JavaScriptProfileNode.h \
loader/appcache/ApplicationCacheGroup.h \
+ loader/appcache/ApplicationCacheHost.h \
loader/appcache/ApplicationCache.h \
loader/appcache/ApplicationCacheResource.h \
loader/appcache/ApplicationCacheStorage.h \
@@ -3033,6 +3034,7 @@
SOURCES += \
loader/appcache/ApplicationCache.cpp \
loader/appcache/ApplicationCacheGroup.cpp \
+ loader/appcache/ApplicationCacheHost.cpp \
loader/appcache/ApplicationCacheStorage.cpp \
loader/appcache/ApplicationCacheResource.cpp \
loader/appcache/DOMApplicationCache.cpp \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index fb68fec..129e68f 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -17296,6 +17296,14 @@
>
</File>
<File
+ RelativePath="..\loader\appcache\ApplicationCacheHost.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\appcache\ApplicationCacheHost.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\appcache\ApplicationCacheResource.cpp"
>
</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 691d2e7..ab096fd 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -352,7 +352,7 @@
1A8F6BC00DB55CDC001DB794 /* ApplicationCacheResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8F6BB50DB55CDC001DB794 /* ApplicationCacheResource.cpp */; };
1A8F6BC10DB55CDC001DB794 /* ApplicationCacheResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F6BB60DB55CDC001DB794 /* ApplicationCacheResource.h */; };
1A8F6BC20DB55CDC001DB794 /* DOMApplicationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8F6BB70DB55CDC001DB794 /* DOMApplicationCache.cpp */; };
- 1A8F6BC30DB55CDC001DB794 /* DOMApplicationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F6BB80DB55CDC001DB794 /* DOMApplicationCache.h */; };
+ 1A8F6BC30DB55CDC001DB794 /* DOMApplicationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F6BB80DB55CDC001DB794 /* DOMApplicationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
1A8F6BC50DB55CDC001DB794 /* ManifestParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8F6BBA0DB55CDC001DB794 /* ManifestParser.cpp */; };
1A8F6BC60DB55CDC001DB794 /* ManifestParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F6BBB0DB55CDC001DB794 /* ManifestParser.h */; };
1A98956B0AA78F80005EF5EF /* KURLCFNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A98956A0AA78F80005EF5EF /* KURLCFNet.cpp */; };
@@ -524,6 +524,8 @@
1CF6BE140E9BB4670025E1CD /* ObjCNodeFilterCondition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CF6BE120E9BB4670025E1CD /* ObjCNodeFilterCondition.mm */; };
1CF6BE150E9BB4670025E1CD /* ObjCNodeFilterCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CF6BE130E9BB4670025E1CD /* ObjCNodeFilterCondition.h */; };
1CFAE3230A6D6A3F0032593D /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CFAE3220A6D6A3F0032593D /* libobjc.dylib */; };
+ 24F54EAC101FE914000AE741 /* ApplicationCacheHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24F54EAA101FE914000AE741 /* ApplicationCacheHost.cpp */; };
+ 24F54EAD101FE914000AE741 /* ApplicationCacheHost.h in Headers */ = {isa = PBXBuildFile; fileRef = 24F54EAB101FE914000AE741 /* ApplicationCacheHost.h */; settings = {ATTRIBUTES = (Private, ); }; };
29A812260FBB9C1D00510293 /* AccessibilityRenderObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29A812080FBB9C1D00510293 /* AccessibilityRenderObject.cpp */; };
29A812270FBB9C1D00510293 /* AccessibilityTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29A812090FBB9C1D00510293 /* AccessibilityTable.cpp */; };
29A812280FBB9C1D00510293 /* AccessibilityARIAGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29A8120A0FBB9C1D00510293 /* AccessibilityARIAGrid.cpp */; };
@@ -5487,6 +5489,8 @@
1CF6BE120E9BB4670025E1CD /* ObjCNodeFilterCondition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ObjCNodeFilterCondition.mm; sourceTree = "<group>"; };
1CF6BE130E9BB4670025E1CD /* ObjCNodeFilterCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCNodeFilterCondition.h; sourceTree = "<group>"; };
1CFAE3220A6D6A3F0032593D /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
+ 24F54EAA101FE914000AE741 /* ApplicationCacheHost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationCacheHost.cpp; sourceTree = "<group>"; };
+ 24F54EAB101FE914000AE741 /* ApplicationCacheHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationCacheHost.h; sourceTree = "<group>"; };
29A812080FBB9C1D00510293 /* AccessibilityRenderObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityRenderObject.cpp; sourceTree = "<group>"; };
29A812090FBB9C1D00510293 /* AccessibilityTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTable.cpp; sourceTree = "<group>"; };
29A8120A0FBB9C1D00510293 /* AccessibilityARIAGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityARIAGrid.cpp; sourceTree = "<group>"; };
@@ -9708,6 +9712,8 @@
1A8F6BB00DB55CDC001DB794 /* appcache */ = {
isa = PBXGroup;
children = (
+ 24F54EAA101FE914000AE741 /* ApplicationCacheHost.cpp */,
+ 24F54EAB101FE914000AE741 /* ApplicationCacheHost.h */,
1A8F6BB10DB55CDC001DB794 /* ApplicationCache.cpp */,
1A8F6BB20DB55CDC001DB794 /* ApplicationCache.h */,
1A8F6BB30DB55CDC001DB794 /* ApplicationCacheGroup.cpp */,
@@ -17062,6 +17068,7 @@
CE54FD381016D9A6008B44C8 /* ScriptSourceProvider.h in Headers */,
7A74ECBB101839A600BF939E /* InspectorBackend.h in Headers */,
7A1E88F6101CC384000C4DF5 /* ScriptArray.h in Headers */,
+ 24F54EAD101FE914000AE741 /* ApplicationCacheHost.h in Headers */,
41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -19104,6 +19111,7 @@
7A74ECBA101839A600BF939E /* InspectorBackend.cpp in Sources */,
7A74ECBD101839DA00BF939E /* JSInspectorBackendCustom.cpp in Sources */,
7A1E88F5101CC384000C4DF5 /* ScriptArray.cpp in Sources */,
+ 24F54EAC101FE914000AE741 /* ApplicationCacheHost.cpp in Sources */,
41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/WebCore/WebCoreSources.bkl b/WebCore/WebCoreSources.bkl
index 8b72bce..bdbb8b9 100644
--- a/WebCore/WebCoreSources.bkl
+++ b/WebCore/WebCoreSources.bkl
@@ -676,6 +676,7 @@
<set append="1" var="WEBCORE_SOURCES_LOADER">
loader/appcache/ApplicationCache.cpp
loader/appcache/ApplicationCacheGroup.cpp
+ loader/appcache/ApplicationCacheHost.cpp
loader/appcache/ApplicationCacheResource.cpp
loader/appcache/DOMApplicationCache.cpp
loader/appcache/ManifestParser.cpp
diff --git a/WebCore/html/HTMLHtmlElement.cpp b/WebCore/html/HTMLHtmlElement.cpp
index d4867a4..d548093 100644
--- a/WebCore/html/HTMLHtmlElement.cpp
+++ b/WebCore/html/HTMLHtmlElement.cpp
@@ -23,8 +23,13 @@
#include "config.h"
#include "HTMLHtmlElement.h"
-#include "ApplicationCacheGroup.h"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
+#endif
+
#include "Document.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
#include "HTMLNames.h"
namespace WebCore {
@@ -68,12 +73,16 @@
if (!document()->frame())
return;
+ DocumentLoader* documentLoader = document()->frame()->loader()->documentLoader();
+ if (!documentLoader)
+ return;
+
// Check the manifest attribute
AtomicString manifest = getAttribute(manifestAttr);
- if (manifest.isNull())
- ApplicationCacheGroup::selectCacheWithoutManifestURL(document()->frame());
+ if (manifest.isEmpty())
+ documentLoader->applicationCacheHost()->selectCacheWithoutManifest();
else
- ApplicationCacheGroup::selectCache(document()->frame(), document()->completeURL(manifest));
+ documentLoader->applicationCacheHost()->selectCacheWithManifest(document()->completeURL(manifest));
}
#endif
diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp
index 87cb725..7eeb448 100644
--- a/WebCore/loader/DocumentLoader.cpp
+++ b/WebCore/loader/DocumentLoader.cpp
@@ -29,11 +29,6 @@
#include "config.h"
#include "DocumentLoader.h"
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "ApplicationCache.h"
-#include "ApplicationCacheGroup.h"
-#include "ApplicationCacheResource.h"
-#endif
#include "ArchiveFactory.h"
#include "ArchiveResourceCollection.h"
#include "CachedPage.h"
@@ -153,7 +148,7 @@
, m_substituteResourceDeliveryTimer(this, &DocumentLoader::substituteResourceDeliveryTimerFired)
, m_didCreateGlobalHistoryEntry(false)
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- , m_candidateApplicationCacheGroup(0)
+ , m_applicationCacheHost(this)
#endif
{
}
@@ -168,13 +163,6 @@
DocumentLoader::~DocumentLoader()
{
ASSERT(!m_frame || frameLoader()->activeDocumentLoader() != this || !frameLoader()->isLoading());
-
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (m_applicationCache)
- m_applicationCache->group()->disassociateDocumentLoader(this);
- else if (m_candidateApplicationCacheGroup)
- m_candidateApplicationCacheGroup->disassociateDocumentLoader(this);
-#endif
}
PassRefPtr<SharedBuffer> DocumentLoader::mainResourceData() const
@@ -258,14 +246,7 @@
ASSERT(!error.isNull());
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- ApplicationCacheGroup* group = m_candidateApplicationCacheGroup;
- if (!group && m_applicationCache) {
- ASSERT(!mainResourceApplicationCache()); // If the main resource were loaded from a cache, it wouldn't fail.
- group = m_applicationCache->group();
- }
-
- if (group)
- group->failedLoadingMainResource(this);
+ m_applicationCacheHost.failedLoadingMainResource();
#endif
if (!frameLoader())
@@ -430,6 +411,9 @@
void DocumentLoader::detachFromFrame()
{
ASSERT(m_frame);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ m_applicationCacheHost.setDOMApplicationCache(0);
+#endif
m_frame = 0;
}
@@ -451,9 +435,6 @@
if (flag) {
if (m_mainResourceLoader) {
m_mainResourceData = m_mainResourceLoader->resourceData();
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- m_mainResourceApplicationCache = m_mainResourceLoader->applicationCache();
-#endif
m_mainResourceLoader = 0;
}
@@ -847,113 +828,4 @@
m_frame->loader()->iconLoadDecisionAvailable();
}
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-void DocumentLoader::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group)
-{
- ASSERT(!m_applicationCache);
- m_candidateApplicationCacheGroup = group;
-}
-
-void DocumentLoader::setApplicationCache(PassRefPtr<ApplicationCache> applicationCache)
-{
- if (m_candidateApplicationCacheGroup) {
- ASSERT(!m_applicationCache);
- m_candidateApplicationCacheGroup = 0;
- }
-
- m_applicationCache = applicationCache;
-}
-
-ApplicationCache* DocumentLoader::mainResourceApplicationCache() const
-{
- if (m_mainResourceApplicationCache)
- return m_mainResourceApplicationCache.get();
- if (m_mainResourceLoader)
- return m_mainResourceLoader->applicationCache();
- return 0;
-}
-
-bool DocumentLoader::shouldLoadResourceFromApplicationCache(const ResourceRequest& request, ApplicationCacheResource*& resource)
-{
- ApplicationCache* cache = applicationCache();
- if (!cache || !cache->isComplete())
- return false;
-
- // If the resource is not a HTTP/HTTPS GET, then abort
- if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
- return false;
-
- // If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry
- // in the application cache, then get the resource from the cache (instead of fetching it).
- resource = cache->resourceForURL(request.url());
-
- // Resources that match fallback namespaces or online whitelist entries are fetched from the network,
- // unless they are also cached.
- if (!resource && (cache->urlMatchesFallbackNamespace(request.url()) || cache->isURLInOnlineWhitelist(request.url())))
- return false;
-
- // Resources that are not present in the manifest will always fail to load (at least, after the
- // cache has been primed the first time), making the testing of offline applications simpler.
- return true;
-}
-
-bool DocumentLoader::getApplicationCacheFallbackResource(const ResourceRequest& request, ApplicationCacheResource*& resource, ApplicationCache* cache)
-{
- if (!cache) {
- cache = applicationCache();
- if (!cache)
- return false;
- }
- if (!cache->isComplete())
- return false;
-
- // If the resource is not a HTTP/HTTPS GET, then abort
- if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
- return false;
-
- KURL fallbackURL;
- if (!cache->urlMatchesFallbackNamespace(request.url(), &fallbackURL))
- return false;
-
- resource = cache->resourceForURL(fallbackURL);
- ASSERT(resource);
-
- return true;
-}
-
-bool DocumentLoader::scheduleApplicationCacheLoad(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL)
-{
- if (!frameLoader()->frame()->settings() || !frameLoader()->frame()->settings()->offlineWebApplicationCacheEnabled())
- return false;
-
- if (request.url() != originalURL)
- return false;
-
- ApplicationCacheResource* resource;
- if (!shouldLoadResourceFromApplicationCache(request, resource))
- return false;
-
- m_pendingSubstituteResources.set(loader, resource);
- deliverSubstituteResourcesAfterDelay();
-
- return true;
-}
-
-bool DocumentLoader::scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader* loader, const ResourceRequest& request, ApplicationCache* cache)
-{
- if (!frameLoader()->frame()->settings() || !frameLoader()->frame()->settings()->offlineWebApplicationCacheEnabled())
- return false;
-
- ApplicationCacheResource* resource;
- if (!getApplicationCacheFallbackResource(request, resource, cache))
- return false;
-
- m_pendingSubstituteResources.set(loader, resource);
- deliverSubstituteResourcesAfterDelay();
-
- return true;
-}
-
-#endif // ENABLE(OFFLINE_WEB_APPLICATIONS)
-
}
diff --git a/WebCore/loader/DocumentLoader.h b/WebCore/loader/DocumentLoader.h
index d4ac427..0e11e68 100644
--- a/WebCore/loader/DocumentLoader.h
+++ b/WebCore/loader/DocumentLoader.h
@@ -29,6 +29,10 @@
#ifndef DocumentLoader_h
#define DocumentLoader_h
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
+#endif
+
#include "NavigationAction.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
@@ -38,9 +42,6 @@
namespace WebCore {
- class ApplicationCache;
- class ApplicationCacheGroup;
- class ApplicationCacheResource;
class Archive;
class ArchiveResource;
class ArchiveResourceCollection;
@@ -207,18 +208,7 @@
void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads);
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- bool scheduleApplicationCacheLoad(ResourceLoader*, const ResourceRequest&, const KURL& originalURL);
- bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, const ResourceRequest&, ApplicationCache* = 0);
- bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
- bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0);
-
- void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group);
- ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; }
-
- void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache);
- ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
-
- ApplicationCache* mainResourceApplicationCache() const;
+ ApplicationCacheHost* applicationCacheHost() { return &m_applicationCacheHost; }
#endif
protected:
@@ -306,16 +296,9 @@
String m_clientRedirectSourceForHistory;
bool m_didCreateGlobalHistoryEntry;
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- // The application cache that the document loader is associated with (if any).
- RefPtr<ApplicationCache> m_applicationCache;
-
- // Before an application cache has finished loading, this will be the candidate application
- // group that the document loader is associated with.
- ApplicationCacheGroup* m_candidateApplicationCacheGroup;
-
- // Once the main resource has finished loading, this is the application cache it was loaded from (if any).
- RefPtr<ApplicationCache> m_mainResourceApplicationCache;
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ friend class ApplicationCacheHost; // for substitute resource delivery
+ ApplicationCacheHost m_applicationCacheHost;
#endif
};
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 9fe5adc..b7cb365 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -95,8 +95,7 @@
#include <wtf/StdLibExtras.h>
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "ApplicationCache.h"
-#include "ApplicationCacheResource.h"
+#include "ApplicationCacheHost.h"
#endif
#if ENABLE(SVG)
@@ -1816,8 +1815,7 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
// FIXME: We should investigating caching frames that have an associated
// application cache. <rdar://problem/5917899> tracks that work.
- && !m_documentLoader->applicationCache()
- && !m_documentLoader->candidateApplicationCacheGroup()
+ && m_documentLoader->applicationCacheHost()->canCacheInPageCache()
#endif
#if ENABLE(WML)
&& !frameContainsWMLContent(m_frame)
@@ -1967,10 +1965,8 @@
if (!m_frame->document()->canSuspendActiveDOMObjects())
{ PCLOG(" -The document cannot suspect its active DOM Objects"); cannotCache = true; }
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (m_documentLoader->applicationCache())
- { PCLOG(" -The DocumentLoader has an active application cache"); cannotCache = true; }
- if (m_documentLoader->candidateApplicationCacheGroup())
- { PCLOG(" -The DocumentLoader has a candidateApplicationCacheGroup"); cannotCache = true; }
+ if (!m_documentLoader->applicationCacheHost()->canCacheInPageCache())
+ { PCLOG(" -The DocumentLoader uses an application cache"); cannotCache = true; }
#endif
if (!m_client->canCachePage())
{ PCLOG(" -The client says this frame cannot be cached"); cannotCache = true; }
@@ -3681,30 +3677,11 @@
ASSERT(!newRequest.isNull());
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- ApplicationCacheResource* resource;
- if (documentLoader()->shouldLoadResourceFromApplicationCache(newRequest, resource)) {
- if (resource) {
- response = resource->response();
- data.append(resource->data()->data(), resource->data()->size());
- } else
- error = cannotShowURLError(newRequest);
- } else {
+ if (!documentLoader()->applicationCacheHost()->maybeLoadSynchronously(newRequest, error, response, data)) {
#endif
ResourceHandle::loadResourceSynchronously(newRequest, storedCredentials, error, response, data, m_frame);
-
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- // If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent,
- // or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry
- // corresponding to the matched namespace.
- if ((!error.isNull() && !error.isCancellation())
- || response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5
- || !protocolHostAndPortAreEqual(newRequest.url(), response.url())) {
- if (documentLoader()->getApplicationCacheFallbackResource(newRequest, resource)) {
- response = resource->response();
- data.clear();
- data.append(resource->data()->data(), resource->data()->size());
- }
- }
+ documentLoader()->applicationCacheHost()->maybeLoadFallbackSynchronously(newRequest, error, response, data);
}
#endif
}
diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp
index 39e5b90..159aaa1 100644
--- a/WebCore/loader/MainResourceLoader.cpp
+++ b/WebCore/loader/MainResourceLoader.cpp
@@ -42,9 +42,7 @@
#include "Settings.h"
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "ApplicationCache.h"
-#include "ApplicationCacheGroup.h"
-#include "ApplicationCacheResource.h"
+#include "ApplicationCacheHost.h"
#endif
// FIXME: More that is in common with SubresourceLoader should move up into ResourceLoader.
@@ -283,15 +281,8 @@
void MainResourceLoader::didReceiveResponse(const ResourceResponse& r)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) {
- ASSERT(!m_applicationCache);
- if (m_frame->settings() && m_frame->settings()->offlineWebApplicationCacheEnabled()) {
- m_applicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request(), documentLoader());
-
- if (scheduleLoadFallbackResourceFromApplicationCache(m_applicationCache.get()))
- return;
- }
- }
+ if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainResponse(request(), r))
+ return;
#endif
HTTPHeaderMap::const_iterator it = r.httpHeaderFields().find(AtomicString("x-frame-options"));
@@ -353,6 +344,10 @@
ASSERT(!defersLoading());
#endif
+ #if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, lengthReceived, allAtOnce);
+#endif
+
// The additional processing can do anything including possibly removing the last
// reference to this object; one example of this is 3266216.
RefPtr<MainResourceLoader> protect(this);
@@ -380,27 +375,15 @@
ResourceLoader::didFinishLoading();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- ApplicationCacheGroup* group = dl->candidateApplicationCacheGroup();
- if (!group && dl->applicationCache() && !dl->mainResourceApplicationCache())
- group = dl->applicationCache()->group();
-
- if (group)
- group->finishedLoadingMainResource(dl.get());
+ dl->applicationCacheHost()->finishedLoadingMainResource();
#endif
}
void MainResourceLoader::didFail(const ResourceError& error)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (!error.isCancellation()) {
- ASSERT(!m_applicationCache);
- if (m_frame->settings() && m_frame->settings()->offlineWebApplicationCacheEnabled()) {
- m_applicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request(), documentLoader());
-
- if (scheduleLoadFallbackResourceFromApplicationCache(m_applicationCache.get()))
- return;
- }
- }
+ if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
+ return;
#endif
// There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
@@ -495,27 +478,15 @@
m_substituteData = substituteData;
+ ResourceRequest request(r);
+
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- // Check if this request should be loaded from the application cache
- if (!m_substituteData.isValid() && frameLoader()->frame()->settings() && frameLoader()->frame()->settings()->offlineWebApplicationCacheEnabled()) {
- ASSERT(!m_applicationCache);
-
- m_applicationCache = ApplicationCacheGroup::cacheForMainRequest(r, m_documentLoader.get());
-
- if (m_applicationCache) {
- // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource.
- ApplicationCacheResource* resource = m_applicationCache->resourceForRequest(r);
- m_substituteData = SubstituteData(resource->data(),
- resource->response().mimeType(),
- resource->response().textEncodingName(), KURL());
- }
- }
+ documentLoader()->applicationCacheHost()->maybeLoadMainResource(request, m_substituteData);
#endif
- ResourceRequest request(r);
bool defer = defersLoading();
if (defer) {
- bool shouldLoadEmpty = shouldLoadAsEmptyDocument(r.url());
+ bool shouldLoadEmpty = shouldLoadAsEmptyDocument(request.url());
if (shouldLoadEmpty)
defer = false;
}
diff --git a/WebCore/loader/MainResourceLoader.h b/WebCore/loader/MainResourceLoader.h
index d9ce2f9..d3f411b 100644
--- a/WebCore/loader/MainResourceLoader.h
+++ b/WebCore/loader/MainResourceLoader.h
@@ -39,9 +39,6 @@
namespace WebCore {
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- class ApplicationCache;
-#endif
class FormState;
struct ResourceRequest;
@@ -71,10 +68,6 @@
bool isLoadingMultipartContent() const { return m_loadingMultipartContent; }
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
-#endif
-
private:
MainResourceLoader(Frame*);
@@ -105,11 +98,6 @@
MainResourceLoaderTimer m_dataLoadTimer;
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- // The application cache that the main resource was loaded from (if any).
- RefPtr<ApplicationCache> m_applicationCache;
-#endif
-
bool m_loadingMultipartContent;
bool m_waitingForContentPolicy;
};
diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp
index e2fc7ba..cc67555 100644
--- a/WebCore/loader/ResourceLoader.cpp
+++ b/WebCore/loader/ResourceLoader.cpp
@@ -30,6 +30,9 @@
#include "config.h"
#include "ResourceLoader.h"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
+#endif
#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -119,7 +122,7 @@
return true;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (m_documentLoader->scheduleApplicationCacheLoad(this, clientRequest, r.url()))
+ if (m_documentLoader->applicationCacheHost()->maybeLoadResource(this, clientRequest, r.url()))
return true;
#endif
@@ -190,17 +193,6 @@
m_resourceData->clear();
}
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-bool ResourceLoader::scheduleLoadFallbackResourceFromApplicationCache(ApplicationCache* cache)
-{
- if (documentLoader()->scheduleLoadFallbackResourceFromApplicationCache(this, m_request, cache)) {
- handle()->cancel();
- return true;
- }
- return false;
-}
-#endif
-
void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
// Protect this in this delegate method since the additional processing can do
@@ -382,10 +374,8 @@
void ResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) {
- if (scheduleLoadFallbackResourceFromApplicationCache())
- return;
- }
+ if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForRedirect(this, request, redirectResponse))
+ return;
#endif
willSendRequest(request, redirectResponse);
}
@@ -398,10 +388,8 @@
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5) {
- if (scheduleLoadFallbackResourceFromApplicationCache())
- return;
- }
+ if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response))
+ return;
#endif
didReceiveResponse(response);
}
@@ -419,10 +407,8 @@
void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- if (!error.isCancellation()) {
- if (documentLoader()->scheduleLoadFallbackResourceFromApplicationCache(this, m_request))
- return;
- }
+ if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(this, error))
+ return;
#endif
didFail(error);
}
diff --git a/WebCore/loader/ResourceLoader.h b/WebCore/loader/ResourceLoader.h
index d3e7b80..5239289a 100644
--- a/WebCore/loader/ResourceLoader.h
+++ b/WebCore/loader/ResourceLoader.h
@@ -40,7 +40,7 @@
namespace WebCore {
- class ApplicationCache;
+ class ApplicationCacheHost;
class DocumentLoader;
class Frame;
class FrameLoader;
@@ -119,7 +119,7 @@
ResourceLoader(Frame*, bool sendResourceLoadCallbacks, bool shouldContentSniff);
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- bool scheduleLoadFallbackResourceFromApplicationCache(ApplicationCache* = 0);
+ friend class ApplicationCacheHost; // for access to request()
#endif
virtual void didCancel(const ResourceError&);
@@ -133,13 +133,13 @@
RefPtr<ResourceHandle> m_handle;
RefPtr<Frame> m_frame;
RefPtr<DocumentLoader> m_documentLoader;
- ResourceResponse m_response;
+ ResourceResponse m_response;
private:
ResourceRequest m_request;
RefPtr<SharedBuffer> m_resourceData;
- unsigned long m_identifier;
+ unsigned long m_identifier;
bool m_reachedTerminalState;
bool m_cancelled;
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index dc73353..318fa3e 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -29,6 +29,7 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "ApplicationCache.h"
+#include "ApplicationCacheHost.h"
#include "ApplicationCacheResource.h"
#include "ApplicationCacheStorage.h"
#include "ChromeClient.h"
@@ -126,7 +127,7 @@
return;
DocumentLoader* documentLoader = frame->loader()->documentLoader();
- ASSERT(!documentLoader->applicationCache());
+ ASSERT(!documentLoader->applicationCacheHost()->applicationCache());
if (passedManifestURL.isNull()) {
selectCacheWithoutManifestURL(frame);
@@ -137,7 +138,7 @@
if (manifestURL.hasRef())
manifestURL.removeRef();
- ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache();
+ ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache();
if (mainResourceCache) {
if (manifestURL == mainResourceCache->group()->m_manifestURL) {
@@ -175,14 +176,14 @@
// Don't change anything on disk if private browsing is enabled.
if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) {
- postListenerTask(&DOMApplicationCache::callCheckingListener, documentLoader);
- postListenerTask(&DOMApplicationCache::callErrorListener, documentLoader);
+ postListenerTask(DOMApplicationCache::CHECKING_EVENT, documentLoader);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, documentLoader);
return;
}
ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL);
- documentLoader->setCandidateApplicationCacheGroup(group);
+ documentLoader->applicationCacheHost()->setCandidateApplicationCacheGroup(group);
group->m_pendingMasterResourceLoaders.add(documentLoader);
group->m_downloadingPendingMasterResourceLoadersCount++;
@@ -196,9 +197,9 @@
return;
DocumentLoader* documentLoader = frame->loader()->documentLoader();
- ASSERT(!documentLoader->applicationCache());
+ ASSERT(!documentLoader->applicationCacheHost()->applicationCache());
- ApplicationCache* mainResourceCache = documentLoader->mainResourceApplicationCache();
+ ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache();
if (mainResourceCache) {
mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache);
@@ -235,9 +236,9 @@
// Cache update has been a failure, so there is no reason to keep the document associated with the incomplete cache
// (its main resource was not cached yet, so it is likely that the application changed significantly server-side).
ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading().
- loader->setApplicationCache(0); // Will unset candidate, too.
+ loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too.
m_associatedDocumentLoaders.remove(loader);
- postListenerTask(&DOMApplicationCache::callErrorListener, loader);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, loader);
break;
case Completed:
ASSERT(m_associatedDocumentLoaders.contains(loader));
@@ -271,28 +272,28 @@
// The manifest didn't change, and we have a relevant cache - but the main resource download failed mid-way, so it cannot be stored to the cache,
// and the loader does not get associated to it. If there are other main resources being downloaded for this cache group, they may still succeed.
- postListenerTask(&DOMApplicationCache::callErrorListener, loader);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, loader);
break;
case Failure:
// Cache update failed, too.
ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading().
- ASSERT(!loader->applicationCache() || loader->applicationCache() == m_cacheBeingUpdated);
+ ASSERT(!loader->applicationCacheHost()->applicationCache() || loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated);
- loader->setApplicationCache(0); // Will unset candidate, too.
+ loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too.
m_associatedDocumentLoaders.remove(loader);
- postListenerTask(&DOMApplicationCache::callErrorListener, loader);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, loader);
break;
case Completed:
// The cache manifest didn't list this main resource, and all cache entries were already updated successfully - but the main resource failed to load,
// so it cannot be stored to the cache. If there are other main resources being downloaded for this cache group, they may still succeed.
ASSERT(m_associatedDocumentLoaders.contains(loader));
- ASSERT(loader->applicationCache() == m_cacheBeingUpdated);
- ASSERT(!loader->candidateApplicationCacheGroup());
+ ASSERT(loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated);
+ ASSERT(!loader->applicationCacheHost()->candidateApplicationCacheGroup());
m_associatedDocumentLoaders.remove(loader);
- loader->setApplicationCache(0);
+ loader->applicationCacheHost()->setApplicationCache(0);
- postListenerTask(&DOMApplicationCache::callErrorListener, loader);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, loader);
break;
}
@@ -332,7 +333,7 @@
m_pendingMasterResourceLoaders.remove(loader);
- loader->setApplicationCache(0); // Will set candidate to 0, too.
+ loader->applicationCacheHost()->setApplicationCache(0); // Will set candidate to 0, too.
if (!m_associatedDocumentLoaders.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty())
return;
@@ -388,9 +389,9 @@
{
if (m_updateStatus == Checking || m_updateStatus == Downloading) {
if (updateOption == ApplicationCacheUpdateWithBrowsingContext) {
- postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader());
+ postListenerTask(DOMApplicationCache::CHECKING_EVENT, frame->loader()->documentLoader());
if (m_updateStatus == Downloading)
- postListenerTask(&DOMApplicationCache::callDownloadingListener, frame->loader()->documentLoader());
+ postListenerTask(DOMApplicationCache::DOWNLOADING_EVENT, frame->loader()->documentLoader());
}
return;
}
@@ -400,8 +401,8 @@
ASSERT(m_pendingMasterResourceLoaders.isEmpty());
ASSERT(m_pendingEntries.isEmpty());
ASSERT(!m_cacheBeingUpdated);
- postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader());
- postListenerTask(&DOMApplicationCache::callNoUpdateListener, frame->loader()->documentLoader());
+ postListenerTask(DOMApplicationCache::CHECKING_EVENT, frame->loader()->documentLoader());
+ postListenerTask(DOMApplicationCache::NOUPDATE_EVENT, frame->loader()->documentLoader());
return;
}
@@ -410,10 +411,10 @@
m_updateStatus = Checking;
- postListenerTask(&DOMApplicationCache::callCheckingListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::CHECKING_EVENT, m_associatedDocumentLoaders);
if (!m_newestCache) {
ASSERT(updateOption == ApplicationCacheUpdateWithBrowsingContext);
- postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader());
+ postListenerTask(DOMApplicationCache::CHECKING_EVENT, frame->loader()->documentLoader());
}
ASSERT(!m_manifestHandle);
@@ -648,7 +649,7 @@
// We have the manifest, now download the resources.
m_updateStatus = Downloading;
- postListenerTask(&DOMApplicationCache::callDownloadingListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::DOWNLOADING_EVENT, m_associatedDocumentLoaders);
ASSERT(m_pendingEntries.isEmpty());
@@ -698,8 +699,8 @@
{
makeObsolete();
- postListenerTask(&DOMApplicationCache::callObsoleteListener, m_associatedDocumentLoaders);
- postListenerTask(&DOMApplicationCache::callErrorListener, m_pendingMasterResourceLoaders);
+ postListenerTask(DOMApplicationCache::OBSOLETE_EVENT, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, m_pendingMasterResourceLoaders);
stopLoading();
@@ -709,9 +710,9 @@
while (!m_pendingMasterResourceLoaders.isEmpty()) {
HashSet<DocumentLoader*>::iterator it = m_pendingMasterResourceLoaders.begin();
- ASSERT((*it)->candidateApplicationCacheGroup() == this);
- ASSERT(!(*it)->applicationCache());
- (*it)->setCandidateApplicationCacheGroup(0);
+ ASSERT((*it)->applicationCacheHost()->candidateApplicationCacheGroup() == this);
+ ASSERT(!(*it)->applicationCacheHost()->applicationCache());
+ (*it)->applicationCacheHost()->setCandidateApplicationCacheGroup(0);
m_pendingMasterResourceLoaders.remove(it);
}
@@ -747,11 +748,11 @@
if (!m_storageID)
cacheStorage().storeNewestCache(this);
- postListenerTask(&DOMApplicationCache::callNoUpdateListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::NOUPDATE_EVENT, m_associatedDocumentLoaders);
break;
case Failure:
ASSERT(!m_cacheBeingUpdated);
- postListenerTask(&DOMApplicationCache::callErrorListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, m_associatedDocumentLoaders);
if (m_caches.isEmpty()) {
ASSERT(m_associatedDocumentLoaders.isEmpty());
delete this;
@@ -780,7 +781,7 @@
if (oldNewestCache)
cacheStorage().remove(oldNewestCache.get());
// Fire the success events.
- postListenerTask(isUpgradeAttempt ? &DOMApplicationCache::callUpdateReadyListener : &DOMApplicationCache::callCachedListener, m_associatedDocumentLoaders);
+ postListenerTask(isUpgradeAttempt ? DOMApplicationCache::UPDATEREADY_EVENT : DOMApplicationCache::CACHED_EVENT, m_associatedDocumentLoaders);
} else {
if (cacheStorage().isMaximumSizeReached() && !m_calledReachedMaxAppCacheSize) {
// We ran out of space. All the changes in the cache storage have
@@ -800,7 +801,7 @@
// Run the "cache failure steps"
// Fire the error events to all pending master entries, as well any other cache hosts
// currently associated with a cache in this group.
- postListenerTask(&DOMApplicationCache::callErrorListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::ERROR_EVENT, m_associatedDocumentLoaders);
// Disassociate the pending master entries from the failed new cache. Note that
// all other loaders in the m_associatedDocumentLoaders are still associated with
// some other cache in this group. They are not associated with the failed new cache.
@@ -846,7 +847,7 @@
EntryMap::const_iterator it = m_pendingEntries.begin();
- postListenerTask(&DOMApplicationCache::callProgressListener, m_associatedDocumentLoaders);
+ postListenerTask(DOMApplicationCache::PROGRESS_EVENT, m_associatedDocumentLoaders);
ASSERT(!m_currentHandle);
@@ -910,7 +911,7 @@
ASSERT(!m_isObsolete);
- loader->setApplicationCache(cache);
+ loader->applicationCacheHost()->setApplicationCache(cache);
ASSERT(!m_associatedDocumentLoaders.contains(loader));
m_associatedDocumentLoaders.add(loader);
@@ -944,39 +945,44 @@
}
class CallCacheListenerTask : public ScriptExecutionContext::Task {
- typedef void (DOMApplicationCache::*ListenerFunction)();
public:
- static PassRefPtr<CallCacheListenerTask> create(ListenerFunction listenerFunction)
+ static PassRefPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, DOMApplicationCache::EventType eventType)
{
- return adoptRef(new CallCacheListenerTask(listenerFunction));
+ return adoptRef(new CallCacheListenerTask(loader, eventType));
}
virtual void performTask(ScriptExecutionContext* context)
{
- ASSERT(context->isDocument());
- if (DOMWindow* window = static_cast<Document*>(context)->domWindow()) {
- if (DOMApplicationCache* domCache = window->optionalApplicationCache())
- (domCache->*m_listenerFunction)();
- }
+
+ ASSERT_UNUSED(context, context->isDocument());
+ Frame* frame = m_documentLoader->frame();
+ if (!frame)
+ return;
+
+ ASSERT(frame->loader()->documentLoader() == m_documentLoader.get());
+
+ m_documentLoader->applicationCacheHost()->notifyEventListener(m_eventType);
}
private:
- CallCacheListenerTask(ListenerFunction listenerFunction)
- : m_listenerFunction(listenerFunction)
+ CallCacheListenerTask(PassRefPtr<DocumentLoader> loader, DOMApplicationCache::EventType eventType)
+ : m_documentLoader(loader)
+ , m_eventType(eventType)
{
}
- ListenerFunction m_listenerFunction;
+ RefPtr<DocumentLoader> m_documentLoader;
+ DOMApplicationCache::EventType m_eventType;
};
-void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, const HashSet<DocumentLoader*>& loaderSet)
+void ApplicationCacheGroup::postListenerTask(DOMApplicationCache::EventType eventType, const HashSet<DocumentLoader*>& loaderSet)
{
HashSet<DocumentLoader*>::const_iterator loaderSetEnd = loaderSet.end();
for (HashSet<DocumentLoader*>::const_iterator iter = loaderSet.begin(); iter != loaderSetEnd; ++iter)
- postListenerTask(listenerFunction, *iter);
+ postListenerTask(eventType, *iter);
}
-void ApplicationCacheGroup::postListenerTask(ListenerFunction listenerFunction, DocumentLoader* loader)
+void ApplicationCacheGroup::postListenerTask(DOMApplicationCache::EventType eventType, DocumentLoader* loader)
{
Frame* frame = loader->frame();
if (!frame)
@@ -984,7 +990,7 @@
ASSERT(frame->loader()->documentLoader() == loader);
- frame->document()->postTask(CallCacheListenerTask::create(listenerFunction));
+ frame->document()->postTask(CallCacheListenerTask::create(loader, eventType));
}
void ApplicationCacheGroup::clearStorageID()
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.h b/WebCore/loader/appcache/ApplicationCacheGroup.h
index 375bd17..57b2f7b 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.h
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.h
@@ -32,6 +32,7 @@
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include "DOMApplicationCache.h"
#include "KURL.h"
#include "PlatformString.h"
#include "ResourceHandle.h"
@@ -42,7 +43,6 @@
class ApplicationCache;
class ApplicationCacheResource;
-class DOMApplicationCache;
class Document;
class DocumentLoader;
class Frame;
@@ -92,9 +92,8 @@
private:
typedef void (DOMApplicationCache::*ListenerFunction)();
- static void postListenerTask(ListenerFunction, const HashSet<DocumentLoader*>&);
- static void postListenerTask(ListenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders);
- static void postListenerTask(ListenerFunction, DocumentLoader*);
+ static void postListenerTask(DOMApplicationCache::EventType, const HashSet<DocumentLoader*>&);
+ static void postListenerTask(DOMApplicationCache::EventType, DocumentLoader*);
void scheduleReachedMaxAppCacheSizeCallback();
PassRefPtr<ResourceHandle> createResourceHandle(const KURL&, ApplicationCacheResource* newestCachedResource);
diff --git a/WebCore/loader/appcache/ApplicationCacheHost.cpp b/WebCore/loader/appcache/ApplicationCacheHost.cpp
new file mode 100644
index 0000000..cba8ce5
--- /dev/null
+++ b/WebCore/loader/appcache/ApplicationCacheHost.cpp
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ApplicationCacheHost.h"
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+
+#include "ApplicationCache.h"
+#include "ApplicationCacheGroup.h"
+#include "ApplicationCacheResource.h"
+#include "DocumentLoader.h"
+#include "DOMApplicationCache.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "MainResourceLoader.h"
+#include "ResourceLoader.h"
+#include "ResourceRequest.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
+ : m_DOMApplicationCache(0)
+ , m_documentLoader(documentLoader)
+ , m_candidateApplicationCacheGroup(0)
+{
+ ASSERT(m_documentLoader);
+}
+
+ApplicationCacheHost::~ApplicationCacheHost()
+{
+ if (m_applicationCache)
+ m_applicationCache->group()->disassociateDocumentLoader(m_documentLoader);
+ else if (m_candidateApplicationCacheGroup)
+ m_candidateApplicationCacheGroup->disassociateDocumentLoader(m_documentLoader);
+}
+
+void ApplicationCacheHost::selectCacheWithoutManifest()
+{
+ ApplicationCacheGroup::selectCacheWithoutManifestURL(m_documentLoader->frame());
+}
+
+void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL)
+{
+ ApplicationCacheGroup::selectCache(m_documentLoader->frame(), manifestURL);
+}
+
+void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData)
+{
+ // Check if this request should be loaded from the application cache
+ if (!substituteData.isValid() && isApplicationCacheEnabled()) {
+ ASSERT(!m_mainResourceApplicationCache);
+
+ m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, m_documentLoader);
+
+ if (m_mainResourceApplicationCache) {
+ // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource.
+ ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request);
+ substituteData = SubstituteData(resource->data(),
+ resource->response().mimeType(),
+ resource->response().textEncodingName(), KURL());
+ }
+ }
+}
+
+bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceRequest& request, const ResourceResponse& r)
+{
+ if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) {
+ ASSERT(!m_mainResourceApplicationCache);
+ if (isApplicationCacheEnabled()) {
+ m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader());
+
+ if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest& request, const ResourceError& error)
+{
+ if (!error.isCancellation()) {
+ ASSERT(!m_mainResourceApplicationCache);
+ if (isApplicationCacheEnabled()) {
+ m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader);
+
+ if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
+ return true;
+ }
+ }
+ return false;
+}
+
+void ApplicationCacheHost::mainResourceDataReceived(const char*, int, long long, bool)
+{
+ // This method is here to facilitate alternate implemetations of this interface by the host browser.
+}
+
+void ApplicationCacheHost::failedLoadingMainResource()
+{
+ ApplicationCacheGroup* group = m_candidateApplicationCacheGroup;
+ if (!group && m_applicationCache) {
+ ASSERT(!mainResourceApplicationCache()); // If the main resource were loaded from a cache, it wouldn't fail.
+ group = m_applicationCache->group();
+ }
+
+ if (group)
+ group->failedLoadingMainResource(m_documentLoader);
+}
+
+void ApplicationCacheHost::finishedLoadingMainResource()
+{
+ ApplicationCacheGroup* group = candidateApplicationCacheGroup();
+ if (!group && applicationCache() && !mainResourceApplicationCache())
+ group = applicationCache()->group();
+
+ if (group)
+ group->finishedLoadingMainResource(m_documentLoader);
+}
+
+bool ApplicationCacheHost::maybeLoadResource(ResourceLoader* loader, ResourceRequest& request, const KURL& originalURL)
+{
+ if (!isApplicationCacheEnabled())
+ return false;
+
+ if (request.url() != originalURL)
+ return false;
+
+ ApplicationCacheResource* resource;
+ if (!shouldLoadResourceFromApplicationCache(request, resource))
+ return false;
+
+ m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
+ m_documentLoader->deliverSubstituteResourcesAfterDelay();
+
+ return true;
+}
+
+bool ApplicationCacheHost::maybeLoadFallbackForRedirect(ResourceLoader* resourceLoader, ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+ if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url()))
+ if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
+ return true;
+ return false;
+}
+
+bool ApplicationCacheHost::maybeLoadFallbackForResponse(ResourceLoader* resourceLoader, const ResourceResponse& response)
+{
+ if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5)
+ if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
+ return true;
+ return false;
+}
+
+bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader* resourceLoader, const ResourceError& error)
+{
+ if (!error.isCancellation())
+ if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
+ return true;
+ return false;
+}
+
+bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+{
+ ApplicationCacheResource* resource;
+ if (shouldLoadResourceFromApplicationCache(request, resource)) {
+ if (resource) {
+ response = resource->response();
+ data.append(resource->data()->data(), resource->data()->size());
+ } else {
+ error = documentLoader()->frameLoader()->client()->cannotShowURLError(request);
+ }
+ return true;
+ }
+ return false;
+}
+
+void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+{
+ // If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent,
+ // or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry
+ // corresponding to the matched namespace.
+ if ((!error.isNull() && !error.isCancellation())
+ || response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5
+ || !protocolHostAndPortAreEqual(request.url(), response.url())) {
+ ApplicationCacheResource* resource;
+ if (getApplicationCacheFallbackResource(request, resource)) {
+ response = resource->response();
+ data.clear();
+ data.append(resource->data()->data(), resource->data()->size());
+ }
+ }
+}
+
+bool ApplicationCacheHost::canCacheInPageCache() const
+{
+ return !applicationCache() && !candidateApplicationCacheGroup();
+}
+
+void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group)
+{
+ ASSERT(!m_applicationCache);
+ m_candidateApplicationCacheGroup = group;
+}
+
+void ApplicationCacheHost::setApplicationCache(PassRefPtr<ApplicationCache> applicationCache)
+{
+ if (m_candidateApplicationCacheGroup) {
+ ASSERT(!m_applicationCache);
+ m_candidateApplicationCacheGroup = 0;
+ }
+
+ m_applicationCache = applicationCache;
+}
+
+bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const ResourceRequest& request, ApplicationCacheResource*& resource)
+{
+ ApplicationCache* cache = applicationCache();
+ if (!cache || !cache->isComplete())
+ return false;
+
+ // If the resource is not a HTTP/HTTPS GET, then abort
+ if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
+ return false;
+
+ // If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry
+ // in the application cache, then get the resource from the cache (instead of fetching it).
+ resource = cache->resourceForURL(request.url());
+
+ // Resources that match fallback namespaces or online whitelist entries are fetched from the network,
+ // unless they are also cached.
+ if (!resource && (cache->urlMatchesFallbackNamespace(request.url()) || cache->isURLInOnlineWhitelist(request.url())))
+ return false;
+
+ // Resources that are not present in the manifest will always fail to load (at least, after the
+ // cache has been primed the first time), making the testing of offline applications simpler.
+ return true;
+}
+
+bool ApplicationCacheHost::getApplicationCacheFallbackResource(const ResourceRequest& request, ApplicationCacheResource*& resource, ApplicationCache* cache)
+{
+ if (!cache) {
+ cache = applicationCache();
+ if (!cache)
+ return false;
+ }
+ if (!cache->isComplete())
+ return false;
+
+ // If the resource is not a HTTP/HTTPS GET, then abort
+ if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
+ return false;
+
+ KURL fallbackURL;
+ if (!cache->urlMatchesFallbackNamespace(request.url(), &fallbackURL))
+ return false;
+
+ resource = cache->resourceForURL(fallbackURL);
+ ASSERT(resource);
+
+ return true;
+}
+
+bool ApplicationCacheHost::scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader* loader, ApplicationCache* cache)
+{
+ if (!isApplicationCacheEnabled())
+ return false;
+
+ ApplicationCacheResource* resource;
+ if (!getApplicationCacheFallbackResource(loader->request(), resource, cache))
+ return false;
+
+ m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
+ m_documentLoader->deliverSubstituteResourcesAfterDelay();
+
+ loader->handle()->cancel();
+
+ return true;
+}
+
+DOMApplicationCache::Status ApplicationCacheHost::status() const
+{
+ ApplicationCache* cache = applicationCache();
+ if (!cache)
+ return DOMApplicationCache::UNCACHED;
+
+ switch (cache->group()->updateStatus()) {
+ case ApplicationCacheGroup::Checking:
+ return DOMApplicationCache::CHECKING;
+ case ApplicationCacheGroup::Downloading:
+ return DOMApplicationCache::DOWNLOADING;
+ case ApplicationCacheGroup::Idle: {
+ if (cache->group()->isObsolete())
+ return DOMApplicationCache::OBSOLETE;
+ if (cache != cache->group()->newestCache())
+ return DOMApplicationCache::UPDATEREADY;
+ return DOMApplicationCache::IDLE;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return DOMApplicationCache::UNCACHED;
+}
+
+bool ApplicationCacheHost::update()
+{
+ ApplicationCache* cache = applicationCache();
+ if (!cache)
+ return false;
+ cache->group()->update(m_documentLoader->frame(), ApplicationCacheUpdateWithoutBrowsingContext);
+ return true;
+}
+
+bool ApplicationCacheHost::swapCache()
+{
+ ApplicationCache* cache = applicationCache();
+ if (!cache)
+ return false;
+
+ // If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache.
+ if (cache->group()->isObsolete()) {
+ cache->group()->disassociateDocumentLoader(m_documentLoader);
+ return true;
+ }
+
+ // If there is no newer cache, raise an INVALID_STATE_ERR exception.
+ ApplicationCache* newestCache = cache->group()->newestCache();
+ if (cache == newestCache)
+ return false;
+
+ ASSERT(cache->group() == newestCache->group());
+ setApplicationCache(newestCache);
+
+ return true;
+}
+
+bool ApplicationCacheHost::isApplicationCacheEnabled()
+{
+ return m_documentLoader->frame()->settings()
+ && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(APPLICATION_CACHE)
diff --git a/WebCore/loader/appcache/ApplicationCacheHost.h b/WebCore/loader/appcache/ApplicationCacheHost.h
new file mode 100644
index 0000000..9954985
--- /dev/null
+++ b/WebCore/loader/appcache/ApplicationCacheHost.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ApplicationCacheHost_h
+#define ApplicationCacheHost_h
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+
+#include "DOMApplicationCache.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class ApplicationCache;
+ class ApplicationCacheGroup;
+ class ApplicationCacheResource;
+ class ApplicationCacheStorage;
+ class DocumentLoader;
+ class KURL;
+ class ResourceLoader;
+ class ResourceError;
+ class ResourceRequest;
+ class ResourceResponse;
+ class SubstituteData;
+
+ class ApplicationCacheHost {
+ public:
+ ApplicationCacheHost(DocumentLoader*);
+ ~ApplicationCacheHost();
+
+ void selectCacheWithoutManifest();
+ void selectCacheWithManifest(const KURL& manifestURL);
+
+ void maybeLoadMainResource(ResourceRequest&, SubstituteData&);
+ bool maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse&);
+ bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&);
+ void mainResourceDataReceived(const char* data, int length, long long lengthReceived, bool allAtOnce);
+ void finishedLoadingMainResource();
+ void failedLoadingMainResource();
+
+ bool maybeLoadResource(ResourceLoader*, ResourceRequest&, const KURL& originalURL);
+ bool maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&);
+ bool maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&);
+ bool maybeLoadFallbackForError(ResourceLoader*, const ResourceError&);
+
+ bool maybeLoadSynchronously(ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
+ void maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
+
+ bool canCacheInPageCache() const;
+
+ DOMApplicationCache::Status status() const;
+ bool update();
+ bool swapCache();
+
+ void setDOMApplicationCache(DOMApplicationCache* domApplicationCache)
+ {
+ ASSERT(!m_DOMApplicationCache || !domApplicationCache);
+ m_DOMApplicationCache = domApplicationCache;
+ }
+
+ void notifyEventListener(DOMApplicationCache::EventType eventType)
+ {
+ if (m_DOMApplicationCache)
+ m_DOMApplicationCache->callEventListener(eventType);
+ }
+
+ private:
+ friend class ApplicationCacheGroup;
+ friend class ApplicationCacheStorage;
+
+ bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = 0);
+ bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
+ bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = 0);
+ void setCandidateApplicationCacheGroup(ApplicationCacheGroup* group);
+ ApplicationCacheGroup* candidateApplicationCacheGroup() const { return m_candidateApplicationCacheGroup; }
+ void setApplicationCache(PassRefPtr<ApplicationCache> applicationCache);
+ ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
+ ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); }
+
+ bool isApplicationCacheEnabled();
+ DocumentLoader* documentLoader() { return m_documentLoader; }
+
+ DOMApplicationCache* m_DOMApplicationCache;
+ DocumentLoader* m_documentLoader;
+
+ // The application cache that the document loader is associated with (if any).
+ RefPtr<ApplicationCache> m_applicationCache;
+
+ // Before an application cache has finished loading, this will be the candidate application
+ // group that the document loader is associated with.
+ ApplicationCacheGroup* m_candidateApplicationCacheGroup;
+
+ // This is the application cache the main resource was loaded from (if any).
+ RefPtr<ApplicationCache> m_mainResourceApplicationCache;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(APPLICATION_CACHE)
+#endif // ApplicationCacheFrontend_h
diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.cpp b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
index 18a0ed4..7068847 100644
--- a/WebCore/loader/appcache/ApplicationCacheStorage.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheStorage.cpp
@@ -29,6 +29,7 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "ApplicationCache.h"
+#include "ApplicationCacheHost.h"
#include "ApplicationCacheGroup.h"
#include "ApplicationCacheResource.h"
#include "CString.h"
@@ -937,6 +938,14 @@
it->second->clearStorageID();
}
+bool ApplicationCacheStorage::transferApplicationCache(const String& cacheDirectory, ApplicationCacheHost* cacheHost)
+{
+ ApplicationCache* cache = cacheHost->applicationCache();
+ if (!cache)
+ return true;
+ return ApplicationCacheStorage::storeCopyOfCache(cacheDirectory, cache);
+}
+
bool ApplicationCacheStorage::storeCopyOfCache(const String& cacheDirectory, ApplicationCache* cache)
{
// Create a new cache.
diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.h b/WebCore/loader/appcache/ApplicationCacheStorage.h
index c6d687e..a0047c6 100644
--- a/WebCore/loader/appcache/ApplicationCacheStorage.h
+++ b/WebCore/loader/appcache/ApplicationCacheStorage.h
@@ -37,6 +37,7 @@
namespace WebCore {
class ApplicationCache;
+class ApplicationCacheHost;
class ApplicationCacheGroup;
class ApplicationCacheResource;
class KURL;
@@ -69,6 +70,7 @@
void empty();
+ static bool transferApplicationCache(const String& cacheDirectory, ApplicationCacheHost*);
static bool storeCopyOfCache(const String& cacheDirectory, ApplicationCache*);
bool manifestURLs(Vector<KURL>* urls);
diff --git a/WebCore/loader/appcache/DOMApplicationCache.cpp b/WebCore/loader/appcache/DOMApplicationCache.cpp
index 5ea5d4f..3778ef9 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.cpp
+++ b/WebCore/loader/appcache/DOMApplicationCache.cpp
@@ -28,9 +28,7 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "ApplicationCache.h"
-#include "ApplicationCacheGroup.h"
-#include "ApplicationCacheResource.h"
+#include "ApplicationCacheHost.h"
#include "DocumentLoader.h"
#include "Event.h"
#include "EventException.h"
@@ -44,80 +42,46 @@
DOMApplicationCache::DOMApplicationCache(Frame* frame)
: m_frame(frame)
{
+ ASSERT(applicationCacheHost());
+ applicationCacheHost()->setDOMApplicationCache(this);
}
void DOMApplicationCache::disconnectFrame()
{
+ ApplicationCacheHost* cacheHost = applicationCacheHost();
+ if (cacheHost)
+ cacheHost->setDOMApplicationCache(0);
m_frame = 0;
}
-ApplicationCache* DOMApplicationCache::associatedCache() const
+ApplicationCacheHost* DOMApplicationCache::applicationCacheHost() const
{
- if (!m_frame)
+ if (!m_frame || !m_frame->loader()->documentLoader())
return 0;
-
- return m_frame->loader()->documentLoader()->applicationCache();
+ return m_frame->loader()->documentLoader()->applicationCacheHost();
}
unsigned short DOMApplicationCache::status() const
{
- ApplicationCache* cache = associatedCache();
- if (!cache)
+ ApplicationCacheHost* cacheHost = applicationCacheHost();
+ if (!cacheHost)
return UNCACHED;
-
- switch (cache->group()->updateStatus()) {
- case ApplicationCacheGroup::Checking:
- return CHECKING;
- case ApplicationCacheGroup::Downloading:
- return DOWNLOADING;
- case ApplicationCacheGroup::Idle: {
- if (cache->group()->isObsolete())
- return OBSOLETE;
- if (cache != cache->group()->newestCache())
- return UPDATEREADY;
- return IDLE;
- }
- }
-
- ASSERT_NOT_REACHED();
- return 0;
+ return cacheHost->status();
}
void DOMApplicationCache::update(ExceptionCode& ec)
{
- ApplicationCache* cache = associatedCache();
- if (!cache) {
+ ApplicationCacheHost* cacheHost = applicationCacheHost();
+ if (!cacheHost || !cacheHost->update())
ec = INVALID_STATE_ERR;
- return;
- }
-
- cache->group()->update(m_frame, ApplicationCacheUpdateWithoutBrowsingContext);
}
bool DOMApplicationCache::swapCache()
{
- if (!m_frame)
+ ApplicationCacheHost* cacheHost = applicationCacheHost();
+ if (!cacheHost)
return false;
-
- ApplicationCache* cache = m_frame->loader()->documentLoader()->applicationCache();
- if (!cache)
- return false;
-
- // If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache.
- if (cache->group()->isObsolete()) {
- cache->group()->disassociateDocumentLoader(m_frame->loader()->documentLoader());
- return true;
- }
-
- // If there is no newer cache, raise an INVALID_STATE_ERR exception.
- ApplicationCache* newestCache = cache->group()->newestCache();
- if (cache == newestCache)
- return false;
-
- ASSERT(cache->group() == newestCache->group());
- m_frame->loader()->documentLoader()->setApplicationCache(newestCache);
-
- return true;
+ return cacheHost->swapCache();
}
void DOMApplicationCache::swapCache(ExceptionCode& ec)
@@ -131,13 +95,13 @@
return m_frame->document();
}
-void DOMApplicationCache::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
+void DOMApplicationCache::addEventListener(const AtomicString& eventName, PassRefPtr<EventListener> eventListener, bool)
{
- EventListenersMap::iterator iter = m_eventListeners.find(eventType);
+ EventListenersMap::iterator iter = m_eventListeners.find(eventName);
if (iter == m_eventListeners.end()) {
ListenerVector listeners;
listeners.append(eventListener);
- m_eventListeners.add(eventType, listeners);
+ m_eventListeners.add(eventName, listeners);
} else {
ListenerVector& listeners = iter->second;
for (ListenerVector::iterator listenerIter = listeners.begin(); listenerIter != listeners.end(); ++listenerIter) {
@@ -146,13 +110,13 @@
}
listeners.append(eventListener);
- m_eventListeners.add(eventType, listeners);
+ m_eventListeners.add(eventName, listeners);
}
}
-void DOMApplicationCache::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool)
+void DOMApplicationCache::removeEventListener(const AtomicString& eventName, EventListener* eventListener, bool)
{
- EventListenersMap::iterator iter = m_eventListeners.find(eventType);
+ EventListenersMap::iterator iter = m_eventListeners.find(eventName);
if (iter == m_eventListeners.end())
return;
@@ -171,7 +135,7 @@
ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
return true;
}
-
+
ListenerVector listenersCopy = m_eventListeners.get(event->type());
for (ListenerVector::const_iterator listenerIter = listenersCopy.begin(); listenerIter != listenersCopy.end(); ++listenerIter) {
event->setTarget(this);
@@ -182,11 +146,11 @@
return !event->defaultPrevented();
}
-void DOMApplicationCache::callListener(const AtomicString& eventType, EventListener* listener)
+void DOMApplicationCache::callListener(const AtomicString& eventName, EventListener* listener)
{
ASSERT(m_frame);
- RefPtr<Event> event = Event::create(eventType, false, false);
+ RefPtr<Event> event = Event::create(eventName, false, false);
if (listener) {
event->setTarget(this);
event->setCurrentTarget(this);
@@ -198,45 +162,55 @@
ASSERT(!ec);
}
-void DOMApplicationCache::callCheckingListener()
+// static
+const AtomicString& DOMApplicationCache::toEventName(EventType eventType)
{
- callListener(eventNames().checkingEvent, m_onCheckingListener.get());
+ switch (eventType) {
+ case CHECKING_EVENT:
+ return eventNames().checkingEvent;
+ case ERROR_EVENT:
+ return eventNames().errorEvent;
+ case NOUPDATE_EVENT:
+ return eventNames().noupdateEvent;
+ case DOWNLOADING_EVENT:
+ return eventNames().downloadingEvent;
+ case PROGRESS_EVENT:
+ return eventNames().progressEvent;
+ case UPDATEREADY_EVENT:
+ return eventNames().updatereadyEvent;
+ case CACHED_EVENT:
+ return eventNames().cachedEvent;
+ case OBSOLETE_EVENT:
+ return eventNames().obsoleteEvent;
+ }
+ ASSERT_NOT_REACHED();
+ return eventNames().errorEvent;
}
-void DOMApplicationCache::callErrorListener()
+// static
+DOMApplicationCache::EventType DOMApplicationCache::toEventType(const AtomicString& eventName)
{
- callListener(eventNames().errorEvent, m_onErrorListener.get());
+ if (eventName == eventNames().checkingEvent)
+ return CHECKING_EVENT;
+ if (eventName == eventNames().errorEvent)
+ return ERROR_EVENT;
+ if (eventName == eventNames().noupdateEvent)
+ return NOUPDATE_EVENT;
+ if (eventName == eventNames().downloadingEvent)
+ return DOWNLOADING_EVENT;
+ if (eventName == eventNames().progressEvent)
+ return PROGRESS_EVENT;
+ if (eventName == eventNames().updatereadyEvent)
+ return UPDATEREADY_EVENT;
+ if (eventName == eventNames().cachedEvent)
+ return CACHED_EVENT;
+ if (eventName == eventNames().obsoleteEvent)
+ return OBSOLETE_EVENT;
+
+ ASSERT_NOT_REACHED();
+ return ERROR_EVENT;
}
-void DOMApplicationCache::callNoUpdateListener()
-{
- callListener(eventNames().noupdateEvent, m_onNoUpdateListener.get());
-}
-
-void DOMApplicationCache::callDownloadingListener()
-{
- callListener(eventNames().downloadingEvent, m_onDownloadingListener.get());
-}
-
-void DOMApplicationCache::callProgressListener()
-{
- callListener(eventNames().progressEvent, m_onProgressListener.get());
-}
-
-void DOMApplicationCache::callUpdateReadyListener()
-{
- callListener(eventNames().updatereadyEvent, m_onUpdateReadyListener.get());
-}
-
-void DOMApplicationCache::callCachedListener()
-{
- callListener(eventNames().cachedEvent, m_onCachedListener.get());
-}
-
-void DOMApplicationCache::callObsoleteListener()
-{
- callListener(eventNames().obsoleteEvent, m_onObsoleteListener.get());
-}
} // namespace WebCore
diff --git a/WebCore/loader/appcache/DOMApplicationCache.h b/WebCore/loader/appcache/DOMApplicationCache.h
index 4fe1511..4ef68b7 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.h
+++ b/WebCore/loader/appcache/DOMApplicationCache.h
@@ -38,7 +38,7 @@
namespace WebCore {
-class ApplicationCache;
+class ApplicationCacheHost;
class AtomicStringImpl;
class Frame;
class KURL;
@@ -47,6 +47,8 @@
class DOMApplicationCache : public RefCounted<DOMApplicationCache>, public EventTarget {
public:
static PassRefPtr<DOMApplicationCache> create(Frame* frame) { return adoptRef(new DOMApplicationCache(frame)); }
+ ~DOMApplicationCache() { ASSERT(!m_frame); }
+
void disconnectFrame();
enum Status {
@@ -58,15 +60,33 @@
OBSOLETE = 5
};
+ enum EventType {
+ CHECKING_EVENT = 0,
+ ERROR_EVENT,
+ NOUPDATE_EVENT,
+ DOWNLOADING_EVENT,
+ PROGRESS_EVENT,
+ UPDATEREADY_EVENT,
+ CACHED_EVENT,
+ OBSOLETE_EVENT
+ };
+
unsigned short status() const;
-
void update(ExceptionCode&);
void swapCache(ExceptionCode&);
-
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+
+ // Event listener attributes by EventType
+
+ void setAttributeEventListener(EventType type, PassRefPtr<EventListener> eventListener) { m_attributeEventListeners[type] = eventListener; }
+ EventListener* getAttributeEventListener(EventType type) const { return m_attributeEventListeners[type].get(); }
+ void clearAttributeEventListener(EventType type) { m_attributeEventListeners[type] = 0; }
+ void callEventListener(EventType type) { callListener(toEventName(type), getAttributeEventListener(type)); }
+
+ // EventTarget impl
+
+ virtual void addEventListener(const AtomicString& eventName, PassRefPtr<EventListener>, bool useCapture);
+ virtual void removeEventListener(const AtomicString& eventName, EventListener*, bool useCapture);
virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
-
typedef Vector<RefPtr<EventListener> > ListenerVector;
typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
EventListenersMap& eventListeners() { return m_eventListeners; }
@@ -74,61 +94,51 @@
using RefCounted<DOMApplicationCache>::ref;
using RefCounted<DOMApplicationCache>::deref;
- void setOnchecking(PassRefPtr<EventListener> eventListener) { m_onCheckingListener = eventListener; }
- EventListener* onchecking() const { return m_onCheckingListener.get(); }
+ // Explicitly named attribute event listener helpers
- void setOnerror(PassRefPtr<EventListener> eventListener) { m_onErrorListener = eventListener; }
- EventListener* onerror() const { return m_onErrorListener.get(); }
+ void setOnchecking(PassRefPtr<EventListener> listener) { setAttributeEventListener(CHECKING_EVENT, listener); }
+ EventListener* onchecking() const { return getAttributeEventListener(CHECKING_EVENT); }
- void setOnnoupdate(PassRefPtr<EventListener> eventListener) { m_onNoUpdateListener = eventListener; }
- EventListener* onnoupdate() const { return m_onNoUpdateListener.get(); }
+ void setOnerror(PassRefPtr<EventListener> listener) { setAttributeEventListener(ERROR_EVENT, listener);}
+ EventListener* onerror() const { return getAttributeEventListener(ERROR_EVENT); }
- void setOndownloading(PassRefPtr<EventListener> eventListener) { m_onDownloadingListener = eventListener; }
- EventListener* ondownloading() const { return m_onDownloadingListener.get(); }
-
- void setOnprogress(PassRefPtr<EventListener> eventListener) { m_onProgressListener = eventListener; }
- EventListener* onprogress() const { return m_onProgressListener.get(); }
+ void setOnnoupdate(PassRefPtr<EventListener> listener) { setAttributeEventListener(NOUPDATE_EVENT, listener); }
+ EventListener* onnoupdate() const { return getAttributeEventListener(NOUPDATE_EVENT); }
- void setOnupdateready(PassRefPtr<EventListener> eventListener) { m_onUpdateReadyListener = eventListener; }
- EventListener* onupdateready() const { return m_onUpdateReadyListener.get(); }
+ void setOndownloading(PassRefPtr<EventListener> listener) { setAttributeEventListener(DOWNLOADING_EVENT, listener); }
+ EventListener* ondownloading() const { return getAttributeEventListener(DOWNLOADING_EVENT); }
- void setOncached(PassRefPtr<EventListener> eventListener) { m_onCachedListener = eventListener; }
- EventListener* oncached() const { return m_onCachedListener.get(); }
+ void setOnprogress(PassRefPtr<EventListener> listener) { setAttributeEventListener(PROGRESS_EVENT, listener); }
+ EventListener* onprogress() const { return getAttributeEventListener(PROGRESS_EVENT); }
- void setOnobsolete(PassRefPtr<EventListener> eventListener) { m_onObsoleteListener = eventListener; }
- EventListener* onobsolete() const { return m_onObsoleteListener.get(); }
+ void setOnupdateready(PassRefPtr<EventListener> listener) { setAttributeEventListener(UPDATEREADY_EVENT, listener); }
+ EventListener* onupdateready() const { return getAttributeEventListener(UPDATEREADY_EVENT); }
+
+ void setOncached(PassRefPtr<EventListener> listener) { setAttributeEventListener(CACHED_EVENT, listener); }
+ EventListener* oncached() const { return getAttributeEventListener(CACHED_EVENT); }
+
+ void setOnobsolete(PassRefPtr<EventListener> listener) { setAttributeEventListener(OBSOLETE_EVENT, listener); }
+ EventListener* onobsolete() const { return getAttributeEventListener(OBSOLETE_EVENT); }
virtual ScriptExecutionContext* scriptExecutionContext() const;
DOMApplicationCache* toDOMApplicationCache() { return this; }
- void callCheckingListener();
- void callErrorListener();
- void callNoUpdateListener();
- void callDownloadingListener();
- void callProgressListener();
- void callUpdateReadyListener();
- void callCachedListener();
- void callObsoleteListener();
-
+ static const AtomicString& toEventName(EventType eventType);
+ static EventType toEventType(const AtomicString& eventName);
+
private:
DOMApplicationCache(Frame*);
- void callListener(const AtomicString& eventType, EventListener*);
+
+ void callListener(const AtomicString& eventName, EventListener*);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
- ApplicationCache* associatedCache() const;
+ ApplicationCacheHost* applicationCacheHost() const;
bool swapCache();
- RefPtr<EventListener> m_onCheckingListener;
- RefPtr<EventListener> m_onErrorListener;
- RefPtr<EventListener> m_onNoUpdateListener;
- RefPtr<EventListener> m_onDownloadingListener;
- RefPtr<EventListener> m_onProgressListener;
- RefPtr<EventListener> m_onUpdateReadyListener;
- RefPtr<EventListener> m_onCachedListener;
- RefPtr<EventListener> m_onObsoleteListener;
-
+ RefPtr<EventListener> m_attributeEventListeners[OBSOLETE_EVENT + 1];
+
EventListenersMap m_eventListeners;
Frame* m_frame;
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index d8b87e5..af93f70 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -957,6 +957,32 @@
return WebCore::protocolIs(string, protocol);
}
+bool protocolHostAndPortAreEqual(const KURL& a, const KURL& b)
+{
+ if (a.parsed().scheme.end() != b.parsed().scheme.end())
+ return false;
+
+ int hostStartA = a.hostStart();
+ int hostStartB = b.hostStart();
+ if (a.hostEnd() - hostStartA != b.hostEnd() - hostStartB)
+ return false;
+
+ // Check the scheme
+ for (int i = 0; i < a.parsed().scheme.end(); ++i)
+ if (a.string()[i] != b.string()[i])
+ return false;
+
+ // And the host
+ for (int i = hostStartA; i < static_cast<int>(a.hostEnd()); ++i)
+ if (a.string()[i] != b.string()[i])
+ return false;
+
+ if (a.port() != b.port())
+ return false;
+
+ return true;
+}
+
} // namespace WebCore
#endif // USE(GOOGLEURL)
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index c0fe418..37675f6 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,14 @@
+2009-07-30 Michael Nordman <michaeln@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=27821
+
+ Mods to keep up with ApplicationCacheHost refactoring.
+
+ * WebView/WebDataSource.mm:
+ (-[WebDataSource _transferApplicationCache:]):
+
2009-07-29 David Kilzer <ddkilzer@apple.com>
<http://webkit.org/b/27788> Don't export WebPluginController.h as a private header
diff --git a/WebKit/mac/WebView/WebDataSource.mm b/WebKit/mac/WebView/WebDataSource.mm
index 68b72349..1e70ad6 100644
--- a/WebKit/mac/WebView/WebDataSource.mm
+++ b/WebKit/mac/WebView/WebDataSource.mm
@@ -198,14 +198,10 @@
if (!loader)
return NO;
-
- ApplicationCache* cache = loader->applicationCache();
- if (!cache)
- return YES;
-
+
NSString *cacheDir = [NSString _webkit_localCacheDirectoryWithBundleIdentifier:destinationBundleIdentifier];
- return ApplicationCacheStorage::storeCopyOfCache(cacheDir, cache);
+ return ApplicationCacheStorage::transferApplicationCache(cacheDir, loader->applicationCacheHost());
}
@end