summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/inspector
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/WebCore/inspector
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/WebCore/inspector')
-rw-r--r--Source/WebCore/inspector/CodeGeneratorInspector.pm541
-rw-r--r--Source/WebCore/inspector/ConsoleMessage.cpp56
-rw-r--r--Source/WebCore/inspector/DOMNodeHighlighter.cpp3
-rw-r--r--Source/WebCore/inspector/EventsCollector.cpp59
-rw-r--r--Source/WebCore/inspector/EventsCollector.h54
-rw-r--r--Source/WebCore/inspector/InjectedScript.cpp17
-rw-r--r--Source/WebCore/inspector/InjectedScript.h8
-rw-r--r--Source/WebCore/inspector/InjectedScriptManager.cpp17
-rw-r--r--Source/WebCore/inspector/InjectedScriptManager.h11
-rw-r--r--Source/WebCore/inspector/InjectedScriptSource.js76
-rw-r--r--Source/WebCore/inspector/Inspector.json708
-rw-r--r--Source/WebCore/inspector/InspectorAgent.cpp48
-rw-r--r--Source/WebCore/inspector/InspectorAgent.h5
-rw-r--r--Source/WebCore/inspector/InspectorCSSAgent.cpp53
-rw-r--r--Source/WebCore/inspector/InspectorCSSAgent.h6
-rw-r--r--Source/WebCore/inspector/InspectorClient.h6
-rw-r--r--Source/WebCore/inspector/InspectorConsoleAgent.cpp2
-rw-r--r--Source/WebCore/inspector/InspectorController.cpp8
-rw-r--r--Source/WebCore/inspector/InspectorController.h1
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.cpp70
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.h12
-rw-r--r--Source/WebCore/inspector/InspectorDatabaseAgent.cpp68
-rw-r--r--Source/WebCore/inspector/InspectorDatabaseAgent.h13
-rw-r--r--Source/WebCore/inspector/InspectorDatabaseResource.h1
-rw-r--r--Source/WebCore/inspector/InspectorDebuggerAgent.cpp140
-rw-r--r--Source/WebCore/inspector/InspectorDebuggerAgent.h17
-rw-r--r--Source/WebCore/inspector/InspectorFrontendChannel.h41
-rw-r--r--Source/WebCore/inspector/InspectorFrontendClientLocal.cpp2
-rw-r--r--Source/WebCore/inspector/InspectorFrontendProxy.cpp (renamed from Source/WebCore/inspector/front-end/Breakpoint.js)56
-rw-r--r--Source/WebCore/inspector/InspectorFrontendProxy.h57
-rw-r--r--Source/WebCore/inspector/InspectorInstrumentation.cpp35
-rw-r--r--Source/WebCore/inspector/InspectorInstrumentation.h61
-rw-r--r--Source/WebCore/inspector/InspectorPageAgent.cpp8
-rw-r--r--Source/WebCore/inspector/InspectorPageAgent.h8
-rw-r--r--Source/WebCore/inspector/InspectorResourceAgent.cpp123
-rw-r--r--Source/WebCore/inspector/InspectorResourceAgent.h16
-rw-r--r--Source/WebCore/inspector/InspectorRuntimeAgent.cpp23
-rw-r--r--Source/WebCore/inspector/InspectorRuntimeAgent.h16
-rw-r--r--Source/WebCore/inspector/InspectorState.cpp2
-rw-r--r--Source/WebCore/inspector/InspectorStyleSheet.cpp100
-rw-r--r--Source/WebCore/inspector/InspectorStyleSheet.h10
-rw-r--r--Source/WebCore/inspector/ScriptBreakpoint.h4
-rw-r--r--Source/WebCore/inspector/ScriptCallFrame.cpp4
-rw-r--r--Source/WebCore/inspector/ScriptDebugListener.h7
-rwxr-xr-xSource/WebCore/inspector/WorkerDebuggerAgent.cpp2
-rw-r--r--Source/WebCore/inspector/WorkerInspectorController.cpp163
-rw-r--r--Source/WebCore/inspector/WorkerInspectorController.h81
-rwxr-xr-xSource/WebCore/inspector/combine-javascript-resources.pl81
-rw-r--r--Source/WebCore/inspector/front-end/AuditRules.js141
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointManager.js437
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js130
-rw-r--r--Source/WebCore/inspector/front-end/CSSStyleModel.js185
-rw-r--r--Source/WebCore/inspector/front-end/CallStackSidebarPane.js39
-rw-r--r--Source/WebCore/inspector/front-end/ConsoleView.js64
-rw-r--r--Source/WebCore/inspector/front-end/DOMAgent.js118
-rw-r--r--Source/WebCore/inspector/front-end/DOMBreakpointsSidebarPane.js308
-rw-r--r--Source/WebCore/inspector/front-end/DataGrid.js1
-rw-r--r--Source/WebCore/inspector/front-end/DebuggerModel.js77
-rw-r--r--Source/WebCore/inspector/front-end/DebuggerPresentationModel.js483
-rw-r--r--Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js296
-rw-r--r--Source/WebCore/inspector/front-end/DetailedHeapshotView.js212
-rw-r--r--Source/WebCore/inspector/front-end/ElementsPanel.js26
-rw-r--r--Source/WebCore/inspector/front-end/ElementsTreeOutline.js19
-rw-r--r--Source/WebCore/inspector/front-end/EventListenersSidebarPane.js2
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionAPI.js58
-rwxr-xr-xSource/WebCore/inspector/front-end/ExtensionAPISchema.json90
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionPanel.js18
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionServer.js62
-rw-r--r--Source/WebCore/inspector/front-end/GoToLineDialog.js6
-rw-r--r--Source/WebCore/inspector/front-end/HAREntry.js17
-rw-r--r--Source/WebCore/inspector/front-end/HeapSnapshot.js84
-rw-r--r--Source/WebCore/inspector/front-end/HeapSnapshotProxy.js287
-rw-r--r--Source/WebCore/inspector/front-end/MetricsSidebarPane.js82
-rw-r--r--Source/WebCore/inspector/front-end/NetworkManager.js32
-rw-r--r--Source/WebCore/inspector/front-end/NetworkPanel.js22
-rw-r--r--Source/WebCore/inspector/front-end/Object.js7
-rw-r--r--Source/WebCore/inspector/front-end/ObjectPropertiesSection.js27
-rw-r--r--Source/WebCore/inspector/front-end/Panel.js10
-rw-r--r--Source/WebCore/inspector/front-end/PleaseWaitMessage.js2
-rw-r--r--Source/WebCore/inspector/front-end/ProfilesPanel.js103
-rw-r--r--Source/WebCore/inspector/front-end/PropertiesSidebarPane.js2
-rw-r--r--Source/WebCore/inspector/front-end/RemoteObject.js19
-rw-r--r--Source/WebCore/inspector/front-end/Resource.js229
-rw-r--r--Source/WebCore/inspector/front-end/ResourceHeadersView.js105
-rw-r--r--Source/WebCore/inspector/front-end/ResourceTreeModel.js18
-rw-r--r--Source/WebCore/inspector/front-end/ResourceView.js133
-rw-r--r--Source/WebCore/inspector/front-end/ResourcesPanel.js225
-rw-r--r--Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js51
-rw-r--r--Source/WebCore/inspector/front-end/Script.js89
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatter.js13
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatterWorker.js34
-rw-r--r--Source/WebCore/inspector/front-end/ScriptsPanel.js118
-rwxr-xr-xSource/WebCore/inspector/front-end/SearchController.js6
-rw-r--r--Source/WebCore/inspector/front-end/Settings.js63
-rw-r--r--Source/WebCore/inspector/front-end/SourceFile.js70
-rw-r--r--Source/WebCore/inspector/front-end/SourceFrame.js389
-rw-r--r--Source/WebCore/inspector/front-end/SourceFrameContent.js111
-rw-r--r--Source/WebCore/inspector/front-end/StylesSidebarPane.js127
-rw-r--r--Source/WebCore/inspector/front-end/TestController.js2
-rw-r--r--Source/WebCore/inspector/front-end/TextEditorModel.js31
-rw-r--r--Source/WebCore/inspector/front-end/TextViewer.js425
-rw-r--r--Source/WebCore/inspector/front-end/WebKit.qrc5
-rw-r--r--Source/WebCore/inspector/front-end/inspector.css28
-rw-r--r--Source/WebCore/inspector/front-end/inspector.html9
-rw-r--r--Source/WebCore/inspector/front-end/inspector.js97
-rw-r--r--Source/WebCore/inspector/front-end/networkPanel.css21
-rw-r--r--Source/WebCore/inspector/front-end/utilities.js33
-rwxr-xr-xSource/WebCore/inspector/generate-inspector-idl45
-rwxr-xr-xSource/WebCore/inspector/inline-javascript-imports.py81
109 files changed, 5526 insertions, 3398 deletions
diff --git a/Source/WebCore/inspector/CodeGeneratorInspector.pm b/Source/WebCore/inspector/CodeGeneratorInspector.pm
index ea65f2e..de8e1db 100644
--- a/Source/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/Source/WebCore/inspector/CodeGeneratorInspector.pm
@@ -90,13 +90,13 @@ $typeTransform{"Frontend"} = {
"forward" => "InspectorFrontend",
"header" => "InspectorFrontend.h",
};
-$typeTransform{"InspectorClient"} = {
- "forward" => "InspectorClient",
- "header" => "InspectorClient.h",
-};
$typeTransform{"PassRefPtr"} = {
"forwardHeader" => "wtf/PassRefPtr.h",
};
+$typeTransform{"InspectorFrontendChannel"} = {
+ "forward" => "InspectorFrontendChannel",
+ "header" => "InspectorFrontendChannel.h",
+};
$typeTransform{"Object"} = {
"param" => "PassRefPtr<InspectorObject>",
"variable" => "RefPtr<InspectorObject>",
@@ -105,7 +105,6 @@ $typeTransform{"Object"} = {
"header" => "InspectorValues.h",
"JSONType" => "Object",
"JSType" => "object",
- "DocType" => "%s"
};
$typeTransform{"Array"} = {
"param" => "PassRefPtr<InspectorArray>",
@@ -115,7 +114,6 @@ $typeTransform{"Array"} = {
"header" => "InspectorValues.h",
"JSONType" => "Array",
"JSType" => "object",
- "DocType" => "array of %s"
};
$typeTransform{"Value"} = {
"param" => "PassRefPtr<InspectorValue>",
@@ -125,7 +123,6 @@ $typeTransform{"Value"} = {
"header" => "InspectorValues.h",
"JSONType" => "Value",
"JSType" => "",
- "DocType" => "value"
};
$typeTransform{"String"} = {
"param" => "const String&",
@@ -195,6 +192,9 @@ $typeTransform{"void"} = {
"forward" => "",
"header" => ""
};
+$typeTransform{"Vector"} = {
+ "header" => "wtf/Vector.h"
+};
# Default License Templates
@@ -223,6 +223,7 @@ my @backendConstantDeclarations;
my @backendConstantDefinitions;
my @backendFooter;
my @backendJSStubs;
+my @backendJSEvents;
my %backendDomains;
my $frontendClassName;
@@ -236,9 +237,6 @@ my @frontendConstantDeclarations;
my @frontendConstantDefinitions;
my @frontendFooter;
-my @documentationToc;
-my @documentationLines;
-
# Default constructor
sub new
{
@@ -267,17 +265,17 @@ sub GenerateModule
$namespace =~ s/core/WebCore/;
$frontendClassName = "InspectorFrontend";
- $frontendConstructor = " ${frontendClassName}(InspectorClient*);";
+ $frontendConstructor = " ${frontendClassName}(InspectorFrontendChannel*);";
push(@frontendFooter, "private:");
- push(@frontendFooter, " InspectorClient* m_inspectorClient;");
+ push(@frontendFooter, " InspectorFrontendChannel* m_inspectorFrontendChannel;");
$frontendTypes{"String"} = 1;
- $frontendTypes{"InspectorClient"} = 1;
+ $frontendTypes{"InspectorFrontendChannel"} = 1;
$frontendTypes{"PassRefPtr"} = 1;
$backendClassName = "InspectorBackendDispatcher";
$backendJSStubName = "InspectorBackendStub";
$backendTypes{"Inspector"} = 1;
- $backendTypes{"InspectorClient"} = 1;
+ $backendTypes{"InspectorFrontendChannel"} = 1;
$backendTypes{"PassRefPtr"} = 1;
$backendTypes{"Object"} = 1;
}
@@ -306,10 +304,12 @@ sub generateAgentDeclaration
my $agentName = $interface->name;
push(@frontendMethods, " class ${agentName} {");
push(@frontendMethods, " public:");
- push(@frontendMethods, " ${agentName}(InspectorClient* inspectorClient) : m_inspectorClient(inspectorClient) { }");
+ push(@frontendMethods, " ${agentName}(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }");
push(@frontendMethods, @{$agent->{methodDeclarations}});
+ push(@frontendMethods, " void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }");
+ push(@frontendMethods, " InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }");
push(@frontendMethods, " private:");
- push(@frontendMethods, " InspectorClient* m_inspectorClient;");
+ push(@frontendMethods, " InspectorFrontendChannel* m_inspectorFrontendChannel;");
push(@frontendMethods, " };");
push(@frontendMethods, "");
@@ -325,10 +325,10 @@ sub generateAgentDeclaration
sub generateFrontendConstructorImpl
{
my @frontendConstructorImpl;
- push(@frontendConstructorImpl, "${frontendClassName}::${frontendClassName}(InspectorClient* inspectorClient)");
- push(@frontendConstructorImpl, " : m_inspectorClient(inspectorClient)");
+ push(@frontendConstructorImpl, "${frontendClassName}::${frontendClassName}(InspectorFrontendChannel* inspectorFrontendChannel)");
+ push(@frontendConstructorImpl, " : m_inspectorFrontendChannel(inspectorFrontendChannel)");
foreach my $agentField (@frontendAgentFields) {
- push(@frontendConstructorImpl, " , ${agentField}(inspectorClient)");
+ push(@frontendConstructorImpl, " , ${agentField}(inspectorFrontendChannel)");
}
push(@frontendConstructorImpl, "{");
push(@frontendConstructorImpl, "}");
@@ -348,20 +348,8 @@ sub generateFunctions
}
}
- push(@documentationToc, "<li><a href='#" . $interface->name . "'>" . $interface->name . "</a></li>");
- push(@documentationLines, "<h2 id='" . $interface->name . "'><a name=" . $interface->name . "></a>" . $interface->name . "</h2>");
-
- push(@documentationLines, "<h3>Events</h3>");
- foreach my $function (grep($_->signature->extendedAttributes->{"event"}, @{$interface->functions}) ) {
- generateDocumentationEvent($interface, $function);
- }
-
- push(@documentationLines, "<h3>Commands</h3>");
- foreach my $function (grep(!$_->signature->extendedAttributes->{"event"}, @{$interface->functions})) {
- generateDocumentationCommand($interface, $function);
- }
-
collectBackendJSStubFunctions($interface);
+ collectBackendJSStubEvents($interface);
}
sub generateFrontendFunction
@@ -386,55 +374,20 @@ sub generateFrontendFunction
push(@function, "void ${frontendClassName}::${domain}::${functionName}(${arguments})");
push(@function, "{");
push(@function, " RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();");
- push(@function, " ${functionName}Message->setString(\"type\", \"event\");");
- push(@function, " ${functionName}Message->setString(\"domain\", \"$domain\");");
- push(@function, " ${functionName}Message->setString(\"event\", \"$functionName\");");
- push(@function, " RefPtr<InspectorObject> bodyObject = InspectorObject::create();");
- my @pushArguments = map(" bodyObject->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered);
- push(@function, @pushArguments);
- push(@function, " ${functionName}Message->setObject(\"body\", bodyObject);");
- push(@function, " m_inspectorClient->sendMessageToFrontend(${functionName}Message->toJSONString());");
- push(@function, "}");
- push(@function, "");
- push(@frontendMethodsImpl, @function);
-}
-
-sub generateDocumentationEvent
-{
- my $interface = shift;
- my $function = shift;
-
- my $functionName = $function->signature->name;
- my $domain = $interface->name;
-
- my @argsFiltered = grep($_->direction eq "out", @{$function->parameters});
-
- my @lines;
- push(@lines, "<h4>" . $interface->name . "." . ${functionName} . "</h4>");
- my $doc = $function->signature->extendedAttributes->{"doc"};
- if ($doc) {
- push(@lines, $doc);
- }
-
- push(@lines, "<pre style='background: lightGrey; padding: 10px'>");
- push(@lines, "{");
- push(@lines, " type: \"event\",");
- push(@lines, " domain: \"$domain\",");
+ push(@function, " ${functionName}Message->setString(\"method\", \"$domain.$functionName\");");
if (scalar(@argsFiltered)) {
- push(@lines, " event: \"${functionName}\",");
- push(@lines, " data: {");
- my @parameters;
+ push(@function, " RefPtr<InspectorObject> paramsObject = InspectorObject::create();");
+
foreach my $parameter (@argsFiltered) {
- push(@parameters, " " . parameterDocLine($parameter));
+ my $optional = $parameter->extendedAttributes->{"optional"} ? "if (" . $parameter->name . ")\n " : "";
+ push(@function, " " . $optional . "paramsObject->set" . typeTraits($parameter->type, "JSONType") . "(\"" . $parameter->name . "\", " . $parameter->name . ");");
}
- push(@lines, join(",\n", @parameters));
- push(@lines, " }");
- } else {
- push(@lines, " event: \"${functionName}\"");
+ push(@function, " ${functionName}Message->setObject(\"params\", paramsObject);");
}
- push(@lines, "}");
- push(@lines, "</pre>");
- push(@documentationLines, @lines);
+ push(@function, " m_inspectorFrontendChannel->sendMessageToFrontend(${functionName}Message->toJSONString());");
+ push(@function, "}");
+ push(@function, "");
+ push(@frontendMethodsImpl, @function);
}
sub camelCase
@@ -452,12 +405,13 @@ sub generateBackendFunction
my $functionName = $function->signature->name;
my $fullQualifiedFunctionName = $interface->name . "_" . $function->signature->name;
+ my $fullQualifiedFunctionNameDot = $interface->name . "." . $function->signature->name;
push(@backendConstantDeclarations, " static const char* ${fullQualifiedFunctionName}Cmd;");
- push(@backendConstantDefinitions, "const char* ${backendClassName}::${fullQualifiedFunctionName}Cmd = \"${fullQualifiedFunctionName}\";");
+ push(@backendConstantDefinitions, "const char* ${backendClassName}::${fullQualifiedFunctionName}Cmd = \"${fullQualifiedFunctionNameDot}\";");
map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types
- my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters});
+ my @inArgs = grep($_->direction eq "in", @{$function->parameters});
my @outArgs = grep($_->direction eq "out", @{$function->parameters});
my $signature = " void ${fullQualifiedFunctionName}(long callId, InspectorObject* requestMessageObject);";
@@ -477,133 +431,106 @@ sub generateBackendFunction
$backendTypes{$domain} = 1;
$backendDomains{$domain} = 1;
push(@function, " if (!$domainAccessor)");
- push(@function, " protocolErrors->pushString(\"Protocol Error: $domain handler is not available.\");");
+ push(@function, " protocolErrors->pushString(\"$domain handler is not available.\");");
push(@function, "");
# declare local variables for out arguments.
- push(@function, map(" " . typeTraits($_->type, "variable") . " " . $_->name . " = " . typeTraits($_->type, "defaultValue") . ";", @outArgs));
- push(@function, "");
+ if (scalar(@outArgs)) {
+ push(@function, map(" " . typeTraits($_->type, "variable") . " out_" . $_->name . " = " . typeTraits($_->type, "defaultValue") . ";", @outArgs));
+ push(@function, "");
+ }
push(@function, " ErrorString error;");
push(@function, "");
my $indent = "";
if (scalar(@inArgs)) {
- push(@function, " if (RefPtr<InspectorObject> argumentsContainer = requestMessageObject->getObject(\"arguments\")) {");
+ push(@function, " if (RefPtr<InspectorObject> paramsContainer = requestMessageObject->getObject(\"params\")) {");
foreach my $parameter (@inArgs) {
my $name = $parameter->name;
my $type = $parameter->type;
my $typeString = camelCase($parameter->type);
- push(@function, " " . typeTraits($type, "variable") . " $name = get$typeString(argumentsContainer.get(), \"$name\", protocolErrors.get());");
+ my $optional = $parameter->extendedAttributes->{"optional"} ? "true" : "false";
+ push(@function, " " . typeTraits($type, "variable") . " in_$name = get$typeString(paramsContainer.get(), \"$name\", $optional, protocolErrors.get());");
}
push(@function, "");
$indent = " ";
}
- my $args = join(", ", ("&error", map($_->name, @inArgs), map("&" . $_->name, @outArgs)));
+
+ my $args = join(", ",
+ ("&error",
+ map(($_->extendedAttributes->{"optional"} ? "&" : "") . "in_" . $_->name, @inArgs),
+ map("&out_" . $_->name, @outArgs)));
+
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, " } else");
+ push(@function, " protocolErrors->pushString(\"'params' 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()) {");
- push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
- push(@function, " responseMessage->setNumber(\"requestId\", callId);");
push(@function, "");
- push(@function, " if (protocolErrors->length())");
- push(@function, " responseMessage->setArray(\"protocolErrors\", protocolErrors);");
- if (scalar(@outArgs)) {
- push(@function, " else {");
- push(@function, " if (error.length())");
- push(@function, " responseMessage->setString(\"error\", error);");
- push(@function, " RefPtr<InspectorObject> responseBody = InspectorObject::create();");
- push(@function, map(" responseBody->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", " . $_->name . ");", @outArgs));
- push(@function, " responseMessage->setObject(\"body\", responseBody);");
- push(@function, " }");
- }
- push(@function, " m_inspectorClient->sendMessageToFrontend(responseMessage->toJSONString());");
+ push(@function, " if (protocolErrors->length()) {");
+ push(@function, " reportProtocolError(&callId, InvalidParams, protocolErrors);");
+ push(@function, " return;");
push(@function, " }");
-
-
+ push(@function, "");
+ push(@function, " if (error.length()) {");
+ push(@function, " reportProtocolError(&callId, ServerError, error);");
+ push(@function, " return;");
+ push(@function, " }");
+ push(@function, "");
+ push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
+ push(@function, " RefPtr<InspectorObject> result = InspectorObject::create();");
+ push(@function, map(" result->set" . typeTraits($_->type, "JSONType") . "(\"" . $_->name . "\", out_" . $_->name . ");", @outArgs));
+ push(@function, " responseMessage->setObject(\"result\", result);");
+ push(@function, "");
+ push(@function, " responseMessage->setNumber(\"id\", callId);");
+ push(@function, " m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());");
push(@function, "}");
push(@function, "");
push(@backendMethodsImpl, @function);
}
-sub generateDocumentationCommand
-{
- my $interface = shift;
- my $function = shift;
-
- my $functionName = $function->signature->name;
- my $domain = $interface->name;
-
- my @lines;
-
- push(@lines, "<h4>" . $interface->name . "." . ${functionName} . "</h4>");
- my $doc = $function->signature->extendedAttributes->{"doc"};
- if ($doc) {
- push(@lines, $doc);
- }
-
- my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters});
- push(@lines, "<pre style='background: lightGrey; padding: 10px'>");
- push(@lines, "request: {");
- push(@lines, " id: &lt;number&gt;,");
- push(@lines, " type: \"request\",");
- push(@lines, " domain: \"" . $interface->name . "\",");
- if (scalar(@inArgs)) {
- push(@lines, " command: \"${functionName}\",");
- push(@lines, " arguments: {");
- my @parameters;
- foreach my $parameter (@inArgs) {
- push(@parameters, " " . parameterDocLine($parameter));
- }
- push(@lines, join(",\n", @parameters));
- push(@lines, " }");
- } else {
- push(@lines, " command: \"${functionName}\"");
- }
- push(@lines, "}");
-
- my @outArgs = grep($_->direction eq "out", @{$function->parameters});
- push(@lines, "");
- push(@lines, "response: {");
- push(@lines, " requestId: &lt;number&gt;,");
- if (scalar(@outArgs)) {
- push(@lines, " type: \"response\",");
- push(@lines, " body: {");
- my @parameters;
- foreach my $parameter (@outArgs) {
- push(@parameters, " " . parameterDocLine($parameter));
- }
- push(@lines, join(",\n", @parameters));
- push(@lines, " }");
- } else {
- push(@lines, " type: \"response\"");
- }
- push(@lines, "}");
- push(@lines, "</pre>");
-
- push(@documentationLines, @lines);
-}
-
sub generateBackendReportProtocolError
{
my $reportProtocolError = << "EOF";
-void ${backendClassName}::reportProtocolError(const long callId, const String& errorText) const
+void ${backendClassName}::reportProtocolError(const long* const callId, CommonErrorCode code, const String& customText) const
{
+ RefPtr<InspectorArray> data = InspectorArray::create();
+ data->pushString(customText);
+ reportProtocolError(callId, code, data.release());
+}
+
+void ${backendClassName}::reportProtocolError(const long* const callId, CommonErrorCode code, PassRefPtr<InspectorArray> data) const
+{
+ DEFINE_STATIC_LOCAL(Vector<String>,s_commonErrors,);
+ if (!s_commonErrors.size()) {
+ s_commonErrors.insert(ParseError, "{\\\"code\\\":-32700,\\\"message\\\":\\\"Parse error.\\\"}");
+ s_commonErrors.insert(InvalidRequest, "{\\\"code\\\":-32600,\\\"message\\\":\\\"Invalid Request.\\\"}");
+ s_commonErrors.insert(MethodNotFound, "{\\\"code\\\":-32601,\\\"message\\\":\\\"Method not found.\\\"}");
+ s_commonErrors.insert(InvalidParams, "{\\\"code\\\":-32602,\\\"message\\\":\\\"Invalid params.\\\"}");
+ s_commonErrors.insert(InternalError, "{\\\"code\\\":-32603,\\\"message\\\":\\\"Internal error.\\\"}");
+ s_commonErrors.insert(ServerError, "{\\\"code\\\":-32000,\\\"message\\\":\\\"Server error.\\\"}");
+ }
+ ASSERT(code >=0);
+ ASSERT((unsigned)code < s_commonErrors.size());
+ ASSERT(s_commonErrors[code]);
+ ASSERT(InspectorObject::parseJSON(s_commonErrors[code]));
+ RefPtr<InspectorObject> error = InspectorObject::parseJSON(s_commonErrors[code])->asObject();
+ ASSERT(error);
+ error->setArray("data", data);
RefPtr<InspectorObject> message = InspectorObject::create();
- message->setNumber("requestId", callId);
- RefPtr<InspectorArray> errors = InspectorArray::create();
- errors->pushString(errorText);
- message->setArray("protocolErrors", errors);
- m_inspectorClient->sendMessageToFrontend(message->toJSONString());
+ message->setObject("error", error);
+ if (callId)
+ message->setNumber("id", *callId);
+ else
+ message->setValue("id", InspectorValue::null());
+ m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
}
EOF
return split("\n", $reportProtocolError);
@@ -618,10 +545,10 @@ sub generateArgumentGetters
my $return = typeTraits($type, "return") ? typeTraits($type, "return") : typeTraits($type, "param");
my $typeString = camelCase($type);
- push(@backendConstantDeclarations, " $return get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors);");
+ push(@backendConstantDeclarations, " $return get$typeString(InspectorObject* object, const String& name, bool optional, InspectorArray* protocolErrors);");
my $getterBody = << "EOF";
-$return InspectorBackendDispatcher::get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors)
+$return InspectorBackendDispatcher::get$typeString(InspectorObject* object, const String& name, bool optional, InspectorArray* protocolErrors)
{
ASSERT(object);
ASSERT(protocolErrors);
@@ -630,12 +557,14 @@ $return InspectorBackendDispatcher::get$typeString(InspectorObject* object, cons
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()));
+ if (valueIterator == end) {
+ if (!optional)
+ protocolErrors->pushString(String::format("Parameter '\%s' with type '$json' was not found.", name.utf8().data()));
+ return value;
}
+
+ if (!valueIterator->second->as$json(&value))
+ protocolErrors->pushString(String::format("Parameter '\%s' has wrong type. It should be '$json'.", name.utf8().data()));
return value;
}
EOF
@@ -650,11 +579,6 @@ sub generateBackendDispatcher
my $mapEntries = join("\n", @mapEntries);
my $backendDispatcherBody = << "EOF";
-static String commandName(const String& domain, const String& command)
-{
- return makeString(domain, "_", command);
-}
-
void ${backendClassName}::dispatch(const String& message)
{
typedef void (${backendClassName}::*CallHandler)(long callId, InspectorObject* messageObject);
@@ -668,54 +592,42 @@ $mapEntries
RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
if (!parsedMessage) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. Message should be in JSON format.");
+ reportProtocolError(0, ParseError, "Message should be in JSON format.");
return;
}
RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
if (!messageObject) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. The message should be a JSONified object.");
+ reportProtocolError(0, InvalidRequest, "Invalid message format. The message should be a JSONified object.");
return;
}
- RefPtr<InspectorValue> commandValue = messageObject->get("command");
- if (!commandValue) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. 'command' property wasn't found.");
- return;
- }
-
- String command;
- if (!commandValue->asString(&command)) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'command' property should be string.");
- return;
- }
-
- RefPtr<InspectorValue> domainValue = messageObject->get("domain");
- if (!domainValue) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. 'domain' property wasn't found.");
+ RefPtr<InspectorValue> callIdValue = messageObject->get("id");
+ if (!callIdValue) {
+ reportProtocolError(0, InvalidRequest, "Invalid message format. 'id' property was not found in the request.");
return;
}
- String domain;
- if (!domainValue->asString(&domain)) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'domain' property should be string.");
+ if (!callIdValue->asNumber(&callId)) {
+ reportProtocolError(0, InvalidRequest, "Invalid message format. The type of 'id' property should be number.");
return;
}
- RefPtr<InspectorValue> callIdValue = messageObject->get("id");
- if (!callIdValue) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. 'id' property was not found in the request.");
+ RefPtr<InspectorValue> methodValue = messageObject->get("method");
+ if (!methodValue) {
+ reportProtocolError(&callId, InvalidRequest, "Invalid message format. 'method' property wasn't found.");
return;
}
- if (!callIdValue->asNumber(&callId)) {
- reportProtocolError(callId, "Protocol Error: Invalid message format. The type of 'id' property should be number.");
+ String method;
+ if (!methodValue->asString(&method)) {
+ reportProtocolError(&callId, InvalidRequest, "Invalid message format. The type of 'method' property should be string.");
return;
}
- HashMap<String, CallHandler>::iterator it = dispatchMap.find(commandName(domain, command));
+ HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
if (it == dispatchMap.end()) {
- reportProtocolError(callId, makeString("Protocol Error: Invalid command was received. '", command, "' wasn't found in domain ", domain, "."));
+ reportProtocolError(&callId, MethodNotFound, makeString("Invalid method name was received. '", method, "' wasn't found."));
return;
}
@@ -738,15 +650,9 @@ bool ${backendClassName}::getCommandName(const String& message, String* result)
if (!object)
return false;
- String domain;
- if (!object->getString("domain", &domain))
+ if (!object->getString("method", result))
return false;
- String command;
- if (!object->getString("command", &command))
- return false;
-
- *result = commandName(domain, command);
return true;
}
EOF
@@ -761,19 +667,40 @@ sub collectBackendJSStubFunctions
foreach my $function (@functions) {
my $name = $function->signature->name;
- my $argumentNames = join(",", map("\"" . $_->name . "\": \"" . typeTraits($_->type, "JSType") . "\"", grep($_->direction eq "in", @{$function->parameters})));
+ my @inArgs = grep($_->direction eq "in", @{$function->parameters});
+ my $argumentNames = join(
+ ",",
+ map("\"" . $_->name . "\": {"
+ . "\"optional\": " . ($_->extendedAttributes->{"optional"} ? "true " : "false") . ", "
+ . "\"type\": \"" . typeTraits($_->type, "JSType") . "\""
+ . "}",
+ @inArgs));
push(@backendJSStubs, " this._registerDelegate('{" .
- "\"id\": 0, " .
- "\"domain\": \"$domain\", " .
- "\"command\": \"$name\", " .
- "\"arguments\": {$argumentNames}" .
+ "\"method\": \"$domain.$name\", " .
+ (scalar(@inArgs) ? "\"params\": {$argumentNames}, " : "") .
+ "\"id\": 0" .
"}');");
}
}
+sub collectBackendJSStubEvents
+{
+ my $interface = shift;
+ my @functions = grep($_->signature->extendedAttributes->{"event"}, @{$interface->functions});
+ my $domain = $interface->name;
+
+ foreach my $function (@functions) {
+ my $name = $domain . "." . $function->signature->name;
+ my @outArgs = grep($_->direction eq "out", @{$function->parameters});
+ my $argumentNames = join(",", map("\"" . $_->name . "\"" , @outArgs));
+ push(@backendJSEvents, " this._eventArgs[\"" . $name . "\"] = [" . $argumentNames ."];");
+ }
+}
+
sub generateBackendStubJS
{
my $JSStubs = join("\n", @backendJSStubs);
+ my $JSEvents = join("\n", @backendJSEvents);
my $inspectorBackendStubJS = << "EOF";
$licenseTemplate
@@ -783,7 +710,9 @@ InspectorBackendStub = function()
this._pendingResponsesCount = 0;
this._callbacks = {};
this._domainDispatchers = {};
+ this._eventArgs = {};
$JSStubs
+$JSEvents
}
InspectorBackendStub.prototype = {
@@ -794,40 +723,53 @@ InspectorBackendStub.prototype = {
return callbackId;
},
- _registerDelegate: function(commandInfo)
+ _registerDelegate: function(requestString)
{
- var commandObject = JSON.parse(commandInfo);
- var agentName = commandObject.domain + "Agent";
+ var domainAndFunction = JSON.parse(requestString).method.split(".");
+ var agentName = domainAndFunction[0] + "Agent";
if (!window[agentName])
window[agentName] = {};
- window[agentName][commandObject.command] = this.sendMessageToBackend.bind(this, commandInfo);
+ window[agentName][domainAndFunction[1]] = this.sendMessageToBackend.bind(this, requestString);
},
sendMessageToBackend: function()
{
var args = Array.prototype.slice.call(arguments);
var request = JSON.parse(args.shift());
+ var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : 0;
+ var domainAndMethod = request.method.split(".");
+ var agentMethod = domainAndMethod[0] + "Agent." + domainAndMethod[1];
+
+ if (request.params) {
+ for (var key in request.params) {
+ var typeName = request.params[key].type;
+ var optionalFlag = request.params[key].optional;
+
+ if (args.length === 0 && !optionalFlag) {
+ console.error("Protocol Error: Invalid number of arguments for method '" + agentMethod + "' call. It should have the next arguments '" + JSON.stringify(request.params) + "'.");
+ return;
+ }
- for (var key in request.arguments) {
- if (args.length === 0) {
- console.error("Protocol Error: Invalid number of arguments for '" + request.domain + "Agent." + request.command + "' call. It should have the next arguments '" + JSON.stringify(request.arguments) + "'.");
- return;
- }
- var value = args.shift();
- if (request.arguments[key] && typeof value !== request.arguments[key]) {
- console.error("Protocol Error: Invalid type of argument '" + key + "' for '" + request.domain + "Agent." + request.command + "' call. It should be '" + request.arguments[key] + "' but it is '" + typeof value + "'.");
- return;
+ var value = args.shift();
+ if (optionalFlag && typeof value === "undefined") {
+ delete request.params[key];
+ continue;
+ }
+
+ if (typeof value !== typeName) {
+ console.error("Protocol Error: Invalid type of argument '" + key + "' for method '" + agentMethod + "' call. It should be '" + typeName + "' but it is '" + typeof value + "'.");
+ return;
+ }
+
+ request.params[key] = value;
}
- request.arguments[key] = value;
}
- var callback;
- if (args.length === 1) {
- if (typeof args[0] !== "function" && typeof args[0] !== "undefined") {
- console.error("Protocol Error: Optional callback argument for '" + request.domain + "Agent." + request.command + "' call should be a function but its type is '" + typeof args[0] + "'.");
+ if (args.length === 1 && !callback) {
+ if (typeof args[0] !== "undefined") {
+ console.error("Protocol Error: Optional callback argument for method '" + agentMethod + "' call should be a function but its type is '" + typeof args[0] + "'.");
return;
}
- callback = args[0];
}
request.id = this._wrap(callback || function() {});
@@ -852,51 +794,64 @@ InspectorBackendStub.prototype = {
var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
- var arguments = [];
- if (messageObject.body)
- for (var key in messageObject.body)
- arguments.push(messageObject.body[key]);
-
- if ("requestId" in messageObject) { // just a response for some request
- if (messageObject.protocolErrors)
+ if ("id" in messageObject) { // just a response for some request
+ if (messageObject.error && messageObject.error.code !== -32000)
this.reportProtocolError(messageObject);
- var callback = this._callbacks[messageObject.requestId];
+ var arguments = [];
+ if (messageObject.result) {
+ for (var key in messageObject.result)
+ arguments.push(messageObject.result[key]);
+ }
+
+ var callback = this._callbacks[messageObject.id];
if (callback) {
- if (!messageObject.protocolErrors) {
- arguments.unshift(messageObject.error);
- callback.apply(null, arguments);
- }
+ arguments.unshift(messageObject.error);
+ callback.apply(null, arguments);
--this._pendingResponsesCount;
- delete this._callbacks[messageObject.requestId];
+ delete this._callbacks[messageObject.id];
}
if (this._scripts && !this._pendingResponsesCount)
this.runAfterPendingDispatches();
return;
- }
-
- if (messageObject.type === "event") {
- if (!(messageObject.domain in this._domainDispatchers)) {
- console.error("Protocol Error: the message is for non-existing domain '" + messageObject.domain + "'");
+ } else {
+ var method = messageObject.method.split(".");
+ var domainName = method[0];
+ var functionName = method[1];
+ if (!(domainName in this._domainDispatchers)) {
+ console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
+ return;
+ }
+ var dispatcher = this._domainDispatchers[domainName];
+ if (!(functionName in dispatcher)) {
+ console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
return;
}
- var dispatcher = this._domainDispatchers[messageObject.domain];
- if (!(messageObject.event in dispatcher)) {
- console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.domain + "." + messageObject.event + "'");
+
+ if (!this._eventArgs[messageObject.method]) {
+ console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
return;
}
- dispatcher[messageObject.event].apply(dispatcher, arguments);
+ var params = [];
+ if (messageObject.params) {
+ var paramNames = this._eventArgs[messageObject.method];
+ for (var i = 0; i < paramNames.length; ++i)
+ params.push(messageObject.params[paramNames[i]]);
+ }
+
+ dispatcher[functionName].apply(dispatcher, params);
}
},
reportProtocolError: function(messageObject)
{
- console.error("Protocol Error: InspectorBackend request with id = " + messageObject.requestId + " failed.");
- for (var i = 0; i < messageObject.protocolErrors.length; ++i)
- console.error(" " + messageObject.protocolErrors[i]);
+ var error = messageObject.error;
+ console.error(error.message + "(" + error.code + "): request with id = " + messageObject.id + " failed.");
+ for (var i = 0; i < error.data.length; ++i)
+ console.error(" " + error.data[i]);
},
runAfterPendingDispatches: function(script)
@@ -1010,44 +965,14 @@ sub typeTraits
return $typeTransform{$type}->{$trait};
}
-sub parameterDocType
-{
- my $parameter = shift;
- my $subtype = $parameter->extendedAttributes->{"type"};
- if ($subtype) {
- my $pattern = typeTraits($parameter->type, "DocType");
- return sprintf($pattern, "&lt;$subtype&gt;");
- }
-
- my $subtypeRef = $parameter->extendedAttributes->{"typeRef"};
- if ($subtypeRef) {
- my $pattern = typeTraits($parameter->type, "DocType");
- return sprintf($pattern, "&lt;<a href='#$subtypeRef'>" . $subtypeRef . "</a>&gt;");
- }
-
- return "&lt;" . typeTraits($parameter->type, "JSType") . "&gt;";
-}
-
-sub parameterDocLine
-{
- my $parameter = shift;
-
- my $result = $parameter->name . ": " . parameterDocType($parameter);
- my $doc = $parameter->extendedAttributes->{"doc"};
- if ($doc) {
- $result = $result . " // " . $doc;
- }
- return $result;
-}
-
sub generateBackendAgentFieldsAndConstructor
{
my @arguments;
my @fieldInitializers;
- push(@arguments, "InspectorClient* inspectorClient");
- push(@fieldInitializers, " : m_inspectorClient(inspectorClient)");
- push(@backendFooter, " InspectorClient* m_inspectorClient;");
+ push(@arguments, "InspectorFrontendChannel* inspectorFrontendChannel");
+ push(@fieldInitializers, " : m_inspectorFrontendChannel(inspectorFrontendChannel)");
+ push(@backendFooter, " InspectorFrontendChannel* m_inspectorFrontendChannel;");
foreach my $domain (sort keys %backendDomains) {
# Add agent field declaration to the footer.
@@ -1067,7 +992,19 @@ sub generateBackendAgentFieldsAndConstructor
push(@backendHead, " ${backendClassName}(${argumentString})");
push(@backendHead, @fieldInitializers);
push(@backendHead, " { }");
- push(@backendHead, " void reportProtocolError(const long callId, const String& errorText) const;");
+ push(@backendHead, "");
+ push(@backendHead, " enum CommonErrorCode {");
+ push(@backendHead, " ParseError = 0,");
+ push(@backendHead, " InvalidRequest,");
+ push(@backendHead, " MethodNotFound,");
+ push(@backendHead, " InvalidParams,");
+ push(@backendHead, " InternalError,");
+ push(@backendHead, " ServerError,");
+ push(@backendHead, " LastEntry,");
+ push(@backendHead, " };");
+ push(@backendHead, "");
+ push(@backendHead, " void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorText) const;");
+ push(@backendHead, " void reportProtocolError(const long* const callId, CommonErrorCode, PassRefPtr<InspectorArray> data) const;");
push(@backendHead, " void dispatch(const String& message);");
push(@backendHead, " static bool getCommandName(const String& message, String* result);");
$backendConstructor = join("\n", @backendHead);
@@ -1121,14 +1058,6 @@ sub finish
print $JS_STUB join("\n", generateBackendStubJS());
close($JS_STUB);
undef($JS_STUB);
-
- open(my $DOCS, ">$outputDir/WebInspectorProtocol.html") || die "Couldn't open file $outputDir/WebInspectorProtocol.html";
- print $DOCS "<ol class='toc' style='list-style: none; padding: 0'>";
- print $DOCS join("\n", @documentationToc);
- print $DOCS "</ol>";
- print $DOCS join("\n", @documentationLines);
- close($DOCS);
- undef($DOCS);
}
1;
diff --git a/Source/WebCore/inspector/ConsoleMessage.cpp b/Source/WebCore/inspector/ConsoleMessage.cpp
index de61ef8..5ced69a 100644
--- a/Source/WebCore/inspector/ConsoleMessage.cpp
+++ b/Source/WebCore/inspector/ConsoleMessage.cpp
@@ -86,18 +86,60 @@ ConsoleMessage::~ConsoleMessage()
{
}
+// Keep in sync with inspector/front-end/ConsoleView.js
+static String messageSourceValue(MessageSource source)
+{
+ switch (source) {
+ case HTMLMessageSource: return "html";
+ case WMLMessageSource: return "wml";
+ case XMLMessageSource: return "xml";
+ case JSMessageSource: return "javascript";
+ case CSSMessageSource: return "css";
+ case OtherMessageSource: return "other";
+ }
+ return "other";
+}
+
+static String messageTypeValue(MessageType type)
+{
+ switch (type) {
+ case LogMessageType: return "log";
+ case ObjectMessageType: return "other";
+ case TraceMessageType: return "trace";
+ case StartGroupMessageType: return "startGroup";
+ case StartGroupCollapsedMessageType: return "startGroupCollapsed";
+ case EndGroupMessageType: return "endGroup";
+ case AssertMessageType: return "assert";
+ case UncaughtExceptionMessageType: return "uncaughtException";
+ case NetworkErrorMessageType: return "networkError";
+ }
+ return "other";
+}
+
+static String messageLevelValue(MessageLevel level)
+{
+ switch (level) {
+ case TipMessageLevel: return "tip";
+ case LogMessageLevel: return "log";
+ case WarningMessageLevel: return "warning";
+ case ErrorMessageLevel: return "error";
+ case DebugMessageLevel: return "debug";
+ }
+ return "log";
+}
+
void ConsoleMessage::addToFrontend(InspectorFrontend::Console* frontend, InjectedScriptManager* injectedScriptManager)
{
RefPtr<InspectorObject> jsonObj = InspectorObject::create();
- jsonObj->setNumber("source", static_cast<int>(m_source));
- jsonObj->setNumber("type", static_cast<int>(m_type));
- jsonObj->setNumber("level", static_cast<int>(m_level));
+ jsonObj->setString("source", messageSourceValue(m_source));
+ jsonObj->setString("type", messageTypeValue(m_type));
+ jsonObj->setString("level", messageLevelValue(m_level));
jsonObj->setNumber("line", static_cast<int>(m_line));
jsonObj->setString("url", m_url);
jsonObj->setNumber("repeatCount", static_cast<int>(m_repeatCount));
- jsonObj->setString("message", m_message);
+ jsonObj->setString("text", m_message);
if (m_type == NetworkErrorMessageType)
- jsonObj->setNumber("requestId", m_requestId);
+ jsonObj->setNumber("networkIdentifier", m_requestId);
if (m_arguments && m_arguments->argumentCount()) {
InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->globalState());
if (!injectedScript.hasNoValue()) {
@@ -115,12 +157,12 @@ void ConsoleMessage::addToFrontend(InspectorFrontend::Console* frontend, Injecte
}
if (m_callStack)
jsonObj->setArray("stackTrace", m_callStack->buildInspectorArray());
- frontend->consoleMessage(jsonObj);
+ frontend->messageAdded(jsonObj);
}
void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend::Console* frontend)
{
- frontend->consoleMessageRepeatCountUpdated(m_repeatCount);
+ frontend->messageRepeatCountUpdated(m_repeatCount);
}
bool ConsoleMessage::isEqual(ConsoleMessage* msg) const
diff --git a/Source/WebCore/inspector/DOMNodeHighlighter.cpp b/Source/WebCore/inspector/DOMNodeHighlighter.cpp
index c87649b..41609d8 100644
--- a/Source/WebCore/inspector/DOMNodeHighlighter.cpp
+++ b/Source/WebCore/inspector/DOMNodeHighlighter.cpp
@@ -243,7 +243,10 @@ void DrawNodeHighlight(GraphicsContext& context, Node* node)
if (renderer->isBox() && !isSVGRenderer) {
RenderBox* renderBox = toRenderBox(renderer);
+ // RenderBox returns the "pure" content area box, exclusive of the scrollbars (if present), which also count towards the content area in CSS.
IntRect contentBox = renderBox->contentBoxRect();
+ contentBox.setWidth(contentBox.width() + renderBox->verticalScrollbarWidth());
+ contentBox.setHeight(contentBox.height() + renderBox->horizontalScrollbarHeight());
IntRect paddingBox(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(),
contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom());
diff --git a/Source/WebCore/inspector/EventsCollector.cpp b/Source/WebCore/inspector/EventsCollector.cpp
new file mode 100644
index 0000000..1c365cf
--- /dev/null
+++ b/Source/WebCore/inspector/EventsCollector.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EventsCollector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "InspectorFrontendChannel.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+EventsCollector::EventsCollector()
+ : m_totalLength(0)
+{
+}
+
+void EventsCollector::addEvent(const String& message)
+{
+ m_totalLength += message.length();
+ m_events.append(message);
+ while (m_totalLength > maxCapacity) {
+ m_totalLength -= m_events[0].length();
+ m_events.remove(0);
+ }
+}
+
+void EventsCollector::sendCollectedEvents(InspectorFrontendChannel* receiver)
+{
+ for (Vector<String>::iterator it = m_events.begin(); it != m_events.end(); ++it)
+ receiver->sendMessageToFrontend(*it);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/EventsCollector.h b/Source/WebCore/inspector/EventsCollector.h
new file mode 100644
index 0000000..d53e109
--- /dev/null
+++ b/Source/WebCore/inspector/EventsCollector.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EventsCollector_h
+#define EventsCollector_h
+
+#if ENABLE(INSPECTOR)
+
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class InspectorFrontendChannel;
+
+class EventsCollector {
+public:
+ EventsCollector();
+ ~EventsCollector() { }
+ void addEvent(const String& message);
+ void sendCollectedEvents(InspectorFrontendChannel*);
+private:
+ static const size_t maxCapacity = 1024*1024; // 1 Mb
+ size_t m_totalLength;
+ Vector<String> m_events;
+};
+
+} // namespace WebCore
+
+#endif // !defined(EventsCollector_h)
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InjectedScript.cpp b/Source/WebCore/inspector/InjectedScript.cpp
index ee2e35a..e653290 100644
--- a/Source/WebCore/inspector/InjectedScript.cpp
+++ b/Source/WebCore/inspector/InjectedScript.cpp
@@ -43,8 +43,14 @@
namespace WebCore {
-InjectedScript::InjectedScript(ScriptObject injectedScriptObject)
+InjectedScript::InjectedScript()
+ : m_inspectedStateAccessCheck(0)
+{
+}
+
+InjectedScript::InjectedScript(ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck)
: m_injectedScriptObject(injectedScriptObject)
+ , m_inspectedStateAccessCheck(accessCheck)
{
}
@@ -75,17 +81,16 @@ void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const String&
makeObjectCall(errorString, function, result);
}
-void InjectedScript::getProperties(ErrorString* errorString, const String& objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorArray>* properties)
+void InjectedScript::getProperties(ErrorString* errorString, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* properties)
{
ScriptFunctionCall function(m_injectedScriptObject, "getProperties");
function.appendArgument(objectId);
function.appendArgument(ignoreHasOwnProperty);
- function.appendArgument(abbreviate);
RefPtr<InspectorValue> result;
makeCall(function, &result);
if (!result || result->type() != InspectorValue::TypeArray) {
- *errorString = "Internal error.";
+ *errorString = "Internal error";
return;
}
*properties = result->asArray();
@@ -179,7 +184,7 @@ void InjectedScript::releaseObjectGroup(const String& objectGroup)
bool InjectedScript::canAccessInspectedWindow()
{
- return InjectedScriptManager::canAccessInspectedWindow(m_injectedScriptObject.scriptState());
+ return m_inspectedStateAccessCheck(m_injectedScriptObject.scriptState());
}
void InjectedScript::makeCall(ScriptFunctionCall& function, RefPtr<InspectorValue>* result)
@@ -209,7 +214,7 @@ void InjectedScript::makeObjectCall(ErrorString* errorString, ScriptFunctionCall
}
if (!result || result->type() != InspectorValue::TypeObject) {
- *errorString = "Internal error.";
+ *errorString = "Internal error";
return;
}
*objectResult = result->asObject();
diff --git a/Source/WebCore/inspector/InjectedScript.h b/Source/WebCore/inspector/InjectedScript.h
index e165e9c..adcb208 100644
--- a/Source/WebCore/inspector/InjectedScript.h
+++ b/Source/WebCore/inspector/InjectedScript.h
@@ -50,7 +50,7 @@ typedef String ErrorString;
class InjectedScript {
public:
- InjectedScript() { }
+ InjectedScript();
~InjectedScript() { }
bool hasNoValue() const { return m_injectedScriptObject.hasNoValue(); }
@@ -58,7 +58,7 @@ public:
void evaluate(ErrorString*, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
void evaluateOn(ErrorString*, const String& objectId, const String& expression, RefPtr<InspectorObject>* result);
void evaluateOnCallFrame(ErrorString*, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
- void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorArray>* result);
+ void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result);
Node* nodeForObjectId(const String& objectId);
void setPropertyValue(ErrorString*, const String& objectId, const String& propertyName, const String& expression);
void releaseObject(const String& objectId);
@@ -75,7 +75,8 @@ public:
private:
friend InjectedScript InjectedScriptManager::injectedScriptFor(ScriptState*);
- explicit InjectedScript(ScriptObject);
+ typedef bool (*InspectedStateAccessCheck)(ScriptState*);
+ InjectedScript(ScriptObject, InspectedStateAccessCheck);
bool canAccessInspectedWindow();
void makeCall(ScriptFunctionCall&, RefPtr<InspectorValue>* result);
@@ -83,6 +84,7 @@ private:
ScriptValue nodeAsScriptValue(Node*);
ScriptObject m_injectedScriptObject;
+ InspectedStateAccessCheck m_inspectedStateAccessCheck;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InjectedScriptManager.cpp b/Source/WebCore/inspector/InjectedScriptManager.cpp
index 5c21802..7464355 100644
--- a/Source/WebCore/inspector/InjectedScriptManager.cpp
+++ b/Source/WebCore/inspector/InjectedScriptManager.cpp
@@ -44,14 +44,20 @@ using namespace std;
namespace WebCore {
-PassOwnPtr<InjectedScriptManager> InjectedScriptManager::create()
+PassOwnPtr<InjectedScriptManager> InjectedScriptManager::createForPage()
{
- return adoptPtr(new InjectedScriptManager());
+ return adoptPtr(new InjectedScriptManager(&InjectedScriptManager::canAccessInspectedWindow));
}
-InjectedScriptManager::InjectedScriptManager()
+PassOwnPtr<InjectedScriptManager> InjectedScriptManager::createForWorker()
+{
+ return adoptPtr(new InjectedScriptManager(&InjectedScriptManager::canAccessInspectedWorkerContext));
+}
+
+InjectedScriptManager::InjectedScriptManager(InspectedStateAccessCheck accessCheck)
: m_nextInjectedScriptId(1)
, m_injectedScriptHost(InjectedScriptHost::create())
+ , m_inspectedStateAccessCheck(accessCheck)
{
}
@@ -95,6 +101,11 @@ void InjectedScriptManager::discardInjectedScripts()
m_idToInjectedScript.clear();
}
+bool InjectedScriptManager::canAccessInspectedWorkerContext(ScriptState*)
+{
+ return true;
+}
+
void InjectedScriptManager::releaseObjectGroup(const String& objectGroup)
{
for (IdToInjectedScriptMap::iterator it = m_idToInjectedScript.begin(); it != m_idToInjectedScript.end(); ++it)
diff --git a/Source/WebCore/inspector/InjectedScriptManager.h b/Source/WebCore/inspector/InjectedScriptManager.h
index 2896e8f..fcfa011 100644
--- a/Source/WebCore/inspector/InjectedScriptManager.h
+++ b/Source/WebCore/inspector/InjectedScriptManager.h
@@ -46,7 +46,8 @@ class ScriptObject;
class InjectedScriptManager {
WTF_MAKE_NONCOPYABLE(InjectedScriptManager);
public:
- static PassOwnPtr<InjectedScriptManager> create();
+ static PassOwnPtr<InjectedScriptManager> createForPage();
+ static PassOwnPtr<InjectedScriptManager> createForWorker();
~InjectedScriptManager();
void disconnect();
@@ -60,19 +61,23 @@ public:
void discardInjectedScripts();
void releaseObjectGroup(const String& objectGroup);
- static bool canAccessInspectedWindow(ScriptState*);
private:
- InjectedScriptManager();
+ typedef bool (*InspectedStateAccessCheck)(ScriptState*);
+ explicit InjectedScriptManager(InspectedStateAccessCheck);
String injectedScriptSource();
ScriptObject createInjectedScript(const String& source, ScriptState*, long id);
void discardInjectedScript(ScriptState*);
+ static bool canAccessInspectedWindow(ScriptState*);
+ static bool canAccessInspectedWorkerContext(ScriptState*);
+
long m_nextInjectedScriptId;
typedef HashMap<long, InjectedScript> IdToInjectedScriptMap;
IdToInjectedScriptMap m_idToInjectedScript;
RefPtr<InjectedScriptHost> m_injectedScriptHost;
+ InspectedStateAccessCheck m_inspectedStateAccessCheck;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InjectedScriptSource.js b/Source/WebCore/inspector/InjectedScriptSource.js
index f499a17..ce43a42 100644
--- a/Source/WebCore/inspector/InjectedScriptSource.js
+++ b/Source/WebCore/inspector/InjectedScriptSource.js
@@ -71,7 +71,7 @@ InjectedScript.prototype = {
if (arguments.length === 0)
return;
- var objectId = this._wrapObject(object, "", false);
+ var objectId = this._wrapObject(object, "");
var hints = {};
switch (injectedScript._describe(object)) {
@@ -90,7 +90,7 @@ InjectedScript.prototype = {
return object;
},
- _wrapObject: function(object, objectGroupName, abbreviate)
+ _wrapObject: function(object, objectGroupName)
{
try {
if (typeof object === "object" || typeof object === "function" || this._isHTMLAllCollection(object)) {
@@ -107,7 +107,7 @@ InjectedScript.prototype = {
this._idToObjectGroupName[id] = objectGroupName;
}
}
- return InjectedScript.RemoteObject.fromObject(object, objectId, abbreviate);
+ return InjectedScript.RemoteObject.fromObject(object, objectId);
} catch (e) {
return InjectedScript.RemoteObject.fromObject("[ Exception: " + e.toString() + " ]");
}
@@ -139,7 +139,7 @@ InjectedScript.prototype = {
return result;
},
- getProperties: function(objectId, ignoreHasOwnProperty, abbreviate)
+ getProperties: function(objectId, ignoreHasOwnProperty)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
@@ -162,7 +162,7 @@ InjectedScript.prototype = {
var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
if (!isGetter) {
try {
- property.value = this._wrapObject(object[propertyName], objectGroupName, abbreviate);
+ property.value = this._wrapObject(object[propertyName], objectGroupName);
} catch(e) {
property.value = new InjectedScript.RemoteObject.fromException(e);
}
@@ -299,7 +299,6 @@ InjectedScript.prototype = {
if (!callFrame)
return false;
- injectedScript.releaseObjectGroup("backtrace");
var result = [];
var depth = 0;
do {
@@ -402,12 +401,13 @@ InjectedScript.prototype = {
return type;
},
- _describe: function(obj, abbreviated)
+ _describe: function(obj)
{
var type = this._type(obj);
switch (type) {
case "object":
+ // Fall through.
case "node":
var result = InjectedScriptHost.internalConstructorName(obj);
if (result === "Object") {
@@ -424,14 +424,9 @@ InjectedScript.prototype = {
className += "[" + obj.length + "]";
return className;
case "string":
- if (abbreviated && obj.length > 100)
- return obj.substring(0, 100) + "\u2026";
return obj;
case "function":
- var objectText = this._toString(obj);
- if (abbreviated)
- objectText = /.*/.exec(objectText)[0].replace(/ +$/g, "");
- return objectText;
+ // Fall through.
default:
return this._toString(obj);
}
@@ -461,14 +456,14 @@ InjectedScript.RemoteObject.fromException = function(e)
return new InjectedScript.RemoteObject(null, "error", e.toString());
}
-InjectedScript.RemoteObject.fromObject = function(object, objectId, abbreviate)
+InjectedScript.RemoteObject.fromObject = function(object, objectId)
{
var type = injectedScript._type(object);
var rawType = typeof object;
var hasChildren = (rawType === "object" && object !== null && (!!Object.getOwnPropertyNames(object).length || !!object.__proto__)) || rawType === "function";
var description = "";
try {
- var description = injectedScript._describe(object, abbreviate);
+ var description = injectedScript._describe(object);
return new InjectedScript.RemoteObject(objectId, type, description, hasChildren);
} catch (e) {
return InjectedScript.RemoteObject.fromException(e);
@@ -478,11 +473,8 @@ InjectedScript.RemoteObject.fromObject = function(object, objectId, abbreviate)
InjectedScript.CallFrameProxy = function(ordinal, callFrame)
{
this.id = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + injectedScriptId + "}";
- this.type = callFrame.type;
- this.functionName = (this.type === "function" ? callFrame.functionName : "");
- this.sourceID = callFrame.sourceID;
- this.line = callFrame.line;
- this.column = callFrame.column;
+ this.functionName = (callFrame.type === "function" ? callFrame.functionName : "");
+ this.location = { sourceID: callFrame.sourceID, lineNumber: callFrame.line, columnNumber: callFrame.column };
this.scopeChain = this._wrapScopeChain(callFrame);
}
@@ -494,38 +486,28 @@ InjectedScript.CallFrameProxy.prototype = {
const WITH_SCOPE = 2;
const CLOSURE_SCOPE = 3;
const CATCH_SCOPE = 4;
-
+
+ var scopeTypeNames = {};
+ scopeTypeNames[GLOBAL_SCOPE] = "global";
+ scopeTypeNames[LOCAL_SCOPE] = "local";
+ scopeTypeNames[WITH_SCOPE] = "with";
+ scopeTypeNames[CLOSURE_SCOPE] = "closure";
+ scopeTypeNames[CATCH_SCOPE] = "catch";
+
var scopeChain = callFrame.scopeChain;
var scopeChainProxy = [];
var foundLocalScope = false;
for (var i = 0; i < scopeChain.length; i++) {
+ var scope = {};
+ scope.object = injectedScript._wrapObject(scopeChain[i], "backtrace");
+
var scopeType = callFrame.scopeType(i);
- var scopeObject = scopeChain[i];
- var scopeObjectProxy = injectedScript._wrapObject(scopeObject, "backtrace", true);
-
- switch(scopeType) {
- case LOCAL_SCOPE: {
- foundLocalScope = true;
- scopeObjectProxy.isLocal = true;
- scopeObjectProxy.thisObject = injectedScript._wrapObject(callFrame.thisObject, "backtrace", true);
- break;
- }
- case CLOSURE_SCOPE: {
- scopeObjectProxy.isClosure = true;
- break;
- }
- case WITH_SCOPE:
- case CATCH_SCOPE: {
- if (foundLocalScope && scopeObject instanceof inspectedWindow.Element)
- scopeObjectProxy.isElement = true;
- else if (foundLocalScope && scopeObject instanceof inspectedWindow.Document)
- scopeObjectProxy.isDocument = true;
- else
- scopeObjectProxy.isWithBlock = true;
- break;
- }
- }
- scopeChainProxy.push(scopeObjectProxy);
+ scope.type = scopeTypeNames[scopeType];
+
+ if (scopeType === LOCAL_SCOPE)
+ scope.this = injectedScript._wrapObject(callFrame.thisObject, "backtrace");
+
+ scopeChainProxy.push(scope);
}
return scopeChainProxy;
}
diff --git a/Source/WebCore/inspector/Inspector.json b/Source/WebCore/inspector/Inspector.json
index ed5929e..9d7168b 100644
--- a/Source/WebCore/inspector/Inspector.json
+++ b/Source/WebCore/inspector/Inspector.json
@@ -3,13 +3,6 @@
"domain": "Inspector",
"types": [],
"commands": [
- {
- "name": "didEvaluateForTestInFrontend",
- "parameters": [
- { "name": "testCallId", "type": "integer" },
- { "name": "jsonResult", "type": "string" }
- ]
- }
],
"events": [
{
@@ -43,7 +36,7 @@
{
"name": "inspect",
"parameters": [
- { "name": "object", "$ref": "RemoteObject" },
+ { "name": "object", "$ref": "Runtime.RemoteObject" },
{ "name": "hints", "type": "object" }
]
},
@@ -79,7 +72,7 @@
{
"name": "reloadPage",
"parameters": [
- { "name": "ignoreCache", "type": "boolean" }
+ { "name": "ignoreCache", "type": "boolean", "optional": true }
]
},
{
@@ -97,7 +90,7 @@
{
"name": "getCookies",
"returns": [
- { "name": "cookies", "type": "array", "items": { "$ref" : "Cookie"} },
+ { "name": "cookies", "type": "array", "items": { "$ref": "Cookie"} },
{ "name": "cookiesString", "type": "string" }
]
},
@@ -119,119 +112,185 @@
{
"name": "domContentEventFired",
"parameters": [
- { "name": "time", "type": "number" }
+ { "name": "timestamp", "type": "number" }
]
},
{
"name": "loadEventFired",
"parameters": [
- { "name": "time", "type": "number" }
+ { "name": "timestamp", "type": "number" }
]
}
]
},
{
"domain": "Runtime",
- "types": [],
+ "description": "Runtime domain exposes JavaScript runtime by means of remote evaluation and mirror objects. Evaluation results are returned as mirror object that expose type, string representation and unique identifier that can be used for further object interaction. Original objects are maintained in memory unless they are either explicitly released or are released along with the other objects in their object group.",
+ "types": [
+ {
+ "id": "RemoteObject",
+ "type": "object",
+ "description": "Mirror object referencing original JavaScript object.",
+ "properties": [
+ { "name": "description", "type": "string", "description": "String representation of the object." },
+ { "name": "hasChildren", "type": "integer", "optional": true, "description": "True when this object can be queried for children." },
+ { "name": "objectId", "type": "string", "optional": true, "description": "Unique object identifier (for non-primitive values)." },
+ { "name": "type", "type": "string", "enum": ["object", "array", "function", "null", "node", "undefined", "string", "number", "boolean", "error", "regexp", "date"], "description": "Object type." }
+ ]
+ },
+ {
+ "id": "RemoteProperty",
+ "type": "object",
+ "description": "Mirror object property.",
+ "properties": [
+ { "name": "name", "type": "string", "description": "Property name." },
+ { "name": "value", "$ref": "RemoteObject", "description": "Property value." },
+ { "name": "isGetter", "type": "string", "description": "True if this property is getter." }
+ ]
+ }
+ ],
"commands": [
{
"name": "evaluate",
"parameters": [
- { "name": "expression", "type": "string" },
- { "name": "objectGroup", "type": "string" },
- { "name": "includeCommandLineAPI", "type": "boolean" }
+ { "name": "expression", "type": "string", "description": "Expression to evaluate." },
+ { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." },
+ { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation." }
],
"returns": [
- { "name": "result", "$ref": "RuntimeObject" }
- ]
+ { "name": "result", "$ref": "RemoteObject", "description": "Evaluation result." }
+ ],
+ "description": "Evaluate expression on global object."
},
{
"name": "evaluateOn",
"parameters": [
- { "name": "objectId", "type": "string" },
- { "name": "expression", "type": "string" }
+ { "name": "objectId", "type": "string", "description": "Identifier of the object to evaluate expression on." },
+ { "name": "expression", "type": "string", "description": "Expression to evaluate." }
],
"returns": [
- { "name": "result", "$ref": "RuntimeObject" }
- ]
+ { "name": "result", "$ref": "RemoteObject", "description": "Evaluation result." }
+ ],
+ "description": "Evaluate expression on given object using it as <code>this</code>."
},
{
"name": "getProperties",
"parameters": [
- { "name": "objectId", "type": "string" },
- { "name": "ignoreHasOwnProperty", "type": "boolean" },
- { "name": "abbreviate", "type": "boolean" }
+ { "name": "objectId", "type": "string", "description": "Identifier of the object to return properties for." },
+ { "name": "ignoreHasOwnProperty", "type": "boolean", "description": "If true, returns properties belonging to any element of the prototype chain." }
],
"returns": [
- { "name": "result", "type": "array", "items": { "$ref" : "RuntimeProperty"} }
- ]
+ { "name": "result", "type": "array", "items": { "$ref": "RuntimeProperty"}, "description": "Object properties." }
+ ],
+ "description": "Returns properties of a given object."
},
{
"name": "setPropertyValue",
"parameters": [
- { "name": "objectId", "type": "string" },
- { "name": "propertyName", "type": "string" },
- { "name": "expression", "type": "string" }
- ]
+ { "name": "objectId", "type": "string", "description": "Identifier of the object to set property on." },
+ { "name": "propertyName", "type": "string", "description": "Property name to set value for." },
+ { "name": "expression", "type": "string", "description": "Expression to evaluate." }
+ ],
+ "description": "Makes property with given name equal to the expression evaluation result."
},
{
"name": "releaseObject",
"parameters": [
- { "name": "objectId", "type": "string" }
- ]
+ { "name": "objectId", "type": "string", "description": "Identifier of the object to release." }
+ ],
+ "description": "Releases remote object with given id."
},
{
"name": "releaseObjectGroup",
"parameters": [
- { "name": "objectGroup", "type": "string" }
- ]
+ { "name": "objectGroup", "type": "string", "description": "Symbolic object group name." }
+ ],
+ "description": "Releases all remote objects that belong to a given group."
}
]
},
{
"domain": "Console",
- "types": [],
+ "description": "Console domain defines methods and events for interaction with the JavaScript console. One needs to enable this domain using <code>enable</code> function in order to start receiving the console messages.",
+ "types": [
+ {
+ "id": "ConsoleMessage",
+ "type": "object",
+ "description": "Console message.",
+ "properties": [
+ { "name": "source", "type": "string", "enum": ["html", "wml", "xml", "javascript", "css", "other"], "description": "Message source." },
+ { "name": "type", "type": "string", "enum": ["log", "other", "trace", "startGroup", "startGroupCollapsed", "endGroup", "assert", "uncaughtException", "networkError", "result"], "description": "Message type." },
+ { "name": "level", "type": "string", "enum": ["tip", "log", "warning", "error", "debug"], "description": "Message severity." },
+ { "name": "line", "type": "integer", "description": "JavaScript source line that created console message." },
+ { "name": "url", "type": "string", "description": "JavaScript source url that created console message." },
+ { "name": "repeatCount", "type": "integer", "optional": true, "description": "Repeat count for repeated messages." },
+ { "name": "text", "type": "string", "description": "Message text." },
+ { "name": "networkIdentifier", "type": "integer", "optional": true, "description": "Identifier of the network request associated with the console message." },
+ { "name": "parameters", "type": "array", "items": { "$ref": "Runtime.RemoteObject" }, "description": "Message parameters in case of the formatted message." },
+ { "name": "stackTrace", "type": "array", "optional": true, "items": { "$ref": "CallFrame" }, "description": "Call frames for assert and error messages." }
+ ]
+ },
+ {
+ "id": "CallFrame",
+ "type": "object",
+ "description": "Stack entry for console errors and assertions.",
+ "properties": [
+ { "name": "functionName", "type": "string", "description": "JavaScript function name." },
+ { "name": "url", "type": "string", "description": "JavaScript source name / url." },
+ { "name": "lineNumber", "type": "string", "description": "JavaScript source line number." },
+ { "name": "columnNumber", "type": "string", "description": "JavaScript source column number." }
+ ]
+ }
+ ],
"commands": [
{
"name": "enable",
"returns": [
- { "name": "expiredMessagesCount", "type": "integer" }
- ]
+ { "name": "expiredMessagesCount", "type": "integer", "description": "Number of messages cleared due to message threashold overflow." }
+ ],
+ "description": "Enables console domain, sends all the messages collected so far to the client."
},
{
- "name": "disable"
- },
+ "name": "disable",
+ "description": "Disables console domain, prevents further console messages from being sent to the client."
+ },
{
- "name": "clearConsoleMessages"
+ "name": "clearConsoleMessages",
+ "description": "Clears collected console messages."
},
{
"name": "setMonitoringXHREnabled",
"parameters": [
- { "name": "enabled", "type": "boolean" }
- ]
+ { "name": "enabled", "type": "boolean", "description": "Monitoring enabled state." }
+ ],
+ "description": "Toggles monitoring of XMLHttpRequest. If <code>true</code>, console will receive messages upon each XHR issued."
},
{
"name": "addInspectedNode",
"parameters": [
- { "name": "nodeId", "type": "integer" }
- ]
+ { "name": "nodeId", "type": "integer", "description": "DOM node id to be accessible by means of $x command line API." }
+ ],
+ "description": "Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions)."
}
],
"events": [
{
- "name": "consoleMessage",
+ "name": "messageAdded",
"parameters": [
- { "name": "messageObj", "$ref": "ConsoleMessage" }
- ]
+ { "name": "messageObj", "$ref": "ConsoleMessage", "description": "Console message that has been added." }
+ ],
+ "description": "Issued for each console message added."
},
- {
- "name": "consoleMessageRepeatCountUpdated",
+ {
+ "name": "messageRepeatCountUpdated",
"parameters": [
- { "name": "count", "type": "integer" }
- ]
+ { "name": "count", "type": "integer", "description": "New repeat count value." }
+ ],
+ "description": "In case of subsequent message being equal to the previous one, only repeat count is being updated."
},
{
- "name": "consoleMessagesCleared"
+ "name": "messagesCleared",
+ "description": "Issued when console is cleared."
}
]
},
@@ -243,89 +302,97 @@
"id": "ResourceTiming",
"type": "object",
"description": "Timing information for the request.",
- "properties": {
- "requestTime": { "type": "number", "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime." },
- "proxyStart": { "type": "number", "description": "Started resolving proxy." },
- "proxyEnd": { "type": "number", "description": "Finished resolving proxy." },
- "dnsStart": { "type": "number", "description": "Started DNS address resolve." },
- "dnsEnd": { "type": "number", "description": "Finished DNS address resolve." },
- "connectStart": { "type": "number", "description": "Started connecting to the remote host." },
- "connectEnd": { "type": "number", "description": "Connected to the remote host." },
- "sslStart": { "type": "number", "description": "Started SSL handshake." },
- "sslEnd": { "type": "number", "description": "Finished SSL handshake." },
- "sendStart": { "type": "number", "description": "Started sending request." },
- "sendEnd": { "type": "number", "description": "Finished sending request." },
- "receiveHeadersEnd": { "type": "number", "description": "Finished receiving response headers." }
- }
+ "properties": [
+ { "name": "requestTime", "type": "number", "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime." },
+ { "name": "proxyStart", "type": "number", "description": "Started resolving proxy." },
+ { "name": "proxyEnd", "type": "number", "description": "Finished resolving proxy." },
+ { "name": "dnsStart", "type": "number", "description": "Started DNS address resolve." },
+ { "name": "dnsEnd", "type": "number", "description": "Finished DNS address resolve." },
+ { "name": "connectStart", "type": "number", "description": "Started connecting to the remote host." },
+ { "name": "connectEnd", "type": "number", "description": "Connected to the remote host." },
+ { "name": "sslStart", "type": "number", "description": "Started SSL handshake." },
+ { "name": "sslEnd", "type": "number", "description": "Finished SSL handshake." },
+ { "name": "sendStart", "type": "number", "description": "Started sending request." },
+ { "name": "sendEnd", "type": "number", "description": "Finished sending request." },
+ { "name": "receiveHeadersEnd", "type": "number", "description": "Finished receiving response headers." }
+ ]
},
{
"id": "ResourceRequest",
"type": "object",
"description": "HTTP request data.",
- "properties": {
- "url": { "type": "string", "description": "Request URL." },
- "method": { "type": "string", "description": "HTTP request method." },
- "headers": { "type": "object", "description": "HTTP request headers." },
- "postData": { "type": "string", "optional": true, "description": "HTTP POST request data." }
- }
+ "properties": [
+ { "name": "url", "type": "string", "description": "Request URL." },
+ { "name": "method", "type": "string", "description": "HTTP request method." },
+ { "name": "headers", "type": "object", "description": "HTTP request headers." },
+ { "name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data." }
+ ]
},
{
"id": "ResourceResponse",
"type": "object",
"description": "HTTP response data.",
- "properties": {
- "status": { "type": "number", "description": "HTTP response status code." },
- "statusText": { "type": "string", "description": "HTTP response status text." },
- "headers": { "type": "object", "description": "HTTP response headers." },
- "mimeType": { "type": "string", "description": "Resource mimeType as determined by the browser." },
- "requestHeaders": { "type": "object", "optional": true, "description": "Refined HTTP request headers that were actually transmitted over the network." },
- "connectionReused": { "type": "boolean", "description": "Specifies whether physical connection was actually reused for this request." },
- "connectionID": { "type": "number", "description": "Physical connection id that was actually used for this request." },
- "fromDiskCache": { "type": "boolean", "optional": true, "description": "Specifies that the resource was loaded from the disk cache." },
- "timing": { "$ref": "ResourceTiming", "optional": true, "description": "Timing information for the given request." }
- }
+ "properties": [
+ { "name": "status", "type": "number", "description": "HTTP response status code." },
+ { "name": "statusText", "type": "string", "description": "HTTP response status text." },
+ { "name": "headers", "type": "object", "description": "HTTP response headers." },
+ { "name": "headersText", "type": "string", "optional": true, "description": "HTTP response headers text." },
+ { "name": "mimeType", "type": "string", "description": "Resource mimeType as determined by the browser." },
+ { "name": "requestHeaders", "type": "object", "optional": true, "description": "Refined HTTP request headers that were actually transmitted over the network." },
+ { "name": "requestHeadersText", "type": "string", "optional": true, "description": "HTTP request headers text." },
+ { "name": "connectionReused", "type": "boolean", "description": "Specifies whether physical connection was actually reused for this request." },
+ { "name": "connectionID", "type": "number", "description": "Physical connection id that was actually used for this request." },
+ { "name": "fromDiskCache", "type": "boolean", "optional": true, "description": "Specifies that the resource was loaded from the disk cache." },
+ { "name": "timing", "$ref": "ResourceTiming", "optional": true, "description": "Timing information for the given request." }
+ ]
+ },
+ {
+ "id": "ResourceType",
+ "type": "string",
+ "enum": ["Document", "Stylesheet", "Image", "Font", "Script", "XHR", "WebSocket", "Other"],
+ "description": "Resource type as it was perceived by the rendering enging."
},
{
"id": "CachedResource",
"type": "object",
"description": "Information about the cached resource.",
- "properties": {
- "url": { "type": "string", "description": "Resource URL." },
- "type": { "type": "string", "description": "Type of this resource. // FIXME" },
- "response": { "$ref": "ResourceResponse", "description": "Cached response data." },
- "bodySize": { "type": "number", "description": "Cached response body size." }
- }
+ "properties": [
+ { "name": "url", "type": "string", "description": "Resource URL." },
+ { "name": "type", "$ref": "ResourceType", "description": "Type of this resource." },
+ { "name": "response", "$ref": "ResourceResponse", "description": "Cached response data." },
+ { "name": "bodySize", "type": "number", "description": "Cached response body size." }
+ ]
},
{
"id": "Frame",
"type": "object",
"description": "Information about the Frame on the page.",
- "properties": {
- "id": { "type": "string", "description": "Frame unique identifier." },
- "parentId": { "type": "string", "description": "Parent frame identifier." },
- "loaderId": { "type": "string", "description": "Identifier of the loader associated with this frame." },
- "name": { "type": "string", "optional": true, "description": "Frame's name as specified in the tag." },
- "url": { "type": "string", "description": "Frame document's URL." }
- }
+ "properties": [
+ { "name": "id", "type": "string", "description": "Frame unique identifier." },
+ { "name": "parentId", "type": "string", "description": "Parent frame identifier." },
+ { "name": "loaderId", "type": "string", "description": "Identifier of the loader associated with this frame." },
+ { "name": "name", "type": "string", "optional": true, "description": "Frame's name as specified in the tag." },
+ { "name": "url", "type": "string", "description": "Frame document's URL." }
+ ]
},
{
"id": "FrameResourceTree",
"type": "object",
"description": "Information about the Frame hierarchy along with their cached resources.",
- "properties": {
- "frame": { "$ref": "Frame", "description": "Frame information for this tree item." },
- "childFrames": { "type": "array", "optional": true, "items": { "$ref": "FrameResourceTree" }, "description": "Child frames." },
- "resources": { "type": "array",
+ "properties": [
+ { "name": "frame", "$ref": "Frame", "description": "Frame information for this tree item." },
+ { "name": "childFrames", "type": "array", "optional": true, "items": { "$ref": "FrameResourceTree" }, "description": "Child frames." },
+ { "name": "resources", "type": "array",
"items": {
"type": "object",
- "properties": {
- "url": { "type": "string", "description": "Resource URL." },
- "type": { "type": "string", "description": "Type of this resource. // FIXME" }
- }
+ "properties": [
+ { "name": "url", "type": "string", "description": "Resource URL." },
+ { "name": "type", "$ref": "ResourceType", "description": "Type of this resource." }
+ ]
},
"description": "Information about frame resources."
}
- }
+ ]
}
],
"commands": [
@@ -366,10 +433,22 @@
],
"events": [
{
+ "name": "domContentEventFired",
+ "parameters": [
+ { "name": "time", "type": "number" }
+ ]
+ },
+ {
+ "name": "loadEventFired",
+ "parameters": [
+ { "name": "time", "type": "number" }
+ ]
+ },
+ {
"name": "frameDetached",
"description": "Fired when frame has been detached from its parent.",
"parameters": [
- { "name": "frameId", "type": "string", "description": "If of the frame that has been detached." }
+ { "name": "frameId", "type": "string", "description": "Id of the frame that has been detached." }
]
},
{
@@ -381,14 +460,14 @@
{ "name": "loaderId", "type": "string", "description": "Loader identifier." },
{ "name": "documentURL", "type": "string", "description": "URL of the document this resource is loaded for." },
{ "name": "request", "$ref": "ResourceRequest", "description": "Request data." },
- { "name": "redirectResponse", "$ref": "ResourceResponse", "description": "Redirect response data." },
- { "name": "time", "type": "number", "description": "Timestamp." },
- { "name": "callStack", "type": "array", "items": { "$ref" : "DebuggerStackFrame"}, "description": "JavaScript stack trace upon issuing this request." }
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
+ { "name": "stackTrace", "type": "array", "items": { "$ref": "Console.CallFrame"}, "description": "JavaScript stack trace upon issuing this request." },
+ { "name": "redirectResponse", "optional": true, "$ref": "ResourceResponse", "description": "Redirect response data." }
]
},
{
"name": "resourceMarkedAsCached",
- "description": "Fired when request is known to be served from memory cache.",
+ "description": "Fired when request is known to be served from disk cache.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." }
]
@@ -398,8 +477,8 @@
"description": "Fired when HTTP response is available.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." },
- { "name": "resourceType", "type": "string", "description": "Resource type. // FIXME" },
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
+ { "name": "type", "$ref": "ResourceType", "description": "Resource type." },
{ "name": "response", "$ref": "ResourceResponse", "description": "Response data." }
]
},
@@ -408,9 +487,9 @@
"description": "Fired when data chunk was received over the network.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." },
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
{ "name": "dataLength", "type": "integer", "description": "Data chunk length." },
- { "name": "lengthReceived", "type": "integer", "description": "Actual bytes received (might be less than dataLength for compressed encodings)." }
+ { "name": "encodedDataLength", "type": "integer", "description": "Actual bytes received (might be less than dataLength for compressed encodings)." }
]
},
{
@@ -418,7 +497,7 @@
"description": "Fired when HTTP request has finished loading.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "finishTime", "type": "number", "description": "Timestamp." }
+ { "name": "timestamp", "type": "number", "description": "Timestamp." }
]
},
{
@@ -426,8 +505,9 @@
"description": "Fired when HTTP request has failed to load.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." },
- { "name": "errorText", "type": "string", "description": "User friendly error message." }
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
+ { "name": "errorText", "type": "string", "description": "User friendly error message." },
+ { "name": "canceled", "type": "boolean", "optional": true, "description": "True if loading was canceled." }
]
},
{
@@ -437,7 +517,7 @@
{ "name": "frameId", "type": "string", "description": "Frame identifier." },
{ "name": "loaderId", "type": "string", "description": "Loader identifier." },
{ "name": "documentURL", "type": "string", "description": "URL of the document this resource is loaded for." },
- { "name": "time", "type": "number", "description": "Timestamp." },
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
{ "name": "resource", "$ref": "CachedResource", "description": "Cached resource data." }
]
},
@@ -447,7 +527,7 @@
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
{ "name": "content", "type": "string", "description": "Resource content." },
- { "name": "type", "type": "string", "description": "Resource type. // FIXME" }
+ { "name": "type", "$ref": "ResourceType", "description": "Resource type." }
]
},
{
@@ -463,7 +543,7 @@
"description": "Fired when WebSocket is about to initiate handshake.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." },
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
{ "name": "request", "type": "object", "description": "WebSocket request data." }
]
},
@@ -472,7 +552,7 @@
"description": "Fired when WebSocket handshake response becomes available.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." },
+ { "name": "timestamp", "type": "number", "description": "Timestamp." },
{ "name": "response", "type": "object", "description": "WebSocket response data." }
]
},
@@ -489,7 +569,7 @@
"description": "Fired when WebSocket is closed.",
"parameters": [
{ "name": "identifier", "type": "integer", "description": "Request identifier." },
- { "name": "time", "type": "number", "description": "Timestamp." }
+ { "name": "timestamp", "type": "number", "description": "Timestamp." }
]
}
]
@@ -499,6 +579,14 @@
"types": [],
"commands": [
{
+ "name": "enable",
+ "description": "Enables database tracking, database events will now be delivered to the client."
+ },
+ {
+ "name": "disable",
+ "description": "Disables database tracking, prevents database events from being sent to the client."
+ },
+ {
"name": "getDatabaseTableNames",
"parameters": [
{ "name": "databaseId", "type": "integer" }
@@ -553,7 +641,7 @@
{ "name": "storageId", "type": "integer" }
],
"returns": [
- { "name": "entries", "type": "array", "items": { "$ref" : "DOMStorageEntry"} }
+ { "name": "entries", "type": "array", "items": { "$ref": "DOMStorageEntry"} }
]
},
{
@@ -626,36 +714,36 @@
{
"id": "DOMNode",
"type": "object",
- "properties": {
- "id": { "type": "integer", "description": "Node identifier that is passed into the rest of the DOM messages as the <code>nodeId</code>. Backend will only push node with given <code>id</code> once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client." },
- "nodeType": { "type": "integer", "description": "<code>Node</code>'s nodeType." },
- "nodeName": { "type": "string", "description": "<code>Node</code>'s nodeName." },
- "localName": { "type": "string", "description": "<code>Node</code>'s localName." },
- "nodeValue": { "type": "string", "description": "<code>Node</code>'s nodeValue." },
- "childNodeCount": { "type": "integer", "optional": true, "description": "Child count for <code>Container</code> nodes." },
- "children": { "type": "array", "optional": true, "items": { "$ref" : "DOMNode" }, "description": "Child nodes of this node when requested with children." },
- "attributes": { "type": "array", "optional": true, "items": { "type" : "string" }, "description": "Attributes of the <code>Element</code> node in the form of flat array <code>[name1, value1, name2, value2]</code>." },
- "documentURL": { "type": "string", "optional": true, "description": "Document URL that <code>Document</code> or <code>FrameOwner</code> node points to." },
- "publicId": { "type": "string", "optional": true, "description": "<code>DocumentType</code>'s publicId. // FIXME" },
- "systemId": { "type": "string", "optional": true, "description": "<code>DocumentType</code>'s systemId. // FIXME" },
- "internalSubset": { "type": "string", "optional": true, "description": "<code>DocumentType</code>'s internalSubset. // FIXME" },
- "name": { "type": "string", "optional": true, "description": "<code>Attr</code>'s name. // FIXME" },
- "value": { "type": "string", "optional": true, "description": "<code>Attr</code>'s value. // FIXME" }
- },
+ "properties": [
+ { "name": "id", "type": "integer", "description": "Node identifier that is passed into the rest of the DOM messages as the <code>nodeId</code>. Backend will only push node with given <code>id</code> once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client." },
+ { "name": "nodeType", "type": "integer", "description": "<code>Node</code>'s nodeType." },
+ { "name": "nodeName", "type": "string", "description": "<code>Node</code>'s nodeName." },
+ { "name": "localName", "type": "string", "description": "<code>Node</code>'s localName." },
+ { "name": "nodeValue", "type": "string", "description": "<code>Node</code>'s nodeValue." },
+ { "name": "childNodeCount", "type": "integer", "optional": true, "description": "Child count for <code>Container</code> nodes." },
+ { "name": "children", "type": "array", "optional": true, "items": { "$ref": "DOMNode" }, "description": "Child nodes of this node when requested with children." },
+ { "name": "attributes", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Attributes of the <code>Element</code> node in the form of flat array <code>[name1, value1, name2, value2]</code>." },
+ { "name": "documentURL", "type": "string", "optional": true, "description": "Document URL that <code>Document</code> or <code>FrameOwner</code> node points to." },
+ { "name": "publicId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s publicId. // FIXME" },
+ { "name": "systemId", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s systemId. // FIXME" },
+ { "name": "internalSubset", "type": "string", "optional": true, "description": "<code>DocumentType</code>'s internalSubset. // FIXME" },
+ { "name": "name", "type": "string", "optional": true, "description": "<code>Attr</code>'s name. // FIXME" },
+ { "name": "value", "type": "string", "optional": true, "description": "<code>Attr</code>'s value. // FIXME" }
+ ],
"description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type."
},
{
"id": "DOMEventListener",
"type": "object",
- "properties": {
- "type": { "type": "string", "description": "<code>EventListener</code>'s type." },
- "useCapture": { "type": "boolean", "description": "<code>EventListener</code>'s useCapture." },
- "isAttribute": { "type": "boolean", "description": "<code>EventListener</code>'s isAttribute." },
- "nodeId": { "type": "integer", "description": "Target <code>DOMNode</code> id." },
- "listenerBody": { "type": "string", "description": "Listener function body." },
- "sourceName": { "type": "string", "optional" : true, "description": "Handler location source name." },
- "lineNumber": { "type": "number", "optional" : true, "description": "Handler location line number." }
- },
+ "properties": [
+ { "name": "type", "type": "string", "description": "<code>EventListener</code>'s type." },
+ { "name": "useCapture", "type": "boolean", "description": "<code>EventListener</code>'s useCapture." },
+ { "name": "isAttribute", "type": "boolean", "description": "<code>EventListener</code>'s isAttribute." },
+ { "name": "nodeId", "type": "integer", "description": "Target <code>DOMNode</code> id." },
+ { "name": "listenerBody", "type": "string", "description": "Listener function body." },
+ { "name": "sourceName", "type": "string", "optional": true, "description": "Handler location source name." },
+ { "name": "lineNumber", "type": "number", "optional": true, "description": "Handler location line number." }
+ ],
"description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type."
}
],
@@ -678,11 +766,10 @@
"name": "querySelector",
"parameters": [
{ "name": "nodeId", "type": "integer", "description": "Id of the node to query upon." },
- { "name": "selectors", "type": "string", "description": "Selector string." },
- { "name": "documentWide", "type": "boolean", "description": "Set to true to start querying from the node's document." }
+ { "name": "selectors", "type": "string", "description": "Selector string." }
],
"returns": [
- { "name": "elementId", "type": "integer", "description": "Query selector result." }
+ { "name": "nodeId", "type": "integer", "description": "Query selector result." }
],
"description": "Executes <code>querySelector</code> on a given node. Setting <code>documentWide</code> to true starts selecting from the document node."
},
@@ -690,18 +777,17 @@
"name": "querySelectorAll",
"parameters": [
{ "name": "nodeId", "type": "integer", "description": "Id of the node to query upon." },
- { "name": "selectors", "type": "string", "description": "Selector string." },
- { "name": "documentWide", "type": "boolean", "description": "Set to true to start querying from the node's document." }
+ { "name": "selectors", "type": "string", "description": "Selector string." }
],
"returns": [
- { "name": "nodeIds", "type": "array", "items": { "type": "integer" }, "description": "Query selector result." }
+ { "name": "nodeIds", "type": "array", "items": { "type": "integer" }, "description": "Query selector result." }
],
"description": "Executes <code>querySelectorAll</code> on a given node. Setting <code>documentWide</code> to true starts selecting from the document node."
},
{
"name": "setNodeName",
"parameters": [
- { "name": "nodeId", "type": "integer", "description": "Id of the node to set name for." },
+ { "name": "nodeId", "type": "integer", "description": "Id of the node to set name for." },
{ "name": "name", "type": "string", "description": "New node's name." }
],
"returns": [
@@ -727,7 +813,7 @@
{
"name": "setAttribute",
"parameters": [
- { "name": "elementId", "type": "integer", "description": "Id of the element to set attribute for." },
+ { "name": "nodeId", "type": "integer", "description": "Id of the element to set attribute for." },
{ "name": "name", "type": "string", "description": "Attribute name." },
{ "name": "value", "type": "string", "description": "Attribute value." }
],
@@ -736,7 +822,7 @@
{
"name": "removeAttribute",
"parameters": [
- { "name": "elementId", "type": "integer", "description": "Id of the element to remove attribute from." },
+ { "name": "nodeId", "type": "integer", "description": "Id of the element to remove attribute from." },
{ "name": "name", "type": "string", "description": "Name of the attribute to remove." }
],
"description": "Removes attribute with given name from an element with given id."
@@ -747,7 +833,7 @@
{ "name": "nodeId", "type": "integer", "description": "Id of the node to get listeners for." }
],
"returns": [
- { "name": "listenersArray", "type": "array", "items": { "$ref" : "DOMEventListener"}, "description": "Array of relevant listeners." }
+ { "name": "listeners", "type": "array", "items": { "$ref": "DOMEventListener"}, "description": "Array of relevant listeners." }
],
"description": "Returns event listeners relevant to the node."
},
@@ -775,7 +861,7 @@
{ "name": "outerHTML", "type": "string", "description": "Outer HTML markup to set." }
],
"returns": [
- { "name": "outNodeId", "type": "integer", "description": "Setting outer HTML can change node's id." }
+ { "name": "newNodeId", "type": "integer", "description": "Setting outer HTML can change node's id." }
],
"description": "Sets node HTML markup, returns new node id."
},
@@ -783,7 +869,7 @@
"name": "performSearch",
"parameters": [
{ "name": "query", "type": "string", "description": "Plain text or query selector or XPath search query." },
- { "name": "runSynchronously", "type": "boolean", "description": "When set to true, performing search synchronously (can block user interaction)." }
+ { "name": "runSynchronously", "type": "boolean", "optional": true, "description": "When set to true, performing search synchronously (can block user interaction)." }
],
"description": "Starts asynchronous search for a given string in the DOM tree. Use <code>cancelSearch</code> to stop given asynchronous search task."
},
@@ -805,9 +891,6 @@
"name": "setSearchingForNode",
"parameters": [
{ "name": "enabled", "type": "boolean" }
- ],
- "returns": [
- { "name": "newState", "type": "boolean" }
]
},
{
@@ -828,7 +911,6 @@
{
"name": "hideFrameHighlight"
},
-
{
"name": "pushNodeByPathToFrontend",
"parameters": [
@@ -845,7 +927,7 @@
{ "name": "nodeId", "type": "integer", "description": "Id of the node to resolve." }
],
"returns": [
- { "name": "object", "$ref": "Object", "description": "JavaScript object wrapper for given node." }
+ { "name": "object", "$ref": "Runtime.RemoteObject", "description": "JavaScript object wrapper for given node." }
],
"description": "Resolves JavaScript node object for given node id."
}
@@ -859,7 +941,7 @@
"name": "setChildNodes",
"parameters": [
{ "name": "parentId", "type": "integer", "description": "Parent node id to populate with children." },
- { "name": "nodes", "type": "array", "items": { "$ref" : "DOMNode"}, "description": "Child nodes array." }
+ { "name": "nodes", "type": "array", "items": { "$ref": "DOMNode"}, "description": "Child nodes array." }
],
"description": "Fired when backend wants to provide client with the missing DOM structure. This happens upon most of the calls requesting node ids."
},
@@ -867,7 +949,7 @@
"name": "attributesUpdated",
"parameters": [
{ "name": "id", "type": "integer", "description": "Id of the node that has changed." },
- { "name": "attributes", "type": "array", "items": { "$ref" : "DOMAttribute"}, "description": "New attributes value." }
+ { "name": "attributes", "type": "array", "items": { "$ref": "DOMAttribute"}, "description": "New attributes value." }
],
"description": "Fired when <code>Element</code>'s attributes are updated."
},
@@ -915,7 +997,140 @@
},
{
"domain": "CSS",
- "types": [],
+ "description": "This domain exposes CSS read/write operations. All CSS objects, like stylesheets, rules, and styles, have an associated <code>id</code> used in subsequent operations on the related object. Each object type has a specific <code>id</code> structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the <code>get*ForNode()</code> calls (which accept a DOM node id). Alternatively, a client can discover all the existing stylesheets with the <code>getAllStyleSheets()</code> method and subsequently load the required stylesheet contents using the <code>getStyleSheet[Text]()</code> methods.",
+ "types": [
+ {
+ "id": "CSSStyleId",
+ "type": "object",
+ "properties": [
+ { "name": "styleSheetId", "type": "string", "description": "Enclosing stylesheet identifier." },
+ { "name": "ordinal", "type": "integer", "description": "The style ordinal within the stylesheet." }
+ ],
+ "description": "This object identifies a CSS style in a unique way."
+ },
+ {
+ "id": "CSSRuleId",
+ "type": "object",
+ "properties": [
+ { "name": "styleSheetId", "type": "string", "description": "Enclosing stylesheet identifier." },
+ { "name": "ordinal", "type": "integer", "description": "The rule ordinal within the stylesheet." }
+ ],
+ "description": "This object identifies a CSS rule in a unique way."
+ },
+ {
+ "id": "CSSNodeStyles",
+ "type": "object",
+ "properties": [
+ { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "The node's inline style, if any." },
+ { "name": "computedStyle", "$ref": "CSSComputedStyle", "description": "The node's computed style." },
+ { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "CSS rules matching this node, from all applicable stylesheets." },
+ { "name": "styleAttributes", "type": "array", "items": { "$ref": "CSSStyleAttribute" }, "description": "Entries for style-related element attributes (e.g. width=20)."},
+ { "name": "pseudoElements", "type": "array", "items": { "$ref": "PseudoIdRules" }, "description": "Pseudo style rules for this node." },
+ { "name": "inherited", "type": "array", "items": { "$ref": "InheritedStyleEntry" }, "description": "A chain of inherited styles (from the immediate node parent up to the DOM tree root)." }
+ ],
+ "description": "A holder for all CSS styles applicable to a particular DOM node."
+ },
+ {
+ "id": "PseudoIdRules",
+ "type": "object",
+ "properties": [
+ { "name": "pseudoId", "type": "integer", "description": "Pseudo style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."},
+ { "name": "rules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "CSS rules applicable to the pseudo style."}
+ ],
+ "description": "CSS rule collection for a single pseudo style."
+ },
+ {
+ "id": "InheritedStyleEntry",
+ "type": "object",
+ "properties": [
+ { "name": "inlineStyle", "$ref": "CSSStyle", "optional": true, "description": "The ancestor node's inline style, if any, in the style inheritance chain." },
+ { "name": "matchedCSSRules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "CSS rules matching the ancestor node in the style inheritance chain." }
+ ],
+ "description": "CSS rule collection for a single pseudo style."
+ },
+ {
+ "id": "CSSStyleAttribute",
+ "type": "object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "DOM attribute name (e.g. \"width\")."},
+ { "name": "style", "$ref": "CSSStyle", "description": "CSS style generated by the respective DOM attribute."}
+ ],
+ "description": "CSS style information for a DOM style attribute."
+ },
+ {
+ "id": "CSSStyleSheetHeader",
+ "type": "object",
+ "properties": [
+ { "name": "styleSheetId", "type": "string", "description": "The stylesheet identifier."},
+ { "name": "sourceURL", "type": "string", "description": "Stylesheet resource URL."},
+ { "name": "title", "type": "string", "description": "Stylesheet title."},
+ { "name": "disabled", "type": "boolean", "description": "Denotes whether the stylesheet is disabled."}
+ ],
+ "description": "CSS stylesheet metainformation."
+ },
+ {
+ "id": "CSSStyleSheetBody",
+ "type": "object",
+ "properties": [
+ { "name": "styleSheetId", "type": "string", "description": "The stylesheet identifier."},
+ { "name": "rules", "type": "array", "items": { "$ref": "CSSRule" }, "description": "Stylesheet resource URL."},
+ { "name": "text", "type": "string", "optional": true, "description": "Stylesheet resource contents (if available)."}
+ ],
+ "description": "CSS stylesheet contents."
+ },
+ {
+ "id": "CSSRule",
+ "type": "object",
+ "properties": [
+ { "name": "ruleId", "$ref": "CSSRuleId", "description": "The CSS rule identifier."},
+ { "name": "selectorText", "type": "string", "description": "Rule selector."},
+ { "name": "sourceURL", "type": "string", "optional": true, "description": "Parent stylesheet resource URL (for regular rules)."},
+ { "name": "sourceLine", "type": "integer", "description": "Line ordinal of the rule selector start character in the resource."},
+ { "name": "origin", "type": "string", "enum": ["user", "user-agent", "inspector", ""], "description": "The parent stylesheet type: \"user\" for user stylesheets, \"user-agent\" for user-agent stylesheets, \"inspector\" for stylesheets created by the inspector (i.e. those holding new rules created with <code>addRule()</code>), \"\" for regular stylesheets."},
+ { "name": "style", "$ref": "CSSStyle", "description": "Associated style declaration." },
+ { "name": "selectorRange", "$ref": "SourceRange", "optional": true, "description": "The rule selector range in the underlying resource (if available)." }
+ ],
+ "description": "CSS rule representation."
+ },
+ {
+ "id": "SourceRange",
+ "type": "object",
+ "properties": [
+ { "name": "start", "type": "integer", "description": "Start of range (inclusive)."},
+ { "name": "end", "type": "integer", "description": "End of range (exclusive)."}
+ ],
+ "description": "Text range within a resource."
+ },
+ {
+ "id": "CSSStyle",
+ "type": "object",
+ "properties": [
+ { "name": "styleId", "$ref": "CSSStyleId", "description": "The CSS style identifier."},
+ { "name": "cssProperties", "type": "array", "items": { "$ref": "CSSProperty" }, "description": "CSS properties in the style."},
+ { "name": "shorthandEntries", "type": "array", "items": { "$ref": "ShorthandEntry" }, "description": "Computed values for all shorthands found in the style." },
+ { "name": "cssText", "type": "string", "optional": true, "description": "Style declaration text (if available)."},
+ { "name": "range", "$ref": "SourceRange", "optional": true, "description": "Style declaration range in the enclosing stylesheet (if available)." },
+ { "name": "width", "type": "integer", "description": "The effective \"width\" property value from this style." },
+ { "name": "height", "type": "integer", "description": "The effective \"height\" property value from this style." }
+ ],
+ "description": "CSS style representation."
+ },
+ {
+ "id": "CSSProperty",
+ "type": "object",
+ "properties": [
+ { "name": "name", "type": "string", "description": "The property name." },
+ { "name": "value", "type": "string", "description": "The property value." },
+ { "name": "priority", "type": "string", "optional": true, "description": "The property priority (implies \"\" if absent)." },
+ { "name": "implicit", "type": "boolean", "optional": true, "description": "Whether the property is implicit (implies <code>false</code> if absent)." },
+ { "name": "parsedOk", "type": "boolean", "optional": true, "description": "Whether the property is understood by the browser (implies <code>true</code> if absent)." },
+ { "name": "status", "type": "string", "enum": ["active", "inactive", "disabled", "style"], "optional": true, "description": "The property status: \"active\" (implied if absent) if the property is effective in the style, \"inactive\" if the property is overridden by a same-named property in this style later on, \"disabled\" if the property is disabled by the user, \"style\" if the property is reported by the browser rather than by the CSS source parser." },
+ { "name": "shorthandName", "type": "string", "description": "The related shorthand property name (absent if this property is not a longhand)." },
+ { "name": "range", "$ref": "SourceRange", "optional": true, "description": "The entire property range in the enclosing style declaration (if available)." }
+ ],
+ "description": "CSS style effective visual dimensions and source offsets."
+ }
+ ],
"commands": [
{
"name": "getStylesForNode",
@@ -923,8 +1138,9 @@
{ "name": "nodeId", "type": "integer" }
],
"returns": [
- { "name": "styles", "$ref": "CSSNodeStyles" }
- ]
+ { "name": "styles", "$ref": "CSSNodeStyles", "description": "All styles for the specified DOM node." }
+ ],
+ "description": "Returns all styles for a DOM node identified by <code>nodeId</code>."
},
{
"name": "getComputedStyleForNode",
@@ -932,8 +1148,9 @@
{ "name": "nodeId", "type": "integer" }
],
"returns": [
- { "name": "style", "$ref": "CSSComputedStyle" }
- ]
+ { "name": "style", "$ref": "CSSStyle", "description": "Computed style for the specified DOM node." }
+ ],
+ "description": "Returns the computed style for a DOM node identified by <code>nodeId</code>."
},
{
"name": "getInlineStyleForNode",
@@ -941,14 +1158,16 @@
{ "name": "nodeId", "type": "integer" }
],
"returns": [
- { "name": "style", "$ref": "CSSStyle" }
- ]
+ { "name": "style", "$ref": "CSSStyle", "description": "Inline style for the specified DOM node." }
+ ],
+ "description": "Returns the inline style (if present) for a DOM node identified by <code>nodeId</code>."
},
{
"name": "getAllStyleSheets",
"returns": [
- { "name": "styleSheetInfos", "type": "array", "items": { "$ref": "CSSStyleSheetInfo" } }
- ]
+ { "name": "headers", "type": "array", "items": { "$ref": "CSSStyleSheetHeader" }, "description": "Descriptor entries for all available stylesheets." }
+ ],
+ "description": "Returns metainfo entries for all known stylesheets."
},
{
"name": "getStyleSheet",
@@ -956,8 +1175,9 @@
{ "name": "styleSheetId", "type": "string" }
],
"returns": [
- { "name": "styleSheet", "$ref": "CSSStyleSheet" }
- ]
+ { "name": "styleSheet", "$ref": "CSSStyleSheetBody", "description": "Stylesheet contents for the specified <code>styleSheetId</code>." }
+ ],
+ "description": "Returns stylesheet data for the specified <code>styleSheetId</code>."
},
{
"name": "getStyleSheetText",
@@ -965,9 +1185,9 @@
{ "name": "styleSheetId", "type": "string" }
],
"returns": [
- { "name": "url", "type": "string" },
- { "name": "text", "type": "string" }
- ]
+ { "name": "text", "type": "string", "description": "The stylesheet text." }
+ ],
+ "description": "Returns the current textual content and the URL for a stylesheet."
},
{
"name": "setStyleSheetText",
@@ -975,9 +1195,7 @@
{ "name": "styleSheetId", "type": "string" },
{ "name": "text", "type": "string" }
],
- "returns": [
- { "name": "success", "type": "boolean" }
- ]
+ "description": "Sets the new stylesheet text, thereby invalidating all existing <code>CSSStyleId</code>'s and <code>CSSRuleId</code>'s contained by this stylesheet."
},
{
"name": "setPropertyText",
@@ -988,8 +1206,9 @@
{ "name": "overwrite", "type": "boolean" }
],
"returns": [
- { "name": "style", "$ref": "CSSStyle" }
- ]
+ { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the property text modification." }
+ ],
+ "description": "Sets the new <code>text</code> for a property in the respective style, at offset <code>propertyIndex</code>. If <code>overwrite</code> is <code>true</code>, a property at the given offset is overwritten, otherwise inserted. <code>text</code> entirely replaces the property <code>name: value</code>."
},
{
"name": "toggleProperty",
@@ -999,8 +1218,9 @@
{ "name": "disable", "type": "boolean" }
],
"returns": [
- { "name": "style", "$ref": "CSSStyle" }
- ]
+ { "name": "style", "$ref": "CSSStyle", "description": "The resulting style after the property toggling." }
+ ],
+ "description": "Toggles the property in the respective style, at offset <code>propertyIndex</code>. The <code>disable</code> parameter denotes whether the property should be disabled (i.e. removed from the style declaration). If <code>disable == false</code>, the property gets put back into its original place in the style declaration."
},
{
"name": "setRuleSelector",
@@ -1009,8 +1229,9 @@
{ "name": "selector", "type": "string" }
],
"returns": [
- { "name": "rule", "$ref": "CSSRule" }
- ]
+ { "name": "rule", "$ref": "CSSRule", "description": "The resulting rule after the selector modification." }
+ ],
+ "description": "Modifies the rule selector."
},
{
"name": "addRule",
@@ -1019,14 +1240,16 @@
{ "name": "selector", "type": "string" }
],
"returns": [
- { "name": "rule", "$ref": "CSSRule" }
- ]
+ { "name": "rule", "$ref": "CSSRule", "description": "The newly created rule." }
+ ],
+ "description": "Creates a new empty rule with the given <code>selector</code> in a special \"inspector\" stylesheet in the owner document of the context node."
},
{
"name": "getSupportedCSSProperties",
"returns": [
- { "name": "cssProperties", "type": "array", "items": { "type": "string" } }
- ]
+ { "name": "cssProperties", "type": "array", "items": { "type": "string" }, "description": "Supported property names." }
+ ],
+ "description": "Returns all supported CSS property names."
}
]
},
@@ -1037,11 +1260,11 @@
{
"id": "TimelineRecord",
"type": "object",
- "properties": {
- "type": { "type": "string", "description": "Event type." },
- "data": { "type": "object", "description": "Event data." },
- "children": { "type": "array", "optional" : true, "items": { "$ref": "TimelineRecord" }, "description": "Nested records." }
- },
+ "properties": [
+ { "name": "type", "type": "string", "description": "Event type." },
+ { "name": "data", "type": "object", "description": "Event data." },
+ { "name": "children", "type": "array", "optional": true, "items": { "$ref": "TimelineRecord" }, "description": "Nested records." }
+ ],
"description": "Timeline record contains information about the recorded activity."
}
],
@@ -1080,25 +1303,32 @@
{
"id": "Location",
"type": "object",
- "properties": {
- "sourceID": { "type": "string", "description": "Script identifier as reported by the <code>scriptParsed</code>" },
- "lineNumber": { "type": "integer", "description": "Line number in the script." },
- "columnNumber": { "type": "integer", "description": "Column number in the script." }
- },
+ "properties": [
+ { "name": "sourceID", "type": "string", "description": "Script identifier as reported by the <code>scriptParsed</code>" },
+ { "name": "lineNumber", "type": "integer", "description": "Line number in the script." },
+ { "name": "columnNumber", "type": "integer", "optional": true, "description": "Column number in the script." }
+ ],
"description": "Location in the source code."
},
{
"id": "CallFrame",
"type": "object",
- "properties": {
- "id": { "type": "string", "description": "Call frame identifier" },
- "type": { "type": "string", "description": "Call frame type. // FIXME" },
- "functionName": { "type": "string", "description": "Name of the function called on this frame." },
- "sourceID": { "type": "string", "description": "Script identifier." },
- "line": { "type": "integer", "description": "Line number in the script." },
- "column": { "type": "integer", "description": "Column number in the script." },
- "scopeChain": { "type": "array", "items": { "type": "object" }, "description": "Scope chain for given call frame. // FIXME" }
- },
+ "properties": [
+ { "name": "id", "type": "string", "description": "Call frame identifier." },
+ { "name": "functionName", "type": "string", "description": "Name of the function called on this frame." },
+ { "name": "location", "$ref": "Location", "description": "Location in the source code." },
+ { "name": "scopeChain", "type": "array", "items": { "$ref": "Scope" }, "description": "Scope chain for given call frame." }
+ ],
+ "description": "Debugger call frame. Array of call frames form call stack."
+ },
+ {
+ "id": "Scope",
+ "type": "object",
+ "properties": [
+ { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch"], "description": "Scope type." },
+ { "name": "object", "$ref": "Runtime.RemoteObject", "description": "Object representing the scope." },
+ { "name": "this", "$ref": "Runtime.RemoteObject", "optional": true, "description": "<code>this</code> object for local scope." }
+ ],
"description": "Debugger call frame. Array of call frames form call stack."
}
],
@@ -1124,28 +1354,23 @@
{ "name": "url", "type": "string", "description": "URL of the resource to set breakpoint on." },
{ "name": "lineNumber", "type": "integer", "description": "Line number to set breakpoint at." },
{ "name": "columnNumber", "type": "integer", "optional": true, "description": "Offset in the line to set breakpoint at." },
- { "name": "condition", "type": "string", "optional": true, "description": "Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true." },
- { "name": "enabled", "type": "boolean", "optional": true, "description": "Determines initial state for the breakpoint." }
+ { "name": "condition", "type": "string", "optional": true, "description": "Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true." }
],
"returns": [
{ "name": "breakpointId", "type": "string", "description": "Id of the created breakpoint for further manipulations." },
- { "name": "locations", "type": "array", "items": { "$ref" : "Location"}, "description": "List of the locations this breakpoint resolved into." }
+ { "name": "locations", "optional": true, "type": "array", "items": { "$ref": "Location"}, "description": "List of the locations this breakpoint resolved into." }
],
"description": "Sets JavaScript breakpoint at a given location specified by URL. This breakpoint will survive page reload."
},
{
"name": "setBreakpoint",
"parameters": [
- { "name": "sourceId", "type": "string", "description": "Source ID of the resource to set breakpoint on (as reported by <code>scriptParsed</code>)." },
- { "name": "lineNumber", "type": "integer", "description": "Line number to set breakpoint at." },
- { "name": "columnNumber", "type": "integer", "optional": true, "description": "Offset in the line to set breakpoint at." },
- { "name": "condition", "type": "string", "optional": true, "description": "Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true." },
- { "name": "enabled", "type": "boolean", "optional": true, "description": "Determines initial state for the breakpoint." }
+ { "name": "location", "$ref": "Location", "description": "Location to set breakpoint in." },
+ { "name": "condition", "type": "string", "optional": true, "description": "Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true." }
],
"returns": [
{ "name": "breakpointId", "type": "string", "description": "Id of the created breakpoint for further manipulations." },
- { "name": "actualLineNumber", "type": "integer", "description": "Line number in the script." },
- { "name": "actualColumnNumber", "type": "integer", "description": "Column number in the script." }
+ { "name": "actualLocation", "$ref": "Location", "description": "Location this breakpoint resolved into." }
],
"description": "Sets JavaScript breakpoint at a given location."
},
@@ -1159,9 +1384,7 @@
{
"name": "continueToLocation",
"parameters": [
- { "name": "sourceId", "type": "string", "description": "Source ID of the resource to continue to (as reported by <code>scriptParsed</code>)." },
- { "name": "lineNumber", "type": "integer", "description": "Line number to stop at." },
- { "name": "columnNumber", "type": "integer", "description": "Column number to stop at." }
+ { "name": "location", "$ref": "Location", "description": "Location to continue to." }
],
"description": "Continues execution until specific location is reached."
},
@@ -1189,11 +1412,10 @@
"name": "editScriptSource",
"parameters": [
{ "name": "sourceID", "type": "string", "description": "Id of the script to edit." },
- { "name": "newContent", "type": "string", "description": "New content of the script." }
+ { "name": "scriptSource", "type": "string", "description": "New content of the script." }
],
"returns": [
- { "name": "result", "type": "string", "description": "New content of the script." },
- { "name": "stackFrames", "type": "array", "items": { "$ref" : "CallFrame"}, "description": "New stack trace in case editing has happened while VM was stopped." }
+ { "name": "callFrames", "type": "array", "optional": true, "items": { "$ref": "CallFrame"}, "description": "New stack trace in case editing has happened while VM was stopped." }
],
"description": "Edits JavaScript script live."
},
@@ -1208,9 +1430,9 @@
"description": "Returns source for the script with given ID."
},
{
- "name": "setPauseOnExceptionsState",
+ "name": "setPauseOnExceptions",
"parameters": [
- { "name": "pauseOnExceptionsState", "type": "integer", "description": "Pause on exceptions mode. // FIXME, make enumerable." }
+ { "name": "state", "type": "string", "enum": ["none", "uncaught", "all"], "description": "Pause on exceptions mode." }
],
"description": "Defines pause on exceptions state. Can be set to stop on all exceptions, uncaught exceptions or no exceptions."
},
@@ -1219,11 +1441,11 @@
"parameters": [
{ "name": "callFrameId", "type": "string", "description": "Call frame identifier to evaluate on. This identifier is a part of backtrace reported by the <code>pausedScript</code>." },
{ "name": "expression", "type": "string", "description": "Expression to evaluate." },
- { "name": "objectGroup", "type": "string", "description": "String object group name to put result into (allows rapid releasing resulting object handles using <code>releaseObjectGroup</code>)." },
+ { "name": "objectGroup", "type": "string", "optional": true, "description": "String object group name to put result into (allows rapid releasing resulting object handles using <code>releaseObjectGroup</code>)." },
{ "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Specifies whether command line API should be available to the evaluated expression, defaults to false." }
],
"returns": [
- { "name": "result", "$ref": "Object", "description": "Object wrapper for the evaluation result." }
+ { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Object wrapper for the evaluation result." }
],
"description": "Evaluates expression on a given call frame."
}
@@ -1231,11 +1453,11 @@
"events": [
{
"name": "debuggerWasEnabled",
- "description": "Fired when debugger gets enabled."
+ "description": "Fired when debugger gets enabled (deprecated)."
},
{
"name": "debuggerWasDisabled",
- "description": "Fired when debugger gets disabled."
+ "description": "Fired when debugger gets disabled (deprecated)."
},
{
"name": "scriptParsed",
@@ -1245,7 +1467,7 @@
{ "name": "lineOffset", "type": "integer", "description": "Line offset of the script within the resource with given URL (for script tags)." },
{ "name": "columnOffset", "type": "integer", "description": "Column offset of the script within the resource with given URL." },
{ "name": "length", "type": "integer", "description": "Length of the script" },
- { "name": "scriptWorldType", "type": "integer", "description": "Script type. // FIXME." }
+ { "name": "isContentScript", "type": "boolean", "optional": true, "description": "Determines whether this script is a user extension script." }
],
"description": "Fired when virtual machine parses script. This even is also fired for all known scripts upon enabling debugger."
},
@@ -1264,9 +1486,7 @@
"name": "breakpointResolved",
"parameters": [
{ "name": "breakpointId", "type": "string", "description": "Breakpoint unique identifier." },
- { "name": "sourceId", "type": "string", "description": "Identifier of the script breakpoint is set in." },
- { "name": "lineNumber", "type": "integer", "description": "Line number of the statement breakpoint is set on." },
- { "name": "columnNumber", "type": "integer", "description": "Column offset of the statement breakpoint is set on." }
+ { "name": "location", "$ref": "Location", "description": "Actual breakpoint location." }
],
"description": "Fired when breakpoint is resolved to an actual script and location."
},
@@ -1276,9 +1496,9 @@
{
"name": "details",
"type": "object",
- "properties": {
- "callFrames": { "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }
- },
+ "properties": [
+ { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }
+ ],
"description": "Call stack information."
}
],
@@ -1365,7 +1585,7 @@
{
"name": "getProfileHeaders",
"returns": [
- { "name": "headers", "type": "array", "items": { "$ref" : "ProfileHeader"} }
+ { "name": "headers", "type": "array", "items": { "$ref": "ProfileHeader"} }
]
},
{
diff --git a/Source/WebCore/inspector/InspectorAgent.cpp b/Source/WebCore/inspector/InspectorAgent.cpp
index beac507..0cfc5d2 100644
--- a/Source/WebCore/inspector/InspectorAgent.cpp
+++ b/Source/WebCore/inspector/InspectorAgent.cpp
@@ -89,6 +89,22 @@ static const char scriptsPanelName[] = "scripts";
static const char consolePanelName[] = "console";
static const char profilesPanelName[] = "profiles";
+namespace {
+
+class PageRuntimeAgent : public InspectorRuntimeAgent {
+public:
+ PageRuntimeAgent(InjectedScriptManager* injectedScriptManager, Page* page)
+ : InspectorRuntimeAgent(injectedScriptManager)
+ , m_inspectedPage(page) { }
+ virtual ~PageRuntimeAgent() { }
+
+private:
+ virtual ScriptState* getDefaultInspectedState() { return mainWorldScriptState(m_inspectedPage->mainFrame()); }
+ Page* m_inspectedPage;
+};
+
+}
+
InspectorAgent::InspectorAgent(Page* page, InspectorClient* client, InjectedScriptManager* injectedScriptManager)
: m_inspectedPage(page)
, m_client(client)
@@ -100,7 +116,7 @@ InspectorAgent::InspectorAgent(Page* page, InspectorClient* client, InjectedScri
, m_domAgent(InspectorDOMAgent::create(m_instrumentingAgents.get(), page, m_client, m_state.get(), injectedScriptManager))
, m_cssAgent(new InspectorCSSAgent(m_instrumentingAgents.get(), m_domAgent.get()))
#if ENABLE(DATABASE)
- , m_databaseAgent(InspectorDatabaseAgent::create(m_instrumentingAgents.get()))
+ , m_databaseAgent(InspectorDatabaseAgent::create(m_instrumentingAgents.get(), m_state.get()))
#endif
#if ENABLE(DOM_STORAGE)
, m_domStorageAgent(InspectorDOMStorageAgent::create(m_instrumentingAgents.get()))
@@ -110,6 +126,7 @@ InspectorAgent::InspectorAgent(Page* page, InspectorClient* client, InjectedScri
, m_applicationCacheAgent(new InspectorApplicationCacheAgent(m_instrumentingAgents.get(), page))
#endif
, m_resourceAgent(InspectorResourceAgent::create(m_instrumentingAgents.get(), page, m_state.get()))
+ , m_runtimeAgent(adoptPtr(new PageRuntimeAgent(m_injectedScriptManager, page)))
, m_consoleAgent(new InspectorConsoleAgent(m_instrumentingAgents.get(), this, m_state.get(), injectedScriptManager, m_domAgent.get()))
#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_debuggerAgent(PageDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), page, injectedScriptManager))
@@ -162,7 +179,6 @@ void InspectorAgent::inspectedPageDestroyed()
InspectorInstrumentation::unbindInspectorAgent(m_inspectedPage);
m_inspectedPage = 0;
- releaseFrontendLifetimeAgents();
m_injectedScriptManager->disconnect();
m_client->inspectorDestroyed();
@@ -180,6 +196,10 @@ void InspectorAgent::restoreInspectorStateFromCookie(const String& inspectorStat
m_resourceAgent->restore();
m_timelineAgent->restore();
+#if ENABLE(DATABASE)
+ m_databaseAgent->restore();
+#endif
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
m_debuggerAgent->restore();
m_profilerAgent->restore();
@@ -201,7 +221,6 @@ void InspectorAgent::setFrontend(InspectorFrontend* inspectorFrontend)
m_state->unmute();
m_frontend = inspectorFrontend;
- createFrontendLifetimeAgents();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
m_applicationCacheAgent->setFrontend(m_frontend);
@@ -272,18 +291,6 @@ void InspectorAgent::disconnectFrontend()
m_domStorageAgent->clearFrontend();
#endif
m_pageAgent->clearFrontend();
-
- releaseFrontendLifetimeAgents();
-}
-
-void InspectorAgent::createFrontendLifetimeAgents()
-{
- m_runtimeAgent = InspectorRuntimeAgent::create(m_injectedScriptManager, m_inspectedPage);
-}
-
-void InspectorAgent::releaseFrontendLifetimeAgents()
-{
- m_runtimeAgent.clear();
}
void InspectorAgent::didCommitLoad()
@@ -390,17 +397,6 @@ void InspectorAgent::evaluateForTestInFrontend(long callId, const String& script
issueEvaluateForTestCommands();
}
-void InspectorAgent::didEvaluateForTestInFrontend(ErrorString*, long callId, const String& jsonResult)
-{
- ScriptState* scriptState = scriptStateFromPage(debuggerWorld(), m_inspectedPage);
- ScriptObject window;
- ScriptGlobalObject::get(scriptState, "window", window);
- ScriptFunctionCall function(window, "didEvaluateForTestInFrontend");
- function.appendArgument(callId);
- function.appendArgument(jsonResult);
- function.call();
-}
-
void InspectorAgent::setInspectorExtensionAPI(const String& source)
{
m_inspectorExtensionAPI = source;
diff --git a/Source/WebCore/inspector/InspectorAgent.h b/Source/WebCore/inspector/InspectorAgent.h
index cda9137..6802ad5 100644
--- a/Source/WebCore/inspector/InspectorAgent.h
+++ b/Source/WebCore/inspector/InspectorAgent.h
@@ -170,16 +170,11 @@ public:
// InspectorAgent API
void getInspectorState(RefPtr<InspectorObject>* state);
void setMonitoringXHREnabled(bool enabled, bool* newState);
- // Following are used from InspectorBackend and internally.
- void didEvaluateForTestInFrontend(ErrorString*, long callId, const String& jsonResult);
private:
void showPanel(const String& panel);
void unbindAllResources();
- void releaseFrontendLifetimeAgents();
- void createFrontendLifetimeAgents();
-
#if ENABLE(JAVASCRIPT_DEBUGGER)
void toggleRecordButton(bool);
#endif
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp
index 980fcf2..153c661 100644
--- a/Source/WebCore/inspector/InspectorCSSAgent.cpp
+++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp
@@ -81,10 +81,11 @@
// ...
// #cssProperty
// ],
-// shorthandValues : {
-// shorthandName1 : shorthandValue1,
-// shorthandName2 : shorthandValue2
-// },
+// shorthandEntries : [
+// #shorthandEntry,
+// ...
+// #shorthandEntry
+// ],
// cssText : <string>, // Optional - declaration text
// properties : {
// width,
@@ -94,6 +95,11 @@
// }
// }
//
+// shorthandEntry = {
+// name: <string>,
+// value: <string>
+// }
+//
// cssRule = {
// ruleId : <string>, // Optional
// selectorText : <string>,
@@ -271,33 +277,32 @@ void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<InspectorArray>*
void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<InspectorObject>* styleSheetObject)
{
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, styleSheetId);
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
if (!inspectorStyleSheet)
return;
*styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet();
}
-void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* url, String* result)
+void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
{
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, styleSheetId);
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
if (!inspectorStyleSheet)
return;
- *url = inspectorStyleSheet->finalURL();
+
inspectorStyleSheet->text(result);
}
-void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text, bool* success)
+void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
{
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, styleSheetId);
- if (!inspectorStyleSheet) {
- *success = false;
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
+ if (!inspectorStyleSheet)
return;
- }
- *success = inspectorStyleSheet->setText(text);
- if (*success)
+ if (inspectorStyleSheet->setText(text))
inspectorStyleSheet->reparseStyleSheet(text);
+ else
+ *errorString = "Internal error setting style sheet text";
}
void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<InspectorObject>* result)
@@ -305,11 +310,11 @@ void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<I
InspectorCSSId compoundId(fullStyleId);
ASSERT(!compoundId.isEmpty());
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, compoundId.styleSheetId());
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
if (!inspectorStyleSheet)
return;
- bool success = inspectorStyleSheet->setPropertyText(compoundId, propertyIndex, text, overwrite);
+ bool success = inspectorStyleSheet->setPropertyText(errorString, compoundId, propertyIndex, text, overwrite);
if (success)
*result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
}
@@ -319,11 +324,11 @@ void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<In
InspectorCSSId compoundId(fullStyleId);
ASSERT(!compoundId.isEmpty());
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, compoundId.styleSheetId());
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
if (!inspectorStyleSheet)
return;
- bool success = inspectorStyleSheet->toggleProperty(compoundId, propertyIndex, disable);
+ bool success = inspectorStyleSheet->toggleProperty(errorString, compoundId, propertyIndex, disable);
if (success)
*result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
}
@@ -333,7 +338,7 @@ void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<I
InspectorCSSId compoundId(fullRuleId);
ASSERT(!compoundId.isEmpty());
- InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(errorString, compoundId.styleSheetId());
+ InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
if (!inspectorStyleSheet)
return;
@@ -402,11 +407,11 @@ Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId)
{
Node* node = m_domAgent->nodeForId(nodeId);
if (!node) {
- *errorString = "No node with given id found.";
+ *errorString = "No node with given id found";
return 0;
}
if (node->nodeType() != Node::ELEMENT_NODE) {
- *errorString = "Not an element node.";
+ *errorString = "Not an element node";
return 0;
}
return static_cast<Element*>(node);
@@ -465,11 +470,11 @@ InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* documen
return inspectorStyleSheet.get();
}
-InspectorStyleSheet* InspectorCSSAgent::styleSheetForId(ErrorString* errorString, const String& styleSheetId)
+InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
{
IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId);
if (it == m_idToInspectorStyleSheet.end()) {
- *errorString = "No style sheet with given id found.";
+ *errorString = "No style sheet with given id found";
return 0;
}
return it->second.get();
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.h b/Source/WebCore/inspector/InspectorCSSAgent.h
index 40bc2ab..c5337d6 100644
--- a/Source/WebCore/inspector/InspectorCSSAgent.h
+++ b/Source/WebCore/inspector/InspectorCSSAgent.h
@@ -66,8 +66,8 @@ public:
void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<InspectorObject>* style);
void getAllStyleSheets(ErrorString*, RefPtr<InspectorArray>* styleSheetInfos);
void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<InspectorObject>* result);
- void getStyleSheetText(ErrorString*, const String& styleSheetId, String* url, String* result);
- void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text, bool* success);
+ void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result);
+ void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text);
void setPropertyText(ErrorString*, const RefPtr<InspectorObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<InspectorObject>* result);
void toggleProperty(ErrorString*, const RefPtr<InspectorObject>& styleId, int propertyIndex, bool disable, RefPtr<InspectorObject>* result);
void setRuleSelector(ErrorString*, const RefPtr<InspectorObject>& ruleId, const String& selector, RefPtr<InspectorObject>* result);
@@ -87,7 +87,7 @@ private:
InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent);
- InspectorStyleSheet* styleSheetForId(ErrorString*, const String&);
+ InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&);
String detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList* ruleList);
diff --git a/Source/WebCore/inspector/InspectorClient.h b/Source/WebCore/inspector/InspectorClient.h
index d24ce4d..551a488 100644
--- a/Source/WebCore/inspector/InspectorClient.h
+++ b/Source/WebCore/inspector/InspectorClient.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +27,7 @@
#ifndef InspectorClient_h
#define InspectorClient_h
+#include "InspectorFrontendChannel.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -34,7 +36,7 @@ class InspectorController;
class Node;
class Page;
-class InspectorClient {
+class InspectorClient : public InspectorFrontendChannel {
public:
virtual ~InspectorClient() { }
@@ -45,8 +47,6 @@ public:
virtual void highlight(Node*) = 0;
virtual void hideHighlight() = 0;
- virtual bool sendMessageToFrontend(const String& message) = 0;
-
// Navigation can cause some WebKit implementations to change the view / page / inspector controller instance.
// However, there are some inspector controller states that should survive navigation (such as tracking resources
// or recording timeline). Following callbacks allow embedders to track these states.
diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.cpp b/Source/WebCore/inspector/InspectorConsoleAgent.cpp
index 47cd2d5..53d647f 100644
--- a/Source/WebCore/inspector/InspectorConsoleAgent.cpp
+++ b/Source/WebCore/inspector/InspectorConsoleAgent.cpp
@@ -103,7 +103,7 @@ void InspectorConsoleAgent::clearConsoleMessages(ErrorString*)
m_injectedScriptManager->releaseObjectGroup("console");
m_inspectorDOMAgent->releaseDanglingNodes();
if (m_frontend)
- m_frontend->consoleMessagesCleared();
+ m_frontend->messagesCleared();
}
void InspectorConsoleAgent::reset()
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
index 62b22ee..d9b9773 100644
--- a/Source/WebCore/inspector/InspectorController.cpp
+++ b/Source/WebCore/inspector/InspectorController.cpp
@@ -55,7 +55,7 @@
namespace WebCore {
InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient)
- : m_injectedScriptManager(InjectedScriptManager::create())
+ : m_injectedScriptManager(InjectedScriptManager::createForPage())
, m_inspectorAgent(new InspectorAgent(page, inspectorClient, m_injectedScriptManager.get()))
, m_inspectorClient(inspectorClient)
, m_openingFrontend(false)
@@ -132,7 +132,6 @@ void InspectorController::connectFrontend()
#if ENABLE(JAVASCRIPT_DEBUGGER)
m_inspectorAgent->debuggerAgent(),
#endif
- m_inspectorAgent.get(),
m_inspectorAgent->resourceAgent(),
m_inspectorAgent->pageAgent(),
#if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -255,6 +254,11 @@ void InspectorController::hideHighlight()
m_inspectorAgent->domAgent()->hideHighlight(&error);
}
+Node* InspectorController::highlightedNode() const
+{
+ return m_inspectorAgent->domAgent()->highlightedNode();
+}
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
void InspectorController::enableProfiler()
{
diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
index f38eb3d..b97373e 100644
--- a/Source/WebCore/inspector/InspectorController.h
+++ b/Source/WebCore/inspector/InspectorController.h
@@ -80,6 +80,7 @@ public:
void inspect(Node*);
void drawNodeHighlight(GraphicsContext&) const;
void hideHighlight();
+ Node* highlightedNode() const;
void evaluateForTestInFrontend(long callId, const String& script);
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp
index 06c5977..cb761d0 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009-2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
@@ -397,7 +397,7 @@ Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
{
Node* node = nodeForId(nodeId);
if (!node) {
- *errorString = "Could not find node with given id.";
+ *errorString = "Could not find node with given id";
return 0;
}
return node;
@@ -410,7 +410,7 @@ Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId)
return 0;
if (node->nodeType() != Node::ELEMENT_NODE) {
- *errorString = "Node is not an Element.";
+ *errorString = "Node is not an Element";
return 0;
}
return toElement(node);
@@ -424,30 +424,12 @@ HTMLElement* InspectorDOMAgent::assertHTMLElement(ErrorString* errorString, int
return 0;
if (!element->isHTMLElement()) {
- *errorString = "Node is not an HTML Element.";
+ *errorString = "Node is not an HTML Element";
return 0;
}
return toHTMLElement(element);
}
-Node* InspectorDOMAgent::nodeToSelectOn(ErrorString* errorString, int nodeId, bool documentWide)
-{
- Node* node;
- if (!nodeId) {
- node = m_document.get();
- if (!node)
- *errorString = "No document to query on.";
- } else
- node = assertNode(errorString, nodeId);
-
- if (!node)
- return 0;
-
- if (documentWide && nodeId)
- node = node->ownerDocument();
- return node;
-}
-
void InspectorDOMAgent::getDocument(ErrorString*, RefPtr<InspectorObject>* root)
{
m_inspectorState->setBoolean(DOMAgentState::documentRequested, true);
@@ -460,8 +442,7 @@ void InspectorDOMAgent::getDocument(ErrorString*, RefPtr<InspectorObject>* root)
reset();
m_document = doc;
- if (!m_documentNodeToIdMap.contains(m_document))
- *root = buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap);
+ *root = buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap);
}
void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId)
@@ -474,7 +455,6 @@ void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId)
NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
RefPtr<InspectorArray> children = buildArrayForContainerChildren(node, 1, nodeMap);
- m_childrenRequested.add(nodeId);
m_frontend->setChildNodes(nodeId, children.release());
}
@@ -502,17 +482,17 @@ void InspectorDOMAgent::getChildNodes(ErrorString*, int nodeId)
pushChildNodesToFrontend(nodeId);
}
-void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, bool documentWide, int* elementId)
+void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId)
{
*elementId = 0;
- Node* node = nodeToSelectOn(errorString, nodeId, documentWide);
+ Node* node = assertNode(errorString, nodeId);
if (!node)
return;
ExceptionCode ec = 0;
RefPtr<Element> element = node->querySelector(selectors, ec);
if (ec) {
- *errorString = "DOM Error while querying.";
+ *errorString = "DOM Error while querying";
return;
}
@@ -520,16 +500,16 @@ void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, cons
*elementId = pushNodePathToFrontend(element.get());
}
-void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, bool documentWide, RefPtr<InspectorArray>* result)
+void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<InspectorArray>* result)
{
- Node* node = nodeToSelectOn(errorString, nodeId, documentWide);
+ Node* node = assertNode(errorString, nodeId);
if (!node)
return;
ExceptionCode ec = 0;
RefPtr<NodeList> nodes = node->querySelectorAll(selectors, ec);
if (ec) {
- *errorString = "DOM Error while querying.";
+ *errorString = "DOM Error while querying";
return;
}
@@ -595,7 +575,7 @@ void InspectorDOMAgent::setAttribute(ErrorString* errorString, int elementId, co
ExceptionCode ec = 0;
element->setAttribute(name, value, ec);
if (ec)
- *errorString = "Exception while setting attribute value.";
+ *errorString = "Exception while setting attribute value";
}
}
@@ -606,7 +586,7 @@ void InspectorDOMAgent::removeAttribute(ErrorString* errorString, int elementId,
ExceptionCode ec = 0;
element->removeAttribute(name, ec);
if (ec)
- *errorString = "Exception while removing attribute.";
+ *errorString = "Exception while removing attribute";
}
}
@@ -618,14 +598,14 @@ void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId)
ContainerNode* parentNode = node->parentNode();
if (!parentNode) {
- *errorString = "Can not remove detached node.";
+ *errorString = "Can not remove detached node";
return;
}
ExceptionCode ec = 0;
parentNode->removeChild(node, ec);
if (ec)
- *errorString = "Could not remove node due to DOM exception.";
+ *errorString = "Could not remove node due to DOM exception";
}
void InspectorDOMAgent::setNodeName(ErrorString*, int nodeId, const String& tagName, int* newId)
@@ -716,7 +696,7 @@ void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const
return;
if (node->nodeType() != Node::TEXT_NODE) {
- *errorString = "Can only set value of text nodes.";
+ *errorString = "Can only set value of text nodes";
return;
}
@@ -724,7 +704,7 @@ void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const
ExceptionCode ec = 0;
textNode->replaceWholeText(value, ec);
if (ec)
- *errorString = "DOM Error while setting the node value.";
+ *errorString = "DOM Error while setting the node value";
}
void InspectorDOMAgent::getEventListenersForNode(ErrorString*, int nodeId, RefPtr<InspectorArray>* listenersArray)
@@ -794,7 +774,7 @@ void InspectorDOMAgent::getEventListenersForNode(ErrorString*, int nodeId, RefPt
}
}
-void InspectorDOMAgent::performSearch(ErrorString* error, const String& whitespaceTrimmedQuery, bool runSynchronously)
+void InspectorDOMAgent::performSearch(ErrorString* error, const String& whitespaceTrimmedQuery, const bool* const runSynchronously)
{
// FIXME: Few things are missing here:
// 1) Search works with node granularity - number of matches within node is not calculated.
@@ -869,7 +849,7 @@ void InspectorDOMAgent::performSearch(ErrorString* error, const String& whitespa
m_pendingMatchJobs.append(new MatchXPathJob(document, whitespaceTrimmedQuery));
}
- if (runSynchronously) {
+ if (runSynchronously && *runSynchronously) {
// For tests.
ListHashSet<Node*> resultCollector;
for (Deque<MatchJob*>::iterator it = m_pendingMatchJobs.begin(); it != m_pendingMatchJobs.end(); ++it)
@@ -961,9 +941,8 @@ void InspectorDOMAgent::setSearchingForNode(bool enabled)
}
}
-void InspectorDOMAgent::setSearchingForNode(ErrorString*, bool enabled, bool* newState)
+void InspectorDOMAgent::setSearchingForNode(ErrorString*, bool enabled)
{
- *newState = enabled;
setSearchingForNode(enabled);
}
@@ -1108,14 +1087,15 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForContainerChildren(Nod
Node* child = innerFirstChild(container);
if (depth == 0) {
- // Special case the_only text child.
+ // Special-case the only text child - pretend that container's children have been requested.
if (child && child->nodeType() == Node::TEXT_NODE && !innerNextSibling(child))
- children->pushObject(buildObjectForNode(child, 0, nodesMap));
+ return buildArrayForContainerChildren(container, 1, nodesMap);
return children.release();
- } else if (depth > 0) {
- depth--;
}
+ depth--;
+ m_childrenRequested.add(bind(container, nodesMap));
+
while (child) {
children->pushObject(buildObjectForNode(child, depth, nodesMap));
child = innerNextSibling(child);
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.h b/Source/WebCore/inspector/InspectorDOMAgent.h
index 8aeb66b..526bf34 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.h
+++ b/Source/WebCore/inspector/InspectorDOMAgent.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009-2011 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -111,8 +111,8 @@ public:
void reset();
// Methods called from the frontend for DOM nodes inspection.
- void querySelector(ErrorString*, int nodeId, const String& selectors, bool documentWide, int* elementId);
- void querySelectorAll(ErrorString*, int nodeId, const String& selectors, bool documentWide, RefPtr<InspectorArray>* result);
+ void querySelector(ErrorString*, int nodeId, const String& selectors, int* elementId);
+ void querySelectorAll(ErrorString*, int nodeId, const String& selectors, RefPtr<InspectorArray>* result);
void getDocument(ErrorString*, RefPtr<InspectorObject>* root);
void getChildNodes(ErrorString*, int nodeId);
void setAttribute(ErrorString*, int elementId, const String& name, const String& value);
@@ -123,10 +123,10 @@ public:
void setOuterHTML(ErrorString*, int nodeId, const String& outerHTML, int* newId);
void setNodeValue(ErrorString*, int nodeId, const String& value);
void getEventListenersForNode(ErrorString*, int nodeId, RefPtr<InspectorArray>* listenersArray);
- void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, bool runSynchronously);
+ void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, const bool* const runSynchronously);
void cancelSearch(ErrorString*);
void resolveNode(ErrorString*, int nodeId, RefPtr<InspectorObject>* result);
- void setSearchingForNode(ErrorString*, bool enabled, bool* newState);
+ void setSearchingForNode(ErrorString*, bool enabled);
void pushNodeToFrontend(ErrorString*, const String& objectId, int* nodeId);
void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId);
void hideHighlight(ErrorString*);
@@ -134,6 +134,7 @@ public:
void hideDOMNodeHighlight(ErrorString* error) { hideHighlight(error); }
void highlightFrame(ErrorString*, const String& frameId);
void hideFrameHighlight(ErrorString* error) { hideHighlight(error); }
+ Node* highlightedNode() const { return m_highlightedNode.get(); }
// Methods called from the InspectorInstrumentation.
void setDocument(Document*);
@@ -186,7 +187,6 @@ private:
Node* assertNode(ErrorString*, int nodeId);
Element* assertElement(ErrorString*, int nodeId);
HTMLElement* assertHTMLElement(ErrorString*, int nodeId);
- Node* nodeToSelectOn(ErrorString*, int nodeId, bool documentWide);
int pushNodePathToFrontend(Node*);
void pushChildNodesToFrontend(int nodeId);
diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp
index 7f6e379..03d8482 100644
--- a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp
@@ -36,6 +36,7 @@
#include "ExceptionCode.h"
#include "InspectorDatabaseResource.h"
#include "InspectorFrontend.h"
+#include "InspectorState.h"
#include "InspectorValues.h"
#include "InstrumentingAgents.h"
#include "SQLError.h"
@@ -52,6 +53,10 @@
namespace WebCore {
+namespace DatabaseAgentState {
+static const char databaseAgentEnabled[] = "databaseAgentEnabled";
+};
+
class InspectorDatabaseAgent::FrontendProvider : public RefCounted<InspectorDatabaseAgent::FrontendProvider> {
public:
static PassRefPtr<FrontendProvider> create(InspectorFrontend* inspectorFrontend)
@@ -220,10 +225,15 @@ private:
void InspectorDatabaseAgent::didOpenDatabase(PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
{
+ if (InspectorDatabaseResource* resource = findByFileName(database->fileName())) {
+ resource->setDatabase(database);
+ return;
+ }
+
RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version);
m_resources.set(resource->id(), resource);
// Resources are only bound while visible.
- if (m_frontendProvider)
+ if (m_frontendProvider && m_enabled)
resource->bind(m_frontendProvider->frontend());
}
@@ -232,8 +242,10 @@ void InspectorDatabaseAgent::clearResources()
m_resources.clear();
}
-InspectorDatabaseAgent::InspectorDatabaseAgent(InstrumentingAgents* instrumentingAgents)
+InspectorDatabaseAgent::InspectorDatabaseAgent(InstrumentingAgents* instrumentingAgents, InspectorState* state)
: m_instrumentingAgents(instrumentingAgents)
+ , m_inspectorState(state)
+ , m_enabled(false)
{
m_instrumentingAgents->setInspectorDatabaseAgent(this);
}
@@ -246,19 +258,47 @@ InspectorDatabaseAgent::~InspectorDatabaseAgent()
void InspectorDatabaseAgent::setFrontend(InspectorFrontend* frontend)
{
m_frontendProvider = FrontendProvider::create(frontend);
- DatabaseResourcesMap::iterator databasesEnd = m_resources.end();
- for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != databasesEnd; ++it)
- it->second->bind(m_frontendProvider->frontend());
}
void InspectorDatabaseAgent::clearFrontend()
{
m_frontendProvider->clearFrontend();
m_frontendProvider.clear();
+ disable(0);
+}
+
+void InspectorDatabaseAgent::enable(ErrorString*)
+{
+ if (m_enabled)
+ return;
+ m_enabled = true;
+ m_inspectorState->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
+
+ DatabaseResourcesMap::iterator databasesEnd = m_resources.end();
+ for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != databasesEnd; ++it)
+ it->second->bind(m_frontendProvider->frontend());
}
-void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString*, int databaseId, RefPtr<InspectorArray>* names)
+void InspectorDatabaseAgent::disable(ErrorString*)
{
+ if (!m_enabled)
+ return;
+ m_enabled = false;
+ m_inspectorState->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
+}
+
+void InspectorDatabaseAgent::restore()
+{
+ m_enabled = m_inspectorState->getBoolean(DatabaseAgentState::databaseAgentEnabled);
+}
+
+void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString* error, int databaseId, RefPtr<InspectorArray>* names)
+{
+ if (!m_enabled) {
+ *error = "Database agent is not enabled";
+ return;
+ }
+
Database* database = databaseForId(databaseId);
if (database) {
Vector<String> tableNames = database->tableNames();
@@ -268,8 +308,13 @@ void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString*, int databaseId,
}
}
-void InspectorDatabaseAgent::executeSQL(ErrorString*, int databaseId, const String& query, bool* success, int* transactionId)
+void InspectorDatabaseAgent::executeSQL(ErrorString* error, int databaseId, const String& query, bool* success, int* transactionId)
{
+ if (!m_enabled) {
+ *error = "Database agent is not enabled";
+ return;
+ }
+
Database* database = databaseForId(databaseId);
if (!database) {
*success = false;
@@ -293,6 +338,15 @@ int InspectorDatabaseAgent::databaseId(Database* database)
return 0;
}
+InspectorDatabaseResource* InspectorDatabaseAgent::findByFileName(const String& fileName)
+{
+ for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) {
+ if (it->second->database()->fileName() == fileName)
+ return it->second.get();
+ }
+ return 0;
+}
+
Database* InspectorDatabaseAgent::databaseForId(int databaseId)
{
DatabaseResourcesMap::iterator it = m_resources.find(databaseId);
diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.h b/Source/WebCore/inspector/InspectorDatabaseAgent.h
index 45fbfa4..354a6cd 100644
--- a/Source/WebCore/inspector/InspectorDatabaseAgent.h
+++ b/Source/WebCore/inspector/InspectorDatabaseAgent.h
@@ -39,6 +39,7 @@ class Database;
class InspectorArray;
class InspectorDatabaseResource;
class InspectorFrontend;
+class InspectorState;
class InstrumentingAgents;
typedef String ErrorString;
@@ -47,9 +48,9 @@ class InspectorDatabaseAgent {
public:
class FrontendProvider;
- static PassOwnPtr<InspectorDatabaseAgent> create(InstrumentingAgents* instrumentingAgents)
+ static PassOwnPtr<InspectorDatabaseAgent> create(InstrumentingAgents* instrumentingAgents, InspectorState* state)
{
- return adoptPtr(new InspectorDatabaseAgent(instrumentingAgents));
+ return adoptPtr(new InspectorDatabaseAgent(instrumentingAgents, state));
}
~InspectorDatabaseAgent();
@@ -57,8 +58,11 @@ public:
void clearFrontend();
void clearResources();
+ void restore();
// Called from the front-end.
+ void enable(ErrorString*);
+ void disable(ErrorString*);
void getDatabaseTableNames(ErrorString*, int databaseId, RefPtr<InspectorArray>* names);
void executeSQL(ErrorString*, int databaseId, const String& query, bool* success, int* transactionId);
@@ -67,14 +71,17 @@ public:
void didOpenDatabase(PassRefPtr<Database>, const String& domain, const String& name, const String& version);
private:
- explicit InspectorDatabaseAgent(InstrumentingAgents*);
+ explicit InspectorDatabaseAgent(InstrumentingAgents*, InspectorState*);
Database* databaseForId(int databaseId);
+ InspectorDatabaseResource* findByFileName(const String& fileName);
InstrumentingAgents* m_instrumentingAgents;
+ InspectorState* m_inspectorState;
typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
DatabaseResourcesMap m_resources;
RefPtr<FrontendProvider> m_frontendProvider;
+ bool m_enabled;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorDatabaseResource.h b/Source/WebCore/inspector/InspectorDatabaseResource.h
index 9fa7ebd..281568c 100644
--- a/Source/WebCore/inspector/InspectorDatabaseResource.h
+++ b/Source/WebCore/inspector/InspectorDatabaseResource.h
@@ -48,6 +48,7 @@ public:
void bind(InspectorFrontend::Database*);
Database* database() { return m_database.get(); }
+ void setDatabase(PassRefPtr<Database> database) { m_database = database; }
int id() const { return m_id; }
private:
diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
index 56bc7b7..70b07bc 100644
--- a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -141,46 +141,71 @@ void InspectorDebuggerAgent::inspectedURLChanged(const String&)
m_breakpointIdToDebugServerBreakpointIds.clear();
}
-void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, RefPtr<InspectorArray>* locations)
+static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition)
{
- String breakpointId = makeString(url, ":", String::number(lineNumber), ":", String::number(columnNumber));
- RefPtr<InspectorObject> breakpointsCookie = m_inspectorState->getObject(DebuggerAgentState::javaScriptBreakpoints);
- if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end())
- return;
RefPtr<InspectorObject> breakpointObject = InspectorObject::create();
breakpointObject->setString("url", url);
breakpointObject->setNumber("lineNumber", lineNumber);
breakpointObject->setNumber("columnNumber", columnNumber);
breakpointObject->setString("condition", condition);
- breakpointObject->setBoolean("enabled", enabled);
- breakpointsCookie->setObject(breakpointId, breakpointObject);
+ return breakpointObject;
+}
+
+void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* outBreakpointId, RefPtr<InspectorArray>* locations)
+{
+ int columnNumber = optionalColumnNumber ? *optionalColumnNumber : 0;
+ String condition = optionalCondition ? *optionalCondition : "";
+
+ String breakpointId = makeString(url, ":", String::number(lineNumber), ":", String::number(columnNumber));
+ RefPtr<InspectorObject> breakpointsCookie = m_inspectorState->getObject(DebuggerAgentState::javaScriptBreakpoints);
+ if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end())
+ return;
+ breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition));
m_inspectorState->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
if (it->second.url != url)
continue;
- int actualLineNumber = 0, actualColumnNumber = 0;
- if (!resolveBreakpoint(breakpointId, it->first, breakpoint, &actualLineNumber, &actualColumnNumber))
- continue;
- RefPtr<InspectorObject> location = InspectorObject::create();
- location->setString("sourceID", it->first);
- location->setNumber("lineNumber", actualLineNumber);
- location->setNumber("columnNumber", actualColumnNumber);
- locations->get()->pushObject(location);
+ RefPtr<InspectorObject> location = resolveBreakpoint(breakpointId, it->first, breakpoint);
+ if (location)
+ (*locations)->pushObject(location);
}
*outBreakpointId = breakpointId;
}
-void InspectorDebuggerAgent::setBreakpoint(ErrorString*, const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, int* actualLineNumber, int* actualColumnNumber)
+static bool parseLocation(ErrorString* errorString, RefPtr<InspectorObject> location, String* sourceId, int* lineNumber, int* columnNumber)
+{
+ if (!location->getString("sourceID", sourceId) || !location->getNumber("lineNumber", lineNumber)) {
+ // FIXME: replace with input validation.
+ *errorString = "sourceId and lineNumber are required.";
+ return false;
+ }
+ *columnNumber = 0;
+ location->getNumber("columnNumber", columnNumber);
+ return true;
+}
+
+void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, PassRefPtr<InspectorObject> location, const String* const optionalCondition, String* outBreakpointId, RefPtr<InspectorObject>* actualLocation)
{
+ String sourceId;
+ int lineNumber;
+ int columnNumber;
+
+ if (!parseLocation(errorString, location, &sourceId, &lineNumber, &columnNumber))
+ return;
+
+ String condition = optionalCondition ? *optionalCondition : "";
+
String breakpointId = makeString(sourceId, ":", String::number(lineNumber), ":", String::number(columnNumber));
if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end())
return;
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
- if (!resolveBreakpoint(breakpointId, sourceId, breakpoint, actualLineNumber, actualColumnNumber))
- return;
- *outBreakpointId = breakpointId;
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
+ *actualLocation = resolveBreakpoint(breakpointId, sourceId, breakpoint);
+ if (*actualLocation)
+ *outBreakpointId = breakpointId;
+ else
+ *errorString = "Could not resolve breakpoint";
}
void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointId)
@@ -197,25 +222,33 @@ void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakp
m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator);
}
-void InspectorDebuggerAgent::continueToLocation(ErrorString* error, const String& sourceId, int lineNumber, int columnNumber)
+void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, PassRefPtr<InspectorObject> location)
{
if (!m_continueToLocationBreakpointId.isEmpty()) {
scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
m_continueToLocationBreakpointId = "";
}
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", true);
+
+ String sourceId;
+ int lineNumber;
+ int columnNumber;
+
+ if (!parseLocation(errorString, location, &sourceId, &lineNumber, &columnNumber))
+ return;
+
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
m_continueToLocationBreakpointId = scriptDebugServer().setBreakpoint(sourceId, breakpoint, &lineNumber, &columnNumber);
- resume(error);
+ resume(errorString);
}
-bool InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint& breakpoint, int* actualLineNumber, int* actualColumnNumber)
+PassRefPtr<InspectorObject> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint& breakpoint)
{
ScriptsMap::iterator scriptIterator = m_scripts.find(sourceId);
if (scriptIterator == m_scripts.end())
- return false;
+ return 0;
Script& script = scriptIterator->second;
if (breakpoint.lineNumber < script.lineOffset)
- return false;
+ return 0;
if (!script.linesCount) {
script.linesCount = 1;
for (size_t i = 0; i < script.data.length(); ++i) {
@@ -224,28 +257,30 @@ bool InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const
}
}
if (breakpoint.lineNumber >= script.lineOffset + script.linesCount)
- return false;
+ return 0;
- String debugServerBreakpointId = scriptDebugServer().setBreakpoint(sourceId, breakpoint, actualLineNumber, actualColumnNumber);
+ int actualLineNumber;
+ int actualColumnNumber;
+ String debugServerBreakpointId = scriptDebugServer().setBreakpoint(sourceId, breakpoint, &actualLineNumber, &actualColumnNumber);
if (debugServerBreakpointId.isEmpty())
- return false;
+ return 0;
BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).first;
debugServerBreakpointIdsIterator->second.append(debugServerBreakpointId);
- return true;
+ RefPtr<InspectorObject> location = InspectorObject::create();
+ location->setString("sourceID", sourceId);
+ location->setNumber("lineNumber", actualLineNumber);
+ location->setNumber("columnNumber", actualColumnNumber);
+ return location;
}
-void InspectorDebuggerAgent::editScriptSource(ErrorString* errorString, const String& sourceID, const String& newContent, String* result, RefPtr<InspectorArray>* newCallFrames)
+void InspectorDebuggerAgent::editScriptSource(ErrorString* error, const String& sourceID, const String& newContent, RefPtr<InspectorArray>* newCallFrames)
{
- String editResult;
- if (scriptDebugServer().editScriptSource(sourceID, newContent, editResult)) {
+ if (scriptDebugServer().editScriptSource(sourceID, newContent, error))
*newCallFrames = currentCallFrames();
- *result = editResult;
- } else
- *errorString = editResult;
}
void InspectorDebuggerAgent::getScriptSource(ErrorString*, const String& sourceID, String* scriptSource)
@@ -279,6 +314,7 @@ void InspectorDebuggerAgent::pause(ErrorString*)
void InspectorDebuggerAgent::resume(ErrorString*)
{
+ m_injectedScriptManager->releaseObjectGroup("backtrace");
scriptDebugServer().continueProgram();
}
@@ -297,18 +333,29 @@ void InspectorDebuggerAgent::stepOut(ErrorString*)
scriptDebugServer().stepOutOfFunction();
}
-void InspectorDebuggerAgent::setPauseOnExceptionsState(ErrorString* errorString, int pauseState)
+void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, const String& stringPauseState)
{
+ ScriptDebugServer::PauseOnExceptionsState pauseState;
+ if (stringPauseState == "none")
+ pauseState = ScriptDebugServer::DontPauseOnExceptions;
+ else if (stringPauseState == "all")
+ pauseState = ScriptDebugServer::PauseOnAllExceptions;
+ else if (stringPauseState == "uncaught")
+ pauseState = ScriptDebugServer::PauseOnUncaughtExceptions;
+ else {
+ *errorString = "Unknown pause on exceptions mode: " + stringPauseState;
+ return;
+ }
scriptDebugServer().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState));
if (scriptDebugServer().pauseOnExceptionsState() != pauseState)
- *errorString = "Internal error. Could not change pause on exceptions state.";
+ *errorString = "Internal error. Could not change pause on exceptions state";
}
-void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
+void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, RefPtr<InspectorObject>* result)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
if (!injectedScript.hasNoValue())
- injectedScript.evaluateOnCallFrame(errorString, callFrameId, expression, objectGroup, includeCommandLineAPI, result);
+ injectedScript.evaluateOnCallFrame(errorString, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, result);
}
PassRefPtr<InspectorArray> InspectorDebuggerAgent::currentCallFrames()
@@ -325,10 +372,10 @@ PassRefPtr<InspectorArray> InspectorDebuggerAgent::currentCallFrames()
// JavaScriptDebugListener functions
-void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, ScriptWorldType worldType)
+void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, bool isContentScript)
{
// Don't send script content to the front end until it's really needed.
- m_frontend->scriptParsed(sourceID, url, lineOffset, columnOffset, data.length(), worldType);
+ m_frontend->scriptParsed(sourceID, url, lineOffset, columnOffset, data.length(), isContentScript);
m_scripts.set(sourceID, Script(url, data, lineOffset, columnOffset));
@@ -346,10 +393,9 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String
breakpointObject->getNumber("lineNumber", &breakpoint.lineNumber);
breakpointObject->getNumber("columnNumber", &breakpoint.columnNumber);
breakpointObject->getString("condition", &breakpoint.condition);
- breakpointObject->getBoolean("enabled", &breakpoint.enabled);
- int actualLineNumber = 0, actualColumnNumber = 0;
- if (resolveBreakpoint(it->first, sourceID, breakpoint, &actualLineNumber, &actualColumnNumber))
- m_frontend->breakpointResolved(it->first, sourceID, actualLineNumber, actualColumnNumber);
+ RefPtr<InspectorObject> location = resolveBreakpoint(it->first, sourceID, breakpoint);
+ if (location)
+ m_frontend->breakpointResolved(it->first, location);
}
}
diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.h b/Source/WebCore/inspector/InspectorDebuggerAgent.h
index d5726e7..4c2e855 100644
--- a/Source/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/Source/WebCore/inspector/InspectorDebuggerAgent.h
@@ -39,6 +39,7 @@
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>
@@ -79,12 +80,12 @@ public:
// Part of the protocol.
void setBreakpointsActive(ErrorString*, bool active);
- void setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, RefPtr<InspectorArray>* locations);
- void setBreakpoint(ErrorString*, const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, int* actualLineNumber, int* actualColumnNumber);
+ void setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* breakpointId, RefPtr<InspectorArray>* locations);
+ void setBreakpoint(ErrorString*, PassRefPtr<InspectorObject> location, const String* const optionalCondition, String* breakpointId, RefPtr<InspectorObject>* actualLocation);
void removeBreakpoint(ErrorString*, const String& breakpointId);
- void continueToLocation(ErrorString*, const String& sourceId, int lineNumber, int columnNumber);
+ void continueToLocation(ErrorString*, PassRefPtr<InspectorObject> location);
- void editScriptSource(ErrorString*, const String& sourceID, const String& newContent, String* result, RefPtr<InspectorArray>* newCallFrames);
+ void editScriptSource(ErrorString*, const String& sourceID, const String& newContent, RefPtr<InspectorArray>* newCallFrames);
void getScriptSource(ErrorString*, const String& sourceID, String* scriptSource);
void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data);
void cancelPauseOnNextStatement();
@@ -94,8 +95,8 @@ public:
void stepOver(ErrorString*);
void stepInto(ErrorString*);
void stepOut(ErrorString*);
- void setPauseOnExceptionsState(ErrorString*, int pauseState);
- void evaluateOnCallFrame(ErrorString*, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
+ void setPauseOnExceptions(ErrorString*, const String& pauseState);
+ void evaluateOnCallFrame(ErrorString*, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, RefPtr<InspectorObject>* result);
class Listener {
public:
@@ -118,12 +119,12 @@ private:
PassRefPtr<InspectorArray> currentCallFrames();
- virtual void didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, ScriptWorldType);
+ virtual void didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, bool isContentScript);
virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
virtual void didPause(ScriptState*);
virtual void didContinue();
- bool resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber);
+ PassRefPtr<InspectorObject> resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint&);
void clear();
class Script {
diff --git a/Source/WebCore/inspector/InspectorFrontendChannel.h b/Source/WebCore/inspector/InspectorFrontendChannel.h
new file mode 100644
index 0000000..b3214ef
--- /dev/null
+++ b/Source/WebCore/inspector/InspectorFrontendChannel.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorFrontendChannel_h
+#define InspectorFrontendChannel_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class InspectorFrontendChannel {
+public:
+ virtual ~InspectorFrontendChannel() { }
+ virtual bool sendMessageToFrontend(const String& message) = 0;
+};
+
+} // namespace WebCore
+
+#endif // !defined(InspectorFrontendChannel_h)
diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp
index 36864f3..7743ec0 100644
--- a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp
+++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp
@@ -44,6 +44,7 @@
#include "PlatformString.h"
#include "ScriptFunctionCall.h"
#include "ScriptObject.h"
+#include "Settings.h"
namespace WebCore {
@@ -67,6 +68,7 @@ InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController*
, m_frontendScriptState(0)
, m_settings(settings)
{
+ m_frontendPage->settings()->setAllowFileAccessFromFileURLs(true);
}
InspectorFrontendClientLocal::~InspectorFrontendClientLocal()
diff --git a/Source/WebCore/inspector/front-end/Breakpoint.js b/Source/WebCore/inspector/InspectorFrontendProxy.cpp
index ebc6029..4e2188d 100644
--- a/Source/WebCore/inspector/front-end/Breakpoint.js
+++ b/Source/WebCore/inspector/InspectorFrontendProxy.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2011 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
@@ -29,21 +28,46 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Breakpoint = function(id, url, sourceID, lineNumber, columnNumber, condition, enabled)
+#include "config.h"
+#include "InspectorFrontendProxy.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "EventsCollector.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+InspectorFrontendProxy::InspectorFrontendProxy(EventsCollector* collector)
+{
+ m_receiver = 0;
+ m_collector = collector;
+}
+
+InspectorFrontendProxy::InspectorFrontendProxy(EventsCollector* collector, InspectorFrontendChannel* nextChannel)
+{
+ m_collector = collector;
+ m_receiver = nextChannel;
+}
+
+void InspectorFrontendProxy::setInspectorFrontendChannel(InspectorFrontendChannel* receiver)
+{
+ m_receiver = receiver;
+}
+
+void InspectorFrontendProxy::setEventsCollector(EventsCollector* collector)
{
- this.id = id;
- this.url = url;
- this.sourceID = sourceID;
- this.lineNumber = lineNumber;
- this.columnNumber = columnNumber;
- this.condition = condition;
- this.enabled = enabled;
- this.locations = [];
+ m_collector = collector;
}
-WebInspector.Breakpoint.prototype = {
- addLocation: function(sourceID, lineNumber, columnNumber)
- {
- this.locations.push({ sourceID: sourceID, lineNumber: lineNumber, columnNumber: columnNumber });
- }
+bool InspectorFrontendProxy::sendMessageToFrontend(const String& message)
+{
+ m_collector->addEvent(message);
+ if (m_receiver)
+ return m_receiver->sendMessageToFrontend(message);
+ return false;
}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InspectorFrontendProxy.h b/Source/WebCore/inspector/InspectorFrontendProxy.h
new file mode 100644
index 0000000..259af67
--- /dev/null
+++ b/Source/WebCore/inspector/InspectorFrontendProxy.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorFrontendProxy_h
+#define InspectorFrontendProxy_h
+
+#if ENABLE(INSPECTOR)
+
+#include "InspectorFrontendChannel.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class EventsCollector;
+
+class InspectorFrontendProxy : public InspectorFrontendChannel {
+public:
+ explicit InspectorFrontendProxy(EventsCollector*);
+ InspectorFrontendProxy(EventsCollector*, InspectorFrontendChannel* nextChannel);
+ virtual ~InspectorFrontendProxy() { }
+
+ void setInspectorFrontendChannel(InspectorFrontendChannel*);
+ void setEventsCollector(EventsCollector*);
+ virtual bool sendMessageToFrontend(const String& message);
+
+private:
+ InspectorFrontendChannel* m_receiver;
+ EventsCollector* m_collector;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
+
+#endif // !defined(InspectorFrontendProxy_h)
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
index 6d3b4ad..9986677 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
@@ -457,10 +457,31 @@ void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorIns
}
}
-void InspectorInstrumentation::didReceiveContentLengthImpl(InspectorAgent* inspectorAgent, unsigned long identifier, int dataLength, int lengthReceived)
+void InspectorInstrumentation::didReceiveResourceResponseButCanceledImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(frame, identifier, r);
+ InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, r);
+}
+
+void InspectorInstrumentation::continueAfterXFrameOptionsDeniedImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+ didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
+}
+
+void InspectorInstrumentation::continueWithPolicyDownloadImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+ didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
+}
+
+void InspectorInstrumentation::continueWithPolicyIgnoreImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+ didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
+}
+
+void InspectorInstrumentation::didReceiveContentLengthImpl(InspectorAgent* inspectorAgent, unsigned long identifier, int dataLength, int encodedDataLength)
{
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
- resourceAgent->didReceiveContentLength(identifier, dataLength, lengthReceived);
+ resourceAgent->didReceiveContentLength(identifier, dataLength, encodedDataLength);
}
void InspectorInstrumentation::didFinishLoadingImpl(InspectorAgent* inspectorAgent, unsigned long identifier, double finishTime)
@@ -484,13 +505,13 @@ void InspectorInstrumentation::resourceRetrievedByXMLHttpRequestImpl(InspectorAg
{
inspectorAgent->consoleAgent()->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber);
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
- resourceAgent->setInitialContent(identifier, sourceString, "XHR");
+ resourceAgent->setInitialXHRContent(identifier, sourceString);
}
void InspectorInstrumentation::scriptImportedImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const String& sourceString)
{
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
- resourceAgent->setInitialContent(identifier, sourceString, "Script");
+ resourceAgent->setInitialScriptContent(identifier, sourceString);
}
void InspectorInstrumentation::domContentLoadedEventFiredImpl(InspectorAgent* inspectorAgent, Frame* frame, const KURL& url)
@@ -509,6 +530,9 @@ void InspectorInstrumentation::domContentLoadedEventFiredImpl(InspectorAgent* in
if (InspectorTimelineAgent* timelineAgent = inspectorAgent->instrumentingAgents()->inspectorTimelineAgent())
timelineAgent->didMarkDOMContentEvent();
+ if (InspectorResourceAgent* resourceAgent = inspectorAgent->instrumentingAgents()->inspectorResourceAgent())
+ resourceAgent->domContentEventFired();
+
if (InspectorPageAgent* pageAgent = inspectorAgent->instrumentingAgents()->inspectorPageAgent())
pageAgent->domContentEventFired();
}
@@ -527,6 +551,9 @@ void InspectorInstrumentation::loadEventFiredImpl(InspectorAgent* inspectorAgent
if (InspectorTimelineAgent* timelineAgent = inspectorAgent->instrumentingAgents()->inspectorTimelineAgent())
timelineAgent->didMarkLoadEvent();
+ if (InspectorResourceAgent* resourceAgent = inspectorAgent->instrumentingAgents()->inspectorResourceAgent())
+ resourceAgent->loadEventFired();
+
if (InspectorPageAgent* pageAgent = inspectorAgent->instrumentingAgents()->inspectorPageAgent())
pageAgent->loadEventFired();
}
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
index 77c464e..d82c6a9 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
@@ -118,7 +118,10 @@ public:
static void didReceiveResourceData(const InspectorInstrumentationCookie&);
static InspectorInstrumentationCookie willReceiveResourceResponse(Frame*, unsigned long identifier, const ResourceResponse&);
static void didReceiveResourceResponse(const InspectorInstrumentationCookie&, unsigned long identifier, DocumentLoader*, const ResourceResponse&);
- static void didReceiveContentLength(Frame*, unsigned long identifier, int dataLength, int lengthReceived);
+ static void continueAfterXFrameOptionsDenied(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void continueWithPolicyDownload(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void continueWithPolicyIgnore(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void didReceiveContentLength(Frame*, unsigned long identifier, int dataLength, int encodedDataLength);
static void didFinishLoading(Frame*, unsigned long identifier, double finishTime);
static void didFailLoading(Frame*, unsigned long identifier, const ResourceError&);
static void resourceRetrievedByXMLHttpRequest(ScriptExecutionContext*, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber);
@@ -234,7 +237,11 @@ private:
static void didReceiveResourceDataImpl(const InspectorInstrumentationCookie&);
static InspectorInstrumentationCookie willReceiveResourceResponseImpl(InspectorAgent*, unsigned long identifier, const ResourceResponse&);
static void didReceiveResourceResponseImpl(const InspectorInstrumentationCookie&, unsigned long identifier, DocumentLoader*, const ResourceResponse&);
- static void didReceiveContentLengthImpl(InspectorAgent*, unsigned long identifier, int dataLength, int lengthReceived);
+ static void didReceiveResourceResponseButCanceledImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void continueAfterXFrameOptionsDeniedImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void continueWithPolicyDownloadImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void continueWithPolicyIgnoreImpl(Frame*, DocumentLoader*, unsigned long identifier, const ResourceResponse&);
+ static void didReceiveContentLengthImpl(InspectorAgent*, unsigned long identifier, int dataLength, int encodedDataLength);
static void didFinishLoadingImpl(InspectorAgent*, unsigned long identifier, double finishTime);
static void didFailLoadingImpl(InspectorAgent*, unsigned long identifier, const ResourceError&);
static void resourceRetrievedByXMLHttpRequestImpl(InspectorAgent*, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber);
@@ -612,7 +619,7 @@ inline void InspectorInstrumentation::applyUserAgentOverride(Frame* frame, Strin
inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* ic = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* ic = inspectorAgentForFrame(frame))
willSendRequestImpl(ic, identifier, loader, request, redirectResponse);
#endif
}
@@ -651,7 +658,7 @@ inline void InspectorInstrumentation::didReceiveResourceData(const InspectorInst
inline InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponse(Frame* frame, unsigned long identifier, const ResourceResponse& response)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
return willReceiveResourceResponseImpl(inspectorAgent, identifier, response);
#endif
return InspectorInstrumentationCookie();
@@ -665,18 +672,42 @@ inline void InspectorInstrumentation::didReceiveResourceResponse(const Inspector
#endif
}
-inline void InspectorInstrumentation::didReceiveContentLength(Frame* frame, unsigned long identifier, int dataLength, int lengthReceived)
+inline void InspectorInstrumentation::continueAfterXFrameOptionsDenied(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
- didReceiveContentLengthImpl(inspectorAgent, identifier, dataLength, lengthReceived);
+ if (inspectorAgentWithFrontendForFrame(frame))
+ InspectorInstrumentation::continueAfterXFrameOptionsDeniedImpl(frame, loader, identifier, r);
+#endif
+}
+
+inline void InspectorInstrumentation::continueWithPolicyDownload(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+#if ENABLE(INSPECTOR)
+ if (inspectorAgentWithFrontendForFrame(frame))
+ InspectorInstrumentation::continueWithPolicyDownloadImpl(frame, loader, identifier, r);
+#endif
+}
+
+inline void InspectorInstrumentation::continueWithPolicyIgnore(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+{
+#if ENABLE(INSPECTOR)
+ if (inspectorAgentWithFrontendForFrame(frame))
+ InspectorInstrumentation::continueWithPolicyIgnoreImpl(frame, loader, identifier, r);
+#endif
+}
+
+inline void InspectorInstrumentation::didReceiveContentLength(Frame* frame, unsigned long identifier, int dataLength, int encodedDataLength)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
+ didReceiveContentLengthImpl(inspectorAgent, identifier, dataLength, encodedDataLength);
#endif
}
inline void InspectorInstrumentation::didFinishLoading(Frame* frame, unsigned long identifier, double finishTime)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
didFinishLoadingImpl(inspectorAgent, identifier, finishTime);
#endif
}
@@ -708,7 +739,7 @@ inline void InspectorInstrumentation::scriptImported(ScriptExecutionContext* con
inline void InspectorInstrumentation::domContentLoadedEventFired(Frame* frame, const KURL& url)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
domContentLoadedEventFiredImpl(inspectorAgent, frame, url);
#endif
}
@@ -716,7 +747,7 @@ inline void InspectorInstrumentation::domContentLoadedEventFired(Frame* frame, c
inline void InspectorInstrumentation::loadEventFired(Frame* frame, const KURL& url)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
loadEventFiredImpl(inspectorAgent, frame, url);
#endif
}
@@ -724,7 +755,7 @@ inline void InspectorInstrumentation::loadEventFired(Frame* frame, const KURL& u
inline void InspectorInstrumentation::frameDetachedFromParent(Frame* frame)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame))
frameDetachedFromParentImpl(inspectorAgent, frame);
#endif
}
@@ -792,7 +823,7 @@ inline void InspectorInstrumentation::didDestroyWorker(ScriptExecutionContext* c
inline void InspectorInstrumentation::didCreateWebSocket(ScriptExecutionContext* context, unsigned long identifier, const KURL& requestURL, const KURL& documentURL)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context))
didCreateWebSocketImpl(inspectorAgent, identifier, requestURL, documentURL);
#endif
}
@@ -800,7 +831,7 @@ inline void InspectorInstrumentation::didCreateWebSocket(ScriptExecutionContext*
inline void InspectorInstrumentation::willSendWebSocketHandshakeRequest(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeRequest& request)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context))
willSendWebSocketHandshakeRequestImpl(inspectorAgent, identifier, request);
#endif
}
@@ -808,7 +839,7 @@ inline void InspectorInstrumentation::willSendWebSocketHandshakeRequest(ScriptEx
inline void InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeResponse& response)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context))
didReceiveWebSocketHandshakeResponseImpl(inspectorAgent, identifier, response);
#endif
}
@@ -816,7 +847,7 @@ inline void InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(Scrip
inline void InspectorInstrumentation::didCloseWebSocket(ScriptExecutionContext* context, unsigned long identifier)
{
#if ENABLE(INSPECTOR)
- if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context))
+ if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context))
didCloseWebSocketImpl(inspectorAgent, identifier);
#endif
}
diff --git a/Source/WebCore/inspector/InspectorPageAgent.cpp b/Source/WebCore/inspector/InspectorPageAgent.cpp
index af053c9..8608543 100644
--- a/Source/WebCore/inspector/InspectorPageAgent.cpp
+++ b/Source/WebCore/inspector/InspectorPageAgent.cpp
@@ -32,7 +32,7 @@
#include "InspectorPageAgent.h"
-#if ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
+#if ENABLE(INSPECTOR)
#include "CachedResourceLoader.h"
#include "Cookie.h"
@@ -93,9 +93,9 @@ void InspectorPageAgent::removeAllScriptsToEvaluateOnLoad(ErrorString*)
m_scriptsToEvaluateOnLoad.clear();
}
-void InspectorPageAgent::reloadPage(ErrorString*, bool ignoreCache)
+void InspectorPageAgent::reloadPage(ErrorString*, const bool* const optionalIgnoreCache)
{
- m_inspectedPage->mainFrame()->loader()->reload(ignoreCache);
+ m_inspectedPage->mainFrame()->loader()->reload(optionalIgnoreCache ? *optionalIgnoreCache : false);
}
void InspectorPageAgent::openInInspectedWindow(ErrorString*, const String& url)
@@ -255,4 +255,4 @@ void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWor
} // namespace WebCore
-#endif // ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InspectorPageAgent.h b/Source/WebCore/inspector/InspectorPageAgent.h
index bb6b96f..233a953 100644
--- a/Source/WebCore/inspector/InspectorPageAgent.h
+++ b/Source/WebCore/inspector/InspectorPageAgent.h
@@ -31,7 +31,7 @@
#ifndef InspectorPageAgent_h
#define InspectorPageAgent_h
-#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
+#if ENABLE(INSPECTOR)
#include "PlatformString.h"
#include <wtf/RefCounted.h>
@@ -58,7 +58,7 @@ public:
// Page API for InspectorFrontend
void addScriptToEvaluateOnLoad(ErrorString*, const String& source);
void removeAllScriptsToEvaluateOnLoad(ErrorString*);
- void reloadPage(ErrorString*, bool ignoreCache);
+ void reloadPage(ErrorString*, const bool* const optionalIgnoreCache);
void openInInspectedWindow(ErrorString*, const String& url);
void setUserAgentOverride(ErrorString*, const String& userAgent);
void getCookies(ErrorString*, RefPtr<InspectorArray>* cookies, WTF::String* cookiesString);
@@ -90,6 +90,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
+#endif // ENABLE(INSPECTOR)
-#endif // !defined(InspectorPageAgent_h)
+#endif // !defined(InspectorPagerAgent_h)
diff --git a/Source/WebCore/inspector/InspectorResourceAgent.cpp b/Source/WebCore/inspector/InspectorResourceAgent.cpp
index 1e2c16d..f200702 100644
--- a/Source/WebCore/inspector/InspectorResourceAgent.cpp
+++ b/Source/WebCore/inspector/InspectorResourceAgent.cpp
@@ -34,21 +34,24 @@
#if ENABLE(INSPECTOR)
#include "Base64.h"
-#include "MemoryCache.h"
#include "CachedResource.h"
#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentLoader.h"
+#include "EventsCollector.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
#include "HTTPHeaderMap.h"
#include "InspectorFrontend.h"
+#include "InspectorFrontendChannel.h"
+#include "InspectorFrontendProxy.h"
#include "InspectorState.h"
#include "InspectorValues.h"
#include "InstrumentingAgents.h"
#include "KURL.h"
+#include "MemoryCache.h"
#include "Page.h"
#include "ProgressTracker.h"
#include "ResourceError.h"
@@ -74,14 +77,36 @@ static const char resourceAgentEnabled[] = "resourceAgentEnabled";
static const char extraRequestHeaders[] = "extraRequestHeaders";
}
+namespace ResourceType {
+static const char document[] = "Document";
+static const char stylesheet[] = "Stylesheet";
+static const char image[] = "Image";
+static const char font[] = "Font";
+static const char script[] = "Script";
+static const char xhr[] = "XHR";
+static const char websocket[] = "WebSocket";
+static const char other[] = "Other";
+}
+
void InspectorResourceAgent::setFrontend(InspectorFrontend* frontend)
{
m_frontend = frontend->network();
+ if (backgroundEventsCollectionEnabled()) {
+ // Insert Message Proxy in receiver chain.
+ InspectorFrontendChannel* client = m_frontend->getInspectorFrontendChannel();
+ m_inspectorFrontendProxy->setInspectorFrontendChannel(client);
+ m_frontend->setInspectorFrontendChannel(m_inspectorFrontendProxy.get());
+ m_eventsCollector->sendCollectedEvents(client);
+ }
}
void InspectorResourceAgent::clearFrontend()
{
- m_frontend = 0;
+ if (backgroundEventsCollectionEnabled()) {
+ m_inspectorFrontendProxy->setInspectorFrontendChannel(0);
+ m_frontend = m_mockFrontend.get();
+ } else
+ m_frontend = 0;
disable(0);
}
@@ -94,7 +119,7 @@ void InspectorResourceAgent::restore()
void InspectorResourceAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result)
{
if (!frame) {
- *errorString = "No frame to get resource content for.";
+ *errorString = "No frame to get resource content for";
return;
}
@@ -108,7 +133,7 @@ void InspectorResourceAgent::resourceContent(ErrorString* errorString, Frame* fr
*result = encoding.decode(buffer->data(), buffer->size());
return;
}
- *errorString = "No resource with given URL found.";
+ *errorString = "No resource with given URL found";
}
void InspectorResourceAgent::resourceContentBase64(ErrorString* errorString, Frame* frame, const KURL& url, String* result)
@@ -117,7 +142,7 @@ void InspectorResourceAgent::resourceContentBase64(ErrorString* errorString, Fra
RefPtr<SharedBuffer> data = InspectorResourceAgent::resourceData(frame, url, &textEncodingName);
if (!data) {
*result = String();
- *errorString = "No resource with given URL found.";
+ *errorString = "No resource with given URL found";
return;
}
@@ -204,13 +229,12 @@ static PassRefPtr<InspectorObject> buildObjectForResourceRequest(const ResourceR
static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const ResourceResponse& response)
{
- RefPtr<InspectorObject> responseObject = InspectorObject::create();
if (response.isNull())
- return responseObject;
+ return 0;
+ RefPtr<InspectorObject> responseObject = InspectorObject::create();
responseObject->setNumber("status", response.resourceLoadInfo() ? response.resourceLoadInfo()->httpStatusCode : response.httpStatusCode());
responseObject->setString("statusText", response.resourceLoadInfo() ? response.resourceLoadInfo()->httpStatusText : response.httpStatusText());
- responseObject->setObject("headers", buildObjectForHeaders(response.resourceLoadInfo() ? response.resourceLoadInfo()->responseHeaders : response.httpHeaderFields()));
responseObject->setString("mimeType", response.mimeType());
responseObject->setBoolean("connectionReused", response.connectionReused());
@@ -219,8 +243,16 @@ static PassRefPtr<InspectorObject> buildObjectForResourceResponse(const Resource
if (response.resourceLoadTiming())
responseObject->setObject("timing", buildObjectForTiming(*response.resourceLoadTiming()));
- if (response.resourceLoadInfo())
+ if (response.resourceLoadInfo()) {
+ responseObject->setObject("headers", buildObjectForHeaders(response.resourceLoadInfo()->responseHeaders));
+ if (!response.resourceLoadInfo()->responseHeadersText.isEmpty())
+ responseObject->setString("headersText", response.resourceLoadInfo()->responseHeadersText);
+
responseObject->setObject("requestHeaders", buildObjectForHeaders(response.resourceLoadInfo()->requestHeaders));
+ if (!response.resourceLoadInfo()->requestHeadersText.isEmpty())
+ responseObject->setString("requestHeadersText", response.resourceLoadInfo()->requestHeadersText);
+ } else
+ responseObject->setObject("headers", buildObjectForHeaders(response.httpHeaderFields()));
return responseObject;
}
@@ -236,21 +268,21 @@ static String cachedResourceTypeString(const CachedResource& cachedResource)
{
switch (cachedResource.type()) {
case CachedResource::ImageResource:
- return "Image";
+ return ResourceType::image;
case CachedResource::FontResource:
- return "Font";
+ return ResourceType::font;
case CachedResource::CSSStyleSheet:
// Fall through.
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
#endif
- return "Stylesheet";
+ return ResourceType::stylesheet;
case CachedResource::Script:
- return "Script";
+ return ResourceType::script;
default:
break;
}
- return "Other";
+ return ResourceType::other;
}
static PassRefPtr<InspectorObject> buildObjectForCachedResource(const CachedResource& cachedResource)
@@ -259,12 +291,18 @@ static PassRefPtr<InspectorObject> buildObjectForCachedResource(const CachedReso
resourceObject->setString("url", cachedResource.url());
resourceObject->setString("type", cachedResourceTypeString(cachedResource));
resourceObject->setNumber("bodySize", cachedResource.encodedSize());
- resourceObject->setObject("response", buildObjectForResourceResponse(cachedResource.response()));
+ RefPtr<InspectorObject> resourceResponse = buildObjectForResourceResponse(cachedResource.response());
+ if (resourceResponse)
+ resourceObject->setObject("response", resourceResponse);
return resourceObject;
}
InspectorResourceAgent::~InspectorResourceAgent()
{
+ if (m_state->getBoolean(ResourceAgentState::resourceAgentEnabled)) {
+ ErrorString error;
+ disable(&error);
+ }
ASSERT(!m_instrumentingAgents->inspectorResourceAgent());
}
@@ -290,7 +328,7 @@ void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentL
callStackValue = callStack->buildInspectorArray();
else
callStackValue = InspectorArray::create();
- m_frontend->requestWillBeSent(static_cast<int>(identifier), pointerAsId(loader->frame()), pointerAsId(loader), loader->url().string(), buildObjectForResourceRequest(request), buildObjectForResourceResponse(redirectResponse), currentTime(), callStackValue);
+ m_frontend->requestWillBeSent(static_cast<int>(identifier), pointerAsId(loader->frame()), pointerAsId(loader), loader->url().string(), buildObjectForResourceRequest(request), currentTime(), callStackValue, buildObjectForResourceResponse(redirectResponse));
}
void InspectorResourceAgent::markResourceAsCached(unsigned long identifier)
@@ -314,9 +352,9 @@ void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, Docume
resourceResponse->setString("mimeType", cachedResource->response().mimeType());
}
if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL()))
- type = "Image";
+ type = ResourceType::image;
else if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == "Other")
- type = "Document";
+ type = ResourceType::document;
}
m_frontend->responseReceived(static_cast<int>(identifier), currentTime(), type, resourceResponse);
// If we revalidated the resource and got Not modified, send content length following didReceiveResponse
@@ -325,9 +363,9 @@ void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, Docume
didReceiveContentLength(identifier, cachedResourceSize, 0);
}
-void InspectorResourceAgent::didReceiveContentLength(unsigned long identifier, int dataLength, int lengthReceived)
+void InspectorResourceAgent::didReceiveContentLength(unsigned long identifier, int dataLength, int encodedDataLength)
{
- m_frontend->dataReceived(static_cast<int>(identifier), currentTime(), dataLength, lengthReceived);
+ m_frontend->dataReceived(static_cast<int>(identifier), currentTime(), dataLength, encodedDataLength);
}
void InspectorResourceAgent::didFinishLoading(unsigned long identifier, double finishTime)
@@ -340,7 +378,7 @@ void InspectorResourceAgent::didFinishLoading(unsigned long identifier, double f
void InspectorResourceAgent::didFailLoading(unsigned long identifier, const ResourceError& error)
{
- m_frontend->loadingFailed(static_cast<int>(identifier), currentTime(), error.localizedDescription());
+ m_frontend->loadingFailed(static_cast<int>(identifier), currentTime(), error.localizedDescription(), error.isCancellation());
}
void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* resource)
@@ -348,9 +386,24 @@ void InspectorResourceAgent::didLoadResourceFromMemoryCache(DocumentLoader* load
m_frontend->resourceLoadedFromMemoryCache(pointerAsId(loader->frame()), pointerAsId(loader), loader->url().string(), currentTime(), buildObjectForCachedResource(*resource));
}
-void InspectorResourceAgent::setInitialContent(unsigned long identifier, const String& sourceString, const String& type)
+void InspectorResourceAgent::setInitialScriptContent(unsigned long identifier, const String& sourceString)
{
- m_frontend->initialContentSet(static_cast<int>(identifier), sourceString, type);
+ m_frontend->initialContentSet(static_cast<int>(identifier), sourceString, ResourceType::script);
+}
+
+void InspectorResourceAgent::setInitialXHRContent(unsigned long identifier, const String& sourceString)
+{
+ m_frontend->initialContentSet(static_cast<int>(identifier), sourceString, ResourceType::xhr);
+}
+
+void InspectorResourceAgent::domContentEventFired()
+{
+ m_frontend->domContentEventFired(currentTime());
+}
+
+void InspectorResourceAgent::loadEventFired()
+{
+ m_frontend->loadEventFired(currentTime());
}
static PassRefPtr<InspectorObject> buildObjectForFrame(Frame* frame)
@@ -465,6 +518,14 @@ Frame* InspectorResourceAgent::frameForId(const String& frameId)
return 0;
}
+bool InspectorResourceAgent::backgroundEventsCollectionEnabled()
+{
+ // FIXME (https://bugs.webkit.org/show_bug.cgi?id=58652)
+ // Add here condition to enable background events collection.
+ // Now this function is disable.
+ return false;
+}
+
void InspectorResourceAgent::enable(ErrorString*)
{
enable();
@@ -489,14 +550,14 @@ void InspectorResourceAgent::getCachedResources(ErrorString*, RefPtr<InspectorOb
*object = buildObjectForFrameTree(m_page->mainFrame());
}
-void InspectorResourceAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, bool base64Encode, String* content)
+void InspectorResourceAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, const bool* const optionalBase64Encode, String* content)
{
Frame* frame = frameForId(frameId);
if (!frame) {
- *errorString = "No frame for given id found.";
+ *errorString = "No frame for given id found";
return;
}
- if (base64Encode)
+ if (optionalBase64Encode ? *optionalBase64Encode : false)
InspectorResourceAgent::resourceContentBase64(errorString, frame, KURL(ParsedURLString, url), content);
else
InspectorResourceAgent::resourceContent(errorString, frame, KURL(ParsedURLString, url), content);
@@ -511,8 +572,16 @@ InspectorResourceAgent::InspectorResourceAgent(InstrumentingAgents* instrumentin
: m_instrumentingAgents(instrumentingAgents)
, m_page(page)
, m_state(state)
- , m_frontend(0)
{
+ if (backgroundEventsCollectionEnabled()) {
+ m_eventsCollector = new EventsCollector();
+ m_inspectorFrontendProxy = new InspectorFrontendProxy(m_eventsCollector.get());
+ // Create mock frontend, so we can collect network events.
+ m_mockFrontend = new InspectorFrontend::Network(m_inspectorFrontendProxy.get());
+ m_frontend = m_mockFrontend.get();
+ enable();
+ } else
+ m_frontend = 0;
}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorResourceAgent.h b/Source/WebCore/inspector/InspectorResourceAgent.h
index c919469..dff7e3a 100644
--- a/Source/WebCore/inspector/InspectorResourceAgent.h
+++ b/Source/WebCore/inspector/InspectorResourceAgent.h
@@ -34,6 +34,7 @@
#include "InspectorFrontend.h"
#include "PlatformString.h"
+#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -51,10 +52,12 @@ class DocumentLoader;
class Frame;
class InspectorArray;
class InspectorFrontend;
+class InspectorFrontendProxy;
class InspectorObject;
class InspectorState;
class InstrumentingAgents;
class KURL;
+class EventsCollector;
class Page;
class ResourceError;
class ResourceRequest;
@@ -91,11 +94,14 @@ public:
void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
void markResourceAsCached(unsigned long identifier);
void didReceiveResponse(unsigned long identifier, DocumentLoader* laoder, const ResourceResponse&);
- void didReceiveContentLength(unsigned long identifier, int dataLength, int lengthReceived);
+ void didReceiveContentLength(unsigned long identifier, int dataLength, int encodedDataLength);
void didFinishLoading(unsigned long identifier, double finishTime);
void didFailLoading(unsigned long identifier, const ResourceError&);
void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
- void setInitialContent(unsigned long identifier, const String& sourceString, const String& type);
+ void setInitialScriptContent(unsigned long identifier, const String& sourceString);
+ void setInitialXHRContent(unsigned long identifier, const String& sourceString);
+ void domContentEventFired();
+ void loadEventFired();
void didCommitLoad(DocumentLoader*);
void frameDetachedFromParent(Frame*);
@@ -107,12 +113,13 @@ public:
#endif
Frame* frameForId(const String& frameId);
+ bool backgroundEventsCollectionEnabled();
// Called from frontend
void enable(ErrorString*);
void disable(ErrorString*);
void getCachedResources(ErrorString*, RefPtr<InspectorObject>*);
- void getResourceContent(ErrorString*, const String& frameId, const String& url, bool base64Encode, String* content);
+ void getResourceContent(ErrorString*, const String& frameId, const String& url, const bool* const base64Encode, String* content);
void setExtraHeaders(ErrorString*, PassRefPtr<InspectorObject>);
private:
@@ -123,7 +130,10 @@ private:
InstrumentingAgents* m_instrumentingAgents;
Page* m_page;
InspectorState* m_state;
+ OwnPtr<EventsCollector> m_eventsCollector;
InspectorFrontend::Network* m_frontend;
+ OwnPtr<InspectorFrontend::Network> m_mockFrontend;
+ OwnPtr<InspectorFrontendProxy> m_inspectorFrontendProxy;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.cpp b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp
index 04fed9d..f139071 100644
--- a/Source/WebCore/inspector/InspectorRuntimeAgent.cpp
+++ b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp
@@ -36,20 +36,12 @@
#include "InjectedScript.h"
#include "InjectedScriptManager.h"
#include "InspectorValues.h"
-#include "Page.h"
-#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
namespace WebCore {
-PassOwnPtr<InspectorRuntimeAgent> InspectorRuntimeAgent::create(InjectedScriptManager* injectedScriptManager, Page* inspectedPage)
-{
- return adoptPtr(new InspectorRuntimeAgent(injectedScriptManager, inspectedPage));
-}
-
-InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScriptManager, Page* inspectedPage)
+InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScriptManager)
: m_injectedScriptManager(injectedScriptManager)
- , m_inspectedPage(inspectedPage)
{
}
@@ -57,12 +49,11 @@ InspectorRuntimeAgent::~InspectorRuntimeAgent()
{
}
-void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
+void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, RefPtr<InspectorObject>* result)
{
- ScriptState* scriptState = mainWorldScriptState(m_inspectedPage->mainFrame());
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(getDefaultInspectedState());
if (!injectedScript.hasNoValue())
- injectedScript.evaluate(errorString, expression, objectGroup, includeCommandLineAPI, result);
+ injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, result);
}
void InspectorRuntimeAgent::evaluateOn(ErrorString* errorString, const String& objectId, const String& expression, RefPtr<InspectorObject>* result)
@@ -72,11 +63,11 @@ void InspectorRuntimeAgent::evaluateOn(ErrorString* errorString, const String& o
injectedScript.evaluateOn(errorString, objectId, expression, result);
}
-void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorArray>* result)
+void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
if (!injectedScript.hasNoValue())
- injectedScript.getProperties(errorString, objectId, ignoreHasOwnProperty, abbreviate, result);
+ injectedScript.getProperties(errorString, objectId, ignoreHasOwnProperty, result);
}
void InspectorRuntimeAgent::setPropertyValue(ErrorString* errorString, const String& objectId, const String& propertyName, const String& expression)
@@ -85,7 +76,7 @@ void InspectorRuntimeAgent::setPropertyValue(ErrorString* errorString, const Str
if (!injectedScript.hasNoValue())
injectedScript.setPropertyValue(errorString, objectId, propertyName, expression);
else
- *errorString = "No injected script found.";
+ *errorString = "No injected script found";
}
void InspectorRuntimeAgent::releaseObject(ErrorString*, const String& objectId)
diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.h b/Source/WebCore/inspector/InspectorRuntimeAgent.h
index 48f3670..406707f 100644
--- a/Source/WebCore/inspector/InspectorRuntimeAgent.h
+++ b/Source/WebCore/inspector/InspectorRuntimeAgent.h
@@ -33,6 +33,7 @@
#if ENABLE(INSPECTOR)
+#include "ScriptState.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -42,29 +43,28 @@ class InjectedScriptManager;
class InspectorArray;
class InspectorObject;
class InspectorValue;
-class Page;
typedef String ErrorString;
class InspectorRuntimeAgent {
WTF_MAKE_NONCOPYABLE(InspectorRuntimeAgent);
public:
- static PassOwnPtr<InspectorRuntimeAgent> create(InjectedScriptManager*, Page*);
- ~InspectorRuntimeAgent();
+ virtual ~InspectorRuntimeAgent();
// Part of the protocol.
- void evaluate(ErrorString*, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
+ void evaluate(ErrorString*, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, RefPtr<InspectorObject>* result);
void evaluateOn(ErrorString*, const String& objectId, const String& expression, RefPtr<InspectorObject>* result);
void releaseObject(ErrorString*, const String& objectId);
- void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorArray>* result);
+ void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result);
void setPropertyValue(ErrorString*, const String& objectId, const String& propertyName, const String& expression);
void releaseObjectGroup(ErrorString*, const String& objectGroup);
-private:
- InspectorRuntimeAgent(InjectedScriptManager*, Page*);
+protected:
+ explicit InspectorRuntimeAgent(InjectedScriptManager*);
+ virtual ScriptState* getDefaultInspectedState() = 0;
+private:
InjectedScriptManager* m_injectedScriptManager;
- Page* m_inspectedPage;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorState.cpp b/Source/WebCore/inspector/InspectorState.cpp
index 2988cf2..02614a0 100644
--- a/Source/WebCore/inspector/InspectorState.cpp
+++ b/Source/WebCore/inspector/InspectorState.cpp
@@ -64,7 +64,7 @@ void InspectorState::unmute()
void InspectorState::updateCookie()
{
- if (!m_isOnMute)
+ if (m_client && !m_isOnMute)
m_client->updateInspectorStateCookie(m_properties->toJSONString());
}
diff --git a/Source/WebCore/inspector/InspectorStyleSheet.cpp b/Source/WebCore/inspector/InspectorStyleSheet.cpp
index 342cf54..2edb8a1 100644
--- a/Source/WebCore/inspector/InspectorStyleSheet.cpp
+++ b/Source/WebCore/inspector/InspectorStyleSheet.cpp
@@ -102,6 +102,14 @@ RefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned i
namespace WebCore {
+static PassRefPtr<InspectorObject> buildSourceRangeObject(const SourceRange& range)
+{
+ RefPtr<InspectorObject> result = InspectorObject::create();
+ result->setNumber("start", range.start);
+ result->setNumber("end", range.end);
+ return result.release();
+}
+
static PassRefPtr<CSSRuleList> asCSSRuleList(StyleBase* styleBase)
{
if (!styleBase)
@@ -154,16 +162,12 @@ PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
if (!m_styleId.isEmpty())
result->setValue("styleId", m_styleId.asInspectorValue());
- RefPtr<InspectorObject> propertiesObject = InspectorObject::create();
- propertiesObject->setString("width", m_style->getPropertyValue("width"));
- propertiesObject->setString("height", m_style->getPropertyValue("height"));
+ result->setString("width", m_style->getPropertyValue("width"));
+ result->setString("height", m_style->getPropertyValue("height"));
RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0;
- if (sourceData) {
- propertiesObject->setNumber("startOffset", sourceData->styleSourceData->styleBodyRange.start);
- propertiesObject->setNumber("endOffset", sourceData->styleSourceData->styleBodyRange.end);
- }
- result->setObject("properties", propertiesObject);
+ if (sourceData)
+ result->setObject("range", buildSourceRangeObject(sourceData->styleSourceData->styleBodyRange));
populateObjectWithStyleProperties(result.get());
@@ -176,11 +180,13 @@ PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
//
// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not,
// the method returns false (denoting an error).
-bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite)
+bool InspectorStyle::setPropertyText(ErrorString* errorString, unsigned index, const String& propertyText, bool overwrite)
{
ASSERT(m_parentStyleSheet);
- if (!m_parentStyleSheet->ensureParsedDataReady())
+ if (!m_parentStyleSheet->ensureParsedDataReady()) {
+ *errorString = "Internal error: no stylesheet parsed data available";
return false;
+ }
Vector<InspectorStyleProperty> allProperties;
populateAllProperties(&allProperties);
@@ -197,12 +203,16 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
unsigned propertyCount = propertyData.size();
// At least one property + the bogus property added just above should be present.
- if (propertyCount < 2)
+ if (propertyCount < 2) {
+ *errorString = "Invalid property value";
return false;
+ }
// Check for a proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
- if (propertyData.at(propertyCount - 1).name != "-webkit-boguz-propertee")
+ if (propertyData.at(propertyCount - 1).name != "-webkit-boguz-propertee") {
+ *errorString = "Invalid property value";
return false;
+ }
}
if (overwrite) {
@@ -216,8 +226,10 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
if (!property.disabled) {
bool success = replacePropertyInStyleText(property, propertyText);
- if (!success)
+ if (!success) {
+ *errorString = "Internal error: could not replace property value";
return false;
+ }
} else {
unsigned textLength = propertyText.length();
unsigned disabledIndex = disabledIndexByOrdinal(index, false, allProperties);
@@ -235,12 +247,16 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
} else {
// Insert at index.
RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
- if (!sourceData)
+ if (!sourceData) {
+ *errorString = "Internal error: no CSS rule source found";
return false;
+ }
String text;
bool success = styleText(&text);
- if (!success)
+ if (!success) {
+ *errorString = "Internal error: could not fetch style text";
return false;
+ }
propertyLengthDelta = propertyText.length();
bool insertLast = true;
@@ -283,19 +299,25 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText,
return true;
}
-bool InspectorStyle::toggleProperty(unsigned index, bool disable)
+bool InspectorStyle::toggleProperty(ErrorString* errorString, unsigned index, bool disable)
{
ASSERT(m_parentStyleSheet);
- if (!m_parentStyleSheet->ensureParsedDataReady())
- return false; // Can toggle only source-based properties.
+ if (!m_parentStyleSheet->ensureParsedDataReady()) {
+ *errorString = "Can toggle only source-based properties";
+ return false;
+ }
RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
- if (!sourceData)
- return false; // No source data for the style.
+ if (!sourceData) {
+ *errorString = "Internal error: No source data for the style found";
+ return false;
+ }
Vector<InspectorStyleProperty> allProperties;
populateAllProperties(&allProperties);
- if (index >= allProperties.size())
- return false; // Outside of property range.
+ if (index >= allProperties.size()) {
+ *errorString = "Property index is outside of property range";
+ return false;
+ }
InspectorStyleProperty& property = allProperties.at(index);
if (property.disabled == disable)
@@ -413,7 +435,7 @@ bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* resul
InspectorStyleProperty p(*it, true, false);
p.setRawTextFromStyleDeclaration(styleDeclaration);
result->append(p);
- sourcePropertyNames.add(it->name);
+ sourcePropertyNames.add(it->name.lower());
}
}
@@ -424,10 +446,10 @@ bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* resul
for (int i = 0, size = m_style->length(); i < size; ++i) {
String name = m_style->item(i);
- if (sourcePropertyNames.contains(name))
+ if (sourcePropertyNames.contains(name.lower()))
continue;
- sourcePropertyNames.add(name);
+ sourcePropertyNames.add(name.lower());
result->append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), true, SourceRange()), false, false));
}
@@ -440,7 +462,7 @@ void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result)
populateAllProperties(&properties);
RefPtr<InspectorArray> propertiesObject = InspectorArray::create();
- RefPtr<InspectorObject> shorthandValues = InspectorObject::create();
+ RefPtr<InspectorArray> shorthandEntries = InspectorArray::create();
HashMap<String, RefPtr<InspectorObject> > propertyNameToPreviousActiveProperty;
HashSet<String> foundShorthands;
@@ -466,8 +488,7 @@ void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result)
if (!it->disabled) {
if (it->hasSource) {
property->setBoolean("implicit", false);
- property->setNumber("startOffset", propertyEntry.range.start);
- property->setNumber("endOffset", propertyEntry.range.end);
+ property->setObject("range", buildSourceRangeObject(propertyEntry.range));
// Parsed property overrides any property with the same name. Non-parsed property overrides
// previous non-parsed property with the same name (if any).
@@ -511,7 +532,10 @@ void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result)
property->setString("shorthandName", shorthand);
if (!foundShorthands.contains(shorthand)) {
foundShorthands.add(shorthand);
- shorthandValues->setString(shorthand, shorthandValue(shorthand));
+ RefPtr<InspectorObject> shorthandEntry = InspectorObject::create();
+ shorthandEntry->setString("name", shorthand);
+ shorthandEntry->setString("value", shorthandValue(shorthand));
+ shorthandEntries->pushObject(shorthandEntry.release());
}
}
}
@@ -519,7 +543,7 @@ void InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result)
}
result->setArray("cssProperties", propertiesObject);
- result->setObject("shorthandValues", shorthandValues);
+ result->setArray("shorthandEntries", shorthandEntries);
}
@@ -799,22 +823,26 @@ PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyle(CSSStyleDec
return result.release();
}
-bool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite)
+bool InspectorStyleSheet::setPropertyText(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite)
{
RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- if (!inspectorStyle)
+ if (!inspectorStyle) {
+ *errorString = "No style found for given id";
return false;
+ }
- return inspectorStyle->setPropertyText(propertyIndex, text, overwrite);
+ return inspectorStyle->setPropertyText(errorString, propertyIndex, text, overwrite);
}
-bool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned propertyIndex, bool disable)
+bool InspectorStyleSheet::toggleProperty(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, bool disable)
{
RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- if (!inspectorStyle)
+ if (!inspectorStyle) {
+ *errorString = "No style found for given id";
return false;
+ }
- bool success = inspectorStyle->toggleProperty(propertyIndex, disable);
+ bool success = inspectorStyle->toggleProperty(errorString, propertyIndex, disable);
if (success) {
if (disable)
rememberInspectorStyle(inspectorStyle);
diff --git a/Source/WebCore/inspector/InspectorStyleSheet.h b/Source/WebCore/inspector/InspectorStyleSheet.h
index 3048b1b..f98b49e 100644
--- a/Source/WebCore/inspector/InspectorStyleSheet.h
+++ b/Source/WebCore/inspector/InspectorStyleSheet.h
@@ -49,6 +49,8 @@ class Node;
#if ENABLE(INSPECTOR)
+typedef String ErrorString;
+
class InspectorCSSId {
public:
InspectorCSSId() { }
@@ -127,8 +129,8 @@ public:
CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
PassRefPtr<InspectorObject> buildObjectForStyle() const;
bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); }
- bool setPropertyText(unsigned index, const String& text, bool overwrite);
- bool toggleProperty(unsigned index, bool disable);
+ bool setPropertyText(ErrorString*, unsigned index, const String& text, bool overwrite);
+ bool toggleProperty(ErrorString*, unsigned index, bool disable);
private:
InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
@@ -171,8 +173,8 @@ public:
PassRefPtr<InspectorObject> buildObjectForStyleSheetInfo();
PassRefPtr<InspectorObject> buildObjectForRule(CSSStyleRule*);
PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*);
- bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite);
- bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable);
+ bool setPropertyText(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite);
+ bool toggleProperty(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, bool disable);
virtual bool text(String* result) const;
virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
diff --git a/Source/WebCore/inspector/ScriptBreakpoint.h b/Source/WebCore/inspector/ScriptBreakpoint.h
index 4917aef..920fb3f 100644
--- a/Source/WebCore/inspector/ScriptBreakpoint.h
+++ b/Source/WebCore/inspector/ScriptBreakpoint.h
@@ -39,18 +39,16 @@ struct ScriptBreakpoint {
{
}
- ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool enabled)
+ ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition)
: lineNumber(lineNumber)
, columnNumber(columnNumber)
, condition(condition)
- , enabled(enabled)
{
}
int lineNumber;
int columnNumber;
String condition;
- bool enabled;
};
} // namespace WebCore
diff --git a/Source/WebCore/inspector/ScriptCallFrame.cpp b/Source/WebCore/inspector/ScriptCallFrame.cpp
index 0b5204b..641d192 100644
--- a/Source/WebCore/inspector/ScriptCallFrame.cpp
+++ b/Source/WebCore/inspector/ScriptCallFrame.cpp
@@ -60,9 +60,9 @@ PassRefPtr<InspectorObject> ScriptCallFrame::buildInspectorObject() const
{
RefPtr<InspectorObject> frame = InspectorObject::create();
frame->setString("functionName", m_functionName);
- frame->setString("scriptName", m_scriptName);
+ frame->setString("url", m_scriptName);
frame->setNumber("lineNumber", m_lineNumber);
- frame->setNumber("column", m_column);
+ frame->setNumber("columnNumber", m_column);
return frame;
}
#endif
diff --git a/Source/WebCore/inspector/ScriptDebugListener.h b/Source/WebCore/inspector/ScriptDebugListener.h
index a28cabb..4a93a4c 100644
--- a/Source/WebCore/inspector/ScriptDebugListener.h
+++ b/Source/WebCore/inspector/ScriptDebugListener.h
@@ -37,16 +37,11 @@
namespace WebCore {
-enum ScriptWorldType {
-MAIN_WORLD = 0,
-EXTENSIONS_WORLD
-};
-
class ScriptDebugListener {
public:
virtual ~ScriptDebugListener() { }
- virtual void didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, ScriptWorldType) = 0;
+ virtual void didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, bool isContentScript) = 0;
virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
virtual void didPause(ScriptState*) = 0;
virtual void didContinue() = 0;
diff --git a/Source/WebCore/inspector/WorkerDebuggerAgent.cpp b/Source/WebCore/inspector/WorkerDebuggerAgent.cpp
index afd00a5..14bde38 100755
--- a/Source/WebCore/inspector/WorkerDebuggerAgent.cpp
+++ b/Source/WebCore/inspector/WorkerDebuggerAgent.cpp
@@ -54,10 +54,12 @@ WorkerDebuggerAgent::~WorkerDebuggerAgent()
void WorkerDebuggerAgent::startListeningScriptDebugServer()
{
+ scriptDebugServer().addListener(this, m_inspectedWorkerContext);
}
void WorkerDebuggerAgent::stopListeningScriptDebugServer()
{
+ scriptDebugServer().removeListener(this, m_inspectedWorkerContext);
}
WorkerScriptDebugServer& WorkerDebuggerAgent::scriptDebugServer()
diff --git a/Source/WebCore/inspector/WorkerInspectorController.cpp b/Source/WebCore/inspector/WorkerInspectorController.cpp
new file mode 100644
index 0000000..383cb04
--- /dev/null
+++ b/Source/WebCore/inspector/WorkerInspectorController.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(INSPECTOR) && ENABLE(WORKERS)
+
+#include "WorkerInspectorController.h"
+
+#include "InjectedScriptHost.h"
+#include "InjectedScriptManager.h"
+#include "InspectorBackendDispatcher.h"
+#include "InspectorClient.h"
+#include "InspectorFrontend.h"
+#include "InspectorFrontendChannel.h"
+#include "InspectorRuntimeAgent.h"
+#include "InspectorState.h"
+#include "InstrumentingAgents.h"
+#include "WorkerDebuggerAgent.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+namespace {
+
+class WorkerRuntimeAgent : public InspectorRuntimeAgent {
+public:
+ WorkerRuntimeAgent(InjectedScriptManager* injectedScriptManager, WorkerContext* workerContext)
+ : InspectorRuntimeAgent(injectedScriptManager)
+ , m_workerContext(workerContext) { }
+ virtual ~WorkerRuntimeAgent() { }
+
+private:
+ virtual ScriptState* getDefaultInspectedState()
+ {
+ return scriptStateFromWorkerContext(m_workerContext);
+ }
+
+ WorkerContext* m_workerContext;
+};
+
+}
+
+WorkerInspectorController::WorkerInspectorController(WorkerContext* workerContext)
+ : m_workerContext(workerContext)
+ , m_state(new InspectorState(0))
+ , m_instrumentingAgents(new InstrumentingAgents())
+ , m_injectedScriptManager(InjectedScriptManager::createForWorker())
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ , m_debuggerAgent(WorkerDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), workerContext, m_injectedScriptManager.get()))
+#endif
+ , m_runtimeAgent(adoptPtr(new WorkerRuntimeAgent(m_injectedScriptManager.get(), workerContext)))
+{
+ m_injectedScriptManager->injectedScriptHost()->init(0
+ , 0
+#if ENABLE(DATABASE)
+ , 0
+#endif
+#if ENABLE(DOM_STORAGE)
+ , 0
+#endif
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ , m_debuggerAgent.get()
+#endif
+ );
+}
+
+WorkerInspectorController::~WorkerInspectorController()
+{
+}
+
+void WorkerInspectorController::connectFrontend(InspectorFrontendChannel* channel)
+{
+ ASSERT(!m_frontend);
+ m_state->unmute();
+ m_frontend = new InspectorFrontend(channel);
+ m_backendDispatcher = new InspectorBackendDispatcher(
+ channel,
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ 0, // InspectorApplicationCacheAgent
+#endif
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ 0, // InspectorBrowserDebuggerAgent
+#endif
+ 0, // InspectorCSSAgent
+ 0, // InspectorConsoleAgent
+ 0, // InspectorDOMAgent
+#if ENABLE(DOM_STORAGE)
+ 0, // InspectorDOMStorageAgent
+#endif
+#if ENABLE(DATABASE)
+ 0, // InspectorDatabaseAgent
+#endif
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_debuggerAgent.get(),
+#endif
+ 0, // InspectorResourceAgent
+ 0, // InspectorPageAgent
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ 0, // InspectorProfilerAgent
+#endif
+ m_runtimeAgent.get(),
+ 0 // InspectorTimelineAgent
+ );
+
+ m_injectedScriptManager->injectedScriptHost()->setFrontend(m_frontend.get());
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_debuggerAgent->setFrontend(m_frontend.get());
+#endif
+}
+
+void WorkerInspectorController::disconnectFrontend()
+{
+ if (!m_frontend)
+ return;
+ m_backendDispatcher.clear();
+ // Destroying agents would change the state, but we don't want that.
+ // Pre-disconnect state will be used to restore inspector agents.
+ m_state->mute();
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_debuggerAgent->clearFrontend();
+#endif
+ m_injectedScriptManager->injectedScriptHost()->clearFrontend();
+
+ m_frontend.clear();
+}
+
+void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
+{
+ if (m_backendDispatcher)
+ m_backendDispatcher->dispatch(message);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/inspector/WorkerInspectorController.h b/Source/WebCore/inspector/WorkerInspectorController.h
new file mode 100644
index 0000000..404c5a6
--- /dev/null
+++ b/Source/WebCore/inspector/WorkerInspectorController.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef WorkerInspectorController_h
+#define WorkerInspectorController_h
+
+#if ENABLE(INSPECTOR) && ENABLE(WORKERS)
+
+#include <wtf/FastAllocBase.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class InjectedScriptManager;
+class InspectorDebuggerAgent;
+class InspectorBackendDispatcher;
+class InspectorFrontend;
+class InspectorFrontendChannel;
+class InspectorInstrumentation;
+class InspectorRuntimeAgent;
+class InspectorState;
+class InstrumentingAgents;
+class WorkerContext;
+
+class WorkerInspectorController {
+ WTF_MAKE_NONCOPYABLE(WorkerInspectorController);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ WorkerInspectorController(WorkerContext*);
+ ~WorkerInspectorController();
+
+ void connectFrontend(InspectorFrontendChannel*);
+ void disconnectFrontend();
+ void dispatchMessageFromFrontend(const String&);
+
+private:
+ WorkerContext* m_workerContext;
+ OwnPtr<InspectorState> m_state;
+ OwnPtr<InstrumentingAgents> m_instrumentingAgents;
+ OwnPtr<InjectedScriptManager> m_injectedScriptManager;
+ OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
+ OwnPtr<InspectorRuntimeAgent> m_runtimeAgent;
+
+ OwnPtr<InspectorFrontend> m_frontend;
+ OwnPtr<InspectorBackendDispatcher> m_backendDispatcher;
+};
+
+}
+
+#endif // ENABLE(WORKERS)
+
+#endif // !defined(WorkerInspectorController_h)
diff --git a/Source/WebCore/inspector/combine-javascript-resources.pl b/Source/WebCore/inspector/combine-javascript-resources.pl
new file mode 100755
index 0000000..428b6b7
--- /dev/null
+++ b/Source/WebCore/inspector/combine-javascript-resources.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2008 Apple Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to combine multiple JavaScript files into one file, based on
+# the script tags in the head of an input HTML file.
+
+use strict;
+use Getopt::Long;
+use File::Basename;
+use File::Path;
+
+my $generatedScriptsDirectory;
+my $outputDirectory;
+my $scriptName;
+my $htmlFile;
+
+GetOptions('output-dir=s' => \$outputDirectory,
+ 'output-script-name=s' => \$scriptName,
+ 'generated-scripts-dir=s' => \$generatedScriptsDirectory,
+ 'input-html=s' => \$htmlFile);
+
+unless (defined $htmlFile and defined $scriptName and defined $outputDirectory) {
+ print "Usage: $0 --input-html <path> --output-dir path --output-script-name <name>\n";
+ exit;
+}
+
+my $htmlDirectory = dirname($htmlFile);
+my $htmlContents;
+
+{
+ local $/;
+ open HTML, $htmlFile or die;
+ $htmlContents = <HTML>;
+ close HTML;
+}
+
+$htmlContents =~ m/<head>(.*)<\/head>/si;
+my $headContents = $1;
+
+mkpath $outputDirectory;
+open SCRIPT_OUT, ">", "$outputDirectory/$scriptName" or die "Can't open $outputDirectory/$scriptName: $!";
+
+while ($headContents =~ m/<script.*src="([^"]*)"[^>]*>/gi) {
+ local $/;
+ open SCRIPT_IN, "$generatedScriptsDirectory/$1" or open SCRIPT_IN, "$htmlDirectory/$1" or die "Can't open $htmlDirectory/$1: $!";
+ print SCRIPT_OUT "/* $1 */\n\n";
+ print SCRIPT_OUT <SCRIPT_IN>;
+ close SCRIPT_IN;
+}
+
+close SCRIPT_OUT;
+
+$headContents =~ s/<script.*src="[^"]*"[^>]*><\/script>\s*//gi;
+$headContents .= "<script type=\"text/javascript\" src=\"$scriptName\"></script>\n";
+$htmlContents =~ s/<head>.*<\/head>/<head>$headContents<\/head>/si;
+
+open HTML, ">", "$outputDirectory/" . basename($htmlFile) or die "Can't open $outputDirectory/" . basename($htmlFile) . ": $!";
+print HTML $htmlContents;
+close HTML;
diff --git a/Source/WebCore/inspector/front-end/AuditRules.js b/Source/WebCore/inspector/front-end/AuditRules.js
index ddab1df..19a2c24 100644
--- a/Source/WebCore/inspector/front-end/AuditRules.js
+++ b/Source/WebCore/inspector/front-end/AuditRules.js
@@ -63,18 +63,6 @@ WebInspector.AuditRules.getDomainToResourcesMap = function(resources, types, nee
return domainToResourcesMap;
}
-WebInspector.AuditRules.evaluateInTargetWindow = function(func, args, callback)
-{
- function mycallback(error, result)
- {
- if (!error && result)
- callback(JSON.parse(result.description));
- else
- callback(null);
- }
- RuntimeAgent.evaluate("JSON.stringify((" + func + ")(" + JSON.stringify(args) + "))", "", false, mycallback);
-}
-
WebInspector.AuditRules.GzipRule = function()
{
WebInspector.AuditRule.call(this, "network-gzip", "Enable gzip compression");
@@ -322,7 +310,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
var rule = styleSheet.rules[curRule];
// Exact computation whenever source ranges are available.
- var textLength = (rule.selectorRange && rule.style.properties.endOffset) ? rule.style.properties.endOffset - rule.selectorRange.start + 1 : 0;
+ var textLength = (rule.selectorRange && rule.style.range && rule.style.range.end) ? rule.style.range.end - rule.selectorRange.start + 1 : 0;
if (!textLength && rule.style.cssText)
textLength = rule.style.cssText.length + rule.selectorText.length;
stylesheetSize += textLength;
@@ -360,21 +348,21 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
callback(result);
}
- function routine(selectorArray)
+ var foundSelectors = {};
+ function queryCallback(boundSelectorsCallback, selector, styleSheets, testedSelectors, nodeId)
{
- var result = {};
- for (var i = 0; i < selectorArray.length; ++i) {
- try {
- if (document.querySelector(selectorArray[i]))
- result[selectorArray[i]] = true;
- } catch(e) {
- // Ignore and mark as unused.
- }
- }
- return result;
+ if (nodeId)
+ foundSelectors[selector] = true;
+ if (boundSelectorsCallback)
+ boundSelectorsCallback(foundSelectors);
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, [selectors], selectorsCallback.bind(null, callback, styleSheets, testedSelectors));
+ function documentLoaded(selectors, document) {
+ for (var i = 0; i < selectors.length; ++i)
+ WebInspector.domAgent.querySelector(document.id, selectors[i], queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, callback, styleSheets, testedSelectors) : null, selectors[i], styleSheets, testedSelectors));
+ }
+
+ WebInspector.domAgent.requestDocument(documentLoaded.bind(null, selectors));
}
function styleSheetCallback(styleSheets, sourceURL, continuation, styleSheet)
@@ -721,20 +709,22 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
doneCallback();
}
- function getStyles(error, nodeIds)
+ function getStyles(nodeIds)
{
- if (error)
+ if (!nodeIds) {
+ console.error("Failed to get styles");
return;
+ }
for (var i = 0; i < nodeIds.length; ++i)
WebInspector.cssModel.getStylesAsync(nodeIds[i], imageStylesReady.bind(this, nodeIds[i], i === nodeIds.length - 1));
}
- function getImages()
+ function onDocumentAvailable(root)
{
- DOMAgent.querySelectorAll(0, "img[src]", true, getStyles);
+ WebInspector.domAgent.querySelectorAll(root.id, "img[src]", getStyles);
}
- WebInspector.domAgent.requestDocument(getImages);
+ WebInspector.domAgent.requestDocument(onDocumentAvailable);
}
}
@@ -771,46 +761,35 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
callback(result);
}
- function routine()
+ function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds)
{
- function allViews() {
- var views = [document.defaultView];
- var curView = 0;
- while (curView < views.length) {
- var view = views[curView];
- var frames = view.frames;
- for (var i = 0; i < frames.length; ++i) {
- if (frames[i] !== view)
- views.push(frames[i]);
- }
- ++curView;
+ var externalStylesheetNodeIds = nodeIds;
+ var result = null;
+ if (inlineStyleNodeIds.length || externalStylesheetNodeIds.length) {
+ var urlToViolationsArray = {};
+ var externalStylesheetHrefs = [];
+ for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
+ var linkNode = WebInspector.domAgent.nodeForId(externalStylesheetNodeIds[j]);
+ var completeHref = WebInspector.completeURL(linkNode.ownerDocument.documentURL, linkNode.getAttribute("href"));
+ externalStylesheetHrefs.push(completeHref || "<empty>");
}
- return views;
+ urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, externalStylesheetHrefs];
+ result = urlToViolationsArray;
}
+ evalCallback(result);
+ }
- var views = allViews();
- var urlToViolationsArray = {};
- var found = false;
- for (var i = 0; i < views.length; ++i) {
- var view = views[i];
- if (!view.document)
- continue;
-
- var inlineStyles = view.document.querySelectorAll("body style");
- var inlineStylesheets = view.document.querySelectorAll("body link[rel~='stylesheet'][href]");
- if (!inlineStyles.length && !inlineStylesheets.length)
- continue;
+ function inlineStylesReceived(root, nodeIds)
+ {
+ WebInspector.domAgent.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
+ }
- found = true;
- var inlineStylesheetHrefs = [];
- for (var j = 0; j < inlineStylesheets.length; ++j)
- inlineStylesheetHrefs.push(inlineStylesheets[j].href);
- urlToViolationsArray[view.location.href] = [inlineStyles.length, inlineStylesheetHrefs];
- }
- return found ? urlToViolationsArray : null;
+ function onDocumentAvailable(root)
+ {
+ WebInspector.domAgent.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback);
+ WebInspector.domAgent.requestDocument(onDocumentAvailable);
}
}
@@ -844,20 +823,34 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
callback(result);
}
- function routine()
+ function cssBeforeInlineReceived(lateStyleIds, nodeIds)
+ {
+ var cssBeforeInlineCount = nodeIds.length;
+ var result = null;
+ if (lateStyleIds.length || cssBeforeInlineCount) {
+ var lateStyleUrls = [];
+ for (var i = 0; i < lateStyleIds.length; ++i) {
+ var lateStyleNode = WebInspector.domAgent.nodeForId(lateStyleIds[i]);
+ var completeHref = WebInspector.completeURL(lateStyleNode.ownerDocument.documentURL, lateStyleNode.getAttribute("href"));
+ lateStyleUrls.push(completeHref || "<empty>");
+ }
+ result = [ lateStyleUrls, cssBeforeInlineCount ];
+ }
+
+ evalCallback(result);
+ }
+
+ function lateStylesReceived(root, nodeIds)
+ {
+ WebInspector.domAgent.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
+ }
+
+ function onDocumentAvailable(root)
{
- var lateStyles = document.querySelectorAll("head script[src] ~ link[rel~='stylesheet'][href]");
- var cssBeforeInlineCount = document.querySelectorAll("head link[rel~='stylesheet'][href] ~ script:not([src])").length;
- if (!lateStyles.length && !cssBeforeInlineCount)
- return null;
-
- var lateStyleUrls = [];
- for (var i = 0; i < lateStyles.length; ++i)
- lateStyleUrls.push(lateStyles[i].href);
- return [ lateStyleUrls, cssBeforeInlineCount ];
+ WebInspector.domAgent.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback.bind(this));
+ WebInspector.domAgent.requestDocument(onDocumentAvailable);
}
}
diff --git a/Source/WebCore/inspector/front-end/BreakpointManager.js b/Source/WebCore/inspector/front-end/BreakpointManager.js
deleted file mode 100644
index 76348ff..0000000
--- a/Source/WebCore/inspector/front-end/BreakpointManager.js
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * 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.BreakpointManager = function()
-{
- this._stickyBreakpoints = {};
- var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints");
- for (var projectId in breakpoints)
- this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]);
-
- this._breakpoints = {};
- this._domBreakpointsRestored = false;
-
- WebInspector.settings.addEventListener(WebInspector.Settings.Events.ProjectChanged, this._projectChanged, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
-}
-
-WebInspector.BreakpointManager.BreakpointTypes = {
- DOM: "DOM",
- EventListener: "EventListener",
- XHR: "XHR"
-}
-
-WebInspector.BreakpointManager.Events = {
- DOMBreakpointAdded: "dom-breakpoint-added",
- ProjectChanged: "project-changed"
-}
-
-WebInspector.BreakpointManager.prototype = {
- createDOMBreakpoint: function(nodeId, type)
- {
- this._createDOMBreakpoint(nodeId, type, true, false);
- },
-
- _createDOMBreakpoint: function(nodeId, type, enabled, restored)
- {
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
- return;
-
- var breakpointId = this._createDOMBreakpointId(nodeId, type);
- if (breakpointId in this._breakpoints)
- return;
-
- var breakpoint = new WebInspector.DOMBreakpoint(node, type);
- this._setBreakpoint(breakpointId, breakpoint, enabled, restored);
- if (enabled && restored)
- breakpoint._enable();
-
- breakpoint.view = new WebInspector.DOMBreakpointView(this, breakpointId, enabled, node, type);
- this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpoint.view);
- },
-
- _setBreakpoint: function(breakpointId, breakpoint, enabled, restored)
- {
- this._breakpoints[breakpointId] = breakpoint;
- breakpoint.enabled = enabled;
- if (restored)
- return;
- if (enabled)
- breakpoint._enable();
- this._saveBreakpoints();
- },
-
- _setBreakpointEnabled: function(breakpointId, enabled)
- {
- var breakpoint = this._breakpoints[breakpointId];
- if (breakpoint.enabled === enabled)
- return;
- if (enabled)
- breakpoint._enable();
- else
- breakpoint._disable();
- breakpoint.enabled = enabled;
- this._saveBreakpoints();
- },
-
- _removeBreakpoint: function(breakpointId)
- {
- var breakpoint = this._breakpoints[breakpointId];
- if (breakpoint.enabled)
- breakpoint._disable();
- delete this._breakpoints[breakpointId];
- this._saveBreakpoints();
- },
-
- breakpointViewForEventData: function(eventData)
- {
- var breakpointId;
- if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.DOM)
- breakpointId = this._createDOMBreakpointId(eventData.nodeId, eventData.type);
- else
- return;
-
- var breakpoint = this._breakpoints[breakpointId];
- if (breakpoint)
- return breakpoint.view;
- },
-
- _debuggerPaused: function(event)
- {
- var eventType = event.data.eventType;
- var eventData = event.data.eventData;
-
- if (eventType !== WebInspector.DebuggerEventTypes.NativeBreakpoint)
- return;
-
- var breakpointView = this.breakpointViewForEventData(eventData);
- if (!breakpointView)
- return;
-
- breakpointView.hit = true;
- this._lastHitBreakpointView = breakpointView;
- },
-
- _debuggerResumed: function(event)
- {
- if (!this._lastHitBreakpointView)
- return;
- this._lastHitBreakpointView.hit = false;
- delete this._lastHitBreakpointView;
- },
-
- _projectChanged: function(event)
- {
- this._breakpoints = {};
- this._domBreakpointsRestored = false;
- this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.ProjectChanged);
- },
-
- restoreDOMBreakpoints: function()
- {
- function didPushNodeByPathToFrontend(path, nodeId)
- {
- if (!nodeId)
- return;
-
- pathToNodeId[path] = nodeId;
- pendingCalls -= 1;
- if (pendingCalls)
- return;
- for (var i = 0; i < breakpoints.length; ++i) {
- var breakpoint = breakpoints[i];
- if (breakpoint.type !== WebInspector.BreakpointManager.BreakpointTypes.DOM)
- continue;
- var nodeId = pathToNodeId[breakpoint.condition.path];
- if (nodeId)
- this._createDOMBreakpoint(nodeId, breakpoint.condition.type, breakpoint.enabled, true);
- }
- this._domBreakpointsRestored = true;
- this._saveBreakpoints();
- }
-
- var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || [];
- var pathToNodeId = {};
- var pendingCalls = 0;
- for (var i = 0; i < breakpoints.length; ++i) {
- if (breakpoints[i].type !== WebInspector.BreakpointManager.BreakpointTypes.DOM)
- continue;
- var path = breakpoints[i].condition.path;
- if (path in pathToNodeId)
- continue;
- pathToNodeId[path] = 0;
- pendingCalls += 1;
- WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
- }
- if (!pendingCalls)
- this._domBreakpointsRestored = true;
- },
-
- _saveBreakpoints: function()
- {
- var breakpoints = [];
- for (var breakpointId in this._breakpoints) {
- var breakpoint = this._breakpoints[breakpointId];
- var persistentBreakpoint = breakpoint._serializeToJSON();
- persistentBreakpoint.enabled = breakpoint.enabled;
- breakpoints.push(persistentBreakpoint);
- }
- if (!this._domBreakpointsRestored) {
- var stickyBreakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || [];
- for (var i = 0; i < stickyBreakpoints.length; ++i) {
- if (stickyBreakpoints[i].type === WebInspector.BreakpointManager.BreakpointTypes.DOM)
- breakpoints.push(stickyBreakpoints[i]);
- }
- }
- WebInspector.settings.nativeBreakpoints = breakpoints;
-
- this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints;
- },
-
- _validateBreakpoints: function(persistentBreakpoints)
- {
- var breakpoints = [];
- var breakpointsSet = {};
- for (var i = 0; i < persistentBreakpoints.length; ++i) {
- var breakpoint = persistentBreakpoints[i];
- if (!("type" in breakpoint && "enabled" in breakpoint && "condition" in breakpoint))
- continue;
- var id = breakpoint.type + ":";
- var condition = breakpoint.condition;
- if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.DOM) {
- if (typeof condition.path !== "string" || typeof condition.type !== "number")
- continue;
- id += condition.path + ":" + condition.type;
- } else
- continue;
-
- if (id in breakpointsSet)
- continue;
- breakpointsSet[id] = true;
- breakpoints.push(breakpoint);
- }
- return breakpoints;
- },
-
- _createDOMBreakpointId: function(nodeId, type)
- {
- return "dom:" + nodeId + ":" + type;
- }
-}
-
-WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
-
-WebInspector.DOMBreakpoint = function(node, type)
-{
- this._nodeId = node.id;
- this._path = node.path();
- this._type = type;
-}
-
-WebInspector.DOMBreakpoint.prototype = {
- _enable: function()
- {
- BrowserDebuggerAgent.setDOMBreakpoint(this._nodeId, this._type);
- },
-
- _disable: function()
- {
- BrowserDebuggerAgent.removeDOMBreakpoint(this._nodeId, this._type);
- },
-
- _serializeToJSON: function()
- {
- var type = WebInspector.BreakpointManager.BreakpointTypes.DOM;
- return { type: type, condition: { path: this._path, type: this._type } };
- }
-}
-
-WebInspector.NativeBreakpointView = function(manager, id, enabled)
-{
- this._manager = manager;
- this._id = id;
- this._enabled = enabled;
- this._hit = false;
-}
-
-WebInspector.NativeBreakpointView.prototype = {
- get enabled()
- {
- return this._enabled;
- },
-
- set enabled(enabled)
- {
- this._manager._setBreakpointEnabled(this._id, enabled);
- this._enabled = enabled;
- this.dispatchEventToListeners("enable-changed");
- },
-
- get hit()
- {
- return this._hit;
- },
-
- set hit(hit)
- {
- this._hit = hit;
- this.dispatchEventToListeners("hit-state-changed");
- },
-
- remove: function()
- {
- this._manager._removeBreakpoint(this._id);
- this._onRemove();
- this.dispatchEventToListeners("removed");
- },
-
- _compare: function(x, y)
- {
- if (x !== y)
- return x < y ? -1 : 1;
- return 0;
- },
-
- _onRemove: function()
- {
- }
-}
-
-WebInspector.NativeBreakpointView.prototype.__proto__ = WebInspector.Object.prototype;
-
-WebInspector.DOMBreakpointView = function(manager, id, enabled, node, type)
-{
- WebInspector.NativeBreakpointView.call(this, manager, id, enabled);
- this._node = node;
- this._nodeId = node.id;
- this._type = type;
- node.breakpoints[this._type] = this;
-}
-
-WebInspector.DOMBreakpointView.prototype = {
- compareTo: function(other)
- {
- return this._compare(this._type, other._type);
- },
-
- populateLabelElement: function(element)
- {
- // FIXME: this should belong to the view, not the manager.
- var linkifiedNode = WebInspector.panels.elements.linkifyNodeById(this._nodeId);
- linkifiedNode.addStyleClass("monospace");
- element.appendChild(linkifiedNode);
- var description = document.createElement("div");
- description.className = "source-text";
- description.textContent = WebInspector.domBreakpointTypeLabel(this._type);
- element.appendChild(description);
- },
-
- populateStatusMessageElement: function(element, eventData)
- {
- if (this._type === WebInspector.DOMBreakpointTypes.SubtreeModified) {
- var targetNodeObject = WebInspector.RemoteObject.fromPayload(eventData.targetNode);
- targetNodeObject.pushNodeToFrontend(decorateNode.bind(this));
- function decorateNode(targetNodeId)
- {
- if (!targetNodeId)
- return;
-
- targetNodeObject.release();
- var targetNode = WebInspector.panels.elements.linkifyNodeById(targetNodeId);
- if (eventData.insertion) {
- if (targetNodeId !== this._nodeId)
- this._format(element, "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.", targetNode);
- else
- this._format(element, "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.");
- } else
- this._format(element, "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.", targetNode);
- }
- } else
- this._format(element, "Paused on a \"%s\" breakpoint set on %s.");
- },
-
- _format: function(element, message, extraSubstitution)
- {
- var substitutions = [WebInspector.domBreakpointTypeLabel(this._type), WebInspector.panels.elements.linkifyNodeById(this._nodeId)];
- if (extraSubstitution)
- substitutions.push(extraSubstitution);
-
- var formatters = {
- s: function(substitution)
- {
- return substitution;
- }
- };
- function append(a, b)
- {
- if (typeof b === "string")
- b = document.createTextNode(b);
- element.appendChild(b);
- }
- WebInspector.formatLocalized(message, substitutions, formatters, "", append);
- },
-
- _onRemove: function()
- {
- delete this._node.breakpoints[this._type];
- }
-}
-
-WebInspector.DOMBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype;
-
-WebInspector.DOMBreakpointTypes = {
- SubtreeModified: 0,
- AttributeModified: 1,
- NodeRemoved: 2
-};
-
-WebInspector.domBreakpointTypeLabel = function(type)
-{
- if (!WebInspector._DOMBreakpointTypeLabels) {
- WebInspector._DOMBreakpointTypeLabels = {};
- WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
- WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
- WebInspector._DOMBreakpointTypeLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
- }
- return WebInspector._DOMBreakpointTypeLabels[type];
-}
-
-WebInspector.domBreakpointTypeContextMenuLabel = function(type)
-{
- if (!WebInspector._DOMBreakpointTypeContextMenuLabels) {
- WebInspector._DOMBreakpointTypeContextMenuLabels = {};
- WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.SubtreeModified] = WebInspector.UIString("Break on Subtree Modifications");
- WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.AttributeModified] = WebInspector.UIString("Break on Attributes Modifications");
- WebInspector._DOMBreakpointTypeContextMenuLabels[WebInspector.DOMBreakpointTypes.NodeRemoved] = WebInspector.UIString("Break on Node Removal");
- }
- return WebInspector._DOMBreakpointTypeContextMenuLabels[type];
-}
diff --git a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 63a6e2a..d2d7257 100644
--- a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -23,11 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.JavaScriptBreakpointsSidebarPane = function(model)
+WebInspector.JavaScriptBreakpointsSidebarPane = function(model, showSourceLineDelegate)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
this._model = model;
+ this._showSourceLineDelegate = showSourceLineDelegate;
this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";
@@ -123,7 +124,7 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
_breakpointClicked: function(breakpoint, event)
{
- WebInspector.panels.scripts.showSourceLine(breakpoint.sourceFileId, breakpoint.lineNumber + 1);
+ this._showSourceLineDelegate(breakpoint.sourceFileId, breakpoint.lineNumber);
},
_breakpointCheckboxClicked: function(breakpoint, event)
@@ -203,41 +204,9 @@ WebInspector.NativeBreakpointsSidebarPane = function(title)
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
this.bodyElement.appendChild(this.emptyElement);
-
- WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
}
WebInspector.NativeBreakpointsSidebarPane.prototype = {
- addBreakpointItem: function(breakpointItem)
- {
- var element = breakpointItem.element;
- element._breakpointItem = breakpointItem;
-
- breakpointItem.addEventListener("breakpoint-hit", this.expand, this);
- breakpointItem.addEventListener("removed", this._removeListElement.bind(this, element), this);
-
- var currentElement = this.listElement.firstChild;
- while (currentElement) {
- if (currentElement._breakpointItem && currentElement._breakpointItem.compareTo(element._breakpointItem) > 0)
- break;
- currentElement = currentElement.nextSibling;
- }
- this._addListElement(element, currentElement);
-
- if (breakpointItem.click) {
- element.addStyleClass("cursor-pointer");
- element.addEventListener("click", breakpointItem.click.bind(breakpointItem), false);
- }
- element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true);
- },
-
- _contextMenuEventFired: function(breakpointItem, event)
- {
- var contextMenu = new WebInspector.ContextMenu();
- contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem));
- contextMenu.show(event);
- },
-
_addListElement: function(element, beforeElement)
{
if (beforeElement)
@@ -260,7 +229,7 @@ WebInspector.NativeBreakpointsSidebarPane.prototype = {
}
},
- _projectChanged: function()
+ _reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
@@ -377,9 +346,9 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
_checkboxClicked: function(url, event)
{
if (event.target.checked)
- WebInspector.breakpointManager.setXHRBreakpoint(url);
+ BrowserDebuggerAgent.setXHRBreakpoint(url);
else
- WebInspector.breakpointManager.removeXHRBreakpoint(url);
+ BrowserDebuggerAgent.removeXHRBreakpoint(url);
this._saveBreakpoints();
},
@@ -443,98 +412,11 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
if (breakpoint && typeof breakpoint.url === "string")
this._setBreakpoint(breakpoint.url, breakpoint.enabled);
}
- },
-
- _projectChanged: function()
- {
}
}
WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;
-WebInspector.BreakpointItem = function(breakpoint)
-{
- this._breakpoint = breakpoint;
-
- this._element = document.createElement("li");
-
- var checkboxElement = document.createElement("input");
- checkboxElement.className = "checkbox-elem";
- checkboxElement.type = "checkbox";
- checkboxElement.checked = this._breakpoint.enabled;
- checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false);
- this._element.appendChild(checkboxElement);
-
- this._createLabelElement();
-
- this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
- this._breakpoint.addEventListener("hit-state-changed", this._hitStateChanged, this);
- this._breakpoint.addEventListener("label-changed", this._labelChanged, this);
- this._breakpoint.addEventListener("removed", this.dispatchEventToListeners.bind(this, "removed"));
- if (breakpoint.click)
- this.click = breakpoint.click.bind(breakpoint);
-}
-
-WebInspector.BreakpointItem.prototype = {
- get element()
- {
- return this._element;
- },
-
- compareTo: function(other)
- {
- return this._breakpoint.compareTo(other._breakpoint);
- },
-
- populateEditElement: function(element)
- {
- this._breakpoint.populateEditElement(element);
- },
-
- remove: function()
- {
- this._breakpoint.remove();
- },
-
- _checkboxClicked: function(event)
- {
- this._breakpoint.enabled = !this._breakpoint.enabled;
-
- // Breakpoint element may have it's own click handler.
- event.stopPropagation();
- },
-
- _enableChanged: function(event)
- {
- var checkbox = this._element.firstChild;
- checkbox.checked = this._breakpoint.enabled;
- },
-
- _hitStateChanged: function(event)
- {
- if (event.target.hit) {
- this._element.addStyleClass("breakpoint-hit");
- this.dispatchEventToListeners("breakpoint-hit");
- } else
- this._element.removeStyleClass("breakpoint-hit");
- },
-
- _labelChanged: function(event)
- {
- this._element.removeChild(this._labelElement);
- this._createLabelElement();
- },
-
- _createLabelElement: function()
- {
- this._labelElement = document.createElement("span");
- this._breakpoint.populateLabelElement(this._labelElement);
- this._element.appendChild(this._labelElement);
- }
-}
-
-WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype;
-
WebInspector.EventListenerBreakpointsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listener Breakpoints"));
diff --git a/Source/WebCore/inspector/front-end/CSSStyleModel.js b/Source/WebCore/inspector/front-end/CSSStyleModel.js
index 148bfd8..7596bc4 100644
--- a/Source/WebCore/inspector/front-end/CSSStyleModel.js
+++ b/Source/WebCore/inspector/front-end/CSSStyleModel.js
@@ -30,6 +30,7 @@
WebInspector.CSSStyleModel = function()
{
+ new WebInspector.CSSStyleModelResourceBinding(this);
}
WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
@@ -40,6 +41,10 @@ WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
return result;
}
+WebInspector.CSSStyleModel.Events = {
+ StyleSheetChanged: 0
+}
+
WebInspector.CSSStyleModel.prototype = {
getStylesAsync: function(nodeId, userCallback)
{
@@ -124,7 +129,7 @@ WebInspector.CSSStyleModel.prototype = {
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
- this._styleSheetChanged(rule.id.styleSheetId, true);
+ this._fireStyleSheetChanged(rule.id.styleSheetId, true);
}
function callback(nodeId, successCallback, failureCallback, error, newSelector, rulePayload)
@@ -133,7 +138,7 @@ WebInspector.CSSStyleModel.prototype = {
if (error)
failureCallback();
else
- DOMAgent.querySelectorAll(nodeId, newSelector, true, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
+ WebInspector.domAgent.querySelectorAll(nodeId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}
CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
@@ -146,7 +151,7 @@ WebInspector.CSSStyleModel.prototype = {
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
- this._styleSheetChanged(rule.id.styleSheetId, true);
+ this._fireStyleSheetChanged(rule.id.styleSheetId, true);
}
function callback(successCallback, failureCallback, selector, error, rulePayload)
@@ -155,39 +160,39 @@ WebInspector.CSSStyleModel.prototype = {
// Invalid syntax for a selector
failureCallback();
} else
- DOMAgent.querySelectorAll(nodeId, selector, true, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
+ WebInspector.domAgent.querySelectorAll(nodeId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
}
CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
},
- _styleSheetChanged: function(styleSheetId, majorChange)
+ _fireStyleSheetChanged: function(styleSheetId, majorChange, callback)
{
- if (!majorChange || !styleSheetId)
+ callback = callback || function() {};
+
+ if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged)) {
+ callback();
return;
+ }
- function callback(error, href, content)
+ function mycallback(error, content)
{
- if (error)
- return;
- var resource = WebInspector.resourceForURL(href);
- if (resource && resource.type === WebInspector.Resource.Type.Stylesheet) {
- resource.setContent(content, this._onRevert.bind(this, styleSheetId));
- this.dispatchEventToListeners("stylesheet changed");
- }
+ if (!error)
+ this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, content: content, majorChange: majorChange });
+ callback();
}
- CSSAgent.getStyleSheetText(styleSheetId, callback.bind(this));
+
+ CSSAgent.getStyleSheetText(styleSheetId, mycallback.bind(this));
},
- _onRevert: function(styleSheetId, contentToRevertTo)
+ setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
{
- function callback(error, success)
+ function callback(error)
{
- if (error)
- return;
- this._styleSheetChanged(styleSheetId, true);
+ if (!error)
+ this._fireStyleSheetChanged(styleSheetId, majorChange, userCallback ? userCallback.bind(this, error) : null);
}
- CSSAgent.setStyleSheetText(styleSheetId, contentToRevertTo, callback.bind(this));
+ CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
}
}
@@ -196,8 +201,10 @@ WebInspector.CSSStyleModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.styleId;
- this.properties = payload.properties;
- this._shorthandValues = payload.shorthandValues;
+ this.width = payload.width;
+ this.height = payload.height;
+ this.range = payload.range;
+ this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
this._livePropertyMap = {}; // LIVE properties (source-based or style-based) : { name -> CSSProperty }
this._allProperties = []; // ALL properties: [ CSSProperty ]
this._longhandProperties = {}; // shorthandName -> [ CSSProperty ]
@@ -232,6 +239,14 @@ WebInspector.CSSStyleDeclaration = function(payload)
this.cssText = payload.cssText;
}
+WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries)
+{
+ var result = {};
+ for (var i = 0; i < shorthandEntries.length; ++i)
+ result[shorthandEntries[i].name] = shorthandEntries[i].value;
+ return result;
+}
+
WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
{
return new WebInspector.CSSStyleDeclaration(payload);
@@ -351,11 +366,12 @@ WebInspector.CSSStyleDeclaration.prototype = {
if (!userCallback)
return;
- if (error)
+ if (error) {
+ console.error(JSON.stringify(error));
userCallback(null);
- else {
+ } else {
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
- WebInspector.cssModel._styleSheetChanged(this.id.styleSheetId, true);
+ WebInspector.cssModel._fireStyleSheetChanged(this.id.styleSheetId, true);
}
}
@@ -476,14 +492,14 @@ WebInspector.CSSProperty.prototype = {
function enabledCallback(style)
{
if (style)
- WebInspector.cssModel._styleSheetChanged(style.id.styleSheetId, majorChange);
+ WebInspector.cssModel._fireStyleSheetChanged(style.id.styleSheetId, majorChange);
if (userCallback)
userCallback(style);
}
function callback(error, stylePayload)
{
- if (!error && stylePayload) {
+ if (!error) {
this.text = propertyText;
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
var newProperty = style.allProperties[this.index];
@@ -491,11 +507,11 @@ WebInspector.CSSProperty.prototype = {
if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
newProperty.setDisabled(false, enabledCallback);
return;
- } else
- WebInspector.cssModel._styleSheetChanged(style.id.styleSheetId, majorChange);
- if (userCallback)
- userCallback(style);
+ }
+
+ WebInspector.cssModel._fireStyleSheetChanged(style.id.styleSheetId, majorChange, userCallback.bind(this, style));
} else {
+ console.error(JSON.stringify(error));
if (userCallback)
userCallback(null);
}
@@ -530,7 +546,7 @@ WebInspector.CSSProperty.prototype = {
else {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
- WebInspector.cssModel._styleSheetChanged(this.ownerStyle.id.styleSheetId, false);
+ WebInspector.cssModel._fireStyleSheetChanged(this.ownerStyle.id.styleSheetId, false);
}
}
@@ -571,16 +587,109 @@ WebInspector.CSSStyleSheet.prototype = {
return this._text;
},
- setText: function(newText, userCallback)
+ setText: function(newText, majorChange, userCallback)
{
- function callback(error, isChangeSuccessful)
+ function callback(error)
{
if (userCallback)
- userCallback(isChangeSuccessful);
- if (isChangeSuccessful)
- WebInspector.cssModel._styleSheetChanged(this.id, true);
+ userCallback(error);
+ if (!error)
+ WebInspector.cssModel._fireStyleSheetChanged(this.id, majorChange);
}
CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
}
}
+
+WebInspector.CSSStyleModelResourceBinding = function(cssModel)
+{
+ this._cssModel = cssModel;
+ this._urlToStyleSheetId = {};
+ this._styleSheetIdToURL = {};
+ this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
+ WebInspector.Resource.registerDomainModelBinding(WebInspector.Resource.Type.Stylesheet, this);
+}
+
+WebInspector.CSSStyleModelResourceBinding.prototype = {
+ setContent: function(resource, content, majorChange, userCallback)
+ {
+ if (this._urlToStyleSheetId[resource.url]) {
+ this._innerSetContent(resource.url, content, majorChange, userCallback);
+ return;
+ }
+ this._loadStyleSheetHeaders(this._innerSetContent.bind(this, resource.url, content, majorChange, userCallback));
+ },
+
+ _frameNavigated: function(event)
+ {
+ var frameId = event.data;
+ if (!frameId) {
+ // Main frame navigation - clear history.
+ this._urlToStyleSheetId = {};
+ this._styleSheetIdToURL = {};
+ }
+ },
+
+ _innerSetContent: function(url, content, majorChange, userCallback, error)
+ {
+ if (error) {
+ userCallback(error);
+ return;
+ }
+
+ var styleSheetId = this._urlToStyleSheetId[url];
+ if (!styleSheetId) {
+ if (userCallback)
+ userCallback("No stylesheet found: " + url);
+ return;
+ }
+ this._cssModel.setStyleSheetText(styleSheetId, content, majorChange, userCallback);
+ },
+
+ _loadStyleSheetHeaders: function(callback)
+ {
+ function didGetAllStyleSheets(error, infos)
+ {
+ if (error) {
+ callback(error);
+ return;
+ }
+
+ for (var i = 0; i < infos.length; ++i) {
+ var info = infos[i];
+ this._urlToStyleSheetId[info.sourceURL] = info.styleSheetId;
+ this._styleSheetIdToURL[info.styleSheetId] = info.sourceURL;
+ }
+ callback();
+ }
+ CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this));
+ },
+
+ _styleSheetChanged: function(event)
+ {
+ var styleSheetId = event.data.styleSheetId;
+ function setContent()
+ {
+ var url = this._styleSheetIdToURL[styleSheetId];
+ if (!url)
+ return;
+
+ var resource = WebInspector.resourceForURL(url);
+ if (!resource)
+ return;
+
+ var majorChange = event.data.majorChange;
+ if (majorChange)
+ resource.addRevision(event.data.content);
+ }
+
+ if (!this._styleSheetIdToURL[styleSheetId]) {
+ this._loadStyleSheetHeaders(setContent.bind(this));
+ return;
+ }
+ setContent.call(this);
+ }
+}
+
+WebInspector.CSSStyleModelResourceBinding.prototype.__proto__ = WebInspector.ResourceDomainModelBinding.prototype;
diff --git a/Source/WebCore/inspector/front-end/CallStackSidebarPane.js b/Source/WebCore/inspector/front-end/CallStackSidebarPane.js
index 3d71101..80187ea 100644
--- a/Source/WebCore/inspector/front-end/CallStackSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/CallStackSidebarPane.js
@@ -46,20 +46,9 @@ WebInspector.CallStackSidebarPane.prototype = {
return;
}
- var title;
- var subtitle;
- var script;
-
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
- switch (callFrame.type) {
- case "function":
- title = callFrame.functionName || WebInspector.UIString("(anonymous function)");
- break;
- case "program":
- title = WebInspector.UIString("(program)");
- break;
- }
+ var title = callFrame.functionName || WebInspector.UIString("(anonymous function)");
var subtitle;
if (!callFrame.isInternalScript)
@@ -71,7 +60,7 @@ WebInspector.CallStackSidebarPane.prototype = {
placard.callFrame = callFrame;
placard.element.addEventListener("click", this._placardSelected.bind(this, placard), false);
- function didGetSourceLocation(placard, sourceFileId, lineNumber, columnNumber)
+ function didGetSourceLine(placard, sourceFileId, lineNumber)
{
if (placard.subtitle)
placard.subtitle += ":" + (lineNumber + 1);
@@ -79,16 +68,11 @@ WebInspector.CallStackSidebarPane.prototype = {
placard.subtitle = WebInspector.UIString("line %d", lineNumber + 1);
placard._text = WebInspector.UIString("%s() at %s", placard.title, placard.subtitle);
}
- callFrame.sourceLocation(didGetSourceLocation.bind(this, placard));
+ callFrame.sourceLine(didGetSourceLine.bind(this, placard));
this.placards.push(placard);
this.bodyElement.appendChild(placard.element);
}
-
- if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
- if (details.eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.DOM)
- this._domBreakpointHit(details.eventData);
- }
},
set selectedCallFrame(x)
@@ -187,19 +171,10 @@ WebInspector.CallStackSidebarPane.prototype = {
{
var statusMessageElement = document.createElement("div");
statusMessageElement.className = "info";
- statusMessageElement.textContent = status;
- this.bodyElement.appendChild(statusMessageElement);
- },
-
- _domBreakpointHit: function(eventData)
- {
- var breakpoint = WebInspector.breakpointManager.breakpointViewForEventData(eventData);
- if (!breakpoint)
- return;
-
- var statusMessageElement = document.createElement("div");
- statusMessageElement.className = "info";
- breakpoint.populateStatusMessageElement(statusMessageElement, eventData);
+ if (typeof status === "string")
+ statusMessageElement.textContent = status;
+ else
+ statusMessageElement.appendChild(status);
this.bodyElement.appendChild(statusMessageElement);
}
}
diff --git a/Source/WebCore/inspector/front-end/ConsoleView.js b/Source/WebCore/inspector/front-end/ConsoleView.js
index f3e3425..4ab16d9e 100644
--- a/Source/WebCore/inspector/front-end/ConsoleView.js
+++ b/Source/WebCore/inspector/front-end/ConsoleView.js
@@ -105,7 +105,7 @@ WebInspector.ConsoleView.prototype = {
_registerConsoleDomainDispatcher: function() {
var console = this;
var dispatcher = {
- consoleMessage: function(payload)
+ messageAdded: function(payload)
{
var consoleMessage = new WebInspector.ConsoleMessage(
payload.source,
@@ -114,14 +114,14 @@ WebInspector.ConsoleView.prototype = {
payload.line,
payload.url,
payload.repeatCount,
- payload.message,
+ payload.text,
payload.parameters,
payload.stackTrace,
- payload.requestId);
+ payload.networkIdentifier);
console.addMessage(consoleMessage);
},
- consoleMessageRepeatCountUpdated: function(count)
+ messageRepeatCountUpdated: function(count)
{
var msg = console.previousMessage;
var prevRepeatCount = msg.totalRepeatCount;
@@ -140,7 +140,7 @@ WebInspector.ConsoleView.prototype = {
}
},
- consoleMessagesCleared: function()
+ messagesCleared: function()
{
console.clearMessages();
},
@@ -362,7 +362,7 @@ WebInspector.ConsoleView.prototype = {
{
if (!result)
return;
- result.getProperties(true, false, evaluatedProperties.bind(this));
+ result.getAllProperties(evaluatedProperties.bind(this));
}
function evaluatedProperties(properties)
@@ -623,7 +623,7 @@ WebInspector.ConsoleView.prototype = {
_formatarray: function(arr, elem)
{
- arr.getOwnProperties(false, this._printArray.bind(this, elem));
+ arr.getOwnProperties(this._printArray.bind(this, elem));
},
_formatstring: function(output, elem)
@@ -691,7 +691,7 @@ WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCou
if (stackTrace && stackTrace.length) {
var topCallFrame = stackTrace[0];
if (!this.url)
- this.url = topCallFrame.scriptName;
+ this.url = topCallFrame.url;
if (!this.line)
this.line = topCallFrame.lineNumber;
}
@@ -923,7 +923,7 @@ WebInspector.ConsoleMessage.prototype = {
messageTextElement.appendChild(document.createTextNode(functionName));
content.appendChild(messageTextElement);
- var urlElement = WebInspector.linkifyResourceAsNode(frame.scriptName, "scripts", frame.lineNumber, "console-message-url");
+ var urlElement = WebInspector.linkifyResourceAsNode(frame.url, "scripts", frame.lineNumber, "console-message-url");
content.appendChild(urlElement);
var treeElement = new TreeElement(content);
@@ -1027,10 +1027,10 @@ WebInspector.ConsoleMessage.prototype = {
var l = this._stackTrace;
var r = msg._stackTrace;
for (var i = 0; i < l.length; i++) {
- if (l[i].scriptName !== r[i].scriptName ||
+ if (l[i].url !== r[i].url ||
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
- l[i].column !== r[i].column)
+ l[i].columnNumber !== r[i].columnNumber)
return false;
}
}
@@ -1047,33 +1047,33 @@ WebInspector.ConsoleMessage.prototype = {
// Note: Keep these constants in sync with the ones in Console.h
WebInspector.ConsoleMessage.MessageSource = {
- HTML: 0,
- WML: 1,
- XML: 2,
- JS: 3,
- CSS: 4,
- Other: 5
+ HTML: "html",
+ WML: "wml",
+ XML: "xml",
+ JS: "javascript",
+ CSS: "css",
+ Other: "other"
}
WebInspector.ConsoleMessage.MessageType = {
- Log: 0,
- Object: 1,
- Trace: 2,
- StartGroup: 3,
- StartGroupCollapsed: 4,
- EndGroup: 5,
- Assert: 6,
- UncaughtException: 7,
- NetworkError:8,
- Result: 9
+ Log: "log",
+ Object: "other",
+ Trace: "trace",
+ StartGroup: "startGroup",
+ StartGroupCollapsed: "startGroupCollapsed",
+ EndGroup: "endGroup",
+ Assert: "assert",
+ UncaughtException: "uncaughtException",
+ NetworkError: "networkError",
+ Result: "result"
}
WebInspector.ConsoleMessage.MessageLevel = {
- Tip: 0,
- Log: 1,
- Warning: 2,
- Error: 3,
- Debug: 4
+ Tip: "tip",
+ Log: "log",
+ Warning: "warning",
+ Error: "error",
+ Debug: "debug"
}
WebInspector.ConsoleCommand = function(command)
diff --git a/Source/WebCore/inspector/front-end/DOMAgent.js b/Source/WebCore/inspector/front-end/DOMAgent.js
index a2a9c2d..5889320 100644
--- a/Source/WebCore/inspector/front-end/DOMAgent.js
+++ b/Source/WebCore/inspector/front-end/DOMAgent.js
@@ -59,8 +59,6 @@ WebInspector.DOMNode = function(doc, payload) {
this.style = null;
this._matchedCSSRules = [];
- this.breakpoints = {};
-
if (this._nodeType === Node.ELEMENT_NODE) {
// HTML and BODY from internal iframes should not overwrite top-level ones.
if (!this.ownerDocument.documentElement && this._nodeName === "HTML")
@@ -223,6 +221,28 @@ WebInspector.DOMNode.prototype = {
return path.join(",");
},
+ appropriateSelectorFor: function(justSelector)
+ {
+ var lowerCaseName = this.localName() || node.nodeName().toLowerCase();
+
+ var id = this.getAttribute("id");
+ if (id) {
+ var selector = "#" + id;
+ return (justSelector ? selector : lowerCaseName + selector);
+ }
+
+ var className = this.getAttribute("class");
+ if (className) {
+ var selector = "." + className.replace(/\s+/, ".");
+ return (justSelector ? selector : lowerCaseName + selector);
+ }
+
+ if (lowerCaseName === "input" && this.getAttribute("type"))
+ return lowerCaseName + "[type=\"" + this.getAttribute("type") + "\"]";
+
+ return lowerCaseName;
+ },
+
_setAttributesPayload: function(attrs)
{
this._attributes = [];
@@ -328,52 +348,69 @@ WebInspector.DOMAgent.prototype = {
return;
}
- function mycallback(error, root)
+ if (this._pendingDocumentRequestCallbacks) {
+ this._pendingDocumentRequestCallbacks.push(callback);
+ return;
+ }
+
+ this._pendingDocumentRequestCallbacks = [callback];
+
+ function onDocumentAvailable(error, root)
{
if (!error)
this._setDocument(root);
- if (callback)
- callback(this._document);
+ for (var i = 0; i < this._pendingDocumentRequestCallbacks.length; ++i) {
+ var callback = this._pendingDocumentRequestCallbacks[i];
+ if (callback)
+ callback(this._document);
+ }
+ delete this._pendingDocumentRequestCallbacks;
}
- DOMAgent.getDocument(mycallback.bind(this));
+
+ DOMAgent.getDocument(onDocumentAvailable.bind(this));
},
pushNodeToFrontend: function(objectId, callback)
{
- function callbackWrapper(error, nodeId)
- {
- if (callback)
- callback(error ? 0 : nodeId);
- }
-
- function mycallback()
- {
- if (this._document)
- DOMAgent.pushNodeToFrontend(objectId, callbackWrapper);
- else
- callbackWrapper("No document");
- }
-
- this.requestDocument(mycallback.bind(this));
+ this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeToFrontend.bind(DOMAgent), objectId, callback);
},
pushNodeByPathToFrontend: function(path, callback)
{
- function callbackWrapper(error, nodeId)
+ this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByPathToFrontend.bind(DOMAgent), path, callback);
+ },
+
+ _wrapClientCallback: function(callback)
+ {
+ if (!callback)
+ return;
+ return function(error, result)
{
- if (callback)
- callback(error ? 0 : nodeId);
+ callback(error ? null : result);
}
+ },
- function mycallback()
+ _dispatchWhenDocumentAvailable: function(action)
+ {
+ var requestArguments = Array.prototype.slice.call(arguments, 1);
+ var callbackWrapper;
+
+ if (typeof requestArguments[requestArguments.length - 1] === "function") {
+ var callback = requestArguments.pop();
+ callbackWrapper = this._wrapClientCallback(callback);
+ requestArguments.push(callbackWrapper);
+ }
+ function onDocumentAvailable()
{
if (this._document)
- DOMAgent.pushNodeByPathToFrontend(path, callbackWrapper);
- else
- callbackWrapper("No document");
+ action.apply(null, requestArguments);
+ else {
+ if (callbackWrapper)
+ callbackWrapper("No document");
+ }
}
- this.requestDocument(mycallback.bind(this));
+ this.requestDocument(onDocumentAvailable.bind(this));
},
_attributesUpdated: function(nodeId, attrsArray)
@@ -465,17 +502,8 @@ WebInspector.DOMAgent.prototype = {
parent.removeChild_(node);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node:node, parent:parent});
delete this._idToDOMNode[nodeId];
- this._removeBreakpoints(node);
- },
-
- _removeBreakpoints: function(node)
- {
- for (var type in node.breakpoints)
- node.breakpoints[type].remove();
- if (!node.children)
- return;
- for (var i = 0; i < node.children.length; ++i)
- this._removeBreakpoints(node.children[i]);
+ if (Preferences.nativeInstrumentationEnabled)
+ WebInspector.panels.elements.sidebarPanes.domBreakpoints.nodeRemoved(node);
},
performSearch: function(query, searchResultCollector, searchSynchronously)
@@ -488,6 +516,16 @@ WebInspector.DOMAgent.prototype = {
{
delete this._searchResultCollector;
DOMAgent.cancelSearch();
+ },
+
+ querySelector: function(nodeId, selectors, callback)
+ {
+ DOMAgent.querySelector(nodeId, selectors, this._wrapClientCallback(callback));
+ },
+
+ querySelectorAll: function(nodeId, selectors, callback)
+ {
+ DOMAgent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callback));
}
}
diff --git a/Source/WebCore/inspector/front-end/DOMBreakpointsSidebarPane.js b/Source/WebCore/inspector/front-end/DOMBreakpointsSidebarPane.js
new file mode 100644
index 0000000..df31f96
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/DOMBreakpointsSidebarPane.js
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011 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.DOMBreakpointsSidebarPane = function()
+{
+ WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));
+
+ this._breakpointElements = {};
+
+ this._breakpointTypes = {
+ SubtreeModified: 0,
+ AttributeModified: 1,
+ NodeRemoved: 2
+ };
+ this._breakpointTypeLabels = [
+ WebInspector.UIString("Subtree Modified"),
+ WebInspector.UIString("Attribute Modified"),
+ WebInspector.UIString("Node Removed")
+ ];
+ this._contextMenuLabels = [
+ WebInspector.UIString("Break on Subtree Modifications"),
+ WebInspector.UIString("Break on Attributes Modifications"),
+ WebInspector.UIString("Break on Node Removal")
+ ];
+}
+
+WebInspector.DOMBreakpointsSidebarPane.prototype = {
+ setInspectedURL: function(url)
+ {
+ this._reset();
+ this._inspectedURL = url.removeURLFragment();
+ },
+
+ populateNodeContextMenu: function(node, contextMenu)
+ {
+ var nodeBreakpoints = {};
+ for (var id in this._breakpointElements) {
+ var element = this._breakpointElements[id];
+ if (element._node === node)
+ nodeBreakpoints[element._type] = true;
+ }
+
+ function toggleBreakpoint(type)
+ {
+ if (!nodeBreakpoints[type])
+ this._setBreakpoint(node, type, true);
+ else
+ this._removeBreakpoint(node, type);
+ this._saveBreakpoints();
+ }
+
+ for (var type = 0; type < 3; ++type) {
+ var label = this._contextMenuLabels[type];
+ contextMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
+ }
+ },
+
+ createBreakpointHitStatusMessage: function(eventData, callback)
+ {
+ if (eventData.type === this._breakpointTypes.SubtreeModified) {
+ var targetNodeObject = WebInspector.RemoteObject.fromPayload(eventData.targetNode);
+ function didPushNodeToFrontend(targetNodeId)
+ {
+ if (targetNodeId)
+ targetNodeObject.release();
+ this._doCreateBreakpointHitStatusMessage(eventData, targetNodeId, callback);
+ }
+ targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
+ } else
+ this._doCreateBreakpointHitStatusMessage(eventData, null, callback);
+ },
+
+ _doCreateBreakpointHitStatusMessage: function (eventData, targetNodeId, callback)
+ {
+ var message;
+ var typeLabel = this._breakpointTypeLabels[eventData.type];
+ var linkifiedNode = WebInspector.panels.elements.linkifyNodeById(eventData.nodeId);
+ var substitutions = [typeLabel, linkifiedNode];
+ var targetNode = "";
+ if (targetNodeId)
+ targetNode = WebInspector.panels.elements.linkifyNodeById(targetNodeId);
+
+ if (eventData.type === this._breakpointTypes.SubtreeModified) {
+ if (eventData.insertion) {
+ if (targetNodeId !== eventData.nodeId) {
+ message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
+ substitutions.push(targetNode);
+ } else
+ message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
+ } else {
+ message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
+ substitutions.push(targetNode);
+ }
+ } else
+ message = "Paused on a \"%s\" breakpoint set on %s.";
+
+ var element = document.createElement("span");
+ var formatters = {
+ s: function(substitution)
+ {
+ return substitution;
+ }
+ };
+ function append(a, b)
+ {
+ if (typeof b === "string")
+ b = document.createTextNode(b);
+ element.appendChild(b);
+ }
+ WebInspector.formatLocalized(message, substitutions, formatters, "", append);
+
+ callback(element);
+ },
+
+ nodeRemoved: function(node)
+ {
+ this._removeBreakpointsForNode(node);
+ if (!node.children)
+ return;
+ for (var i = 0; i < node.children.length; ++i)
+ this._removeBreakpointsForNode(node.children[i]);
+ this._saveBreakpoints();
+ },
+
+ _removeBreakpointsForNode: function(node)
+ {
+ for (var id in this._breakpointElements) {
+ var element = this._breakpointElements[id];
+ if (element._node === node)
+ this._removeBreakpoint(element._node, element._type);
+ }
+ },
+
+ _setBreakpoint: function(node, type, enabled)
+ {
+ var breakpointId = this._createBreakpointId(node.id, type);
+ if (breakpointId in this._breakpointElements)
+ return;
+
+ var element = document.createElement("li");
+ element._node = node;
+ element._type = type;
+ element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);
+
+ var checkboxElement = document.createElement("input");
+ checkboxElement.className = "checkbox-elem";
+ checkboxElement.type = "checkbox";
+ checkboxElement.checked = enabled;
+ checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
+ element._checkboxElement = checkboxElement;
+ element.appendChild(checkboxElement);
+
+ var labelElement = document.createElement("span");
+ element.appendChild(labelElement);
+
+ var linkifiedNode = WebInspector.panels.elements.linkifyNodeById(node.id);
+ linkifiedNode.addStyleClass("monospace");
+ labelElement.appendChild(linkifiedNode);
+
+ var description = document.createElement("div");
+ description.className = "source-text";
+ description.textContent = this._breakpointTypeLabels[type];
+ labelElement.appendChild(description);
+
+ var currentElement = this.listElement.firstChild;
+ while (currentElement) {
+ if (currentElement._type && currentElement._type < element._type)
+ break;
+ currentElement = currentElement.nextSibling;
+ }
+ this._addListElement(element, currentElement);
+ this._breakpointElements[breakpointId] = element;
+ if (enabled)
+ BrowserDebuggerAgent.setDOMBreakpoint(node.id, type);
+ },
+
+ _removeBreakpoint: function(node, type)
+ {
+ var breakpointId = this._createBreakpointId(node.id, type);
+ var element = this._breakpointElements[breakpointId];
+ if (!element)
+ return;
+
+ this._removeListElement(element);
+ delete this._breakpointElements[breakpointId];
+ if (element._checkboxElement.checked)
+ BrowserDebuggerAgent.removeDOMBreakpoint(node.id, type);
+ },
+
+ _contextMenu: function(node, type, event)
+ {
+ var contextMenu = new WebInspector.ContextMenu();
+ function removeBreakpoint()
+ {
+ this._removeBreakpoint(node, type);
+ this._saveBreakpoints();
+ }
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint.bind(this));
+ contextMenu.show(event);
+ },
+
+ _checkboxClicked: function(node, type, event)
+ {
+ if (event.target.checked)
+ BrowserDebuggerAgent.setDOMBreakpoint(node.id, type);
+ else
+ BrowserDebuggerAgent.removeDOMBreakpoint(node.id, type);
+ this._saveBreakpoints();
+ },
+
+ highlightBreakpoint: function(eventData)
+ {
+ var breakpointId = this._createBreakpointId(eventData.nodeId, eventData.type);
+ var element = this._breakpointElements[breakpointId];
+ if (!element)
+ return;
+ this.expanded = true;
+ element.addStyleClass("breakpoint-hit");
+ this._highlightedElement = element;
+ },
+
+ clearBreakpointHighlight: function()
+ {
+ if (this._highlightedElement) {
+ this._highlightedElement.removeStyleClass("breakpoint-hit");
+ delete this._highlightedElement;
+ }
+ },
+
+ _createBreakpointId: function(nodeId, type)
+ {
+ return nodeId + ":" + type;
+ },
+
+ _saveBreakpoints: function()
+ {
+ var breakpoints = [];
+ var storedBreakpoints = WebInspector.settings.domBreakpoints;
+ for (var i = 0; i < storedBreakpoints.length; ++i) {
+ var breakpoint = storedBreakpoints[i];
+ if (breakpoint.url !== this._inspectedURL)
+ breakpoints.push(breakpoint);
+ }
+ for (var id in this._breakpointElements) {
+ var element = this._breakpointElements[id];
+ breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
+ }
+ WebInspector.settings.domBreakpoints = breakpoints;
+ },
+
+ restoreBreakpoints: function()
+ {
+ var pathToBreakpoints = {};
+
+ function didPushNodeByPathToFrontend(path, nodeId)
+ {
+ var node = WebInspector.domAgent.nodeForId(nodeId);
+ if (!node)
+ return;
+
+ var breakpoints = pathToBreakpoints[path];
+ for (var i = 0; i < breakpoints.length; ++i)
+ this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
+ }
+
+ var breakpoints = WebInspector.settings.domBreakpoints;
+ for (var i = 0; i < breakpoints.length; ++i) {
+ var breakpoint = breakpoints[i];
+ if (breakpoint.url !== this._inspectedURL)
+ continue;
+ var path = breakpoint.path;
+ if (!pathToBreakpoints[path]) {
+ pathToBreakpoints[path] = [];
+ WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
+ }
+ pathToBreakpoints[path].push(breakpoint);
+ }
+ }
+}
+
+WebInspector.DOMBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;
diff --git a/Source/WebCore/inspector/front-end/DataGrid.js b/Source/WebCore/inspector/front-end/DataGrid.js
index 6d54941..7d7109a 100644
--- a/Source/WebCore/inspector/front-end/DataGrid.js
+++ b/Source/WebCore/inspector/front-end/DataGrid.js
@@ -133,6 +133,7 @@ WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
this._columnsArray = [];
for (var columnIdentifier in columns) {
columns[columnIdentifier].ordinal = this._columnsArray.length;
+ columns[columnIdentifier].identifier = columnIdentifier;
this._columnsArray.push(columns[columnIdentifier]);
}
diff --git a/Source/WebCore/inspector/front-end/DebuggerModel.js b/Source/WebCore/inspector/front-end/DebuggerModel.js
index c1d59b1..a33d69b 100644
--- a/Source/WebCore/inspector/front-end/DebuggerModel.js
+++ b/Source/WebCore/inspector/front-end/DebuggerModel.js
@@ -31,7 +31,6 @@
WebInspector.DebuggerModel = function()
{
this._debuggerPausedDetails = {};
- this._breakpoints = {};
this._scripts = {};
InspectorBackend.registerDomainDispatcher("Debugger", new WebInspector.DebuggerDispatcher(this));
@@ -66,16 +65,15 @@ WebInspector.DebuggerModel.prototype = {
_debuggerWasDisabled: function()
{
- this._breakpoints = {};
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
},
- continueToLocation: function(sourceID, lineNumber, columnNumber)
+ continueToLocation: function(location)
{
- DebuggerAgent.continueToLocation(sourceID, lineNumber, columnNumber);
+ DebuggerAgent.continueToLocation(location);
},
- setBreakpoint: function(url, lineNumber, columnNumber, condition, enabled, callback)
+ setBreakpoint: function(url, lineNumber, columnNumber, condition, callback)
{
// Adjust column if needed.
var minColumnNumber = 0;
@@ -88,62 +86,35 @@ WebInspector.DebuggerModel.prototype = {
function didSetBreakpoint(error, breakpointId, locations)
{
- var breakpoint;
- if (!error && breakpointId) {
- breakpoint = new WebInspector.Breakpoint(breakpointId, url, "", lineNumber, columnNumber, condition, enabled);
- breakpoint.locations = locations;
- this._breakpoints[breakpointId] = breakpoint;
- }
if (callback)
- callback(breakpoint);
+ callback(error ? null : breakpointId, locations);
}
- DebuggerAgent.setBreakpointByUrl(url, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+ DebuggerAgent.setBreakpointByUrl(url, lineNumber, columnNumber, condition, didSetBreakpoint.bind(this));
},
- setBreakpointBySourceId: function(sourceID, lineNumber, columnNumber, condition, enabled, callback)
+ setBreakpointBySourceId: function(location, condition, callback)
{
- function didSetBreakpoint(error, breakpointId, actualLineNumber, actualColumnNumber)
+ function didSetBreakpoint(error, breakpointId, actualLocation)
{
- var breakpoint;
- if (!error && breakpointId) {
- breakpoint = new WebInspector.Breakpoint(breakpointId, "", sourceID, lineNumber, columnNumber, condition, enabled);
- breakpoint.addLocation(sourceID, actualLineNumber, actualColumnNumber);
- this._breakpoints[breakpointId] = breakpoint;
- }
if (callback)
- callback(breakpoint);
+ callback(error ? null : breakpointId, [actualLocation]);
}
- DebuggerAgent.setBreakpoint(sourceID, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+ DebuggerAgent.setBreakpoint(location, condition, didSetBreakpoint.bind(this));
},
- removeBreakpoint: function(breakpointId)
+ removeBreakpoint: function(breakpointId, callback)
{
- DebuggerAgent.removeBreakpoint(breakpointId);
- delete this._breakpoints[breakpointId];
+ DebuggerAgent.removeBreakpoint(breakpointId, callback);
},
- _breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber)
+ _breakpointResolved: function(breakpointId, location)
{
- var breakpoint = this._breakpoints[breakpointId];
- breakpoint.addLocation(sourceID, lineNumber, columnNumber);
- this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, breakpoint);
- },
-
- get breakpoints()
- {
- return this._breakpoints;
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, {breakpointId: breakpointId, location: location});
},
reset: function()
{
this._debuggerPausedDetails = {};
- for (var id in this._breakpoints) {
- var breakpoint = this._breakpoints[id];
- if (!breakpoint.url)
- delete this._breakpoints[id];
- else
- breakpoint.locations = [];
- }
this._scripts = {};
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Reset);
},
@@ -176,16 +147,14 @@ WebInspector.DebuggerModel.prototype = {
editScriptSource: function(sourceID, newSource, callback)
{
- DebuggerAgent.editScriptSource(sourceID, newSource, this._didEditScriptSource.bind(this, sourceID, callback));
+ this._scripts[sourceID].editSource(newSource, this._didEditScriptSource.bind(this, sourceID, newSource, callback));
},
- _didEditScriptSource: function(sourceID, callback, error, newBody, callFrames)
+ _didEditScriptSource: function(sourceID, newSource, callback, error, callFrames)
{
- callback(!error, error || newBody);
- if (error)
- return;
- this._scripts[sourceID].source = newBody;
- this._debuggerPausedDetails.callFrames = callFrames;
+ if (!error && callFrames && callFrames.length)
+ this._debuggerPausedDetails.callFrames = callFrames;
+ callback(error);
},
get callFrames()
@@ -210,16 +179,16 @@ WebInspector.DebuggerModel.prototype = {
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
},
- _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
+ _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript)
{
- var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, length, undefined, undefined, scriptWorldType);
+ var script = new WebInspector.Script(sourceID, sourceURL, lineOffset, columnOffset, length, undefined, undefined, isContentScript);
this._scripts[sourceID] = script;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
},
_failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage)
{
- var script = new WebInspector.Script(null, sourceURL, source, startingLine, errorLine, errorMessage, undefined);
+ var script = new WebInspector.Script(null, sourceURL, startingLine, errorLine, errorMessage, undefined);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script);
}
}
@@ -258,9 +227,9 @@ WebInspector.DebuggerDispatcher.prototype = {
this._debuggerModel._debuggerWasDisabled();
},
- scriptParsed: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
+ scriptParsed: function(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript)
{
- this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType);
+ this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript);
},
scriptFailedToParse: function(sourceURL, source, startingLine, errorLine, errorMessage)
diff --git a/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js b/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js
index d12affe..106d62f 100644
--- a/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js
+++ b/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js
@@ -32,7 +32,9 @@ WebInspector.DebuggerPresentationModel = function()
{
this._sourceFiles = {};
this._messages = [];
- this._presentationBreakpoints = {};
+ this._breakpointsByDebuggerId = {};
+ this._breakpointsWithoutSourceFile = {};
+
this._presentationCallFrames = [];
this._selectedCallFrameIndex = 0;
@@ -42,7 +44,9 @@ WebInspector.DebuggerPresentationModel = function()
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Reset, this._reset, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.Reset, this._debuggerReset, this);
+
+ new WebInspector.DebuggerPresentationModelResourceBinding(this);
}
WebInspector.DebuggerPresentationModel.Events = {
@@ -59,7 +63,7 @@ WebInspector.DebuggerPresentationModel.Events = {
WebInspector.DebuggerPresentationModel.prototype = {
_debuggerWasEnabled: function()
{
- this._restoreBreakpoints();
+ this._restoreBreakpointsFromSettings();
},
sourceFile: function(sourceFileId)
@@ -67,6 +71,11 @@ WebInspector.DebuggerPresentationModel.prototype = {
return this._sourceFiles[sourceFileId];
},
+ sourceFileForScriptURL: function(scriptURL)
+ {
+ return this._sourceFiles[scriptURL];
+ },
+
requestSourceFileContent: function(sourceFileId, callback)
{
this._sourceFiles[sourceFileId].requestContent(callback);
@@ -75,18 +84,16 @@ WebInspector.DebuggerPresentationModel.prototype = {
_parsedScriptSource: function(event)
{
this._addScript(event.data);
- this._refreshBreakpoints();
},
_failedToParseScriptSource: function(event)
{
this._addScript(event.data);
- this._refreshBreakpoints();
},
_addScript: function(script)
{
- var sourceFileId = script.sourceURL || script.sourceID;
+ var sourceFileId = this._createSourceFileId(script.sourceURL, script.sourceID);
var sourceFile = this._sourceFiles[sourceFileId];
if (sourceFile) {
sourceFile.addScript(script);
@@ -100,65 +107,74 @@ WebInspector.DebuggerPresentationModel.prototype = {
if (!this._formatSourceFiles)
sourceFile = new WebInspector.SourceFile(sourceFileId, script, contentChanged.bind(this));
else
- sourceFile = new WebInspector.FormattedSourceFile(sourceFileId, script, contentChanged.bind(this), this._formatter);
+ sourceFile = new WebInspector.FormattedSourceFile(sourceFileId, script, contentChanged.bind(this), this._formatter());
this._sourceFiles[sourceFileId] = sourceFile;
+
+ this._restoreBreakpoints(sourceFile);
+
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.SourceFileAdded, sourceFile);
},
- _refreshBreakpoints: function()
+ _restoreBreakpoints: function(sourceFile)
{
- var breakpoints = WebInspector.debuggerModel.breakpoints;
- for (var id in breakpoints) {
- if (!(id in this._presentationBreakpoints))
- this._breakpointAdded(breakpoints[id]);
+ var pendingBreakpoints = this._breakpointsWithoutSourceFile[sourceFile.id];
+ for (var i = 0; pendingBreakpoints && i < pendingBreakpoints.length; ++i) {
+ var breakpointData = pendingBreakpoints[i];
+ if ("debuggerId" in breakpointData) {
+ var breakpoint = new WebInspector.PresentationBreakpoint(sourceFile, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled);
+ this._bindDebuggerId(breakpoint, breakpointData.debuggerId);
+ this._breakpointAdded(breakpoint);
+ } else
+ this.setBreakpoint(sourceFile.id, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled, true);
}
+ delete this._breakpointsWithoutSourceFile[sourceFile.id];
},
canEditScriptSource: function(sourceFileId)
{
- if (!Preferences.canEditScriptSource)
+ if (!Preferences.canEditScriptSource || this._formatSourceFiles)
return false;
var script = this._scriptForSourceFileId(sourceFileId);
- return !script.lineOffset && !script.columnOffset;
+ return !script.lineOffset && !script.columnOffset;
},
- editScriptSource: function(sourceFileId, text, callback)
+ editScriptSource: function(sourceFileId, newSource, callback)
{
var script = this._scriptForSourceFileId(sourceFileId);
var sourceFile = this._sourceFiles[sourceFileId];
- var oldSource = sourceFile.content;
- function didEditScriptSource(success, newBodyOrErrorMessage)
- {
- if (!success) {
- callback(false, newBodyOrErrorMessage);
- return;
- }
- var newSource = newBodyOrErrorMessage;
- this._updateBreakpointsAfterLiveEdit(sourceFileId, oldSource, newSource);
+ function didEditScriptSource(oldSource, error)
+ {
+ if (!error) {
+ sourceFile.content = newSource;
- var resource = WebInspector.resourceForURL(script.sourceURL);
- if (resource) {
- var revertHandle = this.editScriptSource.bind(this, sourceFileId, oldSource, sourceFile.reload.bind(sourceFile));
- resource.setContent(newSource, revertHandle);
+ var resource = WebInspector.resourceForURL(sourceFile.url);
+ if (resource)
+ resource.addRevision(newSource);
}
- callback(true, newSource);
+ callback(error);
- if (WebInspector.debuggerModel.callFrames)
+ if (!error && WebInspector.debuggerModel.callFrames)
this._debuggerPaused();
}
- WebInspector.debuggerModel.editScriptSource(script.sourceID, text, didEditScriptSource.bind(this));
+
+ var oldSource = sourceFile.requestContent(didReceiveSource.bind(this));
+ function didReceiveSource(oldSource)
+ {
+ WebInspector.debuggerModel.editScriptSource(script.sourceID, newSource, didEditScriptSource.bind(this, oldSource));
+ }
},
_updateBreakpointsAfterLiveEdit: function(sourceFileId, oldSource, newSource)
{
+ var sourceFile = this._sourceFiles[sourceFileId];
+
// Clear and re-create breakpoints according to text diff.
var diff = Array.diff(oldSource.split("\n"), newSource.split("\n"));
- for (var id in this._presentationBreakpoints) {
- var breakpoint = this._presentationBreakpoints[id];
- if (breakpoint.sourceFileId !== sourceFileId)
- continue;
+ for (var lineNumber in sourceFile.breakpoints) {
+ var breakpoint = sourceFile.breakpoints[lineNumber];
+
var lineNumber = breakpoint.lineNumber;
this.removeBreakpoint(sourceFileId, lineNumber);
@@ -184,13 +200,15 @@ WebInspector.DebuggerPresentationModel.prototype = {
toggleFormatSourceFiles: function()
{
this._formatSourceFiles = !this._formatSourceFiles;
- if (this._formatSourceFiles && !this._formatter)
- this._formatter = new WebInspector.ScriptFormatter();
+
+ for (var id in this._sourceFiles) {
+ var sourceFile = this._sourceFiles[id];
+ for (var line in sourceFile.breakpoints)
+ this._removeBreakpointFromDebugger(sourceFile.breakpoints[line]);
+ }
var messages = this._messages;
- this._sourceFiles = {};
- this._messages = [];
- this._presentationBreakpoints = {};
+ this._reset();
var scripts = WebInspector.debuggerModel.scripts;
for (var id in scripts)
@@ -199,17 +217,27 @@ WebInspector.DebuggerPresentationModel.prototype = {
for (var i = 0; i < messages.length; ++i)
this.addConsoleMessage(messages[i]);
- this._refreshBreakpoints();
-
if (WebInspector.debuggerModel.callFrames)
this._debuggerPaused();
},
+ formatSourceFilesToggled: function()
+ {
+ return this._formatSourceFiles;
+ },
+
+ _formatter: function()
+ {
+ if (!this._scriptFormatter)
+ this._scriptFormatter = new WebInspector.ScriptFormatter();
+ return this._scriptFormatter;
+ },
+
addConsoleMessage: function(message)
{
this._messages.push(message);
- var sourceFile = this._sourceFileForScriptURL(message.url);
+ var sourceFile = this._sourceFileForScript(message.url);
if (!sourceFile)
return;
@@ -217,7 +245,7 @@ WebInspector.DebuggerPresentationModel.prototype = {
{
var presentationMessage = {};
presentationMessage.sourceFileId = sourceFile.id;
- presentationMessage.lineNumber = mapping.scriptLocationToSourceLocation(message.line - 1, 0).lineNumber;
+ presentationMessage.lineNumber = mapping.scriptLocationToSourceLine({lineNumber:message.line - 1, columnNumber:0});
presentationMessage.originalMessage = message;
sourceFile.messages.push(presentationMessage);
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ConsoleMessageAdded, presentationMessage);
@@ -236,8 +264,8 @@ WebInspector.DebuggerPresentationModel.prototype = {
{
function didRequestSourceMapping(mapping)
{
- var location = mapping.sourceLocationToScriptLocation(lineNumber, 0);
- WebInspector.debuggerModel.continueToLocation(location.scriptId, location.lineNumber, location.columnNumber);
+ var location = mapping.sourceLineToScriptLocation(lineNumber);
+ WebInspector.debuggerModel.continueToLocation(location);
}
this._sourceFiles[sourceFileId].requestSourceMapping(didRequestSourceMapping.bind(this));
},
@@ -253,32 +281,104 @@ WebInspector.DebuggerPresentationModel.prototype = {
return breakpoints;
},
- setBreakpoint: function(sourceFileId, lineNumber, condition, enabled)
+ setBreakpoint: function(sourceFileId, lineNumber, condition, enabled, dontSaveBreakpoints)
{
- function didSetBreakpoint(breakpoint)
+ var sourceFile = this._sourceFiles[sourceFileId];
+ if (!sourceFile)
+ return;
+
+ var breakpoint = new WebInspector.PresentationBreakpoint(sourceFile, lineNumber, condition, enabled);
+ if (!enabled) {
+ this._breakpointAdded(breakpoint);
+ if (!dontSaveBreakpoints)
+ this._saveBreakpoints();
+ return;
+ }
+
+ function callback()
{
- if (breakpoint) {
- this._breakpointAdded(breakpoint);
+ this._breakpointAdded(breakpoint);
+ if (!dontSaveBreakpoints)
this._saveBreakpoints();
- }
+ }
+ this._setBreakpointInDebugger(breakpoint, callback.bind(this));
+ },
+
+ _setBreakpointInDebugger: function(breakpoint, callback)
+ {
+ function didSetBreakpoint(breakpointId, locations)
+ {
+ if (!breakpointId)
+ return;
+
+ this._bindDebuggerId(breakpoint, breakpointId);
+ breakpoint.location = locations[0];
+ callback();
}
function didRequestSourceMapping(mapping)
{
- var location = mapping.sourceLocationToScriptLocation(lineNumber, 0);
- var script = WebInspector.debuggerModel.scriptForSourceID(location.scriptId);
+ var location = mapping.sourceLineToScriptLocation(breakpoint.lineNumber);
+ var script = WebInspector.debuggerModel.scriptForSourceID(location.sourceID);
if (script.sourceURL)
- WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
- else
- WebInspector.debuggerModel.setBreakpointBySourceId(script.sourceID, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+ WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, breakpoint.condition, didSetBreakpoint.bind(this));
+ else {
+ location.sourceID = script.sourceID;
+ WebInspector.debuggerModel.setBreakpointBySourceId(location, breakpoint.condition, didSetBreakpoint.bind(this));
+ }
}
- this._sourceFiles[sourceFileId].requestSourceMapping(didRequestSourceMapping.bind(this));
+ breakpoint.sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
+ },
+
+ _removeBreakpointFromDebugger: function(breakpoint, callback)
+ {
+ if (!("debuggerId" in breakpoint)) {
+ if (callback)
+ callback();
+ return;
+ }
+
+ function didRemoveBreakpoint()
+ {
+ this._unbindDebuggerId(breakpoint);
+ if (callback)
+ callback();
+ }
+ WebInspector.debuggerModel.removeBreakpoint(breakpoint.debuggerId, didRemoveBreakpoint.bind(this));
+ },
+
+ _bindDebuggerId: function(breakpoint, debuggerId)
+ {
+ breakpoint.debuggerId = debuggerId;
+ this._breakpointsByDebuggerId[debuggerId] = breakpoint;
+ },
+
+ _unbindDebuggerId: function(breakpoint)
+ {
+ delete this._breakpointsByDebuggerId[breakpoint.debuggerId];
+ delete breakpoint.debuggerId;
},
setBreakpointEnabled: function(sourceFileId, lineNumber, enabled)
{
- var breakpoint = this.removeBreakpoint(sourceFileId, lineNumber);
- this.setBreakpoint(sourceFileId, lineNumber, breakpoint.condition, enabled);
+ var breakpoint = this.findBreakpoint(sourceFileId, lineNumber);
+ if (!breakpoint)
+ return;
+
+ this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+
+ breakpoint.enabled = enabled;
+
+ function afterUpdate()
+ {
+ this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
+ this._saveBreakpoints();
+ }
+
+ if (!enabled)
+ this._removeBreakpointFromDebugger(breakpoint, afterUpdate.call(this));
+ else
+ this._setBreakpointInDebugger(breakpoint, afterUpdate.bind(this));
},
updateBreakpoint: function(sourceFileId, lineNumber, condition, enabled)
@@ -290,10 +390,15 @@ WebInspector.DebuggerPresentationModel.prototype = {
removeBreakpoint: function(sourceFileId, lineNumber)
{
var breakpoint = this.findBreakpoint(sourceFileId, lineNumber);
- WebInspector.debuggerModel.removeBreakpoint(breakpoint._id);
- this._breakpointRemoved(breakpoint._id);
- this._saveBreakpoints();
- return breakpoint;
+ if (!breakpoint)
+ return;
+
+ function callback()
+ {
+ this._breakpointRemoved(breakpoint);
+ this._saveBreakpoints();
+ }
+ this._removeBreakpointFromDebugger(breakpoint, callback.bind(this));
},
findBreakpoint: function(sourceFileId, lineNumber)
@@ -305,84 +410,96 @@ WebInspector.DebuggerPresentationModel.prototype = {
_breakpointAdded: function(breakpoint)
{
- var script;
- if (breakpoint.url)
- script = WebInspector.debuggerModel.scriptsForURL(breakpoint.url)[0];
- else
- script = WebInspector.debuggerModel.scriptForSourceID(breakpoint.sourceID);
- if (!script)
+ var sourceFile = breakpoint.sourceFile;
+ if (!sourceFile)
return;
function didRequestSourceMapping(mapping)
{
- var scriptLocation = breakpoint.locations.length ? breakpoint.locations[0] : breakpoint;
- var sourceLocation = mapping.scriptLocationToSourceLocation(scriptLocation.lineNumber, scriptLocation.columnNumber);
- var lineNumber = sourceLocation.lineNumber;
+ // Refine line number based on resolved location.
+ if (breakpoint.location)
+ breakpoint.lineNumber = mapping.scriptLocationToSourceLine(breakpoint.location);
- if (this.findBreakpoint(sourceFile.id, lineNumber)) {
+ var existingBreakpoint = this.findBreakpoint(sourceFile.id, breakpoint.lineNumber);
+ if (existingBreakpoint) {
// We can't show more than one breakpoint on a single source file line.
- WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
+ this._removeBreakpointFromDebugger(breakpoint);
return;
}
-
- var presentationBreakpoint = new WebInspector.PresentationBreakpoint(breakpoint, sourceFile, lineNumber);
- presentationBreakpoint._id = breakpoint.id;
- this._presentationBreakpoints[breakpoint.id] = presentationBreakpoint;
- sourceFile.breakpoints[lineNumber] = presentationBreakpoint;
- this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, presentationBreakpoint);
+ sourceFile.breakpoints[breakpoint.lineNumber] = breakpoint;
+ this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
}
- var sourceFile = this._sourceFileForScript(script);
sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
},
- _breakpointRemoved: function(breakpointId)
+ _breakpointRemoved: function(breakpoint)
{
- var breakpoint = this._presentationBreakpoints[breakpointId];
- delete this._presentationBreakpoints[breakpointId];
- var sourceFile = this.sourceFile(breakpoint.sourceFileId);
- delete sourceFile.breakpoints[breakpoint.lineNumber];
- this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+ var sourceFile = breakpoint.sourceFile;
+ if (sourceFile.breakpoints[breakpoint.lineNumber] === breakpoint) {
+ // There can already be a newer breakpoint;
+ delete sourceFile.breakpoints[breakpoint.lineNumber];
+ this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+ }
},
_breakpointResolved: function(event)
{
- var breakpoint = event.data;
- if (!(breakpoint.id in this._presentationBreakpoints))
+ var debuggerId = event.data.breakpointId;
+ if (!(debuggerId in this._breakpointsByDebuggerId))
return;
- this._breakpointRemoved(breakpoint.id);
+ var breakpoint = this._breakpointsByDebuggerId[debuggerId];
+
+ this._breakpointRemoved(breakpoint);
+ breakpoint.location = event.data.location;
this._breakpointAdded(breakpoint);
},
- _restoreBreakpoints: function()
+ _restoreBreakpointsFromSettings: function()
{
- function didSetBreakpoint(breakpoint)
- {
- if (breakpoint)
- this._breakpointAdded(breakpoint);
- }
var breakpoints = WebInspector.settings.breakpoints;
for (var i = 0; i < breakpoints.length; ++i) {
- var breakpoint = breakpoints[i];
- WebInspector.debuggerModel.setBreakpoint(breakpoint.url, breakpoint.lineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled, didSetBreakpoint.bind(this));
+ var breakpointData = breakpoints[i];
+ var sourceFileId = breakpointData.sourceFileId;
+ if (!sourceFileId)
+ continue;
+ var sourceFile = this._sourceFiles[sourceFileId];
+ if (sourceFile) {
+ this.setBreakpoint(sourceFileId, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled);
+ continue;
+ }
+
+ // Add breakpoint once source file becomes available.
+ var pendingBreakpoints = this._breakpointsWithoutSourceFile[sourceFileId];
+ if (!pendingBreakpoints) {
+ pendingBreakpoints = [];
+ this._breakpointsWithoutSourceFile[sourceFileId] = pendingBreakpoints;
+ }
+ pendingBreakpoints.push(breakpointData);
}
},
_saveBreakpoints: function()
{
var serializedBreakpoints = [];
- var breakpoints = WebInspector.debuggerModel.breakpoints;
- for (var id in breakpoints) {
- var breakpoint = breakpoints[id];
- if (!breakpoint.url)
+
+ // Store added breakpoints.
+ for (var sourceFileId in this._sourceFiles) {
+ var sourceFile = this._sourceFiles[sourceFileId];
+ if (!sourceFile.url)
continue;
- var serializedBreakpoint = {};
- serializedBreakpoint.url = breakpoint.url;
- serializedBreakpoint.lineNumber = breakpoint.lineNumber;
- serializedBreakpoint.columnNumber = breakpoint.columnNumber;
- serializedBreakpoint.condition = breakpoint.condition;
- serializedBreakpoint.enabled = breakpoint.enabled;
- serializedBreakpoints.push(serializedBreakpoint);
+
+ for (var lineNumber in sourceFile.breakpoints)
+ serializedBreakpoints.push(sourceFile.breakpoints[lineNumber].serialize());
}
+
+ // Store not added breakpoints.
+ for (var sourceFileId in this._breakpointsWithoutSourceFile)
+ serializedBreakpoints = serializedBreakpoints.concat(this._breakpointsWithoutSourceFile[sourceFileId]);
+
+ // Sanitize debugger ids.
+ for (var i = 0; i < serializedBreakpoints.length; ++i)
+ delete serializedBreakpoints[i].debuggerId;
+
WebInspector.settings.breakpoints = serializedBreakpoints;
},
@@ -393,9 +510,9 @@ WebInspector.DebuggerPresentationModel.prototype = {
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
var sourceFile;
- var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID);
+ var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.location.sourceID);
if (script)
- sourceFile = this._sourceFileForScript(script);
+ sourceFile = this._sourceFileForScript(script.sourceURL, script.sourceID);
this._presentationCallFrames.push(new WebInspector.PresenationCallFrame(callFrame, i, sourceFile));
}
var details = WebInspector.debuggerModel.debuggerPausedDetails;
@@ -423,30 +540,48 @@ WebInspector.DebuggerPresentationModel.prototype = {
return this._presentationCallFrames[this._selectedCallFrameIndex];
},
- _sourceFileForScript: function(script)
+ _sourceFileForScript: function(sourceURL, sourceID)
{
- return this._sourceFiles[script.sourceURL || script.sourceID];
- },
-
- _sourceFileForScriptURL: function(scriptURL)
- {
- return this._sourceFiles[scriptURL];
+ return this._sourceFiles[this._createSourceFileId(sourceURL, sourceID)];
},
_scriptForSourceFileId: function(sourceFileId)
{
function filter(script)
{
- return (script.sourceURL || script.sourceID) === sourceFileId;
+ return this._createSourceFileId(script.sourceURL, script.sourceID) === sourceFileId;
}
- return WebInspector.debuggerModel.queryScripts(filter)[0];
+ return WebInspector.debuggerModel.queryScripts(filter.bind(this))[0];
+ },
+
+ _createSourceFileId: function(sourceURL, sourceID)
+ {
+ var prefix = this._formatSourceFiles ? "deobfuscated:" : "";
+ return prefix + (sourceURL || sourceID);
},
_reset: function()
{
+ for (var id in this._sourceFiles) {
+ var sourceFile = this._sourceFiles[id];
+ for (var line in sourceFile.breakpoints) {
+ var breakpoints = this._breakpointsWithoutSourceFile[sourceFile.id];
+ if (!breakpoints) {
+ breakpoints = [];
+ this._breakpointsWithoutSourceFile[sourceFile.id] = breakpoints;
+ }
+ breakpoints.push(sourceFile.breakpoints[line].serialize());
+ }
+ }
+
this._sourceFiles = {};
this._messages = [];
- this._presentationBreakpoints = {};
+ this._breakpointsByDebuggerId = {};
+ },
+
+ _debuggerReset: function()
+ {
+ this._reset();
this._presentationCallFrames = [];
this._selectedCallFrameIndex = 0;
}
@@ -454,42 +589,24 @@ WebInspector.DebuggerPresentationModel.prototype = {
WebInspector.DebuggerPresentationModel.prototype.__proto__ = WebInspector.Object.prototype;
-WebInspector.PresentationBreakpoint = function(breakpoint, sourceFile, lineNumber)
+WebInspector.PresentationBreakpoint = function(sourceFile, lineNumber, condition, enabled)
{
- this._breakpoint = breakpoint;
- this._sourceFile = sourceFile;
- this._lineNumber = lineNumber;
+ this.sourceFile = sourceFile;
+ this.sourceFileId = sourceFile.id;
+ this.lineNumber = lineNumber;
+ this.condition = condition;
+ this.enabled = enabled;
}
WebInspector.PresentationBreakpoint.prototype = {
- get sourceFileId()
- {
- return this._sourceFile.id;
- },
-
- get lineNumber()
- {
- return this._lineNumber;
- },
-
- get condition()
- {
- return this._breakpoint.condition;
- },
-
- get enabled()
- {
- return this._breakpoint.enabled;
- },
-
get url()
{
- return this._sourceFile.url;
+ return this.sourceFile.url;
},
get resolved()
{
- return !!this._breakpoint.locations.length
+ return !!this.location;
},
loadSnippet: function(callback)
@@ -502,7 +619,22 @@ WebInspector.PresentationBreakpoint.prototype = {
snippet = content.substring(lineEndings[this.lineNumber - 1], lineEndings[this.lineNumber]);
callback(snippet);
}
- this._sourceFile.requestContent(didRequestContent.bind(this));
+ if (!this.sourceFile) {
+ callback(WebInspector.UIString("N/A"));
+ return;
+ }
+ this.sourceFile.requestContent(didRequestContent.bind(this));
+ },
+
+ serialize: function()
+ {
+ var serializedBreakpoint = {};
+ serializedBreakpoint.sourceFileId = this.sourceFile.id;
+ serializedBreakpoint.lineNumber = this.lineNumber;
+ serializedBreakpoint.condition = this.condition;
+ serializedBreakpoint.enabled = this.enabled;
+ serializedBreakpoint.debuggerId = this.debuggerId;
+ return serializedBreakpoint;
}
}
@@ -511,7 +643,7 @@ WebInspector.PresenationCallFrame = function(callFrame, index, sourceFile)
this._callFrame = callFrame;
this._index = index;
this._sourceFile = sourceFile;
- this._script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID);
+ this._script = WebInspector.debuggerModel.scriptForSourceID(callFrame.location.sourceID);
}
WebInspector.PresenationCallFrame.prototype = {
@@ -561,18 +693,63 @@ WebInspector.PresenationCallFrame.prototype = {
DebuggerAgent.evaluateOnCallFrame(this._callFrame.id, code, objectGroup, includeCommandLineAPI, didEvaluateOnCallFrame.bind(this));
},
- sourceLocation: function(callback)
+ sourceLine: function(callback)
{
if (!this._sourceFile) {
- callback(undefined, this._callFrame.line, this._callFrame.column);
+ callback(undefined, this._callFrame.location.lineNumber);
return;
}
function didRequestSourceMapping(mapping)
{
- var sourceLocation = mapping.scriptLocationToSourceLocation(this._callFrame.line, this._callFrame.column);
- callback(this._sourceFile.id, sourceLocation.lineNumber, sourceLocation.columnNumber);
+ callback(this._sourceFile.id, mapping.scriptLocationToSourceLine(this._callFrame.location));
}
this._sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
}
}
+
+WebInspector.DebuggerPresentationModelResourceBinding = function(model)
+{
+ this._presentationModel = model;
+ WebInspector.Resource.registerDomainModelBinding(WebInspector.Resource.Type.Script, this);
+}
+
+WebInspector.DebuggerPresentationModelResourceBinding.prototype = {
+ canSetContent: function(resource)
+ {
+ var sourceFile = this._presentationModel._sourceFileForScript(resource.url)
+ if (!sourceFile)
+ return false;
+ return this._presentationModel.canEditScriptSource(sourceFile.id);
+ },
+
+ setContent: function(resource, content, majorChange, userCallback)
+ {
+ if (!majorChange)
+ return;
+
+ var sourceFile = this._presentationModel._sourceFileForScript(resource.url);
+ if (!sourceFile) {
+ userCallback("Resource is not editable");
+ return;
+ }
+
+ resource.requestContent(this._setContentWithInitialContent.bind(this, sourceFile, content, userCallback));
+ },
+
+ _setContentWithInitialContent: function(sourceFile, content, userCallback, oldContent)
+ {
+ function callback(error)
+ {
+ if (userCallback)
+ userCallback(error);
+ if (!error) {
+ this._presentationModel._updateBreakpointsAfterLiveEdit(sourceFile.id, oldContent, content);
+ sourceFile.reload();
+ }
+ }
+ this._presentationModel.editScriptSource(sourceFile.id, content, callback.bind(this));
+ }
+}
+
+WebInspector.DebuggerPresentationModelResourceBinding.prototype.__proto__ = WebInspector.ResourceDomainModelBinding.prototype;
diff --git a/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js b/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js
index 4fc1844..e706e1d 100644
--- a/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js
+++ b/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js
@@ -28,10 +28,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.HeapSnapshotGridNode = function(tree, hasChildren, populateCount)
+WebInspector.HeapSnapshotGridNode = function(tree, hasChildren)
{
WebInspector.DataGridNode.call(this, null, hasChildren);
- this._defaultPopulateCount = populateCount;
+ this._defaultPopulateCount = tree._defaultPopulateCount;
this._provider = null;
this.addEventListener("populate", this._populate, this);
}
@@ -51,20 +51,24 @@ WebInspector.HeapSnapshotGridNode.prototype = {
function doPopulate()
{
- this._provider.sort(this.comparator());
- this._provider.first();
- this.populateChildren();
this.removeEventListener("populate", this._populate, this);
+ function sorted(ignored)
+ {
+ this.populateChildren();
+ }
+ this._provider.sortAndRewind(this.comparator(), sorted.bind(this));
}
},
- populateChildren: function(provider, howMany, atIndex)
+ populateChildren: function(provider, howMany, atIndex, afterPopulate, suppressNotifyAboutCompletion)
{
if (!howMany && provider) {
howMany = provider.instanceCount;
provider.instanceCount = 0;
}
provider = provider || this._provider;
+ if (!("instanceCount" in provider))
+ provider.instanceCount = 0;
howMany = howMany || this._defaultPopulateCount;
atIndex = atIndex || this.children.length;
var haveSavedChildren = !!this._savedChildren;
@@ -75,19 +79,35 @@ WebInspector.HeapSnapshotGridNode.prototype = {
break;
}
}
- for ( ; howMany > 0 && provider.hasNext(); provider.next(), ++provider.instanceCount, --howMany) {
- var item = provider.item;
- if (haveSavedChildren) {
- var hash = this._childHashForEntity(item);
- if (hash in this._savedChildren) {
- this.insertChild(this._savedChildren[hash], atIndex++);
- continue;
+
+ function childrenRetrieved(items, hasNext, length)
+ {
+ for (var i = 0, l = items.length; i < l; ++i) {
+ var item = items[i];
+ if (haveSavedChildren) {
+ var hash = this._childHashForEntity(item);
+ if (hash in this._savedChildren) {
+ this.insertChild(this._savedChildren[hash], atIndex++);
+ continue;
+ }
+ }
+ this.insertChild(this._createChildNode(item, provider), atIndex++);
+ }
+ provider.instanceCount += items.length;
+
+ if (hasNext)
+ this.insertChild(new WebInspector.ShowMoreDataGridNode(this.populateChildren.bind(this, provider), this._defaultPopulateCount, length), atIndex++);
+ if (afterPopulate)
+ afterPopulate();
+ if (!suppressNotifyAboutCompletion) {
+ function notify()
+ {
+ this.dispatchEventToListeners("populate complete");
}
+ setTimeout(notify.bind(this), 0);
}
- this.insertChild(this._createChildNode(provider), atIndex++);
}
- if (provider.hasNext())
- this.insertChild(new WebInspector.ShowMoreDataGridNode(this.populateChildren.bind(this, provider), this._defaultPopulateCount, provider.length), atIndex++);
+ provider.getNextItems(howMany, childrenRetrieved.bind(this));
},
_saveChildren: function()
@@ -102,31 +122,38 @@ WebInspector.HeapSnapshotGridNode.prototype = {
sort: function()
{
- var comparator = this.comparator();
- WebInspector.PleaseWaitMessage.prototype.startAction(this.dataGrid.element, doSort.bind(this));
-
function doSort()
{
- if (!this._provider.sort(comparator))
- return;
- this._saveChildren();
- this.removeChildren();
- this._provider.first();
- this.populateChildren(this._provider);
- for (var i = 0, l = this.children.length; i < l; ++i) {
- var child = this.children[i];
- if (child.expanded)
- child.sort();
+ function afterSort(sorted)
+ {
+ if (!sorted)
+ return;
+ this._saveChildren();
+ this.removeChildren();
+
+ function afterPopulate()
+ {
+ for (var i = 0, l = this.children.length; i < l; ++i) {
+ var child = this.children[i];
+ if (child.expanded)
+ child.sort();
+ }
+ this.dataGrid.dispatchEventToListeners("sorting complete");
+ }
+ this.populateChildren(this._provider, null, null, afterPopulate.bind(this));
}
+ this._provider.sortAndRewind(this.comparator(), afterSort.bind(this));
}
+ this.dataGrid.dispatchEventToListeners("start sorting");
+ WebInspector.PleaseWaitMessage.prototype.startAction(this.dataGrid.element, doSort.bind(this));
}
};
WebInspector.HeapSnapshotGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
-WebInspector.HeapSnapshotGenericObjectNode = function(tree, node, hasChildren, populateCount)
+WebInspector.HeapSnapshotGenericObjectNode = function(tree, node)
{
- WebInspector.HeapSnapshotGridNode.call(this, tree, hasChildren, populateCount);
+ WebInspector.HeapSnapshotGridNode.call(this, tree, false);
this._name = node.name;
this._type = node.type;
this._shallowSize = node.selfSize;
@@ -167,7 +194,7 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
get _countPercent()
{
- return this._count / this.tree.snapshot.nodeCount * 100.0;
+ return this._count / this.dataGrid.snapshot.nodeCount * 100.0;
},
get data()
@@ -216,6 +243,15 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
get _shallowSizePercent()
{
return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0;
+ },
+
+ _updateHasChildren: function()
+ {
+ function isEmptyCallback(isEmpty)
+ {
+ this.hasChildren = !isEmpty;
+ }
+ this._provider.isEmpty(isEmptyCallback.bind(this));
}
}
@@ -223,24 +259,23 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype.__proto__ = WebInspector.He
WebInspector.HeapSnapshotObjectNode = function(tree, edge)
{
- var provider = this._createProvider(tree.snapshot, edge.nodeIndex);
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, edge.node, !provider.isEmpty, 100);
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, edge.node);
this._referenceName = edge.name;
this._referenceType = edge.type;
- this._provider = provider;
+ this._provider = this._createProvider(tree.snapshot, edge.nodeIndex);
+ this._updateHasChildren();
}
WebInspector.HeapSnapshotObjectNode.prototype = {
- _createChildNode: function(provider)
+ _createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, provider.item);
+ return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, item);
},
_createProvider: function(snapshot, nodeIndex)
{
var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
- return new WebInspector.HeapSnapshotEdgesProvider(
- snapshot,
+ return snapshot.createEdgesProvider(
nodeIndex,
function(edge) {
return !edge.isInvisible
@@ -312,23 +347,22 @@ WebInspector.HeapSnapshotObjectNode.prototype.__proto__ = WebInspector.HeapSnaps
WebInspector.HeapSnapshotInstanceNode = function(tree, baseSnapshot, snapshot, node)
{
- var provider = this._createProvider(baseSnapshot || snapshot, node.nodeIndex);
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node, !provider.isEmpty, 100);
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
this._isDeletedNode = !!baseSnapshot;
- this._provider = provider;
+ this._provider = this._createProvider(baseSnapshot || snapshot, node.nodeIndex);
+ this._updateHasChildren();
};
WebInspector.HeapSnapshotInstanceNode.prototype = {
- _createChildNode: function(provider)
+ _createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, provider.item);
+ return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, item);
},
_createProvider: function(snapshot, nodeIndex)
{
var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
- return new WebInspector.HeapSnapshotEdgesProvider(
- snapshot,
+ return snapshot.createEdgesProvider(
nodeIndex,
function(edge) {
return !edge.isInvisible
@@ -387,7 +421,7 @@ WebInspector.HeapSnapshotInstanceNode.prototype.__proto__ = WebInspector.HeapSna
WebInspector.HeapSnapshotConstructorNode = function(tree, className, aggregate)
{
- WebInspector.HeapSnapshotGridNode.call(this, tree, aggregate.count > 0, 100);
+ WebInspector.HeapSnapshotGridNode.call(this, tree, aggregate.count > 0);
this._name = className;
this._count = aggregate.count;
this._shallowSize = aggregate.self;
@@ -396,15 +430,14 @@ WebInspector.HeapSnapshotConstructorNode = function(tree, className, aggregate)
}
WebInspector.HeapSnapshotConstructorNode.prototype = {
- _createChildNode: function(provider)
+ _createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, this.dataGrid.snapshot, provider.item);
+ return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, this.dataGrid.snapshot, item);
},
_createNodesProvider: function(snapshot, nodeType, nodeClassName)
{
- return new WebInspector.HeapSnapshotNodesProvider(
- snapshot,
+ return snapshot.createNodesProvider(
function (node) {
return node.type === nodeType
&& (nodeClassName === null || node.className === nodeClassName);
@@ -469,97 +502,94 @@ WebInspector.HeapSnapshotIteratorsTuple = function(it1, it2)
}
WebInspector.HeapSnapshotIteratorsTuple.prototype = {
- first: function()
+ sortAndRewind: function(comparator, callback)
{
- this._it1.first();
- this._it2.first();
- },
-
- sort: function(comparator)
- {
- this._it1.sort(comparator);
- this._it2.sort(comparator);
+ function afterSort(ignored)
+ {
+ this._it2.sortAndRewind(comparator, callback);
+ }
+ this._it1.sortAndRewind(comparator, afterSort.bind(this));
}
};
WebInspector.HeapSnapshotDiffNode = function(tree, className, baseAggregate, aggregate)
{
- if (!baseAggregate)
- baseAggregate = { count: 0, self: 0, maxRet: 0, type:aggregate.type, name:aggregate.name, idxs: [] };
- if (!aggregate)
- aggregate = { count: 0, self: 0, maxRet: 0, type:baseAggregate.type, name:baseAggregate.name, idxs: [] };
- WebInspector.HeapSnapshotGridNode.call(this, tree, true, 50);
+ WebInspector.HeapSnapshotGridNode.call(this, tree, true);
this._name = className;
- this._calculateDiff(tree.baseSnapshot, tree.snapshot, baseAggregate.idxs, aggregate.idxs);
- this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate.type, className);
+ this._baseIndexes = baseAggregate ? baseAggregate.idxs : [];
+ this._indexes = aggregate ? aggregate.idxs : [];
+ this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate ? aggregate.type : baseAggregate.type, className);
}
WebInspector.HeapSnapshotDiffNode.prototype = {
- _calculateDiff: function(baseSnapshot, snapshot, baseIndexes, currentIndexes)
- {
- var i = 0, l = baseIndexes.length;
- var j = 0, m = currentIndexes.length;
- this._addedCount = 0;
- this._removedCount = 0;
- this._addedSize = 0;
- this._removedSize = 0;
- var nodeA = new WebInspector.HeapSnapshotNode(baseSnapshot);
- var nodeB = new WebInspector.HeapSnapshotNode(snapshot);
- nodeA.nodeIndex = baseIndexes[i];
- nodeB.nodeIndex = currentIndexes[j];
- while (i < l && j < m) {
- if (nodeA.id < nodeB.id) {
- this._removedCount++;
- this._removedSize += nodeA.selfSize;
- nodeA.nodeIndex = baseIndexes[++i];
- } else if (nodeA.id > nodeB.id) {
- this._addedCount++;
- this._addedSize += nodeB.selfSize;
- nodeB.nodeIndex = currentIndexes[++j];
- } else {
- nodeA.nodeIndex = baseIndexes[++i];
- nodeB.nodeIndex = currentIndexes[++j];
- }
+ calculateDiff: function(dataGrid, callback)
+ {
+ var diff = dataGrid.snapshot.createDiff(this._name);
+
+ function diffCalculated(diffResult)
+ {
+ this._diff = diffResult;
+ this._baseIndexes = null;
+ this._indexes = null;
+ callback(this._diff.addedSize === 0 && this._diff.removedSize === 0);
+ }
+ function baseSelfSizesReceived(baseSelfSizes)
+ {
+ diff.pushBaseSelfSizes(baseSelfSizes);
+ diff.calculate(diffCalculated.bind(this));
}
- while (i < l) {
- this._removedCount++;
- this._removedSize += nodeA.selfSize;
- nodeA.nodeIndex = baseIndexes[++i];
+ function baseIdsReceived(baseIds)
+ {
+ diff.pushBaseIds(dataGrid.baseSnapshot.uid, baseIds);
+ dataGrid.snapshot.pushBaseIds(dataGrid.baseSnapshot.uid, this._name, baseIds);
+ dataGrid.baseSnapshot.nodeFieldValuesByIndex("selfSize", this._baseIndexes, baseSelfSizesReceived.bind(this));
}
- while (j < m) {
- this._addedCount++;
- this._addedSize += nodeB.selfSize;
- nodeB.nodeIndex = currentIndexes[++j];
+ function idsReceived(ids)
+ {
+ dataGrid.baseSnapshot.pushBaseIds(dataGrid.snapshot.uid, this._name, ids);
}
- this._countDelta = this._addedCount - this._removedCount;
- this._sizeDelta = this._addedSize - this._removedSize;
+ dataGrid.baseSnapshot.nodeFieldValuesByIndex("id", this._baseIndexes, baseIdsReceived.bind(this));
+ dataGrid.snapshot.nodeFieldValuesByIndex("id", this._indexes, idsReceived.bind(this));
},
- _createChildNode: function(provider)
+ _createChildNode: function(item, provider)
{
if (provider === this._provider._it1)
- return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, provider.snapshot, provider.item);
+ return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, provider.snapshot, item);
else
- return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, provider.snapshot, null, provider.item);
+ return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, provider.snapshot, null, item);
},
_createNodesProvider: function(baseSnapshot, snapshot, nodeType, nodeClassName)
{
+ var className = this._name;
return new WebInspector.HeapSnapshotIteratorsTuple(
createProvider(snapshot, baseSnapshot), createProvider(baseSnapshot, snapshot));
function createProvider(snapshot, otherSnapshot)
{
- return new WebInspector.HeapSnapshotNodesProvider(
- snapshot,
+ var otherSnapshotId = otherSnapshot.uid;
+ var provider = snapshot.createNodesProvider(
function (node) {
return node.type === nodeType
&& (nodeClassName === null || node.className === nodeClassName)
- && !otherSnapshot.hasId(node.id);
+ && !this.baseSnapshotHasNode(otherSnapshotId, className, node.id);
});
+ provider.snapshot = snapshot;
+ return provider;
}
},
+ _childHashForEntity: function(node)
+ {
+ return node.id;
+ },
+
+ _childHashForNode: function(childNode)
+ {
+ return childNode.snapshotNodeId;
+ },
+
comparator: function()
{
var sortAscending = this.dataGrid.sortOrder === "ascending";
@@ -576,16 +606,22 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
},
- populateChildren: function(provider, howMany, atIndex)
+ populateChildren: function(provider, howMany, atIndex, afterPopulate)
{
if (!provider && !howMany) {
- WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, this._defaultPopulateCount);
- WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, this._defaultPopulateCount);
+ var firstProviderPopulated = function()
+ {
+ WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, this._defaultPopulateCount, atIndex, afterPopulate);
+ };
+ WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, this._defaultPopulateCount, atIndex, firstProviderPopulated.bind(this), true);
} else if (!howMany) {
- WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1);
- WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2);
+ var firstProviderPopulated = function()
+ {
+ WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, null, atIndex, afterPopulate);
+ };
+ WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, null, atIndex, firstProviderPopulated.bind(this), true);
} else
- WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, provider, howMany, atIndex);
+ WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, provider, howMany, atIndex, afterPopulate);
},
_signForDelta: function(delta)
@@ -602,19 +638,16 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
{
var data = {object: this._name};
- data["addedCount"] = this._addedCount;
- data["removedCount"] = this._removedCount;
- data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(this._countDelta), Math.abs(this._countDelta));
- data["addedSize"] = Number.bytesToString(this._addedSize);
- data["removedSize"] = Number.bytesToString(this._removedSize);
- data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(this._sizeDelta), Number.bytesToString(Math.abs(this._sizeDelta)));
+ data["addedCount"] = this._diff.addedCount;
+ data["removedCount"] = this._diff.removedCount;
+ var countDelta = this._diff.countDelta;
+ data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(countDelta), Math.abs(countDelta));
+ data["addedSize"] = Number.bytesToString(this._diff.addedSize);
+ data["removedSize"] = Number.bytesToString(this._diff.removedSize);
+ var sizeDelta = this._diff.sizeDelta;
+ data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(sizeDelta), Number.bytesToString(Math.abs(sizeDelta)));
return data;
- },
-
- get zeroDiff()
- {
- return this._addedCount === 0 && this._removedCount === 0;
}
};
@@ -622,22 +655,21 @@ WebInspector.HeapSnapshotDiffNode.prototype.__proto__ = WebInspector.HeapSnapsho
WebInspector.HeapSnapshotDominatorObjectNode = function(tree, node)
{
- var provider = this._createProvider(tree.snapshot, node.nodeIndex);
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node, !provider.isEmpty, 25);
- this._provider = provider;
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
+ this._provider = this._createProvider(tree.snapshot, node.nodeIndex);
+ this._updateHasChildren();
};
WebInspector.HeapSnapshotDominatorObjectNode.prototype = {
- _createChildNode: function(provider)
+ _createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotDominatorObjectNode(this.dataGrid, provider.item);
+ return new WebInspector.HeapSnapshotDominatorObjectNode(this.dataGrid, item);
},
_createProvider: function(snapshot, nodeIndex)
{
var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
- return new WebInspector.HeapSnapshotNodesProvider(
- snapshot,
+ return snapshot.createNodesProvider(
function (node) {
var dominatorIndex = node.dominatorIndex;
return dominatorIndex === nodeIndex
diff --git a/Source/WebCore/inspector/front-end/DetailedHeapshotView.js b/Source/WebCore/inspector/front-end/DetailedHeapshotView.js
index 21d0fa9..1e46b51 100644
--- a/Source/WebCore/inspector/front-end/DetailedHeapshotView.js
+++ b/Source/WebCore/inspector/front-end/DetailedHeapshotView.js
@@ -37,10 +37,11 @@ WebInspector.HeapSnapshotContainmentDataGrid = function()
};
WebInspector.DataGrid.call(this, columns);
this.addEventListener("sorting changed", this.sort, this);
- this._defaultPopulateCount = 100;
}
WebInspector.HeapSnapshotContainmentDataGrid.prototype = {
+ _defaultPopulateCount: 100,
+
setDataSource: function(snapshotView, snapshot)
{
this.snapshotView = snapshotView;
@@ -65,6 +66,10 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
{
var sortAscending = this.sortOrder === "ascending";
var sortColumnIdentifier = this.sortColumnIdentifier;
+ if (this._lastSortColumnIdentifier === sortColumnIdentifier && this._lastSortAscending === sortAscending)
+ return;
+ this._lastSortColumnIdentifier = sortColumnIdentifier;
+ this._lastSortAscending = sortAscending;
var sortFields = this._sortFields(sortColumnIdentifier, sortAscending);
function SortByTwoFields(nodeA, nodeB)
@@ -89,6 +94,7 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
_performSorting: function(sortFunction)
{
+ this.dispatchEventToListeners("start sorting");
var children = this.children;
this.removeChildren();
children.sort(sortFunction);
@@ -98,6 +104,7 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
if (child.expanded)
child.sort();
}
+ this.dispatchEventToListeners("sorting complete");
}
};
@@ -115,6 +122,8 @@ WebInspector.HeapSnapshotConstructorsDataGrid = function()
}
WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
+ _defaultPopulateCount: 100,
+
_sortFields: function(sortColumn, sortAscending)
{
return {
@@ -130,14 +139,17 @@ WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
this.snapshotView = snapshotView;
this.snapshot = snapshot;
this.populateChildren();
- this.sortingChanged();
},
populateChildren: function()
{
- var aggregates = this.snapshot.aggregates();
- for (var constructor in aggregates)
- this.appendChild(new WebInspector.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor]));
+ function aggregatesReceived(aggregates)
+ {
+ for (var constructor in aggregates)
+ this.appendChild(new WebInspector.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor]));
+ this.sortingChanged();
+ }
+ this.snapshot.aggregates(false, aggregatesReceived.bind(this));
}
};
@@ -147,7 +159,6 @@ WebInspector.HeapSnapshotDiffDataGrid = function()
{
var columns = {
object: { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
- // \xb1 is a "plus-minus" sign.
addedCount: { title: WebInspector.UIString("# New"), width: "72px", sortable: true, sort: "descending" },
removedCount: { title: WebInspector.UIString("# Deleted"), width: "72px", sortable: true },
// \u0394 is a Greek delta letter.
@@ -160,6 +171,8 @@ WebInspector.HeapSnapshotDiffDataGrid = function()
}
WebInspector.HeapSnapshotDiffDataGrid.prototype = {
+ _defaultPopulateCount: 50,
+
_sortFields: function(sortColumn, sortAscending)
{
return {
@@ -183,28 +196,41 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
{
this.baseSnapshot = baseSnapshot;
this.removeChildren();
- if (this.baseSnapshot !== this.snapshot) {
- this.populateChildren();
- this.sortingChanged();
- }
+ if (this.baseSnapshot === this.snapshot)
+ return;
+ this.populateChildren();
},
populateChildren: function()
{
- var baseClasses = this.baseSnapshot.aggregates(true);
- var classes = this.snapshot.aggregates(true);
- for (var clss in baseClasses) {
- var node = new WebInspector.HeapSnapshotDiffNode(this, clss, baseClasses[clss], classes[clss]);
- if (!node.zeroDiff)
- this.appendChild(node);
- }
- for (clss in classes) {
- if (!(clss in baseClasses)) {
- var node = new WebInspector.HeapSnapshotDiffNode(this, clss, null, classes[clss]);
- if (!node.zeroDiff)
- this.appendChild(node);
+ function baseAggregatesReceived(baseClasses)
+ {
+ function aggregatesReceived(classes)
+ {
+ var nodeCount = 0;
+ function addNodeIfNonZeroDiff(node, zeroDiff)
+ {
+ if (!zeroDiff)
+ this.appendChild(node);
+ if (!--nodeCount)
+ this.sortingChanged();
+ }
+ for (var clss in baseClasses) {
+ var node = new WebInspector.HeapSnapshotDiffNode(this, clss, baseClasses[clss], classes[clss]);
+ ++nodeCount;
+ node.calculateDiff(this, addNodeIfNonZeroDiff.bind(this, node));
+ }
+ for (clss in classes) {
+ if (!(clss in baseClasses)) {
+ var node = new WebInspector.HeapSnapshotDiffNode(this, clss, null, classes[clss]);
+ ++nodeCount;
+ node.calculateDiff(this, addNodeIfNonZeroDiff.bind(this, node));
+ }
+ }
}
+ this.snapshot.aggregates(true, aggregatesReceived.bind(this));
}
+ this.baseSnapshot.aggregates(true, baseAggregatesReceived.bind(this));
}
};
@@ -219,10 +245,11 @@ WebInspector.HeapSnapshotDominatorsDataGrid = function()
};
WebInspector.DataGrid.call(this, columns);
this.addEventListener("sorting changed", this.sort, this);
- this._defaultPopulateCount = 25;
}
WebInspector.HeapSnapshotDominatorsDataGrid.prototype = {
+ _defaultPopulateCount: 25,
+
setDataSource: function(snapshotView, snapshot)
{
this.snapshotView = snapshotView;
@@ -243,6 +270,7 @@ WebInspector.HeapSnapshotRetainingPathsList = function()
len: { title: WebInspector.UIString("Length"), width: "90px", sortable: true, sort: "ascending" }
};
WebInspector.HeapSnapshotSortableDataGrid.call(this, columns);
+ this._defaultPopulateCount = 100;
}
WebInspector.HeapSnapshotRetainingPathsList.prototype = {
@@ -254,6 +282,14 @@ WebInspector.HeapSnapshotRetainingPathsList.prototype = {
}[sortColumn];
},
+ _resetPaths: function()
+ {
+ this._setRootChildrenForFinder();
+ this.removeChildren();
+ this._counter = 0;
+ this.showNext(this._defaultPopulateCount);
+ },
+
setDataSource: function(snapshotView, snapshot, nodeIndex, prefix)
{
this.snapshotView = snapshotView;
@@ -261,53 +297,49 @@ WebInspector.HeapSnapshotRetainingPathsList.prototype = {
if (this.pathFinder)
this.searchCancelled();
-
- this.pathFinder = new WebInspector.HeapSnapshotPathFinder(snapshot, nodeIndex);
- this._setRootChildrenForFinder();
-
- this.removeChildren();
-
- this._counter = 0;
- this.showNext(100);
+ this.pathFinder = snapshot.createPathFinder(nodeIndex);
+ this._resetPaths();
},
refresh: function()
{
- this.removeChildren();
- this._counter = 0;
delete this._cancel;
- this._setRootChildrenForFinder();
- this.showNext(100);
+ this._resetPaths();
},
showNext: function(pathsCount)
{
WebInspector.PleaseWaitMessage.prototype.show(this.element, this.searchCancelled.bind(this, pathsCount));
- window.setTimeout(startSearching.bind(this), 500);
+
+ function pathFound(result)
+ {
+ if (result === null) {
+ WebInspector.PleaseWaitMessage.prototype.hide();
+ if (!this.children.length)
+ this.appendChild(new WebInspector.DataGridNode({path:WebInspector.UIString("Can't find any paths."), len:""}, false));
+ return;
+ } else if (result !== false) {
+ if (this._prefix)
+ result.path = this._prefix + result.path;
+ this.appendChild(new WebInspector.DataGridNode(result, false));
+ ++this._counter;
+ }
+ setTimeout(startSearching.bind(this), 0);
+ }
function startSearching()
{
- if (this._cancel !== this.pathFinder) {
- if (this._counter < pathsCount) {
- var result = this.pathFinder.findNext();
- if (result === null) {
- WebInspector.PleaseWaitMessage.prototype.hide();
- if (!this.children.length)
- this.appendChild(new WebInspector.DataGridNode({path:WebInspector.UIString("Can't find any paths."), len:""}, false));
- return;
- } else if (result !== false) {
- if (this._prefix)
- result.path = this._prefix + result.path;
- this.appendChild(new WebInspector.DataGridNode(result, false));
- ++this._counter;
- }
- window.setTimeout(startSearching.bind(this), 0);
- return;
- } else
- this.searchCancelled.call(this, pathsCount);
+ if (this._cancel === this.pathFinder)
+ return;
+ delete this._cancel;
+ if (this._counter < pathsCount)
+ this.pathFinder.findNext(pathFound.bind(this));
+ else {
+ this.searchCancelled.call(this, pathsCount);
+ delete this._cancel;
}
- this._cancel = false;
}
+ setTimeout(startSearching.bind(this), 0);
},
searchCancelled: function(pathsCount)
@@ -419,20 +451,17 @@ WebInspector.DetailedHeapshotView = function(parent, profile)
this.viewSelectElement.className = "status-bar-item";
this.viewSelectElement.addEventListener("change", this._changeView.bind(this), false);
- var classesViewOption = document.createElement("option");
- classesViewOption.label = WebInspector.UIString("Summary");
- var diffViewOption = document.createElement("option");
- diffViewOption.label = WebInspector.UIString("Comparison");
- var containmentViewOption = document.createElement("option");
- containmentViewOption.label = WebInspector.UIString("Containment");
- var dominatorsViewOption = document.createElement("option");
- dominatorsViewOption.label = WebInspector.UIString("Dominators");
- this.viewSelectElement.appendChild(classesViewOption);
- this.viewSelectElement.appendChild(diffViewOption);
- this.viewSelectElement.appendChild(containmentViewOption);
- this.viewSelectElement.appendChild(dominatorsViewOption);
- this.views = ["Summary", "Comparison", "Containment", "Dominators"];
+ this.views = [{title: "Summary", view: this.constructorsView, grid: this.constructorsDataGrid},
+ {title: "Comparison", view: this.diffView, grid: this.diffDataGrid},
+ {title: "Containment", view: this.containmentView, grid: this.containmentDataGrid},
+ {title: "Dominators", view: this.dominatorView, grid: this.dominatorDataGrid}];
this.views.current = 0;
+ for (var i = 0; i < this.views.length; ++i) {
+ var view = this.views[i];
+ var option = document.createElement("option");
+ option.label = WebInspector.UIString(view.title);
+ this.viewSelectElement.appendChild(option);
+ }
this._profileUid = profile.uid;
@@ -450,12 +479,12 @@ WebInspector.DetailedHeapshotView = function(parent, profile)
this._loadProfile(this._profileUid, profileCallback.bind(this));
- function profileCallback(profile)
+ function profileCallback()
{
var list = this._profiles();
var profileIndex;
for (var i = 0; i < list.length; ++i)
- if (list[i].uid === profile.uid) {
+ if (list[i].uid === this._profileUid) {
profileIndex = i;
break;
}
@@ -490,7 +519,7 @@ WebInspector.DetailedHeapshotView.prototype = {
get profileWrapper()
{
if (!this._profileWrapper)
- this._profileWrapper = new WebInspector.HeapSnapshot(this.profile);
+ this._profileWrapper = this.profile.proxy;
return this._profileWrapper;
},
@@ -501,34 +530,27 @@ WebInspector.DetailedHeapshotView.prototype = {
get baseProfileWrapper()
{
- if (!this._baseProfileWrapper) {
- if (this.baseProfile !== this.profile)
- this._baseProfileWrapper = new WebInspector.HeapSnapshot(this.baseProfile);
- else
- this._baseProfileWrapper = this.profileWrapper;
- }
+ if (!this._baseProfileWrapper)
+ this._baseProfileWrapper = this.baseProfile.proxy;
return this._baseProfileWrapper;
},
show: function(parentElement)
{
WebInspector.View.prototype.show.call(this, parentElement);
- if (!this.profile._loaded)
+ if (!this.profileWrapper.loaded)
this._loadProfile(this._profileUid, profileCallback1.bind(this));
else
- profileCallback1.call(this, this.profile);
+ profileCallback1.call(this);
- function profileCallback1(profile) {
- this.profileWrapper.restore(profile);
- if (this.baseProfile && !this.baseProfile._loaded)
+ function profileCallback1() {
+ if (this.baseProfile && !this.baseProfileWrapper.loaded)
this._loadProfile(this._baseProfileUid, profileCallback2.bind(this));
else
- profileCallback2.call(this, this.baseProfile);
+ profileCallback2.call(this);
}
- function profileCallback2(profile) {
- if (profile)
- this.baseProfileWrapper.restore(profile);
+ function profileCallback2() {
this.currentView.show();
this.dataGrid.updateWidths();
}
@@ -697,7 +719,7 @@ WebInspector.DetailedHeapshotView.prototype = {
this._baseProfileUid = this._profiles()[this.baseSelectElement.selectedIndex].uid;
this._loadProfile(this._baseProfileUid, baseProfileLoaded.bind(this));
- function baseProfileLoaded(profile)
+ function baseProfileLoaded()
{
delete this._baseProfileWrapper;
this.baseProfile._lastShown = Date.now();
@@ -770,19 +792,9 @@ WebInspector.DetailedHeapshotView.prototype = {
this.views.current = event.target.selectedIndex;
this.currentView.hide();
- if (this.views[this.views.current] === "Containment") {
- this.currentView = this.containmentView;
- this.dataGrid = this.containmentDataGrid;
- } else if (this.views[this.views.current] === "Summary") {
- this.currentView = this.constructorsView;
- this.dataGrid = this.constructorsDataGrid;
- } else if (this.views[this.views.current] === "Comparison") {
- this.currentView = this.diffView;
- this.dataGrid = this.diffDataGrid;
- } else if (this.views[this.views.current] === "Dominators") {
- this.currentView = this.dominatorView;
- this.dataGrid = this.dominatorDataGrid;
- }
+ var view = this.views[this.views.current];
+ this.currentView = view.view;
+ this.dataGrid = view.grid;
this.currentView.show();
this.refreshVisibleData();
if (this.currentView === this.diffView) {
diff --git a/Source/WebCore/inspector/front-end/ElementsPanel.js b/Source/WebCore/inspector/front-end/ElementsPanel.js
index 724e0e2..1f6f56b 100644
--- a/Source/WebCore/inspector/front-end/ElementsPanel.js
+++ b/Source/WebCore/inspector/front-end/ElementsPanel.js
@@ -38,7 +38,7 @@ WebInspector.ElementsPanel = function()
if (!WebInspector.settings.domWordWrap)
this.contentElement.classList.add("nowrap");
- this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
+ this.contentElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
this.treeOutline = new WebInspector.ElementsTreeOutline();
this.treeOutline.panel = this;
@@ -79,7 +79,7 @@ WebInspector.ElementsPanel = function()
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
if (Preferences.nativeInstrumentationEnabled)
- this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
+ this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane;
this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane();
this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this);
@@ -153,6 +153,9 @@ WebInspector.ElementsPanel.prototype = {
if (this.recentlyModifiedNodes.length)
this.updateModifiedNodes();
+ if (Preferences.nativeInstrumentationEnabled)
+ this.sidebarElement.insertBefore(this.sidebarPanes.domBreakpoints.element, this.sidebarPanes.eventListeners.element);
+
if (!this.rootDOMNode)
WebInspector.domAgent.requestDocument();
},
@@ -199,8 +202,8 @@ WebInspector.ElementsPanel.prototype = {
if (!inspectedRootDocument)
return;
- WebInspector.breakpointManager.restoreDOMBreakpoints();
-
+ if (Preferences.nativeInstrumentationEnabled)
+ this.sidebarPanes.domBreakpoints.restoreBreakpoints();
this.rootDOMNode = inspectedRootDocument;
@@ -483,7 +486,7 @@ WebInspector.ElementsPanel.prototype = {
nodeItem.updateTitle();
continue;
}
-
+
if (!parent)
continue;
@@ -768,13 +771,13 @@ WebInspector.ElementsPanel.prototype = {
var i = 0;
var crumb = crumbs.firstChild;
while (crumb) {
- // Find the selected crumb and index.
+ // Find the selected crumb and index.
if (!selectedCrumb && crumb.hasStyleClass("selected")) {
selectedCrumb = crumb;
selectedIndex = i;
}
- // Find the focused crumb index.
+ // Find the focused crumb index.
if (crumb === focusedCrumb)
focusedIndex = i;
@@ -883,7 +886,7 @@ WebInspector.ElementsPanel.prototype = {
while (crumb) {
var hidden = crumb.hasStyleClass("hidden");
if (!hidden) {
- var collapsed = crumb.hasStyleClass("collapsed");
+ var collapsed = crumb.hasStyleClass("collapsed");
if (collapsedRun && collapsed) {
crumb.addStyleClass("hidden");
crumb.removeStyleClass("compact");
@@ -1120,15 +1123,14 @@ WebInspector.ElementsPanel.prototype = {
this._nodeSearchButton.toggled = false;
},
- _setSearchingForNode: function(error, enabled)
+ _setSearchingForNode: function(enabled)
{
- if (!error)
- this._nodeSearchButton.toggled = enabled;
+ this._nodeSearchButton.toggled = enabled;
},
setSearchingForNode: function(enabled)
{
- DOMAgent.setSearchingForNode(enabled, this._setSearchingForNode.bind(this));
+ DOMAgent.setSearchingForNode(enabled, this._setSearchingForNode.bind(this, enabled));
},
toggleSearchingForNode: function()
diff --git a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
index dd99db1..2ecc3f9 100644
--- a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -791,23 +791,8 @@ WebInspector.ElementsTreeElement.prototype = {
if (Preferences.nativeInstrumentationEnabled) {
// Add debbuging-related actions
contextMenu.appendSeparator();
-
- function handlerFunction(nodeId, breakType)
- {
- WebInspector.breakpointManager.createDOMBreakpoint(nodeId, breakType);
- WebInspector.panels.elements.sidebarPanes.domBreakpoints.expand();
- }
- var node = this.representedObject;
- for (var key in WebInspector.DOMBreakpointTypes) {
- var type = WebInspector.DOMBreakpointTypes[key];
- var label = WebInspector.domBreakpointTypeContextMenuLabel(type);
- var breakpoint = node.breakpoints[type];
- if (!breakpoint)
- var handler = handlerFunction.bind(this, node.id, type);
- else
- var handler = breakpoint.remove.bind(breakpoint);
- contextMenu.appendCheckboxItem(label, handler, !!breakpoint);
- }
+ var pane = WebInspector.panels.elements.sidebarPanes.domBreakpoints;
+ pane.populateNodeContextMenu(this.representedObject, contextMenu);
}
},
diff --git a/Source/WebCore/inspector/front-end/EventListenersSidebarPane.js b/Source/WebCore/inspector/front-end/EventListenersSidebarPane.js
index 00576f1..2dce7ee 100644
--- a/Source/WebCore/inspector/front-end/EventListenersSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/EventListenersSidebarPane.js
@@ -214,7 +214,7 @@ WebInspector.EventListenerBar.prototype = {
}
if (node.id === this._nodeId) {
- this.titleElement.textContent = appropriateSelectorForNode(node);
+ this.titleElement.textContent = node.appropriateSelectorFor();
return;
}
diff --git a/Source/WebCore/inspector/front-end/ExtensionAPI.js b/Source/WebCore/inspector/front-end/ExtensionAPI.js
index ea7324c..940e340 100644
--- a/Source/WebCore/inspector/front-end/ExtensionAPI.js
+++ b/Source/WebCore/inspector/front-end/ExtensionAPI.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2011 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
@@ -111,6 +111,7 @@ function Resources()
this._fire(resource);
}
this.onFinished = new EventSink("resource-finished", resourceDispatch);
+ this.onNavigated = new EventSink("inspectedURLChanged");
}
Resources.prototype = {
@@ -182,6 +183,8 @@ Panels.prototype = {
function PanelImpl(id)
{
this._id = id;
+ this.onShown = new EventSink("panel-shown-" + id);
+ this.onHidden = new EventSink("panel-hidden-" + id);
}
function PanelWithSidebarImpl(id)
@@ -190,35 +193,18 @@ function PanelWithSidebarImpl(id)
}
PanelWithSidebarImpl.prototype = {
- createSidebarPane: function(title, url, callback)
+ createSidebarPane: function(title, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: "createSidebarPane",
panel: this._id,
id: id,
- title: title,
- url: expandURL(url)
- };
- function callbackWrapper()
- {
- callback(new ExtensionSidebarPane(id));
- }
- extensionServer.sendRequest(request, callback && callbackWrapper);
- },
-
- createWatchExpressionSidebarPane: function(title, callback)
- {
- var id = "watch-sidebar-" + extensionServer.nextObjectId();
- var request = {
- command: "createWatchExpressionSidebarPane",
- panel: this._id,
- id: id,
title: title
};
function callbackWrapper()
{
- callback(new WatchExpressionSidebarPane(id));
+ callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
}
@@ -242,39 +228,29 @@ function ExtensionPanel(id)
function ExtensionSidebarPaneImpl(id)
{
this._id = id;
+ this.onUpdated = new EventSink("sidebar-updated-" + id);
}
ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: "setSidebarHeight", id: this._id, height: height });
- }
-}
-
-function WatchExpressionSidebarPaneImpl(id)
-{
- ExtensionSidebarPaneImpl.call(this, id);
- this.onUpdated = new EventSink("watch-sidebar-updated-" + id);
-}
+ },
-WatchExpressionSidebarPaneImpl.prototype = {
setExpression: function(expression, rootTitle)
{
- extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true });
+ extensionServer.sendRequest({ command: "setSidebarContent", id: this._id, expression: expression, rootTitle: rootTitle, evaluateOnPage: true });
},
setObject: function(jsonObject, rootTitle)
{
- extensionServer.sendRequest({ command: "setWatchSidebarContent", id: this._id, expression: jsonObject, rootTitle: rootTitle });
- }
-}
-
-WatchExpressionSidebarPaneImpl.prototype.__proto__ = ExtensionSidebarPaneImpl.prototype;
+ extensionServer.sendRequest({ command: "setSidebarContent", id: this._id, expression: jsonObject, rootTitle: rootTitle });
+ },
-function WatchExpressionSidebarPane(id)
-{
- var impl = new WatchExpressionSidebarPaneImpl(id);
- ExtensionSidebarPane.call(this, id, impl);
+ setPage: function(url)
+ {
+ extensionServer.sendRequest({ command: "setSidebarPage", id: this._id, url: expandURL(url) });
+ }
}
function Audits()
@@ -381,9 +357,6 @@ AuditResultNode.prototype = {
function InspectedWindow()
{
- this.onDOMContentLoaded = new EventSink("inspectedPageDOMContentLoaded");
- this.onLoaded = new EventSink("inspectedPageLoaded");
- this.onNavigated = new EventSink("inspectedURLChanged");
}
InspectedWindow.prototype = {
@@ -511,7 +484,6 @@ var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var Panel = declareInterfaceClass(PanelImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Resource = declareInterfaceClass(ResourceImpl);
-var WatchExpressionSidebarPane = declareInterfaceClass(WatchExpressionSidebarPaneImpl);
var extensionServer = new ExtensionServerClient();
diff --git a/Source/WebCore/inspector/front-end/ExtensionAPISchema.json b/Source/WebCore/inspector/front-end/ExtensionAPISchema.json
index 0aa7aa8..c4c8358 100755
--- a/Source/WebCore/inspector/front-end/ExtensionAPISchema.json
+++ b/Source/WebCore/inspector/front-end/ExtensionAPISchema.json
@@ -19,11 +19,6 @@
"description": "A text that is displayed in sidebar caption."
},
{
- "name": "url",
- "type": "string",
- "description": "An URL of the page that represents the sidebar."
- },
- {
"name": "callback",
"type": "function",
"description": "A callback invoked when sidebar is created",
@@ -36,30 +31,6 @@
]
}
]
- },
- {
- "name": "createWatchExpressionSidebarPane",
- "type": "function",
- "description": "Creates a pane with an object property tree (similar to a watch sidebar pane).",
- "parameters": [
- {
- "name": "title",
- "type": "string",
- "description": "A text that is displayed in sidebar caption."
- },
- {
- "name": "callback",
- "type": "function",
- "description": "A callback invoked when sidebar is created",
- "parameters": [
- {
- "name": "result",
- "description": "A WatchExpressionSidebarPane object for created sidebar pane",
- "$ref": "WatchExpressionSidebarPane"
- }
- ]
- }
- ]
}
]
},
@@ -116,25 +87,6 @@
"description": "A CSS-like size specification, e.g. '10px' or '12pt'"
}
]
- }
- ]
- },
- {
- "id": "WatchExpressionSidebarPane",
- "type": "object",
- "description": "A sidebar created by the extension.",
- "functions": [
- {
- "name": "setHeight",
- "type": "function",
- "description": "Sets the height of the sidebar.",
- "parameters": [
- {
- "name": "height",
- "type": "string",
- "description": "A CSS-like size specification, e.g. '10px' or '12pt'"
- }
- ]
},
{
"name": "setExpression",
@@ -171,6 +123,18 @@
"description": "An optional title for the root of the expression tree."
}
]
+ },
+ {
+ "name": "setPage",
+ "type": "function",
+ "description": "Sets an HTML page to be displayed in the sidebar pane.",
+ "parameters": [
+ {
+ "name": "url",
+ "type": "string",
+ "description": "An URL of an extension page to display within the sidebar."
+ }
+ ]
}
]
}
@@ -201,12 +165,20 @@
"name": "pageURL",
"type": "string",
"description": "An URL of the page that represents this panel."
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "description": "A function that is called upon request completion.",
+ "parameters": [
+ {
+ "name": "panel",
+ "description": "An ExtensionPanel object representing the created panel.",
+ "$ref": "ExtensionPanel"
+ }
+ ]
}
- ],
- "returns" : {
- "$ref": "ExtensionPanel",
- "description": "A panel that was created."
- }
+ ]
}
]
},
@@ -274,6 +246,18 @@
"parameters": [
{ "name": "resource", "$ref": "Resource" }
]
+ },
+ {
+ "name": "onNavigation",
+ "type": "function",
+ "description": "Fired when an inspected window navigates to a new URL.",
+ "parameters": [
+ {
+ "name": "url",
+ "type": "stirng",
+ "description": "URL of the new page."
+ }
+ ]
}
]
},
diff --git a/Source/WebCore/inspector/front-end/ExtensionPanel.js b/Source/WebCore/inspector/front-end/ExtensionPanel.js
index 4249b2c..f09a720 100644
--- a/Source/WebCore/inspector/front-end/ExtensionPanel.js
+++ b/Source/WebCore/inspector/front-end/ExtensionPanel.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2011 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
@@ -81,13 +81,13 @@ WebInspector.ExtensionPanel.prototype = {
WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;
-WebInspector.ExtensionWatchSidebarPane = function(title, id)
+WebInspector.ExtensionSidebarPane = function(title, id)
{
WebInspector.SidebarPane.call(this, title);
this._id = id;
}
-WebInspector.ExtensionWatchSidebarPane.prototype = {
+WebInspector.ExtensionSidebarPane.prototype = {
setObject: function(object, title)
{
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title);
@@ -98,6 +98,14 @@ WebInspector.ExtensionWatchSidebarPane.prototype = {
RuntimeAgent.evaluate(expression, "extension-watch", false, this._onEvaluate.bind(this, title));
},
+ setPage: function(url)
+ {
+ this.bodyElement.removeChildren();
+ WebInspector.extensionServer.createClientIframe(this.bodyElement, url);
+ // TODO: Consider doing this upon load event.
+ WebInspector.extensionServer.notifyExtensionSidebarUpdated(this._id);
+ },
+
_onEvaluate: function(title, error, result)
{
if (!error)
@@ -112,8 +120,8 @@ WebInspector.ExtensionWatchSidebarPane.prototype = {
section.headerElement.addStyleClass("hidden");
section.expanded = true;
this.bodyElement.appendChild(section.element);
- WebInspector.extensionServer.notifyExtensionWatchSidebarUpdated(this._id);
+ WebInspector.extensionServer.notifyExtensionSidebarUpdated(this._id);
}
}
-WebInspector.ExtensionWatchSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+WebInspector.ExtensionSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
diff --git a/Source/WebCore/inspector/front-end/ExtensionServer.js b/Source/WebCore/inspector/front-end/ExtensionServer.js
index 9554dfa..2c95ef0 100644
--- a/Source/WebCore/inspector/front-end/ExtensionServer.js
+++ b/Source/WebCore/inspector/front-end/ExtensionServer.js
@@ -42,15 +42,15 @@ WebInspector.ExtensionServer = function()
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("createSidebarPane", this._onCreateSidebarPane.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("setWatchSidebarContent", this._onSetWatchSidebarContent.bind(this));
+ this._registerHandler("setSidebarContent", this._onSetSidebarContent.bind(this));
+ this._registerHandler("setSidebarPage", this._onSetSidebarPage.bind(this));
this._registerHandler("stopAuditCategoryRun", this._onStopAuditCategoryRun.bind(this));
this._registerHandler("subscribe", this._onSubscribe.bind(this));
this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
@@ -59,11 +59,6 @@ WebInspector.ExtensionServer = function()
}
WebInspector.ExtensionServer.prototype = {
- notifyPanelShown: function(panelName)
- {
- this._postNotification("panel-shown-" + panelName);
- },
-
notifyObjectSelected: function(panelId, objectId)
{
this._postNotification("panel-objectSelected-" + panelId, objectId);
@@ -74,19 +69,19 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("panel-search-" + panelId, action, searchString);
},
- notifyPageLoaded: function(milliseconds)
+ notifyPanelShown: function(panelId)
{
- this._postNotification("inspectedPageLoaded", milliseconds);
+ this._postNotification("panel-shown-" + panelId);
},
- notifyPageDOMContentLoaded: function(milliseconds)
+ notifyPanelHidden: function(panelId)
{
- this._postNotification("inspectedPageDOMContentLoaded", milliseconds);
+ this._postNotification("panel-hidden-" + panelId);
},
- notifyInspectedURLChanged: function()
+ notifyInspectedURLChanged: function(url)
{
- this._postNotification("inspectedURLChanged");
+ this._postNotification("inspectedURLChanged", url);
},
notifyInspectorReset: function()
@@ -94,9 +89,9 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("reset");
},
- notifyExtensionWatchSidebarUpdated: function(id)
+ notifyExtensionSidebarUpdated: function(id)
{
- this._postNotification("watch-sidebar-updated-" + id);
+ this._postNotification("sidebar-updated-" + id);
},
startAuditRun: function(category, auditRun)
@@ -195,27 +190,12 @@ WebInspector.ExtensionServer.prototype = {
WebInspector.panels[id] = panel;
WebInspector.addPanel(panel);
- var iframe = this._createClientIframe(panel.element, message.url);
+ var iframe = this.createClientIframe(panel.element, message.url);
iframe.style.height = "100%";
return this._status.OK();
},
- _onCreateSidebar: function(message)
- {
- var sidebar = this._createSidebar(message, WebInspector.SidebarPane);
- if (sidebar.isError)
- return sidebar;
- this._createClientIframe(sidebar.bodyElement, message.url);
- return this._status.OK();
- },
-
- _onCreateWatchExpressionSidebarPane: function(message)
- {
- var sidebar = this._createSidebar(message, WebInspector.ExtensionWatchSidebarPane);
- return sidebar.isError ? sidebar : this._status.OK();
- },
-
- _createSidebar: function(message, constructor)
+ _onCreateSidebarPane: function(message, constructor)
{
var panel = WebInspector.panels[message.panel];
if (!panel)
@@ -223,15 +203,15 @@ WebInspector.ExtensionServer.prototype = {
if (!panel.sidebarElement || !panel.sidebarPanes)
return this._status.E_NOTSUPPORTED();
var id = message.id;
- var sidebar = new constructor(message.title, message.id);
+ var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id);
this._clientObjects[id] = sidebar;
panel.sidebarPanes[id] = sidebar;
panel.sidebarElement.appendChild(sidebar.element);
- return sidebar;
+ return this._status.OK();
},
- _createClientIframe: function(parent, url, requestId, port)
+ createClientIframe: function(parent, url)
{
var iframe = document.createElement("iframe");
iframe.src = url;
@@ -248,7 +228,7 @@ WebInspector.ExtensionServer.prototype = {
sidebar.bodyElement.firstChild.style.height = message.height;
},
- _onSetWatchSidebarContent: function(message)
+ _onSetSidebarContent: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
@@ -259,6 +239,14 @@ WebInspector.ExtensionServer.prototype = {
sidebar.setObject(message.expression, message.rootTitle);
},
+ _onSetSidebarPage: function(message)
+ {
+ var sidebar = this._clientObjects[message.id];
+ if (!sidebar)
+ return this._status.E_NOTFOUND(message.id);
+ sidebar.setPage(message.url);
+ },
+
_onLog: function(message)
{
WebInspector.log(message.message);
diff --git a/Source/WebCore/inspector/front-end/GoToLineDialog.js b/Source/WebCore/inspector/front-end/GoToLineDialog.js
index 9f4504d..b2490e6 100644
--- a/Source/WebCore/inspector/front-end/GoToLineDialog.js
+++ b/Source/WebCore/inspector/front-end/GoToLineDialog.js
@@ -118,9 +118,9 @@ WebInspector.GoToLineDialog.prototype = {
_highlightSelectedLine: function()
{
var value = this._input.value;
- var lineNumber = parseInt(value, 10);
- if (!isNaN(lineNumber) && lineNumber > 0) {
- lineNumber = Math.min(lineNumber, this._view.textModel.linesCount);
+ var lineNumber = parseInt(value, 10) - 1;
+ if (!isNaN(lineNumber) && lineNumber >= 0) {
+ lineNumber = Math.min(lineNumber, this._view.textModel.linesCount - 1);
this._view.highlightLine(lineNumber);
}
}
diff --git a/Source/WebCore/inspector/front-end/HAREntry.js b/Source/WebCore/inspector/front-end/HAREntry.js
index b5223b6..072a55b 100644
--- a/Source/WebCore/inspector/front-end/HAREntry.js
+++ b/Source/WebCore/inspector/front-end/HAREntry.js
@@ -31,6 +31,9 @@
// See http://groups.google.com/group/http-archive-specification/web/har-1-2-spec
// for HAR specification.
+// FIXME: Some fields are not yet supported due to back-end limitations.
+// See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
+
WebInspector.HAREntry = function(resource)
{
this._resource = resource;
@@ -45,7 +48,7 @@ WebInspector.HAREntry.prototype = {
time: WebInspector.HAREntry._toMilliseconds(this._resource.duration),
request: this._buildRequest(),
response: this._buildResponse(),
- // cache: {...}, -- Not supproted yet.
+ cache: { }, // Not supproted yet.
timings: this._buildTimings()
};
},
@@ -57,33 +60,29 @@ WebInspector.HAREntry.prototype = {
url: this._resource.url,
// httpVersion: "HTTP/1.1" -- Not available.
headers: this._buildHeaders(this._resource.requestHeaders),
+ queryString: this._buildParameters(this._resource.queryParameters || []),
+ cookies: this._buildCookies(this._resource.requestCookies || []),
headersSize: -1, // Not available.
bodySize: -1 // Not available.
};
- if (this._resource.queryParameters)
- res.queryString = this._buildParameters(this._resource.queryParameters);
if (this._resource.requestFormData)
res.postData = this._buildPostData();
- if (this._resource.requestCookies)
- res.cookies = this._buildCookies(this._resource.requestCookies);
return res;
},
_buildResponse: function()
{
- var res = {
+ return {
status: this._resource.statusCode,
statusText: this._resource.statusText,
// "httpVersion": "HTTP/1.1" -- Not available.
headers: this._buildHeaders(this._resource.responseHeaders),
+ cookies: this._buildCookies(this._resource.responseCookies || []),
content: this._buildContent(),
redirectURL: this._resource.responseHeaderValue("Location") || "",
headersSize: -1, // Not available.
bodySize: this._resource.resourceSize
};
- if (this._resource.responseCookies)
- res.cookies = this._buildCookies(this._resource.responseCookies);
- return res;
},
_buildContent: function()
diff --git a/Source/WebCore/inspector/front-end/HeapSnapshot.js b/Source/WebCore/inspector/front-end/HeapSnapshot.js
index c9d1e30..781a13b 100644
--- a/Source/WebCore/inspector/front-end/HeapSnapshot.js
+++ b/Source/WebCore/inspector/front-end/HeapSnapshot.js
@@ -482,7 +482,7 @@ WebInspector.HeapSnapshotNodeIterator.prototype = {
WebInspector.HeapSnapshot = function(profile)
{
- this.uid = profile.uid;
+ this.uid = profile.snapshot.uid;
this._nodes = profile.nodes;
this._strings = profile.strings;
@@ -534,6 +534,7 @@ WebInspector.HeapSnapshot.prototype = {
delete this._aggregates;
this._aggregatesWithIndexes = false;
}
+ delete this._baseNodeIds;
},
get _allNodes()
@@ -552,10 +553,15 @@ WebInspector.HeapSnapshot.prototype = {
return this._nodeCount;
},
- restore: function(profile)
+ nodeFieldValuesByIndex: function(fieldName, indexes)
{
- this._nodes = profile.nodes;
- this._strings = profile.strings;
+ var node = new WebInspector.HeapSnapshotNode(this);
+ var result = new Array(indexes.length);
+ for (var i = 0, l = indexes.length; i < l; ++i) {
+ node.nodeIndex = indexes[i];
+ result[i] = node[fieldName];
+ }
+ return result;
},
get rootNode()
@@ -762,6 +768,20 @@ WebInspector.HeapSnapshot.prototype = {
_numbersComparator: function(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
+ },
+
+ baseSnapshotHasNode: function(baseSnapshotId, className, nodeId)
+ {
+ return this._baseNodeIds[baseSnapshotId][className].binaryIndexOf(nodeId, this._numbersComparator) !== -1;
+ },
+
+ updateBaseNodeIds: function(baseSnapshotId, className, nodeIds)
+ {
+ if (!this._baseNodeIds)
+ this._baseNodeIds = [];
+ if (!this._baseNodeIds[baseSnapshotId])
+ this._baseNodeIds[baseSnapshotId] = {};
+ this._baseNodeIds[baseSnapshotId][className] = nodeIds;
}
};
@@ -1125,3 +1145,59 @@ WebInspector.HeapSnapshotPathFinder.prototype = {
return sPath.join("");
}
};
+
+WebInspector.HeapSnapshotsDiff = function(snapshot, className)
+{
+ this._snapshot = snapshot;
+ this._className = className;
+};
+
+WebInspector.HeapSnapshotsDiff.prototype = {
+ set baseIds(baseIds)
+ {
+ this._baseIds = baseIds;
+ },
+
+ set baseSelfSizes(baseSelfSizes)
+ {
+ this._baseSelfSizes = baseSelfSizes;
+ },
+
+ calculate: function()
+ {
+ var indexes = this._snapshot.aggregates(true)[this._className].idxs;
+ var i = 0, l = this._baseIds.length;
+ var j = 0, m = indexes.length;
+ var diff = { addedCount: 0, removedCount: 0, addedSize: 0, removedSize: 0 };
+
+ var nodeB = new WebInspector.HeapSnapshotNode(this._snapshot);
+ while (i < l && j < m) {
+ var nodeAId = this._baseIds[i];
+ if (nodeAId < nodeB.id) {
+ diff.removedCount++;
+ diff.removedSize += this._baseSelfSizes[i];
+ ++i;
+ } else if (nodeAId > nodeB.id) {
+ diff.addedCount++;
+ diff.addedSize += nodeB.selfSize;
+ nodeB.nodeIndex = indexes[++j];
+ } else {
+ ++i;
+ nodeB.nodeIndex = indexes[++j];
+ }
+ }
+ while (i < l) {
+ diff.removedCount++;
+ diff.removedSize += this._baseSelfSizes[i];
+ ++i;
+ }
+ while (j < m) {
+ diff.addedCount++;
+ diff.addedSize += nodeB.selfSize;
+ nodeB.nodeIndex = indexes[++j];
+ }
+ diff.countDelta = diff.addedCount - diff.removedCount;
+ diff.sizeDelta = diff.addedSize - diff.removedSize;
+ return diff;
+ }
+};
diff --git a/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js b/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js
new file mode 100644
index 0000000..bb0a7ec
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2011 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 copyrightdd
+ * 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.HeapSnapshotProxy = function()
+{
+ this._snapshot = null;
+}
+
+WebInspector.HeapSnapshotProxy.prototype = {
+ _invokeGetter: function(getterName, callback)
+ {
+ function returnResult()
+ {
+ callback(this._snapshot[getterName]);
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ aggregates: function(withNodeIndexes, callback)
+ {
+ function returnResult()
+ {
+ callback(this._snapshot.aggregates(withNodeIndexes));
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ _extractEdgeData: function(edge)
+ {
+ return {name: edge.name, node: this._extractNodeData(edge.node), nodeIndex: edge.nodeIndex, type: edge.type};
+ },
+
+ _extractNodeData: function(node)
+ {
+ return {id: node.id, name: node.name, nodeIndex: node.nodeIndex, retainedSize: node.retainedSize, selfSize: node.selfSize, type: node.type};
+ },
+
+ createDiff: function(className)
+ {
+ return new WebInspector.HeapSnapshotsDiffProxy(new WebInspector.HeapSnapshotsDiff(this._snapshot, className));
+ },
+
+ createEdgesProvider: function(nodeIndex, filter)
+ {
+ function createProvider()
+ {
+ if (filter)
+ filter = filter.bind(this._snapshot);
+ return new WebInspector.HeapSnapshotEdgesProvider(this._snapshot, nodeIndex, filter);
+ }
+ return new WebInspector.HeapSnapshotProviderProxy(createProvider.bind(this), this._extractEdgeData.bind(this));
+ },
+
+ createNodesProvider: function(filter)
+ {
+ function createProvider()
+ {
+ if (filter)
+ filter = filter.bind(this._snapshot);
+ return new WebInspector.HeapSnapshotNodesProvider(this._snapshot, filter);
+ }
+ return new WebInspector.HeapSnapshotProviderProxy(createProvider.bind(this), this._extractNodeData.bind(this));
+ },
+
+ createPathFinder: function(targetNodeIndex)
+ {
+ return new WebInspector.HeapSnapshotPathFinderProxy(new WebInspector.HeapSnapshotPathFinder(this._snapshot, targetNodeIndex));
+ },
+
+ dispose: function()
+ {
+ this._snapshot.dispose();
+ },
+
+ finishLoading: function(callback)
+ {
+ if (this._snapshot || !this._isLoading)
+ return false;
+ function parse() {
+ var rawSnapshot = JSON.parse(this._json);
+ var loadCallbacks = this._onLoadCallbacks;
+ loadCallbacks.splice(0, 0, callback);
+ delete this._onLoadCallback;
+ delete this._json;
+ delete this._isLoading;
+ this._snapshot = new WebInspector.HeapSnapshot(rawSnapshot);
+ this._nodeCount = this._snapshot.nodeCount;
+ this._rootNodeIndex = this._snapshot._rootNodeIndex;
+ this._totalSize = this._snapshot.totalSize;
+ for (var i = 0; i < loadCallbacks.length; ++i)
+ loadCallbacks[i]();
+ }
+ setTimeout(parse.bind(this), 0);
+ return true;
+ },
+
+ get loaded()
+ {
+ return !!this._snapshot;
+ },
+
+ get nodeCount()
+ {
+ return this._nodeCount;
+ },
+
+ nodeFieldValuesByIndex: function(fieldName, indexes, callback)
+ {
+ function returnResult()
+ {
+ callback(this._snapshot.nodeFieldValuesByIndex(fieldName, indexes));
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ nodeIds: function(callback)
+ {
+ this._invokeGetter("nodeIds", callback);
+ },
+
+ pushJSONChunk: function(chunk)
+ {
+ if (this.loaded || !this._isLoading)
+ return;
+ this._json += chunk;
+ },
+
+ pushBaseIds: function(snapshotId, className, nodeIds)
+ {
+ this._snapshot.updateBaseNodeIds(snapshotId, className, nodeIds);
+ },
+
+ get rootNodeIndex()
+ {
+ return this._rootNodeIndex;
+ },
+
+ startLoading: function(callback)
+ {
+ if (this._snapshot) {
+ function asyncInvoke()
+ {
+ callback();
+ }
+ setTimeout(callback, 0);
+ return false;
+ } else if (this._isLoading) {
+ this._onLoadCallbacks.push(callback);
+ return false;
+ } else {
+ this._isLoading = true;
+ this._onLoadCallbacks = [callback];
+ this._json = "";
+ return true;
+ }
+ },
+
+ get totalSize()
+ {
+ return this._totalSize;
+ },
+
+ get uid()
+ {
+ return this._snapshot.uid;
+ }
+};
+
+WebInspector.HeapSnapshotProviderProxy = function(createProvider, extractData)
+{
+ this._provider = createProvider();
+ this._extractData = extractData;
+}
+
+WebInspector.HeapSnapshotProviderProxy.prototype = {
+ getNextItems: function(count, callback)
+ {
+ function returnResult()
+ {
+ var result = new Array(count);
+ for (var i = 0 ; i < count && this._provider.hasNext(); ++i, this._provider.next())
+ result[i] = this._extractData(this._provider.item);
+ result.length = i;
+ callback(result, this._provider.hasNext(), this._provider.length);
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ isEmpty: function(callback)
+ {
+ function returnResult()
+ {
+ callback(this._provider.isEmpty);
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ sortAndRewind: function(comparator, callback)
+ {
+ function returnResult()
+ {
+ var result = this._provider.sort(comparator);
+ if (result)
+ this._provider.first();
+ callback(result);
+ }
+ setTimeout(returnResult.bind(this), 0);
+ }
+};
+
+WebInspector.HeapSnapshotPathFinderProxy = function(pathFinder)
+{
+ this._pathFinder = pathFinder;
+}
+
+WebInspector.HeapSnapshotPathFinderProxy.prototype = {
+ findNext: function(callback)
+ {
+ function returnResult()
+ {
+ callback(this._pathFinder.findNext());
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ updateRoots: function(filter)
+ {
+ function asyncInvoke()
+ {
+ this._pathFinder.updateRoots(filter);
+ }
+ setTimeout(asyncInvoke.bind(this), 0);
+ }
+};
+
+WebInspector.HeapSnapshotsDiffProxy = function(diff)
+{
+ this._diff = diff;
+}
+
+WebInspector.HeapSnapshotsDiffProxy.prototype = {
+ calculate: function(callback)
+ {
+ function returnResult()
+ {
+ callback(this._diff.calculate());
+ }
+ setTimeout(returnResult.bind(this), 0);
+ },
+
+ pushBaseIds: function(baseSnapshotId, baseIds)
+ {
+ this._diff.baseIds = baseIds;
+ },
+
+ pushBaseSelfSizes: function(baseSelfSizes)
+ {
+ this._diff.baseSelfSizes = baseSelfSizes;
+ }
+};
diff --git a/Source/WebCore/inspector/front-end/MetricsSidebarPane.js b/Source/WebCore/inspector/front-end/MetricsSidebarPane.js
index 1288973..afa3839 100644
--- a/Source/WebCore/inspector/front-end/MetricsSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/MetricsSidebarPane.js
@@ -61,11 +61,27 @@ WebInspector.MetricsSidebarPane.prototype = {
WebInspector.cssModel.getInlineStyleAsync(node.id, inlineStyleCallback);
},
+ _getPropertyValueAsPx: function(style, propertyName)
+ {
+ return Number(style.getPropertyValue(propertyName).replace(/px$/, "") || 0);
+ },
+
+ _getBox: function(computedStyle, componentName)
+ {
+ var suffix = componentName === "border" ? "-width" : "";
+ var left = this._getPropertyValueAsPx(computedStyle, componentName + "-left" + suffix);
+ var top = this._getPropertyValueAsPx(computedStyle, componentName + "-top" + suffix);
+ var right = this._getPropertyValueAsPx(computedStyle, componentName + "-right" + suffix);
+ var bottom = this._getPropertyValueAsPx(computedStyle, componentName + "-bottom" + suffix);
+ return { left: left, top: top, right: right, bottom: bottom };
+ },
+
_update: function(style)
{
// Updating with computed style.
var metricsElement = document.createElement("div");
metricsElement.className = "metrics";
+ var self = this;
function createBoxPartElement(style, name, side, suffix)
{
@@ -84,6 +100,32 @@ WebInspector.MetricsSidebarPane.prototype = {
return element;
}
+ function getContentAreaWidthPx(style)
+ {
+ var width = style.getPropertyValue("width").replace(/px$/, "");
+ if (style.getPropertyValue("box-sizing") === "border-box") {
+ var borderBox = self._getBox(style, "border");
+ var paddingBox = self._getBox(style, "padding");
+
+ width = width - borderBox.left - borderBox.right - paddingBox.left - paddingBox.right;
+ }
+
+ return width;
+ }
+
+ function getContentAreaHeightPx(style)
+ {
+ var height = style.getPropertyValue("height").replace(/px$/, "");
+ if (style.getPropertyValue("box-sizing") === "border-box") {
+ var borderBox = self._getBox(style, "border");
+ var paddingBox = self._getBox(style, "padding");
+
+ height = height - borderBox.top - borderBox.bottom - paddingBox.top - paddingBox.bottom;
+ }
+
+ return height;
+ }
+
// Display types for which margin is ignored.
var noMarginDisplayType = {
"table-cell": true,
@@ -127,15 +169,13 @@ WebInspector.MetricsSidebarPane.prototype = {
boxElement.className = name;
if (name === "content") {
- var width = style.getPropertyValue("width").replace(/px$/, "");
var widthElement = document.createElement("span");
- widthElement.textContent = width;
- widthElement.addEventListener("dblclick", this.startEditing.bind(this, widthElement, "width", "width"), false);
+ widthElement.textContent = getContentAreaWidthPx(style);
+ widthElement.addEventListener("dblclick", this.startEditing.bind(this, widthElement, "width", "width", style), false);
- var height = style.getPropertyValue("height").replace(/px$/, "");
var heightElement = document.createElement("span");
- heightElement.textContent = height;
- heightElement.addEventListener("dblclick", this.startEditing.bind(this, heightElement, "height", "height"), false);
+ heightElement.textContent = getContentAreaHeightPx(style);
+ heightElement.addEventListener("dblclick", this.startEditing.bind(this, heightElement, "height", "height", style), false);
boxElement.appendChild(widthElement);
boxElement.appendChild(document.createTextNode(" \u00D7 "));
@@ -168,12 +208,12 @@ WebInspector.MetricsSidebarPane.prototype = {
this.bodyElement.appendChild(metricsElement);
},
- startEditing: function(targetElement, box, styleProperty)
+ startEditing: function(targetElement, box, styleProperty, computedStyle)
{
if (WebInspector.isBeingEdited(targetElement))
return;
- var context = { box: box, styleProperty: styleProperty };
+ var context = { box: box, styleProperty: styleProperty, computedStyle: computedStyle };
WebInspector.startEditing(targetElement, {
context: context,
@@ -202,10 +242,34 @@ WebInspector.MetricsSidebarPane.prototype = {
else if (context.box === "position" && (!userInput || userInput === "\u2012"))
userInput = "auto";
+ userInput = userInput.toLowerCase();
// Append a "px" unit if the user input was just a number.
if (/^\d+$/.test(userInput))
userInput += "px";
+ var styleProperty = context.styleProperty;
+ var computedStyle = context.computedStyle;
+
+ if (computedStyle.getPropertyValue("box-sizing") === "border-box" && (styleProperty === "width" || styleProperty === "height")) {
+ if (!userInput.match(/px$/)) {
+ WebInspector.log("For elements with box-sizing: border-box, only absolute content area dimensions can be applied", WebInspector.ConsoleMessage.MessageLevel.Error);
+ WebInspector.showConsole();
+ return;
+ }
+
+ var borderBox = this._getBox(computedStyle, "border");
+ var paddingBox = this._getBox(computedStyle, "padding");
+ var userValuePx = Number(userInput.replace(/px$/, ""));
+ if (isNaN(userValuePx))
+ return;
+ if (styleProperty === "width")
+ userValuePx += borderBox.left + borderBox.right + paddingBox.left + paddingBox.right;
+ else
+ userValuePx += borderBox.top + borderBox.bottom + paddingBox.top + paddingBox.bottom;
+
+ userInput = userValuePx + "px";
+ }
+
var self = this;
var callback = function(style) {
if (!style)
@@ -217,7 +281,7 @@ WebInspector.MetricsSidebarPane.prototype = {
function setEnabledValueCallback(context, style)
{
- var property = style.getLiveProperty(context.styleProperty);
+ var property = style.getLiveProperty(styleProperty);
if (!property)
style.appendProperty(context.styleProperty, userInput, callback);
else
diff --git a/Source/WebCore/inspector/front-end/NetworkManager.js b/Source/WebCore/inspector/front-end/NetworkManager.js
index 98aa060..b6d413f 100644
--- a/Source/WebCore/inspector/front-end/NetworkManager.js
+++ b/Source/WebCore/inspector/front-end/NetworkManager.js
@@ -85,16 +85,19 @@ WebInspector.NetworkDispatcher.prototype = {
_updateResourceWithResponse: function(resource, response)
{
- if (!("status" in response))
+ if (!response)
return;
resource.mimeType = response.mimeType;
resource.statusCode = response.status;
resource.statusText = response.statusText;
resource.responseHeaders = response.headers;
- // Raw request headers can be a part of response as well.
+ if (response.headersText)
+ resource.responseHeadersText = response.headersText;
if (response.requestHeaders)
resource.requestHeaders = response.requestHeaders;
+ if (response.requestHeadersText)
+ resource.requestHeadersText = response.requestHeadersText;
resource.connectionReused = response.connectionReused;
resource.connectionID = response.connectionID;
@@ -112,14 +115,14 @@ WebInspector.NetworkDispatcher.prototype = {
this._updateResourceWithResponse(resource, cachedResource.response);
},
- requestWillBeSent: function(identifier, frameId, loaderId, documentURL, request, redirectResponse, time, callStack)
+ requestWillBeSent: function(identifier, frameId, loaderId, documentURL, request, time, stackTrace, redirectResponse)
{
var resource = this._inflightResourcesById[identifier];
if (resource) {
this.responseReceived(identifier, time, "Other", redirectResponse);
resource = this._appendRedirect(identifier, time, request.url);
} else
- resource = this._createResource(identifier, frameId, loaderId, request.url, documentURL, callStack);
+ resource = this._createResource(identifier, frameId, loaderId, request.url, documentURL, stackTrace);
this._updateResourceWithRequest(resource, request);
resource.startTime = time;
@@ -150,15 +153,27 @@ WebInspector.NetworkDispatcher.prototype = {
this._updateResource(resource);
},
- dataReceived: function(identifier, time, dataLength, lengthReceived)
+ domContentEventFired: function(time)
+ {
+ if (WebInspector.panels.network)
+ WebInspector.panels.network.mainResourceDOMContentTime = time;
+ },
+
+ loadEventFired: function(time)
+ {
+ if (WebInspector.panels.network)
+ WebInspector.panels.network.mainResourceLoadTime = time;
+ },
+
+ dataReceived: function(identifier, time, dataLength, encodedDataLength)
{
var resource = this._inflightResourcesById[identifier];
if (!resource)
return;
resource.resourceSize += dataLength;
- if (lengthReceived != -1)
- resource.increaseTransferSize(lengthReceived);
+ if (encodedDataLength != -1)
+ resource.increaseTransferSize(encodedDataLength);
resource.endTime = time;
this._updateResource(resource);
@@ -173,13 +188,14 @@ WebInspector.NetworkDispatcher.prototype = {
this._finishResource(resource, finishTime);
},
- loadingFailed: function(identifier, time, localizedDescription)
+ loadingFailed: function(identifier, time, localizedDescription, canceled)
{
var resource = this._inflightResourcesById[identifier];
if (!resource)
return;
resource.failed = true;
+ resource.canceled = canceled;
resource.localizedFailDescription = localizedDescription;
this._finishResource(resource, time);
},
diff --git a/Source/WebCore/inspector/front-end/NetworkPanel.js b/Source/WebCore/inspector/front-end/NetworkPanel.js
index 3c497d6..38be11a 100644
--- a/Source/WebCore/inspector/front-end/NetworkPanel.js
+++ b/Source/WebCore/inspector/front-end/NetworkPanel.js
@@ -827,14 +827,14 @@ WebInspector.NetworkPanel.prototype = {
this._appendResource(resourcesToPreserve[i]);
},
- canShowSourceLine: function(url, line)
+ canShowAnchorLocation: function(anchor)
{
- return !!this._resourcesByURL[url];
+ return !!this._resourcesByURL[anchor.href];
},
- showSourceLine: function(url, line)
+ showAnchorLocation: function(anchor)
{
- this._showResource(this._resourcesByURL[url], line);
+ this._showResource(this._resourcesByURL[anchor.href], anchor.getAttribute("line_number") - 1);
},
_showResource: function(resource, line)
@@ -1506,6 +1506,15 @@ WebInspector.NetworkDataGridNode.prototype = {
{
this._statusCell.removeChildren();
+ if (this._resource.failed) {
+ if (this._resource.canceled)
+ this._statusCell.textContent = WebInspector.UIString("(canceled)");
+ else
+ this._statusCell.textContent = WebInspector.UIString("(failed)");
+ this._statusCell.addStyleClass("network-dim-cell");
+ return;
+ }
+
var fromCache = this._resource.cached;
if (fromCache) {
this._statusCell.textContent = WebInspector.UIString("(from cache)");
@@ -1520,8 +1529,11 @@ WebInspector.NetworkDataGridNode.prototype = {
this._appendSubtitle(this._statusCell, this._resource.statusText);
this._statusCell.title = this._resource.statusCode + " " + this._resource.statusText;
} else {
+ if (this._resource.isDataURL() && this._resource.finished)
+ this._statusCell.textContent = WebInspector.UIString("(data url)");
+ else
+ this._statusCell.textContent = WebInspector.UIString("Pending");
this._statusCell.addStyleClass("network-dim-cell");
- this._statusCell.textContent = WebInspector.UIString("Pending");
}
},
diff --git a/Source/WebCore/inspector/front-end/Object.js b/Source/WebCore/inspector/front-end/Object.js
index 5872b8b..53c20e2 100644
--- a/Source/WebCore/inspector/front-end/Object.js
+++ b/Source/WebCore/inspector/front-end/Object.js
@@ -57,6 +57,13 @@ WebInspector.Object.prototype = {
delete this._listeners;
},
+ hasEventListeners: function(eventType)
+ {
+ if (!("_listeners" in this) || !(eventType in this._listeners))
+ return false;
+ return true;
+ },
+
dispatchEventToListeners: function(eventType, eventData)
{
if (!("_listeners" in this) || !(eventType in this._listeners))
diff --git a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
index 1795843..b42bea3 100644
--- a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
+++ b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js
@@ -45,12 +45,16 @@ WebInspector.ObjectPropertiesSection.prototype = {
update: function()
{
var self = this;
- var callback = function(properties) {
+ function callback(properties)
+ {
if (!properties)
return;
self.updateProperties(properties);
- };
- this.object.getProperties(this.ignoreHasOwnProperty, true, callback);
+ }
+ if (this.ignoreHasOwnProperty)
+ this.object.getAllProperties(callback);
+ else
+ this.object.getOwnProperties(callback);
},
updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
@@ -155,7 +159,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i]));
}
};
- this.property.value.getOwnProperties(true, callback.bind(this));
+ this.property.value.getOwnProperties(callback.bind(this));
},
ondblclick: function(event)
@@ -183,9 +187,14 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
var description = this.property.value.description;
// Render \n as a nice unicode cr symbol.
- if (this.property.value.type === "string" && typeof description === "string")
- description = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
- this.valueElement.textContent = description;
+ if (this.property.value.type === "string" && typeof description === "string") {
+ this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
+ this.valueElement._originalTextContent = "\"" + description + "\"";
+ } else if (this.property.value.type === "function" && typeof description === "string") {
+ this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
+ this.valueElement._originalTextContent = description;
+ } else
+ this.valueElement.textContent = description;
if (this.property.isGetter)
this.valueElement.addStyleClass("dimmed");
@@ -243,6 +252,10 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.listItemElement.addStyleClass("editing-sub-part");
+ // Edit original source.
+ if (typeof this.valueElement._originalTextContent === "string")
+ this.valueElement.textContent = this.valueElement._originalTextContent;
+
WebInspector.startEditing(this.valueElement, {
context: context,
commitHandler: this.editingCommitted.bind(this),
diff --git a/Source/WebCore/inspector/front-end/Panel.js b/Source/WebCore/inspector/front-end/Panel.js
index 1b99dd4..49d7cc6 100644
--- a/Source/WebCore/inspector/front-end/Panel.js
+++ b/Source/WebCore/inspector/front-end/Panel.js
@@ -74,6 +74,7 @@ WebInspector.Panel.prototype = {
this.restoreSidebarWidth();
this._restoreScrollPositions();
+ WebInspector.extensionServer.notifyPanelShown(this.name);
},
hide: function()
@@ -86,6 +87,7 @@ WebInspector.Panel.prototype = {
delete this._statusBarItemContainer;
if ("_toolbarItem" in this)
this._toolbarItem.removeStyleClass("toggled-on");
+ WebInspector.extensionServer.notifyPanelHidden(this.name);
},
reset: function()
@@ -235,7 +237,7 @@ WebInspector.Panel.prototype = {
if (currentView !== this.visibleView) {
this.showView(currentView);
- WebInspector.focusSearchField();
+ WebInspector.searchController.focusSearchField();
}
if (showFirstResult)
@@ -268,7 +270,7 @@ WebInspector.Panel.prototype = {
if (currentView !== this.visibleView) {
this.showView(currentView);
- WebInspector.focusSearchField();
+ WebInspector.searchController.focusSearchField();
}
if (showLastResult)
@@ -384,12 +386,12 @@ WebInspector.Panel.prototype = {
visibleView.resize();
},
- canShowSourceLine: function(url, line)
+ canShowAnchorLocation: function(anchor)
{
return false;
},
- showSourceLine: function(url, line)
+ showAnchorLocation: function(anchor)
{
return false;
},
diff --git a/Source/WebCore/inspector/front-end/PleaseWaitMessage.js b/Source/WebCore/inspector/front-end/PleaseWaitMessage.js
index e1980a0..c5ddd49 100644
--- a/Source/WebCore/inspector/front-end/PleaseWaitMessage.js
+++ b/Source/WebCore/inspector/front-end/PleaseWaitMessage.js
@@ -86,7 +86,7 @@ WebInspector.PleaseWaitMessage.prototype = {
var instance = WebInspector.PleaseWaitMessage.prototype.instance;
var message = instance.element;
if (message.parentNode === element) {
- actionCallback();
+ setTimeout(actionCallback, 0);
return;
}
diff --git a/Source/WebCore/inspector/front-end/ProfilesPanel.js b/Source/WebCore/inspector/front-end/ProfilesPanel.js
index ea5327b..d9a1178 100644
--- a/Source/WebCore/inspector/front-end/ProfilesPanel.js
+++ b/Source/WebCore/inspector/front-end/ProfilesPanel.js
@@ -211,11 +211,6 @@ WebInspector.ProfilesPanel.prototype = {
if (view && ("dispose" in view))
view.dispose();
delete this._profiles[i]._profileView;
- var profile = this._profiles[i];
- if (profile.nodes) {
- delete profile.nodes;
- delete profile.strings;
- }
}
delete this.visibleView;
@@ -450,58 +445,84 @@ WebInspector.ProfilesPanel.prototype = {
if (!profile)
return;
- if (profile._loaded)
- callback(profile);
- else if (profile._is_loading)
- profile._callbacks.push(callback);
- else {
- profile._is_loading = true;
- profile._callbacks = [callback];
- profile._json = "";
- profile.sideBarElement.subtitle = WebInspector.UIString("Loading…");
- ProfilerAgent.getProfile(profile.typeId, profile.uid);
+ if (!Preferences.detailedHeapProfiles) {
+ if (profile._loaded)
+ callback(profile);
+ else if (profile._is_loading)
+ profile._callbacks.push(callback);
+ else {
+ profile._is_loading = true;
+ profile._callbacks = [callback];
+ profile._json = "";
+ profile.sideBarElement.subtitle = WebInspector.UIString("Loading\u2026");
+ ProfilerAgent.getProfile(profile.typeId, profile.uid);
+ }
+ } else {
+ if (!profile.proxy)
+ profile.proxy = new WebInspector.HeapSnapshotProxy();
+ var proxy = profile.proxy;
+ if (proxy.startLoading(callback)) {
+ profile.sideBarElement.subtitle = WebInspector.UIString("Loading\u2026");
+ ProfilerAgent.getProfile(profile.typeId, profile.uid);
+ }
}
},
_addHeapSnapshotChunk: function(uid, chunk)
{
var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)];
- if (!profile || profile._loaded || !profile._is_loading)
+ if (!profile)
return;
-
- profile._json += chunk;
+ if (!Preferences.detailedHeapProfiles) {
+ if (profile._loaded || !profile._is_loading)
+ return;
+ profile._json += chunk;
+ } else {
+ if (!profile.proxy)
+ return;
+ profile.proxy.pushJSONChunk(chunk);
+ }
},
_finishHeapSnapshot: function(uid)
{
var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)];
- if (!profile || profile._loaded || !profile._is_loading)
+ if (!profile)
return;
-
- var callbacks = profile._callbacks;
- delete profile._callbacks;
- profile.sideBarElement.subtitle = WebInspector.UIString("Parsing…");
- window.setTimeout(doParse, 0);
-
- function doParse()
- {
- var loadedSnapshot = JSON.parse(profile._json);
- delete profile._json;
- delete profile._is_loading;
- profile._loaded = true;
- profile.sideBarElement.subtitle = "";
-
- if (!Preferences.detailedHeapProfiles && WebInspector.DetailedHeapshotView.prototype.isDetailedSnapshot(loadedSnapshot)) {
- WebInspector.panels.profiles._enableDetailedHeapProfiles(false);
+ if (!Preferences.detailedHeapProfiles) {
+ if (profile._loaded || !profile._is_loading)
return;
- }
+ profile.sideBarElement.subtitle = WebInspector.UIString("Parsing\u2026");
+ function doParse()
+ {
+ var loadedSnapshot = JSON.parse(profile._json);
+ var callbacks = profile._callbacks;
+ delete profile._callbacks;
+ delete profile._json;
+ delete profile._is_loading;
+ profile._loaded = true;
+ profile.sideBarElement.subtitle = "";
+
+ if (WebInspector.DetailedHeapshotView.prototype.isDetailedSnapshot(loadedSnapshot)) {
+ WebInspector.panels.profiles._enableDetailedHeapProfiles(false);
+ return;
+ }
- if (!Preferences.detailedHeapProfiles)
WebInspector.HeapSnapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot);
- else
- WebInspector.DetailedHeapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot);
- for (var i = 0; i < callbacks.length; ++i)
- callbacks[i](profile);
+ for (var i = 0; i < callbacks.length; ++i)
+ callbacks[i](profile);
+ }
+ setTimeout(doParse, 0);
+ } else {
+ if (!profile.proxy)
+ return;
+ var proxy = profile.proxy;
+ function parsed()
+ {
+ profile.sideBarElement.subtitle = Number.bytesToString(proxy.totalSize);
+ }
+ if (proxy.finishLoading(parsed))
+ profile.sideBarElement.subtitle = WebInspector.UIString("Parsing\u2026");
}
},
diff --git a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
index 4df313c..e6ce0b2 100644
--- a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
@@ -57,7 +57,7 @@ WebInspector.PropertiesSidebarPane.prototype = {
if (error || !objectPayload)
return;
var object = WebInspector.RemoteObject.fromPayload(objectPayload);
- object.getOwnProperties(false, fillSection.bind(this));
+ object.getOwnProperties(fillSection.bind(this));
}
function fillSection(prototypes)
diff --git a/Source/WebCore/inspector/front-end/RemoteObject.js b/Source/WebCore/inspector/front-end/RemoteObject.js
index 294be50..b6038ca 100644
--- a/Source/WebCore/inspector/front-end/RemoteObject.js
+++ b/Source/WebCore/inspector/front-end/RemoteObject.js
@@ -107,12 +107,17 @@ WebInspector.RemoteObject.prototype = {
return this._type === "error";
},
- getOwnProperties: function(abbreviate, callback)
+ getOwnProperties: function(callback)
{
- this.getProperties(false, abbreviate, callback);
+ this._getProperties(false, callback);
},
- getProperties: function(ignoreHasOwnProperty, abbreviate, callback)
+ getAllProperties: function(callback)
+ {
+ this._getProperties(true, callback);
+ },
+
+ _getProperties: function(ignoreHasOwnProperty, callback)
{
if (!this._objectId) {
callback([]);
@@ -126,7 +131,7 @@ WebInspector.RemoteObject.prototype = {
properties[i].value = WebInspector.RemoteObject.fromPayload(properties[i].value);
callback(properties);
}
- RuntimeAgent.getProperties(this._objectId, !!ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
+ RuntimeAgent.getProperties(this._objectId, !!ignoreHasOwnProperty, remoteObjectBinder);
},
setPropertyValue: function(name, value, callback)
@@ -237,12 +242,12 @@ WebInspector.LocalJSONObject.prototype = {
return typeof this._value === "object" && this._value !== null && Object.keys(this._value).length;
},
- getOwnProperties: function(abbreviate, callback)
+ getOwnProperties: function(callback)
{
- return this.getProperties(false, abbreviate, callback);
+ callback(this._children());
},
- getProperties: function(ignoreHasOwnProperty, abbreviate, callback)
+ getAllProperties: function(callback)
{
callback(this._children());
},
diff --git a/Source/WebCore/inspector/front-end/Resource.js b/Source/WebCore/inspector/front-end/Resource.js
index 8035fd8..d8373cd 100644
--- a/Source/WebCore/inspector/front-end/Resource.js
+++ b/Source/WebCore/inspector/front-end/Resource.js
@@ -33,7 +33,7 @@ WebInspector.Resource = function(identifier, url)
this._endTime = -1;
this._category = WebInspector.resourceCategories.other;
this._pendingContentCallbacks = [];
- this._responseHeadersSize = 0;
+ this.history = [];
}
// Keep these in sync with WebCore::InspectorResource::Type
@@ -101,6 +101,17 @@ WebInspector.Resource.Type = {
}
}
+WebInspector.Resource._domainModelBindings = [];
+
+WebInspector.Resource.registerDomainModelBinding = function(type, binding)
+{
+ WebInspector.Resource._domainModelBindings[type] = binding;
+}
+
+WebInspector.Resource.Events = {
+ RevisionAdded: 0
+}
+
WebInspector.Resource.prototype = {
get url()
{
@@ -240,7 +251,7 @@ WebInspector.Resource.prototype = {
if (this.cached)
return 0;
if (this.statusCode === 304) // Not modified
- return this._responseHeadersSize;
+ return this.responseHeadersSize;
if (this._transferSize !== undefined)
return this._transferSize;
// If we did not receive actual transfer size from network
@@ -254,7 +265,7 @@ WebInspector.Resource.prototype = {
// work for chunks with non-trivial encodings. We need a way to
// get actual transfer size from the network stack.
var bodySize = Number(this.responseHeaders["Content-Length"] || this.resourceSize);
- return this._responseHeadersSize + bodySize;
+ return this.responseHeadersSize + bodySize;
},
increaseTransferSize: function(x)
@@ -292,6 +303,16 @@ WebInspector.Resource.prototype = {
this._failed = x;
},
+ get canceled()
+ {
+ return this._canceled;
+ },
+
+ set canceled(x)
+ {
+ this._canceled = x;
+ },
+
get category()
{
return this._category;
@@ -393,10 +414,35 @@ WebInspector.Resource.prototype = {
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;
+ delete this._responseHeadersSize;
this.dispatchEventToListeners("requestHeaders changed");
},
+ get requestHeadersText()
+ {
+ return this._requestHeadersText;
+ },
+
+ set requestHeadersText(x)
+ {
+ this._requestHeadersText = x;
+ delete this._responseHeadersSize;
+
+ this.dispatchEventToListeners("requestHeaders changed");
+ },
+
+ get requestHeadersSize()
+ {
+ if (typeof(this._requestHeadersSize) === "undefined") {
+ if (this._requestHeadersText)
+ this._requestHeadersSize = this._requestHeadersText.length;
+ else
+ this._requestHeadersSize = this._headersSize(this._requestHeaders)
+ }
+ return this._requestHeadersSize;
+ },
+
get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
@@ -441,13 +487,37 @@ WebInspector.Resource.prototype = {
set responseHeaders(x)
{
this._responseHeaders = x;
- // FIXME: we should take actual headers size from network stack, when possible.
- this._responseHeadersSize = this._headersSize(x);
+ delete this._responseHeadersSize;
delete this._sortedResponseHeaders;
delete this._responseCookies;
this.dispatchEventToListeners("responseHeaders changed");
},
+
+ get responseHeadersText()
+ {
+ return this._responseHeadersText;
+ },
+
+ set responseHeadersText(x)
+ {
+ this._responseHeadersText = x;
+ delete this._responseHeadersSize;
+
+ this.dispatchEventToListeners("responseHeaders changed");
+ },
+
+ get responseHeadersSize()
+ {
+ if (typeof(this._responseHeadersSize) === "undefined") {
+ if (this._responseHeadersText)
+ this._responseHeadersSize = this._responseHeadersText.length;
+ else
+ this._responseHeadersSize = this._headersSize(this._responseHeaders)
+ }
+ return this._responseHeadersSize;
+ },
+
get sortedResponseHeaders()
{
@@ -526,9 +596,11 @@ WebInspector.Resource.prototype = {
_headersSize: function(headers)
{
+ // We should take actual headers size from network stack, when possible, but fall back to
+ // this lousy computation when no headers text is available.
var size = 0;
for (var header in headers)
- size += header.length + headers[header].length + 3; // _typical_ overhead per herader is ": ".length + "\n".length.
+ size += header.length + headers[header].length + 4; // _typical_ overhead per header is ": ".length + "\r\n".length.
return size;
},
@@ -566,7 +638,10 @@ WebInspector.Resource.prototype = {
// If status is an error, content is likely to be of an inconsistent type,
// as it's going to be an error message. We do not want to emit a warning
// for this, though, as this will already be reported as resource loading failure.
- if (this.statusCode >= 400)
+ // Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,
+ // it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.
+ // Don't check for mime-types in 304-resources.
+ if (this.statusCode >= 400 || this.statusCode === 304)
return true;
if (typeof this.type === "undefined"
@@ -627,59 +702,34 @@ WebInspector.Resource.prototype = {
this._content = content;
},
- isLocallyModified: function()
+ isEditable: function()
{
- return !!this._baseRevision;
+ if (this._actualResource)
+ return false;
+ var binding = WebInspector.Resource._domainModelBindings[this.type];
+ return binding && binding.canSetContent(this);
},
- setContent: function(newContent, onRevert)
+ setContent: function(newContent, majorChange, callback)
{
- 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.isEditable(this)) {
+ if (callback)
+ callback("Resource is not editable");
+ return;
}
-
- 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);
+ var binding = WebInspector.Resource._domainModelBindings[this.type];
+ binding.setContent(this, newContent, majorChange, callback);
},
- revertToThis: function()
+ addRevision: function(newContent)
{
- if (!this._actualResource || !this._fireOnRevert)
- return;
+ var revision = new WebInspector.ResourceRevision(this, this._content, this._contentTimestamp);
+ this.history.push(revision);
- function callback(content)
- {
- if (content)
- this._fireOnRevert(content);
- }
- this.requestContent(callback.bind(this));
- },
+ this._content = newContent;
+ this._contentTimestamp = new Date();
- get baseRevision()
- {
- return this._baseRevision;
+ this.dispatchEventToListeners(WebInspector.Resource.Events.RevisionAdded, revision);
},
requestContent: function(callback)
@@ -713,6 +763,11 @@ WebInspector.Resource.prototype = {
image.src = this.url;
},
+ isDataURL: function()
+ {
+ return this.url.match(/^data:/i);
+ },
+
_contentURL: function()
{
const maxDataUrlSize = 1024 * 1024;
@@ -733,6 +788,7 @@ WebInspector.Resource.prototype = {
function onResourceContent(data)
{
this._content = data;
+ this._originalContent = data;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded);
@@ -744,3 +800,76 @@ WebInspector.Resource.prototype = {
}
WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.ResourceRevision = function(resource, content, timestamp)
+{
+ this._resource = resource;
+ this._content = content;
+ this._timestamp = timestamp;
+}
+
+WebInspector.ResourceRevision.prototype = {
+ get resource()
+ {
+ return this._resource;
+ },
+
+ get timestamp()
+ {
+ return this._timestamp;
+ },
+
+ get content()
+ {
+ return this._content;
+ },
+
+ revertToThis: function()
+ {
+ function revert(content)
+ {
+ this._resource.setContent(content, true);
+ }
+ this.requestContent(revert.bind(this));
+ },
+
+ requestContent: function(callback)
+ {
+ if (typeof this._content === "string") {
+ callback(this._content);
+ return;
+ }
+
+ // If we are here, this is initial revision. First, look up content fetched over the wire.
+ if (typeof this.resource._originalContent === "string") {
+ this._content = this._resource._originalContent;
+ callback(this._content);
+ return;
+ }
+
+ // If unsuccessful, request the content.
+ function mycallback(content)
+ {
+ this._content = content;
+ callback(content);
+ }
+ WebInspector.networkManager.requestContent(this._resource, false, mycallback.bind(this));
+ }
+}
+
+WebInspector.ResourceDomainModelBinding = function()
+{
+}
+
+WebInspector.ResourceDomainModelBinding.prototype = {
+ canSetContent: function()
+ {
+ // Implemented by the domains.
+ return true;
+ },
+
+ setContent: function(resource, content, majorChange, callback)
+ {
+ // Implemented by the domains.
+ }
+}
diff --git a/Source/WebCore/inspector/front-end/ResourceHeadersView.js b/Source/WebCore/inspector/front-end/ResourceHeadersView.js
index e79078a..f13a392 100644
--- a/Source/WebCore/inspector/front-end/ResourceHeadersView.js
+++ b/Source/WebCore/inspector/front-end/ResourceHeadersView.js
@@ -59,9 +59,11 @@ WebInspector.ResourceHeadersView = function(resource)
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._showRequestHeadersText = false;
+ this._showResponseHeadersText = false;
+
this._queryStringTreeElement = new TreeElement("", null, true);
this._queryStringTreeElement.expanded = true;
this._queryStringTreeElement.selectable = false;
@@ -146,7 +148,19 @@ WebInspector.ResourceHeadersView.prototype = {
{
parmsTreeElement.removeChildren();
- parmsTreeElement.titleHTML = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";
+ parmsTreeElement.listItemElement.removeChildren();
+ parmsTreeElement.listItemElement.appendChild(document.createTextNode(title));
+
+ var headerCount = document.createElement("span");
+ headerCount.addStyleClass("header-count");
+ headerCount.textContent = WebInspector.UIString(" (%d)", parms.length);
+ parmsTreeElement.listItemElement.appendChild(headerCount);
+
+ var toggleTitle = this._decodeRequestParameters ? WebInspector.UIString("view URL encoded") : WebInspector.UIString("view decoded");
+ var toggleButton = this._createToggleButton(toggleTitle);
+ toggleButton.addEventListener("click", this._toggleURLdecoding.bind(this));
+ parmsTreeElement.listItemElement.appendChild(toggleButton);
+
for (var i = 0; i < parms.length; ++i) {
var name = parms[i].name;
@@ -175,8 +189,6 @@ WebInspector.ResourceHeadersView.prototype = {
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);
}
},
@@ -202,7 +214,17 @@ WebInspector.ResourceHeadersView.prototype = {
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);
+ if (this._showRequestHeadersText)
+ this._refreshHeadersText(WebInspector.UIString("Request Headers"), this._resource.requestHeadersText, this._requestHeadersTreeElement);
+ else
+ this._refreshHeaders(WebInspector.UIString("Request Headers"), this._resource.sortedRequestHeaders, additionalRow, this._requestHeadersTreeElement);
+
+ if (this._resource.requestHeadersText) {
+ var toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
+ toggleButton.addEventListener("click", this._toggleRequestHeadersText.bind(this));
+ this._requestHeadersTreeElement.listItemElement.appendChild(toggleButton);
+ }
+
this._refreshFormData();
},
@@ -211,7 +233,16 @@ WebInspector.ResourceHeadersView.prototype = {
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);
+ if (this._showResponseHeadersText)
+ this._refreshHeadersText(WebInspector.UIString("Response Headers"), this._resource.responseHeadersText, this._responseHeadersTreeElement);
+ else
+ this._refreshHeaders(WebInspector.UIString("Response Headers"), this._resource.sortedResponseHeaders, additionalRow, this._responseHeadersTreeElement);
+
+ if (this._resource.responseHeadersText) {
+ var toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
+ toggleButton.addEventListener("click", this._toggleResponseHeadersText.bind(this));
+ this._responseHeadersTreeElement.listItemElement.appendChild(toggleButton);
+ }
},
_refreshHTTPInformation: function()
@@ -242,15 +273,26 @@ WebInspector.ResourceHeadersView.prototype = {
}
},
+ _refreshHeadersTitle: function(title, headersTreeElement, isHeadersTextShown, headersLength)
+ {
+ headersTreeElement.listItemElement.removeChildren();
+ headersTreeElement.listItemElement.appendChild(document.createTextNode(title));
+
+ if (!isHeadersTextShown) {
+ var headerCount = document.createElement("span");
+ headerCount.addStyleClass("header-count");
+ headerCount.textContent = WebInspector.UIString(" (%d)", headersLength);
+ headersTreeElement.listItemElement.appendChild(headerCount);
+ }
+ },
+
_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>";
+ this._refreshHeadersTitle(title, headersTreeElement, false, length);
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>"
@@ -270,6 +312,49 @@ WebInspector.ResourceHeadersView.prototype = {
headerTreeElement.selectable = false;
headersTreeElement.appendChild(headerTreeElement);
}
+ },
+
+ _refreshHeadersText: function(title, headersText, headersTreeElement)
+ {
+ headersTreeElement.removeChildren();
+
+ this._refreshHeadersTitle(title, headersTreeElement, true);
+ var headerTreeElement = new TreeElement(null, null, false);
+ headerTreeElement.selectable = false;
+ headersTreeElement.appendChild(headerTreeElement);
+ headerTreeElement.listItemElement.addStyleClass("headers-text");
+
+ var headersTextElement = document.createElement("span");
+ headersTextElement.addStyleClass("header-value");
+ headersTextElement.addStyleClass("source-code");
+ headersTextElement.textContent = String(headersText).trim();
+ headerTreeElement.listItemElement.appendChild(headersTextElement);
+ },
+
+ _toggleRequestHeadersText: function(event)
+ {
+ this._showRequestHeadersText = !this._showRequestHeadersText;
+ this._refreshRequestHeaders();
+ },
+
+ _toggleResponseHeadersText: function(event)
+ {
+ this._showResponseHeadersText = !this._showResponseHeadersText;
+ this._refreshResponseHeaders();
+ },
+
+ _createToggleButton: function(title)
+ {
+ var button = document.createElement("span");
+ button.addStyleClass("header-toggle");
+ button.textContent = title;
+ return button;
+ },
+
+ _createHeadersToggleButton: function(isHeadersTextShown)
+ {
+ var toggleTitle = isHeadersTextShown ? WebInspector.UIString("view parsed") : WebInspector.UIString("view source");
+ return this._createToggleButton(toggleTitle);
}
}
diff --git a/Source/WebCore/inspector/front-end/ResourceTreeModel.js b/Source/WebCore/inspector/front-end/ResourceTreeModel.js
index fa2c44e..890daeb 100644
--- a/Source/WebCore/inspector/front-end/ResourceTreeModel.js
+++ b/Source/WebCore/inspector/front-end/ResourceTreeModel.js
@@ -31,8 +31,9 @@
WebInspector.ResourceTreeModel = function(networkManager)
{
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceUpdated, this);
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.FrameDetached, this._onFrameDetachedFromParent, this);
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.FrameCommittedLoad, this._onCommitLoad, this);
@@ -43,7 +44,8 @@ WebInspector.ResourceTreeModel.EventTypes = {
FrameAdded: "FrameAdded",
FrameNavigated: "FrameNavigated",
FrameDetached: "FrameDetached",
- ResourceAdded: "ResourceAdded"
+ ResourceAdded: "ResourceAdded",
+ CachedResourcesLoaded: "CachedResourcesLoaded"
}
WebInspector.ResourceTreeModel.prototype = {
@@ -64,6 +66,8 @@ WebInspector.ResourceTreeModel.prototype = {
WebInspector.mainResource = this._addFramesRecursively(mainFramePayload);
this._cachedResourcesProcessed = true;
+
+ this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
},
_addOrUpdateFrame: function(frame)
@@ -131,6 +135,13 @@ WebInspector.ResourceTreeModel.prototype = {
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, frameId);
},
+ _onResourceStarted: function(event)
+ {
+ if (!this._cachedResourcesProcessed)
+ return;
+ this._bindResourceURL(event.data);
+ },
+
_onResourceUpdated: function(event)
{
if (!this._cachedResourcesProcessed)
@@ -238,8 +249,6 @@ WebInspector.ResourceTreeModel.prototype = {
_callForFrameResources: function(frameId, callback)
{
var resources = this._resourcesByFrameId[frameId];
- if (!resources)
- return;
for (var url in resources) {
if (callback(resources[url]))
@@ -293,6 +302,7 @@ WebInspector.ResourceTreeModel.prototype = {
var resource = new WebInspector.Resource(null, url);
resource.frameId = frame.id;
resource.loaderId = frame.loaderId;
+ resource.documentURL = frame.url;
return resource;
}
}
diff --git a/Source/WebCore/inspector/front-end/ResourceView.js b/Source/WebCore/inspector/front-end/ResourceView.js
index ffd9062..acf5a28 100644
--- a/Source/WebCore/inspector/front-end/ResourceView.js
+++ b/Source/WebCore/inspector/front-end/ResourceView.js
@@ -45,20 +45,12 @@ WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ResourceView.createResourceView = function(resource)
{
- function sourceFrameForDelegateAndURL(delegate, url)
- {
- var view = new WebInspector.SourceFrame(delegate, url);
- view.resource = resource;
- return view;
- }
-
switch (resource.category) {
case WebInspector.resourceCategories.documents:
case WebInspector.resourceCategories.scripts:
case WebInspector.resourceCategories.xhr:
- return sourceFrameForDelegateAndURL(new WebInspector.SourceFrameDelegateForResourcesPanel(resource), resource.url);
case WebInspector.resourceCategories.stylesheets:
- return sourceFrameForDelegateAndURL(new WebInspector.CSSSourceFrameDelegateForResourcesPanel(resource), resource.url);
+ return new WebInspector.ResourceSourceFrame(resource);
case WebInspector.resourceCategories.images:
return new WebInspector.ImageView(resource);
case WebInspector.resourceCategories.fonts:
@@ -70,13 +62,13 @@ WebInspector.ResourceView.createResourceView = function(resource)
WebInspector.ResourceView.resourceViewTypeMatchesResource = function(resource)
{
- var resourceView = resource._resourcesView;
+ var resourceView = resource._resourceView;
switch (resource.category) {
case WebInspector.resourceCategories.documents:
- case WebInspector.resourceCategories.stylesheets:
case WebInspector.resourceCategories.scripts:
case WebInspector.resourceCategories.xhr:
- return resourceView.__proto__ === WebInspector.SourceFrame.prototype;
+ case WebInspector.resourceCategories.stylesheets:
+ return resourceView.__proto__ === WebInspector.ResourceSourceFrame.prototype;
case WebInspector.resourceCategories.images:
return resourceView.__proto__ === WebInspector.ImageView.prototype;
case WebInspector.resourceCategories.fonts:
@@ -90,23 +82,23 @@ WebInspector.ResourceView.resourceViewForResource = function(resource)
{
if (!resource)
return null;
- if (!resource._resourcesView)
- resource._resourcesView = WebInspector.ResourceView.createResourceView(resource);
- return resource._resourcesView;
+ if (!resource._resourceView)
+ resource._resourceView = WebInspector.ResourceView.createResourceView(resource);
+ return resource._resourceView;
}
WebInspector.ResourceView.recreateResourceView = function(resource)
{
var newView = WebInspector.ResourceView.createResourceView(resource);
- var oldView = resource._resourcesView;
+ var oldView = resource._resourceView;
var oldViewParentNode = oldView.visible ? oldView.element.parentNode : null;
var scrollTop = oldView.scrollTop;
- resource._resourcesView.detach();
- delete resource._resourcesView;
+ resource._resourceView.detach();
+ delete resource._resourceView;
- resource._resourcesView = newView;
+ resource._resourceView = newView;
if (oldViewParentNode)
newView.show(oldViewParentNode);
@@ -120,88 +112,99 @@ WebInspector.ResourceView.existingResourceViewForResource = function(resource)
{
if (!resource)
return null;
- return resource._resourcesView;
+ return resource._resourceView;
}
-WebInspector.SourceFrameDelegateForResourcesPanel = function(resource)
+WebInspector.ResourceSourceFrame = function(resource)
{
- WebInspector.SourceFrameDelegate.call(this);
+ WebInspector.SourceFrame.call(this, new WebInspector.SourceFrameDelegate(), resource.url);
this._resource = resource;
}
//This is a map from resource.type to mime types
//found in WebInspector.SourceTokenizer.Registry.
-WebInspector.SourceFrameDelegateForResourcesPanel.DefaultMIMETypeForResourceType = {
+WebInspector.ResourceSourceFrame.DefaultMIMETypeForResourceType = {
0: "text/html",
1: "text/css",
4: "text/javascript"
}
-WebInspector.SourceFrameDelegateForResourcesPanel.prototype = {
+WebInspector.ResourceSourceFrame.prototype = {
+ get resource()
+ {
+ return this._resource;
+ },
+
+ isContentEditable: function()
+ {
+ return this._resource.isEditable();
+ },
+
+ editContent: function(newText, callback)
+ {
+ this._clearIncrementalUpdateTimer();
+ var majorChange = true;
+ this._resource.setContent(newText, majorChange, callback);
+ },
+
+ endEditing: function(oldRange, newRange)
+ {
+ function commitIncrementalEdit()
+ {
+ var majorChange = false;
+ this._resource.setContent(this._textModel.text, majorChange, function() {});
+ }
+ const updateTimeout = 200;
+ this._incrementalUpdateTimer = setTimeout(commitIncrementalEdit.bind(this), updateTimeout);
+ },
+
+ _clearIncrementalUpdateTimer: function()
+ {
+ if (this._incrementalUpdateTimer)
+ clearTimeout(this._incrementalUpdateTimer);
+ delete this._incrementalUpdateTimer;
+ },
+
requestContent: function(callback)
{
function contentLoaded(text)
{
- var mimeType = WebInspector.SourceFrameDelegateForResourcesPanel.DefaultMIMETypeForResourceType[this._resource.type] || this._resource.mimeType;
- var sourceMapping = new WebInspector.IdenticalSourceMapping();
- callback(mimeType, new WebInspector.SourceFrameContent(text, sourceMapping, []));
+ var mimeType = WebInspector.ResourceSourceFrame.DefaultMIMETypeForResourceType[this._resource.type] || this._resource.mimeType;
+ callback(mimeType, text);
}
this._resource.requestContent(contentLoaded.bind(this));
}
}
-WebInspector.SourceFrameDelegateForResourcesPanel.prototype.__proto__ = WebInspector.SourceFrameDelegate.prototype;
-
+WebInspector.ResourceSourceFrame.prototype.__proto__ = WebInspector.SourceFrame.prototype;
-WebInspector.CSSSourceFrameDelegateForResourcesPanel = function(resource)
+WebInspector.RevisionSourceFrame = function(revision)
{
- WebInspector.SourceFrameDelegateForResourcesPanel.call(this, resource);
+ WebInspector.SourceFrame.call(this, new WebInspector.SourceFrameDelegate(), revision.resource.url);
+ this._revision = revision;
}
-WebInspector.CSSSourceFrameDelegateForResourcesPanel.prototype = {
- canEditScriptSource: function()
+WebInspector.RevisionSourceFrame.prototype = {
+ get resource()
{
- return true;
+ return this._revision.resource;
},
- editScriptSource: function(newText)
+ isContentEditable: function()
{
- function handleStyleSheet(newText, styleSheet)
- {
- this._styleSheet = styleSheet;
- this._saveStyleSheet(newText);
- }
-
- function handleInfos(newText, error, infos)
- {
- if (error)
- return;
- for (var i = 0; i < infos.length; ++i) {
- var info = infos[i];
- if (info.sourceURL === this._resource.url) {
- WebInspector.CSSStyleSheet.createForId(info.styleSheetId, handleStyleSheet.bind(this, newText));
- break;
- }
- }
- }
-
- if (this._styleSheet)
- this._saveStyleSheet(newText);
- else
- CSSAgent.getAllStyleSheets(handleInfos.bind(this, newText));
+ return false;
},
- _saveStyleSheet: function(newText)
+ requestContent: function(callback)
{
- function callback(success)
+ function contentLoaded(text)
{
- if (!success)
- console.error("Failed to save modified stylesheet %s", this._resource.url);
+ var mimeType = WebInspector.ResourceSourceFrame.DefaultMIMETypeForResourceType[this._revision.resource.type] || this._revision.resource.mimeType;
+ callback(mimeType, text);
}
-
- this._styleSheet.setText(newText, callback.bind(this));
+ this._revision.requestContent(contentLoaded.bind(this));
}
}
-WebInspector.CSSSourceFrameDelegateForResourcesPanel.prototype.__proto__ = WebInspector.SourceFrameDelegateForResourcesPanel.prototype;
+WebInspector.RevisionSourceFrame.prototype.__proto__ = WebInspector.SourceFrame.prototype;
diff --git a/Source/WebCore/inspector/front-end/ResourcesPanel.js b/Source/WebCore/inspector/front-end/ResourcesPanel.js
index c65e6b7..d8e2b10 100644
--- a/Source/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/Source/WebCore/inspector/front-end/ResourcesPanel.js
@@ -111,10 +111,6 @@ WebInspector.ResourcesPanel.prototype = {
_initDefaultSelection: function()
{
- if (this._initializedDefaultSelection)
- return;
-
- this._initializedDefaultSelection = true;
var itemURL = WebInspector.settings.resourcesLastSelectedItem;
if (itemURL) {
for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
@@ -177,6 +173,7 @@ WebInspector.ResourcesPanel.prototype = {
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
function populateFrame(frameId)
{
@@ -191,7 +188,6 @@ WebInspector.ResourcesPanel.prototype = {
this._resourceAdded({data:resources[i]});
}
populateFrame.call(this, 0);
- this._initDefaultSelection();
},
_frameAdded: function(event)
@@ -205,7 +201,11 @@ WebInspector.ResourcesPanel.prototype = {
var frameTreeElement = this._treeElementForFrameId[frameId];
if (frameTreeElement) {
+ // Maintain sorted order.
+ var parent = frameTreeElement.parent;
+ parent.removeChild(frameTreeElement);
frameTreeElement.setTitles(title, subtitle);
+ parent.appendChild(frameTreeElement);
return;
}
@@ -217,20 +217,6 @@ WebInspector.ResourcesPanel.prototype = {
var frameTreeElement = new WebInspector.FrameTreeElement(this, frameId, title, subtitle);
this._treeElementForFrameId[frameId] = frameTreeElement;
-
- // Insert in the alphabetical order, first frames, then resources.
- var children = parentTreeElement.children;
- for (var i = 0; i < children.length; ++i) {
- var child = children[i];
- if (!(child instanceof WebInspector.FrameTreeElement)) {
- parentTreeElement.insertChild(frameTreeElement, i);
- return;
- }
- if (child.displayName.localeCompare(frameTreeElement.displayName) > 0) {
- parentTreeElement.insertChild(frameTreeElement, i);
- return;
- }
- }
parentTreeElement.appendChild(frameTreeElement);
},
@@ -260,22 +246,7 @@ WebInspector.ResourcesPanel.prototype = {
return;
}
- var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this, resource);
-
- // Insert in the alphabetical order, first frames, then resources. Document resource goes first.
- var children = frameTreeElement.children;
- for (var i = 0; i < children.length; ++i) {
- var child = children[i];
- if (!(child instanceof WebInspector.FrameResourceTreeElement))
- continue;
-
- if (resource.type === WebInspector.Resource.Type.Document ||
- (child._resource.type !== WebInspector.Resource.Type.Document && child._resource.displayName.localeCompare(resource.displayName) > 0)) {
- frameTreeElement.insertChild(resourceTreeElement, i);
- return;
- }
- }
- frameTreeElement.appendChild(resourceTreeElement);
+ frameTreeElement.appendResource(resource);
},
_frameNavigated: function(event)
@@ -294,6 +265,11 @@ WebInspector.ResourcesPanel.prototype = {
frameTreeElement.removeChildren();
},
+ _cachedResourcesLoaded: function()
+ {
+ this._initDefaultSelection();
+ },
+
_refreshResource: function(event)
{
var resource = event.data;
@@ -365,23 +341,23 @@ WebInspector.ResourcesPanel.prototype = {
}
},
- canShowSourceLine: function(url, line)
+ canShowAnchorLocation: function(anchor)
{
- return !!WebInspector.resourceForURL(url);
+ return !!WebInspector.resourceForURL(anchor.href);
},
- showSourceLine: function(url, line)
+ showAnchorLocation: function(anchor)
{
- var resource = WebInspector.resourceForURL(url);
+ var resource = WebInspector.resourceForURL(anchor.href);
if (resource.type === WebInspector.Resource.Type.XHR) {
// Show XHRs in the network panel only.
- if (WebInspector.panels.network && WebInspector.panels.network.canShowSourceLine(url, line)) {
+ if (WebInspector.panels.network && WebInspector.panels.network.canShowAnchorLocation(anchor)) {
WebInspector.currentPanel = WebInspector.panels.network;
- WebInspector.panels.network.showSourceLine(url, line);
+ WebInspector.panels.network.showAnchorLocation(anchor);
}
return;
}
- this.showResource(WebInspector.resourceForURL(url), line);
+ this.showResource(resource, anchor.getAttribute("line_number") - 1);
},
showResource: function(resource, line)
@@ -392,10 +368,8 @@ WebInspector.ResourcesPanel.prototype = {
resourceTreeElement.select();
}
- if (line) {
+ if (line !== undefined) {
var view = WebInspector.ResourceView.resourceViewForResource(resource);
- if (view.revealLine)
- view.revealLine(line);
if (view.highlightLine)
view.highlightLine(line);
}
@@ -405,19 +379,40 @@ WebInspector.ResourcesPanel.prototype = {
_showResourceView: function(resource)
{
var view = WebInspector.ResourceView.resourceViewForResource(resource);
+ this._fetchAndApplyDiffMarkup(view, resource);
+ this._innerShowView(view);
+ },
- // Consider rendering diff markup here.
- if (resource.baseRevision && view instanceof WebInspector.SourceFrame) {
- function callback(baseContent)
- {
- if (baseContent)
- this._applyDiffMarkup(view, baseContent, resource.content);
- }
- resource.baseRevision.requestContent(callback.bind(this));
- }
+ _showRevisionView: function(revision)
+ {
+ if (!revision._view)
+ revision._view = new WebInspector.RevisionSourceFrame(revision);
+ var view = revision._view;
+ this._fetchAndApplyDiffMarkup(view, revision.resource, revision);
this._innerShowView(view);
},
+ _fetchAndApplyDiffMarkup: function(view, resource, revision)
+ {
+ var baseRevision = resource.history[0];
+ if (!baseRevision)
+ return;
+ if (!(view instanceof WebInspector.SourceFrame))
+ return;
+
+ baseRevision.requestContent(step1.bind(this));
+
+ function step1(baseContent)
+ {
+ (revision ? revision : resource).requestContent(step2.bind(this, baseContent));
+ }
+
+ function step2(baseContent, revisionContent)
+ {
+ this._applyDiffMarkup(view, baseContent, revisionContent);
+ }
+ },
+
_applyDiffMarkup: function(view, baseContent, newContent) {
var oldLines = baseContent.split(/\r?\n/);
var newLines = newContent.split(/\r?\n/);
@@ -695,7 +690,7 @@ WebInspector.ResourcesPanel.prototype = {
var views = [];
const visibleView = this.visibleView;
- if (visibleView.performSearch)
+ if (visibleView && visibleView.performSearch)
views.push(visibleView);
function callback(resourceTreeElement)
@@ -810,12 +805,13 @@ WebInspector.ResourcesPanel.prototype = {
WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
-WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren)
+WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon)
{
TreeElement.call(this, "", representedObject, hasChildren);
this._storagePanel = storagePanel;
this._titleText = title;
this._iconClasses = iconClasses;
+ this._noIcon = noIcon;
}
WebInspector.BaseStorageTreeElement.prototype = {
@@ -831,9 +827,11 @@ WebInspector.BaseStorageTreeElement.prototype = {
selectionElement.className = "selection";
this.listItemElement.appendChild(selectionElement);
- this.imageElement = document.createElement("img");
- this.imageElement.className = "icon";
- this.listItemElement.appendChild(this.imageElement);
+ if (!this._noIcon) {
+ this.imageElement = document.createElement("img");
+ this.imageElement.className = "icon";
+ this.listItemElement.appendChild(this.imageElement);
+ }
this.titleElement = document.createElement("div");
this.titleElement.className = "base-storage-tree-element-title";
@@ -879,9 +877,9 @@ WebInspector.BaseStorageTreeElement.prototype = {
WebInspector.BaseStorageTreeElement.prototype.__proto__ = TreeElement.prototype;
-WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses)
+WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
{
- WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, true);
+ WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, true, noIcon);
this._expandedSettingKey = "resources" + settingsKey + "Expanded";
WebInspector.settings.installApplicationSetting(this._expandedSettingKey, settingsKey === "Frames");
this._categoryName = categoryName;
@@ -923,6 +921,7 @@ WebInspector.FrameTreeElement = function(storagePanel, frameId, title, subtitle)
WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
this._frameId = frameId;
this.setTitles(title, subtitle);
+ this._categoryElements = {};
}
WebInspector.FrameTreeElement.prototype = {
@@ -957,15 +956,16 @@ WebInspector.FrameTreeElement.prototype = {
setTitles: function(title, subtitle)
{
- this._displayName = "";
+ this._displayName = title || "";
+ if (subtitle)
+ this._displayName += " (" + subtitle + ")";
+
if (this.parent) {
this.titleElement.textContent = title || "";
- this._displayName = title || "";
if (subtitle) {
var subtitleElement = document.createElement("span");
subtitleElement.className = "base-storage-tree-element-subtitle";
subtitleElement.textContent = "(" + subtitle + ")";
- this._displayName += " (" + subtitle + ")";
this.titleElement.appendChild(subtitleElement);
}
} else {
@@ -983,8 +983,67 @@ WebInspector.FrameTreeElement.prototype = {
this.listItemElement.removeStyleClass("hovered");
DOMAgent.hideFrameHighlight();
}
+ },
+
+ appendResource: function(resource)
+ {
+ var categoryName = resource.category.name;
+ var categoryElement = resource.category === WebInspector.resourceCategories.documents ? this : this._categoryElements[categoryName];
+ if (!categoryElement) {
+ categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.category.title, categoryName, null, true);
+ this._categoryElements[resource.category.name] = categoryElement;
+ this._insertInPresentationOrder(this, categoryElement);
+ }
+ var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
+ this._insertInPresentationOrder(categoryElement, resourceTreeElement);
+ resourceTreeElement._populateRevisions();
+ },
+
+ appendChild: function(treeElement)
+ {
+ this._insertInPresentationOrder(this, treeElement);
+ },
+
+ _insertInPresentationOrder: function(parentTreeElement, childTreeElement)
+ {
+ // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
+ function typeWeight(treeElement)
+ {
+ if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
+ return 2;
+ if (treeElement instanceof WebInspector.FrameTreeElement)
+ return 1;
+ return 3;
+ }
+
+ function compare(treeElement1, treeElement2)
+ {
+ var typeWeight1 = typeWeight(treeElement1);
+ var typeWeight2 = typeWeight(treeElement2);
+
+ var result;
+ if (typeWeight1 > typeWeight2)
+ result = 1;
+ else if (typeWeight1 < typeWeight2)
+ result = -1;
+ else {
+ var title1 = treeElement1.displayName || treeElement1.titleText;
+ var title2 = treeElement2.displayName || treeElement2.titleText;
+ result = title1.localeCompare(title2);
+ }
+ return result;
+ }
+
+ var children = parentTreeElement.children;
+ var i;
+ for (i = 0; i < children.length; ++i) {
+ if (compare(childTreeElement, children[i]) < 0)
+ break;
+ }
+ parentTreeElement.insertChild(childTreeElement, i);
}
}
+
WebInspector.FrameTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype;
WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
@@ -992,7 +1051,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._resource.addEventListener(WebInspector.Resource.Events.RevisionAdded, this._revisionAdded, this);
this.tooltip = resource.url;
}
@@ -1104,9 +1163,20 @@ WebInspector.FrameResourceTreeElement.prototype = {
this._bubbleElement.addStyleClass("error");
},
- _contentChanged: function(event)
+ _populateRevisions: function()
+ {
+ for (var i = 0; i < this._resource.history.length; ++i)
+ this._appendRevision(this._resource.history[i]);
+ },
+
+ _revisionAdded: function(event)
+ {
+ this._appendRevision(event.data);
+ },
+
+ _appendRevision: function(revision)
{
- this.insertChild(new WebInspector.ResourceRevisionTreeElement(this._storagePanel, event.data.revision), 0);
+ this.insertChild(new WebInspector.ResourceRevisionTreeElement(this._storagePanel, revision), 0);
var oldView = WebInspector.ResourceView.existingResourceViewForResource(this._resource);
if (oldView) {
var newView = WebInspector.ResourceView.recreateResourceView(this._resource);
@@ -1243,13 +1313,18 @@ WebInspector.ApplicationCacheTreeElement.prototype.__proto__ = WebInspector.Base
WebInspector.ResourceRevisionTreeElement = function(storagePanel, revision)
{
var title = revision.timestamp ? revision.timestamp.toLocaleTimeString() : WebInspector.UIString("(original)");
- WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["resource-sidebar-tree-item", "resources-category-" + revision.category.name]);
+ WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["resource-sidebar-tree-item", "resources-category-" + revision.resource.category.name]);
if (revision.timestamp)
this.tooltip = revision.timestamp.toLocaleString();
- this._resource = revision;
+ this._revision = revision;
}
WebInspector.ResourceRevisionTreeElement.prototype = {
+ get itemURL()
+ {
+ return this._revision.resource.url;
+ },
+
onattach: function()
{
WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
@@ -1261,20 +1336,22 @@ WebInspector.ResourceRevisionTreeElement.prototype = {
onselect: function()
{
WebInspector.BaseStorageTreeElement.prototype.onselect.call(this);
- this._storagePanel._showResourceView(this._resource);
+ this._storagePanel._showRevisionView(this._revision);
},
_ondragstart: function(event)
{
- event.dataTransfer.setData("text/plain", this._resource.content);
- event.dataTransfer.effectAllowed = "copy";
- return true;
+ if (this._revision.content) {
+ event.dataTransfer.setData("text/plain", this._revision.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.appendItem(WebInspector.UIString("Revert to this revision"), this._revision.revertToThis.bind(this._revision));
contextMenu.show(event);
}
}
diff --git a/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js b/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js
index bdbb0cf..b7f0dad 100644
--- a/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js
@@ -59,40 +59,45 @@ WebInspector.ScopeChainSidebarPane.prototype = {
var foundLocalScope = false;
var scopeChain = callFrame.scopeChain;
for (var i = 0; i < scopeChain.length; ++i) {
- var scopeObjectProxy = scopeChain[i];
+ var scope = scopeChain[i];
var title = null;
- var subtitle = scopeObjectProxy.description;
+ var subtitle = scope.object.description;
var emptyPlaceholder = null;
var extraProperties = null;
- if (scopeObjectProxy.isLocal) {
- foundLocalScope = true;
- title = WebInspector.UIString("Local");
- emptyPlaceholder = WebInspector.UIString("No Variables");
- subtitle = null;
- if (scopeObjectProxy.thisObject)
- extraProperties = [ new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(scopeObjectProxy.thisObject)) ];
- } else if (scopeObjectProxy.isClosure) {
- title = WebInspector.UIString("Closure");
- emptyPlaceholder = WebInspector.UIString("No Variables");
- subtitle = null;
- } else if (i === (scopeChain.length - 1))
- title = WebInspector.UIString("Global");
- else if (scopeObjectProxy.isElement)
- title = WebInspector.UIString("Event Target");
- else if (scopeObjectProxy.isDocument)
- title = WebInspector.UIString("Event Document");
- else if (scopeObjectProxy.isWithBlock)
- title = WebInspector.UIString("With Block");
+ switch (scope.type) {
+ case "local":
+ foundLocalScope = true;
+ title = WebInspector.UIString("Local");
+ emptyPlaceholder = WebInspector.UIString("No Variables");
+ subtitle = null;
+ if (scope.this)
+ extraProperties = [ new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(scope.this)) ];
+ break;
+ case "closure":
+ title = WebInspector.UIString("Closure");
+ emptyPlaceholder = WebInspector.UIString("No Variables");
+ subtitle = null;
+ break;
+ case "catch":
+ title = WebInspector.UIString("Catch");
+ break;
+ case "with":
+ title = WebInspector.UIString("With Block");
+ break;
+ case "global":
+ title = WebInspector.UIString("Global");
+ break;
+ }
if (!title || title === subtitle)
subtitle = null;
- var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scopeObjectProxy), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
+ var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scope.object), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
section.editInSelectedCallFrameWhenPaused = true;
section.pane = this;
- if (!foundLocalScope || scopeObjectProxy.isLocal || title in this._expandedSections)
+ if (!foundLocalScope || scope.type === "local" || title in this._expandedSections)
section.expanded = true;
this._sections.push(section);
diff --git a/Source/WebCore/inspector/front-end/Script.js b/Source/WebCore/inspector/front-end/Script.js
index 805e191..9e75d83 100644
--- a/Source/WebCore/inspector/front-end/Script.js
+++ b/Source/WebCore/inspector/front-end/Script.js
@@ -23,91 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Script = function(sourceID, sourceURL, source, lineOffset, columnOffset, length, errorLine, errorMessage, worldType)
+WebInspector.Script = function(sourceID, sourceURL, lineOffset, columnOffset, length, errorLine, errorMessage, isContentScript)
{
this.sourceID = sourceID;
this.sourceURL = sourceURL;
- this._source = source;
this.lineOffset = lineOffset;
this.columnOffset = columnOffset;
this.length = length;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
- this.worldType = worldType;
-
- // if no URL, look for "//@ sourceURL=" decorator
- // note that this sourceURL comment decorator is behavior that FireBug added
- // in it's 1.1 release as noted in the release notes:
- // http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
- if (!sourceURL) {
- // use of [ \t] rather than \s is to prevent \n from matching
- var pattern = /^\s*\/\/[ \t]*@[ \t]*sourceURL[ \t]*=[ \t]*(\S+).*$/m;
- var match = pattern.exec(source);
-
- if (match)
- this.sourceURL = match[1];
- }
-}
-
-WebInspector.Script.WorldType = {
- MAIN_WORLD: 0,
- EXTENSIONS_WORLD: 1
-}
-
-WebInspector.Script.WorldType = {
- MAIN_WORLD: 0,
- EXTENSIONS_WORLD: 1
+ this.isContentScript = isContentScript;
}
WebInspector.Script.prototype = {
- get startingLine()
- {
- return this.lineOffset + 1;
- },
-
- get linesCount()
- {
- if (!this.source)
- return 0;
- if (!this._lineEndings)
- this._lineEndings = this._source.findAll("\n");
- return this._lineEndings.length + 1;
- },
-
- sourceLine: function(lineNumber, callback)
- {
- function extractSourceLine()
- {
- lineNumber -= this.lineOffset;
- callback(this._source.substring(this._lineEndings[lineNumber - 1], this._lineEndings[lineNumber]));
- }
-
- if (this._lineEndings) {
- extractSourceLine.call(this);
- return;
- }
-
- function didRequestSource()
- {
- this._lineEndings = this._source.findAll("\n");
- extractSourceLine.call(this);
- }
- this.requestSource(didRequestSource.bind(this));
- },
-
- get source()
- {
- if (!this._source && this.resource)
- this._source = this.resource.content;
- return this._source;
- },
-
- set source(source)
- {
- this._source = source;
- delete this._lineEndings;
- },
-
requestSource: function(callback)
{
if (this._source) {
@@ -117,11 +45,20 @@ WebInspector.Script.prototype = {
function didGetScriptSource(error, source)
{
- if (error)
- return;
this._source = source;
callback(this._source);
}
DebuggerAgent.getScriptSource(this.sourceID, didGetScriptSource.bind(this));
+ },
+
+ editSource: function(newSource, callback)
+ {
+ function didEditScriptSource(error, callFrames)
+ {
+ if (!error)
+ this._source = newSource;
+ callback(error, callFrames);
+ }
+ DebuggerAgent.editScriptSource(this.sourceID, newSource, didEditScriptSource.bind(this));
}
}
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatter.js b/Source/WebCore/inspector/front-end/ScriptFormatter.js
index 2e166f4..8085c55 100644
--- a/Source/WebCore/inspector/front-end/ScriptFormatter.js
+++ b/Source/WebCore/inspector/front-end/ScriptFormatter.js
@@ -36,10 +36,15 @@ WebInspector.ScriptFormatter = function()
this._tasks = [];
}
-WebInspector.ScriptFormatter.locationToPosition = function(lineEndings, lineNumber, columnNumber)
+WebInspector.ScriptFormatter.locationToPosition = function(lineEndings, location)
{
- var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
- return position + columnNumber;
+ var position = location.lineNumber ? lineEndings[location.lineNumber - 1] + 1 : 0;
+ return position + location.columnNumber;
+}
+
+WebInspector.ScriptFormatter.lineToPosition = function(lineEndings, lineNumber)
+{
+ return this.locationToPosition(lineEndings, { lineNumber: lineNumber, columnNumber: 0 });
}
WebInspector.ScriptFormatter.positionToLocation = function(lineEndings, position)
@@ -58,7 +63,7 @@ WebInspector.ScriptFormatter.findScriptRanges = function(lineEndings, scripts)
var scriptRanges = [];
for (var i = 0; i < scripts.length; ++i) {
var start = { lineNumber: scripts[i].lineOffset, columnNumber: scripts[i].columnOffset };
- start.position = WebInspector.ScriptFormatter.locationToPosition(lineEndings, start.lineNumber, start.columnNumber);
+ start.position = WebInspector.ScriptFormatter.locationToPosition(lineEndings, start);
var endPosition = start.position + scripts[i].length;
var end = WebInspector.ScriptFormatter.positionToLocation(lineEndings, endPosition);
end.position = endPosition;
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
index 1a4c28e..ab68524 100644
--- a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
+++ b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
@@ -28,9 +28,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-var parse = loadModule("parse-js.js");
-var process = loadModule("process.js");
-
onmessage = function(event) {
var source = event.data;
var formattedSource = beautify(source);
@@ -53,34 +50,31 @@ function beautify(source)
function buildMapping(source, formattedSource)
{
var mapping = { original: [], formatted: [] };
- var lastCodePosition = 0;
- var regexp = /[\$\.\w]+|{|}/g;
+ var lastPosition = 0;
+ var regexp = /(^|[^\\])\b((?=\D)[\$\.\w]+)\b/g;
while (true) {
var match = regexp.exec(formattedSource);
if (!match)
break;
- var position = source.indexOf(match[0], lastCodePosition);
+ var position = source.indexOf(match[2], lastPosition);
if (position === -1)
- continue;
+ throw "No match found in original source for " + match[2];
mapping.original.push(position);
- mapping.formatted.push(match.index);
- lastCodePosition = position + match[0].length;
+ mapping.formatted.push(match.index + match[1].length);
+ lastPosition = position + match[2].length;
}
return mapping;
}
-function loadModule(src)
-{
- var request = new XMLHttpRequest();
- request.open("GET", src, false);
- request.send();
-
- var exports = {};
- eval(request.responseText);
- return exports;
-}
-
function require()
{
return parse;
}
+
+var exports = {};
+importScripts("UglifyJS/parse-js.js");
+var parse = exports;
+
+var exports = {};
+importScripts("UglifyJS/process.js");
+var process = exports;
diff --git a/Source/WebCore/inspector/front-end/ScriptsPanel.js b/Source/WebCore/inspector/front-end/ScriptsPanel.js
index 7547c36..8a6c58e 100644
--- a/Source/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/Source/WebCore/inspector/front-end/ScriptsPanel.js
@@ -65,15 +65,6 @@ WebInspector.ScriptsPanel = function()
// FIXME: append the functions select element to the top status bar when it is implemented.
// this.topStatusBar.appendChild(this.functionsSelectElement);
- this.formatButton = document.createElement("button");
- this.formatButton.className = "status-bar-item";
- this.formatButton.id = "format-script";
- this.formatButton.title = WebInspector.UIString("Format script.");
- this.formatButton.appendChild(document.createElement("img"));
- this.formatButton.addEventListener("click", this._toggleFormatSourceFiles.bind(this), false);
- if (Preferences.debugMode)
- this.topStatusBar.appendChild(this.formatButton);
-
this.sidebarButtonsElement = document.createElement("div");
this.sidebarButtonsElement.id = "scripts-sidebar-buttons";
this.topStatusBar.appendChild(this.sidebarButtonsElement);
@@ -142,9 +133,9 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(this._presentationModel);
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
- this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(this._presentationModel);
+ this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(this._presentationModel, this._showSourceLine.bind(this));
if (Preferences.nativeInstrumentationEnabled) {
- this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
+ this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane;
this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
}
@@ -204,11 +195,17 @@ WebInspector.ScriptsPanel = function()
// Keep these in sync with WebCore::ScriptDebugServer
WebInspector.ScriptsPanel.PauseOnExceptionsState = {
- DontPauseOnExceptions : 0,
- PauseOnAllExceptions : 1,
- PauseOnUncaughtExceptions: 2
+ DontPauseOnExceptions : "none",
+ PauseOnAllExceptions : "all",
+ PauseOnUncaughtExceptions: "uncaught"
};
+WebInspector.ScriptsPanel.BrowserBreakpointTypes = {
+ DOM: "DOM",
+ EventListener: "EventListener",
+ XHR: "XHR"
+}
+
WebInspector.ScriptsPanel.prototype = {
get toolbarItemLabel()
{
@@ -234,6 +231,8 @@ WebInspector.ScriptsPanel.prototype = {
{
WebInspector.Panel.prototype.show.call(this);
this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth - 3) + "px";
+ if (Preferences.nativeInstrumentationEnabled)
+ this.sidebarElement.insertBefore(this.sidebarPanes.domBreakpoints.element, this.sidebarPanes.xhrBreakpoints.element);
if (this.visibleView)
this.visibleView.show(this.viewsContainerElement);
@@ -280,7 +279,7 @@ WebInspector.ScriptsPanel.prototype = {
var select = this._filesSelectElement;
var option = document.createElement("option");
option.text = sourceFile.url ? WebInspector.displayNameForURL(sourceFile.url) : WebInspector.UIString("(program)");
- if (sourceFile.isExtensionScript)
+ if (sourceFile.isContentScript)
option.addStyleClass("extension-script");
function optionCompare(a, b)
{
@@ -375,29 +374,33 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.callstack.update(callFrames, details);
this.sidebarPanes.callstack.selectedCallFrame = this._presentationModel.selectedCallFrame;
- var status;
if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
- if (details.eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.EventListener) {
+ if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.DOM) {
+ this.sidebarPanes.domBreakpoints.highlightBreakpoint(details.eventData);
+ function didCreateBreakpointHitStatusMessage(element)
+ {
+ this.sidebarPanes.callstack.setStatus(element);
+ }
+ this.sidebarPanes.domBreakpoints.createBreakpointHitStatusMessage(details.eventData, didCreateBreakpointHitStatusMessage.bind(this));
+ } else if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.EventListener) {
var eventName = details.eventData.eventName;
this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.eventData.eventName);
var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
- status = WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI);
- } else if (details.eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.XHR) {
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
+ } else if (details.eventData.breakpointType === WebInspector.ScriptsPanel.BrowserBreakpointTypes.XHR) {
this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.eventData.breakpointURL);
- status = WebInspector.UIString("Paused on a XMLHttpRequest.");
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
}
} else {
- function didGetSourceLocation(sourceFileId, lineNumber, columnNumber)
+ function didGetSourceLocation(sourceFileId, lineNumber)
{
if (!sourceFileId || !this._presentationModel.findBreakpoint(sourceFileId, lineNumber))
return;
this.sidebarPanes.jsBreakpoints.highlightBreakpoint(sourceFileId, lineNumber);
- status = WebInspector.UIString("Paused on a JavaScript breakpoint.");
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
}
- callFrames[0].sourceLocation(didGetSourceLocation.bind(this));
+ callFrames[0].sourceLine(didGetSourceLocation.bind(this));
}
- if (status)
- this.sidebarPanes.callstack.setStatus(status);
window.focus();
InspectorFrontendHost.bringToFront();
@@ -414,7 +417,7 @@ WebInspector.ScriptsPanel.prototype = {
_debuggerWasEnabled: function()
{
- this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionState);
+ this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString);
if (this._debuggerEnabled)
return;
@@ -478,17 +481,26 @@ WebInspector.ScriptsPanel.prototype = {
x.show(this.viewsContainerElement);
},
- canShowSourceLine: function(url, line)
+ canShowAnchorLocation: function(anchor)
{
- return this._debuggerEnabled && (url in this._sourceFileIdToFilesSelectOption);
+ return this._debuggerEnabled && this._presentationModel.sourceFileForScriptURL(anchor.href);
},
- showSourceLine: function(url, line)
+ showAnchorLocation: function(anchor)
{
- if (!(url in this._sourceFileIdToFilesSelectOption))
- return;
- var sourceFrame = this._showSourceFrameAndAddToHistory(url);
- sourceFrame.highlightLine(line);
+ function didRequestSourceMapping(mapping)
+ {
+ var lineNumber = mapping.scriptLocationToSourceLine({lineNumber:anchor.getAttribute("line_number") - 1, columnNumber:0});
+ this._showSourceLine(sourceFile.id, lineNumber);
+ }
+ var sourceFile = this._presentationModel.sourceFileForScriptURL(anchor.href);
+ sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
+ },
+
+ _showSourceLine: function(sourceFileId, lineNumber)
+ {
+ var sourceFrame = this._showSourceFrameAndAddToHistory(sourceFileId);
+ sourceFrame.highlightLine(lineNumber);
},
handleShortcut: function(event)
@@ -612,7 +624,7 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.watchExpressions.refreshExpressions();
this.sidebarPanes.callstack.selectedCallFrame = this._presentationModel.selectedCallFrame;
- function didGetSourceLocation(sourceFileId, lineNumber, columnNumber)
+ function didGetSourceLocation(sourceFileId, lineNumber)
{
if (!sourceFileId)
return;
@@ -625,7 +637,7 @@ WebInspector.ScriptsPanel.prototype = {
sourceFrame.setExecutionLine(lineNumber);
this._executionSourceFrame = sourceFrame;
}
- callFrame.sourceLocation(didGetSourceLocation.bind(this));
+ callFrame.sourceLine(didGetSourceLocation.bind(this));
},
_filesSelectChanged: function()
@@ -672,6 +684,7 @@ WebInspector.ScriptsPanel.prototype = {
_setPauseOnExceptions: function(pauseOnExceptionsState)
{
+ pauseOnExceptionsState = pauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions;
function callback(error)
{
if (error)
@@ -684,9 +697,9 @@ WebInspector.ScriptsPanel.prototype = {
this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
this._pauseOnExceptionButton.state = pauseOnExceptionsState;
- WebInspector.settings.pauseOnExceptionState = pauseOnExceptionsState;
+ WebInspector.settings.pauseOnExceptionStateString = pauseOnExceptionsState;
}
- DebuggerAgent.setPauseOnExceptionsState(pauseOnExceptionsState, callback.bind(this));
+ DebuggerAgent.setPauseOnExceptions(pauseOnExceptionsState, callback.bind(this));
},
_updateDebuggerButtons: function()
@@ -741,6 +754,7 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.scopechain.update(null);
this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
if (Preferences.nativeInstrumentationEnabled) {
+ this.sidebarPanes.domBreakpoints.clearBreakpointHighlight();
this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
}
@@ -771,12 +785,6 @@ WebInspector.ScriptsPanel.prototype = {
this._updateBackAndForwardButtons();
},
- _toggleFormatSourceFiles: function()
- {
- this.reset();
- this._presentationModel.toggleFormatSourceFiles();
- },
-
_enableDebugging: function()
{
if (this._debuggerEnabled)
@@ -801,7 +809,12 @@ WebInspector.ScriptsPanel.prototype = {
_togglePauseOnExceptions: function()
{
- this._setPauseOnExceptions((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states);
+ var nextStateMap = {};
+ var stateEnum = WebInspector.ScriptsPanel.PauseOnExceptionsState;
+ nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
+ nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
+ nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
+ this._setPauseOnExceptions(nextStateMap[this._pauseOnExceptionButton.state]);
},
_togglePause: function()
@@ -1008,11 +1021,7 @@ WebInspector.SourceFrameDelegateForScriptsPanel = function(model, sourceFileId)
WebInspector.SourceFrameDelegateForScriptsPanel.prototype = {
requestContent: function(callback)
{
- function didRequestSourceFileContent(mimeType, text)
- {
- callback(mimeType, { text: text });
- }
- this._model.requestSourceFileContent(this._sourceFileId, didRequestSourceFileContent.bind(this));
+ this._model.requestSourceFileContent(this._sourceFileId, callback);
},
debuggingSupported: function()
@@ -1076,6 +1085,17 @@ WebInspector.SourceFrameDelegateForScriptsPanel.prototype = {
releaseEvaluationResult: function()
{
RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
+ },
+
+ toggleFormatSourceFiles: function()
+ {
+ WebInspector.panels.scripts.reset();
+ this._model.toggleFormatSourceFiles();
+ },
+
+ formatSourceFilesToggled: function()
+ {
+ return this._model.formatSourceFilesToggled();
}
}
diff --git a/Source/WebCore/inspector/front-end/SearchController.js b/Source/WebCore/inspector/front-end/SearchController.js
index 735c424..d0f9cb4 100755
--- a/Source/WebCore/inspector/front-end/SearchController.js
+++ b/Source/WebCore/inspector/front-end/SearchController.js
@@ -84,7 +84,7 @@ WebInspector.SearchController.prototype = {
var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey;
if (isFindKey) {
- this._focusSearchField();
+ this.focusSearchField();
event.handled = true;
}
break;
@@ -92,7 +92,7 @@ WebInspector.SearchController.prototype = {
case "F3":
if (!isMac) {
- this._focusSearchField();
+ this.focusSearchField();
event.handled = true;
}
break;
@@ -157,7 +157,7 @@ WebInspector.SearchController.prototype = {
WebInspector.toolbar.resize();
},
- _focusSearchField: function()
+ focusSearchField: function()
{
this.element.focus();
this.element.select();
diff --git a/Source/WebCore/inspector/front-end/Settings.js b/Source/WebCore/inspector/front-end/Settings.js
index 9995ca2..856153a 100644
--- a/Source/WebCore/inspector/front-end/Settings.js
+++ b/Source/WebCore/inspector/front-end/Settings.js
@@ -72,13 +72,8 @@ WebInspector.Settings = function()
this.installApplicationSetting("watchExpressions", []);
this.installApplicationSetting("breakpoints", []);
this.installApplicationSetting("eventListenerBreakpoints", []);
+ this.installApplicationSetting("domBreakpoints", []);
this.installApplicationSetting("xhrBreakpoints", []);
-
- this.installProjectSetting("nativeBreakpoints", []);
-}
-
-WebInspector.Settings.Events = {
- ProjectChanged: "project-changed"
}
WebInspector.Settings.prototype = {
@@ -91,47 +86,6 @@ WebInspector.Settings.prototype = {
this.__defineSetter__(key, this._set.bind(this, key));
},
- installProjectSetting: function(key, defaultValue)
- {
- this.__defineGetter__(key, this._getProjectSetting.bind(this, key, defaultValue));
- this.__defineSetter__(key, this._setProjectSetting.bind(this, key));
- },
-
- inspectedURLChanged: function(url)
- {
- var fragmentIndex = url.indexOf("#");
- if (fragmentIndex !== -1)
- url = url.substring(0, fragmentIndex);
- this._projectId = url;
- this.dispatchEventToListeners(WebInspector.Settings.Events.ProjectChanged);
- },
-
- get projectId()
- {
- return this._projectId;
- },
-
- findSettingForAllProjects: function(key)
- {
- var result = {};
- if (window.localStorage == null)
- return result;
-
- var regexp = "^" + key + ":(.*)";
- for (var i = 0; i < window.localStorage.length; ++i) {
- var fullKey = window.localStorage.key(i);
- var match = fullKey.match(regexp);
- if (!match)
- continue;
- try {
- result[match[1]] = JSON.parse(window.localStorage[fullKey]);
- } catch(e) {
- window.localStorage.removeItem(fullKey);
- }
- }
- return result;
- },
-
_get: function(key, defaultValue)
{
if (window.localStorage != null && key in window.localStorage) {
@@ -148,21 +102,6 @@ WebInspector.Settings.prototype = {
{
if (window.localStorage != null)
window.localStorage[key] = JSON.stringify(value);
- },
-
- _getProjectSetting: function(key, defaultValue)
- {
- return this._get(this._formatProjectKey(key), defaultValue);
- },
-
- _setProjectSetting: function(key, value)
- {
- return this._set(this._formatProjectKey(key), value);
- },
-
- _formatProjectKey: function(key)
- {
- return key + ":" + this._projectId;
}
}
diff --git a/Source/WebCore/inspector/front-end/SourceFile.js b/Source/WebCore/inspector/front-end/SourceFile.js
index 4f56c00..c58a0c7 100644
--- a/Source/WebCore/inspector/front-end/SourceFile.js
+++ b/Source/WebCore/inspector/front-end/SourceFile.js
@@ -38,7 +38,7 @@ WebInspector.SourceFile = function(id, script, contentChangedDelegate)
this.id = id;
this.url = script.sourceURL;
- this.isExtensionScript = script.worldType === WebInspector.Script.WorldType.EXTENSIONS_WORLD;
+ this.isContentScript = script.isContentScript;
this.messages = [];
this.breakpoints = {};
@@ -68,6 +68,12 @@ WebInspector.SourceFile.prototype = {
return this._content;
},
+ set content(content)
+ {
+ // FIXME: move live edit implementation to SourceFile and remove this setter.
+ this._content = content;
+ },
+
requestSourceMapping: function(callback)
{
if (!this._mapping)
@@ -126,6 +132,11 @@ WebInspector.SourceFile.prototype = {
{
function didRequestContent(text)
{
+ if (!text) {
+ this._loadAndConcatenateScriptsContent();
+ return;
+ }
+
if (resource.type === WebInspector.Resource.Type.Script)
this._didRequestContent("text/javascript", text);
else {
@@ -150,7 +161,11 @@ WebInspector.SourceFile.prototype = {
function didRequestSource(source)
{
sources.push(source);
- if (sources.length === scripts.length)
+ if (sources.length < scripts.length)
+ return;
+ if (scripts.length === 1 && !scripts[0].lineOffset && !scripts[0].columnOffset)
+ this._didRequestContent("text/javascript", source);
+ else
this._concatenateScriptsContent(scripts, sources);
}
for (var i = 0; i < scripts.length; ++i)
@@ -248,18 +263,24 @@ WebInspector.FormattedSourceFile.prototype = {
WebInspector.FormattedSourceFile.prototype.__proto__ = WebInspector.SourceFile.prototype;
-WebInspector.SourceMapping = function(sortedScripts)
+WebInspector.SourceMapping = function(scripts)
{
- this._sortedScripts = sortedScripts;
+ this._sortedScripts = scripts.slice();
+ this._sortedScripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });
}
WebInspector.SourceMapping.prototype = {
- scriptLocationToSourceLocation: function(lineNumber, columnNumber)
+ scriptLocationToSourceLine: function(location)
{
- return { lineNumber: lineNumber, columnNumber: columnNumber };
+ return location.lineNumber;
},
- sourceLocationToScriptLocation: function(lineNumber, columnNumber)
+ sourceLineToScriptLocation: function(lineNumber)
+ {
+ return this._sourceLocationToScriptLocation(lineNumber, 0);
+ },
+
+ _sourceLocationToScriptLocation: function(lineNumber, columnNumber)
{
var closestScript = this._sortedScripts[0];
for (var i = 1; i < this._sortedScripts.length; ++i) {
@@ -268,43 +289,34 @@ WebInspector.SourceMapping.prototype = {
break;
closestScript = script;
}
- return { scriptId: closestScript.sourceID, lineNumber: lineNumber, columnNumber: columnNumber };
+ return { sourceID: closestScript.sourceID, lineNumber: lineNumber, columnNumber: columnNumber };
}
}
-WebInspector.FormattedSourceMapping = function(sortedScripts, originalText, formattedText, mapping)
+WebInspector.FormattedSourceMapping = function(scripts, originalText, formattedText, mapping)
{
- WebInspector.SourceMapping.call(this, sortedScripts);
+ WebInspector.SourceMapping.call(this, scripts);
this._originalLineEndings = originalText.lineEndings();
this._formattedLineEndings = formattedText.lineEndings();
this._mapping = mapping;
}
WebInspector.FormattedSourceMapping.prototype = {
- scriptLocationToSourceLocation: function(lineNumber, columnNumber)
+ scriptLocationToSourceLine: function(location)
{
- var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber);
- var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition);
- return WebInspector.ScriptFormatter.positionToLocation(this._formattedLineEndings, formattedPosition);
+ var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, location);
+ var index = this._mapping.original.upperBound(originalPosition - 1);
+ var formattedPosition = this._mapping.formatted[index];
+ return WebInspector.ScriptFormatter.positionToLocation(this._formattedLineEndings, formattedPosition).lineNumber;
},
- sourceLocationToScriptLocation: function(lineNumber, columnNumber)
+ sourceLineToScriptLocation: function(lineNumber)
{
- var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber);
- var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
+ var formattedPosition = WebInspector.ScriptFormatter.lineToPosition(this._formattedLineEndings, lineNumber);
+ var index = this._mapping.formatted.upperBound(formattedPosition - 1);
+ var originalPosition = this._mapping.original[index];
var originalLocation = WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, originalPosition);
- return WebInspector.SourceMapping.prototype.sourceLocationToScriptLocation.call(this, originalLocation.lineNumber, originalLocation.columnNumber);
- },
-
- _convertPosition: function(positions1, positions2, position)
- {
- var index = positions1.upperBound(position);
- var range1 = positions1[index] - positions1[index - 1];
- var range2 = positions2[index] - positions2[index - 1];
- var position2 = positions2[index - 1];
- if (range1)
- position2 += Math.round((position - positions1[index - 1]) * range2 / range1);
- return position2;
+ return WebInspector.SourceMapping.prototype._sourceLocationToScriptLocation.call(this, originalLocation.lineNumber, originalLocation.columnNumber);
}
}
diff --git a/Source/WebCore/inspector/front-end/SourceFrame.js b/Source/WebCore/inspector/front-end/SourceFrame.js
index 7482f34..fda3e0c 100644
--- a/Source/WebCore/inspector/front-end/SourceFrame.js
+++ b/Source/WebCore/inspector/front-end/SourceFrame.js
@@ -30,9 +30,7 @@
WebInspector.SourceFrame = function(delegate, url)
{
- WebInspector.View.call(this);
-
- this.element.addStyleClass("script-view");
+ WebInspector.TextViewerDelegate.call(this);
this._delegate = delegate;
this._url = url;
@@ -40,6 +38,10 @@ WebInspector.SourceFrame = function(delegate, url)
this._textModel = new WebInspector.TextEditorModel();
this._textModel.replaceTabsWithSpaces = true;
+ this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url, this);
+ this._textViewer.element.addStyleClass("script-view");
+ this._visible = false;
+
this._currentSearchResultIndex = -1;
this._searchResults = [];
@@ -47,8 +49,7 @@ WebInspector.SourceFrame = function(delegate, url)
this._rowMessages = {};
this._messageBubbles = {};
- this._registerShortcuts();
- this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
+ this._breakpoints = {};
}
WebInspector.SourceFrame.Events = {
@@ -56,39 +57,54 @@ WebInspector.SourceFrame.Events = {
}
WebInspector.SourceFrame.prototype = {
+ get visible()
+ {
+ return this._textViewer.visible;
+ },
+
+ set visible(x)
+ {
+ this._textViewer.visible = x;
+ },
show: function(parentElement)
{
- WebInspector.View.prototype.show.call(this, parentElement);
+ this._ensureContentLoaded();
- if (!this._contentRequested) {
- this._contentRequested = true;
- this._delegate.requestContent(this._createTextViewer.bind(this));
- }
+ this._textViewer.show(parentElement);
+ this._textViewer.resize();
- if (this._textViewer) {
+ if (this.loaded) {
if (this._scrollTop)
this._textViewer.scrollTop = this._scrollTop;
if (this._scrollLeft)
this._textViewer.scrollLeft = this._scrollLeft;
- this._textViewer.resize();
}
},
hide: function()
{
- if (this._textViewer) {
+ if (this.loaded) {
this._scrollTop = this._textViewer.scrollTop;
this._scrollLeft = this._textViewer.scrollLeft;
this._textViewer.freeCachedElements();
}
- WebInspector.View.prototype.hide.call(this);
-
+ this._textViewer.hide();
this._hidePopup();
this._clearLineHighlight();
},
+ detach: function()
+ {
+ this._textViewer.detach();
+ },
+
+ get element()
+ {
+ return this._textViewer.element;
+ },
+
get loaded()
{
return !!this._content;
@@ -99,28 +115,33 @@ WebInspector.SourceFrame.prototype = {
return true;
},
+ _ensureContentLoaded: function()
+ {
+ if (!this._contentRequested) {
+ this._contentRequested = true;
+ this.requestContent(this._initializeTextViewer.bind(this));
+ }
+ },
+
+ requestContent: function(callback)
+ {
+ this._delegate.requestContent(callback);
+ },
+
markDiff: function(diffData)
{
- if (this._diffLines && this._textViewer)
+ if (this._diffLines && this.loaded)
this._removeDiffDecorations();
this._diffLines = diffData;
- if (this._textViewer)
+ if (this.loaded)
this._updateDiffDecorations();
},
- revealLine: function(lineNumber)
- {
- if (this._textViewer)
- this._textViewer.revealLine(lineNumber - 1, 0);
- else
- this._lineNumberToReveal = lineNumber;
- },
-
addMessage: function(msg)
{
this._messages.push(msg);
- if (this._textViewer)
+ if (this.loaded)
this.addMessageToSource(msg.line - 1, msg);
},
@@ -134,8 +155,8 @@ WebInspector.SourceFrame.prototype = {
this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
- if (this._textViewer)
- this._textViewer.resize();
+
+ this._textViewer.resize();
},
get textModel()
@@ -145,36 +166,87 @@ WebInspector.SourceFrame.prototype = {
get scrollTop()
{
- return this._textViewer ? this._textViewer.scrollTop : this._scrollTop;
+ return this.loaded ? this._textViewer.scrollTop : this._scrollTop;
},
set scrollTop(scrollTop)
{
this._scrollTop = scrollTop;
- if (this._textViewer)
+ if (this.loaded)
this._textViewer.scrollTop = scrollTop;
},
highlightLine: function(line)
{
- if (this._textViewer)
- this._textViewer.highlightLine(line - 1);
+ if (this.loaded)
+ this._textViewer.highlightLine(line);
else
this._lineToHighlight = line;
},
_clearLineHighlight: function()
{
- if (this._textViewer)
+ if (this.loaded)
this._textViewer.clearLineHighlight();
else
delete this._lineToHighlight;
},
- _startEditing: function()
+ _saveViewerState: function()
{
- if (this._originalTextModelContent === undefined) {
- this._originalTextModelContent = this._textModel.text;
+ this._viewerState = {
+ textModelContent: this._textModel.text,
+ executionLineNumber: this._executionLineNumber,
+ messages: this._messages,
+ diffLines: this._diffLines,
+ breakpoints: this._breakpoints
+ };
+ },
+
+ _restoreViewerState: function()
+ {
+ if (!this._viewerState)
+ return;
+ this._textModel.setText(null, this._viewerState.textModelContent);
+
+ this._messages = this._viewerState.messages;
+ this._diffLines = this._viewerState.diffLines;
+ this._setTextViewerDecorations();
+
+ if (typeof this._viewerState.executionLineNumber === "number") {
+ this.clearExecutionLine();
+ this.setExecutionLine(this._viewerState.executionLineNumber);
+ }
+
+ var oldBreakpoints = this._breakpoints;
+ this._breakpoints = {};
+ for (var lineNumber in oldBreakpoints)
+ this.removeBreakpoint(Number(lineNumber));
+
+ var newBreakpoints = this._viewerState.breakpoints;
+ for (var lineNumber in newBreakpoints) {
+ lineNumber = Number(lineNumber);
+ var breakpoint = newBreakpoints[lineNumber];
+ this.addBreakpoint(lineNumber, breakpoint.resolved, breakpoint.conditional, breakpoint.enabled);
+ }
+
+ delete this._viewerState;
+ },
+
+ isContentEditable: function()
+ {
+ return this._delegate.canEditScriptSource();
+ },
+
+ readOnlyStateChanged: function(readOnly)
+ {
+ WebInspector.markBeingEdited(this._textViewer.element, !readOnly);
+ },
+
+ startEditing: function()
+ {
+ if (!this._viewerState) {
+ this._saveViewerState();
this._delegate.setScriptSourceIsBeingEdited(true);
}
@@ -182,19 +254,61 @@ WebInspector.SourceFrame.prototype = {
this.clearMessages();
},
- _endEditing: function(oldRange, newRange)
+ endEditing: function(oldRange, newRange)
{
- // FIXME: Implement this.
+ if (!oldRange || !newRange)
+ return;
+
+ // Adjust execution line number.
+ if (typeof this._executionLineNumber === "number") {
+ var newExecutionLineNumber = this._lineNumberAfterEditing(this._executionLineNumber, oldRange, newRange);
+ this.clearExecutionLine();
+ this.setExecutionLine(newExecutionLineNumber, true);
+ }
+
+ // Adjust breakpoints.
+ var oldBreakpoints = this._breakpoints;
+ this._breakpoints = {};
+ for (var lineNumber in oldBreakpoints) {
+ lineNumber = Number(lineNumber);
+ var breakpoint = oldBreakpoints[lineNumber];
+ var newLineNumber = this._lineNumberAfterEditing(lineNumber, oldRange, newRange);
+ if (lineNumber === newLineNumber)
+ this._breakpoints[lineNumber] = breakpoint;
+ else {
+ this.removeBreakpoint(lineNumber);
+ this.addBreakpoint(newLineNumber, breakpoint.resolved, breakpoint.conditional, breakpoint.enabled);
+ }
+ }
},
- _createTextViewer: function(mimeType, content)
+ _lineNumberAfterEditing: function(lineNumber, oldRange, newRange)
{
- this._content = content;
- this._textModel.setText(null, content.text);
+ var shiftOffset = lineNumber <= oldRange.startLine ? 0 : newRange.linesCount - oldRange.linesCount;
+
+ // Special case of editing the line itself. We should decide whether the line number should move below or not.
+ if (lineNumber === oldRange.startLine) {
+ var whiteSpacesRegex = /^[\s\xA0]*$/;
+ for (var i = 0; lineNumber + i <= newRange.endLine; ++i) {
+ if (!whiteSpacesRegex.test(this._textModel.line(lineNumber + i))) {
+ shiftOffset = i;
+ break;
+ }
+ }
+ }
- this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
- this._textViewer.startEditingListener = this._startEditing.bind(this);
- this._textViewer.endEditingListener = this._endEditing.bind(this);
+ var newLineNumber = Math.max(0, lineNumber + shiftOffset);
+ if (oldRange.startLine < lineNumber && lineNumber < oldRange.endLine)
+ newLineNumber = oldRange.startLine;
+ return newLineNumber;
+ },
+
+ _initializeTextViewer: function(mimeType, content)
+ {
+ this._textViewer.mimeType = mimeType;
+
+ this._content = content;
+ this._textModel.setText(null, content);
var element = this._textViewer.element;
if (this._delegate.debuggingSupported()) {
@@ -204,24 +318,13 @@ WebInspector.SourceFrame.prototype = {
element.addEventListener("scroll", this._scroll.bind(this), true);
}
- if (this._delegate.canEditScriptSource())
- element.addEventListener("dblclick", this._doubleClick.bind(this), true);
-
- this.element.appendChild(element);
-
this._textViewer.beginUpdates();
- this._textViewer.mimeType = mimeType;
this._setTextViewerDecorations();
- if ("_executionLineNumber" in this)
+ if (typeof this._executionLineNumber === "number")
this.setExecutionLine(this._executionLineNumber);
- if (this._lineNumberToReveal) {
- this.revealLine(this._lineNumberToReveal);
- delete this._lineNumberToReveal;
- }
-
if (this._lineToHighlight) {
this.highlightLine(this._lineToHighlight);
delete this._lineToHighlight;
@@ -235,6 +338,9 @@ WebInspector.SourceFrame.prototype = {
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.Loaded);
this._textViewer.endUpdates();
+
+ if (this._parentElement)
+ this.show(this._parentElement)
},
_setTextViewerDecorations: function()
@@ -277,17 +383,18 @@ WebInspector.SourceFrame.prototype = {
callback(this, this._searchResults.length);
}
- if (this._textViewer)
+ if (this.loaded)
doFindSearchMatches.call(this, query);
else
this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);
+ this._ensureContentLoaded();
},
searchCanceled: function()
{
delete this._delayedFindSearchMatches;
- if (!this._textViewer)
+ if (!this.loaded)
return;
this._currentSearchResultIndex = -1;
@@ -327,7 +434,7 @@ WebInspector.SourceFrame.prototype = {
_jumpToSearchResult: function(index)
{
- if (!this._textViewer || !this._searchResults.length)
+ if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
this._textViewer.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
@@ -365,18 +472,19 @@ WebInspector.SourceFrame.prototype = {
msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
},
- setExecutionLine: function(lineNumber)
+ setExecutionLine: function(lineNumber, skipRevealLine)
{
this._executionLineNumber = lineNumber;
- if (this._textViewer) {
+ if (this.loaded) {
this._textViewer.addDecoration(lineNumber, "webkit-execution-line");
- this._textViewer.revealLine(lineNumber);
+ if (!skipRevealLine)
+ this._textViewer.revealLine(lineNumber);
}
},
clearExecutionLine: function()
{
- if (this._textViewer)
+ if (this.loaded)
this._textViewer.removeDecoration(this._executionLineNumber, "webkit-execution-line");
delete this._executionLineNumber;
},
@@ -418,7 +526,9 @@ WebInspector.SourceFrame.prototype = {
addMessageToSource: function(lineNumber, msg)
{
if (lineNumber >= this._textModel.linesCount)
- return;
+ lineNumber = this._textModel.linesCount - 1;
+ if (lineNumber < 0)
+ lineNumber = 0;
var messageBubbleElement = this._messageBubbles[lineNumber];
if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
@@ -471,6 +581,11 @@ WebInspector.SourceFrame.prototype = {
addBreakpoint: function(lineNumber, resolved, conditional, enabled)
{
+ this._breakpoints[lineNumber] = {
+ resolved: resolved,
+ conditional: conditional,
+ enabled: enabled
+ };
this._textViewer.beginUpdates();
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
if (!enabled)
@@ -482,6 +597,7 @@ WebInspector.SourceFrame.prototype = {
removeBreakpoint: function(lineNumber)
{
+ delete this._breakpoints[lineNumber];
this._textViewer.beginUpdates();
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
@@ -491,13 +607,17 @@ WebInspector.SourceFrame.prototype = {
_contextMenu: function(event)
{
- var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
- if (!target)
- return;
- var lineNumber = target.lineNumber;
-
var contextMenu = new WebInspector.ContextMenu();
+ var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
+ if (target)
+ this._populateLineGutterContextMenu(target.lineNumber, contextMenu);
+ else
+ this._populateTextAreaContextMenu(contextMenu);
+ contextMenu.show(event);
+ },
+ _populateLineGutterContextMenu: function(lineNumber, contextMenu)
+ {
contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._delegate.continueToLine.bind(this._delegate, lineNumber));
var breakpoint = this._delegate.findBreakpoint(lineNumber);
@@ -539,7 +659,11 @@ WebInspector.SourceFrame.prototype = {
else
contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), setBreakpointEnabled.bind(this, true));
}
- contextMenu.show(event);
+ },
+
+ _populateTextAreaContextMenu: function(contextMenu)
+ {
+ contextMenu.appendCheckboxItem(WebInspector.UIString("De-obfuscate Source"), this._delegate.toggleFormatSourceFiles.bind(this._delegate), this._delegate.formatSourceFilesToggled());
},
_scroll: function(event)
@@ -764,107 +888,64 @@ WebInspector.SourceFrame.prototype = {
resize: function()
{
- if (this._textViewer)
- this._textViewer.resize();
+ this._textViewer.resize();
},
- formatSource: function()
+ commitEditing: function(callback)
{
- if (!this._content)
+ if (!this._viewerState) {
+ // No editing was actually done.
+ this._delegate.setScriptSourceIsBeingEdited(false);
+ callback();
return;
+ }
- function didFormat(formattedContent)
+ function didEditContent(error)
{
- this._content = formattedContent;
- this._textModel.setText(null, formattedContent.text);
- this._setTextViewerDecorations();
- }
- var formatter = new WebInspector.ScriptFormatter();
- formatter.formatContent(this._content, didFormat.bind(this))
- },
+ if (error) {
+ if (error.data && error.data[0]) {
+ WebInspector.log(error.data[0], WebInspector.ConsoleMessage.MessageLevel.Error);
+ WebInspector.showConsole();
+ }
+ callback(error);
+ return;
+ }
- _registerShortcuts: function()
- {
- this._shortcuts = {};
- var handleSaveCallback = this._handleSave.bind(this);
- this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = handleSaveCallback;
- this._shortcuts[WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.Keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = handleSaveCallback;
- this._shortcuts[WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.Keys.Esc.code)] = this._handleRevertEditing.bind(this);
- },
+ var newBreakpoints = {};
+ for (var lineNumber in this._breakpoints) {
+ newBreakpoints[lineNumber] = this._breakpoints[lineNumber];
+ this.removeBreakpoint(Number(lineNumber));
+ }
- _handleKeyDown: function(e)
- {
- var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
- var handler = this._shortcuts[shortcutKey];
- if (handler && handler.call(this)) {
- e.preventDefault();
- e.stopPropagation();
- }
- },
+ for (var lineNumber in this._viewerState.breakpoints)
+ this._delegate.removeBreakpoint(Number(lineNumber));
- _handleSave: function()
- {
- if (this._textViewer.readOnly || !this._delegate.canEditScriptSource())
- return false;
+ for (var lineNumber in newBreakpoints) {
+ var breakpoint = newBreakpoints[lineNumber];
+ this._delegate.setBreakpoint(Number(lineNumber), breakpoint.condition, breakpoint.enabled);
+ }
- if (this._originalTextModelContent === undefined) {
- // No editing was actually done.
- this._textViewer.readOnly = true;
+ delete this._viewerState;
this._delegate.setScriptSourceIsBeingEdited(false);
- return true;
- }
-
- var originalTextModelContent = this._originalTextModelContent;
- var newSource = this._textModel.text;
-
- delete this._originalTextModelContent;
- this._textViewer.readOnly = true;
- this._delegate.setScriptSourceIsBeingEdited(false);
- function didEditScriptSource(success, newBodyOrErrorMessage)
- {
- if (!success && this._originalTextModelContent === undefined && this._textModel.text === newSource) {
- this._originalTextModelContent = originalTextModelContent;
- this._textViewer.readOnly = false;
- this._delegate.setScriptSourceIsBeingEdited(true);
- WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Error);
- WebInspector.showConsole();
- }
+ callback();
}
- this._delegate.editScriptSource(newSource, didEditScriptSource.bind(this));
- return true;
+ this.editContent(this._textModel.text, didEditContent.bind(this));
},
- _handleRevertEditing: function()
+ editContent: function(newContent, callback)
{
- if (this._textViewer.readOnly)
- return false;
-
- if (this._originalTextModelContent !== undefined)
- this._textModel.setText(null, this._originalTextModelContent);
- delete this._originalTextModelContent;
- this._textViewer.readOnly = true;
- this._delegate.setScriptSourceIsBeingEdited(false);
- return true;
+ this._delegate.editScriptSource(newContent, callback);
},
- _doubleClick: function(event)
+ cancelEditing: function()
{
- if (!this._delegate.canEditScriptSource())
- return;
-
- var lineRow = event.target.enclosingNodeOrSelfWithClass("webkit-line-content");
- if (!lineRow)
- return; // Do not trigger editing from line numbers.
-
- if (this._textViewer.readOnly) {
- this._textViewer.readOnly = false;
- window.getSelection().collapseToStart();
- }
+ this._restoreViewerState();
+ this._delegate.setScriptSourceIsBeingEdited(false);
}
}
-WebInspector.SourceFrame.prototype.__proto__ = WebInspector.View.prototype;
+WebInspector.SourceFrame.prototype.__proto__ = WebInspector.TextViewerDelegate.prototype;
WebInspector.SourceFrameDelegate = function()
@@ -935,5 +1016,15 @@ WebInspector.SourceFrameDelegate.prototype = {
releaseEvaluationResult: function()
{
// Should be implemented by subclasses.
+ },
+
+ toggleFormatSourceFiles: function()
+ {
+ // Should be implemented by subclasses.
+ },
+
+ formatSourceFilesToggled: function()
+ {
+ // Should be implemented by subclasses.
}
}
diff --git a/Source/WebCore/inspector/front-end/SourceFrameContent.js b/Source/WebCore/inspector/front-end/SourceFrameContent.js
deleted file mode 100644
index 3f3a8e9..0000000
--- a/Source/WebCore/inspector/front-end/SourceFrameContent.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2011 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.SourceFrameContent = function(text, mapping, scriptRanges)
-{
- this._text = text;
- this._mapping = mapping;
- this._scriptRanges = scriptRanges;
-}
-
-WebInspector.SourceFrameContent.prototype = {
- get text()
- {
- return this._text;
- },
-
- get scriptRanges()
- {
- return this._scriptRanges;
- },
-
- sourceFrameLineNumberToActualLocation: function(lineNumber)
- {
- var location = this._mapping.sourceLocationToActualLocation(lineNumber, 0);
- location.sourceID = this._sourceIDForSourceFrameLineNumber(lineNumber);
- return location;
- },
-
- actualLocationToSourceFrameLineNumber: function(lineNumber, columnNumber)
- {
- return this._mapping.actualLocationToSourceLocation(lineNumber, columnNumber).lineNumber;
- },
-
- _sourceIDForSourceFrameLineNumber: function(lineNumber)
- {
- for (var i = 0; i < this._scriptRanges.length; ++i) {
- var scriptRange = this._scriptRanges[i];
- if (lineNumber < scriptRange.start.lineNumber)
- return;
- if (lineNumber > scriptRange.end.lineNumber)
- continue;
- if (lineNumber === scriptRange.end.lineNumber && !scriptRange.end.columnNumber)
- continue;
- return scriptRange.sourceID;
- }
- }
-}
-
-
-WebInspector.SourceMapping = function()
-{
-}
-
-WebInspector.SourceMapping.prototype = {
- actualLocationToSourceLocation: function(lineNumber, columnNumber)
- {
- // Should be implemented by subclasses.
- },
-
- sourceLocationToActualLocation: function(lineNumber, columnNumber)
- {
- // Should be implemented by subclasses.
- }
-}
-
-
-WebInspector.IdenticalSourceMapping = function()
-{
- WebInspector.SourceMapping.call(this);
-}
-
-WebInspector.IdenticalSourceMapping.prototype = {
- actualLocationToSourceLocation: function(lineNumber, columnNumber)
- {
- return { lineNumber: lineNumber, columnNumber: columnNumber};
- },
-
- sourceLocationToActualLocation: function(lineNumber, columnNumber)
- {
- return { lineNumber: lineNumber, columnNumber: columnNumber};
- }
-}
-
-WebInspector.IdenticalSourceMapping.prototype.__proto__ = WebInspector.SourceMapping.prototype;
diff --git a/Source/WebCore/inspector/front-end/StylesSidebarPane.js b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
index 29d0317..a662008 100644
--- a/Source/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -503,7 +503,7 @@ WebInspector.StylesSidebarPane.prototype = {
addBlankSection: function()
{
- var blankSection = new WebInspector.BlankStylePropertiesSection(this, appropriateSelectorForNode(this.node, true));
+ var blankSection = new WebInspector.BlankStylePropertiesSection(this, this.node ? this.node.appropriateSelectorFor(true) : "");
blankSection.pane = this;
var elementStyleSection = this.sections[0][1];
@@ -635,8 +635,6 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
function linkifyUncopyable(url, line)
{
var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1);
- link.setAttribute("data-uncopyable", link.textContent);
- link.textContent = "";
return link;
}
@@ -1643,47 +1641,29 @@ WebInspector.StylePropertyTreeElement.prototype = {
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.valueElement);
var wordString = wordRange.toString();
- var replacementString = wordString;
+ var replacementString;
+ var prefix, suffix, number;
- var matches = /(.*?)(-?\d+(?:\.\d+)?)(.*)/.exec(wordString);
+ var matches;
+ matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
if (matches && matches.length) {
- var prefix = matches[1];
- var number = parseFloat(matches[2]);
- var suffix = matches[3];
-
- // If the number is near zero or the number is one and the direction will take it near zero.
- var numberNearZero = (number < 1 && number > -1);
- if (number === 1 && event.keyIdentifier === "Down")
- numberNearZero = true;
- else if (number === -1 && event.keyIdentifier === "Up")
- numberNearZero = true;
-
- if (numberNearZero && event.altKey && arrowKeyPressed) {
- if (event.keyIdentifier === "Down")
- number = Math.ceil(number - 1);
- else
- number = Math.floor(number + 1);
- } else {
- // Jump by 10 when shift is down or jump by 0.1 when near zero or Alt/Option is down.
- // Also jump by 10 for page up and down, or by 100 if shift is held with a page key.
- var changeAmount = 1;
- if (event.shiftKey && pageKeyPressed)
- changeAmount = 100;
- else if (event.shiftKey || pageKeyPressed)
- changeAmount = 10;
- else if (event.altKey || numberNearZero)
- changeAmount = 0.1;
-
- if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
- changeAmount *= -1;
-
- // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
- // Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
- number = Number((number + changeAmount).toFixed(6));
- }
+ prefix = matches[1];
+ suffix = matches[3];
+ number = this._alteredHexNumber(matches[2], event);
replacementString = prefix + number + suffix;
+ } else {
+ matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
+ if (matches && matches.length) {
+ prefix = matches[1];
+ suffix = matches[3];
+ number = this._alteredFloatNumber(parseFloat(matches[2]), event);
+ replacementString = prefix + number + suffix;
+ }
+ }
+
+ if (replacementString) {
var replacementTextNode = document.createTextNode(replacementString);
wordRange.deleteContents();
@@ -1710,6 +1690,75 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
},
+ _alteredFloatNumber: function(number, event)
+ {
+ var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
+ // If the number is near zero or the number is one and the direction will take it near zero.
+ var numberNearZero = (number < 1 && number > -1);
+ if (number === 1 && event.keyIdentifier === "Down")
+ numberNearZero = true;
+ else if (number === -1 && event.keyIdentifier === "Up")
+ numberNearZero = true;
+
+ var result;
+ if (numberNearZero && event.altKey && arrowKeyPressed) {
+ if (event.keyIdentifier === "Down")
+ result = Math.ceil(number - 1);
+ else
+ result = Math.floor(number + 1);
+ } else {
+ // Jump by 10 when shift is down or jump by 0.1 when near zero or Alt/Option is down.
+ // Also jump by 10 for page up and down, or by 100 if shift is held with a page key.
+ var changeAmount = 1;
+ if (event.shiftKey && !arrowKeyPressed)
+ changeAmount = 100;
+ else if (event.shiftKey || !arrowKeyPressed)
+ changeAmount = 10;
+ else if (event.altKey || numberNearZero)
+ changeAmount = 0.1;
+
+ if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
+ changeAmount *= -1;
+
+ // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
+ // Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
+ result = Number((number + changeAmount).toFixed(6));
+ }
+
+ return result;
+ },
+
+ _alteredHexNumber: function(hexString, event)
+ {
+ var number = parseInt(hexString, 16);
+ if (isNaN(number) || !isFinite(number))
+ return hexString;
+
+ var maxValue = Math.pow(16, hexString.length) - 1;
+ var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
+
+ var delta;
+ if (arrowKeyPressed)
+ delta = (event.keyIdentifier === "Up") ? 1 : -1;
+ else
+ delta = (event.keyIdentifier === "PageUp") ? 16 : -16;
+
+ if (event.shiftKey)
+ delta *= 16;
+
+ var result = number + delta;
+ if (result < 0)
+ result = 0; // Color hex values are never negative, so clamp to 0.
+ else if (result > maxValue)
+ return hexString;
+
+ // Ensure the result length is the same as the original hex value.
+ var resultString = result.toString(16).toUpperCase();
+ for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
+ resultString = "0" + resultString;
+ return resultString;
+ },
+
editingEnded: function(context)
{
this.hasChildren = context.hasChildren;
diff --git a/Source/WebCore/inspector/front-end/TestController.js b/Source/WebCore/inspector/front-end/TestController.js
index e6783f9..301994c 100644
--- a/Source/WebCore/inspector/front-end/TestController.js
+++ b/Source/WebCore/inspector/front-end/TestController.js
@@ -36,7 +36,7 @@ WebInspector.TestController.prototype = {
notifyDone: function(callId, result)
{
var message = typeof result === "undefined" ? "\"<undefined>\"" : JSON.stringify(result);
- InspectorAgent.didEvaluateForTestInFrontend(callId, message);
+ RuntimeAgent.evaluate("didEvaluateForTestInFrontend(" + callId + ", " + message + ")", "test");
}
}
diff --git a/Source/WebCore/inspector/front-end/TextEditorModel.js b/Source/WebCore/inspector/front-end/TextEditorModel.js
index b14a3b7..47c53d7 100644
--- a/Source/WebCore/inspector/front-end/TextEditorModel.js
+++ b/Source/WebCore/inspector/front-end/TextEditorModel.js
@@ -59,6 +59,7 @@ WebInspector.TextEditorModel = function()
this._attributes = [];
this._undoStack = [];
this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
+ this._lineBreak = "\n";
}
WebInspector.TextEditorModel.prototype = {
@@ -74,7 +75,7 @@ WebInspector.TextEditorModel.prototype = {
get text()
{
- return this._lines.join("\n");
+ return this._lines.join(this._lineBreak);
},
line: function(lineNumber)
@@ -91,9 +92,12 @@ WebInspector.TextEditorModel.prototype = {
setText: function(range, text)
{
- if (!range)
+ text = text || "";
+ if (!range) {
range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
- var command = this._pushUndoableCommand(range, text);
+ this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n";
+ }
+ var command = this._pushUndoableCommand(range);
var newRange = this._innerSetText(range, text);
command.range = newRange.clone();
@@ -113,11 +117,10 @@ WebInspector.TextEditorModel.prototype = {
if (text === "")
return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn);
- var newLines = text.split("\n");
+ var newLines = text.split(/\r?\n/);
this._replaceTabsIfNeeded(newLines);
var prefix = this._lines[range.startLine].substring(0, range.startColumn);
- var prefixArguments = this._arguments
var suffix = this._lines[range.startLine].substring(range.startColumn);
var postCaret = prefix.length;
@@ -211,13 +214,13 @@ WebInspector.TextEditorModel.prototype = {
var clip = [];
if (range.startLine === range.endLine) {
clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
- return clip.join("\n");
+ return clip.join(this._lineBreak);
}
clip.push(this._lines[range.startLine].substring(range.startColumn));
for (var i = range.startLine + 1; i < range.endLine; ++i)
clip.push(this._lines[i]);
clip.push(this._lines[range.endLine].substring(0, range.endColumn));
- return clip.join("\n");
+ return clip.join(this._lineBreak);
},
setAttribute: function(line, name, value)
@@ -243,7 +246,7 @@ WebInspector.TextEditorModel.prototype = {
delete attrs[name];
},
- _pushUndoableCommand: function(range, text)
+ _pushUndoableCommand: function(range)
{
var command = {
text: this.copyRange(range),
@@ -262,29 +265,29 @@ WebInspector.TextEditorModel.prototype = {
return command;
},
- undo: function()
+ undo: function(callback)
{
this._markRedoableState();
this._inUndo = true;
- var range = this._doUndo(this._undoStack);
+ var range = this._doUndo(this._undoStack, callback);
delete this._inUndo;
return range;
},
- redo: function()
+ redo: function(callback)
{
this.markUndoableState();
this._inRedo = true;
- var range = this._doUndo(this._redoStack);
+ var range = this._doUndo(this._redoStack, callback);
delete this._inRedo;
return range;
},
- _doUndo: function(stack)
+ _doUndo: function(stack, callback)
{
var range = null;
for (var i = stack.length - 1; i >= 0; --i) {
@@ -292,6 +295,8 @@ WebInspector.TextEditorModel.prototype = {
stack.length = i;
range = this.setText(command.range, command.text);
+ if (callback)
+ callback(command.range, range);
if (i > 0 && stack[i - 1].explicit)
return range;
}
diff --git a/Source/WebCore/inspector/front-end/TextViewer.js b/Source/WebCore/inspector/front-end/TextViewer.js
index 43b34f6..1b40b3e 100644
--- a/Source/WebCore/inspector/front-end/TextViewer.js
+++ b/Source/WebCore/inspector/front-end/TextViewer.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,12 +29,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.TextViewer = function(textModel, platform, url)
+WebInspector.TextViewer = function(textModel, platform, url, delegate)
{
+ WebInspector.View.call(this);
+
this._textModel = textModel;
this._textModel.changeListener = this._textChanged.bind(this);
+ this._textModel.resetUndoStack();
+ this._delegate = delegate;
- this.element = document.createElement("div");
this.element.className = "text-editor monospace";
var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this);
@@ -49,7 +52,12 @@ WebInspector.TextViewer = function(textModel, platform, url)
// Forward mouse wheel events from the unscrollable gutter to the main panel.
this._gutterPanel.element.addEventListener("mousewheel", function(e) {
this._mainPanel.element.dispatchEvent(e);
- }.bind(this), false)
+ }.bind(this), false);
+
+ this.element.addEventListener("dblclick", this._doubleClick.bind(this), true);
+ this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
+
+ this._registerShortcuts();
}
WebInspector.TextViewer.prototype = {
@@ -60,7 +68,10 @@ WebInspector.TextViewer.prototype = {
set readOnly(readOnly)
{
+ if (this._mainPanel.readOnly === readOnly)
+ return;
this._mainPanel.readOnly = readOnly;
+ this._delegate.readOnlyStateChanged(readOnly);
},
get readOnly()
@@ -68,16 +79,6 @@ WebInspector.TextViewer.prototype = {
return this._mainPanel.readOnly;
},
- set startEditingListener(startEditingListener)
- {
- this._startEditingListener = startEditingListener;
- },
-
- set endEditingListener(endEditingListener)
- {
- this._endEditingListener = endEditingListener;
- },
-
get textModel()
{
return this._textModel;
@@ -164,31 +165,23 @@ WebInspector.TextViewer.prototype = {
// WebInspector.TextModel listener
_textChanged: function(oldRange, newRange, oldText, newText)
{
- if (!this._internalTextChangeMode) {
- this._mainPanel.textChanged(oldRange, newRange);
- this._gutterPanel.textChanged(oldRange, newRange);
- this._updatePanelOffsets();
- }
+ if (!this._internalTextChangeMode)
+ this._textModel.resetUndoStack();
+ this._mainPanel.textChanged(oldRange, newRange);
+ this._gutterPanel.textChanged(oldRange, newRange);
+ this._updatePanelOffsets();
},
_enterInternalTextChangeMode: function()
{
this._internalTextChangeMode = true;
-
- if (this._startEditingListener)
- this._startEditingListener();
+ this._delegate.startEditing();
},
_exitInternalTextChangeMode: function(oldRange, newRange)
{
this._internalTextChangeMode = false;
-
- // Update the gutter panel.
- this._gutterPanel.textChanged(oldRange, newRange);
- this._updatePanelOffsets();
-
- if (this._endEditingListener)
- this._endEditingListener(oldRange, newRange);
+ this._delegate.endEditing(oldRange, newRange);
},
_updatePanelOffsets: function()
@@ -218,7 +211,7 @@ WebInspector.TextViewer.prototype = {
return;
var mainChunk = this._mainPanel.chunkForLine(lineNumber);
- if (mainChunk.linesCount === 1) {
+ if (mainChunk.linesCount === 1 && mainChunk.decorated) {
var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
var height = mainChunk.height;
if (height)
@@ -230,9 +223,125 @@ WebInspector.TextViewer.prototype = {
if (gutterChunk.linesCount === 1)
gutterChunk.element.style.removeProperty("height");
}
+ },
+
+ _doubleClick: function(event)
+ {
+ if (!this.readOnly || this._commitEditingInProgress)
+ return;
+
+ var lineRow = event.target.enclosingNodeOrSelfWithClass("webkit-line-content");
+ if (!lineRow)
+ return; // Do not trigger editing from line numbers.
+
+ if (!this._delegate.isContentEditable())
+ return;
+
+ this.readOnly = false;
+ window.getSelection().collapseToStart();
+ },
+
+ _registerShortcuts: function()
+ {
+ var keys = WebInspector.KeyboardShortcut.Keys;
+ var modifiers = WebInspector.KeyboardShortcut.Modifiers;
+
+ this._shortcuts = {};
+ var commitEditing = this._commitEditing.bind(this);
+ var cancelEditing = this._cancelEditing.bind(this);
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", modifiers.CtrlOrMeta)] = commitEditing;
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, modifiers.CtrlOrMeta)] = commitEditing;
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Esc.code)] = cancelEditing;
+
+ var handleUndo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false);
+ var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true);
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = handleUndo;
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;
+
+ var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false);
+ var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true);
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
+ },
+
+ _handleKeyDown: function(e)
+ {
+ var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
+ var handler = this._shortcuts[shortcutKey];
+ if (handler && handler.call(this)) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ },
+
+ _commitEditing: function()
+ {
+ if (this.readOnly)
+ return false;
+
+ this.readOnly = true;
+ function didCommitEditing(error)
+ {
+ this._commitEditingInProgress = false;
+ if (error)
+ this.readOnly = false;
+ }
+ this._commitEditingInProgress = true;
+ this._delegate.commitEditing(didCommitEditing.bind(this));
+ return true;
+ },
+
+ _cancelEditing: function()
+ {
+ if (this.readOnly)
+ return false;
+
+ this.readOnly = true;
+ this._delegate.cancelEditing();
+ return true;
}
}
+WebInspector.TextViewer.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.TextViewerDelegate = function()
+{
+}
+
+WebInspector.TextViewerDelegate.prototype = {
+ isContentEditable: function()
+ {
+ // Should be implemented by subclasses.
+ },
+
+ readOnlyStateChanged: function(readOnly)
+ {
+ // Should be implemented by subclasses.
+ },
+
+ startEditing: function()
+ {
+ // Should be implemented by subclasses.
+ },
+
+ endEditing: function(oldRange, newRange)
+ {
+ // Should be implemented by subclasses.
+ },
+
+ commitEditing: function()
+ {
+ // Should be implemented by subclasses.
+ },
+
+ cancelEditing: function()
+ {
+ // Should be implemented by subclasses.
+ }
+}
+
+WebInspector.TextViewerDelegate.prototype.__proto__ = WebInspector.Object.prototype;
+
WebInspector.TextEditorChunkedPanel = function(textModel)
{
this._textModel = textModel;
@@ -259,19 +368,20 @@ WebInspector.TextEditorChunkedPanel.prototype = {
addDecoration: function(lineNumber, decoration)
{
+ if (lineNumber >= this._textModel.linesCount)
+ return;
+
var chunk = this.makeLineAChunk(lineNumber);
chunk.addDecoration(decoration);
},
removeDecoration: function(lineNumber, decoration)
{
- var chunk = this.makeLineAChunk(lineNumber);
- chunk.removeDecoration(decoration);
- },
+ if (lineNumber >= this._textModel.linesCount)
+ return;
- textChanged: function(oldRange, newRange)
- {
- this._buildChunks();
+ var chunk = this.chunkForLine(lineNumber);
+ chunk.removeDecoration(decoration);
},
_buildChunks: function()
@@ -294,16 +404,19 @@ WebInspector.TextEditorChunkedPanel.prototype = {
makeLineAChunk: function(lineNumber)
{
- if (!this._textChunks)
- this._buildChunks();
-
var chunkNumber = this._chunkNumberForLine(lineNumber);
var oldChunk = this._textChunks[chunkNumber];
if (oldChunk.linesCount === 1)
return oldChunk;
+ return this._splitChunkOnALine(lineNumber, chunkNumber);
+ },
+
+ _splitChunkOnALine: function(lineNumber, chunkNumber)
+ {
this.beginDomUpdates();
+ var oldChunk = this._textChunks[chunkNumber];
var wasExpanded = oldChunk.expanded;
oldChunk.expanded = false;
@@ -447,9 +560,6 @@ WebInspector.TextEditorChunkedPanel.prototype = {
if (this._paintCoalescingLevel || this._dirtyLines)
return;
- if (!this._textChunks)
- this._buildChunks();
-
var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;
@@ -526,10 +636,7 @@ WebInspector.TextEditorGutterPanel.prototype = {
textChanged: function(oldRange, newRange)
{
- if (!this._textChunks) {
- this._buildChunks();
- return;
- }
+ this.beginDomUpdates();
var linesDiff = newRange.linesCount - oldRange.linesCount;
if (linesDiff) {
@@ -565,6 +672,8 @@ WebInspector.TextEditorGutterPanel.prototype = {
chunk = this._textChunks[++chunkNumber];
}
}
+
+ this.endDomUpdates();
},
syncClientHeight: function(clientHeight)
@@ -744,6 +853,9 @@ WebInspector.TextEditorMainPanel.prototype = {
set readOnly(readOnly)
{
+ if (this._readOnly === readOnly)
+ return;
+
this.beginDomUpdates();
this._readOnly = readOnly;
if (this._readOnly)
@@ -762,14 +874,25 @@ WebInspector.TextEditorMainPanel.prototype = {
{
if (this._rangeToMark) {
var markedLine = this._rangeToMark.startLine;
- this._rangeToMark = null;
- this._paintLines(markedLine, markedLine + 1);
+ delete this._rangeToMark;
+ // Remove the marked region immediately.
+ if (!this._dirtyLines) {
+ this.beginDomUpdates();
+ var chunk = this.chunkForLine(markedLine);
+ var wasExpanded = chunk.expanded;
+ chunk.expanded = false;
+ chunk.updateCollapsedLineRow();
+ chunk.expanded = wasExpanded;
+ this.endDomUpdates();
+ } else
+ this._paintLines(markedLine, markedLine + 1);
}
if (range) {
this._rangeToMark = range;
this.revealLine(range.startLine);
- this._paintLines(range.startLine, range.startLine + 1);
+ var chunk = this.makeLineAChunk(range.startLine);
+ this._paintLine(chunk.element);
if (this._markedRangeElement)
this._markedRangeElement.scrollIntoViewIfNeeded();
}
@@ -799,6 +922,65 @@ WebInspector.TextEditorMainPanel.prototype = {
this._cachedRows = [];
},
+ handleUndoRedo: function(redo)
+ {
+ if (this._readOnly || this._dirtyLines)
+ return false;
+
+ this.beginUpdates();
+ this._enterTextChangeMode();
+
+ var callback = function(oldRange, newRange) {
+ this._exitTextChangeMode(oldRange, newRange);
+ this._enterTextChangeMode();
+ }.bind(this);
+
+ var range = redo ? this._textModel.redo(callback) : this._textModel.undo(callback);
+ if (range)
+ this._setCaretLocation(range.endLine, range.endColumn, true);
+
+ this._exitTextChangeMode(null, null);
+ this.endUpdates();
+
+ return true;
+ },
+
+ handleTabKeyPress: function(shiftKey)
+ {
+ if (this._readOnly || this._dirtyLines)
+ return false;
+
+ var selection = this._getSelection();
+ if (!selection)
+ return false;
+
+ if (shiftKey)
+ return true;
+
+ this.beginUpdates();
+ this._enterTextChangeMode();
+
+ var range = selection;
+ if (range.startLine > range.endLine || (range.startLine === range.endLine && range.startColumn > range.endColumn))
+ range = new WebInspector.TextRange(range.endLine, range.endColumn, range.startLine, range.startColumn);
+
+ var newRange = this._setText(range, "\t");
+
+ this._exitTextChangeMode(range, newRange);
+ this.endUpdates();
+
+ this._setCaretLocation(newRange.endLine, newRange.endColumn, true);
+ return true;
+ },
+
+ _splitChunkOnALine: function(lineNumber, chunkNumber)
+ {
+ var selection = this._getSelection();
+ var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber);
+ this._restoreSelection(selection);
+ return chunk;
+ },
+
_buildChunks: function()
{
for (var i = 0; i < this._textModel.linesCount; ++i)
@@ -825,6 +1007,7 @@ WebInspector.TextEditorMainPanel.prototype = {
this._restorePaintLinesOperationsCredit();
WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex);
+ this._adjustPaintLinesOperationsRefreshValue();
this._restoreSelection(selection);
},
@@ -844,7 +1027,7 @@ WebInspector.TextEditorMainPanel.prototype = {
if (!this._scheduledPaintLines) {
this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ];
- this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 10);
+ this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0);
} else {
for (var i = 0; i < this._scheduledPaintLines.length; ++i) {
var chunk = this._scheduledPaintLines[i];
@@ -879,14 +1062,31 @@ WebInspector.TextEditorMainPanel.prototype = {
var scheduledPaintLines = this._scheduledPaintLines;
delete this._scheduledPaintLines;
-
+
this._restorePaintLinesOperationsCredit();
this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection);
+ this._adjustPaintLinesOperationsRefreshValue();
},
_restorePaintLinesOperationsCredit: function()
{
- this._paintLinesOperationsCredit = 250;
+ if (!this._paintLinesOperationsRefreshValue)
+ this._paintLinesOperationsRefreshValue = 250;
+ this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue;
+ this._paintLinesOperationsLastRefresh = Date.now();
+ },
+
+ _adjustPaintLinesOperationsRefreshValue: function()
+ {
+ var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit;
+ if (operationsDone <= 0)
+ return;
+ var timePast = Date.now() - this._paintLinesOperationsLastRefresh;
+ if (timePast <= 0)
+ return;
+ // Make the synchronous CPU chunk for painting the lines 50 msec.
+ var value = Math.floor(operationsDone / timePast * 50);
+ this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500);
},
_paintLines: function(fromLine, toLine, restoreSelection)
@@ -943,20 +1143,22 @@ WebInspector.TextEditorMainPanel.prototype = {
_paintLine: function(lineRow)
{
var lineNumber = lineRow.lineNumber;
- if (this._dirtyLines || this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
+ if (this._dirtyLines) {
this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}
this.beginDomUpdates();
try {
- var highlight = this._textModel.getAttribute(lineNumber, "highlight");
- if (!highlight) {
- if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
- this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
+ if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
+ this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}
+ var highlight = this._textModel.getAttribute(lineNumber, "highlight");
+ if (!highlight)
+ return;
+
lineRow.removeChildren();
var line = this._textModel.line(lineNumber);
if (!line)
@@ -990,11 +1192,11 @@ WebInspector.TextEditorMainPanel.prototype = {
this._appendTextNode(lineRow, line.substring(plainTextStart, line.length));
--this._paintLinesOperationsCredit;
}
- if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
- this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
if (lineRow.decorationsElement)
lineRow.appendChild(lineRow.decorationsElement);
} finally {
+ if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
+ this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
this.endDomUpdates();
}
},
@@ -1035,13 +1237,28 @@ WebInspector.TextEditorMainPanel.prototype = {
return new WebInspector.TextRange(end.line, end.column, start.line, start.column);
},
- _restoreSelection: function(range)
+ _restoreSelection: function(range, scrollIntoView)
{
if (!range)
return;
var start = this._positionToSelection(range.startLine, range.startColumn);
var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);
+
+ if (scrollIntoView) {
+ for (var node = end.container; node; node = node.parentElement) {
+ if (node.scrollIntoViewIfNeeded) {
+ node.scrollIntoViewIfNeeded();
+ break;
+ }
+ }
+ }
+ },
+
+ _setCaretLocation: function(line, column, scrollIntoView)
+ {
+ var range = new WebInspector.TextRange(line, column, line, column);
+ this._restoreSelection(range, scrollIntoView);
},
_selectionToPosition: function(container, offset)
@@ -1051,14 +1268,14 @@ WebInspector.TextEditorMainPanel.prototype = {
if (container === this._container && offset === 1)
return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };
- var lineRow = container.enclosingNodeOrSelfWithNodeName("DIV");
+ var lineRow = this._enclosingLineRowOrSelf(container);
var lineNumber = lineRow.lineNumber;
if (container === lineRow && offset === 0)
return { line: lineNumber, column: 0 };
// This may be chunk and chunks may contain \n.
var column = 0;
- var node = lineRow.traverseNextTextNode(lineRow);
+ var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow);
while (node && node !== container) {
var text = node.textContent;
for (var i = 0; i < text.length; ++i) {
@@ -1087,7 +1304,8 @@ WebInspector.TextEditorMainPanel.prototype = {
_positionToSelection: function(line, column)
{
var chunk = this.chunkForLine(line);
- var lineRow = chunk.getExpandedLineRow(line);
+ // One-lined collapsed chunks may still stay highlighted.
+ var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line);
if (lineRow)
var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
else {
@@ -1103,6 +1321,18 @@ WebInspector.TextEditorMainPanel.prototype = {
return rangeBoundary;
},
+ _enclosingLineRowOrSelf: function(element)
+ {
+ var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
+ if (lineRow)
+ return lineRow;
+ for (var lineRow = element; lineRow; lineRow = lineRow.parentElement) {
+ if (lineRow.parentElement === this._container)
+ return lineRow;
+ }
+ return null;
+ },
+
_appendSpan: function(element, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
@@ -1167,7 +1397,7 @@ WebInspector.TextEditorMainPanel.prototype = {
if (target === this._container)
return;
- var lineRow = target.enclosingNodeOrSelfWithClass("webkit-line-content");
+ var lineRow = this._enclosingLineRowOrSelf(target);
if (!lineRow)
return;
@@ -1195,7 +1425,7 @@ WebInspector.TextEditorMainPanel.prototype = {
var endLine = startLine + 1;
for (var row = lineRow.nextSibling; row; row = row.nextSibling) {
- if (typeof row.lineNumber === "number") {
+ if (typeof row.lineNumber === "number" && row.lineNumber > startLine) {
endLine = row.lineNumber;
break;
}
@@ -1205,7 +1435,7 @@ WebInspector.TextEditorMainPanel.prototype = {
// Now this will no longer be valid.
delete lineRow.lineNumber;
}
-
+
if (this._dirtyLines) {
this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine);
this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine);
@@ -1258,7 +1488,7 @@ WebInspector.TextEditorMainPanel.prototype = {
this._collectLinesFromDiv(lines, lineRow);
}
- // Try to decrease the range being replaced if possible.
+ // Try to decrease the range being replaced, if possible.
var startOffset = 0;
while (startLine < dirtyLines.start && startOffset < lines.length) {
if (this._textModel.line(startLine) !== lines[startOffset])
@@ -1277,26 +1507,65 @@ WebInspector.TextEditorMainPanel.prototype = {
lines = lines.slice(startOffset, endOffset);
+ // Try to decrease the range being replaced by column offsets, if possible.
+ var startColumn = 0;
+ var endColumn = this._textModel.lineLength(endLine - 1);
+ if (lines.length > 0) {
+ var line1 = this._textModel.line(startLine);
+ var line2 = lines[0];
+ while (line1[startColumn] && line1[startColumn] === line2[startColumn])
+ ++startColumn;
+ lines[0] = line2.substring(startColumn);
+
+ var line1 = this._textModel.line(endLine - 1);
+ var line2 = lines[lines.length - 1];
+ for (var i = 0; i < endColumn && i < line2.length; ++i) {
+ if (startLine === endLine - 1 && endColumn - i <= startColumn)
+ break;
+ if (line1[endColumn - i - 1] !== line2[line2.length - i - 1])
+ break;
+ }
+ if (i) {
+ endColumn -= i;
+ lines[lines.length - 1] = line2.substring(0, line2.length - i);
+ }
+ }
+
var selection = this._getSelection();
- if (lines.length === 0 && endLine < this._textModel.linesCount) {
+ if (lines.length === 0 && endLine < this._textModel.linesCount)
var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0);
- var newRange = this._textModel.setText(oldRange, "");
- } else {
- var oldRange = new WebInspector.TextRange(startLine, 0, endLine - 1, this._textModel.lineLength(endLine - 1));
- var newRange = this._textModel.setText(oldRange, lines.join("\n"));
- }
+ else if (lines.length === 0 && startLine > 0)
+ var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1));
+ else
+ var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);
+
+ var newRange = this._setText(oldRange, lines.join("\n"));
+
+ this._paintScheduledLines(true);
+ this._restoreSelection(selection);
+
+ this._exitTextChangeMode(oldRange, newRange);
+ },
+ textChanged: function(oldRange, newRange)
+ {
this.beginDomUpdates();
this._removeDecorationsInRange(oldRange);
this._updateChunksForRanges(oldRange, newRange);
this._updateHighlightsForRange(newRange);
- this._paintScheduledLines(true);
this.endDomUpdates();
+ },
- this._restoreSelection(selection);
+ _setText: function(range, text)
+ {
+ if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
+ this._textModel.markUndoableState();
- this._exitTextChangeMode(oldRange, newRange);
+ var newRange = this._textModel.setText(range, text);
+ this._lastEditedRange = newRange;
+
+ return newRange;
},
_removeDecorationsInRange: function(range)
@@ -1342,6 +1611,8 @@ WebInspector.TextEditorMainPanel.prototype = {
// Most frequent case: a chunk remained the same.
for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) {
var chunk = this._textChunks[chunkNumber];
+ if (chunk.startLine + chunk.linesCount > this._textModel.linesCount)
+ break;
var lineNumber = chunk.startLine;
for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) {
if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild)
@@ -1428,7 +1699,7 @@ WebInspector.TextEditorMainPanel.prototype = {
_collectLinesFromDiv: function(lines, element)
{
var textContents = [];
- var node = element.traverseNextNode(element);
+ var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element);
while (node) {
if (element.decorationsElement === node) {
node = node.nextSibling;
diff --git a/Source/WebCore/inspector/front-end/WebKit.qrc b/Source/WebCore/inspector/front-end/WebKit.qrc
index 0777a19..1b5cb39 100644
--- a/Source/WebCore/inspector/front-end/WebKit.qrc
+++ b/Source/WebCore/inspector/front-end/WebKit.qrc
@@ -9,8 +9,6 @@
<file>AuditRules.js</file>
<file>AuditsPanel.js</file>
<file>BottomUpProfileDataGridTree.js</file>
- <file>Breakpoint.js</file>
- <file>BreakpointManager.js</file>
<file>BreakpointsSidebarPane.js</file>
<file>CallStackSidebarPane.js</file>
<file>Checkbox.js</file>
@@ -34,6 +32,7 @@
<file>DebuggerPresentationModel.js</file>
<file>SourceFile.js</file>
<file>DOMAgent.js</file>
+ <file>DOMBreakpointsSidebarPane.js</file>
<file>DOMStorage.js</file>
<file>DOMStorageItemsView.js</file>
<file>DOMSyntaxHighlighter.js</file>
@@ -51,6 +50,7 @@
<file>GoToLineDialog.js</file>
<file>HAREntry.js</file>
<file>HeapSnapshot.js</file>
+ <file>HeapSnapshotProxy.js</file>
<file>HeapSnapshotView.js</file>
<file>HelpScreen.js</file>
<file>ImageView.js</file>
@@ -98,7 +98,6 @@
<file>SidebarTreeElement.js</file>
<file>SourceCSSTokenizer.js</file>
<file>SourceFrame.js</file>
- <file>SourceFrameContent.js</file>
<file>SourceHTMLTokenizer.js</file>
<file>SourceJavaScriptTokenizer.js</file>
<file>SourceTokenizer.js</file>
diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css
index 0311f22..d6fef89 100644
--- a/Source/WebCore/inspector/front-end/inspector.css
+++ b/Source/WebCore/inspector/front-end/inspector.css
@@ -89,8 +89,8 @@ body.inactive #toolbar {
border-bottom: 1px solid rgb(64%, 64%, 64%);
}
-body.detached.platform-mac-leopard #toolbar,
-body.detached.platform-mac-snowleopard #toolbar {
+body.detached.platform-mac-leopard:not(.remote) #toolbar,
+body.detached.platform-mac-snowleopard:not(.remote) #toolbar {
background: transparent !important;
}
@@ -349,7 +349,7 @@ body.attached #search {
background-position: 0 0;
background-color: transparent;
border: 0 none transparent;
- margin-top: 9px;
+ margin-top: 4px;
}
#close-button-left:hover, #close-button-right:hover {
@@ -493,14 +493,6 @@ button.status-bar-item.toggled-on .glyph {
background-color: rgb(66, 129, 235);
}
-button.status-bar-item.toggled-1 .glyph {
- background-color: rgb(66, 129, 235);
-}
-
-button.status-bar-item.toggled-2 .glyph {
- background-color: purple;
-}
-
button.status-bar-item:disabled {
opacity: 0.5;
background-position: 0 0 !important;
@@ -872,7 +864,7 @@ body.platform-linux .monospace, body.platform-linux .source-code {
.console-formatted-string, .console-formatted-regexp {
color: rgb(196, 26, 22);
- white-space: pre-wrap;
+ white-space: pre;
}
.console-formatted-null, .console-formatted-undefined {
@@ -2520,6 +2512,14 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
-webkit-mask-image: url(Images/pauseOnExceptionButtonGlyph.png);
}
+.scripts-pause-on-exceptions-status-bar-item.toggled-all .glyph {
+ background-color: rgb(66, 129, 235);
+}
+
+.scripts-pause-on-exceptions-status-bar-item.toggled-uncaught .glyph {
+ background-color: purple;
+}
+
#scripts-status-bar {
position: absolute;
top: -1px;
@@ -4309,10 +4309,6 @@ a.worker-item {
color: inherit;
}
-.styles-section a::before {
- content: attr(data-uncopyable);
-}
-
.styles-section .properties {
display: none;
margin: 0;
diff --git a/Source/WebCore/inspector/front-end/inspector.html b/Source/WebCore/inspector/front-end/inspector.html
index 9ba1dca..18c2564 100644
--- a/Source/WebCore/inspector/front-end/inspector.html
+++ b/Source/WebCore/inspector/front-end/inspector.html
@@ -46,7 +46,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="ExtensionRegistryStub.js"></script>
<script type="text/javascript" src="Object.js"></script>
<script type="text/javascript" src="Settings.js"></script>
- <script type="text/javascript" src="CSSStyleModel.js"></script>
<script type="text/javascript" src="Checkbox.js"></script>
<script type="text/javascript" src="ContextMenu.js"></script>
<script type="text/javascript" src="KeyboardShortcut.js"></script>
@@ -61,6 +60,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="Panel.js"></script>
<script type="text/javascript" src="TimelineGrid.js"></script>
<script type="text/javascript" src="Resource.js"></script>
+ <script type="text/javascript" src="CSSStyleModel.js"></script>
<script type="text/javascript" src="NetworkManager.js"></script>
<script type="text/javascript" src="ResourceTreeModel.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
@@ -73,8 +73,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="CookieItemsView.js"></script>
<script type="text/javascript" src="ApplicationCacheItemsView.js"></script>
<script type="text/javascript" src="Script.js"></script>
- <script type="text/javascript" src="Breakpoint.js"></script>
- <script type="text/javascript" src="BreakpointManager.js"></script>
<script type="text/javascript" src="SidebarPane.js"></script>
<script type="text/javascript" src="ElementsTreeOutline.js"></script>
<script type="text/javascript" src="SidebarTreeElement.js"></script>
@@ -83,6 +81,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="RemoteObject.js"></script>
<script type="text/javascript" src="ObjectPropertiesSection.js"></script>
<script type="text/javascript" src="BreakpointsSidebarPane.js"></script>
+ <script type="text/javascript" src="DOMBreakpointsSidebarPane.js"></script>
<script type="text/javascript" src="CallStackSidebarPane.js"></script>
<script type="text/javascript" src="ScopeChainSidebarPane.js"></script>
<script type="text/javascript" src="WatchExpressionsSidebarPane.js"></script>
@@ -101,8 +100,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="ElementsPanel.js"></script>
<script type="text/javascript" src="NetworkPanel.js"></script>
<script type="text/javascript" src="InjectedFakeWorker.js"></script>
+ <script type="text/javascript" src="TextViewer.js"></script>
<script type="text/javascript" src="SourceFrame.js"></script>
- <script type="text/javascript" src="SourceFrameContent.js"></script>
<script type="text/javascript" src="ResourceView.js"></script>
<script type="text/javascript" src="ScriptsPanel.js"></script>
<script type="text/javascript" src="ResourcesPanel.js"></script>
@@ -128,7 +127,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="DOMSyntaxHighlighter.js"></script>
<script type="text/javascript" src="TextEditorModel.js"></script>
<script type="text/javascript" src="TextEditorHighlighter.js"></script>
- <script type="text/javascript" src="TextViewer.js"></script>
<script type="text/javascript" src="SourceTokenizer.js"></script>
<script type="text/javascript" src="SourceCSSTokenizer.js"></script>
<script type="text/javascript" src="SourceHTMLTokenizer.js"></script>
@@ -142,6 +140,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="TopDownProfileDataGridTree.js"></script>
<script type="text/javascript" src="ProfileView.js"></script>
<script type="text/javascript" src="HeapSnapshot.js"></script>
+ <script type="text/javascript" src="HeapSnapshotProxy.js"></script>
<script type="text/javascript" src="HeapSnapshotView.js"></script>
<script type="text/javascript" src="DetailedHeapshotGridNodes.js"></script>
<script type="text/javascript" src="DetailedHeapshotView.js"></script>
diff --git a/Source/WebCore/inspector/front-end/inspector.js b/Source/WebCore/inspector/front-end/inspector.js
index 59171db..b125e7e 100644
--- a/Source/WebCore/inspector/front-end/inspector.js
+++ b/Source/WebCore/inspector/front-end/inspector.js
@@ -171,17 +171,6 @@ var WebInspector = {
}
},
- createDOMBreakpointsSidebarPane: function()
- {
- var pane = new WebInspector.NativeBreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
- function breakpointAdded(event)
- {
- pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
- }
- WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpointAdded);
- return pane;
- },
-
_createPanels: function()
{
var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(',');
@@ -427,6 +416,8 @@ WebInspector.doLoadedDone = function()
document.body.addStyleClass("platform-" + flavor);
var port = WebInspector.port;
document.body.addStyleClass("port-" + port);
+ if (WebInspector.socket)
+ document.body.addStyleClass("remote");
WebInspector.settings = new WebInspector.Settings();
@@ -460,8 +451,8 @@ WebInspector.doLoadedDone = function()
this.cssModel = new WebInspector.CSSStyleModel();
this.debuggerModel = new WebInspector.DebuggerModel();
- this.breakpointManager = new WebInspector.BreakpointManager();
this.searchController = new WebInspector.SearchController();
+ this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
this.panels = {};
this._createPanels();
@@ -508,6 +499,8 @@ WebInspector.doLoadedDone = function()
ConsoleAgent.setMonitoringXHREnabled(true);
ConsoleAgent.enable(this.console.setConsoleMessageExpiredCount.bind(this.console));
+ DatabaseAgent.enable();
+
WebInspector.showPanel(WebInspector.settings.lastActivePanel);
function propertyNamesCallback(error, names)
@@ -624,16 +617,8 @@ WebInspector.documentClick = function(event)
function followLink()
{
- // FIXME: support webkit-html-external-link links here.
- if (WebInspector.canShowSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"))) {
- if (anchor.hasStyleClass("webkit-html-external-link")) {
- anchor.removeStyleClass("webkit-html-external-link");
- anchor.addStyleClass("webkit-html-resource-link");
- }
-
- WebInspector.showSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"));
+ if (WebInspector._showAnchorLocation(anchor))
return;
- }
const profileMatch = WebInspector.ProfileType.URLRegExp.exec(anchor.href);
if (profileMatch) {
@@ -995,18 +980,13 @@ WebInspector.startUserInitiatedDebugging = function()
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;
}
WebInspector.loadEventFired = function(time)
{
this.panels.audits.mainResourceLoadTime = time;
- this.panels.network.mainResourceLoadTime = time;
this.panels.resources.loadEventFired();
- this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000);
this.mainResourceLoadTime = time;
}
@@ -1045,8 +1025,8 @@ WebInspector.bringToFront = function()
WebInspector.inspectedURLChanged = function(url)
{
InspectorFrontendHost.inspectedURLChanged(url);
- this.settings.inspectedURLChanged(url);
- this.extensionServer.notifyInspectedURLChanged();
+ this.domBreakpointsSidebarPane.setInspectedURL(url);
+ this.extensionServer.notifyInspectedURLChanged(url);
}
WebInspector.didCreateWorker = function()
@@ -1225,30 +1205,31 @@ WebInspector.displayNameForURL = function(url)
return url.trimURL(WebInspector.mainResource.domain);
}
-WebInspector._choosePanelToShowSourceLine = function(url, line, preferredPanel)
-{
- preferredPanel = preferredPanel || "resources";
-
- var panel = this.panels[preferredPanel];
- if (panel && panel.canShowSourceLine(url, line))
- return panel;
- panel = this.panels.resources;
- return panel.canShowSourceLine(url, line) ? panel : null;
-}
-
-WebInspector.canShowSourceLine = function(url, line, preferredPanel)
+WebInspector._showAnchorLocation = function(anchor)
{
- return !!this._choosePanelToShowSourceLine(url, line, preferredPanel);
+ var preferedPanel = this.panels[anchor.getAttribute("preferred_panel") || "resources"];
+ if (WebInspector._showAnchorLocationInPanel(anchor, preferedPanel))
+ return true;
+ if (preferedPanel !== this.panels.resources && WebInspector._showAnchorLocationInPanel(anchor, this.panels.resources))
+ return true;
+ return false;
}
-WebInspector.showSourceLine = function(url, line, preferredPanel)
+WebInspector._showAnchorLocationInPanel = function(anchor, panel)
{
- this.currentPanel = this._choosePanelToShowSourceLine(url, line, preferredPanel);
- if (!this.currentPanel)
+ if (!panel.canShowAnchorLocation(anchor))
return false;
+
+ // FIXME: support webkit-html-external-link links here.
+ if (anchor.hasStyleClass("webkit-html-external-link")) {
+ anchor.removeStyleClass("webkit-html-external-link");
+ anchor.addStyleClass("webkit-html-resource-link");
+ }
+
+ this.currentPanel = panel;
if (this.drawer)
this.drawer.immediatelyFinishAnimation();
- this.currentPanel.showSourceLine(url, line);
+ this.currentPanel.showAnchorLocation(anchor);
return true;
}
@@ -1315,6 +1296,7 @@ WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, too
else if (typeof tooltipText !== "string" || tooltipText.length)
a.title = tooltipText;
a.textContent = linkText;
+ a.style.maxWidth = "100%";
return a;
}
@@ -1451,9 +1433,25 @@ WebInspector.isBeingEdited = function(element)
return element.__editing;
}
+WebInspector.markBeingEdited = function(element, value)
+{
+ if (value) {
+ if (element.__editing)
+ return false;
+ element.__editing = true;
+ WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
+ } else {
+ if (!element.__editing)
+ return false;
+ delete element.__editing;
+ --WebInspector.__editingCount;
+ }
+ return true;
+}
+
WebInspector.isEditingAnyField = function()
{
- return this.__editing;
+ return !!WebInspector.__editingCount;
}
// Available config fields (all optional):
@@ -1465,10 +1463,8 @@ WebInspector.isEditingAnyField = function()
// multiline: Boolean - whether the edited element is multiline
WebInspector.startEditing = function(element, config)
{
- if (element.__editing)
+ if (!WebInspector.markBeingEdited(element, true))
return;
- element.__editing = true;
- WebInspector.__editing = true;
config = config || {};
var committedCallback = config.commitHandler;
@@ -1496,8 +1492,7 @@ WebInspector.startEditing = function(element, config)
}
function cleanUpAfterEditing() {
- delete this.__editing;
- delete WebInspector.__editing;
+ WebInspector.markBeingEdited(element, false);
this.removeStyleClass("editing");
this.tabIndex = oldTabIndex;
diff --git a/Source/WebCore/inspector/front-end/networkPanel.css b/Source/WebCore/inspector/front-end/networkPanel.css
index 2711347..8ff5e9e 100644
--- a/Source/WebCore/inspector/front-end/networkPanel.css
+++ b/Source/WebCore/inspector/front-end/networkPanel.css
@@ -714,6 +714,22 @@
display: none;
}
+.resource-headers-view .outline-disclosure li .header-toggle {
+ display: none;
+}
+
+.resource-headers-view .outline-disclosure li.expanded .header-toggle {
+ display: inline;
+ margin-left: 30px;
+ font-weight: normal;
+ color: rgb(45%, 45%, 45%);
+}
+
+.resource-headers-view .outline-disclosure li .header-toggle:hover {
+ color: rgb(20%, 20%, 45%);
+ cursor: pointer;
+}
+
.resource-headers-view .outline-disclosure .header-name {
color: rgb(33%, 33%, 33%);
display: inline-block;
@@ -731,6 +747,11 @@
margin-top: 1px;
}
+.resource-headers-view .outline-disclosure li.headers-text {
+ text-indent: 0;
+ margin-left: -2px;
+}
+
.resource-headers-view .outline-disclosure .raw-form-data {
white-space: pre-wrap;
}
diff --git a/Source/WebCore/inspector/front-end/utilities.js b/Source/WebCore/inspector/front-end/utilities.js
index fbfdfbb..839fce5 100644
--- a/Source/WebCore/inspector/front-end/utilities.js
+++ b/Source/WebCore/inspector/front-end/utilities.js
@@ -451,6 +451,14 @@ String.prototype.trimURL = function(baseURLDomain)
return result;
}
+String.prototype.removeURLFragment = function()
+{
+ var fragmentIndex = this.indexOf("#");
+ if (fragmentIndex == -1)
+ fragmentIndex = this.length;
+ return this.substring(0, fragmentIndex);
+}
+
function isNodeWhitespace()
{
if (!this || this.nodeType !== Node.TEXT_NODE)
@@ -592,31 +600,6 @@ function traversePreviousNode(stayWithin)
return this.parentNode;
}
-function appropriateSelectorForNode(node, justSelector)
-{
- if (!node)
- return "";
-
- var lowerCaseName = node.localName || node.nodeName.toLowerCase();
-
- var id = node.getAttribute("id");
- if (id) {
- var selector = "#" + id;
- return (justSelector ? selector : lowerCaseName + selector);
- }
-
- var className = node.getAttribute("class");
- if (className) {
- var selector = "." + className.replace(/\s+/, ".");
- return (justSelector ? selector : lowerCaseName + selector);
- }
-
- if (lowerCaseName === "input" && node.getAttribute("type"))
- return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
-
- return lowerCaseName;
-}
-
function getDocumentForNode(node)
{
return node.nodeType == Node.DOCUMENT_NODE ? node : node.ownerDocument;
diff --git a/Source/WebCore/inspector/generate-inspector-idl b/Source/WebCore/inspector/generate-inspector-idl
index f2f0e35..b5ecb78 100755
--- a/Source/WebCore/inspector/generate-inspector-idl
+++ b/Source/WebCore/inspector/generate-inspector-idl
@@ -81,6 +81,8 @@ type_traits = {
"object": "Object"
}
+ref_types = {}
+
macro_traits = {
"Database": "DATABASE",
"DOMStorage": "DOM_STORAGE",
@@ -90,34 +92,61 @@ macro_traits = {
"Profiler": "JAVASCRIPT_DEBUGGER"
}
-def param_type(param):
+def full_qualified_type_id(domain_name, type_id):
+ if type_id.find(".") == -1:
+ return "%s.%s" % (domain_name, type_id)
+ return type_id
+
+
+def param_type(domain_name, param):
if "type" in param:
- return type_traits[param["type"]];
+ return type_traits[param["type"]]
if "$ref" in param:
- return "Object"
+ type_id = full_qualified_type_id(domain_name, param["$ref"])
+ if type_id in ref_types:
+ ref_type = ref_types[type_id]
+ return type_traits[ref_type["type"]]
+ else:
+ return "Object"
for domain in json_api:
domain_name = domain["domain"]
if domain_name in macro_traits:
output_file.write("\n#if defined(ENABLE_%s) && ENABLE_%s" % (macro_traits[domain_name], macro_traits[domain_name]))
output_file.write("\n interface [Conditional=INSPECTOR] %s {" % domain_name)
+
+ if "types" in domain:
+ for type in domain["types"]:
+ type_id = full_qualified_type_id(domain_name, type["id"])
+ ref_types[type_id] = type;
+
if "commands" in domain:
for command in domain["commands"]:
- params = [];
+ params = []
if ("parameters" in command):
for in_param in command["parameters"]:
- params.append("in %s %s" % (param_type(in_param), in_param["name"]))
+ if ("optional" in in_param):
+ optional = " [optional]"
+ else:
+ optional = ""
+ params.append("in%s %s %s" % (optional, param_type(domain_name, in_param), in_param["name"]))
if ("returns" in command):
for out_param in command["returns"]:
- params.append("out %s %s" % (param_type(out_param), out_param["name"]))
+ params.append("out %s %s" % (param_type(domain_name, out_param), out_param["name"]))
output_file.write("\n void %s(%s);" % (command["name"], ", ".join(params)))
+
if "events" in domain:
for event in domain["events"]:
- params = [];
+ params = []
if ("parameters" in event):
for in_param in event["parameters"]:
- params.append("out %s %s" % (param_type(in_param), in_param["name"]))
+ if ("optional" in in_param):
+ optional = " [optional]"
+ else:
+ optional = ""
+ params.append("out%s %s %s" % (optional, param_type(domain_name, in_param), in_param["name"]))
output_file.write("\n [event] void %s(%s);" % (event["name"], ", ".join(params)))
+
output_file.write("\n };")
if domain["domain"] in macro_traits:
output_file.write("\n#endif // ENABLE_%s" % macro_traits[domain["domain"]])
diff --git a/Source/WebCore/inspector/inline-javascript-imports.py b/Source/WebCore/inspector/inline-javascript-imports.py
new file mode 100755
index 0000000..5f1d9e4
--- /dev/null
+++ b/Source/WebCore/inspector/inline-javascript-imports.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2011 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.
+#
+
+# This script replaces calls to importScripts with script sources
+# in input script file and dumps result into output script file.
+
+from cStringIO import StringIO
+
+import os.path
+import re
+import sys
+
+
+def main(argv):
+
+ if len(argv) < 3:
+ print('usage: %s inputFile importsDir outputFile' % argv[0])
+ return 1
+
+ inputFileName = argv[1]
+ importsDir = argv[2]
+ outputFileName = argv[3]
+
+ inputFile = open(inputFileName, 'r')
+ inputScript = inputFile.read()
+ inputFile.close()
+
+ def replace(match):
+ importFileName = match.group(1)
+ fullPath = os.path.join(importsDir, importFileName)
+ if not os.access(fullPath, os.F_OK):
+ raise Exception('File %s referenced in %s not found on any source paths, '
+ 'check source tree for consistency' %
+ (importFileName, inputFileName))
+ importFile = open(fullPath, 'r')
+ importScript = importFile.read()
+ importFile.close()
+ return importScript
+
+ outputScript = re.sub(r'importScripts\([\'"]([^\'"]+)[\'"]\)', replace, inputScript)
+
+ outputFile = open(outputFileName, 'w')
+ outputFile.write(outputScript)
+ outputFile.close()
+
+ # Touch output file directory to make sure that Xcode will copy
+ # modified resource files.
+ if sys.platform == 'darwin':
+ outputDirName = os.path.dirname(outputFileName)
+ os.utime(outputDirName, None)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))