From 2fc2651226baac27029e38c9d6ef883fa32084db Mon Sep 17 00:00:00 2001 From: Steve Block Date: Wed, 18 May 2011 13:36:51 +0100 Subject: Merge WebKit at r78450: Initial merge by git. Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1 --- Source/WebCore/inspector/CodeGeneratorInspector.pm | 149 ++- Source/WebCore/inspector/InjectedScript.cpp | 14 +- Source/WebCore/inspector/InjectedScript.h | 8 +- Source/WebCore/inspector/InjectedScriptHost.cpp | 40 +- Source/WebCore/inspector/InjectedScriptHost.h | 14 +- Source/WebCore/inspector/InjectedScriptSource.js | 218 ++-- Source/WebCore/inspector/Inspector.idl | 459 +++---- Source/WebCore/inspector/InspectorAgent.cpp | 1269 ++++++++++++++++++ Source/WebCore/inspector/InspectorAgent.h | 327 +++++ .../inspector/InspectorApplicationCacheAgent.cpp | 16 +- .../inspector/InspectorApplicationCacheAgent.h | 9 +- .../inspector/InspectorBrowserDebuggerAgent.cpp | 68 +- .../inspector/InspectorBrowserDebuggerAgent.h | 15 +- Source/WebCore/inspector/InspectorCSSAgent.cpp | 28 +- Source/WebCore/inspector/InspectorCSSAgent.h | 22 +- Source/WebCore/inspector/InspectorClient.h | 3 - Source/WebCore/inspector/InspectorConsoleAgent.cpp | 48 +- Source/WebCore/inspector/InspectorConsoleAgent.h | 6 +- .../inspector/InspectorConsoleInstrumentation.h | 127 ++ Source/WebCore/inspector/InspectorController.cpp | 1346 ++------------------ Source/WebCore/inspector/InspectorController.h | 368 +----- Source/WebCore/inspector/InspectorDOMAgent.cpp | 154 +-- Source/WebCore/inspector/InspectorDOMAgent.h | 41 +- .../WebCore/inspector/InspectorDOMStorageAgent.cpp | 3 + .../WebCore/inspector/InspectorDOMStorageAgent.h | 12 +- .../inspector/InspectorDOMStorageResource.h | 1 + .../WebCore/inspector/InspectorDatabaseAgent.cpp | 94 +- Source/WebCore/inspector/InspectorDatabaseAgent.h | 17 +- .../inspector/InspectorDatabaseInstrumentation.h | 52 + .../inspector/InspectorDatabaseResource.cpp | 11 - .../WebCore/inspector/InspectorDatabaseResource.h | 2 - .../WebCore/inspector/InspectorDebuggerAgent.cpp | 191 ++- Source/WebCore/inspector/InspectorDebuggerAgent.h | 67 +- .../WebCore/inspector/InspectorFileSystemAgent.cpp | 171 --- .../WebCore/inspector/InspectorFileSystemAgent.h | 77 -- .../inspector/InspectorFrontendClientLocal.cpp | 24 +- .../inspector/InspectorFrontendClientLocal.h | 12 +- Source/WebCore/inspector/InspectorFrontendHost.cpp | 5 +- .../WebCore/inspector/InspectorInstrumentation.cpp | 353 ++--- .../WebCore/inspector/InspectorInstrumentation.h | 511 ++++---- .../WebCore/inspector/InspectorProfilerAgent.cpp | 55 +- Source/WebCore/inspector/InspectorProfilerAgent.h | 10 +- .../WebCore/inspector/InspectorResourceAgent.cpp | 87 +- Source/WebCore/inspector/InspectorResourceAgent.h | 3 +- Source/WebCore/inspector/InspectorRuntimeAgent.cpp | 8 +- Source/WebCore/inspector/InspectorRuntimeAgent.h | 4 +- Source/WebCore/inspector/InspectorSettings.cpp | 95 -- Source/WebCore/inspector/InspectorSettings.h | 73 -- Source/WebCore/inspector/InspectorState.cpp | 122 +- Source/WebCore/inspector/InspectorState.h | 93 +- .../WebCore/inspector/InspectorTimelineAgent.cpp | 35 +- Source/WebCore/inspector/InspectorTimelineAgent.h | 19 +- Source/WebCore/inspector/InspectorValues.cpp | 40 +- Source/WebCore/inspector/InspectorValues.h | 19 +- Source/WebCore/inspector/ScriptBreakpoint.cpp | 74 -- Source/WebCore/inspector/ScriptBreakpoint.h | 25 +- .../front-end/ApplicationCacheItemsView.js | 2 +- Source/WebCore/inspector/front-end/AuditRules.js | 4 +- Source/WebCore/inspector/front-end/AuditsPanel.js | 2 +- Source/WebCore/inspector/front-end/Breakpoint.js | 44 +- .../inspector/front-end/BreakpointManager.js | 80 +- .../inspector/front-end/BreakpointsSidebarPane.js | 61 +- .../WebCore/inspector/front-end/CSSCompletions.js | 7 +- .../inspector/front-end/CSSKeywordCompletions.js | 2 +- .../WebCore/inspector/front-end/CSSStyleModel.js | 26 +- Source/WebCore/inspector/front-end/ChangesView.js | 80 -- Source/WebCore/inspector/front-end/ConsoleView.js | 34 +- Source/WebCore/inspector/front-end/ContextMenu.js | 1 + Source/WebCore/inspector/front-end/DOMAgent.js | 24 +- Source/WebCore/inspector/front-end/DataGrid.js | 5 + .../WebCore/inspector/front-end/DebuggerModel.js | 171 ++- .../inspector/front-end/DetailedHeapshotView.js | 92 ++ Source/WebCore/inspector/front-end/Drawer.js | 89 +- .../WebCore/inspector/front-end/ElementsPanel.js | 11 +- .../inspector/front-end/ElementsTreeOutline.js | 3 +- Source/WebCore/inspector/front-end/ExtensionAPI.js | 4 +- .../inspector/front-end/ExtensionAPISchema.json | 513 ++++++++ .../WebCore/inspector/front-end/ExtensionPanel.js | 2 +- .../WebCore/inspector/front-end/ExtensionServer.js | 13 +- .../WebCore/inspector/front-end/FileSystemView.js | 211 --- .../WebCore/inspector/front-end/GoToLineDialog.js | 4 +- Source/WebCore/inspector/front-end/HeapSnapshot.js | 909 +++++++++++++ .../inspector/front-end/HeapSnapshotView.js | 196 +-- .../WebCore/inspector/front-end/NetworkManager.js | 234 ++-- Source/WebCore/inspector/front-end/NetworkPanel.js | 87 +- .../inspector/front-end/ObjectPropertiesSection.js | 13 +- .../inspector/front-end/PleaseWaitMessage.js | 107 ++ .../WebCore/inspector/front-end/ProfilesPanel.js | 110 +- Source/WebCore/inspector/front-end/Resource.js | 44 +- .../inspector/front-end/ResourceTreeModel.js | 61 +- Source/WebCore/inspector/front-end/ResourceView.js | 43 +- .../WebCore/inspector/front-end/ResourcesPanel.js | 96 +- .../inspector/front-end/ScopeChainSidebarPane.js | 21 +- Source/WebCore/inspector/front-end/Script.js | 2 +- .../WebCore/inspector/front-end/ScriptFormatter.js | 162 +-- .../inspector/front-end/ScriptFormatterWorker.js | 24 +- Source/WebCore/inspector/front-end/ScriptView.js | 96 -- Source/WebCore/inspector/front-end/ScriptsPanel.js | 188 +-- Source/WebCore/inspector/front-end/Settings.js | 14 +- .../inspector/front-end/ShowMoreDataGridNode.js | 78 ++ .../inspector/front-end/SidebarTreeElement.js | 4 +- Source/WebCore/inspector/front-end/SourceFrame.js | 371 +++--- .../inspector/front-end/SourceFrameContent.js | 153 +++ .../inspector/front-end/SourceHTMLTokenizer.js | 291 +++-- .../inspector/front-end/SourceHTMLTokenizer.re2js | 62 +- Source/WebCore/inspector/front-end/SourceView.js | 208 --- .../inspector/front-end/StylesSidebarPane.js | 39 +- Source/WebCore/inspector/front-end/TextPrompt.js | 7 +- Source/WebCore/inspector/front-end/TextViewer.js | 964 +++++++++----- .../inspector/front-end/UglifyJS/parse-js.js | 92 +- .../inspector/front-end/UglifyJS/process.js | 476 +++---- .../front-end/WatchExpressionsSidebarPane.js | 2 +- Source/WebCore/inspector/front-end/WebKit.qrc | 9 +- Source/WebCore/inspector/front-end/inspector.css | 37 +- Source/WebCore/inspector/front-end/inspector.html | 15 +- Source/WebCore/inspector/front-end/inspector.js | 137 +- .../WebCore/inspector/front-end/networkPanel.css | 12 + Source/WebCore/inspector/front-end/textViewer.css | 41 +- 118 files changed, 7883 insertions(+), 6121 deletions(-) create mode 100644 Source/WebCore/inspector/InspectorAgent.cpp create mode 100644 Source/WebCore/inspector/InspectorAgent.h create mode 100644 Source/WebCore/inspector/InspectorConsoleInstrumentation.h create mode 100644 Source/WebCore/inspector/InspectorDatabaseInstrumentation.h delete mode 100644 Source/WebCore/inspector/InspectorFileSystemAgent.cpp delete mode 100644 Source/WebCore/inspector/InspectorFileSystemAgent.h delete mode 100644 Source/WebCore/inspector/InspectorSettings.cpp delete mode 100644 Source/WebCore/inspector/InspectorSettings.h delete mode 100644 Source/WebCore/inspector/ScriptBreakpoint.cpp delete mode 100644 Source/WebCore/inspector/front-end/ChangesView.js create mode 100644 Source/WebCore/inspector/front-end/DetailedHeapshotView.js create mode 100755 Source/WebCore/inspector/front-end/ExtensionAPISchema.json delete mode 100644 Source/WebCore/inspector/front-end/FileSystemView.js create mode 100644 Source/WebCore/inspector/front-end/HeapSnapshot.js create mode 100644 Source/WebCore/inspector/front-end/PleaseWaitMessage.js delete mode 100644 Source/WebCore/inspector/front-end/ScriptView.js create mode 100644 Source/WebCore/inspector/front-end/ShowMoreDataGridNode.js create mode 100644 Source/WebCore/inspector/front-end/SourceFrameContent.js delete mode 100644 Source/WebCore/inspector/front-end/SourceView.js (limited to 'Source/WebCore/inspector') diff --git a/Source/WebCore/inspector/CodeGeneratorInspector.pm b/Source/WebCore/inspector/CodeGeneratorInspector.pm index e215a91..e4e19b0 100644 --- a/Source/WebCore/inspector/CodeGeneratorInspector.pm +++ b/Source/WebCore/inspector/CodeGeneratorInspector.pm @@ -60,7 +60,7 @@ $typeTransform{"InjectedScript"} = { "domainAccessor" => "m_inspectorAgent->injectedScriptAgent()", }; $typeTransform{"Inspector"} = { - "forwardHeader" => "InspectorController.h", # FIXME: Temporary solution until extracting the real InspectorAgent from InspectorController. + "forwardHeader" => "InspectorAgent.h", "domainAccessor" => "m_inspectorAgent", }; $typeTransform{"Network"} = { @@ -205,18 +205,20 @@ my $namespace; my $backendClassName; my $backendJSStubName; my %backendTypes; -my %backendMethods; +my @backendMethods; my @backendMethodsImpl; +my %backendMethodSignatures; my $backendConstructor; my @backendConstantDeclarations; my @backendConstantDefinitions; my $backendFooter; -my @backendStubJS; +my @backendJSStubs; my $frontendClassName; my %frontendTypes; -my %frontendMethods; +my @frontendMethods; my @frontendMethodsImpl; +my %frontendMethodSignatures; my $frontendConstructor; my @frontendConstantDeclarations; my @frontendConstantDefinitions; @@ -259,17 +261,16 @@ sub GenerateInterface my $className = $interface->name; - $frontendClassName = $className . "Frontend"; + $frontendClassName = "InspectorFrontend"; $frontendConstructor = " ${frontendClassName}(InspectorClient* inspectorClient) : m_inspectorClient(inspectorClient) { }"; - $frontendFooter = " InspectorClient* m_inspectorClient;"; + $frontendFooter = " private:\n InspectorClient* m_inspectorClient;"; $frontendTypes{"String"} = 1; $frontendTypes{"InspectorClient"} = 1; $frontendTypes{"PassRefPtr"} = 1; - $backendClassName = $className . "BackendDispatcher"; - $backendJSStubName = $className . "BackendStub"; + $backendClassName = "InspectorBackendDispatcher"; + $backendJSStubName = "InspectorBackendStub"; my @backendHead; - push(@backendHead, " typedef InspectorController InspectorAgent;"); # FIXME: Temporary substitution until extracting InspectorAgent from InspectorController. push(@backendHead, " ${backendClassName}(InspectorAgent* inspectorAgent) : m_inspectorAgent(inspectorAgent) { }"); push(@backendHead, " void reportProtocolError(const long callId, const String& errorText) const;"); push(@backendHead, " void dispatch(const String& message);"); @@ -281,12 +282,7 @@ sub GenerateInterface $backendTypes{"PassRefPtr"} = 1; $backendTypes{"Object"} = 1; - push(@backendMethodsImpl, generateBackendMessageParser()); generateFunctions($interface); - - # Make dispatcher methods private on the backend. - push(@backendConstantDeclarations, ""); - push(@backendConstantDeclarations, "private:"); } sub generateFunctions @@ -295,55 +291,48 @@ sub generateFunctions foreach my $function (@{$interface->functions}) { if ($function->signature->extendedAttributes->{"notify"}) { - generateFrontendFunction($function); + generateFrontendFunction($interface, $function); } else { - generateBackendFunction($function); + generateBackendFunction($interface, $function); } } - push(@backendMethodsImpl, generateBackendDispatcher()); - push(@backendMethodsImpl, generateBackendReportProtocolError()); - foreach my $type (keys %backendTypes) { - if ($typeTransform{$type}{"JSONType"}) { - push(@backendMethodsImpl, generateArgumentGetters($type)); - } - } - - @backendStubJS = generateBackendStubJS($interface); + collectBackendJSStubFunctions($interface); } sub generateFrontendFunction { + my $interface = shift; my $function = shift; my $functionName = $function->signature->name; - my $domain = $function->signature->extendedAttributes->{"domain"} || "Inspector"; + my $domain = $interface->name; my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface. map($frontendTypes{$_->type} = 1, @argsFiltered); # register required types. my $arguments = join(", ", map($typeTransform{$_->type}->{"param"} . " " . $_->name, @argsFiltered)); # prepare arguments for function signature. my $signature = " void ${functionName}(${arguments});"; - if (!$frontendMethods{${signature}}) { - $frontendMethods{${signature}} = 1; - - my @function; - push(@function, "void ${frontendClassName}::${functionName}(${arguments})"); - push(@function, "{"); - push(@function, " RefPtr ${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 payloadDataObject = InspectorObject::create();"); - my @pushArguments = map(" payloadDataObject->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered); - push(@function, @pushArguments); - push(@function, " ${functionName}Message->setObject(\"data\", payloadDataObject);"); - push(@function, " m_inspectorClient->sendMessageToFrontend(${functionName}Message->toJSONString());"); - - push(@function, "}"); - push(@function, ""); - push(@frontendMethodsImpl, @function); - } + !$frontendMethodSignatures{${signature}} || die "Duplicate frontend function was detected for signature '$signature'."; + $frontendMethodSignatures{${signature}} = 1; + push(@frontendMethods, $signature); + + my @function; + push(@function, "void ${frontendClassName}::${functionName}(${arguments})"); + push(@function, "{"); + push(@function, " RefPtr ${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 payloadDataObject = InspectorObject::create();"); + my @pushArguments = map(" payloadDataObject->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered); + push(@function, @pushArguments); + push(@function, " ${functionName}Message->setObject(\"data\", payloadDataObject);"); + push(@function, " m_inspectorClient->sendMessageToFrontend(${functionName}Message->toJSONString());"); + + push(@function, "}"); + push(@function, ""); + push(@frontendMethodsImpl, @function); } sub camelCase @@ -356,29 +345,32 @@ sub camelCase sub generateBackendFunction { + my $interface = shift; my $function = shift; my $functionName = $function->signature->name; + my $fullQualifiedFunctionName = $interface->name . "_" . $function->signature->name; - push(@backendConstantDeclarations, " static const char* ${functionName}Cmd;"); - push(@backendConstantDefinitions, "const char* ${backendClassName}::${functionName}Cmd = \"${functionName}\";"); + push(@backendConstantDeclarations, " static const char* ${fullQualifiedFunctionName}Cmd;"); + push(@backendConstantDefinitions, "const char* ${backendClassName}::${fullQualifiedFunctionName}Cmd = \"${functionName}\";"); map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters}); my @outArgs = grep($_->direction eq "out", @{$function->parameters}); - my $signature = " void ${functionName}(long callId, InspectorObject* requestMessageObject);"; - !$backendMethods{${signature}} || die "Duplicate function was detected for signature '$signature'."; - $backendMethods{${signature}} = $functionName; + my $signature = " void ${fullQualifiedFunctionName}(long callId, InspectorObject* requestMessageObject);"; + !$backendMethodSignatures{${signature}} || die "Duplicate function was detected for signature '$signature'."; + $backendMethodSignatures{${signature}} = "$fullQualifiedFunctionName"; + push(@backendMethods, ${signature}); my @function; my $requestMessageObject = scalar(@inArgs) ? " requestMessageObject" : ""; - push(@function, "void ${backendClassName}::${functionName}(long callId, InspectorObject*$requestMessageObject)"); + push(@function, "void ${backendClassName}::${fullQualifiedFunctionName}(long callId, InspectorObject*$requestMessageObject)"); push(@function, "{"); push(@function, " RefPtr protocolErrors = InspectorArray::create();"); push(@function, ""); - my $domain = $function->signature->extendedAttributes->{"domain"} || "Inspector"; + my $domain = $interface->name; my $domainAccessor = $typeTransform{$domain}->{"domainAccessor"}; $backendTypes{$domain} = 1; push(@function, " if (!$domainAccessor)"); @@ -463,7 +455,7 @@ sub generateArgumentGetters my $return = $typeTransform{$type}{"return"} ? $typeTransform{$type}{"return"} : $typeTransform{$type}{"param"}; my $typeString = camelCase($type); - push(@backendConstantDeclarations, "$return get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors);"); + push(@backendConstantDeclarations, " $return get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors);"); my $getterBody = << "EOF"; $return InspectorBackendDispatcher::get$typeString(InspectorObject* object, const String& name, InspectorArray* protocolErrors) @@ -491,8 +483,7 @@ EOF sub generateBackendDispatcher { my @body; - my @methods = map($backendMethods{$_}, keys %backendMethods); - my @mapEntries = map(" dispatchMap.add(${_}Cmd, &${backendClassName}::$_);", @methods); + my @mapEntries = map(" dispatchMap.add(${_}Cmd, &${backendClassName}::$_);", map ($backendMethodSignatures{$_}, @backendMethods)); my $mapEntries = join("\n", @mapEntries); my $backendDispatcherBody = << "EOF"; @@ -573,30 +564,31 @@ bool ${backendClassName}::getCommandName(const String& message, String* result) return commandValue->asString(result); } - EOF return split("\n", $messageParserBody); } -sub generateBackendStubJS +sub collectBackendJSStubFunctions { my $interface = shift; - my @backendFunctions = grep(!$_->signature->extendedAttributes->{"notify"}, @{$interface->functions}); - my @JSStubs; + my @functions = grep(!$_->signature->extendedAttributes->{"notify"}, @{$interface->functions}); + my $domain = $interface->name; - foreach my $function (@backendFunctions) { + foreach my $function (@functions) { my $name = $function->signature->name; - my $domain = $function->signature->extendedAttributes->{"domain"}; my $argumentNames = join(",", map("\"" . $_->name . "\": \"" . $typeTransform{$_->type}->{"JSType"} . "\"", grep($_->direction eq "in", @{$function->parameters}))); - push(@JSStubs, " this._registerDelegate('{" . + push(@backendJSStubs, " this._registerDelegate('{" . "\"seq\": 0, " . "\"domain\": \"$domain\", " . "\"command\": \"$name\", " . "\"arguments\": {$argumentNames}" . "}');"); } +} - my $JSStubs = join("\n", @JSStubs); +sub generateBackendStubJS +{ + my $JSStubs = join("\n", @backendJSStubs); my $inspectorBackendStubJS = << "EOF"; $licenseTemplate @@ -735,7 +727,7 @@ sub generateHeader my $forwardHeaders = join("\n", sort(map("#include <" . $typeTransform{$_}->{"forwardHeader"} . ">", grep($typeTransform{$_}->{"forwardHeader"}, keys %{$types})))); my $forwardDeclarations = join("\n", sort(map("class " . $typeTransform{$_}->{"forward"} . ";", grep($typeTransform{$_}->{"forward"}, keys %{$types})))); my $constantDeclarations = join("\n", @{$constants}); - my $methodsDeclarations = join("\n", keys %{$methods}); + my $methodsDeclarations = join("\n", @{$methods}); my $headerBody = << "EOF"; // Copyright (c) 2010 The Chromium Authors. All rights reserved. @@ -757,7 +749,6 @@ $constructor $constantDeclarations $methodsDeclarations -private: $footer }; @@ -792,7 +783,7 @@ sub generateSource push(@sourceContent, ""); push(@sourceContent, "namespace $namespace {"); push(@sourceContent, ""); - push (@sourceContent, join("\n", @{$constants})); + push(@sourceContent, join("\n", @{$constants})); push(@sourceContent, ""); push(@sourceContent, @{$methods}); push(@sourceContent, ""); @@ -807,28 +798,46 @@ sub finish { my $object = shift; + push(@backendMethodsImpl, generateBackendDispatcher()); + push(@backendMethodsImpl, generateBackendReportProtocolError()); + open(my $SOURCE, ">$outputDir/$frontendClassName.cpp") || die "Couldn't open file $outputDir/$frontendClassName.cpp"; print $SOURCE join("\n", generateSource($frontendClassName, \%frontendTypes, \@frontendConstantDefinitions, \@frontendMethodsImpl)); close($SOURCE); undef($SOURCE); open(my $HEADER, ">$outputHeadersDir/$frontendClassName.h") || die "Couldn't open file $outputHeadersDir/$frontendClassName.h"; - print $HEADER generateHeader($frontendClassName, \%frontendTypes, $frontendConstructor, \@frontendConstantDeclarations, \%frontendMethods, $frontendFooter); + print $HEADER generateHeader($frontendClassName, \%frontendTypes, $frontendConstructor, \@frontendConstantDeclarations, \@frontendMethods, $frontendFooter); close($HEADER); undef($HEADER); + # Make dispatcher methods private on the backend. + push(@backendConstantDeclarations, ""); + push(@backendConstantDeclarations, "private:"); + + foreach my $type (keys %backendTypes) { + if ($typeTransform{$type}{"JSONType"}) { + push(@backendMethodsImpl, generateArgumentGetters($type)); + } + } + + push(@backendMethodsImpl, generateBackendMessageParser()); + push(@backendMethodsImpl, ""); + + push(@backendConstantDeclarations, ""); + open($SOURCE, ">$outputDir/$backendClassName.cpp") || die "Couldn't open file $outputDir/$backendClassName.cpp"; print $SOURCE join("\n", generateSource($backendClassName, \%backendTypes, \@backendConstantDefinitions, \@backendMethodsImpl)); close($SOURCE); undef($SOURCE); open($HEADER, ">$outputHeadersDir/$backendClassName.h") || die "Couldn't open file $outputHeadersDir/$backendClassName.h"; - print $HEADER join("\n", generateHeader($backendClassName, \%backendTypes, $backendConstructor, \@backendConstantDeclarations, \%backendMethods, $backendFooter)); + print $HEADER join("\n", generateHeader($backendClassName, \%backendTypes, $backendConstructor, \@backendConstantDeclarations, \@backendMethods, $backendFooter)); close($HEADER); undef($HEADER); open(my $JS_STUB, ">$outputDir/$backendJSStubName.js") || die "Couldn't open file $outputDir/$backendJSStubName.js"; - print $JS_STUB join("\n", @backendStubJS); + print $JS_STUB join("\n", generateBackendStubJS()); close($JS_STUB); undef($JS_STUB); } diff --git a/Source/WebCore/inspector/InjectedScript.cpp b/Source/WebCore/inspector/InjectedScript.cpp index 1969f34..9fd606b 100644 --- a/Source/WebCore/inspector/InjectedScript.cpp +++ b/Source/WebCore/inspector/InjectedScript.cpp @@ -44,20 +44,22 @@ InjectedScript::InjectedScript(ScriptObject injectedScriptObject) { } -void InjectedScript::evaluate(const String& expression, const String& objectGroup, RefPtr* result) +void InjectedScript::evaluate(const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result) { ScriptFunctionCall function(m_injectedScriptObject, "evaluate"); function.appendArgument(expression); function.appendArgument(objectGroup); + function.appendArgument(includeCommandLineAPI); makeCall(function, result); } -void InjectedScript::evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, RefPtr* result) +void InjectedScript::evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result) { ScriptFunctionCall function(m_injectedScriptObject, "evaluateOnCallFrame"); function.appendArgument(callFrameId->toJSONString()); function.appendArgument(expression); function.appendArgument(objectGroup); + function.appendArgument(includeCommandLineAPI); makeCall(function, result); } @@ -69,20 +71,20 @@ void InjectedScript::evaluateOnSelf(const String& functionBody, PassRefPtr* result) +void InjectedScript::getCompletions(const String& expression, bool includeCommandLineAPI, RefPtr* result) { ScriptFunctionCall function(m_injectedScriptObject, "getCompletions"); function.appendArgument(expression); - function.appendArgument(includeInspectorCommandLineAPI); + function.appendArgument(includeCommandLineAPI); makeCall(function, result); } -void InjectedScript::getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result) +void InjectedScript::getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeCommandLineAPI, RefPtr* result) { ScriptFunctionCall function(m_injectedScriptObject, "getCompletionsOnCallFrame"); function.appendArgument(callFrameId->toJSONString()); function.appendArgument(expression); - function.appendArgument(includeInspectorCommandLineAPI); + function.appendArgument(includeCommandLineAPI); makeCall(function, result); } diff --git a/Source/WebCore/inspector/InjectedScript.h b/Source/WebCore/inspector/InjectedScript.h index 0a3f24b..0dd41ae 100644 --- a/Source/WebCore/inspector/InjectedScript.h +++ b/Source/WebCore/inspector/InjectedScript.h @@ -50,11 +50,11 @@ public: bool hasNoValue() const { return m_injectedScriptObject.hasNoValue(); } - void evaluate(const String& expression, const String& objectGroup, RefPtr* result); - void evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, RefPtr* result); + void evaluate(const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result); + void evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result); void evaluateOnSelf(const String& functionBody, PassRefPtr argumentsArray, RefPtr* result); - void getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result); - void getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result); + void getCompletions(const String& expression, bool includeCommandLineAPI, RefPtr* result); + void getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeCommandLineAPI, RefPtr* result); void getProperties(PassRefPtr objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr* result); void pushNodeToFrontend(PassRefPtr objectId, RefPtr* result); void resolveNode(long nodeId, RefPtr* result); diff --git a/Source/WebCore/inspector/InjectedScriptHost.cpp b/Source/WebCore/inspector/InjectedScriptHost.cpp index d67adaf..fbb4dbf 100644 --- a/Source/WebCore/inspector/InjectedScriptHost.cpp +++ b/Source/WebCore/inspector/InjectedScriptHost.cpp @@ -39,9 +39,9 @@ #include "HTMLFrameOwnerElement.h" #include "InjectedScript.h" #include "InjectedScriptSource.h" +#include "InspectorAgent.h" #include "InspectorClient.h" #include "InspectorConsoleAgent.h" -#include "InspectorController.h" #include "InspectorDOMAgent.h" #include "InspectorDOMStorageAgent.h" #include "InspectorDatabaseAgent.h" @@ -69,8 +69,8 @@ using namespace std; namespace WebCore { -InjectedScriptHost::InjectedScriptHost(InspectorController* inspectorController) - : m_inspectorController(inspectorController) +InjectedScriptHost::InjectedScriptHost(InspectorAgent* inspectorAgent) + : m_inspectorAgent(inspectorAgent) , m_nextInjectedScriptId(1) , m_lastWorkerId(1 << 31) // Distinguish ids of fake workers from real ones, to minimize the chances they overlap. { @@ -89,8 +89,8 @@ void InjectedScriptHost::evaluateOnSelf(const String& functionBody, PassRefPtrconsoleAgent()->clearConsoleMessages(); + if (m_inspectorAgent) + m_inspectorAgent->consoleAgent()->clearConsoleMessages(); } void InjectedScriptHost::copyText(const String& text) @@ -130,23 +130,23 @@ long InjectedScriptHost::inspectedNode(unsigned long num) #if ENABLE(DATABASE) Database* InjectedScriptHost::databaseForId(long databaseId) { - if (m_inspectorController && m_inspectorController->databaseAgent()) - return m_inspectorController->databaseAgent()->databaseForId(databaseId); + if (m_inspectorAgent && m_inspectorAgent->databaseAgent()) + return m_inspectorAgent->databaseAgent()->databaseForId(databaseId); return 0; } void InjectedScriptHost::selectDatabase(Database* database) { - if (m_inspectorController && m_inspectorController->databaseAgent()) - m_inspectorController->databaseAgent()->selectDatabase(database); + if (m_inspectorAgent && m_inspectorAgent->databaseAgent()) + m_inspectorAgent->databaseAgent()->selectDatabase(database); } #endif #if ENABLE(DOM_STORAGE) void InjectedScriptHost::selectDOMStorage(Storage* storage) { - if (m_inspectorController && m_inspectorController->domStorageAgent()) - m_inspectorController->domStorageAgent()->selectDOMStorage(storage); + if (m_inspectorAgent && m_inspectorAgent->domStorageAgent()) + m_inspectorAgent->domStorageAgent()->selectDOMStorage(storage); } #endif @@ -166,7 +166,7 @@ InjectedScript InjectedScriptHost::injectedScriptForObjectId(InspectorObject* ob InjectedScript InjectedScriptHost::injectedScriptForMainFrame() { - return injectedScriptFor(mainWorldScriptState(m_inspectorController->inspectedPage()->mainFrame())); + return injectedScriptFor(mainWorldScriptState(m_inspectorAgent->inspectedPage()->mainFrame())); } void InjectedScriptHost::discardInjectedScripts() @@ -192,16 +192,16 @@ void InjectedScriptHost::releaseWrapperObjectGroup(long injectedScriptId, const InspectorDOMAgent* InjectedScriptHost::inspectorDOMAgent() { - if (!m_inspectorController) + if (!m_inspectorAgent) return 0; - return m_inspectorController->domAgent(); + return m_inspectorAgent->domAgent(); } InspectorFrontend* InjectedScriptHost::frontend() { - if (!m_inspectorController) + if (!m_inspectorAgent) return 0; - return m_inspectorController->frontend(); + return m_inspectorAgent->frontend(); } String InjectedScriptHost::injectedScriptSource() @@ -223,14 +223,14 @@ long InjectedScriptHost::nextWorkerId() void InjectedScriptHost::didCreateWorker(long id, const String& url, bool isSharedWorker) { - if (m_inspectorController) - m_inspectorController->didCreateWorker(id, url, isSharedWorker); + if (m_inspectorAgent) + m_inspectorAgent->didCreateWorker(id, url, isSharedWorker); } void InjectedScriptHost::didDestroyWorker(long id) { - if (m_inspectorController) - m_inspectorController->didDestroyWorker(id); + if (m_inspectorAgent) + m_inspectorAgent->didDestroyWorker(id); } #endif // ENABLE(WORKERS) diff --git a/Source/WebCore/inspector/InjectedScriptHost.h b/Source/WebCore/inspector/InjectedScriptHost.h index 108f118..f51f8da 100644 --- a/Source/WebCore/inspector/InjectedScriptHost.h +++ b/Source/WebCore/inspector/InjectedScriptHost.h @@ -31,7 +31,7 @@ #define InjectedScriptHost_h #include "Console.h" -#include "InspectorController.h" +#include "InspectorAgent.h" #include "PlatformString.h" #include "ScriptState.h" @@ -52,9 +52,9 @@ class Storage; class InjectedScriptHost : public RefCounted { public: - static PassRefPtr create(InspectorController* inspectorController) + static PassRefPtr create(InspectorAgent* inspectorAgent) { - return adoptRef(new InjectedScriptHost(inspectorController)); + return adoptRef(new InjectedScriptHost(inspectorAgent)); } ~InjectedScriptHost(); @@ -62,8 +62,8 @@ public: // Part of the protocol. void evaluateOnSelf(const String& functionBody, PassRefPtr argumentsArray, RefPtr* result); - InspectorController* inspectorController() { return m_inspectorController; } - void disconnectController() { m_inspectorController = 0; } + InspectorAgent* inspectorAgent() { return m_inspectorAgent; } + void disconnectController() { m_inspectorAgent = 0; } void clearConsoleMessages(); @@ -96,14 +96,14 @@ public: static bool canAccessInspectedWindow(ScriptState*); private: - InjectedScriptHost(InspectorController* inspectorController); + InjectedScriptHost(InspectorAgent*); InspectorDOMAgent* inspectorDOMAgent(); InspectorFrontend* frontend(); String injectedScriptSource(); ScriptObject createInjectedScript(const String& source, ScriptState* scriptState, long id); void discardInjectedScript(ScriptState*); - InspectorController* m_inspectorController; + InspectorAgent* m_inspectorAgent; long m_nextInjectedScriptId; long m_lastWorkerId; typedef HashMap IdToInjectedScriptMap; diff --git a/Source/WebCore/inspector/InjectedScriptSource.js b/Source/WebCore/inspector/InjectedScriptSource.js index 3aa24a6..c88e8e4 100644 --- a/Source/WebCore/inspector/InjectedScriptSource.js +++ b/Source/WebCore/inspector/InjectedScriptSource.js @@ -28,6 +28,20 @@ (function (InjectedScriptHost, inspectedWindow, injectedScriptId) { +function bind(thisObject, memberFunction) +{ + var func = memberFunction; + var args = Array.prototype.slice.call(arguments, 2); + function bound() + { + return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))); + } + bound.toString = function() { + return "bound: " + func; + }; + return bound; +} + var InjectedScript = function() { this._lastBoundObjectId = 1; @@ -186,27 +200,27 @@ InjectedScript.prototype = { return Object.keys(propertyNameSet); }, - getCompletions: function(expression, includeInspectorCommandLineAPI) + getCompletions: function(expression, includeCommandLineAPI) { var props = {}; try { if (!expression) expression = "this"; - var expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false); + var expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false, false); if (typeof expressionResult === "object") this._populatePropertyNames(expressionResult, props); - - if (includeInspectorCommandLineAPI) { - for (var prop in this._commandLineAPI) - props[prop] = true; + + if (includeCommandLineAPI) { + for (var prop in CommandLineAPI.members_) + props[CommandLineAPI.members_[prop]] = true; } } catch(e) { } return props; }, - getCompletionsOnCallFrame: function(callFrameId, expression, includeInspectorCommandLineAPI) + getCompletionsOnCallFrame: function(callFrameId, expression, includeCommandLineAPI) { var props = {}; try { @@ -215,7 +229,7 @@ InjectedScript.prototype = { return props; if (expression) { - var expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression, true); + var expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression, true, false); if (typeof expressionResult === "object") this._populatePropertyNames(expressionResult, props); } else { @@ -225,49 +239,52 @@ InjectedScript.prototype = { this._populatePropertyNames(scopeChain[i], props); } - if (includeInspectorCommandLineAPI) { - for (var prop in this._commandLineAPI) - props[prop] = true; + if (includeCommandLineAPI) { + for (var prop in CommandLineAPI.members_) + props[CommandLineAPI.members_[prop]] = true; } } catch(e) { } return props; }, - evaluate: function(expression, objectGroup) + evaluate: function(expression, objectGroup, injectCommandLineAPI) { - return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup, false); + return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup, false, injectCommandLineAPI); }, - _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame) + _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI) { try { - return this._wrapObject(this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame), objectGroup); + return this._wrapObject(this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGroup); } catch (e) { return InjectedScript.RemoteObject.fromException(e); } }, - _evaluateOn: function(evalFunction, object, expression, isEvalOnCallFrame) + _evaluateOn: function(evalFunction, object, expression, isEvalOnCallFrame, injectCommandLineAPI) { // Only install command line api object for the time of evaluation. // Surround the expression in with statements to inject our command line API so that // the window object properties still take more precedent than our API functions. - inspectedWindow.console._commandLineAPI = this._commandLineAPI; - - // We don't want local variables to be shadowed by global ones when evaluating on CallFrame. - if (!isEvalOnCallFrame) - expression = "with (window) {\n" + expression + "\n} "; - expression = "with (window ? window.console._commandLineAPI : {}) {\n" + expression + "\n}"; - var value = evalFunction.call(object, expression); - - delete inspectedWindow.console._commandLineAPI; - - // When evaluating on call frame error is not thrown, but returned as a value. - if (this._type(value) === "error") - throw value.toString(); - - return value; + + try { + if (injectCommandLineAPI && inspectedWindow.console) { + inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null); + expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}"; + } + + var value = evalFunction.call(object, expression); + + // When evaluating on call frame error is not thrown, but returned as a value. + if (this._type(value) === "error") + throw value.toString(); + + return value; + } finally { + if (injectCommandLineAPI && inspectedWindow.console) + delete inspectedWindow.console._commandLineAPI; + } }, getNodeId: function(node) @@ -291,12 +308,12 @@ InjectedScript.prototype = { return result; }, - evaluateOnCallFrame: function(callFrameId, code, objectGroup) + evaluateOnCallFrame: function(callFrameId, expression, objectGroup, injectCommandLineAPI) { var callFrame = this._callFrameForId(callFrameId); if (!callFrame) return false; - return this._evaluateAndWrap(callFrame.evaluate, callFrame, code, objectGroup, true); + return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI); }, _callFrameForId: function(callFrameId) @@ -471,49 +488,6 @@ InjectedScript.prototype = { { // We don't use String(obj) because inspectedWindow.String is undefined if owning frame navigated to another page. return "" + obj; - }, - - _logEvent: function(event) - { - console.log(event.type, event); - }, - - _normalizeEventTypes: function(types) - { - if (typeof types === "undefined") - types = [ "mouse", "key", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll" ]; - else if (typeof types === "string") - types = [ types ]; - - var result = []; - for (var i = 0; i < types.length; i++) { - if (types[i] === "mouse") - result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout"); - else if (types[i] === "key") - result.splice(0, 0, "keydown", "keyup", "keypress"); - else - result.push(types[i]); - } - return result; - }, - - _inspectedNode: function(num) - { - var nodeId = InjectedScriptHost.inspectedNode(num); - return this._nodeForId(nodeId); - }, - - _bindToScript: function(func) - { - var args = Array.prototype.slice.call(arguments, 1); - function bound() - { - return func.apply(injectedScript, args.concat(Array.prototype.slice.call(arguments))); - } - bound.toString = function() { - return "bound: " + func; - }; - return bound; } } @@ -602,15 +576,48 @@ InjectedScript.CallFrameProxy.prototype = { } } -function CommandLineAPI() +function CommandLineAPI(commandLineAPIImpl, callFrame) +{ + function inScopeVariables(member) + { + if (!callFrame) + return false; + + var scopeChain = callFrame.scopeChain; + for (var i = 0; i < scopeChain.length; ++i) { + if (member in scopeChain[i]) + return true; + } + return false; + } + + for (var i = 0; i < CommandLineAPI.members_.length; ++i) { + var member = CommandLineAPI.members_[i]; + if (member in inspectedWindow || inScopeVariables(member)) + continue; + + this[member] = bind(commandLineAPIImpl, commandLineAPIImpl[member]); + } + + for (var i = 0; i < 5; ++i) { + var member = "$" + i; + if (member in inspectedWindow || inScopeVariables(member)) + continue; + + this.__defineGetter__("$" + i, bind(commandLineAPIImpl, commandLineAPIImpl._inspectedNode, i)); + } +} + +CommandLineAPI.members_ = [ + "$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", + "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear" +]; + +function CommandLineAPIImpl() { - for (var i = 0; i < 5; ++i) - this.__defineGetter__("$" + i, injectedScript._bindToScript(injectedScript._inspectedNode, i)); } -CommandLineAPI.prototype = { - // Only add API functions here, private stuff should go to - // InjectedScript so that it is not suggested by the completion. +CommandLineAPIImpl.prototype = { $: function() { return document.getElementById.apply(document, arguments) @@ -625,8 +632,8 @@ CommandLineAPI.prototype = { { var nodes = []; try { - var doc = context || document; - var results = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null); + var doc = (context && context.ownerDocument) || inspectedWindow.document; + var results = doc.evaluate(xpath, context || doc, null, XPathResult.ANY_TYPE, null); var node; while (node = results.iterateNext()) nodes.push(node); @@ -672,10 +679,10 @@ CommandLineAPI.prototype = { { if (!object || !object.addEventListener || !object.removeEventListener) return; - types = injectedScript._normalizeEventTypes(types); + types = this._normalizeEventTypes(types); for (var i = 0; i < types.length; ++i) { - object.removeEventListener(types[i], injectedScript._logEvent, false); - object.addEventListener(types[i], injectedScript._logEvent, false); + object.removeEventListener(types[i], this._logEvent, false); + object.addEventListener(types[i], this._logEvent, false); } }, @@ -683,9 +690,9 @@ CommandLineAPI.prototype = { { if (!object || !object.addEventListener || !object.removeEventListener) return; - types = injectedScript._normalizeEventTypes(types); + types = this._normalizeEventTypes(types); for (var i = 0; i < types.length; ++i) - object.removeEventListener(types[i], injectedScript._logEvent, false); + object.removeEventListener(types[i], this._logEvent, false); }, inspect: function(object) @@ -718,10 +725,39 @@ CommandLineAPI.prototype = { clear: function() { InjectedScriptHost.clearConsoleMessages(); + }, + + _inspectedNode: function(num) + { + var nodeId = InjectedScriptHost.inspectedNode(num); + return injectedScript._nodeForId(nodeId); + }, + + _normalizeEventTypes: function(types) + { + if (typeof types === "undefined") + types = [ "mouse", "key", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll" ]; + else if (typeof types === "string") + types = [ types ]; + + var result = []; + for (var i = 0; i < types.length; i++) { + if (types[i] === "mouse") + result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout"); + else if (types[i] === "key") + result.splice(0, 0, "keydown", "keyup", "keypress"); + else + result.push(types[i]); + } + return result; + }, + + _logEvent: function(event) + { + console.log(event.type, event); } } -injectedScript._commandLineAPI = new CommandLineAPI(); +injectedScript._commandLineAPIImpl = new CommandLineAPIImpl(); return injectedScript; }) - diff --git a/Source/WebCore/inspector/Inspector.idl b/Source/WebCore/inspector/Inspector.idl index 79b33f6..80c24db 100644 --- a/Source/WebCore/inspector/Inspector.idl +++ b/Source/WebCore/inspector/Inspector.idl @@ -31,286 +31,249 @@ module core { interface [Conditional=INSPECTOR] Inspector { + void addScriptToEvaluateOnLoad(in String scriptSource); + void removeAllScriptsToEvaluateOnLoad(); + void reloadPage(in boolean ignoreCache); + void populateScriptObjects(); + + void openInInspectedWindow(in String url); + void setSearchingForNode(in boolean enabled, out boolean newState); + [notify] void frontendReused(); + [notify] void addNodesToSearchResult(out Array nodeIds); + [notify] void bringToFront(); + [notify] void disconnectFromBackend(); + [notify] void inspectedURLChanged(out String url); + [notify] void domContentEventFired(out double time); + [notify] void loadEventFired(out double time); + [notify] void reset(); + [notify] void showPanel(out String panel); + + [notify] void evaluateForTestInFrontend(out long testCallId, out String script); + void didEvaluateForTestInFrontend(in long testCallId, in String jsonResult); + + void highlightDOMNode(in long nodeId); + void hideDOMNodeHighlight(); + void highlightFrame(in unsigned long frameId); + void hideFrameHighlight(); + [notify] void updateFocusedNode(out long nodeId); + + void setUserAgentOverride(in String userAgent); + + void getCookies(out Array cookies, out String cookiesString); + void deleteCookie(in String cookieName, in String domain); + + // FIXME: dispatch on agents. + void startTimelineProfiler(); + void stopTimelineProfiler(); - /////////////////////////////////////////////////////////////////////// - // generic Inspector's methods - /////////////////////////////////////////////////////////////////////// - - [domain=Inspector] void addScriptToEvaluateOnLoad(in String scriptSource); - [domain=Inspector] void removeAllScriptsToEvaluateOnLoad(); - [domain=Inspector] void reloadPage(); - [domain=Inspector] void populateScriptObjects(); - - [domain=Inspector] void openInInspectedWindow(in String url); - [domain=Inspector] void setSearchingForNode(in boolean enabled, out boolean newState); - [notify, domain=Inspector] void frontendReused(); - [notify, domain=Inspector] void addNodesToSearchResult(out Array nodeIds); - [notify, domain=Inspector] void bringToFront(); - [notify, domain=Inspector] void disconnectFromBackend(); - [notify, domain=Inspector] void inspectedURLChanged(out String url); - [notify, domain=Inspector] void domContentEventFired(out double time); - [notify, domain=Inspector] void loadEventFired(out double time); - [notify, domain=Inspector] void reset(); - [notify, domain=Inspector] void showPanel(out String panel); - - [notify, domain=Inspector] void evaluateForTestInFrontend(out long testCallId, out String script); - [domain=Inspector] void didEvaluateForTestInFrontend(in long testCallId, in String jsonResult); - - [domain=Inspector] void highlightDOMNode(in long nodeId); - [domain=Inspector] void hideDOMNodeHighlight(); - [domain=Inspector] void highlightFrame(in unsigned long frameId); - [domain=Inspector] void hideFrameHighlight(); - [notify, domain=Inspector] void updateFocusedNode(out long nodeId); - - [domain=Inspector] void setExtraHeaders(in Object headers); - - [domain=Inspector] void getCookies(out Array cookies, out String cookiesString); - [domain=Inspector] void deleteCookie(in String cookieName, in String domain); - - /////////////////////////////////////////////////////////////////////// - // Runtime - /////////////////////////////////////////////////////////////////////// - - [domain=Runtime] void evaluate(in String expression, in String objectGroup, out Value result); - [domain=Runtime] void getCompletions(in String expression, in boolean includeInspectorCommandLineAPI, out Value result); - [domain=Runtime] void getProperties(in Object objectId, in boolean ignoreHasOwnProperty, in boolean abbreviate, out Value result); - [domain=Runtime] void setPropertyValue(in Object objectId, in String propertyName, in String expression, out Value result); - [domain=Runtime] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup); - - /////////////////////////////////////////////////////////////////////// - // Injected Script - /////////////////////////////////////////////////////////////////////// - - [domain=InjectedScript] void evaluateOnSelf(in String functionBody, in Array argumentsArray, out Value result); - - /////////////////////////////////////////////////////////////////////// - // Console API - /////////////////////////////////////////////////////////////////////// - - [domain=Console] void setConsoleMessagesEnabled(in boolean enabled, out boolean newState); - [notify, domain=Console] void addConsoleMessage(out Object messageObj); - [notify, domain=Console] void updateConsoleMessageExpiredCount(out unsigned long count); - [notify, domain=Console] void updateConsoleMessageRepeatCount(out unsigned long count); - [domain=Console] void clearConsoleMessages(); - [notify, domain=Console] void consoleMessagesCleared(); - [domain=Console] void setMonitoringXHREnabled(in boolean enabled); - [notify, domain=Console] void monitoringXHRStateChanged(out boolean enabled); - - /////////////////////////////////////////////////////////////////////// - // Network API - /////////////////////////////////////////////////////////////////////// - - [domain=Network] void cachedResources(out Object resources); - [domain=Network] void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out String content); - - [notify, domain=Network] void frameDetachedFromParent(out unsigned long frameId); - [notify, domain=Network] void identifierForInitialRequest(out long identifier, out String url, out Object loader, out Value callStack); - [notify, domain=Network] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse); - [notify, domain=Network] void markResourceAsCached(out long identifier); - [notify, domain=Network] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response); - [notify, domain=Network] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived); - [notify, domain=Network] void didFinishLoading(out long identifier, out double finishTime); - [notify, domain=Network] void didFailLoading(out long identifier, out double time, out String localizedDescription); - [notify, domain=Network] void didLoadResourceFromMemoryCache(out double time, out Object resource); - [notify, domain=Network] void setInitialContent(out long identifier, out String sourceString, out String type); - [notify, domain=Network] void didCommitLoadForFrame(out Object frame, out Object loader); - [notify, domain=Network] void didCreateWebSocket(out unsigned long identifier, out String requestURL); - [notify, domain=Network] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request); - [notify, domain=Network] void didReceiveWebSocketHandshakeResponse(out unsigned long identifier, out double time, out Object response); - [notify, domain=Network] void didCloseWebSocket(out unsigned long identifier, out double time); +#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER + void enableDebugger(); + void disableDebugger(); + void enableProfiler(); + void disableProfiler(); + void startProfiling(); + void stopProfiling(); +#endif // ENABLE_JAVASCRIPT_DEBUGGER + }; -#if defined(ENABLE_DATABASE) && ENABLE_DATABASE + interface [Conditional=INSPECTOR] Runtime { + void evaluate(in String expression, in String objectGroup, in boolean includeCommandLineAPI, out Value result); + void getCompletions(in String expression, in boolean includeCommandLineAPI, out Value result); + void getProperties(in Object objectId, in boolean ignoreHasOwnProperty, in boolean abbreviate, out Value result); + void setPropertyValue(in Object objectId, in String propertyName, in String expression, out Value result); + void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup); + }; - /////////////////////////////////////////////////////////////////////// - // Database API - /////////////////////////////////////////////////////////////////////// + interface [Conditional=INSPECTOR] InjectedScript { + void evaluateOnSelf(in String functionBody, in Array argumentsArray, out Value result); + }; - [domain=Database] void getDatabaseTableNames(in long databaseId, out Array tableNames); - [domain=Database] void executeSQL(in long databaseId, in String query, out boolean success, out long transactionId); + interface [Conditional=INSPECTOR] Console { + void setConsoleMessagesEnabled(in boolean enabled, out boolean newState); + [notify] void addConsoleMessage(out Object messageObj); + [notify] void updateConsoleMessageExpiredCount(out unsigned long count); + [notify] void updateConsoleMessageRepeatCount(out unsigned long count); + void clearConsoleMessages(); + [notify] void consoleMessagesCleared(); + void setMonitoringXHREnabled(in boolean enabled); + }; - [notify, domain=Database] void addDatabase(out Object database); - [notify, domain=Database] void selectDatabase(out int databaseId); - [notify, domain=Database] void sqlTransactionSucceeded(out long transactionId, out Value columnNames, out Value values); - [notify, domain=Database] void sqlTransactionFailed(out long transactionId, out Value sqlError); + interface [Conditional=INSPECTOR] Network { + void cachedResources(out Object resources); + void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out boolean success, out String content); + void setExtraHeaders(in Object headers); + + [notify] void frameDetachedFromParent(out unsigned long frameId); + [notify] void identifierForInitialRequest(out long identifier, out String url, out Object loader, out Value callStack); + [notify] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse); + [notify] void markResourceAsCached(out long identifier); + [notify] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response); + [notify] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived); + [notify] void didFinishLoading(out long identifier, out double finishTime); + [notify] void didFailLoading(out long identifier, out double time, out String localizedDescription); + [notify] void didLoadResourceFromMemoryCache(out double time, out Object resource); + [notify] void setInitialContent(out long identifier, out String sourceString, out String type); + [notify] void didCommitLoadForFrame(out Object frame, out Object loader); + [notify] void didCreateWebSocket(out unsigned long identifier, out String requestURL); + [notify] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request); + [notify] void didReceiveWebSocketHandshakeResponse(out unsigned long identifier, out double time, out Object response); + [notify] void didCloseWebSocket(out unsigned long identifier, out double time); + }; + +#if defined(ENABLE_DATABASE) && ENABLE_DATABASE + interface [Conditional=INSPECTOR] Database { + void getDatabaseTableNames(in long databaseId, out Array tableNames); + void executeSQL(in long databaseId, in String query, out boolean success, out long transactionId); + + [notify] void addDatabase(out Object database); + [notify] void selectDatabase(out int databaseId); + [notify] void sqlTransactionSucceeded(out long transactionId, out Value columnNames, out Value values); + [notify] void sqlTransactionFailed(out long transactionId, out Value sqlError); + }; #endif #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE - - /////////////////////////////////////////////////////////////////////// - // DOM Storage API - /////////////////////////////////////////////////////////////////////// - - [domain=DOMStorage] void getDOMStorageEntries(in long storageId, out Array entries); - [domain=DOMStorage] void setDOMStorageItem(in long storageId, in String key, in String value, out boolean success); - [domain=DOMStorage] void removeDOMStorageItem(in long storageId, in String key, out boolean success); - [notify, domain=DOMStorage] void addDOMStorage(out Object storage); - [notify, domain=DOMStorage] void updateDOMStorage(out int storageId); - [notify, domain=DOMStorage] void selectDOMStorage(out int storageId); + interface [Conditional=INSPECTOR] DOMStorage { + void getDOMStorageEntries(in long storageId, out Array entries); + void setDOMStorageItem(in long storageId, in String key, in String value, out boolean success); + void removeDOMStorageItem(in long storageId, in String key, out boolean success); + [notify] void addDOMStorage(out Object storage); + [notify] void updateDOMStorage(out int storageId); + [notify] void selectDOMStorage(out int storageId); + }; #endif #if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS - - /////////////////////////////////////////////////////////////////////// - // AppCache API - /////////////////////////////////////////////////////////////////////// - - [domain=ApplicationCache] void getApplicationCaches(out Value applicationCaches); - [notify, domain=ApplicationCache] void updateApplicationCacheStatus(out int status); - [notify, domain=ApplicationCache] void updateNetworkState(out boolean isNowOnline); + interface [Conditional=INSPECTOR] ApplicationCache { + void getApplicationCaches(out Value applicationCaches); + [notify] void updateApplicationCacheStatus(out int status); + [notify] void updateNetworkState(out boolean isNowOnline); + }; #endif -#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM - - /////////////////////////////////////////////////////////////////////// - // Filesystem API - /////////////////////////////////////////////////////////////////////// - - [domain=FileSystem] void getFileSystemPathAsync(in unsigned int type, in String origin); - [domain=FileSystem] void revealFolderInOS(in String path); + interface [Conditional=INSPECTOR] DOM { + void getChildNodes(in long nodeId); + void setAttribute(in long elementId, in String name, in String value, out boolean success); + void removeAttribute(in long elementId, in String name, out boolean success); + void setTextNodeValue(in long nodeId, in String value, out boolean success); + void getEventListenersForNode(in long nodeId, out long outNodeId, out Array listenersArray); + void copyNode(in long nodeId); + void removeNode(in long nodeId, out long outNodeId); + void changeTagName(in long nodeId, in String newTagName, out long outNodeId); + void getOuterHTML(in long nodeId, out String outerHTML); + void setOuterHTML(in long nodeId, in String outerHTML, out long outNodeId); + void addInspectedNode(in long nodeId); + void performSearch(in String query, in boolean runSynchronously); + void searchCanceled(); + void pushNodeByPathToFrontend(in String path, out long nodeId); + void resolveNode(in long nodeId, out Value result); + void getNodeProperties(in long nodeId, in Array propertiesArray, out Value result); + void getNodePrototypes(in long nodeId, out Value result); + void pushNodeToFrontend(in Object objectId, out Value result); + + [notify] void setDocument(out Value root); // FIXME: should be requested from the front-end as getDocument. + [notify] void attributesUpdated(out long id, out Array attributes); + [notify] void characterDataModified(out long id, out String newValue); + [notify] void setChildNodes(out long parentId, out Array nodes); + [notify] void setDetachedRoot(out Object root); + [notify] void childNodeCountUpdated(out long id, out int newValue); + [notify] void childNodeInserted(out long parentId, out long prevId, out Object node); + [notify] void childNodeRemoved(out long parentId, out long id); + }; - [notify, domain=FileSystem] void didGetFileSystemPath(out String root, out int type, out String origin); - [notify, domain=FileSystem] void didGetFileSystemError(out int type, out String origin); - [notify, domain=FileSystem] void didGetFileSystemDisabled(); -#endif + interface [Conditional=INSPECTOR] CSS { + void getStylesForNode(in long nodeId, out Value styles); + void getComputedStyleForNode(in long nodeId, out Value style); + void getInlineStyleForNode(in long nodeId, out Value style); + void getAllStyles(out Array styleSheetIds); + void getStyleSheet(in String styleSheetId, out Value styleSheet); + void getStyleSheetText(in String styleSheetId, out String url, out String text); + void setStyleSheetText(in String styleSheetId, in String text, out boolean success); + void setPropertyText(in Object styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style); + void toggleProperty(in Object styleId, in long propertyIndex, in boolean disable, out Value style); + void setRuleSelector(in Object ruleId, in String selector, out Value rule); + void addRule(in long contextNodeId, in String selector, out Value rule); + void getSupportedCSSProperties(out Array cssProperties); + void querySelectorAll(in long documentId, in String selector, out Array result); + }; - /////////////////////////////////////////////////////////////////////// - // DOM API - /////////////////////////////////////////////////////////////////////// - - [domain=DOM] void getChildNodes(in long nodeId); - [domain=DOM] void setAttribute(in long elementId, in String name, in String value, out boolean success); - [domain=DOM] void removeAttribute(in long elementId, in String name, out boolean success); - [domain=DOM] void setTextNodeValue(in long nodeId, in String value, out boolean success); - [domain=DOM] void getEventListenersForNode(in long nodeId, out long outNodeId, out Array listenersArray); - [domain=DOM] void copyNode(in long nodeId); - [domain=DOM] void removeNode(in long nodeId, out long outNodeId); - [domain=DOM] void changeTagName(in long nodeId, in String newTagName, out long outNodeId); - [domain=DOM] void getOuterHTML(in long nodeId, out String outerHTML); - [domain=DOM] void setOuterHTML(in long nodeId, in String outerHTML, out long outNodeId); - [domain=DOM] void addInspectedNode(in long nodeId); - [domain=DOM] void performSearch(in String query, in boolean runSynchronously); - [domain=DOM] void searchCanceled(); - [domain=DOM] void pushNodeByPathToFrontend(in String path, out long nodeId); - [domain=DOM] void resolveNode(in long nodeId, out Value result); - [domain=DOM] void getNodeProperties(in long nodeId, in Array propertiesArray, out Value result); - [domain=DOM] void getNodePrototypes(in long nodeId, out Value result); - [domain=DOM] void pushNodeToFrontend(in Object objectId, out Value result); - - [notify, domain=DOM] void setDocument(out Value root); // FIXME: should be requested from the front-end as getDocument. - [notify, domain=DOM] void attributesUpdated(out long id, out Array attributes); - [notify, domain=DOM] void characterDataModified(out long id, out String newValue); - [notify, domain=DOM] void setChildNodes(out long parentId, out Array nodes); - [notify, domain=DOM] void setDetachedRoot(out Object root); - [notify, domain=DOM] void childNodeCountUpdated(out long id, out int newValue); - [notify, domain=DOM] void childNodeInserted(out long parentId, out long prevId, out Object node); - [notify, domain=DOM] void childNodeRemoved(out long parentId, out long id); - - /////////////////////////////////////////////////////////////////////// - // CSS API - /////////////////////////////////////////////////////////////////////// - - [domain=CSS] void getStylesForNode2(in long nodeId, out Value styles); - [domain=CSS] void getComputedStyleForNode2(in long nodeId, out Value style); - [domain=CSS] void getInlineStyleForNode2(in long nodeId, out Value style); - [domain=CSS] void getAllStyles2(out Array styleSheetIds); - [domain=CSS] void getStyleSheet2(in String styleSheetId, out Value styleSheet); - [domain=CSS] void getStyleSheetText2(in String styleSheetId, out String url, out String text); - [domain=CSS] void setStyleSheetText2(in String styleSheetId, in String text, out boolean success); - [domain=CSS] void setPropertyText2(in Object styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style); - [domain=CSS] void toggleProperty2(in Object styleId, in long propertyIndex, in boolean disable, out Value style); - [domain=CSS] void setRuleSelector2(in Object ruleId, in String selector, out Value rule); - [domain=CSS] void addRule2(in long contextNodeId, in String selector, out Value rule); - [domain=CSS] void getSupportedCSSProperties(out Array cssProperties); - [domain=CSS] void querySelectorAll(in long documentId, in String selector, out Array result); - - /////////////////////////////////////////////////////////////////////// - // Timeline API - /////////////////////////////////////////////////////////////////////// - - [domain=Inspector] void startTimelineProfiler(); - [domain=Inspector] void stopTimelineProfiler(); - [notify, domain=Timeline] void timelineProfilerWasStarted(); - [notify, domain=Timeline] void timelineProfilerWasStopped(); - [notify, domain=Timeline] void addRecordToTimeline(out Object record); + interface [Conditional=INSPECTOR] Timeline { + [notify] void timelineProfilerWasStarted(); + [notify] void timelineProfilerWasStopped(); + [notify] void addRecordToTimeline(out Object record); + }; #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER + interface [Conditional=INSPECTOR] Debugger { + [notify] void debuggerWasEnabled(); + [notify] void debuggerWasDisabled(); - /////////////////////////////////////////////////////////////////////// - // Debugger API - /////////////////////////////////////////////////////////////////////// - - [domain=Inspector] void enableDebugger(in boolean always); - [domain=Inspector] void disableDebugger(in boolean always); - - [domain=Inspector] void setAllBrowserBreakpoints(in Object breakpoints); - - [notify, domain=Debugger] void debuggerWasEnabled(); - [notify, domain=Debugger] void debuggerWasDisabled(); - - [notify, domain=Debugger] void parsedScriptSource(out String sourceID, out String url, out int lineOffset, out int columnOffset, out int length, out int scriptWorldType); - [notify, domain=Debugger] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage); - - [domain=Debugger] void activateBreakpoints(); - [domain=Debugger] void deactivateBreakpoints(); - - [domain=Debugger] void setBreakpoint(in String sourceID, in unsigned int lineNumber, in String condition, in boolean enabled, out String breakpointId, out unsigned int actualLineNumber); - [domain=Debugger] void removeBreakpoint(in String breakpointId); + [notify] void parsedScriptSource(out String sourceID, out String url, out int lineOffset, out int columnOffset, out int length, out int scriptWorldType); + [notify] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage); - [domain=BrowserDebugger] void setDOMBreakpoint(in long nodeId, in long type); - [domain=BrowserDebugger] void removeDOMBreakpoint(in long nodeId, in long type); - [domain=BrowserDebugger] void setEventListenerBreakpoint(in String eventName); - [domain=BrowserDebugger] void removeEventListenerBreakpoint(in String eventName); - [domain=BrowserDebugger] void setXHRBreakpoint(in String url); - [domain=BrowserDebugger] void removeXHRBreakpoint(in String url); + void activateBreakpoints(); + void deactivateBreakpoints(); - [domain=Debugger] void stepOver(); - [domain=Debugger] void stepInto(); - [domain=Debugger] void stepOut(); - [domain=Debugger] void pause(); - [notify, domain=Debugger] void pausedScript(out Object details); - [domain=Debugger] void resume(); - [notify, domain=Debugger] void resumedScript(); // FIXME: Make this out parameter of resume if possible. + void setJavaScriptBreakpoint(in String url, in int lineNumber, in int columnNumber, in String condition, in boolean enabled, out String breakpointId, out Array locations); + void setJavaScriptBreakpointBySourceId(in String sourceId, in int lineNumber, in int columnNumber, in String condition, in boolean enabled, out String breakpointId, out int actualLineNumber, out int actualColumnNumber); + void removeJavaScriptBreakpoint(in String breakpointId); + [notify] void breakpointResolved(out String breakpointId, out String sourceId, out int lineNumber, out int columnNumber); + void continueToLocation(in String sourceId, in int lineNumber, in int columnNumber); - [domain=Debugger] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames); - [domain=Debugger] void getScriptSource(in String sourceID, out String scriptSource); + void stepOver(); + void stepInto(); + void stepOut(); + void pause(); + [notify] void pausedScript(out Object details); + void resume(); + [notify] void resumedScript(); // FIXME: Make this out parameter of resume if possible. - [domain=Debugger] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState); + void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames); + void getScriptSource(in String sourceID, out String scriptSource); - [domain=Debugger] void evaluateOnCallFrame(in Object callFrameId, in String expression, in String objectGroup, out Value result); - [domain=Debugger] void getCompletionsOnCallFrame(in Object callFrameId, in String expression, in boolean includeInspectorCommandLineAPI, out Value result); + void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState); - [notify, domain=Debugger] void breakpointResolved(out String breakpointId, out String sourceID, out unsigned int lineNumber, out String condition, out boolean enabled, out unsigned int originalLineNumber); + void evaluateOnCallFrame(in Object callFrameId, in String expression, in String objectGroup, in boolean includeCommandLineAPI, out Value result); + void getCompletionsOnCallFrame(in Object callFrameId, in String expression, in boolean includeCommandLineAPI, out Value result); #if defined(ENABLE_WORKERS) && ENABLE_WORKERS - [notify, domain=Debugger] void didCreateWorker(out long id, out String url, out boolean isShared); - [notify, domain=Debugger] void didDestroyWorker(out long id); + [notify] void didCreateWorker(out long id, out String url, out boolean isShared); + [notify] void didDestroyWorker(out long id); #endif // ENABLE_WORKERS - /////////////////////////////////////////////////////////////////////// - // Profiler API - /////////////////////////////////////////////////////////////////////// + }; +#endif // ENABLE_JAVASCRIPT_DEBUGGER - [domain=Inspector] void enableProfiler(in boolean always); - [domain=Inspector] void disableProfiler(in boolean always); - [notify, domain=Profiler] void profilerWasEnabled(); - [notify, domain=Profiler] void profilerWasDisabled(); +#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER + interface [Conditional=INSPECTOR] BrowserDebugger { + void setAllBrowserBreakpoints(in Object breakpoints); + void setDOMBreakpoint(in long nodeId, in long type); + void removeDOMBreakpoint(in long nodeId, in long type); + void setEventListenerBreakpoint(in String eventName); + void removeEventListenerBreakpoint(in String eventName); + void setXHRBreakpoint(in String url); + void removeXHRBreakpoint(in String url); + }; +#endif // ENABLE_JAVASCRIPT_DEBUGGER - [domain=Inspector] void startProfiling(); // FIXME: dispatch on profiler agent. - [domain=Inspector] void stopProfiling(); // FIXME: dispatch on profiler agent. +#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER + interface [Conditional=INSPECTOR] Profiler { + [notify] void profilerWasEnabled(); + [notify] void profilerWasDisabled(); - [domain=Profiler] void getProfileHeaders(out Array headers); - [domain=Profiler] void getProfile(in String type, in unsigned long uid, out Object profile); - [domain=Profiler] void removeProfile(in String type, in unsigned long uid); - [domain=Profiler] void clearProfiles(); + void getProfileHeaders(out Array headers); + void getProfile(in String type, in unsigned long uid, out Object profile); + void removeProfile(in String type, in unsigned long uid); + void clearProfiles(); // FIXME: split into Profiler and HeapProfiler. - [domain=Profiler] void takeHeapSnapshot(); - [notify, domain=Profiler] void addProfileHeader(out Object header); - [notify, domain=Profiler] void addHeapSnapshotChunk(out unsigned long uid, out String chunk); - [notify, domain=Profiler] void finishHeapSnapshot(out unsigned long uid); - [notify, domain=Profiler] void setRecordingProfile(out boolean isProfiling); - [notify, domain=Profiler] void resetProfiles(); - -#endif // ENABLE_JAVASCRIPT_DEBUGGER + void takeHeapSnapshot(in boolean detailed); + [notify] void addProfileHeader(out Object header); + [notify] void addHeapSnapshotChunk(out unsigned long uid, out String chunk); + [notify] void finishHeapSnapshot(out unsigned long uid); + [notify] void setRecordingProfile(out boolean isProfiling); + [notify] void resetProfiles(); + [notify] void reportHeapSnapshotProgress(out int done, out int total); }; +#endif // ENABLE_JAVASCRIPT_DEBUGGER } diff --git a/Source/WebCore/inspector/InspectorAgent.cpp b/Source/WebCore/inspector/InspectorAgent.cpp new file mode 100644 index 0000000..9559099 --- /dev/null +++ b/Source/WebCore/inspector/InspectorAgent.cpp @@ -0,0 +1,1269 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2008 Matt Lilek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InspectorAgent.h" + +#if ENABLE(INSPECTOR) + +#include "CachedResource.h" +#include "CachedResourceLoader.h" +#include "Chrome.h" +#include "Cookie.h" +#include "CookieJar.h" +#include "DOMWindow.h" +#include "DOMWrapperWorld.h" +#include "Document.h" +#include "DocumentLoader.h" +#include "Element.h" +#include "FloatConversion.h" +#include "FloatQuad.h" +#include "FloatRect.h" +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "FrameLoader.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "HTMLFrameOwnerElement.h" +#include "HTTPHeaderMap.h" +#include "HitTestResult.h" +#include "InjectedScript.h" +#include "InjectedScriptHost.h" +#include "InspectorBrowserDebuggerAgent.h" +#include "InspectorCSSAgent.h" +#include "InspectorClient.h" +#include "InspectorConsoleAgent.h" +#include "InspectorController.h" +#include "InspectorDOMAgent.h" +#include "InspectorDOMStorageResource.h" +#include "InspectorDatabaseResource.h" +#include "InspectorDebuggerAgent.h" +#include "InspectorFrontend.h" +#include "InspectorFrontendClient.h" +#include "InspectorInstrumentation.h" +#include "InspectorProfilerAgent.h" +#include "InspectorResourceAgent.h" +#include "InspectorRuntimeAgent.h" +#include "InspectorState.h" +#include "InspectorTimelineAgent.h" +#include "InspectorValues.h" +#include "InspectorWorkerResource.h" +#include "IntRect.h" +#include "Page.h" +#include "ProgressTracker.h" +#include "Range.h" +#include "RenderInline.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "ScriptArguments.h" +#include "ScriptCallStack.h" +#include "ScriptFunctionCall.h" +#include "ScriptObject.h" +#include "ScriptProfile.h" +#include "ScriptProfiler.h" +#include "ScriptSourceCode.h" +#include "ScriptState.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include "SharedBuffer.h" +#include "TextEncoding.h" +#include "TextIterator.h" +#include "TextRun.h" +#include "UserGestureIndicator.h" +#include "WindowFeatures.h" +#include +#include +#include +#include +#include +#include + +#if ENABLE(DATABASE) +#include "Database.h" +#include "InspectorDatabaseAgent.h" +#endif + +#if ENABLE(DOM_STORAGE) +#include "InspectorDOMStorageAgent.h" +#include "Storage.h" +#include "StorageArea.h" +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "InspectorApplicationCacheAgent.h" +#endif + +using namespace std; + +namespace WebCore { + +namespace InspectorAgentState { +static const char searchingForNode[] = "searchingForNode"; +static const char timelineProfilerEnabled[] = "timelineProfilerEnabled"; +static const char userInitiatedProfiling[] = "userInitiatedProfiling"; +static const char debuggerEnabled[] = "debuggerEnabled"; +static const char profilerEnabled[] = "profilerEnabled"; +} + +static const char scriptsPanelName[] = "scripts"; +static const char consolePanelName[] = "console"; +static const char profilesPanelName[] = "profiles"; + +InspectorAgent::InspectorAgent(Page* page, InspectorClient* client) + : m_inspectedPage(page) + , m_client(client) + , m_frontend(0) + , m_cssAgent(new InspectorCSSAgent()) + , m_state(new InspectorState(client)) + , m_injectedScriptHost(InjectedScriptHost::create(this)) + , m_consoleAgent(new InspectorConsoleAgent(this)) +#if ENABLE(JAVASCRIPT_DEBUGGER) + , m_profilerAgent(InspectorProfilerAgent::create(this)) +#endif +{ + ASSERT_ARG(page, page); + ASSERT_ARG(client, client); + InspectorInstrumentation::bindInspectorAgent(m_inspectedPage, this); +} + +InspectorAgent::~InspectorAgent() +{ + // These should have been cleared in inspectedPageDestroyed(). + ASSERT(!m_client); + ASSERT(!m_inspectedPage); + ASSERT(!m_highlightedNode); +} + +void InspectorAgent::inspectedPageDestroyed() +{ + if (m_frontend) + m_frontend->disconnectFromBackend(); + + hideHighlight(); + +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_debuggerAgent.clear(); + m_browserDebuggerAgent.clear(); +#endif + + ASSERT(m_inspectedPage); + InspectorInstrumentation::unbindInspectorAgent(m_inspectedPage); + m_inspectedPage = 0; + + releaseFrontendLifetimeAgents(); + m_injectedScriptHost->disconnectController(); + + m_client->inspectorDestroyed(); + m_client = 0; +} + +bool InspectorAgent::searchingForNodeInPage() const +{ + return m_state->getBoolean(InspectorAgentState::searchingForNode); +} + +void InspectorAgent::restoreInspectorStateFromCookie(const String& inspectorStateCookie) +{ + m_state = new InspectorState(m_client, inspectorStateCookie); + + m_frontend->frontendReused(); + m_frontend->inspectedURLChanged(inspectedURL().string()); + pushDataCollectedOffline(); + + m_resourceAgent = InspectorResourceAgent::restore(m_inspectedPage, m_state.get(), m_frontend); + m_timelineAgent = InspectorTimelineAgent::restore(m_state.get(), m_frontend); + +#if ENABLE(JAVASCRIPT_DEBUGGER) + restoreDebugger(false); + restoreProfiler(ProfilerRestoreResetAgent); + if (m_state->getBoolean(InspectorAgentState::userInitiatedProfiling)) + startUserInitiatedProfiling(); +#endif +} + +void InspectorAgent::inspect(Node* node) +{ + if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE) + node = node->parentNode(); + m_nodeToFocus = node; + + if (!m_frontend) + return; + + focusNode(); +} + +void InspectorAgent::focusNode() +{ + if (!enabled()) + return; + + ASSERT(m_frontend); + ASSERT(m_nodeToFocus); + + long id = m_domAgent->pushNodePathToFrontend(m_nodeToFocus.get()); + m_frontend->updateFocusedNode(id); + m_nodeToFocus = 0; +} + +void InspectorAgent::highlight(Node* node) +{ + if (!enabled()) + return; + ASSERT_ARG(node, node); + m_highlightedNode = node; + m_client->highlight(node); +} + +void InspectorAgent::highlightDOMNode(long nodeId) +{ + Node* node = 0; + if (m_domAgent && (node = m_domAgent->nodeForId(nodeId))) + highlight(node); +} + +void InspectorAgent::highlightFrame(unsigned long frameId) +{ + Frame* mainFrame = m_inspectedPage->mainFrame(); + for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext(mainFrame)) { + if (reinterpret_cast(frame) == frameId && frame->ownerElement()) { + highlight(frame->ownerElement()); + return; + } + } +} + +void InspectorAgent::hideHighlight() +{ + if (!enabled()) + return; + m_highlightedNode = 0; + m_client->hideHighlight(); +} + +void InspectorAgent::mouseDidMoveOverElement(const HitTestResult& result, unsigned) +{ + if (!enabled() || !searchingForNodeInPage()) + return; + + Node* node = result.innerNode(); + while (node && node->nodeType() == Node::TEXT_NODE) + node = node->parentNode(); + if (node) + highlight(node); +} + +bool InspectorAgent::handleMousePress() +{ + if (!enabled() || !searchingForNodeInPage()) + return false; + + if (m_highlightedNode) { + RefPtr node = m_highlightedNode; + setSearchingForNode(false); + inspect(node.get()); + } + return true; +} + +void InspectorAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world) +{ + if (world != mainThreadNormalWorld()) + return; + + if (enabled()) { + if (m_frontend && frame == m_inspectedPage->mainFrame()) + m_injectedScriptHost->discardInjectedScripts(); + + if (m_scriptsToEvaluateOnLoad.size()) { + ScriptState* scriptState = mainWorldScriptState(frame); + for (Vector::iterator it = m_scriptsToEvaluateOnLoad.begin(); + it != m_scriptsToEvaluateOnLoad.end(); ++it) { + m_injectedScriptHost->injectScript(*it, scriptState); + } + } + } + + if (!m_inspectorExtensionAPI.isEmpty()) + m_injectedScriptHost->injectScript(m_inspectorExtensionAPI, mainWorldScriptState(frame)); +} + +void InspectorAgent::setSearchingForNode(bool enabled) +{ + if (searchingForNodeInPage() == enabled) + return; + m_state->setBoolean(InspectorAgentState::searchingForNode, enabled); + if (!enabled) + hideHighlight(); +} + +void InspectorAgent::setSearchingForNode(bool enabled, bool* newState) +{ + *newState = enabled; + setSearchingForNode(enabled); +} + +void InspectorAgent::setFrontend(InspectorFrontend* inspectorFrontend) +{ + m_frontend = inspectorFrontend; + createFrontendLifetimeAgents(); + + m_cssAgent->setDOMAgent(m_domAgent.get()); + m_consoleAgent->setFrontend(m_frontend); + + // Initialize Web Inspector title. + m_frontend->inspectedURLChanged(inspectedURL().string()); +} + +void InspectorAgent::disconnectFrontend() +{ + if (!m_frontend) + return; + + // 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(); + + m_frontend = 0; + +#if ENABLE(JAVASCRIPT_DEBUGGER) + // If the window is being closed with the debugger enabled, + // remember this state to re-enable debugger on the next window + // opening. + disableDebugger(); +#endif + setSearchingForNode(false); + + hideHighlight(); + +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_profilerAgent->setFrontend(0); + m_profilerAgent->stopUserInitiatedProfiling(true); +#endif + + m_consoleAgent->setFrontend(0); + + releaseFrontendLifetimeAgents(); + m_userAgentOverride = ""; +} + +InspectorResourceAgent* InspectorAgent::resourceAgent() +{ + if (!m_resourceAgent && m_frontend) + m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_state.get(), m_frontend); + return m_resourceAgent.get(); +} + +void InspectorAgent::createFrontendLifetimeAgents() +{ + m_domAgent = InspectorDOMAgent::create(m_injectedScriptHost.get(), m_frontend); + m_runtimeAgent = InspectorRuntimeAgent::create(m_injectedScriptHost.get()); + +#if ENABLE(DATABASE) + m_databaseAgent = InspectorDatabaseAgent::create(&m_databaseResources, m_frontend); +#endif + +#if ENABLE(DOM_STORAGE) + m_domStorageAgent = InspectorDOMStorageAgent::create(&m_domStorageResources, m_frontend); +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + m_applicationCacheAgent = new InspectorApplicationCacheAgent(m_inspectedPage->mainFrame()->loader()->documentLoader(), m_frontend); +#endif +} + +void InspectorAgent::releaseFrontendLifetimeAgents() +{ + m_resourceAgent.clear(); + m_runtimeAgent.clear(); + m_timelineAgent.clear(); + +#if ENABLE(DATABASE) + m_databaseAgent.clear(); +#endif + +#if ENABLE(DOM_STORAGE) + m_domStorageAgent.clear(); +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + m_applicationCacheAgent.clear(); +#endif + + // This should be invoked prior to m_domAgent destruction. + m_cssAgent->setDOMAgent(0); + m_domAgent.clear(); +} + +void InspectorAgent::populateScriptObjects() +{ + ASSERT(m_frontend); + if (!m_frontend) + return; + +#if ENABLE(JAVASCRIPT_DEBUGGER) + if (m_profilerAgent->enabled()) + m_frontend->profilerWasEnabled(); +#endif + + pushDataCollectedOffline(); + + if (m_nodeToFocus) + focusNode(); + + if (!m_requiredPanel.isEmpty()) { + m_frontend->showPanel(m_requiredPanel); + m_requiredPanel = ""; + } + + restoreDebugger(true); + restoreProfiler(ProfilerRestoreNoAction); + + // Dispatch pending frontend commands + for (Vector >::iterator it = m_pendingEvaluateTestCommands.begin(); it != m_pendingEvaluateTestCommands.end(); ++it) + m_frontend->evaluateForTestInFrontend((*it).first, (*it).second); + m_pendingEvaluateTestCommands.clear(); +} + +void InspectorAgent::pushDataCollectedOffline() +{ + m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); + +#if ENABLE(DATABASE) + DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); + for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) + it->second->bind(m_frontend); +#endif +#if ENABLE(DOM_STORAGE) + DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end(); + for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) + it->second->bind(m_frontend); +#endif +#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS) + WorkersMap::iterator workersEnd = m_workers.end(); + for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it) { + InspectorWorkerResource* worker = it->second.get(); + m_frontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker()); + } +#endif +} + +void InspectorAgent::restoreDebugger(bool eraseStickyBreakpoints) +{ + ASSERT(m_frontend); +#if ENABLE(JAVASCRIPT_DEBUGGER) + if (m_state->getBoolean(InspectorAgentState::debuggerEnabled)) + enableDebugger(eraseStickyBreakpoints); +#endif +} + +void InspectorAgent::restoreProfiler(ProfilerRestoreAction action) +{ + ASSERT(m_frontend); +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_profilerAgent->setFrontend(m_frontend); + if (m_state->getBoolean(InspectorAgentState::profilerEnabled)) + enableProfiler(); + if (action == ProfilerRestoreResetAgent) + m_profilerAgent->resetFrontendProfiles(); +#endif +} + +void InspectorAgent::didCommitLoad(DocumentLoader* loader) +{ + if (!enabled()) + return; + + if (m_resourceAgent) + m_resourceAgent->didCommitLoad(loader); + + ASSERT(m_inspectedPage); + + if (loader->frame() == m_inspectedPage->mainFrame()) { + if (m_frontend) + m_frontend->inspectedURLChanged(loader->url().string()); + + m_injectedScriptHost->discardInjectedScripts(); + m_consoleAgent->reset(); + + if (m_timelineAgent) + m_timelineAgent->didCommitLoad(); + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + if (m_applicationCacheAgent) + m_applicationCacheAgent->didCommitLoad(loader); +#endif + +#if ENABLE(JAVASCRIPT_DEBUGGER) + if (m_debuggerAgent) { + KURL url = inspectedURLWithoutFragment(); + m_debuggerAgent->inspectedURLChanged(url); + if (m_browserDebuggerAgent) + m_browserDebuggerAgent->inspectedURLChanged(url); + } +#endif + +#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) + m_profilerAgent->stopUserInitiatedProfiling(true); + m_profilerAgent->resetState(); +#endif + + if (m_frontend) { + m_frontend->reset(); + m_domAgent->reset(); + m_cssAgent->reset(); + } +#if ENABLE(WORKERS) + m_workers.clear(); +#endif +#if ENABLE(DATABASE) + m_databaseResources.clear(); +#endif +#if ENABLE(DOM_STORAGE) + m_domStorageResources.clear(); +#endif + + if (m_frontend) + m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); + } +} + +void InspectorAgent::domContentLoadedEventFired(DocumentLoader* loader, const KURL& url) +{ + if (!enabled() || !isMainResourceLoader(loader, url)) + return; + + if (m_domAgent) + m_domAgent->mainFrameDOMContentLoaded(); + if (m_timelineAgent) + m_timelineAgent->didMarkDOMContentEvent(); + if (m_frontend) + m_frontend->domContentEventFired(currentTime()); +} + +void InspectorAgent::loadEventFired(DocumentLoader* loader, const KURL& url) +{ + if (!enabled()) + return; + + if (m_domAgent) + m_domAgent->loadEventFired(loader->frame()->document()); + + if (!isMainResourceLoader(loader, url)) + return; + + if (m_timelineAgent) + m_timelineAgent->didMarkLoadEvent(); + if (m_frontend) + m_frontend->loadEventFired(currentTime()); +} + +bool InspectorAgent::isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl) +{ + return loader->frame() == m_inspectedPage->mainFrame() && requestUrl == loader->requestURL(); +} + +void InspectorAgent::setUserAgentOverride(const String& userAgent) +{ + m_userAgentOverride = userAgent; +} + +void InspectorAgent::applyUserAgentOverride(String* userAgent) const +{ + if (!m_userAgentOverride.isEmpty()) + *userAgent = m_userAgentOverride; +} + +void InspectorAgent::startTimelineProfiler() +{ + if (m_timelineAgent || !enabled() || !m_frontend) + return; + + m_timelineAgent = InspectorTimelineAgent::create(m_state.get(), m_frontend); +} + +void InspectorAgent::stopTimelineProfiler() +{ + m_timelineAgent.clear(); +} + +#if ENABLE(WORKERS) +class PostWorkerNotificationToFrontendTask : public ScriptExecutionContext::Task { +public: + static PassOwnPtr create(PassRefPtr worker, InspectorAgent::WorkerAction action) + { + return new PostWorkerNotificationToFrontendTask(worker, action); + } + +private: + PostWorkerNotificationToFrontendTask(PassRefPtr worker, InspectorAgent::WorkerAction action) + : m_worker(worker) + , m_action(action) + { + } + + virtual void performTask(ScriptExecutionContext* scriptContext) + { + if (scriptContext->isDocument()) { + if (InspectorAgent* inspectorAgent = static_cast(scriptContext)->page()->inspectorController()->m_inspectorAgent.get()) + inspectorAgent->postWorkerNotificationToFrontend(*m_worker, m_action); + } + } + +private: + RefPtr m_worker; + InspectorAgent::WorkerAction m_action; +}; + +void InspectorAgent::postWorkerNotificationToFrontend(const InspectorWorkerResource& worker, InspectorAgent::WorkerAction action) +{ + if (!m_frontend) + return; +#if ENABLE(JAVASCRIPT_DEBUGGER) + switch (action) { + case InspectorAgent::WorkerCreated: + m_frontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker()); + break; + case InspectorAgent::WorkerDestroyed: + m_frontend->didDestroyWorker(worker.id()); + break; + } +#endif +} + +void InspectorAgent::didCreateWorker(intptr_t id, const String& url, bool isSharedWorker) +{ + if (!enabled()) + return; + + RefPtr workerResource(InspectorWorkerResource::create(id, url, isSharedWorker)); + m_workers.set(id, workerResource); + if (m_inspectedPage && m_frontend) + m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource, InspectorAgent::WorkerCreated)); +} + +void InspectorAgent::didDestroyWorker(intptr_t id) +{ + if (!enabled()) + return; + + WorkersMap::iterator workerResource = m_workers.find(id); + if (workerResource == m_workers.end()) + return; + if (m_inspectedPage && m_frontend) + m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource->second, InspectorAgent::WorkerDestroyed)); + m_workers.remove(workerResource); +} +#endif // ENABLE(WORKERS) + +#if ENABLE(DATABASE) +void InspectorAgent::didOpenDatabase(PassRefPtr database, const String& domain, const String& name, const String& version) +{ + if (!enabled()) + return; + + RefPtr resource = InspectorDatabaseResource::create(database, domain, name, version); + + m_databaseResources.set(resource->id(), resource); + + // Resources are only bound while visible. + if (m_frontend) + resource->bind(m_frontend); +} +#endif + +void InspectorAgent::getCookies(RefPtr* cookies, WTF::String* cookiesString) +{ + // If we can get raw cookies. + ListHashSet rawCookiesList; + + // If we can't get raw cookies - fall back to String representation + String stringCookiesList; + + // Return value to getRawCookies should be the same for every call because + // the return value is platform/network backend specific, and the call will + // always return the same true/false value. + bool rawCookiesImplemented = false; + + for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { + Document* document = frame->document(); + const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); + CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); + for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) { + Vector docCookiesList; + rawCookiesImplemented = getRawCookies(document, KURL(ParsedURLString, it->second->url()), docCookiesList); + + if (!rawCookiesImplemented) { + // FIXME: We need duplication checking for the String representation of cookies. + ExceptionCode ec = 0; + stringCookiesList += document->cookie(ec); + // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here + // because "document" is the document of the main frame of the page. + ASSERT(!ec); + } else { + int cookiesSize = docCookiesList.size(); + for (int i = 0; i < cookiesSize; i++) { + if (!rawCookiesList.contains(docCookiesList[i])) + rawCookiesList.add(docCookiesList[i]); + } + } + } + } + + if (rawCookiesImplemented) + *cookies = buildArrayForCookies(rawCookiesList); + else + *cookiesString = stringCookiesList; +} + +PassRefPtr InspectorAgent::buildArrayForCookies(ListHashSet& cookiesList) +{ + RefPtr cookies = InspectorArray::create(); + + ListHashSet::iterator end = cookiesList.end(); + ListHashSet::iterator it = cookiesList.begin(); + for (int i = 0; it != end; ++it, i++) + cookies->pushObject(buildObjectForCookie(*it)); + + return cookies; +} + +PassRefPtr InspectorAgent::buildObjectForCookie(const Cookie& cookie) +{ + RefPtr value = InspectorObject::create(); + value->setString("name", cookie.name); + value->setString("value", cookie.value); + value->setString("domain", cookie.domain); + value->setString("path", cookie.path); + value->setNumber("expires", cookie.expires); + value->setNumber("size", (cookie.name.length() + cookie.value.length())); + value->setBoolean("httpOnly", cookie.httpOnly); + value->setBoolean("secure", cookie.secure); + value->setBoolean("session", cookie.session); + return value; +} + +void InspectorAgent::deleteCookie(const String& cookieName, const String& domain) +{ + for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { + Document* document = frame->document(); + if (document->url().host() != domain) + continue; + const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); + CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); + for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) + WebCore::deleteCookie(document, KURL(ParsedURLString, it->second->url()), cookieName); + } +} + +#if ENABLE(DOM_STORAGE) +void InspectorAgent::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame) +{ + if (!enabled()) + return; + + DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end(); + for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) + if (it->second->isSameHostAndType(frame, isLocalStorage)) + return; + + RefPtr domStorage = Storage::create(frame, storageArea); + RefPtr resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame); + + m_domStorageResources.set(resource->id(), resource); + + // Resources are only bound while visible. + if (m_frontend) + resource->bind(m_frontend); +} +#endif + +#if ENABLE(WEB_SOCKETS) +void InspectorAgent::didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL) +{ + if (!enabled()) + return; + ASSERT(m_inspectedPage); + + if (m_resourceAgent) + m_resourceAgent->didCreateWebSocket(identifier, requestURL); + UNUSED_PARAM(documentURL); +} + +void InspectorAgent::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request) +{ + if (m_resourceAgent) + m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); +} + +void InspectorAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response) +{ + if (m_resourceAgent) + m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); +} + +void InspectorAgent::didCloseWebSocket(unsigned long identifier) +{ + if (m_resourceAgent) + m_resourceAgent->didCloseWebSocket(identifier); +} +#endif // ENABLE(WEB_SOCKETS) + +#if ENABLE(JAVASCRIPT_DEBUGGER) +bool InspectorAgent::isRecordingUserInitiatedProfile() const +{ + return m_profilerAgent->isRecordingUserInitiatedProfile(); +} + +void InspectorAgent::startUserInitiatedProfiling() +{ + if (!enabled()) + return; + m_profilerAgent->startUserInitiatedProfiling(); + m_state->setBoolean(InspectorAgentState::userInitiatedProfiling, true); +} + +void InspectorAgent::stopUserInitiatedProfiling() +{ + if (!enabled()) + return; + m_profilerAgent->stopUserInitiatedProfiling(); + m_state->setBoolean(InspectorAgentState::userInitiatedProfiling, false); + showPanel(profilesPanelName); +} + +bool InspectorAgent::profilerEnabled() const +{ + return enabled() && m_profilerAgent->enabled(); +} + +void InspectorAgent::enableProfiler() +{ + if (profilerEnabled()) + return; + m_state->setBoolean(InspectorAgentState::profilerEnabled, true); + m_profilerAgent->enable(false); +} + +void InspectorAgent::disableProfiler() +{ + m_state->setBoolean(InspectorAgentState::profilerEnabled, false); + m_profilerAgent->disable(); +} +#endif + +#if ENABLE(JAVASCRIPT_DEBUGGER) +void InspectorAgent::showAndEnableDebugger() +{ + if (!enabled()) + return; + + if (debuggerEnabled()) + return; + + if (!m_frontend) { + m_state->setBoolean(InspectorAgentState::debuggerEnabled, true); + showPanel(scriptsPanelName); + } else + enableDebugger(true); +} + +void InspectorAgent::enableDebugger(bool eraseStickyBreakpoints) +{ + if (debuggerEnabled()) + return; + m_state->setBoolean(InspectorAgentState::debuggerEnabled, true); + ASSERT(m_inspectedPage); + + m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend, eraseStickyBreakpoints); + m_browserDebuggerAgent = InspectorBrowserDebuggerAgent::create(this, eraseStickyBreakpoints); + + m_frontend->debuggerWasEnabled(); +} + +void InspectorAgent::disableDebugger() +{ + if (!enabled()) + return; + ASSERT(m_inspectedPage); + m_debuggerAgent.clear(); + m_browserDebuggerAgent.clear(); + + if (m_frontend) { + m_frontend->debuggerWasDisabled(); + m_state->setBoolean(InspectorAgentState::debuggerEnabled, false); + } +} + +void InspectorAgent::resume() +{ + if (m_debuggerAgent) + m_debuggerAgent->resume(); +} +#endif + +void InspectorAgent::evaluateForTestInFrontend(long callId, const String& script) +{ + if (m_frontend) + m_frontend->evaluateForTestInFrontend(callId, script); + else + m_pendingEvaluateTestCommands.append(pair(callId, script)); +} + +void InspectorAgent::didEvaluateForTestInFrontend(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(); +} + +static Path quadToPath(const FloatQuad& quad) +{ + Path quadPath; + quadPath.moveTo(quad.p1()); + quadPath.addLineTo(quad.p2()); + quadPath.addLineTo(quad.p3()); + quadPath.addLineTo(quad.p4()); + quadPath.closeSubpath(); + return quadPath; +} + +static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor) +{ + static const int outlineThickness = 2; + static const Color outlineColor(62, 86, 180, 228); + + Path quadPath = quadToPath(quad); + + // Clip out the quad, then draw with a 2px stroke to get a pixel + // of outline (because inflating a quad is hard) + { + context.save(); + context.clipOut(quadPath); + + context.setStrokeThickness(outlineThickness); + context.setStrokeColor(outlineColor, ColorSpaceDeviceRGB); + context.strokePath(quadPath); + + context.restore(); + } + + // Now do the fill + context.setFillColor(fillColor, ColorSpaceDeviceRGB); + context.fillPath(quadPath); +} + +static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor) +{ + context.save(); + Path clipQuadPath = quadToPath(clipQuad); + context.clipOut(clipQuadPath); + drawOutlinedQuad(context, quad, fillColor); + context.restore(); +} + +static void drawHighlightForBox(GraphicsContext& context, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad) +{ + static const Color contentBoxColor(125, 173, 217, 128); + static const Color paddingBoxColor(125, 173, 217, 160); + static const Color borderBoxColor(125, 173, 217, 192); + static const Color marginBoxColor(125, 173, 217, 228); + + if (marginQuad != borderQuad) + drawOutlinedQuadWithClip(context, marginQuad, borderQuad, marginBoxColor); + if (borderQuad != paddingQuad) + drawOutlinedQuadWithClip(context, borderQuad, paddingQuad, borderBoxColor); + if (paddingQuad != contentQuad) + drawOutlinedQuadWithClip(context, paddingQuad, contentQuad, paddingBoxColor); + + drawOutlinedQuad(context, contentQuad, contentBoxColor); +} + +static void drawHighlightForLineBoxesOrSVGRenderer(GraphicsContext& context, const Vector& lineBoxQuads) +{ + static const Color lineBoxColor(125, 173, 217, 128); + + for (size_t i = 0; i < lineBoxQuads.size(); ++i) + drawOutlinedQuad(context, lineBoxQuads[i], lineBoxColor); +} + +static inline void convertFromFrameToMainFrame(Frame* frame, IntRect& rect) +{ + rect = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(rect)); +} + +static inline IntSize frameToMainFrameOffset(Frame* frame) +{ + IntPoint mainFramePoint = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(IntPoint())); + return mainFramePoint - IntPoint(); +} + +void InspectorAgent::drawNodeHighlight(GraphicsContext& context) const +{ + if (!m_highlightedNode) + return; + + RenderObject* renderer = m_highlightedNode->renderer(); + Frame* containingFrame = m_highlightedNode->document()->frame(); + if (!renderer || !containingFrame) + return; + + IntSize mainFrameOffset = frameToMainFrameOffset(containingFrame); + IntRect boundingBox = renderer->absoluteBoundingBoxRect(true); + boundingBox.move(mainFrameOffset); + + IntRect titleReferenceBox = boundingBox; + + ASSERT(m_inspectedPage); + + FrameView* view = m_inspectedPage->mainFrame()->view(); + FloatRect overlayRect = view->visibleContentRect(); + if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect))) + overlayRect = view->visibleContentRect(); + context.translate(-overlayRect.x(), -overlayRect.y()); + + // RenderSVGRoot should be highlighted through the isBox() code path, all other SVG elements should just dump their absoluteQuads(). +#if ENABLE(SVG) + bool isSVGRenderer = renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGRoot(); +#else + bool isSVGRenderer = false; +#endif + + if (renderer->isBox() && !isSVGRenderer) { + RenderBox* renderBox = toRenderBox(renderer); + + IntRect contentBox = renderBox->contentBoxRect(); + + IntRect paddingBox(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(), + contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom()); + IntRect borderBox(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(), + paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom()); + IntRect marginBox(borderBox.x() - renderBox->marginLeft(), borderBox.y() - renderBox->marginTop(), + borderBox.width() + renderBox->marginLeft() + renderBox->marginRight(), borderBox.height() + renderBox->marginTop() + renderBox->marginBottom()); + + titleReferenceBox = marginBox; + titleReferenceBox.move(mainFrameOffset); + titleReferenceBox.move(boundingBox.x(), boundingBox.y()); + + FloatQuad absContentQuad = renderBox->localToAbsoluteQuad(FloatRect(contentBox)); + FloatQuad absPaddingQuad = renderBox->localToAbsoluteQuad(FloatRect(paddingBox)); + FloatQuad absBorderQuad = renderBox->localToAbsoluteQuad(FloatRect(borderBox)); + FloatQuad absMarginQuad = renderBox->localToAbsoluteQuad(FloatRect(marginBox)); + + absContentQuad.move(mainFrameOffset); + absPaddingQuad.move(mainFrameOffset); + absBorderQuad.move(mainFrameOffset); + absMarginQuad.move(mainFrameOffset); + + drawHighlightForBox(context, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad); + } else if (renderer->isRenderInline() || isSVGRenderer) { + // FIXME: We should show margins/padding/border for inlines. + Vector lineBoxQuads; + renderer->absoluteQuads(lineBoxQuads); + for (unsigned i = 0; i < lineBoxQuads.size(); ++i) + lineBoxQuads[i] += mainFrameOffset; + + drawHighlightForLineBoxesOrSVGRenderer(context, lineBoxQuads); + } + + // Draw node title if necessary. + + if (!m_highlightedNode->isElementNode()) + return; + + WebCore::Settings* settings = containingFrame->settings(); + drawElementTitle(context, titleReferenceBox, overlayRect, settings); +} + +void InspectorAgent::drawElementTitle(GraphicsContext& context, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings* settings) const +{ + static const int rectInflatePx = 4; + static const int fontHeightPx = 12; + static const int borderWidthPx = 1; + static const Color tooltipBackgroundColor(255, 255, 194, 255); + static const Color tooltipBorderColor(Color::black); + static const Color tooltipFontColor(Color::black); + + Element* element = static_cast(m_highlightedNode.get()); + bool isXHTML = element->document()->isXHTMLDocument(); + String nodeTitle = isXHTML ? element->nodeName() : element->nodeName().lower(); + const AtomicString& idValue = element->getIdAttribute(); + if (!idValue.isNull() && !idValue.isEmpty()) { + nodeTitle += "#"; + nodeTitle += idValue; + } + if (element->hasClass() && element->isStyledElement()) { + const SpaceSplitString& classNamesString = static_cast(element)->classNames(); + size_t classNameCount = classNamesString.size(); + if (classNameCount) { + HashSet usedClassNames; + for (size_t i = 0; i < classNameCount; ++i) { + const AtomicString& className = classNamesString[i]; + if (usedClassNames.contains(className)) + continue; + usedClassNames.add(className); + nodeTitle += "."; + nodeTitle += className; + } + } + } + + Element* highlightedElement = m_highlightedNode->isElementNode() ? static_cast(m_highlightedNode.get()) : 0; + nodeTitle += " ["; + nodeTitle += String::number(highlightedElement ? highlightedElement->offsetWidth() : boundingBox.width()); + nodeTitle.append(static_cast(0x00D7)); // × + nodeTitle += String::number(highlightedElement ? highlightedElement->offsetHeight() : boundingBox.height()); + nodeTitle += "]"; + + FontDescription desc; + FontFamily family; + family.setFamily(settings->fixedFontFamily()); + desc.setFamily(family); + desc.setComputedSize(fontHeightPx); + Font font = Font(desc, 0, 0); + font.update(0); + + TextRun nodeTitleRun(nodeTitle); + IntPoint titleBasePoint = IntPoint(boundingBox.x(), boundingBox.maxY() - 1); + titleBasePoint.move(rectInflatePx, rectInflatePx); + IntRect titleRect = enclosingIntRect(font.selectionRectForText(nodeTitleRun, titleBasePoint, fontHeightPx)); + titleRect.inflate(rectInflatePx); + + // The initial offsets needed to compensate for a 1px-thick border stroke (which is not a part of the rectangle). + int dx = -borderWidthPx; + int dy = borderWidthPx; + + // If the tip sticks beyond the right of overlayRect, right-align the tip with the said boundary. + if (titleRect.maxX() > overlayRect.maxX()) + dx = overlayRect.maxX() - titleRect.maxX(); + + // If the tip sticks beyond the left of overlayRect, left-align the tip with the said boundary. + if (titleRect.x() + dx < overlayRect.x()) + dx = overlayRect.x() - titleRect.x() - borderWidthPx; + + // If the tip sticks beyond the bottom of overlayRect, show the tip at top of bounding box. + if (titleRect.maxY() > overlayRect.maxY()) { + dy = boundingBox.y() - titleRect.maxY() - borderWidthPx; + // If the tip still sticks beyond the bottom of overlayRect, bottom-align the tip with the said boundary. + if (titleRect.maxY() + dy > overlayRect.maxY()) + dy = overlayRect.maxY() - titleRect.maxY(); + } + + // If the tip sticks beyond the top of overlayRect, show the tip at top of overlayRect. + if (titleRect.y() + dy < overlayRect.y()) + dy = overlayRect.y() - titleRect.y() + borderWidthPx; + + titleRect.move(dx, dy); + context.setStrokeColor(tooltipBorderColor, ColorSpaceDeviceRGB); + context.setStrokeThickness(borderWidthPx); + context.setFillColor(tooltipBackgroundColor, ColorSpaceDeviceRGB); + context.drawRect(titleRect); + context.setFillColor(tooltipFontColor, ColorSpaceDeviceRGB); + context.drawText(font, nodeTitleRun, IntPoint(titleRect.x() + rectInflatePx, titleRect.y() + font.fontMetrics().height())); +} + +void InspectorAgent::openInInspectedWindow(const String& url) +{ + Frame* mainFrame = m_inspectedPage->mainFrame(); + + FrameLoadRequest request(mainFrame->document()->securityOrigin(), ResourceRequest(), "_blank"); + + bool created; + WindowFeatures windowFeatures; + Frame* newFrame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created); + if (!newFrame) + return; + + UserGestureIndicator indicator(DefinitelyProcessingUserGesture); + newFrame->loader()->setOpener(mainFrame); + newFrame->page()->setOpenedByDOM(); + newFrame->loader()->changeLocation(mainFrame->document()->securityOrigin(), newFrame->loader()->completeURL(url), "", false, false); +} + +void InspectorAgent::addScriptToEvaluateOnLoad(const String& source) +{ + m_scriptsToEvaluateOnLoad.append(source); +} + +void InspectorAgent::removeAllScriptsToEvaluateOnLoad() +{ + m_scriptsToEvaluateOnLoad.clear(); +} + +void InspectorAgent::setInspectorExtensionAPI(const String& source) +{ + m_inspectorExtensionAPI = source; +} + +KURL InspectorAgent::inspectedURL() const +{ + return m_inspectedPage->mainFrame()->document()->url(); +} + +KURL InspectorAgent::inspectedURLWithoutFragment() const +{ + KURL url = inspectedURL(); + url.removeFragmentIdentifier(); + return url; +} + +void InspectorAgent::reloadPage(bool ignoreCache) +{ + m_inspectedPage->mainFrame()->loader()->reload(ignoreCache); +} + +bool InspectorAgent::enabled() const +{ + if (!m_inspectedPage) + return false; + return m_inspectedPage->settings()->developerExtrasEnabled(); +} + +void InspectorAgent::showConsole() +{ + showPanel(consolePanelName); +} + +void InspectorAgent::showPanel(const String& panel) +{ + if (!m_frontend) { + m_requiredPanel = panel; + return; + } + m_frontend->showPanel(panel); +} + +} // namespace WebCore + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorAgent.h b/Source/WebCore/inspector/InspectorAgent.h new file mode 100644 index 0000000..1f14dd9 --- /dev/null +++ b/Source/WebCore/inspector/InspectorAgent.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef InspectorAgent_h +#define InspectorAgent_h + +#include "CharacterData.h" +#include "Console.h" +#include "Cookie.h" +#include "Page.h" +#include "PlatformString.h" +#include +#include +#include +#include +#include +#include + +namespace WebCore { + +class CachedResource; +class CharacterData; +class Database; +class DOMWrapperWorld; +class Document; +class DocumentLoader; +class FloatRect; +class GraphicsContext; +class HTTPHeaderMap; +class HitTestResult; +class InjectedScript; +class InjectedScriptHost; +class InspectorArray; +class InspectorBrowserDebuggerAgent; +class InspectorClient; +class InspectorConsoleAgent; +class InspectorCSSAgent; +class InspectorDOMAgent; +class InspectorDOMStorageAgent; +class InspectorDOMStorageResource; +class InspectorDatabaseAgent; +class InspectorDatabaseResource; +class InspectorDebuggerAgent; +class InspectorFrontend; +class InspectorFrontendClient; +class InspectorObject; +class InspectorProfilerAgent; +class InspectorResourceAgent; +class InspectorRuntimeAgent; +class InspectorState; +class InspectorStorageAgent; +class InspectorTimelineAgent; +class InspectorValue; +class InspectorWorkerResource; +class IntRect; +class KURL; +class Node; +class Page; +class ResourceRequest; +class ResourceResponse; +class ResourceError; +class ScriptArguments; +class ScriptCallStack; +class ScriptProfile; +class SharedBuffer; +class StorageArea; + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +class InspectorApplicationCacheAgent; +#endif + +#if ENABLE(WEB_SOCKETS) +class WebSocketHandshakeRequest; +class WebSocketHandshakeResponse; +#endif + +class InspectorAgent { + WTF_MAKE_NONCOPYABLE(InspectorAgent); + WTF_MAKE_FAST_ALLOCATED; +public: + InspectorAgent(Page*, InspectorClient*); + virtual ~InspectorAgent(); + + InspectorClient* inspectorClient() { return m_client; } + InjectedScriptHost* injectedScriptHost() { return m_injectedScriptHost.get(); } + + void inspectedPageDestroyed(); + + bool enabled() const; + + Page* inspectedPage() const { return m_inspectedPage; } + KURL inspectedURL() const; + KURL inspectedURLWithoutFragment() const; + void reloadPage(bool ignoreCache); + void showConsole(); + + void restoreInspectorStateFromCookie(const String& inspectorCookie); + + void highlight(Node*); + void hideHighlight(); + void inspect(Node*); + void highlightDOMNode(long nodeId); + void hideDOMNodeHighlight() { hideHighlight(); } + + void highlightFrame(unsigned long frameId); + void hideFrameHighlight() { hideHighlight(); } + + void setFrontend(InspectorFrontend*); + InspectorFrontend* frontend() const { return m_frontend; } + void disconnectFrontend(); + + InspectorResourceAgent* resourceAgent(); + + InspectorAgent* inspectorAgent() { return this; } + InspectorConsoleAgent* consoleAgent() { return m_consoleAgent.get(); } + InspectorCSSAgent* cssAgent() { return m_cssAgent.get(); } + InspectorDOMAgent* domAgent() { return m_domAgent.get(); } + InjectedScriptHost* injectedScriptAgent() { return m_injectedScriptHost.get(); } + InspectorRuntimeAgent* runtimeAgent() { return m_runtimeAgent.get(); } + InspectorTimelineAgent* timelineAgent() { return m_timelineAgent.get(); } +#if ENABLE(DATABASE) + InspectorDatabaseAgent* databaseAgent() { return m_databaseAgent.get(); } +#endif +#if ENABLE(DOM_STORAGE) + InspectorDOMStorageAgent* domStorageAgent() { return m_domStorageAgent.get(); } +#endif +#if ENABLE(JAVASCRIPT_DEBUGGER) + InspectorBrowserDebuggerAgent* browserDebuggerAgent() const { return m_browserDebuggerAgent.get(); } + InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); } + InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); } +#endif +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); } +#endif + + bool handleMousePress(); + bool searchingForNodeInPage() const; + void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); + + void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*); + + void didCommitLoad(DocumentLoader*); + + void startTimelineProfiler(); + void stopTimelineProfiler(); + + void getCookies(RefPtr* cookies, WTF::String* cookiesString); + void deleteCookie(const String& cookieName, const String& domain); + + void domContentLoadedEventFired(DocumentLoader*, const KURL&); + void loadEventFired(DocumentLoader*, const KURL&); + +#if ENABLE(WORKERS) + enum WorkerAction { WorkerCreated, WorkerDestroyed }; + + void postWorkerNotificationToFrontend(const InspectorWorkerResource&, WorkerAction); + void didCreateWorker(intptr_t, const String& url, bool isSharedWorker); + void didDestroyWorker(intptr_t); +#endif + +#if ENABLE(DATABASE) + void didOpenDatabase(PassRefPtr, const String& domain, const String& name, const String& version); +#endif + +#if ENABLE(DOM_STORAGE) + void didUseDOMStorage(StorageArea*, bool isLocalStorage, Frame*); +#endif + +#if ENABLE(WEB_SOCKETS) + void didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL); + void willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest&); + void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse&); + void didCloseWebSocket(unsigned long identifier); +#endif + + bool hasFrontend() const { return m_frontend; } + + void drawNodeHighlight(GraphicsContext&) const; + void openInInspectedWindow(const String& url); + void drawElementTitle(GraphicsContext&, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings*) const; + +#if ENABLE(JAVASCRIPT_DEBUGGER) + bool isRecordingUserInitiatedProfile() const; + void startProfiling() { startUserInitiatedProfiling(); } + void startUserInitiatedProfiling(); + void stopProfiling() { stopUserInitiatedProfiling(); } + void stopUserInitiatedProfiling(); + void enableProfiler(); + void disableProfiler(); + bool profilerEnabled() const; + + void showAndEnableDebugger(); + void enableDebugger() { enableDebugger(false); } + void enableDebugger(bool eraseStickyBreakpoints); + void disableDebugger(); + bool debuggerEnabled() const { return m_debuggerAgent; } + void resume(); +#endif + + // Generic code called from custom implementations. + void evaluateForTestInFrontend(long testCallId, const String& script); + + void addScriptToEvaluateOnLoad(const String& source); + void removeAllScriptsToEvaluateOnLoad(); + void setInspectorExtensionAPI(const String& source); + + InspectorState* state() { return m_state.get(); } + + // InspectorAgent API + void getInspectorState(RefPtr* state); + void setMonitoringXHREnabled(bool enabled, bool* newState); + void populateScriptObjects(); + // Following are used from InspectorBackend and internally. + void setSearchingForNode(bool enabled, bool* newState); + void didEvaluateForTestInFrontend(long callId, const String& jsonResult); + + void setUserAgentOverride(const String& userAgent); + void applyUserAgentOverride(String* userAgent) const; + +private: + void showPanel(const String& panel); + void pushDataCollectedOffline(); + void restoreDebugger(bool eraseStickyBreakpoints); + enum ProfilerRestoreAction { + ProfilerRestoreNoAction = 0, + ProfilerRestoreResetAgent = 1 + }; + void restoreProfiler(ProfilerRestoreAction); + void unbindAllResources(); + void setSearchingForNode(bool enabled); + + void releaseFrontendLifetimeAgents(); + void createFrontendLifetimeAgents(); + +#if ENABLE(JAVASCRIPT_DEBUGGER) + void toggleRecordButton(bool); +#endif + + PassRefPtr buildObjectForCookie(const Cookie&); + PassRefPtr buildArrayForCookies(ListHashSet&); + + void focusNode(); + bool isMainResourceLoader(DocumentLoader*, const KURL& requestUrl); + + Page* m_inspectedPage; + InspectorClient* m_client; + InspectorFrontend* m_frontend; + OwnPtr m_cssAgent; + OwnPtr m_domAgent; + +#if ENABLE(DATABASE) + OwnPtr m_databaseAgent; +#endif + +#if ENABLE(DOM_STORAGE) + OwnPtr m_domStorageAgent; +#endif + + OwnPtr m_timelineAgent; + OwnPtr m_state; + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + OwnPtr m_applicationCacheAgent; +#endif + + RefPtr m_highlightedNode; + RefPtr m_nodeToFocus; + RefPtr m_resourceAgent; + OwnPtr m_runtimeAgent; + +#if ENABLE(DATABASE) + typedef HashMap > DatabaseResourcesMap; + DatabaseResourcesMap m_databaseResources; +#endif +#if ENABLE(DOM_STORAGE) + typedef HashMap > DOMStorageResourcesMap; + DOMStorageResourcesMap m_domStorageResources; +#endif + + RefPtr m_injectedScriptHost; + OwnPtr m_consoleAgent; + + Vector > m_pendingEvaluateTestCommands; + String m_requiredPanel; + Vector m_scriptsToEvaluateOnLoad; + String m_inspectorExtensionAPI; +#if ENABLE(JAVASCRIPT_DEBUGGER) + OwnPtr m_debuggerAgent; + OwnPtr m_browserDebuggerAgent; + OwnPtr m_profilerAgent; +#endif + String m_userAgentOverride; +#if ENABLE(WORKERS) + typedef HashMap > WorkersMap; + + WorkersMap m_workers; +#endif +}; + +} // namespace WebCore + +#endif // !defined(InspectorAgent_h) diff --git a/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp b/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp index 1cca6fe..b38bb83 100644 --- a/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp +++ b/Source/WebCore/inspector/InspectorApplicationCacheAgent.cpp @@ -32,7 +32,7 @@ #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoader.h" -#include "InspectorController.h" +#include "InspectorAgent.h" #include "InspectorFrontend.h" #include "InspectorValues.h" #include "NetworkStateNotifier.h" @@ -41,12 +41,17 @@ namespace WebCore { -InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend) - : m_inspectorController(inspectorController) +InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(DocumentLoader* documentLoader, InspectorFrontend* frontend) + : m_documentLoader(documentLoader) , m_frontend(frontend) { } +void InspectorApplicationCacheAgent::didCommitLoad(DocumentLoader* documentLoader) +{ + m_documentLoader = documentLoader; +} + void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame) { ApplicationCacheHost::Status status = frame->loader()->documentLoader()->applicationCacheHost()->status(); @@ -61,9 +66,8 @@ void InspectorApplicationCacheAgent::networkStateChanged() void InspectorApplicationCacheAgent::getApplicationCaches(RefPtr* applicationCaches) { - DocumentLoader* documentLoader = m_inspectorController->inspectedPage()->mainFrame()->loader()->documentLoader(); - if (documentLoader) { - ApplicationCacheHost* host = documentLoader->applicationCacheHost(); + if (m_documentLoader) { + ApplicationCacheHost* host = m_documentLoader->applicationCacheHost(); ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo(); ApplicationCacheHost::ResourceInfoList resources; diff --git a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h index ac0acbf..33cee59 100644 --- a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h +++ b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h @@ -33,9 +33,10 @@ namespace WebCore { +class DocumentLoader; class Frame; class InspectorArray; -class InspectorController; +class InspectorAgent; class InspectorFrontend; class InspectorObject; class InspectorValue; @@ -44,9 +45,11 @@ class ResourceResponse; class InspectorApplicationCacheAgent { WTF_MAKE_NONCOPYABLE(InspectorApplicationCacheAgent); WTF_MAKE_FAST_ALLOCATED; public: - InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend); + InspectorApplicationCacheAgent(DocumentLoader*, InspectorFrontend*); ~InspectorApplicationCacheAgent() { } + void didCommitLoad(DocumentLoader*); + // Backend to Frontend void updateApplicationCacheStatus(Frame*); void networkStateChanged(); @@ -59,7 +62,7 @@ private: PassRefPtr buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList&); PassRefPtr buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); - InspectorController* m_inspectorController; + DocumentLoader* m_documentLoader; InspectorFrontend* m_frontend; }; diff --git a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp index 023dc49..5fe9937 100644 --- a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp +++ b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp @@ -35,7 +35,7 @@ #if ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER) #include "HTMLElement.h" -#include "InspectorController.h" +#include "InspectorAgent.h" #include "InspectorDOMAgent.h" #include "InspectorDebuggerAgent.h" #include "InspectorState.h" @@ -61,26 +61,41 @@ const int domBreakpointDerivedTypeShift = 16; namespace WebCore { -InspectorBrowserDebuggerAgent::InspectorBrowserDebuggerAgent(InspectorController* inspectorController) - : m_inspectorController(inspectorController) +namespace BrowserDebuggerAgentState { +static const char browserBreakpoints[] = "browserBreakpoints"; +} + +PassOwnPtr InspectorBrowserDebuggerAgent::create(InspectorAgent* inspectorAgent, bool eraseStickyBreakpoints) +{ + return adoptPtr(new InspectorBrowserDebuggerAgent(inspectorAgent, eraseStickyBreakpoints)); +} + +InspectorBrowserDebuggerAgent::InspectorBrowserDebuggerAgent(InspectorAgent* inspectorAgent, bool eraseStickyBreakpoints) + : m_inspectorAgent(inspectorAgent) , m_hasXHRBreakpointWithEmptyURL(false) { + if (eraseStickyBreakpoints) + inspectorAgent->state()->setObject(BrowserDebuggerAgentState::browserBreakpoints, InspectorObject::create()); } InspectorBrowserDebuggerAgent::~InspectorBrowserDebuggerAgent() { } -void InspectorBrowserDebuggerAgent::inspectedURLChanged(const KURL& url) +void InspectorBrowserDebuggerAgent::setAllBrowserBreakpoints(PassRefPtr breakpoints) +{ + m_inspectorAgent->state()->setObject(BrowserDebuggerAgentState::browserBreakpoints, breakpoints); + inspectedURLChanged(m_inspectorAgent->inspectedURLWithoutFragment()); +} + +void InspectorBrowserDebuggerAgent::inspectedURLChanged(const String& url) { m_eventListenerBreakpoints.clear(); m_XHRBreakpoints.clear(); m_hasXHRBreakpointWithEmptyURL = false; - RefPtr allBreakpoints = m_inspectorController->state()->getObject(InspectorState::browserBreakpoints); - KURL urlCopy = url; - urlCopy.removeFragmentIdentifier(); - RefPtr breakpoints = allBreakpoints->getArray(urlCopy); + RefPtr allBreakpoints = m_inspectorAgent->state()->getObject(BrowserDebuggerAgentState::browserBreakpoints); + RefPtr breakpoints = allBreakpoints->getArray(url); if (!breakpoints) return; for (unsigned i = 0; i < breakpoints->length(); ++i) @@ -89,10 +104,6 @@ void InspectorBrowserDebuggerAgent::inspectedURLChanged(const KURL& url) void InspectorBrowserDebuggerAgent::restoreStickyBreakpoint(PassRefPtr breakpoint) { - DEFINE_STATIC_LOCAL(String, eventListenerBreakpointType, ("EventListener")); - DEFINE_STATIC_LOCAL(String, javaScriptBreakpointType, ("JS")); - DEFINE_STATIC_LOCAL(String, xhrBreakpointType, ("XHR")); - if (!breakpoint) return; String type; @@ -105,25 +116,14 @@ void InspectorBrowserDebuggerAgent::restoreStickyBreakpoint(PassRefPtrgetString("eventName", &eventName)) return; setEventListenerBreakpoint(eventName); - } else if (type == javaScriptBreakpointType && m_inspectorController->debuggerAgent()) { - String url; - if (!condition->getString("url", &url)) - return; - double lineNumber; - if (!condition->getNumber("lineNumber", &lineNumber)) - return; - String javaScriptCondition; - if (!condition->getString("condition", &javaScriptCondition)) - return; - m_inspectorController->debuggerAgent()->setStickyBreakpoint(url, static_cast(lineNumber), javaScriptCondition, enabled); - } else if (type == xhrBreakpointType) { + } else if (type == xhrNativeBreakpointType) { if (!enabled) return; String url; @@ -178,7 +178,7 @@ void InspectorBrowserDebuggerAgent::didRemoveDOMNode(Node* node) void InspectorBrowserDebuggerAgent::setDOMBreakpoint(long nodeId, long type) { - Node* node = m_inspectorController->domAgent()->nodeForId(nodeId); + Node* node = m_inspectorAgent->domAgent()->nodeForId(nodeId); if (!node) return; @@ -192,7 +192,7 @@ void InspectorBrowserDebuggerAgent::setDOMBreakpoint(long nodeId, long type) void InspectorBrowserDebuggerAgent::removeDOMBreakpoint(long nodeId, long type) { - Node* node = m_inspectorController->domAgent()->nodeForId(nodeId); + Node* node = m_inspectorAgent->domAgent()->nodeForId(nodeId); if (!node) return; @@ -211,7 +211,7 @@ void InspectorBrowserDebuggerAgent::removeDOMBreakpoint(long nodeId, long type) void InspectorBrowserDebuggerAgent::willInsertDOMNode(Node*, Node* parent) { - InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent(); + InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent(); if (!debuggerAgent) return; @@ -225,7 +225,7 @@ void InspectorBrowserDebuggerAgent::willInsertDOMNode(Node*, Node* parent) void InspectorBrowserDebuggerAgent::willRemoveDOMNode(Node* node) { - InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent(); + InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent(); if (!debuggerAgent) return; @@ -244,7 +244,7 @@ void InspectorBrowserDebuggerAgent::willRemoveDOMNode(Node* node) void InspectorBrowserDebuggerAgent::willModifyDOMAttr(Element* element) { - InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent(); + InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent(); if (!debuggerAgent) return; @@ -264,7 +264,7 @@ void InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, long br if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) { // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint. // Target node may be unknown to frontend, so we need to push it first. - long targetNodeId = m_inspectorController->domAgent()->pushNodePathToFrontend(target); + long targetNodeId = m_inspectorAgent->domAgent()->pushNodePathToFrontend(target); ASSERT(targetNodeId); description->setNumber("targetNodeId", targetNodeId); @@ -281,7 +281,7 @@ void InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, long br description->setBoolean("insertion", insertion); } - long breakpointOwnerNodeId = m_inspectorController->domAgent()->pushNodePathToFrontend(breakpointOwner); + long breakpointOwnerNodeId = m_inspectorAgent->domAgent()->pushNodePathToFrontend(breakpointOwner); ASSERT(breakpointOwnerNodeId); description->setNumber("nodeId", breakpointOwnerNodeId); description->setNumber("type", breakpointType); @@ -314,7 +314,7 @@ void InspectorBrowserDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_ void InspectorBrowserDebuggerAgent::pauseOnNativeEventIfNeeded(const String& categoryType, const String& eventName, bool synchronous) { - InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent(); + InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent(); if (!debuggerAgent) return; @@ -349,7 +349,7 @@ void InspectorBrowserDebuggerAgent::removeXHRBreakpoint(const String& url) void InspectorBrowserDebuggerAgent::willSendXMLHttpRequest(const String& url) { - InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent(); + InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent(); if (!debuggerAgent) return; diff --git a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h index 0ffa85c..fac54bb 100644 --- a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h +++ b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h @@ -44,22 +44,19 @@ namespace WebCore { class Element; -class InspectorController; +class InspectorAgent; class InspectorObject; -class KURL; class Node; class InspectorBrowserDebuggerAgent { WTF_MAKE_NONCOPYABLE(InspectorBrowserDebuggerAgent); public: - static PassOwnPtr create(InspectorController* inspectorController) - { - return adoptPtr(new InspectorBrowserDebuggerAgent(inspectorController)); - } + static PassOwnPtr create(InspectorAgent*, bool eraseStickyBreakpoints); virtual ~InspectorBrowserDebuggerAgent(); - void inspectedURLChanged(const KURL&); + void setAllBrowserBreakpoints(PassRefPtr); + void inspectedURLChanged(const String& url); // BrowserDebugger API for InspectorFrontend void setXHRBreakpoint(const String& url); @@ -79,7 +76,7 @@ public: void pauseOnNativeEventIfNeeded(const String& categoryType, const String& eventName, bool synchronous); private: - InspectorBrowserDebuggerAgent(InspectorController*); + InspectorBrowserDebuggerAgent(InspectorAgent*, bool eraseStickyBreakpoints); void restoreStickyBreakpoint(PassRefPtr breakpoint); @@ -88,7 +85,7 @@ private: bool hasBreakpoint(Node*, long type); void discardBindings(); - InspectorController* m_inspectorController; + InspectorAgent* m_inspectorAgent; HashMap m_domBreakpoints; HashSet m_eventListenerBreakpoints; HashSet m_XHRBreakpoints; diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp index bacf741..f49f89c 100644 --- a/Source/WebCore/inspector/InspectorCSSAgent.cpp +++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp @@ -42,10 +42,10 @@ #include "InspectorFrontend.h" #include "InspectorValues.h" #include "Node.h" +#include "NodeList.h" #include "StyleSheetList.h" #include -#include #include #include @@ -173,7 +173,7 @@ void InspectorCSSAgent::reset() m_documentToInspectorStyleSheet.clear(); } -void InspectorCSSAgent::getStylesForNode2(long nodeId, RefPtr* result) +void InspectorCSSAgent::getStylesForNode(long nodeId, RefPtr* result) { Element* element = elementForId(nodeId); if (!element) @@ -228,7 +228,7 @@ void InspectorCSSAgent::getStylesForNode2(long nodeId, RefPtr* r *result = resultObject.release(); } -void InspectorCSSAgent::getInlineStyleForNode2(long nodeId, RefPtr* style) +void InspectorCSSAgent::getInlineStyleForNode(long nodeId, RefPtr* style) { Element* element = elementForId(nodeId); if (!element) @@ -241,7 +241,7 @@ void InspectorCSSAgent::getInlineStyleForNode2(long nodeId, RefPtrbuildObjectForStyle(element->style()); } -void InspectorCSSAgent::getComputedStyleForNode2(long nodeId, RefPtr* style) +void InspectorCSSAgent::getComputedStyleForNode(long nodeId, RefPtr* style) { Element* element = elementForId(nodeId); if (!element) @@ -252,10 +252,10 @@ void InspectorCSSAgent::getComputedStyleForNode2(long nodeId, RefPtrbuildObjectForStyle(); } -void InspectorCSSAgent::getAllStyles2(RefPtr* styles) +void InspectorCSSAgent::getAllStyles(RefPtr* styles) { - const ListHashSet >& documents = m_domAgent->documents(); - for (ListHashSet >::const_iterator it = documents.begin(); it != documents.end(); ++it) { + Vector documents = m_domAgent->documents(); + for (Vector::iterator it = documents.begin(); it != documents.end(); ++it) { StyleSheetList* list = (*it)->styleSheets(); for (unsigned i = 0; i < list->length(); ++i) { StyleSheet* styleSheet = list->item(i); @@ -267,7 +267,7 @@ void InspectorCSSAgent::getAllStyles2(RefPtr* styles) } } -void InspectorCSSAgent::getStyleSheet2(const String& styleSheetId, RefPtr* styleSheetObject) +void InspectorCSSAgent::getStyleSheet(const String& styleSheetId, RefPtr* styleSheetObject) { InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(styleSheetId); if (!inspectorStyleSheet) @@ -276,7 +276,7 @@ void InspectorCSSAgent::getStyleSheet2(const String& styleSheetId, RefPtrbuildObjectForStyleSheet(); } -void InspectorCSSAgent::getStyleSheetText2(const String& styleSheetId, String* url, String* result) +void InspectorCSSAgent::getStyleSheetText(const String& styleSheetId, String* url, String* result) { InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(styleSheetId); if (!inspectorStyleSheet) @@ -285,7 +285,7 @@ void InspectorCSSAgent::getStyleSheetText2(const String& styleSheetId, String* u inspectorStyleSheet->text(result); } -void InspectorCSSAgent::setStyleSheetText2(const String& styleSheetId, const String& text, bool* success) +void InspectorCSSAgent::setStyleSheetText(const String& styleSheetId, const String& text, bool* success) { InspectorStyleSheet* inspectorStyleSheet = styleSheetForId(styleSheetId); if (!inspectorStyleSheet) { @@ -298,7 +298,7 @@ void InspectorCSSAgent::setStyleSheetText2(const String& styleSheetId, const Str inspectorStyleSheet->reparseStyleSheet(text); } -void InspectorCSSAgent::setPropertyText2(const RefPtr& fullStyleId, long propertyIndex, const String& text, bool overwrite, RefPtr* result) +void InspectorCSSAgent::setPropertyText(const RefPtr& fullStyleId, long propertyIndex, const String& text, bool overwrite, RefPtr* result) { InspectorCSSId compoundId(fullStyleId); ASSERT(!compoundId.isEmpty()); @@ -312,7 +312,7 @@ void InspectorCSSAgent::setPropertyText2(const RefPtr& fullStyl *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } -void InspectorCSSAgent::toggleProperty2(const RefPtr& fullStyleId, long propertyIndex, bool disable, RefPtr* result) +void InspectorCSSAgent::toggleProperty(const RefPtr& fullStyleId, long propertyIndex, bool disable, RefPtr* result) { InspectorCSSId compoundId(fullStyleId); ASSERT(!compoundId.isEmpty()); @@ -326,7 +326,7 @@ void InspectorCSSAgent::toggleProperty2(const RefPtr& fullStyle *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } -void InspectorCSSAgent::setRuleSelector2(const RefPtr& fullRuleId, const String& selector, RefPtr* result) +void InspectorCSSAgent::setRuleSelector(const RefPtr& fullRuleId, const String& selector, RefPtr* result) { InspectorCSSId compoundId(fullRuleId); ASSERT(!compoundId.isEmpty()); @@ -342,7 +342,7 @@ void InspectorCSSAgent::setRuleSelector2(const RefPtr& fullRule *result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId)); } -void InspectorCSSAgent::addRule2(const long contextNodeId, const String& selector, RefPtr* result) +void InspectorCSSAgent::addRule(const long contextNodeId, const String& selector, RefPtr* result) { Node* node = m_domAgent->nodeForId(contextNodeId); if (!node) diff --git a/Source/WebCore/inspector/InspectorCSSAgent.h b/Source/WebCore/inspector/InspectorCSSAgent.h index 619f958..12b3f9b 100644 --- a/Source/WebCore/inspector/InspectorCSSAgent.h +++ b/Source/WebCore/inspector/InspectorCSSAgent.h @@ -61,17 +61,17 @@ public: void setDOMAgent(InspectorDOMAgent* domAgent); void reset(); - void getStylesForNode2(long nodeId, RefPtr* result); - void getInlineStyleForNode2(long nodeId, RefPtr* style); - void getComputedStyleForNode2(long nodeId, RefPtr* style); - void getAllStyles2(RefPtr* styles); - void getStyleSheet2(const String& styleSheetId, RefPtr* result); - void getStyleSheetText2(const String& styleSheetId, String* url, String* result); - void setStyleSheetText2(const String& styleSheetId, const String& text, bool* success); - void setPropertyText2(const RefPtr& styleId, long propertyIndex, const String& text, bool overwrite, RefPtr* result); - void toggleProperty2(const RefPtr& styleId, long propertyIndex, bool disable, RefPtr* result); - void setRuleSelector2(const RefPtr& ruleId, const String& selector, RefPtr* result); - void addRule2(const long contextNodeId, const String& selector, RefPtr* result); + void getStylesForNode(long nodeId, RefPtr* result); + void getInlineStyleForNode(long nodeId, RefPtr* style); + void getComputedStyleForNode(long nodeId, RefPtr* style); + void getAllStyles(RefPtr* styles); + void getStyleSheet(const String& styleSheetId, RefPtr* result); + void getStyleSheetText(const String& styleSheetId, String* url, String* result); + void setStyleSheetText(const String& styleSheetId, const String& text, bool* success); + void setPropertyText(const RefPtr& styleId, long propertyIndex, const String& text, bool overwrite, RefPtr* result); + void toggleProperty(const RefPtr& styleId, long propertyIndex, bool disable, RefPtr* result); + void setRuleSelector(const RefPtr& ruleId, const String& selector, RefPtr* result); + void addRule(const long contextNodeId, const String& selector, RefPtr* result); void getSupportedCSSProperties(RefPtr* result); void querySelectorAll(const long nodeId, const String& selector, RefPtr* result); diff --git a/Source/WebCore/inspector/InspectorClient.h b/Source/WebCore/inspector/InspectorClient.h index 3b8007e..d24ce4d 100644 --- a/Source/WebCore/inspector/InspectorClient.h +++ b/Source/WebCore/inspector/InspectorClient.h @@ -45,9 +45,6 @@ public: virtual void highlight(Node*) = 0; virtual void hideHighlight() = 0; - virtual void populateSetting(const String& key, String* value) = 0; - virtual void storeSetting(const String& key, const String& value) = 0; - virtual bool sendMessageToFrontend(const String& message) = 0; // Navigation can cause some WebKit implementations to change the view / page / inspector controller instance. diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.cpp b/Source/WebCore/inspector/InspectorConsoleAgent.cpp index 2c837f3..7d11a7a 100644 --- a/Source/WebCore/inspector/InspectorConsoleAgent.cpp +++ b/Source/WebCore/inspector/InspectorConsoleAgent.cpp @@ -30,10 +30,9 @@ #include "Console.h" #include "ConsoleMessage.h" #include "InjectedScriptHost.h" -#include "InspectorController.h" +#include "InspectorAgent.h" #include "InspectorDOMAgent.h" #include "InspectorFrontend.h" -#include "InspectorSettings.h" #include "InspectorState.h" #include "ResourceError.h" #include "ResourceResponse.h" @@ -50,8 +49,13 @@ namespace WebCore { static const unsigned maximumConsoleMessages = 1000; static const unsigned expireConsoleMessagesStep = 100; -InspectorConsoleAgent::InspectorConsoleAgent(InspectorController* inspectorController) - : m_inspectorController(inspectorController) +namespace ConsoleAgentState { +static const char monitoringXHR[] = "monitoringXHR"; +static const char consoleMessagesEnabled[] = "consoleMessagesEnabled"; +} + +InspectorConsoleAgent::InspectorConsoleAgent(InspectorAgent* inspectorAgent) + : m_inspectorAgent(inspectorAgent) , m_frontend(0) , m_previousMessage(0) , m_expiredConsoleMessageCount(0) @@ -60,7 +64,7 @@ InspectorConsoleAgent::InspectorConsoleAgent(InspectorController* inspectorContr InspectorConsoleAgent::~InspectorConsoleAgent() { - m_inspectorController = 0; + m_inspectorAgent = 0; } void InspectorConsoleAgent::setConsoleMessagesEnabled(bool enabled, bool* newState) @@ -74,8 +78,8 @@ void InspectorConsoleAgent::clearConsoleMessages() m_consoleMessages.clear(); m_expiredConsoleMessageCount = 0; m_previousMessage = 0; - m_inspectorController->injectedScriptHost()->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console"); - if (InspectorDOMAgent* domAgent = m_inspectorController->domAgent()) + m_inspectorAgent->injectedScriptHost()->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console"); + if (InspectorDOMAgent* domAgent = m_inspectorAgent->domAgent()) domAgent->releaseDanglingNodes(); if (m_frontend) m_frontend->consoleMessagesCleared(); @@ -95,14 +99,14 @@ void InspectorConsoleAgent::setFrontend(InspectorFrontend* frontend) void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr arguments, PassRefPtr callStack) { - if (!m_inspectorController->enabled()) + if (!m_inspectorAgent->enabled()) return; addConsoleMessage(new ConsoleMessage(source, type, level, message, arguments, callStack)); } void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) { - if (!m_inspectorController->enabled()) + if (!m_inspectorAgent->enabled()) return; addConsoleMessage(new ConsoleMessage(source, type, level, message, lineNumber, sourceID)); } @@ -163,15 +167,15 @@ void InspectorConsoleAgent::count(PassRefPtr arguments, PassRef void InspectorConsoleAgent::resourceRetrievedByXMLHttpRequest(const String& url, const String& sendURL, unsigned sendLineNumber) { - if (!m_inspectorController->enabled()) + if (!m_inspectorAgent->enabled()) return; - if (m_inspectorController->state()->getBoolean(InspectorState::monitoringXHR)) + if (m_inspectorAgent->state()->getBoolean(ConsoleAgentState::monitoringXHR)) addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL); } void InspectorConsoleAgent::didReceiveResponse(unsigned long identifier, const ResourceResponse& response) { - if (!m_inspectorController->enabled()) + if (!m_inspectorAgent->enabled()) return; if (response.httpStatusCode() >= 400) { @@ -182,7 +186,7 @@ void InspectorConsoleAgent::didReceiveResponse(unsigned long identifier, const R void InspectorConsoleAgent::didFailLoading(unsigned long identifier, const ResourceError& error) { - if (!m_inspectorController->enabled()) + if (!m_inspectorAgent->enabled()) return; String message = "Failed to load resource"; @@ -193,40 +197,36 @@ void InspectorConsoleAgent::didFailLoading(unsigned long identifier, const Resou void InspectorConsoleAgent::setMonitoringXHREnabled(bool enabled) { - m_inspectorController->state()->setBoolean(InspectorState::monitoringXHR, enabled); - m_inspectorController->settings()->setBoolean(InspectorSettings::MonitoringXHREnabled, enabled); - if (m_frontend) - m_frontend->monitoringXHRStateChanged(enabled); + m_inspectorAgent->state()->setBoolean(ConsoleAgentState::monitoringXHR, enabled); } void InspectorConsoleAgent::setConsoleMessagesEnabled(bool enabled) { - m_inspectorController->state()->setBoolean(InspectorState::consoleMessagesEnabled, enabled); + m_inspectorAgent->state()->setBoolean(ConsoleAgentState::consoleMessagesEnabled, enabled); if (!enabled || !m_frontend) return; - m_frontend->monitoringXHRStateChanged(m_inspectorController->state()->getBoolean(InspectorState::monitoringXHR)); if (m_expiredConsoleMessageCount) m_frontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount); unsigned messageCount = m_consoleMessages.size(); for (unsigned i = 0; i < messageCount; ++i) - m_consoleMessages[i]->addToFrontend(m_frontend, m_inspectorController->injectedScriptHost()); + m_consoleMessages[i]->addToFrontend(m_frontend, m_inspectorAgent->injectedScriptHost()); } void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr consoleMessage) { - ASSERT(m_inspectorController->enabled()); + ASSERT(m_inspectorAgent->enabled()); ASSERT_ARG(consoleMessage, consoleMessage); if (m_previousMessage && m_previousMessage->isEqual(consoleMessage.get())) { m_previousMessage->incrementCount(); - if (m_inspectorController->state()->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend) + if (m_inspectorAgent->state()->getBoolean(ConsoleAgentState::consoleMessagesEnabled) && m_frontend) m_previousMessage->updateRepeatCountInConsole(m_frontend); } else { m_previousMessage = consoleMessage.get(); m_consoleMessages.append(consoleMessage); - if (m_inspectorController->state()->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend) - m_previousMessage->addToFrontend(m_frontend, m_inspectorController->injectedScriptHost()); + if (m_inspectorAgent->state()->getBoolean(ConsoleAgentState::consoleMessagesEnabled) && m_frontend) + m_previousMessage->addToFrontend(m_frontend, m_inspectorAgent->injectedScriptHost()); } if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) { diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.h b/Source/WebCore/inspector/InspectorConsoleAgent.h index 411f709..10ffb02 100644 --- a/Source/WebCore/inspector/InspectorConsoleAgent.h +++ b/Source/WebCore/inspector/InspectorConsoleAgent.h @@ -37,7 +37,7 @@ namespace WebCore { #if ENABLE(INSPECTOR) class ConsoleMessage; -class InspectorController; +class InspectorAgent; class InspectorFrontend; class InspectorState; class ResourceError; @@ -49,7 +49,7 @@ class ScriptProfile; class InspectorConsoleAgent { WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent); public: - InspectorConsoleAgent(InspectorController*); + InspectorConsoleAgent(InspectorAgent*); ~InspectorConsoleAgent(); void setConsoleMessagesEnabled(bool enabled, bool* newState); @@ -77,7 +77,7 @@ private: void setConsoleMessagesEnabled(bool); void addConsoleMessage(PassOwnPtr); - InspectorController* m_inspectorController; + InspectorAgent* m_inspectorAgent; InspectorFrontend* m_frontend; ConsoleMessage* m_previousMessage; Vector > m_consoleMessages; diff --git a/Source/WebCore/inspector/InspectorConsoleInstrumentation.h b/Source/WebCore/inspector/InspectorConsoleInstrumentation.h new file mode 100644 index 0000000..8326741 --- /dev/null +++ b/Source/WebCore/inspector/InspectorConsoleInstrumentation.h @@ -0,0 +1,127 @@ +/* +* 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 InspectorConsoleInstrumentation_h +#define InspectorConsoleInstrumentation_h + +#include "InspectorInstrumentation.h" +#include "ScriptArguments.h" +#include "ScriptCallStack.h" +#include + +namespace WebCore { + +inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr arguments, PassRefPtr callStack) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + addMessageToConsoleImpl(inspectorAgent, source, type, level, message, arguments, callStack); +#endif +} + +inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + addMessageToConsoleImpl(inspectorAgent, source, type, level, message, lineNumber, sourceID); +#endif +} + +inline void InspectorInstrumentation::consoleCount(Page* page, PassRefPtr arguments, PassRefPtr stack) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + consoleCountImpl(inspectorAgent, arguments, stack); +#endif +} + +inline void InspectorInstrumentation::startConsoleTiming(Page* page, const String& title) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + startConsoleTimingImpl(inspectorAgent, title); +#endif +} + +inline void InspectorInstrumentation::stopConsoleTiming(Page* page, const String& title, PassRefPtr stack) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + stopConsoleTimingImpl(inspectorAgent, title, stack); +#endif +} + +inline void InspectorInstrumentation::consoleMarkTimeline(Page* page, PassRefPtr arguments) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForPage(page)) + consoleMarkTimelineImpl(inspectorAgent, arguments); +#endif +} + +#if ENABLE(JAVASCRIPT_DEBUGGER) +inline void InspectorInstrumentation::addStartProfilingMessageToConsole(Page* page, const String& title, unsigned lineNumber, const String& sourceURL) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + addStartProfilingMessageToConsoleImpl(inspectorAgent, title, lineNumber, sourceURL); +#endif +} + +inline void InspectorInstrumentation::addProfile(Page* page, RefPtr profile, PassRefPtr callStack) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + addProfileImpl(inspectorAgent, profile, callStack); +#endif +} + +inline bool InspectorInstrumentation::profilerEnabled(Page* page) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + return profilerEnabledImpl(inspectorAgent); +#endif + return false; +} + +inline String InspectorInstrumentation::getCurrentUserInitiatedProfileName(Page* page, bool incrementProfileNumber) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + return InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(inspectorAgent, incrementProfileNumber); +#endif + return ""; +} +#endif + +} // namespace WebCore + +#endif // !defined(InspectorConsoleInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp index 8533a5f..426e5f3 100644 --- a/Source/WebCore/inspector/InspectorController.cpp +++ b/Source/WebCore/inspector/InspectorController.cpp @@ -1,30 +1,31 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek + * 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: + * modification, are permitted provided that the following conditions are + * met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * * 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 APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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" @@ -32,307 +33,42 @@ #if ENABLE(INSPECTOR) -#include "CachedResource.h" -#include "CachedResourceLoader.h" -#include "Chrome.h" -#include "Cookie.h" -#include "CookieJar.h" -#include "DOMWindow.h" -#include "DOMWrapperWorld.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "Element.h" -#include "FloatConversion.h" -#include "FloatQuad.h" -#include "FloatRect.h" #include "Frame.h" -#include "FrameLoadRequest.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "FrameView.h" #include "GraphicsContext.h" -#include "HTMLFrameOwnerElement.h" -#include "HTTPHeaderMap.h" -#include "HitTestResult.h" -#include "InjectedScript.h" #include "InjectedScriptHost.h" +#include "InspectorAgent.h" #include "InspectorBackendDispatcher.h" -#include "InspectorBrowserDebuggerAgent.h" -#include "InspectorCSSAgent.h" -#include "InspectorClient.h" -#include "InspectorConsoleAgent.h" -#include "InspectorDOMAgent.h" -#include "InspectorDOMStorageResource.h" -#include "InspectorDatabaseResource.h" #include "InspectorDebuggerAgent.h" +#include "InspectorClient.h" #include "InspectorFrontend.h" #include "InspectorFrontendClient.h" #include "InspectorInstrumentation.h" -#include "InspectorProfilerAgent.h" -#include "InspectorResourceAgent.h" -#include "InspectorRuntimeAgent.h" -#include "InspectorSettings.h" -#include "InspectorState.h" -#include "InspectorTimelineAgent.h" -#include "InspectorValues.h" -#include "InspectorWorkerResource.h" -#include "IntRect.h" #include "Page.h" -#include "ProgressTracker.h" -#include "Range.h" -#include "RenderInline.h" -#include "ResourceRequest.h" -#include "ResourceResponse.h" -#include "ScriptArguments.h" -#include "ScriptCallStack.h" -#include "ScriptFunctionCall.h" #include "ScriptObject.h" -#include "ScriptProfile.h" -#include "ScriptProfiler.h" -#include "ScriptSourceCode.h" -#include "ScriptState.h" -#include "SecurityOrigin.h" #include "Settings.h" -#include "SharedBuffer.h" -#include "TextEncoding.h" -#include "TextIterator.h" -#include "TextRun.h" -#include "UserGestureIndicator.h" -#include "WindowFeatures.h" -#include -#include -#include -#include -#include -#include - -#if ENABLE(DATABASE) -#include "Database.h" -#include "InspectorDatabaseAgent.h" -#endif - -#if ENABLE(DOM_STORAGE) -#include "InspectorDOMStorageAgent.h" -#include "Storage.h" -#include "StorageArea.h" -#endif - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) -#include "InspectorApplicationCacheAgent.h" -#endif - -#if ENABLE(FILE_SYSTEM) -#include "InspectorFileSystemAgent.h" -#endif - -using namespace std; namespace WebCore { -const char* const InspectorController::ElementsPanel = "elements"; -const char* const InspectorController::ConsolePanel = "console"; -const char* const InspectorController::ScriptsPanel = "scripts"; -const char* const InspectorController::ProfilesPanel = "profiles"; - -InspectorController::InspectorController(Page* page, InspectorClient* client) - : m_inspectedPage(page) - , m_client(client) +InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient) + : m_inspectorAgent(new InspectorAgent(page, inspectorClient)) + , m_inspectorBackendDispatcher(new InspectorBackendDispatcher(m_inspectorAgent.get())) + , m_inspectorClient(inspectorClient) , m_openingFrontend(false) - , m_cssAgent(new InspectorCSSAgent()) - , m_state(new InspectorState(client)) - , m_inspectorBackendDispatcher(new InspectorBackendDispatcher(this)) - , m_injectedScriptHost(InjectedScriptHost::create(this)) - , m_consoleAgent(new InspectorConsoleAgent(this)) -#if ENABLE(JAVASCRIPT_DEBUGGER) - , m_attachDebuggerWhenShown(false) - , m_profilerAgent(InspectorProfilerAgent::create(this)) -#endif { - ASSERT_ARG(page, page); - ASSERT_ARG(client, client); } InspectorController::~InspectorController() { - // These should have been cleared in inspectedPageDestroyed(). - ASSERT(!m_client); - ASSERT(!m_inspectedPage); - ASSERT(!m_highlightedNode); -} - -void InspectorController::inspectedPageDestroyed() -{ - if (m_frontend) - m_frontend->disconnectFromBackend(); - - hideHighlight(); - -#if ENABLE(JAVASCRIPT_DEBUGGER) - m_debuggerAgent.clear(); - m_browserDebuggerAgent.clear(); -#endif - - ASSERT(m_inspectedPage); - m_inspectedPage = 0; - - releaseFrontendLifetimeAgents(); - m_injectedScriptHost->disconnectController(); - - m_client->inspectorDestroyed(); - m_client = 0; -} - -bool InspectorController::enabled() const -{ - if (!m_inspectedPage) - return false; - return m_inspectedPage->settings()->developerExtrasEnabled(); -} - -bool InspectorController::inspectorStartsAttached() -{ - return m_settings->getBoolean(InspectorSettings::InspectorStartsAttached); -} - -void InspectorController::setInspectorStartsAttached(bool attached) -{ - m_settings->setBoolean(InspectorSettings::InspectorStartsAttached, attached); -} - -void InspectorController::setInspectorAttachedHeight(long height) -{ - m_settings->setLong(InspectorSettings::InspectorAttachedHeight, height); -} - -long InspectorController::inspectorAttachedHeight() const -{ - return m_settings->getLong(InspectorSettings::InspectorAttachedHeight); -} - -bool InspectorController::searchingForNodeInPage() const -{ - return m_state->getBoolean(InspectorState::searchingForNode); -} - -void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie) -{ - m_state->restoreFromInspectorCookie(inspectorStateCookie); - - if (!m_frontend) { - connectFrontend(); - m_frontend->frontendReused(); - m_frontend->inspectedURLChanged(inspectedURL().string()); - m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); - pushDataCollectedOffline(); - } - - m_resourceAgent = InspectorResourceAgent::restore(m_inspectedPage, m_state.get(), m_frontend.get()); - - if (m_state->getBoolean(InspectorState::timelineProfilerEnabled)) - startTimelineProfiler(); - -#if ENABLE(JAVASCRIPT_DEBUGGER) - restoreDebugger(); - restoreProfiler(ProfilerRestoreResetAgent); - if (m_state->getBoolean(InspectorState::userInitiatedProfiling)) - startUserInitiatedProfiling(); -#endif -} - -void InspectorController::inspect(Node* node) -{ - if (!enabled()) - return; - - show(); - - if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE) - node = node->parentNode(); - m_nodeToFocus = node; - - if (!m_frontend) - return; - - focusNode(); -} - -void InspectorController::focusNode() -{ - if (!enabled()) - return; - - ASSERT(m_frontend); - ASSERT(m_nodeToFocus); - - long id = m_domAgent->pushNodePathToFrontend(m_nodeToFocus.get()); - m_frontend->updateFocusedNode(id); - m_nodeToFocus = 0; -} - -void InspectorController::highlight(Node* node) -{ - if (!enabled()) - return; - ASSERT_ARG(node, node); - m_highlightedNode = node; - m_client->highlight(node); -} - -void InspectorController::highlightDOMNode(long nodeId) -{ - Node* node = 0; - if (m_domAgent && (node = m_domAgent->nodeForId(nodeId))) - highlight(node); -} - -void InspectorController::highlightFrame(unsigned long frameId) -{ - Frame* mainFrame = m_inspectedPage->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext(mainFrame)) { - if (reinterpret_cast(frame) == frameId && frame->ownerElement()) { - highlight(frame->ownerElement()); - return; - } - } -} - -void InspectorController::hideHighlight() -{ - if (!enabled()) - return; - m_highlightedNode = 0; - m_client->hideHighlight(); } -void InspectorController::mouseDidMoveOverElement(const HitTestResult& result, unsigned) +void InspectorController::setInspectorFrontendClient(PassOwnPtr inspectorFrontendClient) { - if (!enabled() || !searchingForNodeInPage()) - return; - - Node* node = result.innerNode(); - while (node && node->nodeType() == Node::TEXT_NODE) - node = node->parentNode(); - if (node) - highlight(node); -} - -bool InspectorController::handleMousePress() -{ - if (!enabled() || !searchingForNodeInPage()) - return false; - - if (m_highlightedNode) { - RefPtr node = m_highlightedNode; - setSearchingForNode(false); - inspect(node.get()); - } - return true; + m_inspectorFrontendClient = inspectorFrontendClient; } -void InspectorController::setInspectorFrontendClient(PassOwnPtr client) +bool InspectorController::hasInspectorFrontendClient() const { - ASSERT(!m_inspectorFrontendClient); - m_inspectorFrontendClient = client; + return m_inspectorFrontendClient; } void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world) @@ -340,1071 +76,191 @@ void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWo if (world != mainThreadNormalWorld()) return; - // If the page is supposed to serve as InspectorFrontend notify inspetor frontend + // If the page is supposed to serve as InspectorFrontend notify inspector frontend // client that it's cleared so that the client can expose inspector bindings. - if (m_inspectorFrontendClient && frame == m_inspectedPage->mainFrame()) + if (m_inspectorFrontendClient && frame == m_inspectorAgent->inspectedPage()->mainFrame()) m_inspectorFrontendClient->windowObjectCleared(); - - if (enabled()) { - if (m_frontend && frame == m_inspectedPage->mainFrame()) - m_injectedScriptHost->discardInjectedScripts(); - if (m_scriptsToEvaluateOnLoad.size()) { - ScriptState* scriptState = mainWorldScriptState(frame); - for (Vector::iterator it = m_scriptsToEvaluateOnLoad.begin(); - it != m_scriptsToEvaluateOnLoad.end(); ++it) { - m_injectedScriptHost->injectScript(*it, scriptState); - } - } - } - if (!m_inspectorExtensionAPI.isEmpty()) - m_injectedScriptHost->injectScript(m_inspectorExtensionAPI, mainWorldScriptState(frame)); } -void InspectorController::setSearchingForNode(bool enabled) +void InspectorController::startTimelineProfiler() { - if (searchingForNodeInPage() == enabled) - return; - m_state->setBoolean(InspectorState::searchingForNode, enabled); - if (!enabled) - hideHighlight(); + m_inspectorAgent->startTimelineProfiler(); } -void InspectorController::setSearchingForNode(bool enabled, bool* newState) +void InspectorController::stopTimelineProfiler() { - *newState = enabled; - setSearchingForNode(enabled); + m_inspectorAgent->stopTimelineProfiler(); } void InspectorController::connectFrontend() { m_openingFrontend = false; - releaseFrontendLifetimeAgents(); - m_frontend = new InspectorFrontend(m_client); - m_domAgent = InspectorDOMAgent::create(m_injectedScriptHost.get(), m_frontend.get()); - m_runtimeAgent = InspectorRuntimeAgent::create(m_injectedScriptHost.get()); - m_cssAgent->setDOMAgent(m_domAgent.get()); - -#if ENABLE(DATABASE) - m_databaseAgent = InspectorDatabaseAgent::create(&m_databaseResources, m_frontend.get()); -#endif - -#if ENABLE(DOM_STORAGE) - m_domStorageAgent = InspectorDOMStorageAgent::create(&m_domStorageResources, m_frontend.get()); -#endif - - if (m_timelineAgent) - m_timelineAgent->resetFrontendProxyObject(m_frontend.get()); - - m_consoleAgent->setFrontend(m_frontend.get()); - - // Initialize Web Inspector title. - m_frontend->inspectedURLChanged(inspectedURL().string()); - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_frontend.get()); -#endif + m_inspectorFrontend = new InspectorFrontend(m_inspectorClient); + m_inspectorAgent->setFrontend(m_inspectorFrontend.get()); -#if ENABLE(FILE_SYSTEM) - m_fileSystemAgent = InspectorFileSystemAgent::create(this, m_frontend.get()); -#endif - if (!InspectorInstrumentation::hasFrontends()) ScriptController::setCaptureCallStackForUncaughtExceptions(true); InspectorInstrumentation::frontendCreated(); } -void InspectorController::show() -{ - if (!enabled()) - return; - - if (m_openingFrontend) - return; - - if (m_frontend) - m_frontend->bringToFront(); - else { - m_openingFrontend = true; - m_client->openInspectorFrontend(this); - } -} - -void InspectorController::showPanel(const String& panel) -{ - if (!enabled()) - return; - - show(); - - if (!m_frontend) { - m_showAfterVisible = panel; - return; - } - m_frontend->showPanel(panel); -} - -void InspectorController::close() -{ - if (!m_frontend) - return; - m_frontend->disconnectFromBackend(); - disconnectFrontend(); -} - void InspectorController::disconnectFrontend() { - if (!m_frontend) + if (!m_inspectorFrontend) return; - m_frontend.clear(); + m_inspectorAgent->disconnectFrontend(); + + m_inspectorFrontend.clear(); InspectorInstrumentation::frontendDeleted(); if (!InspectorInstrumentation::hasFrontends()) ScriptController::setCaptureCallStackForUncaughtExceptions(false); -#if ENABLE(JAVASCRIPT_DEBUGGER) - // If the window is being closed with the debugger enabled, - // remember this state to re-enable debugger on the next window - // opening. - bool debuggerWasEnabled = debuggerEnabled(); - disableDebugger(); - m_attachDebuggerWhenShown = debuggerWasEnabled; -#endif - setSearchingForNode(false); - unbindAllResources(); - stopTimelineProfiler(); - - hideHighlight(); - -#if ENABLE(JAVASCRIPT_DEBUGGER) - m_profilerAgent->setFrontend(0); - m_profilerAgent->stopUserInitiatedProfiling(true); -#endif - m_consoleAgent->setFrontend(0); - - releaseFrontendLifetimeAgents(); - m_timelineAgent.clear(); - m_extraHeaders.clear(); -} - -InspectorResourceAgent* InspectorController::resourceAgent() -{ - if (!m_resourceAgent && m_frontend) - m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_state.get(), m_frontend.get()); - return m_resourceAgent.get(); -} - -void InspectorController::releaseFrontendLifetimeAgents() -{ - m_resourceAgent.clear(); - m_runtimeAgent.clear(); - - // This should be invoked prior to m_domAgent destruction. - m_cssAgent->setDOMAgent(0); - - // m_domAgent is RefPtr. Remove DOM listeners first to ensure that there are - // no references to the DOM agent from the DOM tree. - if (m_domAgent) - m_domAgent->reset(); - m_domAgent.clear(); - -#if ENABLE(DATABASE) - if (m_databaseAgent) - m_databaseAgent->clearFrontend(); - m_databaseAgent.clear(); -#endif - -#if ENABLE(DOM_STORAGE) - m_domStorageAgent.clear(); -#endif - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - m_applicationCacheAgent.clear(); -#endif - -#if ENABLE(FILE_SYSTEM) - if (m_fileSystemAgent) - m_fileSystemAgent->stop(); - m_fileSystemAgent.clear(); -#endif -} - -void InspectorController::populateScriptObjects() -{ - ASSERT(m_frontend); - if (!m_frontend) - return; - - if (!m_showAfterVisible.isEmpty()) { - showPanel(m_showAfterVisible); - m_showAfterVisible = ""; - } - -#if ENABLE(JAVASCRIPT_DEBUGGER) - if (m_profilerAgent->enabled()) - m_frontend->profilerWasEnabled(); -#endif - - pushDataCollectedOffline(); - - if (m_nodeToFocus) - focusNode(); - - // Dispatch pending frontend commands - for (Vector >::iterator it = m_pendingEvaluateTestCommands.begin(); it != m_pendingEvaluateTestCommands.end(); ++it) - m_frontend->evaluateForTestInFrontend((*it).first, (*it).second); - m_pendingEvaluateTestCommands.clear(); - - restoreDebugger(); - restoreProfiler(ProfilerRestoreNoAction); -} - -void InspectorController::pushDataCollectedOffline() -{ - m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); - -#if ENABLE(DATABASE) - DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); - for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) - it->second->bind(m_frontend.get()); -#endif -#if ENABLE(DOM_STORAGE) - DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end(); - for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) - it->second->bind(m_frontend.get()); -#endif -#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS) - WorkersMap::iterator workersEnd = m_workers.end(); - for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it) { - InspectorWorkerResource* worker = it->second.get(); - m_frontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker()); - } -#endif -} - -void InspectorController::restoreDebugger() -{ - ASSERT(m_frontend); -#if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorDebuggerAgent::isDebuggerAlwaysEnabled() || m_attachDebuggerWhenShown || m_settings->getBoolean(InspectorSettings::DebuggerAlwaysEnabled)) { - enableDebugger(false); - m_attachDebuggerWhenShown = false; - } -#endif -} - -void InspectorController::restoreProfiler(ProfilerRestoreAction action) -{ - ASSERT(m_frontend); -#if ENABLE(JAVASCRIPT_DEBUGGER) - m_profilerAgent->setFrontend(m_frontend.get()); - if (!ScriptProfiler::isProfilerAlwaysEnabled() && m_settings->getBoolean(InspectorSettings::ProfilerAlwaysEnabled)) - enableProfiler(); - if (action == ProfilerRestoreResetAgent) - m_profilerAgent->resetFrontendProfiles(); -#endif -} - -void InspectorController::unbindAllResources() -{ -#if ENABLE(DATABASE) - DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); - for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) - it->second->unbind(); -#endif -#if ENABLE(DOM_STORAGE) - DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end(); - for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) - it->second->unbind(); -#endif - if (m_timelineAgent) - m_timelineAgent->reset(); } -void InspectorController::didCommitLoad(DocumentLoader* loader) +void InspectorController::show() { if (!enabled()) return; - if (m_resourceAgent) - m_resourceAgent->didCommitLoad(loader); - - ASSERT(m_inspectedPage); - - if (loader->frame() == m_inspectedPage->mainFrame()) { - if (m_frontend) - m_frontend->inspectedURLChanged(loader->url().string()); - - m_injectedScriptHost->discardInjectedScripts(); - m_consoleAgent->reset(); - -#if ENABLE(JAVASCRIPT_DEBUGGER) - if (m_debuggerAgent) { - m_debuggerAgent->clearForPageNavigation(); - if (m_browserDebuggerAgent) - m_browserDebuggerAgent->inspectedURLChanged(inspectedURL()); - } -#endif - -#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) - m_profilerAgent->stopUserInitiatedProfiling(true); - m_profilerAgent->resetState(); -#endif - - // unbindAllResources should be called before database and DOM storage - // resources are cleared so that it has a chance to unbind them. - unbindAllResources(); - - if (m_frontend) { - m_frontend->reset(); - m_domAgent->reset(); - m_cssAgent->reset(); - } -#if ENABLE(WORKERS) - m_workers.clear(); -#endif -#if ENABLE(DATABASE) - m_databaseResources.clear(); -#endif -#if ENABLE(DOM_STORAGE) - m_domStorageResources.clear(); -#endif - - if (m_frontend) - m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); - } -} - -void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loader, const KURL& url) -{ - if (!enabled() || !isMainResourceLoader(loader, url)) - return; - - if (m_timelineAgent) - m_timelineAgent->didMarkDOMContentEvent(); - if (m_frontend) - m_frontend->domContentEventFired(currentTime()); -} - -void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, const KURL& url) -{ - if (!enabled() || !isMainResourceLoader(loader, url)) - return; - - if (m_timelineAgent) - m_timelineAgent->didMarkLoadEvent(); - if (m_frontend) - m_frontend->loadEventFired(currentTime()); -} - -bool InspectorController::isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl) -{ - return loader->frame() == m_inspectedPage->mainFrame() && requestUrl == loader->requestURL(); -} - -void InspectorController::willSendRequest(ResourceRequest& request) -{ - if (!enabled()) + if (m_openingFrontend) return; - if (m_frontend) { - // Only enable load timing and raw headers if front-end is attached, as otherwise we may produce overhead. - request.setReportLoadTiming(true); - request.setReportRawHeaders(true); - - if (m_extraHeaders) { - HTTPHeaderMap::const_iterator end = m_extraHeaders->end(); - for (HTTPHeaderMap::const_iterator it = m_extraHeaders->begin(); it != end; ++it) - request.setHTTPHeaderField(it->first, it->second); - } + if (m_inspectorFrontend) + m_inspectorFrontend->bringToFront(); + else { + m_openingFrontend = true; + m_inspectorClient->openInspectorFrontend(this); } } -void InspectorController::ensureSettingsLoaded() -{ - if (m_settings) - return; - m_settings = new InspectorSettings(m_client); - m_state->setBoolean(InspectorState::monitoringXHR, m_settings->getBoolean(InspectorSettings::MonitoringXHREnabled)); -} - -void InspectorController::startTimelineProfiler() +void InspectorController::close() { - if (!enabled()) - return; - - if (m_timelineAgent) + if (!m_inspectorFrontend) return; - - m_timelineAgent = new InspectorTimelineAgent(m_frontend.get()); - if (m_frontend) - m_frontend->timelineProfilerWasStarted(); - - m_state->setBoolean(InspectorState::timelineProfilerEnabled, true); + m_inspectorFrontend->disconnectFromBackend(); + disconnectFrontend(); } -void InspectorController::stopTimelineProfiler() +void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie) { - if (!enabled()) - return; - - if (!m_timelineAgent) - return; - - m_timelineAgent = 0; - if (m_frontend) - m_frontend->timelineProfilerWasStopped(); - - m_state->setBoolean(InspectorState::timelineProfilerEnabled, false); + ASSERT(!m_inspectorFrontend); + connectFrontend(); + m_inspectorAgent->restoreInspectorStateFromCookie(inspectorStateCookie); } -#if ENABLE(WORKERS) -class PostWorkerNotificationToFrontendTask : public ScriptExecutionContext::Task { -public: - static PassOwnPtr create(PassRefPtr worker, InspectorController::WorkerAction action) - { - return new PostWorkerNotificationToFrontendTask(worker, action); - } - -private: - PostWorkerNotificationToFrontendTask(PassRefPtr worker, InspectorController::WorkerAction action) - : m_worker(worker) - , m_action(action) - { - } - - virtual void performTask(ScriptExecutionContext* scriptContext) - { - if (scriptContext->isDocument()) { - if (InspectorController* inspector = static_cast(scriptContext)->page()->inspectorController()) - inspector->postWorkerNotificationToFrontend(*m_worker, m_action); - } - } - -private: - RefPtr m_worker; - InspectorController::WorkerAction m_action; -}; - -void InspectorController::postWorkerNotificationToFrontend(const InspectorWorkerResource& worker, InspectorController::WorkerAction action) +void InspectorController::evaluateForTestInFrontend(long callId, const String& script) { - if (!m_frontend) - return; -#if ENABLE(JAVASCRIPT_DEBUGGER) - switch (action) { - case InspectorController::WorkerCreated: - m_frontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker()); - break; - case InspectorController::WorkerDestroyed: - m_frontend->didDestroyWorker(worker.id()); - break; - } -#endif + m_inspectorAgent->evaluateForTestInFrontend(callId, script); } -void InspectorController::didCreateWorker(intptr_t id, const String& url, bool isSharedWorker) +void InspectorController::drawNodeHighlight(GraphicsContext& context) const { - if (!enabled()) - return; - - RefPtr workerResource(InspectorWorkerResource::create(id, url, isSharedWorker)); - m_workers.set(id, workerResource); - if (m_inspectedPage && m_frontend) - m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource, InspectorController::WorkerCreated)); + m_inspectorAgent->drawNodeHighlight(context); } -void InspectorController::didDestroyWorker(intptr_t id) +void InspectorController::showConsole() { if (!enabled()) return; - - WorkersMap::iterator workerResource = m_workers.find(id); - if (workerResource == m_workers.end()) - return; - if (m_inspectedPage && m_frontend) - m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource->second, InspectorController::WorkerDestroyed)); - m_workers.remove(workerResource); + show(); + m_inspectorAgent->showConsole(); } -#endif // ENABLE(WORKERS) -#if ENABLE(DATABASE) -void InspectorController::didOpenDatabase(PassRefPtr database, const String& domain, const String& name, const String& version) +void InspectorController::inspect(Node* node) { if (!enabled()) return; - RefPtr resource = InspectorDatabaseResource::create(database, domain, name, version); - - m_databaseResources.set(resource->id(), resource); - - // Resources are only bound while visible. - if (m_frontend) - resource->bind(m_frontend.get()); -} -#endif - -void InspectorController::getCookies(RefPtr* cookies, WTF::String* cookiesString) -{ - // If we can get raw cookies. - ListHashSet rawCookiesList; - - // If we can't get raw cookies - fall back to String representation - String stringCookiesList; - - // Return value to getRawCookies should be the same for every call because - // the return value is platform/network backend specific, and the call will - // always return the same true/false value. - bool rawCookiesImplemented = false; - - for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { - Document* document = frame->document(); - const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); - CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); - for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) { - Vector docCookiesList; - rawCookiesImplemented = getRawCookies(document, KURL(ParsedURLString, it->second->url()), docCookiesList); - - if (!rawCookiesImplemented) { - // FIXME: We need duplication checking for the String representation of cookies. - ExceptionCode ec = 0; - stringCookiesList += document->cookie(ec); - // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here - // because "document" is the document of the main frame of the page. - ASSERT(!ec); - } else { - int cookiesSize = docCookiesList.size(); - for (int i = 0; i < cookiesSize; i++) { - if (!rawCookiesList.contains(docCookiesList[i])) - rawCookiesList.add(docCookiesList[i]); - } - } - } - } + show(); - if (rawCookiesImplemented) - *cookies = buildArrayForCookies(rawCookiesList); - else - *cookiesString = stringCookiesList; + m_inspectorAgent->inspect(node); } -PassRefPtr InspectorController::buildArrayForCookies(ListHashSet& cookiesList) +bool InspectorController::enabled() const { - RefPtr cookies = InspectorArray::create(); - - ListHashSet::iterator end = cookiesList.end(); - ListHashSet::iterator it = cookiesList.begin(); - for (int i = 0; it != end; ++it, i++) - cookies->pushObject(buildObjectForCookie(*it)); - - return cookies; + return m_inspectorAgent->enabled(); } -PassRefPtr InspectorController::buildObjectForCookie(const Cookie& cookie) +Page* InspectorController::inspectedPage() const { - RefPtr value = InspectorObject::create(); - value->setString("name", cookie.name); - value->setString("value", cookie.value); - value->setString("domain", cookie.domain); - value->setString("path", cookie.path); - value->setNumber("expires", cookie.expires); - value->setNumber("size", (cookie.name.length() + cookie.value.length())); - value->setBoolean("httpOnly", cookie.httpOnly); - value->setBoolean("secure", cookie.secure); - value->setBoolean("session", cookie.session); - return value; + return m_inspectorAgent->inspectedPage(); } -void InspectorController::deleteCookie(const String& cookieName, const String& domain) +bool InspectorController::timelineProfilerEnabled() { - for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree()->traverseNext(m_inspectedPage->mainFrame())) { - Document* document = frame->document(); - if (document->url().host() != domain) - continue; - const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources(); - CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end(); - for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) - WebCore::deleteCookie(document, KURL(ParsedURLString, it->second->url()), cookieName); - } + return m_inspectorAgent->timelineAgent(); } -#if ENABLE(DOM_STORAGE) -void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame) +#if ENABLE(JAVASCRIPT_DEBUGGER) +void InspectorController::enableProfiler() { - if (!enabled()) - return; - - DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end(); - for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) - if (it->second->isSameHostAndType(frame, isLocalStorage)) - return; - - RefPtr domStorage = Storage::create(frame, storageArea); - RefPtr resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame); - - m_domStorageResources.set(resource->id(), resource); - - // Resources are only bound while visible. - if (m_frontend) - resource->bind(m_frontend.get()); + m_inspectorAgent->enableProfiler(); } -#endif -#if ENABLE(WEB_SOCKETS) -void InspectorController::didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL) +void InspectorController::disableProfiler() { - if (!enabled()) - return; - ASSERT(m_inspectedPage); - - if (m_resourceAgent) - m_resourceAgent->didCreateWebSocket(identifier, requestURL); - UNUSED_PARAM(documentURL); + m_inspectorAgent->disableProfiler(); } -void InspectorController::willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest& request) +bool InspectorController::profilerEnabled() { - if (m_resourceAgent) - m_resourceAgent->willSendWebSocketHandshakeRequest(identifier, request); + return m_inspectorAgent->profilerEnabled(); } -void InspectorController::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse& response) +bool InspectorController::debuggerEnabled() { - if (m_resourceAgent) - m_resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response); + return m_inspectorAgent->debuggerEnabled(); } -void InspectorController::didCloseWebSocket(unsigned long identifier) +void InspectorController::showAndEnableDebugger() { - if (m_resourceAgent) - m_resourceAgent->didCloseWebSocket(identifier); + m_inspectorAgent->showAndEnableDebugger(); } -#endif // ENABLE(WEB_SOCKETS) -#if ENABLE(JAVASCRIPT_DEBUGGER) -bool InspectorController::isRecordingUserInitiatedProfile() const +void InspectorController::disableDebugger() { - return m_profilerAgent->isRecordingUserInitiatedProfile(); + m_inspectorAgent->disableDebugger(); } void InspectorController::startUserInitiatedProfiling() { - if (!enabled()) - return; - m_profilerAgent->startUserInitiatedProfiling(); - m_state->setBoolean(InspectorState::userInitiatedProfiling, true); + m_inspectorAgent->startUserInitiatedProfiling(); } void InspectorController::stopUserInitiatedProfiling() { - if (!enabled()) - return; - m_profilerAgent->stopUserInitiatedProfiling(); - m_state->setBoolean(InspectorState::userInitiatedProfiling, false); -} - -bool InspectorController::profilerEnabled() const -{ - return enabled() && m_profilerAgent->enabled(); -} - -void InspectorController::enableProfiler(bool always, bool skipRecompile) -{ - if (always) - m_settings->setBoolean(InspectorSettings::ProfilerAlwaysEnabled, true); - m_profilerAgent->enable(skipRecompile); -} - -void InspectorController::disableProfiler(bool always) -{ - if (always) - m_settings->setBoolean(InspectorSettings::ProfilerAlwaysEnabled, false); - m_profilerAgent->disable(); + m_inspectorAgent->stopUserInitiatedProfiling(); } -#endif - -#if ENABLE(JAVASCRIPT_DEBUGGER) -void InspectorController::showAndEnableDebugger() -{ - if (!enabled()) - return; - if (debuggerEnabled()) - return; - - if (!m_frontend) { - m_attachDebuggerWhenShown = true; - showPanel(ScriptsPanel); - } else - enableDebugger(false); -} - -void InspectorController::enableDebugger(bool always) +bool InspectorController::isRecordingUserInitiatedProfile() const { - ASSERT(!debuggerEnabled()); - if (always) - m_settings->setBoolean(InspectorSettings::DebuggerAlwaysEnabled, true); - - ASSERT(m_inspectedPage); - - m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get()); - m_browserDebuggerAgent = InspectorBrowserDebuggerAgent::create(this); - m_browserDebuggerAgent->inspectedURLChanged(inspectedURL()); - - m_frontend->debuggerWasEnabled(); + return m_inspectorAgent->isRecordingUserInitiatedProfile(); } -void InspectorController::disableDebugger(bool always) +void InspectorController::setInspectorExtensionAPI(const String& source) { - if (!enabled()) - return; - - if (always) - m_settings->setBoolean(InspectorSettings::DebuggerAlwaysEnabled, false); - - ASSERT(m_inspectedPage); - - m_debuggerAgent.clear(); - m_browserDebuggerAgent.clear(); - - m_attachDebuggerWhenShown = false; - - if (m_frontend) - m_frontend->debuggerWasDisabled(); + m_inspectorAgent->setInspectorExtensionAPI(source); } void InspectorController::resume() { - if (m_debuggerAgent) - m_debuggerAgent->resume(); -} - -void InspectorController::setAllBrowserBreakpoints(PassRefPtr breakpoints) -{ - m_state->setObject(InspectorState::browserBreakpoints, breakpoints); -} -#endif - -void InspectorController::evaluateForTestInFrontend(long callId, const String& script) -{ - if (m_frontend) - m_frontend->evaluateForTestInFrontend(callId, script); - else - m_pendingEvaluateTestCommands.append(pair(callId, script)); -} - -void InspectorController::didEvaluateForTestInFrontend(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(); -} - -static Path quadToPath(const FloatQuad& quad) -{ - Path quadPath; - quadPath.moveTo(quad.p1()); - quadPath.addLineTo(quad.p2()); - quadPath.addLineTo(quad.p3()); - quadPath.addLineTo(quad.p4()); - quadPath.closeSubpath(); - return quadPath; -} - -static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor) -{ - static const int outlineThickness = 2; - static const Color outlineColor(62, 86, 180, 228); - - Path quadPath = quadToPath(quad); - - // Clip out the quad, then draw with a 2px stroke to get a pixel - // of outline (because inflating a quad is hard) - { - context.save(); - context.clipOut(quadPath); - - context.setStrokeThickness(outlineThickness); - context.setStrokeColor(outlineColor, ColorSpaceDeviceRGB); - context.strokePath(quadPath); - - context.restore(); - } - - // Now do the fill - context.setFillColor(fillColor, ColorSpaceDeviceRGB); - context.fillPath(quadPath); -} - -static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor) -{ - context.save(); - Path clipQuadPath = quadToPath(clipQuad); - context.clipOut(clipQuadPath); - drawOutlinedQuad(context, quad, fillColor); - context.restore(); -} - -static void drawHighlightForBox(GraphicsContext& context, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad) -{ - static const Color contentBoxColor(125, 173, 217, 128); - static const Color paddingBoxColor(125, 173, 217, 160); - static const Color borderBoxColor(125, 173, 217, 192); - static const Color marginBoxColor(125, 173, 217, 228); - - if (marginQuad != borderQuad) - drawOutlinedQuadWithClip(context, marginQuad, borderQuad, marginBoxColor); - if (borderQuad != paddingQuad) - drawOutlinedQuadWithClip(context, borderQuad, paddingQuad, borderBoxColor); - if (paddingQuad != contentQuad) - drawOutlinedQuadWithClip(context, paddingQuad, contentQuad, paddingBoxColor); - - drawOutlinedQuad(context, contentQuad, contentBoxColor); -} - -static void drawHighlightForLineBoxesOrSVGRenderer(GraphicsContext& context, const Vector& lineBoxQuads) -{ - static const Color lineBoxColor(125, 173, 217, 128); - - for (size_t i = 0; i < lineBoxQuads.size(); ++i) - drawOutlinedQuad(context, lineBoxQuads[i], lineBoxColor); + if (InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent()) + debuggerAgent->resume(); } -static inline void convertFromFrameToMainFrame(Frame* frame, IntRect& rect) +void InspectorController::hideHighlight() { - rect = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(rect)); + m_inspectorAgent->hideHighlight(); } -static inline IntSize frameToMainFrameOffset(Frame* frame) +void InspectorController::dispatchMessageFromFrontend(const String& message) { - IntPoint mainFramePoint = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(IntPoint())); - return mainFramePoint - IntPoint(); + m_inspectorBackendDispatcher->dispatch(message); } -void InspectorController::drawNodeHighlight(GraphicsContext& context) const -{ - if (!m_highlightedNode) - return; - - RenderObject* renderer = m_highlightedNode->renderer(); - Frame* containingFrame = m_highlightedNode->document()->frame(); - if (!renderer || !containingFrame) - return; - - IntSize mainFrameOffset = frameToMainFrameOffset(containingFrame); - IntRect boundingBox = renderer->absoluteBoundingBoxRect(true); - boundingBox.move(mainFrameOffset); - - IntRect titleReferenceBox = boundingBox; - - ASSERT(m_inspectedPage); - - FrameView* view = m_inspectedPage->mainFrame()->view(); - FloatRect overlayRect = view->visibleContentRect(); - if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect))) - overlayRect = view->visibleContentRect(); - context.translate(-overlayRect.x(), -overlayRect.y()); - - // RenderSVGRoot should be highlighted through the isBox() code path, all other SVG elements should just dump their absoluteQuads(). -#if ENABLE(SVG) - bool isSVGRenderer = renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGRoot(); -#else - bool isSVGRenderer = false; #endif - if (renderer->isBox() && !isSVGRenderer) { - RenderBox* renderBox = toRenderBox(renderer); - - IntRect contentBox = renderBox->contentBoxRect(); - - IntRect paddingBox(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(), - contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom()); - IntRect borderBox(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(), - paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom()); - IntRect marginBox(borderBox.x() - renderBox->marginLeft(), borderBox.y() - renderBox->marginTop(), - borderBox.width() + renderBox->marginLeft() + renderBox->marginRight(), borderBox.height() + renderBox->marginTop() + renderBox->marginBottom()); - - titleReferenceBox = marginBox; - titleReferenceBox.move(mainFrameOffset); - titleReferenceBox.move(boundingBox.x(), boundingBox.y()); - - FloatQuad absContentQuad = renderBox->localToAbsoluteQuad(FloatRect(contentBox)); - FloatQuad absPaddingQuad = renderBox->localToAbsoluteQuad(FloatRect(paddingBox)); - FloatQuad absBorderQuad = renderBox->localToAbsoluteQuad(FloatRect(borderBox)); - FloatQuad absMarginQuad = renderBox->localToAbsoluteQuad(FloatRect(marginBox)); - - absContentQuad.move(mainFrameOffset); - absPaddingQuad.move(mainFrameOffset); - absBorderQuad.move(mainFrameOffset); - absMarginQuad.move(mainFrameOffset); - - drawHighlightForBox(context, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad); - } else if (renderer->isRenderInline() || isSVGRenderer) { - // FIXME: We should show margins/padding/border for inlines. - Vector lineBoxQuads; - renderer->absoluteQuads(lineBoxQuads); - for (unsigned i = 0; i < lineBoxQuads.size(); ++i) - lineBoxQuads[i] += mainFrameOffset; - - drawHighlightForLineBoxesOrSVGRenderer(context, lineBoxQuads); - } - - // Draw node title if necessary. - - if (!m_highlightedNode->isElementNode()) - return; - - WebCore::Settings* settings = containingFrame->settings(); - drawElementTitle(context, titleReferenceBox, overlayRect, settings); -} - -void InspectorController::drawElementTitle(GraphicsContext& context, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings* settings) const -{ - static const int rectInflatePx = 4; - static const int fontHeightPx = 12; - static const int borderWidthPx = 1; - static const Color tooltipBackgroundColor(255, 255, 194, 255); - static const Color tooltipBorderColor(Color::black); - static const Color tooltipFontColor(Color::black); - - Element* element = static_cast(m_highlightedNode.get()); - bool isXHTML = element->document()->isXHTMLDocument(); - String nodeTitle = isXHTML ? element->nodeName() : element->nodeName().lower(); - const AtomicString& idValue = element->getIdAttribute(); - if (!idValue.isNull() && !idValue.isEmpty()) { - nodeTitle += "#"; - nodeTitle += idValue; - } - if (element->hasClass() && element->isStyledElement()) { - const SpaceSplitString& classNamesString = static_cast(element)->classNames(); - size_t classNameCount = classNamesString.size(); - if (classNameCount) { - HashSet usedClassNames; - for (size_t i = 0; i < classNameCount; ++i) { - const AtomicString& className = classNamesString[i]; - if (usedClassNames.contains(className)) - continue; - usedClassNames.add(className); - nodeTitle += "."; - nodeTitle += className; - } - } - } - - Element* highlightedElement = m_highlightedNode->isElementNode() ? static_cast(m_highlightedNode.get()) : 0; - nodeTitle += " ["; - nodeTitle += String::number(highlightedElement ? highlightedElement->offsetWidth() : boundingBox.width()); - nodeTitle.append(static_cast(0x00D7)); // × - nodeTitle += String::number(highlightedElement ? highlightedElement->offsetHeight() : boundingBox.height()); - nodeTitle += "]"; - - FontDescription desc; - FontFamily family; - family.setFamily(settings->fixedFontFamily()); - desc.setFamily(family); - desc.setComputedSize(fontHeightPx); - Font font = Font(desc, 0, 0); - font.update(0); - - TextRun nodeTitleRun(nodeTitle); - IntPoint titleBasePoint = boundingBox.bottomLeft(); - titleBasePoint.move(rectInflatePx, rectInflatePx); - IntRect titleRect = enclosingIntRect(font.selectionRectForText(nodeTitleRun, titleBasePoint, fontHeightPx)); - titleRect.inflate(rectInflatePx); - - // The initial offsets needed to compensate for a 1px-thick border stroke (which is not a part of the rectangle). - int dx = -borderWidthPx; - int dy = borderWidthPx; - - // If the tip sticks beyond the right of overlayRect, right-align the tip with the said boundary. - if (titleRect.right() > overlayRect.right()) - dx = overlayRect.right() - titleRect.right(); - - // If the tip sticks beyond the left of overlayRect, left-align the tip with the said boundary. - if (titleRect.x() + dx < overlayRect.x()) - dx = overlayRect.x() - titleRect.x() - borderWidthPx; - - // If the tip sticks beyond the bottom of overlayRect, show the tip at top of bounding box. - if (titleRect.bottom() > overlayRect.bottom()) { - dy = boundingBox.y() - titleRect.bottom() - borderWidthPx; - // If the tip still sticks beyond the bottom of overlayRect, bottom-align the tip with the said boundary. - if (titleRect.bottom() + dy > overlayRect.bottom()) - dy = overlayRect.bottom() - titleRect.bottom(); - } - - // If the tip sticks beyond the top of overlayRect, show the tip at top of overlayRect. - if (titleRect.y() + dy < overlayRect.y()) - dy = overlayRect.y() - titleRect.y() + borderWidthPx; - - titleRect.move(dx, dy); - context.setStrokeColor(tooltipBorderColor, ColorSpaceDeviceRGB); - context.setStrokeThickness(borderWidthPx); - context.setFillColor(tooltipBackgroundColor, ColorSpaceDeviceRGB); - context.drawRect(titleRect); - context.setFillColor(tooltipFontColor, ColorSpaceDeviceRGB); - context.drawText(font, nodeTitleRun, IntPoint(titleRect.x() + rectInflatePx, titleRect.y() + font.height())); -} - -void InspectorController::openInInspectedWindow(const String& url) -{ - Frame* mainFrame = m_inspectedPage->mainFrame(); - - FrameLoadRequest request(mainFrame->document()->securityOrigin(), ResourceRequest(), "_blank"); - - bool created; - WindowFeatures windowFeatures; - Frame* newFrame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created); - if (!newFrame) - return; - - UserGestureIndicator indicator(DefinitelyProcessingUserGesture); - newFrame->loader()->setOpener(mainFrame); - newFrame->page()->setOpenedByDOM(); - newFrame->loader()->changeLocation(mainFrame->document()->securityOrigin(), newFrame->loader()->completeURL(url), "", false, false); -} - -void InspectorController::addScriptToEvaluateOnLoad(const String& source) -{ - m_scriptsToEvaluateOnLoad.append(source); -} - -void InspectorController::removeAllScriptsToEvaluateOnLoad() -{ - m_scriptsToEvaluateOnLoad.clear(); -} - -void InspectorController::setInspectorExtensionAPI(const String& source) -{ - m_inspectorExtensionAPI = source; -} - -KURL InspectorController::inspectedURL() const -{ - return m_inspectedPage->mainFrame()->loader()->url(); -} - -void InspectorController::reloadPage() -{ - // FIXME: Why do we set the user gesture indicator here? - UserGestureIndicator indicator(DefinitelyProcessingUserGesture); - m_inspectedPage->mainFrame()->navigationScheduler()->scheduleRefresh(); -} - -void InspectorController::setExtraHeaders(PassRefPtr headers) -{ - m_extraHeaders = adoptPtr(new HTTPHeaderMap()); - InspectorObject::const_iterator end = headers->end(); - for (InspectorObject::const_iterator it = headers->begin(); it != end; ++it) { - String value; - if (!it->second->asString(&value)) - continue; - m_extraHeaders->add(it->first, value); - } -} - } // namespace WebCore #endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h index 90a0300..7db024c 100644 --- a/Source/WebCore/inspector/InspectorController.h +++ b/Source/WebCore/inspector/InspectorController.h @@ -1,365 +1,115 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 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 - * are met: + * modification, are permitted provided that the following conditions are + * met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * * 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 APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 InspectorController_h #define InspectorController_h -#include "CharacterData.h" -#include "Console.h" -#include "Cookie.h" -#include "Page.h" #include "PlatformString.h" -#include -#include -#include -#include +#include +#include #include -#include namespace WebCore { -class CachedResource; -class CharacterData; -class Database; class DOMWrapperWorld; -class Document; -class DocumentLoader; -class FloatRect; +class Frame; class GraphicsContext; -class HTTPHeaderMap; -class HitTestResult; -class InjectedScript; -class InjectedScriptHost; -class InspectorArray; +class InspectorAgent; class InspectorBackendDispatcher; -class InspectorBrowserDebuggerAgent; class InspectorClient; -class InspectorConsoleAgent; -class InspectorCSSAgent; -class InspectorDOMAgent; -class InspectorDOMStorageAgent; -class InspectorDOMStorageResource; -class InspectorDatabaseAgent; -class InspectorDatabaseResource; -class InspectorDebuggerAgent; class InspectorFrontend; class InspectorFrontendClient; -class InspectorObject; -class InspectorProfilerAgent; -class InspectorResourceAgent; -class InspectorRuntimeAgent; -class InspectorSettings; -class InspectorState; -class InspectorStorageAgent; -class InspectorTimelineAgent; -class InspectorValue; -class InspectorWorkerResource; -class IntRect; -class KURL; -class Node; class Page; -class ResourceRequest; -class ResourceResponse; -class ResourceError; -class ScriptArguments; -class ScriptCallStack; -class ScriptProfile; -class SharedBuffer; -class StorageArea; - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) -class InspectorApplicationCacheAgent; -#endif - -#if ENABLE(FILE_SYSTEM) -class InspectorFileSystemAgent; -#endif - -#if ENABLE(WEB_SOCKETS) -class WebSocketHandshakeRequest; -class WebSocketHandshakeResponse; -#endif +class PostWorkerNotificationToFrontendTask; +class Node; class InspectorController { - WTF_MAKE_NONCOPYABLE(InspectorController); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_NONCOPYABLE(InspectorController); + WTF_MAKE_FAST_ALLOCATED; public: - static const char* const ConsolePanel; - static const char* const ElementsPanel; - static const char* const ProfilesPanel; - static const char* const ScriptsPanel; - InspectorController(Page*, InspectorClient*); ~InspectorController(); - InspectorBackendDispatcher* inspectorBackendDispatcher() { return m_inspectorBackendDispatcher.get(); } - InspectorClient* inspectorClient() { return m_client; } - InjectedScriptHost* injectedScriptHost() { return m_injectedScriptHost.get(); } - - void inspectedPageDestroyed(); - bool enabled() const; - - Page* inspectedPage() const { return m_inspectedPage; } - KURL inspectedURL() const; - void reloadPage(); - - void restoreInspectorStateFromCookie(const String& inspectorCookie); - - void inspect(Node*); - void highlight(Node*); - void hideHighlight(); - void highlightDOMNode(long nodeId); - void hideDOMNodeHighlight() { hideHighlight(); } - - void highlightFrame(unsigned long frameId); - void hideFrameHighlight() { hideHighlight(); } + Page* inspectedPage() const; void show(); - void showPanel(const String&); void close(); - void connectFrontend(); - void reuseFrontend(); - void disconnectFrontend(); - InspectorFrontend* frontend() const { return m_frontend.get(); } - - InspectorResourceAgent* resourceAgent(); - - InspectorController* inspectorAgent() { return this; } - InspectorConsoleAgent* consoleAgent() { return m_consoleAgent.get(); } - InspectorCSSAgent* cssAgent() { return m_cssAgent.get(); } - InspectorDOMAgent* domAgent() { return m_domAgent.get(); } - InjectedScriptHost* injectedScriptAgent() { return m_injectedScriptHost.get(); } - InspectorRuntimeAgent* runtimeAgent() { return m_runtimeAgent.get(); } - InspectorTimelineAgent* timelineAgent() { return m_timelineAgent.get(); } -#if ENABLE(DATABASE) - InspectorDatabaseAgent* databaseAgent() { return m_databaseAgent.get(); } -#endif -#if ENABLE(DOM_STORAGE) - InspectorDOMStorageAgent* domStorageAgent() { return m_domStorageAgent.get(); } -#endif -#if ENABLE(FILE_SYSTEM) - InspectorFileSystemAgent* fileSystemAgent() { return m_fileSystemAgent.get(); } -#endif -#if ENABLE(JAVASCRIPT_DEBUGGER) - InspectorBrowserDebuggerAgent* browserDebuggerAgent() const { return m_browserDebuggerAgent.get(); } - InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); } - InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); } -#endif -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); } -#endif - - - bool searchingForNodeInPage() const; - void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); - bool handleMousePress(); + void setInspectorFrontendClient(PassOwnPtr); + bool hasInspectorFrontendClient() const; + void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*); + void setInspectorExtensionAPI(const String& source); - void setInspectorFrontendClient(PassOwnPtr client); - bool hasInspectorFrontendClient() const { return m_inspectorFrontendClient; } + void dispatchMessageFromFrontend(const String& message); - void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*); + bool hasFrontend() const { return m_inspectorFrontend; } + void connectFrontend(); + void disconnectFrontend(); + void restoreInspectorStateFromCookie(const String& inspectorCookie); - void didCommitLoad(DocumentLoader*); + void showConsole(); + void inspect(Node*); + void drawNodeHighlight(GraphicsContext&) const; + void hideHighlight(); - void setExtraHeaders(PassRefPtr); + void evaluateForTestInFrontend(long callId, const String& script); void startTimelineProfiler(); void stopTimelineProfiler(); - - void getCookies(RefPtr* cookies, WTF::String* cookiesString); - void deleteCookie(const String& cookieName, const String& domain); - - void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&); - void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&); - -#if ENABLE(WORKERS) - enum WorkerAction { WorkerCreated, WorkerDestroyed }; - - void postWorkerNotificationToFrontend(const InspectorWorkerResource&, WorkerAction); - void didCreateWorker(intptr_t, const String& url, bool isSharedWorker); - void didDestroyWorker(intptr_t); -#endif - -#if ENABLE(DATABASE) - void didOpenDatabase(PassRefPtr, const String& domain, const String& name, const String& version); -#endif - -#if ENABLE(DOM_STORAGE) - void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame); -#endif - -#if ENABLE(WEB_SOCKETS) - void didCreateWebSocket(unsigned long identifier, const KURL& requestURL, const KURL& documentURL); - void willSendWebSocketHandshakeRequest(unsigned long identifier, const WebSocketHandshakeRequest&); - void didReceiveWebSocketHandshakeResponse(unsigned long identifier, const WebSocketHandshakeResponse&); - void didCloseWebSocket(unsigned long identifier); -#endif - - bool hasFrontend() const { return m_frontend; } - - void drawNodeHighlight(GraphicsContext&) const; - void openInInspectedWindow(const String& url); - void drawElementTitle(GraphicsContext&, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings*) const; + bool timelineProfilerEnabled(); #if ENABLE(JAVASCRIPT_DEBUGGER) - bool isRecordingUserInitiatedProfile() const; - void startProfiling() { startUserInitiatedProfiling(); } + bool profilerEnabled(); + void enableProfiler(); void startUserInitiatedProfiling(); - void stopProfiling() { stopUserInitiatedProfiling(); } + bool isRecordingUserInitiatedProfile() const; void stopUserInitiatedProfiling(); - void enableProfiler(bool always = false, bool skipRecompile = false); - void disableProfiler(bool always = false); - bool profilerEnabled() const; - + void disableProfiler(); void showAndEnableDebugger(); - void enableDebugger(bool always); - void disableDebugger(bool always = false); - bool debuggerEnabled() const { return m_debuggerAgent; } + bool debuggerEnabled(); + void disableDebugger(); void resume(); - - void setAllBrowserBreakpoints(PassRefPtr); #endif - // Generic code called from custom implementations. - void evaluateForTestInFrontend(long testCallId, const String& script); - - void addScriptToEvaluateOnLoad(const String& source); - void removeAllScriptsToEvaluateOnLoad(); - void setInspectorExtensionAPI(const String& source); - - bool inspectorStartsAttached(); - void setInspectorStartsAttached(bool); - void setInspectorAttachedHeight(long height); - long inspectorAttachedHeight() const; - - InspectorState* state() { return m_state.get(); } - InspectorSettings* settings() { return m_settings.get(); } - - // InspectorAgent API - void getInspectorState(RefPtr* state); - void setMonitoringXHREnabled(bool enabled, bool* newState); - void populateScriptObjects(); - // Following are used from InspectorBackend and internally. - void setSearchingForNode(bool enabled, bool* newState); - void didEvaluateForTestInFrontend(long callId, const String& jsonResult); - - // InspectorInstrumentation API - void ensureSettingsLoaded(); - void willSendRequest(ResourceRequest&); - private: - void pushDataCollectedOffline(); - void restoreDebugger(); - enum ProfilerRestoreAction { - ProfilerRestoreNoAction = 0, - ProfilerRestoreResetAgent = 1 - }; - void restoreProfiler(ProfilerRestoreAction action); - void unbindAllResources(); - void setSearchingForNode(bool enabled); - - void releaseFrontendLifetimeAgents(); - -#if ENABLE(JAVASCRIPT_DEBUGGER) - void toggleRecordButton(bool); -#endif - - PassRefPtr buildObjectForCookie(const Cookie&); - PassRefPtr buildArrayForCookies(ListHashSet&); - - void focusNode(); - bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl); + friend class PostWorkerNotificationToFrontendTask; - Page* m_inspectedPage; - InspectorClient* m_client; + OwnPtr m_inspectorAgent; + OwnPtr m_inspectorBackendDispatcher; OwnPtr m_inspectorFrontendClient; + OwnPtr m_inspectorFrontend; + InspectorClient* m_inspectorClient; bool m_openingFrontend; - OwnPtr m_frontend; - OwnPtr m_cssAgent; - RefPtr m_domAgent; - -#if ENABLE(DATABASE) - RefPtr m_databaseAgent; -#endif - -#if ENABLE(DOM_STORAGE) - RefPtr m_domStorageAgent; -#endif - - OwnPtr m_timelineAgent; - OwnPtr m_state; - OwnPtr m_settings; - -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - OwnPtr m_applicationCacheAgent; -#endif - -#if ENABLE(FILE_SYSTEM) - RefPtr m_fileSystemAgent; -#endif - - RefPtr m_nodeToFocus; - RefPtr m_resourceAgent; - OwnPtr m_runtimeAgent; - -#if ENABLE(DATABASE) - typedef HashMap > DatabaseResourcesMap; - DatabaseResourcesMap m_databaseResources; -#endif -#if ENABLE(DOM_STORAGE) - typedef HashMap > DOMStorageResourcesMap; - DOMStorageResourcesMap m_domStorageResources; -#endif - - String m_showAfterVisible; - RefPtr m_highlightedNode; - OwnPtr m_inspectorBackendDispatcher; - RefPtr m_injectedScriptHost; - OwnPtr m_consoleAgent; - - Vector > m_pendingEvaluateTestCommands; - Vector m_scriptsToEvaluateOnLoad; - String m_inspectorExtensionAPI; -#if ENABLE(JAVASCRIPT_DEBUGGER) - bool m_attachDebuggerWhenShown; - OwnPtr m_debuggerAgent; - OwnPtr m_browserDebuggerAgent; - OwnPtr m_profilerAgent; -#endif - OwnPtr m_extraHeaders; -#if ENABLE(WORKERS) - typedef HashMap > WorkersMap; - - WorkersMap m_workers; -#endif }; -} // namespace WebCore +} #endif // !defined(InspectorController_h) diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp index 6e10f09..e222edb 100644 --- a/Source/WebCore/inspector/InspectorDOMAgent.cpp +++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp @@ -208,8 +208,7 @@ public: } InspectorDOMAgent::InspectorDOMAgent(InjectedScriptHost* injectedScriptHost, InspectorFrontend* frontend) - : EventListener(InspectorDOMAgentType) - , m_injectedScriptHost(injectedScriptHost) + : m_injectedScriptHost(injectedScriptHost) , m_frontend(frontend) , m_domListener(0) , m_lastNodeId(1) @@ -222,16 +221,22 @@ InspectorDOMAgent::~InspectorDOMAgent() reset(); } +Vector InspectorDOMAgent::documents() +{ + Vector result; + for (Frame* frame = m_document->frame(); frame; frame = frame->tree()->traverseNext()) { + Document* document = frame->document(); + if (!document) + continue; + result.append(document); + } + return result; +} + void InspectorDOMAgent::reset() { searchCanceled(); discardBindings(); - - ListHashSet > copy = m_documents; - for (ListHashSet >::iterator it = copy.begin(); it != copy.end(); ++it) - stopListening((*it).get()); - - ASSERT(!m_documents.size()); } void InspectorDOMAgent::setDOMListener(DOMListener* listener) @@ -241,13 +246,14 @@ void InspectorDOMAgent::setDOMListener(DOMListener* listener) void InspectorDOMAgent::setDocument(Document* doc) { - if (doc == mainFrameDocument()) + if (doc == m_document.get()) return; reset(); + m_document = doc; + if (doc) { - startListening(doc); if (doc->documentElement()) pushDocumentToFrontend(); } else @@ -260,66 +266,6 @@ void InspectorDOMAgent::releaseDanglingNodes() m_danglingNodeToIdMaps.clear(); } -void InspectorDOMAgent::startListeningFrameDocument(Node* frameOwnerNode) -{ - ASSERT(frameOwnerNode->isFrameOwnerElement()); - HTMLFrameOwnerElement* frameOwner = static_cast(frameOwnerNode); - Document* doc = frameOwner->contentDocument(); - if (doc) - startListening(doc); -} - -void InspectorDOMAgent::startListening(Document* doc) -{ - if (m_documents.contains(doc)) - return; - - doc->addEventListener(eventNames().DOMContentLoadedEvent, this, false); - doc->addEventListener(eventNames().loadEvent, this, true); - m_documents.add(doc); -} - -void InspectorDOMAgent::stopListening(Document* doc) -{ - if (!m_documents.contains(doc)) - return; - - doc->removeEventListener(eventNames().DOMContentLoadedEvent, this, false); - doc->removeEventListener(eventNames().loadEvent, this, true); - m_documents.remove(doc); -} - -void InspectorDOMAgent::handleEvent(ScriptExecutionContext*, Event* event) -{ - AtomicString type = event->type(); - Node* node = event->target()->toNode(); - - if (type == eventNames().DOMContentLoadedEvent) { - // Re-push document once it is loaded. - discardBindings(); - pushDocumentToFrontend(); - } else if (type == eventNames().loadEvent) { - long frameOwnerId = m_documentNodeToIdMap.get(node); - if (!frameOwnerId) - return; - - if (!m_childrenRequested.contains(frameOwnerId)) { - // No children are mapped yet -> only notify on changes of hasChildren. - m_frontend->childNodeCountUpdated(frameOwnerId, innerChildNodeCount(node)); - } else { - // Re-add frame owner element together with its new children. - long parentId = m_documentNodeToIdMap.get(innerParentNode(node)); - m_frontend->childNodeRemoved(parentId, frameOwnerId); - RefPtr value = buildObjectForNode(node, 0, &m_documentNodeToIdMap); - Node* previousSibling = innerPreviousSibling(node); - long prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0; - m_frontend->childNodeInserted(parentId, prevId, value.release()); - // Invalidate children requested flag for the element. - m_childrenRequested.remove(m_childrenRequested.find(frameOwnerId)); - } - } -} - long InspectorDOMAgent::bind(Node* node, NodeToIdMap* nodesMap) { long id = nodesMap->get(node); @@ -336,7 +282,6 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap) { if (node->isFrameOwnerElement()) { const HTMLFrameOwnerElement* frameOwner = static_cast(node); - stopListening(frameOwner->contentDocument()); if (m_domListener) m_domListener->didRemoveDocument(frameOwner->contentDocument()); } @@ -360,11 +305,10 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap) bool InspectorDOMAgent::pushDocumentToFrontend() { - Document* document = mainFrameDocument(); - if (!document) + if (!m_document) return false; - if (!m_documentNodeToIdMap.contains(document)) - m_frontend->setDocument(buildObjectForNode(document, 2, &m_documentNodeToIdMap)); + if (!m_documentNodeToIdMap.contains(m_document)) + m_frontend->setDocument(buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap)); return true; } @@ -537,7 +481,7 @@ void InspectorDOMAgent::getOuterHTML(long nodeId, WTF::String* outerHTML) if (!node || !node->isHTMLElement()) return; - *outerHTML = static_cast(node)->outerHTML(); + *outerHTML = toHTMLElement(node)->outerHTML(); } void InspectorDOMAgent::setOuterHTML(long nodeId, const String& outerHTML, long* newId) @@ -552,16 +496,16 @@ void InspectorDOMAgent::setOuterHTML(long nodeId, const String& outerHTML, long* Node* previousSibling = node->previousSibling(); ContainerNode* parentNode = node->parentNode(); - HTMLElement* htmlElement = static_cast(node); + HTMLElement* htmlElement = toHTMLElement(node); ExceptionCode ec = 0; htmlElement->setOuterHTML(outerHTML, ec); if (ec) return; if (requiresTotalUpdate) { - Document* document = mainFrameDocument(); + RefPtr document = m_document; reset(); - setDocument(document); + setDocument(document.get()); *newId = 0; return; } @@ -693,10 +637,9 @@ void InspectorDOMAgent::performSearch(const String& whitespaceTrimmedQuery, bool searchCanceled(); // Find all frames, iframes and object elements to search their documents. - for (Frame* frame = mainFrameDocument()->frame(); frame; frame = frame->tree()->traverseNext()) { - Document* document = frame->document(); - if (!document) - continue; + Vector docs = documents(); + for (Vector::iterator it = docs.begin(); it != docs.end(); ++it) { + Document* document = *it; if (!tagNameQuery.isEmpty() && startTagFound && endTagFound) { m_pendingMatchJobs.append(new MatchExactTagNamesJob(document, tagNameQuery)); @@ -891,9 +834,6 @@ PassRefPtr InspectorDOMAgent::buildArrayForContainerChildren(Nod depth--; } - if (container->isFrameOwnerElement()) - startListeningFrameDocument(container); - while (child) { children->pushObject(buildObjectForNode(child, depth, nodesMap)); child = innerNextSibling(child); @@ -974,19 +914,37 @@ bool InspectorDOMAgent::isWhitespace(Node* node) return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stripWhiteSpace().length() == 0; } -Document* InspectorDOMAgent::mainFrameDocument() const +void InspectorDOMAgent::mainFrameDOMContentLoaded() { - ListHashSet >::const_iterator it = m_documents.begin(); - if (it != m_documents.end()) - return it->get(); - return 0; + // Re-push document once it is loaded. + discardBindings(); + pushDocumentToFrontend(); } -bool InspectorDOMAgent::operator==(const EventListener& listener) +void InspectorDOMAgent::loadEventFired(Document* document) { - if (const InspectorDOMAgent* inspectorDOMAgentListener = InspectorDOMAgent::cast(&listener)) - return mainFrameDocument() == inspectorDOMAgentListener->mainFrameDocument(); - return false; + Element* frameOwner = document->ownerElement(); + if (!frameOwner) + return; + + long frameOwnerId = m_documentNodeToIdMap.get(frameOwner); + if (!frameOwnerId) + return; + + if (!m_childrenRequested.contains(frameOwnerId)) { + // No children are mapped yet -> only notify on changes of hasChildren. + m_frontend->childNodeCountUpdated(frameOwnerId, innerChildNodeCount(frameOwner)); + } else { + // Re-add frame owner element together with its new children. + long parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner)); + m_frontend->childNodeRemoved(parentId, frameOwnerId); + RefPtr value = buildObjectForNode(frameOwner, 0, &m_documentNodeToIdMap); + Node* previousSibling = innerPreviousSibling(frameOwner); + long prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0; + m_frontend->childNodeInserted(parentId, prevId, value.release()); + // Invalidate children requested flag for the element. + m_childrenRequested.remove(m_childrenRequested.find(frameOwnerId)); + } } void InspectorDOMAgent::didInsertDOMNode(Node* node) @@ -1062,10 +1020,10 @@ void InspectorDOMAgent::characterDataModified(CharacterData* characterData) Node* InspectorDOMAgent::nodeForPath(const String& path) { // The path is of form "1,HTML,2,BODY,1,DIV" - Node* node = mainFrameDocument(); - if (!node) + if (!m_document) return 0; + Node* node = m_document.get(); Vector pathTokens; path.split(",", false, pathTokens); if (!pathTokens.size()) @@ -1153,7 +1111,7 @@ InjectedScript InspectorDOMAgent::injectedScriptForNodeId(long nodeId) frame = document->frame(); } } else - frame = mainFrameDocument()->frame(); + frame = m_document->frame(); if (frame) return m_injectedScriptHost->injectedScriptFor(mainWorldScriptState(frame)); diff --git a/Source/WebCore/inspector/InspectorDOMAgent.h b/Source/WebCore/inspector/InspectorDOMAgent.h index e4edf5d..4e603da 100644 --- a/Source/WebCore/inspector/InspectorDOMAgent.h +++ b/Source/WebCore/inspector/InspectorDOMAgent.h @@ -30,29 +30,22 @@ #ifndef InspectorDOMAgent_h #define InspectorDOMAgent_h -#include "EventListener.h" -#include "EventTarget.h" #include "InjectedScript.h" #include "InjectedScriptHost.h" #include "InspectorValues.h" -#include "NodeList.h" #include "Timer.h" #include #include #include #include -#include +#include #include +#include #include namespace WebCore { class ContainerNode; -class CSSRule; -class CSSRuleList; -class CSSStyleDeclaration; -class CSSStyleRule; -class CSSStyleSheet; class CharacterData; class Document; class Element; @@ -79,7 +72,7 @@ struct EventListenerInfo { const EventListenerVector eventListenerVector; }; -class InspectorDOMAgent : public EventListener { +class InspectorDOMAgent { public: struct DOMListener { virtual ~DOMListener() @@ -90,25 +83,17 @@ public: virtual void didModifyDOMAttr(Element*) = 0; }; - static PassRefPtr create(InjectedScriptHost* injectedScriptHost, InspectorFrontend* frontend) + static PassOwnPtr create(InjectedScriptHost* injectedScriptHost, InspectorFrontend* frontend) { - return adoptRef(new InspectorDOMAgent(injectedScriptHost, frontend)); - } - - static const InspectorDOMAgent* cast(const EventListener* listener) - { - return listener->type() == InspectorDOMAgentType - ? static_cast(listener) - : 0; + return adoptPtr(new InspectorDOMAgent(injectedScriptHost, frontend)); } InspectorDOMAgent(InjectedScriptHost*, InspectorFrontend*); ~InspectorDOMAgent(); + Vector documents(); void reset(); - virtual bool operator==(const EventListener& other); - // Methods called from the frontend for DOM nodes inspection. void getChildNodes(long nodeId); void setAttribute(long elementId, const String& name, const String& value, bool* success); @@ -131,6 +116,9 @@ public: void setDocument(Document*); void releaseDanglingNodes(); + void mainFrameDOMContentLoaded(); + void loadEventFired(Document*); + void didInsertDOMNode(Node*); void didRemoveDOMNode(Node*); void didModifyDOMAttr(Element*); @@ -142,7 +130,6 @@ public: void pushNodeByPathToFrontend(const String& path, long* nodeId); long inspectedNode(unsigned long num); void copyNode(long nodeId); - const ListHashSet >& documents() { return m_documents; } void setDOMListener(DOMListener*); String documentURLString(Document*) const; @@ -157,12 +144,6 @@ public: static bool isWhitespace(Node*); private: - void startListeningFrameDocument(Node* frameOwnerNode); - void startListening(Document*); - void stopListening(Document*); - - virtual void handleEvent(ScriptExecutionContext*, Event*); - // Node-related methods. typedef HashMap, long> NodeToIdMap; long bind(Node*, NodeToIdMap*); @@ -179,8 +160,6 @@ private: PassRefPtr buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); PassRefPtr buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*); - Document* mainFrameDocument() const; - void onMatchJobsTimer(Timer*); void reportNodesAsSearchResults(ListHashSet& resultCollector); @@ -201,7 +180,7 @@ private: HashMap m_idToNodesMap; HashSet m_childrenRequested; long m_lastNodeId; - ListHashSet > m_documents; + RefPtr m_document; Deque m_pendingMatchJobs; Timer m_matchJobsTimer; HashSet > m_searchResults; diff --git a/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp b/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp index 2241a16..0919b64 100644 --- a/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp +++ b/Source/WebCore/inspector/InspectorDOMStorageAgent.cpp @@ -48,6 +48,9 @@ namespace WebCore { InspectorDOMStorageAgent::~InspectorDOMStorageAgent() { + DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources->end(); + for (DOMStorageResourcesMap::iterator it = m_domStorageResources->begin(); it != domStorageEnd; ++it) + it->second->unbind(); } void InspectorDOMStorageAgent::getDOMStorageEntries(long storageId, RefPtr* entries) diff --git a/Source/WebCore/inspector/InspectorDOMStorageAgent.h b/Source/WebCore/inspector/InspectorDOMStorageAgent.h index f1d4d5c..987c530 100644 --- a/Source/WebCore/inspector/InspectorDOMStorageAgent.h +++ b/Source/WebCore/inspector/InspectorDOMStorageAgent.h @@ -30,8 +30,8 @@ #define InspectorDOMStorageAgent_h #include "PlatformString.h" -#include "wtf/HashMap.h" -#include "wtf/PassRefPtr.h" +#include +#include namespace WebCore { @@ -40,13 +40,13 @@ class InspectorDOMStorageResource; class InspectorFrontend; class Storage; -class InspectorDOMStorageAgent : public RefCounted { +class InspectorDOMStorageAgent { public: typedef HashMap > DOMStorageResourcesMap; - static PassRefPtr create(DOMStorageResourcesMap* domStorageResources, InspectorFrontend* frontend) + static PassOwnPtr create(DOMStorageResourcesMap* domStorageResources, InspectorFrontend* frontend) { - return adoptRef(new InspectorDOMStorageAgent(domStorageResources, frontend)); + return adoptPtr(new InspectorDOMStorageAgent(domStorageResources, frontend)); } virtual ~InspectorDOMStorageAgent(); @@ -59,8 +59,6 @@ public: // Called from the injected script. void selectDOMStorage(Storage* storage); - InspectorFrontend* frontend() { return m_frontend; } - private: InspectorDOMStorageAgent(DOMStorageResourcesMap*, InspectorFrontend*); diff --git a/Source/WebCore/inspector/InspectorDOMStorageResource.h b/Source/WebCore/inspector/InspectorDOMStorageResource.h index ee09974..f0975ba 100644 --- a/Source/WebCore/inspector/InspectorDOMStorageResource.h +++ b/Source/WebCore/inspector/InspectorDOMStorageResource.h @@ -51,6 +51,7 @@ namespace WebCore { { return adoptRef(new InspectorDOMStorageResource(domStorage, isLocalStorage, frame)); } + static const InspectorDOMStorageResource* cast(const EventListener* listener) { return listener->type() == InspectorDOMStorageResourceType ? static_cast(listener) : 0; diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp index 36bcab8..221bdf2 100644 --- a/Source/WebCore/inspector/InspectorDatabaseAgent.cpp +++ b/Source/WebCore/inspector/InspectorDatabaseAgent.cpp @@ -34,7 +34,7 @@ #include "Database.h" #include "ExceptionCode.h" -#include "InspectorController.h" +#include "InspectorAgent.h" #include "InspectorDatabaseResource.h" #include "InspectorFrontend.h" #include "InspectorValues.h" @@ -52,32 +52,48 @@ namespace WebCore { +class InspectorDatabaseAgent::FrontendProvider : public RefCounted { +public: + static PassRefPtr create(InspectorFrontend* inspectorFrontend) + { + return adoptRef(new FrontendProvider(inspectorFrontend)); + } + + virtual ~FrontendProvider() { } + + InspectorFrontend* frontend() { return m_inspectorFrontend; } + void clearFrontend() { m_inspectorFrontend = 0; } +private: + FrontendProvider(InspectorFrontend* inspectorFrontend) : m_inspectorFrontend(inspectorFrontend) { } + InspectorFrontend* m_inspectorFrontend; +}; + namespace { long lastTransactionId = 0; -void reportTransactionFailed(InspectorDatabaseAgent* agent, long transactionId, SQLError* error) +void reportTransactionFailed(InspectorFrontend* frontend, long transactionId, SQLError* error) { - if (!agent->frontend()) + if (!frontend) return; RefPtr errorObject = InspectorObject::create(); errorObject->setString("message", error->message()); errorObject->setNumber("code", error->code()); - agent->frontend()->sqlTransactionFailed(transactionId, errorObject); + frontend->sqlTransactionFailed(transactionId, errorObject); } class StatementCallback : public SQLStatementCallback { public: - static PassRefPtr create(long transactionId, PassRefPtr agent) + static PassRefPtr create(long transactionId, PassRefPtr frontendProvider) { - return adoptRef(new StatementCallback(transactionId, agent)); + return adoptRef(new StatementCallback(transactionId, frontendProvider)); } virtual ~StatementCallback() { } virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet) { - if (!m_agent->frontend()) + if (!m_frontendProvider->frontend()) return true; SQLResultSetRowList* rowList = resultSet->rows(); @@ -97,92 +113,92 @@ public: case SQLValue::NullValue: values->pushValue(InspectorValue::null()); break; } } - m_agent->frontend()->sqlTransactionSucceeded(m_transactionId, columnNames, values); + m_frontendProvider->frontend()->sqlTransactionSucceeded(m_transactionId, columnNames, values); return true; } private: - StatementCallback(long transactionId, PassRefPtr agent) + StatementCallback(long transactionId, PassRefPtr frontendProvider) : m_transactionId(transactionId) - , m_agent(agent) { } + , m_frontendProvider(frontendProvider) { } long m_transactionId; - RefPtr m_agent; + RefPtr m_frontendProvider; }; class StatementErrorCallback : public SQLStatementErrorCallback { public: - static PassRefPtr create(long transactionId, PassRefPtr agent) + static PassRefPtr create(long transactionId, PassRefPtr frontendProvider) { - return adoptRef(new StatementErrorCallback(transactionId, agent)); + return adoptRef(new StatementErrorCallback(transactionId, frontendProvider)); } virtual ~StatementErrorCallback() { } virtual bool handleEvent(SQLTransaction*, SQLError* error) { - reportTransactionFailed(m_agent.get(), m_transactionId, error); + reportTransactionFailed(m_frontendProvider->frontend(), m_transactionId, error); return true; } private: - StatementErrorCallback(long transactionId, RefPtr agent) + StatementErrorCallback(long transactionId, PassRefPtr frontendProvider) : m_transactionId(transactionId) - , m_agent(agent) { } + , m_frontendProvider(frontendProvider) { } long m_transactionId; - RefPtr m_agent; + RefPtr m_frontendProvider; }; class TransactionCallback : public SQLTransactionCallback { public: - static PassRefPtr create(const String& sqlStatement, long transactionId, PassRefPtr agent) + static PassRefPtr create(const String& sqlStatement, long transactionId, PassRefPtr frontendProvider) { - return adoptRef(new TransactionCallback(sqlStatement, transactionId, agent)); + return adoptRef(new TransactionCallback(sqlStatement, transactionId, frontendProvider)); } virtual ~TransactionCallback() { } virtual bool handleEvent(SQLTransaction* transaction) { - if (!m_agent->frontend()) + if (!m_frontendProvider->frontend()) return true; Vector sqlValues; - RefPtr callback(StatementCallback::create(m_transactionId, m_agent)); - RefPtr errorCallback(StatementErrorCallback::create(m_transactionId, m_agent)); + RefPtr callback(StatementCallback::create(m_transactionId, m_frontendProvider)); + RefPtr errorCallback(StatementErrorCallback::create(m_transactionId, m_frontendProvider)); ExceptionCode ec = 0; transaction->executeSQL(m_sqlStatement, sqlValues, callback.release(), errorCallback.release(), ec); return true; } private: - TransactionCallback(const String& sqlStatement, long transactionId, PassRefPtr agent) + TransactionCallback(const String& sqlStatement, long transactionId, PassRefPtr frontendProvider) : m_sqlStatement(sqlStatement) , m_transactionId(transactionId) - , m_agent(agent) { } + , m_frontendProvider(frontendProvider) { } String m_sqlStatement; long m_transactionId; - RefPtr m_agent; + RefPtr m_frontendProvider; }; class TransactionErrorCallback : public SQLTransactionErrorCallback { public: - static PassRefPtr create(long transactionId, PassRefPtr agent) + static PassRefPtr create(long transactionId, PassRefPtr frontendProvider) { - return adoptRef(new TransactionErrorCallback(transactionId, agent)); + return adoptRef(new TransactionErrorCallback(transactionId, frontendProvider)); } virtual ~TransactionErrorCallback() { } virtual bool handleEvent(SQLError* error) { - reportTransactionFailed(m_agent.get(), m_transactionId, error); + reportTransactionFailed(m_frontendProvider->frontend(), m_transactionId, error); return true; } private: - TransactionErrorCallback(long transactionId, PassRefPtr agent) + TransactionErrorCallback(long transactionId, PassRefPtr frontendProvider) : m_transactionId(transactionId) - , m_agent(agent) { } + , m_frontendProvider(frontendProvider) { } long m_transactionId; - RefPtr m_agent; + RefPtr m_frontendProvider; }; class TransactionSuccessCallback : public VoidCallback { @@ -204,6 +220,7 @@ private: InspectorDatabaseAgent::~InspectorDatabaseAgent() { + m_frontendProvider->clearFrontend(); } void InspectorDatabaseAgent::getDatabaseTableNames(long databaseId, RefPtr* names) @@ -226,8 +243,8 @@ void InspectorDatabaseAgent::executeSQL(long databaseId, const String& query, bo } *transactionId = ++lastTransactionId; - RefPtr callback(TransactionCallback::create(query, *transactionId, this)); - RefPtr errorCallback(TransactionErrorCallback::create(*transactionId, this)); + RefPtr callback(TransactionCallback::create(query, *transactionId, m_frontendProvider)); + RefPtr errorCallback(TransactionErrorCallback::create(*transactionId, m_frontendProvider)); RefPtr successCallback(TransactionSuccessCallback::create()); database->transaction(callback.release(), errorCallback.release(), successCallback.release()); *success = true; @@ -243,25 +260,20 @@ Database* InspectorDatabaseAgent::databaseForId(long databaseId) void InspectorDatabaseAgent::selectDatabase(Database* database) { - if (!m_frontend) + if (!m_frontendProvider->frontend()) return; for (DatabaseResourcesMap::iterator it = m_databaseResources->begin(); it != m_databaseResources->end(); ++it) { if (it->second->database() == database) { - m_frontend->selectDatabase(it->first); + m_frontendProvider->frontend()->selectDatabase(it->first); break; } } } -void InspectorDatabaseAgent::clearFrontend() -{ - m_frontend = 0; -} - InspectorDatabaseAgent::InspectorDatabaseAgent(DatabaseResourcesMap* databaseResources, InspectorFrontend* frontend) : m_databaseResources(databaseResources) - , m_frontend(frontend) + , m_frontendProvider(FrontendProvider::create(frontend)) { } diff --git a/Source/WebCore/inspector/InspectorDatabaseAgent.h b/Source/WebCore/inspector/InspectorDatabaseAgent.h index a9e9a5d..4ad3e62 100644 --- a/Source/WebCore/inspector/InspectorDatabaseAgent.h +++ b/Source/WebCore/inspector/InspectorDatabaseAgent.h @@ -30,8 +30,8 @@ #define InspectorDatabaseAgent_h #include "PlatformString.h" -#include "wtf/HashMap.h" -#include "wtf/PassRefPtr.h" +#include +#include namespace WebCore { @@ -40,13 +40,15 @@ class InspectorArray; class InspectorDatabaseResource; class InspectorFrontend; -class InspectorDatabaseAgent : public RefCounted { +class InspectorDatabaseAgent { public: + class FrontendProvider; + typedef HashMap > DatabaseResourcesMap; - static PassRefPtr create(DatabaseResourcesMap* databaseResources, InspectorFrontend* frontend) + static PassOwnPtr create(DatabaseResourcesMap* databaseResources, InspectorFrontend* frontend) { - return adoptRef(new InspectorDatabaseAgent(databaseResources, frontend)); + return adoptPtr(new InspectorDatabaseAgent(databaseResources, frontend)); } virtual ~InspectorDatabaseAgent(); @@ -59,14 +61,11 @@ public: Database* databaseForId(long databaseId); void selectDatabase(Database* database); - InspectorFrontend* frontend() { return m_frontend; } - void clearFrontend(); - private: InspectorDatabaseAgent(DatabaseResourcesMap*, InspectorFrontend*); DatabaseResourcesMap* m_databaseResources; - InspectorFrontend* m_frontend; + RefPtr m_frontendProvider; }; } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h b/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h new file mode 100644 index 0000000..0ad1460 --- /dev/null +++ b/Source/WebCore/inspector/InspectorDatabaseInstrumentation.h @@ -0,0 +1,52 @@ +/* +* 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 InspectorDatabaseInstrumentation_h +#define InspectorDatabaseInstrumentation_h + +#include "Database.h" +#include "InspectorInstrumentation.h" +#include + +namespace WebCore { + +#if ENABLE(DATABASE) +inline void InspectorInstrumentation::didOpenDatabase(ScriptExecutionContext* context, PassRefPtr database, const String& domain, const String& name, const String& version) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context)) + didOpenDatabaseImpl(inspectorAgent, database, domain, name, version); +#endif +} +#endif + +} // namespace WebCore + +#endif // !defined(InspectorDatabaseInstrumentation_h) diff --git a/Source/WebCore/inspector/InspectorDatabaseResource.cpp b/Source/WebCore/inspector/InspectorDatabaseResource.cpp index ba67818..e2d2f81 100644 --- a/Source/WebCore/inspector/InspectorDatabaseResource.cpp +++ b/Source/WebCore/inspector/InspectorDatabaseResource.cpp @@ -51,28 +51,17 @@ InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr databa , m_domain(domain) , m_name(name) , m_version(version) - , m_scriptObjectCreated(false) { } void InspectorDatabaseResource::bind(InspectorFrontend* frontend) { - if (m_scriptObjectCreated) - return; - RefPtr jsonObject = InspectorObject::create(); jsonObject->setNumber("id", m_id); jsonObject->setString("domain", m_domain); jsonObject->setString("name", m_name); jsonObject->setString("version", m_version); - frontend->addDatabase(jsonObject); - m_scriptObjectCreated = true; -} - -void InspectorDatabaseResource::unbind() -{ - m_scriptObjectCreated = false; } } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorDatabaseResource.h b/Source/WebCore/inspector/InspectorDatabaseResource.h index 203995b..24d4f1c 100644 --- a/Source/WebCore/inspector/InspectorDatabaseResource.h +++ b/Source/WebCore/inspector/InspectorDatabaseResource.h @@ -46,7 +46,6 @@ public: static PassRefPtr create(PassRefPtr database, const String& domain, const String& name, const String& version); void bind(InspectorFrontend* frontend); - void unbind(); Database* database() { return m_database.get(); } long id() const { return m_id; } private: @@ -57,7 +56,6 @@ private: String m_domain; String m_name; String m_version; - bool m_scriptObjectCreated; }; } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp index acfbb6e..e8b4ad5 100644 --- a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp +++ b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp @@ -34,41 +34,44 @@ #include "InjectedScript.h" #include "InjectedScriptHost.h" #include "InspectorFrontend.h" +#include "InspectorState.h" #include "InspectorValues.h" #include "PlatformString.h" #include "ScriptDebugServer.h" +#include namespace WebCore { -PassOwnPtr InspectorDebuggerAgent::create(InspectorController* inspectorController, InspectorFrontend* frontend) +namespace DebuggerAgentState { +static const char javaScriptBreakpoints[] = "javaScriptBreakopints"; +}; + +PassOwnPtr InspectorDebuggerAgent::create(InspectorAgent* inspectorAgent, InspectorFrontend* frontend, bool eraseStickyBreakpoints) { - OwnPtr agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, frontend)); + OwnPtr agent = adoptPtr(new InspectorDebuggerAgent(inspectorAgent, frontend, eraseStickyBreakpoints)); ScriptDebugServer::shared().clearBreakpoints(); // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends ScriptDebugServer::shared().setBreakpointsActivated(true); - ScriptDebugServer::shared().addListener(agent.get(), inspectorController->inspectedPage()); + ScriptDebugServer::shared().addListener(agent.get(), inspectorAgent->inspectedPage()); return agent.release(); } -InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend) - : m_inspectorController(inspectorController) +InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorAgent* inspectorAgent, InspectorFrontend* frontend, bool eraseStickyBreakpoints) + : m_inspectorAgent(inspectorAgent) , m_frontend(frontend) , m_pausedScriptState(0) , m_javaScriptPauseScheduled(false) { + if (eraseStickyBreakpoints) + inspectorAgent->state()->setObject(DebuggerAgentState::javaScriptBreakpoints, InspectorObject::create()); } InspectorDebuggerAgent::~InspectorDebuggerAgent() { - ScriptDebugServer::shared().removeListener(this, m_inspectorController->inspectedPage()); + ScriptDebugServer::shared().removeListener(this, m_inspectorAgent->inspectedPage()); m_pausedScriptState = 0; } -bool InspectorDebuggerAgent::isDebuggerAlwaysEnabled() -{ - return ScriptDebugServer::shared().isDebuggerAlwaysEnabled(); -} - void InspectorDebuggerAgent::activateBreakpoints() { ScriptDebugServer::shared().activateBreakpoints(); @@ -79,37 +82,107 @@ void InspectorDebuggerAgent::deactivateBreakpoints() ScriptDebugServer::shared().deactivateBreakpoints(); } -void InspectorDebuggerAgent::setStickyBreakpoint(const String& url, unsigned lineNumber, const String& condition, bool enabled) +void InspectorDebuggerAgent::inspectedURLChanged(const String&) { - HashMap::iterator it = m_stickyBreakpoints.find(url); - if (it == m_stickyBreakpoints.end()) - it = m_stickyBreakpoints.set(url, ScriptBreakpoints()).first; - it->second.set(lineNumber, Breakpoint(condition, enabled)); + m_scripts.clear(); + m_breakpointIdToDebugServerBreakpointIds.clear(); +} - URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url); - if (urlToSourceIDsIterator == m_urlToSourceIDs.end()) +void InspectorDebuggerAgent::setJavaScriptBreakpoint(const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, RefPtr* locations) +{ + String breakpointId = makeString(url, ":", String::number(lineNumber), ":", String::number(columnNumber)); + RefPtr breakpointsCookie = m_inspectorAgent->state()->getObject(DebuggerAgentState::javaScriptBreakpoints); + if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end()) return; - const Vector& sourceIDs = urlToSourceIDsIterator->second; - for (size_t i = 0; i < sourceIDs.size(); ++i) - restoreBreakpoint(sourceIDs[i], lineNumber, condition, enabled); + RefPtr 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); + m_inspectorAgent->state()->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie); + + ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled); + 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 location = InspectorObject::create(); + location->setString("sourceID", it->first); + location->setNumber("lineNumber", actualLineNumber); + location->setNumber("columnNumber", actualColumnNumber); + locations->get()->pushObject(location); + } + *outBreakpointId = breakpointId; } -void InspectorDebuggerAgent::setBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled, String* breakpointId, unsigned int* actualLineNumber) +void InspectorDebuggerAgent::setJavaScriptBreakpointBySourceId(const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, int* actualLineNumber, int* actualColumnNumber) { - *breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, lineNumber, condition, enabled, actualLineNumber); + 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; } -void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId) +void InspectorDebuggerAgent::removeJavaScriptBreakpoint(const String& breakpointId) { - ScriptDebugServer::shared().removeBreakpoint(breakpointId); + RefPtr breakpointsCookie = m_inspectorAgent->state()->getObject(DebuggerAgentState::javaScriptBreakpoints); + breakpointsCookie->remove(breakpointId); + m_inspectorAgent->state()->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie); + + BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId); + if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end()) + return; + for (size_t i = 0; i < debugServerBreakpointIdsIterator->second.size(); ++i) + ScriptDebugServer::shared().removeBreakpoint(debugServerBreakpointIdsIterator->second[i]); + m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator); } -void InspectorDebuggerAgent::restoreBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled) +void InspectorDebuggerAgent::continueToLocation(const String& sourceId, int lineNumber, int columnNumber) { - unsigned actualLineNumber = 0; - String breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, lineNumber, condition, enabled, &actualLineNumber); - if (!breakpointId.isEmpty()) - m_frontend->breakpointResolved(breakpointId, sourceID, actualLineNumber, condition, enabled, lineNumber); + if (!m_continueToLocationBreakpointId.isEmpty()) { + ScriptDebugServer::shared().removeBreakpoint(m_continueToLocationBreakpointId); + m_continueToLocationBreakpointId = ""; + } + ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", true); + m_continueToLocationBreakpointId = ScriptDebugServer::shared().setBreakpoint(sourceId, breakpoint, &lineNumber, &columnNumber); + resume(); +} + +bool InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint& breakpoint, int* actualLineNumber, int* actualColumnNumber) +{ + ScriptsMap::iterator scriptIterator = m_scripts.find(sourceId); + if (scriptIterator == m_scripts.end()) + return false; + Script& script = scriptIterator->second; + if (breakpoint.lineNumber < script.lineOffset) + return false; + if (!script.linesCount) { + script.linesCount = 1; + for (size_t i = 0; i < script.data.length(); ++i) { + if (script.data[i] == '\n') + script.linesCount += 1; + } + } + if (breakpoint.lineNumber >= script.lineOffset + script.linesCount) + return false; + + String debugServerBreakpointId = ScriptDebugServer::shared().setBreakpoint(sourceId, breakpoint, actualLineNumber, actualColumnNumber); + if (debugServerBreakpointId.isEmpty()) + return false; + + BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId); + if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end()) + debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector()).first; + debugServerBreakpointIdsIterator->second.append(debugServerBreakpointId); + + return true; } void InspectorDebuggerAgent::editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr* newCallFrames) @@ -120,7 +193,7 @@ void InspectorDebuggerAgent::editScriptSource(const String& sourceID, const Stri void InspectorDebuggerAgent::getScriptSource(const String& sourceID, String* scriptSource) { - *scriptSource = m_scriptIDToContent.get(sourceID); + *scriptSource = m_scripts.get(sourceID).data; } void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr data) @@ -173,32 +246,25 @@ void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState, long* ne *newState = ScriptDebugServer::shared().pauseOnExceptionsState(); } -void InspectorDebuggerAgent::evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, RefPtr* result) +void InspectorDebuggerAgent::evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result) { - InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get()); + InjectedScript injectedScript = m_inspectorAgent->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get()); if (!injectedScript.hasNoValue()) - injectedScript.evaluateOnCallFrame(callFrameId, expression, objectGroup, result); + injectedScript.evaluateOnCallFrame(callFrameId, expression, objectGroup, includeCommandLineAPI, result); } -void InspectorDebuggerAgent::getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result) +void InspectorDebuggerAgent::getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeCommandLineAPI, RefPtr* result) { - InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get()); + InjectedScript injectedScript = m_inspectorAgent->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get()); if (!injectedScript.hasNoValue()) - injectedScript.getCompletionsOnCallFrame(callFrameId, expression, includeInspectorCommandLineAPI, result); -} - -void InspectorDebuggerAgent::clearForPageNavigation() -{ - m_scriptIDToContent.clear(); - m_urlToSourceIDs.clear(); - m_stickyBreakpoints.clear(); + injectedScript.getCompletionsOnCallFrame(callFrameId, expression, includeCommandLineAPI, result); } PassRefPtr InspectorDebuggerAgent::currentCallFrames() { if (!m_pausedScriptState) return InspectorValue::null(); - InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptFor(m_pausedScriptState); + InjectedScript injectedScript = m_inspectorAgent->injectedScriptHost()->injectedScriptFor(m_pausedScriptState); if (injectedScript.hasNoValue()) { ASSERT_NOT_REACHED(); return InspectorValue::null(); @@ -213,24 +279,26 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String // Don't send script content to the front end until it's really needed. m_frontend->parsedScriptSource(sourceID, url, lineOffset, columnOffset, data.length(), worldType); - m_scriptIDToContent.set(sourceID, data); + m_scripts.set(sourceID, Script(url, data, lineOffset, columnOffset)); if (url.isEmpty()) return; - URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url); - if (urlToSourceIDsIterator == m_urlToSourceIDs.end()) - urlToSourceIDsIterator = m_urlToSourceIDs.set(url, Vector()).first; - urlToSourceIDsIterator->second.append(sourceID); - - HashMap::iterator stickyBreakpointsIterator = m_stickyBreakpoints.find(url); - if (stickyBreakpointsIterator == m_stickyBreakpoints.end()) - return; - - const ScriptBreakpoints& breakpoints = stickyBreakpointsIterator->second; - for (ScriptBreakpoints::const_iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { - const Breakpoint& breakpoint = it->second; - restoreBreakpoint(sourceID, it->first, breakpoint.first, breakpoint.second); + RefPtr breakpointsCookie = m_inspectorAgent->state()->getObject(DebuggerAgentState::javaScriptBreakpoints); + for (InspectorObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) { + RefPtr breakpointObject = it->second->asObject(); + String breakpointURL; + breakpointObject->getString("url", &breakpointURL); + if (breakpointURL != url) + continue; + ScriptBreakpoint breakpoint; + 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); } } @@ -250,6 +318,11 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState) m_frontend->pausedScript(m_breakProgramDetails); m_javaScriptPauseScheduled = false; + + if (!m_continueToLocationBreakpointId.isEmpty()) { + ScriptDebugServer::shared().removeBreakpoint(m_continueToLocationBreakpointId); + m_continueToLocationBreakpointId = ""; + } } void InspectorDebuggerAgent::didContinue() diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.h b/Source/WebCore/inspector/InspectorDebuggerAgent.h index 4cb9f9c..644557f 100644 --- a/Source/WebCore/inspector/InspectorDebuggerAgent.h +++ b/Source/WebCore/inspector/InspectorDebuggerAgent.h @@ -32,6 +32,7 @@ #if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR) #include "InjectedScript.h" +#include "ScriptBreakpoint.h" #include "ScriptDebugListener.h" #include "ScriptState.h" #include @@ -42,7 +43,7 @@ namespace WebCore { class InjectedScriptHost; -class InspectorController; +class InspectorAgent; class InspectorFrontend; class InspectorObject; class InspectorValue; @@ -56,17 +57,20 @@ enum DebuggerEventType { class InspectorDebuggerAgent : public ScriptDebugListener { WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED; public: - static PassOwnPtr create(InspectorController*, InspectorFrontend*); + static PassOwnPtr create(InspectorAgent*, InspectorFrontend*, bool eraseStickyBreakpoints); virtual ~InspectorDebuggerAgent(); - static bool isDebuggerAlwaysEnabled(); + void inspectedURLChanged(const String& url); // Part of the protocol. void activateBreakpoints(); void deactivateBreakpoints(); - void setStickyBreakpoint(const String& url, unsigned lineNumber, const String& condition, bool enabled); - void setBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled, String* breakpointId, unsigned int* actualLineNumber); - void removeBreakpoint(const String& breakpointId); + + void setJavaScriptBreakpoint(const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, RefPtr* locations); + void setJavaScriptBreakpointBySourceId(const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, int* actualLineNumber, int* actualColumnNumber); + void removeJavaScriptBreakpoint(const String& breakpointId); + void continueToLocation(const String& sourceId, int lineNumber, int columnNumber); + void editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr* newCallFrames); void getScriptSource(const String& sourceID, String* scriptSource); void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr data); @@ -78,13 +82,11 @@ public: void stepInto(); void stepOut(); void setPauseOnExceptionsState(long pauseState, long* newState); - void evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, RefPtr* result); - void getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result); - - void clearForPageNavigation(); + void evaluateOnCallFrame(PassRefPtr callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result); + void getCompletionsOnCallFrame(PassRefPtr callFrameId, const String& expression, bool includeCommandLineAPI, RefPtr* result); private: - InspectorDebuggerAgent(InspectorController*, InspectorFrontend*); + InspectorDebuggerAgent(InspectorAgent*, InspectorFrontend*, bool eraseStickyBreakpoints); PassRefPtr currentCallFrames(); @@ -93,17 +95,42 @@ private: virtual void didPause(ScriptState*); virtual void didContinue(); - void restoreBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled); - - InspectorController* m_inspectorController; + bool resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber); + + class Script { + public: + Script() + : lineOffset(0) + , columnOffset(0) + , linesCount(0) + { + } + + Script(const String& url, const String& data, int lineOffset, int columnOffset) + : url(url) + , data(data) + , lineOffset(lineOffset) + , columnOffset(columnOffset) + , linesCount(0) + { + } + + String url; + String data; + int lineOffset; + int columnOffset; + int linesCount; + }; + + typedef HashMap ScriptsMap; + typedef HashMap > BreakpointIdToDebugServerBreakpointIdsMap; + + InspectorAgent* m_inspectorAgent; InspectorFrontend* m_frontend; ScriptState* m_pausedScriptState; - HashMap m_scriptIDToContent; - typedef HashMap > URLToSourceIDsMap; - URLToSourceIDsMap m_urlToSourceIDs; - typedef std::pair Breakpoint; - typedef HashMap ScriptBreakpoints; - HashMap m_stickyBreakpoints; + ScriptsMap m_scripts; + BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds; + String m_continueToLocationBreakpointId; RefPtr m_breakProgramDetails; bool m_javaScriptPauseScheduled; }; diff --git a/Source/WebCore/inspector/InspectorFileSystemAgent.cpp b/Source/WebCore/inspector/InspectorFileSystemAgent.cpp deleted file mode 100644 index 2a0df3c..0000000 --- a/Source/WebCore/inspector/InspectorFileSystemAgent.cpp +++ /dev/null @@ -1,171 +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. - */ - -#include "config.h" -#include "InspectorFileSystemAgent.h" - -#if ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) - -#include "AsyncFileWriter.h" -#include "Document.h" -#include "FileSystem.h" -#include "FileSystemCallbacks.h" -#include "Frame.h" -#include "FrameTree.h" -#include "InspectorController.h" -#include "InspectorFrontend.h" -#include "LocalFileSystem.h" -#include "NotImplemented.h" -#include "Page.h" -#include "RuntimeEnabledFeatures.h" - -namespace WebCore { - -class InspectorFileSystemAgentCallbacks : public AsyncFileSystemCallbacks { -public: - InspectorFileSystemAgentCallbacks(InspectorFileSystemAgent* agent, AsyncFileSystem::Type type, const String& origin) - : m_agent(agent) - , m_type(type) - , m_origin(origin) - { - } - - ~InspectorFileSystemAgentCallbacks() - { - } - - // FileSystemCallbacks is only used for getting filesystem. All other methods are irrelevant and will not be called. - void didSucceed() - { - ASSERT_NOT_REACHED(); - } - - void didOpenFileSystem(const String&, PassOwnPtr fileSystem) - { - // Agent will be alive even if InspectorController is destroyed until callback is run. - m_agent->didGetFileSystemPath(fileSystem->root(), m_type, m_origin); - } - - void didReadMetadata(const FileMetadata&) - { - ASSERT_NOT_REACHED(); - } - - void didReadDirectoryEntry(const String&, bool) - { - ASSERT_NOT_REACHED(); - } - - void didReadDirectoryEntries(bool) - { - ASSERT_NOT_REACHED(); - } - - void didCreateFileWriter(PassOwnPtr, long long) - { - ASSERT_NOT_REACHED(); - } - - void didFail(int) - { - // FIXME: Is it useful to give back the code to Inspector UI? - m_agent->didGetFileSystemError(m_type, m_origin); - } - -private: - RefPtr m_agent; - AsyncFileSystem::Type m_type; - String m_origin; -}; - -InspectorFileSystemAgent::InspectorFileSystemAgent(InspectorController* inspectorController, InspectorFrontend* frontend) - : m_inspectorController(inspectorController) - , m_frontend(frontend) -{ -} - -InspectorFileSystemAgent::~InspectorFileSystemAgent() { } - -void InspectorFileSystemAgent::stop() -{ - m_inspectorController = 0; -} - -#if PLATFORM(CHROMIUM) -void InspectorFileSystemAgent::revealFolderInOS(const String& path) -{ - // FIXME: Remove guard when revealFolderInOS is implemented for non-chromium platforms. - WebCore::revealFolderInOS(path); -} -#else -void InspectorFileSystemAgent::revealFolderInOS(const String&) -{ - notImplemented(); -} -#endif - -void InspectorFileSystemAgent::getFileSystemPathAsync(unsigned int type, const String& origin) -{ - if (!RuntimeEnabledFeatures::fileSystemEnabled()) { - m_frontend->didGetFileSystemDisabled(); - return; - } - - AsyncFileSystem::Type asyncFileSystemType = static_cast(type); - Frame* mainFrame = m_inspectorController->inspectedPage()->mainFrame(); - for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) { - Document* document = frame->document(); - if (document && document->securityOrigin()->toString() == origin) { - LocalFileSystem::localFileSystem().readFileSystem(document, asyncFileSystemType, 0, new InspectorFileSystemAgentCallbacks(this, asyncFileSystemType, origin)); - return; - } - } -} - -void InspectorFileSystemAgent::didGetFileSystemPath(const String& root, AsyncFileSystem::Type type, const String& origin) -{ - // When controller is being destroyed, this is set to 0. Agent can live even after m_inspectorController is destroyed. - if (!m_inspectorController) - return; - - m_frontend->didGetFileSystemPath(root, static_cast(type), origin); -} - -void InspectorFileSystemAgent::didGetFileSystemError(AsyncFileSystem::Type type, const String& origin) -{ - // When controller is being destroyed, this is set to 0. Agent can live even after m_inspectorController is destroyed. - if (!m_inspectorController) - return; - m_frontend->didGetFileSystemError(static_cast(type), origin); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) diff --git a/Source/WebCore/inspector/InspectorFileSystemAgent.h b/Source/WebCore/inspector/InspectorFileSystemAgent.h deleted file mode 100644 index a85ad0f..0000000 --- a/Source/WebCore/inspector/InspectorFileSystemAgent.h +++ /dev/null @@ -1,77 +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. - */ - -#ifndef InspectorFileSystemAgent_h -#define InspectorFileSystemAgent_h - -#if ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) - -#include "AsyncFileSystem.h" -#include "AsyncFileSystemCallbacks.h" -#include - -namespace WebCore { - -class Document; -class InspectorController; -class InspectorFrontend; -class LocalFileSystem; - -class InspectorFileSystemAgent : public RefCounted { -public: - static PassRefPtr create(InspectorController* inspectorController, InspectorFrontend* frontend) - { - return adoptRef(new InspectorFileSystemAgent(inspectorController, frontend)); - } - - ~InspectorFileSystemAgent(); - void stop(); - - // From Frontend - void getFileSystemPathAsync(unsigned int type, const String& origin); - void revealFolderInOS(const String& path); - - // Backend to Frontend - void didGetFileSystemPath(const String&, AsyncFileSystem::Type, const String& origin); - void didGetFileSystemError(AsyncFileSystem::Type, const String& origin); - void didGetFileSystemDisabled(); - -private: - InspectorFileSystemAgent(InspectorController*, InspectorFrontend*); - void getFileSystemRoot(AsyncFileSystem::Type); - - InspectorController* m_inspectorController; - InspectorFrontend* m_frontend; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) && ENABLE(FILE_SYSTEM) -#endif // InspectorFileSystemAgent_h diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp index 4812b2a..36864f3 100644 --- a/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp +++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp @@ -47,14 +47,25 @@ namespace WebCore { +static const char* inspectorAttachedHeightSetting = "inspectorAttachedHeight"; static const unsigned defaultAttachedHeight = 300; static const float minimumAttachedHeight = 250.0f; static const float maximumAttachedHeightRatio = 0.75f; -InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage) +String InspectorFrontendClientLocal::Settings::getProperty(const String&) +{ + return String(); +} + +void InspectorFrontendClientLocal::Settings::setProperty(const String&, const String&) +{ +} + +InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController* inspectorController, Page* frontendPage, PassOwnPtr settings) : m_inspectorController(inspectorController) , m_frontendPage(frontendPage) , m_frontendScriptState(0) + , m_settings(settings) { } @@ -66,7 +77,7 @@ InspectorFrontendClientLocal::~InspectorFrontendClientLocal() m_frontendPage = 0; m_inspectorController = 0; } - + void InspectorFrontendClientLocal::windowObjectCleared() { // FIXME: don't keep reference to the script state @@ -107,7 +118,7 @@ void InspectorFrontendClientLocal::changeAttachedWindowHeight(unsigned height) { unsigned totalHeight = m_frontendPage->mainFrame()->view()->visibleHeight() + m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight(); unsigned attachedHeight = constrainedAttachedWindowHeight(height, totalHeight); - m_inspectorController->setInspectorAttachedHeight(attachedHeight); + m_settings->setProperty(inspectorAttachedHeightSetting, String::number(attachedHeight)); setAttachedWindowHeight(attachedHeight); } @@ -133,9 +144,8 @@ void InspectorFrontendClientLocal::setAttachedWindow(bool attached) void InspectorFrontendClientLocal::restoreAttachedWindowHeight() { unsigned inspectedPageHeight = m_inspectorController->inspectedPage()->mainFrame()->view()->visibleHeight(); - int attachedHeight = m_inspectorController->inspectorAttachedHeight(); - bool success = true; - unsigned preferredHeight = success ? static_cast(attachedHeight) : defaultAttachedHeight; + String value = m_settings->getProperty(inspectorAttachedHeightSetting); + unsigned preferredHeight = value.isEmpty() ? defaultAttachedHeight : value.toUInt(); // This call might not go through (if the window starts out detached), but if the window is initially created attached, // InspectorController::attachWindow is never called, so we need to make sure to set the attachedWindowHeight. @@ -151,7 +161,7 @@ unsigned InspectorFrontendClientLocal::constrainedAttachedWindowHeight(unsigned void InspectorFrontendClientLocal::sendMessageToBackend(const String& message) { - m_inspectorController->inspectorBackendDispatcher()->dispatch(message); + m_inspectorController->dispatchMessageFromFrontend(message); } } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.h b/Source/WebCore/inspector/InspectorFrontendClientLocal.h index 19f6ad1..238a262 100644 --- a/Source/WebCore/inspector/InspectorFrontendClientLocal.h +++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.h @@ -33,6 +33,7 @@ #include "InspectorFrontendClient.h" #include "ScriptState.h" +#include #include namespace WebCore { @@ -44,7 +45,15 @@ class Page; class InspectorFrontendClientLocal : public InspectorFrontendClient { WTF_MAKE_NONCOPYABLE(InspectorFrontendClientLocal); WTF_MAKE_FAST_ALLOCATED; public: - InspectorFrontendClientLocal(InspectorController*, Page*); + class Settings { + public: + Settings() { } + virtual ~Settings() { } + virtual String getProperty(const String& name); + virtual void setProperty(const String& name, const String& value); + }; + + InspectorFrontendClientLocal(InspectorController*, Page*, PassOwnPtr); virtual ~InspectorFrontendClientLocal(); virtual void windowObjectCleared(); @@ -76,6 +85,7 @@ private: ScriptState* m_frontendScriptState; // TODO(yurys): this ref shouldn't be needed. RefPtr m_frontendHost; + OwnPtr m_settings; }; } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorFrontendHost.cpp b/Source/WebCore/inspector/InspectorFrontendHost.cpp index 342af0f..f2e66bc 100644 --- a/Source/WebCore/inspector/InspectorFrontendHost.cpp +++ b/Source/WebCore/inspector/InspectorFrontendHost.cpp @@ -41,6 +41,7 @@ #include "FrameLoader.h" #include "HitTestResult.h" #include "HTMLFrameOwnerElement.h" +#include "InspectorAgent.h" #include "InspectorController.h" #include "InspectorFrontendClient.h" #include "Page.h" @@ -200,8 +201,8 @@ void InspectorFrontendHost::moveWindowBy(float x, float y) const void InspectorFrontendHost::setExtensionAPI(const String& script) { - InspectorController* inspector = m_frontendPage->inspectorController(); - inspector->setInspectorExtensionAPI(script); + ASSERT(m_frontendPage->inspectorController()); + m_frontendPage->inspectorController()->setInspectorExtensionAPI(script); } String InspectorFrontendHost::localizedStringsURL() diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp index 9ae97be..e7bb1eb 100644 --- a/Source/WebCore/inspector/InspectorInstrumentation.cpp +++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp @@ -38,10 +38,10 @@ #include "DocumentLoader.h" #include "Event.h" #include "EventContext.h" +#include "InspectorAgent.h" #include "InspectorApplicationCacheAgent.h" #include "InspectorBrowserDebuggerAgent.h" #include "InspectorConsoleAgent.h" -#include "InspectorController.h" #include "InspectorDOMAgent.h" #include "InspectorDebuggerAgent.h" #include "InspectorProfilerAgent.h" @@ -61,6 +61,12 @@ static const char* const setTimerEventName = "setTimer"; static const char* const clearTimerEventName = "clearTimer"; static const char* const timerFiredEventName = "timerFired"; +HashMap& InspectorInstrumentation::inspectorAgents() +{ + static HashMap& agents = *new HashMap; + return agents; +} + int InspectorInstrumentation::s_frontendCounter = 0; static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector& ancestors) @@ -80,119 +86,119 @@ static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, return false; } -void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InspectorController* inspectorController, Frame* frame, DOMWrapperWorld* world) +void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InspectorAgent* inspectorAgent, Frame* frame, DOMWrapperWorld* world) { - inspectorController->didClearWindowObjectInWorld(frame, world); + inspectorAgent->didClearWindowObjectInWorld(frame, world); } -void InspectorInstrumentation::inspectedPageDestroyedImpl(InspectorController* inspectorController) +void InspectorInstrumentation::inspectedPageDestroyedImpl(InspectorAgent* inspectorAgent) { - inspectorController->inspectedPageDestroyed(); + inspectorAgent->inspectedPageDestroyed(); } -void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspectorController, Node* node, Node* parent) +void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node, Node* parent) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->willInsertDOMNode(node, parent); #endif } -void InspectorInstrumentation::didInsertDOMNodeImpl(InspectorController* inspectorController, Node* node) +void InspectorInstrumentation::didInsertDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node) { - if (InspectorDOMAgent* domAgent = inspectorController->domAgent()) + if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent()) domAgent->didInsertDOMNode(node); #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->didInsertDOMNode(node); #endif } -void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspectorController, Node* node) +void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->willRemoveDOMNode(node); #endif } -void InspectorInstrumentation::didRemoveDOMNodeImpl(InspectorController* inspectorController, Node* node) +void InspectorInstrumentation::didRemoveDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->didRemoveDOMNode(node); #endif - if (InspectorDOMAgent* domAgent = inspectorController->domAgent()) + if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent()) domAgent->didRemoveDOMNode(node); } -void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorController* inspectorController, Element* element) +void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorAgent* inspectorAgent, Element* element) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->willModifyDOMAttr(element); #endif } -void InspectorInstrumentation::didModifyDOMAttrImpl(InspectorController* inspectorController, Element* element) +void InspectorInstrumentation::didModifyDOMAttrImpl(InspectorAgent* inspectorAgent, Element* element) { - if (InspectorDOMAgent* domAgent = inspectorController->domAgent()) + if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent()) domAgent->didModifyDOMAttr(element); } -void InspectorInstrumentation::mouseDidMoveOverElementImpl(InspectorController* inspectorController, const HitTestResult& result, unsigned modifierFlags) +void InspectorInstrumentation::mouseDidMoveOverElementImpl(InspectorAgent* inspectorAgent, const HitTestResult& result, unsigned modifierFlags) { - inspectorController->mouseDidMoveOverElement(result, modifierFlags); + inspectorAgent->mouseDidMoveOverElement(result, modifierFlags); } -bool InspectorInstrumentation::handleMousePressImpl(InspectorController* inspectorController) +bool InspectorInstrumentation::handleMousePressImpl(InspectorAgent* inspectorAgent) { - return inspectorController->handleMousePress(); + return inspectorAgent->handleMousePress(); } -void InspectorInstrumentation::characterDataModifiedImpl(InspectorController* inspectorController, CharacterData* characterData) +void InspectorInstrumentation::characterDataModifiedImpl(InspectorAgent* inspectorAgent, CharacterData* characterData) { - if (InspectorDOMAgent* domAgent = inspectorController->domAgent()) + if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent()) domAgent->characterDataModified(characterData); } -void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* inspectorController, const String& url) +void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorAgent* inspectorAgent, const String& url) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->willSendXMLHttpRequest(url); #endif } -void InspectorInstrumentation::didScheduleResourceRequestImpl(InspectorController* inspectorController, const String& url) +void InspectorInstrumentation::didScheduleResourceRequestImpl(InspectorAgent* inspectorAgent, const String& url) { - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController)) + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->didScheduleResourceRequest(url); } -void InspectorInstrumentation::didInstallTimerImpl(InspectorController* inspectorController, int timerId, int timeout, bool singleShot) +void InspectorInstrumentation::didInstallTimerImpl(InspectorAgent* inspectorAgent, int timerId, int timeout, bool singleShot) { - pauseOnNativeEventIfNeeded(inspectorController, instrumentationEventCategoryType, setTimerEventName, true); - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController)) + pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, setTimerEventName, true); + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->didInstallTimer(timerId, timeout, singleShot); } -void InspectorInstrumentation::didRemoveTimerImpl(InspectorController* inspectorController, int timerId) +void InspectorInstrumentation::didRemoveTimerImpl(InspectorAgent* inspectorAgent, int timerId) { - pauseOnNativeEventIfNeeded(inspectorController, instrumentationEventCategoryType, clearTimerEventName, true); - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController)) + pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, clearTimerEventName, true); + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->didRemoveTimer(timerId); } -InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InspectorController* inspectorController, const String& scriptName, int scriptLine) +InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InspectorAgent* inspectorAgent, const String& scriptName, int scriptLine) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willCallFunction(scriptName, scriptLine); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentationCookie& cookie) @@ -201,15 +207,15 @@ void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentatio timelineAgent->didCallFunction(); } -InspectorInstrumentationCookie InspectorInstrumentation::willChangeXHRReadyStateImpl(InspectorController* inspectorController, XMLHttpRequest* request) +InspectorInstrumentationCookie InspectorInstrumentation::willChangeXHRReadyStateImpl(InspectorAgent* inspectorAgent, XMLHttpRequest* request) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent && request->hasEventListeners(eventNames().readystatechangeEvent)) { timelineAgent->willChangeXHRReadyState(request->url().string(), request->readyState()); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didChangeXHRReadyStateImpl(const InspectorInstrumentationCookie& cookie) @@ -218,17 +224,17 @@ void InspectorInstrumentation::didChangeXHRReadyStateImpl(const InspectorInstrum timelineAgent->didChangeXHRReadyState(); } -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window, Node* node, const Vector& ancestors) +InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InspectorAgent* inspectorAgent, const Event& event, DOMWindow* window, Node* node, const Vector& ancestors) { - pauseOnNativeEventIfNeeded(inspectorController, listenerEventCategoryType, event.type(), false); + pauseOnNativeEventIfNeeded(inspectorAgent, listenerEventCategoryType, event.type(), false); int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) { timelineAgent->willDispatchEvent(event); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentationCookie& cookie) @@ -239,17 +245,17 @@ void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentati timelineAgent->didDispatchEvent(); } -InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window) +InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InspectorAgent* inspectorAgent, const Event& event, DOMWindow* window) { - pauseOnNativeEventIfNeeded(inspectorController, listenerEventCategoryType, event.type(), false); + pauseOnNativeEventIfNeeded(inspectorAgent, listenerEventCategoryType, event.type(), false); int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent && window->hasEventListeners(event.type())) { timelineAgent->willDispatchEvent(event); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie& cookie) @@ -260,15 +266,15 @@ void InspectorInstrumentation::didDispatchEventOnWindowImpl(const InspectorInstr timelineAgent->didDispatchEvent(); } -InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InspectorController* inspectorController, const String& url, int lineNumber) +InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InspectorAgent* inspectorAgent, const String& url, int lineNumber) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willEvaluateScript(url, lineNumber); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentationCookie& cookie) @@ -277,17 +283,17 @@ void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentat timelineAgent->didEvaluateScript(); } -InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InspectorController* inspectorController, int timerId) +InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InspectorAgent* inspectorAgent, int timerId) { - pauseOnNativeEventIfNeeded(inspectorController, instrumentationEventCategoryType, timerFiredEventName, false); + pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, timerFiredEventName, false); int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willFireTimer(timerId); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didFireTimerImpl(const InspectorInstrumentationCookie& cookie) @@ -298,15 +304,15 @@ void InspectorInstrumentation::didFireTimerImpl(const InspectorInstrumentationCo timelineAgent->didFireTimer(); } -InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InspectorController* inspectorController) +InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InspectorAgent* inspectorAgent) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willLayout(); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCookie& cookie) @@ -315,15 +321,15 @@ void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCooki timelineAgent->didLayout(); } -InspectorInstrumentationCookie InspectorInstrumentation::willLoadXHRImpl(InspectorController* inspectorController, XMLHttpRequest* request) +InspectorInstrumentationCookie InspectorInstrumentation::willLoadXHRImpl(InspectorAgent* inspectorAgent, XMLHttpRequest* request) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent && request->hasEventListeners(eventNames().loadEvent)) { timelineAgent->willLoadXHR(request->url()); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didLoadXHRImpl(const InspectorInstrumentationCookie& cookie) @@ -332,15 +338,15 @@ void InspectorInstrumentation::didLoadXHRImpl(const InspectorInstrumentationCook timelineAgent->didLoadXHR(); } -InspectorInstrumentationCookie InspectorInstrumentation::willPaintImpl(InspectorController* inspectorController, const IntRect& rect) +InspectorInstrumentationCookie InspectorInstrumentation::willPaintImpl(InspectorAgent* inspectorAgent, const IntRect& rect) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willPaint(rect); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didPaintImpl(const InspectorInstrumentationCookie& cookie) @@ -349,15 +355,15 @@ void InspectorInstrumentation::didPaintImpl(const InspectorInstrumentationCookie timelineAgent->didPaint(); } -InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InspectorController* inspectorController) +InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InspectorAgent* inspectorAgent) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willRecalculateStyle(); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrumentationCookie& cookie) @@ -366,49 +372,51 @@ void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrument timelineAgent->didRecalculateStyle(); } -void InspectorInstrumentation::identifierForInitialRequestImpl(InspectorController* ic, unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) +void InspectorInstrumentation::identifierForInitialRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) { - if (!ic->enabled()) + if (!inspectorAgent->enabled()) return; - ic->ensureSettingsLoaded(); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->identifierForInitialRequest(identifier, request.url(), loader); } -void InspectorInstrumentation::willSendRequestImpl(InspectorController* ic, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) +void InspectorInstrumentation::applyUserAgentOverrideImpl(InspectorAgent* inspectorAgent, String* userAgent) { - ic->willSendRequest(request); - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(ic)) + inspectorAgent->applyUserAgentOverride(userAgent); +} + +void InspectorInstrumentation::willSendRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->willSendResourceRequest(identifier, request); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->willSendRequest(identifier, request, redirectResponse); } -void InspectorInstrumentation::markResourceAsCachedImpl(InspectorController* ic, unsigned long identifier) +void InspectorInstrumentation::markResourceAsCachedImpl(InspectorAgent* inspectorAgent, unsigned long identifier) { - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->markResourceAsCached(identifier); } -void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InspectorController* ic, DocumentLoader* loader, const CachedResource* cachedResource) +void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InspectorAgent* inspectorAgent, DocumentLoader* loader, const CachedResource* cachedResource) { - if (!ic->enabled()) + if (!inspectorAgent->enabled()) return; - ic->ensureSettingsLoaded(); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource); } -InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceDataImpl(InspectorController* inspectorController, unsigned long identifier) +InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceDataImpl(InspectorAgent* inspectorAgent, unsigned long identifier) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willReceiveResourceData(identifier); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didReceiveResourceDataImpl(const InspectorInstrumentationCookie& cookie) @@ -417,93 +425,93 @@ void InspectorInstrumentation::didReceiveResourceDataImpl(const InspectorInstrum timelineAgent->didReceiveResourceData(); } -InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponseImpl(InspectorController* inspectorController, unsigned long identifier, const ResourceResponse& response) +InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponseImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const ResourceResponse& response) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willReceiveResourceResponse(identifier, response); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorInstrumentationCookie& cookie, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response) { - InspectorController* ic = cookie.first; - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + InspectorAgent* inspectorAgent = cookie.first; + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->didReceiveResponse(identifier, loader, response); - ic->consoleAgent()->didReceiveResponse(identifier, response); + inspectorAgent->consoleAgent()->didReceiveResponse(identifier, response); if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie)) timelineAgent->didReceiveResourceResponse(); } -void InspectorInstrumentation::didReceiveContentLengthImpl(InspectorController* ic, unsigned long identifier, int lengthReceived) +void InspectorInstrumentation::didReceiveContentLengthImpl(InspectorAgent* inspectorAgent, unsigned long identifier, int lengthReceived) { - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->didReceiveContentLength(identifier, lengthReceived); } -void InspectorInstrumentation::didFinishLoadingImpl(InspectorController* ic, unsigned long identifier, double finishTime) +void InspectorInstrumentation::didFinishLoadingImpl(InspectorAgent* inspectorAgent, unsigned long identifier, double finishTime) { - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(ic)) + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->didFinishLoadingResource(identifier, false, finishTime); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->didFinishLoading(identifier, finishTime); } -void InspectorInstrumentation::didFailLoadingImpl(InspectorController* ic, unsigned long identifier, const ResourceError& error) +void InspectorInstrumentation::didFailLoadingImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const ResourceError& error) { - ic->consoleAgent()->didFailLoading(identifier, error); - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(ic)) + inspectorAgent->consoleAgent()->didFailLoading(identifier, error); + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) timelineAgent->didFinishLoadingResource(identifier, true, 0); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->didFailLoading(identifier, error); } -void InspectorInstrumentation::resourceRetrievedByXMLHttpRequestImpl(InspectorController* ic, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) +void InspectorInstrumentation::resourceRetrievedByXMLHttpRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) { - ic->consoleAgent()->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber); - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + inspectorAgent->consoleAgent()->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber); + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->setInitialContent(identifier, sourceString, "XHR"); } -void InspectorInstrumentation::scriptImportedImpl(InspectorController* ic, unsigned long identifier, const String& sourceString) +void InspectorInstrumentation::scriptImportedImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const String& sourceString) { - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->setInitialContent(identifier, sourceString, "Script"); } -void InspectorInstrumentation::mainResourceFiredLoadEventImpl(InspectorController* inspectorController, Frame* frame, const KURL& url) +void InspectorInstrumentation::domContentLoadedEventFiredImpl(InspectorAgent* inspectorAgent, Frame* frame, const KURL& url) { - inspectorController->mainResourceFiredLoadEvent(frame->loader()->documentLoader(), url); + inspectorAgent->domContentLoadedEventFired(frame->loader()->documentLoader(), url); } -void InspectorInstrumentation::mainResourceFiredDOMContentEventImpl(InspectorController* inspectorController, Frame* frame, const KURL& url) +void InspectorInstrumentation::loadEventFiredImpl(InspectorAgent* inspectorAgent, Frame* frame, const KURL& url) { - inspectorController->mainResourceFiredDOMContentEvent(frame->loader()->documentLoader(), url); + inspectorAgent->loadEventFired(frame->loader()->documentLoader(), url); } -void InspectorInstrumentation::frameDetachedFromParentImpl(InspectorController* inspectorController, Frame* frame) +void InspectorInstrumentation::frameDetachedFromParentImpl(InspectorAgent* inspectorAgent, Frame* frame) { - if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorController)) + if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent)) resourceAgent->frameDetachedFromParent(frame); } -void InspectorInstrumentation::didCommitLoadImpl(InspectorController* inspectorController, DocumentLoader* loader) +void InspectorInstrumentation::didCommitLoadImpl(InspectorAgent* inspectorAgent, DocumentLoader* loader) { - inspectorController->didCommitLoad(loader); + inspectorAgent->didCommitLoad(loader); } -InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTMLImpl(InspectorController* inspectorController, unsigned int length, unsigned int startLine) +InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTMLImpl(InspectorAgent* inspectorAgent, unsigned int length, unsigned int startLine) { int timelineAgentId = 0; - InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController); + InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent); if (timelineAgent) { timelineAgent->willWriteHTML(length, startLine); timelineAgentId = timelineAgent->id(); } - return InspectorInstrumentationCookie(inspectorController, timelineAgentId); + return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId); } void InspectorInstrumentation::didWriteHTMLImpl(const InspectorInstrumentationCookie& cookie, unsigned int endLine) @@ -512,161 +520,154 @@ void InspectorInstrumentation::didWriteHTMLImpl(const InspectorInstrumentationCo timelineAgent->didWriteHTML(endLine); } -void InspectorInstrumentation::addMessageToConsoleImpl(InspectorController* inspectorController, MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptArguments* arguments, ScriptCallStack* callStack) +void InspectorInstrumentation::addMessageToConsoleImpl(InspectorAgent* inspectorAgent, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr arguments, PassRefPtr callStack) { - inspectorController->consoleAgent()->addMessageToConsole(source, type, level, message, arguments, callStack); + inspectorAgent->consoleAgent()->addMessageToConsole(source, type, level, message, arguments, callStack); } -void InspectorInstrumentation::addMessageToConsoleImpl(InspectorController* inspectorController, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) +void InspectorInstrumentation::addMessageToConsoleImpl(InspectorAgent* inspectorAgent, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) { - inspectorController->consoleAgent()->addMessageToConsole(source, type, level, message, lineNumber, sourceID); + inspectorAgent->consoleAgent()->addMessageToConsole(source, type, level, message, lineNumber, sourceID); } -void InspectorInstrumentation::consoleCountImpl(InspectorController* inspectorController, ScriptArguments* arguments, ScriptCallStack* stack) +void InspectorInstrumentation::consoleCountImpl(InspectorAgent* inspectorAgent, PassRefPtr arguments, PassRefPtr stack) { - inspectorController->consoleAgent()->count(arguments, stack); + inspectorAgent->consoleAgent()->count(arguments, stack); } -void InspectorInstrumentation::startConsoleTimingImpl(InspectorController* inspectorController, const String& title) +void InspectorInstrumentation::startConsoleTimingImpl(InspectorAgent* inspectorAgent, const String& title) { - inspectorController->consoleAgent()->startTiming(title); + inspectorAgent->consoleAgent()->startTiming(title); } -void InspectorInstrumentation::stopConsoleTimingImpl(InspectorController* inspectorController, const String& title, ScriptCallStack* stack) +void InspectorInstrumentation::stopConsoleTimingImpl(InspectorAgent* inspectorAgent, const String& title, PassRefPtr stack) { - inspectorController->consoleAgent()->stopTiming(title, stack); + inspectorAgent->consoleAgent()->stopTiming(title, stack); } -void InspectorInstrumentation::consoleMarkTimelineImpl(InspectorController* inspectorController, ScriptArguments* arguments) +void InspectorInstrumentation::consoleMarkTimelineImpl(InspectorAgent* inspectorAgent, PassRefPtr arguments) { - if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorController)) { + if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) { String message; arguments->getFirstArgumentAsString(message); timelineAgent->didMarkTimeline(message); - } + } } #if ENABLE(JAVASCRIPT_DEBUGGER) -void InspectorInstrumentation::addStartProfilingMessageToConsoleImpl(InspectorController* inspectorController, const String& title, unsigned lineNumber, const String& sourceURL) +void InspectorInstrumentation::addStartProfilingMessageToConsoleImpl(InspectorAgent* inspectorAgent, const String& title, unsigned lineNumber, const String& sourceURL) { - if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent()) + if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent()) profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, sourceURL); } -void InspectorInstrumentation::addProfileImpl(InspectorController* inspectorController, RefPtr profile, ScriptCallStack* callStack) +void InspectorInstrumentation::addProfileImpl(InspectorAgent* inspectorAgent, RefPtr profile, PassRefPtr callStack) { - if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent()) { + if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent()) { const ScriptCallFrame& lastCaller = callStack->at(0); profilerAgent->addProfile(profile, lastCaller.lineNumber(), lastCaller.sourceURL()); } } -bool InspectorInstrumentation::profilerEnabledImpl(InspectorController* inspectorController) +String InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(InspectorAgent* inspectorAgent, bool incrementProfileNumber) { - if (!inspectorController->enabled()) - return false; - - InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent(); - if (!profilerAgent) - return false; - - return profilerAgent->enabled(); + if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent()) + return profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber); + return ""; } -String InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(InspectorController* inspectorController, bool incrementProfileNumber) +bool InspectorInstrumentation::profilerEnabledImpl(InspectorAgent* inspectorAgent) { - if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent()) - return profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber); - return ""; + return inspectorAgent->profilerEnabled(); } #endif #if ENABLE(DATABASE) -void InspectorInstrumentation::didOpenDatabaseImpl(InspectorController* inspectorController, Database* database, const String& domain, const String& name, const String& version) +void InspectorInstrumentation::didOpenDatabaseImpl(InspectorAgent* inspectorAgent, PassRefPtr database, const String& domain, const String& name, const String& version) { - inspectorController->didOpenDatabase(database, domain, name, version); + inspectorAgent->didOpenDatabase(database, domain, name, version); } #endif #if ENABLE(DOM_STORAGE) -void InspectorInstrumentation::didUseDOMStorageImpl(InspectorController* inspectorController, StorageArea* storageArea, bool isLocalStorage, Frame* frame) +void InspectorInstrumentation::didUseDOMStorageImpl(InspectorAgent* inspectorAgent, StorageArea* storageArea, bool isLocalStorage, Frame* frame) { - inspectorController->didUseDOMStorage(storageArea, isLocalStorage, frame); + inspectorAgent->didUseDOMStorage(storageArea, isLocalStorage, frame); } #endif #if ENABLE(WORKERS) -void InspectorInstrumentation::didCreateWorkerImpl(InspectorController* inspectorController, intptr_t id, const String& url, bool isSharedWorker) +void InspectorInstrumentation::didCreateWorkerImpl(InspectorAgent* inspectorAgent, intptr_t id, const String& url, bool isSharedWorker) { - inspectorController->didCreateWorker(id, url, isSharedWorker); + inspectorAgent->didCreateWorker(id, url, isSharedWorker); } -void InspectorInstrumentation::didDestroyWorkerImpl(InspectorController* inspectorController, intptr_t id) +void InspectorInstrumentation::didDestroyWorkerImpl(InspectorAgent* inspectorAgent, intptr_t id) { - inspectorController->didDestroyWorker(id); + inspectorAgent->didDestroyWorker(id); } #endif #if ENABLE(WEB_SOCKETS) -void InspectorInstrumentation::didCreateWebSocketImpl(InspectorController* inspectorController, unsigned long identifier, const KURL& requestURL, const KURL& documentURL) +void InspectorInstrumentation::didCreateWebSocketImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const KURL& requestURL, const KURL& documentURL) { - inspectorController->didCreateWebSocket(identifier, requestURL, documentURL); + inspectorAgent->didCreateWebSocket(identifier, requestURL, documentURL); } -void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InspectorController* inspectorController, unsigned long identifier, const WebSocketHandshakeRequest& request) +void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const WebSocketHandshakeRequest& request) { - inspectorController->willSendWebSocketHandshakeRequest(identifier, request); + inspectorAgent->willSendWebSocketHandshakeRequest(identifier, request); } -void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InspectorController* inspectorController, unsigned long identifier, const WebSocketHandshakeResponse& response) +void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const WebSocketHandshakeResponse& response) { - inspectorController->didReceiveWebSocketHandshakeResponse(identifier, response); + inspectorAgent->didReceiveWebSocketHandshakeResponse(identifier, response); } -void InspectorInstrumentation::didCloseWebSocketImpl(InspectorController* inspectorController, unsigned long identifier) +void InspectorInstrumentation::didCloseWebSocketImpl(InspectorAgent* inspectorAgent, unsigned long identifier) { - inspectorController->didCloseWebSocket(identifier); + inspectorAgent->didCloseWebSocket(identifier); } #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) -void InspectorInstrumentation::networkStateChangedImpl(InspectorController* ic) +void InspectorInstrumentation::networkStateChangedImpl(InspectorAgent* inspectorAgent) { - if (InspectorApplicationCacheAgent* applicationCacheAgent = ic->applicationCacheAgent()) + if (InspectorApplicationCacheAgent* applicationCacheAgent = inspectorAgent->applicationCacheAgent()) applicationCacheAgent->networkStateChanged(); } -void InspectorInstrumentation::updateApplicationCacheStatusImpl(InspectorController* ic, Frame* frame) +void InspectorInstrumentation::updateApplicationCacheStatusImpl(InspectorAgent* inspectorAgent, Frame* frame) { - if (InspectorApplicationCacheAgent* applicationCacheAgent = ic->applicationCacheAgent()) + if (InspectorApplicationCacheAgent* applicationCacheAgent = inspectorAgent->applicationCacheAgent()) applicationCacheAgent->updateApplicationCacheStatus(frame); } #endif -bool InspectorInstrumentation::hasFrontend(InspectorController* inspectorController) +bool InspectorInstrumentation::hasFrontend(InspectorAgent* inspectorAgent) { - return inspectorController->hasFrontend(); + return inspectorAgent->hasFrontend(); } -void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorController* inspectorController, const String& categoryType, const String& eventName, bool synchronous) +void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorAgent* inspectorAgent, const String& categoryType, const String& eventName, bool synchronous) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent()) + if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->browserDebuggerAgent()) browserDebuggerAgent->pauseOnNativeEventIfNeeded(categoryType, eventName, synchronous); #endif } -void InspectorInstrumentation::cancelPauseOnNativeEvent(InspectorController* inspectorController) +void InspectorInstrumentation::cancelPauseOnNativeEvent(InspectorAgent* inspectorAgent) { #if ENABLE(JAVASCRIPT_DEBUGGER) - if (InspectorDebuggerAgent* debuggerAgent = inspectorController->debuggerAgent()) + if (InspectorDebuggerAgent* debuggerAgent = inspectorAgent->debuggerAgent()) debuggerAgent->cancelPauseOnNextStatement(); #endif } -InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(InspectorController* inspectorController) +InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(InspectorAgent* inspectorAgent) { - return inspectorController->timelineAgent(); + return inspectorAgent->timelineAgent(); } InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie) @@ -677,9 +678,9 @@ InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const In return 0; } -InspectorResourceAgent* InspectorInstrumentation::retrieveResourceAgent(InspectorController* ic) +InspectorResourceAgent* InspectorInstrumentation::retrieveResourceAgent(InspectorAgent* inspectorAgent) { - return ic->resourceAgent(); + return inspectorAgent->resourceAgent(); } } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h index 7a7ee43..e406e40 100644 --- a/Source/WebCore/inspector/InspectorInstrumentation.h +++ b/Source/WebCore/inspector/InspectorInstrumentation.h @@ -35,8 +35,7 @@ #include "Frame.h" #include "Page.h" #include "ScriptExecutionContext.h" - -#include +#include namespace WebCore { @@ -48,7 +47,7 @@ class Element; class EventContext; class DocumentLoader; class HitTestResult; -class InspectorController; +class InspectorAgent; class InspectorResourceAgent; class InspectorTimelineAgent; class KURL; @@ -66,7 +65,7 @@ class WebSocketHandshakeRequest; class WebSocketHandshakeResponse; #endif -typedef pair InspectorInstrumentationCookie; +typedef pair InspectorInstrumentationCookie; class InspectorInstrumentation { public: @@ -109,6 +108,7 @@ public: static InspectorInstrumentationCookie willRecalculateStyle(Document*); static void didRecalculateStyle(const InspectorInstrumentationCookie&); + static void applyUserAgentOverride(Frame*, String*); static void identifierForInitialRequest(Frame*, unsigned long identifier, DocumentLoader*, const ResourceRequest&); static void willSendRequest(Frame*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); static void markResourceAsCached(Page*, unsigned long identifier); @@ -122,30 +122,30 @@ public: 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); static void scriptImported(ScriptExecutionContext*, unsigned long identifier, const String& sourceString); - static void mainResourceFiredLoadEvent(Frame*, const KURL&); - static void mainResourceFiredDOMContentEvent(Frame*, const KURL&); + static void domContentLoadedEventFired(Frame*, const KURL&); + static void loadEventFired(Frame*, const KURL&); static void frameDetachedFromParent(Frame*); static void didCommitLoad(Frame*, DocumentLoader*); static InspectorInstrumentationCookie willWriteHTML(Document*, unsigned int length, unsigned int startLine); static void didWriteHTML(const InspectorInstrumentationCookie&, unsigned int endLine); - static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, ScriptArguments*, ScriptCallStack*); + static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr, PassRefPtr); static void addMessageToConsole(Page*, MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String&); - static void consoleCount(Page*, ScriptArguments*, ScriptCallStack*); + static void consoleCount(Page*, PassRefPtr, PassRefPtr); static void startConsoleTiming(Page*, const String& title); - static void stopConsoleTiming(Page*, const String& title, ScriptCallStack*); - static void consoleMarkTimeline(Page*, ScriptArguments*); + static void stopConsoleTiming(Page*, const String& title, PassRefPtr); + static void consoleMarkTimeline(Page*, PassRefPtr); #if ENABLE(JAVASCRIPT_DEBUGGER) static void addStartProfilingMessageToConsole(Page*, const String& title, unsigned lineNumber, const String& sourceURL); - static void addProfile(Page*, RefPtr, ScriptCallStack*); - static bool profilerEnabled(Page*); + static void addProfile(Page*, RefPtr, PassRefPtr); static String getCurrentUserInitiatedProfileName(Page*, bool incrementProfileNumber); + static bool profilerEnabled(Page*); #endif #if ENABLE(DATABASE) - static void didOpenDatabase(ScriptExecutionContext*, Database*, const String& domain, const String& name, const String& version); + static void didOpenDatabase(ScriptExecutionContext*, PassRefPtr, const String& domain, const String& name, const String& version); #endif #if ENABLE(DOM_STORAGE) @@ -171,129 +171,136 @@ public: #endif #if ENABLE(INSPECTOR) + static void bindInspectorAgent(Page* page, InspectorAgent* inspectorAgent) { inspectorAgents().set(page, inspectorAgent); } + static void unbindInspectorAgent(Page* page) { inspectorAgents().remove(page); } static void frontendCreated() { s_frontendCounter += 1; } static void frontendDeleted() { s_frontendCounter -= 1; } static bool hasFrontends() { return s_frontendCounter; } + static bool hasFrontend(Page*); #else static bool hasFrontends() { return false; } + static bool hasFrontend(Page*) { return false; } #endif private: #if ENABLE(INSPECTOR) - static void didClearWindowObjectInWorldImpl(InspectorController*, Frame*, DOMWrapperWorld*); - static void inspectedPageDestroyedImpl(InspectorController*); + static void didClearWindowObjectInWorldImpl(InspectorAgent*, Frame*, DOMWrapperWorld*); + static void inspectedPageDestroyedImpl(InspectorAgent*); - static void willInsertDOMNodeImpl(InspectorController*, Node* node, Node* parent); - static void didInsertDOMNodeImpl(InspectorController*, Node*); - static void willRemoveDOMNodeImpl(InspectorController*, Node*); - static void didRemoveDOMNodeImpl(InspectorController*, Node*); - static void willModifyDOMAttrImpl(InspectorController*, Element*); - static void didModifyDOMAttrImpl(InspectorController*, Element*); - static void characterDataModifiedImpl(InspectorController*, CharacterData*); + static void willInsertDOMNodeImpl(InspectorAgent*, Node* node, Node* parent); + static void didInsertDOMNodeImpl(InspectorAgent*, Node*); + static void willRemoveDOMNodeImpl(InspectorAgent*, Node*); + static void didRemoveDOMNodeImpl(InspectorAgent*, Node*); + static void willModifyDOMAttrImpl(InspectorAgent*, Element*); + static void didModifyDOMAttrImpl(InspectorAgent*, Element*); + static void characterDataModifiedImpl(InspectorAgent*, CharacterData*); - static void mouseDidMoveOverElementImpl(InspectorController*, const HitTestResult&, unsigned modifierFlags); - static bool handleMousePressImpl(InspectorController*); + static void mouseDidMoveOverElementImpl(InspectorAgent*, const HitTestResult&, unsigned modifierFlags); + static bool handleMousePressImpl(InspectorAgent*); - static void willSendXMLHttpRequestImpl(InspectorController*, const String& url); - static void didScheduleResourceRequestImpl(InspectorController*, const String& url); - static void didInstallTimerImpl(InspectorController*, int timerId, int timeout, bool singleShot); - static void didRemoveTimerImpl(InspectorController*, int timerId); + static void willSendXMLHttpRequestImpl(InspectorAgent*, const String& url); + static void didScheduleResourceRequestImpl(InspectorAgent*, const String& url); + static void didInstallTimerImpl(InspectorAgent*, int timerId, int timeout, bool singleShot); + static void didRemoveTimerImpl(InspectorAgent*, int timerId); - static InspectorInstrumentationCookie willCallFunctionImpl(InspectorController*, const String& scriptName, int scriptLine); + static InspectorInstrumentationCookie willCallFunctionImpl(InspectorAgent*, const String& scriptName, int scriptLine); static void didCallFunctionImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willChangeXHRReadyStateImpl(InspectorController*, XMLHttpRequest* request); + static InspectorInstrumentationCookie willChangeXHRReadyStateImpl(InspectorAgent*, XMLHttpRequest* request); static void didChangeXHRReadyStateImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEventImpl(InspectorController*, const Event& event, DOMWindow* window, Node* node, const Vector& ancestors); + static InspectorInstrumentationCookie willDispatchEventImpl(InspectorAgent*, const Event& event, DOMWindow* window, Node* node, const Vector& ancestors); static void didDispatchEventImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InspectorController*, const Event& event, DOMWindow* window); + static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InspectorAgent*, const Event& event, DOMWindow* window); static void didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willEvaluateScriptImpl(InspectorController*, const String& url, int lineNumber); + static InspectorInstrumentationCookie willEvaluateScriptImpl(InspectorAgent*, const String& url, int lineNumber); static void didEvaluateScriptImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willFireTimerImpl(InspectorController*, int timerId); + static InspectorInstrumentationCookie willFireTimerImpl(InspectorAgent*, int timerId); static void didFireTimerImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willLayoutImpl(InspectorController*); + static InspectorInstrumentationCookie willLayoutImpl(InspectorAgent*); static void didLayoutImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willLoadXHRImpl(InspectorController*, XMLHttpRequest* request); + static InspectorInstrumentationCookie willLoadXHRImpl(InspectorAgent*, XMLHttpRequest* request); static void didLoadXHRImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willPaintImpl(InspectorController*, const IntRect& rect); + static InspectorInstrumentationCookie willPaintImpl(InspectorAgent*, const IntRect& rect); static void didPaintImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willRecalculateStyleImpl(InspectorController*); + static InspectorInstrumentationCookie willRecalculateStyleImpl(InspectorAgent*); static void didRecalculateStyleImpl(const InspectorInstrumentationCookie&); - static void identifierForInitialRequestImpl(InspectorController*, unsigned long identifier, DocumentLoader*, const ResourceRequest&); - static void willSendRequestImpl(InspectorController*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); - static void markResourceAsCachedImpl(InspectorController*, unsigned long identifier); - static void didLoadResourceFromMemoryCacheImpl(InspectorController*, DocumentLoader*, const CachedResource*); - static InspectorInstrumentationCookie willReceiveResourceDataImpl(InspectorController*, unsigned long identifier); + + static void applyUserAgentOverrideImpl(InspectorAgent*, String*); + static void identifierForInitialRequestImpl(InspectorAgent*, unsigned long identifier, DocumentLoader*, const ResourceRequest&); + static void willSendRequestImpl(InspectorAgent*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); + static void markResourceAsCachedImpl(InspectorAgent*, unsigned long identifier); + static void didLoadResourceFromMemoryCacheImpl(InspectorAgent*, DocumentLoader*, const CachedResource*); + static InspectorInstrumentationCookie willReceiveResourceDataImpl(InspectorAgent*, unsigned long identifier); static void didReceiveResourceDataImpl(const InspectorInstrumentationCookie&); - static InspectorInstrumentationCookie willReceiveResourceResponseImpl(InspectorController*, unsigned long identifier, const ResourceResponse&); + static InspectorInstrumentationCookie willReceiveResourceResponseImpl(InspectorAgent*, unsigned long identifier, const ResourceResponse&); static void didReceiveResourceResponseImpl(const InspectorInstrumentationCookie&, unsigned long identifier, DocumentLoader*, const ResourceResponse&); - static void didReceiveContentLengthImpl(InspectorController*, unsigned long identifier, int lengthReceived); - static void didFinishLoadingImpl(InspectorController*, unsigned long identifier, double finishTime); - static void didFailLoadingImpl(InspectorController*, unsigned long identifier, const ResourceError&); - static void resourceRetrievedByXMLHttpRequestImpl(InspectorController*, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber); - static void scriptImportedImpl(InspectorController*, unsigned long identifier, const String& sourceString); - static void mainResourceFiredLoadEventImpl(InspectorController*, Frame*, const KURL&); - static void mainResourceFiredDOMContentEventImpl(InspectorController*, Frame*, const KURL&); - static void frameDetachedFromParentImpl(InspectorController*, Frame*); - static void didCommitLoadImpl(InspectorController*, DocumentLoader*); - - static InspectorInstrumentationCookie willWriteHTMLImpl(InspectorController*, unsigned int length, unsigned int startLine); + static void didReceiveContentLengthImpl(InspectorAgent*, unsigned long identifier, int lengthReceived); + 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); + static void scriptImportedImpl(InspectorAgent*, unsigned long identifier, const String& sourceString); + static void domContentLoadedEventFiredImpl(InspectorAgent*, Frame*, const KURL&); + static void loadEventFiredImpl(InspectorAgent*, Frame*, const KURL&); + static void frameDetachedFromParentImpl(InspectorAgent*, Frame*); + static void didCommitLoadImpl(InspectorAgent*, DocumentLoader*); + + static InspectorInstrumentationCookie willWriteHTMLImpl(InspectorAgent*, unsigned int length, unsigned int startLine); static void didWriteHTMLImpl(const InspectorInstrumentationCookie&, unsigned int endLine); - static void addMessageToConsoleImpl(InspectorController*, MessageSource, MessageType, MessageLevel, const String& message, ScriptArguments*, ScriptCallStack*); - static void addMessageToConsoleImpl(InspectorController*, MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID); - static void consoleCountImpl(InspectorController*, ScriptArguments*, ScriptCallStack*); - static void startConsoleTimingImpl(InspectorController*, const String& title); - static void stopConsoleTimingImpl(InspectorController*, const String& title, ScriptCallStack*); - static void consoleMarkTimelineImpl(InspectorController*, ScriptArguments*); + static void addMessageToConsoleImpl(InspectorAgent*, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr, PassRefPtr); + static void addMessageToConsoleImpl(InspectorAgent*, MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID); + static void consoleCountImpl(InspectorAgent*, PassRefPtr, PassRefPtr); + static void startConsoleTimingImpl(InspectorAgent*, const String& title); + static void stopConsoleTimingImpl(InspectorAgent*, const String& title, PassRefPtr); + static void consoleMarkTimelineImpl(InspectorAgent*, PassRefPtr); #if ENABLE(JAVASCRIPT_DEBUGGER) - static void addStartProfilingMessageToConsoleImpl(InspectorController*, const String& title, unsigned lineNumber, const String& sourceURL); - static void addProfileImpl(InspectorController*, RefPtr, ScriptCallStack*); - static bool profilerEnabledImpl(InspectorController*); - static String getCurrentUserInitiatedProfileNameImpl(InspectorController*, bool incrementProfileNumber); + static void addStartProfilingMessageToConsoleImpl(InspectorAgent*, const String& title, unsigned lineNumber, const String& sourceURL); + static void addProfileImpl(InspectorAgent*, RefPtr, PassRefPtr); + static String getCurrentUserInitiatedProfileNameImpl(InspectorAgent*, bool incrementProfileNumber); + static bool profilerEnabledImpl(InspectorAgent*); #endif #if ENABLE(DATABASE) - static void didOpenDatabaseImpl(InspectorController*, Database*, const String& domain, const String& name, const String& version); + static void didOpenDatabaseImpl(InspectorAgent*, PassRefPtr, const String& domain, const String& name, const String& version); #endif #if ENABLE(DOM_STORAGE) - static void didUseDOMStorageImpl(InspectorController*, StorageArea*, bool isLocalStorage, Frame*); + static void didUseDOMStorageImpl(InspectorAgent*, StorageArea*, bool isLocalStorage, Frame*); #endif #if ENABLE(WORKERS) - static void didCreateWorkerImpl(InspectorController*, intptr_t id, const String& url, bool isSharedWorker); - static void didDestroyWorkerImpl(InspectorController*, intptr_t id); + static void didCreateWorkerImpl(InspectorAgent*, intptr_t id, const String& url, bool isSharedWorker); + static void didDestroyWorkerImpl(InspectorAgent*, intptr_t id); #endif #if ENABLE(WEB_SOCKETS) - static void didCreateWebSocketImpl(InspectorController*, unsigned long identifier, const KURL& requestURL, const KURL& documentURL); - static void willSendWebSocketHandshakeRequestImpl(InspectorController*, unsigned long identifier, const WebSocketHandshakeRequest&); - static void didReceiveWebSocketHandshakeResponseImpl(InspectorController*, unsigned long identifier, const WebSocketHandshakeResponse&); - static void didCloseWebSocketImpl(InspectorController*, unsigned long identifier); + static void didCreateWebSocketImpl(InspectorAgent*, unsigned long identifier, const KURL& requestURL, const KURL& documentURL); + static void willSendWebSocketHandshakeRequestImpl(InspectorAgent*, unsigned long identifier, const WebSocketHandshakeRequest&); + static void didReceiveWebSocketHandshakeResponseImpl(InspectorAgent*, unsigned long identifier, const WebSocketHandshakeResponse&); + static void didCloseWebSocketImpl(InspectorAgent*, unsigned long identifier); #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) - static void networkStateChangedImpl(InspectorController*); - static void updateApplicationCacheStatusImpl(InspectorController*, Frame*); -#endif - - static InspectorController* inspectorControllerForFrame(Frame*); - static InspectorController* inspectorControllerForContext(ScriptExecutionContext*); - static InspectorController* inspectorControllerForPage(Page*); - static InspectorController* inspectorControllerWithFrontendForContext(ScriptExecutionContext*); - static InspectorController* inspectorControllerWithFrontendForDocument(Document*); - static InspectorController* inspectorControllerWithFrontendForFrame(Frame*); - static InspectorController* inspectorControllerWithFrontendForPage(Page*); - - static bool hasFrontend(InspectorController*); - static void pauseOnNativeEventIfNeeded(InspectorController*, const String& categoryType, const String& eventName, bool synchronous); - static void cancelPauseOnNativeEvent(InspectorController*); - static InspectorTimelineAgent* retrieveTimelineAgent(InspectorController*); + static void networkStateChangedImpl(InspectorAgent*); + static void updateApplicationCacheStatusImpl(InspectorAgent*, Frame*); +#endif + + static InspectorAgent* inspectorAgentForFrame(Frame*); + static InspectorAgent* inspectorAgentForContext(ScriptExecutionContext*); + static InspectorAgent* inspectorAgentForPage(Page*); + static InspectorAgent* inspectorAgentWithFrontendForContext(ScriptExecutionContext*); + static InspectorAgent* inspectorAgentWithFrontendForDocument(Document*); + static InspectorAgent* inspectorAgentWithFrontendForFrame(Frame*); + static InspectorAgent* inspectorAgentWithFrontendForPage(Page*); + + static bool hasFrontend(InspectorAgent*); + static void pauseOnNativeEventIfNeeded(InspectorAgent*, const String& categoryType, const String& eventName, bool synchronous); + static void cancelPauseOnNativeEvent(InspectorAgent*); + static InspectorTimelineAgent* retrieveTimelineAgent(InspectorAgent*); static InspectorTimelineAgent* retrieveTimelineAgent(const InspectorInstrumentationCookie&); - static InspectorResourceAgent* retrieveResourceAgent(InspectorController*); + static InspectorResourceAgent* retrieveResourceAgent(InspectorAgent*); + static HashMap& inspectorAgents(); static int s_frontendCounter; #endif }; @@ -301,41 +308,41 @@ private: inline void InspectorInstrumentation::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForFrame(frame)) - didClearWindowObjectInWorldImpl(inspectorController, frame, world); + if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame)) + didClearWindowObjectInWorldImpl(inspectorAgent, frame, world); #endif } inline void InspectorInstrumentation::inspectedPageDestroyed(Page* page) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - inspectedPageDestroyedImpl(inspectorController); + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + inspectedPageDestroyedImpl(inspectorAgent); #endif } inline void InspectorInstrumentation::willInsertDOMNode(Document* document, Node* node, Node* parent) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - willInsertDOMNodeImpl(inspectorController, node, parent); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + willInsertDOMNodeImpl(inspectorAgent, node, parent); #endif } inline void InspectorInstrumentation::didInsertDOMNode(Document* document, Node* node) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - didInsertDOMNodeImpl(inspectorController, node); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + didInsertDOMNodeImpl(inspectorAgent, node); #endif } inline void InspectorInstrumentation::willRemoveDOMNode(Document* document, Node* node) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) { - willRemoveDOMNodeImpl(inspectorController, node); - didRemoveDOMNodeImpl(inspectorController, node); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) { + willRemoveDOMNodeImpl(inspectorAgent, node); + didRemoveDOMNodeImpl(inspectorAgent, node); } #endif } @@ -343,32 +350,32 @@ inline void InspectorInstrumentation::willRemoveDOMNode(Document* document, Node inline void InspectorInstrumentation::willModifyDOMAttr(Document* document, Element* element) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - willModifyDOMAttrImpl(inspectorController, element); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + willModifyDOMAttrImpl(inspectorAgent, element); #endif } inline void InspectorInstrumentation::didModifyDOMAttr(Document* document, Element* element) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - didModifyDOMAttrImpl(inspectorController, element); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + didModifyDOMAttrImpl(inspectorAgent, element); #endif } inline void InspectorInstrumentation::mouseDidMoveOverElement(Page* page, const HitTestResult& result, unsigned modifierFlags) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForPage(page)) - mouseDidMoveOverElementImpl(inspectorController, result, modifierFlags); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForPage(page)) + mouseDidMoveOverElementImpl(inspectorAgent, result, modifierFlags); #endif } inline bool InspectorInstrumentation::handleMousePress(Page* page) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForPage(page)) - return handleMousePressImpl(inspectorController); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForPage(page)) + return handleMousePressImpl(inspectorAgent); #endif return false; } @@ -376,40 +383,40 @@ inline bool InspectorInstrumentation::handleMousePress(Page* page) inline void InspectorInstrumentation::characterDataModified(Document* document, CharacterData* characterData) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - characterDataModifiedImpl(inspectorController, characterData); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + characterDataModifiedImpl(inspectorAgent, characterData); #endif } inline void InspectorInstrumentation::willSendXMLHttpRequest(ScriptExecutionContext* context, const String& url) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - willSendXMLHttpRequestImpl(inspectorController, url); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + willSendXMLHttpRequestImpl(inspectorAgent, url); #endif } inline void InspectorInstrumentation::didScheduleResourceRequest(Document* document, const String& url) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - didScheduleResourceRequestImpl(inspectorController, url); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + didScheduleResourceRequestImpl(inspectorAgent, url); #endif } inline void InspectorInstrumentation::didInstallTimer(ScriptExecutionContext* context, int timerId, int timeout, bool singleShot) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didInstallTimerImpl(inspectorController, timerId, timeout, singleShot); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didInstallTimerImpl(inspectorAgent, timerId, timeout, singleShot); #endif } inline void InspectorInstrumentation::didRemoveTimer(ScriptExecutionContext* context, int timerId) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didRemoveTimerImpl(inspectorController, timerId); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didRemoveTimerImpl(inspectorAgent, timerId); #endif } @@ -417,8 +424,8 @@ inline void InspectorInstrumentation::didRemoveTimer(ScriptExecutionContext* con inline InspectorInstrumentationCookie InspectorInstrumentation::willCallFunction(Frame* frame, const String& scriptName, int scriptLine) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willCallFunctionImpl(inspectorController, scriptName, scriptLine); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willCallFunctionImpl(inspectorAgent, scriptName, scriptLine); #endif return InspectorInstrumentationCookie(); } @@ -434,8 +441,8 @@ inline void InspectorInstrumentation::didCallFunction(const InspectorInstrumenta inline InspectorInstrumentationCookie InspectorInstrumentation::willChangeXHRReadyState(ScriptExecutionContext* context, XMLHttpRequest* request) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - return willChangeXHRReadyStateImpl(inspectorController, request); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + return willChangeXHRReadyStateImpl(inspectorAgent, request); #endif return InspectorInstrumentationCookie(); } @@ -451,8 +458,8 @@ inline void InspectorInstrumentation::didChangeXHRReadyState(const InspectorInst inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector& ancestors) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - return willDispatchEventImpl(inspectorController, event, window, node, ancestors); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + return willDispatchEventImpl(inspectorAgent, event, window, node, ancestors); #endif return InspectorInstrumentationCookie(); } @@ -468,8 +475,8 @@ inline void InspectorInstrumentation::didDispatchEvent(const InspectorInstrument inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindow(Frame* frame, const Event& event, DOMWindow* window) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willDispatchEventOnWindowImpl(inspectorController, event, window); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willDispatchEventOnWindowImpl(inspectorAgent, event, window); #endif return InspectorInstrumentationCookie(); } @@ -485,8 +492,8 @@ inline void InspectorInstrumentation::didDispatchEventOnWindow(const InspectorIn inline InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScript(Frame* frame, const String& url, int lineNumber) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willEvaluateScriptImpl(inspectorController, url, lineNumber); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willEvaluateScriptImpl(inspectorAgent, url, lineNumber); #endif return InspectorInstrumentationCookie(); } @@ -502,8 +509,8 @@ inline void InspectorInstrumentation::didEvaluateScript(const InspectorInstrumen inline InspectorInstrumentationCookie InspectorInstrumentation::willFireTimer(ScriptExecutionContext* context, int timerId) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - return willFireTimerImpl(inspectorController, timerId); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + return willFireTimerImpl(inspectorAgent, timerId); #endif return InspectorInstrumentationCookie(); } @@ -519,8 +526,8 @@ inline void InspectorInstrumentation::didFireTimer(const InspectorInstrumentatio inline InspectorInstrumentationCookie InspectorInstrumentation::willLayout(Frame* frame) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willLayoutImpl(inspectorController); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willLayoutImpl(inspectorAgent); #endif return InspectorInstrumentationCookie(); } @@ -536,8 +543,8 @@ inline void InspectorInstrumentation::didLayout(const InspectorInstrumentationCo inline InspectorInstrumentationCookie InspectorInstrumentation::willLoadXHR(ScriptExecutionContext* context, XMLHttpRequest* request) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - return willLoadXHRImpl(inspectorController, request); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + return willLoadXHRImpl(inspectorAgent, request); #endif return InspectorInstrumentationCookie(); } @@ -553,8 +560,8 @@ inline void InspectorInstrumentation::didLoadXHR(const InspectorInstrumentationC inline InspectorInstrumentationCookie InspectorInstrumentation::willPaint(Frame* frame, const IntRect& rect) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willPaintImpl(inspectorController, rect); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willPaintImpl(inspectorAgent, rect); #endif return InspectorInstrumentationCookie(); } @@ -570,8 +577,8 @@ inline void InspectorInstrumentation::didPaint(const InspectorInstrumentationCoo inline InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyle(Document* document) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - return willRecalculateStyleImpl(inspectorController); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + return willRecalculateStyleImpl(inspectorAgent); #endif return InspectorInstrumentationCookie(); } @@ -590,15 +597,23 @@ inline void InspectorInstrumentation::identifierForInitialRequest(Frame* frame, // This notification should be procecessed even in cases there is no frontend. if (!frame) return; - if (InspectorController* ic = inspectorControllerForPage(frame->page())) + if (InspectorAgent* ic = inspectorAgentForPage(frame->page())) identifierForInitialRequestImpl(ic, identifier, loader, request); #endif } +inline void InspectorInstrumentation::applyUserAgentOverride(Frame* frame, String* userAgent) +{ +#if ENABLE(INSPECTOR) + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + applyUserAgentOverrideImpl(inspectorAgent, userAgent); +#endif +} + inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) { #if ENABLE(INSPECTOR) - if (InspectorController* ic = inspectorControllerWithFrontendForFrame(frame)) + if (InspectorAgent* ic = inspectorAgentWithFrontendForFrame(frame)) willSendRequestImpl(ic, identifier, request, redirectResponse); #endif } @@ -606,22 +621,22 @@ inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned lon inline void InspectorInstrumentation::markResourceAsCached(Page* page, unsigned long identifier) { #if ENABLE(INSPECTOR) - markResourceAsCachedImpl(inspectorControllerForPage(page), identifier); + markResourceAsCachedImpl(inspectorAgentForPage(page), identifier); #endif } inline void InspectorInstrumentation::didLoadResourceFromMemoryCache(Page* page, DocumentLoader* loader, const CachedResource* resource) { #if ENABLE(INSPECTOR) - didLoadResourceFromMemoryCacheImpl(inspectorControllerForPage(page), loader, resource); + didLoadResourceFromMemoryCacheImpl(inspectorAgentForPage(page), loader, resource); #endif } inline InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceData(Frame* frame, unsigned long identifier) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willReceiveResourceDataImpl(inspectorController, identifier); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willReceiveResourceDataImpl(inspectorAgent, identifier); #endif return InspectorInstrumentationCookie(); } @@ -637,8 +652,8 @@ inline void InspectorInstrumentation::didReceiveResourceData(const InspectorInst inline InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponse(Frame* frame, unsigned long identifier, const ResourceResponse& response) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - return willReceiveResourceResponseImpl(inspectorController, identifier, response); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + return willReceiveResourceResponseImpl(inspectorAgent, identifier, response); #endif return InspectorInstrumentationCookie(); } @@ -654,80 +669,80 @@ inline void InspectorInstrumentation::didReceiveResourceResponse(const Inspector inline void InspectorInstrumentation::didReceiveContentLength(Frame* frame, unsigned long identifier, int lengthReceived) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - didReceiveContentLengthImpl(inspectorController, identifier, lengthReceived); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + didReceiveContentLengthImpl(inspectorAgent, identifier, lengthReceived); #endif } inline void InspectorInstrumentation::didFinishLoading(Frame* frame, unsigned long identifier, double finishTime) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - didFinishLoadingImpl(inspectorController, identifier, finishTime); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + didFinishLoadingImpl(inspectorAgent, identifier, finishTime); #endif } inline void InspectorInstrumentation::didFailLoading(Frame* frame, unsigned long identifier, const ResourceError& error) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - didFailLoadingImpl(inspectorController, identifier, error); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + didFailLoadingImpl(inspectorAgent, identifier, error); #endif } inline void InspectorInstrumentation::resourceRetrievedByXMLHttpRequest(ScriptExecutionContext* context, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForContext(context)) - resourceRetrievedByXMLHttpRequestImpl(inspectorController, identifier, sourceString, url, sendURL, sendLineNumber); + if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context)) + resourceRetrievedByXMLHttpRequestImpl(inspectorAgent, identifier, sourceString, url, sendURL, sendLineNumber); #endif } inline void InspectorInstrumentation::scriptImported(ScriptExecutionContext* context, unsigned long identifier, const String& sourceString) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForContext(context)) - scriptImportedImpl(inspectorController, identifier, sourceString); + if (InspectorAgent* inspectorAgent = inspectorAgentForContext(context)) + scriptImportedImpl(inspectorAgent, identifier, sourceString); #endif } -inline void InspectorInstrumentation::mainResourceFiredLoadEvent(Frame* frame, const KURL& url) +inline void InspectorInstrumentation::domContentLoadedEventFired(Frame* frame, const KURL& url) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - mainResourceFiredLoadEventImpl(inspectorController, frame, url); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + domContentLoadedEventFiredImpl(inspectorAgent, frame, url); #endif } -inline void InspectorInstrumentation::mainResourceFiredDOMContentEvent(Frame* frame, const KURL& url) +inline void InspectorInstrumentation::loadEventFired(Frame* frame, const KURL& url) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - mainResourceFiredDOMContentEventImpl(inspectorController, frame, url); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + loadEventFiredImpl(inspectorAgent, frame, url); #endif } inline void InspectorInstrumentation::frameDetachedFromParent(Frame* frame) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - frameDetachedFromParentImpl(inspectorController, frame); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + frameDetachedFromParentImpl(inspectorAgent, frame); #endif } inline void InspectorInstrumentation::didCommitLoad(Frame* frame, DocumentLoader* loader) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForFrame(frame)) - didCommitLoadImpl(inspectorController, loader); + if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(frame)) + didCommitLoadImpl(inspectorAgent, loader); #endif } inline InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTML(Document* document, unsigned int length, unsigned int startLine) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForDocument(document)) - return willWriteHTMLImpl(inspectorController, length, startLine); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForDocument(document)) + return willWriteHTMLImpl(inspectorAgent, length, startLine); #endif return InspectorInstrumentationCookie(); } @@ -740,22 +755,12 @@ inline void InspectorInstrumentation::didWriteHTML(const InspectorInstrumentatio #endif } -#if ENABLE(DATABASE) -inline void InspectorInstrumentation::didOpenDatabase(ScriptExecutionContext* context, Database* database, const String& domain, const String& name, const String& version) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForContext(context)) - didOpenDatabaseImpl(inspectorController, database, domain, name, version); -#endif -} -#endif - #if ENABLE(DOM_STORAGE) inline void InspectorInstrumentation::didUseDOMStorage(Page* page, StorageArea* storageArea, bool isLocalStorage, Frame* frame) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - didUseDOMStorageImpl(inspectorController, storageArea, isLocalStorage, frame); + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) + didUseDOMStorageImpl(inspectorAgent, storageArea, isLocalStorage, frame); #endif } #endif @@ -764,16 +769,16 @@ inline void InspectorInstrumentation::didUseDOMStorage(Page* page, StorageArea* inline void InspectorInstrumentation::didCreateWorker(ScriptExecutionContext* context, intptr_t id, const String& url, bool isSharedWorker) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didCreateWorkerImpl(inspectorController, id, url, isSharedWorker); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didCreateWorkerImpl(inspectorAgent, id, url, isSharedWorker); #endif } inline void InspectorInstrumentation::didDestroyWorker(ScriptExecutionContext* context, intptr_t id) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didDestroyWorkerImpl(inspectorController, id); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didDestroyWorkerImpl(inspectorAgent, id); #endif } #endif @@ -783,32 +788,32 @@ 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 (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didCreateWebSocketImpl(inspectorController, identifier, requestURL, documentURL); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didCreateWebSocketImpl(inspectorAgent, identifier, requestURL, documentURL); #endif } inline void InspectorInstrumentation::willSendWebSocketHandshakeRequest(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeRequest& request) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - willSendWebSocketHandshakeRequestImpl(inspectorController, identifier, request); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + willSendWebSocketHandshakeRequestImpl(inspectorAgent, identifier, request); #endif } inline void InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(ScriptExecutionContext* context, unsigned long identifier, const WebSocketHandshakeResponse& response) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didReceiveWebSocketHandshakeResponseImpl(inspectorController, identifier, response); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didReceiveWebSocketHandshakeResponseImpl(inspectorAgent, identifier, response); #endif } inline void InspectorInstrumentation::didCloseWebSocket(ScriptExecutionContext* context, unsigned long identifier) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForContext(context)) - didCloseWebSocketImpl(inspectorController, identifier); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForContext(context)) + didCloseWebSocketImpl(inspectorAgent, identifier); #endif } #endif @@ -816,8 +821,8 @@ inline void InspectorInstrumentation::didCloseWebSocket(ScriptExecutionContext* inline void InspectorInstrumentation::networkStateChanged(Page* page) { #if ENABLE(INSPECTOR) && ENABLE(OFFLINE_WEB_APPLICATIONS) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForPage(page)) - networkStateChangedImpl(inspectorController); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForPage(page)) + networkStateChangedImpl(inspectorAgent); #endif } @@ -825,145 +830,69 @@ inline void InspectorInstrumentation::networkStateChanged(Page* page) inline void InspectorInstrumentation::updateApplicationCacheStatus(Frame* frame) { #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForFrame(frame)) - updateApplicationCacheStatusImpl(inspectorController, frame); + if (InspectorAgent* inspectorAgent = inspectorAgentWithFrontendForFrame(frame)) + updateApplicationCacheStatusImpl(inspectorAgent, frame); #endif } #endif -inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptArguments* arguments, ScriptCallStack* callStack) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - addMessageToConsoleImpl(inspectorController, source, type, level, message, arguments, callStack); -#endif -} - -inline void InspectorInstrumentation::addMessageToConsole(Page* page, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) -{ #if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - addMessageToConsoleImpl(inspectorController, source, type, level, message, lineNumber, sourceID); -#endif -} - -inline void InspectorInstrumentation::consoleCount(Page* page, ScriptArguments* arguments, ScriptCallStack* stack) +inline bool InspectorInstrumentation::hasFrontend(Page* page) { -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - consoleCountImpl(inspectorController, arguments, stack); -#endif + return inspectorAgentWithFrontendForPage(page); } - -inline void InspectorInstrumentation::startConsoleTiming(Page* page, const String& title) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - startConsoleTimingImpl(inspectorController, title); #endif -} -inline void InspectorInstrumentation::stopConsoleTiming(Page* page, const String& title, ScriptCallStack* stack) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - stopConsoleTimingImpl(inspectorController, title, stack); -#endif -} - -inline void InspectorInstrumentation::consoleMarkTimeline(Page* page, ScriptArguments* arguments) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerWithFrontendForPage(page)) - consoleMarkTimelineImpl(inspectorController, arguments); -#endif -} - -#if ENABLE(JAVASCRIPT_DEBUGGER) -inline void InspectorInstrumentation::addStartProfilingMessageToConsole(Page* page, const String& title, unsigned lineNumber, const String& sourceURL) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - addStartProfilingMessageToConsoleImpl(inspectorController, title, lineNumber, sourceURL); -#endif -} - -inline void InspectorInstrumentation::addProfile(Page* page, RefPtr profile, ScriptCallStack* callStack) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - addProfileImpl(inspectorController, profile, callStack); -#endif -} - -inline bool InspectorInstrumentation::profilerEnabled(Page* page) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - return profilerEnabledImpl(inspectorController); -#endif - return false; -} - -inline String InspectorInstrumentation::getCurrentUserInitiatedProfileName(Page* page, bool incrementProfileNumber) -{ -#if ENABLE(INSPECTOR) - if (InspectorController* inspectorController = inspectorControllerForPage(page)) - return InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(inspectorController, incrementProfileNumber); -#endif - return ""; -} -#endif #if ENABLE(INSPECTOR) -inline InspectorController* InspectorInstrumentation::inspectorControllerForContext(ScriptExecutionContext* context) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentForContext(ScriptExecutionContext* context) { if (context && context->isDocument()) - return inspectorControllerForPage(static_cast(context)->page()); + return inspectorAgentForPage(static_cast(context)->page()); return 0; } -inline InspectorController* InspectorInstrumentation::inspectorControllerForFrame(Frame* frame) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentForFrame(Frame* frame) { if (frame) - return inspectorControllerForPage(frame->page()); + return inspectorAgentForPage(frame->page()); return 0; } -inline InspectorController* InspectorInstrumentation::inspectorControllerForPage(Page* page) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentForPage(Page* page) { if (!page) return 0; - return page->inspectorController(); + return inspectorAgents().get(page); } -inline InspectorController* InspectorInstrumentation::inspectorControllerWithFrontendForContext(ScriptExecutionContext* context) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentWithFrontendForContext(ScriptExecutionContext* context) { if (hasFrontends() && context && context->isDocument()) - return inspectorControllerWithFrontendForPage(static_cast(context)->page()); + return inspectorAgentWithFrontendForPage(static_cast(context)->page()); return 0; } -inline InspectorController* InspectorInstrumentation::inspectorControllerWithFrontendForDocument(Document* document) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentWithFrontendForDocument(Document* document) { if (hasFrontends() && document) - return inspectorControllerWithFrontendForPage(document->page()); + return inspectorAgentWithFrontendForPage(document->page()); return 0; } -inline InspectorController* InspectorInstrumentation::inspectorControllerWithFrontendForFrame(Frame* frame) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentWithFrontendForFrame(Frame* frame) { if (hasFrontends() && frame) - return inspectorControllerWithFrontendForPage(frame->page()); + return inspectorAgentWithFrontendForPage(frame->page()); return 0; } -inline InspectorController* InspectorInstrumentation::inspectorControllerWithFrontendForPage(Page* page) +inline InspectorAgent* InspectorInstrumentation::inspectorAgentWithFrontendForPage(Page* page) { if (page) { - if (InspectorController* inspectorController = inspectorControllerForPage(page)) { - if (hasFrontend(inspectorController)) - return inspectorController; + if (InspectorAgent* inspectorAgent = inspectorAgentForPage(page)) { + if (hasFrontend(inspectorAgent)) + return inspectorAgent; } } return 0; diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.cpp b/Source/WebCore/inspector/InspectorProfilerAgent.cpp index 8c4f28f..550febf 100644 --- a/Source/WebCore/inspector/InspectorProfilerAgent.cpp +++ b/Source/WebCore/inspector/InspectorProfilerAgent.cpp @@ -33,8 +33,8 @@ #if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR) #include "Console.h" +#include "InspectorAgent.h" #include "InspectorConsoleAgent.h" -#include "InspectorController.h" #include "InspectorFrontend.h" #include "InspectorValues.h" #include "KURL.h" @@ -56,16 +56,16 @@ static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-in static const char* const CPUProfileType = "CPU"; static const char* const HeapProfileType = "HEAP"; -PassOwnPtr InspectorProfilerAgent::create(InspectorController* inspectorController) +PassOwnPtr InspectorProfilerAgent::create(InspectorAgent* inspectorAgent) { - OwnPtr agent = adoptPtr(new InspectorProfilerAgent(inspectorController)); + OwnPtr agent = adoptPtr(new InspectorProfilerAgent(inspectorAgent)); return agent.release(); } -InspectorProfilerAgent::InspectorProfilerAgent(InspectorController* inspectorController) - : m_inspectorController(inspectorController) +InspectorProfilerAgent::InspectorProfilerAgent(InspectorAgent* inspectorAgent) + : m_inspectorAgent(inspectorAgent) , m_frontend(0) - , m_enabled(ScriptProfiler::isProfilerAlwaysEnabled()) + , m_enabled(false) , m_recordingUserInitiatedProfile(false) , m_currentUserInitiatedProfileNumber(-1) , m_nextUserInitiatedProfileNumber(1) @@ -93,7 +93,7 @@ void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr profile = prpProfile; String title = profile->title(); String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), '#', String::number(profile->uid()), "\" finished."); - m_inspectorController->consoleAgent()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); + m_inspectorAgent->consoleAgent()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); } void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL) @@ -101,7 +101,7 @@ void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& tit if (!m_frontend) return; String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0\" started."); - m_inspectorController->consoleAgent()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); + m_inspectorAgent->consoleAgent()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); } PassRefPtr InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile) @@ -220,7 +220,9 @@ void InspectorProfilerAgent::resetState() void InspectorProfilerAgent::resetFrontendProfiles() { - if (m_frontend && m_profiles.begin() == m_profiles.end()) + if (m_frontend + && m_profiles.begin() == m_profiles.end() + && m_snapshots.begin() == m_snapshots.end()) m_frontend->resetProfiles(); } @@ -229,13 +231,13 @@ void InspectorProfilerAgent::startUserInitiatedProfiling() if (m_recordingUserInitiatedProfile) return; if (!enabled()) { - enable(false); + enable(true); ScriptDebugServer::shared().recompileAllJSFunctions(); } m_recordingUserInitiatedProfile = true; String title = getCurrentUserInitiatedProfileName(true); #if USE(JSC) - JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); + JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorAgent->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); #else ScriptState* scriptState = 0; #endif @@ -251,7 +253,7 @@ void InspectorProfilerAgent::stopUserInitiatedProfiling(bool ignoreProfile) m_recordingUserInitiatedProfile = false; String title = getCurrentUserInitiatedProfileName(); #if USE(JSC) - JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); + JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorAgent->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); #else // Use null script state to avoid filtering by context security token. // All functions from all iframes should be visible from Inspector UI. @@ -267,12 +269,37 @@ void InspectorProfilerAgent::stopUserInitiatedProfiling(bool ignoreProfile) toggleRecordButton(false); } -void InspectorProfilerAgent::takeHeapSnapshot() +namespace { + +class HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress { +public: + explicit HeapSnapshotProgress(InspectorFrontend* frontend) + : m_frontend(frontend) { } + void Start(int totalWork) + { + m_totalWork = totalWork; + } + void Worked(int workDone) + { + if (m_frontend) + m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork); + } + void Done() { } + bool isCanceled() { return false; } +private: + InspectorFrontend* m_frontend; + int m_totalWork; +}; + +}; + +void InspectorProfilerAgent::takeHeapSnapshot(bool detailed) { String title = makeString(UserInitiatedProfileName, '.', String::number(m_nextUserInitiatedHeapSnapshotNumber)); ++m_nextUserInitiatedHeapSnapshotNumber; - RefPtr snapshot = ScriptProfiler::takeHeapSnapshot(title); + HeapSnapshotProgress progress(m_frontend); + RefPtr snapshot = ScriptProfiler::takeHeapSnapshot(title, detailed ? &progress : 0); if (snapshot) { m_snapshots.add(snapshot->uid(), snapshot); if (m_frontend) diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.h b/Source/WebCore/inspector/InspectorProfilerAgent.h index 436ae51..93637f5 100644 --- a/Source/WebCore/inspector/InspectorProfilerAgent.h +++ b/Source/WebCore/inspector/InspectorProfilerAgent.h @@ -41,7 +41,7 @@ namespace WebCore { class InspectorArray; -class InspectorController; +class InspectorAgent; class InspectorFrontend; class InspectorObject; class ScriptHeapSnapshot; @@ -50,7 +50,7 @@ class ScriptProfile; class InspectorProfilerAgent { WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent); WTF_MAKE_FAST_ALLOCATED; public: - static PassOwnPtr create(InspectorController*); + static PassOwnPtr create(InspectorAgent*); virtual ~InspectorProfilerAgent(); void addProfile(PassRefPtr prpProfile, unsigned lineNumber, const String& sourceURL); @@ -70,18 +70,18 @@ public: void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; } void startUserInitiatedProfiling(); void stopUserInitiatedProfiling(bool ignoreProfile = false); - void takeHeapSnapshot(); + void takeHeapSnapshot(bool detailed); void toggleRecordButton(bool isProfiling); private: typedef HashMap > ProfilesMap; typedef HashMap > HeapSnapshotsMap; - InspectorProfilerAgent(InspectorController*); + InspectorProfilerAgent(InspectorAgent*); PassRefPtr createProfileHeader(const ScriptProfile& profile); PassRefPtr createSnapshotHeader(const ScriptHeapSnapshot& snapshot); - InspectorController* m_inspectorController; + InspectorAgent* m_inspectorAgent; InspectorFrontend* m_frontend; bool m_enabled; bool m_recordingUserInitiatedProfile; diff --git a/Source/WebCore/inspector/InspectorResourceAgent.cpp b/Source/WebCore/inspector/InspectorResourceAgent.cpp index 029c79d..38d9e32 100644 --- a/Source/WebCore/inspector/InspectorResourceAgent.cpp +++ b/Source/WebCore/inspector/InspectorResourceAgent.cpp @@ -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 @@ -67,9 +67,14 @@ namespace WebCore { +namespace ResourceAgentState { +static const char resourceAgentEnabled[] = "resourceAgentEnabled"; +static const char extraRequestHeaders[] = "extraRequestHeaders"; +} + PassRefPtr InspectorResourceAgent::restore(Page* page, InspectorState* state, InspectorFrontend* frontend) { - if (state->getBoolean(InspectorState::resourceAgentEnabled)) + if (state->getBoolean(ResourceAgentState::resourceAgentEnabled)) return create(page, state, frontend); return 0; } @@ -95,7 +100,6 @@ bool InspectorResourceAgent::resourceContent(Frame* frame, const KURL& url, Stri bool InspectorResourceAgent::resourceContentBase64(Frame* frame, const KURL& url, String* result) { - Vector out; String textEncodingName; RefPtr data = InspectorResourceAgent::resourceData(frame, url, &textEncodingName); if (!data) { @@ -103,8 +107,7 @@ bool InspectorResourceAgent::resourceContentBase64(Frame* frame, const KURL& url return false; } - base64Encode(data->buffer(), out); - *result = String(out.data(), out.size()); + *result = base64Encode(data->buffer()); return true; } @@ -121,6 +124,10 @@ PassRefPtr InspectorResourceAgent::resourceData(Frame* frame, cons if (!cachedResource) return 0; + // Zero-sized resources don't have data at all -- so fake the empty buffer, insted of indicating error by returning 0. + if (!cachedResource->encodedSize()) + return SharedBuffer::create(); + if (cachedResource->isPurgeable()) { // If the resource is purgeable then make it unpurgeable to get // get its data. This might fail, in which case we return an @@ -289,7 +296,7 @@ static void populateObjectWithFrameResources(Frame* frame, PassRefPtrsetBoolean(InspectorState::resourceAgentEnabled, false); + m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, false); } void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader) @@ -304,8 +311,28 @@ void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifie m_frontend->identifierForInitialRequest(identifier, url.string(), loaderObject, callStackValue); } +void InspectorResourceAgent::setExtraHeaders(PassRefPtr headers) +{ + m_state->setObject(ResourceAgentState::extraRequestHeaders, headers); +} + + void InspectorResourceAgent::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) { + RefPtr headers = m_state->getObject(ResourceAgentState::extraRequestHeaders); + + if (headers) { + InspectorObject::const_iterator end = headers->end(); + for (InspectorObject::const_iterator it = headers->begin(); it != end; ++it) { + String value; + if (it->second->asString(&value)) + request.setHTTPHeaderField(it->first, value); + } + } + + request.setReportLoadTiming(true); + request.setReportRawHeaders(true); + m_frontend->willSendRequest(identifier, currentTime(), buildObjectForResourceRequest(request), buildObjectForResourceResponse(redirectResponse)); } @@ -318,23 +345,27 @@ void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, Docume { RefPtr resourceResponse = buildObjectForResourceResponse(response); String type = "Other"; - if (loader) { - if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL())) - type = "Image"; - else { - CachedResource* cachedResource = InspectorResourceAgent::cachedResource(loader->frame(), response.url()); - if (cachedResource) - type = cachedResourceTypeString(*cachedResource); - - if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == "Other") - type = "Document"; + long cachedResourceSize = 0; + if (loader) { + CachedResource* cachedResource = InspectorResourceAgent::cachedResource(loader->frame(), response.url()); + if (cachedResource) { + type = cachedResourceTypeString(*cachedResource); + cachedResourceSize = cachedResource->encodedSize(); // Use mime type from cached resource in case the one in response is empty. - if (response.mimeType().isEmpty() && cachedResource) + if (response.mimeType().isEmpty()) resourceResponse->setString("mimeType", cachedResource->response().mimeType()); } + if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL())) + type = "Image"; + else if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == "Other") + type = "Document"; } m_frontend->didReceiveResponse(identifier, currentTime(), type, resourceResponse); + // If we revalidated the resource and got Not modified, send content length following didReceiveResponse + // as there will be no calls to didReceiveContentLength from the network stack. + if (cachedResourceSize && response.httpStatusCode() == 304) + didReceiveContentLength(identifier, cachedResourceSize); } void InspectorResourceAgent::didReceiveContentLength(unsigned long identifier, int lengthReceived) @@ -376,7 +407,7 @@ static PassRefPtr buildObjectForFrame(Frame* frame) name = frame->ownerElement()->getAttribute(HTMLNames::idAttr); frameObject->setString("name", name); } - frameObject->setString("url", frame->loader()->url().string()); + frameObject->setString("url", frame->document()->url().string()); return frameObject; } @@ -472,17 +503,17 @@ void InspectorResourceAgent::cachedResources(RefPtr* object) *object = buildObjectForFrameTree(m_page->mainFrame(), true); } -void InspectorResourceAgent::resourceContent(unsigned long id, const String& url, bool base64Encode, String* content) +void InspectorResourceAgent::resourceContent(unsigned long frameId, const String& url, bool base64Encode, bool* success, String* content) { - for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) { - if (frameId(frame) != id) - continue; - if (base64Encode) - InspectorResourceAgent::resourceContentBase64(frame, KURL(ParsedURLString, url), content); - else - InspectorResourceAgent::resourceContent(frame, KURL(ParsedURLString, url), content); - break; + Frame* frame = frameForId(frameId); + if (!frame) { + *success = false; + return; } + if (base64Encode) + *success = InspectorResourceAgent::resourceContentBase64(frame, KURL(ParsedURLString, url), content); + else + *success = InspectorResourceAgent::resourceContent(frame, KURL(ParsedURLString, url), content); } InspectorResourceAgent::InspectorResourceAgent(Page* page, InspectorState* state, InspectorFrontend* frontend) @@ -490,7 +521,7 @@ InspectorResourceAgent::InspectorResourceAgent(Page* page, InspectorState* state , m_state(state) , m_frontend(frontend) { - m_state->setBoolean(InspectorState::resourceAgentEnabled, true); + m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, true); } } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorResourceAgent.h b/Source/WebCore/inspector/InspectorResourceAgent.h index 6c2df24..fb24b70 100644 --- a/Source/WebCore/inspector/InspectorResourceAgent.h +++ b/Source/WebCore/inspector/InspectorResourceAgent.h @@ -103,7 +103,8 @@ public: // Called from frontend void cachedResources(RefPtr*); - void resourceContent(unsigned long frameID, const String& url, bool base64Encode, String* content); + void resourceContent(unsigned long frameId, const String& url, bool base64Encode, bool* resourceFound, String* content); + void setExtraHeaders(PassRefPtr); private: InspectorResourceAgent(Page* page, InspectorState*, InspectorFrontend* frontend); diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.cpp b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp index 0502437..7938afd 100644 --- a/Source/WebCore/inspector/InspectorRuntimeAgent.cpp +++ b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp @@ -45,18 +45,18 @@ InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptHost* injectedScriptH InspectorRuntimeAgent::~InspectorRuntimeAgent() { } -void InspectorRuntimeAgent::evaluate(const String& expression, const String& objectGroup, RefPtr* result) +void InspectorRuntimeAgent::evaluate(const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result) { InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForMainFrame(); if (!injectedScript.hasNoValue()) - injectedScript.evaluate(expression, objectGroup, result); + injectedScript.evaluate(expression, objectGroup, includeCommandLineAPI, result); } -void InspectorRuntimeAgent::getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result) +void InspectorRuntimeAgent::getCompletions(const String& expression, bool includeCommandLineAPI, RefPtr* result) { InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForMainFrame(); if (!injectedScript.hasNoValue()) - injectedScript.getCompletions(expression, includeInspectorCommandLineAPI, result); + injectedScript.getCompletions(expression, includeCommandLineAPI, result); } void InspectorRuntimeAgent::getProperties(PassRefPtr objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr* result) diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.h b/Source/WebCore/inspector/InspectorRuntimeAgent.h index 3ac2eed..9fb2716 100644 --- a/Source/WebCore/inspector/InspectorRuntimeAgent.h +++ b/Source/WebCore/inspector/InspectorRuntimeAgent.h @@ -57,8 +57,8 @@ public: ~InspectorRuntimeAgent(); // Part of the protocol. - void evaluate(const String& expression, const String& objectGroup, RefPtr* result); - void getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr* result); + void evaluate(const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr* result); + void getCompletions(const String& expression, bool includeCommandLineAPI, RefPtr* result); void getProperties(PassRefPtr objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr* result); void setPropertyValue(PassRefPtr objectId, const String& propertyName, const String& expression, RefPtr* result); void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup); diff --git a/Source/WebCore/inspector/InspectorSettings.cpp b/Source/WebCore/inspector/InspectorSettings.cpp deleted file mode 100644 index 3ebc3ab..0000000 --- a/Source/WebCore/inspector/InspectorSettings.cpp +++ /dev/null @@ -1,95 +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. - */ -#include "config.h" -#include "InspectorSettings.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorClient.h" - -namespace WebCore { - -const char* InspectorSettings::MonitoringXHREnabled = "xhrMonitor"; -const char* InspectorSettings::ProfilerAlwaysEnabled = "profilerEnabled"; -const char* InspectorSettings::DebuggerAlwaysEnabled = "debuggerEnabled"; -const char* InspectorSettings::InspectorStartsAttached = "inspectorStartsAttached"; -const char* InspectorSettings::InspectorAttachedHeight = "inspectorAttachedHeight"; - -InspectorSettings::InspectorSettings(InspectorClient* client) - : m_client(client) -{ - registerBoolean(MonitoringXHREnabled, false); - registerBoolean(ProfilerAlwaysEnabled, false); - registerBoolean(DebuggerAlwaysEnabled, false); - registerBoolean(InspectorStartsAttached, true); - registerLong(InspectorAttachedHeight, 300); -} - -bool InspectorSettings::getBoolean(const String& name) -{ - String value; - m_client->populateSetting(name, &value); - if (value.isEmpty()) - value = m_defaultValues.get(name); - return value == "true"; -} - -void InspectorSettings::setBoolean(const String& name, bool value) -{ - m_client->storeSetting(name, value ? "true" : "false"); -} - -long InspectorSettings::getLong(const String& name) -{ - String value; - m_client->populateSetting(name, &value); - if (value.isEmpty()) - value = m_defaultValues.get(name); - return value.toInt(); -} - -void InspectorSettings::setLong(const String& name, long value) -{ - m_client->storeSetting(name, String::number(value)); -} - -void InspectorSettings::registerBoolean(const String& name, bool defaultValue) -{ - m_defaultValues.set(name, defaultValue ? "true" : "false"); -} - -void InspectorSettings::registerLong(const String& name, long defaultValue) -{ - m_defaultValues.set(name, String::number(defaultValue)); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/InspectorSettings.h b/Source/WebCore/inspector/InspectorSettings.h deleted file mode 100644 index 717d11f..0000000 --- a/Source/WebCore/inspector/InspectorSettings.h +++ /dev/null @@ -1,73 +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. - */ - -#ifndef InspectorSettings_h -#define InspectorSettings_h - -#if ENABLE(INSPECTOR) - -#include "PlatformString.h" - -#include -#include - -namespace WebCore { - -class InspectorClient; - -class InspectorSettings { -public: - static const char* MonitoringXHREnabled; - static const char* ProfilerAlwaysEnabled; - static const char* DebuggerAlwaysEnabled; - static const char* InspectorStartsAttached; - static const char* InspectorAttachedHeight; - - InspectorSettings(InspectorClient* client); - - bool getBoolean(const String& name); - void setBoolean(const String& name, bool value); - - long getLong(const String& name); - void setLong(const String& name, long value); - -private: - void registerBoolean(const String& name, bool defaultValue); - void registerLong(const String& name, long defaultValue); - - typedef HashMap Dictionary; - Dictionary m_defaultValues; - InspectorClient* m_client; -}; - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) -#endif // !defined(InspectorSettings_h) diff --git a/Source/WebCore/inspector/InspectorState.cpp b/Source/WebCore/inspector/InspectorState.cpp index dba9e4d..290ffc2 100644 --- a/Source/WebCore/inspector/InspectorState.cpp +++ b/Source/WebCore/inspector/InspectorState.cpp @@ -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 @@ -37,121 +37,75 @@ namespace WebCore { InspectorState::InspectorState(InspectorClient* client) : m_client(client) + , m_properties(InspectorObject::create()) + , m_isOnMute(false) { - // Pure reload state - registerBoolean(userInitiatedProfiling, false); - registerBoolean(timelineProfilerEnabled, false); - registerBoolean(searchingForNode, false); - registerObject(browserBreakpoints); - registerBoolean(consoleMessagesEnabled, false); - registerBoolean(monitoringXHR, false); - registerBoolean(resourceAgentEnabled, false); } -void InspectorState::restoreFromInspectorCookie(const String& json) +InspectorState::InspectorState(InspectorClient* client, const String& json) + : m_client(client) + , m_properties(InspectorObject::create()) + , m_isOnMute(false) { RefPtr jsonValue = InspectorValue::parseJSON(json); - if (!jsonValue) - return; - - RefPtr jsonObject = jsonValue->asObject(); - if (!jsonObject) - return; + if (jsonValue) + m_properties = jsonValue->asObject(); + if (!m_properties) + m_properties = InspectorObject::create(); +} - for (InspectorObject::iterator i = jsonObject->begin(); i != jsonObject->end(); ++i) { - InspectorPropertyId id = (InspectorPropertyId)i->first.toInt(); - ASSERT(id > 0 && id < lastPropertyId); - PropertyMap::iterator j = m_properties.find(id); - ASSERT(j != m_properties.end()); - ASSERT(j->second.m_value->type() == i->second->type()); - j->second.m_value = i->second; - } +void InspectorState::mute() +{ + m_isOnMute = true; } void InspectorState::updateCookie() { - RefPtr cookieObject = InspectorObject::create(); - for (PropertyMap::iterator i = m_properties.begin(); i != m_properties.end(); ++i) - cookieObject->setValue(String::number(i->first), i->second.m_value); - m_client->updateInspectorStateCookie(cookieObject->toJSONString()); + if (!m_isOnMute) + m_client->updateInspectorStateCookie(m_properties->toJSONString()); } -void InspectorState::setValue(InspectorPropertyId id, PassRefPtr value) +void InspectorState::setValue(const String& propertyName, PassRefPtr value) { - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); - i->second.m_value = value; + m_properties->setValue(propertyName, value); updateCookie(); } -bool InspectorState::getBoolean(InspectorPropertyId id) +bool InspectorState::getBoolean(const String& propertyName) { - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); + InspectorObject::iterator it = m_properties->find(propertyName); bool value = false; - i->second.m_value->asBoolean(&value); + if (it != m_properties->end()) + it->second->asBoolean(&value); return value; } -String InspectorState::getString(InspectorPropertyId id) +String InspectorState::getString(const String& propertyName) { - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); + InspectorObject::iterator it = m_properties->find(propertyName); String value; - i->second.m_value->asString(&value); + if (it != m_properties->end()) + it->second->asString(&value); return value; } -long InspectorState::getLong(InspectorPropertyId id) +long InspectorState::getLong(const String& propertyName) { - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); + InspectorObject::iterator it = m_properties->find(propertyName); long value = 0; - i->second.m_value->asNumber(&value); + if (it != m_properties->end()) + it->second->asNumber(&value); return value; } -PassRefPtr InspectorState::getObject(InspectorPropertyId id) +PassRefPtr InspectorState::getObject(const String& propertyName) { - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); - return i->second.m_value->asObject(); -} - -void InspectorState::setObject(InspectorPropertyId id, PassRefPtr value) -{ - PropertyMap::iterator i = m_properties.find(id); - ASSERT(i != m_properties.end()); - Property& property = i->second; - property.m_value = value; - updateCookie(); -} - -void InspectorState::registerBoolean(InspectorPropertyId propertyId, bool value) -{ - m_properties.set(propertyId, Property::create(InspectorBasicValue::create(value))); -} - -void InspectorState::registerString(InspectorPropertyId propertyId, const String& value) -{ - m_properties.set(propertyId, Property::create(InspectorString::create(value))); -} - -void InspectorState::registerLong(InspectorPropertyId propertyId, long value) -{ - m_properties.set(propertyId, Property::create(InspectorBasicValue::create((double)value))); -} - -void InspectorState::registerObject(InspectorPropertyId propertyId) -{ - m_properties.set(propertyId, Property::create(InspectorObject::create())); -} - -InspectorState::Property InspectorState::Property::create(PassRefPtr value) -{ - Property property; - property.m_value = value; - return property; + InspectorObject::iterator it = m_properties->find(propertyName); + if (it == m_properties->end()) { + m_properties->setObject(propertyName, InspectorObject::create()); + it = m_properties->find(propertyName); + } + return it->second->asObject(); } } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorState.h b/Source/WebCore/inspector/InspectorState.h index 6e12673..3a9c3ed 100644 --- a/Source/WebCore/inspector/InspectorState.h +++ b/Source/WebCore/inspector/InspectorState.h @@ -1,29 +1,31 @@ /* - * 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 met: + * modification, are permitted provided that the following conditions are + * met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * * 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 GOOGLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 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 InspectorState_h @@ -43,48 +45,29 @@ class InspectorClient; class InspectorState { public: - enum InspectorPropertyId { - monitoringXHR = 1, - timelineProfilerEnabled, - searchingForNode, - consoleMessagesEnabled, - userInitiatedProfiling, - browserBreakpoints, - resourceAgentEnabled, - lastPropertyId - }; + InspectorState(InspectorClient*); + InspectorState(InspectorClient*, const String& jsonString); + virtual ~InspectorState() {} - InspectorState(InspectorClient* client); + void mute(); - void restoreFromInspectorCookie(const String& jsonString); + bool getBoolean(const String& propertyName); + String getString(const String& propertyName); + long getLong(const String& propertyName); + PassRefPtr getObject(const String& propertyName); - bool getBoolean(InspectorPropertyId); - String getString(InspectorPropertyId); - long getLong(InspectorPropertyId); - PassRefPtr getObject(InspectorPropertyId); - - void setBoolean(InspectorPropertyId propertyId, bool value) { setValue(propertyId, InspectorBasicValue::create(value)); } - void setString(InspectorPropertyId propertyId, const String& value) { setValue(propertyId, InspectorString::create(value)); } - void setLong(InspectorPropertyId propertyId, long value) { setValue(propertyId, InspectorBasicValue::create((double)value)); } - void setObject(InspectorPropertyId, PassRefPtr value); + void setBoolean(const String& propertyName, bool value) { setValue(propertyName, InspectorBasicValue::create(value)); } + void setString(const String& propertyName, const String& value) { setValue(propertyName, InspectorString::create(value)); } + void setLong(const String& propertyName, long value) { setValue(propertyName, InspectorBasicValue::create((double)value)); } + void setObject(const String& propertyName, PassRefPtr value) { setValue(propertyName, value); } private: void updateCookie(); - void setValue(InspectorPropertyId, PassRefPtr); - - struct Property { - static Property create(PassRefPtr value); - RefPtr m_value; - }; - typedef HashMap PropertyMap; - PropertyMap m_properties; - - void registerBoolean(InspectorPropertyId, bool value); - void registerString(InspectorPropertyId, const String& value); - void registerLong(InspectorPropertyId, long value); - void registerObject(InspectorPropertyId); + void setValue(const String& propertyName, PassRefPtr); InspectorClient* m_client; + RefPtr m_properties; + bool m_isOnMute; }; } // namespace WebCore diff --git a/Source/WebCore/inspector/InspectorTimelineAgent.cpp b/Source/WebCore/inspector/InspectorTimelineAgent.cpp index 081a5f0..dd0a119 100644 --- a/Source/WebCore/inspector/InspectorTimelineAgent.cpp +++ b/Source/WebCore/inspector/InspectorTimelineAgent.cpp @@ -35,6 +35,7 @@ #include "Event.h" #include "InspectorFrontend.h" +#include "InspectorState.h" #include "IntRect.h" #include "ResourceRequest.h" #include "ResourceResponse.h" @@ -44,14 +45,17 @@ namespace WebCore { +namespace TimelineAgentState { +static const char timelineAgentEnabled[] = "timelineAgentEnabled"; +} + int InspectorTimelineAgent::s_id = 0; -InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend) - : m_frontend(frontend) - , m_id(++s_id) +PassOwnPtr InspectorTimelineAgent::restore(InspectorState* state, InspectorFrontend* frontend) { - ScriptGCEvent::addEventListener(this); - ASSERT(m_frontend); + if (state->getBoolean(TimelineAgentState::timelineAgentEnabled)) + return create(state, frontend); + return 0; } void InspectorTimelineAgent::pushGCEventRecords() @@ -76,7 +80,9 @@ void InspectorTimelineAgent::didGC(double startTime, double endTime, size_t coll InspectorTimelineAgent::~InspectorTimelineAgent() { + m_frontend->timelineProfilerWasStopped(); ScriptGCEvent::removeEventListener(this); + m_state->setBoolean(TimelineAgentState::timelineAgentEnabled, false); } void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine) @@ -272,15 +278,15 @@ void InspectorTimelineAgent::didMarkLoadEvent() addRecordToTimeline(record.release(), MarkLoadEventType); } -void InspectorTimelineAgent::reset() +void InspectorTimelineAgent::didCommitLoad() { m_recordStack.clear(); } -void InspectorTimelineAgent::resetFrontendProxyObject(InspectorFrontend* frontend) +void InspectorTimelineAgent::setFrontend(InspectorFrontend* frontend) { ASSERT(frontend); - reset(); + m_recordStack.clear(); m_frontend = frontend; } @@ -301,7 +307,8 @@ void InspectorTimelineAgent::setHeapSizeStatistic(InspectorObject* record) { size_t usedHeapSize = 0; size_t totalHeapSize = 0; - ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize); + size_t heapSizeLimit = 0; + ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize, heapSizeLimit); record->setNumber("usedHeapSize", usedHeapSize); record->setNumber("totalHeapSize", totalHeapSize); } @@ -322,6 +329,16 @@ void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type) } } +InspectorTimelineAgent::InspectorTimelineAgent(InspectorState* state, InspectorFrontend* frontend) + : m_state(state) + , m_frontend(frontend) + , m_id(++s_id) +{ + ScriptGCEvent::addEventListener(this); + m_frontend->timelineProfilerWasStarted(); + m_state->setBoolean(TimelineAgentState::timelineAgentEnabled, true); +} + void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr data, TimelineRecordType type) { pushGCEventRecords(); diff --git a/Source/WebCore/inspector/InspectorTimelineAgent.h b/Source/WebCore/inspector/InspectorTimelineAgent.h index cae5aad..36c2df2 100644 --- a/Source/WebCore/inspector/InspectorTimelineAgent.h +++ b/Source/WebCore/inspector/InspectorTimelineAgent.h @@ -36,11 +36,13 @@ #include "InspectorValues.h" #include "ScriptGCEvent.h" #include "ScriptGCEventListener.h" +#include #include namespace WebCore { class Event; class InspectorFrontend; +class InspectorState; class IntRect; class ResourceRequest; class ResourceResponse; @@ -71,15 +73,21 @@ enum TimelineRecordType { }; class InspectorTimelineAgent : ScriptGCEventListener { - WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); public: - InspectorTimelineAgent(InspectorFrontend* frontend); + static PassOwnPtr create(InspectorState* state, InspectorFrontend* frontend) + { + return adoptPtr(new InspectorTimelineAgent(state, frontend)); + } + + static PassOwnPtr restore(InspectorState*, InspectorFrontend*); + ~InspectorTimelineAgent(); int id() const { return m_id; } - void reset(); - void resetFrontendProxyObject(InspectorFrontend*); + void didCommitLoad(); + void setFrontend(InspectorFrontend*); // Methods called from WebCore. void willCallFunction(const String& scriptName, int scriptLine); @@ -141,6 +149,8 @@ private: TimelineRecordType type; }; + InspectorTimelineAgent(InspectorState*, InspectorFrontend*); + void pushCurrentRecord(PassRefPtr, TimelineRecordType); void setHeapSizeStatistic(InspectorObject* record); @@ -150,6 +160,7 @@ private: void pushGCEventRecords(); + InspectorState* m_state; InspectorFrontend* m_frontend; Vector m_recordStack; diff --git a/Source/WebCore/inspector/InspectorValues.cpp b/Source/WebCore/inspector/InspectorValues.cpp index d1b8093..09d1258 100644 --- a/Source/WebCore/inspector/InspectorValues.cpp +++ b/Source/WebCore/inspector/InspectorValues.cpp @@ -491,6 +491,11 @@ bool InspectorValue::asNumber(long*) const return false; } +bool InspectorValue::asNumber(int*) const +{ + return false; +} + bool InspectorValue::asNumber(unsigned long*) const { return false; @@ -581,6 +586,14 @@ bool InspectorBasicValue::asNumber(long* output) const return true; } +bool InspectorBasicValue::asNumber(int* output) const +{ + if (type() != TypeNumber) + return false; + *output = static_cast(m_doubleValue); + return true; +} + bool InspectorBasicValue::asNumber(unsigned long* output) const { if (type() != TypeNumber) @@ -647,22 +660,6 @@ bool InspectorObject::getBoolean(const String& name, bool* output) const return value->asBoolean(output); } -bool InspectorObject::getNumber(const String& name, long* output) const -{ - RefPtr value = get(name); - if (!value) - return false; - return value->asNumber(output); -} - -bool InspectorObject::getNumber(const String& name, double* output) const -{ - RefPtr value = get(name); - if (!value) - return false; - return value->asNumber(output); -} - bool InspectorObject::getString(const String& name, String* output) const { RefPtr value = get(name); @@ -695,6 +692,17 @@ PassRefPtr InspectorObject::get(const String& name) const return it->second; } +void InspectorObject::remove(const String& name) +{ + m_data.remove(name); + for (size_t i = 0; i < m_order.size(); ++i) { + if (m_order[i] == name) { + m_order.remove(i); + break; + } + } +} + void InspectorObject::writeJSON(Vector* output) const { output->append('{'); diff --git a/Source/WebCore/inspector/InspectorValues.h b/Source/WebCore/inspector/InspectorValues.h index 843f369..835c982 100644 --- a/Source/WebCore/inspector/InspectorValues.h +++ b/Source/WebCore/inspector/InspectorValues.h @@ -72,6 +72,7 @@ public: virtual bool asBoolean(bool* output) const; virtual bool asNumber(double* output) const; virtual bool asNumber(long* output) const; + virtual bool asNumber(int* output) const; virtual bool asNumber(unsigned long* output) const; virtual bool asNumber(unsigned int* output) const; virtual bool asString(String* output) const; @@ -114,6 +115,7 @@ public: virtual bool asBoolean(bool* output) const; virtual bool asNumber(double* output) const; virtual bool asNumber(long* output) const; + virtual bool asNumber(int* output) const; virtual bool asNumber(unsigned long* output) const; virtual bool asNumber(unsigned int* output) const; @@ -178,15 +180,23 @@ public: void setObject(const String& name, PassRefPtr); void setArray(const String& name, PassRefPtr); + iterator find(const String& name); const_iterator find(const String& name) const; bool getBoolean(const String& name, bool* output) const; - bool getNumber(const String& name, long* output) const; - bool getNumber(const String& name, double* output) const; + template bool getNumber(const String& name, T* output) const + { + RefPtr value = get(name); + if (!value) + return false; + return value->asNumber(output); + } bool getString(const String& name, String* output) const; PassRefPtr getObject(const String& name) const; PassRefPtr getArray(const String& name) const; PassRefPtr get(const String& name) const; + void remove(const String& name); + virtual void writeJSON(Vector* output) const; iterator begin() { return m_data.begin(); } @@ -228,6 +238,11 @@ private: Vector > m_data; }; +inline InspectorObject::iterator InspectorObject::find(const String& name) +{ + return m_data.find(name); +} + inline InspectorObject::const_iterator InspectorObject::find(const String& name) const { return m_data.find(name); diff --git a/Source/WebCore/inspector/ScriptBreakpoint.cpp b/Source/WebCore/inspector/ScriptBreakpoint.cpp deleted file mode 100644 index b7205a7..0000000 --- a/Source/WebCore/inspector/ScriptBreakpoint.cpp +++ /dev/null @@ -1,74 +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: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScriptBreakpoint.h" - -#if ENABLE(INSPECTOR) - -#include "InspectorValues.h" - -namespace WebCore { - -void ScriptBreakpoint::sourceBreakpointsFromInspectorObject(PassRefPtr breakpoints, SourceBreakpoints* sourceBreakpoints) -{ - for (InspectorObject::iterator it = breakpoints->begin(); it != breakpoints->end(); ++it) { - bool ok; - int lineNumber = it->first.toInt(&ok); - if (!ok) - continue; - RefPtr breakpoint = it->second->asObject(); - if (!breakpoint) - continue; - bool enabled; - RefPtr enabledValue = breakpoint->get("enabled"); - if (!enabledValue || !enabledValue->asBoolean(&enabled)) - continue; - String condition; - RefPtr conditionValue = breakpoint->get("condition"); - if (!conditionValue || !conditionValue->asString(&condition)) - continue; - sourceBreakpoints->set(lineNumber, ScriptBreakpoint(enabled, condition)); - } -} - -PassRefPtr ScriptBreakpoint::inspectorObjectFromSourceBreakpoints(const SourceBreakpoints& sourceBreakpoints) -{ - RefPtr breakpoints = InspectorObject::create(); - for (SourceBreakpoints::const_iterator it = sourceBreakpoints.begin(); it != sourceBreakpoints.end(); ++it) { - RefPtr breakpoint = InspectorObject::create(); - breakpoint->setBoolean("enabled", it->second.enabled); - breakpoint->setString("condition", it->second.condition); - breakpoints->setObject(String::number(it->first), breakpoint); - } - return breakpoints.release(); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebCore/inspector/ScriptBreakpoint.h b/Source/WebCore/inspector/ScriptBreakpoint.h index d8ac762..4917aef 100644 --- a/Source/WebCore/inspector/ScriptBreakpoint.h +++ b/Source/WebCore/inspector/ScriptBreakpoint.h @@ -31,33 +31,26 @@ #define ScriptBreakpoint_h #include "PlatformString.h" -#include namespace WebCore { -class InspectorObject; -struct ScriptBreakpoint; - -typedef HashMap SourceBreakpoints; - struct ScriptBreakpoint { - ScriptBreakpoint(bool enabled, const String& condition) - : enabled(enabled) - , condition(condition) + ScriptBreakpoint() { } - ScriptBreakpoint() + ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool enabled) + : lineNumber(lineNumber) + , columnNumber(columnNumber) + , condition(condition) + , enabled(enabled) { } - bool enabled; + int lineNumber; + int columnNumber; String condition; - -#if ENABLE(INSPECTOR) - static void sourceBreakpointsFromInspectorObject(PassRefPtr, SourceBreakpoints*); - static PassRefPtr inspectorObjectFromSourceBreakpoints(const SourceBreakpoints&); -#endif + bool enabled; }; } // namespace WebCore diff --git a/Source/WebCore/inspector/front-end/ApplicationCacheItemsView.js b/Source/WebCore/inspector/front-end/ApplicationCacheItemsView.js index e7aa188..b345749 100644 --- a/Source/WebCore/inspector/front-end/ApplicationCacheItemsView.js +++ b/Source/WebCore/inspector/front-end/ApplicationCacheItemsView.js @@ -136,7 +136,7 @@ WebInspector.ApplicationCacheItemsView.prototype = { _update: function() { - WebInspector.ApplicationCache.getApplicationCachesAsync(this._updateCallback.bind(this)); + WebInspector.ApplicationCacheDispatcher.getApplicationCachesAsync(this._updateCallback.bind(this)); }, _updateCallback: function(applicationCaches) diff --git a/Source/WebCore/inspector/front-end/AuditRules.js b/Source/WebCore/inspector/front-end/AuditRules.js index c2bbcbb..c122ba4 100644 --- a/Source/WebCore/inspector/front-end/AuditRules.js +++ b/Source/WebCore/inspector/front-end/AuditRules.js @@ -326,7 +326,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = { if (!unusedRules.length) continue; - var resource = WebInspector.resourceTreeModel.resourceForURL(styleSheet.sourceURL); + var resource = WebInspector.resourceForURL(styleSheet.sourceURL); var isInlineBlock = resource && resource.type == WebInspector.Resource.Type.Document; var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal); var pctUnused = Math.round(100 * unusedStylesheetSize / stylesheetSize); @@ -383,7 +383,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = { WebInspector.CSSStyleSheet.createForId(styleSheetIds[i], styleSheetCallback.bind(null, styleSheets, i == styleSheetIds.length - 1 ? evalCallback : null)); } - InspectorBackend.getAllStyles2(allStylesCallback); + InspectorBackend.getAllStyles(allStylesCallback); } } diff --git a/Source/WebCore/inspector/front-end/AuditsPanel.js b/Source/WebCore/inspector/front-end/AuditsPanel.js index f3cbfa7..47c0b30 100644 --- a/Source/WebCore/inspector/front-end/AuditsPanel.js +++ b/Source/WebCore/inspector/front-end/AuditsPanel.js @@ -192,7 +192,7 @@ WebInspector.AuditsPanel.prototype = { _reloadResources: function(callback) { this._pageReloadCallback = callback; - InspectorBackend.reloadPage(); + InspectorBackend.reloadPage(false); }, _didMainResourceLoad: function() diff --git a/Source/WebCore/inspector/front-end/Breakpoint.js b/Source/WebCore/inspector/front-end/Breakpoint.js index aa600a7..ebc6029 100644 --- a/Source/WebCore/inspector/front-end/Breakpoint.js +++ b/Source/WebCore/inspector/front-end/Breakpoint.js @@ -29,47 +29,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.Breakpoint = function(debuggerModel, breakpointId, sourceID, url, line, enabled, condition) +WebInspector.Breakpoint = function(id, url, sourceID, lineNumber, columnNumber, condition, enabled) { - this.id = breakpointId; + this.id = id; this.url = url; - this.line = line; this.sourceID = sourceID; - this._enabled = enabled; - this._condition = condition || ""; - this._debuggerModel = debuggerModel; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + this.condition = condition; + this.enabled = enabled; + this.locations = []; } WebInspector.Breakpoint.prototype = { - get enabled() + addLocation: function(sourceID, lineNumber, columnNumber) { - return this._enabled; - }, - - set enabled(enabled) - { - if (this._enabled === enabled) - return; - this.remove(); - WebInspector.debuggerModel.setBreakpoint(this.sourceID, this.line, enabled, this.condition); - }, - - get condition() - { - return this._condition; - }, - - get data() - { - return { id: this.id, url: this.url, sourceID: this.sourceID, lineNumber: this.line, condition: this.condition }; - }, - - remove: function() - { - this._debuggerModel.removeBreakpoint(this.id); - this.removeAllListeners(); - delete this._debuggerModel; + this.locations.push({ sourceID: sourceID, lineNumber: lineNumber, columnNumber: columnNumber }); } } - -WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/Source/WebCore/inspector/front-end/BreakpointManager.js b/Source/WebCore/inspector/front-end/BreakpointManager.js index d943d5b..94345d5 100644 --- a/Source/WebCore/inspector/front-end/BreakpointManager.js +++ b/Source/WebCore/inspector/front-end/BreakpointManager.js @@ -34,22 +34,17 @@ WebInspector.BreakpointManager = function() var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints"); for (var projectId in breakpoints) this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]); - InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints); this._breakpoints = {}; this._domBreakpointsRestored = false; - this._scriptBreakpoints = {}; WebInspector.settings.addEventListener(WebInspector.Settings.Events.ProjectChanged, this._projectChanged, this); - WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._scriptBreakpointAdded, this); - WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._scriptBreakpointRemoved, 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", - JS: "JS", EventListener: "EventListener", XHR: "XHR" } @@ -104,38 +99,6 @@ WebInspector.BreakpointManager.prototype = { this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, breakpoint.view); }, - _createJavaScriptBreakpoint: function(url, lineNumber, condition, enabled, restored) - { - var breakpointId = this._createJavaScriptBreakpointId(url, lineNumber); - if (breakpointId in this._breakpoints) - return; - - var breakpoint = new WebInspector.JavaScriptBreakpoint(url, lineNumber, condition); - this._setBreakpoint(breakpointId, breakpoint, enabled, restored); - }, - - _scriptBreakpointAdded: function(event) - { - var scriptBreakpoint = event.data; - - if (!scriptBreakpoint.url) - return; - - if (!scriptBreakpoint.restored) - this._createJavaScriptBreakpoint(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber, scriptBreakpoint.condition, scriptBreakpoint.enabled, false); - var breakpointId = this._createJavaScriptBreakpointId(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber); - this._scriptBreakpoints[scriptBreakpoint.id] = breakpointId; - }, - - _scriptBreakpointRemoved: function(event) - { - var scriptBreakpointId = event.data; - var breakpointId = this._scriptBreakpoints[scriptBreakpointId]; - delete this._scriptBreakpoints[scriptBreakpointId]; - if (breakpointId in this._breakpoints) - this._removeBreakpoint(breakpointId); - }, - createXHRBreakpoint: function(url) { this._createXHRBreakpoint(url, true, false); @@ -232,7 +195,6 @@ WebInspector.BreakpointManager.prototype = { { this._breakpoints = {}; this._domBreakpointsRestored = false; - this._scriptBreakpoints = {}; this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.ProjectChanged); var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; @@ -240,11 +202,14 @@ WebInspector.BreakpointManager.prototype = { var breakpoint = breakpoints[i]; if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener) this._createEventListenerBreakpoint(breakpoint.condition.eventName, breakpoint.enabled, true); - else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) - this._createJavaScriptBreakpoint(breakpoint.condition.url, breakpoint.condition.lineNumber, breakpoint.condition.condition, breakpoint.enabled, true); else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) this._createXHRBreakpoint(breakpoint.condition.url, breakpoint.enabled, true); } + + if (!this._breakpointsPushedToFrontend) { + InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints); + this._breakpointsPushedToFrontend = true; + } }, restoreDOMBreakpoints: function() @@ -324,15 +289,12 @@ WebInspector.BreakpointManager.prototype = { if (typeof condition.eventName !== "string") continue; id += condition.eventName; - } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) { - if (typeof condition.url !== "string" || typeof condition.lineNumber !== "number" || typeof condition.condition !== "string") - continue; - id += condition.url + ":" + condition.lineNumber; } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) { if (typeof condition.url !== "string") continue; id += condition.url; - } + } else + continue; if (id in breakpointsSet) continue; breakpointsSet[id] = true; @@ -346,11 +308,6 @@ WebInspector.BreakpointManager.prototype = { return "dom:" + nodeId + ":" + type; }, - _createJavaScriptBreakpointId: function(url, lineNumber) - { - return "js:" + url + ":" + lineNumber; - }, - _createEventListenerBreakpointId: function(eventName) { return "eventListner:" + eventName; @@ -389,29 +346,6 @@ WebInspector.DOMBreakpoint.prototype = { } } -WebInspector.JavaScriptBreakpoint = function(url, lineNumber, condition) -{ - this._url = url; - this._lineNumber = lineNumber; - this._condition = condition; -} - -WebInspector.JavaScriptBreakpoint.prototype = { - _enable: function() - { - }, - - _disable: function() - { - }, - - _serializeToJSON: function() - { - var type = WebInspector.BreakpointManager.BreakpointTypes.JS; - return { type: type, condition: { url: this._url, lineNumber: this._lineNumber, condition: this._condition } }; - } -} - WebInspector.EventListenerBreakpoint = function(eventName) { this._eventName = eventName; diff --git a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js index b237ca2..0a47bf8 100644 --- a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -40,6 +40,8 @@ WebInspector.JavaScriptBreakpointsSidebarPane = function(title) WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this); @@ -50,7 +52,9 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { { var breakpoint = event.data; var breakpointId = breakpoint.id; - var data = breakpoint.data; + + if (breakpoint.url && !WebInspector.debuggerModel.scriptsForURL(breakpoint.url).length) + return; var element = document.createElement("li"); @@ -64,7 +68,7 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { var label = document.createElement("span"); element.appendChild(label); - element._data = data; + element._data = breakpoint; var currentElement = this.listElement.firstChild; while (currentElement) { if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0) @@ -75,10 +79,9 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointId), true); - this._setupBreakpointElement(data, element); + this._setupBreakpointElement(breakpoint, element); var breakpointItem = {}; - breakpointItem.data = data; breakpointItem.element = element; breakpointItem.checkbox = checkbox; this._items[breakpointId] = breakpointItem; @@ -97,6 +100,23 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { } }, + _breakpointResolved: function(event) + { + var breakpoint = event.data; + this._breakpointRemoved({ data: breakpoint.id }); + this._breakpointAdded({ data: breakpoint }); + }, + + _parsedScriptSource: function(event) + { + var url = event.data.sourceURL; + var breakpoints = WebInspector.debuggerModel.breakpoints; + for (var id in breakpoints) { + if (!(id in this._items)) + this._breakpointAdded({ data: breakpoints[id] }); + } + }, + _breakpointEnableChanged: function(enabled, event) { var breakpointId = event.data; @@ -107,7 +127,8 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { _breakpointItemCheckboxClicked: function(breakpointId, event) { - this._setBreakpointEnabled(breakpointId, event.target.checked); + var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId); + WebInspector.debuggerModel.updateBreakpoint(breakpointId, breakpoint.condition, event.target.checked); // Breakpoint element may have it's own click handler. event.stopPropagation(); @@ -186,23 +207,32 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { _setupBreakpointElement: function(data, element) { + var sourceID; + var lineNumber = data.lineNumber; + if (data.locations.length) { + sourceID = data.locations[0].sourceID; + lineNumber = data.locations[0].lineNumber; + } + var displayName = data.url ? WebInspector.displayNameForURL(data.url) : WebInspector.UIString("(program)"); - var labelElement = document.createTextNode(displayName + ":" + data.lineNumber); + var labelElement = document.createTextNode(displayName + ":" + (lineNumber + 1)); element.appendChild(labelElement); var sourceTextElement = document.createElement("div"); sourceTextElement.className = "source-text monospace"; element.appendChild(sourceTextElement); - function didGetSourceLine(text) - { - sourceTextElement.textContent = text; + if (sourceID) { + function didGetSourceLine(text) + { + sourceTextElement.textContent = text; + } + var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); + script.sourceLine(lineNumber, didGetSourceLine.bind(this)); } - var script = WebInspector.debuggerModel.scriptForSourceID(data.sourceID); - script.sourceLine(data.lineNumber, didGetSourceLine.bind(this)); element.addStyleClass("cursor-pointer"); - var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, data.lineNumber); + var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, lineNumber + 1); element.addEventListener("click", clickHandler, false); }, @@ -214,13 +244,6 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = { return breakpoint.id; }, - _setBreakpointEnabled: function(breakpointId, enabled) - { - var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId); - WebInspector.debuggerModel.removeBreakpoint(breakpointId); - WebInspector.debuggerModel.setBreakpoint(breakpoint.sourceID, breakpoint.line, enabled, breakpoint.condition); - }, - _removeBreakpoint: function(breakpointId) { WebInspector.debuggerModel.removeBreakpoint(breakpointId); diff --git a/Source/WebCore/inspector/front-end/CSSCompletions.js b/Source/WebCore/inspector/front-end/CSSCompletions.js index f60c297..ba3aca2 100644 --- a/Source/WebCore/inspector/front-end/CSSCompletions.js +++ b/Source/WebCore/inspector/front-end/CSSCompletions.js @@ -30,10 +30,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.CSSCompletions = function(values) +WebInspector.CSSCompletions = function(values, acceptEmptyPrefix) { this._values = values.slice(); this._values.sort(); + this._acceptEmptyPrefix = acceptEmptyPrefix; } WebInspector.CSSCompletions.prototype = { @@ -57,10 +58,10 @@ WebInspector.CSSCompletions.prototype = { _firstIndexOfPrefix: function(prefix) { - if (!prefix) - return -1; if (!this._values.length) return -1; + if (!prefix) + return this._acceptEmptyPrefix ? 0 : -1; var maxIndex = this._values.length - 1; var minIndex = 0; diff --git a/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js index ac62aff..de2072a 100755 --- a/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js +++ b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js @@ -38,7 +38,7 @@ WebInspector.CSSKeywordCompletions = { acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors); if (propertyName in WebInspector.StylesSidebarPane.InheritedProperties) acceptedKeywords.push("inherit"); - return new WebInspector.CSSCompletions(acceptedKeywords); + return new WebInspector.CSSCompletions(acceptedKeywords, true); } }; diff --git a/Source/WebCore/inspector/front-end/CSSStyleModel.js b/Source/WebCore/inspector/front-end/CSSStyleModel.js index 4f20660..69bd7a9 100644 --- a/Source/WebCore/inspector/front-end/CSSStyleModel.js +++ b/Source/WebCore/inspector/front-end/CSSStyleModel.js @@ -83,7 +83,7 @@ WebInspector.CSSStyleModel.prototype = { userCallback(result); } - InspectorBackend.getStylesForNode2(nodeId, callback.bind(null, userCallback)); + InspectorBackend.getStylesForNode(nodeId, callback.bind(null, userCallback)); }, getComputedStyleAsync: function(nodeId, userCallback) @@ -96,7 +96,7 @@ WebInspector.CSSStyleModel.prototype = { userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload)); } - InspectorBackend.getComputedStyleForNode2(nodeId, callback.bind(null, userCallback)); + InspectorBackend.getComputedStyleForNode(nodeId, callback.bind(null, userCallback)); }, getInlineStyleAsync: function(nodeId, userCallback) @@ -109,7 +109,7 @@ WebInspector.CSSStyleModel.prototype = { userCallback(WebInspector.CSSStyleDeclaration.parsePayload(stylePayload)); } - InspectorBackend.getInlineStyleForNode2(nodeId, callback.bind(null, userCallback)); + InspectorBackend.getInlineStyleForNode(nodeId, callback.bind(null, userCallback)); }, setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback) @@ -130,7 +130,7 @@ WebInspector.CSSStyleModel.prototype = { InspectorBackend.querySelectorAll(nodeId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload)); } - InspectorBackend.setRuleSelector2(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback)); + InspectorBackend.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback)); }, addRule: function(nodeId, selector, successCallback, failureCallback) @@ -152,7 +152,7 @@ WebInspector.CSSStyleModel.prototype = { InspectorBackend.querySelectorAll(nodeId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload)); } - InspectorBackend.addRule2(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector)); + InspectorBackend.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector)); }, _styleSheetChanged: function(styleSheetId, majorChange) @@ -162,11 +162,11 @@ WebInspector.CSSStyleModel.prototype = { function callback(href, content) { - var resource = WebInspector.resourceTreeModel.resourceForURL(href); + var resource = WebInspector.resourceForURL(href); if (resource && resource.type === WebInspector.Resource.Type.Stylesheet) resource.setContent(content, this._onRevert.bind(this, styleSheetId)); } - InspectorBackend.getStyleSheetText2(styleSheetId, callback.bind(this)); + InspectorBackend.getStyleSheetText(styleSheetId, callback.bind(this)); }, _onRevert: function(styleSheetId, contentToRevertTo) @@ -176,7 +176,7 @@ WebInspector.CSSStyleModel.prototype = { this._styleSheetChanged(styleSheetId, true); this.dispatchEventToListeners("stylesheet changed"); } - InspectorBackend.setStyleSheetText2(styleSheetId, contentToRevertTo, callback.bind(this)); + InspectorBackend.setStyleSheetText(styleSheetId, contentToRevertTo, callback.bind(this)); } } @@ -348,7 +348,7 @@ WebInspector.CSSStyleDeclaration.prototype = { } } - InspectorBackend.setPropertyText2(this.id, index, name + ": " + value + ";", false, callback.bind(null, userCallback)); + InspectorBackend.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(null, userCallback)); }, appendProperty: function(name, value, userCallback) @@ -488,7 +488,7 @@ WebInspector.CSSProperty.prototype = { throw "No ownerStyle for property"; // An index past all the properties adds a new property to the style. - InspectorBackend.setPropertyText2(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this)); + InspectorBackend.setPropertyText(this.ownerStyle.id, this.index, propertyText, this.index < this.ownerStyle.pastLastSourcePropertyIndex(), callback.bind(this)); }, setValue: function(newValue, userCallback) @@ -517,7 +517,7 @@ WebInspector.CSSProperty.prototype = { } } - InspectorBackend.toggleProperty2(this.ownerStyle.id, this.index, disabled, callback.bind(this)); + InspectorBackend.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this)); } } @@ -548,7 +548,7 @@ WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback) else userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload)); } - InspectorBackend.getStyleSheet2(styleSheetId, callback.bind(this)); + InspectorBackend.getStyleSheet(styleSheetId, callback.bind(this)); } WebInspector.CSSStyleSheet.prototype = { @@ -569,6 +569,6 @@ WebInspector.CSSStyleSheet.prototype = { } } - InspectorBackend.setStyleSheetText2(this.id, newText, callback.bind(this)); + InspectorBackend.setStyleSheetText(this.id, newText, callback.bind(this)); } } diff --git a/Source/WebCore/inspector/front-end/ChangesView.js b/Source/WebCore/inspector/front-end/ChangesView.js deleted file mode 100644 index 5ab6942..0000000 --- a/Source/WebCore/inspector/front-end/ChangesView.js +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Joseph Pecoraro - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.ChangesView = function(drawer) -{ - WebInspector.View.call(this); - this.element.innerHTML = "

Not Implemented Yet

"; - - this.drawer = drawer; - - this.clearButton = document.createElement("button"); - this.clearButton.id = "clear-changes-status-bar-item"; - this.clearButton.title = WebInspector.UIString("Clear changes log."); - this.clearButton.className = "status-bar-item clear-status-bar-item"; - this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false); - - this.toggleChangesButton = document.getElementById("changes-status-bar-item"); - this.toggleChangesButton.title = WebInspector.UIString("Show changes view."); - this.toggleChangesButton.addEventListener("click", this._toggleChangesButtonClicked.bind(this), false); - var anchoredStatusBar = document.getElementById("anchored-status-bar-items"); - anchoredStatusBar.appendChild(this.toggleChangesButton); -} - -WebInspector.ChangesView.prototype = { - _clearButtonClicked: function() - { - // Not Implemented Yet - }, - - _toggleChangesButtonClicked: function() - { - this.drawer.visibleView = this; - }, - - attach: function(mainElement, statusBarElement) - { - mainElement.appendChild(this.element); - statusBarElement.appendChild(this.clearButton); - }, - - show: function() - { - this.toggleChangesButton.addStyleClass("toggled-on"); - this.toggleChangesButton.title = WebInspector.UIString("Hide changes view."); - }, - - hide: function() - { - this.toggleChangesButton.removeStyleClass("toggled-on"); - this.toggleChangesButton.title = WebInspector.UIString("Show changes view."); - } -} - -WebInspector.ChangesView.prototype.__proto__ = WebInspector.View.prototype; diff --git a/Source/WebCore/inspector/front-end/ConsoleView.js b/Source/WebCore/inspector/front-end/ConsoleView.js index bd08e60..35d1ebf 100644 --- a/Source/WebCore/inspector/front-end/ConsoleView.js +++ b/Source/WebCore/inspector/front-end/ConsoleView.js @@ -89,7 +89,7 @@ WebInspector.ConsoleView = function(drawer) this.filter(this.allElement, false); this._registerShortcuts(); - this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); + this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false); this._customFormatters = { "object": this._formatobject, @@ -150,11 +150,6 @@ WebInspector.ConsoleView.prototype = { { console.clearMessages(); }, - - monitoringXHRStateChanged: function(enabled) - { - console._monitoringXHREnabled = enabled; - } } InspectorBackend.registerDomainDispatcher("Console", dispatcher); }, @@ -278,6 +273,7 @@ WebInspector.ConsoleView.prototype = { if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) { this._incrementErrorWarningCount(msg); WebInspector.resourceTreeModel.addConsoleMessage(msg); + WebInspector.panels.scripts.addConsoleMessage(msg); this.commandSincePreviousMessage = false; this.previousMessage = msg; } else if (msg instanceof WebInspector.ConsoleCommand) { @@ -326,6 +322,7 @@ WebInspector.ConsoleView.prototype = { clearMessages: function() { WebInspector.resourceTreeModel.clearConsoleMessages(); + WebInspector.panels.scripts.clearConsoleMessages(); this.messages = []; @@ -359,12 +356,12 @@ WebInspector.ConsoleView.prototype = { var reportCompletions = this._reportCompletions.bind(this, bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix); // Collect comma separated object properties for the completion. - var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation); + var includeCommandLineAPI = (!dotNotation && !bracketNotation); var injectedScriptAccess; if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) - InspectorBackend.getCompletionsOnCallFrame(WebInspector.panels.scripts.selectedCallFrameId(), expressionString, includeInspectorCommandLineAPI, reportCompletions); + InspectorBackend.getCompletionsOnCallFrame(WebInspector.panels.scripts.selectedCallFrameId(), expressionString, includeCommandLineAPI, reportCompletions); else - InspectorBackend.getCompletions(expressionString, includeInspectorCommandLineAPI, reportCompletions); + InspectorBackend.getCompletions(expressionString, includeCommandLineAPI, reportCompletions); }, _reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) { @@ -418,9 +415,12 @@ WebInspector.ConsoleView.prototype = { return; } - var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !this._monitoringXHREnabled); + var itemAction = function () { + WebInspector.settings.monitoringXHREnabled = !WebInspector.settings.monitoringXHREnabled; + InspectorBackend.setMonitoringXHREnabled(WebInspector.settings.monitoringXHREnabled); + }.bind(this); var contextMenu = new WebInspector.ContextMenu(); - contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, this._monitoringXHREnabled); + contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.settings.monitoringXHREnabled) contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this)); contextMenu.show(event); }, @@ -510,17 +510,13 @@ WebInspector.ConsoleView.prototype = { } }, - evalInInspectedWindow: function(expression, objectGroup, callback) + evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, callback) { if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) { - WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, objectGroup, callback); + WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, objectGroup, includeCommandLineAPI, callback); return; } - this.doEvalInWindow(expression, objectGroup, callback); - }, - doEvalInWindow: function(expression, objectGroup, callback) - { if (!expression) { // There is no expression, so the completion should happen against global properties. expression = "this"; @@ -530,7 +526,7 @@ WebInspector.ConsoleView.prototype = { { callback(WebInspector.RemoteObject.fromPayload(result)); } - InspectorBackend.evaluate(expression, objectGroup, evalCallback); + InspectorBackend.evaluate(expression, objectGroup, includeCommandLineAPI, evalCallback); }, _enterKeyPressed: function(event) @@ -561,7 +557,7 @@ WebInspector.ConsoleView.prototype = { self.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage)); } - this.evalInInspectedWindow(str, "console", printResult); + this.evalInInspectedWindow(str, "console", true, printResult); }, _format: function(output, forceObjectFormat) diff --git a/Source/WebCore/inspector/front-end/ContextMenu.js b/Source/WebCore/inspector/front-end/ContextMenu.js index 47045a2..58810fb 100644 --- a/Source/WebCore/inspector/front-end/ContextMenu.js +++ b/Source/WebCore/inspector/front-end/ContextMenu.js @@ -44,6 +44,7 @@ WebInspector.ContextMenu.prototype = { WebInspector._contextMenu = this; InspectorFrontendHost.showContextMenu(event, this._items); } + event.stopPropagation(); }, appendItem: function(label, handler, disabled) diff --git a/Source/WebCore/inspector/front-end/DOMAgent.js b/Source/WebCore/inspector/front-end/DOMAgent.js index e4fc7ad..3645bb9 100644 --- a/Source/WebCore/inspector/front-end/DOMAgent.js +++ b/Source/WebCore/inspector/front-end/DOMAgent.js @@ -502,19 +502,19 @@ WebInspector.ApplicationCacheDispatcher = function() { } -WebInspector.ApplicationCacheDispatcher.prototype = { - getApplicationCachesAsync: function(callback) +WebInspector.ApplicationCacheDispatcher.getApplicationCachesAsync = function(callback) +{ + function mycallback(applicationCaches) { - function mycallback(applicationCaches) - { - // FIXME: Currently, this list only returns a single application cache. - if (applicationCaches) - callback(applicationCaches); - } - - InspectorBackend.getApplicationCaches(mycallback); - }, - + // FIXME: Currently, this list only returns a single application cache. + if (applicationCaches) + callback(applicationCaches); + } + + InspectorBackend.getApplicationCaches(mycallback); +} + +WebInspector.ApplicationCacheDispatcher.prototype = { updateApplicationCacheStatus: function(status) { WebInspector.panels.resources.updateApplicationCacheStatus(status); diff --git a/Source/WebCore/inspector/front-end/DataGrid.js b/Source/WebCore/inspector/front-end/DataGrid.js index 5831d1e..45f0b55 100644 --- a/Source/WebCore/inspector/front-end/DataGrid.js +++ b/Source/WebCore/inspector/front-end/DataGrid.js @@ -493,6 +493,11 @@ WebInspector.DataGrid.prototype = { this._columnWidthsInitialized = false; }, + get scrollContainer() + { + return this._scrollContainer; + }, + isScrolledToLastRow: function() { return this._scrollContainer.isScrolledToBottom(); diff --git a/Source/WebCore/inspector/front-end/DebuggerModel.js b/Source/WebCore/inspector/front-end/DebuggerModel.js index 717486c..1bf1e47 100644 --- a/Source/WebCore/inspector/front-end/DebuggerModel.js +++ b/Source/WebCore/inspector/front-end/DebuggerModel.js @@ -33,7 +33,6 @@ WebInspector.DebuggerModel = function() this._paused = false; this._callFrames = []; this._breakpoints = {}; - this._sourceIDAndLineToBreakpointId = {}; this._scripts = {}; InspectorBackend.registerDomainDispatcher("Debugger", new WebInspector.DebuggerDispatcher(this)); @@ -46,64 +45,116 @@ WebInspector.DebuggerModel.Events = { FailedToParseScriptSource: "failed-to-parse-script-source", ScriptSourceChanged: "script-source-changed", BreakpointAdded: "breakpoint-added", - BreakpointRemoved: "breakpoint-removed" + BreakpointRemoved: "breakpoint-removed", + BreakpointResolved: "breakpoint-resolved" } WebInspector.DebuggerModel.prototype = { + enableDebugger: function() + { + InspectorBackend.enableDebugger(); + if (this._breakpointsPushedToBackend) + return; + var breakpoints = WebInspector.settings.breakpoints; + for (var i = 0; i < breakpoints.length; ++i) { + var breakpoint = breakpoints[i]; + if (typeof breakpoint.url !== "string" || typeof breakpoint.lineNumber !== "number" || typeof breakpoint.columnNumber !== "number" || + typeof breakpoint.condition !== "string" || typeof breakpoint.enabled !== "boolean") + continue; + this.setBreakpoint(breakpoint.url, breakpoint.lineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled); + } + this._breakpointsPushedToBackend = true; + }, + + disableDebugger: function() + { + InspectorBackend.disableDebugger(); + }, + continueToLine: function(sourceID, lineNumber) { - function didSetBreakpoint(breakpointId, actualLineNumber) + InspectorBackend.continueToLocation(sourceID, lineNumber, 0); + }, + + setBreakpoint: function(url, lineNumber, columnNumber, condition, enabled) + { + function didSetBreakpoint(breakpointsPushedToBackend, breakpointId, locations) { if (!breakpointId) return; - if (this.findBreakpoint(sourceID, actualLineNumber)) { - InspectorBackend.removeBreakpoint(breakpointId); - return; - } - if ("_continueToLineBreakpointId" in this) - InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); - this._continueToLineBreakpointId = breakpointId; + var breakpoint = new WebInspector.Breakpoint(breakpointId, url, "", lineNumber, columnNumber, condition, enabled); + breakpoint.locations = locations; + this._breakpoints[breakpointId] = breakpoint; + if (breakpointsPushedToBackend) + this._saveBreakpoints(); + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint); } - InspectorBackend.setBreakpoint(sourceID, lineNumber, "", true, didSetBreakpoint.bind(this)); - if (this._paused) - InspectorBackend.resume(); + InspectorBackend.setJavaScriptBreakpoint(url, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this, this._breakpointsPushedToBackend)); }, - setBreakpoint: function(sourceID, lineNumber, enabled, condition) + setBreakpointBySourceId: function(sourceID, lineNumber, columnNumber, condition, enabled) { - function didSetBreakpoint(breakpointId, actualLineNumber) + function didSetBreakpoint(breakpointId, actualLineNumber, actualColumnNumber) { - if (breakpointId) - this._breakpointSetOnBackend(breakpointId, sourceID, actualLineNumber, condition, enabled, lineNumber, false); + if (!breakpointId) + return; + var breakpoint = new WebInspector.Breakpoint(breakpointId, "", sourceID, lineNumber, columnNumber, condition, enabled); + breakpoint.addLocation(sourceID, actualLineNumber, actualColumnNumber); + this._breakpoints[breakpointId] = breakpoint; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint); } - InspectorBackend.setBreakpoint(sourceID, lineNumber, condition, enabled, didSetBreakpoint.bind(this)); + InspectorBackend.setJavaScriptBreakpointBySourceId(sourceID, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this)); }, removeBreakpoint: function(breakpointId) { - InspectorBackend.removeBreakpoint(breakpointId); + InspectorBackend.removeJavaScriptBreakpoint(breakpointId); var breakpoint = this._breakpoints[breakpointId]; delete this._breakpoints[breakpointId]; - delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)]; + this._saveBreakpoints(); this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId); - breakpoint.dispatchEventToListeners("removed"); }, - _breakpointSetOnBackend: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, restored) + updateBreakpoint: function(breakpointId, condition, enabled) { - var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); - if (sourceIDAndLine in this._sourceIDAndLineToBreakpointId) { - InspectorBackend.removeBreakpoint(breakpointId); + var breakpoint = this._breakpoints[breakpointId]; + this.removeBreakpoint(breakpointId); + if (breakpoint.url) + this.setBreakpoint(breakpoint.url, breakpoint.lineNumber, breakpoint.columnNumber, condition, enabled); + else + this.setBreakpointBySourceId(breakpoint.sourceID, breakpoint.lineNumber, breakpoint.columnNumber, condition, enabled); + }, + + _breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber) + { + var breakpoint = this._breakpoints[breakpointId]; + if (!breakpoint) return; + breakpoint.addLocation(sourceID, lineNumber, columnNumber); + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, breakpoint); + }, + + _saveBreakpoints: function() + { + var serializedBreakpoints = []; + for (var id in this._breakpoints) { + var breakpoint = this._breakpoints[id]; + if (!breakpoint.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); } + WebInspector.settings.breakpoints = serializedBreakpoints; + }, - var url = this._scripts[sourceID].sourceURL; - var breakpoint = new WebInspector.Breakpoint(this, breakpointId, sourceID, url, lineNumber, enabled, condition); - breakpoint.restored = restored; - breakpoint.originalLineNumber = originalLineNumber; - this._breakpoints[breakpointId] = breakpoint; - this._sourceIDAndLineToBreakpointId[sourceIDAndLine] = breakpointId; - this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint); + get breakpoints() + { + return this._breakpoints; }, breakpointForId: function(breakpointId) @@ -124,23 +175,26 @@ WebInspector.DebuggerModel.prototype = { findBreakpoint: function(sourceID, lineNumber) { - var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); - var breakpointId = this._sourceIDAndLineToBreakpointId[sourceIDAndLine]; - return this._breakpoints[breakpointId]; - }, - - _encodeSourceIDAndLine: function(sourceID, lineNumber) - { - return sourceID + ":" + lineNumber; + for (var id in this._breakpoints) { + var locations = this._breakpoints[id].locations; + for (var i = 0; i < locations.length; ++i) { + if (locations[i].sourceID == sourceID && locations[i].lineNumber + 1 === lineNumber) + return this._breakpoints[id]; + } + } }, reset: function() { this._paused = false; this._callFrames = []; - this._breakpoints = {}; - delete this._oneTimeBreakpoint; - this._sourceIDAndLineToBreakpointId = {}; + for (var id in this._breakpoints) { + var breakpoint = this._breakpoints[id]; + if (!breakpoint.url) + this.removeBreakpoint(id); + else + breakpoint.locations = []; + } this._scripts = {}; }, @@ -189,10 +243,15 @@ WebInspector.DebuggerModel.prototype = { var diff = Array.diff(oldSource.split("\n"), script.source.split("\n")); for (var id in this._breakpoints) { var breakpoint = this._breakpoints[id]; - if (breakpoint.sourceID !== sourceID) - continue; - breakpoint.remove(); - var lineNumber = breakpoint.line - 1; + if (breakpoint.url) { + if (breakpoint.url !== script.sourceURL) + continue; + } else { + if (breakpoint.sourceID !== sourceID) + continue; + } + this.removeBreakpoint(breakpoint.id); + var lineNumber = breakpoint.lineNumber; var newLineNumber = diff.left[lineNumber].row; if (newLineNumber === undefined) { for (var i = lineNumber - 1; i >= 0; --i) { @@ -207,8 +266,12 @@ WebInspector.DebuggerModel.prototype = { break; } } - if (newLineNumber !== undefined) - this.setBreakpoint(sourceID, newLineNumber + 1, breakpoint.enabled, breakpoint.condition); + if (newLineNumber === undefined) + continue; + if (breakpoint.url) + this.setBreakpoint(breakpoint.url, newLineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled); + else + this.setBreakpointBySourceId(sourceID, newLineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled); } this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ScriptSourceChanged, { sourceID: sourceID, oldSource: oldSource }); @@ -223,10 +286,6 @@ WebInspector.DebuggerModel.prototype = { { this._paused = true; this._callFrames = details.callFrames; - if ("_continueToLineBreakpointId" in this) { - InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); - delete this._continueToLineBreakpointId; - } this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details); }, @@ -241,7 +300,7 @@ WebInspector.DebuggerModel.prototype = { { var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, length, undefined, undefined, scriptWorldType); this._scripts[sourceID] = script; - this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, sourceID); + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script); }, _failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage) @@ -295,9 +354,9 @@ WebInspector.DebuggerDispatcher.prototype = { this._debuggerModel._failedToParseScriptSource(sourceURL, source, startingLine, errorLine, errorMessage); }, - breakpointResolved: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber) + breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber) { - this._debuggerModel._breakpointSetOnBackend(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, true); + this._debuggerModel._breakpointResolved(breakpointId, sourceID, lineNumber, columnNumber); }, didCreateWorker: function() diff --git a/Source/WebCore/inspector/front-end/DetailedHeapshotView.js b/Source/WebCore/inspector/front-end/DetailedHeapshotView.js new file mode 100644 index 0000000..5291bf2 --- /dev/null +++ b/Source/WebCore/inspector/front-end/DetailedHeapshotView.js @@ -0,0 +1,92 @@ +/* + * 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.DetailedHeapshotView = function(parent, profile) +{ + WebInspector.View.call(this); + + this.element.addStyleClass("heap-snapshot-view"); + + this.parent = parent; + this.profile = profile; +} + +WebInspector.DetailedHeapshotView.prototype = { + get profile() + { + return this._profile; + }, + + set profile(profile) + { + this._profile = profile; + } +}; + +WebInspector.DetailedHeapshotView.prototype.__proto__ = WebInspector.View.prototype; + +WebInspector.DetailedHeapshotProfileType = function() +{ + WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS")); +} + +WebInspector.DetailedHeapshotProfileType.prototype = { + get buttonTooltip() + { + return WebInspector.UIString("Take heap snapshot."); + }, + + get buttonStyle() + { + return "heap-snapshot-status-bar-item status-bar-item"; + }, + + buttonClicked: function() + { + WebInspector.panels.profiles.takeHeapSnapshot(true); + }, + + get welcomeMessage() + { + return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar."); + }, + + createSidebarTreeElementForProfile: function(profile) + { + return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Snapshot %d"), "heap-snapshot-sidebar-tree-item"); + }, + + createView: function(profile) + { + return new WebInspector.DetailedHeapshotView(WebInspector.panels.profiles, profile); + } +} + +WebInspector.DetailedHeapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype; diff --git a/Source/WebCore/inspector/front-end/Drawer.js b/Source/WebCore/inspector/front-end/Drawer.js index 3f827fb..4861c90 100644 --- a/Source/WebCore/inspector/front-end/Drawer.js +++ b/Source/WebCore/inspector/front-end/Drawer.js @@ -35,11 +35,11 @@ WebInspector.Drawer = function() this.state = WebInspector.Drawer.State.Hidden; this.fullPanel = false; - this.mainElement = document.getElementById("main"); - this.toolbarElement = document.getElementById("toolbar"); - this.mainStatusBar = document.getElementById("main-status-bar"); - this.mainStatusBar.addEventListener("mousedown", this._startStatusBarDragging.bind(this), true); - this.viewStatusBar = document.getElementById("other-drawer-status-bar-items"); + this._mainElement = document.getElementById("main"); + this._toolbarElement = document.getElementById("toolbar"); + this._mainStatusBar = document.getElementById("main-status-bar"); + this._mainStatusBar.addEventListener("mousedown", this._startStatusBarDragging.bind(this), true); + this._viewStatusBar = document.getElementById("other-drawer-status-bar-items"); this._counters = document.getElementById("counters"); this._drawerStatusBar = document.getElementById("drawer-status-bar"); } @@ -67,8 +67,8 @@ WebInspector.Drawer.prototype = { if (x && !firstTime) { this._safelyRemoveChildren(); - this.viewStatusBar.removeChildren(); // optimize this? call old.detach() - x.attach(this.element, this.viewStatusBar); + this._viewStatusBar.removeChildren(); // optimize this? call old.detach() + x.attach(this.element, this._viewStatusBar); x.show(); this.visible = true; } @@ -77,7 +77,7 @@ WebInspector.Drawer.prototype = { get savedHeight() { var height = this._savedHeight || this.element.offsetHeight; - return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this.mainElement.totalOffsetTop - Preferences.minConsoleHeight); + return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop - Preferences.minConsoleHeight); }, showView: function(view) @@ -101,16 +101,15 @@ WebInspector.Drawer.prototype = { document.body.addStyleClass("drawer-visible"); var anchoredItems = document.getElementById("anchored-status-bar-items"); - var height = (this.fullPanel ? window.innerHeight - this.toolbarElement.offsetHeight : this.savedHeight); + var height = (this.fullPanel ? window.innerHeight - this._toolbarElement.offsetHeight : this.savedHeight); var animations = [ {element: this.element, end: {height: height}}, - {element: document.getElementById("main"), end: {bottom: height}}, - {element: document.getElementById("main-status-bar"), start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}}, - {element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 0}, end: {opacity: 1}} + {element: this._mainElement, end: {bottom: height}}, + {element: this._mainStatusBar, start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}}, + {element: this._viewStatusBar, start: {opacity: 0}, end: {opacity: 1}} ]; - var drawerStatusBar = document.getElementById("drawer-status-bar"); - drawerStatusBar.insertBefore(anchoredItems, drawerStatusBar.firstChild); + this._drawerStatusBar.insertBefore(anchoredItems, this._drawerStatusBar.firstChild); if (this._currentPanelCounters) { var oldRight = this._drawerStatusBar.clientWidth - (this._counters.offsetLeft + this._currentPanelCounters.offsetWidth); @@ -118,7 +117,7 @@ WebInspector.Drawer.prototype = { var rightPadding = (oldRight - newRight); animations.push({element: this._currentPanelCounters, start: {"padding-right": rightPadding}, end: {"padding-right": 0}}); this._currentPanelCounters.parentNode.removeChild(this._currentPanelCounters); - this.mainStatusBar.appendChild(this._currentPanelCounters); + this._mainStatusBar.appendChild(this._currentPanelCounters); } function animationFinished() @@ -128,13 +127,13 @@ WebInspector.Drawer.prototype = { if (this.visibleView.afterShow) this.visibleView.afterShow(); delete this._animating; - delete this._currentAnimationInterval; + delete this._currentAnimation; this.state = (this.fullPanel ? WebInspector.Drawer.State.Full : WebInspector.Drawer.State.Variable); if (this._currentPanelCounters) this._currentPanelCounters.removeAttribute("style"); } - this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); + this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); }, hide: function() @@ -159,21 +158,21 @@ WebInspector.Drawer.prototype = { // Temporarily set properties and classes to mimic the post-animation values so panels // like Elements in their updateStatusBarItems call will size things to fit the final location. - this.mainStatusBar.style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px"); + this._mainStatusBar.style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px"); document.body.removeStyleClass("drawer-visible"); if ("updateStatusBarItems" in WebInspector.currentPanel) WebInspector.currentPanel.updateStatusBarItems(); document.body.addStyleClass("drawer-visible"); var animations = [ - {element: document.getElementById("main"), end: {bottom: 0}}, - {element: document.getElementById("main-status-bar"), start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}}, - {element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 1}, end: {opacity: 0}} + {element: this._mainElement, end: {bottom: 0}}, + {element: this._mainStatusBar, start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}}, + {element: this._viewStatusBar, start: {opacity: 1}, end: {opacity: 0}} ]; if (this._currentPanelCounters) { var newRight = this._drawerStatusBar.clientWidth - this._counters.offsetLeft; - var oldRight = this.mainStatusBar.clientWidth - (this._currentPanelCounters.offsetLeft + this._currentPanelCounters.offsetWidth); + var oldRight = this._mainStatusBar.clientWidth - (this._currentPanelCounters.offsetLeft + this._currentPanelCounters.offsetWidth); var rightPadding = (newRight - oldRight); animations.push({element: this._currentPanelCounters, start: {"padding-right": 0}, end: {"padding-right": rightPadding}}); } @@ -181,9 +180,8 @@ WebInspector.Drawer.prototype = { function animationFinished() { WebInspector.currentPanel.resize(); - var mainStatusBar = document.getElementById("main-status-bar"); - mainStatusBar.insertBefore(anchoredItems, mainStatusBar.firstChild); - mainStatusBar.style.removeProperty("padding-left"); + this._mainStatusBar.insertBefore(anchoredItems, this._mainStatusBar.firstChild); + this._mainStatusBar.style.removeProperty("padding-left"); if (this._currentPanelCounters) { this._currentPanelCounters.setAttribute("style", null); @@ -193,11 +191,11 @@ WebInspector.Drawer.prototype = { document.body.removeStyleClass("drawer-visible"); delete this._animating; - delete this._currentAnimationInterval; + delete this._currentAnimation; this.state = WebInspector.Drawer.State.Hidden; } - this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); + this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); }, resize: function() @@ -206,14 +204,13 @@ WebInspector.Drawer.prototype = { return; var height; - var mainElement = document.getElementById("main"); if (this.state === WebInspector.Drawer.State.Variable) { height = parseInt(this.element.style.height); - height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight); + height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop - Preferences.minConsoleHeight); } else - height = window.innerHeight - this.toolbarElement.offsetHeight; + height = window.innerHeight - this._toolbarElement.offsetHeight; - mainElement.style.bottom = height + "px"; + this._mainElement.style.bottom = height + "px"; this.element.style.height = height + "px"; }, @@ -224,7 +221,7 @@ WebInspector.Drawer.prototype = { if (this.visible) { this._savedHeight = this.element.offsetHeight; - var height = window.innerHeight - this.toolbarElement.offsetHeight; + var height = window.innerHeight - this._toolbarElement.offsetHeight; this._animateDrawerHeight(height, WebInspector.Drawer.State.Full); } }, @@ -249,6 +246,12 @@ WebInspector.Drawer.prototype = { this.fullPanel = false; }, + immediatelyFinishAnimation: function() + { + if (this._currentAnimation) + this._currentAnimation.forceComplete(); + }, + set currentPanelCounters(x) { if (!x) { @@ -260,7 +263,7 @@ WebInspector.Drawer.prototype = { this._currentPanelCounters = x; if (this.visible) - this.mainStatusBar.appendChild(x); + this._mainStatusBar.appendChild(x); else this._counters.insertBefore(x, this._counters.firstChild); }, @@ -268,9 +271,10 @@ WebInspector.Drawer.prototype = { _cancelAnimationIfNeeded: function() { if (this._animating) { - clearInterval(this._currentAnimationInterval); + if (this._currentAnimation) + this._currentAnimation.cancel(); delete this._animating; - delete this._currentAnimationInterval; + delete this._currentAnimation; } }, @@ -279,17 +283,17 @@ WebInspector.Drawer.prototype = { this._animating = true; var animations = [ {element: this.element, end: {height: height}}, - {element: document.getElementById("main"), end: {bottom: height}} + {element: this._mainElement, end: {bottom: height}} ]; function animationFinished() { delete this._animating; - delete this._currentAnimationInterval; + delete this._currentAnimation; this.state = finalState; } - this._currentAnimationInterval = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); + this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(), animationFinished.bind(this)); }, _animationDuration: function() @@ -316,10 +320,10 @@ WebInspector.Drawer.prototype = { _startStatusBarDragging: function(event) { - if (!this.visible || event.target !== this.mainStatusBar) + if (!this.visible || event.target !== this._mainStatusBar) return; - WebInspector.elementDragStart(this.mainStatusBar, this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), event, "row-resize"); + WebInspector.elementDragStart(this._mainStatusBar, this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), event, "row-resize"); this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop; @@ -328,11 +332,10 @@ WebInspector.Drawer.prototype = { _statusBarDragging: function(event) { - var mainElement = document.getElementById("main"); var height = window.innerHeight - event.pageY + this._statusBarDragOffset; - height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight); + height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop - Preferences.minConsoleHeight); - mainElement.style.bottom = height + "px"; + this._mainElement.style.bottom = height + "px"; this.element.style.height = height + "px"; event.preventDefault(); diff --git a/Source/WebCore/inspector/front-end/ElementsPanel.js b/Source/WebCore/inspector/front-end/ElementsPanel.js index 9299479..e6af93c 100644 --- a/Source/WebCore/inspector/front-end/ElementsPanel.js +++ b/Source/WebCore/inspector/front-end/ElementsPanel.js @@ -255,13 +255,20 @@ WebInspector.ElementsPanel.prototype = { return false; // Add resource-related actions. - // Keep these consistent with those added in WebInspector.StylesSidebarPane.prototype._populateHrefContextMenu(). - contextMenu.appendItem(WebInspector.UIString("Open Link in New Window"), WebInspector.openResource.bind(null, resourceURL, false)); + contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(null, resourceURL, false)); if (WebInspector.resourceForURL(resourceURL)) contextMenu.appendItem(WebInspector.UIString("Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true)); return true; }, + switchToAndFocus: function(node) + { + // Reset search restore. + WebInspector.cancelSearch(); + WebInspector.currentPanel = this; + this.focusedDOMNode = node; + }, + _updateMatchesCount: function() { WebInspector.updateSearchMatchesCount(this._searchResults.length, this); diff --git a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js index 722c028..56c3e75 100644 --- a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -268,8 +268,7 @@ WebInspector.ElementsTreeOutline.prototype = { if (this.showInElementsPanelEnabled) { function focusElement() { - WebInspector.currentPanel = WebInspector.panels.elements; - WebInspector.panels.elements.focusedDOMNode = listItem.treeElement.representedObject; + WebInspector.panels.elements.switchToAndFocus(listItem.treeElement.representedObject); } contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this)); } else { diff --git a/Source/WebCore/inspector/front-end/ExtensionAPI.js b/Source/WebCore/inspector/front-end/ExtensionAPI.js index b10452d..6a11d62 100644 --- a/Source/WebCore/inspector/front-end/ExtensionAPI.js +++ b/Source/WebCore/inspector/front-end/ExtensionAPI.js @@ -387,9 +387,9 @@ function InspectedWindow() } InspectedWindow.prototype = { - reload: function() + reload: function(userAgent) { - return extensionServer.sendRequest({ command: "reload" }); + return extensionServer.sendRequest({ command: "reload", userAgent: userAgent }); }, eval: function(expression, callback) diff --git a/Source/WebCore/inspector/front-end/ExtensionAPISchema.json b/Source/WebCore/inspector/front-end/ExtensionAPISchema.json new file mode 100755 index 0000000..28084ba --- /dev/null +++ b/Source/WebCore/inspector/front-end/ExtensionAPISchema.json @@ -0,0 +1,513 @@ +[ + { + "namespace": "experimental.webInspector.inspectedWindow", + "description": "Provides access to the window being inspected.", + "functions": [ + { + "name": "eval", + "type": "function", + "description": "Evaluates a JavaScript expression in the context of inspected page (NOTE: the expression must evaluate to a JSON-compliant object, otherwise the exception is thrown)", + "parameters": [ + { + "name": "expression", + "type": "string", + "description": "An expression to evaluate." + }, + { + "name": "callback", + "type": "function", + "description": "A function called when evaluation completes.", + "parameters": [ + { + "name": "result", + "type": "object", + "description": "The result of evaluation" + }, + { + "name": "isException", + "type": "boolean", + "description": "Set if an exception was caught while evaluating the expression" + } + ] + } + ] + } + ], + "events": [ + { + "name": "onDOMContentLoaded", + "type": "function", + "description": "Fired after DOMContentLoaded event on inspected page is fired." + }, + { + "name": "onLoaded", + "type": "function", + "description": "Fired after load event on inspected page is fired." + }, + { + "name": "onNavigated", + "type": "function", + "description": "Fired when navigation occurs in the window being inspected." + } + ] + }, + { + "namespace": "experimental.webInspector.panels", + "types": [ + { + "id": "PanelWithSidebars", + "type": "object", + "isInstanceOf": "Panel", + "description": "A panel within Web Inspector UI that has sidebars.", + "functions": [ + { + "name": "createSidebarPane", + "type": "function", + "description": "Creates a pane within panel's sidebar.", + "parameters": [ + { + "name": "title", + "type": "string", + "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", + "parameters": [ + { + "name": "result", + "description": "An ExtensionSidebarPane object for created sidebar pane", + "$ref": "ExtensionSidebarPane" + } + ] + } + ] + }, + { + "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" + } + ] + } + ] + } + ] + }, + { + "id": "ElementsPanel", + "type": "object", + "isInstanceOf": "PanelWithSidebars", + "description": "Represents Elements panel", + "events": [ + { + "name": "onSelectionChanged", + "description": "Fired when an objects is selected in the panel." + } + ] + }, + { + "id": "ExtensionPanel", + "type": "object", + "isInstanceOf": "Panel", + "description": "Represents a panel created by extension", + "events": [ + { + "name": "onSearch", + "description": "Fired upon a search action (start of a new search, search result navigation or search being canceled).", + "parameters": [ + { + "name": "action", + "type": "string", + "description": "Type of search action being performed." + }, + { + "name": "queryString", + "type": "string", + "optional": true, + "description": "Query string (only for 'performSearch')" + } + ] + } + ] + }, + { + "id": "ExtensionSidebarPane", + "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'" + } + ] + } + ] + }, + { + "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", + "type": "function", + "description": "Sets an expression that is evaluated within the inspected page. The result is displayed in the sidebar pane.", + "parameters": [ + { + "name": "expression", + "type": "string", + "description": "An expression to be evaluated in context of the inspected page. JavaScript objects and DOM nodes are displayed in an expandable tree similar to the console/watch." + }, + { + "name": "rootTitle", + "type": "string", + "optional": true, + "description": "An optional title for the root of the expression tree." + } + ] + }, + { + "name": "setObject", + "type": "function", + "description": "Sets a JSON-compliant object to be displayed in the sidebar pane.", + "parameters": [ + { + "name": "jsonObject", + "type": "string", + "description": "An object to be displayed in context of the inspected page. Evaluated in the context of the caller (API client)." + }, + { + "name": "rootTitle", + "type": "string", + "optional": true, + "description": "An optional title for the root of the expression tree." + } + ] + } + ] + } + ], + "properties": { + "scripts": { + "$ref": "ScriptsPanel", + "description": "Scripts panel" + } + }, + "functions": [ + { + "name": "create", + "type": "function", + "description": "Creates an extension panel.", + "parameters": [ + { + "name": "title", + "type": "string", + "description": "Title that is displayed under the extension icon in the toolbar." + }, + { + "name": "iconURL", + "type": "string", + "description": "An URL of the toolbar icon." + }, + { + "name": "pageURL", + "type": "string", + "description": "An URL of the page that represents this panel." + } + ], + "returns" : { + "$ref": "ExtensionPanel", + "description": "A panel that was created." + } + } + ] + }, + { + "namespace": "experimental.webInspector.resources", + "types": [ + { + "id": "Resource", + "type": "object", + "description": "Represents a resource (document, script, image etc). See HAR Specification for reference.", + "functions": [ + { + "name": "getContent", + "type": "function", + "description": "Returns resource content.", + "parameters": [ + { + "name": "callback", + "type": "function", + "description": "A function that is called upon request completion.", + "parameters": [ + { + "name": "content", + "type": "string", + "description": "Resource content (potentially encoded)." + }, + { + "name": "encoding", + "type": "string", + "description": "Empty if content is not encoded, encoding name otherwise. Currently, only base64 supported." + } + ] + } + ] + } + ] + } + ], + "functions": [ + { + "name": "getHAR", + "type": "function", + "description": "Returns HAR archive that contains all known resource objects.", + "parameters": [ + { + "name": "callback", + "type": "function", + "description": "A function that is called upon request completion.", + "parameters": [ + { + "name": "har", + "type": "object", + "description": "A HAR archieve. See HAR specification for details." + } + ] + } + ] + } + ], + "events": [ + { + "name": "onFinished", + "type": "function", + "description": "Fired when a resource request is finished and all resource data are available.", + "parameters": [ + { "name": "resource", "$ref": "Resource" } + ] + } + ] + }, + { + "namespace": "experimental.webInspector.audits", + "functions": [ + { + "name": "addCategory", + "type": "function", + "description": "Adds an audit category.", + "parameters": [ + { "name": "displayName", "type": "string", "description": "A display name for the category" }, + { "name": "resultCount", "type": "number", "description": "The expected number of audit results in the category." } + ], + "returns": { + "$ref": "AuditCategory" + } + } + ], + "types": [ + { + "id": "AuditCategory", + "type": "object", + "description": "A set of audit rules", + "events": [ + { + "name": "onAuditStarted", + "type": "function", + "description": "Fired when the audit is started, if the category is enabled -- the extension is expected to begin executing audit rules.", + "parameters": [ + { "name": "results", "$ref": "AuditResults" } + ] + } + ] + }, + { + "id": "FormattedValue", + "type": "object", + "description": "A value returned from one of the formatters (an URL, code snippet etc), to be passed to createResult or addChild" + }, + { + "id": "AuditResults", + "type": "object", + "description": "A collection of audit results for current run of the audit category", + "functions": [ + { + "name": "addResult", + "type": "function", + "parameters": [ + { + "name": "displayName", + "type": "string", + "description": "A concise, high-level description of audit rule result" + }, + { + "name": "description", + "type": "string", + "description": "A detailed description of what the displayName means" + }, + { + "name": "severity", + "$ref": "AuditResultSeverety" + }, + { + "name": "details", + "$ref": "AuditResultNode", + "optional": true, + "description": "A subtree that appears under added result that may provide additional details on the violations found" + } + ] + }, + { + "name": "createResult", + "type": "function", + "description": "Creates a result node that may be user as details parameters to addResult", + "parameters": [ + { + "name": "content ...", + "choices": [ + { "type": "string" }, + { "$ref": "FormattedValue" } + ], + "description": "Either string or formatted values returned by one of AuditResult formatters (url, snippet etc)" + } + ], + "returns": { + "$ref": "AuditResultNode" + } + }, + { + "name": "done", + "type": "function", + "description": "Signals the WebInspector Audits panel that the run of this category is over. Normally the run completes automatically when a number of added top-level results is equal to that declared when AuditCategory was created." + }, + { + "name": "url", + "type": "function", + "description": "Render passed value as an URL in the Audits panel", + "parameters": [ + { "name": "href", "type": "string", "description": "An URL that will appear as href value on resulting link" }, + { "name": "displayText", "type": "string", "description": "A text that will appear to user", "optional": true } + ], + "returns": { "$ref": "FormattedValue" } + }, + { + "name": "snippet", + "type": "function", + "description": "Render passed text as a code snippet in the Audits panel", + "parameters": [ + { "name": "text", "type": "string", "description": "Snippet text" } + ], + "returns": { "$ref": "FormattedValue" } + } + ], + "properties": { + "Severity": { + "$ref": "AuditResultSeverity", + "description": "A class that contains possible values for audit result severities." + }, + "text": { + "type": "string", + "description": "The contents of the node." + }, + "children": { + "optional": true, + "type": "array", + "items": { "$ref": "AuditResultNode" }, + "description": "Children of this node." + }, + "expanded": { + "optional": "true", + "type": "boolean", + "description": "Whether the node is expanded by default." + } + } + }, + { + "id": "AuditResultNode", + "type": "object", + "description": "A node in the audit result trees. Displays some content and optionally has children node", + "functions": [ + { + "name": "addChild", + "description": "Adds another child node to this node", + "parameters": [ + { + "name": "content ...", + "choices": [ + { "type": "string" }, + { "$ref": "FormattedValue" } + ], + "description": "Either string or formatted values returned by one of AuditResult formatters (url, snippet etc)" + } + ], + "returns": { + "$ref": "AuditResultNode" + } + } + ], + "properties": { + "expanded": { + "type": "boolean", + "description": "If set, the subtree will always be expanded" + } + } + }, + { + "id": "AuditResultSeverity", + "type": "object", + "properties": { + "Info": { + "type": "string" + }, + "Warning": { + "type": "string" + }, + "Severe": { + "type": "string" + } + } + } + ] + } +] + diff --git a/Source/WebCore/inspector/front-end/ExtensionPanel.js b/Source/WebCore/inspector/front-end/ExtensionPanel.js index fb98350..144d55d 100644 --- a/Source/WebCore/inspector/front-end/ExtensionPanel.js +++ b/Source/WebCore/inspector/front-end/ExtensionPanel.js @@ -95,7 +95,7 @@ WebInspector.ExtensionWatchSidebarPane.prototype = { setExpression: function(expression, title) { - InspectorBackend.evaluate(expression, "extension-watch", this._onEvaluate.bind(this, title)); + InspectorBackend.evaluate(expression, "extension-watch", false, this._onEvaluate.bind(this, title)); }, _onEvaluate: function(title, result) diff --git a/Source/WebCore/inspector/front-end/ExtensionServer.js b/Source/WebCore/inspector/front-end/ExtensionServer.js index 0924106..7d33b73 100644 --- a/Source/WebCore/inspector/front-end/ExtensionServer.js +++ b/Source/WebCore/inspector/front-end/ExtensionServer.js @@ -252,9 +252,12 @@ WebInspector.ExtensionServer.prototype = { WebInspector.log(message.message); }, - _onReload: function() + _onReload: function(message) { - InspectorBackend.reloadPage(); + if (typeof message.userAgent === "string") + InspectorBackend.setUserAgentOverride(message.userAgent); + + InspectorBackend.reloadPage(false); return this._status.OK(); }, @@ -269,10 +272,8 @@ WebInspector.ExtensionServer.prototype = { result.value = resultObject.description; this._dispatchCallback(message.requestId, port, result); } - var evalExpression = "JSON.stringify(eval('" + - "with (window.console._commandLineAPI) with (window) {' + unescape('" + escape(message.expression) + - "') + '}'));"; - InspectorBackend.evaluate(evalExpression, "none", callback.bind(this)); + var evalExpression = "JSON.stringify(eval(unescape('" + escape(message.expression) + "')));"; + InspectorBackend.evaluate(evalExpression, "none", true, callback.bind(this)); }, _onRevealAndSelect: function(message) diff --git a/Source/WebCore/inspector/front-end/FileSystemView.js b/Source/WebCore/inspector/front-end/FileSystemView.js deleted file mode 100644 index 56f21a4..0000000 --- a/Source/WebCore/inspector/front-end/FileSystemView.js +++ /dev/null @@ -1,211 +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.FileSystemDispatcher = function() -{ -} - -// Keep in sync with Type in AsyncFileSystem.h -WebInspector.FileSystemDispatcher.TEMPORARY = 0; -WebInspector.FileSystemDispatcher.PERSISTENT = 1; - -WebInspector.FileSystemDispatcher.prototype = { - getFileSystemPathsAsync: function(origin) - { - InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystemDispatcher.PERSISTENT, origin); - InspectorBackend.getFileSystemPathAsync(WebInspector.FileSystemDispatcher.TEMPORARY, origin); - }, - - didGetFileSystemPath: function(root, type, origin) - { - WebInspector.panels.resources.updateFileSystemPath(root, type, origin); - }, - - didGetFileSystemError: function(type, origin) - { - WebInspector.panels.resources.updateFileSystemError(type, origin); - }, - - didGetFileSystemDisabled: function() - { - WebInspector.panels.resources.setFileSystemDisabled(); - } -} - -InspectorBackend.registerDomainDispatcher("FileSystem", new WebInspector.FileSystemDispatcher()); - -WebInspector.FileSystemView = function(treeElement, fileSystemOrigin) -{ - WebInspector.View.call(this); - - this.element.addStyleClass("resource-view"); - this._treeElement = treeElement; - this._origin = fileSystemOrigin; - this._tabbedPane = new WebInspector.TabbedPane(this.element); - - this._persistentFileSystemElement = document.createElement("div"); - this._persistentFileSystemElement.className = "resource-view-headers"; - this._tabbedPane.appendTab("persistent", WebInspector.UIString("Persistent File System"), this._persistentFileSystemElement, this._selectFileSystemTab.bind(this, true)); - - this._tempFileSystemElement = document.createElement("div"); - this._tempFileSystemElement.className = "resource-view-headers"; - this._tabbedPane.appendTab("temp", WebInspector.UIString("Temporary File System"), this._tempFileSystemElement, this.selectTemporaryFileSystemTab.bind(this, true)); - - this._temporaryRoot = ""; - this._persistentRoot = ""; - this._isFileSystemDisabled = false; - this._persistentRootError = false; - this._temporaryRootError = false; - this.fileSystemVisible = true; - this._selectFileSystemTab(); - this.refreshFileSystem(); -} - -WebInspector.FileSystemView.prototype = { - show: function(parentElement) - { - WebInspector.View.prototype.show.call(this, parentElement); - this._update(); - }, - - set fileSystemVisible(x) - { - if (x === this._fileSystemVisible) - return; - this._fileSystemVisible = x; - if (x) - this.element.addStyleClass("headers-visible"); - else - this.element.removeStyleClass("headers-visible"); - this._selectFileSystemTab(); - }, - - _update: function() - { - this._selectFileSystemTab(); - WebInspector.FileSystem.getFileSystemPathsAsync(this._origin); - }, - - updateFileSystemPath: function(root, type, origin) - { - if (origin == this._origin && type == WebInspector.FileSystem.PERSISTENT) { - this._persistentRoot = root; - this._persistentRootError = false; - } - - if (origin == this._origin && type == WebInspector.FileSystem.TEMPORARY) { - this._temporaryRoot = root; - this._temporaryRootErrorError = false; - } - - this.refreshFileSystem(); - }, - - updateFileSystemError: function(type, origin) - { - if (type == WebInspector.FileSystem.PERSISTENT) - this._persistentRootError = true; - - if (type == WebInspector.FileSystem.TEMPORARY) - this._temporaryRootError = true; - - this.refreshFileSystem(); - }, - - setFileSystemDisabled: function() - { - this._isFileSystemDisabled = true; - this.refreshFileSystem(); - }, - _selectFileSystemTab: function() - { - this._tabbedPane.selectTab("persistent"); - }, - - selectTemporaryFileSystemTab: function() - { - this._tabbedPane.selectTab("temp"); - }, - - _revealPersistentFolderInOS: function() - { - InspectorBackend.revealFolderInOS(this._persistentRoot); - }, - - _revealTemporaryFolderInOS: function() - { - InspectorBackend.revealFolderInOS(this._temporaryRoot); - }, - - _createTextAndButton: function(fileSystemElement, rootPathText, type, isError) - { - fileSystemElement.removeChildren(); - var rootPath = WebInspector.UIString("File System root path not available."); - if (this._isFileSystemDisabled) - rootPath = WebInspector.UIString("File System is disabled."); - else if (isError) - rootPath = WebInspector.UIString("Error in fetching root path for file system."); - else if (rootPathText) - rootPath = rootPathText; - - var rootTextNode = document.createTextNode("Root: " + rootPath.escapeHTML()); - var rootSystemElement = document.createElement("div"); - rootSystemElement.className = "header-value source-code"; - rootSystemElement.appendChild(rootTextNode); - fileSystemElement.appendChild(rootSystemElement); - - if (!isError && rootPathText) { - // Append Browse button iff root path is available and it is not an error. - var contentElement = document.createElement("div"); - contentElement.className = "panel-enabler-view-content"; - fileSystemElement.appendChild(contentElement); - var choicesForm = document.createElement("form"); - contentElement.appendChild(choicesForm); - var enableButton = document.createElement("button"); - enableButton.setAttribute("type", "button"); - enableButton.textContent = WebInspector.UIString("Reveal folder in OS"); - // FIXME: Bind this directly to InspectorBackend. - if (type == WebInspector.FileSystem.PERSISTENT) - enableButton.addEventListener("click", this._revealPersistentFolderInOS.bind(this), false); - if (type == WebInspector.FileSystem.TEMPORARY) - enableButton.addEventListener("click", this._revealTemporaryFolderInOS.bind(this), false); - choicesForm.appendChild(enableButton); - fileSystemElement.appendChild(contentElement); - } - }, - - refreshFileSystem: function() - { - this._createTextAndButton(this._persistentFileSystemElement, this._persistentRoot, WebInspector.FileSystem.PERSISTENT, this._persistentRootError); - this._createTextAndButton(this._tempFileSystemElement, this._temporaryRoot, WebInspector.FileSystem.TEMPORARY, this._temporaryRootError); - }, -} - -WebInspector.FileSystemView.prototype.__proto__ = WebInspector.View.prototype; diff --git a/Source/WebCore/inspector/front-end/GoToLineDialog.js b/Source/WebCore/inspector/front-end/GoToLineDialog.js index c96344c..f246159 100644 --- a/Source/WebCore/inspector/front-end/GoToLineDialog.js +++ b/Source/WebCore/inspector/front-end/GoToLineDialog.js @@ -45,7 +45,7 @@ WebInspector.GoToLineDialog = function(view) this._input = dialogWindow.createChild("input"); this._input.setAttribute("type", "text"); this._input.setAttribute("size", 6); - var linesCount = view.sourceFrame.textModel.linesCount; + var linesCount = view.textModel.linesCount; if (linesCount) this._input.setAttribute("title", WebInspector.UIString("1 - %d", linesCount)); var blurHandler = this._onBlur.bind(this); @@ -120,7 +120,7 @@ WebInspector.GoToLineDialog.prototype = { var value = this._input.value; var lineNumber = parseInt(value, 10); if (!isNaN(lineNumber) && lineNumber > 0) { - lineNumber = Math.min(lineNumber, this._view.sourceFrame.textModel.linesCount); + lineNumber = Math.min(lineNumber, this._view.textModel.linesCount); this._view.highlightLine(lineNumber); } } diff --git a/Source/WebCore/inspector/front-end/HeapSnapshot.js b/Source/WebCore/inspector/front-end/HeapSnapshot.js new file mode 100644 index 0000000..ef450af --- /dev/null +++ b/Source/WebCore/inspector/front-end/HeapSnapshot.js @@ -0,0 +1,909 @@ +/* + * 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.HeapSnapshotArraySlice = function(snapshot, arrayName, start, end) +{ + // Note: we don't reference snapshot contents directly to avoid + // holding references to big chunks of data. + this._snapshot = snapshot; + this._arrayName = arrayName; + this._start = start; + this.length = end - start; +} + +WebInspector.HeapSnapshotArraySlice.prototype = { + item: function(index) + { + return this._snapshot[this._arrayName][this._start + index]; + } +} + +WebInspector.HeapSnapshotEdge = function(snapshot, edges, edgeIndex) +{ + this._snapshot = snapshot; + this._edges = edges; + this.edgeIndex = edgeIndex || 0; +} + +WebInspector.HeapSnapshotEdge.prototype = { + clone: function() + { + return new WebInspector.HeapSnapshotEdge(this._snapshot, this._edges, this.edgeIndex); + }, + + get hasStringName() + { + if (!this.isShortcut) + return this._hasStringName; + return isNaN(parseInt(this._name, 10)); + }, + + get isElement() + { + return this._type() === this._snapshot._edgeElementType; + }, + + get isHidden() + { + return this._type() === this._snapshot._edgeHiddenType; + }, + + get isInternal() + { + return this._type() === this._snapshot._edgeInternalType; + }, + + get isShortcut() + { + return this._type() === this._snapshot._edgeShortcutType; + }, + + get name() + { + if (!this.isShortcut) + return this._name; + var numName = parseInt(this._name, 10); + return isNaN(numName) ? this._name : numName; + }, + + get node() + { + return new WebInspector.HeapSnapshotNode(this._snapshot, this.nodeIndex); + }, + + get nodeIndex() + { + return this._edges.item(this.edgeIndex + this._snapshot._edgeToNodeOffset); + }, + + get rawEdges() + { + return this._edges; + }, + + toString: function() + { + switch (this.type) { + case "context": return "->" + this.name; + case "element": return "[" + this.name + "]"; + case "property": + return this.name.indexOf(" ") === -1 ? "." + this.name : "[\"" + this.name + "\"]"; + case "shortcut": + var name = this.name; + if (typeof name === "string") + return this.name.indexOf(" ") === -1 ? "." + this.name : "[\"" + this.name + "\"]"; + else + return "[" + this.name + "]"; + case "internal": + case "hidden": + return "{" + this.name + "}"; + }; + return "?" + this.name + "?"; + }, + + get type() + { + return this._snapshot._edgeTypes[this._type()]; + }, + + get _hasStringName() + { + return !this.isElement && !this.isHidden; + }, + + get _name() + { + return this._hasStringName ? this._snapshot._strings[this._nameOrIndex] : this._nameOrIndex; + }, + + get _nameOrIndex() + { + return this._edges.item(this.edgeIndex + this._snapshot._edgeNameOffset); + }, + + _type: function() + { + return this._edges.item(this.edgeIndex + this._snapshot._edgeTypeOffset); + } +}; + +WebInspector.HeapSnapshotEdgeIterator = function(edge) +{ + this.edge = edge; +} + +WebInspector.HeapSnapshotEdgeIterator.prototype = { + first: function() + { + this.edge.edgeIndex = 0; + }, + + hasNext: function() + { + return this.edge.edgeIndex < this.edge._edges.length; + }, + + get index() + { + return this.edge.edgeIndex; + }, + + set index(newIndex) + { + this.edge.edgeIndex = newIndex; + }, + + get item() + { + return this.edge; + }, + + next: function() + { + this.edge.edgeIndex += this.edge._snapshot._edgeFieldsCount; + } +}; + +WebInspector.HeapSnapshotNode = function(snapshot, nodeIndex) +{ + this._snapshot = snapshot; + this._firstNodeIndex = nodeIndex; + this.nodeIndex = nodeIndex; +} + +WebInspector.HeapSnapshotNode.prototype = { + get className() + { + switch (this.type) { + case "hidden": + return WebInspector.UIString("(system)"); + case "object": + return this.name; + case "code": + return WebInspector.UIString("(compiled code)"); + default: + return "(" + this.type + ")"; + } + }, + + dominatorIndex: function() + { + return this._nodes[this.nodeIndex + this._snapshot._dominatorOffset]; + }, + + get edges() + { + return new WebInspector.HeapSnapshotEdgeIterator(new WebInspector.HeapSnapshotEdge(this._snapshot, this.rawEdges)); + }, + + get edgesCount() + { + return this._nodes[this.nodeIndex + this._snapshot._edgesCountOffset]; + }, + + get id() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeIdOffset]; + }, + + get instancesCount() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeInstancesCountOffset]; + }, + + get isHidden() + { + return this._type() === this._snapshot._nodeHiddenType; + }, + + get isRoot() + { + return this.nodeIndex === this._snapshot._rootNodeIndex; + }, + + get name() + { + return this._snapshot._strings[this._name()]; + }, + + get rawEdges() + { + var firstEdgeIndex = this._firstEdgeIndex(); + return new WebInspector.HeapSnapshotArraySlice(this._snapshot, "_nodes", firstEdgeIndex, firstEdgeIndex + this.edgesCount * this._snapshot._edgeFieldsCount); + }, + + get retainedSize() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeRetainedSizeOffset]; + }, + + get retainers() + { + return new WebInspector.HeapSnapshotEdgeIterator(new WebInspector.HeapSnapshotEdge(this._snapshot, this._snapshot.retainers(this))); + }, + + get selfSize() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeSelfSizeOffset]; + }, + + get type() + { + return this._snapshot._nodeTypes[this._type()]; + }, + + _name: function() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeNameOffset]; + }, + + get _nodes() + { + return this._snapshot._nodes; + }, + + _firstEdgeIndex: function() + { + return this.nodeIndex + this._snapshot._firstEdgeOffset; + }, + + get _nextNodeIndex() + { + return this._firstEdgeIndex() + this.edgesCount * this._snapshot._edgeFieldsCount; + }, + + _type: function() + { + return this._nodes[this.nodeIndex + this._snapshot._nodeTypeOffset]; + } +}; + +WebInspector.HeapSnapshotNodeIterator = function(node) +{ + this.node = node; +} + +WebInspector.HeapSnapshotNodeIterator.prototype = { + first: function() + { + this.node.nodeIndex = this.node._firstNodeIndex; + }, + + hasNext: function() + { + return this.node.nodeIndex < this.node._nodes.length; + }, + + get index() + { + return this.node.nodeIndex; + }, + + set index(newIndex) + { + this.node.nodeIndex = newIndex; + }, + + get item() + { + return this.node; + }, + + next: function() + { + this.node.nodeIndex = this.node._nextNodeIndex; + } +} + +WebInspector.HeapSnapshot = function(profile) +{ + this._nodes = profile.nodes; + this._strings = profile.strings; + + this._init(); +} + +WebInspector.HeapSnapshot.prototype = { + _init: function() + { + this._metaNodeIndex = 0; + this._rootNodeIndex = 1; + var meta = this._nodes[this._metaNodeIndex]; + this._nodeTypeOffset = meta.fields.indexOf("type"); + this._nodeNameOffset = meta.fields.indexOf("name"); + this._nodeIdOffset = meta.fields.indexOf("id"); + this._nodeInstancesCountOffset = this._nodeIdOffset; + this._nodeSelfSizeOffset = meta.fields.indexOf("self_size"); + this._nodeRetainedSizeOffset = meta.fields.indexOf("retained_size"); + this._dominatorOffset = meta.fields.indexOf("dominator"); + this._edgesCountOffset = meta.fields.indexOf("children_count"); + this._firstEdgeOffset = meta.fields.indexOf("children"); + this._nodeTypes = meta.types[this._nodeTypeOffset]; + this._nodeHiddenType = this._nodeTypes.indexOf("hidden"); + var edgesMeta = meta.types[this._firstEdgeOffset]; + this._edgeFieldsCount = edgesMeta.fields.length; + this._edgeTypeOffset = edgesMeta.fields.indexOf("type"); + this._edgeNameOffset = edgesMeta.fields.indexOf("name_or_index"); + this._edgeToNodeOffset = edgesMeta.fields.indexOf("to_node"); + this._edgeTypes = edgesMeta.types[this._edgeTypeOffset]; + this._edgeElementType = this._edgeTypes.indexOf("element"); + this._edgeHiddenType = this._edgeTypes.indexOf("hidden"); + this._edgeInternalType = this._edgeTypes.indexOf("internal"); + this._edgeShortcutType = this._edgeTypes.indexOf("shortcut"); + }, + + dispose: function() + { + delete this._nodes; + delete this._strings; + if (this._idsMap) + delete this._idsMap; + if (this._retainers) { + delete this._retainers; + delete this._nodesToRetainers; + } + if (this._aggregates) { + delete this._aggregates; + this._aggregatesWithIndexes = false; + } + }, + + get allNodes() + { + return new WebInspector.HeapSnapshotNodeIterator(this.rootNode); + }, + + get nodesCount() + { + if (this._nodesCount) + return this._nodesCount; + + this._nodesCount = 0; + for (var iter = this.allNodes; iter.hasNext(); iter.next()) + ++this._nodesCount; + return this._nodesCount; + }, + + restore: function(profile) + { + this._nodes = profile.nodes; + this._strings = profile.strings; + }, + + get rootNode() + { + return new WebInspector.HeapSnapshotNode(this, this._rootNodeIndex); + }, + + get totalSize() + { + return this.rootNode.retainedSize; + }, + + get idsMap() + { + if (this._idsMap) + return this._idsMap; + + this._idsMap = []; + for (var iter = this.allNodes; iter.hasNext(); iter.next()) { + this._idsMap[iter.node.id] = true; + } + return this._idsMap; + }, + + retainers: function(node) + { + if (!this._retainers) + this._buildRetainers(); + + var retIndexFrom = this._nodesToRetainers[node.nodeIndex]; + var retIndexTo = this._nodesToRetainers[node._nextNodeIndex]; + return new WebInspector.HeapSnapshotArraySlice(this, "_retainers", retIndexFrom, retIndexTo); + }, + + aggregates: function(withNodeIndexes) + { + if (!this._aggregates) + this._buildAggregates(); + if (withNodeIndexes && !this._aggregatesWithIndexes) + this._buildAggregatesIndexes(); + return this._aggregates; + }, + + _buildRetainers: function() + { + this._nodesToRetainers = []; + for (var nodesIter = this.allNodes; nodesIter.hasNext(); nodesIter.next()) { + var node = nodesIter.node; + if (!(node.nodeIndex in this._nodesToRetainers)) + this._nodesToRetainers[node.nodeIndex] = 0; + for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next()) { + var edge = edgesIter.edge; + var nodeIndex = edge.nodeIndex; + if (!(nodeIndex in this._nodesToRetainers)) + this._nodesToRetainers[nodeIndex] = 0; + this._nodesToRetainers[nodeIndex] += this._edgeFieldsCount; + } + } + nodesIter = this.allNodes; + var node = nodesIter.node; + var prevIndex = this._nodesToRetainers[node.nodeIndex] = 0; + var prevRetsCount = this._nodesToRetainers[node.nodeIndex]; + nodesIter.next(); + for (; nodesIter.hasNext(); nodesIter.next()) { + node = nodesIter.node; + var savedRefsCount = this._nodesToRetainers[node.nodeIndex]; + this._nodesToRetainers[node.nodeIndex] = prevIndex + prevRetsCount; + prevIndex = this._nodesToRetainers[node.nodeIndex]; + prevRetsCount = savedRefsCount; + } + this._retainers = new Array(prevIndex + prevRetsCount); + this._nodesToRetainers[this._nodes.length] = this._retainers.length; + for (nodesIter = this.allNodes; nodesIter.hasNext(); nodesIter.next()) { + node = nodesIter.node; + var retsCount = this._nodesToRetainers[node._nextNodeIndex] - this._nodesToRetainers[node.nodeIndex]; + if (retsCount > 0) { + this._retainers[this._nodesToRetainers[node.nodeIndex]] = retsCount; + } + } + for (nodesIter = this.allNodes; nodesIter.hasNext(); nodesIter.next()) { + node = nodesIter.node; + for (var edgesIter = node.edges; edgesIter.hasNext(); edgesIter.next()) { + var edge = edgesIter.edge; + var nodeIndex = edge.nodeIndex; + var retIndex = this._nodesToRetainers[nodeIndex]; + this._retainers[retIndex] -= this._edgeFieldsCount; + var idx = retIndex + this._retainers[retIndex]; + this._retainers[idx + this._edgeTypeOffset] = edge._type(); + this._retainers[idx + this._edgeNameOffset] = edge._nameOrIndex; + this._retainers[idx + this._edgeToNodeOffset] = node.nodeIndex; + } + } + }, + + _buildAggregates: function() + { + this._aggregates = {}; + for (var iter = this.allNodes; iter.hasNext(); iter.next()) { + var node = iter.node; + var className = node.className; + var nameMatters = node.type === "object"; + if (node.selfSize === 0) + continue; + if (!(className in this._aggregates)) + this._aggregates[className] = { count: 0, self: 0, maxRet: 0, type: node.type, name: nameMatters ? node.name : null, idxs: [] }; + var clss = this._aggregates[className]; + ++clss.count; + clss.self += node.selfSize; + if (node.retainedSize > clss.maxRet) + clss.maxRet = node.retainedSize; + } + }, + + _buildAggregatesIndexes: function() + { + for (var iter = this.allNodes; iter.hasNext(); iter.next()) { + var node = iter.node; + var className = node.className; + var clss = this._aggregates[className]; + if (clss) + clss.idxs.push(node.nodeIndex); + } + + var nodeA = new WebInspector.HeapSnapshotNode(this); + var nodeB = new WebInspector.HeapSnapshotNode(this); + for (var clss in this._aggregates) + this._aggregates[clss].idxs.sort( + function(idxA, idxB) { + nodeA.nodeIndex = idxA; + nodeB.nodeIndex = idxB; + return nodeA.id < nodeB.id ? -1 : 1; + }); + + this._aggregatesWithIndexes = true; + } +}; + +WebInspector.HeapSnapshotFilteredOrderedIterator = function(snapshot, iterator, filter) +{ + this._snapshot = snapshot; + this._filter = filter; + this._iterator = iterator; + this._iterationOrder = null; + this._position = 0; + this._lastComparator = null; +} + +WebInspector.HeapSnapshotFilteredOrderedIterator.prototype = { + _createIterationOrder: function() + { + this._iterationOrder = []; + var iterator = this._iterator; + if (!this._filter) { + for (iterator.first(); iterator.hasNext(); iterator.next()) + this._iterationOrder.push(iterator.index); + } else { + for (iterator.first(); iterator.hasNext(); iterator.next()) { + if (this._filter(iterator.item)) + this._iterationOrder.push(iterator.index); + } + } + }, + + first: function() + { + this._position = 0; + }, + + hasNext: function() + { + return this._position < this._iterationOrder.length; + }, + + get isEmpty() + { + if (this._iterationOrder) + return !this._iterationOrder.length; + var iterator = this._iterator; + if (!this._filter) { + iterator.first(); + return !iterator.hasNext(); + } + for (iterator.first(); iterator.hasNext(); iterator.next()) + if (this._filter(iterator.item)) return false; + return true; + }, + + get item() + { + this._iterator.index = this._iterationOrder[this._position]; + return this._iterator.item; + }, + + get lastComparator() + { + return this._lastComparator; + }, + + get length() + { + if (!this._iterationOrder) + this._createIterationOrder(); + return this._iterationOrder.length; + }, + + next: function() + { + ++this._position; + } +} + +WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator = function(fieldNames) +{ + return {fieldName1:fieldNames[0], ascending1:fieldNames[1], fieldName2:fieldNames[2], ascending2:fieldNames[3]}; +} + +WebInspector.HeapSnapshotEdgesProvider = function(snapshot, rawEdges, filter) +{ + WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot, new WebInspector.HeapSnapshotEdgeIterator(new WebInspector.HeapSnapshotEdge(snapshot, rawEdges)), filter); +} + +WebInspector.HeapSnapshotEdgesProvider.prototype = { + sort: function(comparator) + { + if (this._lastComparator === comparator) + return false; + this._lastComparator = comparator; + var fieldName1 = comparator.fieldName1; + var fieldName2 = comparator.fieldName2; + var ascending1 = comparator.ascending1; + var ascending2 = comparator.ascending2; + + var edgeA = this._iterator.item.clone(); + var edgeB = edgeA.clone(); + var nodeA = new WebInspector.HeapSnapshotNode(this._snapshot); + var nodeB = new WebInspector.HeapSnapshotNode(this._snapshot); + + function sortByEdgeFieldName(ascending, indexA, indexB) + { + edgeA.edgeIndex = indexA; + edgeB.edgeIndex = indexB; + if (edgeB.name === "__proto__") return -1; + if (edgeA.name === "__proto__") return 1; + var result = + edgeA.hasStringName === edgeB.hasStringName ? + (edgeA.name < edgeB.name ? -1 : (edgeA.name > edgeB.name ? 1 : 0)) : + (edgeA.hasStringName ? -1 : 1); + return ascending ? result : -result; + } + + function sortByNodeField(fieldName, ascending, indexA, indexB) + { + edgeA.edgeIndex = indexA; + edgeB.edgeIndex = indexB; + nodeA.nodeIndex = edgeA.nodeIndex; + nodeB.nodeIndex = edgeB.nodeIndex; + var valueA = nodeA[fieldName]; + var valueB = nodeB[fieldName]; + var result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0); + return ascending ? result : -result; + } + + if (!this._iterationOrder) + this._createIterationOrder(); + + function sortByEdgeAndNode(indexA, indexB) { + var result = sortByEdgeFieldName(ascending1, indexA, indexB); + if (result === 0) + result = sortByNodeField(fieldName2, ascending2, indexA, indexB); + return result; + } + + function sortByNodeAndEdge(indexA, indexB) { + var result = sortByNodeField(fieldName1, ascending1, indexA, indexB); + if (result === 0) + result = sortByEdgeFieldName(ascending2, indexA, indexB); + return result; + } + + function sortByNodeAndNode(indexA, indexB) { + var result = sortByNodeField(fieldName1, ascending1, indexA, indexB); + if (result === 0) + result = sortByNodeField(fieldName2, ascending2, indexA, indexB); + return result; + } + + if (fieldName1 === "!edgeName") + this._iterationOrder.sort(sortByEdgeAndNode); + else if (fieldName2 === "!edgeName") + this._iterationOrder.sort(sortByNodeAndEdge); + else + this._iterationOrder.sort(sortByNodeAndNode); + return true; + } +}; + +WebInspector.HeapSnapshotEdgesProvider.prototype.__proto__ = WebInspector.HeapSnapshotFilteredOrderedIterator.prototype; + +WebInspector.HeapSnapshotNodesProvider = function(snapshot, nodes, filter) +{ + WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot, nodes, filter); +} + +WebInspector.HeapSnapshotNodesProvider.prototype = { + sort: function(comparator) + { + if (this._lastComparator === comparator) + return false; + this._lastComparator = comparator; + var fieldName1 = comparator.fieldName1; + var fieldName2 = comparator.fieldName2; + var ascending1 = comparator.ascending1; + var ascending2 = comparator.ascending2; + + var nodeA = new WebInspector.HeapSnapshotNode(this._snapshot); + var nodeB = new WebInspector.HeapSnapshotNode(this._snapshot); + + function sortByNodeField(fieldName, ascending, indexA, indexB) + { + nodeA.nodeIndex = indexA; + nodeB.nodeIndex = indexB; + var valueA = nodeA[fieldName]; + var valueB = nodeB[fieldName]; + var result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0); + return ascending ? result : -result; + } + + if (!this._iterationOrder) + this._createIterationOrder(); + + function sortByComparator(indexA, indexB) { + var result = sortByNodeField(fieldName1, ascending1, indexA, indexB); + if (result === 0) + result = sortByNodeField(fieldName2, ascending2, indexA, indexB); + return result; + } + + this._iterationOrder.sort(sortByComparator); + return true; + } +}; + +WebInspector.HeapSnapshotNodesProvider.prototype.__proto__ = WebInspector.HeapSnapshotFilteredOrderedIterator.prototype; + +WebInspector.HeapSnapshotPathFinder = function(snapshot, targetNodeIndex) +{ + this._snapshot = snapshot; + this._maxLength = 1; + this._lengthLimit = 15; + this._targetNodeIndex = targetNodeIndex; + this._currentPath = null; + this._skipHidden = !WebInspector.DetailedHeapshotView.prototype.showHiddenData; + this._rootChildren = this._fillRootChildren(); +} + +WebInspector.HeapSnapshotPathFinder.prototype = { + findNext: function() + { + for (var i = 0; i < 100000; ++i) { + if (!this._buildNextPath()) { + if (++this._maxLength >= this._lengthLimit) + return null; + this._currentPath = null; + if (!this._buildNextPath()) + return null; + } + if (this._isPathFound()) + return {path:this._pathToString(this._currentPath), len:this._currentPath.length}; + } + + return false; + }, + + _fillRootChildren: function() + { + var result = []; + for (var iter = this._snapshot.rootNode.edges; iter.hasNext(); iter.next()) + result[iter.edge.nodeIndex] = true; + return result; + }, + + _appendToCurrentPath: function(iter) + { + this._currentPath._cache[this._lastEdge.nodeIndex] = true; + this._currentPath.push(iter); + }, + + _removeLastFromCurrentPath: function() + { + this._currentPath.pop(); + delete this._currentPath._cache[this._lastEdge.nodeIndex]; + }, + + _hasInPath: function(nodeIndex) + { + return this._targetNodeIndex === nodeIndex + || !!this._currentPath._cache[nodeIndex]; + }, + + _isPathFound: function() + { + return this._currentPath.length === this._maxLength + && this._lastEdge.nodeIndex in this._rootChildren; + }, + + get _lastEdgeIter() + { + return this._currentPath[this._currentPath.length - 1]; + }, + + get _lastEdge() + { + return this._lastEdgeIter.edge; + }, + + _skipEdge: function(edge) + { + return (this._skipHidden && (edge.isHidden || edge.node.isHidden)) + || this._hasInPath(edge.nodeIndex); + }, + + _nextEdgeIter: function() + { + var iter = this._lastEdgeIter; + while (this._skipEdge(iter.edge) && iter.hasNext()) + iter.next(); + return iter; + }, + + _buildNextPath: function() + { + if (this._currentPath !== null) { + var iter = this._lastEdgeIter; + while (true) { + iter.next(); + if (iter.hasNext()) + return true; + while (true) { + if (this._currentPath.length > 1) { + this._removeLastFromCurrentPath(); + iter = this._lastEdgeIter; + iter.next(); + iter = this._nextEdgeIter(); + if (iter.hasNext()) { + while (this._currentPath.length < this._maxLength) { + iter = this._nextEdgeIter(); + if (iter.hasNext()) + this._appendToCurrentPath(iter.edge.node.retainers); + else + return true; + } + return true; + } + } else + return false; + } + } + } else { + var node = new WebInspector.HeapSnapshotNode(this._snapshot, this._targetNodeIndex); + this._currentPath = [node.retainers]; + this._currentPath._cache = {}; + while (this._currentPath.length < this._maxLength) { + var iter = this._nextEdgeIter(); + if (iter.hasNext()) + this._appendToCurrentPath(iter.edge.node.retainers); + else + break; + } + return true; + } + }, + + _nodeToString: function(node) + { + if (node.id === 1) + return node.name; + else + return node.name + "@" + node.id; + }, + + _pathToString: function(path) + { + if (!path) + return ""; + var sPath = []; + for (var j = 0; j < path.length; ++j) + sPath.push(path[j].edge.toString()); + sPath.push(this._nodeToString(path[path.length - 1].edge.node)); + sPath.reverse(); + return sPath.join(""); + } +}; diff --git a/Source/WebCore/inspector/front-end/HeapSnapshotView.js b/Source/WebCore/inspector/front-end/HeapSnapshotView.js index f349361..44b95c3 100644 --- a/Source/WebCore/inspector/front-end/HeapSnapshotView.js +++ b/Source/WebCore/inspector/front-end/HeapSnapshotView.js @@ -27,154 +27,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.HeapSnapshotEdgesIterator = function(snapshot, edges) -{ - this._snapshot = snapshot; - this._edges = edges; - this._edgeIndex = 0; -} - -WebInspector.HeapSnapshotEdgesIterator.prototype = { - get done() - { - return this._edgeIndex >= this._edges.length; - }, - - get isElement() - { - return this._getType() === this._snapshot._edgeElementType; - }, - - get isHidden() - { - return this._getType() === this._snapshot._edgeHiddenType; - }, - - get name() - { - return this.isElement || this.isHidden ? this._getNameOrIndex() : this._snapshot._strings[this._getNameOrIndex()]; - }, - - next: function() - { - this._edgeIndex += this._snapshot._edgeFieldsCount; - }, - - get node() - { - return new WebInspector.HeapSnapshotNodeWrapper(this._snapshot, this.nodeIndex); - }, - - get nodeIndex() - { - return this._edges[this._edgeIndex + this._snapshot._edgeToNodeOffset]; - }, - - _getNameOrIndex: function() - { - return this._edges[this._edgeIndex + this._snapshot._edgeNameOffset]; - }, - - _getType: function() - { - return this._edges[this._edgeIndex + this._snapshot._edgeTypeOffset]; - } -}; - -WebInspector.HeapSnapshotNodeWrapper = function(snapshot, nodeIndex) -{ - this._snapshot = snapshot; - this._nodes = snapshot._nodes; - this._nodeIndex = nodeIndex; -} - -WebInspector.HeapSnapshotNodeWrapper.prototype = { - get edges() - { - return new WebInspector.HeapSnapshotEdgesIterator(this._snapshot, this._getEdges()); - }, - - get edgesCount() - { - return this._nodes[this._nodeIndex + this._snapshot._edgesCountOffset]; - }, - - get instancesCount() - { - return this._nodes[this._nodeIndex + this._snapshot._nodeInstancesCountOffset]; - }, - - get isHidden() - { - return this._getType() === this._snapshot._nodeHiddenType; - }, - - get name() - { - return this._snapshot._strings[this._getName()]; - }, - - get selfSize() - { - return this._nodes[this._nodeIndex + this._snapshot._nodeSelfSizeOffset]; - }, - - _getName: function() - { - return this._nodes[this._nodeIndex + this._snapshot._nodeNameOffset]; - }, - - _getEdges: function() - { - var firstEdgeIndex = this._nodeIndex + this._snapshot._firstEdgeOffset; - return this._nodes.slice(firstEdgeIndex, firstEdgeIndex + this.edgesCount * this._snapshot._edgeFieldsCount); - }, - - _getType: function() - { - return this._nodes[this._nodeIndex + this._snapshot._nodeTypeOffset]; - } -}; - -WebInspector.HeapSnapshot = function(profile) -{ - this._profile = profile; - this._nodes = profile.nodes; - this._strings = profile.strings; - - this._init(); -} - -WebInspector.HeapSnapshot.prototype = { - _init: function() - { - this._metaNodeIndex = 0; - this._rootNodeIndex = 1; - var meta = this._nodes[this._metaNodeIndex]; - this._nodeTypeOffset = meta.fields.indexOf("type"); - this._nodeNameOffset = meta.fields.indexOf("name"); - this._nodeIdOffset = meta.fields.indexOf("id"); - this._nodeInstancesCountOffset = this._nodeIdOffset; - this._nodeSelfSizeOffset = meta.fields.indexOf("self_size"); - this._edgesCountOffset = meta.fields.indexOf("children_count"); - this._firstEdgeOffset = meta.fields.indexOf("children"); - this._nodeTypes = meta.types[this._nodeTypeOffset]; - this._nodeHiddenType = this._nodeTypes.indexOf("hidden"); - var edgesMeta = meta.types[this._firstEdgeOffset]; - this._edgeFieldsCount = edgesMeta.fields.length; - this._edgeTypeOffset = edgesMeta.fields.indexOf("type"); - this._edgeNameOffset = edgesMeta.fields.indexOf("name_or_index"); - this._edgeToNodeOffset = edgesMeta.fields.indexOf("to_node"); - this._edgeTypes = edgesMeta.types[this._edgeTypeOffset]; - this._edgeElementType = this._edgeTypes.indexOf("element"); - this._edgeHiddenType = this._edgeTypes.indexOf("hidden"); - }, - - get rootEdges() - { - return (new WebInspector.HeapSnapshotNodeWrapper(this, this._rootNodeIndex)).edges; - } -}; WebInspector.HeapSnapshotView = function(parent, profile) { @@ -246,7 +98,7 @@ WebInspector.HeapSnapshotView = function(parent, profile) function profileCallback(profile) { - var list = this._getProfiles(); + var list = this._profiles(); var profileIndex; for (var i = 0; i < list.length; ++i) if (list[i].uid === profile.uid) { @@ -440,7 +292,7 @@ WebInspector.HeapSnapshotView.prototype = { _changeBase: function() { - if (this.baseSnapshot.uid === this._getProfiles()[this.baseSelectElement.selectedIndex].uid) + if (this.baseSnapshot.uid === this._profiles()[this.baseSelectElement.selectedIndex].uid) return; this._resetDataGridList(resetCompleted.bind(this)); @@ -468,7 +320,7 @@ WebInspector.HeapSnapshotView.prototype = { return this._snapshotDataGridList; }, - _getProfiles: function() + _profiles: function() { return WebInspector.panels.profiles.getProfiles(WebInspector.HeapSnapshotProfileType.TypeId); }, @@ -530,17 +382,20 @@ WebInspector.HeapSnapshotView.prototype = { { var snapshot = new WebInspector.HeapSnapshot(loadedSnapshot); var result = {lowlevels: {}, entries: {}, children: {}}; - for (var rootEdges = snapshot.rootEdges; !rootEdges.done; rootEdges.next()) { - var node = rootEdges.node; + var rootEdgesIter = snapshot.rootNode.edges; + for (var iter = rootEdgesIter; iter.hasNext(); iter.next()) { + var node = iter.edge.node; if (node.isHidden) result.lowlevels[node.name] = {count: node.instancesCount, size: node.selfSize, type: node.name}; else if (node.instancesCount) result.entries[node.name] = {constructorName: node.name, count: node.instancesCount, size: node.selfSize}; else { var entry = {constructorName: node.name}; - for (var edges = node.edges; !edges.done; edges.next()) - entry[edges.nodeIndex] = {constructorName: edges.node.name, count: edges.name}; - result.children[rootEdges.nodeIndex] = entry; + for (var innerIter = node.edges; innerIter.hasNext(); innerIter.next()) { + var edge = innerIter.edge; + entry[edge.nodeIndex] = {constructorName: edge.node.name, count: edge.name}; + } + result.children[rootEdgesIter.edge.nodeIndex] = entry; } } return result; @@ -581,7 +436,7 @@ WebInspector.HeapSnapshotView.prototype = { _resetDataGridList: function(callback) { - this._loadProfile(this._getProfiles()[this.baseSelectElement.selectedIndex], profileLoaded.bind(this)); + this._loadProfile(this._profiles()[this.baseSelectElement.selectedIndex], profileLoaded.bind(this)); function profileLoaded(profile) { @@ -601,10 +456,10 @@ WebInspector.HeapSnapshotView.prototype = { var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; var sortProperty = { cons: ["constructorName", null], - count: ["count", null], - size: ["size", "count"], - countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null], - sizeDelta: this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"] + count: ["count", "constructorName"], + size: ["size", "constructorName"], + countDelta: [this.showCountDeltaAsPercent ? "countDeltaPercent" : "countDelta", "constructorName"], + sizeDelta: [this.showSizeDeltaAsPercent ? "sizeDeltaPercent" : "sizeDelta", "constructorName"] }[sortColumnIdentifier]; this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending)); @@ -614,7 +469,7 @@ WebInspector.HeapSnapshotView.prototype = { _updateBaseOptions: function() { - var list = this._getProfiles(); + var list = this._profiles(); // We're assuming that snapshots can only be added. if (this.baseSelectElement.length === list.length) return; @@ -1046,10 +901,17 @@ WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, pr if (!comparator) { comparator = function(lhs, rhs) { var l = lhs[property], r = rhs[property]; - if ((l === null || r === null) && property2 !== null) - l = lhs[property2], r = rhs[property2]; - var result = l < r ? -1 : (l > r ? 1 : 0); - return isAscending ? result : -result; + var result = 0; + if (l !== null && r !== null) { + result = l < r ? -1 : (l > r ? 1 : 0); + } + if (result !== 0 || property2 === null) { + return isAscending ? result : -result; + } else { + l = lhs[property2]; + r = rhs[property2]; + return l < r ? -1 : (l > r ? 1 : 0); + } }; this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator; } @@ -1148,7 +1010,7 @@ WebInspector.HeapSnapshotProfileType.prototype = { buttonClicked: function() { - InspectorBackend.takeHeapSnapshot(); + InspectorBackend.takeHeapSnapshot(false); }, get welcomeMessage() diff --git a/Source/WebCore/inspector/front-end/NetworkManager.js b/Source/WebCore/inspector/front-end/NetworkManager.js index ed4309e..da043fe 100644 --- a/Source/WebCore/inspector/front-end/NetworkManager.js +++ b/Source/WebCore/inspector/front-end/NetworkManager.js @@ -31,86 +31,114 @@ WebInspector.NetworkManager = function(resourceTreeModel) { WebInspector.Object.call(this); - - this._inflightResources = {}; this._resourceTreeModel = resourceTreeModel; - this._lastIdentifierForCachedResource = 0; - InspectorBackend.registerDomainDispatcher("Network", this); + this._dispatcher = new WebInspector.NetworkDispatcher(resourceTreeModel, this); + InspectorBackend.cachedResources(this._processCachedResources.bind(this)); } -WebInspector.NetworkManager.requestContent = function(resource, base64Encode, callback) -{ - InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callback); -} - -WebInspector.NetworkManager.updateResourceWithRequest = function(resource, request) -{ - resource.requestMethod = request.httpMethod; - resource.requestHeaders = request.httpHeaderFields; - resource.requestFormData = request.requestFormData; +WebInspector.NetworkManager.EventTypes = { + ResourceStarted: "ResourceStarted", + ResourceUpdated: "ResourceUpdated", + ResourceFinished: "ResourceFinished", + MainResourceCommitLoad: "MainResourceCommitLoad" } -WebInspector.NetworkManager.updateResourceWithResponse = function(resource, response) -{ - if (resource.isNull) - return; +WebInspector.NetworkManager.prototype = { + reset: function() + { + WebInspector.panels.network.clear(); + this._resourceTreeModel.reset(); + InspectorBackend.cachedResources(this._processCachedResources.bind(this)); + }, - resource.mimeType = response.mimeType; - resource.expectedContentLength = response.expectedContentLength; - resource.textEncodingName = response.textEncodingName; - resource.suggestedFilename = response.suggestedFilename; - resource.statusCode = response.httpStatusCode; - resource.statusText = response.httpStatusText; + requestContent: function(resource, base64Encode, callback) + { + function callbackWrapper(success, content) + { + callback(success ? content : null); + } + InspectorBackend.resourceContent(resource.loader.frameId, resource.url, base64Encode, callbackWrapper); + }, - resource.responseHeaders = response.httpHeaderFields; - resource.connectionReused = response.connectionReused; - resource.connectionID = response.connectionID; + _processCachedResources: function(mainFramePayload) + { + var mainResource = this._dispatcher._addFramesRecursively(mainFramePayload); + WebInspector.mainResource = mainResource; + mainResource.isMainResource = true; + }, - if (response.wasCached) - resource.cached = true; - else - resource.timing = response.timing; - - if (response.loadInfo) { - if (response.loadInfo.httpStatusCode) - resource.statusCode = response.loadInfo.httpStatusCode; - if (response.loadInfo.httpStatusText) - resource.statusText = response.loadInfo.httpStatusText; - resource.requestHeaders = response.loadInfo.requestHeaders; - resource.responseHeaders = response.loadInfo.responseHeaders; + inflightResourceForURL: function(url) + { + return this._dispatcher._inflightResourcesByURL[url]; } } -WebInspector.NetworkManager.updateResourceWithCachedResource = function(resource, cachedResource) +WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.NetworkDispatcher = function(resourceTreeModel, manager) { - resource.type = WebInspector.Resource.Type[cachedResource.type]; - resource.resourceSize = cachedResource.encodedSize; - WebInspector.NetworkManager.updateResourceWithResponse(resource, cachedResource.response); + this._manager = manager; + this._inflightResourcesById = {}; + this._inflightResourcesByURL = {}; + this._resourceTreeModel = resourceTreeModel; + this._lastIdentifierForCachedResource = 0; + InspectorBackend.registerDomainDispatcher("Network", this); } -WebInspector.NetworkManager.EventTypes = { - ResourceStarted: "ResourceStarted", - ResourceUpdated: "ResourceUpdated", - ResourceFinished: "ResourceFinished", - MainResourceCommitLoad: "MainResourceCommitLoad" -} +WebInspector.NetworkDispatcher.prototype = { + _updateResourceWithRequest: function(resource, request) + { + resource.requestMethod = request.httpMethod; + resource.requestHeaders = request.httpHeaderFields; + resource.requestFormData = request.requestFormData; + }, -WebInspector.NetworkManager.prototype = { - reset: function() + _updateResourceWithResponse: function(resource, response) { - WebInspector.panels.network.clear(); - WebInspector.panels.resources.clear(); - this._resourceTreeModel.reloadCachedResources(); + if (resource.isNull) + return; + + resource.mimeType = response.mimeType; + resource.expectedContentLength = response.expectedContentLength; + resource.textEncodingName = response.textEncodingName; + resource.suggestedFilename = response.suggestedFilename; + resource.statusCode = response.httpStatusCode; + resource.statusText = response.httpStatusText; + + resource.responseHeaders = response.httpHeaderFields; + resource.connectionReused = response.connectionReused; + resource.connectionID = response.connectionID; + + if (response.wasCached) + resource.cached = true; + else + resource.timing = response.timing; + + if (response.loadInfo) { + if (response.loadInfo.httpStatusCode) + resource.statusCode = response.loadInfo.httpStatusCode; + if (response.loadInfo.httpStatusText) + resource.statusText = response.loadInfo.httpStatusText; + resource.requestHeaders = response.loadInfo.requestHeaders; + resource.responseHeaders = response.loadInfo.responseHeaders; + } + }, + + _updateResourceWithCachedResource: function(resource, cachedResource) + { + resource.type = WebInspector.Resource.Type[cachedResource.type]; + resource.resourceSize = cachedResource.encodedSize; + this._updateResourceWithResponse(resource, cachedResource.response); }, identifierForInitialRequest: function(identifier, url, loader, callStack) { - this._startResource(this._resourceTreeModel.createResource(identifier, url, loader, callStack)); + this._startResource(this._createResource(identifier, url, loader, callStack)); }, willSendRequest: function(identifier, time, request, redirectResponse) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -122,7 +150,7 @@ WebInspector.NetworkManager.prototype = { resource = this._appendRedirect(resource.identifier, time, request.url); } - WebInspector.NetworkManager.updateResourceWithRequest(resource, request); + this._updateResourceWithRequest(resource, request); resource.startTime = time; if (isRedirect) @@ -133,7 +161,7 @@ WebInspector.NetworkManager.prototype = { markResourceAsCached: function(identifier) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -143,14 +171,14 @@ WebInspector.NetworkManager.prototype = { didReceiveResponse: function(identifier, time, resourceType, response) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; resource.responseReceivedTime = time; resource.type = WebInspector.Resource.Type[resourceType]; - WebInspector.NetworkManager.updateResourceWithResponse(resource, response); + this._updateResourceWithResponse(resource, response); this._updateResource(resource); this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource); @@ -158,7 +186,7 @@ WebInspector.NetworkManager.prototype = { didReceiveContentLength: function(identifier, time, lengthReceived) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -170,7 +198,7 @@ WebInspector.NetworkManager.prototype = { didFinishLoading: function(identifier, finishTime) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -179,7 +207,7 @@ WebInspector.NetworkManager.prototype = { didFailLoading: function(identifier, time, localizedDescription) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -190,8 +218,8 @@ WebInspector.NetworkManager.prototype = { didLoadResourceFromMemoryCache: function(time, cachedResource) { - var resource = this._resourceTreeModel.createResource("cached:" + ++this._lastIdentifierForCachedResource, cachedResource.url, cachedResource.loader); - WebInspector.NetworkManager.updateResourceWithCachedResource(resource, cachedResource); + var resource = this._createResource("cached:" + ++this._lastIdentifierForCachedResource, cachedResource.url, cachedResource.loader); + this._updateResourceWithCachedResource(resource, cachedResource); resource.cached = true; resource.requestMethod = "GET"; this._startResource(resource); @@ -224,21 +252,21 @@ WebInspector.NetworkManager.prototype = { if (mainResource) { WebInspector.mainResource = mainResource; mainResource.isMainResource = true; - this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, mainResource); + this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, mainResource); } } }, didCreateWebSocket: function(identifier, requestURL) { - var resource = this._resourceTreeModel.createResource(identifier, requestURL); + var resource = this._createResource(identifier, requestURL); resource.type = WebInspector.Resource.Type.WebSocket; this._startResource(resource); }, willSendWebSocketHandshakeRequest: function(identifier, time, request) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -252,7 +280,7 @@ WebInspector.NetworkManager.prototype = { didReceiveWebSocketHandshakeResponse: function(identifier, time, response) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; @@ -267,7 +295,7 @@ WebInspector.NetworkManager.prototype = { didCloseWebSocket: function(identifier, time) { - var resource = this._inflightResources[identifier]; + var resource = this._inflightResourcesById[identifier]; if (!resource) return; this._finishResource(resource, time); @@ -275,40 +303,76 @@ WebInspector.NetworkManager.prototype = { _appendRedirect: function(identifier, time, redirectURL) { - var originalResource = this._inflightResources[identifier]; + var originalResource = this._inflightResourcesById[identifier]; var previousRedirects = originalResource.redirects || []; originalResource.identifier = "redirected:" + identifier + "." + previousRedirects.length; delete originalResource.redirects; this._finishResource(originalResource, time); - // We bound resource early, but it happened to be a redirect and won't make it through to - // the resource tree -- so unbind it. - // FIXME: we should bind upon adding to the tree only (encapsulated into ResourceTreeModel), - // Script debugger should do explicit late binding on its own. - this._resourceTreeModel.unbindResourceURL(originalResource); - - var newResource = this._resourceTreeModel.createResource(identifier, redirectURL, originalResource.loader, originalResource.stackTrace); + var newResource = this._createResource(identifier, redirectURL, originalResource.loader, originalResource.stackTrace); newResource.redirects = previousRedirects.concat(originalResource); return newResource; }, _startResource: function(resource) { - this._inflightResources[resource.identifier] = resource; - this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceStarted, resource); + this._inflightResourcesById[resource.identifier] = resource; + this._inflightResourcesByURL[resource.url] = resource; + this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceStarted, resource); }, _updateResource: function(resource) { - this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceUpdated, resource); + this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceUpdated, resource); }, _finishResource: function(resource, finishTime) { resource.endTime = finishTime; resource.finished = true; - this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceFinished, resource); - delete this._inflightResources[resource.identifier]; + this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceFinished, resource); + delete this._inflightResourcesById[resource.identifier]; + delete this._inflightResourcesByURL[resource.url]; + }, + + _addFramesRecursively: function(framePayload) + { + var frameResource = this._createResource(null, framePayload.resource.url, framePayload.resource.loader); + this._updateResourceWithRequest(frameResource, framePayload.resource.request); + this._updateResourceWithResponse(frameResource, framePayload.resource.response); + frameResource.type = WebInspector.Resource.Type["Document"]; + frameResource.finished = true; + + this._resourceTreeModel.addOrUpdateFrame(framePayload); + this._resourceTreeModel.addResourceToFrame(framePayload.id, frameResource); + + for (var i = 0; framePayload.children && i < framePayload.children.length; ++i) + this._addFramesRecursively(framePayload.children[i]); + + if (!framePayload.subresources) + return; + + for (var i = 0; i < framePayload.subresources.length; ++i) { + var cachedResource = framePayload.subresources[i]; + var resource = this._createResource(null, cachedResource.url, cachedResource.loader); + this._updateResourceWithCachedResource(resource, cachedResource); + resource.finished = true; + this._resourceTreeModel.addResourceToFrame(framePayload.id, resource); + } + return frameResource; + }, + + _dispatchEventToListeners: function(eventType, resource) + { + this._manager.dispatchEventToListeners(eventType, resource); + }, + + _createResource: function(identifier, url, loader, stackTrace) + { + var resource = new WebInspector.Resource(identifier, url); + resource.loader = loader; + if (loader) + resource.documentURL = loader.url; + resource.stackTrace = stackTrace; + return resource; } } - -WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/Source/WebCore/inspector/front-end/NetworkPanel.js b/Source/WebCore/inspector/front-end/NetworkPanel.js index 943ee7f..085f468 100644 --- a/Source/WebCore/inspector/front-end/NetworkPanel.js +++ b/Source/WebCore/inspector/front-end/NetworkPanel.js @@ -103,7 +103,7 @@ WebInspector.NetworkPanel.prototype = { elementsToRestoreScrollPositionsFor: function() { - return [this.containerElement]; + return [this.containerElement, this._dataGrid.scrollContainer]; }, resize: function() @@ -118,8 +118,6 @@ WebInspector.NetworkPanel.prototype = { if (!this._viewingResourceMode) return; WebInspector.Panel.prototype.updateSidebarWidth.call(this, width); - if (this._summaryBarElement.parentElement === this.element) - this._summaryBarElement.style.width = width + "px"; }, updateMainViewWidth: function(width) @@ -147,7 +145,6 @@ WebInspector.NetworkPanel.prototype = { delete this._summaryBarRowNode; } this._summaryBarElement.addStyleClass("network-summary-bar-bottom"); - this._summaryBarElement.style.setProperty("width", this.sidebarElement.offsetWidth + "px"); this.element.appendChild(this._summaryBarElement); this._dataGrid.element.style.bottom = "20px"; return; @@ -157,11 +154,11 @@ WebInspector.NetworkPanel.prototype = { // Glue status to table. this._summaryBarRowNode = new WebInspector.NetworkTotalGridNode(this._summaryBarElement); this._summaryBarElement.removeStyleClass("network-summary-bar-bottom"); - this._summaryBarElement.style.removeProperty("width"); this._dataGrid.appendChild(this._summaryBarRowNode); this._dataGrid.element.style.bottom = 0; this._sortItems(); } + this._updateOffscreenRows(); }, _resetSummaryBar: function() @@ -218,6 +215,7 @@ WebInspector.NetworkPanel.prototype = { this.containerElement.appendChild(this._dataGrid.element); this._dataGrid.addEventListener("sorting changed", this._sortItems, this); this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this); + this._dataGrid.scrollContainer.addEventListener("scroll", this._updateOffscreenRows.bind(this)); this._patchTimelineHeader(); }, @@ -316,6 +314,7 @@ WebInspector.NetworkPanel.prototype = { this._dataGrid.sortNodes(sortingFunction, this._dataGrid.sortOrder === "descending"); this._timelineSortSelector.selectedIndex = 0; + this._updateOffscreenRows(); }, _sortByTimeline: function() @@ -334,6 +333,7 @@ WebInspector.NetworkPanel.prototype = { else this._timelineGrid.showEventDividers(); this._dataGrid.markColumnAsSortedBy("timeline", "ascending"); + this._updateOffscreenRows(); }, _createFilterStatusBarItems: function() @@ -492,6 +492,7 @@ WebInspector.NetworkPanel.prototype = { target.addStyleClass("selected"); this._showCategory(target.category); } + this._updateOffscreenRows(); }, _scheduleRefresh: function() @@ -933,7 +934,6 @@ WebInspector.NetworkPanel.prototype = { this._viewsContainerElement.addStyleClass("hidden"); this.sidebarElement.style.right = 0; this.sidebarElement.style.removeProperty("width"); - this._summaryBarElement.style.removeProperty("width"); if (this._dataGrid.selectedNode) this._dataGrid.selectedNode.selected = false; } @@ -1023,13 +1023,55 @@ WebInspector.NetworkPanel.prototype = { var harArchive = { log: (new WebInspector.HARLog()).build() } - offerFileForDownload(JSON.stringify(harArchive)); + InspectorFrontendHost.copyText(JSON.stringify(harArchive)); }, _exportResource: function(resource) { var har = (new WebInspector.HAREntry(resource)).build(); - offerFileForDownload(JSON.stringify(har)); + InspectorFrontendHost.copyText(JSON.stringify(har)); + }, + + _updateOffscreenRows: function(e) + { + var dataTableBody = this._dataGrid.dataTableBody; + var rows = dataTableBody.children; + var recordsCount = rows.length; + if (recordsCount < 2) + return; // Filler row only. + + var visibleTop = this._dataGrid.scrollContainer.scrollTop; + var visibleBottom = visibleTop + this._dataGrid.scrollContainer.offsetHeight; + + var rowHeight = 0; + + // Filler is at recordsCount - 1. + var unfilteredRowIndex = 0; + for (var i = 0; i < recordsCount - 1; ++i) { + var row = rows[i]; + // Don't touch summaty - quit instead. + if (this._summaryBarRowNode && row === this._summaryBarRowNode.element) + break; + + var dataGridNode = this._dataGrid.dataGridNodeFromNode(row); + if (dataGridNode.isFilteredOut()) { + row.removeStyleClass("offscreen"); + continue; + } + + if (!rowHeight) + rowHeight = row.offsetHeight; + + var rowIsVisible = unfilteredRowIndex * rowHeight < visibleBottom && (unfilteredRowIndex + 1) * rowHeight > visibleTop; + if (rowIsVisible !== row.rowIsVisible) { + if (rowIsVisible) + row.removeStyleClass("offscreen"); + else + row.addStyleClass("offscreen"); + row.rowIsVisible = rowIsVisible; + } + unfilteredRowIndex++; + } } } @@ -1335,6 +1377,14 @@ WebInspector.NetworkDataGridNode.prototype = { this._timeCell = this._createDivInTD("time"); this._createTimelineCell(); this._nameCell.addEventListener("click", this.select.bind(this), false); + this._nameCell.addEventListener("dblclick", this._openInNewTab.bind(this), false); + }, + + isFilteredOut: function() + { + if (!this._panel._hiddenCategories.all) + return false; + return this._resource.category.name in this._panel._hiddenCategories; }, select: function() @@ -1343,15 +1393,16 @@ WebInspector.NetworkDataGridNode.prototype = { WebInspector.DataGridNode.prototype.select.apply(this, arguments); }, + _openInNewTab: function() + { + InspectorBackend.openInInspectedWindow(this._resource.url); + }, + get selectable() { if (!this._panel._viewingResourceMode) return false; - if (!this._panel._hiddenCategories.all) - return true; - if (this._panel._hiddenCategories[this._resource.category.name]) - return false; - return true; + return !this.isFilteredOut(); }, _createDivInTD: function(columnIdentifier) @@ -1668,6 +1719,16 @@ WebInspector.NetworkTotalGridNode = function(element) } WebInspector.NetworkTotalGridNode.prototype = { + isFilteredOut: function() + { + return false; + }, + + get selectable() + { + return false; + }, + createCells: function() { var td = document.createElement("td"); diff --git a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js index e4794f3..88fddd6 100644 --- a/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js +++ b/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js @@ -180,7 +180,13 @@ WebInspector.ObjectPropertyTreeElement.prototype = { this.valueElement = document.createElement("span"); this.valueElement.className = "value"; - this.valueElement.textContent = this.property.value.description; + + 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.isGetter) this.valueElement.addStyleClass("dimmed"); if (this.property.value.isError()) @@ -188,7 +194,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = { if (this.property.value.type) this.valueElement.addStyleClass("console-formatted-" + this.property.value.type); if (this.property.value.type === "node") - this.valueElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); + this.valueElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false); this.listItemElement.removeChildren(); @@ -203,8 +209,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = { function selectNode(nodeId) { if (nodeId) { - WebInspector.currentPanel = WebInspector.panels.elements; - WebInspector.panels.elements.focusedDOMNode = WebInspector.domAgent.nodeForId(nodeId); + WebInspector.panels.elements.switchToAndFocus(WebInspector.domAgent.nodeForId(nodeId)); } } diff --git a/Source/WebCore/inspector/front-end/PleaseWaitMessage.js b/Source/WebCore/inspector/front-end/PleaseWaitMessage.js new file mode 100644 index 0000000..54d805d --- /dev/null +++ b/Source/WebCore/inspector/front-end/PleaseWaitMessage.js @@ -0,0 +1,107 @@ +/* + * 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.PleaseWaitMessage = function() +{ + this.element = document.createElement("div"); + this.element.className = "please-wait-msg"; + this.element.textContent = WebInspector.UIString("Please wait\u2026"); + + this.cancelButton = document.createElement("button"); + this.cancelButton.textContent = WebInspector.UIString("Cancel"); + this.cancelButton.addEventListener("click", this._cancelClicked.bind(this), false); +} + +WebInspector.PleaseWaitMessage.prototype = { + _cancelClicked: function() + { + if (this._cancelCallback) { + var cancelCallback = this._cancelCallback; + delete this._cancelCallback; + cancelCallback(); + } + }, + + hide: function() + { + var instance = WebInspector.PleaseWaitMessage.prototype.instance; + var message = instance.element; + if (message.parentNode) + message.parentNode.removeChild(message); + }, + + get instance() + { + if (!"_instance" in WebInspector.PleaseWaitMessage.prototype) + WebInspector.PleaseWaitMessage.prototype._instance = new WebInspector.PleaseWaitMessage(); + return WebInspector.PleaseWaitMessage.prototype._instance; + }, + + show: function(element, cancelCallback) + { + var instance = WebInspector.PleaseWaitMessage.prototype.instance; + var message = instance.element; + if (message.parentNode === element) + return; + else if (message.parentNode) + message.parentNode.removeChild(message); + if (message.childNodes.length > 1) + message.removeChild(instance.cancelButton); + if (cancelCallback) { + message.appendChild(instance.cancelButton); + instance._cancelCallback = cancelCallback; + } + element.appendChild(message); + }, + + startAction: function(element, actionCallback, cancelCallback) + { + var instance = WebInspector.PleaseWaitMessage.prototype.instance; + var message = instance.element; + if (message.parentNode === element) { + actionCallback(); + return; + } + + function doAction() + { + try { + actionCallback(); + } finally { + if (message.parentNode) + message.parentNode.removeChild(message); + } + } + + WebInspector.PleaseWaitMessage.prototype.show(element, cancelCallback); + setTimeout(doAction, 0); + } +}; + diff --git a/Source/WebCore/inspector/front-end/ProfilesPanel.js b/Source/WebCore/inspector/front-end/ProfilesPanel.js index 2e0ab28..b87ea7f 100644 --- a/Source/WebCore/inspector/front-end/ProfilesPanel.js +++ b/Source/WebCore/inspector/front-end/ProfilesPanel.js @@ -112,7 +112,7 @@ WebInspector.ProfilesPanel = function() this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggle-status-bar-item"); this.enableToggleButton.addEventListener("click", this._toggleProfiling.bind(this), false); - this.clearResultsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear CPU profiles."), "clear-status-bar-item"); + this.clearResultsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear all profiles."), "clear-status-bar-item"); this.clearResultsButton.addEventListener("click", this._clearProfiles.bind(this), false); this.profileViewStatusBarItemsContainer = document.createElement("div"); @@ -195,7 +195,7 @@ WebInspector.ProfilesPanel.prototype = { this._profiles = []; this._profilesIdMap = {}; this._profileGroups = {}; - this._profileGroupsForLinks = {} + this._profileGroupsForLinks = {}; this._profilesWereRequested = false; this.sidebarTreeElement.removeStyleClass("some-expandable"); @@ -259,6 +259,13 @@ WebInspector.ProfilesPanel.prototype = { _addProfileHeader: function(profile) { + if (this.hasTemporaryProfile(profile.typeId)) { + if (profile.typeId === WebInspector.CPUProfileType.TypeId) + this._removeProfileHeader(this._temporaryRecordingProfile); + else + this._removeProfileHeader(this._temporaryTakingSnapshot); + } + var typeId = profile.typeId; var profileType = this.getProfileType(typeId); var sidebarParent = profileType.treeElement; @@ -308,6 +315,7 @@ WebInspector.ProfilesPanel.prototype = { } var profileTreeElement = profileType.createSidebarTreeElementForProfile(profile); + profile.sideBarElement = profileTreeElement; profileTreeElement.small = small; if (alternateTitle) profileTreeElement.mainTitle = alternateTitle; @@ -370,17 +378,20 @@ WebInspector.ProfilesPanel.prototype = { this.profileViewStatusBarItemsContainer.removeChildren(); var statusBarItems = view.statusBarItems; - for (var i = 0; i < statusBarItems.length; ++i) - this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i]); + if (statusBarItems) + for (var i = 0; i < statusBarItems.length; ++i) + this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i]); }, getProfiles: function(typeId) { var result = []; var profilesCount = this._profiles.length; - for (var i = 0; i < profilesCount; ++i) - if (this._profiles[i].typeId === typeId) - result.push(this._profiles[i]); + for (var i = 0; i < profilesCount; ++i) { + var profile = this._profiles[i]; + if (!profile.isTemporary && profile.typeId === typeId) + result.push(profile); + } return result; }, @@ -398,17 +409,6 @@ WebInspector.ProfilesPanel.prototype = { return !!this._profilesIdMap[this._makeKey(profile.uid, profile.typeId)]; }, - updateProfile: function(profile) - { - var profilesCount = this._profiles.length; - for (var i = 0; i < profilesCount; ++i) - if (this._profiles[i].typeId === profile.typeId - && this._profiles[i].uid === profile.uid) { - this._profiles[i] = profile; - break; - } - }, - loadHeapSnapshot: function(uid, callback) { var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; @@ -423,6 +423,7 @@ WebInspector.ProfilesPanel.prototype = { profile._is_loading = true; profile._callbacks = [callback]; profile._json = ""; + profile.sideBarElement.subtitle = WebInspector.UIString("Loading…"); InspectorBackend.getProfile(profile.typeId, profile.uid); } }, @@ -444,13 +445,23 @@ WebInspector.ProfilesPanel.prototype = { var callbacks = profile._callbacks; delete profile._callbacks; - var loadedSnapshot = JSON.parse(profile._json); - delete profile._json; - delete profile._is_loading; - profile._loaded = true; - WebInspector.HeapSnapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot); - for (var i = 0; i < callbacks.length; ++i) - callbacks[i](profile); + 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.HeapSnapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot); + else + WebInspector.DetailedHeapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot); + for (var i = 0; i < callbacks.length; ++i) + callbacks[i](profile); + } }, showView: function(view) @@ -579,10 +590,13 @@ WebInspector.ProfilesPanel.prototype = { _toggleProfiling: function(optionalAlways) { - if (this._profilerEnabled) + if (this._profilerEnabled) { + WebInspector.settings.profilerEnabled = false; InspectorBackend.disableProfiler(true); - else - InspectorBackend.enableProfiler(!!optionalAlways); + } else { + WebInspector.settings.profilerEnabled = !!optionalAlways; + InspectorBackend.enableProfiler(); + } }, _populateProfiles: function() @@ -629,6 +643,31 @@ WebInspector.ProfilesPanel.prototype = { this._removeProfileHeader(this._temporaryRecordingProfile); } this.updateProfileTypeButtons(); + }, + + takeHeapSnapshot: function(detailed) + { + if (!this.hasTemporaryProfile(WebInspector.HeapSnapshotProfileType.TypeId)) { + if (!this._temporaryTakingSnapshot) { + this._temporaryTakingSnapshot = { + typeId: WebInspector.HeapSnapshotProfileType.TypeId, + title: WebInspector.UIString("Snapshotting…"), + uid: -1, + isTemporary: true + }; + } + this._addProfileHeader(this._temporaryTakingSnapshot); + } + InspectorBackend.takeHeapSnapshot(detailed); + }, + + _reportHeapSnapshotProgress: function(done, total) + { + if (this.hasTemporaryProfile(WebInspector.HeapSnapshotProfileType.TypeId)) { + this._temporaryTakingSnapshot.sideBarElement.subtitle = WebInspector.UIString("%.2f%%", (done / total) * 100); + if (done >= total) + this._removeProfileHeader(this._temporaryTakingSnapshot); + } } } @@ -674,6 +713,11 @@ WebInspector.ProfilerDispatcher.prototype = { setRecordingProfile: function(isProfiling) { this._profiler._setRecordingProfile(isProfiling); + }, + + reportHeapSnapshotProgress: function(done, total) + { + this._profiler._reportHeapSnapshotProgress(done, total); } } @@ -717,16 +761,6 @@ WebInspector.ProfileSidebarTreeElement.prototype = { this.refreshTitles(); }, - get subtitle() - { - // There is no subtitle. - }, - - set subtitle(x) - { - // Can't change subtitle. - }, - set searchMatches(matches) { if (!matches) { diff --git a/Source/WebCore/inspector/front-end/Resource.js b/Source/WebCore/inspector/front-end/Resource.js index 00c1fb9..6cf5b9c 100644 --- a/Source/WebCore/inspector/front-end/Resource.js +++ b/Source/WebCore/inspector/front-end/Resource.js @@ -31,9 +31,9 @@ WebInspector.Resource = function(identifier, url) this.url = url; this._startTime = -1; this._endTime = -1; - this._requestMethod = ""; this._category = WebInspector.resourceCategories.other; this._pendingContentCallbacks = []; + this._responseHeadersSize = 0; } // Keep these in sync with WebCore::InspectorResource::Type @@ -237,8 +237,21 @@ WebInspector.Resource.prototype = { get transferSize() { - // FIXME: this is wrong for chunked-encoding resources. - return this.cached ? 0 : Number(this.responseHeaders["Content-Length"] || this.resourceSize || 0); + if (this.cached) + return 0; + if (this.statusCode === 304) // Not modified + return this._responseHeadersSize; + // FIXME: We prefer using Content-Length over resourceSize as + // resourceSize may differ from actual transfer size if platform's + // network stack performed decoding (e.g. gzip decompression). + // The Content-Length, though, is expected to come from raw + // response headers and will reflect actual transfer length. + // This won't work for chunked content encoding, so fall back to + // resourceSize when we don't have Content-Length. This still won't + // work for chunks with non-trivial encodings. We need a way to + // get actaul transfer size from the network stack. + var bodySize = Number(this.responseHeaders["Content-Length"] || this.resourceSize); + return this._responseHeadersSize + bodySize; }, get expectedContentLength() @@ -303,7 +316,6 @@ WebInspector.Resource.prototype = { delete this._timing; }, - get timing() { return this._timing; @@ -431,6 +443,8 @@ 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._sortedResponseHeaders; delete this._responseCookies; @@ -512,6 +526,14 @@ WebInspector.Resource.prototype = { } }, + _headersSize: function(headers) + { + var size = 0; + for (var header in headers) + size += header.length + headers[header].length + 3; // _typical_ overhead per herader is ": ".length + "\n".length. + return size; + }, + get errors() { return this._errors || 0; @@ -550,9 +572,9 @@ WebInspector.Resource.prototype = { return true; if (typeof this.type === "undefined" - || this.type === WebInspector.Resource.Type.Other - || this.type === WebInspector.Resource.Type.XHR - || this.type === WebInspector.Resource.Type.WebSocket) + || this.type === WebInspector.Resource.Type.Other + || this.type === WebInspector.Resource.Type.XHR + || this.type === WebInspector.Resource.Type.WebSocket) return true; if (!this.mimeType) @@ -671,8 +693,8 @@ WebInspector.Resource.prototype = { callback(null, null); return; } - if (this._content) { - callback(this._content, this._contentEncoded); + if (typeof this._content !== "undefined") { + callback(this.content, this._contentEncoded); return; } this._pendingContentCallbacks.push(callback); @@ -697,7 +719,7 @@ WebInspector.Resource.prototype = { { const maxDataUrlSize = 1024 * 1024; // If resource content is not available or won't fit a data URL, fall back to using original URL. - if (!this._content || this._content.length > maxDataUrlSize) + if (this._content == null || this._content.length > maxDataUrlSize) return this.url; return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content; @@ -719,7 +741,7 @@ WebInspector.Resource.prototype = { this._pendingContentCallbacks.length = 0; delete this._contentRequested; } - WebInspector.NetworkManager.requestContent(this, this._contentEncoded, onResourceContent.bind(this)); + WebInspector.networkManager.requestContent(this, this._contentEncoded, onResourceContent.bind(this)); } } diff --git a/Source/WebCore/inspector/front-end/ResourceTreeModel.js b/Source/WebCore/inspector/front-end/ResourceTreeModel.js index b114b94..da2d47a 100644 --- a/Source/WebCore/inspector/front-end/ResourceTreeModel.js +++ b/Source/WebCore/inspector/front-end/ResourceTreeModel.js @@ -31,16 +31,17 @@ WebInspector.ResourceTreeModel = function() { - this.reloadCachedResources(); + this.reset(); } WebInspector.ResourceTreeModel.prototype = { - reloadCachedResources: function() + reset: function() { this._resourcesByURL = {}; this._resourcesByFrameId = {}; this._subframes = {}; - InspectorBackend.cachedResources(this._processCachedResources.bind(this)); + if (WebInspector.panels) + WebInspector.panels.resources.clear(); }, addOrUpdateFrame: function(frame) @@ -81,6 +82,7 @@ WebInspector.ResourceTreeModel.prototype = { this._resourcesByFrameId[frameId] = resourcesForFrame; } resourcesForFrame.push(resource); + this._bindResourceURL(resource); WebInspector.panels.resources.addResourceToFrame(frameId, resource); }, @@ -128,7 +130,7 @@ WebInspector.ResourceTreeModel.prototype = { return entry; }, - bindResourceURL: function(resource) + _bindResourceURL: function(resource) { var resourceForURL = this._resourcesByURL[resource.url]; if (!resourceForURL) @@ -168,7 +170,7 @@ WebInspector.ResourceTreeModel.prototype = { preservedResourcesForFrame.push(resource); continue; } - this.unbindResourceURL(resource); + this._unbindResourceURL(resource); } delete this._resourcesByFrameId[frameId]; @@ -194,7 +196,7 @@ WebInspector.ResourceTreeModel.prototype = { return false; }, - unbindResourceURL: function(resource) + _unbindResourceURL: function(resource) { var resourceForURL = this._resourcesByURL[resource.url]; if (!resourceForURL) @@ -208,52 +210,5 @@ WebInspector.ResourceTreeModel.prototype = { } delete this._resourcesByURL[resource.url]; - }, - - _processCachedResources: function(mainFramePayload) - { - var mainResource = this._addFramesRecursively(mainFramePayload); - WebInspector.mainResource = mainResource; - mainResource.isMainResource = true; - }, - - _addFramesRecursively: function(framePayload) - { - var frameResource = this.createResource(null, framePayload.resource.url, framePayload.resource.loader); - WebInspector.NetworkManager.updateResourceWithRequest(frameResource, framePayload.resource.request); - WebInspector.NetworkManager.updateResourceWithResponse(frameResource, framePayload.resource.response); - frameResource.type = WebInspector.Resource.Type["Document"]; - frameResource.finished = true; - - this.addOrUpdateFrame(framePayload); - this.addResourceToFrame(framePayload.id, frameResource); - - for (var i = 0; framePayload.children && i < framePayload.children.length; ++i) - this._addFramesRecursively(framePayload.children[i]); - - if (!framePayload.subresources) - return; - - for (var i = 0; i < framePayload.subresources.length; ++i) { - var cachedResource = framePayload.subresources[i]; - var resource = this.createResource(null, cachedResource.url, cachedResource.loader); - WebInspector.NetworkManager.updateResourceWithCachedResource(resource, cachedResource); - resource.finished = true; - this.addResourceToFrame(framePayload.id, resource); - } - return frameResource; - }, - - createResource: function(identifier, url, loader, stackTrace) - { - var resource = new WebInspector.Resource(identifier, url); - resource.loader = loader; - if (loader) { - resource.documentURL = loader.url; - this.bindResourceURL(resource); - } - resource.stackTrace = stackTrace; - - return resource; } } diff --git a/Source/WebCore/inspector/front-end/ResourceView.js b/Source/WebCore/inspector/front-end/ResourceView.js index b69097d..e38cd0a 100644 --- a/Source/WebCore/inspector/front-end/ResourceView.js +++ b/Source/WebCore/inspector/front-end/ResourceView.js @@ -50,7 +50,11 @@ WebInspector.ResourceView.createResourceView = function(resource) case WebInspector.resourceCategories.stylesheets: case WebInspector.resourceCategories.scripts: case WebInspector.resourceCategories.xhr: - return new WebInspector.SourceView(resource); + var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource); + var isScript = resource.type === WebInspector.Resource.Type.Script; + var view = new WebInspector.SourceFrame(contentProvider, resource.url, isScript); + view.resource = resource; + return view; case WebInspector.resourceCategories.images: return new WebInspector.ImageView(resource); case WebInspector.resourceCategories.fonts: @@ -68,7 +72,7 @@ WebInspector.ResourceView.resourceViewTypeMatchesResource = function(resource) case WebInspector.resourceCategories.stylesheets: case WebInspector.resourceCategories.scripts: case WebInspector.resourceCategories.xhr: - return resourceView.__proto__ === WebInspector.SourceView.prototype; + return resourceView.__proto__ === WebInspector.SourceFrame.prototype; case WebInspector.resourceCategories.images: return resourceView.__proto__ === WebInspector.ImageView.prototype; case WebInspector.resourceCategories.fonts: @@ -105,7 +109,6 @@ WebInspector.ResourceView.recreateResourceView = function(resource) if (scrollTop) newView.scrollTop = scrollTop; - WebInspector.panels.scripts.viewRecreated(oldView, newView); return newView; } @@ -115,3 +118,37 @@ WebInspector.ResourceView.existingResourceViewForResource = function(resource) return null; return resource._resourcesView; } + + +WebInspector.SourceFrameContentProviderForResource = function(resource) +{ + WebInspector.SourceFrameContentProvider.call(this); + this._resource = resource; +} + +//This is a map from resource.type to mime types +//found in WebInspector.SourceTokenizer.Registry. +WebInspector.SourceFrameContentProviderForResource.DefaultMIMETypeForResourceType = { + 0: "text/html", + 1: "text/css", + 4: "text/javascript" +} + +WebInspector.SourceFrameContentProviderForResource.prototype = { + requestContent: function(callback) + { + function contentLoaded(content) + { + var mimeType = WebInspector.SourceFrameContentProviderForResource.DefaultMIMETypeForResourceType[this._resource.type] || this._resource.mimeType; + callback(mimeType, content); + } + this._resource.requestContent(contentLoaded.bind(this)); + }, + + scripts: function() + { + return WebInspector.debuggerModel.scriptsForURL(this._resource.url); + } +} + +WebInspector.SourceFrameContentProviderForResource.prototype.__proto__ = WebInspector.SourceFrameContentProvider.prototype; diff --git a/Source/WebCore/inspector/front-end/ResourcesPanel.js b/Source/WebCore/inspector/front-end/ResourcesPanel.js index 7e1fcc0..7c0649f 100644 --- a/Source/WebCore/inspector/front-end/ResourcesPanel.js +++ b/Source/WebCore/inspector/front-end/ResourcesPanel.js @@ -56,12 +56,6 @@ WebInspector.ResourcesPanel = function(database) this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", "application-cache-storage-tree-item"); this.sidebarTree.appendChild(this.applicationCacheListTreeElement); - if (Preferences.fileSystemEnabled) { - this.fileSystemListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("File System"), "FileSystem", "file-system-storage-tree-item"); - this.sidebarTree.appendChild(this.fileSystemListTreeElement); - this.fileSystemListTreeElement.expand(); - } - this.storageViews = document.createElement("div"); this.storageViews.id = "storage-views"; this.storageViews.className = "diff-container"; @@ -102,9 +96,19 @@ WebInspector.ResourcesPanel.prototype = { { WebInspector.Panel.prototype.show.call(this); - if (this.visibleView instanceof WebInspector.ResourceView) + if (this.visibleView && this.visibleView.resource) this._showResourceView(this.visibleView.resource); + this._initDefaultSelection(); + }, + + loadEventFired: function() + { + this._initDefaultSelection(); + }, + + _initDefaultSelection: function() + { if (this._initializedDefaultSelection) return; @@ -119,17 +123,14 @@ WebInspector.ResourcesPanel.prototype = { } } } - this._initDefaultSelection(); - }, - _initDefaultSelection: function() - { if (WebInspector.mainResource && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded) this.showResource(WebInspector.mainResource); }, reset: function() { + delete this._initializedDefaultSelection; this._origins = {}; this._domains = {}; for (var i = 0; i < this._databases.length; ++i) { @@ -147,7 +148,6 @@ WebInspector.ResourcesPanel.prototype = { this._domStorage = []; this._cookieViews = {}; - this._fileSystemView = null; this._applicationCacheView = null; delete this._cachedApplicationCacheViewStatus; @@ -157,8 +157,6 @@ WebInspector.ResourcesPanel.prototype = { this.sessionStorageListTreeElement.removeChildren(); this.cookieListTreeElement.removeChildren(); this.applicationCacheListTreeElement.removeChildren(); - if (Preferences.fileSystemEnabled) - this.fileSystemListTreeElement.removeChildren(); this.storageViews.removeChildren(); this.storageViewStatusBarItemsContainer.removeChildren(); @@ -170,6 +168,7 @@ WebInspector.ResourcesPanel.prototype = { clear: function() { this.resourcesListTreeElement.removeChildren(); + this._treeElementForFrameId = {}; this.reset(); }, @@ -291,16 +290,6 @@ WebInspector.ResourcesPanel.prototype = { var applicationCacheTreeElement = new WebInspector.ApplicationCacheTreeElement(this, domain); this.applicationCacheListTreeElement.appendChild(applicationCacheTreeElement); } - - if (Preferences.fileSystemEnabled) { - // FIXME: This should match the SecurityOrigin::toString(), add a test for this. - var securityOrigin = parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : ""); - if (!this._origins[securityOrigin]) { - this._origins[securityOrigin] = true; - var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this, securityOrigin); - this.fileSystemListTreeElement.appendChild(fileSystemTreeElement); - } - } }, addDOMStorage: function(domStorage) @@ -338,12 +327,12 @@ WebInspector.ResourcesPanel.prototype = { canShowSourceLine: function(url, line) { - return !!WebInspector.resourceTreeModel.resourceForURL(url); + return !!WebInspector.resourceForURL(url); }, showSourceLine: function(url, line) { - var resource = WebInspector.resourceTreeModel.resourceForURL(url); + var resource = WebInspector.resourceForURL(url); if (resource.type === WebInspector.Resource.Type.XHR) { // Show XHRs in the network panel only. if (WebInspector.panels.network && WebInspector.panels.network.canShowSourceLine(url, line)) { @@ -352,7 +341,7 @@ WebInspector.ResourcesPanel.prototype = { } return; } - this.showResource(WebInspector.resourceTreeModel.resourceForURL(url), line); + this.showResource(WebInspector.resourceForURL(url), line); }, showResource: function(resource, line) @@ -378,7 +367,7 @@ WebInspector.ResourcesPanel.prototype = { var view = WebInspector.ResourceView.resourceViewForResource(resource); // Consider rendering diff markup here. - if (resource.baseRevision && view instanceof WebInspector.SourceView) { + if (resource.baseRevision && view instanceof WebInspector.SourceFrame) { function callback(baseContent) { if (baseContent) @@ -413,7 +402,7 @@ WebInspector.ResourcesPanel.prototype = { } else offset = i - right[i].row; } - view.sourceFrame.markDiff(diffData); + view.markDiff(diffData); }, showDatabase: function(database, tableName) @@ -481,12 +470,6 @@ WebInspector.ResourcesPanel.prototype = { this._applicationCacheView.updateStatus(this._cachedApplicationCacheViewStatus); }, - showFileSystem: function(treeElement, origin) - { - this._fileSystemView = new WebInspector.FileSystemView(treeElement, origin); - this._innerShowView(this._fileSystemView); - }, - showCategoryView: function(categoryName) { if (!this._categoryView) @@ -635,24 +618,6 @@ WebInspector.ResourcesPanel.prototype = { this._applicationCacheView.updateStatus(status); }, - updateFileSystemPath: function(root, type, origin) - { - if (this._fileSystemView && this._fileSystemView === this.visibleView) - this._fileSystemView.updateFileSystemPath(root, type, origin); - }, - - updateFileSystemError: function(type, origin) - { - if (this._fileSystemView && this._fileSystemView === this.visibleView) - this._fileSystemView.updateFileSystemError(type, origin); - }, - - setFileSystemDisabled: function() - { - if (this._fileSystemView && this._fileSystemView === this.visibleView) - this._fileSystemView.setFileSystemDisabled(); - }, - updateNetworkState: function(isNowOnline) { if (this._applicationCacheView && this._applicationCacheView === this.visibleView) @@ -690,7 +655,7 @@ WebInspector.ResourcesPanel.prototype = { var views = []; const visibleView = this.visibleView; - if (visibleView instanceof WebInspector.ResourceView && visibleView.performSearch) + if (visibleView.performSearch) views.push(visibleView); function callback(resourceTreeElement) @@ -1076,7 +1041,7 @@ WebInspector.FrameResourceTreeElement.prototype = { _errorsWarningsUpdated: function() { - // FIXME: move to the Script/SourceView. + // FIXME: move to the SourceFrame. if (!this._resource.warnings && !this._resource.errors) { var view = WebInspector.ResourceView.existingResourceViewForResource(this._resource); if (view && view.clearMessages) @@ -1275,27 +1240,6 @@ WebInspector.ResourceRevisionTreeElement.prototype = { WebInspector.ResourceRevisionTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; -WebInspector.FileSystemTreeElement = function(storagePanel, origin) -{ - WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, origin, "file-system-storage-tree-item"); - this._origin = origin; -} - -WebInspector.FileSystemTreeElement.prototype = { - get itemURL() - { - return "file-system://" + encodeURI(this._origin); - }, - - onselect: function() - { - WebInspector.BaseStorageTreeElement.prototype.onselect.call(this); - this._storagePanel.showFileSystem(this, this._origin); - } -} - -WebInspector.FileSystemTreeElement.prototype.__proto__ = WebInspector.BaseStorageTreeElement.prototype; - WebInspector.StorageCategoryView = function() { WebInspector.View.call(this); diff --git a/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js b/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js index d3190a9..bdbb0cf 100644 --- a/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js +++ b/Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js @@ -26,6 +26,8 @@ WebInspector.ScopeChainSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Scope Variables")); + this._sections = []; + this._expandedSections = {}; this._expandedProperties = []; } @@ -34,9 +36,6 @@ WebInspector.ScopeChainSidebarPane.prototype = { { this.bodyElement.removeChildren(); - this.sections = []; - this.callFrame = callFrame; - if (!callFrame) { var infoElement = document.createElement("div"); infoElement.className = "info"; @@ -45,6 +44,18 @@ WebInspector.ScopeChainSidebarPane.prototype = { return; } + for (var i = 0; i < this._sections.length; ++i) { + var section = this._sections[i]; + if (!section.title) + continue; + if (section.expanded) + this._expandedSections[section.title] = true; + else + delete this._expandedSections[section.title]; + } + + this._sections = []; + var foundLocalScope = false; var scopeChain = callFrame.scopeChain; for (var i = 0; i < scopeChain.length; ++i) { @@ -81,10 +92,10 @@ WebInspector.ScopeChainSidebarPane.prototype = { section.editInSelectedCallFrameWhenPaused = true; section.pane = this; - if (!foundLocalScope || scopeObjectProxy.isLocal) + if (!foundLocalScope || scopeObjectProxy.isLocal || title in this._expandedSections) section.expanded = true; - this.sections.push(section); + this._sections.push(section); this.bodyElement.appendChild(section.element); } } diff --git a/Source/WebCore/inspector/front-end/Script.js b/Source/WebCore/inspector/front-end/Script.js index 6e3b18d..8d3eabf 100644 --- a/Source/WebCore/inspector/front-end/Script.js +++ b/Source/WebCore/inspector/front-end/Script.js @@ -78,7 +78,7 @@ WebInspector.Script.prototype = { { function extractSourceLine() { - lineNumber -= this.startingLine; + lineNumber -= this.lineOffset; callback(this._source.substring(this._lineEndings[lineNumber - 1], this._lineEndings[lineNumber])); } diff --git a/Source/WebCore/inspector/front-end/ScriptFormatter.js b/Source/WebCore/inspector/front-end/ScriptFormatter.js index 69ffb74..5c00e51 100644 --- a/Source/WebCore/inspector/front-end/ScriptFormatter.js +++ b/Source/WebCore/inspector/front-end/ScriptFormatter.js @@ -28,107 +28,117 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.ScriptFormatter = function(source) +WebInspector.ScriptFormatter = function() { - this._originalSource = source; - this._originalLineEndings = source.findAll("\n"); - this._originalLineEndings.push(source.length); -} - -WebInspector.ScriptFormatter.locationToPosition = function(lineEndings, location) -{ - var position = location.line ? lineEndings[location.line - 1] + 1 : 0; - return position + location.column; -} - -WebInspector.ScriptFormatter.positionToLocation = function(lineEndings, position) -{ - var location = {}; - location.line = lineEndings.upperBound(position - 1); - if (!location.line) - location.column = position; - else - location.column = position - lineEndings[location.line - 1] - 1; - return location; + this._worker = new Worker("ScriptFormatterWorker.js"); + this._worker.onmessage = this._handleMessage.bind(this); + this._worker.onerror = this._handleError.bind(this); + this._tasks = []; } WebInspector.ScriptFormatter.prototype = { - format: function(callback) + formatContent: function(content, callback) { - var worker = new Worker("scriptFormatterWorker.js"); - function messageHandler(event) + var chunks = this._splitContentIntoChunks(content.text, content.scriptRanges); + + function didFormatChunks() { - var formattedSource = event.data; - this._formatted = true; - this._formattedSource = formattedSource; - this._formattedLineEndings = formattedSource.findAll("\n"); - this._formattedLineEndings.push(formattedSource.length); - this._buildMapping(); - callback(formattedSource); + var result = this._buildContentFromChunks(chunks); + callback(new WebInspector.FormattedSourceFrameContent(content, result.text, result.mapping)); } - worker.onmessage = messageHandler.bind(this); - worker.postMessage(this._originalSource); + this._formatChunks(chunks, 0, didFormatChunks.bind(this)); }, - _buildMapping: function() + _splitContentIntoChunks: function(text, scriptRanges) { - this._originalSymbolPositions = []; - this._formattedSymbolPositions = []; - var lastCodePosition = 0; - var regexp = /[\$\.\w]+|{|}|;/g; - while (true) { - var match = regexp.exec(this._formattedSource); - if (!match) - break; - var position = this._originalSource.indexOf(match[0], lastCodePosition); - if (position === -1) - continue; - this._originalSymbolPositions.push(position); - this._formattedSymbolPositions.push(match.index); - lastCodePosition = position + match[0].length; + var chunks = []; + function addChunk(start, end, isScript) + { + var chunk = {}; + chunk.start = start; + chunk.end = end; + chunk.isScript = isScript; + chunk.text = text.substring(start, end); + chunks.push(chunk); + } + var currentPosition = 0; + for (var i = 0; i < scriptRanges.length; ++i) { + var scriptRange = scriptRanges[i]; + if (currentPosition < scriptRange.start) + addChunk(currentPosition, scriptRange.start, false); + addChunk(scriptRange.start, scriptRange.end, true); + currentPosition = scriptRange.end; } - this._originalSymbolPositions.push(this._originalSource.length); - this._formattedSymbolPositions.push(this._formattedSource.length); + if (currentPosition < text.length) + addChunk(currentPosition, text.length, false); + return chunks; }, - originalLineNumberToFormattedLineNumber: function(originalLineNumber) + _formatChunks: function(chunks, index, callback) { - if (!this._formatted) - return originalLineNumber; - var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, { line: originalLineNumber, column: 0 }); - return this.originalPositionToFormattedLineNumber(originalPosition); + while(true) { + if (index === chunks.length) { + callback(); + return; + } + var chunk = chunks[index++]; + if (chunk.isScript) + break; + } + + function didFormat(formattedSource, mapping) + { + chunk.text = formattedSource; + chunk.mapping = mapping; + this._formatChunks(chunks, index, callback); + } + this._formatScript(chunk.text, didFormat.bind(this)); }, - formattedLineNumberToOriginalLineNumber: function(formattedLineNumber) + _buildContentFromChunks: function(chunks) { - if (!this._formatted) - return formattedLineNumber; - var originalPosition = this.formattedLineNumberToOriginalPosition(formattedLineNumber); - return WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, originalPosition).line; + var text = ""; + var mapping = { original: [], formatted: [] }; + for (var i = 0; i < chunks.length; ++i) { + var chunk = chunks[i]; + mapping.original.push(chunk.start); + mapping.formatted.push(text.length); + if (chunk.isScript) { + if (text) + text += "\n"; + for (var j = 0; j < chunk.mapping.original.length; ++j) { + mapping.original.push(chunk.mapping.original[j] + chunk.start); + mapping.formatted.push(chunk.mapping.formatted[j] + text.length); + } + text += chunk.text; + } else { + if (text) + text += "\n"; + text += chunk.text; + } + mapping.original.push(chunk.end); + mapping.formatted.push(text.length); + } + return { text: text, mapping: mapping }; }, - originalPositionToFormattedLineNumber: function(originalPosition) + _formatScript: function(source, callback) { - var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings; - if (this._formatted) - formattedPosition = this._convertPosition(this._originalSymbolPositions, this._formattedSymbolPositions, originalPosition); - return WebInspector.ScriptFormatter.positionToLocation(lineEndings, formattedPosition).line; + this._tasks.push({ source: source, callback: callback }); + this._worker.postMessage(source); }, - formattedLineNumberToOriginalPosition: function(formattedLineNumber) + _handleMessage: function(event) { - var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings; - var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(lineEndings, { line: formattedLineNumber, column: 0 }); - if (!this._formatted) - return formattedPosition; - return this._convertPosition(this._formattedSymbolPositions, this._originalSymbolPositions, formattedPosition); + var task = this._tasks.shift(); + task.callback(event.data.formattedSource, event.data.mapping); }, - _convertPosition: function(symbolPositions1, symbolPositions2, position) + _handleError: function(event) { - var index = symbolPositions1.upperBound(position); - if (index === symbolPositions2.length - 1) - return symbolPositions2[index] - 1; - return symbolPositions2[index]; + console.warn("Error in script formatter worker:", event); + event.preventDefault() + var task = this._tasks.shift(); + task.callback(task.source, { original: [], formatted: [] }); } } diff --git a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js index e900317..1a4c28e 100644 --- a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js +++ b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js @@ -32,7 +32,10 @@ var parse = loadModule("parse-js.js"); var process = loadModule("process.js"); onmessage = function(event) { - postMessage(beautify(event.data)); + var source = event.data; + var formattedSource = beautify(source); + var mapping = buildMapping(source, formattedSource); + postMessage({ formattedSource: formattedSource, mapping: mapping }); }; function beautify(source) @@ -47,6 +50,25 @@ function beautify(source) return process.gen_code(ast, beautifyOptions); } +function buildMapping(source, formattedSource) +{ + var mapping = { original: [], formatted: [] }; + var lastCodePosition = 0; + var regexp = /[\$\.\w]+|{|}/g; + while (true) { + var match = regexp.exec(formattedSource); + if (!match) + break; + var position = source.indexOf(match[0], lastCodePosition); + if (position === -1) + continue; + mapping.original.push(position); + mapping.formatted.push(match.index); + lastCodePosition = position + match[0].length; + } + return mapping; +} + function loadModule(src) { var request = new XMLHttpRequest(); diff --git a/Source/WebCore/inspector/front-end/ScriptView.js b/Source/WebCore/inspector/front-end/ScriptView.js deleted file mode 100644 index f631fcc..0000000 --- a/Source/WebCore/inspector/front-end/ScriptView.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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. - */ - -WebInspector.ScriptView = function(script) -{ - WebInspector.View.call(this); - - this.element.addStyleClass("script-view"); - - var contentProvider = new WebInspector.SourceFrameContentProviderForScript(script); - this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", true); -} - -WebInspector.ScriptView.prototype = { - // The following methods are pulled from SourceView, since they are - // generic and work with ScriptView just fine. - - show: WebInspector.SourceView.prototype.show, - hide: WebInspector.SourceView.prototype.hide, - revealLine: WebInspector.SourceView.prototype.revealLine, - highlightLine: WebInspector.SourceView.prototype.highlightLine, - addMessage: WebInspector.SourceView.prototype.addMessage, - clearMessages: WebInspector.SourceView.prototype.clearMessages, - searchCanceled: WebInspector.SourceView.prototype.searchCanceled, - performSearch: WebInspector.SourceView.prototype.performSearch, - jumpToFirstSearchResult: WebInspector.SourceView.prototype.jumpToFirstSearchResult, - jumpToLastSearchResult: WebInspector.SourceView.prototype.jumpToLastSearchResult, - jumpToNextSearchResult: WebInspector.SourceView.prototype.jumpToNextSearchResult, - jumpToPreviousSearchResult: WebInspector.SourceView.prototype.jumpToPreviousSearchResult, - showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult, - showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult, - _jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult, - resize: WebInspector.SourceView.prototype.resize -} - -WebInspector.ScriptView.prototype.__proto__ = WebInspector.View.prototype; - - -WebInspector.SourceFrameContentProviderForScript = function(script) -{ - WebInspector.SourceFrameContentProvider.call(this); - this._script = script; -} - -WebInspector.SourceFrameContentProviderForScript.prototype = { - requestContent: function(callback) - { - if (this._script.source) { - callback("text/javascript", this._script.source); - return; - } - - function didRequestSource(content) - { - var source; - if (content) { - var prefix = ""; - for (var i = 0; i < this._script.startingLine - 1; ++i) - prefix += "\n"; - source = prefix + content; - } else - source = WebInspector.UIString(""); - callback("text/javascript", source); - } - this._script.requestSource(didRequestSource.bind(this)); - }, - - scripts: function() - { - return [this._script]; - } -} - -WebInspector.SourceFrameContentProviderForScript.prototype.__proto__ = WebInspector.SourceFrameContentProvider.prototype; diff --git a/Source/WebCore/inspector/front-end/ScriptsPanel.js b/Source/WebCore/inspector/front-end/ScriptsPanel.js index a74f80d..264291f 100644 --- a/Source/WebCore/inspector/front-end/ScriptsPanel.js +++ b/Source/WebCore/inspector/front-end/ScriptsPanel.js @@ -242,9 +242,7 @@ WebInspector.ScriptsPanel.prototype = { _parsedScriptSource: function(event) { - var sourceID = event.data; - var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); - this._addScript(script); + this._addScript(event.data); }, _failedToParseScriptSource: function(event) @@ -257,16 +255,23 @@ WebInspector.ScriptsPanel.prototype = { var sourceID = event.data.sourceID; var oldSource = event.data.oldSource; + var oldView, newView; var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); - var oldView = script._scriptView; - if (oldView) { - script._scriptView = new WebInspector.ScriptView(script); - this.viewRecreated(oldView, script._scriptView); - } if (script.resource) { + oldView = this._urlToSourceFrame[script.resource.url]; + delete this._urlToSourceFrame[script.resource.url]; + newView = this._sourceFrameForResource(script.resource); var revertHandle = WebInspector.debuggerModel.editScriptSource.bind(WebInspector.debuggerModel, sourceID, oldSource); script.resource.setContent(script.source, revertHandle); + } else { + var oldView = script._sourceFrame; + delete script._sourceFrame; + newView = this._sourceFrameForScript(script); } + newView.scrollTop = oldView.scrollTop; + + if (this.visibleView === oldView) + this.visibleView = newView; var callFrames = WebInspector.debuggerModel.callFrames; if (callFrames.length) @@ -275,7 +280,7 @@ WebInspector.ScriptsPanel.prototype = { _addScript: function(script) { - var resource = WebInspector.resourceForURL(script.sourceURL); + var resource = WebInspector.networkManager.inflightResourceForURL(script.sourceURL) || WebInspector.resourceForURL(script.sourceURL); if (resource) { if (resource.finished) { // Resource is finished, bind the script right away. @@ -295,17 +300,41 @@ WebInspector.ScriptsPanel.prototype = { _resourceLoadingFinished: function(e) { var resource = e.target; + + var visible = false; + var select = this.filesSelectElement; for (var i = 0; i < resource._scriptsPendingResourceLoad.length; ++i) { // Bind script to resource. var script = resource._scriptsPendingResourceLoad[i]; script.resource = resource; + if (select.options[select.selectedIndex] === script.filesSelectOption) + visible = true; + // Remove script from the files list. script.filesSelectOption.parentElement.removeChild(script.filesSelectOption); } // Adding first script will add resource. this._addScriptToFilesMenu(resource._scriptsPendingResourceLoad[0]); delete resource._scriptsPendingResourceLoad; + + if (visible) + this._showScriptOrResource(resource, { initialLoad: true }); + }, + + addConsoleMessage: function(message) + { + this._messages.push(message); + var sourceFrame = this._urlToSourceFrame[message.url]; + if (sourceFrame) + sourceFrame.addMessage(message); + }, + + clearConsoleMessages: function() + { + this._messages = []; + for (var url in this._urlToSourceFrame) + this._urlToSourceFrame[url].clearMessages(); }, selectedCallFrameId: function() @@ -316,7 +345,7 @@ WebInspector.ScriptsPanel.prototype = { return selectedCallFrame.id; }, - evaluateInSelectedCallFrame: function(code, updateInterface, objectGroup, callback) + evaluateInSelectedCallFrame: function(code, updateInterface, objectGroup, includeCommandLineAPI, callback) { var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame; if (!this._paused || !selectedCallFrame) @@ -325,24 +354,15 @@ WebInspector.ScriptsPanel.prototype = { if (typeof updateInterface === "undefined") updateInterface = true; - var self = this; function updatingCallbackWrapper(result) { - callback(result); - if (updateInterface) - self.sidebarPanes.scopechain.update(selectedCallFrame); - } - this.doEvalInCallFrame(selectedCallFrame, code, objectGroup, updatingCallbackWrapper); - }, - - doEvalInCallFrame: function(callFrame, code, objectGroup, callback) - { - function evalCallback(result) - { - if (result) + if (result) { callback(WebInspector.RemoteObject.fromPayload(result)); + if (updateInterface) + this.sidebarPanes.scopechain.update(selectedCallFrame); + } } - InspectorBackend.evaluateOnCallFrame(callFrame.id, code, objectGroup, evalCallback); + InspectorBackend.evaluateOnCallFrame(selectedCallFrame.id, code, objectGroup, includeCommandLineAPI, updatingCallbackWrapper.bind(this)); }, _debuggerPaused: function(event) @@ -405,6 +425,8 @@ WebInspector.ScriptsPanel.prototype = { this._currentBackForwardIndex = -1; this._updateBackAndForwardButtons(); + this._urlToSourceFrame = {}; + this._messages = []; this._resourceForURLInFilesSelect = {}; this.filesSelectElement.removeChildren(); this.functionsSelectElement.removeChildren(); @@ -434,12 +456,6 @@ WebInspector.ScriptsPanel.prototype = { x.show(this.viewsContainerElement); }, - viewRecreated: function(oldView, newView) - { - if (this.visibleView === oldView) - this.visibleView = newView; - }, - canShowSourceLine: function(url, line) { if (!this._debuggerEnabled) @@ -484,43 +500,37 @@ WebInspector.ScriptsPanel.prototype = { this.sidebarPanes.callstack.handleShortcut(event); }, - scriptViewForScript: function(script) - { - if (!script) - return null; - if (!script._scriptView) - script._scriptView = new WebInspector.ScriptView(script); - return script._scriptView; - }, - - sourceFrameForScript: function(script) - { - var view = this.scriptViewForScript(script); - if (!view) - return null; - - // Setting up the source frame requires that we be attached. - if (!this.element.parentNode) - this.attach(); - - return view.sourceFrame; - }, - _sourceFrameForScriptOrResource: function(scriptOrResource) { if (scriptOrResource instanceof WebInspector.Resource) return this._sourceFrameForResource(scriptOrResource); - if (scriptOrResource instanceof WebInspector.Script) - return this.sourceFrameForScript(scriptOrResource); + return this._sourceFrameForScript(scriptOrResource); }, _sourceFrameForResource: function(resource) { - var view = WebInspector.ResourceView.resourceViewForResource(resource); - if (!view) - return null; + var sourceFrame = this._urlToSourceFrame[resource.url]; + if (sourceFrame) + return sourceFrame; + var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource); + var isScript = resource.type === WebInspector.Resource.Type.Script; + sourceFrame = new WebInspector.SourceFrame(contentProvider, resource.url, isScript); + for (var i = 0; i < this._messages.length; ++i) { + var message = this._messages[i]; + if (this._messages[i].url === resource.url) + sourceFrame.addMessage(message); + } + this._urlToSourceFrame[resource.url] = sourceFrame; + return sourceFrame; + }, - return view.sourceFrame; + _sourceFrameForScript: function(script) + { + if (script._sourceFrame) + return script._sourceFrame; + var contentProvider = new WebInspector.SourceFrameContentProviderForScript(script); + script._sourceFrame = new WebInspector.SourceFrame(contentProvider, script.sourceURL, true); + return script._sourceFrame; }, _showScriptOrResource: function(scriptOrResource, options) @@ -531,12 +541,7 @@ WebInspector.ScriptsPanel.prototype = { if (!scriptOrResource) return; - var view; - if (scriptOrResource instanceof WebInspector.Resource) - view = WebInspector.ResourceView.resourceViewForResource(scriptOrResource); - else if (scriptOrResource instanceof WebInspector.Script) - view = this.scriptViewForScript(scriptOrResource); - + var view = this._sourceFrameForScriptOrResource(scriptOrResource); if (!view) return; @@ -738,7 +743,7 @@ WebInspector.ScriptsPanel.prototype = { this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions."); else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions."); - + this._pauseOnExceptionButton.state = pauseOnExceptionsState; WebInspector.settings.pauseOnExceptionState = pauseOnExceptionsState; } @@ -824,8 +829,8 @@ WebInspector.ScriptsPanel.prototype = { _formatScript: function() { - if (this.visibleView && this.visibleView.sourceFrame) - this.visibleView.sourceFrame.formatSource(); + if (this.visibleView) + this.visibleView.formatSource(); }, _enableDebugging: function() @@ -841,10 +846,13 @@ WebInspector.ScriptsPanel.prototype = { this._waitingToPause = false; this._stepping = false; - if (this._debuggerEnabled) - InspectorBackend.disableDebugger(true); - else - InspectorBackend.enableDebugger(!!optionalAlways); + if (this._debuggerEnabled) { + WebInspector.settings.debuggerEnabled = false; + WebInspector.debuggerModel.disableDebugger(); + } else { + WebInspector.settings.debuggerEnabled = !!optionalAlways; + WebInspector.debuggerModel.enableDebugger(); + } }, _togglePauseOnExceptions: function() @@ -1043,3 +1051,41 @@ WebInspector.ScriptsPanel.prototype = { } WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype; + + +WebInspector.SourceFrameContentProviderForScript = function(script) +{ + WebInspector.SourceFrameContentProvider.call(this); + this._script = script; +} + +WebInspector.SourceFrameContentProviderForScript.prototype = { + requestContent: function(callback) + { + if (this._script.source) { + callback("text/javascript", this._script.source); + return; + } + + function didRequestSource(content) + { + var source; + if (content) { + var prefix = ""; + for (var i = 0; i < this._script.startingLine - 1; ++i) + prefix += "\n"; + source = prefix + content; + } else + source = WebInspector.UIString(""); + callback("text/javascript", source); + } + this._script.requestSource(didRequestSource.bind(this)); + }, + + scripts: function() + { + return [this._script]; + } +} + +WebInspector.SourceFrameContentProviderForScript.prototype.__proto__ = WebInspector.SourceFrameContentProvider.prototype; diff --git a/Source/WebCore/inspector/front-end/Settings.js b/Source/WebCore/inspector/front-end/Settings.js index e26b1d7..68b81a5 100644 --- a/Source/WebCore/inspector/front-end/Settings.js +++ b/Source/WebCore/inspector/front-end/Settings.js @@ -45,29 +45,33 @@ var Preferences = { onlineDetectionEnabled: true, nativeInstrumentationEnabled: false, resourceExportEnabled: false, - fileSystemEnabled: false, useDataURLForResourceImageIcons: true, showTimingTab: false, showCookiesTab: false, - debugMode: false + debugMode: false, + heapProfilerPresent: false, + detailedHeapProfiles: false } WebInspector.Settings = function() { this.installApplicationSetting("colorFormat", "hex"); this.installApplicationSetting("consoleHistory", []); + this.installApplicationSetting("debuggerEnabled", false); + this.installApplicationSetting("profilerEnabled", false); this.installApplicationSetting("eventListenersFilter", "all"); + this.installApplicationSetting("lastActivePanel", "elements"); this.installApplicationSetting("lastViewedScriptFile", "application"); + this.installApplicationSetting("monitoringXHREnabled", false); + this.installApplicationSetting("pauseOnExceptionState", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); this.installApplicationSetting("resourcesLargeRows", true); this.installApplicationSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"}); this.installApplicationSetting("resourceViewTab", "content"); this.installApplicationSetting("showInheritedComputedStyleProperties", false); this.installApplicationSetting("showUserAgentStyles", true); this.installApplicationSetting("watchExpressions", []); - this.installApplicationSetting("lastActivePanel", "elements"); - this.installApplicationSetting("pauseOnExceptionState", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); + this.installApplicationSetting("breakpoints", []); - this.installProjectSetting("breakpoints", {}); this.installProjectSetting("nativeBreakpoints", []); } diff --git a/Source/WebCore/inspector/front-end/ShowMoreDataGridNode.js b/Source/WebCore/inspector/front-end/ShowMoreDataGridNode.js new file mode 100644 index 0000000..4fe2fef --- /dev/null +++ b/Source/WebCore/inspector/front-end/ShowMoreDataGridNode.js @@ -0,0 +1,78 @@ +/* + * 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.ShowMoreDataGridNode = function(callback, nextCount, allCount) +{ + function populate(count) + { + var index = this.parent.children.indexOf(this); + this.parent.removeChild(this); + callback(count, index); + } + + this.showNext = document.createElement("button"); + this.showNext.setAttribute("type", "button"); + this.showNext.textContent = WebInspector.UIString("Show next %d", nextCount); + this.showNext.addEventListener("click", populate.bind(this, nextCount), false); + + if (allCount) { + this.showAll = document.createElement("button"); + this.showAll.setAttribute("type", "button"); + this.showAll.textContent = WebInspector.UIString("Show all %d", allCount); + this.showAll.addEventListener("click", populate.bind(this, allCount), false); + } + + WebInspector.DataGridNode.call(this, {summaryRow:true}, false); + this.selectable = false; +} + +WebInspector.ShowMoreDataGridNode.prototype = { + createCells: function() + { + var cell = document.createElement("td"); + if (this.depth) + cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px"); + cell.appendChild(this.showNext); + if (this.showAll) + cell.appendChild(this.showAll); + this._element.appendChild(cell); + + var columns = this.dataGrid.columns; + var count = 0; + for (var c in columns) + ++count; + while (--count > 0) { + cell = document.createElement("td"); + this._element.appendChild(cell); + } + } +}; + +WebInspector.ShowMoreDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype; diff --git a/Source/WebCore/inspector/front-end/SidebarTreeElement.js b/Source/WebCore/inspector/front-end/SidebarTreeElement.js index c08b0ef..a27c457 100644 --- a/Source/WebCore/inspector/front-end/SidebarTreeElement.js +++ b/Source/WebCore/inspector/front-end/SidebarTreeElement.js @@ -164,8 +164,10 @@ WebInspector.SidebarTreeElement.prototype = { if (this.subtitleElement.textContent !== subtitle) this.subtitleElement.textContent = subtitle; this.titlesElement.removeStyleClass("no-subtitle"); - } else + } else { + this.subtitleElement.textContent = ""; this.titlesElement.addStyleClass("no-subtitle"); + } }, isEventWithinDisclosureTriangle: function(event) diff --git a/Source/WebCore/inspector/front-end/SourceFrame.js b/Source/WebCore/inspector/front-end/SourceFrame.js index eb89f24..f2e0be1 100644 --- a/Source/WebCore/inspector/front-end/SourceFrame.js +++ b/Source/WebCore/inspector/front-end/SourceFrame.js @@ -28,17 +28,22 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.SourceFrame = function(parentElement, contentProvider, url, isScript) +WebInspector.SourceFrame = function(contentProvider, url, isScript) { - this._parentElement = parentElement; + WebInspector.View.call(this); + + this.element.addStyleClass("script-view"); + this._contentProvider = contentProvider; this._url = url; this._isScript = isScript; - this._textModel = new WebInspector.TextEditorModel(); this._textModel.replaceTabsWithSpaces = true; + this._currentSearchResultIndex = -1; + this._searchResults = []; + this._messages = []; this._rowMessages = {}; this._messageBubbles = {}; @@ -48,28 +53,41 @@ WebInspector.SourceFrame = function(parentElement, contentProvider, url, isScrip WebInspector.SourceFrame.prototype = { - set visible(visible) + show: function(parentElement) { + WebInspector.View.prototype.show.call(this, parentElement); + if (!this._contentRequested) { this._contentRequested = true; this._contentProvider.requestContent(this._createTextViewer.bind(this)); } - if (visible) { - if (this._textViewer && this._scrollTop) - this._textViewer.element.scrollTop = this._scrollTop; - if (this._textViewer && this._scrollLeft) - this._textViewer.element.scrollLeft = this._scrollLeft; - if (this._textViewer) - this._textViewer.resize(); - } else { - this._hidePopup(); - if (this._textViewer) { - this._scrollTop = this._textViewer.element.scrollTop; - this._scrollLeft = this._textViewer.element.scrollLeft; - this._textViewer.freeCachedElements(); - } + if (this._textViewer) { + if (this._scrollTop) + this._textViewer.scrollTop = this._scrollTop; + if (this._scrollLeft) + this._textViewer.scrollLeft = this._scrollLeft; + this._textViewer.resize(); + } + }, + + hide: function() + { + if (this._textViewer) { + this._scrollTop = this._textViewer.scrollTop; + this._scrollLeft = this._textViewer.scrollLeft; + this._textViewer.freeCachedElements(); } + + WebInspector.View.prototype.hide.call(this); + + this._hidePopup(); + this._clearLineHighlight(); + }, + + hasContent: function() + { + return true; }, markDiff: function(diffData) @@ -95,7 +113,7 @@ WebInspector.SourceFrame.prototype = { // Don't add the message if there is no message or valid line or if the msg isn't an error or warning. if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning()) return; - this._messages.push(msg) + this._messages.push(msg); if (this._textViewer) this._addMessageToSource(msg); }, @@ -127,13 +145,14 @@ WebInspector.SourceFrame.prototype = { get scrollTop() { - return this._textViewer ? this._textViewer.element.scrollTop : 0; + return this._textViewer ? this._textViewer.scrollTop : this._scrollTop; }, set scrollTop(scrollTop) { + this._scrollTop = scrollTop; if (this._textViewer) - this._textViewer.element.scrollTop = scrollTop; + this._textViewer.scrollTop = scrollTop; }, highlightLine: function(line) @@ -144,7 +163,7 @@ WebInspector.SourceFrame.prototype = { this._lineToHighlight = line; }, - clearLineHighlight: function() + _clearLineHighlight: function() { if (this._textViewer) this._textViewer.clearLineHighlight(); @@ -152,11 +171,10 @@ WebInspector.SourceFrame.prototype = { delete this._lineToHighlight; }, - _createTextViewer: function(mimeType, content) + _createTextViewer: function(mimeType, text) { - this._content = content; - this._textModel.setText(null, content); - this._formatter = new WebInspector.ScriptFormatter(content); + this._content = new WebInspector.SourceFrameContent(text, this._contentProvider.scripts()); + this._textModel.setText(null, text); this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url); var element = this._textViewer.element; @@ -165,7 +183,7 @@ WebInspector.SourceFrame.prototype = { element.addEventListener("mousemove", this._mouseMove.bind(this), true); element.addEventListener("scroll", this._scroll.bind(this), true); element.addEventListener("dblclick", this._doubleClick.bind(this), true); - this._parentElement.appendChild(element); + this.element.appendChild(element); this._textViewer.beginUpdates(); @@ -177,12 +195,6 @@ WebInspector.SourceFrame.prototype = { delete this._lineNumberToReveal; } - if (this._pendingMarkRange) { - var range = this._pendingMarkRange; - this.markAndRevealRange(range); - delete this._pendingMarkRange; - } - if (this._lineToHighlight) { this.highlightLine(this._lineToHighlight); delete this._lineToHighlight; @@ -196,9 +208,8 @@ WebInspector.SourceFrame.prototype = { this._textViewer.endUpdates(); WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this); - - if (this._canEditScripts) - this._textViewer.editCallback = this._editLine.bind(this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this); }, _setTextViewerDecorations: function() @@ -214,44 +225,108 @@ WebInspector.SourceFrame.prototype = { if (this._executionLine) this.setExecutionLine(this._executionLine); - var breakpoints = this._breakpoints(); - for (var i = 0; i < breakpoints.length; ++i) - this._addBreakpoint(breakpoints[i]); + this._breakpointIdToTextViewerLineNumber = {}; + this._textViewerLineNumberToBreakpointId = {}; + var breakpoints = WebInspector.debuggerModel.breakpoints; + for (var id in breakpoints) + this._breakpointAdded({ data: breakpoints[id] }); this._textViewer.resize(); this._textViewer.endUpdates(); }, - findSearchMatches: function(query, finishedCallback) + _shouldDisplayBreakpoint: function(breakpoint) { - function doFindSearchMatches() + if (this._url) + return this._url === breakpoint.url; + var scripts = this._contentProvider.scripts(); + for (var i = 0; i < scripts.length; ++i) { + if (breakpoint.sourceID === scripts[i].sourceID) + return true; + } + return false; + }, + + performSearch: function(query, callback) + { + // Call searchCanceled since it will reset everything we need before doing a new search. + this.searchCanceled(); + + function doFindSearchMatches(query) { - var ranges = []; + this._currentSearchResultIndex = -1; + this._searchResults = []; // First do case-insensitive search. var regexObject = createSearchRegex(query); - this._collectRegexMatches(regexObject, ranges); + this._collectRegexMatches(regexObject, this._searchResults); // Then try regex search if user knows the / / hint. try { if (/^\/.*\/$/.test(query)) - this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), ranges); + this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), this._searchResults); } catch (e) { // Silent catch. } - finishedCallback(ranges); + + callback(this, this._searchResults.length); } if (this._textViewer) - doFindSearchMatches.call(this); + doFindSearchMatches.call(this, query); else - this._delayedFindSearchMatches = doFindSearchMatches.bind(this); + this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query); + }, - cancelFindSearchMatches: function() + searchCanceled: function() { delete this._delayedFindSearchMatches; + if (!this._textViewer) + return; + + this._currentSearchResultIndex = -1; + this._searchResults = []; + this._textViewer.markAndRevealRange(null); + }, + + jumpToFirstSearchResult: function() + { + this._jumpToSearchResult(0); + }, + + jumpToLastSearchResult: function() + { + this._jumpToSearchResult(this._searchResults.length - 1); + }, + + jumpToNextSearchResult: function() + { + this._jumpToSearchResult(this._currentSearchResultIndex + 1); + }, + + jumpToPreviousSearchResult: function() + { + this._jumpToSearchResult(this._currentSearchResultIndex - 1); + }, + + showingFirstSearchResult: function() + { + return this._searchResults.length && this._currentSearchResultIndex === 0; + }, + + showingLastSearchResult: function() + { + return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1); + }, + + _jumpToSearchResult: function(index) + { + if (!this._textViewer || !this._searchResults.length) + return; + this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length; + this._textViewer.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]); }, _collectRegexMatches: function(regexObject, ranges) @@ -271,22 +346,6 @@ WebInspector.SourceFrame.prototype = { return ranges; }, - markAndRevealRange: function(range) - { - if (this._textViewer) - this._textViewer.markAndRevealRange(range); - else - this._pendingMarkRange = range; - }, - - clearMarkedRange: function() - { - if (this._textViewer) { - this._textViewer.markAndRevealRange(null); - } else - delete this._pendingMarkRange; - }, - _incrementMessageRepeatCount: function(msg, repeatDelta) { if (!msg._resourceMessageLineElement) @@ -307,7 +366,7 @@ WebInspector.SourceFrame.prototype = { this._executionLine = lineNumber; if (!this._textViewer) return; - var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1); + var textViewerLineNumber = this._originalLocationToTextViewerLineNumber(this._executionLine - 1, 0); this._textViewer.addDecoration(textViewerLineNumber, "webkit-execution-line"); }, @@ -315,7 +374,7 @@ WebInspector.SourceFrame.prototype = { { if (!this._textViewer) return; - var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1); + var textViewerLineNumber = this._originalLocationToTextViewerLineNumber(this._executionLine - 1, 0); this._textViewer.removeDecoration(textViewerLineNumber, "webkit-execution-line"); delete this._executionLine; }, @@ -356,7 +415,7 @@ WebInspector.SourceFrame.prototype = { _addMessageToSource: function(msg) { - if (msg.line >= this._textModel.linesCount) + if (msg.line > this._textModel.linesCount) return; var messageBubbleElement = this._messageBubbles[msg.line]; @@ -412,54 +471,55 @@ WebInspector.SourceFrame.prototype = { { var breakpoint = event.data; - if (breakpoint.sourceID in this._sourceIDSet()) - this._addBreakpoint(breakpoint); - }, + if (!this._shouldDisplayBreakpoint(breakpoint)) + return; - _addBreakpoint: function(breakpoint) - { - var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1); + var resolved = breakpoint.locations.length; + var location = resolved ? breakpoint.locations[0] : breakpoint; + + var textViewerLineNumber = this._originalLocationToTextViewerLineNumber(location.lineNumber, location.columnNumber); if (textViewerLineNumber >= this._textModel.linesCount) return; - breakpoint.addEventListener("enable-changed", this._breakpointChanged, this); - breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); - breakpoint.addEventListener("removed", this._breakpointRemoved, this); + var existingBreakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber]; + if (existingBreakpointId) { + WebInspector.debuggerModel.removeBreakpoint(breakpoint.id); + return; + } - this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition); + this._breakpointIdToTextViewerLineNumber[breakpoint.id] = textViewerLineNumber; + this._textViewerLineNumberToBreakpointId[textViewerLineNumber] = breakpoint.id; + this._setBreakpointDecoration(textViewerLineNumber, resolved, breakpoint.enabled, !!breakpoint.condition); }, _breakpointRemoved: function(event) { - var breakpoint = event.target; + var breakpointId = event.data; - breakpoint.removeEventListener("enable-changed", null, this); - breakpoint.removeEventListener("condition-changed", null, this); - breakpoint.removeEventListener("removed", null, this); + var textViewerLineNumber = this._breakpointIdToTextViewerLineNumber[breakpointId]; + if (textViewerLineNumber === undefined) + return; - var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1); + delete this._breakpointIdToTextViewerLineNumber[breakpointId]; + delete this._textViewerLineNumberToBreakpointId[textViewerLineNumber]; this._removeBreakpointDecoration(textViewerLineNumber); }, - _breakpointChanged: function(event) + _breakpointResolved: function(event) { - var breakpoint = event.target; - var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1); - this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition); + var breakpoint = event.data; + this._breakpointRemoved({ data: breakpoint.id }); + this._breakpointAdded({ data: breakpoint }); }, - _setBreakpointDecoration: function(lineNumber, enabled, hasCondition) + _setBreakpointDecoration: function(lineNumber, resolved, enabled, hasCondition) { this._textViewer.beginUpdates(); this._textViewer.addDecoration(lineNumber, "webkit-breakpoint"); - if (enabled) - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); - else + if (!enabled) this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled"); if (hasCondition) this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional"); - else - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); this._textViewer.endUpdates(); }, @@ -480,49 +540,49 @@ WebInspector.SourceFrame.prototype = { var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (!target) return; - var textViewerLineNumber = target.parentElement.lineNumber; - var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(textViewerLineNumber); + var textViewerLineNumber = target.lineNumber; var contextMenu = new WebInspector.ContextMenu(); - contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, originalLineNumber)); + contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, textViewerLineNumber)); - var breakpoint = this._findBreakpoint(originalLineNumber); + var breakpoint = this._findBreakpoint(textViewerLineNumber); if (!breakpoint) { // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. - contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, originalLineNumber, "", true)); + contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, textViewerLineNumber, "", true)); function addConditionalBreakpoint() { - this._setBreakpointDecoration(textViewerLineNumber, true, true); + this._setBreakpointDecoration(textViewerLineNumber, true, true, true); function didEditBreakpointCondition(committed, condition) { this._removeBreakpointDecoration(textViewerLineNumber); if (committed) - this._setBreakpoint(originalLineNumber, true, condition); + this._setBreakpoint(textViewerLineNumber, condition, true); } this._editBreakpointCondition(textViewerLineNumber, "", didEditBreakpointCondition.bind(this)); } contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this)); } else { // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. - contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint)); + function removeBreakpoint() + { + WebInspector.debuggerModel.removeBreakpoint(breakpoint.id); + } + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint); function editBreakpointCondition() { function didEditBreakpointCondition(committed, condition) { - if (committed) { - breakpoint.remove(); - this._setBreakpoint(originalLineNumber, breakpoint.enabled, condition); - } + if (committed) + WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, condition, breakpoint.enabled); } this._editBreakpointCondition(textViewerLineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this)); } contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this)); function setBreakpointEnabled(enabled) { - breakpoint.remove(); - this._setBreakpoint(originalLineNumber, enabled, breakpoint.condition); + WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, enabled); } if (breakpoint.enabled) contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false)); @@ -546,15 +606,16 @@ WebInspector.SourceFrame.prototype = { var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (!target) return; - var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(target.parentElement.lineNumber); + var textViewerLineNumber = target.lineNumber; - var breakpoint = this._findBreakpoint(originalLineNumber); + var breakpoint = this._findBreakpoint(textViewerLineNumber); if (breakpoint) { - breakpoint.remove(); if (event.shiftKey) - this._setBreakpoint(originalLineNumber, !breakpoint.enabled, breakpoint.condition); + WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, !breakpoint.enabled); + else + WebInspector.debuggerModel.removeBreakpoint(breakpoint.id); } else - this._setBreakpoint(originalLineNumber, true, ""); + this._setBreakpoint(textViewerLineNumber, "", true); event.preventDefault(); }, @@ -629,7 +690,7 @@ WebInspector.SourceFrame.prototype = { if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) return; - var lineRow = element.enclosingNodeOrSelfWithNodeName("tr"); + var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content"); if (!lineRow) return; @@ -713,7 +774,7 @@ WebInspector.SourceFrame.prototype = { return; showObjectPopup.call(this, result); } - WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, evaluateCallback.bind(this)); + WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, false, evaluateCallback.bind(this)); }, _editBreakpointCondition: function(lineNumber, condition, callback) @@ -752,7 +813,7 @@ WebInspector.SourceFrame.prototype = { var editorElement = document.createElement("input"); editorElement.id = "source-frame-breakpoint-condition"; editorElement.className = "monospace"; - editorElement.type = "text" + editorElement.type = "text"; conditionElement.appendChild(editorElement); this._conditionEditorElement = editorElement; @@ -785,23 +846,24 @@ WebInspector.SourceFrame.prototype = { formatSource: function() { - if (!this._formatter) + if (!this._content) return; - function didFormat(source) + function didFormat(formattedContent) { - this._textModel.setText(null, source); + this._formattedContent = formattedContent; + this._textModel.setText(null, formattedContent.text); this._setTextViewerDecorations(); } - this._formatter.format(didFormat.bind(this)); + var formatter = new WebInspector.ScriptFormatter(); + formatter.formatContent(this._content, didFormat.bind(this)) }, _continueToLine: function(lineNumber) { - var sourceID = this._sourceIDForLine(lineNumber); - if (!sourceID) - return; - WebInspector.debuggerModel.continueToLine(sourceID, lineNumber + 1); + var location = this._textViewerLineNumberToScriptLocation(lineNumber); + if (location.sourceID) + WebInspector.debuggerModel.continueToLine(location.sourceID, location.lineNumber); }, _doubleClick: function(event) @@ -809,79 +871,66 @@ WebInspector.SourceFrame.prototype = { if (!Preferences.canEditScriptSource || !this._isScript) return; - var target = event.target.enclosingNodeOrSelfWithNodeName("TD"); - if (!target || target.parentElement.firstChild === target) + var lineRow = event.target.enclosingNodeOrSelfWithClass("webkit-line-content"); + if (!lineRow) return; // Do not trigger editing from line numbers. - var lineRow = target.parentElement; var lineNumber = lineRow.lineNumber; - var sourceID = this._sourceIDForLine(lineNumber); - if (!sourceID) + var location = this._textViewerLineNumberToScriptLocation(lineNumber); + if (!location.sourceID) return; function didEditLine(newContent) { var lines = []; - var oldLines = this._content.split('\n'); + var oldLines = this._content.text.split('\n'); for (var i = 0; i < oldLines.length; ++i) { if (i === lineNumber) lines.push(newContent); else lines.push(oldLines[i]); } - WebInspector.debuggerModel.editScriptSource(sourceID, lines.join("\n")); + WebInspector.debuggerModel.editScriptSource(location.sourceID, lines.join("\n")); } this._textViewer.editLine(lineRow, didEditLine.bind(this)); }, - _setBreakpoint: function(lineNumber, enabled, condition) + _setBreakpoint: function(lineNumber, condition, enabled) { - var sourceID = this._sourceIDForLine(lineNumber); - if (!sourceID) + var location = this._textViewerLineNumberToScriptLocation(lineNumber); + if (this._url) + WebInspector.debuggerModel.setBreakpoint(this._url, location.lineNumber, location.columnNumber, condition, enabled); + else if (location.sourceID) + WebInspector.debuggerModel.setBreakpointBySourceId(location.sourceID, location.lineNumber, location.columnNumber, condition, enabled); + else return; - WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber + 1, enabled, condition); + if (!WebInspector.panels.scripts.breakpointsActivated) WebInspector.panels.scripts.toggleBreakpointsClicked(); }, - _breakpoints: function() + _findBreakpoint: function(textViewerLineNumber) { - var sourceIDSet = this._sourceIDSet(); - return WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID in sourceIDSet; }); + var breakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber]; + return WebInspector.debuggerModel.breakpointForId(breakpointId); }, - _findBreakpoint: function(lineNumber) + _originalLocationToTextViewerLineNumber: function(lineNumber, columnNumber) { - var sourceID = this._sourceIDForLine(lineNumber); - return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber + 1); + if (!this._formattedContent) + return lineNumber; + return this._formattedContent.originalLocationToFormattedLocation(lineNumber, columnNumber).lineNumber; }, - _sourceIDForLine: function(lineNumber) + _textViewerLineNumberToScriptLocation: function(lineNumber) { - var sourceIDForLine = null; - var closestStartingLine = 0; - var scripts = this._contentProvider.scripts(); - for (var i = 0; i < scripts.length; ++i) { - var lineOffset = scripts[i].lineOffset; - if (lineOffset <= lineNumber && lineOffset >= closestStartingLine) { - closestStartingLine = lineOffset; - sourceIDForLine = scripts[i].sourceID; - } - } - return sourceIDForLine; - }, - - _sourceIDSet: function() - { - var scripts = this._contentProvider.scripts(); - var sourceIDSet = {}; - for (var i = 0; i < scripts.length; ++i) - sourceIDSet[scripts[i].sourceID] = true; - return sourceIDSet; + if (!this._formattedContent) + return this._content.scriptLocationForLineNumber(lineNumber); + return this._formattedContent.scriptLocationForFormattedLineNumber(lineNumber); } } -WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; +WebInspector.SourceFrame.prototype.__proto__ = WebInspector.View.prototype; WebInspector.SourceFrameContentProvider = function() diff --git a/Source/WebCore/inspector/front-end/SourceFrameContent.js b/Source/WebCore/inspector/front-end/SourceFrameContent.js new file mode 100644 index 0000000..e4a74ec --- /dev/null +++ b/Source/WebCore/inspector/front-end/SourceFrameContent.js @@ -0,0 +1,153 @@ +/* + * 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, scripts) +{ + if (scripts.length && scripts[0].length < text.length) { + // WebKit html lexer normalizes line endings and scripts are passed to VM with "\n" line endings. + // However, resource content has original line endings, so we have to normalize line endings here. + text = text.replace(/\r\n/g, "\n"); + } + this._text = text; + this._lineEndings = text.findAll("\n"); + this._lineEndings.push(text.length); + + this._scriptRanges = []; + for (var i = 0; i < scripts.length; ++i) { + var script = scripts[i]; + var offset = this.locationToPosition(script.lineOffset, script.columnOffset); + this._scriptRanges.push({ start: offset, end: offset + script.length, script: script }); + } + this._scriptRanges.sort(function(x, y) { return x.start - y.start; }); +} + +WebInspector.SourceFrameContent.prototype = { + get text() + { + return this._text; + }, + + get scriptRanges() + { + return this._scriptRanges; + }, + + locationToPosition: function(lineNumber, columnNumber) + { + var position = lineNumber ? this._lineEndings[lineNumber - 1] + 1 : 0; + return position + columnNumber; + }, + + positionToLocation: function(position) + { + var location = {}; + location.lineNumber = this._lineEndings.upperBound(position - 1); + if (!location.lineNumber) + location.columnNumber = position; + else + location.columnNumber = position - this._lineEndings[location.lineNumber - 1] - 1; + return location; + }, + + scriptLocationForLineNumber: function(lineNumber) + { + var range = this.lineNumberToRange(lineNumber); + return this.scriptLocationForRange(range.start, range.end); + }, + + scriptLocationForRange: function(start, end) + { + var position = start; + var scriptRange = this._intersectingScriptRange(start, end); + if (scriptRange) + position = Math.max(position, scriptRange.start); + var scriptLocation = this.positionToLocation(position); + if (scriptRange) + scriptLocation.sourceID = scriptRange.script.sourceID; + return scriptLocation; + }, + + lineNumberToRange: function(lineNumber) + { + var previousLineEnd = this._lineEndings[lineNumber - 1] || 0; + var lineEnd = this._lineEndings[lineNumber]; + return { start: previousLineEnd + 1, end: lineEnd }; + }, + + _intersectingScriptRange: function(start, end) + { + for (var i = 0; i < this._scriptRanges.length; ++i) { + var scriptRange = this._scriptRanges[i]; + if (start < scriptRange.end && end > scriptRange.start) + return scriptRange; + } + } +} + + +WebInspector.FormattedSourceFrameContent = function(originalContent, text, mapping) +{ + this._originalContent = originalContent; + this._formattedContent = new WebInspector.SourceFrameContent(text, []); + this._mapping = mapping; +} + +WebInspector.FormattedSourceFrameContent.prototype = { + get text() + { + return this._formattedContent.text; + }, + + originalLocationToFormattedLocation: function(lineNumber, columnNumber) + { + var originalPosition = this._originalContent.locationToPosition(lineNumber, columnNumber); + var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition); + return this._formattedContent.positionToLocation(formattedPosition); + }, + + scriptLocationForFormattedLineNumber: function(lineNumber) + { + var range = this._formattedContent.lineNumberToRange(lineNumber); + var start = this._convertPosition(this._mapping.formatted, this._mapping.original, range.start); + var end = this._convertPosition(this._mapping.formatted, this._mapping.original, range.end); + return this._originalContent.scriptLocationForRange(start, end); + }, + + _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; + } +} diff --git a/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.js b/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.js index cfbc44f..48c5bd4 100644 --- a/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.js +++ b/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.js @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Thu Feb 25 21:44:55 2010 */ +/* Generated by re2c 0.13.5 on Fri Jan 28 18:32:27 2011 */ /* * Copyright (C) 2009 Google Inc. All rights reserved. * @@ -67,7 +67,8 @@ WebInspector.SourceHTMLTokenizer = function() ATTRIBUTE_VALUE: 2, LINKIFY: 4, A_NODE: 8, - SCRIPT: 16 + SCRIPT: 16, + STYLE: 32 }; this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }; @@ -82,6 +83,12 @@ WebInspector.SourceHTMLTokenizer.prototype = { this._internalJavaScriptTokenizer.line = line.substring(0, match.index); } else this._internalJavaScriptTokenizer.line = line; + } else if (this._internalCSSTokenizer) { + var match = /<\/style/i.exec(line); + if (match) { + this._internalCSSTokenizer.line = line.substring(0, match.index); + } else + this._internalCSSTokenizer.line = line; } this._line = line; }, @@ -146,6 +153,18 @@ WebInspector.SourceHTMLTokenizer.prototype = { return result; } else if (cursor !== this._line.length) delete this._internalJavaScriptTokenizer; + } else if (this._internalCSSTokenizer) { + // Re-set line to force detection first. + this.line = this._line; + if (cursor !== this._internalCSSTokenizer._line.length) { + // Tokenizer is stateless, so restore its condition before tokenizing and save it after. + this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition; + var result = this._internalCSSTokenizer.nextToken(cursor); + this.tokenType = this._internalCSSTokenizer.tokenType; + this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition; + return result; + } else if (cursor !== this._line.length) + delete this._internalCSSTokenizer; } var cursorOnEnter = cursor; @@ -331,8 +350,8 @@ case 39: case 40: this.setLexCondition(this._lexConditions.TAG); { - if (this._condition.parseCondition & this._parseConditions.SCRIPT) { - // Do not tokenize script tag contents, keep lexer state although processing "<". + if (this._condition.parseCondition & (this._parseConditions.SCRIPT | this._parseConditions.STYLE)) { + // Do not tokenize script and style tag contents, keep lexer state, even though processing "<". this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; @@ -345,13 +364,21 @@ case 40: case 41: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); - if (yych == 'S') { gotoCase = 68; continue; }; - if (yych == 's') { gotoCase = 68; continue; }; + if (yych == 'S') { gotoCase = 73; continue; }; + if (yych == 's') { gotoCase = 73; continue; }; { gotoCase = 40; continue; }; case 42: yych = this._charAt(++cursor); - if (yych == 'C') { gotoCase = 62; continue; }; - if (yych == 'c') { gotoCase = 62; continue; }; + if (yych <= 'T') { + if (yych == 'C') { gotoCase = 62; continue; }; + if (yych >= 'T') { gotoCase = 63; continue; }; + } else { + if (yych <= 'c') { + if (yych >= 'c') { gotoCase = 62; continue; }; + } else { + if (yych == 't') { gotoCase = 63; continue; }; + } + } case 43: cursor = YYMARKER; { gotoCase = 40; continue; }; @@ -421,56 +448,113 @@ case 59: { this.tokenType = "html-comment"; return cursor; } case 62: yych = this._charAt(++cursor); - if (yych == 'R') { gotoCase = 63; continue; }; - if (yych != 'r') { gotoCase = 43; continue; }; + if (yych == 'R') { gotoCase = 68; continue; }; + if (yych == 'r') { gotoCase = 68; continue; }; + { gotoCase = 43; continue; }; case 63: yych = this._charAt(++cursor); - if (yych == 'I') { gotoCase = 64; continue; }; - if (yych != 'i') { gotoCase = 43; continue; }; + if (yych == 'Y') { gotoCase = 64; continue; }; + if (yych != 'y') { gotoCase = 43; continue; }; case 64: yych = this._charAt(++cursor); - if (yych == 'P') { gotoCase = 65; continue; }; - if (yych != 'p') { gotoCase = 43; continue; }; + if (yych == 'L') { gotoCase = 65; continue; }; + if (yych != 'l') { gotoCase = 43; continue; }; case 65: yych = this._charAt(++cursor); - if (yych == 'T') { gotoCase = 66; continue; }; - if (yych != 't') { gotoCase = 43; continue; }; + if (yych == 'E') { gotoCase = 66; continue; }; + if (yych != 'e') { gotoCase = 43; continue; }; case 66: ++cursor; this.setLexCondition(this._lexConditions.TAG); { - if (this._condition.parseCondition & this._parseConditions.SCRIPT) { - // Do not tokenize script tag contents, keep lexer state although processing "<". + if (this._condition.parseCondition & this._parseConditions.STYLE) { + // Do not tokenize style tag contents, keep lexer state, even though processing "<". this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; } this.tokenType = "html-tag"; - this._condition.parseCondition = this._parseConditions.SCRIPT; + this._condition.parseCondition = this._parseConditions.STYLE; this._setExpectingAttribute(); return cursor; } case 68: yych = this._charAt(++cursor); - if (yych == 'C') { gotoCase = 69; continue; }; - if (yych != 'c') { gotoCase = 43; continue; }; + if (yych == 'I') { gotoCase = 69; continue; }; + if (yych != 'i') { gotoCase = 43; continue; }; case 69: yych = this._charAt(++cursor); - if (yych == 'R') { gotoCase = 70; continue; }; - if (yych != 'r') { gotoCase = 43; continue; }; + if (yych == 'P') { gotoCase = 70; continue; }; + if (yych != 'p') { gotoCase = 43; continue; }; case 70: yych = this._charAt(++cursor); - if (yych == 'I') { gotoCase = 71; continue; }; - if (yych != 'i') { gotoCase = 43; continue; }; + if (yych == 'T') { gotoCase = 71; continue; }; + if (yych != 't') { gotoCase = 43; continue; }; case 71: + ++cursor; + this.setLexCondition(this._lexConditions.TAG); + { + if (this._condition.parseCondition & this._parseConditions.SCRIPT) { + // Do not tokenize script tag contents, keep lexer state, even though processing "<". + this.setLexCondition(this._lexConditions.INITIAL); + this.tokenType = null; + return cursor; + } + this.tokenType = "html-tag"; + this._condition.parseCondition = this._parseConditions.SCRIPT; + this._setExpectingAttribute(); + return cursor; + } +case 73: + yych = this._charAt(++cursor); + if (yych <= 'T') { + if (yych == 'C') { gotoCase = 75; continue; }; + if (yych <= 'S') { gotoCase = 43; continue; }; + } else { + if (yych <= 'c') { + if (yych <= 'b') { gotoCase = 43; continue; }; + { gotoCase = 75; continue; }; + } else { + if (yych != 't') { gotoCase = 43; continue; }; + } + } + yych = this._charAt(++cursor); + if (yych == 'Y') { gotoCase = 81; continue; }; + if (yych == 'y') { gotoCase = 81; continue; }; + { gotoCase = 43; continue; }; +case 75: + yych = this._charAt(++cursor); + if (yych == 'R') { gotoCase = 76; continue; }; + if (yych != 'r') { gotoCase = 43; continue; }; +case 76: + yych = this._charAt(++cursor); + if (yych == 'I') { gotoCase = 77; continue; }; + if (yych != 'i') { gotoCase = 43; continue; }; +case 77: yych = this._charAt(++cursor); - if (yych == 'P') { gotoCase = 72; continue; }; + if (yych == 'P') { gotoCase = 78; continue; }; if (yych != 'p') { gotoCase = 43; continue; }; -case 72: +case 78: yych = this._charAt(++cursor); - if (yych == 'T') { gotoCase = 73; continue; }; + if (yych == 'T') { gotoCase = 79; continue; }; if (yych != 't') { gotoCase = 43; continue; }; -case 73: +case 79: + ++cursor; + this.setLexCondition(this._lexConditions.TAG); + { + this.tokenType = "html-tag"; + this._condition.parseCondition = this._parseConditions.INITIAL; + return cursor; + } +case 81: + yych = this._charAt(++cursor); + if (yych == 'L') { gotoCase = 82; continue; }; + if (yych != 'l') { gotoCase = 43; continue; }; +case 82: + yych = this._charAt(++cursor); + if (yych == 'E') { gotoCase = 83; continue; }; + if (yych != 'e') { gotoCase = 43; continue; }; +case 83: ++cursor; this.setLexCondition(this._lexConditions.TAG); { @@ -482,78 +566,78 @@ case 73: case this.case_SSTRING: yych = this._charAt(cursor); if (yych <= '\f') { - if (yych == '\n') { gotoCase = 79; continue; }; - { gotoCase = 78; continue; }; + if (yych == '\n') { gotoCase = 89; continue; }; + { gotoCase = 88; continue; }; } else { - if (yych <= '\r') { gotoCase = 79; continue; }; - if (yych == '\'') { gotoCase = 81; continue; }; - { gotoCase = 78; continue; }; + if (yych <= '\r') { gotoCase = 89; continue; }; + if (yych == '\'') { gotoCase = 91; continue; }; + { gotoCase = 88; continue; }; } -case 77: +case 87: { return this._stringToken(cursor); } -case 78: +case 88: yych = this._charAt(++cursor); - { gotoCase = 85; continue; }; -case 79: + { gotoCase = 95; continue; }; +case 89: ++cursor; { this.tokenType = null; return cursor; } -case 81: +case 91: ++cursor; -case 82: +case 92: this.setLexCondition(this._lexConditions.TAG); { return this._stringToken(cursor, true); } -case 83: +case 93: yych = this._charAt(++cursor); - { gotoCase = 82; continue; }; -case 84: + { gotoCase = 92; continue; }; +case 94: ++cursor; yych = this._charAt(cursor); -case 85: +case 95: if (yych <= '\f') { - if (yych == '\n') { gotoCase = 77; continue; }; - { gotoCase = 84; continue; }; + if (yych == '\n') { gotoCase = 87; continue; }; + { gotoCase = 94; continue; }; } else { - if (yych <= '\r') { gotoCase = 77; continue; }; - if (yych == '\'') { gotoCase = 83; continue; }; - { gotoCase = 84; continue; }; + if (yych <= '\r') { gotoCase = 87; continue; }; + if (yych == '\'') { gotoCase = 93; continue; }; + { gotoCase = 94; continue; }; } /* *********************************** */ case this.case_TAG: yych = this._charAt(cursor); if (yych <= '&') { if (yych <= '\r') { - if (yych == '\n') { gotoCase = 90; continue; }; - if (yych >= '\r') { gotoCase = 90; continue; }; + if (yych == '\n') { gotoCase = 100; continue; }; + if (yych >= '\r') { gotoCase = 100; continue; }; } else { if (yych <= ' ') { - if (yych >= ' ') { gotoCase = 90; continue; }; + if (yych >= ' ') { gotoCase = 100; continue; }; } else { - if (yych == '"') { gotoCase = 92; continue; }; + if (yych == '"') { gotoCase = 102; continue; }; } } } else { if (yych <= '>') { if (yych <= ';') { - if (yych <= '\'') { gotoCase = 93; continue; }; + if (yych <= '\'') { gotoCase = 103; continue; }; } else { - if (yych <= '<') { gotoCase = 90; continue; }; - if (yych <= '=') { gotoCase = 94; continue; }; - { gotoCase = 96; continue; }; + if (yych <= '<') { gotoCase = 100; continue; }; + if (yych <= '=') { gotoCase = 104; continue; }; + { gotoCase = 106; continue; }; } } else { if (yych <= '[') { - if (yych >= '[') { gotoCase = 90; continue; }; + if (yych >= '[') { gotoCase = 100; continue; }; } else { - if (yych == ']') { gotoCase = 90; continue; }; + if (yych == ']') { gotoCase = 100; continue; }; } } } ++cursor; yych = this._charAt(cursor); - { gotoCase = 109; continue; }; -case 89: + { gotoCase = 119; continue; }; +case 99: { - if (this._condition.parseCondition === this._parseConditions.SCRIPT) { + if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) { // Fall through if expecting attributes. this.tokenType = null; return cursor; @@ -580,18 +664,18 @@ case 89: this.tokenType = null; return cursor; } -case 90: +case 100: ++cursor; { this.tokenType = null; return cursor; } -case 92: +case 102: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); - { gotoCase = 105; continue; }; -case 93: + { gotoCase = 115; continue; }; +case 103: yyaccept = 0; yych = this._charAt(YYMARKER = ++cursor); - { gotoCase = 99; continue; }; -case 94: + { gotoCase = 109; continue; }; +case 104: ++cursor; { if (this._isExpectingAttribute()) @@ -599,7 +683,7 @@ case 94: this.tokenType = null; return cursor; } -case 96: +case 106: ++cursor; this.setLexCondition(this._lexConditions.INITIAL); { @@ -613,68 +697,77 @@ case 96: return cursor; } + if (this._condition.parseCondition & this._parseConditions.STYLE) { + if (!this._internalCSSTokenizer) { + this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css"); + this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition; + } + // Do not tokenize style tag contents. + return cursor; + } + this._condition.parseCondition = this._parseConditions.INITIAL; return cursor; } -case 98: +case 108: ++cursor; yych = this._charAt(cursor); -case 99: +case 109: if (yych <= '\f') { - if (yych != '\n') { gotoCase = 98; continue; }; + if (yych != '\n') { gotoCase = 108; continue; }; } else { - if (yych <= '\r') { gotoCase = 100; continue; }; - if (yych == '\'') { gotoCase = 102; continue; }; - { gotoCase = 98; continue; }; + if (yych <= '\r') { gotoCase = 110; continue; }; + if (yych == '\'') { gotoCase = 112; continue; }; + { gotoCase = 108; continue; }; } -case 100: +case 110: ++cursor; this.setLexCondition(this._lexConditions.SSTRING); { return this._stringToken(cursor); } -case 102: +case 112: ++cursor; { return this._stringToken(cursor, true); } -case 104: +case 114: ++cursor; yych = this._charAt(cursor); -case 105: +case 115: if (yych <= '\f') { - if (yych != '\n') { gotoCase = 104; continue; }; + if (yych != '\n') { gotoCase = 114; continue; }; } else { - if (yych <= '\r') { gotoCase = 106; continue; }; - if (yych == '"') { gotoCase = 102; continue; }; - { gotoCase = 104; continue; }; + if (yych <= '\r') { gotoCase = 116; continue; }; + if (yych == '"') { gotoCase = 112; continue; }; + { gotoCase = 114; continue; }; } -case 106: +case 116: ++cursor; this.setLexCondition(this._lexConditions.DSTRING); { return this._stringToken(cursor); } -case 108: +case 118: ++cursor; yych = this._charAt(cursor); -case 109: +case 119: if (yych <= '"') { if (yych <= '\r') { - if (yych == '\n') { gotoCase = 89; continue; }; - if (yych <= '\f') { gotoCase = 108; continue; }; - { gotoCase = 89; continue; }; + if (yych == '\n') { gotoCase = 99; continue; }; + if (yych <= '\f') { gotoCase = 118; continue; }; + { gotoCase = 99; continue; }; } else { - if (yych == ' ') { gotoCase = 89; continue; }; - if (yych <= '!') { gotoCase = 108; continue; }; - { gotoCase = 89; continue; }; + if (yych == ' ') { gotoCase = 99; continue; }; + if (yych <= '!') { gotoCase = 118; continue; }; + { gotoCase = 99; continue; }; } } else { if (yych <= '>') { - if (yych == '\'') { gotoCase = 89; continue; }; - if (yych <= ';') { gotoCase = 108; continue; }; - { gotoCase = 89; continue; }; + if (yych == '\'') { gotoCase = 99; continue; }; + if (yych <= ';') { gotoCase = 118; continue; }; + { gotoCase = 99; continue; }; } else { if (yych <= '[') { - if (yych <= 'Z') { gotoCase = 108; continue; }; - { gotoCase = 89; continue; }; + if (yych <= 'Z') { gotoCase = 118; continue; }; + { gotoCase = 99; continue; }; } else { - if (yych == ']') { gotoCase = 89; continue; }; - { gotoCase = 108; continue; }; + if (yych == ']') { gotoCase = 99; continue; }; + { gotoCase = 118; continue; }; } } } diff --git a/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js b/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js index 44c62b3..769e984 100644 --- a/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js +++ b/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js @@ -66,7 +66,8 @@ WebInspector.SourceHTMLTokenizer = function() ATTRIBUTE_VALUE: 2, LINKIFY: 4, A_NODE: 8, - SCRIPT: 16 + SCRIPT: 16, + STYLE: 32 }; this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }; @@ -81,6 +82,12 @@ WebInspector.SourceHTMLTokenizer.prototype = { this._internalJavaScriptTokenizer.line = line.substring(0, match.index); } else this._internalJavaScriptTokenizer.line = line; + } else if (this._internalCSSTokenizer) { + var match = /<\/style/i.exec(line); + if (match) { + this._internalCSSTokenizer.line = line.substring(0, match.index); + } else + this._internalCSSTokenizer.line = line; } this._line = line; }, @@ -145,6 +152,18 @@ WebInspector.SourceHTMLTokenizer.prototype = { return result; } else if (cursor !== this._line.length) delete this._internalJavaScriptTokenizer; + } else if (this._internalCSSTokenizer) { + // Re-set line to force detection first. + this.line = this._line; + if (cursor !== this._internalCSSTokenizer._line.length) { + // Tokenizer is stateless, so restore its condition before tokenizing and save it after. + this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition; + var result = this._internalCSSTokenizer.nextToken(cursor); + this.tokenType = this._internalCSSTokenizer.tokenType; + this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition; + return result; + } else if (cursor !== this._line.length) + delete this._internalCSSTokenizer; } var cursorOnEnter = cursor; @@ -175,6 +194,9 @@ WebInspector.SourceHTMLTokenizer.prototype = { ScriptStart = "<" [Ss] [Cc] [Rr] [Ii] [Pp] [Tt]; ScriptEnd = ""; EqualSign = "="; @@ -201,7 +223,7 @@ WebInspector.SourceHTMLTokenizer.prototype = { ScriptStart => TAG { if (this._condition.parseCondition & this._parseConditions.SCRIPT) { - // Do not tokenize script tag contents, keep lexer state although processing "<". + // Do not tokenize script tag contents, keep lexer state, even though processing "<". this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; @@ -219,10 +241,31 @@ WebInspector.SourceHTMLTokenizer.prototype = { return cursor; } + StyleStart => TAG + { + if (this._condition.parseCondition & this._parseConditions.STYLE) { + // Do not tokenize style tag contents, keep lexer state, even though processing "<". + this.setLexCondition(this._lexConditions.INITIAL); + this.tokenType = null; + return cursor; + } + this.tokenType = "html-tag"; + this._condition.parseCondition = this._parseConditions.STYLE; + this._setExpectingAttribute(); + return cursor; + } + + StyleEnd => TAG + { + this.tokenType = "html-tag"; + this._condition.parseCondition = this._parseConditions.INITIAL; + return cursor; + } + LT => TAG { - if (this._condition.parseCondition & this._parseConditions.SCRIPT) { - // Do not tokenize script tag contents, keep lexer state although processing "<". + if (this._condition.parseCondition & (this._parseConditions.SCRIPT | this._parseConditions.STYLE)) { + // Do not tokenize script and style tag contents, keep lexer state, even though processing "<". this.setLexCondition(this._lexConditions.INITIAL); this.tokenType = null; return cursor; @@ -245,6 +288,15 @@ WebInspector.SourceHTMLTokenizer.prototype = { return cursor; } + if (this._condition.parseCondition & this._parseConditions.STYLE) { + if (!this._internalCSSTokenizer) { + this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css"); + this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition; + } + // Do not tokenize style tag contents. + return cursor; + } + this._condition.parseCondition = this._parseConditions.INITIAL; return cursor; } @@ -267,7 +319,7 @@ WebInspector.SourceHTMLTokenizer.prototype = { Identifier { - if (this._condition.parseCondition === this._parseConditions.SCRIPT) { + if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) { // Fall through if expecting attributes. this.tokenType = null; return cursor; diff --git a/Source/WebCore/inspector/front-end/SourceView.js b/Source/WebCore/inspector/front-end/SourceView.js deleted file mode 100644 index 37caabb..0000000 --- a/Source/WebCore/inspector/front-end/SourceView.js +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2007, 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.SourceView = function(resource) -{ - WebInspector.ResourceView.call(this, resource); - - this.element.addStyleClass("source"); - - var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource); - var isScript = resource.type === WebInspector.Resource.Type.Script; - this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, isScript); -} - -WebInspector.SourceView.prototype = { - show: function(parentElement) - { - WebInspector.View.prototype.show.call(this, parentElement); - this.sourceFrame.visible = true; - }, - - hide: function() - { - this.sourceFrame.visible = false; - this.sourceFrame.clearLineHighlight(); - WebInspector.View.prototype.hide.call(this); - this._currentSearchResultIndex = -1; - }, - - resize: function() - { - this.sourceFrame.resize(); - }, - - get scrollTop() - { - return this.sourceFrame.scrollTop; - }, - - set scrollTop(scrollTop) - { - this.sourceFrame.scrollTop = scrollTop; - }, - - hasContent: function() - { - return true; - }, - - // The rest of the methods in this prototype need to be generic enough to work with a ScriptView. - // The ScriptView prototype pulls these methods into it's prototype to avoid duplicate code. - - searchCanceled: function() - { - this._currentSearchResultIndex = -1; - this._searchResults = []; - this.sourceFrame.clearMarkedRange(); - this.sourceFrame.cancelFindSearchMatches(); - }, - - performSearch: function(query, finishedCallback) - { - // Call searchCanceled since it will reset everything we need before doing a new search. - this.searchCanceled(); - - function didFindSearchMatches(searchResults) - { - this._searchResults = searchResults; - if (this._searchResults) - finishedCallback(this, this._searchResults.length); - } - this.sourceFrame.findSearchMatches(query, didFindSearchMatches.bind(this)); - }, - - jumpToFirstSearchResult: function() - { - if (!this._searchResults || !this._searchResults.length) - return; - this._currentSearchResultIndex = 0; - this._jumpToSearchResult(this._currentSearchResultIndex); - }, - - jumpToLastSearchResult: function() - { - if (!this._searchResults || !this._searchResults.length) - return; - this._currentSearchResultIndex = (this._searchResults.length - 1); - this._jumpToSearchResult(this._currentSearchResultIndex); - }, - - jumpToNextSearchResult: function() - { - if (!this._searchResults || !this._searchResults.length) - return; - if (++this._currentSearchResultIndex >= this._searchResults.length) - this._currentSearchResultIndex = 0; - this._jumpToSearchResult(this._currentSearchResultIndex); - }, - - jumpToPreviousSearchResult: function() - { - if (!this._searchResults || !this._searchResults.length) - return; - if (--this._currentSearchResultIndex < 0) - this._currentSearchResultIndex = (this._searchResults.length - 1); - this._jumpToSearchResult(this._currentSearchResultIndex); - }, - - showingFirstSearchResult: function() - { - return (this._currentSearchResultIndex === 0); - }, - - showingLastSearchResult: function() - { - return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1)); - }, - - revealLine: function(lineNumber) - { - this.sourceFrame.revealLine(lineNumber); - }, - - highlightLine: function(lineNumber) - { - this.sourceFrame.highlightLine(lineNumber); - }, - - addMessage: function(msg) - { - this.sourceFrame.addMessage(msg); - }, - - clearMessages: function() - { - this.sourceFrame.clearMessages(); - }, - - _jumpToSearchResult: function(index) - { - var foundRange = this._searchResults[index]; - if (!foundRange) - return; - - this.sourceFrame.markAndRevealRange(foundRange); - } -} - -WebInspector.SourceView.prototype.__proto__ = WebInspector.ResourceView.prototype; - - -WebInspector.SourceFrameContentProviderForResource = function(resource) -{ - WebInspector.SourceFrameContentProvider.call(this); - this._resource = resource; -} - -//This is a map from resource.type to mime types -//found in WebInspector.SourceTokenizer.Registry. -WebInspector.SourceFrameContentProviderForResource.DefaultMIMETypeForResourceType = { - 0: "text/html", - 1: "text/css", - 4: "text/javascript" -} - -WebInspector.SourceFrameContentProviderForResource.prototype = { - requestContent: function(callback) - { - function contentLoaded(content) - { - var mimeType = WebInspector.SourceFrameContentProviderForResource.DefaultMIMETypeForResourceType[this._resource.type] || this._resource.mimeType; - callback(mimeType, content); - } - this._resource.requestContent(contentLoaded.bind(this)); - }, - - scripts: function() - { - return WebInspector.debuggerModel.scriptsForURL(this._resource.url); - } -} - -WebInspector.SourceFrameContentProviderForResource.prototype.__proto__ = WebInspector.SourceFrameContentProvider.prototype; diff --git a/Source/WebCore/inspector/front-end/StylesSidebarPane.js b/Source/WebCore/inspector/front-end/StylesSidebarPane.js index 9880adc..57d3b76 100644 --- a/Source/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/Source/WebCore/inspector/front-end/StylesSidebarPane.js @@ -1709,10 +1709,6 @@ WebInspector.StylePropertyTreeElement.prototype = { editingEnded: function(context) { - if (this._prompt) { - this._prompt.removeFromElement(); - delete this._prompt; - } this.hasChildren = context.hasChildren; if (context.expanded) this.expand(); @@ -1727,6 +1723,7 @@ WebInspector.StylePropertyTreeElement.prototype = { editingCancelled: function(element, context) { + this._removePrompt(); if ("originalPropertyText" in this) this.applyStyleText(this.originalPropertyText, true); else { @@ -1742,6 +1739,7 @@ WebInspector.StylePropertyTreeElement.prototype = { editingCommitted: function(element, userInput, previousContent, context, moveDirection) { + this._removePrompt(); this.editingEnded(context); var isEditingName = context.isEditingName; @@ -1839,6 +1837,15 @@ WebInspector.StylePropertyTreeElement.prototype = { } }, + _removePrompt: function() + { + // BUG 53242. This cannot go into editingEnded(), as it should always happen first for any editing outcome. + if (this._prompt) { + this._prompt.removeFromElement(); + delete this._prompt; + } + }, + _hasBeenAppliedToPageViaUpDown: function() { // New properties applied via up/down have an originalPropertyText and will be deleted later @@ -1922,16 +1929,34 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = { var reverse = event.keyIdentifier === "Up"; if (this.autoCompleteElement) this.complete(false, reverse); // Accept the current suggestion, if any. + else { + // Select the word suffix to affect it when computing the subsequent suggestion. + this._selectCurrentWordSuffix(); + } + this.complete(false, reverse); // Actually increment/decrement the suggestion. event.handled = true; }, - _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback) + _selectCurrentWordSuffix: function() { - var prefix = wordRange.toString().toLowerCase(); - if (!prefix.length) + var selection = window.getSelection(); + if (!selection.rangeCount) return; + var selectionRange = selection.getRangeAt(0); + if (!selectionRange.commonAncestorContainer.isDescendant(this.element)) + return; + var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.element, "forward"); + if (!wordSuffixRange.toString()) + return; + selection.removeAllRanges(); + selection.addRange(wordSuffixRange); + }, + + _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback) + { + var prefix = wordRange.toString().toLowerCase(); var results; if (bestMatchOnly) { results = []; diff --git a/Source/WebCore/inspector/front-end/TextPrompt.js b/Source/WebCore/inspector/front-end/TextPrompt.js index ac54d8c..36a38cc 100644 --- a/Source/WebCore/inspector/front-end/TextPrompt.js +++ b/Source/WebCore/inspector/front-end/TextPrompt.js @@ -196,7 +196,12 @@ WebInspector.TextPrompt.prototype = { return; var selectionRange = selection.getRangeAt(0); - if (!selectionRange.commonAncestorContainer.isDescendant(this.element)) + var isEmptyInput = selectionRange.commonAncestorContainer === this.element; // this.element has no child Text nodes. + + // Do not attempt to auto-complete an empty input in the auto mode (only on demand). + if (auto && isEmptyInput) + return; + if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this.element)) return; if (auto && !this.isCaretAtEndOfPrompt()) return; diff --git a/Source/WebCore/inspector/front-end/TextViewer.js b/Source/WebCore/inspector/front-end/TextViewer.js index ea36513..ce6502d 100644 --- a/Source/WebCore/inspector/front-end/TextViewer.js +++ b/Source/WebCore/inspector/front-end/TextViewer.js @@ -32,37 +32,23 @@ WebInspector.TextViewer = function(textModel, platform, url) { this._textModel = textModel; - this._textModel.changeListener = this._buildChunks.bind(this); - this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel, this._highlightDataReady.bind(this)); + this._textModel.changeListener = this._textChanged.bind(this); this.element = document.createElement("div"); this.element.className = "text-editor monospace"; - this.element.tabIndex = 0; - - this.element.addEventListener("scroll", this._scroll.bind(this), false); - this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false); - this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false); - this.element.addEventListener("copy", this._copy.bind(this), false); - - this._url = url; - - this._linesContainerElement = document.createElement("table"); - this._linesContainerElement.className = "text-editor-lines"; - this._linesContainerElement.setAttribute("cellspacing", 0); - this._linesContainerElement.setAttribute("cellpadding", 0); - this.element.appendChild(this._linesContainerElement); - - this._defaultChunkSize = 50; - this._paintCoalescingLevel = 0; - this.freeCachedElements(); - this._buildChunks(); + var syncScrollListener = this._syncScroll.bind(this); + var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this); + this._mainPanel = new WebInspector.TextEditorMainPanel(this._textModel, url, syncScrollListener, syncDecorationsForLineListener); + this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener); + this.element.appendChild(this._mainPanel.element); + this.element.appendChild(this._gutterPanel.element); } WebInspector.TextViewer.prototype = { set mimeType(mimeType) { - this._highlighter.mimeType = mimeType; + this._mainPanel.mimeType = mimeType; }, get textModel() @@ -72,85 +58,190 @@ WebInspector.TextViewer.prototype = { revealLine: function(lineNumber) { - if (lineNumber >= this._textModel.linesCount) - return; - - var chunk = this._makeLineAChunk(lineNumber); - chunk.element.scrollIntoViewIfNeeded(); + this._mainPanel.revealLine(lineNumber); }, addDecoration: function(lineNumber, decoration) { - var chunk = this._makeLineAChunk(lineNumber); - chunk.addDecoration(decoration); + this._mainPanel.addDecoration(lineNumber, decoration); + this._gutterPanel.addDecoration(lineNumber, decoration); }, removeDecoration: function(lineNumber, decoration) { - var chunk = this._makeLineAChunk(lineNumber); - chunk.removeDecoration(decoration); + this._mainPanel.removeDecoration(lineNumber, decoration); + this._gutterPanel.removeDecoration(lineNumber, decoration); }, markAndRevealRange: function(range) { - if (this._rangeToMark) { - var markedLine = this._rangeToMark.startLine; - this._rangeToMark = null; - this._paintLines(markedLine, markedLine + 1); - } - - if (range) { - this._rangeToMark = range; - this.revealLine(range.startLine); - this._paintLines(range.startLine, range.startLine + 1); - if (this._markedRangeElement) - this._markedRangeElement.scrollIntoViewIfNeeded(); - } - delete this._markedRangeElement; + this._mainPanel.markAndRevealRange(range); }, highlightLine: function(lineNumber) { - this.clearLineHighlight(); - this._highlightedLine = lineNumber; - this.revealLine(lineNumber); - var chunk = this._makeLineAChunk(lineNumber); - chunk.addDecoration("webkit-highlighted-line"); + this._mainPanel.highlightLine(lineNumber); }, clearLineHighlight: function() { - if (typeof this._highlightedLine === "number") { - var chunk = this._makeLineAChunk(this._highlightedLine); - chunk.removeDecoration("webkit-highlighted-line"); - delete this._highlightedLine; - } + this._mainPanel.clearLineHighlight(); }, freeCachedElements: function() { - this._cachedSpans = []; - this._cachedTextNodes = []; - this._cachedRows = []; + this._mainPanel.freeCachedElements(); + this._gutterPanel.freeCachedElements(); + }, + + editLine: function(lineRow, callback) + { + this._mainPanel.editLine(lineRow, callback); + }, + + get scrollTop() + { + return this._mainPanel.element.scrollTop; + }, + + set scrollTop(scrollTop) + { + this._mainPanel.element.scrollTop = scrollTop; + }, + + get scrollLeft() + { + return this._mainPanel.element.scrollLeft; + }, + + set scrollLeft(scrollLeft) + { + this._mainPanel.element.scrollLeft = scrollLeft; + }, + + beginUpdates: function() + { + this._mainPanel.beginUpdates(); + this._gutterPanel.beginUpdates(); + }, + + endUpdates: function() + { + this._mainPanel.endUpdates(); + this._gutterPanel.endUpdates(); + }, + + resize: function() + { + this._mainPanel.resize(); + this._gutterPanel.resize(); + this._updatePanelOffsets(); + }, + + // WebInspector.TextModel listener + _textChanged: function(oldRange, newRange, oldText, newText) + { + this._mainPanel.textChanged(); + this._gutterPanel.textChanged(); + this._updatePanelOffsets(); + }, + + _updatePanelOffsets: function() + { + var lineNumbersWidth = this._gutterPanel.element.offsetWidth; + if (lineNumbersWidth) + this._mainPanel.element.style.setProperty("left", lineNumbersWidth + "px"); + else + this._mainPanel.element.style.removeProperty("left"); // Use default value set in CSS. + }, + + _syncScroll: function() + { + // Async call due to performance reasons. + setTimeout(function() { + var mainElement = this._mainPanel.element; + var gutterElement = this._gutterPanel.element; + + // Handle horizontal scroll bar at the bottom of the main panel. + if (gutterElement.offsetHeight > mainElement.clientHeight) + gutterElement.style.setProperty("padding-bottom", (gutterElement.offsetHeight - mainElement.clientHeight) + "px"); + else + gutterElement.style.removeProperty("padding-bottom"); + + gutterElement.scrollTop = mainElement.scrollTop; + }.bind(this), 0); + }, + + _syncDecorationsForLine: function(lineNumber) + { + if (lineNumber >= this._textModel.linesCount) + return; + + var mainChunk = this._mainPanel.makeLineAChunk(lineNumber); + var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber); + var height = mainChunk.height; + if (height) + gutterChunk.element.style.setProperty("height", height + "px"); + else + gutterChunk.element.style.removeProperty("height"); + } +} + +WebInspector.TextEditorChunkedPanel = function(textModel) +{ + this._textModel = textModel; + + this._defaultChunkSize = 50; + this._paintCoalescingLevel = 0; +} + +WebInspector.TextEditorChunkedPanel.prototype = { + get textModel() + { + return this._textModel; + }, + + revealLine: function(lineNumber) + { + if (lineNumber >= this._textModel.linesCount) + return; + + var chunk = this.makeLineAChunk(lineNumber); + chunk.element.scrollIntoViewIfNeeded(); + }, + + addDecoration: function(lineNumber, decoration) + { + var chunk = this.makeLineAChunk(lineNumber); + chunk.addDecoration(decoration); + }, + + removeDecoration: function(lineNumber, decoration) + { + var chunk = this.makeLineAChunk(lineNumber); + chunk.removeDecoration(decoration); + }, + + textChanged: function(oldRange, newRange, oldText, newText) + { + this._buildChunks(); }, _buildChunks: function() { - this._linesContainerElement.removeChildren(); + this.element.removeChildren(); this._textChunks = []; for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) { - var chunk = new WebInspector.TextChunk(this, i, i + this._defaultChunkSize); + var chunk = this._createNewChunk(i, i + this._defaultChunkSize); this._textChunks.push(chunk); - this._linesContainerElement.appendChild(chunk.element); + this.element.appendChild(chunk.element); } - this._indexChunks(); - this._highlighter.reset(); this._repaintAll(); }, - _makeLineAChunk: function(lineNumber) + makeLineAChunk: function(lineNumber) { if (!this._textChunks) this._buildChunks(); @@ -163,31 +254,30 @@ WebInspector.TextViewer.prototype = { var wasExpanded = oldChunk.expanded; oldChunk.expanded = false; - var insertIndex = oldChunk.chunkNumber + 1; + var insertIndex = chunkNumber + 1; // Prefix chunk. if (lineNumber > oldChunk.startLine) { - var prefixChunk = new WebInspector.TextChunk(this, oldChunk.startLine, lineNumber); + var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber); this._textChunks.splice(insertIndex++, 0, prefixChunk); - this._linesContainerElement.insertBefore(prefixChunk.element, oldChunk.element); + this.element.insertBefore(prefixChunk.element, oldChunk.element); } // Line chunk. - var lineChunk = new WebInspector.TextChunk(this, lineNumber, lineNumber + 1); + var lineChunk = this._createNewChunk(lineNumber, lineNumber + 1); this._textChunks.splice(insertIndex++, 0, lineChunk); - this._linesContainerElement.insertBefore(lineChunk.element, oldChunk.element); + this.element.insertBefore(lineChunk.element, oldChunk.element); // Suffix chunk. if (oldChunk.startLine + oldChunk.linesCount > lineNumber + 1) { - var suffixChunk = new WebInspector.TextChunk(this, lineNumber + 1, oldChunk.startLine + oldChunk.linesCount); + var suffixChunk = this._createNewChunk(lineNumber + 1, oldChunk.startLine + oldChunk.linesCount); this._textChunks.splice(insertIndex, 0, suffixChunk); - this._linesContainerElement.insertBefore(suffixChunk.element, oldChunk.element); + this.element.insertBefore(suffixChunk.element, oldChunk.element); } // Remove enclosing chunk. - this._textChunks.splice(oldChunk.chunkNumber, 1); - this._linesContainerElement.removeChild(oldChunk.element); - this._indexChunks(); + this._textChunks.splice(chunkNumber, 1); + this.element.removeChild(oldChunk.element); if (wasExpanded) { if (prefixChunk) @@ -200,19 +290,315 @@ WebInspector.TextViewer.prototype = { return lineChunk; }, - _indexChunks: function() + _scroll: function() { - for (var i = 0; i < this._textChunks.length; ++i) - this._textChunks[i].chunkNumber = i; + this._scheduleRepaintAll(); + if (this._syncScrollListener) + this._syncScrollListener(); }, - _scroll: function() + _scheduleRepaintAll: function() { - var scrollTop = this.element.scrollTop; - setTimeout(function() { - if (scrollTop === this.element.scrollTop) - this._repaintAll(); - }.bind(this), 50); + if (this._repaintAllTimer) + clearTimeout(this._repaintAllTimer); + this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50); + }, + + beginUpdates: function() + { + this._paintCoalescingLevel++; + }, + + endUpdates: function() + { + this._paintCoalescingLevel--; + if (!this._paintCoalescingLevel) + this._repaintAll(); + }, + + _chunkNumberForLine: function(lineNumber) + { + for (var i = 0; i < this._textChunks.length; ++i) { + var line = this._textChunks[i].startLine; + if (lineNumber >= line && lineNumber < line + this._textChunks[i].linesCount) + return i; + } + return this._textChunks.length - 1; + }, + + _chunkForLine: function(lineNumber) + { + return this._textChunks[this._chunkNumberForLine(lineNumber)]; + }, + + _repaintAll: function() + { + delete this._repaintAllTimer; + + if (this._paintCoalescingLevel) + return; + + if (!this._textChunks) + this._buildChunks(); + + var visibleFrom = this.element.scrollTop; + var visibleTo = this.element.scrollTop + this.element.clientHeight; + + var offset = 0; + var fromIndex = -1; + var toIndex = 0; + for (var i = 0; i < this._textChunks.length; ++i) { + var chunk = this._textChunks[i]; + var chunkHeight = chunk.height; + if (offset + chunkHeight > visibleFrom && offset < visibleTo) { + if (fromIndex === -1) + fromIndex = i; + toIndex = i + 1; + } else { + if (offset >= visibleTo) + break; + } + offset += chunkHeight; + } + + if (toIndex) + this._expandChunks(fromIndex, toIndex); + }, + + _totalHeight: function(firstElement, lastElement) + { + lastElement = (lastElement || firstElement).nextElementSibling; + if (lastElement) + return lastElement.offsetTop - firstElement.offsetTop; + else if (firstElement.offsetParent) + return firstElement.offsetParent.scrollHeight - firstElement.offsetTop; + return firstElement.offsetHeight; + }, + + resize: function() + { + this._repaintAll(); + } +} + +WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener) +{ + WebInspector.TextEditorChunkedPanel.call(this, textModel); + + this._syncDecorationsForLineListener = syncDecorationsForLineListener; + + this.element = document.createElement("div"); + this.element.className = "text-editor-lines"; + + this.element.addEventListener("scroll", this._scroll.bind(this), false); + + this.freeCachedElements(); + this._buildChunks(); +} + +WebInspector.TextEditorGutterPanel.prototype = { + freeCachedElements: function() + { + this._cachedRows = []; + }, + + _createNewChunk: function(startLine, endLine) + { + return new WebInspector.TextEditorGutterChunk(this, startLine, endLine); + }, + + _expandChunks: function(fromIndex, toIndex) + { + for (var i = 0; i < this._textChunks.length; ++i) { + this._textChunks[i].expanded = (fromIndex <= i && i < toIndex); + } + } +} + +WebInspector.TextEditorGutterPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype; + +WebInspector.TextEditorGutterChunk = function(textViewer, startLine, endLine) +{ + this._textViewer = textViewer; + this._textModel = textViewer._textModel; + + this.startLine = startLine; + endLine = Math.min(this._textModel.linesCount, endLine); + this.linesCount = endLine - startLine; + + this._expanded = false; + + this.element = document.createElement("div"); + this.element.lineNumber = startLine; + this.element.className = "webkit-line-number"; + + if (this.linesCount === 1) { + // Single line chunks are typically created for decorations. Host line number in + // the sub-element in order to allow flexible border / margin management. + var innerSpan = document.createElement("span"); + innerSpan.className = "webkit-line-number-inner"; + innerSpan.textContent = startLine + 1; + var outerSpan = document.createElement("div"); + outerSpan.className = "webkit-line-number-outer"; + outerSpan.appendChild(innerSpan); + this.element.appendChild(outerSpan); + } else { + var lineNumbers = []; + for (var i = startLine; i < endLine; ++i) { + lineNumbers.push(i + 1); + } + this.element.textContent = lineNumbers.join("\n"); + } +} + +WebInspector.TextEditorGutterChunk.prototype = { + addDecoration: function(decoration) + { + if (typeof decoration === "string") { + this.element.addStyleClass(decoration); + } + }, + + removeDecoration: function(decoration) + { + if (typeof decoration === "string") { + this.element.removeStyleClass(decoration); + } + }, + + get expanded() + { + return this._expanded; + }, + + set expanded(expanded) + { + if (this.linesCount === 1) + this._textViewer._syncDecorationsForLineListener(this.startLine); + + if (this._expanded === expanded) + return; + + this._expanded = expanded; + + if (this.linesCount === 1) + return; + + if (expanded) { + this._expandedLineRows = []; + var parentElement = this.element.parentElement; + for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { + var lineRow = this._createRow(i); + parentElement.insertBefore(lineRow, this.element); + this._expandedLineRows.push(lineRow); + } + parentElement.removeChild(this.element); + } else { + var elementInserted = false; + for (var i = 0; i < this._expandedLineRows.length; ++i) { + var lineRow = this._expandedLineRows[i]; + var parentElement = lineRow.parentElement; + if (parentElement) { + if (!elementInserted) { + elementInserted = true; + parentElement.insertBefore(this.element, lineRow); + } + this._textViewer._cachedRows.push(lineRow); + parentElement.removeChild(lineRow); + } + } + delete this._expandedLineRows; + } + }, + + get height() + { + if (!this._expandedLineRows) + return this._textViewer._totalHeight(this.element); + return this._textViewer._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]); + }, + + _createRow: function(lineNumber) + { + var lineRow = this._textViewer._cachedRows.pop() || document.createElement("div"); + lineRow.lineNumber = lineNumber; + lineRow.className = "webkit-line-number"; + lineRow.textContent = lineNumber + 1; + return lineRow; + } +} + +WebInspector.TextEditorMainPanel = function(textModel, url, syncScrollListener, syncDecorationsForLineListener) +{ + WebInspector.TextEditorChunkedPanel.call(this, textModel); + + this._syncScrollListener = syncScrollListener; + this._syncDecorationsForLineListener = syncDecorationsForLineListener; + + this._url = url; + this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this)); + + this.element = document.createElement("div"); + this.element.className = "text-editor-contents"; + this.element.tabIndex = 0; + + this.element.addEventListener("scroll", this._scroll.bind(this), false); + this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false); + + var handleDOMUpdates = this._handleDOMUpdates.bind(this); + this.element.addEventListener("DOMCharacterDataModified", handleDOMUpdates, false); + this.element.addEventListener("DOMNodeInserted", handleDOMUpdates, false); + this.element.addEventListener("DOMNodeRemoved", handleDOMUpdates, false); + + this.freeCachedElements(); + this._buildChunks(); +} + +WebInspector.TextEditorMainPanel.prototype = { + set mimeType(mimeType) + { + this._highlighter.mimeType = mimeType; + }, + + markAndRevealRange: function(range) + { + if (this._rangeToMark) { + var markedLine = this._rangeToMark.startLine; + this._rangeToMark = null; + this._paintLines(markedLine, markedLine + 1); + } + + if (range) { + this._rangeToMark = range; + this.revealLine(range.startLine); + this._paintLines(range.startLine, range.startLine + 1); + if (this._markedRangeElement) + this._markedRangeElement.scrollIntoViewIfNeeded(); + } + delete this._markedRangeElement; + }, + + highlightLine: function(lineNumber) + { + this.clearLineHighlight(); + this._highlightedLine = lineNumber; + this.revealLine(lineNumber); + this.addDecoration(lineNumber, "webkit-highlighted-line"); + }, + + clearLineHighlight: function() + { + if (typeof this._highlightedLine === "number") { + this.removeDecoration(this._highlightedLine, "webkit-highlighted-line"); + delete this._highlightedLine; + } + }, + + freeCachedElements: function() + { + this._cachedSpans = []; + this._cachedTextNodes = []; + this._cachedRows = []; }, _handleKeyDown: function() @@ -248,16 +634,15 @@ WebInspector.TextViewer.prototype = { editLine: function(lineRow, callback) { - var element = lineRow.lastChild; - var oldContent = element.innerHTML; + var oldContent = lineRow.innerHTML; function finishEditing(committed, e, newContent) { if (committed) callback(newContent); - element.innerHTML = oldContent; + lineRow.innerHTML = oldContent; delete this._editingLine; } - this._editingLine = WebInspector.startEditing(element, { + this._editingLine = WebInspector.startEditing(lineRow, { context: null, commitHandler: finishEditing.bind(this, true), cancelHandler: finishEditing.bind(this, false), @@ -265,102 +650,21 @@ WebInspector.TextViewer.prototype = { }); }, - _beforeCopy: function(e) - { - e.preventDefault(); - }, - - _copy: function(e) - { - var range = this._getSelection(); - var text = this._textModel.copyRange(range); - InspectorFrontendHost.copyText(text); - e.preventDefault(); - }, - - beginUpdates: function(enabled) - { - this._paintCoalescingLevel++; - }, - - endUpdates: function(enabled) - { - this._paintCoalescingLevel--; - if (!this._paintCoalescingLevel) - this._repaintAll(); - }, - - _chunkForOffset: function(offset) - { - var currentOffset = 0; - var row = this._linesContainerElement.firstChild; - while (row) { - var rowHeight = row.offsetHeight; - if (offset >= currentOffset && offset < currentOffset + rowHeight) - return row.chunkNumber; - row = row.nextSibling; - currentOffset += rowHeight; - } - return this._textChunks.length - 1; - }, - - _chunkNumberForLine: function(lineNumber) - { - for (var i = 0; i < this._textChunks.length; ++i) { - var line = this._textChunks[i].startLine; - if (lineNumber >= this._textChunks[i].startLine && lineNumber < this._textChunks[i].startLine + this._textChunks[i].linesCount) - return i; - } - return this._textChunks.length - 1; - }, - - _chunkForLine: function(lineNumber) + _buildChunks: function() { - return this._textChunks[this._chunkNumberForLine(lineNumber)]; + this._highlighter.reset(); + WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this); }, - _chunkStartLine: function(chunkNumber) + _createNewChunk: function(startLine, endLine) { - var lineNumber = 0; - for (var i = 0; i < chunkNumber && i < this._textChunks.length; ++i) - lineNumber += this._textChunks[i].linesCount; - return lineNumber; + return new WebInspector.TextEditorMainChunk(this, startLine, endLine); }, - _repaintAll: function() + _expandChunks: function(fromIndex, toIndex) { - if (this._paintCoalescingLevel) - return; - - if (!this._textChunks) - this._buildChunks(); - - var visibleFrom = this.element.scrollTop; - var visibleTo = this.element.scrollTop + this.element.clientHeight; - - var offset = 0; - var firstVisibleLine = -1; - var lastVisibleLine = 0; - var toExpand = []; - var toCollapse = []; - for (var i = 0; i < this._textChunks.length; ++i) { - var chunk = this._textChunks[i]; - var chunkHeight = chunk.height; - if (offset + chunkHeight > visibleFrom && offset < visibleTo) { - toExpand.push(chunk); - if (firstVisibleLine === -1) - firstVisibleLine = chunk.startLine; - lastVisibleLine = chunk.startLine + chunk.linesCount; - } else { - toCollapse.push(chunk); - if (offset >= visibleTo) - break; - } - offset += chunkHeight; - } - - for (var j = i; j < this._textChunks.length; ++j) - toCollapse.push(this._textChunks[i]); + var lastChunk = this._textChunks[toIndex - 1]; + var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount; var selection = this._getSelection(); @@ -368,10 +672,9 @@ WebInspector.TextViewer.prototype = { this._highlighter.highlight(lastVisibleLine); delete this._muteHighlightListener; - for (var i = 0; i < toCollapse.length; ++i) - toCollapse[i].expanded = false; - for (var i = 0; i < toExpand.length; ++i) - toExpand[i].expanded = true; + for (var i = 0; i < this._textChunks.length; ++i) { + this._textChunks[i].expanded = (fromIndex <= i && i < toIndex); + } this._restoreSelection(selection); }, @@ -380,40 +683,40 @@ WebInspector.TextViewer.prototype = { { if (this._muteHighlightListener) return; + this._paintLines(fromLine, toLine, true /*restoreSelection*/); + }, + _paintLines: function(fromLine, toLine, restoreSelection) + { var selection; + var chunk = this._chunkForLine(fromLine); for (var i = fromLine; i < toLine; ++i) { - var lineRow = this._textModel.getAttribute(i, "line-row"); - if (!lineRow || lineRow.highlighted) + if (i >= chunk.startLine + chunk.linesCount) + chunk = this._chunkForLine(i); + var lineRow = chunk.getExpandedLineRow(i); + if (!lineRow) continue; - if (!selection) + if (restoreSelection && !selection) selection = this._getSelection(); this._paintLine(lineRow, i); } - this._restoreSelection(selection); - }, - - _paintLines: function(fromLine, toLine) - { - for (var i = fromLine; i < toLine; ++i) { - var lineRow = this._textModel.getAttribute(i, "line-row"); - if (lineRow) - this._paintLine(lineRow, i); - } + if (restoreSelection) + this._restoreSelection(selection); }, _paintLine: function(lineRow, lineNumber) { - var element = lineRow.lastChild; var highlight = this._textModel.getAttribute(lineNumber, "highlight"); if (!highlight) { if (this._rangeToMark && this._rangeToMark.startLine === lineNumber) - this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn); + this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn); return; } - element.removeChildren(); + lineRow.removeChildren(); var line = this._textModel.line(lineNumber); + if (!line) + lineRow.appendChild(document.createElement("br")); var plainTextStart = -1; for (var j = 0; j < line.length;) { @@ -430,98 +733,64 @@ WebInspector.TextViewer.prototype = { j++; } else { if (plainTextStart !== -1) { - this._appendTextNode(element, line.substring(plainTextStart, j)); + this._appendTextNode(lineRow, line.substring(plainTextStart, j)); plainTextStart = -1; } - this._appendSpan(element, line.substring(j, j + attribute.length), attribute.tokenType); + this._appendSpan(lineRow, line.substring(j, j + attribute.length), attribute.tokenType); j += attribute.length; } } if (plainTextStart !== -1) - this._appendTextNode(element, line.substring(plainTextStart, line.length)); + this._appendTextNode(lineRow, line.substring(plainTextStart, line.length)); if (this._rangeToMark && this._rangeToMark.startLine === lineNumber) - this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn); + this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn); if (lineRow.decorationsElement) - element.appendChild(lineRow.decorationsElement); + lineRow.appendChild(lineRow.decorationsElement); }, - _releaseLinesHighlight: function(fromLine, toLine) + _releaseLinesHighlight: function(lineRow) { - for (var i = fromLine; i < toLine; ++i) { - var lineRow = this._textModel.getAttribute(i, "line-row"); - if (!lineRow) - continue; - var element = lineRow.lastChild; - if ("spans" in element) { - var spans = element.spans; - for (var j = 0; j < spans.length; ++j) - this._cachedSpans.push(spans[j]); - delete element.spans; - } - if ("textNodes" in element) { - var textNodes = element.textNodes; - for (var j = 0; j < textNodes.length; ++j) - this._cachedTextNodes.push(textNodes[j]); - delete element.textNodes; - } + if (!lineRow) + return; + if ("spans" in lineRow) { + var spans = lineRow.spans; + for (var j = 0; j < spans.length; ++j) + this._cachedSpans.push(spans[j]); + delete lineRow.spans; } + if ("textNodes" in lineRow) { + var textNodes = lineRow.textNodes; + for (var j = 0; j < textNodes.length; ++j) + this._cachedTextNodes.push(textNodes[j]); + delete lineRow.textNodes; + } + this._cachedRows.push(lineRow); }, _getSelection: function() { var selection = window.getSelection(); - if (selection.isCollapsed) + if (!selection.rangeCount) return null; var selectionRange = selection.getRangeAt(0); // Selection may be outside of the viewer. if (!this.element.isAncestor(selectionRange.startContainer) || !this.element.isAncestor(selectionRange.endContainer)) return null; var start = this._selectionToPosition(selectionRange.startContainer, selectionRange.startOffset); - var end = this._selectionToPosition(selectionRange.endContainer, selectionRange.endOffset); - return new WebInspector.TextRange(start.line, start.column, end.line, end.column); + var end = selectionRange.collapsed ? start : this._selectionToPosition(selectionRange.endContainer, selectionRange.endOffset); + if (selection.anchorNode === selectionRange.startContainer && selection.anchorOffset === selectionRange.startOffset) + return new WebInspector.TextRange(start.line, start.column, end.line, end.column); + else + return new WebInspector.TextRange(end.line, end.column, start.line, start.column); }, _restoreSelection: function(range) { if (!range) return; - var startRow = this._textModel.getAttribute(range.startLine, "line-row"); - if (startRow) - var start = startRow.lastChild.rangeBoundaryForOffset(range.startColumn); - else { - var offset = range.startColumn; - var chunkNumber = this._chunkNumberForLine(range.startLine); - for (var i = this._chunkStartLine(chunkNumber); i < range.startLine; ++i) - offset += this._textModel.line(i).length + 1; // \n - var lineCell = this._textChunks[chunkNumber].element.lastChild; - if (lineCell.firstChild) - var start = { container: lineCell.firstChild, offset: offset }; - else - var start = { container: lineCell, offset: 0 }; - } - - var endRow = this._textModel.getAttribute(range.endLine, "line-row"); - if (endRow) - var end = endRow.lastChild.rangeBoundaryForOffset(range.endColumn); - else { - var offset = range.endColumn; - var chunkNumber = this._chunkNumberForLine(range.endLine); - for (var i = this._chunkStartLine(chunkNumber); i < range.endLine; ++i) - offset += this._textModel.line(i).length + 1; // \n - var lineCell = this._textChunks[chunkNumber].element.lastChild; - if (lineCell.firstChild) - var end = { container: lineCell.firstChild, offset: offset }; - else - var end = { container: lineCell, offset: 0 }; - } - - var selectionRange = document.createRange(); - selectionRange.setStart(start.container, start.offset); - selectionRange.setEnd(end.container, end.offset); - - var selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange(selectionRange); + 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); }, _selectionToPosition: function(container, offset) @@ -531,21 +800,26 @@ WebInspector.TextViewer.prototype = { if (container === this.element && offset === 1) return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) }; - var lineRow = container.enclosingNodeOrSelfWithNodeName("tr"); + var lineRow = container.enclosingNodeOrSelfWithNodeName("DIV"); var lineNumber = lineRow.lineNumber; - if (container.nodeName === "TD" && offset === 0) + if (container === lineRow && offset === 0) return { line: lineNumber, column: 0 }; - if (container.nodeName === "TD" && offset === 1) - return { line: lineNumber, column: this._textModel.lineLength(lineNumber) }; + // This may be chunk and chunks may contain \n. var column = 0; - var node = lineRow.lastChild.traverseNextTextNode(lineRow.lastChild); + var node = lineRow.traverseNextTextNode(lineRow); while (node && node !== container) { - column += node.textContent.length; - node = node.traverseNextTextNode(lineRow.lastChild); + var text = node.textContent; + for (var i = 0; i < text.length; ++i) { + if (text.charAt(i) === "\n") { + lineNumber++; + column = 0; + } else + column++; + } + node = node.traverseNextTextNode(lineRow); } - // This may be chunk and chunks may contain \n. if (node === container && offset) { var text = node.textContent; for (var i = 0; i < offset; ++i) { @@ -559,6 +833,25 @@ WebInspector.TextViewer.prototype = { return { line: lineNumber, column: column }; }, + _positionToSelection: function(line, column) + { + var chunk = this._chunkForLine(line); + var lineRow = chunk.getExpandedLineRow(line); + if (lineRow) + var rangeBoundary = lineRow.rangeBoundaryForOffset(column); + else { + var offset = column; + for (var i = chunk.startLine; i < line; ++i) + offset += this._textModel.lineLength(i) + 1; // \n + lineRow = chunk.element; + if (lineRow.firstChild) + var rangeBoundary = { container: lineRow.firstChild, offset: offset }; + else + var rangeBoundary = { container: lineRow, offset: 0 }; + } + return rangeBoundary; + }, + _appendSpan: function(element, content, className) { if (className === "html-resource-link" || className === "html-external-link") { @@ -578,9 +871,9 @@ WebInspector.TextViewer.prototype = { _appendTextNode: function(element, text) { var textNode = this._cachedTextNodes.pop(); - if (textNode) { + if (textNode) textNode.nodeValue = text; - } else + else textNode = document.createTextNode(text); element.appendChild(textNode); if (!("textNodes" in element)) @@ -614,58 +907,52 @@ WebInspector.TextViewer.prototype = { return WebInspector.completeURL(this._url, hrefValue); }, - resize: function() + _handleDOMUpdates: function(e) { - this._repaintAll(); + var target = e.target; + var lineRow = target.enclosingNodeOrSelfWithClass("webkit-line-content"); + if (lineRow === target || !lineRow || !lineRow.decorationsElement || !lineRow.decorationsElement.isAncestor(target)) + return; + if (this._syncDecorationsForLineListener) { + // Wait until this event is processed and only then sync the sizes. This is necessary in + // case of the DOMNodeRemoved event, because it is dispatched before the removal takes place. + setTimeout(function() { + this._syncDecorationsForLineListener(lineRow.lineNumber); + }.bind(this), 0); + } } } -var cachedSpans = []; +WebInspector.TextEditorMainPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype; -WebInspector.TextChunk = function(textViewer, startLine, endLine) +WebInspector.TextEditorMainChunk = function(textViewer, startLine, endLine) { this._textViewer = textViewer; - this.element = document.createElement("tr"); this._textModel = textViewer._textModel; - this.element.chunk = this; + + this.element = document.createElement("div"); this.element.lineNumber = startLine; + this.element.className = "webkit-line-content"; this.startLine = startLine; endLine = Math.min(this._textModel.linesCount, endLine); this.linesCount = endLine - startLine; - this._lineNumberElement = document.createElement("td"); - this._lineNumberElement.className = "webkit-line-number"; - this.element.appendChild(this._lineNumberElement); - - this._lineContentElement = document.createElement("td"); - this._lineContentElement.className = "webkit-line-content"; - this.element.appendChild(this._lineContentElement); - this._expanded = false; - var lineNumbers = []; var lines = []; for (var i = startLine; i < endLine; ++i) { - lineNumbers.push(i + 1); lines.push(this._textModel.line(i)); } - if (this.linesCount === 1) { - // Single line chunks are typically created for decorations. Host line number in - // the sub-element in order to allow flexible border / margin management. - var innerSpan = document.createElement("span"); - innerSpan.className = "webkit-line-number-inner"; - innerSpan.textContent = startLine + 1; - var outerSpan = document.createElement("div"); - outerSpan.className = "webkit-line-number-outer"; - outerSpan.appendChild(innerSpan); - this._lineNumberElement.appendChild(outerSpan); - } else - this._lineNumberElement.textContent = lineNumbers.join("\n"); - this._lineContentElement.textContent = lines.join("\n"); + + this.element.textContent = lines.join("\n"); + + // The last empty line will get swallowed otherwise. + if (!lines[lines.length - 1]) + this.element.appendChild(document.createElement("br")); } -WebInspector.TextChunk.prototype = { +WebInspector.TextEditorMainChunk.prototype = { addDecoration: function(decoration) { if (typeof decoration === "string") { @@ -674,7 +961,8 @@ WebInspector.TextChunk.prototype = { } if (!this.element.decorationsElement) { this.element.decorationsElement = document.createElement("div"); - this._lineContentElement.appendChild(this.element.decorationsElement); + this.element.decorationsElement.className = "webkit-line-decorations"; + this.element.appendChild(this.element.decorationsElement); } this.element.decorationsElement.appendChild(decoration); }, @@ -703,71 +991,63 @@ WebInspector.TextChunk.prototype = { this._expanded = expanded; if (this.linesCount === 1) { - this._textModel.setAttribute(this.startLine, "line-row", this.element); if (expanded) - this._textViewer._paintLines(this.startLine, this.startLine + 1); + this._textViewer._paintLine(this.element, this.startLine); return; } if (expanded) { + this._expandedLineRows = []; var parentElement = this.element.parentElement; for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { var lineRow = this._createRow(i); - this._textModel.setAttribute(i, "line-row", lineRow); parentElement.insertBefore(lineRow, this.element); + this._expandedLineRows.push(lineRow); + this._textViewer._paintLine(lineRow, i); } parentElement.removeChild(this.element); - - this._textViewer._paintLines(this.startLine, this.startLine + this.linesCount); } else { - var firstLine = this._textModel.getAttribute(this.startLine, "line-row"); - var parentElement = firstLine.parentElement; - this._textViewer._releaseLinesHighlight(this.startLine, this.startLine + this.linesCount); - - parentElement.insertBefore(this.element, firstLine); - for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { - var lineRow = this._textModel.getAttribute(i, "line-row"); - this._textModel.removeAttribute(i, "line-row"); - this._textViewer._cachedRows.push(lineRow); - parentElement.removeChild(lineRow); + var elementInserted = false; + for (var i = 0; i < this._expandedLineRows.length; ++i) { + var lineRow = this._expandedLineRows[i]; + var parentElement = lineRow.parentElement; + if (parentElement) { + if (!elementInserted) { + elementInserted = true; + parentElement.insertBefore(this.element, lineRow); + } + this._textViewer._releaseLinesHighlight(lineRow); + parentElement.removeChild(lineRow); + } } + delete this._expandedLineRows; } }, get height() { - if (!this._expanded) - return this.element.offsetHeight; - var result = 0; - for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) { - var lineRow = this._textModel.getAttribute(i, "line-row"); - result += lineRow.offsetHeight; - } - return result; + if (!this._expandedLineRows) + return this._textViewer._totalHeight(this.element); + return this._textViewer._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]); }, _createRow: function(lineNumber) { - var cachedRows = this._textViewer._cachedRows; - if (cachedRows.length) { - var lineRow = cachedRows[cachedRows.length - 1]; - cachedRows.length--; - var lineNumberElement = lineRow.firstChild; - var lineContentElement = lineRow.lastChild; - } else { - var lineRow = document.createElement("tr"); - - var lineNumberElement = document.createElement("td"); - lineNumberElement.className = "webkit-line-number"; - lineRow.appendChild(lineNumberElement); - - var lineContentElement = document.createElement("td"); - lineContentElement.className = "webkit-line-content"; - lineRow.appendChild(lineContentElement); - } + var lineRow = this._textViewer._cachedRows.pop() || document.createElement("div"); lineRow.lineNumber = lineNumber; - lineNumberElement.textContent = lineNumber + 1; - lineContentElement.textContent = this._textModel.line(lineNumber); + lineRow.className = "webkit-line-content"; + lineRow.textContent = this._textModel.line(lineNumber); + if (!lineRow.textContent) + lineRow.appendChild(document.createElement("br")); return lineRow; + }, + + getExpandedLineRow: function(lineNumber) + { + if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount) + return null; + if (!this._expandedLineRows) + return this.element; + return this._expandedLineRows[lineNumber - this.startLine]; } } diff --git a/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js index a218c01..a559145 100644 --- a/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js +++ b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js @@ -182,7 +182,6 @@ var OPERATORS = array_to_hash([ ">>=", "<<=", ">>>=", - "~=", "%=", "|=", "^=", @@ -253,18 +252,19 @@ function is_token(token, type, val) { var EX_EOF = {}; -function tokenizer($TEXT, skip_comments) { +function tokenizer($TEXT) { var S = { - text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''), - pos : 0, - tokpos : 0, - line : 0, - tokline : 0, - col : 0, - tokcol : 0, - newline_before : false, - regex_allowed : false + text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''), + pos : 0, + tokpos : 0, + line : 0, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false, + comments_before : [] }; function peek() { return S.text.charAt(S.pos); }; @@ -299,7 +299,7 @@ function tokenizer($TEXT, skip_comments) { S.tokpos = S.pos; }; - function token(type, value) { + function token(type, value, is_comment) { S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) || (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) || (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value))); @@ -311,6 +311,10 @@ function tokenizer($TEXT, skip_comments) { pos : S.tokpos, nlb : S.newline_before }; + if (!is_comment) { + ret.comments_before = S.comments_before; + S.comments_before = []; + } S.newline_before = false; return ret; }; @@ -334,7 +338,7 @@ function tokenizer($TEXT, skip_comments) { }; function read_num(prefix) { - var has_e = false, after_e = false, has_x = false; + var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; var num = read_while(function(ch, i){ if (ch == "x" || ch == "X") { if (has_x) return false; @@ -350,7 +354,12 @@ function tokenizer($TEXT, skip_comments) { } if (ch == "+") return after_e; after_e = false; - return is_alphanumeric_char(ch) || ch == "."; + if (ch == ".") { + if (!has_dot) + return has_dot = true; + return false; + } + return is_alphanumeric_char(ch); }); if (prefix) num = prefix + num; @@ -412,7 +421,7 @@ function tokenizer($TEXT, skip_comments) { ret = S.text.substring(S.pos, i); S.pos = i; } - return token("comment1", ret); + return token("comment1", ret, true); }; function read_multiline_comment() { @@ -420,8 +429,9 @@ function tokenizer($TEXT, skip_comments) { return with_eof_error("Unterminated multiline comment", function(){ var i = find("*/", true), text = S.text.substring(S.pos, i), - tok = token("comment2", text); + tok = token("comment2", text, true); S.pos = i + 2; + S.line += text.split("\n").length - 1; S.newline_before = text.indexOf("\n") >= 0; return tok; }); @@ -455,6 +465,7 @@ function tokenizer($TEXT, skip_comments) { function read_operator(prefix) { function grow(op) { + if (!peek()) return op; var bigger = op + peek(); if (HOP(OPERATORS, bigger)) { next(); @@ -466,19 +477,18 @@ function tokenizer($TEXT, skip_comments) { return token("operator", grow(prefix || next())); }; - var handle_slash = skip_comments ? function() { + function handle_slash() { next(); var regex_allowed = S.regex_allowed; switch (peek()) { - case "/": read_line_comment(); S.regex_allowed = regex_allowed; return next_token(); - case "*": read_multiline_comment(); S.regex_allowed = regex_allowed; return next_token(); - } - return S.regex_allowed ? read_regexp() : read_operator("/"); - } : function() { - next(); - switch (peek()) { - case "/": return read_line_comment(); - case "*": return read_multiline_comment(); + case "/": + S.comments_before.push(read_line_comment()); + S.regex_allowed = regex_allowed; + return next_token(); + case "*": + S.comments_before.push(read_multiline_comment()); + S.regex_allowed = regex_allowed; + return next_token(); } return S.regex_allowed ? read_regexp() : read_operator("/"); }; @@ -559,7 +569,7 @@ var ASSIGNMENT = (function(a, ret, i){ } return ret; })( - ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "~=", "%=", "|=", "^=", "&="], + ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="], { "=": true }, 0 ); @@ -605,13 +615,13 @@ NodeWithToken.prototype.toString = function() { return this.name; }; function parse($TEXT, strict_mode, embed_tokens) { var S = { - input: tokenizer($TEXT, true), - token: null, - prev: null, - peeked: null, - in_function: 0, - in_loop: 0, - labels: [] + input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT, + token : null, + prev : null, + peeked : null, + in_function : 0, + in_loop : 0, + labels : [] }; S.token = next(); @@ -1016,20 +1026,23 @@ function parse($TEXT, strict_mode, embed_tokens) { unexpected(); }; - function expr_list(closing, allow_trailing_comma) { + function expr_list(closing, allow_trailing_comma, allow_empty) { var first = true, a = []; while (!is("punc", closing)) { if (first) first = false; else expect(","); - if (allow_trailing_comma && is("punc", closing)) - break; - a.push(expression(false)); + if (allow_trailing_comma && is("punc", closing)) break; + if (is("punc", ",") && allow_empty) { + a.push([ "atom", "undefined" ]); + } else { + a.push(expression(false)); + } } next(); return a; }; function array_() { - return as("array", expr_list("]", !strict_mode)); + return as("array", expr_list("]", !strict_mode, true)); }; function object_() { @@ -1231,3 +1244,4 @@ exports.KEYWORDS = KEYWORDS; exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN; exports.OPERATORS = OPERATORS; exports.is_alphanumeric_char = is_alphanumeric_char; +exports.is_identifier_char = is_identifier_char; diff --git a/Source/WebCore/inspector/front-end/UglifyJS/process.js b/Source/WebCore/inspector/front-end/UglifyJS/process.js index 65dbc0e..5e32dd0 100755 --- a/Source/WebCore/inspector/front-end/UglifyJS/process.js +++ b/Source/WebCore/inspector/front-end/UglifyJS/process.js @@ -69,139 +69,135 @@ var jsp = require("./parse-js"), function ast_walker(ast) { function _vardefs(defs) { - return MAP(defs, function(def){ + return [ this[0], MAP(defs, function(def){ var a = [ def[0] ]; if (def.length > 1) a[1] = walk(def[1]); return a; - }); + }) ]; }; var walkers = { "string": function(str) { - return [ "string", str ]; + return [ this[0], str ]; }, "num": function(num) { - return [ "num", num ]; + return [ this[0], num ]; }, "name": function(name) { - return [ "name", name ]; + return [ this[0], name ]; }, "toplevel": function(statements) { - return [ "toplevel", MAP(statements, walk) ]; + return [ this[0], MAP(statements, walk) ]; }, "block": function(statements) { - var out = [ "block" ]; + var out = [ this[0] ]; if (statements != null) out.push(MAP(statements, walk)); return out; }, - "var": function(defs) { - return [ "var", _vardefs(defs) ]; - }, - "const": function(defs) { - return [ "const", _vardefs(defs) ]; - }, + "var": _vardefs, + "const": _vardefs, "try": function(t, c, f) { return [ - "try", + this[0], MAP(t, walk), c != null ? [ c[0], MAP(c[1], walk) ] : null, f != null ? MAP(f, walk) : null ]; }, "throw": function(expr) { - return [ "throw", walk(expr) ]; + return [ this[0], walk(expr) ]; }, "new": function(ctor, args) { - return [ "new", walk(ctor), MAP(args, walk) ]; + return [ this[0], walk(ctor), MAP(args, walk) ]; }, "switch": function(expr, body) { - return [ "switch", walk(expr), MAP(body, function(branch){ + return [ this[0], walk(expr), MAP(body, function(branch){ return [ branch[0] ? walk(branch[0]) : null, MAP(branch[1], walk) ]; }) ]; }, "break": function(label) { - return [ "break", label ]; + return [ this[0], label ]; }, "continue": function(label) { - return [ "continue", label ]; + return [ this[0], label ]; }, "conditional": function(cond, t, e) { - return [ "conditional", walk(cond), walk(t), walk(e) ]; + return [ this[0], walk(cond), walk(t), walk(e) ]; }, "assign": function(op, lvalue, rvalue) { - return [ "assign", op, walk(lvalue), walk(rvalue) ]; + return [ this[0], op, walk(lvalue), walk(rvalue) ]; }, "dot": function(expr) { - return [ "dot", walk(expr) ].concat(slice(arguments, 1)); + return [ this[0], walk(expr) ].concat(slice(arguments, 1)); }, "call": function(expr, args) { - return [ "call", walk(expr), MAP(args, walk) ]; + return [ this[0], walk(expr), MAP(args, walk) ]; }, "function": function(name, args, body) { - return [ "function", name, args.slice(), MAP(body, walk) ]; + return [ this[0], name, args.slice(), MAP(body, walk) ]; }, "defun": function(name, args, body) { - return [ "defun", name, args.slice(), MAP(body, walk) ]; + return [ this[0], name, args.slice(), MAP(body, walk) ]; }, "if": function(conditional, t, e) { - return [ "if", walk(conditional), walk(t), walk(e) ]; + return [ this[0], walk(conditional), walk(t), walk(e) ]; }, "for": function(init, cond, step, block) { - return [ "for", walk(init), walk(cond), walk(step), walk(block) ]; + return [ this[0], walk(init), walk(cond), walk(step), walk(block) ]; }, "for-in": function(has_var, key, hash, block) { - return [ "for-in", has_var, key, walk(hash), walk(block) ]; + return [ this[0], has_var, key, walk(hash), walk(block) ]; }, "while": function(cond, block) { - return [ "while", walk(cond), walk(block) ]; + return [ this[0], walk(cond), walk(block) ]; }, "do": function(cond, block) { - return [ "do", walk(cond), walk(block) ]; + return [ this[0], walk(cond), walk(block) ]; }, "return": function(expr) { - return [ "return", walk(expr) ]; + return [ this[0], walk(expr) ]; }, "binary": function(op, left, right) { - return [ "binary", op, walk(left), walk(right) ]; + return [ this[0], op, walk(left), walk(right) ]; }, "unary-prefix": function(op, expr) { - return [ "unary-prefix", op, walk(expr) ]; + return [ this[0], op, walk(expr) ]; }, "unary-postfix": function(op, expr) { - return [ "unary-postfix", op, walk(expr) ]; + return [ this[0], op, walk(expr) ]; }, "sub": function(expr, subscript) { - return [ "sub", walk(expr), walk(subscript) ]; + return [ this[0], walk(expr), walk(subscript) ]; }, "object": function(props) { - return [ "object", MAP(props, function(p){ + return [ this[0], MAP(props, function(p){ return p.length == 2 ? [ p[0], walk(p[1]) ] : [ p[0], walk(p[1]), p[2] ]; // get/set-ter }) ]; }, "regexp": function(rx, mods) { - return [ "regexp", rx, mods ]; + return [ this[0], rx, mods ]; }, "array": function(elements) { - return [ "array", MAP(elements, walk) ]; + return [ this[0], MAP(elements, walk) ]; }, "stat": function(stat) { - return [ "stat", walk(stat) ]; + return [ this[0], walk(stat) ]; }, "seq": function() { - return [ "seq" ].concat(MAP(slice(arguments), walk)); + return [ this[0] ].concat(MAP(slice(arguments), walk)); }, "label": function(name, block) { - return [ "label", name, walk(block) ]; + return [ this[0], name, walk(block) ]; }, "with": function(expr, block) { - return [ "with", walk(expr), walk(block) ]; + return [ this[0], walk(expr), walk(block) ]; }, "atom": function(name) { - return [ "atom", name ]; + return [ this[0], name ]; } }; @@ -405,7 +401,7 @@ function ast_add_scope(ast) { }, "try": function(t, c, f) { if (c != null) return [ - "try", + this[0], MAP(t, walk), [ define(c[0]), MAP(c[1], walk) ], f != null ? MAP(f, walk) : null @@ -491,9 +487,9 @@ function ast_mangle(ast, do_toplevel) { }; function _vardefs(defs) { - return MAP(defs, function(d){ + return [ this[0], MAP(defs, function(d){ return [ get_mangled(d[0]), walk(d[1]) ]; - }); + }) ]; }; return w.with_walkers({ @@ -510,28 +506,25 @@ function ast_mangle(ast, do_toplevel) { } return ast; }, - "var": function(defs) { - return [ "var", _vardefs(defs) ]; - }, - "const": function(defs) { - return [ "const", _vardefs(defs) ]; - }, + "var": _vardefs, + "const": _vardefs, "name": function(name) { - return [ "name", get_mangled(name) ]; + return [ this[0], get_mangled(name) ]; }, "try": function(t, c, f) { - return [ "try", + return [ this[0], MAP(t, walk), c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null, f != null ? MAP(f, walk) : null ]; }, "toplevel": function(body) { - return with_scope(this.scope, function(){ - return [ "toplevel", MAP(body, walk) ]; + var self = this; + return with_scope(self.scope, function(){ + return [ self[0], MAP(body, walk) ]; }); }, "for-in": function(has_var, name, obj, stat) { - return [ "for-in", has_var, get_mangled(name), walk(obj), walk(stat) ]; + return [ this[0], has_var, get_mangled(name), walk(obj), walk(stat) ]; } }, function() { return walk(ast_add_scope(ast)); @@ -569,28 +562,29 @@ function aborts(t) { } }; -function negate(c) { - var not_c = [ "unary-prefix", "!", c ]; - switch (c[0]) { - case "unary-prefix": - return c[1] == "!" ? c[2] : not_c; - case "binary": - var op = c[1], left = c[2], right = c[3]; - switch (op) { - case "<=": return [ "binary", ">", left, right ]; - case "<": return [ "binary", ">=", left, right ]; - case ">=": return [ "binary", "<", left, right ]; - case ">": return [ "binary", "<=", left, right ]; - case "==": return [ "binary", "!=", left, right ]; - case "!=": return [ "binary", "==", left, right ]; - case "===": return [ "binary", "!==", left, right ]; - case "!==": return [ "binary", "===", left, right ]; - case "&&": return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]); - case "||": return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]); - } - break; - } - return not_c; +function boolean_expr(expr) { + return ( (expr[0] == "unary-prefix" + && member(expr[1], [ "!", "delete" ])) || + + (expr[0] == "binary" + && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) || + + (expr[0] == "binary" + && member(expr[1], [ "&&", "||" ]) + && boolean_expr(expr[2]) + && boolean_expr(expr[3])) || + + (expr[0] == "conditional" + && boolean_expr(expr[2]) + && boolean_expr(expr[3])) || + + (expr[0] == "assign" + && expr[1] === true + && boolean_expr(expr[3])) || + + (expr[0] == "seq" + && boolean_expr(expr[expr.length - 1])) + ); }; function make_conditional(c, t, e) { @@ -609,12 +603,44 @@ function ast_squeeze(ast, options) { options = defaults(options, { make_seqs : true, dead_code : true, - no_warnings : false, - extra : false + keep_comps : true, + no_warnings : false }); var w = ast_walker(), walk = w.walk, scope; + function negate(c) { + var not_c = [ "unary-prefix", "!", c ]; + switch (c[0]) { + case "unary-prefix": + return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c; + case "seq": + c = slice(c); + c[c.length - 1] = negate(c[c.length - 1]); + return c; + case "conditional": + return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]); + case "binary": + var op = c[1], left = c[2], right = c[3]; + if (!options.keep_comps) switch (op) { + case "<=" : return [ "binary", ">", left, right ]; + case "<" : return [ "binary", ">=", left, right ]; + case ">=" : return [ "binary", "<", left, right ]; + case ">" : return [ "binary", "<=", left, right ]; + } + switch (op) { + case "==" : return [ "binary", "!=", left, right ]; + case "!=" : return [ "binary", "==", left, right ]; + case "===" : return [ "binary", "!==", left, right ]; + case "!==" : return [ "binary", "===", left, right ]; + case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]); + case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]); + } + break; + } + return not_c; + }; + function with_scope(s, cont) { var _scope = scope; scope = s; @@ -628,87 +654,12 @@ function ast_squeeze(ast, options) { return node[0] == "string" || node[0] == "num"; }; - function find_first_execute(node) { - if (!node) - return false; - - switch (node[0]) { - case "num": - case "string": - case "name": - return node; - case "call": - case "conditional": - case "for": - case "if": - case "new": - case "return": - case "stat": - case "switch": - case "throw": - return find_first_execute(node[1]); - case "binary": - return find_first_execute(node[2]); - case "assign": - if (node[1] === true) - return find_first_execute(node[3]); - break; - case "var": - if (node[1][0].length > 1) - return find_first_execute(node[1][0][1]); - break; - } - return null; - } - - function find_assign_recursive(p, v) { - if (p[0] == "assign" && p[1] != true || p[0] == "unary-prefix") { - if (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1]) - return true; - return false; - } - - if (p[0] != "assign" || p[1] !== true) - return false; - - if ((is_constant(p[3]) && p[3][0] == v[0] && p[3][1] == v[1]) || - (p[3][0] == "name" && v[0] == "name" && p[3][1] == v[1]) || - (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1])) - return true; - - return find_assign_recursive(p[3], v); - }; - function rmblock(block) { if (block != null && block[0] == "block" && block[1] && block[1].length == 1) block = block[1][0]; return block; }; - function clone(obj) { - if (obj && obj.constructor == Array) - return MAP(obj, clone); - return obj; - }; - - function make_seq_to_statements(node) { - if (node[0] != "seq") { - switch (node[0]) { - case "var": - case "const": - return [ node ]; - default: - return [ [ "stat", node ] ]; - } - } - - var ret = []; - for (var i = 1; i < node.length; i++) - ret.push.apply(ret, make_seq_to_statements(node[i])); - - return ret; - }; - function _lambda(name, args, body) { return [ this[0], name, args, with_scope(body.scope, function(){ return tighten(MAP(body, walk), "lambda"); @@ -734,64 +685,6 @@ function ast_squeeze(ast, options) { return a; }, []); - if (options.extra) { - // Detightening things. We do this because then we can assume that the - // statements are structured in a specific way. - statements = (function(a, prev) { - statements.forEach(function(cur) { - switch (cur[0]) { - case "for": - if (cur[1] != null) { - a.push.apply(a, make_seq_to_statements(cur[1])); - cur[1] = null; - } - a.push(cur); - break; - case "stat": - var stats = make_seq_to_statements(cur[1]); - stats.forEach(function(s) { - if (s[1][0] == "unary-postfix") - s[1][0] = "unary-prefix"; - }); - a.push.apply(a, stats); - break; - default: - a.push(cur); - } - }); - return a; - })([]); - - statements = (function(a, prev) { - statements.forEach(function(cur) { - if (!(prev && prev[0] == "stat")) { - a.push(cur); - prev = cur; - return; - } - - var p = prev[1]; - var c = find_first_execute(cur); - if (c && find_assign_recursive(p, c)) { - var old_cur = clone(cur); - c.splice(0, c.length); - c.push.apply(c, p); - var tmp_cur = best_of(cur, [ "toplevel", [ prev, old_cur ] ]); - if (tmp_cur == cur) { - a[a.length -1] = cur; - } else { - cur = old_cur; - a.push(cur); - } - } else { - a.push(cur); - } - prev = cur; - }); - return a; - })([]); - } - statements = (function(a, prev){ statements.forEach(function(cur){ if (prev && ((cur[0] == "var" && prev[0] == "var") || @@ -835,22 +728,6 @@ function ast_squeeze(ast, options) { return a; })([]); - if (options.extra) { - statements = (function(a, prev){ - statements.forEach(function(cur){ - var replaced = false; - if (prev && cur[0] == "for" && cur[1] == null && (prev[0] == "var" || prev[0] == "const" || prev[0] == "stat")) { - cur[1] = prev; - a[a.length - 1] = cur; - } else { - a.push(cur); - } - prev = cur; - }); - return a; - })([]); - } - if (block_type == "lambda") statements = (function(i, a, stat){ while (i < statements.length) { stat = statements[i++]; @@ -901,7 +778,10 @@ function ast_squeeze(ast, options) { if (empty(e) && empty(t)) return [ "stat", c ]; var ret = [ "if", c, t, e ]; - if (t[0] == "stat") { + if (t[0] == "if" && empty(t[3]) && empty(e)) { + ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ])); + } + else if (t[0] == "stat") { if (e) { if (e[0] == "stat") { ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]); @@ -972,23 +852,34 @@ function ast_squeeze(ast, options) { left = walk(left); right = walk(right); var best = [ "binary", op, left, right ]; - if (is_constant(right)) { - if (is_constant(left)) { - var val = null; - switch (op) { - case "+": val = left[1] + right[1]; break; - case "*": val = left[1] * right[1]; break; - case "/": val = left[1] / right[1]; break; - case "-": val = left[1] - right[1]; break; - case "<<": val = left[1] << right[1]; break; - case ">>": val = left[1] >> right[1]; break; - case ">>>": val = left[1] >>> right[1]; break; - } - if (val != null) { - best = best_of(best, [ typeof val == "string" ? "string" : "num", val ]); + if (is_constant(right) && is_constant(left)) { + var val = {}; + var orig = val; + switch (op) { + case "+" : val = left[1] + right[1]; break; + case "*" : val = left[1] * right[1]; break; + case "/" : val = left[1] / right[1]; break; + case "-" : val = left[1] - right[1]; break; + case "<<" : val = left[1] << right[1]; break; + case ">>" : val = left[1] >> right[1]; break; + case ">>>" : val = left[1] >>> right[1]; break; + case "==" : val = left[1] == right[1]; break; + case "===" : val = left[1] === right[1]; break; + case "!=" : val = left[1] != right[1]; break; + case "!==" : val = left[1] !== right[1]; break; + case "<" : val = left[1] < right[1]; break; + case "<=" : val = left[1] <= right[1]; break; + case ">" : val = left[1] > right[1]; break; + case ">=" : val = left[1] >= right[1]; break; + } + if (val !== orig) { + switch (typeof val) { + case "string": val = [ "string", val ]; break; + case "boolean": val = [ "name", val+"" ]; break; + case "number": val = [ "num", val ]; break; + default: return best; } - } else if (left[0] == "binary" && left[1] == "+" && left[3][0] == "string") { - best = best_of(best, [ "binary", "+", left[2], [ "string", left[3][1] + right[1] ] ]); + best = best_of(best, walk(val)); } } return best; @@ -1004,17 +895,12 @@ function ast_squeeze(ast, options) { f != null ? tighten(MAP(f, walk)) : null ]; }, - "unary-prefix": function(op, cond) { - if (op == "!") { - cond = walk(cond); - if (cond[0] == "unary-prefix" && cond[1] == "!") { - var p = w.parent(); - if (p[0] == "unary-prefix" && p[1] == "!") - return cond[2]; - return [ "unary-prefix", "!", cond ]; - } - return best_of(this, negate(cond)); - } + "unary-prefix": function(op, expr) { + expr = walk(expr); + var ret = [ "unary-prefix", op, expr ]; + if (op == "!") + ret = best_of(ret, negate(expr)); + return ret; }, "name": function(name) { switch (name) { @@ -1253,7 +1139,9 @@ function gen_code(ast, beautify) { }, "dot": function(expr) { var out = make(expr), i = 1; - if (needs_parens(expr)) + if (expr[0] == "num") + out += "."; + else if (needs_parens(expr)) out = "(" + out + ")"; while (i < arguments.length) out += "." + make_name(arguments[i++]); @@ -1314,7 +1202,8 @@ function gen_code(ast, beautify) { left = "(" + left + ")"; } if (member(rvalue[0], [ "assign", "conditional", "seq" ]) || - rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]]) { + rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] && + !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) { right = "(" + right + ")"; } return add_spaces([ left, operator, right ]); @@ -1350,7 +1239,8 @@ function gen_code(ast, beautify) { var key = p[0], val = make(p[1]); if (beautify && beautify.quote_keys) { key = make_string(key); - } else if (typeof key == "number" || !beautify && +key + "" == key) { + } else if ((typeof key == "number" || !beautify && +key + "" == key) + && parseFloat(key) >= 0) { key = make_num(+key); } else if (!is_identifier(key)) { key = make_string(key); @@ -1367,6 +1257,7 @@ function gen_code(ast, beautify) { "array": function(elements) { if (elements.length == 0) return "[]"; return add_spaces([ "[", add_commas(MAP(elements, function(el){ + if (!beautify && el[0] == "atom" && el[1] == "undefined") return ""; return parenthesize(el, "seq"); })), "]" ]); }, @@ -1384,12 +1275,6 @@ function gen_code(ast, beautify) { }, "atom": function(name) { return make_name(name); - }, - "comment1": function(text) { - return "//" + text + "\n"; - }, - "comment2": function(text) { - return "/*" + text + "*/"; } }; @@ -1442,8 +1327,16 @@ function gen_code(ast, beautify) { var stat = statements[i]; var code = make(stat); if (code != ";") { - if (!beautify && i == last) - code = code.replace(/;+\s*$/, ""); + if (!beautify && i == last) { + if ((stat[0] == "while" && empty(stat[2])) || + (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) || + (stat[0] == "if" && empty(stat[2]) && !stat[3]) || + (stat[0] == "if" && stat[3] && empty(stat[3]))) { + code = code.replace(/;*\s*$/, ";"); + } else { + code = code.replace(/;+\s*$/, ""); + } + } a.push(code); } } @@ -1498,6 +1391,49 @@ function gen_code(ast, beautify) { return make(ast); }; +function split_lines(code, max_line_length) { + var splits = [ 0 ]; + jsp.parse(function(){ + var next_token = jsp.tokenizer(code); + var last_split = 0; + var prev_token; + function current_length(tok) { + return tok.pos - last_split; + }; + function split_here(tok) { + last_split = tok.pos; + splits.push(last_split); + }; + function custom(){ + var tok = next_token.apply(this, arguments); + out: { + if (prev_token) { + if (prev_token.type == "keyword") break out; + } + if (current_length(tok) > max_line_length) { + switch (tok.type) { + case "keyword": + case "atom": + case "name": + case "punc": + split_here(tok); + break out; + } + } + } + prev_token = tok; + return tok; + }; + custom.context = function() { + return next_token.context.apply(this, arguments); + }; + return custom; + }()); + return splits.map(function(pos, i){ + return code.substring(pos, splits[i + 1] || code.length); + }).join("\n"); +}; + /* -----[ Utilities ]----- */ function repeat_string(str, i) { @@ -1558,3 +1494,5 @@ exports.gen_code = gen_code; exports.ast_add_scope = ast_add_scope; exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more; exports.set_logger = function(logger) { warn = logger }; +exports.make_string = make_string; +exports.split_lines = split_lines; diff --git a/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index a01046b..a6f59ca 100644 --- a/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -139,7 +139,7 @@ WebInspector.WatchExpressionsSection.prototype = { if (!expression) continue; - WebInspector.console.evalInInspectedWindow("(" + expression + ")", this._watchObjectGroupId, appendResult.bind(this, expression, i)); + WebInspector.console.evalInInspectedWindow("(" + expression + ")", this._watchObjectGroupId, false, appendResult.bind(this, expression, i)); } // note this is setting the expansion of the tree, not the section; diff --git a/Source/WebCore/inspector/front-end/WebKit.qrc b/Source/WebCore/inspector/front-end/WebKit.qrc index edc1861..dd325ba 100644 --- a/Source/WebCore/inspector/front-end/WebKit.qrc +++ b/Source/WebCore/inspector/front-end/WebKit.qrc @@ -13,7 +13,6 @@ BreakpointManager.js BreakpointsSidebarPane.js CallStackSidebarPane.js - ChangesView.js Checkbox.js Color.js ConsolePanel.js @@ -28,6 +27,7 @@ Database.js DatabaseQueryView.js DatabaseTableView.js + DetailedHeapshotView.js DataGrid.js DebuggerModel.js DOMAgent.js @@ -44,10 +44,10 @@ ExtensionPanel.js ExtensionRegistryStub.js ExtensionServer.js - FileSystemView.js FontView.js GoToLineDialog.js HAREntry.js + HeapSnapshot.js HeapSnapshotView.js HelpScreen.js ImageView.js @@ -64,6 +64,7 @@ Panel.js PanelEnablerView.js Placard.js + PleaseWaitMessage.js Popover.js ProfileDataGridTree.js ProfilesPanel.js @@ -84,18 +85,18 @@ ScriptFormatter.js ScriptFormatterWorker.js ScriptsPanel.js - ScriptView.js Section.js Settings.js ShortcutsHelp.js + ShowMoreDataGridNode.js SidebarPane.js SidebarTreeElement.js SourceCSSTokenizer.js SourceFrame.js + SourceFrameContent.js SourceHTMLTokenizer.js SourceJavaScriptTokenizer.js SourceTokenizer.js - SourceView.js StatusBarButton.js StylesSidebarPane.js SummaryBar.js diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css index f629d12..c992806 100644 --- a/Source/WebCore/inspector/front-end/inspector.css +++ b/Source/WebCore/inspector/front-end/inspector.css @@ -428,10 +428,6 @@ body.port-qt #dock-status-bar-item { -webkit-mask-image: url(Images/clearConsoleButtonGlyph.png); } -#changes-status-bar-item .glyph { - -webkit-mask-image: url(Images/consoleButtonGlyph.png); /* TODO: Needs Image for Changes Toggle Button */ -} - #counters { position: absolute; right: 16px; @@ -442,22 +438,14 @@ body.port-qt #dock-status-bar-item { height: 19px; } -#changes-count, #error-warning-count { +#error-warning-count { display: inline; } -#error-warning-count:hover, #changes-count:hover { +#error-warning-count:hover { border-bottom: 1px solid rgb(96, 96, 96); } -#style-changes-count::before { - content: url(Images/styleIcon.png); /* TODO: Needs Image for Style Changes Icon */ - width: 10px; - height: 10px; - vertical-align: -1px; - margin-right: 2px; -} - #error-count::before { content: url(Images/errorIcon.png); width: 10px; @@ -466,7 +454,7 @@ body.port-qt #dock-status-bar-item { margin-right: 2px; } -#changes-count + #error-warning-count, #error-count + #warning-count { +#error-count + #warning-count { margin-left: 6px; } @@ -685,6 +673,7 @@ body.platform-linux .monospace, body.platform-linux .source-code { .console-message-url { float: right; + margin-left: 4px; } .console-group-messages .section { @@ -2096,6 +2085,10 @@ li.selected .base-storage-tree-element-subtitle { content: url(Images/treeDownTriangleBlack.png); } +.data-grid button { + line-height: 19px; +} + body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-descending { background-image: url(Images/glossyHeader.png); border-right: 1px solid rgb(179, 179, 179); @@ -4320,3 +4313,17 @@ a.worker-item:hover { .cursor-auto { cursor: auto; } + +.please-wait-msg { + position: absolute; + left: 0; + top: 0; + border: 4px black solid; + border-radius: 4px; + background-color: black; + opacity: 0.85; + color: white; + font-size: 12px; + font-weight: bold; + z-index: 10000; +} diff --git a/Source/WebCore/inspector/front-end/inspector.html b/Source/WebCore/inspector/front-end/inspector.html index 0e0b9e9..0435dc3 100644 --- a/Source/WebCore/inspector/front-end/inspector.html +++ b/Source/WebCore/inspector/front-end/inspector.html @@ -54,9 +54,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + - @@ -68,10 +68,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + - @@ -101,6 +101,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + @@ -120,8 +123,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - @@ -131,17 +132,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - + + @@ -164,7 +165,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+

diff --git a/Source/WebCore/inspector/front-end/inspector.js b/Source/WebCore/inspector/front-end/inspector.js index 77abe78..0959289 100644 --- a/Source/WebCore/inspector/front-end/inspector.js +++ b/Source/WebCore/inspector/front-end/inspector.js @@ -223,8 +223,12 @@ var WebInspector = { if (hiddenPanels.indexOf("profiles") === -1) { this.panels.profiles = new WebInspector.ProfilesPanel(); this.panels.profiles.registerProfileType(new WebInspector.CPUProfileType()); - if (Preferences.heapProfilerPresent) - this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType()); + if (Preferences.heapProfilerPresent) { + if (!Preferences.detailedHeapProfiles) + this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType()); + else + this.panels.profiles.registerProfileType(new WebInspector.DetailedHeapshotProfileType()); + } } if (hiddenPanels.indexOf("audits") === -1) this.panels.audits = new WebInspector.AuditsPanel(); @@ -344,53 +348,6 @@ var WebInspector = { errorWarningElement.title = null; }, - get styleChanges() - { - return this._styleChanges; - }, - - set styleChanges(x) - { - x = Math.max(x, 0); - - if (this._styleChanges === x) - return; - this._styleChanges = x; - this._updateChangesCount(); - }, - - _updateChangesCount: function() - { - // TODO: Remove immediate return when enabling the Changes Panel - return; - - var changesElement = document.getElementById("changes-count"); - if (!changesElement) - return; - - if (!this.styleChanges) { - changesElement.addStyleClass("hidden"); - return; - } - - changesElement.removeStyleClass("hidden"); - changesElement.removeChildren(); - - if (this.styleChanges) { - var styleChangesElement = document.createElement("span"); - styleChangesElement.id = "style-changes-count"; - styleChangesElement.textContent = this.styleChanges; - changesElement.appendChild(styleChangesElement); - } - - if (this.styleChanges) { - if (this.styleChanges === 1) - changesElement.title = WebInspector.UIString("%d style change", this.styleChanges); - else - changesElement.title = WebInspector.UIString("%d style changes", this.styleChanges); - } - }, - highlightDOMNode: function(nodeId) { if ("_hideDOMNodeHighlightTimeout" in this) { @@ -445,6 +402,11 @@ var WebInspector = { resourceForURL: function(url) { return this.resourceTreeModel.resourceForURL(url); + }, + + openLinkExternallyLabel: function() + { + return WebInspector.UIString("Open Link in New Window"); } } @@ -471,7 +433,9 @@ WebInspector.PlatformFlavor = { WebInspector.loaded = function() { if ("page" in WebInspector.queryParamsObject) { - WebInspector.socket = new WebSocket("ws://" + window.location.host + "/devtools/page/" + WebInspector.queryParamsObject.page); + var page = WebInspector.queryParamsObject.page; + var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host; + WebInspector.socket = new WebSocket("ws://" + host + "/devtools/page/" + page); WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); } WebInspector.socket.onerror = function(error) { console.error(error); } WebInspector.socket.onopen = function() { @@ -506,9 +470,6 @@ WebInspector.doLoadedDone = function() this.drawer = new WebInspector.Drawer(); this.console = new WebInspector.ConsoleView(this.drawer); - // TODO: Uncomment when enabling the Changes Panel - // this.changes = new WebInspector.ChangesView(this.drawer); - // TODO: Remove class="hidden" from inspector.html on button#changes-status-bar-item this.drawer.visibleView = this.console; this.resourceTreeModel = new WebInspector.ResourceTreeModel(); this.networkManager = new WebInspector.NetworkManager(this.resourceTreeModel); @@ -573,12 +534,6 @@ WebInspector.doLoadedDone = function() errorWarningCount.addEventListener("click", this.showConsole.bind(this), false); this._updateErrorAndWarningCounts(); - this.styleChanges = 0; - // TODO: Uncomment when enabling the Changes Panel - // var changesElement = document.getElementById("changes-count"); - // changesElement.addEventListener("click", this.showChanges.bind(this), false); - // this._updateErrorAndWarningCounts(); - var searchField = document.getElementById("search"); searchField.addEventListener("search", this.performSearch.bind(this), false); // when the search is emptied searchField.addEventListener("mousedown", this._searchFieldManualFocus.bind(this), false); // when the search field is manually selected @@ -597,6 +552,13 @@ WebInspector.doLoadedDone = function() } InspectorBackend.populateScriptObjects(onPopulateScriptObjects); + if (Preferences.debuggerAlwaysEnabled || WebInspector.settings.debuggerEnabled) + this.debuggerModel.enableDebugger(); + if (Preferences.profilerAlwaysEnabled || WebInspector.settings.profilerEnabled) + InspectorBackend.enableProfiler(); + if (WebInspector.settings.monitoringXHREnabled) + InspectorBackend.setMonitoringXHREnabled(true); + InspectorBackend.setConsoleMessagesEnabled(true); function propertyNamesCallback(names) @@ -913,13 +875,13 @@ WebInspector.documentKeyDown = function(event) case "U+0052": // R key if ((event.metaKey && isMac) || (event.ctrlKey && !isMac)) { - InspectorBackend.reloadPage(); + InspectorBackend.reloadPage(event.shiftKey); event.preventDefault(); } break; case "F5": if (!isMac) - InspectorBackend.reloadPage(); + InspectorBackend.reloadPage(event.ctrlKey || event.shiftKey); break; } } @@ -946,6 +908,7 @@ WebInspector.animateStyle = function(animations, duration, callback) { var interval; var complete = 0; + var hasCompleted = false; const intervalDuration = (1000 / 30); // 30 frames per second. const animationsLength = animations.length; @@ -1014,14 +977,32 @@ WebInspector.animateStyle = function(animations, duration, callback) // End condition. if (complete >= duration) { + hasCompleted = true; clearInterval(interval); if (callback) callback(); } } + function forceComplete() + { + if (!hasCompleted) { + complete = duration; + animateLoop(); + } + } + + function cancel() + { + hasCompleted = true; + clearInterval(interval); + } + interval = setInterval(animateLoop, intervalDuration); - return interval; + return { + cancel: cancel, + forceComplete: forceComplete + }; } WebInspector.updateSearchLabel = function() @@ -1147,11 +1128,6 @@ WebInspector.showConsole = function() this.drawer.showView(this.console); } -WebInspector.showChanges = function() -{ - this.drawer.showView(this.changes); -} - WebInspector.showPanel = function(panel) { if (!(panel in this.panels)) @@ -1171,8 +1147,8 @@ WebInspector.domContentEventFired = function(time) WebInspector.loadEventFired = function(time) { this.panels.audits.mainResourceLoadTime = time; - if (this.panels.network) - this.panels.network.mainResourceLoadTime = time; + this.panels.network.mainResourceLoadTime = time; + this.panels.resources.loadEventFired(); this.extensionServer.notifyPageLoaded((time - WebInspector.mainResource.startTime) * 1000); this.mainResourceLoadTime = time; } @@ -1381,6 +1357,8 @@ WebInspector.showSourceLine = function(url, line, preferredPanel) this.currentPanel = this._choosePanelToShowSourceLine(url, line, preferredPanel); if (!this.currentPanel) return false; + if (this.drawer) + this.drawer.immediatelyFinishAnimation(); this.currentPanel.showSourceLine(url, line); return true; } @@ -1511,7 +1489,19 @@ WebInspector.completeURL = function(baseURL, href) var path = href; if (path.charAt(0) !== "/") { var basePath = parsedURL.path; - path = basePath.substring(0, basePath.lastIndexOf("/")) + "/" + path; + // A href of "?foo=bar" implies "basePath?foo=bar". + // With "basePath?a=b" and "?foo=bar" we should get "basePath?foo=bar". + var prefix; + if (path.charAt(0) === "?") { + var basePathCutIndex = basePath.indexOf("?"); + if (basePathCutIndex !== -1) + prefix = basePath.substring(0, basePathCutIndex); + else + prefix = basePath; + } else + prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/"; + + path = prefix + path; } else if (path.length > 1 && path.charAt(1) === "/") { // href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol). return parsedURL.scheme + ":" + path; @@ -1576,6 +1566,12 @@ WebInspector.performSearch = function(event) this.doPerformSearch(event.target.value, forceSearch, event.shiftKey, false); } +WebInspector.cancelSearch = function() +{ + document.getElementById("search").value = ""; + this.doPerformSearch(""); +} + WebInspector.doPerformSearch = function(query, forceSearch, isBackwardSearch, repeatSearch) { var isShortSearch = (query.length < 3); @@ -1873,6 +1869,7 @@ WebInspector.MIMETypes = { "font/opentype": {3: true}, "application/x-font-type1": {3: true}, "application/x-font-ttf": {3: true}, + "application/x-font-woff": {3: true}, "application/x-truetype-font": {3: true}, "text/javascript": {4: true}, "text/ecmascript": {4: true}, diff --git a/Source/WebCore/inspector/front-end/networkPanel.css b/Source/WebCore/inspector/front-end/networkPanel.css index 95ed1bf..c750323 100644 --- a/Source/WebCore/inspector/front-end/networkPanel.css +++ b/Source/WebCore/inspector/front-end/networkPanel.css @@ -65,6 +65,18 @@ font-weight: bold; } +.network-sidebar .data-grid.small tr.offscreen { + height: 21px; +} + +.network-sidebar .data-grid tr.offscreen { + height: 41px; +} + +.network-sidebar .data-grid tr.offscreen td { + display: none; +} + .network-sidebar .data-grid tr.filler { background-color: white; } diff --git a/Source/WebCore/inspector/front-end/textViewer.css b/Source/WebCore/inspector/front-end/textViewer.css index bee9fe5..f6aa65e 100644 --- a/Source/WebCore/inspector/front-end/textViewer.css +++ b/Source/WebCore/inspector/front-end/textViewer.css @@ -9,12 +9,34 @@ } .text-editor-lines { - border: 0; - -webkit-border-horizontal-spacing: 0; - -webkit-border-vertical-spacing: 0; + position: absolute; + top: 0; + left: 0; + bottom: 0; + overflow: hidden; + -webkit-user-select: none; +} + +.text-editor-contents { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: auto; -webkit-user-select: text; } +.text-editor-editable { + -webkit-user-modify: read-write-plaintext-only; +} + +.webkit-line-decorations { + pointer-events: none; + -webkit-user-select: none; + -webkit-user-modify: read-only; +} + .webkit-html-message-bubble { -webkit-box-shadow: black 0px 2px 5px; -webkit-border-radius: 9px; @@ -63,7 +85,6 @@ text-align: right; vertical-align: top; word-break: normal; - -webkit-user-select: none; padding-right: 4px; padding-left: 6px; } @@ -86,9 +107,7 @@ } .webkit-line-content { - width: 100%; padding-left: 2px; - vertical-align: top; } .webkit-breakpoint .webkit-line-number-outer { @@ -136,21 +155,21 @@ opacity: 0.3; } -.webkit-execution-line .webkit-line-content { +.webkit-execution-line.webkit-line-content { background-color: rgb(171, 191, 254); outline: 1px solid rgb(64, 115, 244); } -.diff-container .webkit-added-line .webkit-line-content { +.diff-container .webkit-added-line.webkit-line-content { background-color: rgb(220, 255, 220); } -.diff-container .webkit-removed-line .webkit-line-content { +.diff-container .webkit-removed-line.webkit-line-content { background-color: rgb(255, 220, 220); text-decoration: line-through; } -.diff-container .webkit-changed-line .webkit-line-content { +.diff-container .webkit-changed-line.webkit-line-content { background-color: rgb(220, 220, 255); } @@ -164,7 +183,7 @@ color: black; } -.webkit-highlighted-line .webkit-line-content { +.webkit-highlighted-line.webkit-line-content { -webkit-animation: "fadeout" 2s 0s; } -- cgit v1.1