Add initiator to CachedResourceRequest.
https://bugs.webkit.org/show_bug.cgi?id=101935

Patch by Marja Hölttä <marja@chromium.org> on 2012-11-16
Reviewed by Adam Barth.

Motivation: Chromium needs to know which elements request a
resource (such as an image or a script) (bug 92761). In addition,
for exposing resource timing information (bug 84883) we need to
store the initiator, and this is the first step towards it.

No new tests: No visible change in behavior.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSCursorImageValue.cpp:
(WebCore::CSSCursorImageValue::cachedImage):
* css/CSSFontFaceSrcValue.cpp:
(WebCore::CSSFontFaceSrcValue::cachedFont):
* css/CSSImageSetValue.cpp:
(WebCore::CSSImageSetValue::cachedImageSet):
* css/CSSImageValue.cpp:
(WebCore::CSSImageValue::cachedImage):
* css/CSSImageValue.h:
(WebCore):
(CSSImageValue):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::loadPendingImage):
* css/StyleRuleImport.cpp:
(WebCore::StyleRuleImport::requestStyleSheet):
* css/WebKitCSSSVGDocumentValue.cpp:
(WebCore::WebKitCSSSVGDocumentValue::load):
* css/WebKitCSSShaderValue.cpp:
(WebCore::WebKitCSSShaderValue::cachedShader):
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::requestScript):
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::process):
* html/parser/CSSPreloadScanner.cpp:
(WebCore::CSSPreloadScanner::emitRule):
* html/parser/CSSPreloadScanner.h:
(CSSPreloadScanner):
* html/parser/HTMLPreloadScanner.cpp:
(WebCore::PreloadTask::preload):
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestImage):
(WebCore::CachedResourceLoader::requestResource):
(WebCore::CachedResourceLoader::determineRevalidationPolicy):
(WebCore):
(WebCore::CachedResourceLoader::preload):
* loader/cache/CachedResourceLoader.h:
(WebCore):
(CachedResourceLoader):
* loader/cache/CachedResourceRequest.cpp:
(WebCore::CachedResourceRequest::CachedResourceRequest):
(WebCore):
(WebCore::CachedResourceRequest::~CachedResourceRequest):
(WebCore::CachedResourceRequest::setInitiator):
(WebCore::CachedResourceRequest::initiatorName):
(WebCore::CachedResourceRequest::initiatorDocument):
(WebCore::CachedResourceRequest::initiatorElement):
* loader/cache/CachedResourceRequest.h:
(WebCore):
(WebCore::CachedResourceRequest::setOptions):
(WebCore::CachedResourceRequest::defer):
(WebCore::CachedResourceRequest::setDefer):
(CachedResourceRequest):
* loader/cache/CachedResourceRequestInitiators.cpp: Copied from Source/WebCore/loader/cache/CachedResourceRequest.cpp.
(WebCore):
(WebCore::CachedResourceRequestInitiators::CachedResourceRequestInitiators):
* loader/cache/CachedResourceRequestInitiators.h: Copied from Source/WebCore/loader/cache/CachedResourceRequest.cpp.
(WebCore):
(CachedResourceRequestInitiators):
(WebCore::cachedResourceRequestInitiators):
* loader/icon/IconLoader.cpp:
(WebCore::IconLoader::startLoading):
* platform/ThreadGlobalData.cpp:
(WebCore::ThreadGlobalData::ThreadGlobalData):
* platform/ThreadGlobalData.h:
(WebCore):
(WebCore::ThreadGlobalData::cachedResourceRequestInitiators):
(ThreadGlobalData):
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::requestImageResource):
* svg/SVGFontFaceUriElement.cpp:
(WebCore::SVGFontFaceUriElement::loadFont):
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::svgAttributeChanged):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@134930 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index d4cba05..83a5a1c 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -164,7 +164,7 @@
             return 0;
         }
     }
-    request.setDefer(clientDefersImage(request.resourceRequest().url()) ? DeferredByClient : NoDefer);
+    request.setDefer(clientDefersImage(request.resourceRequest().url()) ? CachedResourceRequest::DeferredByClient : CachedResourceRequest::NoDefer);
     return static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request).get());
 }
 
@@ -458,7 +458,7 @@
         return 0;
 
     resource->setLoadPriority(request.priority());
-    if ((policy != Use || resource->stillNeedsLoad()) && NoDefer == request.defer()) {
+    if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest::NoDefer == request.defer()) {
         resource->load(this, request.options());
 
         // We don't support immediate loads, but we do support immediate failure.
@@ -510,7 +510,7 @@
     return resource;
 }
 
-CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, ResourceRequest& request, bool forPreload, CachedResource* existingResource, DeferOption defer) const
+CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, ResourceRequest& request, bool forPreload, CachedResource* existingResource, CachedResourceRequest::DeferOption defer) const
 {
     if (!existingResource)
         return Load;
@@ -539,7 +539,7 @@
 
     // Do not load from cache if images are not enabled. The load for this image will be blocked
     // in CachedImage::load.
-    if (DeferredByClient == defer)
+    if (CachedResourceRequest::DeferredByClient == defer)
         return Reload;
     
     // Don't reload resources while pasting.
@@ -764,8 +764,8 @@
     --m_requestCount;
     ASSERT(m_requestCount > -1);
 }
-    
-void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
+
+void CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest& request, const String& charset, bool referencedFromBody)
 {
     // FIXME: Rip this out when we are sure it is no longer necessary (even for mobile).
     UNUSED_PARAM(referencedFromBody);
@@ -780,12 +780,12 @@
         if (!hasRendering && !canBlockParser) {
             // Don't preload subresources that can't block the parser before we have something to draw.
             // This helps prevent preloads from delaying first display when bandwidth is limited.
-            PendingPreload pendingPreload = { type, request, charset };
+            PendingPreload pendingPreload = { type, request.resourceRequest(), charset };
             m_pendingPreloads.append(pendingPreload);
             return;
         }
     }
-    requestPreload(type, request, charset);
+    requestPreload(type, request.mutableResourceRequest(), charset);
 }
 
 void CachedResourceLoader::checkForPendingPreloads() 
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index e2e2ae4..c5b2365 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -26,9 +26,10 @@
 #ifndef CachedResourceLoader_h
 #define CachedResourceLoader_h
 
+#include "CachePolicy.h"
 #include "CachedResource.h"
 #include "CachedResourceHandle.h"
-#include "CachePolicy.h"
+#include "CachedResourceRequest.h"
 #include "ResourceLoadPriority.h"
 #include "Timer.h"
 #include <wtf/Deque.h>
@@ -44,7 +45,6 @@
 class CachedFont;
 class CachedImage;
 class CachedRawResource;
-class CachedResourceRequest;
 class CachedScript;
 class CachedShader;
 class CachedTextTrack;
@@ -69,7 +69,6 @@
 friend class ResourceCacheValidationSuppressor;
 
 public:
-    enum DeferOption { NoDefer, DeferredByClient };
     static PassRefPtr<CachedResourceLoader> create(DocumentLoader* documentLoader) { return adoptRef(new CachedResourceLoader(documentLoader)); }
     ~CachedResourceLoader();
 
@@ -131,7 +130,7 @@
     bool isPreloaded(const String& urlString) const;
     void clearPreloads();
     void clearPendingPreloads();
-    void preload(CachedResource::Type, ResourceRequest&, const String& charset, bool referencedFromBody);
+    void preload(CachedResource::Type, CachedResourceRequest&, const String& charset, bool referencedFromBody);
     void checkForPendingPreloads();
     void printPreloadStats();
     bool canRequest(CachedResource::Type, const KURL&, bool forPreload = false);
@@ -149,7 +148,7 @@
     void requestPreload(CachedResource::Type, ResourceRequest&, const String& charset);
 
     enum RevalidationPolicy { Use, Revalidate, Reload, Load };
-    RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, ResourceRequest&, bool forPreload, CachedResource* existingResource, DeferOption) const;
+    RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, ResourceRequest&, bool forPreload, CachedResource* existingResource, CachedResourceRequest::DeferOption) const;
     
     void notifyLoadedFromMemoryCache(CachedResource*);
     bool checkInsecureContent(CachedResource::Type, const KURL&) const;
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index 6add39b..7be7349 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -26,6 +26,10 @@
 #include "config.h"
 #include "CachedResourceRequest.h"
 
+#include "CachedResourceLoader.h"
+#include "Document.h"
+#include "Element.h"
+
 namespace WebCore {
 
 CachedResourceRequest::CachedResourceRequest(const ResourceRequest& resourceRequest, const String& charset, ResourceLoadPriority priority)
@@ -34,7 +38,7 @@
     , m_options(CachedResourceLoader::defaultCachedResourceOptions())
     , m_priority(priority)
     , m_forPreload(false)
-    , m_defer(CachedResourceLoader::NoDefer)
+    , m_defer(NoDefer)
 {
 }
 
@@ -43,7 +47,7 @@
     , m_options(options)
     , m_priority(ResourceLoadPriorityUnresolved)
     , m_forPreload(false)
-    , m_defer(CachedResourceLoader::NoDefer)
+    , m_defer(NoDefer)
 {
 }
 
@@ -52,8 +56,48 @@
     , m_options(CachedResourceLoader::defaultCachedResourceOptions())
     , m_priority(priority)
     , m_forPreload(false)
-    , m_defer(CachedResourceLoader::NoDefer)
+    , m_defer(NoDefer)
 {
 }
 
+CachedResourceRequest::~CachedResourceRequest()
+{
 }
+
+void CachedResourceRequest::setInitiator(PassRefPtr<Element> element)
+{
+    ASSERT(!m_initiatorElement && !m_initiatorDocument);
+    m_initiatorElement = element;
+}
+
+void CachedResourceRequest::setInitiator(const AtomicString& name, PassRefPtr<Document> document)
+{
+    ASSERT(!m_initiatorElement && !m_initiatorDocument);
+    m_initiatorName = name;
+    m_initiatorDocument = document;
+}
+
+const AtomicString& CachedResourceRequest::initiatorName() const
+{
+    if (m_initiatorElement)
+        return m_initiatorElement->localName();
+    if (!m_initiatorName.isEmpty())
+        return m_initiatorName;
+
+    DEFINE_STATIC_LOCAL(AtomicString, defaultName, ("resource", AtomicString::ConstructFromLiteral));
+    return defaultName;
+}
+
+PassRefPtr<Document> CachedResourceRequest::initiatorDocument()
+{
+    if (m_initiatorElement)
+        return m_initiatorElement->document();
+    return m_initiatorDocument;
+}
+
+PassRefPtr<Element> CachedResourceRequest::initiatorElement()
+{
+    return m_initiatorElement;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.h b/Source/WebCore/loader/cache/CachedResourceRequest.h
index cb043df..4aa30d4 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.h
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.h
@@ -26,27 +26,41 @@
 #ifndef CachedResourceRequest_h
 #define CachedResourceRequest_h
 
-#include "CachedResourceLoader.h"
 #include "ResourceLoadPriority.h"
+#include "ResourceLoaderOptions.h"
+#include "ResourceRequest.h"
+#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicString.h>
 
 namespace WebCore {
+class Document;
+class Element;
 
 class CachedResourceRequest {
 public:
+    enum DeferOption { NoDefer, DeferredByClient };
+
     explicit CachedResourceRequest(const ResourceRequest&, const String& charset = String(), ResourceLoadPriority = ResourceLoadPriorityUnresolved);
     CachedResourceRequest(const ResourceRequest&, const ResourceLoaderOptions&);
     CachedResourceRequest(const ResourceRequest&, ResourceLoadPriority);
+    ~CachedResourceRequest();
 
     ResourceRequest& mutableResourceRequest() { return m_resourceRequest; }
     const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
     const String& charset() const { return m_charset; }
     void setCharset(const String& charset) { m_charset = charset; }
     const ResourceLoaderOptions& options() const { return m_options; }
+    void setOptions(const ResourceLoaderOptions& options) { m_options = options; }
     ResourceLoadPriority priority() const { return m_priority; }
     bool forPreload() const { return m_forPreload; }
     void setForPreload(bool forPreload) { m_forPreload = forPreload; }
-    CachedResourceLoader::DeferOption defer() const { return m_defer; }
-    void setDefer(CachedResourceLoader::DeferOption defer) { m_defer = defer; }
+    DeferOption defer() const { return m_defer; }
+    void setDefer(DeferOption defer) { m_defer = defer; }
+    void setInitiator(PassRefPtr<Element>);
+    void setInitiator(const AtomicString& name, PassRefPtr<Document>);
+    const AtomicString& initiatorName() const;
+    PassRefPtr<Document> initiatorDocument();
+    PassRefPtr<Element> initiatorElement();
 
 private:
     ResourceRequest m_resourceRequest;
@@ -54,7 +68,10 @@
     ResourceLoaderOptions m_options;
     ResourceLoadPriority m_priority;
     bool m_forPreload;
-    CachedResourceLoader::DeferOption m_defer;
+    DeferOption m_defer;
+    RefPtr<Element> m_initiatorElement;
+    RefPtr<Document> m_initiatorDocument;
+    AtomicString m_initiatorName;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/loader/cache/CachedResourceRequestInitiators.cpp b/Source/WebCore/loader/cache/CachedResourceRequestInitiators.cpp
new file mode 100644
index 0000000..463145c
--- /dev/null
+++ b/Source/WebCore/loader/cache/CachedResourceRequestInitiators.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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:
+ * 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 GOOGLE 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 COMPUTER, 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 "CachedResourceRequestInitiators.h"
+
+namespace WebCore {
+
+CachedResourceRequestInitiators::CachedResourceRequestInitiators()
+    : css("css", AtomicString::ConstructFromLiteral)
+    , icon("icon", AtomicString::ConstructFromLiteral)
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/loader/cache/CachedResourceRequestInitiators.h b/Source/WebCore/loader/cache/CachedResourceRequestInitiators.h
new file mode 100644
index 0000000..552c5d8
--- /dev/null
+++ b/Source/WebCore/loader/cache/CachedResourceRequestInitiators.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 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:
+ * 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 GOOGLE 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 COMPUTER, 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.
+ */
+
+#ifndef CachedResourceRequestInitiators_h
+#define CachedResourceRequestInitiators_h
+
+#include "ThreadGlobalData.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+struct CachedResourceRequestInitiators {
+    const AtomicString css;
+    const AtomicString icon;
+    WTF_MAKE_NONCOPYABLE(CachedResourceRequestInitiators); WTF_MAKE_FAST_ALLOCATED;
+private:
+    CachedResourceRequestInitiators();
+    friend class ThreadGlobalData;
+};
+
+inline const CachedResourceRequestInitiators& cachedResourceRequestInitiators()
+{
+    return threadGlobalData().cachedResourceRequestInitiators();
+}
+
+} // namespace WebCore
+
+#endif