summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector')
-rw-r--r--WebCore/inspector/CodeGeneratorInspector.pm95
-rw-r--r--WebCore/inspector/ConsoleMessage.cpp3
-rw-r--r--WebCore/inspector/ConsoleMessage.h6
-rw-r--r--WebCore/inspector/InjectedScriptHost.idl1
-rw-r--r--WebCore/inspector/Inspector.idl13
-rw-r--r--WebCore/inspector/InspectorCSSAgent.cpp25
-rw-r--r--WebCore/inspector/InspectorCSSAgent.h9
-rw-r--r--WebCore/inspector/InspectorController.cpp15
-rw-r--r--WebCore/inspector/InspectorController.h4
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.cpp4
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.h4
-rw-r--r--WebCore/inspector/InspectorProfilerAgent.cpp27
-rw-r--r--WebCore/inspector/InspectorProfilerAgent.h4
-rw-r--r--WebCore/inspector/InspectorResourceAgent.cpp16
-rw-r--r--WebCore/inspector/InspectorResourceAgent.h2
-rw-r--r--WebCore/inspector/InspectorStyleSheet.cpp324
-rw-r--r--WebCore/inspector/InspectorStyleSheet.h58
-rw-r--r--WebCore/inspector/ScriptArguments.cpp5
-rw-r--r--WebCore/inspector/ScriptArguments.h9
-rw-r--r--WebCore/inspector/ScriptBreakpoint.h2
-rw-r--r--WebCore/inspector/ScriptCallFrame.h2
-rw-r--r--WebCore/inspector/ScriptCallStack.cpp9
-rw-r--r--WebCore/inspector/ScriptCallStack.h14
-rw-r--r--WebCore/inspector/front-end/AuditRules.js4
-rw-r--r--WebCore/inspector/front-end/CSSStyleModel.js67
-rw-r--r--WebCore/inspector/front-end/Color.js4
-rw-r--r--WebCore/inspector/front-end/CookieItemsView.js269
-rw-r--r--WebCore/inspector/front-end/CookiesTable.js205
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js2
-rw-r--r--WebCore/inspector/front-end/ExtensionAPI.js167
-rw-r--r--WebCore/inspector/front-end/ExtensionCommon.js8
-rw-r--r--WebCore/inspector/front-end/ExtensionServer.js124
-rw-r--r--WebCore/inspector/front-end/FileSystemView.js4
-rw-r--r--WebCore/inspector/front-end/FontView.js9
-rw-r--r--WebCore/inspector/front-end/HAREntry.js8
-rw-r--r--WebCore/inspector/front-end/HeapSnapshotView.js203
-rw-r--r--WebCore/inspector/front-end/HelpScreen.js16
-rw-r--r--WebCore/inspector/front-end/ImageView.js21
-rw-r--r--WebCore/inspector/front-end/InjectedScript.js41
-rw-r--r--WebCore/inspector/front-end/NetworkItemView.js91
-rw-r--r--WebCore/inspector/front-end/NetworkPanel.js184
-rw-r--r--WebCore/inspector/front-end/Popover.js12
-rw-r--r--WebCore/inspector/front-end/ProfilesPanel.js20
-rw-r--r--WebCore/inspector/front-end/Resource.js92
-rw-r--r--WebCore/inspector/front-end/ResourceCookiesView.js69
-rw-r--r--WebCore/inspector/front-end/ResourceHeadersView.js276
-rw-r--r--WebCore/inspector/front-end/ResourceManager.js49
-rw-r--r--WebCore/inspector/front-end/ResourceTimingView.js157
-rw-r--r--WebCore/inspector/front-end/ResourceView.js396
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js109
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js27
-rw-r--r--WebCore/inspector/front-end/Settings.js2
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js49
-rw-r--r--WebCore/inspector/front-end/SourceView.js72
-rw-r--r--WebCore/inspector/front-end/StylesSidebarPane.js106
-rw-r--r--WebCore/inspector/front-end/TabbedPane.js75
-rw-r--r--WebCore/inspector/front-end/TimelinePanel.js2
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc5
-rw-r--r--WebCore/inspector/front-end/WorkersSidebarPane.js1
-rw-r--r--WebCore/inspector/front-end/inspector.css134
-rw-r--r--WebCore/inspector/front-end/inspector.html6
-rw-r--r--WebCore/inspector/front-end/inspector.js16
-rw-r--r--WebCore/inspector/front-end/networkPanel.css185
-rw-r--r--WebCore/inspector/front-end/textViewer.css17
-rw-r--r--WebCore/inspector/front-end/utilities.js48
65 files changed, 2476 insertions, 1527 deletions
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm
index 550b5b4..177ca3b 100644
--- a/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/WebCore/inspector/CodeGeneratorInspector.pm
@@ -92,6 +92,7 @@ $typeTransform{"Value"} = {
$typeTransform{"String"} = {
"param" => "const String&",
"variable" => "String",
+ "return" => "String",
"defaultValue" => "\"\"",
"forwardHeader" => "wtf/Forward.h",
"header" => "PlatformString.h",
@@ -266,6 +267,12 @@ sub generateFunctions
push(@backendMethodsImpl, generateBackendDispatcher());
push(@backendMethodsImpl, generateBackendReportProtocolError());
+ foreach my $type (keys %backendTypes) {
+ if ($typeTransform{$type}{"JSONType"}) {
+ push(@backendMethodsImpl, generateArgumentGetters($type));
+ }
+ }
+
@backendStubJS = generateBackendStubJS($interface);
}
@@ -301,6 +308,14 @@ sub generateFrontendFunction
}
}
+sub camelCase
+{
+ my $value = shift;
+ $value =~ s/\b(\w)/\U$1/g; # make a camel-case name for type name
+ $value =~ s/ //g;
+ return $value;
+}
+
sub generateBackendFunction
{
my $function = shift;
@@ -332,43 +347,31 @@ sub generateBackendFunction
push(@function, " protocolErrors->pushString(\"Protocol Error: $domain handler is not available.\");");
push(@function, "");
- if (scalar(@inArgs)) {
- # declare variables for all 'in' args;
- push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @inArgs));
+ # declare local variables for out arguments.
+ push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @outArgs));
- push(@function, "");
- push(@function, " RefPtr<InspectorObject> argumentsContainer;");
- push(@function, " if (!(argumentsContainer = requestMessageObject->getObject(\"arguments\"))) {");
- push(@function, " protocolErrors->pushString(\"Protocol Error: 'arguments' property with type 'object' was not found.\");");
- push(@function, " } else {");
- push(@function, " InspectorObject::const_iterator argumentsEndIterator = argumentsContainer->end();");
+ my $indent = "";
+ if (scalar(@inArgs)) {
+ push(@function, " if (RefPtr<InspectorObject> argumentsContainer = requestMessageObject->getObject(\"arguments\")) {");
foreach my $parameter (@inArgs) {
my $name = $parameter->name;
my $type = $parameter->type;
- my $variableType = $typeTransform{$type}->{"variable"};
- my $JSONType = $typeTransform{$type}->{"JSONType"};
-
- push(@function, "");
- push(@function, " InspectorObject::const_iterator ${name}ValueIterator = argumentsContainer->find(\"$name\");");
- push(@function, " if (${name}ValueIterator == argumentsEndIterator) {");
- push(@function, " protocolErrors->pushString(\"Protocol Error: Argument '$name' with type '$JSONType' was not found.\");");
- push(@function, " } else {");
- push(@function, " if (!${name}ValueIterator->second->as$JSONType(&$name)) {");
- push(@function, " protocolErrors->pushString(\"Protocol Error: Argument '$name' has wrong type. It should be '$JSONType'.\");");
- push(@function, " }");
- push(@function, " }");
+ my $typeString = camelCase($parameter->type);
+ push(@function, " " . $typeTransform{$type}->{"variable"} . " $name = get$typeString(argumentsContainer.get(), \"$name\", protocolErrors.get());");
}
- push(@function, " }");
+ push(@function, "");
+ $indent = " ";
}
- # declare local variables for out arguments.
- push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @outArgs));
-
my $args = join(", ", (map($_->name, @inArgs), map("&" . $_->name, @outArgs)));
- push(@function, " if (!protocolErrors->length())");
- push(@function, " $domainAccessor->$functionName($args);");
- push(@function, "");
+ push(@function, "$indent if (!protocolErrors->length())");
+ push(@function, "$indent $domainAccessor->$functionName($args);");
+ if (scalar(@inArgs)) {
+ push(@function, " } else {");
+ push(@function, " protocolErrors->pushString(\"Protocol Error: 'arguments' property with type 'object' was not found.\");");
+ push(@function, " }");
+ }
push(@function, " // use InspectorFrontend as a marker of WebInspector availability");
push(@function, " if ((callId || protocolErrors->length()) && m_inspectorController->hasFrontend()) {");
@@ -412,6 +415,39 @@ EOF
return split("\n", $reportProtocolError);
}
+sub generateArgumentGetters
+{
+ my $type = shift;
+ my $json = $typeTransform{$type}{"JSONType"};
+ my $variable = $typeTransform{$type}{"variable"};
+ my $defaultValue = $typeTransform{$type}{"defaultValue"};
+ my $return = $typeTransform{$type}{"return"} ? $typeTransform{$type}{"return"} : $typeTransform{$type}{"param"};
+
+ my $typeString = camelCase($type);
+ push(@backendConstantDeclarations, "$return get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors);");
+ my $getterBody = << "EOF";
+
+$return InspectorBackendDispatcher::get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors)
+{
+ ASSERT(object);
+ ASSERT(protocolErrors);
+
+ $variable value = $defaultValue;
+ InspectorObject::const_iterator end = object->end();
+ InspectorObject::const_iterator valueIterator = object->find(name);
+
+ if (valueIterator == end)
+ protocolErrors->pushString(String::format("Protocol Error: Argument '\%s' with type '$json' was not found.", name.utf8().data()));
+ else {
+ if (!valueIterator->second->as$json(&value))
+ protocolErrors->pushString(String::format("Protocol Error: Argument '\%s' has wrong type. It should be '$json'.", name.utf8().data()));
+ }
+ return value;
+}
+EOF
+
+ return split("\n", $getterBody);
+}
sub generateBackendDispatcher
{
@@ -563,6 +599,9 @@ WebInspector.InspectorBackendStub.prototype = {
request.seq = WebInspector.Callback.wrap(args[0]);
}
+ if (window.dumpInspectorProtocolMessages)
+ console.log("frontend: " + JSON.stringify(request));
+
var message = JSON.stringify(request);
InspectorFrontendHost.sendMessageToBackend(message);
}
diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp
index a5e9ec6..f1534df 100644
--- a/WebCore/inspector/ConsoleMessage.cpp
+++ b/WebCore/inspector/ConsoleMessage.cpp
@@ -40,7 +40,6 @@
#include "ScriptArguments.h"
#include "ScriptCallStack.h"
#include "ScriptValue.h"
-#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -56,7 +55,7 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, c
{
}
-ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, unsigned g)
+ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack, unsigned g)
: m_source(s)
, m_type(t)
, m_level(l)
diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h
index 4e88bec..351c584 100644
--- a/WebCore/inspector/ConsoleMessage.h
+++ b/WebCore/inspector/ConsoleMessage.h
@@ -49,7 +49,7 @@ class ScriptValue;
class ConsoleMessage : public Noncopyable {
public:
ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u, unsigned g);
- ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>, unsigned g);
+ ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack>, unsigned g);
void addToFrontend(InspectorFrontend*, InjectedScriptHost*);
void updateRepeatCountInConsole(InspectorFrontend* frontend);
@@ -64,8 +64,8 @@ private:
MessageType m_type;
MessageLevel m_level;
String m_message;
- OwnPtr<ScriptArguments> m_arguments;
- OwnPtr<ScriptCallStack> m_callStack;
+ RefPtr<ScriptArguments> m_arguments;
+ RefPtr<ScriptCallStack> m_callStack;
unsigned m_line;
String m_url;
unsigned m_groupLevel;
diff --git a/WebCore/inspector/InjectedScriptHost.idl b/WebCore/inspector/InjectedScriptHost.idl
index 9b2ed6c..5fb57b4 100644
--- a/WebCore/inspector/InjectedScriptHost.idl
+++ b/WebCore/inspector/InjectedScriptHost.idl
@@ -38,6 +38,7 @@ module core {
[Custom] DOMObject nodeForId(in long nodeId);
[Custom] int pushNodePathToFrontend(in DOMObject node, in boolean withChildren, in boolean selectInUI);
long inspectedNode(in unsigned long num);
+ [Custom] DOMObject internalConstructorName(in DOMObject object);
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
[Custom] DOMObject currentCallFrame();
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index 29a3ba0..c185d2d 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -58,10 +58,12 @@ module core {
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
[notify] void addProfileHeader(out Object header);
+ [notify] void addHeapSnapshotChunk(out unsigned long uid, out String chunk);
[notify] void attachDebuggerWhenShown();
[notify] void debuggerWasEnabled();
[notify] void debuggerWasDisabled();
[notify] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage);
+ [notify] void finishHeapSnapshot(out unsigned long uid);
[notify] void parsedScriptSource(out String sourceID, out String url, out String data, out int firstLine, out int scriptWorldType);
[notify] void pausedScript(out Object details);
[notify] void profilerWasEnabled();
@@ -113,7 +115,7 @@ module core {
[notify] void didFinishLoading(out long identifier, out double finishTime);
[notify] void didFailLoading(out long identifier, out double time, out String localizedDescription);
[notify] void didLoadResourceFromMemoryCache(out double time, out Object resource);
- [notify] void setOverrideContent(out long identifier, out String sourceString, out String type);
+ [notify] void setInitialContent(out long identifier, out String sourceString, out String type);
[notify] void didCommitLoadForFrame(out Object frame, out Object loader);
[notify] void frameDetachedFromParent(out unsigned long frameId);
@@ -213,10 +215,11 @@ module core {
[handler=CSS] void getInlineStyleForNode2(in long nodeId, out Value style);
[handler=CSS] void getAllStyles2(out Array styleSheetIds);
[handler=CSS] void getStyleSheet2(in String styleSheetId, out Value styleSheet);
- [handler=CSS] void setStyleSheetText2(in String styleSheetId, in String text);
- [handler=CSS] void setPropertyText2(in String styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style);
- [handler=CSS] void toggleProperty2(in String styleId, in long propertyIndex, in boolean disable, out Value style);
- [handler=CSS] void setRuleSelector2(in String ruleId, in String selector, out Value rule);
+ [handler=CSS] void getStyleSheetText2(in String styleSheetId, out String url, out String text);
+ [handler=CSS] void setStyleSheetText2(in String styleSheetId, in String text, out boolean success);
+ [handler=CSS] void setPropertyText2(in Object styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style);
+ [handler=CSS] void toggleProperty2(in Object styleId, in long propertyIndex, in boolean disable, out Value style);
+ [handler=CSS] void setRuleSelector2(in Object ruleId, in String selector, out Value rule);
[handler=CSS] void addRule2(in long contextNodeId, in String selector, out Value rule);
[handler=CSS] void getSupportedCSSProperties(out Array cssProperties);
[handler=CSS] void querySelectorAll(in long documentId, in String selector, out Array result);
diff --git a/WebCore/inspector/InspectorCSSAgent.cpp b/WebCore/inspector/InspectorCSSAgent.cpp
index 37bf2b3..31d951a 100644
--- a/WebCore/inspector/InspectorCSSAgent.cpp
+++ b/WebCore/inspector/InspectorCSSAgent.cpp
@@ -214,7 +214,7 @@ void InspectorCSSAgent::getStylesForNode2(long nodeId, RefPtr<InspectorValue>* r
if (parentElement->style() && parentElement->style()->length()) {
InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
if (styleSheet)
- parentStyle->setObject("inlineStyle", styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId::createFromParts(styleSheet->id(), "0"))));
+ parentStyle->setObject("inlineStyle", styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
}
CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector();
@@ -276,16 +276,29 @@ void InspectorCSSAgent::getStyleSheet2(const String& styleSheetId, RefPtr<Inspec
*styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet();
}
-void InspectorCSSAgent::setStyleSheetText2(const String& styleSheetId, const String& text)
+void InspectorCSSAgent::getStyleSheetText2(const String& styleSheetId, String* url, String* result)
{
InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(styleSheetId);
if (!inspectorStyleSheet)
return;
+ *url = inspectorStyleSheet->finalURL();
+ inspectorStyleSheet->text(result);
+}
+
+void InspectorCSSAgent::setStyleSheetText2(const String& styleSheetId, const String& text, bool* success)
+{
+ InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(styleSheetId);
+ if (!inspectorStyleSheet) {
+ *success = false;
+ return;
+ }
- inspectorStyleSheet->setText(text);
+ *success = inspectorStyleSheet->setText(text);
+ if (*success)
+ inspectorStyleSheet->reparseStyleSheet(text);
}
-void InspectorCSSAgent::setPropertyText2(const String& fullStyleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result)
+void InspectorCSSAgent::setPropertyText2(const RefPtr<InspectorObject>& fullStyleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result)
{
InspectorCSSId compoundId(fullStyleId);
ASSERT(!compoundId.isEmpty());
@@ -299,7 +312,7 @@ void InspectorCSSAgent::setPropertyText2(const String& fullStyleId, long propert
*result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
}
-void InspectorCSSAgent::toggleProperty2(const String& fullStyleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result)
+void InspectorCSSAgent::toggleProperty2(const RefPtr<InspectorObject>& fullStyleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result)
{
InspectorCSSId compoundId(fullStyleId);
ASSERT(!compoundId.isEmpty());
@@ -313,7 +326,7 @@ void InspectorCSSAgent::toggleProperty2(const String& fullStyleId, long property
*result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
}
-void InspectorCSSAgent::setRuleSelector2(const String& fullRuleId, const String& selector, RefPtr<InspectorValue>* result)
+void InspectorCSSAgent::setRuleSelector2(const RefPtr<InspectorObject>& fullRuleId, const String& selector, RefPtr<InspectorValue>* result)
{
InspectorCSSId compoundId(fullRuleId);
ASSERT(!compoundId.isEmpty());
diff --git a/WebCore/inspector/InspectorCSSAgent.h b/WebCore/inspector/InspectorCSSAgent.h
index 71ca580..2d2efb5 100644
--- a/WebCore/inspector/InspectorCSSAgent.h
+++ b/WebCore/inspector/InspectorCSSAgent.h
@@ -65,10 +65,11 @@ public:
void getComputedStyleForNode2(long nodeId, RefPtr<InspectorValue>* style);
void getAllStyles2(RefPtr<InspectorArray>* styles);
void getStyleSheet2(const String& styleSheetId, RefPtr<InspectorValue>* result);
- void setStyleSheetText2(const String& styleSheetId, const String& text);
- void setPropertyText2(const String& styleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result);
- void toggleProperty2(const String& styleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result);
- void setRuleSelector2(const String& ruleId, const String& selector, RefPtr<InspectorValue>* result);
+ void getStyleSheetText2(const String& styleSheetId, String* url, String* result);
+ void setStyleSheetText2(const String& styleSheetId, const String& text, bool* success);
+ void setPropertyText2(const RefPtr<InspectorObject>& styleId, long propertyIndex, const String& text, bool overwrite, RefPtr<InspectorValue>* result);
+ void toggleProperty2(const RefPtr<InspectorObject>& styleId, long propertyIndex, bool disable, RefPtr<InspectorValue>* result);
+ void setRuleSelector2(const RefPtr<InspectorObject>& ruleId, const String& selector, RefPtr<InspectorValue>* result);
void addRule2(const long contextNodeId, const String& selector, RefPtr<InspectorValue>* result);
void getSupportedCSSProperties(RefPtr<InspectorArray>* result);
void querySelectorAll(const long nodeId, const String& selector, RefPtr<InspectorArray>* result);
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index c47699f..ed319f3 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -330,7 +330,7 @@ void InspectorController::setConsoleMessagesEnabled(bool enabled)
m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
}
-void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack)
+void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
{
if (!enabled())
return;
@@ -381,7 +381,7 @@ void InspectorController::clearConsoleMessages()
m_frontend->consoleMessagesCleared();
}
-void InspectorController::startGroup(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, bool collapsed)
+void InspectorController::startGroup(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack, bool collapsed)
{
++m_groupLevel;
@@ -924,7 +924,7 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL);
if (m_resourceAgent)
- m_resourceAgent->setOverrideContent(identifier, sourceString, "XHR");
+ m_resourceAgent->setInitialContent(identifier, sourceString, "XHR");
}
void InspectorController::scriptImported(unsigned long identifier, const String& sourceString)
@@ -933,7 +933,7 @@ void InspectorController::scriptImported(unsigned long identifier, const String&
return;
if (m_resourceAgent)
- m_resourceAgent->setOverrideContent(identifier, sourceString, "Script");
+ m_resourceAgent->setInitialContent(identifier, sourceString, "Script");
}
void InspectorController::ensureSettingsLoaded()
@@ -1537,21 +1537,18 @@ static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, co
// of outline (because inflating a quad is hard)
{
context.save();
- context.addPath(quadPath);
context.clipOut(quadPath);
- context.addPath(quadPath);
context.setStrokeThickness(outlineThickness);
context.setStrokeColor(outlineColor, ColorSpaceDeviceRGB);
- context.strokePath();
+ context.strokePath(quadPath);
context.restore();
}
// Now do the fill
- context.addPath(quadPath);
context.setFillColor(fillColor, ColorSpaceDeviceRGB);
- context.fillPath();
+ context.fillPath(quadPath);
}
static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor)
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index ca5a9d9..5b407e0 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -146,7 +146,7 @@ public:
void disconnectFrontend();
void setConsoleMessagesEnabled(bool enabled, bool* newState);
- void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack>);
+ void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack>);
void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String&);
void clearConsoleMessages();
const Vector<OwnPtr<ConsoleMessage> >& consoleMessages() const { return m_consoleMessages; }
@@ -230,7 +230,7 @@ public:
void startTiming(const String& title);
bool stopTiming(const String& title, double& elapsed);
- void startGroup(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack> callFrame, bool collapsed = false);
+ void startGroup(PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack> callFrame, bool collapsed = false);
void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
void markTimeline(const String& message);
diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp
index ebd03e6..b3caa2e 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -30,7 +30,7 @@
#include "config.h"
#include "InspectorDebuggerAgent.h"
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#include "InjectedScript.h"
#include "InjectedScriptHost.h"
#include "InspectorFrontend.h"
@@ -335,4 +335,4 @@ void InspectorDebuggerAgent::breakProgram(DebuggerEventType type, PassRefPtr<Ins
} // namespace WebCore
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h
index 9501ac8..adc925a 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/WebCore/inspector/InspectorDebuggerAgent.h
@@ -30,7 +30,7 @@
#ifndef InspectorDebuggerAgent_h
#define InspectorDebuggerAgent_h
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#include "ScriptBreakpoint.h"
#include "ScriptDebugListener.h"
#include "ScriptState.h"
@@ -111,6 +111,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#endif // !defined(InspectorDebuggerAgent_h)
diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp
index 3f107d6..6d5364f 100644
--- a/WebCore/inspector/InspectorProfilerAgent.cpp
+++ b/WebCore/inspector/InspectorProfilerAgent.cpp
@@ -30,7 +30,7 @@
#include "config.h"
#include "InspectorProfilerAgent.h"
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#include "Console.h"
#include "InspectorController.h"
@@ -156,6 +156,21 @@ void InspectorProfilerAgent::getProfileHeaders(RefPtr<InspectorArray>* headers)
(*headers)->pushObject(createSnapshotHeader(*it->second));
}
+namespace {
+
+class OutputStream : public ScriptHeapSnapshot::OutputStream {
+public:
+ OutputStream(InspectorFrontend* frontend, unsigned long uid)
+ : m_frontend(frontend), m_uid(uid) { }
+ void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(m_uid, chunk); }
+ void Close() { m_frontend->finishHeapSnapshot(m_uid); }
+private:
+ InspectorFrontend* m_frontend;
+ unsigned long m_uid;
+};
+
+} // namespace
+
void InspectorProfilerAgent::getProfile(const String& type, unsigned uid, RefPtr<InspectorObject>* profileObject)
{
if (type == CPUProfileType) {
@@ -167,8 +182,12 @@ void InspectorProfilerAgent::getProfile(const String& type, unsigned uid, RefPtr
} else if (type == HeapProfileType) {
HeapSnapshotsMap::iterator it = m_snapshots.find(uid);
if (it != m_snapshots.end()) {
- *profileObject = createSnapshotHeader(*it->second);
- (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
+ RefPtr<ScriptHeapSnapshot> snapshot = it->second;
+ *profileObject = createSnapshotHeader(*snapshot);
+ if (m_frontend) {
+ OutputStream stream(m_frontend, uid);
+ snapshot->writeJSON(&stream);
+ }
}
}
}
@@ -259,4 +278,4 @@ void InspectorProfilerAgent::toggleRecordButton(bool isProfiling)
} // namespace WebCore
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
diff --git a/WebCore/inspector/InspectorProfilerAgent.h b/WebCore/inspector/InspectorProfilerAgent.h
index c1f5db1..e67848d 100644
--- a/WebCore/inspector/InspectorProfilerAgent.h
+++ b/WebCore/inspector/InspectorProfilerAgent.h
@@ -30,7 +30,7 @@
#ifndef InspectorProfilerAgent_h
#define InspectorProfilerAgent_h
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#include "PlatformString.h"
#include <wtf/Forward.h>
@@ -92,6 +92,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(JAVASCRIPT_DEBUGGER)
+#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
#endif // !defined(InspectorProfilerAgent_h)
diff --git a/WebCore/inspector/InspectorResourceAgent.cpp b/WebCore/inspector/InspectorResourceAgent.cpp
index fcdebbc..9dab24a 100644
--- a/WebCore/inspector/InspectorResourceAgent.cpp
+++ b/WebCore/inspector/InspectorResourceAgent.cpp
@@ -193,11 +193,13 @@ static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const Resource
responseObject->setBoolean("wasCached", response.wasCached());
if (response.resourceLoadTiming())
responseObject->setObject("timing", buildObjectForTiming(*response.resourceLoadTiming()));
- if (response.resourceRawHeaders()) {
- RefPtr<InspectorObject> rawHeadersObject = InspectorObject::create();
- rawHeadersObject->setObject("requestHeaders", buildObjectForHeaders(response.resourceRawHeaders()->requestHeaders));
- rawHeadersObject->setObject("responseHeaders", buildObjectForHeaders(response.resourceRawHeaders()->responseHeaders));
- responseObject->setObject("rawHeaders", rawHeadersObject);
+ if (response.resourceLoadInfo()) {
+ RefPtr<InspectorObject> loadInfoObject = InspectorObject::create();
+ loadInfoObject->setNumber("httpStatusCode", response.resourceLoadInfo()->httpStatusCode);
+ loadInfoObject->setString("httpStatusText", response.resourceLoadInfo()->httpStatusText);
+ loadInfoObject->setObject("requestHeaders", buildObjectForHeaders(response.resourceLoadInfo()->requestHeaders));
+ loadInfoObject->setObject("responseHeaders", buildObjectForHeaders(response.resourceLoadInfo()->responseHeaders));
+ responseObject->setObject("loadInfo", loadInfoObject);
}
return responseObject;
}
@@ -342,9 +344,9 @@ void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* load
m_frontend->didLoadResourceFromMemoryCache(currentTime(), buildObjectForCachedResource(loader, *resource));
}
-void InspectorResourceAgent::setOverrideContent(unsigned long identifier, const String& sourceString, const String& type)
+void InspectorResourceAgent::setInitialContent(unsigned long identifier, const String& sourceString, const String& type)
{
- m_frontend->setOverrideContent(identifier, sourceString, type);
+ m_frontend->setInitialContent(identifier, sourceString, type);
}
static PassRefPtr<InspectorObject> buildObjectForFrame(Frame* frame)
diff --git a/WebCore/inspector/InspectorResourceAgent.h b/WebCore/inspector/InspectorResourceAgent.h
index e3153bf..1e77d58 100644
--- a/WebCore/inspector/InspectorResourceAgent.h
+++ b/WebCore/inspector/InspectorResourceAgent.h
@@ -85,7 +85,7 @@ public:
void didFinishLoading(unsigned long identifier, double finishTime);
void didFailLoading(unsigned long identifier, const ResourceError&);
void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
- void setOverrideContent(unsigned long identifier, const String& sourceString, const String& type);
+ void setInitialContent(unsigned long identifier, const String& sourceString, const String& type);
void didCommitLoad(DocumentLoader*);
void frameDetachedFromParent(Frame*);
diff --git a/WebCore/inspector/InspectorStyleSheet.cpp b/WebCore/inspector/InspectorStyleSheet.cpp
index 2384795..eb1538f 100644
--- a/WebCore/inspector/InspectorStyleSheet.cpp
+++ b/WebCore/inspector/InspectorStyleSheet.cpp
@@ -27,6 +27,8 @@
#if ENABLE(INSPECTOR)
+#include "CSSImportRule.h"
+#include "CSSMediaRule.h"
#include "CSSParser.h"
#include "CSSPropertySourceData.h"
#include "CSSRule.h"
@@ -43,6 +45,7 @@
#include "InspectorValues.h"
#include "Node.h"
#include "StyleSheetList.h"
+#include "WebKitCSSKeyframesRule.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -99,11 +102,40 @@ RefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned i
namespace WebCore {
+static PassRefPtr<CSSRuleList> asCSSRuleList(StyleBase* styleBase)
+{
+ if (!styleBase)
+ return 0;
+
+ if (styleBase->isCSSStyleSheet())
+ return CSSRuleList::create(static_cast<CSSStyleSheet*>(styleBase), true);
+ if (styleBase->isRule()) {
+ unsigned ruleType = static_cast<CSSRule*>(styleBase)->type();
+ RefPtr<CSSRuleList> result = 0;
+
+ switch (ruleType) {
+ case CSSRule::MEDIA_RULE:
+ result = static_cast<CSSMediaRule*>(styleBase)->cssRules();
+ break;
+ case CSSRule::WEBKIT_KEYFRAMES_RULE:
+ result = static_cast<WebKitCSSKeyframesRule*>(styleBase)->cssRules();
+ break;
+ case CSSRule::IMPORT_RULE:
+ case CSSRule::PAGE_RULE:
+ default:
+ return 0;
+ }
+
+ return result.release();
+ }
+ return 0;
+}
+
PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
{
RefPtr<InspectorObject> result = InspectorObject::create();
if (!m_styleId.isEmpty())
- result->setString("styleId", m_styleId.asString());
+ result->setValue("styleId", m_styleId.asInspectorValue());
RefPtr<InspectorObject> propertiesObject = InspectorObject::create();
propertiesObject->setString("width", m_style->getPropertyValue("width"));
@@ -146,7 +178,9 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
p.parseDeclaration(tempMutableStyle.get(), propertyText + " -webkit-boguz-propertee: none", &sourceData);
Vector<CSSPropertySourceData>& propertyData = sourceData->propertyData;
unsigned propertyCount = propertyData.size();
- if (!propertyCount)
+
+ // At least one property + the bogus property added just above should be present.
+ if (propertyCount < 2)
return false;
// Check for a proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
@@ -412,12 +446,27 @@ void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result)
property->setNumber("startOffset", propertyEntry.range.start);
property->setNumber("endOffset", propertyEntry.range.end);
+ // Parsed property overrides any property with the same name. Non-parsed property overrides
+ // previous non-parsed property with the same name (if any).
+ bool shouldInactivate = false;
HashMap<String, RefPtr<InspectorObject> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(name);
if (activeIt != propertyNameToPreviousActiveProperty.end()) {
+ if (propertyEntry.parsedOk)
+ shouldInactivate = true;
+ else {
+ bool previousParsedOk;
+ bool success = activeIt->second->getBoolean("parsedOk", &previousParsedOk);
+ if (success && !previousParsedOk)
+ shouldInactivate = true;
+ }
+ } else
+ propertyNameToPreviousActiveProperty.set(name, property);
+
+ if (shouldInactivate) {
activeIt->second->setString("status", "inactive");
activeIt->second->setString("shorthandName", "");
+ propertyNameToPreviousActiveProperty.set(name, property);
}
- propertyNameToPreviousActiveProperty.set(name, property);
} else {
property->setBoolean("implicit", m_style->isPropertyImplicit(name));
property->setString("status", "style");
@@ -529,17 +578,30 @@ InspectorStyleSheet::~InspectorStyleSheet()
delete m_parsedStyleSheet;
}
+String InspectorStyleSheet::finalURL() const
+{
+ if (m_pageStyleSheet && !m_pageStyleSheet->finalURL().isEmpty())
+ return m_pageStyleSheet->finalURL().string();
+ return m_documentURL;
+}
+
+void InspectorStyleSheet::reparseStyleSheet(const String& text)
+{
+ for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i)
+ m_pageStyleSheet->remove(i);
+ m_pageStyleSheet->parseString(text, m_pageStyleSheet->useStrictParsing());
+ m_pageStyleSheet->styleSheetChanged();
+ m_inspectorStyles.clear();
+}
+
bool InspectorStyleSheet::setText(const String& text)
{
if (!m_parsedStyleSheet)
return false;
m_parsedStyleSheet->setText(text);
- for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i)
- m_pageStyleSheet->remove(i);
- m_inspectorStyles.clear();
+ m_flatRules.clear();
- m_pageStyleSheet->parseString(text, m_pageStyleSheet->useStrictParsing());
return true;
}
@@ -584,7 +646,8 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector)
styleSheetText += selector;
styleSheetText += " {}";
- m_parsedStyleSheet->setText(styleSheetText);
+ // Using setText() as this operation changes the style sheet rule set.
+ setText(styleSheetText);
return rule;
}
@@ -595,22 +658,9 @@ CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const
return 0;
ASSERT(!id.isEmpty());
- bool ok;
- unsigned index = id.ordinal().toUInt(&ok);
- if (!ok)
- return 0;
+ ensureFlatRules();
+ return id.ordinal() >= m_flatRules.size() ? 0 : m_flatRules.at(id.ordinal());
- unsigned currentIndex = 0;
- for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i) {
- CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(m_pageStyleSheet->item(i));
- if (!rule)
- continue;
- if (index == currentIndex)
- return rule;
-
- ++currentIndex;
- }
- return 0;
}
PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyleSheet()
@@ -621,7 +671,7 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyleSheet()
RefPtr<InspectorObject> result = InspectorObject::create();
result->setBoolean("disabled", styleSheet->disabled());
- result->setString("sourceURL", styleSheet->href());
+ result->setString("sourceURL", finalURL());
result->setString("title", styleSheet->title());
RefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true);
RefPtr<InspectorArray> cssRules = buildArrayForRuleList(cssRuleList.get());
@@ -647,13 +697,16 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForRule(CSSStyleRule
result->setString("selectorText", rule->selectorText());
// "sourceURL" is present only for regular rules, otherwise "origin" should be used in the frontend.
if (!m_origin.length())
- result->setString("sourceURL", !styleSheet->href().isEmpty() ? styleSheet->href() : m_documentURL);
+ result->setString("sourceURL", finalURL());
result->setNumber("sourceLine", rule->sourceLine());
result->setString("origin", m_origin);
result->setObject("style", buildObjectForStyle(rule->style()));
- if (canBind())
- result->setString("ruleId", ruleId(rule).asString());
+ if (canBind()) {
+ InspectorCSSId id(ruleId(rule));
+ if (!id.isEmpty())
+ result->setValue("ruleId", id.asInspectorValue());
+ }
RefPtr<CSSRuleSourceData> sourceData;
if (ensureParsedDataReady())
@@ -674,7 +727,15 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyle(CSSStyleDec
if (ensureParsedDataReady())
sourceData = ruleSourceDataFor(style);
- RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(ruleOrStyleId(style));
+ InspectorCSSId id = ruleOrStyleId(style);
+ if (id.isEmpty()) {
+ RefPtr<InspectorObject> bogusStyle = InspectorObject::create();
+ bogusStyle->setArray("cssProperties", InspectorArray::create());
+ bogusStyle->setObject("shorthandValues", InspectorObject::create());
+ bogusStyle->setObject("properties", InspectorObject::create());
+ return bogusStyle.release();
+ }
+ RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
RefPtr<InspectorObject> result = inspectorStyle->buildObjectForStyle();
// Style text cannot be retrieved without stylesheet, so set cssText here.
@@ -715,6 +776,14 @@ bool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned prop
return success;
}
+bool InspectorStyleSheet::text(String* result) const
+{
+ if (!ensureText())
+ return false;
+ *result = m_parsedStyleSheet->text();
+ return true;
+}
+
CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) const
{
CSSStyleRule* rule = ruleForId(id);
@@ -752,55 +821,10 @@ InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) co
{
unsigned index = ruleIndexByStyle(style);
if (index != UINT_MAX)
- return InspectorCSSId::createFromParts(id(), String::number(index));
+ return InspectorCSSId(id(), index);
return InspectorCSSId();
}
-void InspectorStyleSheet::fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText)
-{
- Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
- unsigned size = propertyData.size();
- if (!size)
- return;
-
- unsigned styleStart = ruleData->styleSourceData->styleBodyRange.start;
- const UChar* characters = styleSheetText.characters();
- CSSPropertySourceData* nextData = &(propertyData.at(0));
- for (unsigned i = 0; i < size; ++i) {
- CSSPropertySourceData* currentData = nextData;
- nextData = i < size - 1 ? &(propertyData.at(i + 1)) : 0;
-
- if (currentData->parsedOk)
- continue;
- if (currentData->range.end > 0 && characters[styleStart + currentData->range.end - 1] == ';')
- continue;
-
- unsigned propertyEndInStyleSheet;
- if (!nextData)
- propertyEndInStyleSheet = ruleData->styleSourceData->styleBodyRange.end - 1;
- else
- propertyEndInStyleSheet = styleStart + nextData->range.start - 1;
-
- while (isHTMLSpace(characters[propertyEndInStyleSheet]))
- --propertyEndInStyleSheet;
-
- // propertyEndInStyleSheet points at the last property text character.
- unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
- if (currentData->range.end != newPropertyEnd) {
- currentData->range.end = newPropertyEnd;
- unsigned valueStartInStyleSheet = styleStart + currentData->range.start + currentData->name.length();
- while (valueStartInStyleSheet < propertyEndInStyleSheet && characters[valueStartInStyleSheet] != ':')
- ++valueStartInStyleSheet;
- if (valueStartInStyleSheet < propertyEndInStyleSheet)
- ++valueStartInStyleSheet; // Shift past the ':'.
- while (valueStartInStyleSheet < propertyEndInStyleSheet && isHTMLSpace(characters[valueStartInStyleSheet]))
- ++valueStartInStyleSheet;
- // Need to exclude the trailing ';' from the property value.
- currentData->value = styleSheetText.substring(valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
- }
- }
-}
-
Document* InspectorStyleSheet::ownerDocument() const
{
return m_pageStyleSheet->document();
@@ -813,12 +837,10 @@ RefPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataFor(CSSStyleDeclara
unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) const
{
+ ensureFlatRules();
unsigned index = 0;
- for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i) {
- CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(m_pageStyleSheet->item(i));
- if (!rule)
- continue;
- if (rule->style() == pageStyle)
+ for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
+ if (m_flatRules.at(i)->style() == pageStyle)
return index;
++index;
@@ -828,15 +850,7 @@ unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) c
bool InspectorStyleSheet::ensureParsedDataReady()
{
- return ensureText() && ensureSourceData(pageStyleSheet()->ownerNode());
-}
-
-bool InspectorStyleSheet::text(String* result) const
-{
- if (!ensureText())
- return false;
- *result = m_parsedStyleSheet->text();
- return true;
+ return ensureText() && ensureSourceData();
}
bool InspectorStyleSheet::ensureText() const
@@ -850,11 +864,12 @@ bool InspectorStyleSheet::ensureText() const
bool success = originalStyleSheetText(&text);
if (success)
m_parsedStyleSheet->setText(text);
+ // No need to clear m_flatRules here - it's empty.
return success;
}
-bool InspectorStyleSheet::ensureSourceData(Node* ownerNode)
+bool InspectorStyleSheet::ensureSourceData()
{
if (m_parsedStyleSheet->hasSourceData())
return true;
@@ -862,17 +877,17 @@ bool InspectorStyleSheet::ensureSourceData(Node* ownerNode)
if (!m_parsedStyleSheet->hasText())
return false;
- RefPtr<CSSStyleSheet> newStyleSheet = CSSStyleSheet::create(ownerNode);
+ RefPtr<CSSStyleSheet> newStyleSheet = CSSStyleSheet::create();
CSSParser p;
StyleRuleRangeMap ruleRangeMap;
p.parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), 0, &ruleRangeMap);
OwnPtr<ParsedStyleSheet::SourceData> rangesVector(new ParsedStyleSheet::SourceData());
- for (unsigned i = 0, length = newStyleSheet->length(); i < length; ++i) {
- CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(newStyleSheet->item(i));
- if (!rule)
- continue;
- StyleRuleRangeMap::iterator it = ruleRangeMap.find(rule);
+ Vector<CSSStyleRule*> rules;
+ RefPtr<CSSRuleList> ruleList = asCSSRuleList(newStyleSheet.get());
+ collectFlatRules(ruleList, &rules);
+ for (unsigned i = 0, size = rules.size(); i < size; ++i) {
+ StyleRuleRangeMap::iterator it = ruleRangeMap.find(rules.at(i));
if (it != ruleRangeMap.end()) {
fixUnparsedPropertyRanges(it->second.get(), m_parsedStyleSheet->text());
rangesVector->append(it->second);
@@ -883,6 +898,13 @@ bool InspectorStyleSheet::ensureSourceData(Node* ownerNode)
return m_parsedStyleSheet->hasSourceData();
}
+void InspectorStyleSheet::ensureFlatRules() const
+{
+ // We are fine with redoing this for empty stylesheets as this will run fast.
+ if (m_flatRules.isEmpty())
+ collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules);
+}
+
bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text)
{
if (!pageStyleSheet())
@@ -928,18 +950,6 @@ bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* st
return true;
}
-CSSStyleRule* InspectorStyleSheet::findPageRuleWithStyle(CSSStyleDeclaration* style)
-{
- for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i) {
- CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(m_pageStyleSheet->item(i));
- if (!rule)
- continue;
- if (rule->style() == style)
- return rule;
- }
- return 0;
-}
-
InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const
{
return ruleOrStyleId(rule->style());
@@ -951,12 +961,9 @@ void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle)
return;
m_isRevalidating = true;
- CSSStyleSheet* parsedSheet = m_parsedStyleSheet->cssStyleSheet();
- for (unsigned i = 0, size = parsedSheet->length(); i < size; ++i) {
- StyleBase* styleBase = parsedSheet->item(i);
- CSSStyleRule* parsedRule = InspectorCSSAgent::asCSSStyleRule(styleBase);
- if (!parsedRule)
- continue;
+ ensureFlatRules();
+ for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
+ CSSStyleRule* parsedRule = m_flatRules.at(i);
if (parsedRule->style() == pageStyle) {
if (parsedRule->style()->cssText() != pageStyle->cssText()) {
// Clear the disabled properties for the invalid style here.
@@ -982,6 +989,9 @@ bool InspectorStyleSheet::originalStyleSheetText(String* result) const
bool InspectorStyleSheet::resourceStyleSheetText(String* result) const
{
+ if (m_origin == "user" || m_origin == "user-agent")
+ return false;
+
if (!m_pageStyleSheet || !ownerDocument())
return false;
@@ -1009,16 +1019,78 @@ PassRefPtr<InspectorArray> InspectorStyleSheet::buildArrayForRuleList(CSSRuleLis
if (!ruleList)
return result.release();
- for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
- CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(ruleList->item(i));
- if (!rule)
+ RefPtr<CSSRuleList> refRuleList = ruleList;
+ Vector<CSSStyleRule*> rules;
+ collectFlatRules(refRuleList, &rules);
+
+ for (unsigned i = 0, size = rules.size(); i < size; ++i)
+ result->pushObject(buildObjectForRule(rules.at(i)));
+
+ return result.release();
+}
+
+void InspectorStyleSheet::fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText)
+{
+ Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
+ unsigned size = propertyData.size();
+ if (!size)
+ return;
+
+ unsigned styleStart = ruleData->styleSourceData->styleBodyRange.start;
+ const UChar* characters = styleSheetText.characters();
+ CSSPropertySourceData* nextData = &(propertyData.at(0));
+ for (unsigned i = 0; i < size; ++i) {
+ CSSPropertySourceData* currentData = nextData;
+ nextData = i < size - 1 ? &(propertyData.at(i + 1)) : 0;
+
+ if (currentData->parsedOk)
+ continue;
+ if (currentData->range.end > 0 && characters[styleStart + currentData->range.end - 1] == ';')
continue;
- result->pushObject(buildObjectForRule(rule));
+ unsigned propertyEndInStyleSheet;
+ if (!nextData)
+ propertyEndInStyleSheet = ruleData->styleSourceData->styleBodyRange.end - 1;
+ else
+ propertyEndInStyleSheet = styleStart + nextData->range.start - 1;
+
+ while (isHTMLSpace(characters[propertyEndInStyleSheet]))
+ --propertyEndInStyleSheet;
+
+ // propertyEndInStyleSheet points at the last property text character.
+ unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
+ if (currentData->range.end != newPropertyEnd) {
+ currentData->range.end = newPropertyEnd;
+ unsigned valueStartInStyleSheet = styleStart + currentData->range.start + currentData->name.length();
+ while (valueStartInStyleSheet < propertyEndInStyleSheet && characters[valueStartInStyleSheet] != ':')
+ ++valueStartInStyleSheet;
+ if (valueStartInStyleSheet < propertyEndInStyleSheet)
+ ++valueStartInStyleSheet; // Shift past the ':'.
+ while (valueStartInStyleSheet < propertyEndInStyleSheet && isHTMLSpace(characters[valueStartInStyleSheet]))
+ ++valueStartInStyleSheet;
+ // Need to exclude the trailing ';' from the property value.
+ currentData->value = styleSheetText.substring(valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
+ }
}
- return result.release();
}
+void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, Vector<CSSStyleRule*>* result)
+{
+ if (!ruleList)
+ return;
+
+ for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
+ CSSRule* rule = ruleList->item(i);
+ CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(rule);
+ if (styleRule)
+ result->append(styleRule);
+ else {
+ RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
+ if (childRuleList)
+ collectFlatRules(childRuleList, result);
+ }
+ }
+}
InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin)
: InspectorStyleSheet(id, 0, origin, "")
@@ -1026,7 +1098,13 @@ InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const Strin
, m_ruleSourceData(0)
{
ASSERT(element);
- m_inspectorStyle = InspectorStyle::create(InspectorCSSId::createFromParts(id, "0"), inlineStyle(), this);
+ m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id, 0), inlineStyle(), this);
+}
+
+bool InspectorStyleSheetForInlineStyle::text(String* result) const
+{
+ *result = m_element->getAttribute("style");
+ return true;
}
bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text)
@@ -1038,12 +1116,6 @@ bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style,
return !ec;
}
-bool InspectorStyleSheetForInlineStyle::text(String* result) const
-{
- *result = m_element->getAttribute("style");
- return true;
-}
-
Document* InspectorStyleSheetForInlineStyle::ownerDocument() const
{
return m_element->document();
@@ -1066,7 +1138,7 @@ bool InspectorStyleSheetForInlineStyle::ensureParsedDataReady()
PassRefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id)
{
- ASSERT_UNUSED(id, id.ordinal() == "0");
+ ASSERT_UNUSED(id, !id.ordinal());
return m_inspectorStyle;
}
diff --git a/WebCore/inspector/InspectorStyleSheet.h b/WebCore/inspector/InspectorStyleSheet.h
index e671834..b649bed 100644
--- a/WebCore/inspector/InspectorStyleSheet.h
+++ b/WebCore/inspector/InspectorStyleSheet.h
@@ -51,28 +51,43 @@ class Node;
class InspectorCSSId {
public:
- static InspectorCSSId createFromParts(const String& styleSheetId, const String& ordinal) { return InspectorCSSId(styleSheetId + ":" + ordinal); }
-
InspectorCSSId() { }
- explicit InspectorCSSId(const String& id)
+
+ explicit InspectorCSSId(RefPtr<InspectorObject> value)
+ {
+ if (!value->getString("styleSheetId", &m_styleSheetId))
+ return;
+
+ RefPtr<InspectorValue> ordinalValue = value->get("ordinal");
+ if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal))
+ m_styleSheetId = "";
+ }
+
+ InspectorCSSId(const String& styleSheetId, unsigned ordinal)
+ : m_styleSheetId(styleSheetId)
+ , m_ordinal(ordinal)
{
- id.split(':', m_idParts);
- ASSERT(m_idParts.size() == 2);
}
- const String& styleSheetId() const { ASSERT(m_idParts.size() == 2); return m_idParts.at(0); }
- const String& ordinal() const { ASSERT(m_idParts.size() == 2); return m_idParts.at(1); }
- bool isEmpty() const { return m_idParts.isEmpty(); }
- String asString() const
+ bool isEmpty() const { return m_styleSheetId.isEmpty(); }
+
+ const String& styleSheetId() const { return m_styleSheetId; }
+ unsigned ordinal() const { return m_ordinal; }
+
+ PassRefPtr<InspectorValue> asInspectorValue() const
{
if (isEmpty())
- return String();
+ return InspectorValue::null();
- return m_idParts.at(0) + ":" + m_idParts.at(1);
+ RefPtr<InspectorObject> result = InspectorObject::create();
+ result->setString("styleSheetId", m_styleSheetId);
+ result->setNumber("ordinal", m_ordinal);
+ return result.release();
}
private:
- Vector<String> m_idParts;
+ String m_styleSheetId;
+ unsigned m_ordinal;
};
struct InspectorStyleProperty {
@@ -156,8 +171,10 @@ public:
InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL);
virtual ~InspectorStyleSheet();
- const String& id() const { return m_id; }
+ String id() const { return m_id; }
+ String finalURL() const;
CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet; }
+ void reparseStyleSheet(const String&);
bool setText(const String&);
bool setRuleSelector(const InspectorCSSId&, const String& selector);
CSSStyleRule* addRule(const String& selector);
@@ -168,13 +185,12 @@ public:
bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite);
bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable);
+ virtual bool text(String* result) const;
virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
protected:
bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; }
InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
- void fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText);
- virtual bool text(String* result) const;
virtual Document* ownerDocument() const;
virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const;
virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
@@ -187,10 +203,12 @@ protected:
virtual bool setStyleText(CSSStyleDeclaration*, const String&);
private:
+ static void fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText);
+ static void collectFlatRules(PassRefPtr<CSSRuleList>, Vector<CSSStyleRule*>* result);
bool ensureText() const;
- bool ensureSourceData(Node* ownerNode);
+ bool ensureSourceData();
+ void ensureFlatRules() const;
bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
- CSSStyleRule* findPageRuleWithStyle(CSSStyleDeclaration*);
InspectorCSSId ruleId(CSSStyleRule* rule) const;
InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
void revalidateStyle(CSSStyleDeclaration*);
@@ -199,7 +217,6 @@ private:
bool inlineStyleSheetText(String* result) const;
PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*);
-
String m_id;
CSSStyleSheet* m_pageStyleSheet;
String m_origin;
@@ -207,6 +224,7 @@ private:
bool m_isRevalidating;
ParsedStyleSheet* m_parsedStyleSheet;
InspectorStyleMap m_inspectorStyles;
+ mutable Vector<CSSStyleRule*> m_flatRules;
friend class InspectorStyle;
};
@@ -219,10 +237,10 @@ public:
}
InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin);
- virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, id.ordinal() == "0"); return inlineStyle(); }
+ virtual bool text(String* result) const;
+ virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
protected:
- virtual bool text(String* result) const;
virtual Document* ownerDocument() const;
virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
diff --git a/WebCore/inspector/ScriptArguments.cpp b/WebCore/inspector/ScriptArguments.cpp
index e30e135..b0fe554 100644
--- a/WebCore/inspector/ScriptArguments.cpp
+++ b/WebCore/inspector/ScriptArguments.cpp
@@ -35,6 +35,11 @@
namespace WebCore {
+PassRefPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments)
+{
+ return adoptRef(new ScriptArguments(scriptState, arguments));
+}
+
ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>& arguments)
: m_scriptState(scriptState)
{
diff --git a/WebCore/inspector/ScriptArguments.h b/WebCore/inspector/ScriptArguments.h
index fdf05ab..26549b6 100644
--- a/WebCore/inspector/ScriptArguments.h
+++ b/WebCore/inspector/ScriptArguments.h
@@ -33,15 +33,18 @@
#include "PlatformString.h"
#include "ScriptState.h"
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
class ScriptValue;
-class ScriptArguments {
+class ScriptArguments : public RefCounted<ScriptArguments> {
public:
- ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments);
+ static PassRefPtr<ScriptArguments> create(ScriptState*, Vector<ScriptValue>& arguments);
+
~ScriptArguments();
const ScriptValue& argumentAt(size_t) const;
@@ -53,6 +56,8 @@ public:
bool isEqual(ScriptArguments*) const;
private:
+ ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments);
+
ScriptStateProtectedPtr m_scriptState;
Vector<ScriptValue> m_arguments;
};
diff --git a/WebCore/inspector/ScriptBreakpoint.h b/WebCore/inspector/ScriptBreakpoint.h
index b7c7a37..d8ac762 100644
--- a/WebCore/inspector/ScriptBreakpoint.h
+++ b/WebCore/inspector/ScriptBreakpoint.h
@@ -54,8 +54,10 @@ struct ScriptBreakpoint {
bool enabled;
String condition;
+#if ENABLE(INSPECTOR)
static void sourceBreakpointsFromInspectorObject(PassRefPtr<InspectorObject>, SourceBreakpoints*);
static PassRefPtr<InspectorObject> inspectorObjectFromSourceBreakpoints(const SourceBreakpoints&);
+#endif
};
} // namespace WebCore
diff --git a/WebCore/inspector/ScriptCallFrame.h b/WebCore/inspector/ScriptCallFrame.h
index 60d77e1..2a1f257 100644
--- a/WebCore/inspector/ScriptCallFrame.h
+++ b/WebCore/inspector/ScriptCallFrame.h
@@ -32,7 +32,7 @@
#define ScriptCallFrame_h
#include "PlatformString.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/Forward.h>
namespace WebCore {
diff --git a/WebCore/inspector/ScriptCallStack.cpp b/WebCore/inspector/ScriptCallStack.cpp
index 31ec1c1..70229e5 100644
--- a/WebCore/inspector/ScriptCallStack.cpp
+++ b/WebCore/inspector/ScriptCallStack.cpp
@@ -35,6 +35,11 @@
namespace WebCore {
+PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
+{
+ return adoptRef(new ScriptCallStack(frames));
+}
+
ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames)
{
m_frames.swap(frames);
@@ -44,13 +49,13 @@ ScriptCallStack::~ScriptCallStack()
{
}
-const ScriptCallFrame &ScriptCallStack::at(size_t index)
+const ScriptCallFrame &ScriptCallStack::at(size_t index) const
{
ASSERT(m_frames.size() > index);
return m_frames[index];
}
-size_t ScriptCallStack::size()
+size_t ScriptCallStack::size() const
{
return m_frames.size();
}
diff --git a/WebCore/inspector/ScriptCallStack.h b/WebCore/inspector/ScriptCallStack.h
index 54c6bba..36ea670 100644
--- a/WebCore/inspector/ScriptCallStack.h
+++ b/WebCore/inspector/ScriptCallStack.h
@@ -32,28 +32,32 @@
#define ScriptCallStack_h
#include "ScriptCallFrame.h"
-#include <wtf/Noncopyable.h>
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
class InspectorArray;
-class ScriptCallStack : public Noncopyable {
+class ScriptCallStack : public RefCounted<ScriptCallStack> {
public:
static const size_t maxCallStackSizeToCapture = 200;
+
+ static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&);
- ScriptCallStack(Vector<ScriptCallFrame>&);
~ScriptCallStack();
- const ScriptCallFrame &at(size_t);
- size_t size();
+ const ScriptCallFrame &at(size_t) const;
+ size_t size() const;
static bool stackTrace(int, const RefPtr<InspectorArray>&);
bool isEqual(ScriptCallStack*) const;
PassRefPtr<InspectorArray> buildInspectorObject() const;
private:
+ ScriptCallStack(Vector<ScriptCallFrame>&);
+
Vector<ScriptCallFrame> m_frames;
};
diff --git a/WebCore/inspector/front-end/AuditRules.js b/WebCore/inspector/front-end/AuditRules.js
index b78bc96..cd1b34f 100644
--- a/WebCore/inspector/front-end/AuditRules.js
+++ b/WebCore/inspector/front-end/AuditRules.js
@@ -326,7 +326,9 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
if (!unusedRules.length)
continue;
- var url = styleSheet.sourceURL ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal);
+ var resource = WebInspector.resourceManager.resourceForURL(styleSheet.sourceURL);
+ var isInlineBlock = resource && resource.type == WebInspector.Resource.Type.Document;
+ var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal);
var pctUnused = Math.round(100 * unusedStylesheetSize / stylesheetSize);
if (!summary)
summary = result.addChild("", true);
diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js
index c3429fd..23ed7a8 100644
--- a/WebCore/inspector/front-end/CSSStyleModel.js
+++ b/WebCore/inspector/front-end/CSSStyleModel.js
@@ -117,7 +117,9 @@ WebInspector.CSSStyleModel.prototype = {
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
- successCallback(WebInspector.CSSRule.parsePayload(rulePayload), doesAffectSelectedNode);
+ var rule = WebInspector.CSSRule.parsePayload(rulePayload);
+ successCallback(rule, doesAffectSelectedNode);
+ this._styleSheetChanged(rule.id.styleSheetId, true);
}
function callback(nodeId, successCallback, failureCallback, newSelector, rulePayload)
@@ -125,10 +127,10 @@ WebInspector.CSSStyleModel.prototype = {
if (!rulePayload)
failureCallback();
else
- InspectorBackend.querySelectorAll(nodeId, newSelector, checkAffectsCallback.bind(null, nodeId, successCallback, rulePayload));
+ InspectorBackend.querySelectorAll(nodeId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}
- InspectorBackend.setRuleSelector2(ruleId, newSelector, callback.bind(null, nodeId, successCallback, failureCallback));
+ InspectorBackend.setRuleSelector2(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback));
},
addRule: function(nodeId, selector, successCallback, failureCallback)
@@ -136,7 +138,9 @@ WebInspector.CSSStyleModel.prototype = {
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
- successCallback(WebInspector.CSSRule.parsePayload(rulePayload), doesAffectSelectedNode);
+ var rule = WebInspector.CSSRule.parsePayload(rulePayload);
+ successCallback(rule, doesAffectSelectedNode);
+ this._styleSheetChanged(rule.id.styleSheetId, true);
}
function callback(successCallback, failureCallback, selector, rulePayload)
@@ -145,10 +149,33 @@ WebInspector.CSSStyleModel.prototype = {
// Invalid syntax for a selector
failureCallback();
} else
- InspectorBackend.querySelectorAll(nodeId, selector, checkAffectsCallback.bind(null, nodeId, successCallback, rulePayload));
+ InspectorBackend.querySelectorAll(nodeId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}
- InspectorBackend.addRule2(nodeId, selector, callback.bind(null, successCallback, failureCallback, selector));
+ InspectorBackend.addRule2(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
+ },
+
+ _styleSheetChanged: function(styleSheetId, majorChange)
+ {
+ if (!majorChange || !styleSheetId)
+ return;
+
+ function callback(href, content)
+ {
+ var resource = WebInspector.resourceManager.resourceForURL(href);
+ if (resource && resource.type === WebInspector.Resource.Type.Stylesheet)
+ resource.setContent(content, this._onRevert.bind(this, styleSheetId));
+ }
+ InspectorBackend.getStyleSheetText2(styleSheetId, callback.bind(this));
+ },
+
+ _onRevert: function(styleSheetId, contentToRevertTo)
+ {
+ function callback(success)
+ {
+ this._styleSheetChanged(styleSheetId, true);
+ }
+ InspectorBackend.setStyleSheetText2(styleSheetId, contentToRevertTo, callback.bind(this));
}
}
@@ -312,8 +339,10 @@ WebInspector.CSSStyleDeclaration.prototype = {
if (!payload)
userCallback(null);
- else
+ else {
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
+ WebInspector.cssModel._styleSheetChanged(this.id.styleSheetId, true);
+ }
}
InspectorBackend.setPropertyText2(this.id, index, name + ": " + value + ";", false, callback.bind(null, userCallback));
@@ -422,9 +451,9 @@ WebInspector.CSSProperty.prototype = {
},
// Replaces "propertyName: propertyValue [!important];" in the stylesheet by an arbitrary propertyText.
- setText: function(propertyText, userCallback)
+ setText: function(propertyText, majorChange, userCallback)
{
- function callback(userCallback, stylePayload)
+ function callback(stylePayload)
{
if (stylePayload)
this.text = propertyText;
@@ -436,6 +465,7 @@ WebInspector.CSSProperty.prototype = {
else {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
+ WebInspector.cssModel._styleSheetChanged(style.id.styleSheetId, majorChange);
}
}
@@ -443,7 +473,7 @@ WebInspector.CSSProperty.prototype = {
throw "No ownerStyle for property";
// An index past all the properties adds a new property to the style.
- InspectorBackend.setPropertyText2(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this, userCallback));
+ InspectorBackend.setPropertyText2(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this));
},
setValue: function(newValue, userCallback)
@@ -459,7 +489,7 @@ WebInspector.CSSProperty.prototype = {
if (disabled === this.disabled && userCallback)
userCallback(this.ownerStyle);
- function callback(userCallback, stylePayload)
+ function callback(stylePayload)
{
if (!userCallback)
return;
@@ -468,10 +498,11 @@ WebInspector.CSSProperty.prototype = {
else {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
+ WebInspector.cssModel._styleSheetChanged(this.ownerStyle.id.styleSheetId, false);
}
}
- InspectorBackend.toggleProperty2(this.ownerStyle.id, this.index, disabled, callback.bind(this, userCallback));
+ InspectorBackend.toggleProperty2(this.ownerStyle.id, this.index, disabled, callback.bind(this));
}
}
@@ -495,14 +526,14 @@ WebInspector.CSSStyleSheet = function(payload)
WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
{
- function callback(userCallback, styleSheetPayload)
+ function callback(styleSheetPayload)
{
if (!styleSheetPayload)
userCallback(null);
else
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
}
- InspectorBackend.getStyleSheet2(styleSheetId, callback.bind(this, userCallback));
+ InspectorBackend.getStyleSheet2(styleSheetId, callback.bind(this));
}
WebInspector.CSSStyleSheet.prototype = {
@@ -513,14 +544,16 @@ WebInspector.CSSStyleSheet.prototype = {
setText: function(newText, userCallback)
{
- function callback(userCallback, styleSheetPayload)
+ function callback(styleSheetPayload)
{
if (!styleSheetPayload)
userCallback(null);
- else
+ else {
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
+ WebInspector.cssModel._styleSheetChanged(this.id, true);
+ }
}
- InspectorBackend.setStyleSheetText2(this.id, newText, callback.bind(this, userCallback));
+ InspectorBackend.setStyleSheetText2(this.id, newText, callback.bind(this));
}
}
diff --git a/WebCore/inspector/front-end/Color.js b/WebCore/inspector/front-end/Color.js
index 11d6bad..5e7314c 100644
--- a/WebCore/inspector/front-end/Color.js
+++ b/WebCore/inspector/front-end/Color.js
@@ -143,6 +143,8 @@ WebInspector.Color.prototype = {
format = this.format;
switch (format) {
+ case "original":
+ return this.value;
case "rgb":
return "rgb(" + this.rgb.join(", ") + ")";
case "rgba":
@@ -324,7 +326,7 @@ WebInspector.Color.prototype = {
throw "unknown color name";
} else if (match[4]) { // hsl
this.format = "hsl";
- var hsl = match[4].replace(/%g/, "").split(/\s*,\s*/);
+ var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/);
this.hsl = hsl;
this.rgb = this._hslToRGB(hsl);
this.hex = this._rgbToHex(this.rgb);
diff --git a/WebCore/inspector/front-end/CookieItemsView.js b/WebCore/inspector/front-end/CookieItemsView.js
index b2da875..75c7f84 100644
--- a/WebCore/inspector/front-end/CookieItemsView.js
+++ b/WebCore/inspector/front-end/CookieItemsView.js
@@ -27,149 +27,19 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.CookiesTable = function()
-{
- WebInspector.View.call(this);
-
- this.element.addStyleClass("table");
-}
-
-WebInspector.CookiesTable.prototype = {
- resize: function()
- {
- if (!this._dataGrid)
- return;
-
- if (this._autoSizingDone)
- this._dataGrid.updateWidths();
- else {
- this._autoSizingDone = true;
- this._dataGrid.autoSizeColumns(4, 45, 1);
- }
- },
-
- _createDataGrid: function(expandable)
- {
- var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
- columns[0].title = WebInspector.UIString("Name");
- columns[0].sortable = true;
- columns[0].disclosure = expandable;
- columns[1].title = WebInspector.UIString("Value");
- columns[1].sortable = true;
- columns[2].title = WebInspector.UIString("Domain");
- columns[2].sortable = true;
- columns[3].title = WebInspector.UIString("Path");
- columns[3].sortable = true;
- columns[4].title = WebInspector.UIString("Expires");
- columns[4].sortable = true;
- columns[5].title = WebInspector.UIString("Size");
- columns[5].aligned = "right";
- columns[5].sortable = true;
- columns[6].title = WebInspector.UIString("HTTP");
- columns[6].aligned = "centered";
- columns[6].sortable = true;
- columns[7].title = WebInspector.UIString("Secure");
- columns[7].aligned = "centered";
- columns[7].sortable = true;
-
- var deleteCallback = this._deleteCookieCallback ? this._deleteCookieCallback.bind(this) : null;
- this._dataGrid = new WebInspector.DataGrid(columns, null, deleteCallback);
- this._dataGrid.addEventListener("sorting changed", this._populateDataGrid, this);
- this.element.appendChild(this._dataGrid.element);
- },
-
- _populateCookies: function(parentNode, cookies)
- {
- var selectedCookie = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.cookie : null;
- parentNode.removeChildren();
- if (!cookies)
- return;
- this._sortCookies(cookies);
- var totalSize = 0;
- for (var i = 0; i < cookies.length; ++i) {
- var cookieNode = this._createGridNode(cookies[i]);
- parentNode.appendChild(cookieNode);
- if (selectedCookie === cookies[i])
- cookieNode.selected = true;
- }
- },
-
- _sortCookies: function(cookies)
- {
- var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;
-
- function localeCompare(field, cookie1, cookie2)
- {
- return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
- }
-
- function numberCompare(field, cookie1, cookie2)
- {
- return sortDirection * (cookie1[field] - cookie2[field]);
- }
-
- function expiresCompare(cookie1, cookie2)
- {
- if (cookie1.session !== cookie2.session)
- return sortDirection * (cookie1.session ? 1 : -1);
-
- if (cookie1.session)
- return 0;
-
- return sortDirection * (cookie1.expires - cookie2.expires);
- }
-
- var comparator;
- switch (parseInt(this._dataGrid.sortColumnIdentifier)) {
- case 0: comparator = localeCompare.bind(this, "name"); break;
- case 1: comparator = localeCompare.bind(this, "value"); break;
- case 2: comparator = localeCompare.bind(this, "domain"); break;
- case 3: comparator = localeCompare.bind(this, "path"); break;
- case 4: comparator = expiresCompare; break;
- case 5: comparator = numberCompare.bind(this, "size"); break;
- case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
- case 7: comparator = localeCompare.bind(this, "secure"); break;
- default: localeCompare.bind(this, "name");
- }
-
- cookies.sort(comparator);
- },
-
- _createGridNode: function(cookie)
- {
- var data = {};
- data[0] = cookie.name;
- data[1] = cookie.value;
- data[2] = cookie.domain || "";
- data[3] = cookie.path || "";
- data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" :
- (cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString());
- data[5] = cookie.size;
- data[6] = (cookie.httpOnly ? "\u2713" : ""); // Checkmark
- data[7] = (cookie.secure ? "\u2713" : ""); // Checkmark
-
- var node = new WebInspector.DataGridNode(data);
- node.cookie = cookie;
- node.selectable = true;
- return node;
- }
-};
-
-WebInspector.CookiesTable.prototype.__proto__ = WebInspector.View.prototype;
-
WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
- WebInspector.CookiesTable.call(this);
+ WebInspector.View.call(this);
this.element.addStyleClass("storage-view");
- this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
- this.deleteButton.visible = false;
- this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
+ this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
+ this._deleteButton.visible = false;
+ this._deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
+
+ this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
+ this._refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
- this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
- this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
-
this._treeElement = treeElement;
this._cookieDomain = cookieDomain;
@@ -182,7 +52,7 @@ WebInspector.CookieItemsView = function(treeElement, cookieDomain)
WebInspector.CookieItemsView.prototype = {
get statusBarItems()
{
- return [this.refreshButton.element, this.deleteButton.element];
+ return [this._refreshButton.element, this._deleteButton.element];
},
show: function(parentElement)
@@ -194,7 +64,13 @@ WebInspector.CookieItemsView.prototype = {
hide: function()
{
WebInspector.View.prototype.hide.call(this);
- this.deleteButton.visible = false;
+ this._deleteButton.visible = false;
+ },
+
+ resize: function()
+ {
+ if (this._cookiesTable)
+ this._cookiesTable.updateWidths();
},
_update: function()
@@ -204,47 +80,35 @@ WebInspector.CookieItemsView.prototype = {
_updateWithCookies: function(allCookies, isAdvanced)
{
- if (isAdvanced)
- this._filterCookiesForDomain(allCookies);
- else
- this._cookies = allCookies;
+ this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies;
+
if (!this._cookies.length) {
// Nothing to show.
this._emptyMsgElement.removeStyleClass("hidden");
- this.deleteButton.visible = false;
- if (this._dataGrid)
- this._dataGrid.element.addStyleClass("hidden");
+ this._deleteButton.visible = false;
+ if (this._cookiesTable)
+ this._cookiesTable.element.addStyleClass("hidden");
return;
}
- if (!this._dataGrid) {
- if (isAdvanced) {
- this._createDataGrid();
- this._populateDataGrid();
- this._dataGrid.autoSizeColumns(6, 33);
- this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
- Number.bytesToString(this._totalSize, WebInspector.UIString));
- } else {
- this._createSimpleDataGrid();
- this._populateSimpleDataGrid();
- this._dataGrid.autoSizeColumns(20, 80);
- }
- } else {
- if (isAdvanced)
- this._populateDataGrid();
- else
- this._populateSimpleDataGrid();
+ if (!this._cookiesTable) {
+ this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this)) : new WebInspector.SimpleCookiesTable();
+ this.element.appendChild(this._cookiesTable.element);
}
- this._dataGrid.element.removeStyleClass("hidden");
+ this._cookiesTable.setCookies(this._cookies);
+ this._cookiesTable.element.removeStyleClass("hidden");
this._emptyMsgElement.addStyleClass("hidden");
- if (isAdvanced)
- this.deleteButton.visible = true;
+ if (isAdvanced) {
+ this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
+ Number.bytesToString(this._totalSize, WebInspector.UIString));
+ this._deleteButton.visible = true;
+ }
},
_filterCookiesForDomain: function(allCookies)
{
- this._cookies = [];
+ var cookies = [];
var resourceURLsForDocumentURL = [];
this._totalSize = 0;
@@ -265,34 +129,52 @@ WebInspector.CookieItemsView.prototype = {
this._totalSize += size;
if (!pushed) {
pushed = true;
- this._cookies.push(allCookies[i]);
+ cookies.push(allCookies[i]);
}
}
}
}
+ return cookies;
},
- _populateDataGrid: function()
+ _deleteCookie: function(cookie)
{
- this._populateCookies(this._dataGrid, this._cookies);
+ InspectorBackend.deleteCookie(cookie.name, this._cookieDomain);
+ this._update();
},
- _createSimpleDataGrid: function()
+ _deleteButtonClicked: function()
{
- var columns = {};
- columns[0] = {};
- columns[1] = {};
- columns[0].title = WebInspector.UIString("Name");
- columns[1].title = WebInspector.UIString("Value");
-
- this._dataGrid = new WebInspector.DataGrid(columns);
- this.element.appendChild(this._dataGrid.element);
- this._dataGrid.updateWidths();
+ if (this._cookiesTable.selectedCookie)
+ this._deleteCookie(this._cookiesTable.selectedCookie);
},
- _populateSimpleDataGrid: function()
+ _refreshButtonClicked: function(event)
+ {
+ this._update();
+ }
+}
+
+WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.SimpleCookiesTable = function()
+{
+ this.element = document.createElement("div");
+ var columns = {};
+ columns[0] = {};
+ columns[1] = {};
+ columns[0].title = WebInspector.UIString("Name");
+ columns[1].title = WebInspector.UIString("Value");
+
+ this._dataGrid = new WebInspector.DataGrid(columns);
+ this._dataGrid.autoSizeColumns(20, 80);
+ this.element.appendChild(this._dataGrid.element);
+ this._dataGrid.updateWidths();
+}
+
+WebInspector.SimpleCookiesTable.prototype = {
+ setCookies: function(cookies)
{
- var cookies = this._cookies;
this._dataGrid.removeChildren();
var addedCookies = {};
for (var i = 0; i < cookies.length; ++i) {
@@ -310,26 +192,9 @@ WebInspector.CookieItemsView.prototype = {
this._dataGrid.children[0].selected = true;
},
- _deleteButtonClicked: function(event)
- {
- if (!this._dataGrid || !this._dataGrid.selectedNode)
- return;
-
- this._deleteCookieCallback(this._dataGrid.selectedNode);
- },
-
- _deleteCookieCallback: function(node)
- {
- var cookie = node.cookie;
- InspectorBackend.deleteCookie(cookie.name, this._cookieDomain);
- this._update();
- },
-
- _refreshButtonClicked: function(event)
+ resize: function()
{
- this._update();
+ if (this._dataGrid)
+ this._dataGrid.updateWidths();
}
}
-
-WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.CookiesTable.prototype;
-
diff --git a/WebCore/inspector/front-end/CookiesTable.js b/WebCore/inspector/front-end/CookiesTable.js
new file mode 100644
index 0000000..2382a8e
--- /dev/null
+++ b/WebCore/inspector/front-end/CookiesTable.js
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ * 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:
+ *
+ * 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.CookiesTable = function(cookieDomain, expandable, deleteCallback)
+{
+ this._cookieDomain = cookieDomain;
+
+ var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
+ columns[0].title = WebInspector.UIString("Name");
+ columns[0].sortable = true;
+ columns[0].disclosure = expandable;
+ columns[0].width = "24%";
+ columns[1].title = WebInspector.UIString("Value");
+ columns[1].sortable = true;
+ columns[1].width = "34%";
+ columns[2].title = WebInspector.UIString("Domain");
+ columns[2].sortable = true;
+ columns[2].width = "7%";
+ columns[3].title = WebInspector.UIString("Path");
+ columns[3].sortable = true;
+ columns[3].width = "7%";
+ columns[4].title = WebInspector.UIString("Expires");
+ columns[4].sortable = true;
+ columns[4].width = "7%";
+ columns[5].title = WebInspector.UIString("Size");
+ columns[5].aligned = "right";
+ columns[5].sortable = true;
+ columns[5].width = "7%";
+ columns[6].title = WebInspector.UIString("HTTP");
+ columns[6].aligned = "centered";
+ columns[6].sortable = true;
+ columns[6].width = "7%";
+ columns[7].title = WebInspector.UIString("Secure");
+ columns[7].aligned = "centered";
+ columns[7].sortable = true;
+ columns[7].width = "7%";
+
+ this._dataGrid = new WebInspector.DataGrid(columns, null, deleteCallback ? this._onDeleteFromGrid.bind(this) : null);
+ this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this);
+
+ this.element = this._dataGrid.element;
+ this._data = [];
+ this._deleteCallback = deleteCallback;
+}
+
+WebInspector.CookiesTable.prototype = {
+ updateWidths: function()
+ {
+ if (this._dataGrid)
+ this._dataGrid.updateWidths();
+ },
+
+ setCookies: function(cookies)
+ {
+ this._data = [{cookies: cookies}];
+ this._rebuildTable();
+ },
+
+ addCookiesFolder: function(folderName, cookies)
+ {
+ this._data.push({cookies: cookies, folderName: folderName});
+ this._rebuildTable();
+ },
+
+ get selectedCookie()
+ {
+ var node = this._dataGrid.selectedNode;
+ return node ? node.cookie : null;
+ },
+
+ _rebuildTable: function()
+ {
+ this._dataGrid.removeChildren();
+ for (var i = 0; i < this._data.length; ++i) {
+ var item = this._data[i];
+ if (item.folderName) {
+ var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ];
+ var groupNode = new WebInspector.DataGridNode(groupData);
+ groupNode.selectable = true;
+ this._dataGrid.appendChild(groupNode);
+ groupNode.element.addStyleClass("row-group");
+ this._populateNode(groupNode, item.cookies);
+ groupNode.expand();
+ } else
+ this._populateNode(this._dataGrid, item.cookies);
+ }
+ },
+
+ _populateNode: function(parentNode, cookies)
+ {
+ var selectedCookie = this.selectedCookie;
+ parentNode.removeChildren();
+ if (!cookies)
+ return;
+
+ this._sortCookies(cookies);
+ for (var i = 0; i < cookies.length; ++i) {
+ var cookieNode = this._createGridNode(cookies[i]);
+ parentNode.appendChild(cookieNode);
+ if (selectedCookie === cookies[i])
+ cookieNode.selected = true;
+ }
+ },
+
+ _totalSize: function(cookies)
+ {
+ var totalSize = 0;
+ for (var i = 0; cookies && i < cookies.length; ++i)
+ totalSize += cookies[i].size;
+ return totalSize;
+ },
+
+ _sortCookies: function(cookies)
+ {
+ var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;
+
+ function localeCompare(field, cookie1, cookie2)
+ {
+ return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
+ }
+
+ function numberCompare(field, cookie1, cookie2)
+ {
+ return sortDirection * (cookie1[field] - cookie2[field]);
+ }
+
+ function expiresCompare(cookie1, cookie2)
+ {
+ if (cookie1.session !== cookie2.session)
+ return sortDirection * (cookie1.session ? 1 : -1);
+
+ if (cookie1.session)
+ return 0;
+
+ return sortDirection * (cookie1.expires - cookie2.expires);
+ }
+
+ var comparator;
+ switch (parseInt(this._dataGrid.sortColumnIdentifier)) {
+ case 0: comparator = localeCompare.bind(this, "name"); break;
+ case 1: comparator = localeCompare.bind(this, "value"); break;
+ case 2: comparator = localeCompare.bind(this, "domain"); break;
+ case 3: comparator = localeCompare.bind(this, "path"); break;
+ case 4: comparator = expiresCompare; break;
+ case 5: comparator = numberCompare.bind(this, "size"); break;
+ case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
+ case 7: comparator = localeCompare.bind(this, "secure"); break;
+ default: localeCompare.bind(this, "name");
+ }
+
+ cookies.sort(comparator);
+ },
+
+ _createGridNode: function(cookie)
+ {
+ var data = {};
+ data[0] = cookie.name;
+ data[1] = cookie.value;
+ data[2] = cookie.domain || "";
+ data[3] = cookie.path || "";
+ data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" :
+ (cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString());
+ data[5] = cookie.size;
+ const checkmark = "\u2713";
+ data[6] = (cookie.httpOnly ? checkmark : "");
+ data[7] = (cookie.secure ? checkmark : "");
+
+ var node = new WebInspector.DataGridNode(data);
+ node.cookie = cookie;
+ node.selectable = true;
+ return node;
+ },
+
+ _onDeleteFromGrid: function(node)
+ {
+ this._deleteCallback(node.cookie);
+ }
+}
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 76c22c5..61ba33e 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -58,7 +58,7 @@ WebInspector.ElementsPanel = function()
if (this._focusedDOMNode) {
InspectorBackend.addInspectedNode(this._focusedDOMNode.id);
- WebInspector.extensionServer.notifyObjectSelected(this.panel.name, "DOMNode");
+ WebInspector.extensionServer.notifyObjectSelected(this.panel.name);
}
};
diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js
index e526cf5..0234994 100644
--- a/WebCore/inspector/front-end/ExtensionAPI.js
+++ b/WebCore/inspector/front-end/ExtensionAPI.js
@@ -104,109 +104,130 @@ InspectorExtensionAPI.prototype = {
function Resources()
{
- this.onFinished = new EventSink("resource-finished");
+ function resourceDispatch(request)
+ {
+ var resource = request.arguments[1];
+ resource.__proto__ = new Resource(request.arguments[0]);
+ this._fire(resource);
+ }
+ this.onFinished = new EventSink("resource-finished", resourceDispatch);
}
Resources.prototype = {
- getAll: function(callback)
- {
- return extensionServer.sendRequest({ command: "getResources" }, callback);
- },
-
- get: function(id, callback)
+ getHAR: function(callback)
{
- return extensionServer.sendRequest({ command: "getResources", id: id }, callback);
- },
+ function callbackWrapper(result)
+ {
+ var entries = (result && result.entries) || [];
+ for (var i = 0; i < entries.length; ++i) {
+ entries[i].__proto__ = new Resource(entries[i]._resourceId);
+ delete entries[i]._resourceId;
+ }
+ callback(result);
+ }
+ return extensionServer.sendRequest({ command: "getHAR" }, callback && callbackWrapper);
+ }
+}
- getPageTimings: function(callback)
- {
- return extensionServer.sendRequest({ command: "getPageTimings" }, callback);
- },
+function ResourceImpl(id)
+{
+ this._id = id;
+}
- getContent: function(ids, callback)
+ResourceImpl.prototype = {
+ getContent: function(callback)
{
- return extensionServer.sendRequest({ command: "getResourceContent", ids: ids }, callback);
+ function callbackWrapper(response)
+ {
+ callback(response.content, response.encoding);
+ }
+ extensionServer.sendRequest({ command: "getResourceContent", id: this._id }, callback && callbackWrapper);
}
-}
-
-var wellKnownPanelNames = [
- "elements",
- "scripts"
-];
+};
function Panels()
{
- var panels = [];
+ var panels = {
+ elements: new ElementsPanel()
+ };
+
function panelGetter(name)
{
return panels[name];
}
-
- for (var i = 0; i < wellKnownPanelNames.length; ++i) {
- var name = wellKnownPanelNames[i];
- panels[name] = new Panel(name);
- this.__defineGetter__(name, bind(panelGetter, null, name));
- }
+ for (var panel in panels)
+ this.__defineGetter__(panel, bind(panelGetter, null, panel));
}
Panels.prototype = {
- create: function(label, pageURL, iconURL, callback)
+ create: function(title, iconURL, pageURL, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
- function callbackWrapper(result)
- {
- if (result.isError)
- callback(result);
- else {
- panel = new ExtensionPanel(id);
- callback(panel);
- }
- }
var request = {
command: "createPanel",
id: id,
- label: label,
- url: expandURL(pageURL),
- icon: expandURL(iconURL)
+ title: title,
+ icon: expandURL(iconURL),
+ url: expandURL(pageURL)
};
- extensionServer.sendRequest(request, callback && bind(callbackWrapper, this));
+ extensionServer.sendRequest(request, callback && bind(callback, this, new ExtensionPanel(id)));
}
}
function PanelImpl(id)
{
this._id = id;
- this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
}
-PanelImpl.prototype = {
+function PanelWithSidebarImpl(id)
+{
+ PanelImpl.call(this, id);
+}
+
+PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, url, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
- function callbackWrapper(result)
+ var request = {
+ command: "createSidebarPane",
+ panel: this._id,
+ id: id,
+ title: title,
+ url: expandURL(url)
+ };
+ function callbackWrapper()
{
- if (result.isError)
- callback(result);
- else
- callback(new ExtensionSidebarPane(id));
+ callback(new ExtensionSidebarPane(id));
}
- extensionServer.sendRequest({ command: "createSidebarPane", panel: this._id, id: id, title: title, url: expandURL(url) }, callback && callbackWrapper);
+ extensionServer.sendRequest(request, callback && callbackWrapper);
},
createWatchExpressionSidebarPane: function(title, callback)
{
var id = "watch-sidebar-" + extensionServer.nextObjectId();
- function callbackWrapper(result)
+ var request = {
+ command: "createWatchExpressionSidebarPane",
+ panel: this._id,
+ id: id,
+ title: title
+ };
+ function callbackWrapper()
{
- if (result.isError)
- callback(result);
- else
- callback(new WatchExpressionSidebarPane(id));
+ callback(new WatchExpressionSidebarPane(id));
}
- extensionServer.sendRequest({ command: "createWatchExpressionSidebarPane", panel: this._id, id: id, title: title }, callback && callbackWrapper);
+ extensionServer.sendRequest(request, callback && callbackWrapper);
}
}
+PanelWithSidebarImpl.prototype.__proto__ = PanelImpl.prototype;
+
+function ElementsPanel()
+{
+ var id = "elements";
+ PanelWithSidebar.call(this, id);
+ this.onSelectionChanged = new EventSink("panel-objectSelected-" + id);
+}
+
function ExtensionPanel(id)
{
Panel.call(this, id);
@@ -222,11 +243,6 @@ ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: "setSidebarHeight", id: this._id, height: height });
- },
-
- setExpanded: function(expanded)
- {
- extensionServer.sendRequest({ command: "setSidebarExpanded", id: this._id, expanded: expanded });
}
}
@@ -261,17 +277,17 @@ function Audits()
}
Audits.prototype = {
- addCategory: function(displayName, ruleCount)
+ addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
- extensionServer.sendRequest({ command: "addAuditCategory", id: id, displayName: displayName, ruleCount: ruleCount });
+ extensionServer.sendRequest({ command: "addAuditCategory", id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}
function AuditCategoryImpl(id)
{
- function customDispatch(request)
+ function auditResultDispatch(request)
{
var auditResult = new AuditResult(request.arguments[0]);
try {
@@ -282,7 +298,7 @@ function AuditCategoryImpl(id)
}
}
this._id = id;
- this.onAuditStarted = new EventSink("audit-started-" + id, customDispatch);
+ this.onAuditStarted = new EventSink("audit-started-" + id, auditResultDispatch);
}
function AuditResultImpl(id)
@@ -330,7 +346,7 @@ AuditResultImpl.prototype = {
get Severity()
{
- return private.audits.Severity;
+ return apiPrivate.audits.Severity;
},
_nodeFactory: function(type)
@@ -360,9 +376,9 @@ AuditResultNode.prototype = {
function InspectedWindow()
{
+ this.onDOMContentLoaded = new EventSink("inspectedPageDOMContentLoaded");
this.onLoaded = new EventSink("inspectedPageLoaded");
this.onNavigated = new EventSink("inspectedURLChanged");
- this.onDOMContentLoaded = new EventSink("DOMContentLoaded");
}
InspectedWindow.prototype = {
@@ -371,13 +387,14 @@ InspectedWindow.prototype = {
return extensionServer.sendRequest({ command: "reload" });
},
- evaluate: function(expression, callback)
+ eval: function(expression, callback)
{
function callbackWrapper(result)
{
- if (result && !result.isException)
- result.value = result.value === "undefined" ? undefined : JSON.parse(result.value);
- callback(result);
+ var value = result.value;
+ if (!result.isException)
+ value = value === "undefined" ? undefined : JSON.parse(value);
+ callback(value, result.isException);
}
return extensionServer.sendRequest({ command: "evaluateOnInspectedPage", expression: expression }, callback && callbackWrapper);
}
@@ -481,12 +498,14 @@ function declareInterfaceClass(implConstructor)
}
}
+var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
+var AuditResult = declareInterfaceClass(AuditResultImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
-var Panel = declareInterfaceClass(PanelImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
+var Panel = declareInterfaceClass(PanelImpl);
+var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
+var Resource = declareInterfaceClass(ResourceImpl);
var WatchExpressionSidebarPane = declareInterfaceClass(WatchExpressionSidebarPaneImpl);
-var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
-var AuditResult = declareInterfaceClass(AuditResultImpl);
var extensionServer = new ExtensionServerClient();
diff --git a/WebCore/inspector/front-end/ExtensionCommon.js b/WebCore/inspector/front-end/ExtensionCommon.js
index b04c18c..8034001 100644
--- a/WebCore/inspector/front-end/ExtensionCommon.js
+++ b/WebCore/inspector/front-end/ExtensionCommon.js
@@ -28,13 +28,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.commonExtensionSymbols = function(private)
+WebInspector.commonExtensionSymbols = function(apiPrivate)
{
- if (!private.audits)
- private.audits = {};
+ if (!apiPrivate.audits)
+ apiPrivate.audits = {};
- private.audits.Severity = {
+ apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js
index 7229785..1050c6f 100644
--- a/WebCore/inspector/front-end/ExtensionServer.js
+++ b/WebCore/inspector/front-end/ExtensionServer.js
@@ -35,23 +35,22 @@ WebInspector.ExtensionServer = function()
this._subscribers = {};
this._status = new WebInspector.ExtensionStatus();
- this._registerHandler("subscribe", this._onSubscribe.bind(this));
- this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
- this._registerHandler("getResources", this._onGetResources.bind(this));
- this._registerHandler("getResourceContent", this._onGetResourceContent.bind(this));
- this._registerHandler("getPageTimings", this._onGetPageTimings.bind(this));
+ this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
+ this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this));
this._registerHandler("createPanel", this._onCreatePanel.bind(this));
this._registerHandler("createSidebarPane", this._onCreateSidebar.bind(this));
this._registerHandler("createWatchExpressionSidebarPane", this._onCreateWatchExpressionSidebarPane.bind(this));
- this._registerHandler("log", this._onLog.bind(this));
this._registerHandler("evaluateOnInspectedPage", this._onEvaluateOnInspectedPage.bind(this));
+ this._registerHandler("getHAR", this._onGetHAR.bind(this));
+ this._registerHandler("getResourceContent", this._onGetResourceContent.bind(this));
+ this._registerHandler("log", this._onLog.bind(this));
+ this._registerHandler("reload", this._onReload.bind(this));
this._registerHandler("setSidebarHeight", this._onSetSidebarHeight.bind(this));
- this._registerHandler("setSidebarExpanded", this._onSetSidebarExpansion.bind(this));
this._registerHandler("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this));
-
- this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this));
- this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this));
this._registerHandler("stopAuditCategoryRun", this._onStopAuditCategoryRun.bind(this));
+ this._registerHandler("subscribe", this._onSubscribe.bind(this));
+ this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
+
window.addEventListener("message", this._onWindowMessage.bind(this), false);
}
@@ -62,14 +61,14 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("panel-shown-" + panelName);
},
- notifyObjectSelected: function(panelId, objectType, objectId)
+ notifyObjectSelected: function(panelId, objectId)
{
- this._postNotification("panel-objectSelected-" + panelId, objectType, objectId);
+ this._postNotification("panel-objectSelected-" + panelId, objectId);
},
notifyResourceFinished: function(resource)
{
- this._postNotification("resource-finished", this._convertResource(resource));
+ this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
},
notifySearchAction: function(panelId, action, searchString)
@@ -77,9 +76,14 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("panel-search-" + panelId, action, searchString);
},
- notifyInspectedPageLoaded: function()
+ notifyPageLoaded: function(milliseconds)
+ {
+ this._postNotification("inspectedPageLoaded", milliseconds);
+ },
+
+ notifyPageDOMContentLoaded: function(milliseconds)
{
- this._postNotification("inspectedPageLoaded");
+ this._postNotification("inspectedPageDOMContentLoaded", milliseconds);
},
notifyInspectedURLChanged: function()
@@ -108,15 +112,6 @@ WebInspector.ExtensionServer.prototype = {
delete this._clientObjects[auditRun.id];
},
- _convertResource: function(resource)
- {
- return {
- id: resource.identifier,
- type: WebInspector.Resource.Type.toString(resource.type),
- har: (new WebInspector.HAREntry(resource)).build(),
- };
- },
-
_postNotification: function(type, details)
{
var subscribers = this._subscribers[type];
@@ -156,7 +151,7 @@ WebInspector.ExtensionServer.prototype = {
// shouldn't be hit unless someone is bypassing the API.
if (id in this._clientObjects || id in WebInspector.panels)
return this._status.E_EXISTS(id);
- var panel = new WebInspector.ExtensionPanel(id, message.label, message.icon);
+ var panel = new WebInspector.ExtensionPanel(id, message.title, message.icon);
this._clientObjects[id] = panel;
var toolbarElement = document.getElementById("toolbar");
@@ -216,17 +211,6 @@ WebInspector.ExtensionServer.prototype = {
sidebar.bodyElement.firstChild.style.height = message.height;
},
- _onSetSidebarExpansion: function(message)
- {
- var sidebar = this._clientObjects[message.id];
- if (!sidebar)
- return this._status.E_NOTFOUND(message.id);
- if (message.expanded)
- sidebar.expand();
- else
- sidebar.collapse();
- },
-
_onSetWatchSidebarContent: function(message)
{
var sidebar = this._clientObjects[message.id];
@@ -243,6 +227,12 @@ WebInspector.ExtensionServer.prototype = {
WebInspector.log(message.message);
},
+ _onReload: function()
+ {
+ InspectorBackend.reloadPage();
+ return this._status.OK();
+ },
+
_onEvaluateOnInspectedPage: function(message, port)
{
function callback(resultPayload)
@@ -286,66 +276,32 @@ WebInspector.ExtensionServer.prototype = {
port.postMessage({ command: "callback", requestId: requestId, result: result });
},
- _onGetResources: function(request)
+ _onGetHAR: function(request)
{
- function resourceWrapper(id)
- {
- return WebInspector.extensionServer._convertResource(WebInspector.networkResources[id]);
- }
-
- var response;
- if (request.id)
- response = WebInspector.networkResources[request.id] ? resourceWrapper(request.id) : this._status.E_NOTFOUND(request.id);
- else
- response = Object.keys(WebInspector.networkResources).map(resourceWrapper);
- return response;
+ var harLog = new WebInspector.HARLog();
+ harLog.includeResourceIds = true;
+ return harLog.build();
},
_onGetResourceContent: function(message, port)
{
- var ids;
- var response = [];
-
- function onContentAvailable(id, content, encoded)
+ function onContentAvailable(content, encoded)
{
- var resourceContent = {
- id: id,
+ var response = {
encoding: encoded ? "base64" : "",
content: content
};
- response.push(resourceContent);
- if (response.length === ids.length)
- this._dispatchCallback(message.requestId, port, response);
- }
-
- if (typeof message.ids === "number")
- ids = [ message.ids ];
- else if (message.ids instanceof Array)
- ids = message.ids;
- else
- return this._status.E_BADARGTYPE("message.ids", "Array", typeof message.ids);
-
- for (var i = 0; i < ids.length; ++i) {
- var id = ids[i];
- var resource = WebInspector.networkResources[id];
-
- if (!resource)
- response.push(this._status.E_NOTFOUND(id));
- else
- resource.requestContent(onContentAvailable.bind(this, id));
- }
- if (response.length === ids.length)
this._dispatchCallback(message.requestId, port, response);
- },
-
- _onGetPageTimings: function()
- {
- return (new WebInspector.HARLog()).buildMainResourceTimings();
+ }
+ var resource = WebInspector.networkResources[message.id];
+ if (!resource)
+ return this._status.E_NOTFOUND(message.id);
+ resource.requestContent(onContentAvailable.bind(this));
},
_onAddAuditCategory: function(request)
{
- var category = new WebInspector.ExtensionAuditCategory(request.id, request.displayName, request.ruleCount);
+ var category = new WebInspector.ExtensionAuditCategory(request.id, request.displayName, request.resultCount);
if (WebInspector.panels.audits.getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[request.id] = category;
@@ -409,8 +365,8 @@ WebInspector.ExtensionServer.prototype = {
}
var platformAPI = WebInspector.buildPlatformExtensionAPI ? WebInspector.buildPlatformExtensionAPI() : "";
return "(function(){ " +
- "var private = {};" +
- "(" + WebInspector.commonExtensionSymbols.toString() + ")(private);" +
+ "var apiPrivate = {};" +
+ "(" + WebInspector.commonExtensionSymbols.toString() + ")(apiPrivate);" +
"(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
"webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
platformAPI +
diff --git a/WebCore/inspector/front-end/FileSystemView.js b/WebCore/inspector/front-end/FileSystemView.js
index 0c6636b..8cd0107 100644
--- a/WebCore/inspector/front-end/FileSystemView.js
+++ b/WebCore/inspector/front-end/FileSystemView.js
@@ -125,12 +125,12 @@ WebInspector.FileSystemView.prototype = {
},
_selectFileSystemTab: function()
{
- this._tabbedPane.selectTabById("persistent");
+ this._tabbedPane.selectTab("persistent");
},
selectTemporaryFileSystemTab: function()
{
- this._tabbedPane.selectTabById("temp");
+ this._tabbedPane.selectTab("temp");
},
_revealPersistentFolderInOS: function()
diff --git a/WebCore/inspector/front-end/FontView.js b/WebCore/inspector/front-end/FontView.js
index 78a7e70..82559ef 100644
--- a/WebCore/inspector/front-end/FontView.js
+++ b/WebCore/inspector/front-end/FontView.js
@@ -34,12 +34,12 @@ WebInspector.FontView = function(resource)
}
WebInspector.FontView.prototype = {
- hasContentTab: function()
+ hasContent: function()
{
return true;
},
- contentTabSelected: function()
+ _createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;
@@ -51,7 +51,7 @@ WebInspector.FontView.prototype = {
document.head.appendChild(this.fontStyleElement);
this.fontPreviewElement = document.createElement("div");
- this.contentElement.appendChild(this.fontPreviewElement);
+ this.element.appendChild(this.fontPreviewElement);
this.fontPreviewElement.style.setProperty("font-family", uniqueFontName, null);
this.fontPreviewElement.innerHTML = "ABCDEFGHIJKLM<br>NOPQRSTUVWXYZ<br>abcdefghijklm<br>nopqrstuvwxyz<br>1234567890";
@@ -63,6 +63,7 @@ WebInspector.FontView.prototype = {
show: function(parentElement)
{
WebInspector.ResourceView.prototype.show.call(this, parentElement);
+ this._createContentIfNeeded();
this.updateFontPreviewSize();
},
@@ -86,7 +87,7 @@ WebInspector.FontView.prototype = {
const width = this.fontPreviewElement.offsetWidth;
// Subtract some padding. This should match the padding in the CSS plus room for the scrollbar.
- const containerWidth = this.contentElement.offsetWidth - 50;
+ const containerWidth = this.element.offsetWidth - 50;
if (!height || !width || !containerWidth) {
this.fontPreviewElement.style.removeProperty("font-size");
diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js
index f3bfb06..6dfbd1b 100644
--- a/WebCore/inspector/front-end/HAREntry.js
+++ b/WebCore/inspector/front-end/HAREntry.js
@@ -189,6 +189,7 @@ WebInspector.HAREntry._toMilliseconds = function(time)
WebInspector.HARLog = function()
{
+ this.includeResourceIds = false;
}
WebInspector.HARLog.prototype = {
@@ -203,7 +204,7 @@ WebInspector.HARLog.prototype = {
version: webKitVersion ? webKitVersion[1] : "n/a"
},
pages: this._buildPages(),
- entries: Object.keys(WebInspector.networkResources).map(this._convertResource)
+ entries: Object.keys(WebInspector.networkResources).map(this._convertResource.bind(this))
}
},
@@ -229,7 +230,10 @@ WebInspector.HARLog.prototype = {
_convertResource: function(id)
{
- return (new WebInspector.HAREntry(WebInspector.networkResources[id])).build();
+ var entry = (new WebInspector.HAREntry(WebInspector.networkResources[id])).build();
+ if (this.includeResourceIds)
+ entry._resourceId = id;
+ return entry;
},
_pageEventTime: function(time)
diff --git a/WebCore/inspector/front-end/HeapSnapshotView.js b/WebCore/inspector/front-end/HeapSnapshotView.js
index 6bcc0ff..d09f91d 100644
--- a/WebCore/inspector/front-end/HeapSnapshotView.js
+++ b/WebCore/inspector/front-end/HeapSnapshotView.js
@@ -27,6 +27,154 @@
* (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.HeapSnapshotEdgesIterator = function(snapshot, edges)
+{
+ this._snapshot = snapshot;
+ this._edges = edges;
+ this._edgeIndex = 0;
+}
+
+WebInspector.HeapSnapshotEdgesIterator.prototype = {
+ get done()
+ {
+ return this._edgeIndex >= this._edges.length;
+ },
+
+ get isElement()
+ {
+ return this._getType() === this._snapshot._edgeElementType;
+ },
+
+ get isHidden()
+ {
+ return this._getType() === this._snapshot._edgeHiddenType;
+ },
+
+ get name()
+ {
+ return this.isElement || this.isHidden ? this._getNameOrIndex() : this._snapshot._strings[this._getNameOrIndex()];
+ },
+
+ next: function()
+ {
+ this._edgeIndex += this._snapshot._edgeFieldsCount;
+ },
+
+ get node()
+ {
+ return new WebInspector.HeapSnapshotNodeWrapper(this._snapshot, this.nodeIndex);
+ },
+
+ get nodeIndex()
+ {
+ return this._edges[this._edgeIndex + this._snapshot._edgeToNodeOffset];
+ },
+
+ _getNameOrIndex: function()
+ {
+ return this._edges[this._edgeIndex + this._snapshot._edgeNameOffset];
+ },
+
+ _getType: function()
+ {
+ return this._edges[this._edgeIndex + this._snapshot._edgeTypeOffset];
+ }
+};
+
+WebInspector.HeapSnapshotNodeWrapper = function(snapshot, nodeIndex)
+{
+ this._snapshot = snapshot;
+ this._nodes = snapshot._nodes;
+ this._nodeIndex = nodeIndex;
+}
+
+WebInspector.HeapSnapshotNodeWrapper.prototype = {
+ get edges()
+ {
+ return new WebInspector.HeapSnapshotEdgesIterator(this._snapshot, this._getEdges());
+ },
+
+ get edgesCount()
+ {
+ return this._nodes[this._nodeIndex + this._snapshot._edgesCountOffset];
+ },
+
+ get instancesCount()
+ {
+ return this._nodes[this._nodeIndex + this._snapshot._nodeInstancesCountOffset];
+ },
+
+ get isHidden()
+ {
+ return this._getType() === this._snapshot._nodeHiddenType;
+ },
+
+ get name()
+ {
+ return this._snapshot._strings[this._getName()];
+ },
+
+ get selfSize()
+ {
+ return this._nodes[this._nodeIndex + this._snapshot._nodeSelfSizeOffset];
+ },
+
+ _getName: function()
+ {
+ return this._nodes[this._nodeIndex + this._snapshot._nodeNameOffset];
+ },
+
+ _getEdges: function()
+ {
+ var firstEdgeIndex = this._nodeIndex + this._snapshot._firstEdgeOffset;
+ return this._nodes.slice(firstEdgeIndex, firstEdgeIndex + this.edgesCount * this._snapshot._edgeFieldsCount);
+ },
+
+ _getType: function()
+ {
+ return this._nodes[this._nodeIndex + this._snapshot._nodeTypeOffset];
+ }
+};
+
+WebInspector.HeapSnapshot = function(profile)
+{
+ this._profile = profile;
+ this._nodes = profile.nodes;
+ this._strings = profile.strings;
+
+ this._init();
+}
+
+WebInspector.HeapSnapshot.prototype = {
+ _init: function()
+ {
+ this._metaNodeIndex = 0;
+ this._rootNodeIndex = 1;
+ var meta = this._nodes[this._metaNodeIndex];
+ this._nodeTypeOffset = meta.fields.indexOf("type");
+ this._nodeNameOffset = meta.fields.indexOf("name");
+ this._nodeIdOffset = meta.fields.indexOf("id");
+ this._nodeInstancesCountOffset = this._nodeIdOffset;
+ this._nodeSelfSizeOffset = meta.fields.indexOf("self_size");
+ this._edgesCountOffset = meta.fields.indexOf("children_count");
+ this._firstEdgeOffset = meta.fields.indexOf("children");
+ this._nodeTypes = meta.types[this._nodeTypeOffset];
+ this._nodeHiddenType = this._nodeTypes.indexOf("hidden");
+ var edgesMeta = meta.types[this._firstEdgeOffset];
+ this._edgeFieldsCount = edgesMeta.fields.length;
+ this._edgeTypeOffset = edgesMeta.fields.indexOf("type");
+ this._edgeNameOffset = edgesMeta.fields.indexOf("name_or_index");
+ this._edgeToNodeOffset = edgesMeta.fields.indexOf("to_node");
+ this._edgeTypes = edgesMeta.types[this._edgeTypeOffset];
+ this._edgeElementType = this._edgeTypes.indexOf("element");
+ this._edgeHiddenType = this._edgeTypes.indexOf("hidden");
+ },
+
+ get rootEdges()
+ {
+ return (new WebInspector.HeapSnapshotNodeWrapper(this, this._rootNodeIndex)).edges;
+ }
+};
WebInspector.HeapSnapshotView = function(parent, profile)
{
@@ -94,6 +242,7 @@ WebInspector.HeapSnapshotView = function(parent, profile)
this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);
+ this._loadedCallbacks = [];
this._loadProfile(this.profile, profileCallback.bind(this));
function profileCallback(profile)
@@ -290,6 +439,14 @@ WebInspector.HeapSnapshotView.prototype = {
this._updateSummaryGraph();
},
+ snapshotLoaded: function(uid, loadedSnapshot)
+ {
+ if (!this._loadedCallbacks[uid])
+ return;
+ this._loadedCallbacks[uid](loadedSnapshot);
+ delete this._loadedCallbacks[uid];
+ },
+
_changeBase: function()
{
if (this.baseSnapshot.uid === this._getProfiles()[this.baseSelectElement.selectedIndex].uid)
@@ -332,15 +489,17 @@ WebInspector.HeapSnapshotView.prototype = {
return;
}
- InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this));
+ this._loadedCallbacks[profile.uid] = processLoadedSnapshot.bind(this);
+ InspectorBackend.getProfile(profile.typeId, profile.uid);
- function loadedCallback(loadedSnapshot) {
- profile.children = loadedSnapshot.head.children;
- profile.entries = loadedSnapshot.head.entries;
- profile.lowlevels = loadedSnapshot.head.lowlevels;
+ function processLoadedSnapshot(loadedSnapshot)
+ {
+ var snapshot = this._convertSnapshot(loadedSnapshot);
+ profile.children = snapshot.children;
+ profile.entries = snapshot.entries;
+ profile.lowlevels = snapshot.lowlevels;
this._prepareProfile(profile);
profile._loaded = true;
- this.parent.updateProfile(profile);
callback(profile);
}
},
@@ -384,6 +543,26 @@ WebInspector.HeapSnapshotView.prototype = {
this.refreshShowAsPercents();
},
+ _convertSnapshot: function(loadedSnapshot)
+ {
+ var snapshot = new WebInspector.HeapSnapshot(loadedSnapshot);
+ var result = {lowlevels: {}, entries: {}, children: {}};
+ for (var rootEdges = snapshot.rootEdges; !rootEdges.done; rootEdges.next()) {
+ var node = rootEdges.node;
+ if (node.isHidden)
+ result.lowlevels[node.name] = {count: node.instancesCount, size: node.selfSize, type: node.name};
+ else if (node.instancesCount)
+ result.entries[node.name] = {constructorName: node.name, count: node.instancesCount, size: node.selfSize};
+ else {
+ var entry = {constructorName: node.name};
+ for (var edges = node.edges; !edges.done; edges.next())
+ entry[edges.nodeIndex] = {constructorName: edges.node.name, count: edges.name};
+ result.children[rootEdges.nodeIndex] = entry;
+ }
+ }
+ return result;
+ },
+
_prepareProfile: function(profile)
{
for (var profileEntry in profile.entries)
@@ -392,12 +571,12 @@ WebInspector.HeapSnapshotView.prototype = {
for (var addr in profile.children) {
var retainer = profile.children[addr];
- var retainerId = retainer.constructorName + ':' + addr;
+ var retainerId = retainer.constructorName + ":" + addr;
for (var childAddr in retainer) {
- if (childAddr === 'constructorName') continue;
+ if (childAddr === "constructorName") continue;
var item = retainer[childAddr];
- var itemId = item.constructorName + ':' + childAddr;
- if ((item.constructorName === 'Object' || item.constructorName === 'Array')) {
+ var itemId = item.constructorName + ":" + childAddr;
+ if ((item.constructorName === "Object" || item.constructorName === "Array")) {
if (!(itemId in profile.clusters))
profile.clusters[itemId] = { constructorName: itemId, retainers: {} };
mergeRetainers(profile.clusters[itemId], item);
@@ -412,7 +591,7 @@ WebInspector.HeapSnapshotView.prototype = {
entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} };
var retainerEntry = entry.retainers[retainer.constructorName];
retainerEntry.count += item.count;
- if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array')
+ if (retainer.constructorName === "Object" || retainer.constructorName === "Array")
retainerEntry.clusters[retainerId] = true;
}
},
@@ -438,7 +617,7 @@ WebInspector.HeapSnapshotView.prototype = {
var sortAscending = this.dataGrid.sortOrder === "ascending";
var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
var sortProperty = {
- cons: ["cons", null],
+ cons: ["constructorName", null],
count: ["count", null],
size: ["size", "count"],
countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
diff --git a/WebCore/inspector/front-end/HelpScreen.js b/WebCore/inspector/front-end/HelpScreen.js
index cad39d0..a1bbf1e 100644
--- a/WebCore/inspector/front-end/HelpScreen.js
+++ b/WebCore/inspector/front-end/HelpScreen.js
@@ -30,8 +30,6 @@
WebInspector.HelpScreen = function(title)
{
- this._addStyleSheetIfNeeded("helpScreen.css");
-
this._element = document.createElement("div");
this._element.className = "help-window-outer";
this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
@@ -86,17 +84,5 @@ WebInspector.HelpScreen.prototype = {
// Pretend we're modal, grab focus back if we're still shown.
if (this._isShown)
WebInspector.currentFocusElement = this.contentElement;
- },
-
- _addStyleSheetIfNeeded: function(href)
- {
- if (WebInspector.HelpScreen._styleSheetAdded)
- return;
-
- WebInspector.HelpScreen._styleSheetAdded = true;
- var link = document.head.createChild("link");
- link.type = "text/css";
- link.rel = "stylesheet";
- link.href = href;
}
-};
+}
diff --git a/WebCore/inspector/front-end/ImageView.js b/WebCore/inspector/front-end/ImageView.js
index f70fad6..54a16bb 100644
--- a/WebCore/inspector/front-end/ImageView.js
+++ b/WebCore/inspector/front-end/ImageView.js
@@ -34,26 +34,33 @@ WebInspector.ImageView = function(resource)
}
WebInspector.ImageView.prototype = {
- hasContentTab: function()
+ hasContent: function()
{
return true;
},
- contentTabSelected: function()
+ show: function(parentElement)
+ {
+ WebInspector.ResourceView.prototype.show.call(this, parentElement);
+ this._createContentIfNeeded();
+ },
+
+ _createContentIfNeeded: function()
{
if (this._container)
return;
- this._container = document.createElement("div");
- this._container.className = "image";
- this.contentElement.appendChild(this._container);
+
+ var imageContainer = document.createElement("div");
+ imageContainer.className = "image";
+ this.element.appendChild(imageContainer);
var imagePreviewElement = document.createElement("img");
imagePreviewElement.addStyleClass("resource-image-view");
- this._container.appendChild(imagePreviewElement);
+ imageContainer.appendChild(imagePreviewElement);
this._container = document.createElement("div");
this._container.className = "info";
- this.contentElement.appendChild(this._container);
+ this.element.appendChild(this._container);
var imageNameElement = document.createElement("h1");
imageNameElement.className = "title";
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
index fff6680..fb6b796 100644
--- a/WebCore/inspector/front-end/InjectedScript.js
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -26,7 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-var injectedScriptConstructor = (function (InjectedScriptHost, inspectedWindow, injectedScriptId, jsEngine) {
+var injectedScriptConstructor = (function (InjectedScriptHost, inspectedWindow, injectedScriptId) {
var InjectedScript = function()
{
@@ -427,9 +427,17 @@ InjectedScript.prototype = {
switch (type) {
case "object":
case "node":
- return this._className(obj);
+ var result = InjectedScriptHost.internalConstructorName(obj);
+ if (result === "Object") {
+ // In Chromium DOM wrapper prototypes will have Object as their constructor name,
+ // get the real DOM wrapper name from the constructor property.
+ var constructorName = obj.constructor && obj.constructor.name;
+ if (constructorName)
+ return constructorName;
+ }
+ return result;
case "array":
- var className = this._className(obj);
+ var className = InjectedScriptHost.internalConstructorName(obj);
if (typeof obj.length === "number")
className += "[" + obj.length + "]";
return className;
@@ -455,25 +463,6 @@ InjectedScript.prototype = {
return "" + obj;
},
- _className: function(obj)
- {
- // We can't use the same code for fetching class names of the dom bindings prototype chain.
- // Both of the methods below result in "Object" names on the foreign engine bindings.
- // I gave up and am using a check below to distinguish between the egine bingings.
-
- if (jsEngine == "JSC") {
- var str = inspectedWindow.Object ? inspectedWindow.Object.prototype.toString.call(obj) : this._toString(obj);
- return str.replace(/^\[object (.*)\]$/i, "$1");
- } else {
- // V8
- if (isFinite(obj.length) && typeof obj.callee === "function") {
- // Arguments.constructor === Object in V8
- return "Arguments";
- }
- return obj.constructor && obj.constructor.name || "Object";
- }
- },
-
_logEvent: function(event)
{
console.log(event.type, event);
@@ -711,11 +700,9 @@ CommandLineAPI.prototype = {
copy: function(object)
{
- if (injectedScript._type(object) === "node") {
- var nodeId = InjectedScriptHost.pushNodePathToFrontend(object, false, false);
- InjectedScriptHost.copyNode(nodeId);
- } else
- InjectedScriptHost.copyText(object);
+ if (injectedScript._type(object) === "node")
+ object = object.outerHTML;
+ InjectedScriptHost.copyText(object);
},
clear: function()
diff --git a/WebCore/inspector/front-end/NetworkItemView.js b/WebCore/inspector/front-end/NetworkItemView.js
new file mode 100644
index 0000000..48e3b19
--- /dev/null
+++ b/WebCore/inspector/front-end/NetworkItemView.js
@@ -0,0 +1,91 @@
+/*
+ * 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.NetworkItemView = function(resource)
+{
+ WebInspector.View.call(this);
+
+ this.element.addStyleClass("network-item-view");
+
+ this._headersView = new WebInspector.ResourceHeadersView(resource);
+ // Do not store reference to content view - it can be recreated.
+ var contentView = WebInspector.ResourceManager.resourceViewForResource(resource);
+
+ this._tabbedPane = new WebInspector.TabbedPane(this.element);
+ this._tabbedPane.appendTab("headers", WebInspector.UIString("Headers"), this._headersView);
+ if (contentView.hasContent()) {
+ // Reusing this view, so hide it at first.
+ contentView.visible = false;
+ this._tabbedPane.appendTab("content", WebInspector.UIString("Content"), contentView);
+ }
+ if (Preferences.showCookiesTab) {
+ this._cookiesView = new WebInspector.ResourceCookiesView(resource);
+ this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView);
+ }
+ if (Preferences.showTimingTab) {
+ var timingView = new WebInspector.ResourceTimingView(resource);
+ this._tabbedPane.appendTab("timing", WebInspector.UIString("Timing"), timingView);
+ }
+
+ this._tabbedPane.addEventListener("tab-selected", this._tabSelected, this);
+}
+
+WebInspector.NetworkItemView.prototype = {
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this._selectTab();
+ },
+
+ _selectTab: function(tabId)
+ {
+ if (!tabId)
+ tabId = WebInspector.settings.resourceViewTab;
+
+ if (!this._tabbedPane.selectTab(tabId)) {
+ this._isInFallbackSelection = true;
+ this._tabbedPane.selectTab("headers");
+ delete this._isInFallbackSelection;
+ }
+ },
+
+ _tabSelected: function(event)
+ {
+ WebInspector.settings.resourceViewTab = event.data.tabId;
+ },
+
+ resize: function()
+ {
+ if (this._cookiesView && this._cookiesView.visible)
+ this._cookiesView.resize();
+ }
+}
+
+WebInspector.NetworkItemView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js
index a695167..8f3cfd6 100644
--- a/WebCore/inspector/front-end/NetworkPanel.js
+++ b/WebCore/inspector/front-end/NetworkPanel.js
@@ -1,7 +1,7 @@
/*
* 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.
+ * 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
@@ -72,6 +72,8 @@ WebInspector.NetworkPanel = function()
this._setLargerResources(WebInspector.settings.resourcesLargeRows);
this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this), true);
+ // Enable faster hint.
+ this._popoverHelper.setTimeout(100);
this.calculator = new WebInspector.NetworkTransferTimeCalculator();
this._filter(this._filterAllElement, false);
@@ -641,27 +643,11 @@ WebInspector.NetworkPanel.prototype = {
show: function()
{
WebInspector.Panel.prototype.show.call(this);
-
this._refreshIfNeeded();
- var visibleView = this.visibleView;
- if (this.visibleResource) {
- this.visibleView.headersVisible = true;
+ if (this.visibleView)
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();
this._positionSummaryBar();
},
@@ -696,13 +682,6 @@ WebInspector.NetworkPanel.prototype = {
WebInspector.Panel.prototype.performSearch.call(this, query);
},
- get visibleView()
- {
- if (this.visibleResource)
- return this.visibleResource._resourcesView;
- return null;
- },
-
refresh: function()
{
this._needsRefresh = false;
@@ -813,28 +792,20 @@ WebInspector.NetworkPanel.prototype = {
this._staleResources.push(resource);
this._scheduleRefresh();
-
- if (!resource || !resource._resourcesView)
+
+ if (!resource)
return;
- if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource, resource._resourcesView))
+ var oldView = WebInspector.ResourceManager.existingResourceViewForResource(resource);
+ if (!oldView)
return;
- var newView = WebInspector.ResourceManager.createResourceView(resource);
-
- 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);
+ if (WebInspector.ResourceManager.resourceViewTypeMatchesResource(resource))
+ return;
- WebInspector.panels.scripts.viewRecreated(oldView, newView);
+ var newView = WebInspector.ResourceManager.recreateResourceView(resource);
+ if (this.visibleView === oldView)
+ this.visibleView = newView;
},
canShowSourceLine: function(url, line)
@@ -856,22 +827,15 @@ WebInspector.NetworkPanel.prototype = {
this._toggleViewingResourceMode();
- if (this.visibleResource && this.visibleResource._resourcesView)
- this.visibleResource._resourcesView.hide();
+ if (this.visibleView) {
+ this.visibleView.detach();
+ delete this.visibleView;
+ }
- var view = WebInspector.ResourceManager.resourceViewForResource(resource);
- view.headersVisible = true;
+ var view = new WebInspector.NetworkItemView(resource);
view.show(this._viewsContainerElement);
+ this.visibleView = view;
- if (line) {
- view.selectContentTab();
- if (view.revealLine)
- view.revealLine(line);
- if (view.highlightLine)
- view.highlightLine(line);
- }
-
- this.visibleResource = resource;
this.updateSidebarWidth();
},
@@ -879,9 +843,10 @@ WebInspector.NetworkPanel.prototype = {
{
this.element.removeStyleClass("viewing-resource");
- if (this.visibleResource && this.visibleResource._resourcesView)
- this.visibleResource._resourcesView.hide();
- delete this.visibleResource;
+ if (this.visibleView) {
+ this.visibleView.detach();
+ delete this.visibleView;
+ }
if (this._lastSelectedGraphTreeElement)
this._lastSelectedGraphTreeElement.select(true);
@@ -923,87 +888,8 @@ WebInspector.NetworkPanel.prototype = {
_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 tableElement = WebInspector.ResourceTimingView.createTimingTable(resource);
var popover = new WebInspector.Popover(tableElement);
popover.show(anchor);
return popover;
@@ -1019,6 +905,8 @@ WebInspector.NetworkPanel.prototype = {
this.sidebarElement.style.right = 0;
this.sidebarElement.style.removeProperty("width");
this._summaryBarElement.style.removeProperty("width");
+ if (this._dataGrid.selectedNode)
+ this._dataGrid.selectedNode.selected = false;
}
if (this._briefGrid) {
@@ -1388,16 +1276,19 @@ WebInspector.NetworkDataGridNode.prototype = {
this._sizeCell = this._createDivInTD("size");
this._timeCell = this._createDivInTD("time");
this._createTimelineCell();
+ this._nameCell.addEventListener("click", this.select.bind(this), false);
},
select: function()
{
- WebInspector.DataGridNode.prototype.select.apply(this, arguments);
this._panel._showResource(this._resource);
+ WebInspector.DataGridNode.prototype.select.apply(this, arguments);
},
get selectable()
{
+ if (!this._panel._viewingResourceMode)
+ return false;
if (!this._panel._hiddenCategories.all)
return true;
if (this._panel._hiddenCategories[this._resource.category.name])
@@ -1419,7 +1310,6 @@ WebInspector.NetworkDataGridNode.prototype = {
{
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";
@@ -1435,6 +1325,7 @@ WebInspector.NetworkDataGridNode.prototype = {
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);
@@ -1443,6 +1334,8 @@ WebInspector.NetworkDataGridNode.prototype = {
this._labelRightElement.className = "network-graph-label";
this._barAreaElement.appendChild(this._labelRightElement);
+ this._graphElement.addEventListener("mouseover", this._refreshLabelPositions.bind(this), false);
+
this._timelineCell = document.createElement("td");
this._timelineCell.className = "timeline-column";
this._element.appendChild(this._timelineCell);
@@ -1529,6 +1422,14 @@ WebInspector.NetworkDataGridNode.prototype = {
{
this._statusCell.removeChildren();
+ var fromCache = this._resource.cached;
+ if (fromCache) {
+ this._statusCell.textContent = WebInspector.UIString("(from cache)");
+ this._statusCell.addStyleClass("network-dim-cell");
+ return;
+ }
+
+ this._statusCell.removeStyleClass("network-dim-cell");
if (this._resource.statusCode) {
this._statusCell.appendChild(document.createTextNode(this._resource.statusCode));
this._statusCell.removeStyleClass("network-dim-cell");
@@ -1577,8 +1478,6 @@ WebInspector.NetworkDataGridNode.prototype = {
refreshGraph: function(calculator)
{
var percentages = calculator.computeBarGraphPercentages(this._resource);
- var labels = calculator.computeBarGraphLabels(this._resource);
-
this._percentages = percentages;
this._barAreaElement.removeStyleClass("hidden");
@@ -1594,6 +1493,7 @@ WebInspector.NetworkDataGridNode.prototype = {
this._barLeftElement.style.setProperty("right", (100 - percentages.end) + "%");
this._barRightElement.style.setProperty("left", percentages.middle + "%");
+ var labels = calculator.computeBarGraphLabels(this._resource);
this._labelLeftElement.textContent = labels.left;
this._labelRightElement.textContent = labels.right;
diff --git a/WebCore/inspector/front-end/Popover.js b/WebCore/inspector/front-end/Popover.js
index 59b48f9..32535e9 100644
--- a/WebCore/inspector/front-end/Popover.js
+++ b/WebCore/inspector/front-end/Popover.js
@@ -155,9 +155,15 @@ WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopup, showOn
this._onHide = onHide;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
+ this.setTimeout(1000);
}
WebInspector.PopoverHelper.prototype = {
+ setTimeout: function(timeout)
+ {
+ this._timeout = timeout;
+ },
+
_mouseDown: function(event)
{
this._killHidePopupTimer();
@@ -170,7 +176,7 @@ WebInspector.PopoverHelper.prototype = {
if (this._hoverElement === event.target || (this._hoverElement && this._hoverElement.isAncestor(event.target)))
return;
- // User has 500ms to reach the popup.
+ // User has 500ms (this._timeout / 2) to reach the popup.
if (this._popup && !this._hidePopupTimer) {
var self = this;
function doHide()
@@ -178,7 +184,7 @@ WebInspector.PopoverHelper.prototype = {
self._hidePopup();
delete self._hidePopupTimer;
}
- this._hidePopupTimer = setTimeout(doHide, 500);
+ this._hidePopupTimer = setTimeout(doHide, this._timeout / 2);
}
this._handleMouseAction(event);
@@ -192,7 +198,7 @@ WebInspector.PopoverHelper.prototype = {
if (!this._hoverElement)
return;
- const toolTipDelay = isMouseDown ? 0 : (this._popup ? 600 : 1000);
+ const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},
diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js
index 0aa4174..50795e8 100644
--- a/WebCore/inspector/front-end/ProfilesPanel.js
+++ b/WebCore/inspector/front-end/ProfilesPanel.js
@@ -123,6 +123,7 @@ WebInspector.ProfilesPanel = function()
this._profiles = [];
this._profilerEnabled = Preferences.profilerAlwaysEnabled;
+ this._tempHeapSnapshots = [];
this._reset();
}
@@ -411,6 +412,25 @@ WebInspector.ProfilesPanel.prototype = {
}
},
+ addHeapSnapshotChunk: function(uid, chunk)
+ {
+ if (this._tempHeapSnapshots[uid])
+ this._tempHeapSnapshots[uid] += chunk;
+ else
+ this._tempHeapSnapshots[uid] = chunk;
+ },
+
+ finishHeapSnapshot: function(uid)
+ {
+ var profile =
+ this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)];
+ if (profile) {
+ var view = profile.__profilesPanelProfileType.viewForProfile(profile);
+ view.snapshotLoaded(uid, JSON.parse(this._tempHeapSnapshots[uid]));
+ }
+ delete this._tempHeapSnapshots[uid];
+ },
+
showView: function(view)
{
this.showProfile(view.profile);
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index 24af165..aefdd6c 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -163,11 +163,6 @@ WebInspector.Resource.prototype = {
get responseReceivedTime()
{
- if (this.timing && this.timing.requestTime) {
- // Calculate responseReceivedTime from timing data for better accuracy.
- // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
- return this.timing.requestTime + this.timing.receiveHeadersEnd / 1000.0;
- }
return this._responseReceivedTime || -1;
},
@@ -183,13 +178,15 @@ WebInspector.Resource.prototype = {
set endTime(x)
{
- // In case of fast load (or in case of cached resources), endTime on network stack
- // can be less then m_responseReceivedTime measured in WebCore. Normalize it here,
- // prefer actualEndTime to m_responseReceivedTime.
- if (x < this.responseReceivedTime)
- this.responseReceivedTime = x;
-
- this._endTime = x;
+ if (this.timing && this.timing.requestTime) {
+ // Check against accurate responseReceivedTime.
+ this._endTime = Math.max(x, this.responseReceivedTime);
+ } else {
+ // Prefer endTime since it might be from the network stack.
+ this._endTime = x;
+ if (this._responseReceivedTime > x)
+ this._responseReceivedTime = x;
+ }
},
get duration()
@@ -299,8 +296,15 @@ WebInspector.Resource.prototype = {
set timing(x)
{
- if (!this._cached)
+ if (x && !this._cached) {
+ // Take startTime and responseReceivedTime from timing data for better accuracy.
+ // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
+ this._startTime = x.requestTime;
+ this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;
+
this._timing = x;
+ this.dispatchEventToListeners("timing changed");
+ }
},
get mimeType()
@@ -621,11 +625,71 @@ WebInspector.Resource.prototype = {
return this._content;
},
- set content(content)
+ get contentTimestamp()
+ {
+ return this._contentTimestamp;
+ },
+
+ setInitialContent: function(content)
{
this._content = content;
},
+ isLocallyModified: function()
+ {
+ return !!this._baseRevision;
+ },
+
+ setContent: function(newContent, onRevert)
+ {
+ var revisionResource = new WebInspector.Resource(null, this.url);
+ revisionResource.type = this.type;
+ revisionResource.loader = this.loader;
+ revisionResource.timestamp = this.timestamp;
+ revisionResource._content = this._content;
+ revisionResource._actualResource = this;
+ revisionResource._fireOnRevert = onRevert;
+
+ if (this.finished)
+ revisionResource.finished = true;
+ else {
+ function finished()
+ {
+ this.removeEventListener("finished", finished);
+ revisionResource.finished = true;
+ }
+ this.addEventListener("finished", finished.bind(this));
+ }
+
+ if (!this._baseRevision)
+ this._baseRevision = revisionResource;
+ else
+ revisionResource._baseRevision = this._baseRevision;
+
+ var data = { revision: revisionResource };
+ this._content = newContent;
+ this.timestamp = new Date();
+ this.dispatchEventToListeners("content-changed", data);
+ },
+
+ revertToThis: function()
+ {
+ if (!this._actualResource || !this._fireOnRevert)
+ return;
+
+ function callback(content)
+ {
+ if (content)
+ this._fireOnRevert(content);
+ }
+ this.requestContent(callback.bind(this));
+ },
+
+ get baseRevision()
+ {
+ return this._baseRevision;
+ },
+
requestContent: function(callback)
{
if (this._content) {
diff --git a/WebCore/inspector/front-end/ResourceCookiesView.js b/WebCore/inspector/front-end/ResourceCookiesView.js
new file mode 100644
index 0000000..e419070
--- /dev/null
+++ b/WebCore/inspector/front-end/ResourceCookiesView.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ResourceCookiesView = function(resource)
+{
+ WebInspector.View.call(this);
+ this.element.addStyleClass("resource-cookies-view");
+
+ this._resource = resource;
+
+ resource.addEventListener("requestHeaders changed", this.show, this);
+ resource.addEventListener("responseHeaders changed", this.show, this);
+}
+
+WebInspector.ResourceCookiesView.prototype = {
+ show: function(parentElement)
+ {
+ if (!this._resource.requestCookies && !this._resource.responseCookies) {
+ if (!this._emptyMsgElement) {
+ this._emptyMsgElement = document.createElement("div");
+ this._emptyMsgElement.className = "storage-empty-view";
+ this._emptyMsgElement.textContent = WebInspector.UIString("This request has no cookies.");
+ this.element.appendChild(this._emptyMsgElement);
+ }
+ WebInspector.View.prototype.show.call(this, parentElement);
+ return;
+ }
+
+ if (this._emptyMsgElement)
+ this._emptyMsgElement.parentElement.removeChild(this._emptyMsgElement);
+
+ this._cookiesTable = new WebInspector.CookiesTable(null, true, true);
+ this._cookiesTable.addCookiesFolder(WebInspector.UIString("Request Cookies"), this._resource.requestCookies);
+ this._cookiesTable.addCookiesFolder(WebInspector.UIString("Response Cookies"), this._resource.responseCookies);
+ this.element.appendChild(this._cookiesTable.element);
+
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this._cookiesTable.updateWidths();
+ }
+}
+
+WebInspector.ResourceCookiesView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/ResourceHeadersView.js b/WebCore/inspector/front-end/ResourceHeadersView.js
new file mode 100644
index 0000000..ee1010f
--- /dev/null
+++ b/WebCore/inspector/front-end/ResourceHeadersView.js
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) IBM Corp. 2009 All rights reserved.
+ * 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:
+ *
+ * 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.ResourceHeadersView = function(resource)
+{
+ WebInspector.View.call(this);
+ this.element.addStyleClass("resource-headers-view");
+
+ this._resource = resource;
+
+ this._headersListElement = document.createElement("ol");
+ this._headersListElement.className = "outline-disclosure";
+ this.element.appendChild(this._headersListElement);
+
+ this._headersTreeOutline = new TreeOutline(this._headersListElement);
+ this._headersTreeOutline.expandTreeElementsWhenArrowing = true;
+
+ this._urlTreeElement = new TreeElement("", null, false);
+ this._urlTreeElement.selectable = false;
+ this._headersTreeOutline.appendChild(this._urlTreeElement);
+
+ this._requestMethodTreeElement = new TreeElement("", null, false);
+ this._requestMethodTreeElement.selectable = false;
+ this._headersTreeOutline.appendChild(this._requestMethodTreeElement);
+
+ this._statusCodeTreeElement = new TreeElement("", null, false);
+ this._statusCodeTreeElement.selectable = false;
+ this._headersTreeOutline.appendChild(this._statusCodeTreeElement);
+
+ this._requestHeadersTreeElement = new TreeElement("", null, true);
+ this._requestHeadersTreeElement.expanded = true;
+ this._requestHeadersTreeElement.selectable = false;
+ this._headersTreeOutline.appendChild(this._requestHeadersTreeElement);
+
+ this._decodeHover = WebInspector.UIString("Double-Click to toggle between URL encoded and decoded formats");
+ this._decodeRequestParameters = true;
+
+ this._queryStringTreeElement = new TreeElement("", null, true);
+ this._queryStringTreeElement.expanded = true;
+ this._queryStringTreeElement.selectable = false;
+ this._queryStringTreeElement.hidden = true;
+ this._headersTreeOutline.appendChild(this._queryStringTreeElement);
+
+ this._formDataTreeElement = new TreeElement("", null, true);
+ this._formDataTreeElement.expanded = true;
+ this._formDataTreeElement.selectable = false;
+ this._formDataTreeElement.hidden = true;
+ this._headersTreeOutline.appendChild(this._formDataTreeElement);
+
+ this._requestPayloadTreeElement = new TreeElement(WebInspector.UIString("Request Payload"), null, true);
+ this._requestPayloadTreeElement.expanded = true;
+ this._requestPayloadTreeElement.selectable = false;
+ this._requestPayloadTreeElement.hidden = true;
+ this._headersTreeOutline.appendChild(this._requestPayloadTreeElement);
+
+ this._responseHeadersTreeElement = new TreeElement("", null, true);
+ this._responseHeadersTreeElement.expanded = true;
+ this._responseHeadersTreeElement.selectable = false;
+ this._headersTreeOutline.appendChild(this._responseHeadersTreeElement);
+
+ resource.addEventListener("requestHeaders changed", this._refreshRequestHeaders, this);
+ resource.addEventListener("responseHeaders changed", this._refreshResponseHeaders, this);
+ resource.addEventListener("finished", this._refreshHTTPInformation, this);
+
+ this._refreshURL();
+ this._refreshQueryString();
+ this._refreshRequestHeaders();
+ this._refreshResponseHeaders();
+ this._refreshHTTPInformation();
+}
+
+WebInspector.ResourceHeadersView.prototype = {
+
+ _refreshURL: function()
+ {
+ this._urlTreeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request URL") + ":</div>" +
+ "<div class=\"header-value source-code\">" + this._resource.url.escapeHTML() + "</div>";
+ },
+
+ _refreshQueryString: function()
+ {
+ var queryParameters = this._resource.queryParameters;
+ this._queryStringTreeElement.hidden = !queryParameters;
+ if (queryParameters)
+ this._refreshParms(WebInspector.UIString("Query String Parameters"), queryParameters, this._queryStringTreeElement);
+ },
+
+ _refreshFormData: function()
+ {
+ this._formDataTreeElement.hidden = true;
+ this._requestPayloadTreeElement.hidden = true;
+
+ var formData = this._resource.requestFormData;
+ if (!formData)
+ return;
+
+ var formParameters = this._resource.formParameters;
+ if (formParameters) {
+ this._formDataTreeElement.hidden = false;
+ this._refreshParms(WebInspector.UIString("Form Data"), formParameters, this._formDataTreeElement);
+ } else {
+ this._requestPayloadTreeElement.hidden = false;
+ this._refreshRequestPayload(formData);
+ }
+ },
+
+ _refreshRequestPayload: function(formData)
+ {
+ this._requestPayloadTreeElement.removeChildren();
+
+ var title = "<div class=\"raw-form-data header-value source-code\">" + formData.escapeHTML() + "</div>";
+ var parmTreeElement = new TreeElement(null, null, false);
+ parmTreeElement.titleHTML = title;
+ parmTreeElement.selectable = false;
+ this._requestPayloadTreeElement.appendChild(parmTreeElement);
+ },
+
+ _refreshParms: function(title, parms, parmsTreeElement)
+ {
+ parmsTreeElement.removeChildren();
+
+ parmsTreeElement.titleHTML = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";
+
+ for (var i = 0; i < parms.length; ++i) {
+ var name = parms[i].name;
+ var value = parms[i].value;
+
+ var errorDecoding = false;
+ if (this._decodeRequestParameters) {
+ if (value.indexOf("%") >= 0) {
+ try {
+ value = decodeURIComponent(value);
+ } catch(e) {
+ errorDecoding = true;
+ }
+ }
+
+ value = value.replace(/\+/g, " ");
+ }
+
+ valueEscaped = value.escapeHTML();
+ if (errorDecoding)
+ valueEscaped += " <span class=\"error-message\">" + WebInspector.UIString("(unable to decode value)").escapeHTML() + "</span>";
+
+ var title = "<div class=\"header-name\">" + name.escapeHTML() + ":</div>";
+ title += "<div class=\"header-value source-code\">" + valueEscaped + "</div>";
+
+ var parmTreeElement = new TreeElement(null, null, false);
+ parmTreeElement.titleHTML = title;
+ parmTreeElement.selectable = false;
+ parmTreeElement.tooltip = this._decodeHover;
+ parmTreeElement.ondblclick = this._toggleURLdecoding.bind(this);
+ parmsTreeElement.appendChild(parmTreeElement);
+ }
+ },
+
+ _toggleURLdecoding: function(event)
+ {
+ this._decodeRequestParameters = !this._decodeRequestParameters;
+ this._refreshQueryString();
+ this._refreshFormData();
+ },
+
+ _getHeaderValue: function(headers, key)
+ {
+ var lowerKey = key.toLowerCase();
+ for (var testKey in headers) {
+ if (testKey.toLowerCase() === lowerKey)
+ return headers[testKey];
+ }
+ },
+
+ _refreshRequestHeaders: function()
+ {
+ var additionalRow = null;
+ if (typeof this._resource.webSocketRequestKey3 !== "undefined")
+ additionalRow = {header: "(Key3)", value: this._resource.webSocketRequestKey3};
+ this._refreshHeaders(WebInspector.UIString("Request Headers"), this._resource.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
+ this._refreshFormData();
+ },
+
+ _refreshResponseHeaders: function()
+ {
+ var additionalRow = null;
+ if (typeof this._resource.webSocketChallengeResponse !== "undefined")
+ additionalRow = {header: "(Challenge Response)", value: this._resource.webSocketChallengeResponse};
+ this._refreshHeaders(WebInspector.UIString("Response Headers"), this._resource.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
+ },
+
+ _refreshHTTPInformation: function()
+ {
+ var requestMethodElement = this._requestMethodTreeElement;
+ requestMethodElement.hidden = !this._resource.statusCode;
+ var statusCodeElement = this._statusCodeTreeElement;
+ statusCodeElement.hidden = !this._resource.statusCode;
+ var statusCodeImage = "";
+
+ if (this._resource.statusCode) {
+ var statusImageSource = "";
+ if (this._resource.statusCode < 300)
+ statusImageSource = "Images/successGreenDot.png";
+ else if (this._resource.statusCode < 400)
+ statusImageSource = "Images/warningOrangeDot.png";
+ else
+ statusImageSource = "Images/errorRedDot.png";
+
+ var statusTextEscaped = this._resource.statusCode + " " + this._resource.statusText.escapeHTML();
+ statusCodeImage = "<img class=\"resource-status-image\" src=\"" + statusImageSource + "\" title=\"" + statusTextEscaped + "\">";
+
+ requestMethodElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request Method") + ":</div>" +
+ "<div class=\"header-value source-code\">" + this._resource.requestMethod + "</div>";
+
+ statusCodeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Status Code") + ":</div>" +
+ statusCodeImage + "<div class=\"header-value source-code\">" + statusTextEscaped + "</div>";
+ }
+ },
+
+ _refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
+ {
+ headersTreeElement.removeChildren();
+
+ var length = headers.length;
+ headersTreeElement.titleHTML = title.escapeHTML() + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", length) + "</span>";
+ headersTreeElement.hidden = !length;
+
+ var length = headers.length;
+ for (var i = 0; i < length; ++i) {
+ var title = "<div class=\"header-name\">" + headers[i].header.escapeHTML() + ":</div>";
+ title += "<div class=\"header-value source-code\">" + headers[i].value.escapeHTML() + "</div>"
+
+ var headerTreeElement = new TreeElement(null, null, false);
+ headerTreeElement.titleHTML = title;
+ headerTreeElement.selectable = false;
+ headersTreeElement.appendChild(headerTreeElement);
+ }
+
+ if (additionalRow) {
+ var title = "<div class=\"header-name\">" + additionalRow.header.escapeHTML() + ":</div>";
+ title += "<div class=\"header-value source-code\">" + additionalRow.value.escapeHTML() + "</div>"
+
+ var headerTreeElement = new TreeElement(null, null, false);
+ headerTreeElement.titleHTML = title;
+ headerTreeElement.selectable = false;
+ headersTreeElement.appendChild(headerTreeElement);
+ }
+ }
+}
+
+WebInspector.ResourceHeadersView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js
index 223e435..056be8c 100644
--- a/WebCore/inspector/front-end/ResourceManager.js
+++ b/WebCore/inspector/front-end/ResourceManager.js
@@ -39,7 +39,7 @@ WebInspector.ResourceManager = function()
"didFinishLoading",
"didFailLoading",
"didLoadResourceFromMemoryCache",
- "setOverrideContent",
+ "setInitialContent",
"didCommitLoadForFrame",
"frameDetachedFromParent",
"didCreateWebSocket",
@@ -141,9 +141,11 @@ WebInspector.ResourceManager.prototype = {
var resource = this._resourcesById[identifier];
if (!resource)
return;
- this._updateResourceWithResponse(resource, response);
- resource.type = WebInspector.Resource.Type[resourceType];
+
resource.responseReceivedTime = time;
+ resource.type = WebInspector.Resource.Type[resourceType];
+
+ this._updateResourceWithResponse(resource, response);
WebInspector.panels.network.refreshResource(resource);
this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource);
@@ -170,9 +172,13 @@ WebInspector.ResourceManager.prototype = {
else
resource.timing = response.timing;
- if (response.rawHeaders) {
- resource.requestHeaders = response.rawHeaders.requestHeaders;
- resource.responseHeaders = response.rawHeaders.responseHeaders;
+ if (response.loadInfo) {
+ if (response.loadInfo.httpStatusCode)
+ resource.statusCode = response.loadInfo.httpStatusCode;
+ if (response.loadInfo.httpStatusText)
+ resource.statusText = response.loadInfo.httpStatusText;
+ resource.requestHeaders = response.loadInfo.requestHeaders;
+ resource.responseHeaders = response.loadInfo.responseHeaders;
}
},
@@ -194,8 +200,8 @@ WebInspector.ResourceManager.prototype = {
if (!resource)
return;
- resource.finished = true;
resource.endTime = finishTime;
+ resource.finished = true;
WebInspector.panels.network.refreshResource(resource);
WebInspector.panels.audits.resourceFinished(resource);
@@ -242,14 +248,14 @@ WebInspector.ResourceManager.prototype = {
this._updateResourceWithResponse(resource, cachedResource.response);
},
- setOverrideContent: function(identifier, sourceString, type)
+ setInitialContent: function(identifier, sourceString, type)
{
var resource = WebInspector.panels.network.resources[identifier];
if (!resource)
return;
resource.type = WebInspector.Resource.Type[type];
- resource.content = sourceString;
+ resource.setInitialContent(sourceString);
WebInspector.panels.resources.refreshResource(resource);
WebInspector.panels.network.refreshResource(resource);
},
@@ -441,8 +447,9 @@ WebInspector.ResourceManager.createResourceView = function(resource)
}
}
-WebInspector.ResourceManager.resourceViewTypeMatchesResource = function(resource, resourceView)
+WebInspector.ResourceManager.resourceViewTypeMatchesResource = function(resource)
{
+ var resourceView = resource._resourcesView;
switch (resource.category) {
case WebInspector.resourceCategories.documents:
case WebInspector.resourceCategories.stylesheets:
@@ -467,6 +474,28 @@ WebInspector.ResourceManager.resourceViewForResource = function(resource)
return resource._resourcesView;
}
+WebInspector.ResourceManager.recreateResourceView = function(resource)
+{
+ var newView = WebInspector.ResourceManager.createResourceView(resource);
+
+ var oldView = resource._resourcesView;
+ var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null;
+ var scrollTop = oldView.scrollTop;
+
+ resource._resourcesView.detach();
+ delete resource._resourcesView;
+
+ resource._resourcesView = newView;
+
+ if (oldViewParentNode)
+ newView.show(oldViewParentNode);
+ if (scrollTop)
+ newView.scrollTop = scrollTop;
+
+ WebInspector.panels.scripts.viewRecreated(oldView, newView);
+ return newView;
+}
+
WebInspector.ResourceManager.existingResourceViewForResource = function(resource)
{
if (!resource)
diff --git a/WebCore/inspector/front-end/ResourceTimingView.js b/WebCore/inspector/front-end/ResourceTimingView.js
new file mode 100644
index 0000000..04f22f8
--- /dev/null
+++ b/WebCore/inspector/front-end/ResourceTimingView.js
@@ -0,0 +1,157 @@
+/*
+ * 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.ResourceTimingView = function(resource)
+{
+ WebInspector.View.call(this);
+ this.element.addStyleClass("resource-timing-view");
+
+ this._resource = resource;
+
+ resource.addEventListener("timing changed", this._refresh, this);
+}
+
+WebInspector.ResourceTimingView.prototype = {
+ show: function(parentElement)
+ {
+ if (!this._resource.timing) {
+ if (!this._emptyMsgElement) {
+ this._emptyMsgElement = document.createElement("div");
+ this._emptyMsgElement.className = "storage-empty-view";
+ this._emptyMsgElement.textContent = WebInspector.UIString("This request has no detailed timing info.");
+ this.element.appendChild(this._emptyMsgElement);
+ }
+ WebInspector.View.prototype.show.call(this, parentElement);
+ return;
+ }
+
+ if (this._emptyMsgElement)
+ this._emptyMsgElement.parentElement.removeChild(this._emptyMsgElement);
+
+ this._refresh();
+ WebInspector.View.prototype.show.call(this, parentElement);
+ },
+
+ _refresh: function()
+ {
+ if (this._tableElement)
+ this._tableElement.parentElement.removeChild(this._tableElement);
+
+ this._tableElement = WebInspector.ResourceTimingView.createTimingTable(this._resource);
+ this.element.appendChild(this._tableElement);
+ }
+}
+
+WebInspector.ResourceTimingView.createTimingTable = function(resource)
+{
+ var tableElement = document.createElement("table");
+ var rows = [];
+
+ function addRow(title, className, start, end, color)
+ {
+ var row = {};
+ row.title = title;
+ row.className = className;
+ row.start = start;
+ row.end = end;
+ rows.push(row);
+ }
+
+ if (resource.timing.proxyStart !== -1)
+ addRow(WebInspector.UIString("Proxy"), "proxy", resource.timing.proxyStart, resource.timing.proxyEnd);
+
+ if (resource.timing.dnsStart !== -1)
+ addRow(WebInspector.UIString("DNS Lookup"), "dns", resource.timing.dnsStart, resource.timing.dnsEnd);
+
+ if (resource.timing.connectStart !== -1) {
+ if (resource.connectionReused)
+ addRow(WebInspector.UIString("Blocking"), "connecting", 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"), "connecting", connectStart, resource.timing.connectEnd);
+ }
+ }
+
+ if (resource.timing.sslStart !== -1)
+ addRow(WebInspector.UIString("SSL"), "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"), "sending", resource.timing.sendStart, resource.timing.sendEnd);
+ addRow(WebInspector.UIString("Waiting"), "waiting", resource.timing.sendEnd, resource.timing.receiveHeadersEnd);
+ addRow(WebInspector.UIString("Receiving"), "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 " + rows[i].className;
+ 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);
+ }
+ return tableElement;
+}
+
+WebInspector.ResourceTimingView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js
index 19e3052..a284da1 100644
--- a/WebCore/inspector/front-end/ResourceView.js
+++ b/WebCore/inspector/front-end/ResourceView.js
@@ -7,13 +7,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * 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.
+ * 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
@@ -30,403 +30,15 @@
WebInspector.ResourceView = function(resource)
{
WebInspector.View.call(this);
-
this.element.addStyleClass("resource-view");
-
this.resource = resource;
-
- this.tabbedPane = new WebInspector.TabbedPane(this.element);
-
- this.headersElement = document.createElement("div");
- this.headersElement.className = "resource-view-headers";
- this.tabbedPane.appendTab("headers", WebInspector.UIString("Headers"), this.headersElement, this._selectTab.bind(this, "headers"));
-
- if (this.hasContentTab()) {
- this.contentElement = document.createElement("div");
- this.contentElement.className = "resource-view-content";
- this.tabbedPane.appendTab("content", WebInspector.UIString("Content"), this.contentElement, this._selectTab.bind(this, "content"));
- }
-
- this.headersListElement = document.createElement("ol");
- this.headersListElement.className = "outline-disclosure";
- this.headersElement.appendChild(this.headersListElement);
-
- this.headersTreeOutline = new TreeOutline(this.headersListElement);
- this.headersTreeOutline.expandTreeElementsWhenArrowing = true;
-
- this.urlTreeElement = new TreeElement("", null, false);
- this.urlTreeElement.selectable = false;
- this.headersTreeOutline.appendChild(this.urlTreeElement);
-
- this.requestMethodTreeElement = new TreeElement("", null, false);
- this.requestMethodTreeElement.selectable = false;
- this.headersTreeOutline.appendChild(this.requestMethodTreeElement);
-
- this.statusCodeTreeElement = new TreeElement("", null, false);
- this.statusCodeTreeElement.selectable = false;
- this.headersTreeOutline.appendChild(this.statusCodeTreeElement);
-
- this.requestHeadersTreeElement = new TreeElement("", null, true);
- this.requestHeadersTreeElement.expanded = true;
- this.requestHeadersTreeElement.selectable = false;
- this.headersTreeOutline.appendChild(this.requestHeadersTreeElement);
-
- this._decodeHover = WebInspector.UIString("Double-Click to toggle between URL encoded and decoded formats");
- this._decodeRequestParameters = true;
-
- this.queryStringTreeElement = new TreeElement("", null, true);
- this.queryStringTreeElement.expanded = true;
- this.queryStringTreeElement.selectable = false;
- this.queryStringTreeElement.hidden = true;
- this.headersTreeOutline.appendChild(this.queryStringTreeElement);
-
- this.formDataTreeElement = new TreeElement("", null, true);
- this.formDataTreeElement.expanded = true;
- this.formDataTreeElement.selectable = false;
- this.formDataTreeElement.hidden = true;
- this.headersTreeOutline.appendChild(this.formDataTreeElement);
-
- this.requestPayloadTreeElement = new TreeElement(WebInspector.UIString("Request Payload"), null, true);
- this.requestPayloadTreeElement.expanded = true;
- this.requestPayloadTreeElement.selectable = false;
- this.requestPayloadTreeElement.hidden = true;
- this.headersTreeOutline.appendChild(this.requestPayloadTreeElement);
-
- this.responseHeadersTreeElement = new TreeElement("", null, true);
- this.responseHeadersTreeElement.expanded = true;
- this.responseHeadersTreeElement.selectable = false;
- this.headersTreeOutline.appendChild(this.responseHeadersTreeElement);
-
- this.headersVisible = true;
-
- resource.addEventListener("requestHeaders changed", this._refreshRequestHeaders, this);
- resource.addEventListener("responseHeaders changed", this._refreshResponseHeaders, this);
- resource.addEventListener("finished", this._refreshHTTPInformation, this);
-
- this._refreshURL();
- this._refreshQueryString();
- this._refreshRequestHeaders();
- this._refreshResponseHeaders();
- this._refreshHTTPInformation();
- this._selectTab();
}
WebInspector.ResourceView.prototype = {
- attach: function()
- {
- if (!this.element.parentNode) {
- var parentElement = (document.getElementById("resource-views") || document.getElementById("script-resource-views"));
- if (parentElement)
- parentElement.appendChild(this.element);
- }
- },
-
- show: function(parentElement)
- {
- WebInspector.View.prototype.show.call(this, parentElement);
- this._selectTab();
- },
-
- set headersVisible(x)
+ hasContent: function()
{
- if (x === this._headersVisible)
- return;
- this._headersVisible = x;
- if (x)
- this.element.addStyleClass("headers-visible");
- else
- this.element.removeStyleClass("headers-visible");
- this._selectTab();
- },
-
- resize: function()
- {
- if (this._cookiesView && !this._cookiesView.element.hasStyleClass("hidden"))
- this._cookiesView.resize();
- },
-
- selectContentTab: function()
- {
- this._selectTab("content");
- },
-
- _selectTab: function(tab)
- {
- if (tab)
- WebInspector.settings.resourceViewTab = tab;
- else {
- var preferredTab = WebInspector.settings.resourceViewTab;
- tab = "content";
-
- // Honor user tab preference (if we can). Fallback to content if headers not visible, headers otherwise.
- if (this._headersVisible)
- tab = this.tabbedPane.hasTab(preferredTab) ? preferredTab : "headers";
- }
- this.tabbedPane.selectTabById(tab);
- if (tab === "content" && this.hasContentTab())
- this.contentTabSelected();
- },
-
- hasContentTab: function()
- {
- // Derived classes should override this method and define this.contentTabSelected for content rendering.
return false;
- },
-
- _refreshURL: function()
- {
- this.urlTreeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request URL") + ":</div>" +
- "<div class=\"header-value source-code\">" + this.resource.url.escapeHTML() + "</div>";
- },
-
- _refreshQueryString: function()
- {
- var queryParameters = this.resource.queryParameters;
- this.queryStringTreeElement.hidden = !queryParameters;
- if (queryParameters)
- this._refreshParms(WebInspector.UIString("Query String Parameters"), queryParameters, this.queryStringTreeElement);
- },
-
- _refreshFormData: function()
- {
- this.formDataTreeElement.hidden = true;
- this.requestPayloadTreeElement.hidden = true;
-
- var formData = this.resource.requestFormData;
- if (!formData)
- return;
-
- var formParameters = this.resource.formParameters;
- if (formParameters) {
- this.formDataTreeElement.hidden = false;
- this._refreshParms(WebInspector.UIString("Form Data"), formParameters, this.formDataTreeElement);
- } else {
- this.requestPayloadTreeElement.hidden = false;
- this._refreshRequestPayload(formData);
- }
- },
-
- _refreshRequestPayload: function(formData)
- {
- this.requestPayloadTreeElement.removeChildren();
-
- var title = "<div class=\"raw-form-data header-value source-code\">" + formData.escapeHTML() + "</div>";
- var parmTreeElement = new TreeElement(null, null, false);
- parmTreeElement.titleHTML = title;
- parmTreeElement.selectable = false;
- this.requestPayloadTreeElement.appendChild(parmTreeElement);
- },
-
- _refreshParms: function(title, parms, parmsTreeElement)
- {
- parmsTreeElement.removeChildren();
-
- parmsTreeElement.titleHTML = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";
-
- for (var i = 0; i < parms.length; ++i) {
- var name = parms[i].name;
- var value = parms[i].value;
-
- var errorDecoding = false;
- if (this._decodeRequestParameters) {
- if (value.indexOf("%") >= 0) {
- try {
- value = decodeURIComponent(value);
- } catch(e) {
- errorDecoding = true;
- }
- }
-
- value = value.replace(/\+/g, " ");
- }
-
- valueEscaped = value.escapeHTML();
- if (errorDecoding)
- valueEscaped += " <span class=\"error-message\">" + WebInspector.UIString("(unable to decode value)").escapeHTML() + "</span>";
-
- var title = "<div class=\"header-name\">" + name.escapeHTML() + ":</div>";
- title += "<div class=\"header-value source-code\">" + valueEscaped + "</div>";
-
- var parmTreeElement = new TreeElement(null, null, false);
- parmTreeElement.titleHTML = title;
- parmTreeElement.selectable = false;
- parmTreeElement.tooltip = this._decodeHover;
- parmTreeElement.ondblclick = this._toggleURLdecoding.bind(this);
- parmsTreeElement.appendChild(parmTreeElement);
- }
- },
-
- _toggleURLdecoding: function(event)
- {
- this._decodeRequestParameters = !this._decodeRequestParameters;
- this._refreshQueryString();
- this._refreshFormData();
- },
-
- _getHeaderValue: function(headers, key)
- {
- var lowerKey = key.toLowerCase();
- for (var testKey in headers) {
- if (testKey.toLowerCase() === lowerKey)
- return headers[testKey];
- }
- },
-
- _refreshRequestHeaders: function()
- {
- var additionalRow = null;
- if (typeof this.resource.webSocketRequestKey3 !== "undefined")
- additionalRow = {header: "(Key3)", value: this.resource.webSocketRequestKey3};
- this._refreshHeaders(WebInspector.UIString("Request Headers"), this.resource.sortedRequestHeaders, additionalRow, this.requestHeadersTreeElement);
- this._refreshFormData();
- this._refreshCookies();
- },
-
- _refreshResponseHeaders: function()
- {
- var additionalRow = null;
- if (typeof this.resource.webSocketChallengeResponse !== "undefined")
- additionalRow = {header: "(Challenge Response)", value: this.resource.webSocketChallengeResponse};
- this._refreshHeaders(WebInspector.UIString("Response Headers"), this.resource.sortedResponseHeaders, additionalRow, this.responseHeadersTreeElement);
- this._refreshCookies();
- },
-
- _refreshHTTPInformation: function()
- {
- var requestMethodElement = this.requestMethodTreeElement;
- requestMethodElement.hidden = !this.resource.statusCode;
- var statusCodeElement = this.statusCodeTreeElement;
- statusCodeElement.hidden = !this.resource.statusCode;
- var statusCodeImage = "";
-
- if (this.resource.statusCode) {
- var statusImageSource = "";
- if (this.resource.statusCode < 300)
- statusImageSource = "Images/successGreenDot.png";
- else if (this.resource.statusCode < 400)
- statusImageSource = "Images/warningOrangeDot.png";
- else
- statusImageSource = "Images/errorRedDot.png";
-
- var statusTextEscaped = this.resource.statusCode + " " + this.resource.statusText.escapeHTML();
- statusCodeImage = "<img class=\"resource-status-image\" src=\"" + statusImageSource + "\" title=\"" + statusTextEscaped + "\">";
-
- requestMethodElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Request Method") + ":</div>" +
- "<div class=\"header-value source-code\">" + this.resource.requestMethod + "</div>";
-
- statusCodeElement.titleHTML = "<div class=\"header-name\">" + WebInspector.UIString("Status Code") + ":</div>" +
- statusCodeImage + "<div class=\"header-value source-code\">" + statusTextEscaped + "</div>";
- }
- },
-
- _refreshHeaders: function(title, headers, additionalRow, headersTreeElement)
- {
- headersTreeElement.removeChildren();
-
- var length = headers.length;
- headersTreeElement.titleHTML = title.escapeHTML() + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", length) + "</span>";
- headersTreeElement.hidden = !length;
-
- var length = headers.length;
- for (var i = 0; i < length; ++i) {
- var title = "<div class=\"header-name\">" + headers[i].header.escapeHTML() + ":</div>";
- title += "<div class=\"header-value source-code\">" + headers[i].value.escapeHTML() + "</div>"
-
- var headerTreeElement = new TreeElement(null, null, false);
- headerTreeElement.titleHTML = title;
- headerTreeElement.selectable = false;
- headersTreeElement.appendChild(headerTreeElement);
- }
-
- if (additionalRow) {
- var title = "<div class=\"header-name\">" + additionalRow.header.escapeHTML() + ":</div>";
- title += "<div class=\"header-value source-code\">" + additionalRow.value.escapeHTML() + "</div>"
-
- var headerTreeElement = new TreeElement(null, null, false);
- headerTreeElement.titleHTML = title;
- headerTreeElement.selectable = false;
- headersTreeElement.appendChild(headerTreeElement);
- }
- },
-
- _refreshCookies: function()
- {
- if (!this._cookiesView) {
- if (!this.resource.requestCookies && !this.resource.responseCookies)
- return;
- this._cookiesView = new WebInspector.ResourceCookiesTab();
- this.tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView, this._selectTab.bind(this, "cookies"));
- }
- this._cookiesView.requestCookies = this.resource.requestCookies;
- this._cookiesView.responseCookies = this.resource.responseCookies;
}
}
WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype;
-
-WebInspector.ResourceCookiesTab = function()
-{
- WebInspector.CookiesTable.call(this);
- this.element.addStyleClass("resource-view-cookies");
- this._requestCookies = [];
- this._responseCookies = [];
- this._createDataGrid(true);
- this._requestCookiesNode = this._createFolder(WebInspector.UIString("Request Cookies"));
- this._responseCookiesNode = this._createFolder(WebInspector.UIString("Response Cookies"));
-}
-
-WebInspector.ResourceCookiesTab.prototype = {
- show: function(parentElement)
- {
- WebInspector.CookiesTable.prototype.show.call(this, parentElement);
- this.resize();
- },
-
- set requestCookies(cookies)
- {
- if (this._requestCookies === cookies)
- return;
- this._requestCookies = cookies;
- this._populateCookies(this._requestCookiesNode, this._requestCookies);
- },
-
- set responseCookies(cookies)
- {
- if (this._responseCookies === cookies)
- return;
- this._responseCookies = cookies;
- this._populateCookies(this._responseCookiesNode, this._responseCookies);
- },
-
- _populateDataGrid: function()
- {
- this._populateCookies(this._requestCookiesNode, this._requestCookies);
- this._populateCookies(this._responseCookiesNode, this._responseCookies);
- },
-
- _populateCookies: function(parentNode, cookies)
- {
- WebInspector.CookiesTable.prototype._populateCookies.call(this, parentNode, cookies);
- var totalSize = 0;
- if (cookies) {
- for (var i = 0; i < cookies.length; ++i)
- totalSize += cookies[i].size;
- }
- parentNode.expanded = true;
- parentNode.data[5] = totalSize;
- parentNode.refresh();
- },
-
- _createFolder: function(name)
- {
- var data = [ name, "", "", "", "", 0, "", "" ];
- var node = new WebInspector.DataGridNode(data);
- node.selectable = true;
- node.expanded = true;
- this._dataGrid.appendChild(node);
- node.element.addStyleClass("row-group");
- return node;
- }
-};
-
-WebInspector.ResourceCookiesTab.prototype.__proto__ = WebInspector.CookiesTable.prototype;
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index 5285dae..d6f7172 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -61,9 +61,10 @@ WebInspector.ResourcesPanel = function(database)
this.sidebarTree.appendChild(this.fileSystemListTreeElement);
this.fileSystemListTreeElement.expand();
}
-
+
this.storageViews = document.createElement("div");
this.storageViews.id = "storage-views";
+ this.storageViews.className = "diff-container";
this.element.appendChild(this.storageViews);
this.storageViewStatusBarItemsContainer = document.createElement("div");
@@ -99,11 +100,8 @@ WebInspector.ResourcesPanel.prototype = {
{
WebInspector.Panel.prototype.show.call(this);
- if (this.visibleView instanceof WebInspector.ResourceView) {
- // SourceViews are shared between the panels.
- this.visibleView.headersVisible = false;
- this.visibleView.show(this.storageViews);
- }
+ if (this.visibleView instanceof WebInspector.ResourceView)
+ this._showResourceView(this.visibleView.resource);
if (this._initializedDefaultSelection)
return;
@@ -147,7 +145,6 @@ WebInspector.ResourcesPanel.prototype = {
this._domStorage = [];
this._cookieViews = {};
-
this._fileSystemView = null;
this._applicationCacheView = null;
@@ -359,7 +356,6 @@ WebInspector.ResourcesPanel.prototype = {
if (line) {
var view = WebInspector.ResourceManager.resourceViewForResource(resource);
- view.selectContentTab();
if (view.revealLine)
view.revealLine(line);
if (view.highlightLine)
@@ -371,10 +367,46 @@ WebInspector.ResourcesPanel.prototype = {
_showResourceView: function(resource)
{
var view = WebInspector.ResourceManager.resourceViewForResource(resource);
- view.headersVisible = false;
+
+ // Consider rendering diff markup here.
+ if (resource.baseRevision && view instanceof WebInspector.SourceView) {
+ function callback(baseContent)
+ {
+ if (baseContent)
+ this._applyDiffMarkup(view, baseContent, resource.content);
+ }
+ resource.baseRevision.requestContent(callback.bind(this));
+ }
this._innerShowView(view);
},
+ _applyDiffMarkup: function(view, baseContent, newContent) {
+ var oldLines = baseContent.split("\n");
+ var newLines = newContent.split("\n");
+
+ var diff = Array.diff(oldLines, newLines);
+
+ var diffData = {};
+ diffData.added = [];
+ diffData.removed = [];
+ diffData.changed = [];
+
+ var offset = 0;
+ var right = diff.right;
+ for (var i = 0; i < right.length; ++i) {
+ if (typeof right[i] === "string") {
+ if (right.length > i + 1 && right[i + 1].row === i + 1 - offset)
+ diffData.changed.push(i);
+ else {
+ diffData.added.push(i);
+ offset++;
+ }
+ } else
+ offset = i - right[i].row;
+ }
+ view.sourceFrame.markDiff(diffData);
+ },
+
showDatabase: function(database, tableName)
{
if (!database)
@@ -813,7 +845,8 @@ WebInspector.BaseStorageTreeElement.prototype = {
set titleText(titleText)
{
this._titleText = titleText;
- this.titleElement.textContent = this._titleText;
+ if (this.titleElement)
+ this.titleElement.textContent = this._titleText;
},
isEventWithinDisclosureTriangle: function()
@@ -944,6 +977,7 @@ WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, "resource-sidebar-tree-item resources-category-" + resource.category.name);
this._resource = resource;
this._resource.addEventListener("errors-warnings-updated", this._errorsWarningsUpdated, this);
+ this._resource.addEventListener("content-changed", this._contentChanged, this);
this.tooltip = resource.url;
}
@@ -989,8 +1023,7 @@ WebInspector.FrameResourceTreeElement.prototype = {
_ondragstart: function(event)
{
- event.dataTransfer.setData("text/plain", this._resource.url);
- event.dataTransfer.setData("text/uri-list", this._resource.url + "\r\n");
+ event.dataTransfer.setData("text/plain", this._resource.content);
event.dataTransfer.effectAllowed = "copy";
return true;
},
@@ -1054,6 +1087,17 @@ WebInspector.FrameResourceTreeElement.prototype = {
if (this._resource.errors)
this._bubbleElement.addStyleClass("error");
+ },
+
+ _contentChanged: function(event)
+ {
+ this.insertChild(new WebInspector.ResourceRevisionTreeElement(this._storagePanel, event.data.revision), 0);
+ var oldView = WebInspector.ResourceManager.existingResourceViewForResource(this._resource);
+ if (oldView) {
+ var newView = WebInspector.ResourceManager.recreateResourceView(this._resource);
+ if (oldView === this._storagePanel.visibleView)
+ this._storagePanel.visibleView = newView;
+ }
}
}
@@ -1181,6 +1225,47 @@ WebInspector.ApplicationCacheTreeElement.prototype = {
}
WebInspector.ApplicationCacheTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;
+WebInspector.ResourceRevisionTreeElement = function(storagePanel, revision)
+{
+ var title = revision.timestamp ? revision.timestamp.toLocaleTimeString() : "(original)";
+ WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, "resource-sidebar-tree-item resources-category-" + revision.category.name);
+ if (revision.timestamp)
+ this.tooltip = revision.timestamp.toLocaleString();
+ this._resource = revision;
+}
+
+WebInspector.ResourceRevisionTreeElement.prototype = {
+ onattach: function()
+ {
+ WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
+ this.listItemElement.draggable = true;
+ this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
+ this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
+ },
+
+ onselect: function()
+ {
+ WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
+ this._storagePanel._showResourceView(this._resource);
+ },
+
+ _ondragstart: function(event)
+ {
+ event.dataTransfer.setData("text/plain", this._resource.content);
+ event.dataTransfer.effectAllowed = "copy";
+ return true;
+ },
+
+ _handleContextMenuEvent: function(event)
+ {
+ var contextMenu = new WebInspector.ContextMenu();
+ contextMenu.appendItem(WebInspector.UIString("Revert to this revision"), this._resource.revertToThis.bind(this._resource));
+ contextMenu.show(event);
+ }
+}
+
+WebInspector.ResourceRevisionTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;
+
WebInspector.FileSystemTreeElement = function(storagePanel, origin)
{
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, origin, "file-system-storage-tree-item");
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 32c7f21..61a2f28 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -213,11 +213,9 @@ WebInspector.ScriptsPanel.prototype = {
WebInspector.Panel.prototype.show.call(this);
this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth - 3) + "px";
- if (this.visibleView) {
- if (this.visibleView instanceof WebInspector.ResourceView)
- this.visibleView.headersVisible = false;
+ if (this.visibleView)
this.visibleView.show(this.viewsContainerElement);
- }
+
if (this._attachDebuggerWhenShown) {
InspectorBackend.enableDebugger(false);
delete this._attachDebuggerWhenShown;
@@ -308,7 +306,7 @@ WebInspector.ScriptsPanel.prototype = {
return Preferences.canEditScriptSource;
},
- editScriptSource: function(sourceID, newContent, line, linesCountToShift, commitEditingCallback, cancelEditingCallback)
+ editScriptSource: function(editData, commitEditingCallback, cancelEditingCallback)
{
if (!this.canEditScripts())
return;
@@ -325,18 +323,19 @@ WebInspector.ScriptsPanel.prototype = {
if (callFrames && callFrames.length)
this.debuggerPaused(callFrames);
} else {
- cancelEditingCallback();
+ if (cancelEditingCallback)
+ cancelEditingCallback();
WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
}
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
var newLine = breakpoint.line;
- if (success && breakpoint.line >= line)
- newLine += linesCountToShift;
- WebInspector.breakpointManager.setBreakpoint(sourceID, breakpoint.url, newLine, breakpoint.enabled, breakpoint.condition);
+ if (success && breakpoint.line >= editData.line)
+ newLine += editData.linesCountToShift;
+ WebInspector.breakpointManager.setBreakpoint(editData.sourceID, breakpoint.url, newLine, breakpoint.enabled, breakpoint.condition);
}
};
- InspectorBackend.editScriptSource(sourceID, newContent, mycallback.bind(this));
+ InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this));
},
selectedCallFrameId: function()
@@ -385,10 +384,11 @@ WebInspector.ScriptsPanel.prototype = {
this._updateDebuggerButtons();
+ WebInspector.currentPanel = this;
+
this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap);
this.sidebarPanes.callstack.selectedCallFrame = callFrames[0];
- WebInspector.currentPanel = this;
window.focus();
},
@@ -597,10 +597,9 @@ WebInspector.ScriptsPanel.prototype = {
return;
var view;
- if (scriptOrResource instanceof WebInspector.Resource) {
+ if (scriptOrResource instanceof WebInspector.Resource)
view = WebInspector.ResourceManager.resourceViewForResource(scriptOrResource);
- view.headersVisible = false;
- } else if (scriptOrResource instanceof WebInspector.Script)
+ else if (scriptOrResource instanceof WebInspector.Script)
view = this.scriptViewForScript(scriptOrResource);
if (!view)
diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js
index 1acc2e0..163b184 100644
--- a/WebCore/inspector/front-end/Settings.js
+++ b/WebCore/inspector/front-end/Settings.js
@@ -47,6 +47,8 @@ var Preferences = {
resourceExportEnabled: false,
fileSystemEnabled: false,
useDataURLForResourceImageIcons: true,
+ showTimingTab: false,
+ showCookiesTab: false,
debugMode: false
}
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 4b391ac..8e077cd 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -87,6 +87,16 @@ WebInspector.SourceFrame.prototype = {
this._updateExecutionLine(previousLine);
},
+ markDiff: function(diffData)
+ {
+ if (this._diffLines && this._textViewer)
+ this._removeDiffDecorations();
+
+ this._diffLines = diffData;
+ if (this._textViewer)
+ this._updateDiffDecorations();
+ },
+
revealLine: function(lineNumber)
{
if (this._textViewer)
@@ -161,6 +171,17 @@ WebInspector.SourceFrame.prototype = {
return this._textModel;
},
+ get scrollTop()
+ {
+ return this._textViewer ? this._textViewer.element.scrollTop : 0;
+ },
+
+ set scrollTop(scrollTop)
+ {
+ if (this._textViewer)
+ this._textViewer.element.scrollTop = scrollTop;
+ },
+
highlightLine: function(line)
{
if (this._textViewer)
@@ -199,6 +220,7 @@ WebInspector.SourceFrame.prototype = {
this._addExistingMessagesToSource();
this._addExistingBreakpointsToSource();
this._updateExecutionLine();
+ this._updateDiffDecorations();
this._textViewer.resize();
if (this._lineNumberToReveal) {
@@ -319,6 +341,33 @@ WebInspector.SourceFrame.prototype = {
this._textViewer.addDecoration(this._executionLine - 1, "webkit-execution-line");
},
+ _updateDiffDecorations: function()
+ {
+ if (!this._diffLines)
+ return;
+
+ function addDecorations(textViewer, lines, className)
+ {
+ for (var i = 0; i < lines.length; ++i)
+ textViewer.addDecoration(lines[i], className);
+ }
+ addDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
+ addDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
+ addDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
+ },
+
+ _removeDiffDecorations: function()
+ {
+ function removeDecorations(textViewer, lines, className)
+ {
+ for (var i = 0; i < lines.length; ++i)
+ textViewer.removeDecoration(lines[i], className);
+ }
+ removeDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
+ removeDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
+ removeDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
+ },
+
_addExistingMessagesToSource: function()
{
var length = this._messages.length;
diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js
index c7a35f7..9616321 100644
--- a/WebCore/inspector/front-end/SourceView.js
+++ b/WebCore/inspector/front-end/SourceView.js
@@ -33,7 +33,7 @@ WebInspector.SourceView = function(resource)
this.element.addStyleClass("source");
var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
- this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
resource.addEventListener("finished", this._resourceLoadingFinished, this);
this._frameNeedsSetup = true;
}
@@ -50,9 +50,8 @@ WebInspector.SourceView.prototype = {
show: function(parentElement)
{
WebInspector.ResourceView.prototype.show.call(this, parentElement);
+ this.setupSourceFrameIfNeeded();
this.sourceFrame.visible = true;
- if (this.localSourceFrame)
- this.localSourceFrame.visible = true;
this.resize();
},
@@ -62,8 +61,6 @@ WebInspector.SourceView.prototype = {
if (!this._frameNeedsSetup)
this.sourceFrame.clearLineHighlight();
WebInspector.View.prototype.hide.call(this);
- if (this.localSourceFrame)
- this.localSourceFrame.visible = false;
this._currentSearchResultIndex = -1;
},
@@ -71,32 +68,33 @@ WebInspector.SourceView.prototype = {
{
if (this.sourceFrame)
this.sourceFrame.resize();
- if (this.localSourceFrame)
- this.localSourceFrame.resize();
- WebInspector.ResourceView.prototype.resize.call(this);
},
+ get scrollTop()
+ {
+ return this.sourceFrame.scrollTop;
+ },
+
+ set scrollTop(scrollTop)
+ {
+ this.sourceFrame.scrollTop = scrollTop;
+ },
+
+
setupSourceFrameIfNeeded: function()
{
if (!this._frameNeedsSetup)
return;
- this.attach();
-
delete this._frameNeedsSetup;
this.resource.requestContent(this._contentLoaded.bind(this));
},
- hasContentTab: function()
+ hasContent: function()
{
return true;
},
- contentTabSelected: function()
- {
- this.setupSourceFrameIfNeeded();
- },
-
_contentLoaded: function(content)
{
var mimeType = this._canonicalMimeType(this.resource);
@@ -149,13 +147,28 @@ WebInspector.SourceView.prototype = {
lines.push(textModel.line(i));
}
- var linesCountToShift = newContent.split("\n").length - 1;
- WebInspector.panels.scripts.editScriptSource(this._sourceIDForLine(line), lines.join("\n"), line, linesCountToShift, this._editLineComplete.bind(this), cancelEditingCallback);
+ var editData = {};
+ editData.sourceID = this._sourceIDForLine(line);
+ editData.content = lines.join("\n");
+ editData.line = line;
+ editData.linesCountToShift = newContent.split("\n").length - 1;
+
+ WebInspector.panels.scripts.editScriptSource(editData, this._editLineComplete.bind(this, editData), cancelEditingCallback);
+ },
+
+ _editLineComplete: function(editData, newContent)
+ {
+ this.resource.setContent(newContent, this._revertEditLine.bind(this, editData));
},
- _editLineComplete: function(newBody)
+ _revertEditLine: function(editData, contentToRevertTo)
{
- this.sourceFrame.updateContent(newBody);
+ var newEditData = {};
+ newEditData.sourceID = editData.sourceID;
+ newEditData.content = editData.content;
+ newEditData.line = editData.line;
+ newEditData.linesCountToShift = -editData.linesCountToShift;
+ WebInspector.panels.scripts.editScriptSource(newEditData, this._editLineComplete.bind(this, newEditData));
},
_sourceIDForLine: function(line)
@@ -208,25 +221,6 @@ WebInspector.SourceView.prototype = {
findSearchMatches.call(this, query, finishedCallback);
},
- updateLocalContent: function(content, mimeType)
- {
- if (!this.localContentElement) {
- this.localContentElement = document.createElement("div");
- this.localContentElement.className = "resource-view-content";
- this.tabbedPane.appendTab("local", WebInspector.UIString("Local"), this.localContentElement, this.selectLocalContentTab.bind(this));
- this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), null, this._continueToLine.bind(this));
- }
- this.localSourceFrame.setContent(mimeType, content, "");
- },
-
- selectLocalContentTab: function()
- {
- this.tabbedPane.selectTabById("local");
- this.localSourceFrame.visible = true;
- if ("resize" in this)
- this.resize();
- },
-
jumpToFirstSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index 1ad0ece..68ad0dd 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -34,6 +34,12 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
this.settingsSelectElement = document.createElement("select");
var option = document.createElement("option");
+ option.value = "original";
+ option.action = this._changeColorFormat.bind(this);
+ option.label = WebInspector.UIString("As Authored");
+ this.settingsSelectElement.appendChild(option);
+
+ var option = document.createElement("option");
option.value = "hex";
option.action = this._changeColorFormat.bind(this);
option.label = WebInspector.UIString("Hex Colors");
@@ -61,12 +67,14 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
var format = WebInspector.settings.colorFormat;
- if (format === "hex")
+ if (format === "original")
this.settingsSelectElement[0].selected = true;
- else if (format === "rgb")
+ else if (format === "hex")
this.settingsSelectElement[1].selected = true;
- else if (format === "hsl")
+ else if (format === "rgb")
this.settingsSelectElement[2].selected = true;
+ else if (format === "hsl")
+ this.settingsSelectElement[3].selected = true;
this.titleElement.appendChild(this.settingsSelectElement);
this._computedStylePane = computedStylePane;
@@ -197,7 +205,7 @@ WebInspector.StylesSidebarPane.prototype = {
// Add rules in reverse order to match the cascade order.
for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) {
var rule = pseudoElementCSSRules.rules[j];
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
}
usedProperties = {};
disabledComputedProperties = {};
@@ -216,7 +224,7 @@ WebInspector.StylesSidebarPane.prototype = {
continue;
if (section.computedStyle)
section.styleRule.style = nodeComputedStyle;
- var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule };
+ var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule, editable: !!(section.styleRule.style && section.styleRule.style.id) };
styleRules.push(styleRule);
}
return styleRules;
@@ -252,7 +260,7 @@ WebInspector.StylesSidebarPane.prototype = {
styleRules.push({ isStyleSeparator: true, text: WebInspector.UIString("Matched CSS Rules") });
for (var i = styles.matchedCSSRules.length - 1; i >= 0; --i) {
var rule = styles.matchedCSSRules[i];
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, editable: !!(rule.style && rule.style.id) });
}
// Walk the node structure and identify styles with inherited properties.
@@ -288,7 +296,7 @@ WebInspector.StylesSidebarPane.prototype = {
insertInheritedNodeSeparator(parentNode);
separatorInserted = true;
}
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, isInherited: true });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, sourceURL: rule.sourceURL, rule: rule, isInherited: true, editable: !!(rule.style && rule.style.id) });
}
parentNode = parentNode.parentNode;
}
@@ -1248,7 +1256,9 @@ WebInspector.StylePropertyTreeElement.prototype = {
swatchElement.addEventListener("dblclick", function(event) { event.stopPropagation() }, false);
var format;
- if (Preferences.showColorNicknames && color.nickname)
+ if (WebInspector.settings.colorFormat === "original")
+ format = "original";
+ else if (Preferences.showColorNicknames && color.nickname)
format = "nickname";
else if (WebInspector.settings.colorFormat === "rgb")
format = (color.simple ? "rgb" : "rgba");
@@ -1262,55 +1272,59 @@ WebInspector.StylePropertyTreeElement.prototype = {
var colorValueElement = document.createElement("span");
colorValueElement.textContent = color.toString(format);
- function changeColorDisplay(event)
+ function nextFormat(curFormat)
{
- switch (format) {
+ // The format loop is as follows:
+ // * original
+ // * rgb(a)
+ // * hsl(a)
+ // * nickname (if the color has a nickname)
+ // * if the color is simple:
+ // - shorthex (if has short hex)
+ // - hex
+ switch (curFormat) {
+ case "original":
+ return color.simple ? "rgb" : "rgba";
+
case "rgb":
- format = "hsl";
- break;
+ case "rgba":
+ return color.simple ? "hsl" : "hsla";
+
+ case "hsl":
+ case "hsla":
+ if (color.nickname)
+ return "nickname";
+ if (color.simple)
+ return color.hasShortHex() ? "shorthex" : "hex";
+ else
+ return "original";
case "shorthex":
- format = "hex";
- break;
+ return "hex";
case "hex":
- format = "rgb";
- break;
+ return "original";
case "nickname":
- if (color.simple) {
- if (color.hasShortHex())
- format = "shorthex";
- else
- format = "hex";
- break;
- }
-
- format = "rgba";
- break;
-
- case "hsl":
- if (color.nickname)
- format = "nickname";
- else if (color.hasShortHex())
- format = "shorthex";
+ if (color.simple)
+ return color.hasShortHex() ? "shorthex" : "hex";
else
- format = "hex";
- break;
-
- case "rgba":
- format = "hsla";
- break;
+ return "original";
- case "hsla":
- if (color.nickname)
- format = "nickname";
- else
- format = "rgba";
- break;
+ default:
+ return null;
}
+ }
+
+ function changeColorDisplay(event)
+ {
+ do {
+ format = nextFormat(format);
+ var currentValue = color.toString(format || "");
+ } while (format && currentValue === color.value && format !== "original");
- colorValueElement.textContent = color.toString(format);
+ if (format)
+ colorValueElement.textContent = currentValue;
}
var container = document.createDocumentFragment();
@@ -1771,7 +1785,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
// FIXME: this does not handle trailing comments.
if (styleText.length && !/;\s*$/.test(styleText))
styleText += ";";
- this.property.setText(styleText, callback.bind(this));
+ this.property.setText(styleText, updateInterface, callback.bind(this));
}
}
diff --git a/WebCore/inspector/front-end/TabbedPane.js b/WebCore/inspector/front-end/TabbedPane.js
index 1ed9725..84ab702 100644
--- a/WebCore/inspector/front-end/TabbedPane.js
+++ b/WebCore/inspector/front-end/TabbedPane.js
@@ -32,62 +32,55 @@ WebInspector.TabbedPane = function(element)
{
this.element = element || document.createElement("div");
this.element.addStyleClass("tabbed-pane");
- this.tabsElement = this.element.createChild("div", "tabbed-pane-header");
- this.contentElement = this.element.createChild("div", "tabbed-pane-content");
-
- this._tabObjects = {};
+ this._tabsElement = this.element.createChild("div", "tabbed-pane-header");
+ this._contentElement = this.element.createChild("div", "tabbed-pane-content");
+ this._tabs = {};
}
WebInspector.TabbedPane.prototype = {
- appendTab: function(id, tabTitle, content, tabClickListener)
+ appendTab: function(id, tabTitle, view)
{
var tabElement = document.createElement("li");
tabElement.textContent = tabTitle;
- tabElement.addEventListener("click", tabClickListener, false);
- this.tabsElement.appendChild(tabElement);
- var tabObject = { tab: tabElement };
- if (content instanceof HTMLElement) {
- tabObject.element = content;
- this.contentElement.appendChild(content);
- }
- else {
- this.contentElement.appendChild(content.element);
- tabObject.view = content;
- }
- this._tabObjects[id] = tabObject;
- },
+ tabElement.addEventListener("click", this.selectTab.bind(this, id, true), false);
- hasTab: function(tabId)
- {
- return tabId in this._tabObjects;
+ this._tabsElement.appendChild(tabElement);
+ this._contentElement.appendChild(view.element);
+
+ this._tabs[id] = { tabElement: tabElement, view: view }
},
-
- selectTabById: function(tabId)
+
+ selectTab: function(id, userGesture)
{
- for (var id in this._tabObjects) {
- if (id === tabId)
- this._showTab(this._tabObjects[id]);
- else
- this._hideTab(this._tabObjects[id]);
+ if (!(id in this._tabs))
+ return false;
+
+ if (this._currentTab) {
+ this._hideTab(this._currentTab)
+ delete this._currentTab;
}
- return this.hasTab(tabId);
+
+ var tab = this._tabs[id];
+ this._showTab(tab);
+ this._currentTab = tab;
+ if (userGesture) {
+ var event = {tabId: id};
+ this.dispatchEventToListeners("tab-selected", event);
+ }
+ return true;
},
- _showTab: function(tabObject)
+ _showTab: function(tab)
{
- tabObject.tab.addStyleClass("selected");
- if (tabObject.element)
- tabObject.element.removeStyleClass("hidden");
- else
- tabObject.view.visible = true;
+ tab.tabElement.addStyleClass("selected");
+ tab.view.show(this._contentElement);
},
- _hideTab: function(tabObject)
+ _hideTab: function(tab)
{
- tabObject.tab.removeStyleClass("selected");
- if (tabObject.element)
- tabObject.element.addStyleClass("hidden");
- else
- tabObject.view.visible = false;
+ tab.tabElement.removeStyleClass("selected");
+ tab.view.visible = false;
}
}
+
+WebInspector.TabbedPane.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js
index 8900d8d..16eb4d7 100644
--- a/WebCore/inspector/front-end/TimelinePanel.js
+++ b/WebCore/inspector/front-end/TimelinePanel.js
@@ -961,7 +961,7 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = {
contentHelper._appendLinkRow(WebInspector.UIString("Script"), this.data.url, this.data.lineNumber);
break;
case recordTypes.Paint:
- contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("%d × %d", this.data.x, this.data.y));
+ contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data.x, this.data.y));
contentHelper._appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", this.data.width, this.data.height));
case recordTypes.RecalculateStyles: // We don't want to see default details.
break;
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 2b87bcc..2db0182 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -21,6 +21,7 @@
<file>ContextMenu.js</file>
<file>CookieItemsView.js</file>
<file>CookieParser.js</file>
+ <file>CookiesTable.js</file>
<file>CSSCompletions.js</file>
<file>CSSStyleModel.js</file>
<file>Database.js</file>
@@ -55,6 +56,7 @@
<file>InspectorFrontendHostStub.js</file>
<file>KeyboardShortcut.js</file>
<file>MetricsSidebarPane.js</file>
+ <file>NetworkItemView.js</file>
<file>NetworkPanel.js</file>
<file>Object.js</file>
<file>ObjectPropertiesSection.js</file>
@@ -70,7 +72,10 @@
<file>RemoteObject.js</file>
<file>Resource.js</file>
<file>ResourceCategory.js</file>
+ <file>ResourceCookiesView.js</file>
+ <file>ResourceHeadersView.js</file>
<file>ResourceManager.js</file>
+ <file>ResourceTimingView.js</file>
<file>ResourceView.js</file>
<file>ResourcesPanel.js</file>
<file>ScopeChainSidebarPane.js</file>
diff --git a/WebCore/inspector/front-end/WorkersSidebarPane.js b/WebCore/inspector/front-end/WorkersSidebarPane.js
index 177cd15..658d57c 100644
--- a/WebCore/inspector/front-end/WorkersSidebarPane.js
+++ b/WebCore/inspector/front-end/WorkersSidebarPane.js
@@ -81,7 +81,6 @@ WebInspector.WorkersSidebarPane.prototype = {
reset: function()
{
- InspectorBackend.removeAllScriptsToEvaluateOnLoad();
this.setInstrumentation(this._enableWorkersCheckbox.checked);
this._treeOutline.removeChildren();
this._workers = {};
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 29f2385..0ee5864 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -798,91 +798,19 @@ body.platform-linux .monospace, body.platform-linux .source-code {
display: block;
}
-.resource-view {
- display: none;
+.webkit-line-gutter-backdrop {
+ /* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */
+ width: 31px;
+ background-color: rgb(240, 240, 240);
+ border-right: 1px solid rgb(187, 187, 187);
position: absolute;
- background: white;
- top: 0;
+ z-index: -1;
left: 0;
- right: 0;
- bottom: 0;
-}
-
-.resource-view.visible {
- display: -webkit-box;
-}
-
-.resource-view .tabbed-pane-header {
- display: none;
- height: 20px;
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
- border-bottom: 1px solid rgb(163, 163, 163);
-}
-
-.resource-view.headers-visible .tabbed-pane-header {
- display: block;
-}
-
-.resource-view .scope-bar li {
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-.resource-view-headers {
- padding: 6px;
- -webkit-user-select: text;
- position: absolute;
top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- overflow: auto;
-}
-
-.resource-view-headers .outline-disclosure .parent {
- -webkit-user-select: none;
- font-weight: bold;
-}
-
-.resource-view-headers .outline-disclosure .children li {
- white-space: nowrap;
-}
-
-.resource-view-headers .outline-disclosure li.expanded .header-count {
- display: none;
-}
-
-.resource-view-headers .outline-disclosure .header-name {
- color: rgb(33%, 33%, 33%);
- display: inline-block;
- margin-right: 0.5em;
- font-weight: bold;
- vertical-align: top;
- white-space: pre-wrap;
-}
-
-.resource-view-headers .outline-disclosure .header-value {
- display: inline;
- margin-right: 100px;
- white-space: pre-wrap;
- word-break: break-all;
- margin-top: 1px;
-}
-
-.resource-view-headers .outline-disclosure .raw-form-data {
- white-space:pre-wrap;
-}
-
-.resource-view .resource-view-content {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- overflow: auto;
+ height: 100%
}
-.resource-view-cookies {
+.resource-view {
display: none;
position: absolute;
top: 0;
@@ -890,36 +818,13 @@ body.platform-linux .monospace, body.platform-linux .source-code {
left: 0;
bottom: 0;
overflow: auto;
- padding: 12px;
- height: 100%;
}
-.resource-view-cookies.visible {
+.resource-view.visible {
display: block;
}
-.resource-view-cookies.table .data-grid {
- height: 100%;
-}
-
-.resource-view-cookies .data-grid .row-group {
- font-weight: bold;
- font-size: 11px;
-}
-
-.webkit-line-gutter-backdrop {
- /* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */
- width: 31px;
- background-color: rgb(240, 240, 240);
- border-right: 1px solid rgb(187, 187, 187);
- position: absolute;
- z-index: -1;
- left: 0;
- top: 0;
- height: 100%
-}
-
-.resource-view.font .resource-view-content {
+.resource-view.font {
font-size: 60px;
white-space: pre-wrap;
word-wrap: break-word;
@@ -927,12 +832,12 @@ body.platform-linux .monospace, body.platform-linux .source-code {
padding: 15px;
}
-.resource-view.image .resource-view-content > .image {
+.resource-view.image > .image {
padding: 20px 20px 10px 20px;
text-align: center;
}
-.resource-view.image .resource-view-content > .info {
+.resource-view.image > .info {
padding-bottom: 10px;
font-size: 11px;
-webkit-user-select: text;
@@ -2002,16 +1907,16 @@ li.selected .base-storage-tree-element-subtitle {
display: block;
}
-.storage-view.table {
+.storage-view {
overflow: hidden;
}
-.storage-view.table .data-grid {
+.storage-view .data-grid {
border: none;
height: 100%;
}
-.storage-empty-view, .storage-view.table .storage-table-error {
+.storage-empty-view, .storage-view .storage-table-error {
position: absolute;
top: 0;
bottom: 25%;
@@ -2029,7 +1934,7 @@ li.selected .base-storage-tree-element-subtitle {
white-space: pre-wrap;
}
-.storage-view.table .storage-table-error {
+.storage-view .storage-table-error {
color: rgb(66%, 33%, 33%);
}
@@ -4257,11 +4162,6 @@ a.worker-item {
cursor: default;
}
-.styles-section .properties .inactive {
- opacity: 0.75;
- background-color: rgb(212, 212, 212);
-}
-
.styles-section .header {
white-space: nowrap;
-webkit-background-origin: padding;
@@ -4372,7 +4272,7 @@ a.worker-item {
z-index: 1;
}
-.styles-section .properties .overloaded, .styles-section .properties .disabled {
+.styles-section .properties .overloaded, .styles-section .properties .inactive, .styles-section .properties .disabled {
text-decoration: line-through;
}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index e0c72e9..67fd081 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<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="helpScreen.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>
@@ -67,6 +68,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="DOMStorage.js"></script>
<script type="text/javascript" src="DOMStorageItemsView.js"></script>
<script type="text/javascript" src="DataGrid.js"></script>
+ <script type="text/javascript" src="CookiesTable.js"></script>
<script type="text/javascript" src="CookieItemsView.js"></script>
<script type="text/javascript" src="ApplicationCacheItemsView.js"></script>
<script type="text/javascript" src="FileSystemView.js"></script>
@@ -112,6 +114,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="AuditRules.js"></script>
<script type="text/javascript" src="AuditCategories.js"></script>
<script type="text/javascript" src="AuditFormatters.js"></script>
+ <script type="text/javascript" src="ResourceHeadersView.js"></script>
+ <script type="text/javascript" src="ResourceCookiesView.js"></script>
+ <script type="text/javascript" src="ResourceTimingView.js"></script>
+ <script type="text/javascript" src="NetworkItemView.js"></script>
<script type="text/javascript" src="ResourceView.js"></script>
<script type="text/javascript" src="SourceFrame.js"></script>
<script type="text/javascript" src="DOMSyntaxHighlighter.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 33b370a..51145cf 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -658,6 +658,9 @@ WebInspector.dispatch = function(message) {
// This function is purposely put into the global scope for easy access.
WebInspector_syncDispatch = function(message)
{
+ if (window.dumpInspectorProtocolMessages)
+ console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
+
var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
var arguments = [];
@@ -1228,6 +1231,7 @@ WebInspector.domContentEventFired = function(time)
this.panels.audits.mainResourceDOMContentTime = time;
if (this.panels.network)
this.panels.network.mainResourceDOMContentTime = time;
+ this.extensionServer.notifyPageDOMContentLoaded((time - WebInspector.mainResource.startTime) * 1000);
this.mainResourceDOMContentTime = time;
}
@@ -1236,6 +1240,7 @@ WebInspector.loadEventFired = function(time)
this.panels.audits.mainResourceLoadTime = time;
if (this.panels.network)
this.panels.network.mainResourceLoadTime = time;
+ this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000);
this.mainResourceLoadTime = time;
}
@@ -1400,7 +1405,6 @@ WebInspector.didCommitLoad = function()
{
// Cleanup elements panel early on inspected page refresh.
WebInspector.setDocument(null);
- this.extensionServer.notifyInspectedPageLoaded();
}
WebInspector.updateConsoleMessageExpiredCount = function(count)
@@ -1541,6 +1545,16 @@ WebInspector.setRecordingProfile = function(isProfiling)
this.panels.profiles.updateProfileTypeButtons();
}
+WebInspector.addHeapSnapshotChunk = function(uid, chunk)
+{
+ this.panels.profiles.addHeapSnapshotChunk(uid, chunk);
+}
+
+WebInspector.finishHeapSnapshot = function(uid)
+{
+ this.panels.profiles.finishHeapSnapshot(uid);
+}
+
WebInspector.drawLoadingPieChart = function(canvas, percent) {
var g = canvas.getContext("2d");
var darkColor = "rgb(122, 168, 218)";
diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css
index 6b6aebe..70ebe56 100644
--- a/WebCore/inspector/front-end/networkPanel.css
+++ b/WebCore/inspector/front-end/networkPanel.css
@@ -26,7 +26,6 @@
line-height: 17px;
height: 37px;
border-right: 1px solid rgb(210, 210, 210);
- -webkit-user-select: none;
vertical-align: middle;
}
@@ -72,6 +71,11 @@
.network-sidebar .data-grid td.name-column {
font-weight: bold;
+ cursor: pointer;
+}
+
+.network.panel:not(.viewing-resource) .network-sidebar td.name-column:hover {
+ text-decoration: underline;
}
.network-sidebar .data-grid td.method-column,
@@ -97,11 +101,15 @@
.network-cell-subtitle {
font-weight: normal;
- color: grey;
+ color: gray;
+}
+
+.network-sidebar tr.selected .network-cell-subtitle {
+ color: white;
}
.network-header-subtitle {
- color: grey;
+ color: gray;
}
.network-sidebar .data-grid.small .network-cell-subtitle,
@@ -362,7 +370,7 @@
.network-timing-row {
position: relative;
- height: 12px;
+ height: 16px;
}
.network-timing-bar {
@@ -370,10 +378,14 @@
background-color: red;
border-left: 1px solid red;
opacity: 0.4;
+ top: 0;
+ bottom: 0;
}
.network-timing-bar-title {
position: absolute;
+ color: black;
+ top: 1px;
}
.network-dim-cell {
@@ -629,13 +641,14 @@
color: black;
}
-#network-views .resource-view .tabbed-pane-header {
+#network-views .network-item-view .tabbed-pane-header {
height: 31px;
padding-top: 8px;
padding-left: 25px;
+ white-space: nowrap;
}
-#network-views.small .resource-view .tabbed-pane-header {
+#network-views.small .network-item-view .tabbed-pane-header {
height: 23px;
padding-top: 0;
}
@@ -643,3 +656,163 @@
.network.panel.viewing-resource .data-grid .data-container {
padding-right: 0;
}
+
+.network-item-view {
+ display: none;
+ position: absolute;
+ background: white;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.network-item-view.visible {
+ display: -webkit-box;
+}
+
+.network-item-view .tabbed-pane-header {
+ height: 20px;
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
+ border-bottom: 1px solid rgb(163, 163, 163);
+}
+
+.network-item-view .scope-bar li {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.resource-headers-view {
+ display: none;
+ padding: 6px;
+ -webkit-user-select: text;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: auto;
+}
+
+.resource-headers-view.visible {
+ display: block;
+}
+
+.resource-headers-view .outline-disclosure .parent {
+ -webkit-user-select: none;
+ font-weight: bold;
+}
+
+.resource-headers-view .outline-disclosure .children li {
+ white-space: nowrap;
+}
+
+.resource-headers-view .outline-disclosure li.expanded .header-count {
+ display: none;
+}
+
+.resource-headers-view .outline-disclosure .header-name {
+ color: rgb(33%, 33%, 33%);
+ display: inline-block;
+ margin-right: 0.5em;
+ font-weight: bold;
+ vertical-align: top;
+ white-space: pre-wrap;
+}
+
+.resource-headers-view .outline-disclosure .header-value {
+ display: inline;
+ margin-right: 100px;
+ white-space: pre-wrap;
+ word-break: break-all;
+ margin-top: 1px;
+}
+
+.resource-headers-view .outline-disclosure .raw-form-data {
+ white-space: pre-wrap;
+}
+
+.resource-cookies-view {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ overflow: auto;
+ padding: 12px;
+ height: 100%;
+}
+
+.resource-cookies-view.visible {
+ display: block;
+}
+
+.resource-cookies-view .data-grid {
+ height: 100%;
+}
+
+.resource-cookies-view .data-grid .row-group {
+ font-weight: bold;
+ font-size: 11px;
+}
+
+.resource-timing-view {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ padding: 6px;
+ font-weight: bold;
+ font-size: 11px;
+ color: rgb(30%, 30%, 30%);
+}
+
+.resource-timing-view table {
+ border-spacing: 21px 0;
+}
+
+.resource-timing-view .network-timing-bar {
+ opacity: 1;
+}
+
+.resource-timing-view .network-timing-bar.proxy {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(239, 228, 176)), to(rgb(139, 128, 76)));
+ border-left: 1px solid rgb(139, 128, 76);
+}
+
+.resource-timing-view .network-timing-bar.dns {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(153, 208, 216)), to(rgb(81, 174, 189)));
+ border-left: 1px solid rgb(81, 174, 189);
+}
+
+.resource-timing-view .network-timing-bar.connecting {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(203, 232, 145)), to(rgb(160, 214, 56)));
+ border-left: 1px solid rgb(160, 214, 56);
+}
+
+.resource-timing-view .network-timing-bar.ssl {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(21, 232, 145)), to(rgb(216, 149, 132)));
+ border-left: 1px solid rgb(216, 149, 132);
+}
+
+.resource-timing-view .network-timing-bar.sending {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(232, 192, 182)), to(rgb(216, 147, 130)));
+ border-left: 1px solid rgb(216, 147, 130);
+}
+
+.resource-timing-view .network-timing-bar.waiting {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(188, 179, 208)), to(rgb(141, 125, 175)));
+ border-left: 1px solid rgb(141, 125, 175);
+}
+
+.resource-timing-view .network-timing-bar.receiving {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(214, 214, 214)), to(rgb(182, 182, 182)));
+ border-left: 1px solid rgb(182, 182, 182);
+}
+
+.resource-timing-view.visible {
+ display: block;
+}
diff --git a/WebCore/inspector/front-end/textViewer.css b/WebCore/inspector/front-end/textViewer.css
index 8a96b1f..bee9fe5 100644
--- a/WebCore/inspector/front-end/textViewer.css
+++ b/WebCore/inspector/front-end/textViewer.css
@@ -64,8 +64,8 @@
vertical-align: top;
word-break: normal;
-webkit-user-select: none;
- padding-right: 4px;
- padding-left: 6px;
+ padding-right: 4px;
+ padding-left: 6px;
}
.webkit-line-number-outer {
@@ -141,6 +141,19 @@
outline: 1px solid rgb(64, 115, 244);
}
+.diff-container .webkit-added-line .webkit-line-content {
+ background-color: rgb(220, 255, 220);
+}
+
+.diff-container .webkit-removed-line .webkit-line-content {
+ background-color: rgb(255, 220, 220);
+ text-decoration: line-through;
+}
+
+.diff-container .webkit-changed-line .webkit-line-content {
+ background-color: rgb(220, 220, 255);
+}
+
.webkit-search-result {
-webkit-border-radius: 4px;
padding: 2px 2px 2px 3px;
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 3aff6bb..f978c6f 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -24,6 +24,9 @@
* 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.
+ *
+ * Contains diff method based on Javascript Diff Algorithm By John Resig
+ * http://ejohn.org/files/jsdiff.js (released under the MIT license).
*/
Function.prototype.bind = function(thisObject)
@@ -731,6 +734,51 @@ Array.prototype.keySet = function()
return keys;
}
+Array.diff = function(left, right)
+{
+ var o = left;
+ var n = right;
+
+ var ns = {};
+ var os = {};
+
+ for (var i = 0; i < n.length; i++) {
+ if (ns[n[i]] == null)
+ ns[n[i]] = { rows: [], o: null };
+ ns[n[i]].rows.push(i);
+ }
+
+ for (var i = 0; i < o.length; i++) {
+ if (os[o[i]] == null)
+ os[o[i]] = { rows: [], n: null };
+ os[o[i]].rows.push(i);
+ }
+
+ for (var i in ns) {
+ if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
+ n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] };
+ o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] };
+ }
+ }
+
+ for (var i = 0; i < n.length - 1; i++) {
+ if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] == o[n[i].row + 1]) {
+ n[i + 1] = { text: n[i + 1], row: n[i].row + 1 };
+ o[n[i].row + 1] = { text: o[n[i].row + 1], row: i + 1 };
+ }
+ }
+
+ for (var i = n.length - 1; i > 0; i--) {
+ if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
+ n[i - 1] == o[n[i].row - 1]) {
+ n[i - 1] = { text: n[i - 1], row: n[i].row - 1 };
+ o[n[i].row - 1] = { text: o[n[i].row - 1], row: i - 1 };
+ }
+ }
+
+ return { left: o, right: n };
+}
+
Array.convert = function(list)
{
// Cast array-like object to an array.