LayoutTests:
Reviewed by Geoff.
<rdar://problem/5244734>
WebKit shouldn't send delegate resource load methods for the user stylesheet (doing so causes assertions in Safari)
* fast/loader/resources/user-style-sheet.css: Added.
* fast/loader/user-style-sheet-resource-load-callbacks.html: Added.
WebCore:
Reviewed by Maciej and Geoff.
<rdar://problem/5244734>
WebKit shouldn't send delegate resource load methods for the user stylesheet (doing so causes assertions in Safari)
Add a sendResourceLoadCallbacks argument to the ResourceLoader and only send resource load callbacks if it's true. Make it so that
loading the user style sheet creates a resource loader with sendResourceLoadCallbacks set to false (done by adding a sendResourceLoadCallbacks
argument to a bunch of classes).
* loader/Cache.cpp:
(WebCore::createResource):
(WebCore::Cache::requestResource):
* loader/Cache.h:
* loader/CachedCSSStyleSheet.cpp:
(WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet):
* loader/CachedCSSStyleSheet.h:
* loader/CachedResource.cpp:
(WebCore::CachedResource::CachedResource):
* loader/CachedResource.h:
(WebCore::CachedResource::sendResourceLoadCallbacks):
* loader/DocLoader.cpp:
(WebCore::DocLoader::requestCSSStyleSheet):
(WebCore::DocLoader::requestResource):
(WebCore::DocLoader::checkCacheObjectStatus):
* loader/DocLoader.h:
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::MainResourceLoader):
* loader/Request.cpp:
(WebCore::Request::Request):
* loader/Request.h:
(WebCore::Request::sendResourceLoadCallbacks):
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::ResourceLoader):
(WebCore::ResourceLoader::willSendRequest):
(WebCore::ResourceLoader::didReceiveResponse):
(WebCore::ResourceLoader::didReceiveData):
(WebCore::ResourceLoader::didFinishLoadingOnePart):
(WebCore::ResourceLoader::didFail):
(WebCore::ResourceLoader::didCancel):
* loader/ResourceLoader.h:
(WebCore::ResourceLoader::sendResourceLoadCallbacks):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::SubresourceLoader):
(WebCore::SubresourceLoader::create):
* loader/SubresourceLoader.h:
* loader/loader.cpp:
(WebCore::Loader::load):
(WebCore::Loader::servePendingRequests):
* loader/loader.h:
* loader/mac/NetscapePlugInStreamLoaderMac.mm:
(WebCore::NetscapePlugInStreamLoader::NetscapePlugInStreamLoader):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@23741 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index 3a1b15f..0240bab 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -56,14 +56,14 @@
{
}
-static CachedResource* createResource(CachedResource::Type type, DocLoader* docLoader, const KURL& url, const String* charset, bool skipCanLoadCheck = false)
+static CachedResource* createResource(CachedResource::Type type, DocLoader* docLoader, const KURL& url, const String* charset, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true)
{
switch (type) {
case CachedResource::ImageResource:
// User agent images need to null check the docloader. No other resources need to.
return new CachedImage(docLoader, url.url(), true /* for cache */);
case CachedResource::CSSStyleSheet:
- return new CachedCSSStyleSheet(docLoader, url.url(), *charset, skipCanLoadCheck);
+ return new CachedCSSStyleSheet(docLoader, url.url(), *charset, skipCanLoadCheck, sendResourceLoadCallbacks);
case CachedResource::Script:
return new CachedScript(docLoader, url.url(), *charset);
#if ENABLE(XSLT)
@@ -81,7 +81,7 @@
return 0;
}
-CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String* charset, bool skipCanLoadCheck)
+CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String* charset, bool skipCanLoadCheck, bool sendResourceLoadCallbacks)
{
// Look up the resource in our map.
CachedResource* resource = m_resources.get(url.url());
@@ -104,7 +104,7 @@
}
// The resource does not exist. Create it.
- resource = createResource(type, docLoader, url, charset, skipCanLoadCheck);
+ resource = createResource(type, docLoader, url, charset, skipCanLoadCheck, sendResourceLoadCallbacks);
ASSERT(resource);
ASSERT(resource->inCache());
if (!disabled())
diff --git a/WebCore/loader/Cache.h b/WebCore/loader/Cache.h
index 21612ee..54400e6 100644
--- a/WebCore/loader/Cache.h
+++ b/WebCore/loader/Cache.h
@@ -86,7 +86,7 @@
// Request resources from the cache. A load will be initiated and a cache object created if the object is not
// found in the cache.
- CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, const String* charset = 0, bool skipCanLoadCheck = false);
+ CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, const String* charset = 0, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true);
// Set/retreive the size of the cache. This will only hold approximately, since the size some
// cached objects (like stylesheets) take up in memory is not exactly known.
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp
index 75e07b9..0054f9f 100644
--- a/WebCore/loader/CachedCSSStyleSheet.cpp
+++ b/WebCore/loader/CachedCSSStyleSheet.cpp
@@ -37,14 +37,14 @@
namespace WebCore {
-CachedCSSStyleSheet::CachedCSSStyleSheet(DocLoader* dl, const String& url, const String& charset, bool skipCanLoadCheck)
- : CachedResource(url, CSSStyleSheet)
+CachedCSSStyleSheet::CachedCSSStyleSheet(DocLoader* dl, const String& url, const String& charset, bool skipCanLoadCheck, bool sendResourceLoadCallbacks)
+ : CachedResource(url, CSSStyleSheet, true, sendResourceLoadCallbacks)
, m_decoder(new TextResourceDecoder("text/css", charset))
{
// Prefer text/css but accept any type (dell.com serves a stylesheet
// as text/html; see <http://bugs.webkit.org/show_bug.cgi?id=11451>).
setAccept("text/css,*/*;q=0.1");
- cache()->loader()->load(dl, this, false, skipCanLoadCheck);
+ cache()->loader()->load(dl, this, false, skipCanLoadCheck, sendResourceLoadCallbacks);
m_loading = true;
}
diff --git a/WebCore/loader/CachedCSSStyleSheet.h b/WebCore/loader/CachedCSSStyleSheet.h
index 4ff48d0..75ffeef 100644
--- a/WebCore/loader/CachedCSSStyleSheet.h
+++ b/WebCore/loader/CachedCSSStyleSheet.h
@@ -39,7 +39,7 @@
class CachedCSSStyleSheet : public CachedResource {
public:
- CachedCSSStyleSheet(DocLoader*, const String& URL, const String& charset, bool skipCanLoadCheck = false);
+ CachedCSSStyleSheet(DocLoader*, const String& URL, const String& charset, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true);
virtual ~CachedCSSStyleSheet();
const String& sheet() const { return m_sheet; }
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index 87fb752..ff26651 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -32,8 +32,9 @@
namespace WebCore {
-CachedResource::CachedResource(const String& URL, Type type, bool forCache)
- : m_inCache(forCache)
+CachedResource::CachedResource(const String& URL, Type type, bool forCache, bool sendResourceLoadCallbacks)
+ : m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)
+ , m_inCache(forCache)
{
m_url = URL;
m_type = type;
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h
index d2cf853..aa6ff40 100644
--- a/WebCore/loader/CachedResource.h
+++ b/WebCore/loader/CachedResource.h
@@ -61,7 +61,7 @@
Cached // regular case
};
- CachedResource(const String& URL, Type, bool forCache = true);
+ CachedResource(const String& URL, Type, bool forCache = true, bool sendResourceLoadCallbacks = false);
virtual ~CachedResource();
virtual void setEncoding(const String&) { }
@@ -127,7 +127,8 @@
bool errorOccurred() const { return m_errorOccurred; }
bool treatAsLocal() const { return m_shouldTreatAsLocal; }
-
+ bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
+
virtual void destroyDecodedData() {};
protected:
@@ -152,6 +153,7 @@
unsigned m_accessCount;
unsigned m_liveAccessCount;
+ bool m_sendResourceLoadCallbacks;
protected:
bool m_inCache;
bool m_loading;
diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp
index 9bf10a3..e186463 100644
--- a/WebCore/loader/DocLoader.cpp
+++ b/WebCore/loader/DocLoader.cpp
@@ -95,7 +95,7 @@
// FIXME: Passing true for "skipCanLoadCheck" here in the isUserStyleSheet case won't have any effect
// if this resource is already in the cache. It's theoretically possible that what's in the cache already
// is a load that failed because of the canLoad check. Probably not an issue in practice.
- return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, &charset, isUserStyleSheet));
+ return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, &charset, isUserStyleSheet, !isUserStyleSheet));
}
CachedCSSStyleSheet* DocLoader::requestUserCSSStyleSheet(const String& url, const String& charset)
@@ -122,7 +122,7 @@
}
#endif
-CachedResource* DocLoader::requestResource(CachedResource::Type type, const String& url, const String* charset, bool skipCanLoadCheck)
+CachedResource* DocLoader::requestResource(CachedResource::Type type, const String& url, const String* charset, bool skipCanLoadCheck, bool sendResourceLoadCallbacks)
{
KURL fullURL = m_doc->completeURL(url.deprecatedString());
@@ -131,7 +131,7 @@
checkForReload(fullURL);
- CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, skipCanLoadCheck);
+ CachedResource* resource = cache()->requestResource(this, type, fullURL, charset, skipCanLoadCheck, sendResourceLoadCallbacks);
if (resource) {
m_docResources.set(resource->url(), resource);
checkCacheObjectStatus(resource);
@@ -204,8 +204,10 @@
const ResourceResponse& response = resource->response();
SharedBuffer* data = resource->data();
- // FIXME: If the WebKit client changes or cancels the request, WebCore does not respect this and continues the load.
- m_frame->loader()->loadedResourceFromMemoryCache(request, response, data ? data->size() : 0);
+ if (resource->sendResourceLoadCallbacks()) {
+ // FIXME: If the WebKit client changes or cancels the request, WebCore does not respect this and continues the load.
+ m_frame->loader()->loadedResourceFromMemoryCache(request, response, data ? data->size() : 0);
+ }
m_frame->loader()->didTellBridgeAboutLoad(resource->url());
}
diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h
index 49fc660..cabed05 100644
--- a/WebCore/loader/DocLoader.h
+++ b/WebCore/loader/DocLoader.h
@@ -91,7 +91,7 @@
void decrementRequestCount();
int requestCount();
private:
- CachedResource* requestResource(CachedResource::Type, const String& url, const String* charset = 0, bool skipCanLoadCheck = false);
+ CachedResource* requestResource(CachedResource::Type, const String& url, const String* charset = 0, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true);
void checkForReload(const KURL&);
void checkCacheObjectStatus(CachedResource*);
diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp
index 19bb811..7ad8e5a 100644
--- a/WebCore/loader/MainResourceLoader.cpp
+++ b/WebCore/loader/MainResourceLoader.cpp
@@ -42,7 +42,7 @@
namespace WebCore {
MainResourceLoader::MainResourceLoader(Frame* frame)
- : ResourceLoader(frame)
+ : ResourceLoader(frame, true)
, m_dataLoadTimer(this, &MainResourceLoader::handleDataLoadNow)
, m_loadingMultipartContent(false)
, m_waitingForContentPolicy(false)
diff --git a/WebCore/loader/Request.cpp b/WebCore/loader/Request.cpp
index 5c0c8f6..b772ba5 100644
--- a/WebCore/loader/Request.cpp
+++ b/WebCore/loader/Request.cpp
@@ -28,12 +28,13 @@
namespace WebCore {
-Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, bool shouldSkipCanLoadCheck)
+Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, bool shouldSkipCanLoadCheck, bool sendResourceLoadCallbacks)
: m_object(object)
, m_docLoader(docLoader)
, m_incremental(incremental)
, m_multipart(false)
, m_shouldSkipCanLoadCheck(shouldSkipCanLoadCheck)
+ , m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)
{
m_object->setRequest(this);
}
diff --git a/WebCore/loader/Request.h b/WebCore/loader/Request.h
index 7dcf980..14b19f6 100644
--- a/WebCore/loader/Request.h
+++ b/WebCore/loader/Request.h
@@ -32,7 +32,7 @@
class Request {
public:
- Request(DocLoader*, CachedResource*, bool incremental, bool skipCanLoadCheck);
+ Request(DocLoader*, CachedResource*, bool incremental, bool skipCanLoadCheck, bool sendResourceLoadCallbacks);
~Request();
Vector<char>& buffer() { return m_buffer; }
@@ -46,7 +46,8 @@
void setIsMultipart(bool b = true) { m_multipart = b; }
bool shouldSkipCanLoadCheck() const { return m_shouldSkipCanLoadCheck; }
-
+ bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
+
private:
Vector<char> m_buffer;
CachedResource* m_object;
@@ -54,6 +55,7 @@
bool m_incremental;
bool m_multipart;
bool m_shouldSkipCanLoadCheck;
+ bool m_sendResourceLoadCallbacks;
};
} //namespace WebCore
diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp
index 3f25e8d..877e61b 100644
--- a/WebCore/loader/ResourceLoader.cpp
+++ b/WebCore/loader/ResourceLoader.cpp
@@ -52,10 +52,11 @@
return 0;
}
-ResourceLoader::ResourceLoader(Frame* frame)
+ResourceLoader::ResourceLoader(Frame* frame, bool sendResourceLoadCallbacks)
: m_reachedTerminalState(false)
, m_cancelled(false)
, m_calledDidFinishLoad(false)
+ , m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)
, m_frame(frame)
, m_documentLoader(frame->loader()->activeDocumentLoader())
, m_identifier(0)
@@ -171,12 +172,15 @@
ASSERT(!m_reachedTerminalState);
- if (!m_identifier) {
- m_identifier = m_frame->page()->progress()->createUniqueIdentifier();
- frameLoader()->assignIdentifierToInitialRequest(m_identifier, request);
- }
+ if (m_sendResourceLoadCallbacks) {
+ if (!m_identifier) {
+ m_identifier = m_frame->page()->progress()->createUniqueIdentifier();
+ frameLoader()->assignIdentifierToInitialRequest(m_identifier, request);
+ }
- frameLoader()->willSendRequest(this, request, redirectResponse);
+ frameLoader()->willSendRequest(this, request, redirectResponse);
+ }
+
m_request = request;
}
@@ -190,7 +194,8 @@
m_response = r;
- frameLoader()->didReceiveResponse(this, m_response);
+ if (m_sendResourceLoadCallbacks)
+ frameLoader()->didReceiveResponse(this, m_response);
}
void ResourceLoader::didReceiveData(const char* data, int length, long long lengthReceived, bool allAtOnce)
@@ -206,7 +211,7 @@
RefPtr<ResourceLoader> protector(this);
addData(data, length, allAtOnce);
- if (m_frame)
+ if (m_sendResourceLoadCallbacks && m_frame)
frameLoader()->didReceiveData(this, data, length, lengthReceived);
}
@@ -237,7 +242,8 @@
if (m_calledDidFinishLoad)
return;
m_calledDidFinishLoad = true;
- frameLoader()->didFinishLoad(this);
+ if (m_sendResourceLoadCallbacks)
+ frameLoader()->didFinishLoad(this);
}
void ResourceLoader::didFail(const ResourceError& error)
@@ -250,7 +256,7 @@
// anything including possibly derefing this; one example of this is Radar 3266216.
RefPtr<ResourceLoader> protector(this);
- if (!m_calledDidFinishLoad)
+ if (m_sendResourceLoadCallbacks && !m_calledDidFinishLoad)
frameLoader()->didFailToLoad(this, error);
releaseResources();
@@ -281,7 +287,7 @@
m_handle->cancel();
m_handle = 0;
}
- if (!m_calledDidFinishLoad)
+ if (m_sendResourceLoadCallbacks && !m_calledDidFinishLoad)
frameLoader()->didFailToLoad(this, error);
releaseResources();
diff --git a/WebCore/loader/ResourceLoader.h b/WebCore/loader/ResourceLoader.h
index 2458c0c..2ff7a5a 100644
--- a/WebCore/loader/ResourceLoader.h
+++ b/WebCore/loader/ResourceLoader.h
@@ -103,9 +103,10 @@
#endif
ResourceHandle* handle() const { return m_handle.get(); }
+ bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
protected:
- ResourceLoader(Frame*);
+ ResourceLoader(Frame*, bool sendResourceLoadCallbacks);
virtual void didCancel(const ResourceError&);
void didFinishLoadingOnePart();
@@ -125,6 +126,7 @@
bool m_cancelled;
bool m_calledDidFinishLoad;
+ bool m_sendResourceLoadCallbacks;
protected:
// FIXME: Once everything is made cross platform, these can be private instead of protected
RefPtr<Frame> m_frame;
diff --git a/WebCore/loader/SubresourceLoader.cpp b/WebCore/loader/SubresourceLoader.cpp
index 81f390f..2013364 100644
--- a/WebCore/loader/SubresourceLoader.cpp
+++ b/WebCore/loader/SubresourceLoader.cpp
@@ -57,8 +57,8 @@
static SubresourceLoaderCounter subresourceLoaderCounter;
#endif
-SubresourceLoader::SubresourceLoader(Frame* frame, SubresourceLoaderClient* client)
- : ResourceLoader(frame)
+SubresourceLoader::SubresourceLoader(Frame* frame, SubresourceLoaderClient* client, bool sendResourceLoadCallbacks)
+ : ResourceLoader(frame, sendResourceLoadCallbacks)
, m_client(client)
, m_loadingMultipartContent(false)
{
@@ -82,7 +82,7 @@
return ResourceLoader::load(r);
}
-PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, bool skipCanLoadCheck)
+PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, bool skipCanLoadCheck, bool sendResourceLoadCallbacks)
{
if (!frame)
return 0;
@@ -118,7 +118,7 @@
fl->addExtraFieldsToRequest(newRequest, false, false);
- RefPtr<SubresourceLoader> subloader(new SubresourceLoader(frame, client));
+ RefPtr<SubresourceLoader> subloader(new SubresourceLoader(frame, client, sendResourceLoadCallbacks));
if (!subloader->load(newRequest))
return 0;
diff --git a/WebCore/loader/SubresourceLoader.h b/WebCore/loader/SubresourceLoader.h
index 843ed08..a77e846 100644
--- a/WebCore/loader/SubresourceLoader.h
+++ b/WebCore/loader/SubresourceLoader.h
@@ -49,7 +49,7 @@
class SubresourceLoader : public ResourceLoader {
public:
- static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, bool skipCanLoadCheck = false);
+ static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true);
virtual ~SubresourceLoader();
@@ -62,7 +62,7 @@
virtual void didFail(const ResourceError&);
private:
- SubresourceLoader(Frame*, SubresourceLoaderClient*);
+ SubresourceLoader(Frame*, SubresourceLoaderClient*, bool sendResourceLoadCallbacks);
virtual void didCancel(const ResourceError&);
SubresourceLoaderClient* m_client;
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index 5530811..08a9770 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -51,10 +51,10 @@
deleteAllValues(m_requestsLoading);
}
-void Loader::load(DocLoader* dl, CachedResource* object, bool incremental, bool skipCanLoadCheck)
+void Loader::load(DocLoader* dl, CachedResource* object, bool incremental, bool skipCanLoadCheck, bool sendResourceLoadCallbacks)
{
ASSERT(dl);
- Request* req = new Request(dl, object, incremental, skipCanLoadCheck);
+ Request* req = new Request(dl, object, incremental, skipCanLoadCheck, sendResourceLoadCallbacks);
m_requestsPending.append(req);
dl->incrementRequestCount();
servePendingRequests();
@@ -82,7 +82,7 @@
domain = static_cast<HTMLDocument*>(dl->doc())->domain().deprecatedString();
RefPtr<SubresourceLoader> loader = SubresourceLoader::create(dl->doc()->frame(),
- this, request, req->shouldSkipCanLoadCheck());
+ this, request, req->shouldSkipCanLoadCheck(), req->sendResourceLoadCallbacks());
if (loader) {
m_requestsLoading.add(loader.release(), req);
diff --git a/WebCore/loader/loader.h b/WebCore/loader/loader.h
index 77861be..9934b63 100644
--- a/WebCore/loader/loader.h
+++ b/WebCore/loader/loader.h
@@ -37,7 +37,7 @@
Loader();
~Loader();
- void load(DocLoader*, CachedResource*, bool incremental = true, bool skipCanLoadCheck = false);
+ void load(DocLoader*, CachedResource*, bool incremental = true, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true);
void cancelRequests(DocLoader*);
diff --git a/WebCore/loader/mac/NetscapePlugInStreamLoaderMac.mm b/WebCore/loader/mac/NetscapePlugInStreamLoaderMac.mm
index b8bb4c5..a5e0d9b 100644
--- a/WebCore/loader/mac/NetscapePlugInStreamLoaderMac.mm
+++ b/WebCore/loader/mac/NetscapePlugInStreamLoaderMac.mm
@@ -39,7 +39,7 @@
namespace WebCore {
NetscapePlugInStreamLoader::NetscapePlugInStreamLoader(Frame* frame, id <WebPlugInStreamLoaderDelegate> stream)
- : ResourceLoader(frame)
+ : ResourceLoader(frame, true)
, m_stream(stream)
{
}