2010-10-17 Pavel Feldman <pfeldman@chromium.org>
authorpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Oct 2010 10:14:56 +0000 (10:14 +0000)
committerpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Oct 2010 10:14:56 +0000 (10:14 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: Introduce InspectorResourceAgent.h/cpp and ResourceManager.js to
        fill network panel with data.
        https://bugs.webkit.org/show_bug.cgi?id=47779

        InspectorResourceAgent instance / JS part are introduced in this patch. Agent's lifetime is equal
        to the front-end's. This new resource agent does not have state, instead it covers two functions:
         1) forwards loader client messages to the front-end 2) is capable of building a tree of cached resources.
        (1) feeds network panel with data, (2) shows the resource tree in the new ResourcesPanel concept.
        This bug is for extracting this new InspectorResourceAgent class and its javascript counterpart.
        Once resources panel is refactored for the new concept, InspectorResource, InspectorController's
        resource-related routines, inspector.js's code dealing with resources, they all will be gone.

        * WebCore.gypi:
        * WebCore.vcproj/WebCore.vcproj:
        * inspector/CodeGeneratorInspector.pm:
        * inspector/Inspector.idl:
        * inspector/InspectorApplicationCacheAgent.cpp:
        (WebCore::InspectorApplicationCacheAgent::didReceiveManifestResponse):
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::connectFrontend):
        (WebCore::InspectorController::releaseFrontendLifetimeAgents):
        (WebCore::InspectorController::didCommitLoad):
        (WebCore::InspectorController::frameDetachedFromParent):
        (WebCore::InspectorController::didLoadResourceFromMemoryCache):
        (WebCore::InspectorController::identifierForInitialRequest):
        (WebCore::InspectorController::willSendRequest):
        (WebCore::InspectorController::markResourceAsCached):
        (WebCore::InspectorController::didReceiveResponse):
        (WebCore::InspectorController::didReceiveContentLength):
        (WebCore::InspectorController::didFinishLoading):
        (WebCore::InspectorController::didFailLoading):
        (WebCore::InspectorController::resourceRetrievedByXMLHttpRequest):
        (WebCore::InspectorController::scriptImported):
        (WebCore::InspectorController::didCreateWebSocket):
        (WebCore::InspectorController::willSendWebSocketHandshakeRequest):
        (WebCore::InspectorController::didReceiveWebSocketHandshakeResponse):
        (WebCore::InspectorController::didCloseWebSocket):
        * inspector/InspectorController.h:
        * inspector/InspectorResource.cpp:
        (WebCore::InspectorResource::updateResponse):
        (WebCore::cachedResourceType):
        (WebCore::InspectorResource::type):
        (WebCore::InspectorResource::sourceString):
        (WebCore::InspectorResource::sourceBytes):
        (WebCore::InspectorResource::endTiming):
        * inspector/InspectorResourceAgent.cpp:
        (WebCore::InspectorResourceAgent::resourceContent):
        (WebCore::InspectorResourceAgent::resourceContentBase64):
        (WebCore::InspectorResourceAgent::resourceData):
        (WebCore::InspectorResourceAgent::cachedResource):
        (WebCore::buildObjectForHeaders):
        (WebCore::buildObjectForTiming):
        (WebCore::buildObjectForResourceRequest):
        (WebCore::buildObjectForResourceResponse):
        (WebCore::buildObjectForMainResource):
        (WebCore::cachedResourceTypeString):
        (WebCore::buildObjectForCachedResource):
        (WebCore::buildObjectForFrameResources):
        (WebCore::InspectorResourceAgent::~InspectorResourceAgent):
        (WebCore::InspectorResourceAgent::identifierForInitialRequest):
        (WebCore::InspectorResourceAgent::willSendRequest):
        (WebCore::InspectorResourceAgent::markResourceAsCached):
        (WebCore::InspectorResourceAgent::didReceiveResponse):
        (WebCore::InspectorResourceAgent::didReceiveContentLength):
        (WebCore::InspectorResourceAgent::didFinishLoading):
        (WebCore::InspectorResourceAgent::didFailLoading):
        (WebCore::InspectorResourceAgent::didLoadResourceFromMemoryCache):
        (WebCore::InspectorResourceAgent::setOverrideContent):
        (WebCore::InspectorResourceAgent::didCommitLoad):
        (WebCore::InspectorResourceAgent::frameDetachedFromParent):
        (WebCore::createReadableStringFromBinary):
        (WebCore::InspectorResourceAgent::didCreateWebSocket):
        (WebCore::InspectorResourceAgent::willSendWebSocketHandshakeRequest):
        (WebCore::InspectorResourceAgent::didReceiveWebSocketHandshakeResponse):
        (WebCore::InspectorResourceAgent::didCloseWebSocket):
        (WebCore::InspectorResourceAgent::cachedResources):
        (WebCore::InspectorResourceAgent::InspectorResourceAgent):
        * inspector/InspectorResourceAgent.h:
        (WebCore::InspectorResourceAgent::create):
        * inspector/InspectorStyleSheet.cpp:
        (WebCore::InspectorStyleSheet::resourceStyleSheetText):
        * inspector/front-end/ExtensionServer.js:
        (WebInspector.ExtensionServer.prototype._onRevealAndSelectResource):
        (WebInspector.ExtensionServer.prototype._onGetResourceContent):
        * inspector/front-end/Resource.js:
        (WebInspector.Resource.prototype.get responseReceivedTime):
        (WebInspector.Resource.prototype.set endTime):
        * inspector/front-end/Settings.js:
        * inspector/front-end/SourceView.js:
        (WebInspector.SourceView.prototype.setupSourceFrameIfNeeded):
        * inspector/front-end/WebKit.qrc:
        * inspector/front-end/inspector.css:
        (.tabbed-pane-header li):
        * inspector/front-end/inspector.html:
        * inspector/front-end/inspector.js:
        (WebInspector.updateResource):
        * loader/ResourceLoadNotifier.cpp:
        (WebCore::ResourceLoadNotifier::dispatchDidReceiveResponse):
        * loader/appcache/ApplicationCacheGroup.cpp:
        (WebCore::ApplicationCacheGroup::didReceiveResponse):

2010-10-17  Pavel Feldman  <pfeldman@chromium.org>

        Reviewed by Yury Semikhatsky.

        Web Inspector: Introduce InspectorResourceAgent.h/cpp and ResourceManager.js to
        fill network panel with data.
        https://bugs.webkit.org/show_bug.cgi?id=47779

        * src/WebDevToolsAgentImpl.cpp:
        (WebKit::WebDevToolsAgentImpl::didReceiveResponse):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69948 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
WebCore/ChangeLog
WebCore/English.lproj/localizedStrings.js
WebCore/WebCore.gypi
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/inspector/CodeGeneratorInspector.pm
WebCore/inspector/Inspector.idl
WebCore/inspector/InspectorApplicationCacheAgent.cpp
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/InspectorResource.cpp
WebCore/inspector/InspectorResourceAgent.cpp
WebCore/inspector/InspectorResourceAgent.h
WebCore/inspector/InspectorStyleSheet.cpp
WebCore/inspector/front-end/DataGrid.js
WebCore/inspector/front-end/ExtensionServer.js
WebCore/inspector/front-end/NetworkPanel.js
WebCore/inspector/front-end/Resource.js
WebCore/inspector/front-end/ResourceManager.js [new file with mode: 0644]
WebCore/inspector/front-end/ResourcesPanel.js
WebCore/inspector/front-end/SourceView.js
WebCore/inspector/front-end/WebKit.qrc
WebCore/inspector/front-end/inspector.html
WebCore/inspector/front-end/inspector.js
WebCore/inspector/front-end/networkPanel.css
WebCore/loader/ResourceLoadNotifier.cpp
WebCore/loader/appcache/ApplicationCacheGroup.cpp
WebKit/chromium/ChangeLog
WebKit/chromium/src/WebDevToolsAgentImpl.cpp

index 2e62d74..ebe3f4d 100644 (file)
@@ -1,3 +1,108 @@
+2010-10-17  Pavel Feldman  <pfeldman@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: Introduce InspectorResourceAgent.h/cpp and ResourceManager.js to
+        fill network panel with data.
+        https://bugs.webkit.org/show_bug.cgi?id=47779
+        
+        InspectorResourceAgent instance / JS part are introduced in this patch. Agent's lifetime is equal
+        to the front-end's. This new resource agent does not have state, instead it covers two functions:
+         1) forwards loader client messages to the front-end 2) is capable of building a tree of cached resources.
+        (1) feeds network panel with data, (2) shows the resource tree in the new ResourcesPanel concept.
+        This bug is for extracting this new InspectorResourceAgent class and its javascript counterpart.
+        Once resources panel is refactored for the new concept, InspectorResource, InspectorController's
+        resource-related routines, inspector.js's code dealing with resources, they all will be gone.
+
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * inspector/CodeGeneratorInspector.pm:
+        * inspector/Inspector.idl:
+        * inspector/InspectorApplicationCacheAgent.cpp:
+        (WebCore::InspectorApplicationCacheAgent::didReceiveManifestResponse):
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::connectFrontend):
+        (WebCore::InspectorController::releaseFrontendLifetimeAgents):
+        (WebCore::InspectorController::didCommitLoad):
+        (WebCore::InspectorController::frameDetachedFromParent):
+        (WebCore::InspectorController::didLoadResourceFromMemoryCache):
+        (WebCore::InspectorController::identifierForInitialRequest):
+        (WebCore::InspectorController::willSendRequest):
+        (WebCore::InspectorController::markResourceAsCached):
+        (WebCore::InspectorController::didReceiveResponse):
+        (WebCore::InspectorController::didReceiveContentLength):
+        (WebCore::InspectorController::didFinishLoading):
+        (WebCore::InspectorController::didFailLoading):
+        (WebCore::InspectorController::resourceRetrievedByXMLHttpRequest):
+        (WebCore::InspectorController::scriptImported):
+        (WebCore::InspectorController::didCreateWebSocket):
+        (WebCore::InspectorController::willSendWebSocketHandshakeRequest):
+        (WebCore::InspectorController::didReceiveWebSocketHandshakeResponse):
+        (WebCore::InspectorController::didCloseWebSocket):
+        * inspector/InspectorController.h:
+        * inspector/InspectorResource.cpp:
+        (WebCore::InspectorResource::updateResponse):
+        (WebCore::cachedResourceType):
+        (WebCore::InspectorResource::type):
+        (WebCore::InspectorResource::sourceString):
+        (WebCore::InspectorResource::sourceBytes):
+        (WebCore::InspectorResource::endTiming):
+        * inspector/InspectorResourceAgent.cpp:
+        (WebCore::InspectorResourceAgent::resourceContent):
+        (WebCore::InspectorResourceAgent::resourceContentBase64):
+        (WebCore::InspectorResourceAgent::resourceData):
+        (WebCore::InspectorResourceAgent::cachedResource):
+        (WebCore::buildObjectForHeaders):
+        (WebCore::buildObjectForTiming):
+        (WebCore::buildObjectForResourceRequest):
+        (WebCore::buildObjectForResourceResponse):
+        (WebCore::buildObjectForMainResource):
+        (WebCore::cachedResourceTypeString):
+        (WebCore::buildObjectForCachedResource):
+        (WebCore::buildObjectForFrameResources):
+        (WebCore::InspectorResourceAgent::~InspectorResourceAgent):
+        (WebCore::InspectorResourceAgent::identifierForInitialRequest):
+        (WebCore::InspectorResourceAgent::willSendRequest):
+        (WebCore::InspectorResourceAgent::markResourceAsCached):
+        (WebCore::InspectorResourceAgent::didReceiveResponse):
+        (WebCore::InspectorResourceAgent::didReceiveContentLength):
+        (WebCore::InspectorResourceAgent::didFinishLoading):
+        (WebCore::InspectorResourceAgent::didFailLoading):
+        (WebCore::InspectorResourceAgent::didLoadResourceFromMemoryCache):
+        (WebCore::InspectorResourceAgent::setOverrideContent):
+        (WebCore::InspectorResourceAgent::didCommitLoad):
+        (WebCore::InspectorResourceAgent::frameDetachedFromParent):
+        (WebCore::createReadableStringFromBinary):
+        (WebCore::InspectorResourceAgent::didCreateWebSocket):
+        (WebCore::InspectorResourceAgent::willSendWebSocketHandshakeRequest):
+        (WebCore::InspectorResourceAgent::didReceiveWebSocketHandshakeResponse):
+        (WebCore::InspectorResourceAgent::didCloseWebSocket):
+        (WebCore::InspectorResourceAgent::cachedResources):
+        (WebCore::InspectorResourceAgent::InspectorResourceAgent):
+        * inspector/InspectorResourceAgent.h:
+        (WebCore::InspectorResourceAgent::create):
+        * inspector/InspectorStyleSheet.cpp:
+        (WebCore::InspectorStyleSheet::resourceStyleSheetText):
+        * inspector/front-end/ExtensionServer.js:
+        (WebInspector.ExtensionServer.prototype._onRevealAndSelectResource):
+        (WebInspector.ExtensionServer.prototype._onGetResourceContent):
+        * inspector/front-end/Resource.js:
+        (WebInspector.Resource.prototype.get responseReceivedTime):
+        (WebInspector.Resource.prototype.set endTime):
+        * inspector/front-end/Settings.js:
+        * inspector/front-end/SourceView.js:
+        (WebInspector.SourceView.prototype.setupSourceFrameIfNeeded):
+        * inspector/front-end/WebKit.qrc:
+        * inspector/front-end/inspector.css:
+        (.tabbed-pane-header li):
+        * inspector/front-end/inspector.html:
+        * inspector/front-end/inspector.js:
+        (WebInspector.updateResource):
+        * loader/ResourceLoadNotifier.cpp:
+        (WebCore::ResourceLoadNotifier::dispatchDidReceiveResponse):
+        * loader/appcache/ApplicationCacheGroup.cpp:
+        (WebCore::ApplicationCacheGroup::didReceiveResponse):
+
 2010-10-16  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index 21081b1..8f3a228 100644 (file)
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
index 5c6c3d2..7880606 100644 (file)
             'inspector/front-end/RemoteObject.js',
             'inspector/front-end/Resource.js',
             'inspector/front-end/ResourceCategory.js',
+            'inspector/front-end/ResourceManager.js',
             'inspector/front-end/ResourcesPanel.js',
             'inspector/front-end/ResourceView.js',
             'inspector/front-end/ScopeChainSidebarPane.js',
index ec20aff..a7cff52 100644 (file)
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath="..\inspector\front-end\ResourceManager.js"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath="..\inspector\front-end\ResourcesPanel.js"\r
                                        >\r
                                </File>\r
index 13e05b0..a566576 100644 (file)
@@ -28,6 +28,11 @@ $typeTransform{"Debug"} = {
     "header" => "InspectorDebuggerAgent.h",
     "domainAccessor" => "m_inspectorController->debuggerAgent()",
 };
+$typeTransform{"Resource"} = {
+    "forward" => "InspectorResourceAgent",
+    "header" => "InspectorResourceAgent.h",
+    "domainAccessor" => "m_inspectorController->m_resourceAgent",
+};
 $typeTransform{"DOM"} = {
     "forward" => "InspectorDOMAgent",
     "header" => "InspectorDOMAgent.h",
index c4773cf..b7f4a0d 100644 (file)
@@ -112,6 +112,25 @@ module core {
         [handler=Controller] void startTimelineProfiler();
         [handler=Controller] void stopTimelineProfiler();
 
+        [handler=Resource] void cachedResources(out Array resources);
+        [handler=Resource] void resourceContent(in unsigned long frameID, in String url, out String content);
+        [notify] void identifierForInitialRequest(out long identifier, out String url, out unsigned long frameID, out boolean isMainResource);
+        [notify] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse);
+        [notify] void markResourceAsCached(out long identifier);
+        [notify] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response);
+        [notify] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived);
+        [notify] void didFinishLoading(out long identifier, out double finishTime);
+        [notify] void didFailLoading(out long identifier, out double time, out String localizedDescription);
+        [notify] void didLoadResourceFromMemoryCache(out double time, out unsigned long frameID, out Object resource);
+        [notify] void setOverrideContent(out long identifier, out String sourceString, out String type);
+        [notify] void didCommitLoad(out unsigned long frameID);
+        [notify] void frameDetachedFromParent(out unsigned long frameID);
+
+        [notify] void didCreateWebSocket(out unsigned long identifier, out String requestURL);
+        [notify] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request);
+        [notify] void didReceiveWebSocketHandshakeResponse(out unsigned long identifier, out double time, out Object response);
+        [notify] void didCloseWebSocket(out unsigned long identifier, out double time);
+
 #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
         [handler=Backend] void enableDebugger(in boolean always);
         [handler=Controller] void disableDebugger(in boolean always);
index 918643b..ced61c5 100644 (file)
@@ -48,7 +48,7 @@ InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorControll
 
 void InspectorApplicationCacheAgent::didReceiveManifestResponse(unsigned long identifier, const ResourceResponse& response)
 {
-    m_inspectorController->didReceiveResponse(identifier, response);
+    m_inspectorController->didReceiveResponse(identifier, 0, response);
 }
 
 void InspectorApplicationCacheAgent::updateApplicationCacheStatus(ApplicationCacheHost::Status status)
index 4d83929..8472aa2 100644 (file)
@@ -69,6 +69,7 @@
 #include "InspectorInstrumentation.h"
 #include "InspectorProfilerAgent.h"
 #include "InspectorResource.h"
+#include "InspectorResourceAgent.h"
 #include "InspectorState.h"
 #include "InspectorStorageAgent.h"
 #include "InspectorTimelineAgent.h"
@@ -499,6 +500,8 @@ void InspectorController::connectFrontend()
     releaseFrontendLifetimeAgents();
     m_frontend = new InspectorFrontend(m_client);
     m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get());
+    // FIXME: enable resource agent once front-end is ready.
+    // m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get());
 
 #if ENABLE(DATABASE)
     m_storageAgent = InspectorStorageAgent::create(m_frontend.get());
@@ -608,6 +611,8 @@ void InspectorController::disconnectFrontend()
 
 void InspectorController::releaseFrontendLifetimeAgents()
 {
+    m_resourceAgent.clear();
+
     // m_domAgent is RefPtr. Remove DOM listeners first to ensure that there are
     // no references to the DOM agent from the DOM tree.
     if (m_domAgent)
@@ -748,6 +753,9 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didCommitLoad(loader);
+
     ASSERT(m_inspectedPage);
 
     if (loader->frame() == m_inspectedPage->mainFrame()) {
@@ -822,6 +830,10 @@ void InspectorController::frameDetachedFromParent(Frame* frame)
 {
     if (!enabled())
         return;
+
+    if (m_resourceAgent)
+        m_resourceAgent->frameDetachedFromParent(frame);
+
     if (ResourcesMap* resourceMap = m_frameResources.get(frame))
         removeAllResources(resourceMap);
 }
@@ -896,6 +908,9 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader,
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource);
+
     // If the resource URL is already known, we don't need to add it again since this is just a cached load.
     if (m_knownResources.contains(cachedResource->url()))
         return;
@@ -926,6 +941,10 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier,
     ASSERT(m_inspectedPage);
 
     bool isMainResource = isMainResourceLoader(loader, request.url());
+
+    if (m_resourceAgent)
+        m_resourceAgent->identifierForInitialRequest(identifier, request.url(), loader, isMainResource);
+
     ensureSettingsLoaded();
     if (!isMainResource && !resourceTrackingEnabled())
         return;
@@ -977,6 +996,9 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->willSendRequest(identifier, request, redirectResponse);
+
     bool isMainResource = (m_mainResource && m_mainResource->identifier() == identifier);
     if (m_timelineAgent)
         m_timelineAgent->willSendResourceRequest(identifier, isMainResource, request);
@@ -1023,15 +1045,21 @@ void InspectorController::markResourceAsCached(unsigned long identifier)
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->markResourceAsCached(identifier);
+
     if (RefPtr<InspectorResource> resource = getTrackedResource(identifier))
         resource->markAsCached();
 }
 
-void InspectorController::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+void InspectorController::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response)
 {
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didReceiveResponse(identifier, loader, response);
+
     if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) {
         resource->updateResponse(response);
 
@@ -1049,6 +1077,9 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didReceiveContentLength(identifier, lengthReceived);
+
     RefPtr<InspectorResource> resource = getTrackedResource(identifier);
     if (!resource)
         return;
@@ -1064,6 +1095,9 @@ void InspectorController::didFinishLoading(unsigned long identifier, double fini
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didFinishLoading(identifier, finishTime);
+
     if (m_timelineAgent)
         m_timelineAgent->didFinishLoadingResource(identifier, false, finishTime);
 
@@ -1083,6 +1117,9 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->didFailLoading(identifier, error);
+
     if (m_timelineAgent)
         m_timelineAgent->didFinishLoadingResource(identifier, true, 0);
 
@@ -1108,6 +1145,9 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
     if (!enabled())
         return;
 
+    if (m_resourceAgent)
+        m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::XHR);
+
     if (m_state->getBoolean(InspectorState::monitoringXHR))
         addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL);
 
@@ -1126,7 +1166,13 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
 
 void InspectorController::scriptImported(unsigned long identifier, const String& sourceString)
 {
-    if (!enabled() || !resourceTrackingEnabled())
+    if (!enabled())
+        return;
+
+    if (m_resourceAgent)
+        m_resourceAgent->setOverrideContent(identifier, sourceString, InspectorResource::Script);
+
+    if (!resourceTrackingEnabled())
         return;
 
     InspectorResource* resource = m_resources.get(identifier).get();
@@ -1482,6 +1528,9 @@ void InspectorController::didCreateWebSocket(unsigned long identifier, const KUR
         return;
     ASSERT(m_inspectedPage);
 
+    if (m_resourceAgent)
+        m_resourceAgent->didCreateWebSocket(identifier, requestURL);
+
     RefPtr<InspectorResource> resource = InspectorResource::createWebSocket(identifier, requestURL, documentURL);
     addResource(resource.get());
 
@@ -1491,6 +1540,9 @@ void InspectorController::didCreateWebSocket(unsigned long identifier, const KUR
 
 void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request)
 {
+    if (m_resourceAgent)
+        m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request);
+
     RefPtr<InspectorResource> resource = getTrackedResource(identifier);
     if (!resource)
         return;
@@ -1502,6 +1554,9 @@ void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identi
 
 void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response)
 {
+    if (m_resourceAgent)
+        m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response);
+
     RefPtr<InspectorResource> resource = getTrackedResource(identifier);
     if (!resource)
         return;
@@ -1515,6 +1570,9 @@ void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long ide
 
 void InspectorController::didCloseWebSocket(unsigned long identifier)
 {
+    if (m_resourceAgent)
+        m_resourceAgent->didCloseWebSocket(identifier);
+
     RefPtr<InspectorResource> resource = getTrackedResource(identifier);
     if (!resource)
         return;
index 80ebca1..6d4d9e0 100644 (file)
@@ -68,6 +68,7 @@ class InspectorFrontendClient;
 class InspectorObject;
 class InspectorProfilerAgent;
 class InspectorResource;
+class InspectorResourceAgent;
 class InspectorState;
 class InspectorStorageAgent;
 class InspectorTimelineAgent;
@@ -165,7 +166,7 @@ public:
     void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
     void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
     void markResourceAsCached(unsigned long identifier);
-    void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
+    void didReceiveResponse(unsigned long identifier, DocumentLoader*, const ResourceResponse&);
     void didReceiveContentLength(unsigned long identifier, int lengthReceived);
     void didFinishLoading(unsigned long identifier, double finishTime);
     void didFailLoading(unsigned long identifier, const ResourceError&);
@@ -344,6 +345,7 @@ private:
     bool m_openingFrontend;
     OwnPtr<InspectorFrontend> m_frontend;
     RefPtr<InspectorDOMAgent> m_domAgent;
+    RefPtr<InspectorResourceAgent> m_resourceAgent;
     RefPtr<InspectorStorageAgent> m_storageAgent;
     OwnPtr<InspectorCSSStore> m_cssStore;
     OwnPtr<InspectorTimelineAgent> m_timelineAgent;
index 5a6caad..f1b270a 100644 (file)
@@ -189,12 +189,7 @@ void InspectorResource::updateResponse(const ResourceResponse& response)
     m_connectionReused = response.connectionReused();
     m_loadTiming = response.resourceLoadTiming();
     m_cached = m_cached || response.wasCached();
-
-    if (!m_cached && m_loadTiming && m_loadTiming->requestTime)
-        m_responseReceivedTime = m_loadTiming->requestTime + m_loadTiming->receiveHeadersEnd / 1000.0;
-    else
-        m_responseReceivedTime = currentTime();
-
+    m_responseReceivedTime = currentTime();
     m_changes.set(TimingChange);
     m_changes.set(ResponseChange);
     m_changes.set(TypeChange);
@@ -340,6 +335,28 @@ void InspectorResource::releaseScriptObject(InspectorFrontend* frontend)
         frontend->removeResource(m_identifier);
 }
 
+static InspectorResource::Type cachedResourceType(CachedResource* cachedResource)
+{
+    if (!cachedResource)
+        return InspectorResource::Other;
+
+    switch (cachedResource->type()) {
+    case CachedResource::ImageResource:
+        return InspectorResource::Image;
+    case CachedResource::FontResource:
+        return InspectorResource::Font;
+    case CachedResource::CSSStyleSheet:
+#if ENABLE(XSLT)
+    case CachedResource::XSLStyleSheet:
+#endif
+        return InspectorResource::Stylesheet;
+    case CachedResource::Script:
+        return InspectorResource::Script;
+    default:
+        return InspectorResource::Other;
+    }
+}
+
 InspectorResource::Type InspectorResource::type() const
 {
     if (!m_overrideContent.isNull())
@@ -358,7 +375,7 @@ InspectorResource::Type InspectorResource::type() const
     if (!m_frame)
         return Other;
 
-    InspectorResource::Type resourceType = InspectorResourceAgent::cachedResourceType(m_frame->document(), m_requestURL);
+    InspectorResource::Type resourceType = cachedResourceType(InspectorResourceAgent::cachedResource(m_frame.get(), m_requestURL));
     if (equalIgnoringFragmentIdentifier(m_requestURL, m_loader->requestURL()) && resourceType == Other)
         return Doc;
 
@@ -378,7 +395,7 @@ String InspectorResource::sourceString() const
         return String(m_overrideContent);
 
     String result;
-    if (!InspectorResourceAgent::resourceContent(m_frame->document(), m_requestURL, &result))
+    if (!InspectorResourceAgent::resourceContent(m_frame.get(), m_requestURL, &result))
         return String();
     return result;
 }
@@ -395,7 +412,7 @@ String InspectorResource::sourceBytes() const
     }
 
     String result;
-    if (!InspectorResourceAgent::resourceContentBase64(m_frame->document(), m_requestURL, &result))
+    if (!InspectorResourceAgent::resourceContentBase64(m_frame.get(), m_requestURL, &result))
         return String();
     return result;
 }
@@ -408,14 +425,9 @@ void InspectorResource::startTiming()
 
 void InspectorResource::endTiming(double actualEndTime)
 {
-    if (actualEndTime) {
+    if (actualEndTime)
         m_endTime = actualEndTime;
-        // In case of fast load (or in case of cached resources), endTime on network stack
-        // can be less then m_responseReceivedTime measured in WebCore. Normalize it here,
-        // prefer actualEndTime to m_responseReceivedTime.
-        if (m_endTime < m_responseReceivedTime)
-            m_responseReceivedTime = m_endTime;
-    } else
+    else
         m_endTime = currentTime();
 
     m_finished = true;
index e39c518..e8f339a 100644 (file)
 #include "DocumentLoader.h"
 #include "Frame.h"
 #include "FrameLoader.h"
+#include "HTTPHeaderMap.h"
+#include "InspectorFrontend.h"
+#include "InspectorValues.h"
 #include "KURL.h"
+#include "Page.h"
+#include "ProgressTracker.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
 #include "SharedBuffer.h"
 #include "TextEncoding.h"
+#include "WebSocketHandshakeRequest.h"
+#include "WebSocketHandshakeResponse.h"
 
+#include <wtf/ListHashSet.h>
 #include <wtf/RefPtr.h>
+#include <wtf/text/StringBuffer.h>
 
 #if ENABLE(INSPECTOR)
 
 namespace WebCore {
 
-bool InspectorResourceAgent::resourceContent(Document* document, const KURL& url, String* result)
+bool InspectorResourceAgent::resourceContent(Frame* frame, const KURL& url, String* result)
 {
-    if (!document)
+    if (!frame)
         return false;
 
     String textEncodingName;
-    RefPtr<SharedBuffer> buffer = InspectorResourceAgent::resourceData(document, url, &textEncodingName);
+    RefPtr<SharedBuffer> buffer = InspectorResourceAgent::resourceData(frame, url, &textEncodingName);
 
     if (buffer) {
         TextEncoding encoding(textEncodingName);
@@ -68,11 +80,11 @@ bool InspectorResourceAgent::resourceContent(Document* document, const KURL& url
     return false;
 }
 
-bool InspectorResourceAgent::resourceContentBase64(Document* document, const KURL& url, String* result)
+bool InspectorResourceAgent::resourceContentBase64(Frame* frame, const KURL& url, String* result)
 {
     Vector<char> out;
     String textEncodingName;
-    RefPtr<SharedBuffer> data = InspectorResourceAgent::resourceData(document, url, &textEncodingName);
+    RefPtr<SharedBuffer> data = InspectorResourceAgent::resourceData(frame, url, &textEncodingName);
     if (!data) {
         *result = String();
         return false;
@@ -83,16 +95,16 @@ bool InspectorResourceAgent::resourceContentBase64(Document* document, const KUR
     return true;
 }
 
-PassRefPtr<SharedBuffer> InspectorResourceAgent::resourceData(Document* document, const KURL& url, String* textEncodingName)
+PassRefPtr<SharedBuffer> InspectorResourceAgent::resourceData(Frame* frame, const KURL& url, String* textEncodingName)
 {
-    FrameLoader* frameLoader = document->frame()->loader();
+    FrameLoader* frameLoader = frame->loader();
     DocumentLoader* loader = frameLoader->documentLoader();
     if (equalIgnoringFragmentIdentifier(url, loader->url())) {
-        *textEncodingName = document->inputEncoding();
+        *textEncodingName = frame->document()->inputEncoding();
         return frameLoader->documentLoader()->mainResourceData();
     }
 
-    CachedResource* cachedResource = InspectorResourceAgent::cachedResource(document, url);
+    CachedResource* cachedResource = InspectorResourceAgent::cachedResource(frame, url);
     if (!cachedResource)
         return 0;
 
@@ -111,36 +123,308 @@ PassRefPtr<SharedBuffer> InspectorResourceAgent::resourceData(Document* document
     return cachedResource->data();
 }
 
-InspectorResource::Type InspectorResourceAgent::cachedResourceType(Document* document, const KURL& url)
+CachedResource* InspectorResourceAgent::cachedResource(Frame* frame, const KURL& url)
 {
-    CachedResource* cachedResource = InspectorResourceAgent::cachedResource(document, url);
+    const String& urlString = url.string();
+    CachedResource* cachedResource = frame->document()->cachedResourceLoader()->cachedResource(urlString);
     if (!cachedResource)
-        return InspectorResource::Other;
+        cachedResource = cache()->resourceForURL(urlString);
+    return cachedResource;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForHeaders(const HTTPHeaderMap& headers)
+{
+    RefPtr<InspectorObject> headersObject = InspectorObject::create();
+    HTTPHeaderMap::const_iterator end = headers.end();
+    for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
+        headersObject->setString(it->first.string(), it->second);
+    return headersObject;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForTiming(const ResourceLoadTiming& timing)
+{
+    RefPtr<InspectorObject> timingObject = InspectorObject::create();
+    timingObject->setNumber("requestTime", timing.requestTime);
+    timingObject->setNumber("proxyStart", timing.proxyStart);
+    timingObject->setNumber("proxyEnd", timing.proxyEnd);
+    timingObject->setNumber("dnsStart", timing.dnsStart);
+    timingObject->setNumber("dnsEnd", timing.dnsEnd);
+    timingObject->setNumber("connectStart", timing.connectStart);
+    timingObject->setNumber("connectEnd", timing.connectEnd);
+    timingObject->setNumber("sslStart", timing.sslStart);
+    timingObject->setNumber("sslEnd", timing.sslEnd);
+    timingObject->setNumber("sendStart", timing.sendStart);
+    timingObject->setNumber("sendEnd", timing.sendEnd);
+    timingObject->setNumber("receiveHeadersEnd", timing.receiveHeadersEnd);
+    return timingObject;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForResourceRequest(const ResourceRequest& request)
+{
+    RefPtr<InspectorObject> requestObject = InspectorObject::create();
+    requestObject->setString("url", request.url().string());
+    requestObject->setString("httpMethod", request.httpMethod());
+    requestObject->setObject("httpHeaderFields", buildObjectForHeaders(request.httpHeaderFields()));
+    if (request.httpBody() && !request.httpBody()->isEmpty())
+        requestObject->setString("requestFormData", request.httpBody()->flattenToString());
+    return requestObject;
+}
 
-    switch (cachedResource->type()) {
+static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const ResourceResponse& response)
+{
+    RefPtr<InspectorObject> responseObject = InspectorObject::create();
+    if (response.isNull()) {
+        responseObject->setBoolean("isNull", true);
+        return responseObject;
+    }
+    responseObject->setString("url", response.url().string());
+    responseObject->setString("mimeType", response.mimeType());
+    responseObject->setNumber("expectedContentLength", response.expectedContentLength());
+    responseObject->setString("textEncodingName", response.textEncodingName());
+    responseObject->setString("suggestedFilename", response.suggestedFilename());
+    responseObject->setNumber("httpStatusCode", response.httpStatusCode());
+    responseObject->setString("httpStatusText", response.httpStatusText());
+    responseObject->setObject("httpHeaderFields", buildObjectForHeaders(response.httpHeaderFields()));
+    responseObject->setBoolean("connectionReused", response.connectionReused());
+    responseObject->setNumber("connectionID", response.connectionID());
+    responseObject->setBoolean("wasCached", response.wasCached());
+    if (response.resourceLoadTiming())
+        responseObject->setObject("timing", buildObjectForTiming(*response.resourceLoadTiming()));
+    if (response.resourceRawHeaders()) {
+        RefPtr<InspectorObject> rawHeadersObject = InspectorObject::create();
+        rawHeadersObject->setObject("requestHeaders", buildObjectForHeaders(response.resourceRawHeaders()->requestHeaders));
+        rawHeadersObject->setObject("responseHeaders", buildObjectForHeaders(response.resourceRawHeaders()->responseHeaders));
+        responseObject->setObject("rawHeaders", rawHeadersObject);
+    }
+    return responseObject;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForMainResource(Frame* frame)
+{
+    FrameLoader* frameLoader = frame->loader();
+    DocumentLoader* loader = frameLoader->documentLoader();
+
+    RefPtr<InspectorObject> resourceObject = InspectorObject::create();
+    resourceObject->setString("url", loader->url().string());
+    resourceObject->setString("host", loader->url().host());
+    resourceObject->setString("path", loader->url().path());
+    resourceObject->setString("lastPathComponent", loader->url().lastPathComponent());
+    resourceObject->setString("type", "Document");
+    resourceObject->setObject("request", buildObjectForResourceRequest(loader->request()));
+    resourceObject->setObject("response", buildObjectForResourceResponse(loader->response()));
+    return resourceObject;
+}
+
+static String cachedResourceTypeString(const CachedResource& cachedResource)
+{
+    switch (cachedResource.type()) {
     case CachedResource::ImageResource:
-        return InspectorResource::Image;
+        return "Image";
+        break;
     case CachedResource::FontResource:
-        return InspectorResource::Font;
+        return "Font";
     case CachedResource::CSSStyleSheet:
+        // Fall through.
 #if ENABLE(XSLT)
     case CachedResource::XSLStyleSheet:
 #endif
-        return InspectorResource::Stylesheet;
+        return "Stylesheet";
     case CachedResource::Script:
-        return InspectorResource::Script;
+        return "Script";
     default:
-        return InspectorResource::Other;
     }
+    return "Other";
 }
 
-CachedResource* InspectorResourceAgent::cachedResource(Document* document, const KURL& url)
+static PassRefPtr<InspectorObject> buildObjectForCachedResource(const CachedResource& cachedResource)
+{
+    RefPtr<InspectorObject> resourceObject = InspectorObject::create();
+    resourceObject->setString("url", cachedResource.url());
+    resourceObject->setString("type", cachedResourceTypeString(cachedResource));
+    resourceObject->setNumber("encodedSize", cachedResource.encodedSize());
+    resourceObject->setObject("response", buildObjectForResourceResponse(cachedResource.response()));
+    return resourceObject;
+}
+
+static PassRefPtr<InspectorObject> buildObjectForFrameResources(Frame* frame)
+{
+    RefPtr<InspectorObject> frameResources = InspectorObject::create();
+    frameResources->setNumber("frameID", reinterpret_cast<uintptr_t>(frame));
+    frameResources->setObject("mainResource", buildObjectForMainResource(frame));
+    RefPtr<InspectorArray> subresources = InspectorArray::create();
+    frameResources->setArray("subresources", subresources);
+
+    const CachedResourceLoader::DocumentResourceMap& allResources = frame->document()->cachedResourceLoader()->allCachedResources();
+    CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end();
+    for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
+        CachedResource* cachedResource = it->second.get();
+        if (cachedResource)
+            subresources->pushValue(buildObjectForCachedResource(*cachedResource));
+    }
+    return frameResources;
+}
+
+InspectorResourceAgent::~InspectorResourceAgent()
+{
+}
+
+void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader, bool isMainResource)
+{
+    m_frontend->identifierForInitialRequest(identifier, url.string(), reinterpret_cast<uintptr_t>(loader->frame()), isMainResource);
+}
+
+void InspectorResourceAgent::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+    m_frontend->willSendRequest(identifier, currentTime(), buildObjectForResourceRequest(request), buildObjectForResourceResponse(redirectResponse));
+}
+
+void InspectorResourceAgent::markResourceAsCached(unsigned long identifier)
+{
+    m_frontend->markResourceAsCached(identifier);
+}
+
+void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response)
+{
+    String type = "Other";
+    if (loader) {
+        if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL()))
+            type = "Image";
+        else {
+            CachedResource* cachedResource = InspectorResourceAgent::cachedResource(loader->frame(), response.url());
+            if (cachedResource)
+                type = cachedResourceTypeString(*cachedResource);
+
+            if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == "Other")
+                type = "Document";
+        }
+    }
+    m_frontend->didReceiveResponse(identifier, currentTime(), type, buildObjectForResourceResponse(response));
+}
+
+void InspectorResourceAgent::didReceiveContentLength(unsigned long identifier, int lengthReceived)
+{
+    m_frontend->didReceiveContentLength(identifier, currentTime(), lengthReceived);
+}
+
+void InspectorResourceAgent::didFinishLoading(unsigned long identifier, double finishTime)
+{
+    if (!finishTime)
+        finishTime = currentTime();
+
+    m_frontend->didFinishLoading(identifier, finishTime);
+}
+
+void InspectorResourceAgent::didFailLoading(unsigned long identifier, const ResourceError& error)
+{
+    m_frontend->didFailLoading(identifier, currentTime(), error.localizedDescription());
+}
+
+void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* resource)
+{
+    Frame* frame = loader->frame();
+    m_frontend->didLoadResourceFromMemoryCache(currentTime(), reinterpret_cast<uintptr_t>(frame), buildObjectForCachedResource(*resource));
+}
+
+void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const String& sourceString, InspectorResource::Type type)
+{
+    String typeString;
+    switch (type) {
+    case InspectorResource::XHR:
+        typeString = "XHR";
+        break;
+    case InspectorResource::Script:
+        typeString = "Script";
+        break;
+    default:
+        typeString = "Other";
+    }
+
+    m_frontend->setOverrideContent(identifier, sourceString, typeString);
+}
+
+void InspectorResourceAgent::didCommitLoad(DocumentLoader* loader)
+{
+    Frame* frame = loader->frame();
+    m_frontend->didCommitLoad(reinterpret_cast<uintptr_t>(frame));
+}
+
+void InspectorResourceAgent::frameDetachedFromParent(Frame* frame)
+{
+    m_frontend->frameDetachedFromParent(reinterpret_cast<uintptr_t>(frame));
+}
+
+
+#if ENABLE(WEB_SOCKETS)
+
+// FIXME: More this into the front-end?
+// Create human-readable binary representation, like "01:23:45:67:89:AB:CD:EF".
+static String createReadableStringFromBinary(const unsigned char* value, size_t length)
+{
+    ASSERT(length > 0);
+    static const char hexDigits[17] = "0123456789ABCDEF";
+    size_t bufferSize = length * 3 - 1;
+    StringBuffer buffer(bufferSize);
+    size_t index = 0;
+    for (size_t i = 0; i < length; ++i) {
+        if (i > 0)
+            buffer[index++] = ':';
+        buffer[index++] = hexDigits[value[i] >> 4];
+        buffer[index++] = hexDigits[value[i] & 0xF];
+    }
+    ASSERT(index == bufferSize);
+    return String::adopt(buffer);
+}
+
+void InspectorResourceAgent::didCreateWebSocket(unsigned long identifier, const KURL& requestURL)
+{
+    m_frontend->didCreateWebSocket(identifier, requestURL.string());
+}
+
+void InspectorResourceAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request)
+{
+    RefPtr<InspectorObject> requestObject = InspectorObject::create();
+    requestObject->setObject("webSocketHeaderFields", buildObjectForHeaders(request.headerFields()));
+    requestObject->setString("webSocketRequestKey3", createReadableStringFromBinary(request.key3().value, sizeof(request.key3().value)));
+    m_frontend->willSendWebSocketHandshakeRequest(identifier, currentTime(), requestObject);
+}
+
+void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response)
+{
+    RefPtr<InspectorObject> responseObject = InspectorObject::create();
+    responseObject->setNumber("statusCode", response.statusCode());
+    responseObject->setString("statusText", response.statusText());
+    responseObject->setObject("webSocketHeaderFields", buildObjectForHeaders(response.headerFields()));
+    responseObject->setString("webSocketChallengeResponse", createReadableStringFromBinary(response.challengeResponse().value, sizeof(response.challengeResponse().value)));
+    m_frontend->didReceiveWebSocketHandshakeResponse(identifier, currentTime(), responseObject);
+}
+
+void InspectorResourceAgent::didCloseWebSocket(unsigned long identifier)
+{
+    m_frontend->didCloseWebSocket(identifier, currentTime());
+}
+#endif // ENABLE(WEB_SOCKETS)
+
+void InspectorResourceAgent::cachedResources(RefPtr<InspectorArray>* resources)
+{
+    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame()))
+        (*resources)->pushObject(buildObjectForFrameResources(frame));
+}
+
+void InspectorResourceAgent::resourceContent(unsigned long frameID, const String& url, String* content)
+{
+    RefPtr<InspectorArray> frameResources = InspectorArray::create();
+    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) {
+        if (reinterpret_cast<uintptr_t>(frame) != frameID)
+            continue;
+        InspectorResourceAgent::resourceContent(frame, KURL(ParsedURLString, url), content);
+        break;
+    }
+}
+
+InspectorResourceAgent::InspectorResourceAgent(Page* page, InspectorFrontend* frontend)
+    : m_page(page)
+    , m_frontend(frontend)
 {
-    const String& urlString = url.string();
-    CachedResource* cachedResource = document->cachedResourceLoader()->cachedResource(urlString);
-    if (!cachedResource)
-        cachedResource = cache()->resourceForURL(urlString);
-    return cachedResource;
 }
 
 } // namespace WebCore
index 3bffd2f..f0bead8 100644 (file)
 #define InspectorResourceAgent_h
 
 #include "InspectorResource.h"
+#include "PlatformString.h"
 
 #include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
 
 #if ENABLE(INSPECTOR)
 
@@ -45,16 +47,64 @@ namespace WebCore {
 
 class CachedResource;
 class Document;
+class DocumentLoader;
+class InspectorArray;
+class InspectorObject;
+class InspectorFrontend;
 class KURL;
+class Page;
+class ResourceError;
+class ResourceRequest;
+class ResourceResponse;
 class SharedBuffer;
 
-class InspectorResourceAgent {
+#if ENABLE(WEB_SOCKETS)
+class WebSocketHandshakeRequest;
+class WebSocketHandshakeResponse;
+#endif
+
+class InspectorResourceAgent : public RefCounted<InspectorResourceAgent> {
 public:
-    static bool resourceContent(Document*, const KURL&, String* result);
-    static bool resourceContentBase64(Document*, const KURL&, String* result);
-    static PassRefPtr<SharedBuffer> resourceData(Document*, const KURL&, String* textEncodingName);
-    static InspectorResource::Type cachedResourceType(Document*, const KURL&);
-    static CachedResource* cachedResource(Document*, const KURL&);
+    static PassRefPtr<InspectorResourceAgent> create(Page* page, InspectorFrontend* frontend)
+    {
+        return adoptRef(new InspectorResourceAgent(page, frontend));
+    }
+
+    static bool resourceContent(Frame*, const KURL&, String* result);
+    static bool resourceContentBase64(Frame*, const KURL&, String* result);
+    static PassRefPtr<SharedBuffer> resourceData(Frame*, const KURL&, String* textEncodingName);
+    static CachedResource* cachedResource(Frame*, const KURL&);
+
+    ~InspectorResourceAgent();
+
+    void identifierForInitialRequest(unsigned long identifier, const KURL&, DocumentLoader*, bool isMainResource);
+    void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
+    void markResourceAsCached(unsigned long identifier);
+    void didReceiveResponse(unsigned long identifier, DocumentLoader* laoder, const ResourceResponse&);
+    void didReceiveContentLength(unsigned long identifier, int lengthReceived);
+    void didFinishLoading(unsigned long identifier, double finishTime);
+    void didFailLoading(unsigned long identifier, const ResourceError&);
+    void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
+    void setOverrideContent(unsigned long identifier, const String& sourceString, InspectorResource::Type);
+    void didCommitLoad(DocumentLoader*);
+    void frameDetachedFromParent(Frame*);
+
+#if ENABLE(WEB_SOCKETS)
+    void didCreateWebSocket(unsigned long identifier, const KURL& requestURL);
+    void willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest&);
+    void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse&);
+    void didCloseWebSocket(unsigned long identifier);
+#endif
+
+    // Called from frontend 
+    void cachedResources(RefPtr<InspectorArray>*);
+    void resourceContent(unsigned long frameID, const String& url, String* content);
+
+private:
+    InspectorResourceAgent(Page* page, InspectorFrontend* frontend);
+
+    Page* m_page;
+    InspectorFrontend* m_frontend;
 };
 
 } // namespace WebCore
index 9ee1f51..11cd649 100644 (file)
@@ -468,7 +468,7 @@ bool InspectorStyleSheet::resourceStyleSheetText(String* result) const
     if (!m_pageStyleSheet)
         return false;
 
-    return InspectorResourceAgent::resourceContent(ownerDocument(), m_pageStyleSheet->finalURL(), result);
+    return InspectorResourceAgent::resourceContent(ownerDocument()->frame(), m_pageStyleSheet->finalURL(), result);
 }
 
 bool InspectorStyleSheet::inlineStyleSheetText(String* result) const
index 12c7138..3007497 100644 (file)
@@ -661,7 +661,7 @@ WebInspector.DataGrid.prototype = {
         var fillerRow = childNodes[childNodes.length - 1];
 
         var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1);
-        sortedRows.sort(comparatorWrapper.bind(this));
+        sortedRows.sort(comparatorWrapper);
         var sortedRowsLength = sortedRows.length;
 
         tbody.removeChildren();
index 479cc02..bc633ca 100644 (file)
@@ -240,7 +240,7 @@ WebInspector.ExtensionServer.prototype = {
         var id = message.id;
         var resource = null;
 
-        resource = typeof id === "number" ? WebInspector.resources[id] : WebInspector.resourceForURL(id);
+        resource = WebInspector.resources[id] || WebInspector.resourceForURL(id);
         if (!resource)
             return this._status.E_NOTFOUND(typeof id + ": " + id);
         WebInspector.panels.resources.showResource(resource, message.line);
@@ -284,13 +284,12 @@ WebInspector.ExtensionServer.prototype = {
                 this._dispatchCallback(message.requestId, port, response);
         }
 
-        if (typeof message.ids === "number") {
+        if (typeof message.ids === "number")
             ids = [ message.ids ];
-        } else if (message.ids instanceof Array) {
+        else if (message.ids instanceof Array)
             ids = message.ids;
-        } else {
+        else
             return this._status.E_BADARGTYPE("message.ids", "Array", typeof message.ids);
-        }
 
         for (var i = 0; i < ids.length; ++i) {
             var id = ids[i];
index 1b8f515..8eed425 100644 (file)
@@ -127,15 +127,19 @@ WebInspector.NetworkPanel.prototype = {
         var parentElement = this._summaryBarElement.parentElement;
 
         if (this._summaryBarElement.parentElement !== this.element && offsetHeight > (this._dataGrid.children.length - 1) * rowHeight + summaryBarHeight) {
-            this._dataGrid.removeChild(this._summaryBarRowNode);
+            // Glue status to bottom.
+            if (this._summaryBarRowNode) {
+                this._dataGrid.removeChild(this._summaryBarRowNode);
+                delete this._summaryBarRowNode;
+            }
             this._summaryBarElement.addStyleClass("network-summary-bar-bottom");
-            delete this._summaryBarRowNode;
             this.element.appendChild(this._summaryBarElement);
             this._dataGrid.element.style.bottom = "20px";
             return;
         }
 
         if (!this._summaryBarRowNode && offsetHeight - summaryBarHeight < this._dataGrid.children.length * rowHeight) {
+            // Glue status to table.
             this._summaryBarRowNode = new WebInspector.NetworkTotalGridNode(this._summaryBarElement);
             this._summaryBarElement.removeStyleClass("network-summary-bar-bottom");
             this._dataGrid.appendChild(this._summaryBarRowNode);
@@ -144,6 +148,13 @@ WebInspector.NetworkPanel.prototype = {
         }
     },
 
+    _resetSummaryBar: function()
+    {
+        delete this._summaryBarRowNode;
+        this._summaryBarElement.parentElement.removeChild(this._summaryBarElement);
+        this._updateSummaryBar();
+    },
+
     _createTimelineGrid: function()
     {
         this._timelineGrid = new WebInspector.TimelineGrid();
@@ -349,20 +360,37 @@ WebInspector.NetworkPanel.prototype = {
     {
         this._positionSummaryBar(); // Grid is growing.
         var numRequests = this._resources.length;
+
+        if (!numRequests) {
+            if (this._summaryBarElement._isDisplayingWarning)
+                return;
+            this._summaryBarElement._isDisplayingWarning = true;
+
+            var img = document.createElement("img");
+            img.src = "Images/warningIcon.png";
+            this._summaryBarElement.removeChildren();
+            this._summaryBarElement.appendChild(img);
+            this._summaryBarElement.appendChild(document.createTextNode(" "));
+            this._summaryBarElement.appendChild(document.createTextNode(
+                WebInspector.UIString("No requests captured. Reload the page to see detailed information on the network activity.")));
+            return;
+        }
+        delete this._summaryBarElement._isDisplayingWarning;
+
         var transferSize = 0;
         var baseTime = -1;
         var maxTime = -1;
         for (var i = 0; i < this._resources.length; ++i) {
             var resource = this._resources[i];
             transferSize += resource.cached ? 0 : resource.transferSize;
-            if (resource === WebInspector.mainResource)
+            if (resource.isMainResource)
                 baseTime = resource.startTime;
             if (resource.endTime > maxTime) 
                 maxTime = resource.endTime;
         }
         var text = String.sprintf(WebInspector.UIString("%d requests"), numRequests);
         text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s transferred"), Number.bytesToString(transferSize));
-        if (baseTime !== -1 && this._mainResourceLoadTime !== -1 && this._mainResourceDOMContentTime !== -1) {
+        if (baseTime !== -1 && this._mainResourceLoadTime !== -1 && this._mainResourceDOMContentTime !== -1 && this._mainResourceDOMContentTime > baseTime) {
             text += "  \u2758  " + String.sprintf(WebInspector.UIString("%s (onload: %s, DOMContentLoaded: %s)"),
                         Number.secondsToString(maxTime - baseTime),
                         Number.secondsToString(this._mainResourceLoadTime - baseTime),
@@ -578,7 +606,7 @@ WebInspector.NetworkPanel.prototype = {
     _createStatusbarButtons: function()
     {
         this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
-        this._clearButton.addEventListener("click", this.reset.bind(this), false);
+        this._clearButton.addEventListener("click", this._reset.bind(this), false);
 
         this._largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "network-larger-resources-status-bar-item");
         WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
@@ -718,39 +746,17 @@ WebInspector.NetworkPanel.prototype = {
         this._dataGrid.updateWidths();
     },
 
-    reset: function()
+    _reset: function()
     {
         this._popoverHelper.hidePopup();
         this._closeVisibleResource();
 
         this._toggleGridMode();
 
-        delete this.currentQuery;
-        this.searchCanceled();
-
-        if (this._resources) {
-            var resourcesLength = this._resources.length;
-            for (var i = 0; i < resourcesLength; ++i) {
-                var resource = this._resources[i];
-
-                resource.warnings = 0;
-                resource.errors = 0;
-
-                delete resource._resourcesView;
-            }
-        }
-
         // Begin reset timeline
         if (this._calculator)
             this._calculator.reset();
 
-        if (this._resources) {
-            var itemsLength = this._resources.length;
-            for (var i = 0; i < itemsLength; ++i) {
-                var item = this._resources[i];
-            }
-        }
-
         this._resources = [];
         this._staleResources = [];
         this._resourceGridNodes = {};
@@ -764,6 +770,7 @@ WebInspector.NetworkPanel.prototype = {
         this._mainResourceDOMContentTime = -1;
  
         this._viewsContainerElement.removeChildren();
+        this._resetSummaryBar();
     },
 
     addResource: function(resource)
@@ -787,9 +794,6 @@ WebInspector.NetworkPanel.prototype = {
         if (newView.__proto__ === resource._resourcesView.__proto__)
             return;
 
-        if (!this.currentQuery && this._resourceGridNode(resource))
-            this._resourceGridNode(resource).updateErrorsAndWarnings();
-
         var oldView = resource._resourcesView;
         var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null;
 
@@ -1097,11 +1101,6 @@ WebInspector.NetworkPanel.prototype = {
 
 WebInspector.NetworkPanel.prototype.__proto__ = WebInspector.Panel.prototype;
 
-WebInspector.getResourceContent = function(identifier, callback)
-{
-    InspectorBackend.getResourceContent(identifier, false, callback);
-}
-
 WebInspector.NetworkBaseCalculator = function()
 {
 }
@@ -1611,6 +1610,8 @@ WebInspector.NetworkDataGridNode.prototype = {
 
     _refreshLabelPositions: function()
     {
+        if (!this._percentages)
+            return;
         this._labelLeftElement.style.removeProperty("left");
         this._labelLeftElement.style.removeProperty("right");
         this._labelLeftElement.removeStyleClass("before");
index 9bbf90b..b4338ab 100644 (file)
@@ -164,6 +164,11 @@ WebInspector.Resource.prototype = {
 
     get responseReceivedTime()
     {
+        if (this.timing && this.timing.requestTime) {
+            // Calculate responseReceivedTime from timing data for better accuracy.
+            // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
+            return this.timing.requestTime + this.timing.receiveHeadersEnd / 1000.0;
+        }
         return this._responseReceivedTime || -1;
     },
 
@@ -185,6 +190,12 @@ WebInspector.Resource.prototype = {
 
     set endTime(x)
     {
+        // In case of fast load (or in case of cached resources), endTime on network stack
+        // can be less then m_responseReceivedTime measured in WebCore. Normalize it here,
+        // prefer actualEndTime to m_responseReceivedTime.
+        if (x < this.responseReceivedTime)
+            this.responseReceivedTime = x;
+
         if (this._endTime === x)
             return;
 
@@ -609,6 +620,15 @@ WebInspector.Resource.prototype = {
 
         if (msg)
             WebInspector.console.addMessage(msg);
+    },
+
+    getContents: function(callback)
+    {
+        // FIXME: eventually, cached resources will have no identifiers.
+        if (this.frameID)
+            InspectorBackend.resourceContent(this.frameID, this.url, callback);
+        else
+            InspectorBackend.getResourceContent(this.identifier, false, callback);
     }
 }
 
diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js
new file mode 100644 (file)
index 0000000..7244cea
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2009, 2010 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.
+ */
+
+WebInspector.ResourceManager = function()
+{
+    this._registerNotifyHandlers(
+        "identifierForInitialRequest",
+        "willSendRequest",
+        "markResourceAsCached",
+        "didReceiveResponse",
+        "didReceiveContentLength",
+        "didFinishLoading",
+        "didFailLoading",
+        "didLoadResourceFromMemoryCache",
+        "setOverrideContent",
+        "didCommitLoad",
+        "frameDetachedFromParent",
+        "didCreateWebSocket",
+        "willSendWebSocketHandshakeRequest",
+        "didReceiveWebSocketHandshakeResponse",
+        "didCloseWebSocket");
+
+    this._resources = {};
+    this._resourcesByFrame = {};
+    this._lastCachedId = 0;
+}
+
+WebInspector.ResourceManager.prototype = {
+    _registerNotifyHandlers: function()
+    {
+        for (var i = 0; i < arguments.length; ++i)
+            WebInspector[arguments[i]] = this[arguments[i]].bind(this);
+    },
+
+    identifierForInitialRequest: function(identifier, url, frameID, isMainResource)
+    {
+        var resource = new WebInspector.Resource(identifier, url);
+        if (isMainResource)
+            resource.isMainResource = true;
+        this._resources[identifier] = resource;
+
+        if (frameID) {
+            resource.frameID = frameID;
+            var resourcesForFrame = this._resourcesByFrame[frameID];
+            if (!resourcesForFrame) {
+                resourcesForFrame = [];
+                this._resourcesByFrame[frameID] = resourcesForFrame;
+            }
+            resourcesForFrame.push(resource);
+        }
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.addResource(resource);
+    },
+
+    willSendRequest: function(identifier, time, request, redirectResponse)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        // Redirect may have empty URL and we'd like to not crash with invalid HashMap entry.
+        // See http/tests/misc/will-send-request-returns-null-on-redirect.html
+        if (!redirectResponse.isNull && request.url.length) {
+            resource.endTime = time;
+            this.didReceiveResponse(identifier, time, "Other", redirectResponse);
+            resource = this._appendRedirect(resource.identifier, request.url);
+        }
+
+        resource.requestMethod = request.httpMethod;
+        resource.requestHeaders = request.httpHeaderFields;
+        resource.requestFormData = request.requestFormData;
+        resource.startTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    _appendRedirect: function(identifier, redirectURL)
+    {
+        // We always store last redirect by the original id key. Rest of the redirects are referenced from within the last one.
+
+        var originalResource = this._resources[identifier];
+        var redirectIdentifier = originalResource.identifier + ":" + (originalResource.redirects ? originalResource.redirects.length : 0);
+        originalResource.identifier = redirectIdentifier;
+        this._resources[redirectIdentifier] = originalResource;
+
+        this.identifierForInitialRequest(identifier, redirectURL, originalResource.frameID);
+
+        var newResource = this._resources[identifier];
+        newResource.redirects = originalResource.redirects || [];
+        delete originalResource.redirects;
+        newResource.redirects.push(originalResource);
+        return newResource;
+    },
+
+    markResourceAsCached: function(identifier)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.cached = true;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didReceiveResponse: function(identifier, time, resourceType, response)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.type = WebInspector.Resource.Type[resourceType];
+        resource.mimeType = response.mimeType;
+        resource.expectedContentLength = response.expectedContentLength;
+        resource.textEncodingName = response.textEncodingName;
+        resource.suggestedFilename = response.suggestedFilename;
+        resource.statusCode = response.httpStatusCode;
+        resource.statusText = response.httpStatusText;
+
+        resource.responseHeaders = response.httpHeaderFields;
+        resource.connectionReused = response.connectionReused;
+        resource.connectionID = response.connectionID;
+        resource.responseReceivedTime = time;
+
+        if (response.wasCached)
+            resource.cached = true;
+        else
+            resource.timing = response.timing;
+
+        if (response.rawHeaders) {
+            resource.requestHeaders = response.rawHeaders.requestHeaders;
+            resource.responseHeaders = response.rawHeaders.responseHeaders;
+        }
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didReceiveContentLength: function(identifier, time, lengthReceived)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.resourceSize += lengthReceived;
+        resource.endTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didFinishLoading: function(identifier, finishTime)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.finished = true;
+        resource.endTime = finishTime;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didFailLoading: function(identifier, time, localizedDescription)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.failed = true;
+        resource.endTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didLoadResourceFromMemoryCache: function(time, frameID, cachedResource)
+    {
+        var identifier = "cached:" + this._lastCachedId++;
+        this.identifierForInitialRequest(identifier, cachedResource.url, frameID);
+
+        var resource = this._resources[identifier];
+        resource.cached = true;
+        resource.startTime = resource.responseReceivedTime = time;
+        resource.resourceSize = cachedResource.encodedSize();
+
+        this.didReceiveResponse(identifier, time, cachedResource.response);
+    },
+
+    setOverrideContent: function(identifier, sourceString, type)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.type = WebInspector.Resource.Type[type];
+        resource.overridenContent = sourceString;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.addResource(resource);
+    },
+
+    didCommitLoad: function(frameID)
+    {
+    },
+
+    frameDetachedFromParent: function(frameID)
+    {
+        var resourcesForFrame = this._resourcesByFrame[frameID];
+        for (var i = 0; resourcesForFrame && i < resourcesForFrame.length; ++i)
+            delete this._resources[resourcesForFrame[i].identifier];
+        delete this._resourcesByFrame[frameID];
+    },
+
+    didCreateWebSocket: function(identifier, requestURL)
+    {
+        this.identifierForInitialRequest(identifier, requestURL);
+        var resource = this._resources[identifier];
+        resource.type = WebInspector.Resource.Type.WebSocket;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.addResource(resource);
+    },
+
+    willSendWebSocketHandshakeRequest: function(identifier, time, request)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.requestMethod = "GET";
+        resource.requestHeaders = request.webSocketHeaderFields;
+        resource.webSocketRequestKey3 = request.webSocketRequestKey3;
+        resource.startTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didReceiveWebSocketHandshakeResponse: function(identifier, time, response)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+
+        resource.statusCode = response.statusCode;
+        resource.statusText = response.statusText;
+        resource.responseHeaders = response.webSocketHeaderFields;
+        resource.webSocketChallengeResponse = response.webSocketChallengeResponse;
+        resource.responseReceivedTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    },
+
+    didCloseWebSocket: function(identifier, time)
+    {
+        var resource = this._resources[identifier];
+        if (!resource)
+            return;
+        resource.endTime = time;
+
+        if (WebInspector.panels.network)
+            WebInspector.panels.network.refreshResource(resource);
+    }
+}
index 8ff82c9..fd16847 100644 (file)
@@ -1291,11 +1291,6 @@ WebInspector.ResourcesPanel.prototype = {
 
 WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
 
-WebInspector.getResourceContent = function(identifier, callback)
-{
-    InspectorBackend.getResourceContent(identifier, false, callback);
-}
-
 WebInspector.ResourceBaseCalculator = function()
 {
 }
index 09549bf..8092505 100644 (file)
@@ -83,7 +83,7 @@ WebInspector.SourceView.prototype = {
         this.attach();
 
         delete this._frameNeedsSetup;
-        WebInspector.getResourceContent(this.resource.identifier, this._contentLoaded.bind(this));
+        this.resource.getContents(this._contentLoaded.bind(this));
     },
 
     hasContentTab: function()
index 11382cd..a5933af 100644 (file)
@@ -68,6 +68,7 @@
     <file>RemoteObject.js</file>
     <file>Resource.js</file>
     <file>ResourceCategory.js</file>
+    <file>ResourceManager.js</file>
     <file>ResourcesPanel.js</file>
     <file>ResourceView.js</file>
     <file>ScopeChainSidebarPane.js</file>
index 949b18f..59a5f79 100644 (file)
@@ -61,6 +61,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     <script type="text/javascript" src="Panel.js"></script>
     <script type="text/javascript" src="TimelineGrid.js"></script>    
     <script type="text/javascript" src="Resource.js"></script>
+    <script type="text/javascript" src="ResourceManager.js"></script>
     <script type="text/javascript" src="ResourceCategory.js"></script>
     <script type="text/javascript" src="Database.js"></script>
     <script type="text/javascript" src="DOMStorage.js"></script>
index a6b4845..4116417 100644 (file)
@@ -507,6 +507,7 @@ WebInspector.doLoadedDone = function()
     // this.changes = new WebInspector.ChangesView(this.drawer);
     // TODO: Remove class="hidden" from inspector.html on button#changes-status-bar-item
     this.drawer.visibleView = this.console;
+    this.resourceManager = new WebInspector.ResourceManager();
     this.domAgent = new WebInspector.DOMAgent();
 
     this.resourceCategories = {
@@ -1220,8 +1221,6 @@ WebInspector.updateResource = function(payload)
         this.resourceURLMap[resource.url] = resource;
         this.panels.resources.addResource(resource);
         this.panels.audits.resourceStarted(resource);
-        if (this.panels.network)
-            this.panels.network.addResource(resource);
     }
 
     if (payload.didRequestChange) {
@@ -1281,12 +1280,8 @@ WebInspector.updateResource = function(payload)
         if (payload.endTime)
             resource.endTime = payload.endTime;
     }
-
-    if (this.panels.network)
-        this.panels.network.refreshResource(resource);
 }
 
-
 WebInspector.domContentEventFired = function(time)
 {
     this.panels.resources.mainResourceDOMContentTime = time;
index 098ca52..773fe99 100644 (file)
     font-size: 11px;
     font-weight: bold;
 }
+
+.network.panel .data-grid tr.filler {
+    background-color: white;
+}
+
 .network.panel .data-grid td.name-column {
     font-weight: bold;
 }
index c43a1da..b32b737 100644 (file)
@@ -136,7 +136,7 @@ void ResourceLoadNotifier::dispatchDidReceiveResponse(DocumentLoader* loader, un
 
 #if ENABLE(INSPECTOR)
     if (Page* page = m_frame->page())
-        page->inspectorController()->didReceiveResponse(identifier, r);
+        page->inspectorController()->didReceiveResponse(identifier, loader, r);
 #endif
 }
 
index dc1e661..8d5d5c0 100644 (file)
@@ -523,7 +523,7 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
             if (InspectorApplicationCacheAgent* applicationCacheAgent = page->inspectorController()->applicationCacheAgent())
                 applicationCacheAgent->didReceiveManifestResponse(m_currentResourceIdentifier, response);
         } else
-            page->inspectorController()->didReceiveResponse(m_currentResourceIdentifier, response);
+            page->inspectorController()->didReceiveResponse(m_currentResourceIdentifier, m_frame->loader()->documentLoader(), response);
     }
 #endif
 
index 028bfec..7820b1a 100644 (file)
@@ -1,3 +1,14 @@
+2010-10-17  Pavel Feldman  <pfeldman@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: Introduce InspectorResourceAgent.h/cpp and ResourceManager.js to
+        fill network panel with data.
+        https://bugs.webkit.org/show_bug.cgi?id=47779
+
+        * src/WebDevToolsAgentImpl.cpp:
+        (WebKit::WebDevToolsAgentImpl::didReceiveResponse):
+
 2010-10-17  Pascal Massimino  <pascal.massimino@gmail.com>
 
         Reviewed by Adam Barth.
index 33cc09b..9b7b2bd 100644 (file)
@@ -333,7 +333,7 @@ void WebDevToolsAgentImpl::didReceiveData(unsigned long resourceId, int length)
 void WebDevToolsAgentImpl::didReceiveResponse(unsigned long resourceId, const WebURLResponse& response)
 {
     if (InspectorController* ic = inspectorController())
-        ic->didReceiveResponse(resourceId, response.toResourceResponse());
+        ic->didReceiveResponse(resourceId, 0, response.toResourceResponse());
 }
 
 void WebDevToolsAgentImpl::didFinishLoading(unsigned long resourceId)