summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /WebCore/inspector
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'WebCore/inspector')
-rw-r--r--WebCore/inspector/Inspector.idl13
-rw-r--r--WebCore/inspector/InspectorController.cpp108
-rw-r--r--WebCore/inspector/InspectorController.h71
-rw-r--r--WebCore/inspector/InspectorDOMAgent.cpp9
-rw-r--r--WebCore/inspector/InspectorDOMAgent.h2
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.cpp29
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.h13
-rw-r--r--WebCore/inspector/front-end/AbstractTimelinePanel.js527
-rw-r--r--WebCore/inspector/front-end/AuditLauncherView.js3
-rw-r--r--WebCore/inspector/front-end/BreakpointManager.js106
-rw-r--r--WebCore/inspector/front-end/BreakpointsSidebarPane.js73
-rw-r--r--WebCore/inspector/front-end/CallStackSidebarPane.js60
-rw-r--r--WebCore/inspector/front-end/DOMAgent.js29
-rw-r--r--WebCore/inspector/front-end/DataGrid.js50
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js49
-rw-r--r--WebCore/inspector/front-end/ElementsTreeOutline.js11
-rw-r--r--WebCore/inspector/front-end/GoToLineDialog.js127
-rw-r--r--WebCore/inspector/front-end/Images/networkIcon.pngbin0 -> 6431 bytes
-rw-r--r--WebCore/inspector/front-end/Images/paneAddButtons.pngbin0 -> 929 bytes
-rw-r--r--WebCore/inspector/front-end/NetworkPanel.js1414
-rw-r--r--WebCore/inspector/front-end/ResourceCategory.js11
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js455
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js30
-rw-r--r--WebCore/inspector/front-end/Settings.js6
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js3
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc7
-rw-r--r--WebCore/inspector/front-end/goToLineDialog.css39
-rw-r--r--WebCore/inspector/front-end/inspector.css37
-rw-r--r--WebCore/inspector/front-end/inspector.html5
-rw-r--r--WebCore/inspector/front-end/inspector.js65
-rw-r--r--WebCore/inspector/front-end/networkPanel.css383
-rw-r--r--WebCore/inspector/front-end/treeoutline.js8
32 files changed, 3008 insertions, 735 deletions
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index ae136b2..a08a622 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -37,9 +37,11 @@ module core {
[notify] void addNodesToSearchResult(out Array nodeIds);
[notify] void attributesUpdated(out long id, out Array attributes);
[notify] void bringToFront();
+ [notify] void characterDataModified(out long id, out String newValue);
[notify] void childNodeCountUpdated(out long id, out int newValue);
[notify] void childNodeInserted(out long parentId, out long prevId, out Object node);
[notify] void childNodeRemoved(out long parentId, out long id);
+ [notify] void consoleMessagesCleared();
[notify] void didCommitLoad();
[notify] void evaluateForTestInFrontend(out long testCallId, out String script);
[notify] void disconnectFromBackend();
@@ -47,8 +49,6 @@ module core {
[notify] void removeResource(out unsigned long identifier);
[notify] void reset();
[notify] void resetProfilesPanel();
- [notify] void searchingForNodeWasEnabled();
- [notify] void searchingForNodeWasDisabled();
[notify] void setChildNodes(out long parentId, out Array nodes);
[notify] void setDetachedRoot(out Object root);
[notify] void setDocument(out Value root);
@@ -59,7 +59,6 @@ module core {
[notify] void updateConsoleMessageRepeatCount(out unsigned long count);
[notify] void updateFocusedNode(out long nodeId);
[notify] void updateResource(out Value resource);
- [notify] void consoleMessagesCleared();
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
[notify] void addProfileHeader(out Object header);
@@ -104,8 +103,7 @@ module core {
[handler=Controller] void saveApplicationSettings(in String settings);
[handler=Controller] void saveSessionSettings(in String settings);
- [handler=Controller] void enableSearchingForNode();
- [handler=Controller] void disableSearchingForNode();
+ [handler=Controller] void setSearchingForNode(in boolean enabled, out boolean newState);
[handler=Controller] void setMonitoringXHREnabled(in boolean enable, out boolean newState);
@@ -132,11 +130,14 @@ module core {
[handler=Debug] void stepIntoStatement();
[handler=Debug] void stepOutOfFunction();
- [handler=Debug] void setPauseOnExceptionsState(in long pauseOnExceptionsState);
+ [handler=Debug] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState);
[handler=Debug] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames);
[handler=Debug] void getScriptSource(in String sourceID, out String scriptSource);
+ [handler=Controller] void setNativeBreakpoint(in Object breakpoint, out unsigned int breakpointId);
+ [handler=Controller] void removeNativeBreakpoint(in unsigned int breakpointId);
+
[handler=Controller] void enableProfiler(in boolean always);
[handler=Controller] void disableProfiler(in boolean always);
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 5f8f190..f2ee2c1 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -111,10 +111,6 @@
#include "StorageArea.h"
#endif
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include "ScriptDebugServer.h"
-#endif
-
using namespace std;
namespace WebCore {
@@ -127,9 +123,11 @@ static const char* const monitoringXHRSettingName = "xhrMonitor";
static const char* const resourceTrackingAlwaysEnabledSettingName = "resourceTrackingEnabled";
static const char* const profilerAlwaysEnabledSettingName = "profilerEnabled";
-static const char* const timelineProfilerEnabledStateName = "timelineProfilerEnabled";
-static const char* const resourceTrackingEnabledStateName = "resourceTrackingEnabled";
static const char* const monitoringXHRStateName = "monitoringXHREnabled";
+static const char* const resourceTrackingEnabledStateName = "resourceTrackingEnabled";
+static const char* const searchingForNodeEnabledStateName = "searchingForNodeEnabled";
+static const char* const timelineProfilerEnabledStateName = "timelineProfilerEnabled";
+static const char* const pauseOnExceptionsStateStateName = "pauseOnExceptionsState";
static const char* const inspectorAttachedHeightName = "inspectorAttachedHeight";
@@ -153,7 +151,7 @@ static const float maximumAttachedHeightRatio = 0.75f;
static const unsigned maximumConsoleMessages = 1000;
static const unsigned expireConsoleMessagesStep = 100;
-static unsigned s_inspectorControllerCount;
+unsigned InspectorController::s_inspectorControllerCount = 0;
InspectorController::InspectorController(Page* page, InspectorClient* client)
: m_inspectedPage(page)
@@ -174,6 +172,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
, m_injectedScriptHost(InjectedScriptHost::create(this))
#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_attachDebuggerWhenShown(false)
+ , m_lastBreakpointId(0)
, m_profilerAgent(InspectorProfilerAgent::create(this))
#endif
{
@@ -256,6 +255,10 @@ void InspectorController::getInspectorState(RefPtr<InspectorObject>* state)
{
(*state)->setBoolean(monitoringXHRStateName, m_monitoringXHR);
(*state)->setBoolean(resourceTrackingEnabledStateName, m_resourceTrackingEnabled);
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (m_debuggerAgent)
+ (*state)->setNumber(pauseOnExceptionsStateStateName, m_debuggerAgent->pauseOnExceptionsState());
+#endif
}
void InspectorController::updateInspectorStateCookie()
@@ -264,6 +267,7 @@ void InspectorController::updateInspectorStateCookie()
state->setBoolean(monitoringXHRStateName, m_monitoringXHR);
state->setBoolean(resourceTrackingEnabledStateName, m_resourceTrackingEnabled);
state->setBoolean(timelineProfilerEnabledStateName, m_timelineAgent);
+ state->setBoolean(searchingForNodeEnabledStateName, m_searchingForNode);
m_client->updateInspectorStateCookie(state->toJSONString());
}
@@ -279,6 +283,7 @@ void InspectorController::restoreInspectorStateFromCookie(const String& inspecto
inspectorState->getBoolean(monitoringXHRStateName, &m_monitoringXHR);
inspectorState->getBoolean(resourceTrackingEnabledStateName, &m_resourceTrackingEnabled);
+ inspectorState->getBoolean(searchingForNodeEnabledStateName, &m_searchingForNode);
bool timelineProfilerEnabled = false;
inspectorState->getBoolean(timelineProfilerEnabledStateName, &timelineProfilerEnabled);
@@ -492,12 +497,13 @@ void InspectorController::setSearchingForNode(bool enabled)
m_searchingForNode = enabled;
if (!m_searchingForNode)
hideHighlight();
- if (m_frontend) {
- if (enabled)
- m_frontend->searchingForNodeWasEnabled();
- else
- m_frontend->searchingForNodeWasDisabled();
- }
+ updateInspectorStateCookie();
+}
+
+void InspectorController::setSearchingForNode(bool enabled, bool* newState)
+{
+ *newState = enabled;
+ setSearchingForNode(enabled);
}
void InspectorController::setMonitoringXHREnabled(bool enabled, bool* newState)
@@ -650,10 +656,6 @@ void InspectorController::populateScriptObjects()
showPanel(m_showAfterVisible);
- if (m_searchingForNode)
- m_frontend->searchingForNodeWasEnabled();
-
-
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (m_profilerAgent->enabled())
m_frontend->profilerWasEnabled();
@@ -674,10 +676,6 @@ void InspectorController::populateScriptObjects()
for (unsigned i = 0; i < messageCount; ++i)
m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (debuggerEnabled())
- m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
-#endif
#if ENABLE(DATABASE)
DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
@@ -790,6 +788,8 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (m_debuggerAgent)
m_debuggerAgent->clearForPageNavigation();
+
+ m_XHRBreakpoints.clear();
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
m_profilerAgent->resetState();
@@ -1672,6 +1672,29 @@ void InspectorController::resume()
m_debuggerAgent->resume();
}
+void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId)
+{
+ *breakpointId = 0;
+ String type;
+ if (!breakpoint->getString("type", &type))
+ return;
+ if (type == "XHR") {
+ RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
+ if (!condition)
+ return;
+ String url;
+ if (!condition->getString("url", &url))
+ return;
+ *breakpointId = ++m_lastBreakpointId;
+ m_XHRBreakpoints.set(*breakpointId, url);
+ }
+}
+
+void InspectorController::removeNativeBreakpoint(unsigned int breakpointId)
+{
+ m_XHRBreakpoints.remove(breakpointId);
+}
+
#endif
void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
@@ -2085,9 +2108,9 @@ void InspectorController::willInsertDOMNodeImpl(Node* node, Node* parent)
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (!m_debuggerAgent || !m_domAgent)
return;
- PassRefPtr<InspectorValue> details;
- if (m_domAgent->shouldBreakOnNodeInsertion(node, parent, &details))
- m_debuggerAgent->breakProgram(details);
+ PassRefPtr<InspectorValue> eventData;
+ if (m_domAgent->shouldBreakOnNodeInsertion(node, parent, &eventData))
+ m_debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
#endif
}
@@ -2102,9 +2125,9 @@ void InspectorController::willRemoveDOMNodeImpl(Node* node)
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (!m_debuggerAgent || !m_domAgent)
return;
- PassRefPtr<InspectorValue> details;
- if (m_domAgent->shouldBreakOnNodeRemoval(node, &details))
- m_debuggerAgent->breakProgram(details);
+ PassRefPtr<InspectorValue> eventData;
+ if (m_domAgent->shouldBreakOnNodeRemoval(node, &eventData))
+ m_debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
#endif
}
@@ -2119,9 +2142,9 @@ void InspectorController::willModifyDOMAttrImpl(Element* element)
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (!m_debuggerAgent || !m_domAgent)
return;
- PassRefPtr<InspectorValue> details;
- if (m_domAgent->shouldBreakOnAttributeModification(element, &details))
- m_debuggerAgent->breakProgram(details);
+ PassRefPtr<InspectorValue> eventData;
+ if (m_domAgent->shouldBreakOnAttributeModification(element, &eventData))
+ m_debuggerAgent->breakProgram(DOMBreakpointDebuggerEventType, eventData);
#endif
}
@@ -2131,6 +2154,31 @@ void InspectorController::didModifyDOMAttrImpl(Element* element)
m_domAgent->didModifyDOMAttr(element);
}
+void InspectorController::characterDataModifiedImpl(CharacterData* characterData)
+{
+ if (m_domAgent)
+ m_domAgent->characterDataModified(characterData);
+}
+
+void InspectorController::instrumentWillSendXMLHttpRequestImpl(const KURL& url)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (m_debuggerAgent) {
+ if (!m_XHRBreakpoints.size())
+ return;
+ for (HashMap<unsigned int, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) {
+ if (!url.string().contains(it->second))
+ continue;
+ RefPtr<InspectorObject> eventData = InspectorObject::create();
+ eventData->setString("type", "XHR");
+ eventData->setString("url", url);
+ m_debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData);
+ break;
+ }
+ }
+#endif
+}
+
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index 6752044..9e63f01 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -29,6 +29,7 @@
#ifndef InspectorController_h
#define InspectorController_h
+#include "CharacterData.h"
#include "Console.h"
#include "Cookie.h"
#include "Element.h"
@@ -45,6 +46,7 @@
namespace WebCore {
class CachedResource;
+class CharacterData;
class ConsoleMessage;
class Database;
class Document;
@@ -201,6 +203,9 @@ public:
static void willRemoveDOMNode(Node*);
static void willModifyDOMAttr(Element*);
static void didModifyDOMAttr(Element*);
+ static void characterDataModified(CharacterData*);
+
+ static void instrumentWillSendXMLHttpRequest(ScriptExecutionContext*, const KURL&);
#if ENABLE(WORKERS)
enum WorkerAction { WorkerCreated, WorkerDestroyed };
@@ -264,6 +269,10 @@ public:
bool debuggerEnabled() const { return m_debuggerAgent; }
InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); }
void resume();
+
+ void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, unsigned int* breakpointId);
+ void removeNativeBreakpoint(unsigned int breakpointId);
+
#endif
void evaluateForTestInFrontend(long testCallId, const String& script);
@@ -288,11 +297,10 @@ private:
void restoreDebugger();
void restoreProfiler();
void unbindAllResources();
+ void setSearchingForNode(bool enabled);
// Following are used from InspectorBackend and internally.
- void setSearchingForNode(bool enabled);
- void enableSearchingForNode() { setSearchingForNode(true); }
- void disableSearchingForNode() { setSearchingForNode(false); }
+ void setSearchingForNode(bool enabled, bool* newState);
void setMonitoringXHREnabled(bool enabled, bool* newState);
void storeLastActivePanel(const String& panelName);
@@ -331,13 +339,19 @@ private:
void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
+ static InspectorController* inspectorControllerForScriptExecutionContext(ScriptExecutionContext* context);
static InspectorController* inspectorControllerForNode(Node*);
+ static InspectorController* inspectorControllerForDocument(Document* document);
+
void willInsertDOMNodeImpl(Node* node, Node* parent);
void didInsertDOMNodeImpl(Node*);
void willRemoveDOMNodeImpl(Node*);
void didRemoveDOMNodeImpl(Node*);
void willModifyDOMAttrImpl(Element*);
void didModifyDOMAttrImpl(Element*);
+ void characterDataModifiedImpl(CharacterData*);
+
+ void instrumentWillSendXMLHttpRequestImpl(const KURL&);
#if ENABLE(JAVASCRIPT_DEBUGGER)
friend class InspectorDebuggerAgent;
@@ -346,6 +360,8 @@ private:
void saveBreakpoints(PassRefPtr<InspectorObject> breakpoints);
#endif
+ static unsigned s_inspectorControllerCount;
+
Page* m_inspectedPage;
InspectorClient* m_client;
OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
@@ -400,6 +416,9 @@ private:
bool m_attachDebuggerWhenShown;
OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
+ HashMap<unsigned int, String> m_XHRBreakpoints;
+ unsigned int m_lastBreakpointId;
+
OwnPtr<InspectorProfilerAgent> m_profilerAgent;
#endif
#if ENABLE(WORKERS)
@@ -451,18 +470,48 @@ inline void InspectorController::didModifyDOMAttr(Element* element)
#endif
}
-inline InspectorController* InspectorController::inspectorControllerForNode(Node* node)
+inline void InspectorController::characterDataModified(CharacterData* characterData)
{
#if ENABLE(INSPECTOR)
- if (Page* page = node->document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController()) {
- if (inspectorController->hasFrontend())
- return inspectorController;
- }
- }
+ if (InspectorController* inspectorController = inspectorControllerForNode(characterData))
+ inspectorController->characterDataModifiedImpl(characterData);
#endif
+}
- return 0;
+inline void InspectorController::instrumentWillSendXMLHttpRequest(ScriptExecutionContext* context, const KURL& url)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForScriptExecutionContext(context))
+ inspectorController->instrumentWillSendXMLHttpRequestImpl(url);
+#endif
+}
+
+inline InspectorController* InspectorController::inspectorControllerForScriptExecutionContext(ScriptExecutionContext* context)
+{
+ if (!s_inspectorControllerCount || !context || !context->isDocument())
+ return 0;
+ return inspectorControllerForDocument(static_cast<Document*>(context));
+}
+
+inline InspectorController* InspectorController::inspectorControllerForNode(Node* node)
+{
+ if (!s_inspectorControllerCount)
+ return 0;
+ return inspectorControllerForDocument(node->document());
+}
+
+inline InspectorController* InspectorController::inspectorControllerForDocument(Document* document)
+{
+ ASSERT(document);
+ Page* page = document->page();
+ if (!page)
+ return 0;
+ InspectorController* inspectorController = page->inspectorController();
+ if (!inspectorController)
+ return 0;
+ if (!inspectorController->hasFrontend())
+ return 0;
+ return inspectorController;
}
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index f1df5b0..f51da73 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -43,6 +43,7 @@
#include "CSSStyleRule.h"
#include "CSSStyleSelector.h"
#include "CSSStyleSheet.h"
+#include "CharacterData.h"
#include "ContainerNode.h"
#include "Cookie.h"
#include "CookieJar.h"
@@ -1120,6 +1121,14 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element)
m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element));
}
+void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
+{
+ long id = m_documentNodeToIdMap.get(characterData);
+ if (!id)
+ return;
+ m_frontend->characterDataModified(id, characterData->data());
+}
+
bool InspectorDOMAgent::hasBreakpoint(Node* node, long type)
{
uint32_t rootBit = 1 << type;
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index 7d86997..89c6fd0 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -53,6 +53,7 @@ namespace WebCore {
class CSSStyleDeclaration;
class CSSStyleRule;
class CSSStyleSheet;
+ class CharacterData;
class Element;
class Event;
class InspectorDOMAgent;
@@ -139,6 +140,7 @@ namespace WebCore {
void didInsertDOMNode(Node*);
void didRemoveDOMNode(Node*);
void didModifyDOMAttr(Element*);
+ void characterDataModified(CharacterData*);
Node* nodeForId(long nodeId);
long pushNodePathToFrontend(Node* node);
diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp
index 3875be0..4964c09 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -64,7 +64,6 @@ InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorCon
, m_frontend(frontend)
, m_pausedScriptState(0)
, m_breakpointsLoaded(false)
- , m_breakProgramReason(InspectorValue::null())
{
}
@@ -173,10 +172,15 @@ void InspectorDebuggerAgent::stepOutOfFunction()
ScriptDebugServer::shared().stepOutOfFunction();
}
-void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState)
+void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState, long* newState)
{
ScriptDebugServer::shared().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState));
- m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
+ *newState = ScriptDebugServer::shared().pauseOnExceptionsState();
+}
+
+long InspectorDebuggerAgent::pauseOnExceptionsState()
+{
+ return ScriptDebugServer::shared().pauseOnExceptionsState();
}
void InspectorDebuggerAgent::clearForPageNavigation()
@@ -289,12 +293,13 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
{
ASSERT(scriptState && !m_pausedScriptState);
- ASSERT(m_breakProgramReason);
m_pausedScriptState = scriptState;
- RefPtr<InspectorObject> details = InspectorObject::create();
- details->setValue("callFrames", currentCallFrames());
- details->setValue("status", m_breakProgramReason);
- m_frontend->pausedScript(details);
+
+ if (!m_breakProgramDetails)
+ m_breakProgramDetails = InspectorObject::create();
+ m_breakProgramDetails->setValue("callFrames", currentCallFrames());
+
+ m_frontend->pausedScript(m_breakProgramDetails);
}
void InspectorDebuggerAgent::didContinue()
@@ -303,17 +308,19 @@ void InspectorDebuggerAgent::didContinue()
m_frontend->resumedScript();
}
-void InspectorDebuggerAgent::breakProgram(PassRefPtr<InspectorValue> reason)
+void InspectorDebuggerAgent::breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data)
{
+ m_breakProgramDetails = InspectorObject::create();
+ m_breakProgramDetails->setNumber("eventType", type);
+ m_breakProgramDetails->setValue("eventData", data);
s_debuggerAgentOnBreakpoint = this;
- m_breakProgramReason = reason;
ScriptDebugServer::shared().breakProgram();
if (!s_debuggerAgentOnBreakpoint)
return;
s_debuggerAgentOnBreakpoint = 0;
- m_breakProgramReason = InspectorValue::null();
+ m_breakProgramDetails = 0;
}
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h
index 79b0a0e..8a5379d 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/WebCore/inspector/InspectorDebuggerAgent.h
@@ -43,8 +43,14 @@ namespace WebCore {
class InjectedScriptHost;
class InspectorController;
class InspectorFrontend;
+class InspectorObject;
class InspectorValue;
+enum DebuggerEventType {
+ DOMBreakpointDebuggerEventType,
+ NativeBreakpointDebuggerEventType
+};
+
class InspectorDebuggerAgent : public ScriptDebugListener, public Noncopyable {
public:
static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, InspectorFrontend*);
@@ -61,13 +67,14 @@ public:
void getScriptSource(const String& sourceID, String* scriptSource);
void pause();
- void breakProgram(PassRefPtr<InspectorValue> reason);
+ void breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data);
void resume();
void stepOverStatement();
void stepIntoStatement();
void stepOutOfFunction();
- void setPauseOnExceptionsState(long pauseState);
+ void setPauseOnExceptionsState(long pauseState, long* newState);
+ long pauseOnExceptionsState();
void clearForPageNavigation();
@@ -95,7 +102,7 @@ private:
HashMap<String, unsigned> m_breakpointsMapping;
bool m_breakpointsLoaded;
static InspectorDebuggerAgent* s_debuggerAgentOnBreakpoint;
- RefPtr<InspectorValue> m_breakProgramReason;
+ RefPtr<InspectorObject> m_breakProgramDetails;
};
} // namespace WebCore
diff --git a/WebCore/inspector/front-end/AbstractTimelinePanel.js b/WebCore/inspector/front-end/AbstractTimelinePanel.js
deleted file mode 100644
index 187ef86..0000000
--- a/WebCore/inspector/front-end/AbstractTimelinePanel.js
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.AbstractTimelinePanel = function(name)
-{
- WebInspector.Panel.call(this, name);
- this._items = [];
- this._staleItems = [];
-}
-
-WebInspector.AbstractTimelinePanel.prototype = {
- get categories()
- {
- // Should be implemented by the concrete subclasses.
- return {};
- },
-
- populateSidebar: function()
- {
- // Should be implemented by the concrete subclasses.
- },
-
- createItemTreeElement: function(item)
- {
- // Should be implemented by the concrete subclasses.
- },
-
- createItemGraph: function(item)
- {
- // Should be implemented by the concrete subclasses.
- },
-
- get items()
- {
- return this._items;
- },
-
- createInterface: function()
- {
- this.containerElement = document.createElement("div");
- this.containerElement.id = "resources-container";
- this.containerElement.addEventListener("scroll", this._updateDividersLabelBarPosition.bind(this), false);
- this.element.appendChild(this.containerElement);
-
- this.createSidebar(this.containerElement, this.element);
- this.sidebarElement.id = "resources-sidebar";
- this.populateSidebar();
-
- this._containerContentElement = document.createElement("div");
- this._containerContentElement.id = "resources-container-content";
- this.containerElement.appendChild(this._containerContentElement);
-
- this.summaryBar = new WebInspector.SummaryBar(this.categories);
- this.summaryBar.element.id = "resources-summary";
- this._containerContentElement.appendChild(this.summaryBar.element);
-
- this._timelineGrid = new WebInspector.TimelineGrid();
- this._containerContentElement.appendChild(this._timelineGrid.element);
- this.itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
- },
-
- createFilterPanel: function()
- {
- this.filterBarElement = document.createElement("div");
- this.filterBarElement.id = "resources-filter";
- this.filterBarElement.className = "scope-bar";
- this.element.appendChild(this.filterBarElement);
-
- function createFilterElement(category)
- {
- if (category === "all")
- var label = WebInspector.UIString("All");
- else if (this.categories[category])
- var label = this.categories[category].title;
-
- var categoryElement = document.createElement("li");
- categoryElement.category = category;
- categoryElement.addStyleClass(category);
- categoryElement.appendChild(document.createTextNode(label));
- categoryElement.addEventListener("click", this._updateFilter.bind(this), false);
- this.filterBarElement.appendChild(categoryElement);
-
- return categoryElement;
- }
-
- this.filterAllElement = createFilterElement.call(this, "all");
-
- // Add a divider
- var dividerElement = document.createElement("div");
- dividerElement.addStyleClass("divider");
- this.filterBarElement.appendChild(dividerElement);
-
- for (var category in this.categories)
- createFilterElement.call(this, category);
- },
-
- showCategory: function(category)
- {
- var filterClass = "filter-" + category.toLowerCase();
- this.itemsGraphsElement.addStyleClass(filterClass);
- this.itemsTreeElement.childrenListElement.addStyleClass(filterClass);
- },
-
- hideCategory: function(category)
- {
- var filterClass = "filter-" + category.toLowerCase();
- this.itemsGraphsElement.removeStyleClass(filterClass);
- this.itemsTreeElement.childrenListElement.removeStyleClass(filterClass);
- },
-
- filter: function(target, selectMultiple)
- {
- function unselectAll()
- {
- for (var i = 0; i < this.filterBarElement.childNodes.length; ++i) {
- var child = this.filterBarElement.childNodes[i];
- if (!child.category)
- continue;
-
- child.removeStyleClass("selected");
- this.hideCategory(child.category);
- }
- }
-
- if (target === this.filterAllElement) {
- if (target.hasStyleClass("selected")) {
- // We can't unselect All, so we break early here
- return;
- }
-
- // If All wasn't selected, and now is, unselect everything else.
- unselectAll.call(this);
- } else {
- // Something other than All is being selected, so we want to unselect All.
- if (this.filterAllElement.hasStyleClass("selected")) {
- this.filterAllElement.removeStyleClass("selected");
- this.hideCategory("all");
- }
- }
-
- if (!selectMultiple) {
- // If multiple selection is off, we want to unselect everything else
- // and just select ourselves.
- unselectAll.call(this);
-
- target.addStyleClass("selected");
- this.showCategory(target.category);
- return;
- }
-
- if (target.hasStyleClass("selected")) {
- // If selectMultiple is turned on, and we were selected, we just
- // want to unselect ourselves.
- target.removeStyleClass("selected");
- this.hideCategory(target.category);
- } else {
- // If selectMultiple is turned on, and we weren't selected, we just
- // want to select ourselves.
- target.addStyleClass("selected");
- this.showCategory(target.category);
- }
- },
-
- _updateFilter: function(e)
- {
- var isMac = WebInspector.isMac();
- var selectMultiple = false;
- if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
- selectMultiple = true;
- if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
- selectMultiple = true;
-
- this.filter(e.target, selectMultiple);
-
- // When we are updating our filtering, scroll to the top so we don't end up
- // in blank graph under all the resources.
- this.containerElement.scrollTop = 0;
-
- var searchField = document.getElementById("search");
- WebInspector.doPerformSearch(searchField.value, WebInspector.shortSearchWasForcedByKeyEvent, false, true);
- },
-
- updateGraphDividersIfNeeded: function(force)
- {
- if (!this.visible) {
- this.needsRefresh = true;
- return false;
- }
- return this._timelineGrid.updateDividers(force, this.calculator);
- },
-
- _updateDividersLabelBarPosition: function()
- {
- const scrollTop = this.containerElement.scrollTop;
- const offsetHeight = this.summaryBar.element.offsetHeight;
- const dividersTop = (scrollTop < offsetHeight ? offsetHeight : scrollTop);
- this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop);
- },
-
- get needsRefresh()
- {
- return this._needsRefresh;
- },
-
- set needsRefresh(x)
- {
- if (this._needsRefresh === x)
- return;
-
- this._needsRefresh = x;
-
- if (x) {
- if (this.visible && !("_refreshTimeout" in this))
- this._refreshTimeout = setTimeout(this.refresh.bind(this), 500);
- } else {
- if ("_refreshTimeout" in this) {
- clearTimeout(this._refreshTimeout);
- delete this._refreshTimeout;
- }
- }
- },
-
- refreshIfNeeded: function()
- {
- if (this.needsRefresh)
- this.refresh();
- },
-
- show: function()
- {
- WebInspector.Panel.prototype.show.call(this);
-
- this._updateDividersLabelBarPosition();
- this.refreshIfNeeded();
- },
-
- resize: function()
- {
- WebInspector.Panel.prototype.resize.call(this);
-
- this.updateGraphDividersIfNeeded();
- },
-
- updateMainViewWidth: function(width)
- {
- this._containerContentElement.style.left = width + "px";
- this.resize();
- },
-
- invalidateAllItems: function()
- {
- this._staleItems = this._items.slice();
- },
-
- refresh: function()
- {
- this.needsRefresh = false;
-
- var staleItemsLength = this._staleItems.length;
-
- var boundariesChanged = false;
-
- for (var i = 0; i < staleItemsLength; ++i) {
- var item = this._staleItems[i];
- if (!item._itemsTreeElement) {
- // Create the timeline tree element and graph.
- item._itemsTreeElement = this.createItemTreeElement(item);
- item._itemsTreeElement._itemGraph = this.createItemGraph(item);
-
- this.itemsTreeElement.appendChild(item._itemsTreeElement);
- this.itemsGraphsElement.appendChild(item._itemsTreeElement._itemGraph.graphElement);
- }
-
- if (item._itemsTreeElement.refresh)
- item._itemsTreeElement.refresh();
-
- if (this.calculator.updateBoundaries(item))
- boundariesChanged = true;
- }
-
- if (boundariesChanged) {
- // The boundaries changed, so all item graphs are stale.
- this._staleItems = this._items.slice();
- staleItemsLength = this._staleItems.length;
- }
-
-
- const isBarOpaqueAtLeft = this.sidebarTree.selectedTreeElement && this.sidebarTree.selectedTreeElement.isBarOpaqueAtLeft;
- for (var i = 0; i < staleItemsLength; ++i)
- this._staleItems[i]._itemsTreeElement._itemGraph.refresh(this.calculator, isBarOpaqueAtLeft);
-
- this._staleItems = [];
-
- this.updateGraphDividersIfNeeded();
- },
-
- reset: function()
- {
- this.containerElement.scrollTop = 0;
-
- if (this._calculator)
- this._calculator.reset();
-
- if (this._items) {
- var itemsLength = this._items.length;
- for (var i = 0; i < itemsLength; ++i) {
- var item = this._items[i];
- delete item._itemsTreeElement;
- }
- }
-
- this._items = [];
- this._staleItems = [];
-
- this.itemsTreeElement.removeChildren();
- this.itemsGraphsElement.removeChildren();
-
- this.updateGraphDividersIfNeeded(true);
- },
-
- get calculator()
- {
- return this._calculator;
- },
-
- set calculator(x)
- {
- if (!x || this._calculator === x)
- return;
-
- this._calculator = x;
- this._calculator.reset();
-
- this._staleItems = this._items.slice();
- this.refresh();
- },
-
- addItem: function(item)
- {
- this._items.push(item);
- this.refreshItem(item);
- },
-
- removeItem: function(item)
- {
- this._items.remove(item, true);
-
- if (item._itemsTreeElement) {
- this.itemsTreeElement.removeChild(item._itemsTreeElement);
- this.itemsGraphsElement.removeChild(item._itemsTreeElement._itemGraph.graphElement);
- }
-
- delete item._itemsTreeElement;
- this.adjustScrollPosition();
- },
-
- refreshItem: function(item)
- {
- this._staleItems.push(item);
- this.needsRefresh = true;
- },
-
- revealAndSelectItem: function(item)
- {
- if (item._itemsTreeElement) {
- item._itemsTreeElement.reveal();
- item._itemsTreeElement.select(true);
- }
- },
-
- sortItems: function(sortingFunction)
- {
- var sortedElements = [].concat(this.itemsTreeElement.children);
- sortedElements.sort(sortingFunction);
-
- var sortedElementsLength = sortedElements.length;
- for (var i = 0; i < sortedElementsLength; ++i) {
- var treeElement = sortedElements[i];
- if (treeElement === this.itemsTreeElement.children[i])
- continue;
-
- var wasSelected = treeElement.selected;
- this.itemsTreeElement.removeChild(treeElement);
- this.itemsTreeElement.insertChild(treeElement, i);
- if (wasSelected)
- treeElement.select(true);
-
- var graphElement = treeElement._itemGraph.graphElement;
- this.itemsGraphsElement.insertBefore(graphElement, this.itemsGraphsElement.children[i]);
- }
- },
-
- adjustScrollPosition: function()
- {
- // Prevent the container from being scrolled off the end.
- if ((this.containerElement.scrollTop + this.containerElement.offsetHeight) > this.sidebarElement.offsetHeight)
- this.containerElement.scrollTop = (this.sidebarElement.offsetHeight - this.containerElement.offsetHeight);
- },
-
- addEventDivider: function(divider)
- {
- this._timelineGrid.addEventDivider(divider);
- },
-
- hideEventDividers: function()
- {
- this._timelineGrid.hideEventDividers();
- },
-
- showEventDividers: function()
- {
- this._timelineGrid.showEventDividers();
- }
-}
-
-WebInspector.AbstractTimelinePanel.prototype.__proto__ = WebInspector.Panel.prototype;
-
-WebInspector.AbstractTimelineCalculator = function()
-{
-}
-
-WebInspector.AbstractTimelineCalculator.prototype = {
- computeSummaryValues: function(items)
- {
- var total = 0;
- var categoryValues = {};
-
- var itemsLength = items.length;
- for (var i = 0; i < itemsLength; ++i) {
- var item = items[i];
- var value = this._value(item);
- if (typeof value === "undefined")
- continue;
- if (!(item.category.name in categoryValues))
- categoryValues[item.category.name] = 0;
- categoryValues[item.category.name] += value;
- total += value;
- }
-
- return {categoryValues: categoryValues, total: total};
- },
-
- computeBarGraphPercentages: function(item)
- {
- return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan) * 100};
- },
-
- computeBarGraphLabels: function(item)
- {
- const label = this.formatValue(this._value(item));
- return {left: label, right: label, tooltip: label};
- },
-
- get boundarySpan()
- {
- return this.maximumBoundary - this.minimumBoundary;
- },
-
- updateBoundaries: function(item)
- {
- this.minimumBoundary = 0;
-
- var value = this._value(item);
- if (typeof this.maximumBoundary === "undefined" || value > this.maximumBoundary) {
- this.maximumBoundary = value;
- return true;
- }
- return false;
- },
-
- reset: function()
- {
- delete this.minimumBoundary;
- delete this.maximumBoundary;
- },
-
- _value: function(item)
- {
- return 0;
- },
-
- formatValue: function(value)
- {
- return value.toString();
- }
-}
-
-WebInspector.AbstractTimelineCategory = function(name, title, color)
-{
- this.name = name;
- this.title = title;
- this.color = color;
-}
-
-WebInspector.AbstractTimelineCategory.prototype = {
- toString: function()
- {
- return this.title;
- }
-}
diff --git a/WebCore/inspector/front-end/AuditLauncherView.js b/WebCore/inspector/front-end/AuditLauncherView.js
index 18daee6..a922715 100644
--- a/WebCore/inspector/front-end/AuditLauncherView.js
+++ b/WebCore/inspector/front-end/AuditLauncherView.js
@@ -190,7 +190,8 @@ WebInspector.AuditLauncherView.prototype = {
var element = document.createElement("input");
element.type = "checkbox";
- element.addEventListener("click", this._boundCategoryClickListener, false);
+ if (id !== "")
+ element.addEventListener("click", this._boundCategoryClickListener, false);
labelElement.appendChild(element);
labelElement.appendChild(document.createTextNode(title));
diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js
index 8518618..ec4e7cf 100644
--- a/WebCore/inspector/front-end/BreakpointManager.js
+++ b/WebCore/inspector/front-end/BreakpointManager.js
@@ -27,6 +27,7 @@
WebInspector.BreakpointManager = function()
{
this._breakpoints = {};
+ this._xhrBreakpoints = {};
}
WebInspector.BreakpointManager.prototype = {
@@ -124,6 +125,22 @@ WebInspector.BreakpointManager.prototype = {
}
}
InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this));
+ },
+
+ createXHRBreakpoint: function(url)
+ {
+ if (url in this._xhrBreakpoints)
+ return;
+ this._xhrBreakpoints[url] = true;
+
+ var breakpoint = new WebInspector.XHRBreakpoint(url);
+ breakpoint.addEventListener("removed", this._xhrBreakpointRemoved.bind(this));
+ this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint);
+ },
+
+ _xhrBreakpointRemoved: function(event)
+ {
+ delete this._xhrBreakpoints[event.target.url];
}
}
@@ -189,6 +206,15 @@ WebInspector.Breakpoint.prototype = {
this.dispatchEventToListeners("condition-changed");
},
+ compareTo: function(other)
+ {
+ if (this.url != other.url)
+ return this.url < other.url ? -1 : 1;
+ if (this.line != other.line)
+ return this.line < other.line ? -1 : 1;
+ return 0;
+ },
+
remove: function()
{
InspectorBackend.removeBreakpoint(this.sourceID, this.line);
@@ -199,3 +225,83 @@ WebInspector.Breakpoint.prototype = {
}
WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.XHRBreakpoint = function(url)
+{
+ this._url = url;
+ this._locked = false;
+ this.enabled = true;
+}
+
+WebInspector.XHRBreakpoint.prototype = {
+ get enabled()
+ {
+ return "_id" in this;
+ },
+
+ set enabled(enabled)
+ {
+ if (this._locked)
+ return;
+ if (this.enabled === enabled)
+ return;
+ if (enabled)
+ this._setOnBackend();
+ else
+ this._removeFromBackend();
+ },
+
+ get url()
+ {
+ return this._url;
+ },
+
+ formatLabel: function()
+ {
+ var label = "";
+ if (!this.url.length)
+ label = WebInspector.UIString("Any XHR");
+ else
+ label = WebInspector.UIString("URL contains \"%s\"", this.url);
+ return label;
+ },
+
+ compareTo: function(other)
+ {
+ if (this.url != other.url)
+ return this.url < other.url ? -1 : 1;
+ return 0;
+ },
+
+ remove: function()
+ {
+ if (this._locked)
+ return;
+ if (this.enabled)
+ this._removeFromBackend();
+ this.dispatchEventToListeners("removed");
+ },
+
+ _setOnBackend: function()
+ {
+ this._locked = true;
+ var data = { type: "XHR", condition: { url: this.url } };
+ InspectorBackend.setNativeBreakpoint(data, didSet.bind(this));
+
+ function didSet(breakpointId)
+ {
+ this._locked = false;
+ this._id = breakpointId;
+ this.dispatchEventToListeners("enable-changed");
+ }
+ },
+
+ _removeFromBackend: function()
+ {
+ InspectorBackend.removeNativeBreakpoint(this._id);
+ delete this._id;
+ this.dispatchEventToListeners("enable-changed");
+ }
+}
+
+WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 9688f3e..16ab041 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -92,6 +92,42 @@ WebInspector.BreakpointsSidebarPane.prototype = {
WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+WebInspector.XHRBreakpointsSidebarPane = function()
+{
+ WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
+
+ var addButton = document.createElement("button");
+ addButton.className = "add";
+ addButton.addEventListener("click", this._showEditBreakpointDialog.bind(this), false);
+ this.titleElement.appendChild(addButton);
+
+ this.urlInputElement = document.createElement("span");
+ this.urlInputElement.className = "breakpoint-condition editing";
+}
+
+WebInspector.XHRBreakpointsSidebarPane.prototype = {
+ _showEditBreakpointDialog: function(event)
+ {
+ event.stopPropagation();
+
+ if (this.urlInputElement.parentElement)
+ return;
+
+ this.urlInputElement.textContent = "";
+ this.bodyElement.insertBefore(this.urlInputElement, this.bodyElement.firstChild);
+ WebInspector.startEditing(this.urlInputElement, this._hideEditBreakpointDialog.bind(this, false), this._hideEditBreakpointDialog.bind(this, true));
+ },
+
+ _hideEditBreakpointDialog: function(discard)
+ {
+ if (!discard)
+ WebInspector.breakpointManager.createXHRBreakpoint(this.urlInputElement.textContent.toLowerCase());
+ this.bodyElement.removeChild(this.urlInputElement);
+ }
+}
+
+WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.BreakpointsSidebarPane.prototype;
+
WebInspector.BreakpointItem = function(breakpoint)
{
this._breakpoint = breakpoint;
@@ -116,6 +152,11 @@ WebInspector.BreakpointItem.prototype = {
return this._element;
},
+ compareTo: function(other)
+ {
+ return this._breakpoint.compareTo(other._breakpoint);
+ },
+
remove: function()
{
this._breakpoint.remove();
@@ -125,7 +166,7 @@ WebInspector.BreakpointItem.prototype = {
{
this._breakpoint.enabled = !this._breakpoint.enabled;
- // without this, we'd switch to the source of the clicked breakpoint
+ // Breakpoint element may have it's own click handler.
event.stopPropagation();
},
@@ -133,6 +174,10 @@ WebInspector.BreakpointItem.prototype = {
{
var checkbox = this._element.firstChild;
checkbox.checked = this._breakpoint.enabled;
+ },
+
+ _breakpointClicked: function(event)
+ {
}
}
@@ -155,15 +200,6 @@ WebInspector.JSBreakpointItem = function(breakpoint)
}
WebInspector.JSBreakpointItem.prototype = {
- compareTo: function(other)
- {
- if (this._breakpoint.url != other._breakpoint.url)
- return this._breakpoint.url < other._breakpoint.url ? -1 : 1;
- if (this._breakpoint.line != other._breakpoint.line)
- return this._breakpoint.line < other._breakpoint.line ? -1 : 1;
- return 0;
- },
-
_breakpointClicked: function()
{
WebInspector.panels.scripts.showSourceLine(this._breakpoint.url, this._breakpoint.line);
@@ -191,13 +227,6 @@ WebInspector.DOMBreakpointItem = function(breakpoint)
}
WebInspector.DOMBreakpointItem.prototype = {
- compareTo: function(other)
- {
- if (this._breakpoint.type != other._breakpoint.type)
- return this._breakpoint.type < other._breakpoint.type ? -1 : 1;
- return 0;
- },
-
_breakpointClicked: function()
{
WebInspector.updateFocusedNode(this._breakpoint.nodeId);
@@ -205,3 +234,13 @@ WebInspector.DOMBreakpointItem.prototype = {
}
WebInspector.DOMBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
+
+WebInspector.XHRBreakpointItem = function(breakpoint)
+{
+ WebInspector.BreakpointItem.call(this, breakpoint);
+
+ var label = document.createTextNode(this._breakpoint.formatLabel());
+ this._element.appendChild(label);
+}
+
+WebInspector.XHRBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype;
diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js
index 91f35a6..6212ea1 100644
--- a/WebCore/inspector/front-end/CallStackSidebarPane.js
+++ b/WebCore/inspector/front-end/CallStackSidebarPane.js
@@ -28,6 +28,11 @@ WebInspector.CallStackSidebarPane = function()
WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
}
+WebInspector.CallStackSidebarPane.DebuggerEventType = {
+ DOMBreakpoint: 0,
+ NativeBreakpoint: 1
+};
+
WebInspector.CallStackSidebarPane.prototype = {
update: function(callFrames, sourceIDMap)
{
@@ -82,36 +87,41 @@ WebInspector.CallStackSidebarPane.prototype = {
}
},
- updateStatus: function(status)
+ updateStatus: function(eventType, eventData)
{
var statusElement = document.createElement("div");
- statusElement.className = "info";
-
- var breakpointType = status.breakpoint.type;
- var substitutions = [WebInspector.DOMBreakpoint.labelForType(breakpointType), WebInspector.panels.elements.linkifyNodeById(status.breakpoint.nodeId)];
- var formatters = {
- s: function(substitution)
+ if (eventType === WebInspector.CallStackSidebarPane.DebuggerEventType.DOMBreakpoint) {
+ var breakpoint = eventData.breakpoint;
+ var substitutions = [WebInspector.DOMBreakpoint.labelForType(breakpoint.type), WebInspector.panels.elements.linkifyNodeById(breakpoint.nodeId)];
+ var formatters = {
+ s: function(substitution)
+ {
+ return substitution;
+ }
+ };
+ function append(a, b)
{
- return substitution;
+ if (typeof b === "string")
+ b = document.createTextNode(b);
+ statusElement.appendChild(b);
}
- };
- function append(a, b)
- {
- if (typeof b === "string")
- b = document.createTextNode(b);
- statusElement.appendChild(b);
- }
- if (breakpointType === WebInspector.DOMBreakpoint.Types.SubtreeModified) {
- var targetNode = WebInspector.panels.elements.linkifyNodeById(status.targetNodeId);
- if (status.insertion) {
- if (status.targetNodeId !== status.breakpoint.nodeId)
- WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append);
- else
- WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append);
+ if (breakpoint.type === WebInspector.DOMBreakpoint.Types.SubtreeModified) {
+ var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId);
+ if (eventData.insertion) {
+ if (eventData.targetNodeId !== breakpoint.nodeId)
+ WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", substitutions.concat(targetNode), formatters, "", append);
+ else
+ WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.", substitutions, formatters, "", append);
+ } else
+ WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append);
} else
- WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", substitutions.concat(targetNode), formatters, "", append);
- } else
- WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
+ WebInspector.formatLocalized("Paused on a \"%s\" breakpoint set on %s.", substitutions, formatters, "", append);
+ } else if (eventType === WebInspector.CallStackSidebarPane.DebuggerEventType.NativeBreakpoint && eventData.type === "XHR")
+ statusElement.appendChild(document.createTextNode(WebInspector.UIString("Paused on XMLHttpRequest.")));
+ else
+ return;
+
+ statusElement.className = "info";
this.bodyElement.appendChild(statusElement);
},
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 9b386c3..279852e 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -98,13 +98,7 @@ WebInspector.DOMNode.prototype = {
set nodeValue(value) {
if (this.nodeType != Node.TEXT_NODE)
return;
- var self = this;
- var callback = function()
- {
- self._nodeValue = value;
- self.textContent = value;
- };
- this.ownerDocument._domAgent.setTextNodeValueAsync(this, value, callback);
+ this.ownerDocument._domAgent.setTextNodeValueAsync(this, value, function() {});
},
getAttribute: function(name)
@@ -384,6 +378,15 @@ WebInspector.DOMAgent.prototype = {
this.document._fireDomEvent("DOMAttrModified", event);
},
+ _characterDataModified: function(nodeId, newValue)
+ {
+ var node = this._idToDOMNode[nodeId];
+ node._nodeValue = newValue;
+ node.textContent = newValue;
+ var event = { target : node };
+ this.document._fireDomEvent("DOMCharacterDataModified", event);
+ },
+
nodeForId: function(nodeId)
{
return this._idToDOMNode[nodeId];
@@ -691,6 +694,11 @@ WebInspector.attributesUpdated = function()
this.domAgent._attributesUpdated.apply(this.domAgent, arguments);
}
+WebInspector.characterDataModified = function()
+{
+ this.domAgent._characterDataModified.apply(this.domAgent, arguments);
+}
+
WebInspector.setDocument = function()
{
this.domAgent._setDocument.apply(this.domAgent, arguments);
@@ -866,6 +874,13 @@ WebInspector.DOMBreakpoint.prototype = {
this.dispatchEventToListeners("enable-changed");
},
+ compareTo: function(other)
+ {
+ if (this.type != other.type)
+ return this.type < other.type ? -1 : 1;
+ return 0;
+ },
+
remove: function()
{
if (this.enabled)
diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js
index 1ecc4f2..f68fe48 100644
--- a/WebCore/inspector/front-end/DataGrid.js
+++ b/WebCore/inspector/front-end/DataGrid.js
@@ -92,10 +92,8 @@ WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
cell.addStyleClass("sortable");
}
- if (column.aligned) {
- cell.addStyleClass(column.aligned);
+ if (column.aligned)
this.aligned[columnIdentifier] = column.aligned;
- }
headerRow.appendChild(cell);
@@ -412,6 +410,7 @@ WebInspector.DataGrid.prototype = {
resizer.style.left = left + "px";
}
+ this.dispatchEventToListeners("width changed");
},
addCreationNode: function(hasChildren)
@@ -535,6 +534,35 @@ WebInspector.DataGrid.prototype = {
this.children = [];
},
+ sortNodes: function(comparator, descending)
+ {
+ function comparatorWrapper(a, b)
+ {
+ var aDataGirdNode = a._dataGridNode;
+ var bDataGirdNode = b._dataGridNode;
+ if (!aDataGirdNode)
+ return 1; // Filler row.
+ if (!bDataGirdNode)
+ return -1; // Filler row.
+ return descending ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode);
+ }
+
+ var tbody = this.dataTableBody;
+ var tbodyParent = tbody.parentElement;
+ tbodyParent.removeChild(tbody);
+
+ var childNodes = tbody.childNodes;
+ var sortedNodes = Array.prototype.slice.call(childNodes);
+ sortedNodes.sort(comparatorWrapper.bind(this));
+
+ var sortedNodesLength = sortedNodes.length;
+ tbody.removeChildren();
+ for (var i = 0; i < sortedNodesLength; ++i) {
+ var node = sortedNodes[i];
+ tbody.appendChild(node);
+ }
+ tbodyParent.appendChild(tbody);
+ },
_keyDown: function(event)
{
@@ -772,12 +800,14 @@ WebInspector.DataGrid.prototype = {
this._dataTableColumnGroup.children[resizer.rightNeighboringColumnID].style.width = percentRightColumn;
event.preventDefault();
+ this.dispatchEventToListeners("width changed");
},
_endResizerDragging: function(event)
{
WebInspector.elementDragEnd(event);
this.currentResizer = null;
+ this.dispatchEventToListeners("width changed");
},
ColumnResizePadding: 10,
@@ -825,12 +855,16 @@ WebInspector.DataGridNode.prototype = {
if (this.revealed)
this._element.addStyleClass("revealed");
+ this.createCells();
+ return this._element;
+ },
+
+ createCells: function()
+ {
for (var columnIdentifier in this.dataGrid.columns) {
var cell = this.createCell(columnIdentifier);
this._element.appendChild(cell);
}
-
- return this._element;
},
get data()
@@ -964,11 +998,7 @@ WebInspector.DataGridNode.prototype = {
return;
this._element.removeChildren();
-
- for (var columnIdentifier in this.dataGrid.columns) {
- var cell = this.createCell(columnIdentifier);
- this._element.appendChild(cell);
- }
+ this.createCells();
},
createCell: function(columnIdentifier)
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 72b23e1..d6437fc 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -74,7 +74,7 @@ WebInspector.ElementsPanel = function()
this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle);
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
- if (Preferences.domBreakpointsEnabled)
+ if (Preferences.nativeInstrumentationEnabled)
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane();
@@ -148,7 +148,7 @@ WebInspector.ElementsPanel.prototype = {
WebInspector.Panel.prototype.hide.call(this);
WebInspector.highlightDOMNode(0);
- InspectorBackend.disableSearchingForNode();
+ this.setSearchingForNode(false);
},
resize: function()
@@ -171,7 +171,7 @@ WebInspector.ElementsPanel.prototype = {
delete this.currentQuery;
- if (Preferences.domBreakpointsEnabled)
+ if (Preferences.nativeInstrumentationEnabled)
this.sidebarPanes.domBreakpoints.reset();
},
@@ -186,6 +186,7 @@ WebInspector.ElementsPanel.prototype = {
inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInserted.bind(this));
inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemoved.bind(this));
inspectedRootDocument.addEventListener("DOMAttrModified", this._attributesUpdated.bind(this));
+ inspectedRootDocument.addEventListener("DOMCharacterDataModified", this._characterDataModified.bind(this));
this.rootDOMNode = inspectedRootDocument;
@@ -247,16 +248,6 @@ WebInspector.ElementsPanel.prototype = {
InspectorBackend.performSearch(whitespaceTrimmedQuery, false);
},
- searchingForNodeWasEnabled: function()
- {
- this._nodeSearchButton.toggled = true;
- },
-
- searchingForNodeWasDisabled: function()
- {
- this._nodeSearchButton.toggled = false;
- },
-
populateHrefContextMenu: function(contextMenu, event, anchorElement)
{
if (!anchorElement.href)
@@ -491,6 +482,13 @@ WebInspector.ElementsPanel.prototype = {
this._updateModifiedNodesSoon();
},
+ _characterDataModified: function(event)
+ {
+ this.recentlyModifiedNodes.push({node: event.target, updated: true});
+ if (this.visible)
+ this._updateModifiedNodesSoon();
+ },
+
_nodeInserted: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, parent: event.relatedNode, inserted: true});
@@ -1152,12 +1150,29 @@ WebInspector.ElementsPanel.prototype = {
this.treeOutline.updateSelection();
},
+ updateFocusedNode: function(nodeId)
+ {
+ var node = WebInspector.domAgent.nodeForId(nodeId);
+ if (!node)
+ return;
+
+ this.focusedDOMNode = node;
+ this._nodeSearchButton.toggled = false;
+ },
+
+ _setSearchingForNode: function(enabled)
+ {
+ this._nodeSearchButton.toggled = enabled;
+ },
+
+ setSearchingForNode: function(enabled)
+ {
+ InspectorBackend.setSearchingForNode(enabled, this._setSearchingForNode.bind(this));
+ },
+
toggleSearchingForNode: function()
{
- if (!this._nodeSearchButton.toggled)
- InspectorBackend.enableSearchingForNode();
- else
- InspectorBackend.disableSearchingForNode();
+ this.setSearchingForNode(!this._nodeSearchButton.toggled);
},
elementsToRestoreScrollPositionsFor: function()
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index e261234..1479c9a 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -637,10 +637,12 @@ WebInspector.ElementsTreeElement.prototype = {
this.listItemElement.scrollIntoViewIfNeeded(false);
},
- onselect: function()
+ onselect: function(treeElement, selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.focusedDOMNode = this.representedObject;
+ if (selectedByUser)
+ WebInspector.highlightDOMNode(this.representedObject.id);
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
},
@@ -752,7 +754,7 @@ WebInspector.ElementsTreeElement.prototype = {
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this));
- if (Preferences.domBreakpointsEnabled) {
+ if (Preferences.nativeInstrumentationEnabled) {
// Add debbuging-related actions
contextMenu.appendSeparator();
@@ -1125,7 +1127,7 @@ WebInspector.ElementsTreeElement.prototype = {
delete this._editing;
var textNode;
- if (this.representedObject.nodeType == Node.ELEMENT_NODE) {
+ if (this.representedObject.nodeType === Node.ELEMENT_NODE) {
// We only show text nodes inline in elements if the element only
// has a single child, and that child is a text node.
textNode = this.representedObject.firstChild;
@@ -1133,9 +1135,6 @@ WebInspector.ElementsTreeElement.prototype = {
textNode = this.representedObject;
textNode.nodeValue = newText;
-
- // Need to restore attributes / node structure.
- this.updateTitle();
},
_editingCancelled: function(element, context)
diff --git a/WebCore/inspector/front-end/GoToLineDialog.js b/WebCore/inspector/front-end/GoToLineDialog.js
new file mode 100644
index 0000000..c96344c
--- /dev/null
+++ b/WebCore/inspector/front-end/GoToLineDialog.js
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 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.GoToLineDialog = function(view)
+{
+ this._element = document.createElement("div");
+ this._element.className = "go-to-line-dialog";
+ this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
+ this._closeKeys = [
+ WebInspector.KeyboardShortcut.Keys.Enter.code,
+ WebInspector.KeyboardShortcut.Keys.Esc.code,
+ ];
+
+ var dialogWindow = this._element;
+
+ dialogWindow.createChild("label").innerText = WebInspector.UIString("Go to line: ");
+
+ this._input = dialogWindow.createChild("input");
+ this._input.setAttribute("type", "text");
+ this._input.setAttribute("size", 6);
+ var linesCount = view.sourceFrame.textModel.linesCount;
+ if (linesCount)
+ this._input.setAttribute("title", WebInspector.UIString("1 - %d", linesCount));
+ var blurHandler = this._onBlur.bind(this);
+ this._input.addEventListener("blur", blurHandler, false);
+
+
+ var go = dialogWindow.createChild("button");
+ go.innerText = WebInspector.UIString("Go");
+ go.addEventListener("click", this._onClick.bind(this), false);
+ go.addEventListener("mousedown", function(e) {
+ // Ok button click will close the dialog, removing onBlur listener
+ // to let click event be handled.
+ this._input.removeEventListener("blur", blurHandler, false);
+ }.bind(this), false);
+
+ this._view = view;
+ view.element.appendChild(this._element);
+
+ this._previousFocusElement = WebInspector.currentFocusElement;
+ WebInspector.currentFocusElement = this._input;
+ this._input.select();
+}
+
+WebInspector.GoToLineDialog.show = function(sourceView)
+{
+ if (this._instance)
+ return;
+ this._instance = new WebInspector.GoToLineDialog(sourceView);
+}
+
+WebInspector.GoToLineDialog.prototype = {
+ _hide: function()
+ {
+ if (this._isHiding)
+ return;
+ this._isHiding = true;
+
+ WebInspector.currentFocusElement = this._previousFocusElement;
+ WebInspector.GoToLineDialog._instance = null;
+ this._element.parentElement.removeChild(this._element);
+ },
+
+ _onBlur: function(event)
+ {
+ this._hide();
+ },
+
+ _onKeyDown: function(event)
+ {
+ if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
+ event.preventDefault();
+ return;
+ }
+
+ if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
+ this._highlightSelectedLine();
+
+ if (this._closeKeys.indexOf(event.keyCode) >= 0) {
+ this._hide();
+ event.stopPropagation();
+ }
+ },
+
+ _onClick: function(event)
+ {
+ this._highlightSelectedLine();
+ this._hide();
+ },
+
+ _highlightSelectedLine: function()
+ {
+ var value = this._input.value;
+ var lineNumber = parseInt(value, 10);
+ if (!isNaN(lineNumber) && lineNumber > 0) {
+ lineNumber = Math.min(lineNumber, this._view.sourceFrame.textModel.linesCount);
+ this._view.highlightLine(lineNumber);
+ }
+ }
+};
diff --git a/WebCore/inspector/front-end/Images/networkIcon.png b/WebCore/inspector/front-end/Images/networkIcon.png
new file mode 100644
index 0000000..982424d
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/networkIcon.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/paneAddButtons.png b/WebCore/inspector/front-end/Images/paneAddButtons.png
new file mode 100644
index 0000000..f1c0047
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/paneAddButtons.png
Binary files differ
diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js
new file mode 100644
index 0000000..f07b3b0
--- /dev/null
+++ b/WebCore/inspector/front-end/NetworkPanel.js
@@ -0,0 +1,1414 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
+ * 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:
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.NetworkPanel = function()
+{
+ WebInspector.Panel.call(this, "network");
+
+ this._resources = [];
+ this._staleResources = [];
+ this._resourceGridNodes = {};
+ this._mainResourceLoadTime = -1;
+ this._mainResourceDOMContentTime = -1;
+
+ this._viewsContainerElement = document.createElement("div");
+ this._viewsContainerElement.id = "network-views";
+ this.element.appendChild(this._viewsContainerElement);
+
+ this._createSortingFunctions();
+ this._createTimelineGrid();
+ this._createTable();
+ this._createStatusbarButtons();
+
+ this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true);
+
+ this.calculator = new WebInspector.NetworkTransferTimeCalculator();
+ this.filter(this.filterAllElement, false);
+}
+
+WebInspector.NetworkPanel.prototype = {
+ get toolbarItemLabel()
+ {
+ return WebInspector.UIString("Network");
+ },
+
+ get statusBarItems()
+ {
+ return [this._largerResourcesButton.element, this._clearButton.element];
+ },
+
+ isCategoryVisible: function(categoryName)
+ {
+ return true;
+ },
+
+ elementsToRestoreScrollPositionsFor: function()
+ {
+ return [this.containerElement];
+ },
+
+ resize: function()
+ {
+ WebInspector.Panel.prototype.resize.call(this);
+ this._dataGrid.updateWidths();
+ },
+
+ _createTimelineGrid: function()
+ {
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._timelineGrid.element.addStyleClass("network-timeline-grid");
+ this.element.appendChild(this._timelineGrid.element);
+ },
+
+ _createTable: function()
+ {
+ this.containerElement = document.createElement("div");
+ this.containerElement.id = "network-container";
+ this.element.appendChild(this.containerElement);
+
+ var columns = {url: {}, method: {}, status: {}, type: {}, size: {}, time: {}, timeline: {}};
+ columns.url.title = WebInspector.UIString("URL");
+ columns.url.sortable = true;
+ columns.url.width = "20%";
+ columns.url.disclosure = true;
+
+ columns.method.title = WebInspector.UIString("Method");
+ columns.method.sortable = true;
+ columns.method.width = "7%";
+
+ columns.status.title = WebInspector.UIString("Status");
+ columns.status.sortable = true;
+ columns.status.width = "8%";
+
+ columns.type.title = WebInspector.UIString("Type");
+ columns.type.sortable = true;
+ columns.type.width = "7%";
+
+ columns.size.title = WebInspector.UIString("Size");
+ columns.size.sortable = true;
+ columns.size.width = "10%";
+ columns.size.aligned = "right";
+
+ columns.time.title = WebInspector.UIString("Time");
+ columns.time.sortable = true;
+ columns.time.width = "10%";
+ columns.time.aligned = "right";
+
+ columns.timeline.title = "";
+ columns.timeline.sortable = true;
+ columns.timeline.width = "40%";
+ columns.timeline.sort = true;
+
+ this._dataGrid = new WebInspector.DataGrid(columns);
+ this.element.appendChild(this._dataGrid.element);
+ this._dataGrid.addEventListener("sorting changed", this._sortItems, this);
+ this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this);
+ },
+
+ _createSortingFunctions: function()
+ {
+ this._sortingFunctions = {};
+ this._sortingFunctions.url = WebInspector.NetworkDataGridNode.URLComparator;
+ this._sortingFunctions.method = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "method");
+ this._sortingFunctions.status = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "statusCode");
+ this._sortingFunctions.type = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "mimeType");
+ this._sortingFunctions.size = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "resourceSize");
+ this._sortingFunctions.time = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "duration");
+ this._sortingFunctions.timeline = WebInspector.NetworkDataGridNode.ResourcePropertyComparator.bind(null, "startTime");
+ },
+
+ filter: function(target, selectMultiple)
+ {
+ },
+
+ _updateFilter: function(e)
+ {
+ var isMac = WebInspector.isMac();
+ var selectMultiple = false;
+ if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
+ selectMultiple = true;
+ if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
+ selectMultiple = true;
+
+ this.filter(e.target, selectMultiple);
+
+ // When we are updating our filtering, scroll to the top so we don't end up
+ // in blank graph under all the resources.
+ this.containerElement.scrollTop = 0;
+
+ var searchField = document.getElementById("search");
+ WebInspector.doPerformSearch(searchField.value, WebInspector.shortSearchWasForcedByKeyEvent, false, true);
+ },
+
+ _scheduleRefresh: function()
+ {
+ if (this._needsRefresh)
+ return;
+
+ this._needsRefresh = true;
+
+ if (this.visible && !("_refreshTimeout" in this))
+ this._refreshTimeout = setTimeout(this.refresh.bind(this), 500);
+ },
+
+ _sortItems: function()
+ {
+ var columnIdentifier = this._dataGrid.sortColumnIdentifier;
+ var sortingFunction = this._sortingFunctions[columnIdentifier];
+ if (!sortingFunction)
+ return;
+ this._dataGrid.sortNodes(sortingFunction, this._dataGrid.sortOrder === "descending");
+ },
+
+ _updateDividersIfNeeded: function(force)
+ {
+ this._timelineGrid.element.style.left = this._dataGrid.resizers[this._dataGrid.resizers.length - 1].style.left;
+
+ var proceed = true;
+ if (!this.visible) {
+ this._scheduleRefresh();
+ proceed = false;
+ } else
+ proceed = this._timelineGrid.updateDividers(force, this.calculator);
+
+ if (!proceed)
+ return;
+
+ if (this.calculator.startAtZero || !this.calculator.computePercentageFromEventTime) {
+ // If our current sorting method starts at zero, that means it shows all
+ // resources starting at the same point, and so onLoad event and DOMContent
+ // event lines really wouldn't make much sense here, so don't render them.
+ // Additionally, if the calculator doesn't have the computePercentageFromEventTime
+ // function defined, we are probably sorting by size, and event times aren't relevant
+ // in this case.
+ return;
+ }
+
+ this._timelineGrid.removeEventDividers();
+ if (this._mainResourceLoadTime !== -1) {
+ var percent = this.calculator.computePercentageFromEventTime(this._mainResourceLoadTime);
+
+ var loadDivider = document.createElement("div");
+ loadDivider.className = "network-event-divider network-red-divider";
+
+ var loadDividerPadding = document.createElement("div");
+ loadDividerPadding.className = "network-event-divider-padding";
+ loadDividerPadding.title = WebInspector.UIString("Load event fired");
+ loadDividerPadding.appendChild(loadDivider);
+ loadDividerPadding.style.left = percent + "%";
+ this._timelineGrid.addEventDivider(loadDividerPadding);
+ }
+
+ if (this._mainResourceDOMContentTime !== -1) {
+ var percent = this.calculator.computePercentageFromEventTime(this._mainResourceDOMContentTime);
+
+ var domContentDivider = document.createElement("div");
+ domContentDivider.className = "network-event-divider network-blue-divider";
+
+ var domContentDividerPadding = document.createElement("div");
+ domContentDividerPadding.className = "network-event-divider-padding";
+ domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired");
+ domContentDividerPadding.appendChild(domContentDivider);
+ domContentDividerPadding.style.left = percent + "%";
+ this._timelineGrid.addEventDivider(domContentDividerPadding);
+ }
+ },
+
+ _refreshIfNeeded: function()
+ {
+ if (this._needsRefresh)
+ this.refresh();
+ },
+
+ _invalidateAllItems: function()
+ {
+ this._staleResources = this._resources.slice();
+ },
+
+ get calculator()
+ {
+ return this._calculator;
+ },
+
+ set calculator(x)
+ {
+ if (!x || this._calculator === x)
+ return;
+
+ this._calculator = x;
+ this._calculator.reset();
+
+ this._invalidateAllItems();
+ this.refresh();
+ },
+
+ _resourceGridNode: function(resource)
+ {
+ return this._resourceGridNodes[resource.identifier];
+ },
+
+ revealAndSelectItem: function(resource)
+ {
+ var node = this._resourceGridNode(resource);
+ if (node) {
+ node.reveal();
+ node.select(true);
+ }
+ },
+
+ addEventDivider: function(divider)
+ {
+ this._timelineGrid.addEventDivider(divider);
+ },
+
+ get resourceTrackingEnabled()
+ {
+ return this._resourceTrackingEnabled;
+ },
+
+ _createStatusbarButtons: function()
+ {
+ this._clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
+ 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);
+ this._largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false);
+ },
+
+ _settingsLoaded: function()
+ {
+ this._largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows;
+ if (!WebInspector.applicationSettings.resourcesLargeRows)
+ this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows);
+ },
+
+ set mainResourceLoadTime(x)
+ {
+ if (this._mainResourceLoadTime === x)
+ return;
+
+ this._mainResourceLoadTime = x || -1;
+ // Update the dividers to draw the new line
+ this._updateDividersIfNeeded(true);
+ },
+
+ set mainResourceDOMContentTime(x)
+ {
+ if (this._mainResourceDOMContentTime === x)
+ return;
+
+ this._mainResourceDOMContentTime = x || -1;
+ this._updateDividersIfNeeded(true);
+ },
+
+ show: function()
+ {
+ WebInspector.Panel.prototype.show.call(this);
+
+ this._refreshIfNeeded();
+
+ var visibleView = this.visibleView;
+ if (this.visibleResource) {
+ this.visibleView.headersVisible = true;
+ this.visibleView.show(this._viewsContainerElement);
+ } else if (visibleView)
+ visibleView.show();
+
+ // Hide any views that are visible that are not this panel's current visible view.
+ // This can happen when a ResourceView is visible in the Scripts panel then switched
+ // to the this panel.
+ var resourcesLength = this._resources.length;
+ for (var i = 0; i < resourcesLength; ++i) {
+ var resource = this._resources[i];
+ var view = resource._resourcesView;
+ if (!view || view === visibleView)
+ continue;
+ view.visible = false;
+ }
+ this._dataGrid.updateWidths();
+ },
+
+ get searchableViews()
+ {
+ var views = [];
+
+ const visibleView = this.visibleView;
+ if (visibleView && visibleView.performSearch)
+ views.push(visibleView);
+
+ var resourcesLength = this._resources.length;
+ for (var i = 0; i < resourcesLength; ++i) {
+ var resource = this._resources[i];
+ if (!this._resourceGridNode(resource) || !this._resourceGridNode(resource).selectable)
+ continue;
+ var resourceView = this.resourceViewForResource(resource);
+ if (!resourceView.performSearch || resourceView === visibleView)
+ continue;
+ views.push(resourceView);
+ }
+
+ return views;
+ },
+
+ searchMatchFound: function(view, matches)
+ {
+ this._resourceGridNode(view.resource).searchMatches = matches;
+ },
+
+ searchCanceled: function(startingNewSearch)
+ {
+ WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch);
+
+ if (startingNewSearch || !this._resources)
+ return;
+ },
+
+ performSearch: function(query)
+ {
+ WebInspector.Panel.prototype.performSearch.call(this, query);
+ },
+
+ get visibleView()
+ {
+ if (this.visibleResource)
+ return this.visibleResource._resourcesView;
+ return null;
+ },
+
+ refresh: function()
+ {
+ this._needsRefresh = false;
+ if ("_refreshTimeout" in this) {
+ clearTimeout(this._refreshTimeout);
+ delete this._refreshTimeout;
+ }
+
+ var staleItemsLength = this._staleResources.length;
+
+ var boundariesChanged = false;
+
+ for (var i = 0; i < staleItemsLength; ++i) {
+ var resource = this._staleResources[i];
+ var node = this._resourceGridNode(resource);
+ if (!node) {
+ // Create the timeline tree element and graph.
+ node = new WebInspector.NetworkDataGridNode(resource);
+ this._resourceGridNodes[resource.identifier] = node;
+ this._dataGrid.appendChild(node);
+ }
+ node.refreshResource();
+
+ if (this.calculator.updateBoundaries(resource))
+ boundariesChanged = true;
+ }
+
+ if (boundariesChanged) {
+ // The boundaries changed, so all item graphs are stale.
+ this._invalidateAllItems();
+ staleItemsLength = this._staleResources.length;
+ }
+
+ for (var i = 0; i < staleItemsLength; ++i)
+ this._resourceGridNode(this._staleResources[i]).refreshGraph(this.calculator);
+
+ this._staleResources = [];
+ this._sortItems();
+ this._dataGrid.updateWidths();
+ },
+
+ reset: function()
+ {
+ this._popoverHelper.hidePopup();
+ this.closeVisibleResource();
+
+ 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
+ this.containerElement.scrollTop = 0;
+
+ 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 = {};
+
+ this._dataGrid.removeChildren();
+ this._updateDividersIfNeeded(true);
+ // End reset timeline.
+
+ this._mainResourceLoadTime = -1;
+ this._mainResourceDOMContentTime = -1;
+
+ this._viewsContainerElement.removeChildren();
+ },
+
+ addResource: function(resource)
+ {
+ this._resources.push(resource);
+ this.refreshResource(resource);
+ },
+
+ refreshResource: function(resource)
+ {
+ this._staleResources.push(resource);
+ this._scheduleRefresh();
+ },
+
+ recreateViewForResourceIfNeeded: function(resource)
+ {
+ if (!resource || !resource._resourcesView)
+ return;
+
+ var newView = this._createResourceView(resource);
+ 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;
+
+ resource._resourcesView.detach();
+ delete resource._resourcesView;
+
+ resource._resourcesView = newView;
+
+ newView.headersVisible = oldView.headersVisible;
+
+ if (oldViewParentNode)
+ newView.show(oldViewParentNode);
+
+ WebInspector.panels.scripts.viewRecreated(oldView, newView);
+ },
+
+ canShowSourceLine: function(url, line)
+ {
+ return this._resourceTrackingEnabled && !!WebInspector.resourceForURL(url);
+ },
+
+ showSourceLine: function(url, line)
+ {
+ this.showResource(WebInspector.resourceForURL(url), line);
+ },
+
+ showResource: function(resource, line)
+ {
+ if (!resource)
+ return;
+
+ this._popoverHelper.hidePopup();
+
+ this.containerElement.addStyleClass("viewing-resource");
+
+ if (this.visibleResource && this.visibleResource._resourcesView)
+ this.visibleResource._resourcesView.hide();
+
+ var view = this.resourceViewForResource(resource);
+ view.headersVisible = true;
+ view.show(this._viewsContainerElement);
+
+ if (line) {
+ view.selectContentTab(true);
+ if (view.revealLine)
+ view.revealLine(line);
+ if (view.highlightLine)
+ view.highlightLine(line);
+ }
+
+ this.revealAndSelectItem(resource);
+
+ this.visibleResource = resource;
+
+ this.updateSidebarWidth();
+ },
+
+ showView: function(view)
+ {
+ if (!view)
+ return;
+ this.showResource(view.resource);
+ },
+
+ closeVisibleResource: function()
+ {
+ this.containerElement.removeStyleClass("viewing-resource");
+
+ if (this.visibleResource && this.visibleResource._resourcesView)
+ this.visibleResource._resourcesView.hide();
+ delete this.visibleResource;
+
+ if (this._lastSelectedGraphTreeElement)
+ this._lastSelectedGraphTreeElement.select(true);
+
+ this.updateSidebarWidth();
+ },
+
+ resourceViewForResource: function(resource)
+ {
+ if (!resource)
+ return null;
+ if (!resource._resourcesView)
+ resource._resourcesView = this._createResourceView(resource);
+ return resource._resourcesView;
+ },
+
+ sourceFrameForResource: function(resource)
+ {
+ var view = this.resourceViewForResource(resource);
+ if (!view)
+ return null;
+
+ if (!view.setupSourceFrameIfNeeded)
+ return null;
+
+ // Setting up the source frame requires that we be attached.
+ if (!this.element.parentNode)
+ this.attach();
+
+ view.setupSourceFrameIfNeeded();
+ return view.sourceFrame;
+ },
+
+ _toggleLargerResources: function()
+ {
+ WebInspector.applicationSettings.resourcesLargeRows = !WebInspector.applicationSettings.resourcesLargeRows;
+ this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows);
+ },
+
+ _setLargerResources: function(enabled)
+ {
+ this._largerResourcesButton.toggled = enabled;
+ if (!enabled) {
+ this._largerResourcesButton.title = WebInspector.UIString("Use large resource rows.");
+ this._dataGrid.element.addStyleClass("small");
+ } else {
+ this._largerResourcesButton.title = WebInspector.UIString("Use small resource rows.");
+ this._dataGrid.element.removeStyleClass("small");
+ }
+ },
+
+ _createResourceView: function(resource)
+ {
+ switch (resource.category) {
+ case WebInspector.resourceCategories.documents:
+ case WebInspector.resourceCategories.stylesheets:
+ case WebInspector.resourceCategories.scripts:
+ case WebInspector.resourceCategories.xhr:
+ return new WebInspector.SourceView(resource);
+ case WebInspector.resourceCategories.images:
+ return new WebInspector.ImageView(resource);
+ case WebInspector.resourceCategories.fonts:
+ return new WebInspector.FontView(resource);
+ default:
+ return new WebInspector.ResourceView(resource);
+ }
+ },
+
+ _getPopoverAnchor: function(element)
+ {
+ var anchor = element.enclosingNodeOrSelfWithClass("network-graph-bar") || element.enclosingNodeOrSelfWithClass("network-graph-label");
+ if (!anchor)
+ return null;
+ var resource = anchor.parentElement.resource;
+ return resource && resource.timing ? anchor : null;
+ },
+
+ _showPopover: function(anchor)
+ {
+ var tableElement = document.createElement("table");
+ var resource = anchor.parentElement.resource;
+ var rows = [];
+
+ function addRow(title, start, end, color)
+ {
+ var row = {};
+ row.title = title;
+ row.start = start;
+ row.end = end;
+ rows.push(row);
+ }
+
+ if (resource.timing.proxyStart !== -1)
+ addRow(WebInspector.UIString("Proxy"), resource.timing.proxyStart, resource.timing.proxyEnd);
+
+ if (resource.timing.dnsStart !== -1)
+ addRow(WebInspector.UIString("DNS Lookup"), resource.timing.dnsStart, resource.timing.dnsEnd);
+
+ if (resource.timing.connectStart !== -1) {
+ if (resource.connectionReused)
+ addRow(WebInspector.UIString("Blocking"), resource.timing.connectStart, resource.timing.connectEnd);
+ else {
+ var connectStart = resource.timing.connectStart;
+ // Connection includes DNS, subtract it here.
+ if (resource.timing.dnsStart !== -1)
+ connectStart += resource.timing.dnsEnd - resource.timing.dnsStart;
+ addRow(WebInspector.UIString("Connecting"), connectStart, resource.timing.connectEnd);
+ }
+ }
+
+ if (resource.timing.sslStart !== -1)
+ addRow(WebInspector.UIString("SSL"), resource.timing.sslStart, resource.timing.sslEnd);
+
+ var sendStart = resource.timing.sendStart;
+ if (resource.timing.sslStart !== -1)
+ sendStart += resource.timing.sslEnd - resource.timing.sslStart;
+
+ addRow(WebInspector.UIString("Sending"), resource.timing.sendStart, resource.timing.sendEnd);
+ addRow(WebInspector.UIString("Waiting"), resource.timing.sendEnd, resource.timing.receiveHeadersEnd);
+ addRow(WebInspector.UIString("Receiving"), (resource.responseReceivedTime - resource.timing.requestTime) * 1000, (resource.endTime - resource.timing.requestTime) * 1000);
+
+ const chartWidth = 200;
+ var total = (resource.endTime - resource.timing.requestTime) * 1000;
+ var scale = chartWidth / total;
+
+ for (var i = 0; i < rows.length; ++i) {
+ var tr = document.createElement("tr");
+ tableElement.appendChild(tr);
+
+ var td = document.createElement("td");
+ td.textContent = rows[i].title;
+ tr.appendChild(td);
+
+ td = document.createElement("td");
+ td.width = chartWidth + "px";
+
+ var row = document.createElement("div");
+ row.className = "network-timing-row";
+ td.appendChild(row);
+
+ var bar = document.createElement("span");
+ bar.className = "network-timing-bar";
+ bar.style.left = scale * rows[i].start + "px";
+ bar.style.right = scale * (total - rows[i].end) + "px";
+ bar.style.backgroundColor = rows[i].color;
+ bar.textContent = "\u200B"; // Important for 0-time items to have 0 width.
+ row.appendChild(bar);
+
+ var title = document.createElement("span");
+ title.className = "network-timing-bar-title";
+ if (total - rows[i].end < rows[i].start)
+ title.style.right = (scale * (total - rows[i].end) + 3) + "px";
+ else
+ title.style.left = (scale * rows[i].start + 3) + "px";
+ title.textContent = Number.millisToString(rows[i].end - rows[i].start);
+ row.appendChild(title);
+
+ tr.appendChild(td);
+ }
+
+ var popover = new WebInspector.Popover(tableElement);
+ popover.show(anchor);
+ return popover;
+ },
+
+ hide: function()
+ {
+ WebInspector.Panel.prototype.hide.call(this);
+ this._popoverHelper.hidePopup();
+ }
+}
+
+WebInspector.NetworkPanel.prototype.__proto__ = WebInspector.Panel.prototype;
+
+WebInspector.getResourceContent = function(identifier, callback)
+{
+ InspectorBackend.getResourceContent(identifier, callback);
+}
+
+WebInspector.NetworkBaseCalculator = function()
+{
+}
+
+WebInspector.NetworkBaseCalculator.prototype = {
+ computeSummaryValues: function(items)
+ {
+ var total = 0;
+ var categoryValues = {};
+
+ var itemsLength = items.length;
+ for (var i = 0; i < itemsLength; ++i) {
+ var item = items[i];
+ var value = this._value(item);
+ if (typeof value === "undefined")
+ continue;
+ if (!(item.category.name in categoryValues))
+ categoryValues[item.category.name] = 0;
+ categoryValues[item.category.name] += value;
+ total += value;
+ }
+
+ return {categoryValues: categoryValues, total: total};
+ },
+
+ computeBarGraphPercentages: function(item)
+ {
+ return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan) * 100};
+ },
+
+ computeBarGraphLabels: function(item)
+ {
+ const label = this.formatValue(this._value(item));
+ return {left: label, right: label, tooltip: label};
+ },
+
+ get boundarySpan()
+ {
+ return this.maximumBoundary - this.minimumBoundary;
+ },
+
+ updateBoundaries: function(item)
+ {
+ this.minimumBoundary = 0;
+
+ var value = this._value(item);
+ if (typeof this.maximumBoundary === "undefined" || value > this.maximumBoundary) {
+ this.maximumBoundary = value;
+ return true;
+ }
+ return false;
+ },
+
+ reset: function()
+ {
+ delete this.minimumBoundary;
+ delete this.maximumBoundary;
+ },
+
+ _value: function(item)
+ {
+ return 0;
+ },
+
+ formatValue: function(value)
+ {
+ return value.toString();
+ }
+}
+
+WebInspector.NetworkTimeCalculator = function(startAtZero)
+{
+ WebInspector.NetworkBaseCalculator.call(this);
+ this.startAtZero = startAtZero;
+}
+
+WebInspector.NetworkTimeCalculator.prototype = {
+ computeSummaryValues: function(resources)
+ {
+ var resourcesByCategory = {};
+ var resourcesLength = resources.length;
+ for (var i = 0; i < resourcesLength; ++i) {
+ var resource = resources[i];
+ if (!(resource.category.name in resourcesByCategory))
+ resourcesByCategory[resource.category.name] = [];
+ resourcesByCategory[resource.category.name].push(resource);
+ }
+
+ var earliestStart;
+ var latestEnd;
+ var categoryValues = {};
+ for (var category in resourcesByCategory) {
+ resourcesByCategory[category].sort(WebInspector.Resource.CompareByTime);
+ categoryValues[category] = 0;
+
+ var segment = {start: -1, end: -1};
+
+ var categoryResources = resourcesByCategory[category];
+ var resourcesLength = categoryResources.length;
+ for (var i = 0; i < resourcesLength; ++i) {
+ var resource = categoryResources[i];
+ if (resource.startTime === -1 || resource.endTime === -1)
+ continue;
+
+ if (typeof earliestStart === "undefined")
+ earliestStart = resource.startTime;
+ else
+ earliestStart = Math.min(earliestStart, resource.startTime);
+
+ if (typeof latestEnd === "undefined")
+ latestEnd = resource.endTime;
+ else
+ latestEnd = Math.max(latestEnd, resource.endTime);
+
+ if (resource.startTime <= segment.end) {
+ segment.end = Math.max(segment.end, resource.endTime);
+ continue;
+ }
+
+ categoryValues[category] += segment.end - segment.start;
+
+ segment.start = resource.startTime;
+ segment.end = resource.endTime;
+ }
+
+ // Add the last segment
+ categoryValues[category] += segment.end - segment.start;
+ }
+
+ return {categoryValues: categoryValues, total: latestEnd - earliestStart};
+ },
+
+ computeBarGraphPercentages: function(resource)
+ {
+ if (resource.startTime !== -1)
+ var start = ((resource.startTime - this.minimumBoundary) / this.boundarySpan) * 100;
+ else
+ var start = 0;
+
+ if (resource.responseReceivedTime !== -1)
+ var middle = ((resource.responseReceivedTime - this.minimumBoundary) / this.boundarySpan) * 100;
+ else
+ var middle = (this.startAtZero ? start : 100);
+
+ if (resource.endTime !== -1)
+ var end = ((resource.endTime - this.minimumBoundary) / this.boundarySpan) * 100;
+ else
+ var end = (this.startAtZero ? middle : 100);
+
+ if (this.startAtZero) {
+ end -= start;
+ middle -= start;
+ start = 0;
+ }
+
+ return {start: start, middle: middle, end: end};
+ },
+
+ computePercentageFromEventTime: function(eventTime)
+ {
+ // This function computes a percentage in terms of the total loading time
+ // of a specific event. If startAtZero is set, then this is useless, and we
+ // want to return 0.
+ if (eventTime !== -1 && !this.startAtZero)
+ return ((eventTime - this.minimumBoundary) / this.boundarySpan) * 100;
+
+ return 0;
+ },
+
+ computeBarGraphLabels: function(resource)
+ {
+ var rightLabel = "";
+ if (resource.responseReceivedTime !== -1 && resource.endTime !== -1)
+ rightLabel = this.formatValue(resource.endTime - resource.responseReceivedTime);
+
+ var hasLatency = resource.latency > 0;
+ if (hasLatency)
+ var leftLabel = this.formatValue(resource.latency);
+ else
+ var leftLabel = rightLabel;
+
+ if (resource.timing)
+ return {left: leftLabel, right: rightLabel};
+
+ if (hasLatency && rightLabel) {
+ var total = this.formatValue(resource.duration);
+ var tooltip = WebInspector.UIString("%s latency, %s download (%s total)", leftLabel, rightLabel, total);
+ } else if (hasLatency)
+ var tooltip = WebInspector.UIString("%s latency", leftLabel);
+ else if (rightLabel)
+ var tooltip = WebInspector.UIString("%s download", rightLabel);
+
+ if (resource.cached)
+ tooltip = WebInspector.UIString("%s (from cache)", tooltip);
+ return {left: leftLabel, right: rightLabel, tooltip: tooltip};
+ },
+
+ updateBoundaries: function(resource)
+ {
+ var didChange = false;
+
+ var lowerBound;
+ if (this.startAtZero)
+ lowerBound = 0;
+ else
+ lowerBound = this._lowerBound(resource);
+
+ if (lowerBound !== -1 && (typeof this.minimumBoundary === "undefined" || lowerBound < this.minimumBoundary)) {
+ this.minimumBoundary = lowerBound;
+ didChange = true;
+ }
+
+ var upperBound = this._upperBound(resource);
+ if (upperBound !== -1 && (typeof this.maximumBoundary === "undefined" || upperBound > this.maximumBoundary)) {
+ this.maximumBoundary = upperBound;
+ didChange = true;
+ }
+
+ return didChange;
+ },
+
+ formatValue: function(value)
+ {
+ return Number.secondsToString(value, WebInspector.UIString);
+ },
+
+ _lowerBound: function(resource)
+ {
+ return 0;
+ },
+
+ _upperBound: function(resource)
+ {
+ return 0;
+ }
+}
+
+WebInspector.NetworkTimeCalculator.prototype.__proto__ = WebInspector.NetworkBaseCalculator.prototype;
+
+WebInspector.NetworkTransferTimeCalculator = function()
+{
+ WebInspector.NetworkTimeCalculator.call(this, false);
+}
+
+WebInspector.NetworkTransferTimeCalculator.prototype = {
+ formatValue: function(value)
+ {
+ return Number.secondsToString(value, WebInspector.UIString);
+ },
+
+ _lowerBound: function(resource)
+ {
+ return resource.startTime;
+ },
+
+ _upperBound: function(resource)
+ {
+ return resource.endTime;
+ }
+}
+
+WebInspector.NetworkTransferTimeCalculator.prototype.__proto__ = WebInspector.NetworkTimeCalculator.prototype;
+
+WebInspector.NetworkTransferDurationCalculator = function()
+{
+ WebInspector.NetworkTimeCalculator.call(this, true);
+}
+
+WebInspector.NetworkTransferDurationCalculator.prototype = {
+ formatValue: function(value)
+ {
+ return Number.secondsToString(value, WebInspector.UIString);
+ },
+
+ _upperBound: function(resource)
+ {
+ return resource.duration;
+ }
+}
+
+WebInspector.NetworkTransferDurationCalculator.prototype.__proto__ = WebInspector.NetworkTimeCalculator.prototype;
+
+WebInspector.NetworkTransferSizeCalculator = function()
+{
+ WebInspector.NetworkBaseCalculator.call(this);
+}
+
+WebInspector.NetworkTransferSizeCalculator.prototype = {
+ computeBarGraphLabels: function(resource)
+ {
+ var networkBytes = this._networkBytes(resource);
+ var resourceBytes = this._value(resource);
+ if (networkBytes && networkBytes !== resourceBytes) {
+ // Transferred size is not the same as reported resource length.
+ var networkBytesString = this.formatValue(networkBytes);
+ var left = networkBytesString;
+ var right = this.formatValue(resourceBytes);
+ var tooltip = right ? WebInspector.UIString("%s (%s transferred)", right, networkBytesString) : right;
+ } else {
+ var left = this.formatValue(resourceBytes);
+ var right = left;
+ var tooltip = left;
+ }
+ if (resource.cached)
+ tooltip = WebInspector.UIString("%s (from cache)", tooltip);
+ return {left: left, right: right, tooltip: tooltip};
+ },
+
+ computeBarGraphPercentages: function(item)
+ {
+ const resourceBytesAsPercent = (this._value(item) / this.boundarySpan) * 100;
+ const networkBytesAsPercent = this._networkBytes(item) ? (this._networkBytes(item) / this.boundarySpan) * 100 : resourceBytesAsPercent;
+ return {start: 0, middle: networkBytesAsPercent, end: resourceBytesAsPercent};
+ },
+
+ _value: function(resource)
+ {
+ return resource.resourceSize;
+ },
+
+ _networkBytes: function(resource)
+ {
+ return resource.transferSize;
+ },
+
+ formatValue: function(value)
+ {
+ return Number.bytesToString(value, WebInspector.UIString);
+ }
+}
+
+WebInspector.NetworkTransferSizeCalculator.prototype.__proto__ = WebInspector.NetworkBaseCalculator.prototype;
+
+WebInspector.NetworkDataGridNode = function(resource)
+{
+ WebInspector.DataGridNode.call(this, {});
+ this._resource = resource;
+}
+
+WebInspector.NetworkDataGridNode.prototype = {
+ createCells: function()
+ {
+ this._urlCell = this._createDivInTD("url-column");
+ this._methodCell = this._createDivInTD("optional-column");
+ this._statusCell = this._createDivInTD("optional-column");
+ this._typeCell = this._createDivInTD("optional-column");
+ this._sizeCell = this._createDivInTD("optional-column right");
+ this._timeCell = this._createDivInTD("optional-column right");
+ this._createTimelineCell();
+ },
+
+ _createDivInTD: function(className) {
+ var td = document.createElement("td");
+ if (className)
+ td.className = className;
+ var div = document.createElement("div");
+ td.appendChild(div);
+ this._element.appendChild(td);
+ return div;
+ },
+
+
+ _createTimelineCell: function()
+ {
+ this._graphElement = document.createElement("div");
+ this._graphElement.className = "network-graph-side";
+ this._graphElement.addEventListener("mouseover", this._refreshLabelPositions.bind(this), false);
+
+ this._barAreaElement = document.createElement("div");
+ // this._barAreaElement.className = "network-graph-bar-area hidden";
+ this._barAreaElement.className = "network-graph-bar-area";
+ this._barAreaElement.resource = this._resource;
+ this._graphElement.appendChild(this._barAreaElement);
+
+ this._barLeftElement = document.createElement("div");
+ this._barLeftElement.className = "network-graph-bar waiting";
+ this._barAreaElement.appendChild(this._barLeftElement);
+
+ this._barRightElement = document.createElement("div");
+ this._barRightElement.className = "network-graph-bar";
+ this._barAreaElement.appendChild(this._barRightElement);
+
+ this._labelLeftElement = document.createElement("div");
+ this._labelLeftElement.className = "network-graph-label waiting";
+ this._barAreaElement.appendChild(this._labelLeftElement);
+
+ this._labelRightElement = document.createElement("div");
+ this._labelRightElement.className = "network-graph-label";
+ this._barAreaElement.appendChild(this._labelRightElement);
+
+ this._timelineCell = document.createElement("td");
+ this._element.appendChild(this._timelineCell);
+ this._timelineCell.appendChild(this._graphElement);
+ },
+
+ refreshResource: function()
+ {
+ this._refreshURLCell();
+
+ this._methodCell.textContent = this._resource.requestMethod;
+
+ this._refreshStatusCell();
+
+ if (this._resource.mimeType) {
+ this._typeCell.removeStyleClass("network-dim-cell");
+ this._typeCell.textContent = this._resource.mimeType;
+ } else {
+ this._typeCell.addStyleClass("network-dim-cell");
+ this._typeCell.textContent = WebInspector.UIString("Pending");
+ }
+
+ this._refreshSizeCell();
+ this._refreshTimeCell();
+
+ if (this._resource.cached)
+ this._graphElement.addStyleClass("resource-cached");
+
+ if (!this._element.hasStyleClass("network-category-" + this._resource.category.name)) {
+ this._element.removeMatchingStyleClasses("network-category-\\w+");
+ this._element.addStyleClass("network-category-" + this._resource.category.name);
+ }
+ },
+
+ _refreshURLCell: function()
+ {
+ this._urlCell.removeChildren();
+
+ if (this._resource.category === WebInspector.resourceCategories.images) {
+ var previewImage = document.createElement("img");
+ previewImage.className = "image-network-icon-preview";
+ previewImage.src = this._resource.url;
+
+ var iconElement = document.createElement("div");
+ iconElement.className = "icon";
+ iconElement.appendChild(previewImage);
+ } else {
+ var iconElement = document.createElement("img");
+ iconElement.className = "icon";
+ }
+ this._urlCell.appendChild(iconElement);
+ this._urlCell.appendChild(document.createTextNode(this._fileName()));
+
+
+ var subtitle = this._resource.displayDomain;
+
+ if (this._resource.path && this._resource.lastPathComponent) {
+ var lastPathComponentIndex = this._resource.path.lastIndexOf("/" + this._resource.lastPathComponent);
+ if (lastPathComponentIndex != -1)
+ subtitle += this._resource.path.substring(0, lastPathComponentIndex);
+ }
+
+ var subtitleElement = document.createElement("div");
+ subtitleElement.className = "network-grid-subtitle";
+ subtitleElement.textContent = subtitle;
+ this._urlCell.appendChild(subtitleElement);
+
+
+ this._urlCell.title = this._resource.url;
+ },
+
+ _fileName: function()
+ {
+ var fileName = this._resource.displayName;
+ if (this._resource.queryString)
+ fileName += "?" + this._resource.queryString;
+ return fileName;
+ },
+
+ _refreshStatusCell: function()
+ {
+ this._statusCell.removeChildren();
+
+ if (this._resource.statusCode) {
+ var img = document.createElement("img");
+ if (this._resource.statusCode < 300)
+ img.src = "Images/successGreenDot.png";
+ else if (this._resource.statusCode < 400)
+ img.src = "Images/warningOrangeDot.png";
+ else
+ img.src = "Images/errorRedDot.png";
+
+ img.className = "resource-status-image";
+ this._statusCell.appendChild(img);
+ this._statusCell.appendChild(document.createTextNode(this._resource.statusCode));
+ this._statusCell.removeStyleClass("network-dim-cell");
+ this._appendSubtitle(this._statusCell, this._resource.statusText);
+ this._statusCell.title = this._resource.statusCode + " " + this._resource.statusText;
+ } else {
+ this._statusCell.addStyleClass("network-dim-cell");
+ this._statusCell.textContent = WebInspector.UIString("Pending");
+ }
+ },
+
+ _refreshSizeCell: function()
+ {
+ var resourceSize = typeof this._resource.resourceSize === "number" ? Number.bytesToString(this._resource.resourceSize) : "?";
+ var transferSize = typeof this._resource.transferSize === "number" ? Number.bytesToString(this._resource.transferSize) : "?";
+ var fromCache = this._resource.cached;
+ this._sizeCell.textContent = !fromCache ? resourceSize : WebInspector.UIString("(from cache)");
+ if (fromCache)
+ this._sizeCell.addStyleClass("network-dim-cell");
+ else
+ this._sizeCell.removeStyleClass("network-dim-cell");
+ if (!fromCache)
+ this._appendSubtitle(this._sizeCell, transferSize);
+ },
+
+ _refreshTimeCell: function()
+ {
+ if (this._resource.duration > 0) {
+ this._timeCell.removeStyleClass("network-dim-cell");
+ this._timeCell.textContent = Number.secondsToString(this._resource.duration);
+ this._appendSubtitle(this._timeCell, Number.secondsToString(this._resource.latency));
+ } else {
+ this._timeCell.addStyleClass("network-dim-cell");
+ this._timeCell.textContent = WebInspector.UIString("Pending");
+ }
+ },
+
+ _appendSubtitle: function(cellElement, subtitleText)
+ {
+ var subtitleElement = document.createElement("div");
+ subtitleElement.className = "network-grid-subtitle";
+ subtitleElement.textContent = subtitleText;
+ cellElement.appendChild(subtitleElement);
+ },
+
+ refreshGraph: function(calculator)
+ {
+ var percentages = calculator.computeBarGraphPercentages(this._resource);
+ var labels = calculator.computeBarGraphLabels(this._resource);
+
+ this._percentages = percentages;
+
+ this._barAreaElement.removeStyleClass("hidden");
+
+ if (!this._graphElement.hasStyleClass("network-category-" + this._resource.category.name)) {
+ this._graphElement.removeMatchingStyleClasses("network-category-\\w+");
+ this._graphElement.addStyleClass("network-category-" + this._resource.category.name);
+ }
+
+ this._barLeftElement.style.setProperty("left", percentages.start + "%");
+ this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
+
+ this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%");
+ this._barRightElement.style.setProperty("left", percentages.middle + "%");
+
+ this._labelLeftElement.textContent = labels.left;
+ this._labelRightElement.textContent = labels.right;
+
+ var tooltip = (labels.tooltip || "");
+ this._barLeftElement.title = tooltip;
+ this._labelLeftElement.title = tooltip;
+ this._labelRightElement.title = tooltip;
+ this._barRightElement.title = tooltip;
+ },
+
+ _refreshLabelPositions: function()
+ {
+ this._labelLeftElement.style.removeProperty("left");
+ this._labelLeftElement.style.removeProperty("right");
+ this._labelLeftElement.removeStyleClass("before");
+ this._labelLeftElement.removeStyleClass("hidden");
+
+ this._labelRightElement.style.removeProperty("left");
+ this._labelRightElement.style.removeProperty("right");
+ this._labelRightElement.removeStyleClass("after");
+ this._labelRightElement.removeStyleClass("hidden");
+
+ const labelPadding = 10;
+ const barRightElementOffsetWidth = this._barRightElement.offsetWidth;
+ const barLeftElementOffsetWidth = this._barLeftElement.offsetWidth;
+
+ if (this._barLeftElement) {
+ var leftBarWidth = barLeftElementOffsetWidth - labelPadding;
+ var rightBarWidth = (barRightElementOffsetWidth - barLeftElementOffsetWidth) - labelPadding;
+ } else {
+ var leftBarWidth = (barLeftElementOffsetWidth - barRightElementOffsetWidth) - labelPadding;
+ var rightBarWidth = barRightElementOffsetWidth - labelPadding;
+ }
+
+ const labelLeftElementOffsetWidth = this._labelLeftElement.offsetWidth;
+ const labelRightElementOffsetWidth = this._labelRightElement.offsetWidth;
+
+ const labelBefore = (labelLeftElementOffsetWidth > leftBarWidth);
+ const labelAfter = (labelRightElementOffsetWidth > rightBarWidth);
+ const graphElementOffsetWidth = this._graphElement.offsetWidth;
+
+ if (labelBefore && (graphElementOffsetWidth * (this._percentages.start / 100)) < (labelLeftElementOffsetWidth + 10))
+ var leftHidden = true;
+
+ if (labelAfter && (graphElementOffsetWidth * ((100 - this._percentages.end) / 100)) < (labelRightElementOffsetWidth + 10))
+ var rightHidden = true;
+
+ if (barLeftElementOffsetWidth == barRightElementOffsetWidth) {
+ // The left/right label data are the same, so a before/after label can be replaced by an on-bar label.
+ if (labelBefore && !labelAfter)
+ leftHidden = true;
+ else if (labelAfter && !labelBefore)
+ rightHidden = true;
+ }
+
+ if (labelBefore) {
+ if (leftHidden)
+ this._labelLeftElement.addStyleClass("hidden");
+ this._labelLeftElement.style.setProperty("right", (100 - this._percentages.start) + "%");
+ this._labelLeftElement.addStyleClass("before");
+ } else {
+ this._labelLeftElement.style.setProperty("left", this._percentages.start + "%");
+ this._labelLeftElement.style.setProperty("right", (100 - this._percentages.middle) + "%");
+ }
+
+ if (labelAfter) {
+ if (rightHidden)
+ this._labelRightElement.addStyleClass("hidden");
+ this._labelRightElement.style.setProperty("left", this._percentages.end + "%");
+ this._labelRightElement.addStyleClass("after");
+ } else {
+ this._labelRightElement.style.setProperty("left", this._percentages.middle + "%");
+ this._labelRightElement.style.setProperty("right", (100 - this._percentages.end) + "%");
+ }
+ }
+}
+
+WebInspector.NetworkDataGridNode.URLComparator = function(a, b)
+{
+ var aFileName = a._resource.displayName + (a._resource.queryString ? a._resource.queryString : "");
+ var bFileName = b._resource.displayName + (b._resource.queryString ? b._resource.queryString : "");
+ if (aFileName > bFileName)
+ return 1;
+ if (bFileName > aFileName)
+ return -1;
+ return 0;
+}
+
+WebInspector.NetworkDataGridNode.ResourcePropertyComparator = function(propertyName, a, b)
+{
+ var aValue = a._resource[propertyName];
+ var bValue = b._resource[propertyName];
+ if (aValue > bValue)
+ return 1;
+ if (bValue > aValue)
+ return -1;
+ return 0;
+}
+
+WebInspector.NetworkDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
diff --git a/WebCore/inspector/front-end/ResourceCategory.js b/WebCore/inspector/front-end/ResourceCategory.js
index 6e94265..84f2cf9 100644
--- a/WebCore/inspector/front-end/ResourceCategory.js
+++ b/WebCore/inspector/front-end/ResourceCategory.js
@@ -28,12 +28,19 @@
WebInspector.ResourceCategory = function(name, title, color)
{
- WebInspector.AbstractTimelineCategory.call(this, name, title, color);
+ this.name = name;
+ this.title = title;
+ this.color = color;
this.resources = [];
}
WebInspector.ResourceCategory.prototype = {
+ toString: function()
+ {
+ return this.title;
+ },
+
addResource: function(resource)
{
var a = resource;
@@ -61,5 +68,3 @@ WebInspector.ResourceCategory.prototype = {
this.resources = [];
}
}
-
-WebInspector.ResourceCategory.prototype.__proto__ = WebInspector.AbstractTimelineCategory.prototype;
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index f329b1a..aa021ff 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -29,7 +29,10 @@
WebInspector.ResourcesPanel = function()
{
- WebInspector.AbstractTimelinePanel.call(this, "resources");
+ WebInspector.Panel.call(this, "resources");
+
+ this._items = [];
+ this._staleItems = [];
this._createPanelEnabler();
@@ -82,6 +85,299 @@ WebInspector.ResourcesPanel.prototype = {
return (this.itemsGraphsElement.hasStyleClass("filter-all") || this.itemsGraphsElement.hasStyleClass("filter-" + categoryName.toLowerCase()));
},
+ get items()
+ {
+ return this._items;
+ },
+
+ createInterface: function()
+ {
+ this.containerElement = document.createElement("div");
+ this.containerElement.id = "resources-container";
+ this.containerElement.addEventListener("scroll", this._updateDividersLabelBarPosition.bind(this), false);
+ this.element.appendChild(this.containerElement);
+
+ this.createSidebar(this.containerElement, this.element);
+ this.sidebarElement.id = "resources-sidebar";
+ this.populateSidebar();
+
+ this._containerContentElement = document.createElement("div");
+ this._containerContentElement.id = "resources-container-content";
+ this.containerElement.appendChild(this._containerContentElement);
+
+ this.summaryBar = new WebInspector.SummaryBar(this.categories);
+ this.summaryBar.element.id = "resources-summary";
+ this._containerContentElement.appendChild(this.summaryBar.element);
+
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._containerContentElement.appendChild(this._timelineGrid.element);
+ this.itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
+ },
+
+ createFilterPanel: function()
+ {
+ this.filterBarElement = document.createElement("div");
+ this.filterBarElement.id = "resources-filter";
+ this.filterBarElement.className = "scope-bar";
+ this.element.appendChild(this.filterBarElement);
+
+ function createFilterElement(category)
+ {
+ if (category === "all")
+ var label = WebInspector.UIString("All");
+ else if (this.categories[category])
+ var label = this.categories[category].title;
+
+ var categoryElement = document.createElement("li");
+ categoryElement.category = category;
+ categoryElement.addStyleClass(category);
+ categoryElement.appendChild(document.createTextNode(label));
+ categoryElement.addEventListener("click", this._updateFilter.bind(this), false);
+ this.filterBarElement.appendChild(categoryElement);
+
+ return categoryElement;
+ }
+
+ this.filterAllElement = createFilterElement.call(this, "all");
+
+ // Add a divider
+ var dividerElement = document.createElement("div");
+ dividerElement.addStyleClass("divider");
+ this.filterBarElement.appendChild(dividerElement);
+
+ for (var category in this.categories)
+ createFilterElement.call(this, category);
+ },
+
+ showCategory: function(category)
+ {
+ var filterClass = "filter-" + category.toLowerCase();
+ this.itemsGraphsElement.addStyleClass(filterClass);
+ this.itemsTreeElement.childrenListElement.addStyleClass(filterClass);
+ },
+
+ hideCategory: function(category)
+ {
+ var filterClass = "filter-" + category.toLowerCase();
+ this.itemsGraphsElement.removeStyleClass(filterClass);
+ this.itemsTreeElement.childrenListElement.removeStyleClass(filterClass);
+ },
+
+ filter: function(target, selectMultiple)
+ {
+ function unselectAll()
+ {
+ for (var i = 0; i < this.filterBarElement.childNodes.length; ++i) {
+ var child = this.filterBarElement.childNodes[i];
+ if (!child.category)
+ continue;
+
+ child.removeStyleClass("selected");
+ this.hideCategory(child.category);
+ }
+ }
+
+ if (target === this.filterAllElement) {
+ if (target.hasStyleClass("selected")) {
+ // We can't unselect All, so we break early here
+ return;
+ }
+
+ // If All wasn't selected, and now is, unselect everything else.
+ unselectAll.call(this);
+ } else {
+ // Something other than All is being selected, so we want to unselect All.
+ if (this.filterAllElement.hasStyleClass("selected")) {
+ this.filterAllElement.removeStyleClass("selected");
+ this.hideCategory("all");
+ }
+ }
+
+ if (!selectMultiple) {
+ // If multiple selection is off, we want to unselect everything else
+ // and just select ourselves.
+ unselectAll.call(this);
+
+ target.addStyleClass("selected");
+ this.showCategory(target.category);
+ return;
+ }
+
+ if (target.hasStyleClass("selected")) {
+ // If selectMultiple is turned on, and we were selected, we just
+ // want to unselect ourselves.
+ target.removeStyleClass("selected");
+ this.hideCategory(target.category);
+ } else {
+ // If selectMultiple is turned on, and we weren't selected, we just
+ // want to select ourselves.
+ target.addStyleClass("selected");
+ this.showCategory(target.category);
+ }
+ },
+
+ _updateFilter: function(e)
+ {
+ var isMac = WebInspector.isMac();
+ var selectMultiple = false;
+ if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
+ selectMultiple = true;
+ if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
+ selectMultiple = true;
+
+ this.filter(e.target, selectMultiple);
+
+ // When we are updating our filtering, scroll to the top so we don't end up
+ // in blank graph under all the resources.
+ this.containerElement.scrollTop = 0;
+
+ var searchField = document.getElementById("search");
+ WebInspector.doPerformSearch(searchField.value, WebInspector.shortSearchWasForcedByKeyEvent, false, true);
+ },
+
+ _updateDividersLabelBarPosition: function()
+ {
+ const scrollTop = this.containerElement.scrollTop;
+ const offsetHeight = this.summaryBar.element.offsetHeight;
+ const dividersTop = (scrollTop < offsetHeight ? offsetHeight : scrollTop);
+ this._timelineGrid.setScrollAndDividerTop(scrollTop, dividersTop);
+ },
+
+ get needsRefresh()
+ {
+ return this._needsRefresh;
+ },
+
+ set needsRefresh(x)
+ {
+ if (this._needsRefresh === x)
+ return;
+
+ this._needsRefresh = x;
+
+ if (x) {
+ if (this.visible && !("_refreshTimeout" in this))
+ this._refreshTimeout = setTimeout(this.refresh.bind(this), 500);
+ } else {
+ if ("_refreshTimeout" in this) {
+ clearTimeout(this._refreshTimeout);
+ delete this._refreshTimeout;
+ }
+ }
+ },
+
+ refreshIfNeeded: function()
+ {
+ if (this.needsRefresh)
+ this.refresh();
+ },
+
+ resize: function()
+ {
+ WebInspector.Panel.prototype.resize.call(this);
+
+ this.updateGraphDividersIfNeeded();
+ },
+
+ invalidateAllItems: function()
+ {
+ this._staleItems = this._items.slice();
+ },
+
+ get calculator()
+ {
+ return this._calculator;
+ },
+
+ set calculator(x)
+ {
+ if (!x || this._calculator === x)
+ return;
+
+ this._calculator = x;
+ this._calculator.reset();
+
+ this._staleItems = this._items.slice();
+ this.refresh();
+ },
+
+ addItem: function(item)
+ {
+ this._items.push(item);
+ this.refreshItem(item);
+ },
+
+ removeItem: function(item)
+ {
+ this._items.remove(item, true);
+
+ if (item._itemsTreeElement) {
+ this.itemsTreeElement.removeChild(item._itemsTreeElement);
+ this.itemsGraphsElement.removeChild(item._itemsTreeElement._itemGraph.graphElement);
+ }
+
+ delete item._itemsTreeElement;
+ this.adjustScrollPosition();
+ },
+
+ refreshItem: function(item)
+ {
+ this._staleItems.push(item);
+ this.needsRefresh = true;
+ },
+
+ revealAndSelectItem: function(item)
+ {
+ if (item._itemsTreeElement) {
+ item._itemsTreeElement.reveal();
+ item._itemsTreeElement.select(true);
+ }
+ },
+
+ sortItems: function(sortingFunction)
+ {
+ var sortedElements = [].concat(this.itemsTreeElement.children);
+ sortedElements.sort(sortingFunction);
+
+ var sortedElementsLength = sortedElements.length;
+ for (var i = 0; i < sortedElementsLength; ++i) {
+ var treeElement = sortedElements[i];
+ if (treeElement === this.itemsTreeElement.children[i])
+ continue;
+
+ var wasSelected = treeElement.selected;
+ this.itemsTreeElement.removeChild(treeElement);
+ this.itemsTreeElement.insertChild(treeElement, i);
+ if (wasSelected)
+ treeElement.select(true);
+
+ var graphElement = treeElement._itemGraph.graphElement;
+ this.itemsGraphsElement.insertBefore(graphElement, this.itemsGraphsElement.children[i]);
+ }
+ },
+
+ adjustScrollPosition: function()
+ {
+ // Prevent the container from being scrolled off the end.
+ if ((this.containerElement.scrollTop + this.containerElement.offsetHeight) > this.sidebarElement.offsetHeight)
+ this.containerElement.scrollTop = (this.sidebarElement.offsetHeight - this.containerElement.offsetHeight);
+ },
+
+ addEventDivider: function(divider)
+ {
+ this._timelineGrid.addEventDivider(divider);
+ },
+
+ hideEventDividers: function()
+ {
+ this._timelineGrid.hideEventDividers();
+ },
+
+ showEventDividers: function()
+ {
+ this._timelineGrid.showEventDividers();
+ },
+
populateSidebar: function()
{
this.timeGraphItem = new WebInspector.SidebarTreeElement("resources-time-graph-sidebar-item", WebInspector.UIString("Time"));
@@ -223,7 +519,10 @@ WebInspector.ResourcesPanel.prototype = {
show: function()
{
- WebInspector.AbstractTimelinePanel.prototype.show.call(this);
+ WebInspector.Panel.prototype.show.call(this);
+
+ this._updateDividersLabelBarPosition();
+ this.refreshIfNeeded();
var visibleView = this.visibleView;
if (this.visibleResource) {
@@ -329,7 +628,44 @@ WebInspector.ResourcesPanel.prototype = {
refresh: function()
{
- WebInspector.AbstractTimelinePanel.prototype.refresh.call(this);
+ this.needsRefresh = false;
+
+ var staleItemsLength = this._staleItems.length;
+
+ var boundariesChanged = false;
+
+ for (var i = 0; i < staleItemsLength; ++i) {
+ var item = this._staleItems[i];
+ if (!item._itemsTreeElement) {
+ // Create the timeline tree element and graph.
+ item._itemsTreeElement = this.createItemTreeElement(item);
+ item._itemsTreeElement._itemGraph = this.createItemGraph(item);
+
+ this.itemsTreeElement.appendChild(item._itemsTreeElement);
+ this.itemsGraphsElement.appendChild(item._itemsTreeElement._itemGraph.graphElement);
+ }
+
+ if (item._itemsTreeElement.refresh)
+ item._itemsTreeElement.refresh();
+
+ if (this.calculator.updateBoundaries(item))
+ boundariesChanged = true;
+ }
+
+ if (boundariesChanged) {
+ // The boundaries changed, so all item graphs are stale.
+ this._staleItems = this._items.slice();
+ staleItemsLength = this._staleItems.length;
+ }
+
+
+ const isBarOpaqueAtLeft = this.sidebarTree.selectedTreeElement && this.sidebarTree.selectedTreeElement.isBarOpaqueAtLeft;
+ for (var i = 0; i < staleItemsLength; ++i)
+ this._staleItems[i]._itemsTreeElement._itemGraph.refresh(this.calculator, isBarOpaqueAtLeft);
+
+ this._staleItems = [];
+
+ this.updateGraphDividersIfNeeded();
this._sortResourcesIfNeeded();
this._updateSummaryGraph();
@@ -373,7 +709,28 @@ WebInspector.ResourcesPanel.prototype = {
}
}
- WebInspector.AbstractTimelinePanel.prototype.reset.call(this);
+ // Begin reset timeline
+ this.containerElement.scrollTop = 0;
+
+ if (this._calculator)
+ this._calculator.reset();
+
+ if (this._items) {
+ var itemsLength = this._items.length;
+ for (var i = 0; i < itemsLength; ++i) {
+ var item = this._items[i];
+ delete item._itemsTreeElement;
+ }
+ }
+
+ this._items = [];
+ this._staleItems = [];
+
+ this.itemsTreeElement.removeChildren();
+ this.itemsGraphsElement.removeChildren();
+
+ this.updateGraphDividersIfNeeded(true);
+ // End reset timeline.
this.mainResourceLoadTime = -1;
this.mainResourceDOMContentTime = -1;
@@ -585,7 +942,12 @@ WebInspector.ResourcesPanel.prototype = {
updateGraphDividersIfNeeded: function(force)
{
- var proceed = WebInspector.AbstractTimelinePanel.prototype.updateGraphDividersIfNeeded.call(this, force);
+ var proceed = true;
+ if (!this.visible) {
+ this.needsRefresh = true;
+ proceed = false;
+ } else
+ proceed = this._timelineGrid.updateDividers(force, this.calculator);
if (!proceed)
return;
@@ -739,8 +1101,7 @@ WebInspector.ResourcesPanel.prototype = {
updateMainViewWidth: function(width)
{
this.viewsContainerElement.style.left = width + "px";
-
- WebInspector.AbstractTimelinePanel.prototype.updateMainViewWidth.call(this, width);
+ this._containerContentElement.style.left = width + "px";
this.resize();
},
@@ -918,16 +1279,86 @@ WebInspector.ResourcesPanel.prototype = {
}
}
-WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.AbstractTimelinePanel.prototype;
+WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
WebInspector.getResourceContent = function(identifier, callback)
{
InspectorBackend.getResourceContent(identifier, callback);
}
+WebInspector.ResourceBaseCalculator = function()
+{
+}
+
+WebInspector.ResourceBaseCalculator.prototype = {
+ computeSummaryValues: function(items)
+ {
+ var total = 0;
+ var categoryValues = {};
+
+ var itemsLength = items.length;
+ for (var i = 0; i < itemsLength; ++i) {
+ var item = items[i];
+ var value = this._value(item);
+ if (typeof value === "undefined")
+ continue;
+ if (!(item.category.name in categoryValues))
+ categoryValues[item.category.name] = 0;
+ categoryValues[item.category.name] += value;
+ total += value;
+ }
+
+ return {categoryValues: categoryValues, total: total};
+ },
+
+ computeBarGraphPercentages: function(item)
+ {
+ return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan) * 100};
+ },
+
+ computeBarGraphLabels: function(item)
+ {
+ const label = this.formatValue(this._value(item));
+ return {left: label, right: label, tooltip: label};
+ },
+
+ get boundarySpan()
+ {
+ return this.maximumBoundary - this.minimumBoundary;
+ },
+
+ updateBoundaries: function(item)
+ {
+ this.minimumBoundary = 0;
+
+ var value = this._value(item);
+ if (typeof this.maximumBoundary === "undefined" || value > this.maximumBoundary) {
+ this.maximumBoundary = value;
+ return true;
+ }
+ return false;
+ },
+
+ reset: function()
+ {
+ delete this.minimumBoundary;
+ delete this.maximumBoundary;
+ },
+
+ _value: function(item)
+ {
+ return 0;
+ },
+
+ formatValue: function(value)
+ {
+ return value.toString();
+ }
+}
+
WebInspector.ResourceTimeCalculator = function(startAtZero)
{
- WebInspector.AbstractTimelineCalculator.call(this);
+ WebInspector.ResourceBaseCalculator.call(this);
this.startAtZero = startAtZero;
}
@@ -1092,7 +1523,7 @@ WebInspector.ResourceTimeCalculator.prototype = {
}
}
-WebInspector.ResourceTimeCalculator.prototype.__proto__ = WebInspector.AbstractTimelineCalculator.prototype;
+WebInspector.ResourceTimeCalculator.prototype.__proto__ = WebInspector.ResourceBaseCalculator.prototype;
WebInspector.ResourceTransferTimeCalculator = function()
{
@@ -1139,7 +1570,7 @@ WebInspector.ResourceTransferDurationCalculator.prototype.__proto__ = WebInspect
WebInspector.ResourceTransferSizeCalculator = function()
{
- WebInspector.AbstractTimelineCalculator.call(this);
+ WebInspector.ResourceBaseCalculator.call(this);
}
WebInspector.ResourceTransferSizeCalculator.prototype = {
@@ -1186,7 +1617,7 @@ WebInspector.ResourceTransferSizeCalculator.prototype = {
}
}
-WebInspector.ResourceTransferSizeCalculator.prototype.__proto__ = WebInspector.AbstractTimelineCalculator.prototype;
+WebInspector.ResourceTransferSizeCalculator.prototype.__proto__ = WebInspector.ResourceBaseCalculator.prototype;
WebInspector.ResourceSidebarTreeElement = function(resource)
{
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 715339d..8283528 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -104,7 +104,6 @@ WebInspector.ScriptsPanel = function()
this.sidebarButtonsElement.appendChild(this.stepOutButton);
this.toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate all breakpoints."), "toggle-breakpoints");
- // Breakpoints should be activated by default, so emulate a click to toggle on.
this.toggleBreakpointsButton.toggled = true;
this.toggleBreakpointsButton.addEventListener("click", this.toggleBreakpointsClicked.bind(this), false);
this.sidebarButtonsElement.appendChild(this.toggleBreakpointsButton.element);
@@ -133,8 +132,13 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane();
- if (Preferences.domBreakpointsEnabled)
+ if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
+ this.sidebarPanes.domBreakpoints.expanded = true;
+ this.sidebarPanes.xhrBreakpoints = WebInspector.createXHRBreakpointsSidebarPane();
+ this.sidebarPanes.xhrBreakpoints.expanded = true;
+ }
+
this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane();
for (var pane in this.sidebarPanes)
@@ -145,8 +149,6 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.scopechain.expanded = true;
this.sidebarPanes.jsBreakpoints.expanded = true;
- if (Preferences.domBreakpointsEnabled)
- this.sidebarPanes.domBreakpoints.expanded = true;
var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
@@ -387,8 +389,8 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.callstack.update(details.callFrames, this._sourceIDMap);
this.sidebarPanes.callstack.selectedCallFrame = details.callFrames[0];
- if (details.status)
- this.sidebarPanes.callstack.updateStatus(details.status);
+ if ("eventType" in details)
+ this.sidebarPanes.callstack.updateStatus(details.eventType, details.eventData);
WebInspector.currentPanel = this;
window.focus();
@@ -467,8 +469,10 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.watchExpressions.refreshExpressions();
if (!preserveItems) {
this.sidebarPanes.jsBreakpoints.reset();
- if (Preferences.domBreakpointsEnabled)
+ if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints.reset();
+ this.sidebarPanes.xhrBreakpoints.reset();
+ }
this.sidebarPanes.workers.reset();
}
},
@@ -891,7 +895,7 @@ WebInspector.ScriptsPanel.prototype = {
_togglePauseOnExceptions: function()
{
- InspectorBackend.setPauseOnExceptionsState((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states);
+ InspectorBackend.setPauseOnExceptionsState((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states, this.updatePauseOnExceptionsState.bind(this));
},
_togglePause: function()
@@ -998,6 +1002,9 @@ WebInspector.ScriptsPanel.prototype = {
this._shortcuts[shortcut2.key] = handler;
section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step out"));
+ shortcut1 = WebInspector.KeyboardShortcut.makeDescriptor("g", platformSpecificModifier);
+ this._shortcuts[shortcut1.key] = this.showGoToLineDialog.bind(this);
+ section.addAlternateKeys([ shortcut1.name ], WebInspector.UIString("Go to Line"));
this.sidebarPanes.callstack.registerShortcuts(section);
},
@@ -1067,6 +1074,13 @@ WebInspector.ScriptsPanel.prototype = {
this._searchView.jumpToLastSearchResult();
else
this._searchView.jumpToPreviousSearchResult();
+ },
+
+ showGoToLineDialog: function(e)
+ {
+ var view = this.visibleView;
+ if (view)
+ WebInspector.GoToLineDialog.show(view);
}
}
diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js
index 63f2641..c6da14d 100644
--- a/WebCore/inspector/front-end/Settings.js
+++ b/WebCore/inspector/front-end/Settings.js
@@ -42,10 +42,10 @@ var Preferences = {
showColorNicknames: true,
debuggerAlwaysEnabled: false,
profilerAlwaysEnabled: false,
- auditsPanelEnabled: true,
onlineDetectionEnabled: true,
- domBreakpointsEnabled: false,
- resourceExportEnabled: false
+ nativeInstrumentationEnabled: false,
+ resourceExportEnabled: false,
+ networkPanelEnabled: false
}
WebInspector.Settings = function(sessionScope)
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index a9033f2..aecd57b 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -498,7 +498,8 @@ WebInspector.SourceFrame.prototype = {
self._hidePopup();
delete self._hidePopupTimer;
}
- this._hidePopupTimer = setTimeout(doHide, 500);
+ if (!("_hidePopupTimer" in this))
+ this._hidePopupTimer = setTimeout(doHide, 500);
}
this._hoverElement = event.target;
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index c222f0e..11382cd 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -1,7 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/webkit/inspector">
<file>inspector.html</file>
- <file>AbstractTimelinePanel.js</file>
<file>ApplicationCacheItemsView.js</file>
<file>AuditCategories.js</file>
<file>AuditFormatters.js</file>
@@ -42,6 +41,7 @@
<file>ExtensionRegistryStub.js</file>
<file>ExtensionServer.js</file>
<file>FontView.js</file>
+ <file>GoToLineDialog.js</file>
<file>HAREntry.js</file>
<file>HeapSnapshotView.js</file>
<file>HelpScreen.js</file>
@@ -53,6 +53,7 @@
<file>InspectorFrontendHostStub.js</file>
<file>KeyboardShortcut.js</file>
<file>MetricsSidebarPane.js</file>
+ <file>NetworkPanel.js</file>
<file>Object.js</file>
<file>ObjectPropertiesSection.js</file>
<file>Panel.js</file>
@@ -106,10 +107,12 @@
<file>WelcomeView.js</file>
<file>WorkersSidebarPane.js</file>
<file>audits.css</file>
+ <file>goToLineDialog.css</file>
<file>heapProfiler.css</file>
<file>helpScreen.css</file>
<file>inspector.css</file>
<file>inspectorSyntaxHighlight.css</file>
+ <file>networkPanel.css</file>
<file>popover.css</file>
<file>textViewer.css</file>
<file>Images/applicationCache.png</file>
@@ -164,7 +167,9 @@
<file>Images/grayConnectorPoint.png</file>
<file>Images/largerResourcesButtonGlyph.png</file>
<file>Images/localStorage.png</file>
+ <file>Images/networkIcon.png</file>
<file>Images/nodeSearchButtonGlyph.png</file>
+ <file>Images/paneAddButtons.png</file>
<file>Images/paneBottomGrow.png</file>
<file>Images/paneBottomGrowActive.png</file>
<file>Images/paneGrowHandleLine.png</file>
diff --git a/WebCore/inspector/front-end/goToLineDialog.css b/WebCore/inspector/front-end/goToLineDialog.css
new file mode 100644
index 0000000..725e4c8
--- /dev/null
+++ b/WebCore/inspector/front-end/goToLineDialog.css
@@ -0,0 +1,39 @@
+.go-to-line-dialog {
+ position: absolute;
+ top: 40%;
+ left: 40%;
+ z-index: 1900;
+
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#E9E9E9), to(#CFCFCF));
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ padding: 10px;
+ border-radius: 10px;
+ border: 1px solid gray;
+ -webkit-box-shadow: rgb(40,40,40) 0px 0px 50px;
+
+ font-size: 11px;
+ font-family: 'Lucida Grande', sans-serif;
+}
+
+.go-to-line-dialog input {
+ font-size: 11px;
+}
+
+.go-to-line-dialog button {
+ font-size: 11px;
+ color: rgb(6, 6, 6);
+ border: 1px solid rgb(165, 165, 165);
+ background-color: rgb(237, 237, 237);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ -webkit-border-radius: 12px;
+ -webkit-appearance: none;
+
+ padding: 3px 20px;
+ margin: 0 0 0 10px;
+}
+
+.go-to-line-dialog button:active {
+ background-color: rgb(215, 215, 215);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+}
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 6d8571c..848afdc 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -207,6 +207,10 @@ body.attached #search-results-matches {
background-image: url(Images/resourcesIcon.png);
}
+.toolbar-item.network .toolbar-icon {
+ background-image: url(Images/networkIcon.png);
+}
+
.toolbar-item.scripts .toolbar-icon {
background-image: url(Images/scriptsIcon.png);
}
@@ -1677,6 +1681,29 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
color: black;
}
+.pane > .title > button.add {
+ float: right;
+ width: 23px;
+ height: 17px;
+ color: transparent;
+ background-color: transparent;
+ border: none;
+ background-image: url(Images/paneAddButtons.png);
+ background-repeat: no-repeat;
+ margin: 1px 0 0 0;
+ padding: 0;
+ -webkit-border-radius: 0;
+ -webkit-appearance: none;
+}
+
+.pane > .title > button.add:hover {
+ background-position: -23px 0px;
+}
+
+.pane > .title > button.add:active {
+ background-position: -46px 0px;
+}
+
.pane > .body {
position: relative;
display: none;
@@ -1701,6 +1728,14 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
display: block;
}
+.pane > .body .breakpoint-condition {
+ display: block;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ margin-left: 25px;
+ margin-right: 10px;
+}
+
.pane.expanded:nth-last-of-type(1) {
border-bottom: 1px solid rgb(189, 189, 189);
}
@@ -1950,8 +1985,6 @@ body.inactive .sidebar {
padding-right: 14px;
overflow-x: hidden;
overflow-y: overlay;
- background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
- -webkit-background-size: 1px 32px;
}
.data-grid.inline .data-container {
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 0536ee6..949b18f 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -30,9 +30,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="audits.css">
+ <link rel="stylesheet" type="text/css" href="goToLineDialog.css">
<link rel="stylesheet" type="text/css" href="heapProfiler.css">
<link rel="stylesheet" type="text/css" href="inspector.css">
<link rel="stylesheet" type="text/css" href="inspectorSyntaxHighlight.css">
+ <link rel="stylesheet" type="text/css" href="networkPanel.css">
<link rel="stylesheet" type="text/css" href="popover.css">
<link rel="stylesheet" type="text/css" href="textViewer.css">
<script type="text/javascript" src="utilities.js"></script>
@@ -58,7 +60,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="ConsoleView.js"></script>
<script type="text/javascript" src="Panel.js"></script>
<script type="text/javascript" src="TimelineGrid.js"></script>
- <script type="text/javascript" src="AbstractTimelinePanel.js"></script>
<script type="text/javascript" src="Resource.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="Database.js"></script>
@@ -92,6 +93,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="StatusBarButton.js"></script>
<script type="text/javascript" src="SummaryBar.js"></script>
<script type="text/javascript" src="ElementsPanel.js"></script>
+ <script type="text/javascript" src="NetworkPanel.js"></script>
<script type="text/javascript" src="ResourcesPanel.js"></script>
<script type="text/javascript" src="InjectedFakeWorker.js"></script>
<script type="text/javascript" src="ScriptsPanel.js"></script>
@@ -138,6 +140,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="TimelineOverviewPane.js"></script>
<script type="text/javascript" src="TestController.js"></script>
<script type="text/javascript" src="HelpScreen.js"></script>
+ <script type="text/javascript" src="GoToLineDialog.js"></script>
<script type="text/javascript" src="ShortcutsHelp.js"></script>
<script type="text/javascript" src="HAREntry.js"></script>
</head>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index f6fa06b..3edae8f 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -219,11 +219,24 @@ var WebInspector = {
return pane;
},
+ createXHRBreakpointsSidebarPane: function()
+ {
+ var pane = new WebInspector.XHRBreakpointsSidebarPane();
+ function breakpointAdded(event)
+ {
+ pane.addBreakpoint(new WebInspector.XHRBreakpointItem(event.data));
+ }
+ WebInspector.breakpointManager.addEventListener("xhr-breakpoint-added", breakpointAdded);
+ return pane;
+ },
+
_createPanels: function()
{
var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
if (hiddenPanels.indexOf("elements") === -1)
this.panels.elements = new WebInspector.ElementsPanel();
+ if (Preferences.networkPanelEnabled && hiddenPanels.indexOf("network") === -1)
+ this.panels.network = new WebInspector.NetworkPanel();
if (hiddenPanels.indexOf("resources") === -1)
this.panels.resources = new WebInspector.ResourcesPanel();
if (hiddenPanels.indexOf("scripts") === -1)
@@ -238,7 +251,7 @@ var WebInspector = {
}
if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1)
this.panels.storage = new WebInspector.StoragePanel();
- if (Preferences.auditsPanelEnabled && hiddenPanels.indexOf("audits") === -1)
+ if (hiddenPanels.indexOf("audits") === -1)
this.panels.audits = new WebInspector.AuditsPanel();
if (hiddenPanels.indexOf("console") === -1)
this.panels.console = new WebInspector.ConsolePanel();
@@ -435,12 +448,8 @@ var WebInspector = {
_updateFocusedNode: function(nodeId)
{
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
- return;
-
this.currentPanel = this.panels.elements;
- this.panels.elements.focusedDOMNode = node;
+ this.panels.elements.updateFocusedNode(nodeId);
}
}
@@ -585,6 +594,8 @@ WebInspector.doLoadedDone = function()
function populateInspectorState(inspectorState)
{
WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled;
+ if ("pauseOnExceptionsState" in inspectorState)
+ WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState);
if (inspectorState.resourceTrackingEnabled)
WebInspector.panels.resources.resourceTrackingWasEnabled();
else
@@ -677,8 +688,8 @@ WebInspector.dispatchMessageFromBackend = function(messageObject)
WebInspector.reportProtocolError = function(messageObject)
{
console.error("Protocol Error: InspectorBackend request with seq = %d failed.", messageObject.seq);
- for (var error in messageObject.errors)
- console.error(" " + error);
+ for (var i = 0; i < messageObject.errors.length; ++i)
+ console.error(" " + messageObject.errors[i]);
WebInspector.removeResponseCallbackEntry(messageObject.seq);
}
@@ -1216,10 +1227,10 @@ WebInspector.updateResource = function(payload)
resource = new WebInspector.Resource(identifier, payload.url);
this.resources[identifier] = resource;
this.resourceURLMap[resource.url] = resource;
- if (this.panels.resources)
- this.panels.resources.addResource(resource);
- if (this.panels.audits)
- this.panels.audits.resourceStarted(resource);
+ this.panels.resources.addResource(resource);
+ this.panels.audits.resourceStarted(resource);
+ if (this.panels.network)
+ this.panels.network.addResource(resource);
}
if (payload.didRequestChange) {
@@ -1261,13 +1272,11 @@ WebInspector.updateResource = function(payload)
resource.webSocketChallengeResponse = payload.webSocketChallengeResponse;
}
- if (payload.didTypeChange) {
+ if (payload.didTypeChange)
resource.type = payload.type;
- }
- if (payload.didLengthChange) {
+ if (payload.didLengthChange)
resource.resourceSize = payload.resourceSize;
- }
if (payload.didCompletionChange) {
resource.failed = payload.failed;
@@ -1289,21 +1298,24 @@ WebInspector.updateResource = function(payload)
// This loadEventTime is for the main resource, and we want to show it
// for all resources on this page. This means we want to set it as a member
// of the resources panel instead of the individual resource.
- if (this.panels.resources)
- this.panels.resources.mainResourceLoadTime = payload.loadEventTime;
- if (this.panels.audits)
- this.panels.audits.mainResourceLoadTime = payload.loadEventTime;
+ this.panels.resources.mainResourceLoadTime = payload.loadEventTime;
+ this.panels.audits.mainResourceLoadTime = payload.loadEventTime;
+ if (this.panels.network)
+ this.panels.network.mainResourceLoadTime = payload.loadEventTime;
}
if (payload.domContentEventTime) {
// This domContentEventTime is for the main resource, so it should go in
// the resources panel for the same reasons as above.
- if (this.panels.resources)
- this.panels.resources.mainResourceDOMContentTime = payload.domContentEventTime;
- if (this.panels.audits)
- this.panels.audits.mainResourceDOMContentTime = payload.domContentEventTime;
+ this.panels.resources.mainResourceDOMContentTime = payload.domContentEventTime;
+ this.panels.audits.mainResourceDOMContentTime = payload.domContentEventTime;
+ if (this.panels.network)
+ this.panels.network.mainResourceDOMContentTime = payload.domContentEventTime;
}
}
+
+ if (this.panels.network)
+ this.panels.network.refreshResource(resource);
}
WebInspector.removeResource = function(identifier)
@@ -1402,11 +1414,6 @@ WebInspector.debuggerWasEnabled = function()
this.panels.scripts.debuggerWasEnabled();
}
-WebInspector.updatePauseOnExceptionsState = function(pauseOnExceptionsState)
-{
- this.panels.scripts.updatePauseOnExceptionsState(pauseOnExceptionsState);
-}
-
WebInspector.debuggerWasDisabled = function()
{
this.panels.scripts.debuggerWasDisabled();
diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css
new file mode 100644
index 0000000..cdea7fe
--- /dev/null
+++ b/WebCore/inspector/front-end/networkPanel.css
@@ -0,0 +1,383 @@
+.network-larger-resources-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/largerResourcesButtonGlyph.png);
+}
+
+.network.panel .data-grid {
+ border: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ font-size: 11px;
+}
+
+.network.panel .data-grid table.data {
+ -webkit-background-size: 1px 82px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0.05)), to(rgba(0, 0, 0, 0.05)));
+ font-size: 11px;
+}
+
+.network.panel .data-grid.small table.data {
+ -webkit-background-size: 1px 42px;
+}
+
+.network.panel .data-grid td {
+ line-height: 17px;
+ border-right: 1px solid rgb(210, 210, 210);
+ -webkit-user-select: none;
+}
+
+.network.panel .data-grid th {
+ border-bottom: 1px solid rgb(64%, 64%, 64%);
+ height: 22px;
+}
+
+.network.panel .data-grid th, .network.panel .data-grid th.sort-descending, .network.panel .data-grid th.sort-ascending {
+ background: -webkit-gradient(linear, left top, left bottom, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
+}
+
+.network.panel .data-grid .data-container {
+ top: 23px;
+}
+
+.network.panel .data-grid td.url-column {
+ font-weight: bold;
+}
+
+.network.panel .data-grid td.optional-column {
+ background-color: rgba(0, 0, 0, 0.07);
+}
+
+.network.panel .small .network-graph-side {
+ height: 14px;
+}
+
+.network.panel .data-grid th.sortable:active {
+ background-image: none;
+}
+
+.network-grid-subtitle {
+ font-weight: normal;
+ color: grey;
+}
+
+.network.panel .data-grid.small .network-grid-subtitle {
+ display: none;
+}
+
+/* Resource preview icons */
+
+.network.panel .data-grid .icon {
+ content: url(Images/resourcePlainIcon.png);
+}
+
+.network.panel .data-grid.small .icon {
+ content: url(Images/resourcePlainIconSmall.png);
+}
+
+.network.panel .network-category-scripts .icon {
+ content: url(Images/resourceJSIcon.png);
+}
+
+.network.panel .data-grid.small .network-category-scripts .icon {
+ content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.network.panel .network-category-documents .icon {
+ content: url(Images/resourceDocumentIcon.png);
+}
+
+.network.panel .data-grid.small .network-category-documents .icon {
+ content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.network.panel .network-category-stylesheets .icon {
+ content: url(Images/resourceCSSIcon.png);
+}
+
+.network.panel .data-grid.small .network-category-stylesheets .icon {
+ content: url(Images/resourceDocumentIconSmall.png);
+}
+
+.network.panel .network-category-images .icon {
+ position: relative;
+ background-image: url(Images/resourcePlainIcon.png);
+ background-repeat: no-repeat;
+ content: "";
+}
+
+.network.panel .network-category-images .icon {
+ position: relative;
+ background-image: url(Images/resourcePlainIcon.png);
+ background-repeat: no-repeat;
+ content: "";
+}
+
+.network.panel .data-grid.small .network-category-images .icon {
+ background-image: url(Images/resourcePlainIconSmall.png);
+ content: "";
+}
+
+.network.panel .data-grid .icon {
+ float: left;
+ width: 32px;
+ height: 32px;
+ margin-top: 1px;
+ margin-right: 3px;
+}
+
+.network.panel .data-grid.small .icon {
+ width: 16px;
+ height: 16px;
+}
+
+.network.panel .image-network-icon-preview {
+ position: absolute;
+ margin: auto;
+ top: 3px;
+ bottom: 4px;
+ left: 5px;
+ right: 5px;
+ max-width: 18px;
+ max-height: 21px;
+ min-width: 1px;
+ min-height: 1px;
+}
+
+.network.panel .data-grid.small .image-network-icon-preview {
+ top: 2px;
+ bottom: 1px;
+ left: 3px;
+ right: 3px;
+ max-width: 8px;
+ max-height: 11px;
+}
+
+/* Graph styles */
+
+.network-graph-side {
+ position: relative;
+ height: 36px;
+ padding: 0 5px;
+ white-space: nowrap;
+ margin-top: 1px;
+ border-top: 1px solid transparent;
+ overflow: hidden;
+}
+
+.network-graph-bar-area {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 8px;
+ left: 9px;
+}
+
+.network-graph-label {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ margin: auto -7px;
+ height: 13px;
+ line-height: 13px;
+ font-size: 9px;
+ color: rgba(0, 0, 0, 0.75);
+ text-shadow: rgba(255, 255, 255, 0.25) 1px 0 0, rgba(255, 255, 255, 0.25) -1px 0 0, rgba(255, 255, 255, 0.333) 0 1px 0, rgba(255, 255, 255, 0.25) 0 -1px 0;
+ z-index: 150;
+ overflow: hidden;
+ text-align: center;
+ font-weight: bold;
+ opacity: 0;
+ -webkit-transition: opacity 250ms ease-in-out;
+}
+
+.network-graph-side:hover .network-graph-label {
+ opacity: 1;
+}
+
+.network-graph-label:empty {
+ display: none;
+}
+
+.network-graph-label.waiting {
+ margin-right: 5px;
+}
+
+.network-graph-label.waiting-right {
+ margin-left: 5px;
+}
+
+.network-graph-label.before {
+ color: rgba(0, 0, 0, 0.7);
+ text-shadow: none;
+ text-align: right;
+ margin-right: 2px;
+}
+
+.network-graph-label.before::after {
+ padding-left: 2px;
+ height: 6px;
+ content: url(Images/graphLabelCalloutLeft.png);
+}
+
+.network-graph-label.after {
+ color: rgba(0, 0, 0, 0.7);
+ text-shadow: none;
+ text-align: left;
+ margin-left: 2px;
+}
+
+.network-graph-label.after::before {
+ padding-right: 2px;
+ height: 6px;
+ content: url(Images/graphLabelCalloutRight.png);
+}
+
+.network-graph-bar {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ margin: auto -7px;
+ border-width: 6px 7px;
+ height: 13px;
+ min-width: 14px;
+ opacity: 0.65;
+ -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+}
+
+.network-graph-bar.waiting, .network-graph-bar.waiting-right {
+ opacity: 0.35;
+}
+
+/* Resource categories */
+
+
+.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+}
+
+.network-category-documents .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillBlue.png) 6 7 6 7;
+}
+
+.network-category-documents.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillBlue.png) 6 7 6 7;
+}
+
+.network-category-stylesheets .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillGreen.png) 6 7 6 7;
+}
+
+.network-category-stylesheets.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillGreen.png) 6 7 6 7;
+}
+
+.network-category-images .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
+}
+
+.network-category-images.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillPurple.png) 6 7 6 7;
+}
+
+.network-category-fonts .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillRed.png) 6 7 6 7;
+}
+
+.network-category-fonts.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillRed.png) 6 7 6 7;
+}
+
+.network-category-scripts .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillOrange.png) 6 7 6 7;
+}
+
+.network-category-scripts.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillOrange.png) 6 7 6 7;
+}
+
+.network-category-xhr .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillYellow.png) 6 7 6 7;
+}
+
+.network-category-xhr.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillYellow.png) 6 7 6 7;
+}
+
+.network-category-websockets .network-graph-bar {
+ -webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
+}
+
+.network-category-websockets.resource-cached .network-graph-bar {
+ -webkit-border-image: url(Images/timelineHollowPillGray.png) 6 7 6 7;
+}
+
+
+/* Popover */
+
+.network-timing-row {
+ position: relative;
+ height: 12px;
+}
+
+.network-timing-bar {
+ position: absolute;
+ background-color: red;
+ border-left: 1px solid red;
+ opacity: 0.4;
+}
+
+.network-timing-bar-title {
+ position: absolute;
+}
+
+.network-dim-cell {
+ color: grey;
+}
+
+/* Dividers */
+
+.network-timeline-grid {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+.network-event-divider-padding {
+ position: absolute;
+ width: 8px;
+ top: 0;
+ bottom: 0;
+ pointer-events: auto;
+}
+
+.network-event-divider {
+ position: absolute;
+ width: 2px;
+ top: 0;
+ bottom: 0;
+ z-index: 300;
+}
+
+.network-red-divider {
+ background-color: rgba(255, 0, 0, 0.5);
+}
+
+.network-blue-divider {
+ background-color: rgba(0, 0, 255, 0.5);
+}
+
+.network.panel .resources-dividers-label-bar {
+ background-color: transparent;
+ border: none;
+ height: 23px;
+ pointer-events: none;
+}
+
+.network.panel .resources-divider-label {
+ top: 6px;
+ color: black;
+}
diff --git a/WebCore/inspector/front-end/treeoutline.js b/WebCore/inspector/front-end/treeoutline.js
index c2a3fe7..e2f879c 100644
--- a/WebCore/inspector/front-end/treeoutline.js
+++ b/WebCore/inspector/front-end/treeoutline.js
@@ -399,7 +399,7 @@ TreeOutline.prototype._treeKeyDown = function(event)
if (nextSelectedElement) {
nextSelectedElement.reveal();
- nextSelectedElement.select();
+ nextSelectedElement.select(false, true);
}
if (handled) {
@@ -794,10 +794,10 @@ TreeElement.prototype.revealed = function()
TreeElement.prototype.selectOnMouseDown = function(event)
{
- this.select();
+ this.select(false, true);
}
-TreeElement.prototype.select = function(supressOnSelect)
+TreeElement.prototype.select = function(supressOnSelect, selectedByUser)
{
if (!this.treeOutline || !this.selectable || this.selected)
return;
@@ -812,7 +812,7 @@ TreeElement.prototype.select = function(supressOnSelect)
this._listItemNode.addStyleClass("selected");
if (this.onselect && !supressOnSelect)
- this.onselect(this);
+ this.onselect(this, selectedByUser);
}
TreeElement.prototype.deselect = function(supressOnDeselect)