diff options
Diffstat (limited to 'WebCore/inspector')
58 files changed, 1564 insertions, 1021 deletions
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm index cd9052a..be0948b 100644 --- a/WebCore/inspector/CodeGeneratorInspector.pm +++ b/WebCore/inspector/CodeGeneratorInspector.pm @@ -17,30 +17,35 @@ $typeTransform{"InspectorClient"} = { $typeTransform{"Backend"} = { "forward" => "InspectorBackend", "header" => "InspectorBackend.h", - "handlerAccessor" => "m_inspectorController->inspectorBackend()", + "domainAccessor" => "m_inspectorController->inspectorBackend()", }; $typeTransform{"Controller"} = { "forwardHeader" => "InspectorController.h", - "handlerAccessor" => "m_inspectorController", + "domainAccessor" => "m_inspectorController", }; $typeTransform{"Debug"} = { "forward" => "InspectorDebuggerAgent", "header" => "InspectorDebuggerAgent.h", - "handlerAccessor" => "m_inspectorController->debuggerAgent()", + "domainAccessor" => "m_inspectorController->debuggerAgent()", }; $typeTransform{"DOM"} = { "forward" => "InspectorDOMAgent", "header" => "InspectorDOMAgent.h", - "handlerAccessor" => "m_inspectorController->domAgent()", + "domainAccessor" => "m_inspectorController->domAgent()", }; $typeTransform{"ApplicationCache"} = { "forward" => "InspectorApplicationCacheAgent", "header" => "InspectorApplicationCacheAgent.h", - "handlerAccessor" => "m_inspectorController->applicationCacheAgent()", + "domainAccessor" => "m_inspectorController->applicationCacheAgent()", +}; +$typeTransform{"Profiler"} = { + "forward" => "InspectorProfilerAgent", + "header" => "InspectorProfilerAgent.h", + "domainAccessor" => "m_inspectorController->profilerAgent()", }; $typeTransform{"Frontend"} = { - "forward" => "RemoteInspectorFrontend", - "header" => "RemoteInspectorFrontend.h", + "forward" => "InspectorFrontend", + "header" => "InspectorFrontend.h", }; $typeTransform{"PassRefPtr"} = { "forwardHeader" => "wtf/PassRefPtr.h", @@ -51,7 +56,7 @@ $typeTransform{"Object"} = { "defaultValue" => "InspectorObject::create()", "forward" => "InspectorObject", "header" => "InspectorValues.h", - "accessorSuffix" => "Object" + "JSONType" => "Object" }; $typeTransform{"Array"} = { "param" => "PassRefPtr<InspectorArray>", @@ -59,7 +64,7 @@ $typeTransform{"Array"} = { "defaultValue" => "InspectorArray::create()", "forward" => "InspectorArray", "header" => "InspectorValues.h", - "accessorSuffix" => "Array" + "JSONType" => "Array" }; $typeTransform{"Value"} = { "param" => "PassRefPtr<InspectorValue>", @@ -67,14 +72,15 @@ $typeTransform{"Value"} = { "defaultValue" => "InspectorValue::null()", "forward" => "InspectorValue", "header" => "InspectorValues.h", - "accessorSuffix" => "Value" + "JSONType" => "Value" }; $typeTransform{"String"} = { "param" => "const String&", "variable" => "String", + "defaultValue" => "\"\"", "forwardHeader" => "wtf/Forward.h", "header" => "PlatformString.h", - "accessorSuffix" => "String" + "JSONType" => "String" }; $typeTransform{"long"} = { "param" => "long", @@ -82,7 +88,7 @@ $typeTransform{"long"} = { "defaultValue" => "0", "forward" => "", "header" => "", - "accessorSuffix" => "Number" + "JSONType" => "Number" }; $typeTransform{"int"} = { "param" => "int", @@ -90,7 +96,7 @@ $typeTransform{"int"} = { "defaultValue" => "0", "forward" => "", "header" => "", - "accessorSuffix" => "Number", + "JSONType" => "Number", }; $typeTransform{"unsigned long"} = { "param" => "unsigned long", @@ -98,7 +104,7 @@ $typeTransform{"unsigned long"} = { "defaultValue" => "0u", "forward" => "", "header" => "", - "accessorSuffix" => "Number" + "JSONType" => "Number" }; $typeTransform{"unsigned int"} = { "param" => "unsigned int", @@ -106,7 +112,7 @@ $typeTransform{"unsigned int"} = { "defaultValue" => "0u", "forward" => "", "header" => "", - "accessorSuffix" => "Number" + "JSONType" => "Number" }; $typeTransform{"boolean"} = { "param" => "bool", @@ -114,7 +120,7 @@ $typeTransform{"boolean"} = { "defaultValue" => "false", "forward" => "", "header" => "", - "accessorSuffix" => "Bool" + "JSONType" => "Bool" }; $typeTransform{"void"} = { "forward" => "", @@ -157,10 +163,6 @@ my @frontendConstantDeclarations; my @frontendConstantDefinitions; my $frontendFooter; -my $callId = new domSignature(); # it is just structure for describing parameters from IDLStructure.pm. -$callId->type("long"); -$callId->name("callId"); - # Default constructor sub new { @@ -198,7 +200,7 @@ sub GenerateInterface my $className = $interface->name; - $frontendClassName = "Remote" . $className . "Frontend"; + $frontendClassName = $className . "Frontend"; $frontendConstructor = " ${frontendClassName}(InspectorClient* inspectorClient) : m_inspectorClient(inspectorClient) { }"; $frontendFooter = " InspectorClient* m_inspectorClient;"; $frontendTypes{"String"} = 1; @@ -217,9 +219,8 @@ sub GenerateInterface $backendTypes{"Controller"} = 1; $backendTypes{"InspectorClient"} = 1; $backendTypes{"PassRefPtr"} = 1; - $backendTypes{"Array"} = 1; + $backendTypes{"Object"} = 1; - push(@backendMethodsImpl, generateBackendPrivateFunctions()); push(@backendMethodsImpl, generateBackendMessageParser()); generateFunctions($interface); @@ -254,7 +255,6 @@ sub generateFrontendFunction 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 @pushArguments = map(" arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @argsFiltered); my $signature = " void ${functionName}(${arguments});"; if (!$frontendMethods{${signature}}) { @@ -263,10 +263,14 @@ sub generateFrontendFunction my @function; push(@function, "void ${frontendClassName}::${functionName}(${arguments})"); push(@function, "{"); - push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();"); - push(@function, " arguments->pushString(\"$functionName\");"); + push(@function, " RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();"); + push(@function, " ${functionName}Message->setString(\"type\", \"event\");"); + push(@function, " ${functionName}Message->setString(\"event\", \"$functionName\");"); + push(@function, " RefPtr<InspectorObject> payloadDataObject = InspectorObject::create();"); + my @pushArguments = map(" payloadDataObject->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered); push(@function, @pushArguments); - push(@function, " m_inspectorClient->sendMessageToFrontend(arguments->toJSONString());"); + push(@function, " ${functionName}Message->setObject(\"data\", payloadDataObject);"); + push(@function, " m_inspectorClient->sendMessageToFrontend(${functionName}Message->toJSONString());"); push(@function, "}"); push(@function, ""); @@ -274,22 +278,6 @@ sub generateFrontendFunction } } -sub generateBackendPrivateFunctions -{ - my $privateFunctions = << "EOF"; -static String formatWrongArgumentsCountMessage(unsigned expected, unsigned actual) -{ - return String::format("Wrong number of parameters: %d (expected: %d)", actual, expected); -} - -static String formatWrongArgumentTypeMessage(unsigned position, const char* name, const char* expectedType) -{ - return String::format("Failed to convert parameter %d (%s) to %s", position, name, expectedType); -} -EOF - return split("\n", $privateFunctions); -} - sub generateBackendFunction { my $function = shift; @@ -300,74 +288,90 @@ sub generateBackendFunction push(@backendConstantDefinitions, "const char* ${backendClassName}::${functionName}Cmd = \"${functionName}\";"); map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types - my @inArgs = grep($_->direction eq "in", @{$function->parameters}); + my @inArgs = grep($_->direction eq "in" && !($_->name eq "callId") , @{$function->parameters}); my @outArgs = grep($_->direction eq "out", @{$function->parameters}); - my $signature = " void ${functionName}(PassRefPtr<InspectorArray> args);"; + my $signature = " void ${functionName}(long callId, InspectorObject* requestMessageObject);"; !$backendMethods{${signature}} || die "Duplicate function was detected for signature '$signature'."; $backendMethods{${signature}} = $functionName; my @function; - push(@function, "void ${backendClassName}::${functionName}(PassRefPtr<InspectorArray> args)"); + my $requestMessageObject = scalar(@inArgs) ? " requestMessageObject" : ""; + push(@function, "void ${backendClassName}::${functionName}(long callId, InspectorObject*$requestMessageObject)"); push(@function, "{"); - push(@function, " long callId = 0;"); + push(@function, " RefPtr<InspectorArray> protocolErrors = InspectorArray::create();"); push(@function, ""); - my $expectedParametersCount = scalar(@inArgs); - my $expectedParametersCountWithMethodName = scalar(@inArgs) + 1; - push(@function, " if (args->length() != $expectedParametersCountWithMethodName) {"); - push(@function, " ASSERT_NOT_REACHED();"); - push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount));"); - push(@function, " return;"); - push(@function, " }"); + my $domain = $function->signature->extendedAttributes->{"handler"} || "Controller"; + my $domainAccessor = $typeTransform{$domain}->{"domainAccessor"}; + $backendTypes{$domain} = 1; + push(@function, " if (!$domainAccessor)"); + push(@function, " protocolErrors->pushString(String::format(\"Error: %s handler is not available.\", \"$domain\"));"); push(@function, ""); - my $i = 1; # zero element is the method name. - foreach my $parameter (@inArgs) { - my $type = $parameter->type; - my $argumentType = $typeTransform{$type}->{"variable"}; - push(@function, " $argumentType " . $parameter->name . ";") if !($parameter->name eq "callId"); - push(@function, " if (!args->get($i)->as" . $typeTransform{$type}->{"accessorSuffix"} . "(&" . $parameter->name . ")) {"); + if (scalar(@inArgs)) { + # declare variables for all 'in' args; + push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @inArgs)); + + push(@function, ""); + push(@function, " RefPtr<InspectorObject> argumentsContainer;"); + push(@function, " if (!(argumentsContainer = requestMessageObject->getObject(\"arguments\"))) {"); push(@function, " ASSERT_NOT_REACHED();"); - push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$type\"));"); - push(@function, " return;"); + push(@function, " protocolErrors->pushString(String::format(\"Error: arguments object was not found.\"));"); + push(@function, " } else {"); + push(@function, " InspectorObject::const_iterator argumentsEndIterator = argumentsContainer->end();"); + + foreach my $parameter (@inArgs) { + my $name = $parameter->name; + my $type = $parameter->type; + my $variableType = $typeTransform{$type}->{"variable"}; + my $JSONType = $typeTransform{$type}->{"JSONType"}; + + push(@function, ""); + push(@function, " InspectorObject::const_iterator ${name}ValueIterator = argumentsContainer->find(\"$name\");"); + push(@function, " if (${name}ValueIterator == argumentsEndIterator) {"); + push(@function, " ASSERT_NOT_REACHED();"); + push(@function, " protocolErrors->pushString(String::format(\"Error: Argument '%s' with type '%s' was not found.\", \"$name\", \"$JSONType\"));"); + push(@function, " } else {"); + push(@function, " if (!${name}ValueIterator->second->as$JSONType(&$name)) {"); + push(@function, " ASSERT_NOT_REACHED();"); + push(@function, " protocolErrors->pushString(String::format(\"Error: Argument '%s' has wrong type. It should be '%s'.\", \"$name\", \"$JSONType\"));"); + push(@function, " }"); + push(@function, " }"); + } push(@function, " }"); - push(@function, ""); - ++$i; } - my $handler = $function->signature->extendedAttributes->{"handler"} || "Controller"; - my $handlerAccessor = $typeTransform{$handler}->{"handlerAccessor"}; - $backendTypes{$handler} = 1; - push(@function, " if (!$handlerAccessor) {"); - push(@function, " reportProtocolError(callId, ${functionName}Cmd, \"Error: $handler handler is not available.\");"); - push(@function, " return;"); - push(@function, " }"); - push(@function, ""); + # declare local variables for out arguments. + push(@function, map(" " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . " = " . $typeTransform{$_->type}->{"defaultValue"} . ";", @outArgs)); + my $args = join(", ", (map($_->name, @inArgs), map("&" . $_->name, @outArgs))); + push(@function, " if (!protocolErrors->length())"); + push(@function, " $domainAccessor->$functionName($args);"); + push(@function, ""); - foreach (@outArgs) { # declare local variables for out arguments. - my $initializer = $typeTransform{$_->type}->{"defaultValue"} ? " = " . $typeTransform{$_->type}->{"defaultValue"} : ""; - push(@function, " " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . "$initializer;"); + push(@function, " // use InspectorFrontend as a marker of WebInspector availability"); + push(@function, " if (callId && m_inspectorController->hasFrontend()) {"); + push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();"); + push(@function, " responseMessage->setNumber(\"seq\", callId);"); + push(@function, " responseMessage->setString(\"type\", \"response\");"); + push(@function, " responseMessage->setString(\"domain\", \"$domain\");"); + push(@function, " responseMessage->setString(\"command\", \"$functionName\");"); + push(@function, " responseMessage->setBool(\"success\", !protocolErrors->length());"); + push(@function, ""); + push(@function, " if (protocolErrors->length())"); + push(@function, " responseMessage->setArray(\"errors\", protocolErrors);"); + if (scalar(@outArgs)) { + push(@function, " else {"); + push(@function, " RefPtr<InspectorObject> responseData = InspectorObject::create();"); + push(@function, map(" responseData->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @outArgs)); + push(@function, " responseMessage->setObject(\"data\", responseData);"); + push(@function, " }"); } + push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(responseMessage->toJSONString());"); + push(@function, " }"); - my $args = join(", ", (grep(!($_ eq "callId"), map($_->name, @inArgs)), map("&" . $_->name, @outArgs))); - push(@function, " $handlerAccessor->$functionName($args);"); - - # The results of function call should be transfered back to frontend. - if (scalar(grep($_->name eq "callId", @inArgs))) { - my @pushArguments = map(" arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @outArgs); - push(@function, ""); - push(@function, " // use InspectorFrontend as a marker of WebInspector availability"); - push(@function, " if (m_inspectorController->hasFrontend()) {"); - push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();"); - push(@function, " arguments->pushString(\"processResponse\");"); - push(@function, " arguments->pushNumber(callId);"); - push(@function, @pushArguments); - push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString());"); - push(@function, " }"); - } push(@function, "}"); push(@function, ""); push(@backendMethodsImpl, @function); @@ -379,17 +383,22 @@ sub generateBackendReportProtocolError void ${backendClassName}::reportProtocolError(const long callId, const String& method, const String& errorText) const { - RefPtr<InspectorArray> arguments = InspectorArray::create(); - arguments->pushString("reportProtocolError"); - arguments->pushNumber(callId); - arguments->pushString(method); - arguments->pushString(errorText); - m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString()); + RefPtr<InspectorObject> message = InspectorObject::create(); + message->setNumber("seq", callId); + message->setString("type", "error"); + message->setString("domain", "inspectorProtocol"); + message->setString("command", method); + message->setBool("success", false); + RefPtr<InspectorArray> errors = InspectorArray::create(); + errors->pushString(errorText); + message->setArray("errors", errors); + m_inspectorController->inspectorClient()->sendMessageToFrontend(message->toJSONString()); } EOF return split("\n", $reportProtocolError); } + sub generateBackendDispatcher { my @body; @@ -400,9 +409,11 @@ sub generateBackendDispatcher my $backendDispatcherBody = << "EOF"; void ${backendClassName}::dispatch(const String& message) { - typedef void (${backendClassName}::*CallHandler)(PassRefPtr<InspectorArray> args); + typedef void (${backendClassName}::*CallHandler)(long callId, InspectorObject* messageObject); typedef HashMap<String, CallHandler> DispatchMap; DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ); + long callId = 0; + if (dispatchMap.isEmpty()) { $mapEntries } @@ -410,38 +421,52 @@ $mapEntries RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message); if (!parsedMessage) { ASSERT_NOT_REACHED(); - reportProtocolError(0, "dispatch", "Error: Invalid message format. Message should be in JSON format."); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. Message should be in JSON format."); + return; + } + + RefPtr<InspectorObject> messageObject = parsedMessage->asObject(); + if (!messageObject) { + ASSERT_NOT_REACHED(); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. The message should be a JSONified object."); return; } - RefPtr<InspectorArray> messageArray = parsedMessage->asArray(); - if (!messageArray) { + RefPtr<InspectorValue> callIdValue = messageObject->get("seq"); + if (!callIdValue) { ASSERT_NOT_REACHED(); - reportProtocolError(0, "dispatch", "Error: Invalid message format. The message should be a JSONified array of arguments."); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. 'seq' property was not found in the request."); return; } - if (!messageArray->length()) { + if (!callIdValue->asNumber(&callId)) { ASSERT_NOT_REACHED(); - reportProtocolError(0, "dispatch", "Error: Invalid message format. Empty message was received."); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. the type of 'seq' property should be number."); return; } - String methodName; - if (!messageArray->get(0)->asString(&methodName)) { + RefPtr<InspectorValue> commandValue = messageObject->get("command"); + if (!commandValue) { ASSERT_NOT_REACHED(); - reportProtocolError(0, "dispatch", "Error: Invalid message format. The first element of the message should be method name."); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. 'command' property wasn't found."); return; } - HashMap<String, CallHandler>::iterator it = dispatchMap.find(methodName); + String command; + if (!commandValue->asString(&command)) { + ASSERT_NOT_REACHED(); + reportProtocolError(callId, "dispatch", "Error: Invalid message format. The type of 'command' property should be string."); + return; + } + + HashMap<String, CallHandler>::iterator it = dispatchMap.find(command); if (it == dispatchMap.end()) { ASSERT_NOT_REACHED(); - reportProtocolError(0, "dispatch", String::format("Error: Invalid method name. '%s' wasn't found.", methodName.utf8().data())); + reportProtocolError(callId, "dispatch", String::format("Error: Invalid command was received. '%s' wasn't found.", command.utf8().data())); return; } - ((*this).*it->second)(messageArray); + ((*this).*it->second)(callId, messageObject.get()); } EOF return split("\n", $backendDispatcherBody); @@ -455,14 +480,18 @@ bool ${backendClassName}::getCommandName(const String& message, String* result) RefPtr<InspectorValue> value = InspectorValue::parseJSON(message); if (!value) return false; - RefPtr<InspectorArray> array = value->asArray(); - if (!array) + + RefPtr<InspectorObject> object = value->asObject(); + if (!object) return false; - if (!array->length()) + RefPtr<InspectorValue> commandValue = object->get("command"); + if (!commandValue) return false; - return array->get(0)->asString(result); + + return commandValue->asString(result); } + EOF return split("\n", $messageParserBody); } @@ -471,7 +500,20 @@ sub generateBackendStubJS { my $interface = shift; my @backendFunctions = grep(!$_->signature->extendedAttributes->{"notify"}, @{$interface->functions}); - my @JSStubs = map(" this._registerDelegate(\"" . $_->signature->name . "\");", @backendFunctions); + my @JSStubs; + + foreach my $function (@backendFunctions) { + my $name = $function->signature->name; + my $domain = $function->signature->extendedAttributes->{"handler"}; + my $argumentNames = join(",", map("\"" . $_->name . "\": null", grep($_->direction eq "in", @{$function->parameters}))); + push(@JSStubs, " this._registerDelegate('{" . + "\"seq\": 0, " . + "\"type\": \"request\", " . + "\"domain\": \"$domain\", " . + "\"command\": \"$name\", " . + "\"arguments\": {$argumentNames}" . + "}');"); + } my $JSStubs = join("\n", @JSStubs); my $inspectorBackendStubJS = << "EOF"; @@ -483,14 +525,26 @@ $JSStubs } WebInspector.InspectorBackendStub.prototype = { - _registerDelegate: function(methodName) + _registerDelegate: function(commandInfo) { - this[methodName] = this.sendMessageToBackend.bind(this, methodName); + var commandObject = JSON.parse(commandInfo); + this[commandObject.command] = this.sendMessageToBackend.bind(this, commandInfo); }, sendMessageToBackend: function() { - var message = JSON.stringify(Array.prototype.slice.call(arguments)); + var args = Array.prototype.slice.call(arguments); + var request = JSON.parse(args.shift()); + for (var key in request.arguments) { + if (key === "callId") + request.seq = args.shift(); + else + request.arguments[key] = args.shift(); + } + if (args.length === 1 && typeof args[0] === "function") + request.seq = WebInspector.Callback.wrap(args[0]); + + var message = JSON.stringify(request); InspectorFrontendHost.sendMessageToBackend(message); } } diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp index 6f19d2a..f3bd6bc 100644 --- a/WebCore/inspector/ConsoleMessage.cpp +++ b/WebCore/inspector/ConsoleMessage.cpp @@ -38,7 +38,7 @@ #include "ScriptValue.h" #if ENABLE(INSPECTOR) -#include "RemoteInspectorFrontend.h" +#include "InspectorFrontend.h" #endif namespace WebCore { @@ -114,7 +114,7 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, c } #if ENABLE(INSPECTOR) -void ConsoleMessage::addToFrontend(RemoteInspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost) +void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost) { RefPtr<InspectorObject> jsonObj = InspectorObject::create(); jsonObj->setNumber("source", static_cast<int>(m_source)); @@ -149,7 +149,7 @@ void ConsoleMessage::addToFrontend(RemoteInspectorFrontend* frontend, InjectedSc frontend->addConsoleMessage(jsonObj); } -void ConsoleMessage::updateRepeatCountInConsole(RemoteInspectorFrontend* frontend) +void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend) { frontend->updateConsoleMessageRepeatCount(m_repeatCount); } diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h index e286f0a..d10fa3d 100644 --- a/WebCore/inspector/ConsoleMessage.h +++ b/WebCore/inspector/ConsoleMessage.h @@ -39,8 +39,8 @@ namespace WebCore { class InjectedScriptHost; +class InspectorFrontend; class InspectorObject; -class RemoteInspectorFrontend; class ScriptCallFrame; class ScriptCallStack; class ScriptValue; @@ -51,8 +51,8 @@ public: ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, ScriptCallStack*, unsigned g, bool storeTrace = false); #if ENABLE(INSPECTOR) - void addToFrontend(RemoteInspectorFrontend*, InjectedScriptHost*); - void updateRepeatCountInConsole(RemoteInspectorFrontend* frontend); + void addToFrontend(InspectorFrontend*, InjectedScriptHost*); + void updateRepeatCountInConsole(InspectorFrontend* frontend); #endif void incrementCount() { ++m_repeatCount; } bool isEqual(ScriptState*, ConsoleMessage* msg) const; diff --git a/WebCore/inspector/InjectedScript.h b/WebCore/inspector/InjectedScript.h index 17389ba..f80cfb4 100644 --- a/WebCore/inspector/InjectedScript.h +++ b/WebCore/inspector/InjectedScript.h @@ -54,6 +54,7 @@ public: #endif PassRefPtr<InspectorValue> wrapForConsole(ScriptValue); void releaseWrapperObjectGroup(const String&); + ScriptState* scriptState() const { return m_injectedScriptObject.scriptState(); } private: friend InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState*); diff --git a/WebCore/inspector/InjectedScriptHost.cpp b/WebCore/inspector/InjectedScriptHost.cpp index 37512be..06b25fe 100644 --- a/WebCore/inspector/InjectedScriptHost.cpp +++ b/WebCore/inspector/InjectedScriptHost.cpp @@ -42,9 +42,9 @@ #include "InspectorClient.h" #include "InspectorController.h" #include "InspectorDOMAgent.h" +#include "InspectorFrontend.h" #include "InspectorResource.h" #include "Pasteboard.h" -#include "RemoteInspectorFrontend.h" #if ENABLE(JAVASCRIPT_DEBUGGER) #include "ScriptDebugServer.h" @@ -98,15 +98,14 @@ Node* InjectedScriptHost::nodeForId(long nodeId) long InjectedScriptHost::pushNodePathToFrontend(Node* node, bool withChildren, bool selectInUI) { - RemoteInspectorFrontend* frontend = remoteFrontend(); InspectorDOMAgent* domAgent = inspectorDOMAgent(); - if (!domAgent || !frontend) + if (!domAgent || !frontend()) return 0; long id = domAgent->pushNodePathToFrontend(node); if (withChildren) domAgent->pushChildNodesToFrontend(id); if (selectInUI) - frontend->updateFocusedNode(id); + frontend()->updateFocusedNode(id); return id; } @@ -149,6 +148,9 @@ InjectedScript InjectedScriptHost::injectedScriptForId(long id) void InjectedScriptHost::discardInjectedScripts() { + IdToInjectedScriptMap::iterator end = m_idToInjectedScript.end(); + for (IdToInjectedScriptMap::iterator it = m_idToInjectedScript.begin(); it != end; ++it) + discardInjectedScript(it->second.scriptState()); m_idToInjectedScript.clear(); } @@ -172,11 +174,11 @@ InspectorDOMAgent* InjectedScriptHost::inspectorDOMAgent() return m_inspectorController->domAgent(); } -RemoteInspectorFrontend* InjectedScriptHost::remoteFrontend() +InspectorFrontend* InjectedScriptHost::frontend() { if (!m_inspectorController) return 0; - return m_inspectorController->m_remoteFrontend.get(); + return m_inspectorController->m_frontend.get(); } pair<long, ScriptObject> InjectedScriptHost::injectScript(const String& source, ScriptState* scriptState) diff --git a/WebCore/inspector/InjectedScriptHost.h b/WebCore/inspector/InjectedScriptHost.h index 997f340..6b70f62 100644 --- a/WebCore/inspector/InjectedScriptHost.h +++ b/WebCore/inspector/InjectedScriptHost.h @@ -43,8 +43,8 @@ namespace WebCore { class Database; class InjectedScript; class InspectorDOMAgent; +class InspectorFrontend; class Node; -class RemoteInspectorFrontend; class ScriptObject; class Storage; @@ -58,6 +58,7 @@ public: ~InjectedScriptHost(); + String injectedScriptSource() { return m_injectedScriptSource; } void setInjectedScriptSource(const String& source) { m_injectedScriptSource = source; } InspectorController* inspectorController() { return m_inspectorController; } @@ -94,8 +95,9 @@ public: private: InjectedScriptHost(InspectorController* inspectorController); InspectorDOMAgent* inspectorDOMAgent(); - RemoteInspectorFrontend* remoteFrontend(); + InspectorFrontend* frontend(); ScriptObject createInjectedScript(const String& source, ScriptState* scriptState, long id); + void discardInjectedScript(ScriptState*); InspectorController* m_inspectorController; String m_injectedScriptSource; diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl index 1c66b59..a56ef14 100644 --- a/WebCore/inspector/Inspector.idl +++ b/WebCore/inspector/Inspector.idl @@ -47,9 +47,6 @@ module core { [notify] void inspectedURLChanged(out String url); [notify] void monitoringXHRWasEnabled(); [notify] void monitoringXHRWasDisabled(); - [notify] void populateApplicationSettings(out String settings); - [notify] void populateInterface(); - [notify] void populateSessionSettings(out String settings); [notify] void removeResource(out unsigned long identifier); [notify] void reset(); [notify] void resetProfilesPanel(); @@ -102,6 +99,10 @@ module core { [notify] void didDestroyWorker(out long id); #endif + // This method is going to be broken down into smaller parts. + [handler=Controller] void populateScriptObjects(); + + [handler=Controller] void getSettings(in long callId, out Object settings); [handler=Controller] void storeLastActivePanel(in String panelName); [handler=Controller] void saveApplicationSettings(in String settings); @@ -145,14 +146,14 @@ module core { [handler=Controller] void enableProfiler(in boolean always); [handler=Controller] void disableProfiler(in boolean always); - [handler=Controller] void startProfiling(); - [handler=Controller] void stopProfiling(); + [handler=Profiler] void startProfiling(); + [handler=Profiler] void stopProfiling(); - [handler=Controller] void getProfileHeaders(in long callId, out Array headers); - [handler=Controller] void getProfile(in long callId, in unsigned long uid, out Object profile); + [handler=Profiler] void getProfileHeaders(in long callId, out Array headers); + [handler=Profiler] void getProfile(in long callId, in unsigned long uid, out Object profile); - [handler=Controller] void removeProfile(in unsigned long uid); - [handler=Controller] void clearProfiles(); + [handler=Profiler] void removeProfile(in unsigned long uid); + [handler=Profiler] void clearProfiles(); [handler=Backend] void takeHeapSnapshot(); [handler=Backend] void getProfilerLogLines(in long callId, in long inPosition, out long outPosition, out String log); @@ -176,6 +177,8 @@ module core { [handler=DOM] void performSearch(in String query, in boolean runSynchronously); [handler=DOM] void searchCanceled(); [handler=DOM] void pushNodeByPathToFrontend(in long callId, in String path, out long nodeId); + [handler=DOM] void setDOMBreakpoint(in long nodeId, in long type); + [handler=DOM] void removeDOMBreakpoint(in long nodeId, in long type); [handler=Controller] void clearConsoleMessages(); [handler=Controller] void highlightDOMNode(in long nodeId); @@ -194,6 +197,7 @@ module core { [handler=DOM] void toggleStyleEnabled(in long callId, in long styleId, in String propertyName, in boolean disabled, out Value style); [handler=DOM] void setRuleSelector(in long callId, in long ruleId, in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode); [handler=DOM] void addRule(in long callId, in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode); + [handler=DOM] void getSupportedCSSProperties(in long callId, out Array cssProperties); [handler=Controller] void getCookies(in long callId, out Array cookies, out String cookiesString); [handler=Controller] void deleteCookie(in String cookieName, in String domain); diff --git a/WebCore/inspector/InspectorApplicationCacheAgent.cpp b/WebCore/inspector/InspectorApplicationCacheAgent.cpp index 1206184..918643b 100644 --- a/WebCore/inspector/InspectorApplicationCacheAgent.cpp +++ b/WebCore/inspector/InspectorApplicationCacheAgent.cpp @@ -33,14 +33,14 @@ #include "Frame.h" #include "FrameLoader.h" #include "InspectorController.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" #include "Page.h" -#include "RemoteInspectorFrontend.h" #include "ResourceResponse.h" namespace WebCore { -InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorController* inspectorController, RemoteInspectorFrontend* frontend) +InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend) : m_inspectorController(inspectorController) , m_frontend(frontend) { diff --git a/WebCore/inspector/InspectorApplicationCacheAgent.h b/WebCore/inspector/InspectorApplicationCacheAgent.h index 3338f84..11f10ce 100644 --- a/WebCore/inspector/InspectorApplicationCacheAgent.h +++ b/WebCore/inspector/InspectorApplicationCacheAgent.h @@ -35,14 +35,14 @@ namespace WebCore { class InspectorArray; class InspectorController; +class InspectorFrontend; class InspectorObject; class InspectorValue; -class RemoteInspectorFrontend; class ResourceResponse; class InspectorApplicationCacheAgent : public Noncopyable { public: - InspectorApplicationCacheAgent(InspectorController* inspectorController, RemoteInspectorFrontend* frontend); + InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend); ~InspectorApplicationCacheAgent() { } // Backend to Frontend @@ -59,7 +59,7 @@ private: PassRefPtr<InspectorObject> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&); InspectorController* m_inspectorController; - RemoteInspectorFrontend* m_frontend; + InspectorFrontend* m_frontend; }; } // namespace WebCore diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp index f0ed94b..99f40a9 100644 --- a/WebCore/inspector/InspectorBackend.cpp +++ b/WebCore/inspector/InspectorBackend.cpp @@ -40,8 +40,8 @@ #include "InjectedScriptHost.h" #include "InspectorController.h" #include "InspectorDOMAgent.h" +#include "InspectorFrontend.h" #include "InspectorStorageAgent.h" -#include "RemoteInspectorFrontend.h" #include "ScriptBreakpoint.h" #include "ScriptProfiler.h" #include "SerializedScriptValue.h" @@ -88,7 +88,7 @@ void InspectorBackend::setInjectedScriptSource(const String& source) void InspectorBackend::dispatchOnInjectedScript(long injectedScriptId, const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException) { - if (!remoteFrontend()) + if (!frontend()) return; // FIXME: explicitly pass injectedScriptId along with node id to the frontend. @@ -137,9 +137,9 @@ void InspectorBackend::executeSQL(long databaseId, const String& query, bool* su #endif -RemoteInspectorFrontend* InspectorBackend::remoteFrontend() +InspectorFrontend* InspectorBackend::frontend() { - return m_inspectorController->m_remoteFrontend.get(); + return m_inspectorController->m_frontend.get(); } } // namespace WebCore diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h index 27a93eb..23b31a3 100644 --- a/WebCore/inspector/InspectorBackend.h +++ b/WebCore/inspector/InspectorBackend.h @@ -40,7 +40,6 @@ namespace WebCore { class InspectorApplicationCacheAgent; class InspectorDOMAgent; class InspectorFrontend; -class RemoteInspectorFrontend; class InspectorBackend : public RefCounted<InspectorBackend> { @@ -78,7 +77,7 @@ public: private: InspectorBackend(InspectorController* inspectorController); - RemoteInspectorFrontend* remoteFrontend(); + InspectorFrontend* frontend(); InspectorController* m_inspectorController; }; diff --git a/WebCore/inspector/InspectorCSSStore.cpp b/WebCore/inspector/InspectorCSSStore.cpp index 16d2508..c2dc4f1 100644 --- a/WebCore/inspector/InspectorCSSStore.cpp +++ b/WebCore/inspector/InspectorCSSStore.cpp @@ -41,7 +41,6 @@ #include "InspectorController.h" #include "InspectorResource.h" #include "PlatformString.h" -#include "RemoteInspectorFrontend.h" #include "StyleSheetList.h" namespace WebCore { diff --git a/WebCore/inspector/InspectorCSSStore.h b/WebCore/inspector/InspectorCSSStore.h index ee435e5..82de622 100644 --- a/WebCore/inspector/InspectorCSSStore.h +++ b/WebCore/inspector/InspectorCSSStore.h @@ -38,7 +38,6 @@ namespace WebCore { class Document; class InspectorController; -class InspectorFrontend; class CSSMutableStyleDeclaration; class CSSStyleDeclaration; class CSSRuleList; diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp index ac670cb..f47b321 100644 --- a/WebCore/inspector/InspectorController.cpp +++ b/WebCore/inspector/InspectorController.cpp @@ -59,10 +59,12 @@ #include "InspectorBackendDispatcher.h" #include "InspectorCSSStore.h" #include "InspectorClient.h" +#include "InspectorFrontend.h" #include "InspectorFrontendClient.h" #include "InspectorDOMStorageResource.h" #include "InspectorDatabaseResource.h" #include "InspectorDebuggerAgent.h" +#include "InspectorProfilerAgent.h" #include "InspectorResource.h" #include "InspectorStorageAgent.h" #include "InspectorTimelineAgent.h" @@ -71,7 +73,6 @@ #include "Page.h" #include "ProgressTracker.h" #include "Range.h" -#include "RemoteInspectorFrontend.h" #include "RenderInline.h" #include "ResourceRequest.h" #include "ResourceResponse.h" @@ -115,8 +116,6 @@ using namespace std; namespace WebCore { -static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated"; -static const char* const CPUProfileType = "CPU"; static const char* const resourceTrackingEnabledSettingName = "resourceTrackingEnabled"; static const char* const debuggerEnabledSettingName = "debuggerEnabled"; static const char* const profilerEnabledSettingName = "profilerEnabled"; @@ -170,11 +169,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_injectedScriptHost(InjectedScriptHost::create(this)) #if ENABLE(JAVASCRIPT_DEBUGGER) , m_attachDebuggerWhenShown(false) - , m_profilerEnabled(!WTF_USE_JSC) - , m_recordingUserInitiatedProfile(false) - , m_currentUserInitiatedProfileNumber(-1) - , m_nextUserInitiatedProfileNumber(1) - , m_startProfiling(this, &InspectorController::startUserInitiatedProfiling) + , m_profilerAgent(InspectorProfilerAgent::create(this)) #endif { ASSERT_ARG(page, page); @@ -202,8 +197,8 @@ InspectorController::~InspectorController() void InspectorController::inspectedPageDestroyed() { - if (m_remoteFrontend) - m_remoteFrontend->inspectedPageDestroyed(); + if (m_frontend) + m_frontend->inspectedPageDestroyed(); hideHighlight(); @@ -252,6 +247,13 @@ void InspectorController::saveSessionSettings(const String& settingsJSON) m_sessionSettings = InspectorValue::parseJSON(settingsJSON); } +void InspectorController::getSettings(RefPtr<InspectorObject>* settings) +{ + *settings = InspectorObject::create(); + (*settings)->setString("application", setting(frontendSettingsSettingName())); + (*settings)->setString("session", m_sessionSettings->toJSONString()); +} + void InspectorController::inspect(Node* node) { if (!enabled()) @@ -263,7 +265,7 @@ void InspectorController::inspect(Node* node) node = node->parentNode(); m_nodeToFocus = node; - if (!m_remoteFrontend) { + if (!m_frontend) { m_showAfterVisible = ElementsPanel; return; } @@ -276,11 +278,11 @@ void InspectorController::focusNode() if (!enabled()) return; - ASSERT(m_remoteFrontend); + ASSERT(m_frontend); ASSERT(m_nodeToFocus); long id = m_domAgent->pushNodePathToFrontend(m_nodeToFocus.get()); - m_remoteFrontend->updateFocusedNode(id); + m_frontend->updateFocusedNode(id); m_nodeToFocus = 0; } @@ -308,11 +310,6 @@ void InspectorController::hideHighlight() m_client->hideHighlight(); } -bool InspectorController::windowVisible() -{ - return m_remoteFrontend; -} - void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, ScriptCallStack* callStack, const String& message) { if (!enabled()) @@ -337,16 +334,16 @@ void InspectorController::addConsoleMessage(ScriptState* scriptState, PassOwnPtr if (m_previousMessage && m_previousMessage->isEqual(scriptState, consoleMessage.get())) { m_previousMessage->incrementCount(); - if (m_remoteFrontend) - m_previousMessage->updateRepeatCountInConsole(m_remoteFrontend.get()); + if (m_frontend) + m_previousMessage->updateRepeatCountInConsole(m_frontend.get()); } else { m_previousMessage = consoleMessage.get(); m_consoleMessages.append(consoleMessage); - if (m_remoteFrontend) - m_previousMessage->addToFrontend(m_remoteFrontend.get(), m_injectedScriptHost.get()); + if (m_frontend) + m_previousMessage->addToFrontend(m_frontend.get(), m_injectedScriptHost.get()); } - if (!m_remoteFrontend && m_consoleMessages.size() >= maximumConsoleMessages) { + if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) { m_expiredConsoleMessageCount += expireConsoleMessagesStep; m_consoleMessages.remove(0, expireConsoleMessagesStep); } @@ -361,8 +358,8 @@ void InspectorController::clearConsoleMessages() m_injectedScriptHost->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console"); if (m_domAgent) m_domAgent->releaseDanglingNodes(); - if (m_remoteFrontend) - m_remoteFrontend->consoleMessagesCleared(); + if (m_frontend) + m_frontend->consoleMessagesCleared(); } void InspectorController::startGroup(MessageSource source, ScriptCallStack* callStack, bool collapsed) @@ -433,7 +430,7 @@ void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame) m_inspectorFrontendClient->windowObjectCleared(); if (enabled()) { - if (m_remoteFrontend && frame == m_inspectedPage->mainFrame()) + if (m_frontend && frame == m_inspectedPage->mainFrame()) m_injectedScriptHost->discardInjectedScripts(); if (m_scriptsToEvaluateOnLoad.size()) { ScriptState* scriptState = mainWorldScriptState(frame); @@ -454,11 +451,11 @@ void InspectorController::setSearchingForNode(bool enabled) m_searchingForNode = enabled; if (!m_searchingForNode) hideHighlight(); - if (m_remoteFrontend) { + if (m_frontend) { if (enabled) - m_remoteFrontend->searchingForNodeWasEnabled(); + m_frontend->searchingForNodeWasEnabled(); else - m_remoteFrontend->searchingForNodeWasDisabled(); + m_frontend->searchingForNodeWasDisabled(); } } @@ -468,11 +465,11 @@ void InspectorController::setMonitoringXHR(bool enabled) return; m_monitoringXHR = enabled; setSetting(monitoringXHRSettingName, enabled ? "true" : "false"); - if (m_remoteFrontend) { + if (m_frontend) { if (enabled) - m_remoteFrontend->monitoringXHRWasEnabled(); + m_frontend->monitoringXHRWasEnabled(); else - m_remoteFrontend->monitoringXHRWasDisabled(); + m_frontend->monitoringXHRWasDisabled(); } } @@ -480,20 +477,18 @@ void InspectorController::connectFrontend() { m_openingFrontend = false; releaseFrontendLifetimeAgents(); - m_remoteFrontend = new RemoteInspectorFrontend(m_client); - m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_remoteFrontend.get()); + m_frontend = new InspectorFrontend(m_client); + m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get()); #if ENABLE(DATABASE) - m_storageAgent = InspectorStorageAgent::create(m_remoteFrontend.get()); + m_storageAgent = InspectorStorageAgent::create(m_frontend.get()); #endif if (m_timelineAgent) - m_timelineAgent->resetFrontendProxyObject(m_remoteFrontend.get()); + m_timelineAgent->resetFrontendProxyObject(m_frontend.get()); // Initialize Web Inspector title. - m_remoteFrontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string()); - - populateScriptObjects(); + m_frontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string()); #if ENABLE(JAVASCRIPT_DEBUGGER) if (InspectorDebuggerAgent::isDebuggerAlwaysEnabled()) { @@ -504,21 +499,17 @@ void InspectorController::connectFrontend() String debuggerEnabled = setting(debuggerEnabledSettingName); if (debuggerEnabled == "true" || m_attachDebuggerWhenShown) enableDebugger(); - String profilerEnabled = setting(profilerEnabledSettingName); - if (profilerEnabled == "true") + } + m_profilerAgent->setFrontend(m_frontend.get()); + if (!ScriptProfiler::isProfilerAlwaysEnabled()) { + String profilerEnabledSetting = setting(profilerEnabledSettingName); + if (profilerEnabledSetting == "true") enableProfiler(); } #endif - if (m_showAfterVisible == lastActivePanel) - m_showAfterVisible = setting(lastActivePanel); - - if (m_nodeToFocus) - focusNode(); - showPanel(m_showAfterVisible); - #if ENABLE(OFFLINE_WEB_APPLICATIONS) - m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_remoteFrontend.get()); + m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_frontend.get()); #endif if (!connectedFrontendCount) @@ -534,8 +525,8 @@ void InspectorController::show() if (m_openingFrontend) return; - if (m_remoteFrontend) - m_remoteFrontend->bringToFront(); + if (m_frontend) + m_frontend->bringToFront(); else { m_openingFrontend = true; m_client->openInspectorFrontend(this); @@ -549,7 +540,7 @@ void InspectorController::showPanel(const String& panel) show(); - if (!m_remoteFrontend) { + if (!m_frontend) { m_showAfterVisible = panel; return; } @@ -557,21 +548,21 @@ void InspectorController::showPanel(const String& panel) if (panel == lastActivePanel) return; - m_remoteFrontend->showPanel(panel); + m_frontend->showPanel(panel); } void InspectorController::close() { - if (!m_remoteFrontend) + if (!m_frontend) return; - m_remoteFrontend->close(); + m_frontend->close(); } void InspectorController::disconnectFrontend() { - if (!m_remoteFrontend) + if (!m_frontend) return; - m_remoteFrontend.clear(); + m_frontend.clear(); connectedFrontendCount--; if (!connectedFrontendCount) @@ -594,7 +585,8 @@ void InspectorController::disconnectFrontend() hideHighlight(); #if ENABLE(JAVASCRIPT_DEBUGGER) - stopUserInitiatedProfiling(); + m_profilerAgent->setFrontend(0); + m_profilerAgent->stopUserInitiatedProfiling(); #endif releaseFrontendLifetimeAgents(); @@ -622,66 +614,67 @@ void InspectorController::releaseFrontendLifetimeAgents() void InspectorController::populateScriptObjects() { - ASSERT(m_remoteFrontend); - if (!m_remoteFrontend) + ASSERT(m_frontend); + if (!m_frontend) return; - m_remoteFrontend->populateApplicationSettings(setting(frontendSettingsSettingName())); + if (m_showAfterVisible == lastActivePanel) + m_showAfterVisible = setting(lastActivePanel); + if (m_nodeToFocus) + focusNode(); + showPanel(m_showAfterVisible); if (m_resourceTrackingEnabled) - m_remoteFrontend->resourceTrackingWasEnabled(); + m_frontend->resourceTrackingWasEnabled(); if (m_searchingForNode) - m_remoteFrontend->searchingForNodeWasEnabled(); + m_frontend->searchingForNodeWasEnabled(); if (m_monitoringXHR) - m_remoteFrontend->monitoringXHRWasEnabled(); + m_frontend->monitoringXHRWasEnabled(); #if ENABLE(JAVASCRIPT_DEBUGGER) - if (m_profilerEnabled) - m_remoteFrontend->profilerWasEnabled(); + if (m_profilerAgent->enabled()) + m_frontend->profilerWasEnabled(); #endif ResourcesMap::iterator resourcesEnd = m_resources.end(); for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it) - it->second->updateScriptObject(m_remoteFrontend.get()); + it->second->updateScriptObject(m_frontend.get()); m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); if (m_expiredConsoleMessageCount) - m_remoteFrontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount); + m_frontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount); unsigned messageCount = m_consoleMessages.size(); for (unsigned i = 0; i < messageCount; ++i) - m_consoleMessages[i]->addToFrontend(m_remoteFrontend.get(), m_injectedScriptHost.get()); + m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get()); #if ENABLE(JAVASCRIPT_DEBUGGER) if (debuggerEnabled()) - m_remoteFrontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState()); + m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState()); #endif #if ENABLE(DATABASE) DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end(); for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) - it->second->bind(m_remoteFrontend.get()); + 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_remoteFrontend.get()); + it->second->bind(m_frontend.get()); #endif #if ENABLE(WORKERS) WorkersMap::iterator workersEnd = m_workers.end(); for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it) { InspectorWorkerResource* worker = it->second.get(); - m_remoteFrontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker()); + m_frontend->didCreateWorker(worker->id(), worker->url(), worker->isSharedWorker()); } #endif - m_remoteFrontend->populateSessionSettings(m_sessionSettings->toJSONString()); - m_remoteFrontend->populateInterface(); - // Dispatch pending frontend commands for (Vector<pair<long, String> >::iterator it = m_pendingEvaluateTestCommands.begin(); it != m_pendingEvaluateTestCommands.end(); ++it) - m_remoteFrontend->evaluateForTestInFrontend((*it).first, (*it).second); + m_frontend->evaluateForTestInFrontend((*it).first, (*it).second); m_pendingEvaluateTestCommands.clear(); } @@ -718,8 +711,8 @@ void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoad if (!loaderToKeep || !resource->isSameLoader(loaderToKeep)) { removeResource(resource); - if (m_remoteFrontend) - resource->releaseScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->releaseScriptObject(m_frontend.get()); } } } @@ -732,8 +725,8 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) ASSERT(m_inspectedPage); if (loader->frame() == m_inspectedPage->mainFrame()) { - if (m_remoteFrontend) - m_remoteFrontend->inspectedURLChanged(loader->url().string()); + if (m_frontend) + m_frontend->inspectedURLChanged(loader->url().string()); m_injectedScriptHost->discardInjectedScripts(); clearConsoleMessages(); @@ -745,11 +738,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) m_debuggerAgent->clearForPageNavigation(); #endif #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) - m_profiles.clear(); - m_currentUserInitiatedProfileNumber = 1; - m_nextUserInitiatedProfileNumber = 1; - if (m_remoteFrontend) - m_remoteFrontend->resetProfilesPanel(); + 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. @@ -757,8 +746,8 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) m_cssStore->reset(); m_sessionSettings = InspectorObject::create(); - if (m_remoteFrontend) { - m_remoteFrontend->reset(); + if (m_frontend) { + m_frontend->reset(); m_domAgent->reset(); } #if ENABLE(WORKERS) @@ -771,13 +760,13 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) m_domStorageResources.clear(); #endif - if (m_remoteFrontend) { + if (m_frontend) { if (!loader->frameLoader()->isLoadingFromCachedPage()) { ASSERT(m_mainResource && m_mainResource->isSameLoader(loader)); // We don't add the main resource until its load is committed. This is // needed to keep the load for a user-entered URL from showing up in the // list of resources for the page they are navigating away from. - m_mainResource->updateScriptObject(m_remoteFrontend.get()); + m_mainResource->updateScriptObject(m_frontend.get()); } else { // Pages loaded from the page cache are committed before // m_mainResource is the right resource for this load, so we @@ -785,7 +774,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) // identifierForInitialRequest. m_mainResource = 0; } - m_remoteFrontend->didCommitLoad(); + m_frontend->didCommitLoad(); m_domAgent->setDocument(m_inspectedPage->mainFrame()->document()); } } @@ -888,8 +877,8 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, addResource(resource.get()); - if (m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) @@ -912,8 +901,8 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier, addResource(resource.get()); - if (m_remoteFrontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loader, const KURL& url) @@ -925,8 +914,8 @@ void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loade m_mainResource->markDOMContentEventTime(); if (m_timelineAgent) m_timelineAgent->didMarkDOMContentEvent(); - if (m_remoteFrontend) - m_mainResource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + m_mainResource->updateScriptObject(m_frontend.get()); } } @@ -939,8 +928,8 @@ void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, con m_mainResource->markLoadEventTime(); if (m_timelineAgent) m_timelineAgent->didMarkLoadEvent(); - if (m_remoteFrontend) - m_mainResource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + m_mainResource->updateScriptObject(m_frontend.get()); } } @@ -987,8 +976,8 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ resource->startTiming(); resource->updateRequest(request); - if (resource != m_mainResource && m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (resource != m_mainResource && m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::didReceiveResponse(unsigned long identifier, const ResourceResponse& response) @@ -999,8 +988,8 @@ void InspectorController::didReceiveResponse(unsigned long identifier, const Res if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) { resource->updateResponse(response); - if (resource != m_mainResource && m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (resource != m_mainResource && m_frontend) + resource->updateScriptObject(m_frontend.get()); } if (response.httpStatusCode() >= 400) { // The ugly code below is due to that String::format() is not utf8-safe at the moment. @@ -1021,8 +1010,8 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int resource->addLength(lengthReceived); - if (resource != m_mainResource && m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (resource != m_mainResource && m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::didFinishLoading(unsigned long identifier) @@ -1040,8 +1029,8 @@ void InspectorController::didFinishLoading(unsigned long identifier) resource->endTiming(); // No need to mute this event for main resource since it happens after did commit load. - if (m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::didFailLoading(unsigned long identifier, const ResourceError& error) @@ -1065,8 +1054,8 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc resource->endTiming(); // No need to mute this event for main resource since it happens after did commit load. - if (m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber) @@ -1086,8 +1075,8 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi resource->setOverrideContent(sourceString, InspectorResource::XHR); - if (m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::scriptImported(unsigned long identifier, const String& sourceString) @@ -1101,8 +1090,8 @@ void InspectorController::scriptImported(unsigned long identifier, const String& resource->setOverrideContent(ScriptString(sourceString), InspectorResource::Script); - if (m_remoteFrontend) - resource->updateScriptObject(m_remoteFrontend.get()); + if (m_frontend) + resource->updateScriptObject(m_frontend.get()); } void InspectorController::enableResourceTracking(bool always, bool reload) @@ -1118,8 +1107,8 @@ void InspectorController::enableResourceTracking(bool always, bool reload) ASSERT(m_inspectedPage); m_resourceTrackingEnabled = true; - if (m_remoteFrontend) - m_remoteFrontend->resourceTrackingWasEnabled(); + if (m_frontend) + m_frontend->resourceTrackingWasEnabled(); m_client->resourceTrackingWasEnabled(); if (reload) @@ -1136,8 +1125,8 @@ void InspectorController::disableResourceTracking(bool always) ASSERT(m_inspectedPage); m_resourceTrackingEnabled = false; - if (m_remoteFrontend) - m_remoteFrontend->resourceTrackingWasDisabled(); + if (m_frontend) + m_frontend->resourceTrackingWasDisabled(); m_client->resourceTrackingWasDisabled(); } @@ -1165,9 +1154,9 @@ void InspectorController::startTimelineProfiler() if (m_timelineAgent) return; - m_timelineAgent = new InspectorTimelineAgent(m_remoteFrontend.get()); - if (m_remoteFrontend) - m_remoteFrontend->timelineProfilerWasStarted(); + m_timelineAgent = new InspectorTimelineAgent(m_frontend.get()); + if (m_frontend) + m_frontend->timelineProfilerWasStarted(); m_client->timelineProfilerWasStarted(); } @@ -1180,8 +1169,8 @@ void InspectorController::stopTimelineProfiler() return; m_timelineAgent = 0; - if (m_remoteFrontend) - m_remoteFrontend->timelineProfilerWasStopped(); + if (m_frontend) + m_frontend->timelineProfilerWasStopped(); m_client->timelineProfilerWasStopped(); } @@ -1213,14 +1202,14 @@ private: void InspectorController::postWorkerNotificationToFrontend(const InspectorWorkerResource& worker, InspectorController::WorkerAction action) { - if (!m_remoteFrontend) + if (!m_frontend) return; switch (action) { case InspectorController::WorkerCreated: - m_remoteFrontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker()); + m_frontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker()); break; case InspectorController::WorkerDestroyed: - m_remoteFrontend->didDestroyWorker(worker.id()); + m_frontend->didDestroyWorker(worker.id()); break; } } @@ -1232,7 +1221,7 @@ void InspectorController::didCreateWorker(intptr_t id, const String& url, bool i RefPtr<InspectorWorkerResource> workerResource(InspectorWorkerResource::create(id, url, isSharedWorker)); m_workers.set(id, workerResource); - if (m_inspectedPage && m_remoteFrontend) + if (m_inspectedPage && m_frontend) m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource, InspectorController::WorkerCreated)); } @@ -1244,7 +1233,7 @@ void InspectorController::didDestroyWorker(intptr_t id) WorkersMap::iterator workerResource = m_workers.find(id); if (workerResource == m_workers.end()) return; - if (m_inspectedPage && m_remoteFrontend) + if (m_inspectedPage && m_frontend) m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource->second, InspectorController::WorkerDestroyed)); m_workers.remove(workerResource); } @@ -1253,12 +1242,12 @@ void InspectorController::didDestroyWorker(intptr_t id) #if ENABLE(DATABASE) void InspectorController::selectDatabase(Database* database) { - if (!m_remoteFrontend) + if (!m_frontend) return; for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != m_databaseResources.end(); ++it) { if (it->second->database() == database) { - m_remoteFrontend->selectDatabase(it->first); + m_frontend->selectDatabase(it->first); break; } } @@ -1282,8 +1271,8 @@ void InspectorController::didOpenDatabase(PassRefPtr<Database> database, const S m_databaseResources.set(resource->id(), resource); // Resources are only bound while visible. - if (m_remoteFrontend) - resource->bind(m_remoteFrontend.get()); + if (m_frontend) + resource->bind(m_frontend.get()); } #endif @@ -1383,14 +1372,14 @@ void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLoca m_domStorageResources.set(resource->id(), resource); // Resources are only bound while visible. - if (m_remoteFrontend) - resource->bind(m_remoteFrontend.get()); + if (m_frontend) + resource->bind(m_frontend.get()); } void InspectorController::selectDOMStorage(Storage* storage) { ASSERT(storage); - if (!m_remoteFrontend) + if (!m_frontend) return; Frame* frame = storage->frame(); @@ -1405,7 +1394,7 @@ void InspectorController::selectDOMStorage(Storage* storage) } } if (storageResourceId) - m_remoteFrontend->selectDOMStorage(storageResourceId); + m_frontend->selectDOMStorage(storageResourceId); } void InspectorController::getDOMStorageEntries(long storageId, RefPtr<InspectorArray>* entries) @@ -1458,176 +1447,61 @@ void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsig { if (!enabled()) return; - - RefPtr<ScriptProfile> profile = prpProfile; - m_profiles.add(profile->uid(), profile); - - if (m_remoteFrontend) { - m_remoteFrontend->addProfileHeader(createProfileHeader(*profile)); - } - - addProfileFinishedMessageToConsole(profile, lineNumber, sourceURL); + m_profilerAgent->addProfile(prpProfile, lineNumber, sourceURL); } void InspectorController::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL) { - RefPtr<ScriptProfile> profile = prpProfile; - - String title = profile->title(); - String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data(), profile->uid()); - addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); + m_profilerAgent->addProfileFinishedMessageToConsole(prpProfile, lineNumber, sourceURL); } void InspectorController::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL) { - String message = String::format("Profile \"webkit-profile://%s/%s#0\" started.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data()); - addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); -} - -void InspectorController::removeProfile(unsigned uid) -{ - if (!enabled()) - return; - - if (m_profiles.contains(uid)) - m_profiles.remove(uid); -} - -void InspectorController::clearProfiles() -{ - if (!enabled()) - return; - - m_profiles.clear(); - m_currentUserInitiatedProfileNumber = 1; - m_nextUserInitiatedProfileNumber = 1; -} - -void InspectorController::getProfileHeaders(RefPtr<InspectorArray>* headers) -{ - ProfilesMap::iterator profilesEnd = m_profiles.end(); - for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it) - (*headers)->pushObject(createProfileHeader(*it->second)); + m_profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, sourceURL); } -void InspectorController::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject) -{ - ProfilesMap::iterator it = m_profiles.find(uid); - if (it != m_profiles.end()) { - *profileObject = createProfileHeader(*it->second); - (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead()); - } -} -PassRefPtr<InspectorObject> InspectorController::createProfileHeader(const ScriptProfile& profile) +bool InspectorController::isRecordingUserInitiatedProfile() const { - RefPtr<InspectorObject> header = InspectorObject::create(); - header->setString("title", profile.title()); - header->setNumber("uid", profile.uid()); - header->setString("typeId", String(CPUProfileType)); - return header; + return m_profilerAgent->isRecordingUserInitiatedProfile(); } -String InspectorController::getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false) +String InspectorController::getCurrentUserInitiatedProfileName(bool incrementProfileNumber) { - if (incrementProfileNumber) - m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++; - - return String::format("%s.%d", UserInitiatedProfileName, m_currentUserInitiatedProfileNumber); + return m_profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber); } -void InspectorController::startUserInitiatedProfilingSoon() -{ - m_startProfiling.startOneShot(0); -} - -void InspectorController::startUserInitiatedProfiling(Timer<InspectorController>*) +void InspectorController::startUserInitiatedProfiling() { if (!enabled()) return; - - if (!profilerEnabled()) { - enableProfiler(false, true); - ScriptDebugServer::shared().recompileAllJSFunctions(); - } - - m_recordingUserInitiatedProfile = true; - - String title = getCurrentUserInitiatedProfileName(true); - -#if USE(JSC) - JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec(); -#else - ScriptState* scriptState = 0; -#endif - ScriptProfiler::start(scriptState, title); - - addStartProfilingMessageToConsole(title, 0, String()); - - toggleRecordButton(true); + m_profilerAgent->startUserInitiatedProfiling(); } void InspectorController::stopUserInitiatedProfiling() { if (!enabled()) return; - - m_recordingUserInitiatedProfile = false; - - String title = getCurrentUserInitiatedProfileName(); - -#if USE(JSC) - JSC::ExecState* scriptState = toJSDOMWindow(m_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. - ScriptState* scriptState = 0; -#endif - RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); - if (profile) - addProfile(profile, 0, String()); - - toggleRecordButton(false); + m_profilerAgent->stopUserInitiatedProfiling(); } -void InspectorController::toggleRecordButton(bool isProfiling) +bool InspectorController::profilerEnabled() const { - if (!m_remoteFrontend) - return; - m_remoteFrontend->setRecordingProfile(isProfiling); + return enabled() && m_profilerAgent->enabled(); } void InspectorController::enableProfiler(bool always, bool skipRecompile) { if (always) setSetting(profilerEnabledSettingName, "true"); - - if (m_profilerEnabled) - return; - - m_profilerEnabled = true; - - if (!skipRecompile) - ScriptDebugServer::shared().recompileAllJSFunctionsSoon(); - - if (m_remoteFrontend) - m_remoteFrontend->profilerWasEnabled(); + m_profilerAgent->enable(skipRecompile); } void InspectorController::disableProfiler(bool always) { if (always) setSetting(profilerEnabledSettingName, "false"); - - if (!m_profilerEnabled) - return; - - m_profilerEnabled = false; - - ScriptDebugServer::shared().recompileAllJSFunctionsSoon(); - - if (m_remoteFrontend) - m_remoteFrontend->profilerWasDisabled(); + m_profilerAgent->disable(); } #endif @@ -1640,9 +1514,9 @@ void InspectorController::enableDebuggerFromFrontend(bool always) ASSERT(m_inspectedPage); - m_debuggerAgent = InspectorDebuggerAgent::create(this, m_remoteFrontend.get()); + m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get()); - m_remoteFrontend->debuggerWasEnabled(); + m_frontend->debuggerWasEnabled(); } void InspectorController::enableDebugger() @@ -1653,10 +1527,10 @@ void InspectorController::enableDebugger() if (debuggerEnabled()) return; - if (!m_remoteFrontend) + if (!m_frontend) m_attachDebuggerWhenShown = true; else { - m_remoteFrontend->attachDebuggerWhenShown(); + m_frontend->attachDebuggerWhenShown(); m_attachDebuggerWhenShown = false; } } @@ -1675,8 +1549,8 @@ void InspectorController::disableDebugger(bool always) m_attachDebuggerWhenShown = false; - if (m_remoteFrontend) - m_remoteFrontend->debuggerWasDisabled(); + if (m_frontend) + m_frontend->debuggerWasDisabled(); } void InspectorController::resume() @@ -1690,8 +1564,8 @@ void InspectorController::resume() void InspectorController::evaluateForTestInFrontend(long callId, const String& script) { - if (m_remoteFrontend) - m_remoteFrontend->evaluateForTestInFrontend(callId, script); + if (m_frontend) + m_frontend->evaluateForTestInFrontend(callId, script); else m_pendingEvaluateTestCommands.append(pair<long, String>(callId, script)); } diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h index 8d96005..7ed2549 100644 --- a/WebCore/inspector/InspectorController.h +++ b/WebCore/inspector/InspectorController.h @@ -33,9 +33,7 @@ #include "Cookie.h" #include "InspectorDOMAgent.h" #include "PlatformString.h" -#include "ScriptProfile.h" #include "ScriptState.h" -#include "Timer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/ListHashSet.h> @@ -63,8 +61,10 @@ class InspectorCSSStore; class InspectorDOMStorageResource; class InspectorDatabaseResource; class InspectorDebuggerAgent; +class InspectorFrontend; class InspectorFrontendClient; class InspectorObject; +class InspectorProfilerAgent; class InspectorResource; class InspectorStorageAgent; class InspectorTimelineAgent; @@ -73,11 +73,11 @@ class InspectorWorkerResource; class KURL; class Node; class Page; -class RemoteInspectorFrontend; class ResourceRequest; class ResourceResponse; class ResourceError; class ScriptCallStack; +class ScriptProfile; class ScriptString; class SharedBuffer; class Storage; @@ -118,7 +118,7 @@ public: void setSetting(const String& key, const String& value); void saveApplicationSettings(const String& settings); void saveSessionSettings(const String&); - + void getSettings(RefPtr<InspectorObject>*); void inspect(Node*); void highlight(Node*); @@ -150,8 +150,6 @@ public: void inspectedWindowScriptObjectCleared(Frame*); - bool windowVisible(); - void didCommitLoad(DocumentLoader*); void frameDetachedFromParent(Frame*); void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*); @@ -209,7 +207,7 @@ public: const ResourcesMap& resources() const { return m_resources; } InspectorResource* resourceForURL(const String& url); - bool hasFrontend() const { return m_remoteFrontend; } + bool hasFrontend() const { return m_frontend; } void drawNodeHighlight(GraphicsContext&) const; void openInInspectedWindow(const String& url); @@ -228,20 +226,14 @@ public: void addProfile(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL); void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL); void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL); - void removeProfile(unsigned); - void clearProfiles(); - - bool isRecordingUserInitiatedProfile() const { return m_recordingUserInitiatedProfile; } - - String getCurrentUserInitiatedProfileName(bool incrementProfileNumber); - void startUserInitiatedProfiling(Timer<InspectorController>* = 0); + bool isRecordingUserInitiatedProfile() const; + String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false); + void startUserInitiatedProfiling(); void stopUserInitiatedProfiling(); - void startProfiling() { startUserInitiatedProfiling(); } - void stopProfiling() { stopUserInitiatedProfiling(); } - void enableProfiler(bool always = false, bool skipRecompile = false); void disableProfiler(bool always = false); - bool profilerEnabled() const { return enabled() && m_profilerEnabled; } + bool profilerEnabled() const; + InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); } void enableDebugger(); void disableDebugger(bool always = false); @@ -283,14 +275,9 @@ private: void releaseFrontendLifetimeAgents(); #if ENABLE(JAVASCRIPT_DEBUGGER) - typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap; - void startUserInitiatedProfilingSoon(); void toggleRecordButton(bool); void enableDebuggerFromFrontend(bool always); - void getProfileHeaders(RefPtr<InspectorArray>* headers); - void getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject); - PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile); #endif #if ENABLE(DATABASE) void selectDatabase(Database* database); @@ -330,7 +317,7 @@ private: InspectorClient* m_client; OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient; bool m_openingFrontend; - OwnPtr<RemoteInspectorFrontend> m_remoteFrontend; + OwnPtr<InspectorFrontend> m_frontend; RefPtr<InspectorDOMAgent> m_domAgent; RefPtr<InspectorStorageAgent> m_storageAgent; OwnPtr<InspectorCSSStore> m_cssStore; @@ -380,12 +367,7 @@ private: bool m_attachDebuggerWhenShown; OwnPtr<InspectorDebuggerAgent> m_debuggerAgent; - bool m_profilerEnabled; - bool m_recordingUserInitiatedProfile; - int m_currentUserInitiatedProfileNumber; - unsigned m_nextUserInitiatedProfileNumber; - Timer<InspectorController> m_startProfiling; - ProfilesMap m_profiles; + OwnPtr<InspectorProfilerAgent> m_profilerAgent; #endif #if ENABLE(WORKERS) typedef HashMap<intptr_t, RefPtr<InspectorWorkerResource> > WorkersMap; diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp index 6243299..b8ae047 100644 --- a/WebCore/inspector/InspectorDOMAgent.cpp +++ b/WebCore/inspector/InspectorDOMAgent.cpp @@ -35,6 +35,7 @@ #include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" +#include "CSSPropertyNames.h" #include "CSSRule.h" #include "CSSRuleList.h" #include "CSSStyleRule.h" @@ -54,14 +55,15 @@ #include "FrameTree.h" #include "HTMLElement.h" #include "HTMLFrameOwnerElement.h" +#include "InspectorFrontend.h" #include "MutationEvent.h" #include "Node.h" #include "NodeList.h" #include "Pasteboard.h" #include "PlatformString.h" -#include "RemoteInspectorFrontend.h" #include "RenderStyle.h" #include "RenderStyleConstants.h" +#include "ScriptDebugServer.h" #include "ScriptEventListener.h" #include "StyleSheetList.h" #include "Text.h" @@ -196,9 +198,20 @@ public: virtual ~MatchPlainTextJob() { } }; +enum DOMBreakpointType { + SubtreeModified = 0, + AttributeModified, + NodeRemoved +}; + +const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified); +const int domBreakpointDerivedTypeShift = 16; + } -InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend) +InspectorDOMAgent* InspectorDOMAgent::s_domAgentOnBreakpoint = 0; + +InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend) : EventListener(InspectorDOMAgentType) , m_cssStore(cssStore) , m_frontend(frontend) @@ -210,6 +223,9 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspecto InspectorDOMAgent::~InspectorDOMAgent() { reset(); + + if (this == s_domAgentOnBreakpoint) + s_domAgentOnBreakpoint = 0; } void InspectorDOMAgent::reset() @@ -371,6 +387,7 @@ void InspectorDOMAgent::discardBindings() releaseDanglingNodes(); m_childrenRequested.clear(); m_inspectedNodes.clear(); + m_breakpoints.clear(); } Node* InspectorDOMAgent::nodeForId(long id) @@ -720,6 +737,39 @@ void InspectorDOMAgent::searchCanceled() m_searchResults.clear(); } +void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type) +{ + Node* node = nodeForId(nodeId); + if (!node) + return; + + uint32_t rootBit = 1 << type; + m_breakpoints.set(node, m_breakpoints.get(node) | rootBit); + if (rootBit & inheritableDOMBreakpointTypesMask) { + for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child)) + updateSubtreeBreakpoints(child, rootBit, true); + } +} + +void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type) +{ + Node* node = nodeForId(nodeId); + if (!node) + return; + + uint32_t rootBit = 1 << type; + uint32_t mask = m_breakpoints.get(node) & ~rootBit; + if (mask) + m_breakpoints.set(node, mask); + else + m_breakpoints.remove(node); + + if ((rootBit & inheritableDOMBreakpointTypesMask) && !(mask & (rootBit << domBreakpointDerivedTypeShift))) { + for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child)) + updateSubtreeBreakpoints(child, rootBit, false); + } +} + String InspectorDOMAgent::documentURLString(Document* document) const { if (!document || document->url().isNull()) @@ -920,6 +970,18 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node) if (isWhitespace(node)) return; + if (m_breakpoints.size()) { + Node* parent = innerParentNode(node); + if (hasBreakpoint(parent, SubtreeModified)) { + if (!pauseOnBreakpoint()) + return; + } + uint32_t mask = m_breakpoints.get(parent); + uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask; + if (inheritableTypesMask) + updateSubtreeBreakpoints(node, inheritableTypesMask, true); + } + // We could be attaching existing subtree. Forget the bindings. unbind(node, &m_documentNodeToIdMap); @@ -946,6 +1008,25 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node) if (isWhitespace(node)) return; + if (m_breakpoints.size()) { + if (hasBreakpoint(node, NodeRemoved) || hasBreakpoint(innerParentNode(node), SubtreeModified)) { + if (!pauseOnBreakpoint()) + return; + } + // Remove subtree breakpoints. + m_breakpoints.remove(node); + Vector<Node*> stack(1, innerFirstChild(node)); + do { + Node* node = stack.last(); + stack.removeLast(); + if (!node) + continue; + m_breakpoints.remove(node); + stack.append(innerFirstChild(node)); + stack.append(innerNextSibling(node)); + } while (!stack.isEmpty()); + } + Node* parent = node->parentNode(); long parentId = m_documentNodeToIdMap.get(parent); // If parent is not mapped yet -> ignore the event. @@ -968,9 +1049,52 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element) if (!id) return; + if (hasBreakpoint(element, AttributeModified)) { + if (!pauseOnBreakpoint()) + return; + } + m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element)); } +bool InspectorDOMAgent::hasBreakpoint(Node* node, long type) +{ + uint32_t rootBit = 1 << type; + uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift; + return m_breakpoints.get(node) & (rootBit | derivedBit); +} + +bool InspectorDOMAgent::pauseOnBreakpoint() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + s_domAgentOnBreakpoint = this; + ScriptDebugServer::shared().breakProgram(); + bool deleted = !s_domAgentOnBreakpoint; + s_domAgentOnBreakpoint = 0; + return !deleted; +#else + return true; +#endif +} + +void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set) +{ + uint32_t oldMask = m_breakpoints.get(node); + uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift; + uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask; + if (newMask) + m_breakpoints.set(node, newMask); + else + m_breakpoints.remove(node); + + uint32_t newRootMask = rootMask & ~newMask; + if (!newRootMask) + return; + + for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child)) + updateSubtreeBreakpoints(child, newRootMask, set); +} + void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles) { Node* node = nodeForId(nodeId); @@ -1297,6 +1421,14 @@ void InspectorDOMAgent::addRule(const String& selector, long selectedNodeId, Ref *ruleObject = buildObjectForRule(node->ownerDocument(), newRule); } +void InspectorDOMAgent::getSupportedCSSProperties(RefPtr<InspectorArray>* cssProperties) +{ + RefPtr<InspectorArray> properties = InspectorArray::create(); + for (int i = 0; i < numCSSProperties; ++i) + properties->pushString(propertyNameStrings[i]); + *cssProperties = properties.release(); +} + PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyle(CSSStyleDeclaration* style, bool bind) { RefPtr<InspectorObject> result = InspectorObject::create(); diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h index 5317a22..fd3c5b5 100644 --- a/WebCore/inspector/InspectorDOMAgent.h +++ b/WebCore/inspector/InspectorDOMAgent.h @@ -57,7 +57,7 @@ namespace WebCore { class Element; class Event; class InspectorDOMAgent; - class RemoteInspectorFrontend; + class InspectorFrontend; class MatchJob; class NameNodeMap; class Node; @@ -80,7 +80,7 @@ namespace WebCore { class InspectorDOMAgent : public EventListener { public: - static PassRefPtr<InspectorDOMAgent> create(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend) + static PassRefPtr<InspectorDOMAgent> create(InspectorCSSStore* cssStore, InspectorFrontend* frontend) { return adoptRef(new InspectorDOMAgent(cssStore, frontend)); } @@ -92,7 +92,7 @@ namespace WebCore { : 0; } - InspectorDOMAgent(InspectorCSSStore* cssStore, RemoteInspectorFrontend* frontend); + InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend); ~InspectorDOMAgent(); void reset(); @@ -112,6 +112,8 @@ namespace WebCore { void addInspectedNode(long nodeId); void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously); void searchCanceled(); + void setDOMBreakpoint(long nodeId, long type); + void removeDOMBreakpoint(long nodeId, long type); // Methods called from the frontend for CSS styles inspection. void getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles); @@ -126,6 +128,7 @@ namespace WebCore { void toggleStyleEnabled(long styleId, const String& propertyName, bool disabled, RefPtr<InspectorValue>* styleObject); void setRuleSelector(long ruleId, const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode); void addRule(const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode); + void getSupportedCSSProperties(RefPtr<InspectorArray>* cssProperties); // Methods called from the InspectorController. void setDocument(Document* document); @@ -156,6 +159,10 @@ namespace WebCore { bool pushDocumentToFrontend(); + bool hasBreakpoint(Node* node, long type); + bool pauseOnBreakpoint(); + void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value); + PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element); PassRefPtr<InspectorArray> buildArrayForCSSRules(Document* ownerDocument, CSSRuleList*); PassRefPtr<InspectorArray> buildArrayForPseudoElements(Element* element, bool authorOnly); @@ -196,7 +203,7 @@ namespace WebCore { void discardBindings(); InspectorCSSStore* m_cssStore; - RemoteInspectorFrontend* m_frontend; + InspectorFrontend* m_frontend; NodeToIdMap m_documentNodeToIdMap; // Owns node mappings for dangling nodes. Vector<NodeToIdMap*> m_danglingNodeToIdMaps; @@ -209,6 +216,9 @@ namespace WebCore { Timer<InspectorDOMAgent> m_matchJobsTimer; HashSet<RefPtr<Node> > m_searchResults; Vector<long> m_inspectedNodes; + HashMap<Node*, uint32_t> m_breakpoints; + + static InspectorDOMAgent* s_domAgentOnBreakpoint; }; #endif diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp index 61095a0..72b4e10 100644 --- a/WebCore/inspector/InspectorDOMStorageResource.cpp +++ b/WebCore/inspector/InspectorDOMStorageResource.cpp @@ -37,8 +37,8 @@ #include "DOMWindow.h" #include "EventNames.h" #include "Frame.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" -#include "RemoteInspectorFrontend.h" #include "Storage.h" #include "StorageEvent.h" @@ -64,7 +64,7 @@ bool InspectorDOMStorageResource::isSameHostAndType(Frame* frame, bool isLocalSt return equalIgnoringCase(m_frame->document()->securityOrigin()->host(), frame->document()->securityOrigin()->host()) && m_isLocalStorage == isLocalStorage; } -void InspectorDOMStorageResource::bind(RemoteInspectorFrontend* frontend) +void InspectorDOMStorageResource::bind(InspectorFrontend* frontend) { ASSERT(!m_frontend); m_frontend = frontend; diff --git a/WebCore/inspector/InspectorDOMStorageResource.h b/WebCore/inspector/InspectorDOMStorageResource.h index a47e74c..ee09974 100644 --- a/WebCore/inspector/InspectorDOMStorageResource.h +++ b/WebCore/inspector/InspectorDOMStorageResource.h @@ -43,7 +43,7 @@ namespace WebCore { class Storage; class Frame; - class RemoteInspectorFrontend; + class InspectorFrontend; class InspectorDOMStorageResource : public EventListener { public: @@ -56,7 +56,7 @@ namespace WebCore { return listener->type() == InspectorDOMStorageResourceType ? static_cast<const InspectorDOMStorageResource*>(listener) : 0; } - void bind(RemoteInspectorFrontend* frontend); + void bind(InspectorFrontend* frontend); void unbind(); void startReportingChangesToFrontend(); @@ -74,7 +74,7 @@ namespace WebCore { RefPtr<Storage> m_domStorage; bool m_isLocalStorage; RefPtr<Frame> m_frame; - RemoteInspectorFrontend* m_frontend; + InspectorFrontend* m_frontend; int m_id; bool m_reportingChangesToFrontend; diff --git a/WebCore/inspector/InspectorDatabaseResource.cpp b/WebCore/inspector/InspectorDatabaseResource.cpp index 036148f..ba67818 100644 --- a/WebCore/inspector/InspectorDatabaseResource.cpp +++ b/WebCore/inspector/InspectorDatabaseResource.cpp @@ -33,8 +33,8 @@ #if ENABLE(DATABASE) && ENABLE(INSPECTOR) #include "Database.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" -#include "RemoteInspectorFrontend.h" namespace WebCore { @@ -55,7 +55,7 @@ InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr<Database> databa { } -void InspectorDatabaseResource::bind(RemoteInspectorFrontend* frontend) +void InspectorDatabaseResource::bind(InspectorFrontend* frontend) { if (m_scriptObjectCreated) return; diff --git a/WebCore/inspector/InspectorDatabaseResource.h b/WebCore/inspector/InspectorDatabaseResource.h index 8e0e1b3..203995b 100644 --- a/WebCore/inspector/InspectorDatabaseResource.h +++ b/WebCore/inspector/InspectorDatabaseResource.h @@ -39,13 +39,13 @@ namespace WebCore { class Database; -class RemoteInspectorFrontend; +class InspectorFrontend; class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> { public: static PassRefPtr<InspectorDatabaseResource> create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version); - void bind(RemoteInspectorFrontend* frontend); + void bind(InspectorFrontend* frontend); void unbind(); Database* database() { return m_database.get(); } long id() const { return m_id; } diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp index e1c0dc0..357a043 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.cpp +++ b/WebCore/inspector/InspectorDebuggerAgent.cpp @@ -33,9 +33,9 @@ #if ENABLE(JAVASCRIPT_DEBUGGER) #include "InjectedScript.h" #include "InjectedScriptHost.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" #include "PlatformString.h" -#include "RemoteInspectorFrontend.h" #include "ScriptDebugServer.h" #include <wtf/MD5.h> @@ -46,17 +46,19 @@ static String formatBreakpointId(const String& sourceID, unsigned lineNumber) return String::format("%s:%d", sourceID.utf8().data(), lineNumber); } -PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorController* inspectorController, RemoteInspectorFrontend* remoteFrontend) +PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorController* inspectorController, InspectorFrontend* frontend) { - OwnPtr<InspectorDebuggerAgent> agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, remoteFrontend)); + OwnPtr<InspectorDebuggerAgent> agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, frontend)); 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()); return agent.release(); } -InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, RemoteInspectorFrontend* remoteFrontend) +InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend) : m_inspectorController(inspectorController) - , m_remoteFrontend(remoteFrontend) + , m_frontend(frontend) , m_pausedScriptState(0) , m_breakpointsLoaded(false) { @@ -167,7 +169,7 @@ void InspectorDebuggerAgent::stepOutOfFunction() void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState) { ScriptDebugServer::shared().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState)); - m_remoteFrontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState()); + m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState()); } void InspectorDebuggerAgent::clearForPageNavigation() @@ -246,7 +248,7 @@ void InspectorDebuggerAgent::saveBreakpoints() void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType worldType) { // Don't send script content to the front end until it's really needed. - m_remoteFrontend->parsedScriptSource(sourceID, url, "", firstLine, worldType); + m_frontend->parsedScriptSource(sourceID, url, "", firstLine, worldType); m_scriptIDToContent.set(sourceID, data); @@ -264,7 +266,7 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String bool success = ScriptDebugServer::shared().setBreakpoint(sourceID, breakpointIt->second, lineNumber, &actualLineNumber); if (!success) continue; - m_remoteFrontend->restoredBreakpoint(sourceID, url, actualLineNumber, breakpointIt->second.enabled, breakpointIt->second.condition); + m_frontend->restoredBreakpoint(sourceID, url, actualLineNumber, breakpointIt->second.enabled, breakpointIt->second.condition); String breakpointId = formatBreakpointId(sourceID, actualLineNumber); m_breakpointsMapping.set(breakpointId, lineNumber); } @@ -274,7 +276,7 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String void InspectorDebuggerAgent::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) { - m_remoteFrontend->failedToParseScriptSource(url, data, firstLine, errorLine, errorMessage); + m_frontend->failedToParseScriptSource(url, data, firstLine, errorLine, errorMessage); } void InspectorDebuggerAgent::didPause(ScriptState* scriptState) @@ -282,13 +284,13 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState) ASSERT(scriptState && !m_pausedScriptState); m_pausedScriptState = scriptState; RefPtr<InspectorValue> callFrames = currentCallFrames(); - m_remoteFrontend->pausedScript(callFrames.get()); + m_frontend->pausedScript(callFrames.get()); } void InspectorDebuggerAgent::didContinue() { m_pausedScriptState = 0; - m_remoteFrontend->resumedScript(); + m_frontend->resumedScript(); } } // namespace WebCore diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h index 2cfbf55..91bcd49 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.h +++ b/WebCore/inspector/InspectorDebuggerAgent.h @@ -42,12 +42,12 @@ namespace WebCore { class InjectedScriptHost; class InspectorController; +class InspectorFrontend; class InspectorValue; -class RemoteInspectorFrontend; class InspectorDebuggerAgent : public ScriptDebugListener, public Noncopyable { public: - static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, RemoteInspectorFrontend*); + static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, InspectorFrontend*); virtual ~InspectorDebuggerAgent(); static bool isDebuggerAlwaysEnabled(); @@ -73,7 +73,7 @@ public: static String md5Base16(const String& string); private: - InspectorDebuggerAgent(InspectorController*, RemoteInspectorFrontend*); + InspectorDebuggerAgent(InspectorController*, InspectorFrontend*); PassRefPtr<InspectorValue> currentCallFrames(); @@ -86,7 +86,7 @@ private: virtual void didContinue(); InspectorController* m_inspectorController; - RemoteInspectorFrontend* m_remoteFrontend; + InspectorFrontend* m_frontend; ScriptState* m_pausedScriptState; HashMap<String, String> m_sourceIDToURL; HashMap<String, String> m_scriptIDToContent; diff --git a/WebCore/inspector/InspectorFrontendClientLocal.cpp b/WebCore/inspector/InspectorFrontendClientLocal.cpp index b45dd34..77616da 100644 --- a/WebCore/inspector/InspectorFrontendClientLocal.cpp +++ b/WebCore/inspector/InspectorFrontendClientLocal.cpp @@ -126,8 +126,7 @@ void InspectorFrontendClientLocal::setAttachedWindow(bool attached) ASSERT_NOT_REACHED(); return; } - ScriptFunctionCall function(webInspectorObj, "dispatch"); - function.appendArgument("setAttachedWindow"); + ScriptFunctionCall function(webInspectorObj, "setAttachedWindow"); function.appendArgument(attached); function.call(); } diff --git a/WebCore/inspector/InspectorFrontendHost.cpp b/WebCore/inspector/InspectorFrontendHost.cpp index f9bf176..8dc00ae 100644 --- a/WebCore/inspector/InspectorFrontendHost.cpp +++ b/WebCore/inspector/InspectorFrontendHost.cpp @@ -92,8 +92,7 @@ private: if (m_frontendHost) { int itemNumber = item->action() - ContextMenuItemBaseCustomTag; - ScriptFunctionCall function(m_webInspector, "dispatch"); - function.appendArgument("contextMenuItemSelected"); + ScriptFunctionCall function(m_webInspector, "contextMenuItemSelected"); function.appendArgument(itemNumber); function.call(); } @@ -102,8 +101,7 @@ private: virtual void contextMenuCleared() { if (m_frontendHost) { - ScriptFunctionCall function(m_webInspector, "dispatch"); - function.appendArgument("contextMenuCleared"); + ScriptFunctionCall function(m_webInspector, "contextMenuCleared"); function.call(); m_frontendHost->m_menuProvider = 0; diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp new file mode 100644 index 0000000..a73469a --- /dev/null +++ b/WebCore/inspector/InspectorProfilerAgent.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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 "InspectorProfilerAgent.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "Console.h" +#include "InspectorController.h" +#include "InspectorFrontend.h" +#include "InspectorValues.h" +#include "KURL.h" +#include "Page.h" +#include "ScriptDebugServer.h" +#include "ScriptProfile.h" +#include "ScriptProfiler.h" +#include <wtf/OwnPtr.h> + +#if USE(JSC) +#include "JSDOMWindow.h" +#endif + +namespace WebCore { + +static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated"; +static const char* const CPUProfileType = "CPU"; + +PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InspectorController* inspectorController) +{ + OwnPtr<InspectorProfilerAgent> agent = adoptPtr(new InspectorProfilerAgent(inspectorController)); + return agent.release(); +} + +InspectorProfilerAgent::InspectorProfilerAgent(InspectorController* inspectorController) + : m_inspectorController(inspectorController) + , m_frontend(0) + , m_enabled(ScriptProfiler::isProfilerAlwaysEnabled()) + , m_recordingUserInitiatedProfile(false) + , m_currentUserInitiatedProfileNumber(-1) + , m_nextUserInitiatedProfileNumber(1) +{ +} + +InspectorProfilerAgent::~InspectorProfilerAgent() +{ +} + +void InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL) +{ + RefPtr<ScriptProfile> profile = prpProfile; + m_profiles.add(profile->uid(), profile); + if (m_frontend) + m_frontend->addProfileHeader(createProfileHeader(*profile)); + addProfileFinishedMessageToConsole(profile, lineNumber, sourceURL); +} + +void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL) +{ + RefPtr<ScriptProfile> profile = prpProfile; + String title = profile->title(); + String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data(), profile->uid()); + m_inspectorController->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); +} + +void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL) +{ + String message = String::format("Profile \"webkit-profile://%s/%s#0\" started.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data()); + m_inspectorController->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL); +} + +PassRefPtr<InspectorObject> InspectorProfilerAgent::createProfileHeader(const ScriptProfile& profile) +{ + RefPtr<InspectorObject> header = InspectorObject::create(); + header->setString("title", profile.title()); + header->setNumber("uid", profile.uid()); + header->setString("typeId", String(CPUProfileType)); + return header; +} + +void InspectorProfilerAgent::disable() +{ + if (!m_enabled) + return; + m_enabled = false; + ScriptDebugServer::shared().recompileAllJSFunctionsSoon(); + if (m_frontend) + m_frontend->profilerWasDisabled(); +} + +void InspectorProfilerAgent::enable(bool skipRecompile) +{ + if (m_enabled) + return; + m_enabled = true; + if (!skipRecompile) + ScriptDebugServer::shared().recompileAllJSFunctionsSoon(); + if (m_frontend) + m_frontend->profilerWasEnabled(); +} + +String InspectorProfilerAgent::getCurrentUserInitiatedProfileName(bool incrementProfileNumber) +{ + if (incrementProfileNumber) + m_currentUserInitiatedProfileNumber = m_nextUserInitiatedProfileNumber++; + + return String::format("%s.%d", UserInitiatedProfileName, m_currentUserInitiatedProfileNumber); +} + +void InspectorProfilerAgent::getProfileHeaders(RefPtr<InspectorArray>* headers) +{ + ProfilesMap::iterator profilesEnd = m_profiles.end(); + for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it) + (*headers)->pushObject(createProfileHeader(*it->second)); +} + +void InspectorProfilerAgent::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject) +{ + ProfilesMap::iterator it = m_profiles.find(uid); + if (it != m_profiles.end()) { + *profileObject = createProfileHeader(*it->second); + (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead()); + } +} + +void InspectorProfilerAgent::removeProfile(unsigned uid) +{ + if (m_profiles.contains(uid)) + m_profiles.remove(uid); +} + +void InspectorProfilerAgent::resetState() +{ + m_profiles.clear(); + m_currentUserInitiatedProfileNumber = 1; + m_nextUserInitiatedProfileNumber = 1; + if (m_frontend) + m_frontend->resetProfilesPanel(); +} + +void InspectorProfilerAgent::startUserInitiatedProfiling() +{ + if (!enabled()) { + enable(false); + ScriptDebugServer::shared().recompileAllJSFunctions(); + } + m_recordingUserInitiatedProfile = true; + String title = getCurrentUserInitiatedProfileName(true); +#if USE(JSC) + JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->inspectedPage()->mainFrame(), debuggerWorld())->globalExec(); +#else + ScriptState* scriptState = 0; +#endif + ScriptProfiler::start(scriptState, title); + addStartProfilingMessageToConsole(title, 0, String()); + toggleRecordButton(true); +} + +void InspectorProfilerAgent::stopUserInitiatedProfiling() +{ + m_recordingUserInitiatedProfile = false; + String title = getCurrentUserInitiatedProfileName(); +#if USE(JSC) + JSC::ExecState* scriptState = toJSDOMWindow(m_inspectorController->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. + ScriptState* scriptState = 0; +#endif + RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title); + if (profile) + addProfile(profile, 0, String()); + toggleRecordButton(false); +} + +void InspectorProfilerAgent::toggleRecordButton(bool isProfiling) +{ + if (m_frontend) + m_frontend->setRecordingProfile(isProfiling); +} + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/WebCore/inspector/InspectorProfilerAgent.h b/WebCore/inspector/InspectorProfilerAgent.h new file mode 100644 index 0000000..9593eba --- /dev/null +++ b/WebCore/inspector/InspectorProfilerAgent.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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 InspectorProfilerAgent_h +#define InspectorProfilerAgent_h + +#if ENABLE(JAVASCRIPT_DEBUGGER) + +#include "PlatformString.h" +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class InspectorArray; +class InspectorController; +class InspectorFrontend; +class InspectorObject; +class ScriptProfile; + +class InspectorProfilerAgent : public Noncopyable { +public: + static PassOwnPtr<InspectorProfilerAgent> create(InspectorController*); + virtual ~InspectorProfilerAgent(); + + void addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL); + void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL); + void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL); + void clearProfiles() { resetState(); } + void disable(); + void enable(bool skipRecompile); + bool enabled() { return m_enabled; } + String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false); + void getProfileHeaders(RefPtr<InspectorArray>* headers); + void getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject); + bool isRecordingUserInitiatedProfile() { return m_recordingUserInitiatedProfile; } + void removeProfile(unsigned uid); + void resetState(); + void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; } + void startProfiling() { startUserInitiatedProfiling(); } + void startUserInitiatedProfiling(); + void stopProfiling() { stopUserInitiatedProfiling(); } + void stopUserInitiatedProfiling(); + void toggleRecordButton(bool isProfiling); + +private: + typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap; + + InspectorProfilerAgent(InspectorController*); + PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile); + + InspectorController* m_inspectorController; + InspectorFrontend* m_frontend; + bool m_enabled; + bool m_recordingUserInitiatedProfile; + int m_currentUserInitiatedProfileNumber; + unsigned m_nextUserInitiatedProfileNumber; + ProfilesMap m_profiles; +}; + +} // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) + +#endif // !defined(InspectorProfilerAgent_h) diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp index a2b55b0..ed07339 100644 --- a/WebCore/inspector/InspectorResource.cpp +++ b/WebCore/inspector/InspectorResource.cpp @@ -38,8 +38,8 @@ #include "DocLoader.h" #include "DocumentLoader.h" #include "Frame.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" -#include "RemoteInspectorFrontend.h" #include "ResourceLoadTiming.h" #include "ResourceRequest.h" #include "ResourceResponse.h" @@ -175,7 +175,7 @@ static PassRefPtr<InspectorObject> buildObjectForTiming(ResourceLoadTiming* timi } -void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend) +void InspectorResource::updateScriptObject(InspectorFrontend* frontend) { if (m_changes.hasChange(NoChange)) return; @@ -251,7 +251,7 @@ void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend) m_changes.clearAll(); } -void InspectorResource::releaseScriptObject(RemoteInspectorFrontend* frontend) +void InspectorResource::releaseScriptObject(InspectorFrontend* frontend) { m_changes.setAll(); diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h index 4c12ea0..4004142 100644 --- a/WebCore/inspector/InspectorResource.h +++ b/WebCore/inspector/InspectorResource.h @@ -46,7 +46,7 @@ namespace WebCore { class CachedResource; class DocumentLoader; class Frame; - class RemoteInspectorFrontend; + class InspectorFrontend; class ResourceLoadTiming; class ResourceRequest; class ResourceResponse; @@ -76,8 +76,8 @@ namespace WebCore { ~InspectorResource(); PassRefPtr<InspectorResource> appendRedirect(unsigned long identifier, const KURL& redirectURL); - void updateScriptObject(RemoteInspectorFrontend* frontend); - void releaseScriptObject(RemoteInspectorFrontend* frontend); + void updateScriptObject(InspectorFrontend* frontend); + void releaseScriptObject(InspectorFrontend* frontend); void updateRequest(const ResourceRequest&); void updateResponse(const ResourceResponse&); diff --git a/WebCore/inspector/InspectorStorageAgent.cpp b/WebCore/inspector/InspectorStorageAgent.cpp index 66d3372..1f565fa 100644 --- a/WebCore/inspector/InspectorStorageAgent.cpp +++ b/WebCore/inspector/InspectorStorageAgent.cpp @@ -34,6 +34,7 @@ #include "Database.h" #include "ExceptionCode.h" +#include "InspectorFrontend.h" #include "InspectorValues.h" #include "SQLError.h" #include "SQLStatementCallback.h" @@ -43,7 +44,6 @@ #include "SQLTransactionCallback.h" #include "SQLTransactionErrorCallback.h" #include "SQLValue.h" -#include "RemoteInspectorFrontend.h" #include "VoidCallback.h" #include <wtf/Vector.h> @@ -200,7 +200,7 @@ private: } // namespace -InspectorStorageAgent::InspectorStorageAgent(RemoteInspectorFrontend* frontend) +InspectorStorageAgent::InspectorStorageAgent(InspectorFrontend* frontend) : m_frontend(frontend) { } diff --git a/WebCore/inspector/InspectorStorageAgent.h b/WebCore/inspector/InspectorStorageAgent.h index b47e0d3..b1ceee4 100644 --- a/WebCore/inspector/InspectorStorageAgent.h +++ b/WebCore/inspector/InspectorStorageAgent.h @@ -35,11 +35,11 @@ namespace WebCore { class Database; -class RemoteInspectorFrontend; +class InspectorFrontend; class InspectorStorageAgent : public RefCounted<InspectorStorageAgent> { public: - static PassRefPtr<InspectorStorageAgent> create(RemoteInspectorFrontend* frontend) + static PassRefPtr<InspectorStorageAgent> create(InspectorFrontend* frontend) { return adoptRef(new InspectorStorageAgent(frontend)); } @@ -48,13 +48,13 @@ public: long executeSQL(Database*, const String& query); - RemoteInspectorFrontend* frontend() { return m_frontend; } + InspectorFrontend* frontend() { return m_frontend; } void clearFrontend(); private: - InspectorStorageAgent(RemoteInspectorFrontend*); + InspectorStorageAgent(InspectorFrontend*); - RemoteInspectorFrontend* m_frontend; + InspectorFrontend* m_frontend; }; } // namespace WebCore diff --git a/WebCore/inspector/InspectorTimelineAgent.cpp b/WebCore/inspector/InspectorTimelineAgent.cpp index aa42a54..fbb17c4 100644 --- a/WebCore/inspector/InspectorTimelineAgent.cpp +++ b/WebCore/inspector/InspectorTimelineAgent.cpp @@ -34,8 +34,8 @@ #if ENABLE(INSPECTOR) #include "Event.h" +#include "InspectorFrontend.h" #include "IntRect.h" -#include "RemoteInspectorFrontend.h" #include "ResourceRequest.h" #include "ResourceResponse.h" #include "TimelineRecordFactory.h" @@ -46,7 +46,7 @@ namespace WebCore { int InspectorTimelineAgent::s_instanceCount = 0; -InspectorTimelineAgent::InspectorTimelineAgent(RemoteInspectorFrontend* frontend) +InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend) : m_frontend(frontend) { ++s_instanceCount; @@ -279,7 +279,7 @@ void InspectorTimelineAgent::reset() m_recordStack.clear(); } -void InspectorTimelineAgent::resetFrontendProxyObject(RemoteInspectorFrontend* frontend) +void InspectorTimelineAgent::resetFrontendProxyObject(InspectorFrontend* frontend) { ASSERT(frontend); reset(); diff --git a/WebCore/inspector/InspectorTimelineAgent.h b/WebCore/inspector/InspectorTimelineAgent.h index 16d7b83..6b3324b 100644 --- a/WebCore/inspector/InspectorTimelineAgent.h +++ b/WebCore/inspector/InspectorTimelineAgent.h @@ -42,7 +42,7 @@ namespace WebCore { class Event; -class RemoteInspectorFrontend; +class InspectorFrontend; class IntRect; class ResourceRequest; class ResourceResponse; @@ -74,11 +74,11 @@ enum TimelineRecordType { class InspectorTimelineAgent : ScriptGCEventListener, public Noncopyable { public: - InspectorTimelineAgent(RemoteInspectorFrontend* frontend); + InspectorTimelineAgent(InspectorFrontend* frontend); ~InspectorTimelineAgent(); void reset(); - void resetFrontendProxyObject(RemoteInspectorFrontend*); + void resetFrontendProxyObject(InspectorFrontend*); // Methods called from WebCore. void willCallFunction(const String& scriptName, int scriptLine); @@ -152,7 +152,7 @@ private: void pushGCEventRecords(); - RemoteInspectorFrontend* m_frontend; + InspectorFrontend* m_frontend; Vector<TimelineRecordEntry> m_recordStack; static int s_instanceCount; diff --git a/WebCore/inspector/InspectorValues.h b/WebCore/inspector/InspectorValues.h index 4bc36f2..473ad21 100644 --- a/WebCore/inspector/InspectorValues.h +++ b/WebCore/inspector/InspectorValues.h @@ -176,6 +176,7 @@ public: void setObject(const String& name, PassRefPtr<InspectorObject>); void setArray(const String& name, PassRefPtr<InspectorArray>); + const_iterator find(const String& name) const; bool getBool(const String& name, bool* output) const; bool getNumber(const String& name, double* output) const; bool getString(const String& name, String* output) const; @@ -224,6 +225,11 @@ private: Vector<RefPtr<InspectorValue> > m_data; }; +inline InspectorObject::const_iterator InspectorObject::find(const String& name) const +{ + return m_data.find(name); +} + inline void InspectorObject::setBool(const String& name, bool value) { setValue(name, InspectorBasicValue::create(value)); diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js index 21fa6a4..824bc31 100644 --- a/WebCore/inspector/front-end/BreakpointManager.js +++ b/WebCore/inspector/front-end/BreakpointManager.js @@ -50,22 +50,16 @@ WebInspector.BreakpointManager.prototype = { } }, - setBreakpoint: function(sourceID, sourceURL, line, enabled, condition) + setBreakpoint: function(sourceID, url, line, enabled, condition) { - var breakpoint = this._setBreakpoint(sourceID, sourceURL, line, enabled, condition); + var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition); if (breakpoint) this._setBreakpointOnBackend(breakpoint); }, - restoredBreakpoint: function(sourceID, sourceURL, line, enabled, condition) + restoredBreakpoint: function(sourceID, url, line, enabled, condition) { - this._setBreakpoint(sourceID, sourceURL, line, enabled, condition); - }, - - removeBreakpoint: function(breakpoint) - { - if (this._removeBreakpoint(breakpoint)) - InspectorBackend.removeBreakpoint(breakpoint.sourceID, breakpoint.line); + this._setBreakpoint(sourceID, url, line, enabled, condition); }, breakpointsForSourceID: function(sourceID) @@ -94,27 +88,22 @@ WebInspector.BreakpointManager.prototype = { delete this._oneTimeBreakpoint; }, - _setBreakpoint: function(sourceID, sourceURL, line, enabled, condition) + _setBreakpoint: function(sourceID, url, line, enabled, condition) { - var breakpoint = new WebInspector.Breakpoint(this, sourceID, sourceURL, line, enabled, condition); + var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition); if (this._breakpoints[breakpoint.id]) return; if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id)) delete this._oneTimeBreakpoint; this._breakpoints[breakpoint.id] = breakpoint; + breakpoint.addEventListener("removed", this._breakpointRemoved, this); this.dispatchEventToListeners("breakpoint-added", breakpoint); return breakpoint; }, - _removeBreakpoint: function(breakpoint) + _breakpointRemoved: function(event) { - if (!(breakpoint.id in this._breakpoints)) - return false; - breakpoint.removeAllListeners(); - delete breakpoint._breakpointManager; - delete this._breakpoints[breakpoint.id]; - this.dispatchEventToListeners("breakpoint-removed", breakpoint); - return true; + delete this._breakpoints[event.target.id]; }, _setBreakpointOnBackend: function(breakpoint, isOneTime) @@ -129,9 +118,9 @@ WebInspector.BreakpointManager.prototype = { else delete this._oneTimeBreakpoint; } else { - this._removeBreakpoint(breakpoint); + breakpoint.remove(); if (success) - this._setBreakpoint(breakpoint.sourceID, breakpoint.sourceURL, line, breakpoint.enabled, breakpoint.condition); + this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition); } } var callbackId = WebInspector.Callback.wrap(didSetBreakpoint.bind(this)); @@ -141,9 +130,9 @@ WebInspector.BreakpointManager.prototype = { WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.Breakpoint = function(breakpointManager, sourceID, sourceURL, line, enabled, condition) +WebInspector.Breakpoint = function(breakpointManager, sourceID, url, line, enabled, condition) { - this.url = sourceURL; + this.url = url; this.line = line; this.sourceID = sourceID; this._enabled = enabled; @@ -165,10 +154,7 @@ WebInspector.Breakpoint.prototype = { this._enabled = x; this._breakpointManager._setBreakpointOnBackend(this); - if (this._enabled) - this.dispatchEventToListeners("enabled"); - else - this.dispatchEventToListeners("disabled"); + this.dispatchEventToListeners("enable-changed"); }, get sourceText() @@ -182,12 +168,6 @@ WebInspector.Breakpoint.prototype = { this.dispatchEventToListeners("text-changed"); }, - get label() - { - var displayName = (this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)")); - return displayName + ":" + this.line; - }, - get id() { return this.sourceID + ":" + this.line; @@ -208,8 +188,15 @@ WebInspector.Breakpoint.prototype = { if (this.enabled) this._breakpointManager._setBreakpointOnBackend(this); this.dispatchEventToListeners("condition-changed"); + }, + + remove: function() + { + InspectorBackend.removeBreakpoint(this.sourceID, this.line); + this.dispatchEventToListeners("removed"); + this.removeAllListeners(); + delete this._breakpointManager; } } WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; - diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js index a4daa2d..ccf45b6 100644 --- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -23,9 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.BreakpointsSidebarPane = function() +WebInspector.BreakpointsSidebarPane = function(title) { - WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints")); + WebInspector.SidebarPane.call(this, title); this.listElement = document.createElement("ol"); this.listElement.className = "breakpoint-list"; @@ -35,9 +35,6 @@ WebInspector.BreakpointsSidebarPane = function() this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); this.bodyElement.appendChild(this.emptyElement); - - WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this); - WebInspector.breakpointManager.addEventListener("breakpoint-removed", this._breakpointRemoved, this); } WebInspector.BreakpointsSidebarPane.prototype = { @@ -50,15 +47,25 @@ WebInspector.BreakpointsSidebarPane.prototype = { } }, - _breakpointAdded: function(event) + addBreakpoint: function(breakpointItem) { - var breakpoint = event.data; + breakpointItem.addEventListener("removed", this._breakpointRemoved, this); + + var element = breakpointItem.element(); + element._breakpointItem = breakpointItem; - breakpoint.addEventListener("enabled", this._breakpointEnableChanged, this); - breakpoint.addEventListener("disabled", this._breakpointEnableChanged, this); - breakpoint.addEventListener("text-changed", this._breakpointTextChanged, this); + var currentElement = this.listElement.firstChild; + while (currentElement) { + if (currentElement._breakpointItem.compareTo(element._breakpointItem) > 0) { + this.listElement.insertBefore(element, currentElement); + break; + } + currentElement = currentElement.nextSibling; + } + if (!currentElement) + this.listElement.appendChild(element); - this._appendBreakpointElement(breakpoint); + element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointItem), true); if (this.emptyElement.parentElement) { this.bodyElement.removeChild(this.emptyElement); @@ -66,88 +73,136 @@ WebInspector.BreakpointsSidebarPane.prototype = { } }, - _appendBreakpointElement: function(breakpoint) + _breakpointRemoved: function(event) { - function checkboxClicked(event) - { - breakpoint.enabled = !breakpoint.enabled; - - // without this, we'd switch to the source of the clicked breakpoint - event.stopPropagation(); + this.listElement.removeChild(event.target.element()); + if (!this.listElement.firstChild) { + this.bodyElement.removeChild(this.listElement); + this.bodyElement.appendChild(this.emptyElement); } + }, - function breakpointClicked() - { - WebInspector.panels.scripts.showSourceLine(breakpoint.url, breakpoint.line); - } + _contextMenuEventFired: function(breakpointItem, event) + { + var contextMenu = new WebInspector.ContextMenu(); + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpointItem.remove.bind(breakpointItem)); + contextMenu.show(event); + } +} - var breakpointElement = document.createElement("li"); - breakpoint._breakpointListElement = breakpointElement; - breakpointElement._breakpointObject = breakpoint; - breakpointElement.addEventListener("click", breakpointClicked, false); +WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; - var checkboxElement = document.createElement("input"); - checkboxElement.className = "checkbox-elem"; - checkboxElement.type = "checkbox"; - checkboxElement.checked = breakpoint.enabled; - checkboxElement.addEventListener("click", checkboxClicked, false); - breakpointElement.appendChild(checkboxElement); +WebInspector.BreakpointItem = function(breakpoint) +{ + this._breakpoint = breakpoint; - var labelElement = document.createTextNode(breakpoint.label); - breakpointElement.appendChild(labelElement); + this._element = document.createElement("li"); - var sourceTextElement = document.createElement("div"); - sourceTextElement.textContent = breakpoint.sourceText; - sourceTextElement.className = "source-text monospace"; - breakpointElement.appendChild(sourceTextElement); + var checkboxElement = document.createElement("input"); + checkboxElement.className = "checkbox-elem"; + checkboxElement.type = "checkbox"; + checkboxElement.checked = this._breakpoint.enabled; + checkboxElement.addEventListener("click", this._checkboxClicked.bind(this), false); + this._element.appendChild(checkboxElement); - var currentElement = this.listElement.firstChild; - while (currentElement) { - var currentBreak = currentElement._breakpointObject; - if (currentBreak.url > breakpoint.url) { - this.listElement.insertBefore(breakpointElement, currentElement); - return; - } else if (currentBreak.url == breakpoint.url && currentBreak.line > breakpoint.line) { - this.listElement.insertBefore(breakpointElement, currentElement); - return; - } - currentElement = currentElement.nextSibling; - } - this.listElement.appendChild(breakpointElement); + this._breakpoint.addEventListener("enable-changed", this._enableChanged, this); + this._breakpoint.addEventListener("removed", this._removed, this); +} + +WebInspector.BreakpointItem.prototype = { + element: function() + { + return this._element; }, - _breakpointRemoved: function(event) + remove: function() { - var breakpoint = event.data; + this._breakpoint.remove(); + }, - breakpoint.removeEventListener("enabled", null, this); - breakpoint.removeEventListener("disabled", null, this); - breakpoint.removeEventListener("text-changed", null, this); + _checkboxClicked: function(event) + { + this._breakpoint.enabled = !this._breakpoint.enabled; - var element = breakpoint._breakpointListElement; - element.parentElement.removeChild(element); + // without this, we'd switch to the source of the clicked breakpoint + event.stopPropagation(); + }, - if (!this.listElement.firstChild) { - this.bodyElement.removeChild(this.listElement); - this.bodyElement.appendChild(this.emptyElement); - } + _enableChanged: function() + { + var checkbox = this._element.firstChild; + checkbox.checked = this._breakpoint.enabled; }, - _breakpointEnableChanged: function(event) + _removed: function() + { + this.dispatchEventToListeners("removed"); + } +} + +WebInspector.BreakpointItem.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.JSBreakpointItem = function(breakpoint) +{ + WebInspector.BreakpointItem.call(this, breakpoint); + + this._element.addEventListener("click", this._breakpointClicked.bind(this), false); + + var displayName = this._breakpoint.url ? WebInspector.displayNameForURL(this._breakpoint.url) : WebInspector.UIString("(program)"); + var labelElement = document.createTextNode(displayName + ":" + this._breakpoint.line); + this._element.appendChild(labelElement); + + var sourceTextElement = document.createElement("div"); + sourceTextElement.textContent = this._breakpoint.sourceText; + sourceTextElement.className = "source-text monospace"; + this._element.appendChild(sourceTextElement); + + this._breakpoint.addEventListener("text-changed", this._textChanged, this); +} + +WebInspector.JSBreakpointItem.prototype = { + compareTo: function(other) { - var breakpoint = event.target; + if (this._breakpoint.url != other._breakpoint.url) + return this._breakpoint.url < other._breakpoint.url ? -1 : 1; + if (this._breakpoint.line != other._breakpoint.line) + return this._breakpoint.line < other._breakpoint.line ? -1 : 1; + return 0; + }, - var checkbox = breakpoint._breakpointListElement.firstChild; - checkbox.checked = breakpoint.enabled; + _breakpointClicked: function() + { + WebInspector.panels.scripts.showSourceLine(this._breakpoint.url, this._breakpoint.line); }, - _breakpointTextChanged: function(event) + _textChanged: function() { - var breakpoint = event.target; + var sourceTextElement = this._element.firstChild.nextSibling.nextSibling; + sourceTextElement.textContent = this._breakpoint.sourceText; + } +} + +WebInspector.JSBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype; - var sourceTextElement = breakpoint._breakpointListElement.firstChild.nextSibling.nextSibling; - sourceTextElement.textContent = breakpoint.sourceText; +WebInspector.DOMBreakpointItem = function(breakpoint) +{ + WebInspector.BreakpointItem.call(this, breakpoint); + + var link = WebInspector.panels.elements.linkifyNodeReference(this._breakpoint.node); + this._element.appendChild(link); + + var type = WebInspector.DOMBreakpoint.Labels[this._breakpoint.type]; + var typeElement = document.createTextNode(" - " + type); + this._element.appendChild(typeElement); +} + +WebInspector.DOMBreakpointItem.prototype = { + compareTo: function(other) + { + if (this._breakpoint.type != other._breakpoint.type) + return this._breakpoint.type < other._breakpoint.type ? -1 : 1; + return 0; } } -WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; +WebInspector.DOMBreakpointItem.prototype.__proto__ = WebInspector.BreakpointItem.prototype; diff --git a/WebCore/inspector/front-end/CSSCompletions.js b/WebCore/inspector/front-end/CSSCompletions.js index 5485464..9480467 100644 --- a/WebCore/inspector/front-end/CSSCompletions.js +++ b/WebCore/inspector/front-end/CSSCompletions.js @@ -1,27 +1,4 @@ -WebInspector.CSSCompletions = (function() { - var used = {}; - var properties = []; - var style = document.documentElement.style; - var list = document.defaultView.getComputedStyle(document.documentElement, ""); - var length = list.length; - for (var i = 0; i < length; ++i) - used[properties[i] = list[i]] = true; - - for (var i = 0, end = length; i < length; ++i) { - var propertyWords = properties[i].split("-"); - var j = propertyWords.length; - while (--j) { - propertyWords.pop(); - var shorthand = propertyWords.join("-"); - if (!(shorthand in used) && style[shorthand] !== undefined) { - used[shorthand] = true; - properties[end++] = shorthand; - } - } - } - - return properties.sort(); -})(); +WebInspector.CSSCompletions = []; WebInspector.CSSCompletions.startsWith = function(prefix) { @@ -45,6 +22,8 @@ WebInspector.CSSCompletions._firstIndexOfPrefix = function(prefix) { if (!prefix) return -1; + if (!this.length) + return -1; var maxIndex = this.length - 1; var minIndex = 0; @@ -100,3 +79,10 @@ WebInspector.CSSCompletions._closest = function(str, prefix, shift) j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; return propertiesWithPrefix[j]; } + +WebInspector.CSSCompletions._load = function(properties) +{ + for (var i = 0; i < properties.length; ++i) + WebInspector.CSSCompletions.push(properties[i]); + WebInspector.CSSCompletions.sort(); +} diff --git a/WebCore/inspector/front-end/Callback.js b/WebCore/inspector/front-end/Callback.js index d8163fe..0621fd1 100644 --- a/WebCore/inspector/front-end/Callback.js +++ b/WebCore/inspector/front-end/Callback.js @@ -42,9 +42,8 @@ WebInspector.Callback.prototype = { return callbackId; }, - processResponse: function(callbackId, opt_vararg) + processResponse: function(callbackId, args) { - var args = Array.prototype.slice.call(arguments, 1); var callback = this._callbacks[callbackId]; callback.apply(null, args); delete this._callbacks[callbackId]; diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 474c362..9785cd0 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -401,9 +401,9 @@ WebInspector.ConsoleView.prototype = { var contextMenu = new WebInspector.ContextMenu(); if (!WebInspector.monitoringXHREnabled) - contextMenu.appendItem(WebInspector.UIString("Enable XMLHttpRequest logging"), InspectorBackend.enableMonitoringXHR.bind(InspectorBackend)); + contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.enableMonitoringXHR.bind(InspectorBackend), false); else - contextMenu.appendItem(WebInspector.UIString("Disable XMLHttpRequest logging"), InspectorBackend.disableMonitoringXHR.bind(InspectorBackend)); + contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), InspectorBackend.disableMonitoringXHR.bind(InspectorBackend), true); contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this)); contextMenu.show(event); }, diff --git a/WebCore/inspector/front-end/ContextMenu.js b/WebCore/inspector/front-end/ContextMenu.js index 3cdb152..47045a2 100644 --- a/WebCore/inspector/front-end/ContextMenu.js +++ b/WebCore/inspector/front-end/ContextMenu.js @@ -46,10 +46,17 @@ WebInspector.ContextMenu.prototype = { } }, - appendItem: function(label, handler) + appendItem: function(label, handler, disabled) { var id = this._items.length; - this._items.push({id: id, label: label}); + this._items.push({type: "item", id: id, label: label, enabled: !disabled}); + this._handlers[id] = handler; + }, + + appendCheckboxItem: function(label, handler, checked, disabled) + { + var id = this._items.length; + this._items.push({type: "checkbox", id: id, label: label, checked: !!checked, enabled: !disabled}); this._handlers[id] = handler; }, @@ -60,7 +67,7 @@ WebInspector.ContextMenu.prototype = { return; if (!("id" in this._items[this._items.length - 1])) return; - this._items.push({}); + this._items.push({type: "separator"}); }, _itemSelected: function(id) diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js index 57422f6..0d79d51 100644 --- a/WebCore/inspector/front-end/DOMAgent.js +++ b/WebCore/inspector/front-end/DOMAgent.js @@ -677,3 +677,94 @@ WebInspector.childNodeRemoved = function() this.domAgent._childNodeRemoved.apply(this.domAgent, arguments); } +WebInspector.DOMBreakpointManager = function() +{ + this._breakpoints = {}; +} + +WebInspector.DOMBreakpointManager.prototype = { + setBreakpoint: function(node, type) + { + if (!(node.id in this._breakpoints)) + this._breakpoints[node.id] = {}; + else if (type in this._breakpoints[node.id]) + return; + + var breakpoint = new WebInspector.DOMBreakpoint(node, type); + this._breakpoints[node.id][type] = breakpoint; + breakpoint.addEventListener("removed", this._breakpointRemoved, this); + + this.dispatchEventToListeners("dom-breakpoint-added", breakpoint); + }, + + removeBreakpointsForNode: function(node) + { + var nodeBreakpoints = this._breakpoints[node.id]; + for (var type in nodeBreakpoints) + nodeBreakpoints[type].remove(); + }, + + _breakpointRemoved: function(event) + { + var breakpoint = event.target; + + var nodeBreakpoints = this._breakpoints[breakpoint.node.id]; + delete nodeBreakpoints[breakpoint.type]; + for (var type in nodeBreakpoints) + return; + delete this._breakpoints[breakpoint.node.id]; + } +} + +WebInspector.DOMBreakpointManager.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.DOMBreakpoint = function(node, type) +{ + this.node = node; + this.type = type; + this._enabled = true; + + InspectorBackend.setDOMBreakpoint(this.node.id, this.type); +} + +WebInspector.DOMBreakpoint.Types = { + SubtreeModified: 0, + AttributeModified: 1, + NodeRemoved: 2 +}; + +WebInspector.DOMBreakpoint.Labels = {}; +WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.SubtreeModified] = WebInspector.UIString("Subtree Modified"); +WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.AttributeModified] = WebInspector.UIString("Attribute Modified"); +WebInspector.DOMBreakpoint.Labels[WebInspector.DOMBreakpoint.Types.NodeRemoved] = WebInspector.UIString("Node Removed"); + +WebInspector.DOMBreakpoint.prototype = { + get enabled() + { + return this._enabled; + }, + + set enabled(enabled) + { + if (this._enabled === enabled) + return; + + this._enabled = enabled; + if (this._enabled) + InspectorBackend.setDOMBreakpoint(this.node.id, this.type); + else + InspectorBackend.removeDOMBreakpoint(this.node.id, this.type); + + this.dispatchEventToListeners("enable-changed"); + }, + + remove: function() + { + if (this._enabled) + InspectorBackend.removeDOMBreakpoint(this.node.id, this.type); + this.dispatchEventToListeners("removed"); + } +} + +WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.Object.prototype; + diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js index 0296737..f18299a 100644 --- a/WebCore/inspector/front-end/ElementsPanel.js +++ b/WebCore/inspector/front-end/ElementsPanel.js @@ -74,6 +74,8 @@ WebInspector.ElementsPanel = function() this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle); this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane(); this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane(); + if (Preferences.domBreakpointsEnabled) + this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane(); this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane(); this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this); @@ -90,11 +92,8 @@ WebInspector.ElementsPanel = function() this.sidebarElement = document.createElement("div"); this.sidebarElement.id = "elements-sidebar"; - this.sidebarElement.appendChild(this.sidebarPanes.computedStyle.element); - this.sidebarElement.appendChild(this.sidebarPanes.styles.element); - this.sidebarElement.appendChild(this.sidebarPanes.metrics.element); - this.sidebarElement.appendChild(this.sidebarPanes.properties.element); - this.sidebarElement.appendChild(this.sidebarPanes.eventListeners.element); + for (var pane in this.sidebarPanes) + this.sidebarElement.appendChild(this.sidebarPanes[pane].element); this.sidebarResizeElement = document.createElement("div"); this.sidebarResizeElement.className = "sidebar-resizer-vertical"; @@ -179,6 +178,9 @@ WebInspector.ElementsPanel.prototype = { this.recentlyModifiedNodes = []; delete this.currentQuery; + + if (Preferences.domBreakpointsEnabled) + this.sidebarPanes.domBreakpoints.reset(); }, setDocument: function(inspectedRootDocument) diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index c7d39f1..7f48161 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -402,7 +402,7 @@ WebInspector.ElementsTreeElement.prototype = { var node = this.representedObject; if (!node.nodeName || node.nodeName.toLowerCase() !== "img") return; - + function setTooltip(properties) { if (!properties) @@ -761,6 +761,21 @@ WebInspector.ElementsTreeElement.prototype = { contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this)); contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this)); contextMenu.appendItem(WebInspector.UIString("Delete Node"), this.remove.bind(this)); + + if (Preferences.domBreakpointsEnabled) { + // Add debbuging-related actions + contextMenu.appendSeparator(); + + contextMenu.appendItem(WebInspector.UIString("Stop on Subtree Modifications"), + WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.SubtreeModified)); + contextMenu.appendItem(WebInspector.UIString("Stop on Attributes Modifications"), + WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.AttributeModified)); + contextMenu.appendItem(WebInspector.UIString("Stop on Node Removal"), + WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, WebInspector.DOMBreakpoint.Types.NodeRemoved)); + + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoints"), + WebInspector.domBreakpointManager.removeBreakpointsForNode.bind(WebInspector.domBreakpointManager, this.representedObject)); + } }, _populateTextContextMenu: function(contextMenu, textNode) diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js index 476a463..a89dcf1 100644 --- a/WebCore/inspector/front-end/ExtensionAPI.js +++ b/WebCore/inspector/front-end/ExtensionAPI.js @@ -160,7 +160,6 @@ Panels.prototype = { function PanelImpl(id) { this._id = id; - this.onSelectionChanged = new EventSink("panel-objectSelected-" + id); } PanelImpl.prototype = { @@ -182,6 +181,7 @@ function Panel(id) { var impl = new PanelImpl(id); this.createSidebarPane = bind(impl.createSidebarPane, impl); + this.onSelectionChanged = new EventSink("panel-objectSelected-" + id); } function ExtensionPanel(id) diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js index 2fa0d34..8cbdebb 100644 --- a/WebCore/inspector/front-end/Panel.js +++ b/WebCore/inspector/front-end/Panel.js @@ -116,7 +116,7 @@ WebInspector.Panel.prototype = { document.getElementById("main-panels").appendChild(this.element); }, - searchCanceled: function(startingNewSearch) + searchCanceled: function() { if (this._searchResults) { for (var i = 0; i < this._searchResults.length; ++i) { @@ -238,11 +238,9 @@ WebInspector.Panel.prototype = { var currentView = this._searchResults[this._currentSearchResultIndex]; if (currentView.showingLastSearchResult()) { - if (this.searchIteratesOverViews()) { - if (++this._currentSearchResultIndex >= this._searchResults.length) - this._currentSearchResultIndex = 0; - currentView = this._searchResults[this._currentSearchResultIndex]; - } + if (++this._currentSearchResultIndex >= this._searchResults.length) + this._currentSearchResultIndex = 0; + currentView = this._searchResults[this._currentSearchResultIndex]; showFirstResult = true; } @@ -273,11 +271,9 @@ WebInspector.Panel.prototype = { var currentView = this._searchResults[this._currentSearchResultIndex]; if (currentView.showingFirstSearchResult()) { - if (this.searchIteratesOverViews()) { - if (--this._currentSearchResultIndex < 0) - this._currentSearchResultIndex = (this._searchResults.length - 1); - currentView = this._searchResults[this._currentSearchResultIndex]; - } + if (--this._currentSearchResultIndex < 0) + this._currentSearchResultIndex = (this._searchResults.length - 1); + currentView = this._searchResults[this._currentSearchResultIndex]; showLastResult = true; } @@ -409,11 +405,6 @@ WebInspector.Panel.prototype = { return false; }, - searchIteratesOverViews: function() - { - return false; - }, - elementsToRestoreScrollPositionsFor: function() { return []; diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js index e5877d9..e18274c 100644 --- a/WebCore/inspector/front-end/ProfilesPanel.js +++ b/WebCore/inspector/front-end/ProfilesPanel.js @@ -158,26 +158,20 @@ WebInspector.ProfilesPanel.prototype = { show: function() { WebInspector.Panel.prototype.show.call(this); - if (this._shouldPopulateProfiles) + if (!this._profilesWereRequested) this._populateProfiles(); }, - populateInterface: function() - { - this._reset(); - if (this.visible) - this._populateProfiles(); - else - this._shouldPopulateProfiles = true; - }, - profilerWasEnabled: function() { if (this._profilerEnabled) return; this._profilerEnabled = true; - this.populateInterface(); + + this._reset(); + if (this.visible) + this._populateProfiles(); }, profilerWasDisabled: function() @@ -207,6 +201,7 @@ WebInspector.ProfilesPanel.prototype = { this._profilesIdMap = {}; this._profileGroups = {}; this._profileGroupsForLinks = {} + this._profilesWereRequested = false; this.sidebarTreeElement.removeStyleClass("some-expandable"); @@ -532,7 +527,7 @@ WebInspector.ProfilesPanel.prototype = { var callId = WebInspector.Callback.wrap(populateCallback); InspectorBackend.getProfileHeaders(callId); - delete this._shouldPopulateProfiles; + this._profilesWereRequested = true; }, updateMainViewWidth: function(width) diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js index 01eefc7..ff0d1ab 100644 --- a/WebCore/inspector/front-end/ResourcesPanel.js +++ b/WebCore/inspector/front-end/ResourcesPanel.js @@ -769,11 +769,6 @@ WebInspector.ResourcesPanel.prototype = { return this.items; }, - searchIteratesOverViews: function() - { - return true; - }, - elementsToRestoreScrollPositionsFor: function() { return [ this.containerElement ]; diff --git a/WebCore/inspector/front-end/ScriptView.js b/WebCore/inspector/front-end/ScriptView.js index 5598577..74dc30a 100644 --- a/WebCore/inspector/front-end/ScriptView.js +++ b/WebCore/inspector/front-end/ScriptView.js @@ -34,7 +34,7 @@ WebInspector.ScriptView = function(script) this._frameNeedsSetup = true; this._sourceFrameSetup = false; var canEditScripts = WebInspector.panels.scripts.canEditScripts(); - this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); } WebInspector.ScriptView.prototype = { @@ -129,7 +129,6 @@ WebInspector.ScriptView.prototype = { showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult, showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult, _jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult, - _removeBreakpoint: WebInspector.SourceView.prototype._removeBreakpoint, _editLine: WebInspector.SourceView.prototype._editLine, resize: WebInspector.SourceView.prototype.resize } diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 8675f79..7521ea9 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -132,7 +132,9 @@ WebInspector.ScriptsPanel = function() this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane(); this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(); this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane(); - this.sidebarPanes.breakpoints = new WebInspector.BreakpointsSidebarPane(); + this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane(); + if (Preferences.domBreakpointsEnabled) + this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane(); this.sidebarPanes.workers = new WebInspector.WorkersSidebarPane(); for (var pane in this.sidebarPanes) @@ -142,7 +144,9 @@ WebInspector.ScriptsPanel = function() this.sidebarPanes.callstack.addEventListener("call frame selected", this._callFrameSelected, this); this.sidebarPanes.scopechain.expanded = true; - this.sidebarPanes.breakpoints.expanded = true; + this.sidebarPanes.jsBreakpoints.expanded = true; + if (Preferences.domBreakpointsEnabled) + this.sidebarPanes.domBreakpoints.expanded = true; var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel."); var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower."); @@ -171,7 +175,6 @@ WebInspector.ScriptsPanel = function() this._debuggerEnabled = Preferences.debuggerAlwaysEnabled; WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this); - WebInspector.breakpointManager.addEventListener("breakpoint-removed", this._breakpointRemoved, this); this.reset(); } @@ -227,11 +230,6 @@ WebInspector.ScriptsPanel.prototype = { WebInspector.Panel.prototype.hide.call(this); }, - get searchableViews() - { - return [ this.visibleView ]; - }, - get breakpointsActivated() { return this.toggleBreakpointsButton.toggled; @@ -312,26 +310,6 @@ WebInspector.ScriptsPanel.prototype = { sourceFrame.addBreakpoint(breakpoint); }, - _breakpointRemoved: function(event) - { - var breakpoint = event.data; - - var sourceFrame; - if (breakpoint.url) { - var resource = WebInspector.resourceURLMap[breakpoint.url]; - if (resource && resource.finished) - sourceFrame = this._sourceFrameForScriptOrResource(resource); - } - - if (breakpoint.sourceID && !sourceFrame) { - var object = this._sourceIDMap[breakpoint.sourceID] - sourceFrame = this._sourceFrameForScriptOrResource(object); - } - - if (sourceFrame) - sourceFrame.removeBreakpoint(breakpoint); - }, - canEditScripts: function() { return Preferences.canEditScriptSource; @@ -345,7 +323,7 @@ WebInspector.ScriptsPanel.prototype = { // Need to clear breakpoints and re-create them later when editing source. var breakpoints = WebInspector.breakpointManager.breakpointsForSourceID(sourceID); for (var i = 0; i < breakpoints.length; ++i) - WebInspector.breakpointManager.removeBreakpoint(breakpoints[i]); + breakpoints[i].remove(); function mycallback(success, newBodyOrErrorMessage, callFrames) { @@ -494,7 +472,9 @@ WebInspector.ScriptsPanel.prototype = { this.sidebarPanes.watchExpressions.refreshExpressions(); if (!preserveItems) { - this.sidebarPanes.breakpoints.reset(); + this.sidebarPanes.jsBreakpoints.reset(); + if (Preferences.domBreakpointsEnabled) + this.sidebarPanes.domBreakpoints.reset(); this.sidebarPanes.workers.reset(); } }, @@ -1029,6 +1009,74 @@ WebInspector.ScriptsPanel.prototype = { section.addAlternateKeys([ shortcut1.name, shortcut2.name ], WebInspector.UIString("Step out")); this.sidebarPanes.callstack.registerShortcuts(section); + }, + + searchCanceled: function() + { + WebInspector.updateSearchMatchesCount(0, this); + + if (this._searchView) + this._searchView.searchCanceled(); + + delete this._searchView; + delete this._searchQuery; + }, + + performSearch: function(query) + { + if (!this.visibleView) + return; + + // Call searchCanceled since it will reset everything we need before doing a new search. + this.searchCanceled(); + + this._searchView = this.visibleView; + this._searchQuery = query; + + function finishedCallback(view, searchMatches) + { + if (!searchMatches) + return; + + WebInspector.updateSearchMatchesCount(searchMatches, this); + view.jumpToFirstSearchResult(); + } + + this._searchView.performSearch(query, finishedCallback.bind(this)); + }, + + jumpToNextSearchResult: function() + { + if (!this._searchView) + return; + + if (this._searchView !== this.visibleView) { + this.performSearch(this._searchQuery); + return; + } + + if (this._searchView.showingLastSearchResult()) + this._searchView.jumpToFirstSearchResult(); + else + this._searchView.jumpToNextSearchResult(); + }, + + jumpToPreviousSearchResult: function() + { + if (!this._searchView) + return; + + if (this._searchView !== this.visibleView) { + this.performSearch(this._searchQuery); + if (this._searchView) + this._searchView.jumpToLastSearchResult(); + return; + } + + if (this._searchView.showingFirstSearchResult()) + this._searchView.jumpToLastSearchResult(); + else + this._searchView.jumpToPreviousSearchResult(); } } diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js index 913d495..a186d43 100644 --- a/WebCore/inspector/front-end/Section.js +++ b/WebCore/inspector/front-end/Section.js @@ -82,21 +82,18 @@ WebInspector.Section.prototype = { if (this._subtitle === x) return; this._subtitle = x; - this.subtitleElement.setAttribute("data-uncopyable", x); + this.subtitleElement.textContent = x; }, - get subtitleAsText() - { - var result = ""; - var data = this.subtitleElement.getAttribute("data-uncopyable"); - if (data) - result += data; - var child = this.subtitleElement.querySelector("[data-uncopyable]"); - if (child) { - var linkData = child.getAttribute("data-uncopyable"); - if (linkData) - result += linkData; - } + get subtitleAsTextForTest()
+ {
+ var result = this.subtitleElement.textContent;
+ var child = this.subtitleElement.querySelector("[data-uncopyable]");
+ if (child) {
+ var linkData = child.getAttribute("data-uncopyable");
+ if (linkData)
+ result += linkData;
+ }
return result; }, diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index c84ba79..33a1b91 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -43,36 +43,48 @@ var Preferences = { debuggerAlwaysEnabled: false, profilerAlwaysEnabled: false, auditsPanelEnabled: true, - onlineDetectionEnabled: true + onlineDetectionEnabled: true, + domBreakpointsEnabled: false } -WebInspector.populateApplicationSettings = function(settingsString) +WebInspector.Settings = function(sessionScope) { - WebInspector.applicationSettings._load(settingsString); - WebInspector.applicationSettings.installSetting("eventListenersFilter", "event-listeners-filter", "all"); - WebInspector.applicationSettings.installSetting("colorFormat", "color-format", "hex"); - WebInspector.applicationSettings.installSetting("resourcesLargeRows", "resources-large-rows", true); - WebInspector.applicationSettings.installSetting("watchExpressions", "watch-expressions", []); - WebInspector.applicationSettings.installSetting("lastViewedScriptFile", "last-viewed-script-file"); - WebInspector.applicationSettings.installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false); - WebInspector.applicationSettings.installSetting("showUserAgentStyles", "show-user-agent-styles", true); - WebInspector.applicationSettings.installSetting("resourceViewTab", "resource-view-tab", "content"); - WebInspector.applicationSettings.installSetting("consoleHistory", "console-history", []); - WebInspector.applicationSettings.installSetting("resourcesSortOptions", "resources-sort-options", {timeOption: "responseTime", sizeOption: "transferSize"}); - - WebInspector.applicationSettings.dispatchEventToListeners("loaded"); + this._sessionScope = sessionScope; + this._store = {}; } -WebInspector.populateSessionSettings = function(settingsString) +WebInspector.Settings.initialize = function() { - WebInspector.sessionSettings._load(settingsString); - WebInspector.sessionSettings.dispatchEventToListeners("loaded"); -} + WebInspector.applicationSettings = new WebInspector.Settings(false); + WebInspector.sessionSettings = new WebInspector.Settings(true); -WebInspector.Settings = function(sessionScope) -{ - this._sessionScope = sessionScope; - this._store = {}; + function populateApplicationSettings(settingsString) + { + WebInspector.applicationSettings._load(settingsString); + WebInspector.applicationSettings.installSetting("eventListenersFilter", "event-listeners-filter", "all"); + WebInspector.applicationSettings.installSetting("colorFormat", "color-format", "hex"); + WebInspector.applicationSettings.installSetting("resourcesLargeRows", "resources-large-rows", true); + WebInspector.applicationSettings.installSetting("watchExpressions", "watch-expressions", []); + WebInspector.applicationSettings.installSetting("lastViewedScriptFile", "last-viewed-script-file"); + WebInspector.applicationSettings.installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false); + WebInspector.applicationSettings.installSetting("showUserAgentStyles", "show-user-agent-styles", true); + WebInspector.applicationSettings.installSetting("resourceViewTab", "resource-view-tab", "content"); + WebInspector.applicationSettings.installSetting("consoleHistory", "console-history", []); + WebInspector.applicationSettings.installSetting("resourcesSortOptions", "resources-sort-options", {timeOption: "responseTime", sizeOption: "transferSize"}); + + WebInspector.applicationSettings.dispatchEventToListeners("loaded"); + } + + function populateSessionSettings(settingsString) + { + WebInspector.sessionSettings._load(settingsString); + WebInspector.sessionSettings.dispatchEventToListeners("loaded"); + } + + InspectorBackend.getSettings(WebInspector.Callback.wrap(function(settings) { + populateApplicationSettings(settings.application); + populateSessionSettings(settings.session); + })); } WebInspector.Settings.prototype = { diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.js b/WebCore/inspector/front-end/SourceCSSTokenizer.js index 2179982..82149e0 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.js @@ -45,60 +45,8 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = [ - "background", "background-attachment", "background-clip", "background-color", "background-image", - "background-origin", "background-position", "background-position-x", "background-position-y", - "background-repeat", "background-repeat-x", "background-repeat-y", "background-size", "border", - "border-bottom", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", "border-color", "border-left", - "border-left-color", "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style", - "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "caption-side", "clear", "clip", "color", "content", - "counter-increment", "counter-reset", "cursor", "direction", "display", "empty-cells", "float", - "font", "font-family", "font-size", "font-stretch", "font-style", "font-variant", "font-weight", - "height", "left", "letter-spacing", "line-height", "list-style", "list-style-image", "list-style-position", - "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "max-height", - "max-width", "min-height", "min-width", "opacity", "orphans", "outline", "outline-color", "outline-offset", - "outline-style", "outline-width", "overflow", "overflow-x", "overflow-y", "padding", "padding-bottom", - "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before", - "page-break-inside", "pointer-events", "position", "quotes", "resize", "right", "size", "src", - "table-layout", "text-align", "text-decoration", "text-indent", "text-line-through", "text-line-through-color", - "text-line-through-mode", "text-line-through-style", "text-line-through-width", "text-overflow", "text-overline", - "text-overline-color", "text-overline-mode", "text-overline-style", "text-overline-width", "text-rendering", - "text-shadow", "text-transform", "text-underline", "text-underline-color", "text-underline-mode", - "text-underline-style", "text-underline-width", "top", "unicode-bidi", "unicode-range", "vertical-align", - "visibility", "white-space", "widows", "width", "word-break", "word-spacing", "word-wrap", "z-index", "zoom", - "-webkit-animation", "-webkit-animation-delay", "-webkit-animation-direction", "-webkit-animation-duration", - "-webkit-animation-iteration-count", "-webkit-animation-name", "-webkit-animation-play-state", - "-webkit-animation-timing-function", "-webkit-appearance", "-webkit-backface-visibility", - "-webkit-background-clip", "-webkit-background-composite", "-webkit-background-origin", "-webkit-background-size", - "-webkit-binding", "-webkit-border-end", "-webkit-border-end-color", "-webkit-border-end-style", "-webkit-border-end-width", - "-webkit-border-fit", "-webkit-border-horizontal-spacing", "-webkit-border-image", - "-webkit-border-radius", "-webkit-border-start", "-webkit-border-start-color", "-webkit-border-start-style", - "-webkit-border-start-width","-webkit-border-vertical-spacing", "-webkit-box-align", "-webkit-box-direction", - "-webkit-box-flex", "-webkit-box-flex-group", "-webkit-box-lines", "-webkit-box-ordinal-group", - "-webkit-box-orient", "-webkit-box-pack", "-webkit-box-reflect", "-webkit-box-shadow", "-webkit-box-sizing", - "-webkit-column-break-after", "-webkit-column-break-before", "-webkit-column-break-inside", "-webkit-column-count", - "-webkit-column-gap", "-webkit-column-rule", "-webkit-column-rule-color", "-webkit-column-rule-style", - "-webkit-column-rule-width", "-webkit-column-width", "-webkit-columns", "-webkit-font-size-delta", - "-webkit-font-smoothing", "-webkit-highlight", "-webkit-line-break", "-webkit-line-clamp", - "-webkit-margin-bottom-collapse", "-webkit-margin-collapse", "-webkit-margin-end", "-webkit-margin-start", "-webkit-margin-top-collapse", - "-webkit-marquee", "-webkit-marquee-direction", "-webkit-marquee-increment", "-webkit-marquee-repetition", - "-webkit-marquee-speed", "-webkit-marquee-style", "-webkit-mask", "-webkit-mask-attachment", - "-webkit-mask-box-image", "-webkit-mask-clip", "-webkit-mask-composite", "-webkit-mask-image", - "-webkit-mask-origin", "-webkit-mask-position", "-webkit-mask-position-x", "-webkit-mask-position-y", - "-webkit-mask-repeat", "-webkit-mask-repeat-x", "-webkit-mask-repeat-y", "-webkit-mask-size", - "-webkit-match-nearest-mail-blockquote-color", "-webkit-nbsp-mode", "-webkit-padding-end", "-webkit-padding-start", - "-webkit-perspective", "-webkit-perspective-origin", "-webkit-perspective-origin-x", "-webkit-perspective-origin-y", - "-webkit-rtl-ordering", "-webkit-text-decorations-in-effect", "-webkit-text-fill-color", "-webkit-text-security", - "-webkit-text-size-adjust", "-webkit-text-stroke", "-webkit-text-stroke-color", "-webkit-text-stroke-width", - "-webkit-transform", "-webkit-transform-origin", "-webkit-transform-origin-x", "-webkit-transform-origin-y", - "-webkit-transform-origin-z", "-webkit-transform-style", "-webkit-transition", "-webkit-transition-delay", - "-webkit-transition-duration", "-webkit-transition-property", "-webkit-transition-timing-function", - "-webkit-user-drag", "-webkit-user-modify", "-webkit-user-select", "-webkit-variable-declaration-block" - ].keySet(); - + this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js index 6ba9f60..b4d3eef 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js @@ -44,58 +44,8 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = [ - "background", "background-attachment", "background-clip", "background-color", "background-image", - "background-origin", "background-position", "background-position-x", "background-position-y", - "background-repeat", "background-repeat-x", "background-repeat-y", "background-size", "border", - "border-bottom", "border-bottom-color", "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", "border-color", "border-left", - "border-left-color", "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", "border-spacing", "border-style", - "border-top", "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "caption-side", "clear", "clip", "color", "content", - "counter-increment", "counter-reset", "cursor", "direction", "display", "empty-cells", "float", - "font", "font-family", "font-size", "font-stretch", "font-style", "font-variant", "font-weight", - "height", "left", "letter-spacing", "line-height", "list-style", "list-style-image", "list-style-position", - "list-style-type", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "max-height", - "max-width", "min-height", "min-width", "opacity", "orphans", "outline", "outline-color", "outline-offset", - "outline-style", "outline-width", "overflow", "overflow-x", "overflow-y", "padding", "padding-bottom", - "padding-left", "padding-right", "padding-top", "page", "page-break-after", "page-break-before", - "page-break-inside", "pointer-events", "position", "quotes", "resize", "right", "size", "src", - "table-layout", "text-align", "text-decoration", "text-indent", "text-line-through", "text-line-through-color", - "text-line-through-mode", "text-line-through-style", "text-line-through-width", "text-overflow", "text-overline", - "text-overline-color", "text-overline-mode", "text-overline-style", "text-overline-width", "text-rendering", - "text-shadow", "text-transform", "text-underline", "text-underline-color", "text-underline-mode", - "text-underline-style", "text-underline-width", "top", "unicode-bidi", "unicode-range", "vertical-align", - "visibility", "white-space", "widows", "width", "word-break", "word-spacing", "word-wrap", "z-index", "zoom", - "-webkit-animation", "-webkit-animation-delay", "-webkit-animation-direction", "-webkit-animation-duration", - "-webkit-animation-iteration-count", "-webkit-animation-name", "-webkit-animation-play-state", - "-webkit-animation-timing-function", "-webkit-appearance", "-webkit-backface-visibility", - "-webkit-background-clip", "-webkit-background-composite", "-webkit-background-origin", "-webkit-background-size", - "-webkit-binding", "-webkit-border-fit", "-webkit-border-horizontal-spacing", "-webkit-border-image", - "-webkit-border-radius", "-webkit-border-vertical-spacing", "-webkit-box-align", "-webkit-box-direction", - "-webkit-box-flex", "-webkit-box-flex-group", "-webkit-box-lines", "-webkit-box-ordinal-group", - "-webkit-box-orient", "-webkit-box-pack", "-webkit-box-reflect", "-webkit-box-shadow", "-webkit-box-sizing", - "-webkit-column-break-after", "-webkit-column-break-before", "-webkit-column-break-inside", "-webkit-column-count", - "-webkit-column-gap", "-webkit-column-rule", "-webkit-column-rule-color", "-webkit-column-rule-style", - "-webkit-column-rule-width", "-webkit-column-width", "-webkit-columns", "-webkit-font-size-delta", - "-webkit-font-smoothing", "-webkit-highlight", "-webkit-line-break", "-webkit-line-clamp", - "-webkit-margin-bottom-collapse", "-webkit-margin-collapse", "-webkit-margin-start", "-webkit-margin-top-collapse", - "-webkit-marquee", "-webkit-marquee-direction", "-webkit-marquee-increment", "-webkit-marquee-repetition", - "-webkit-marquee-speed", "-webkit-marquee-style", "-webkit-mask", "-webkit-mask-attachment", - "-webkit-mask-box-image", "-webkit-mask-clip", "-webkit-mask-composite", "-webkit-mask-image", - "-webkit-mask-origin", "-webkit-mask-position", "-webkit-mask-position-x", "-webkit-mask-position-y", - "-webkit-mask-repeat", "-webkit-mask-repeat-x", "-webkit-mask-repeat-y", "-webkit-mask-size", - "-webkit-match-nearest-mail-blockquote-color", "-webkit-nbsp-mode", "-webkit-padding-start", - "-webkit-perspective", "-webkit-perspective-origin", "-webkit-perspective-origin-x", "-webkit-perspective-origin-y", - "-webkit-rtl-ordering", "-webkit-text-decorations-in-effect", "-webkit-text-fill-color", "-webkit-text-security", - "-webkit-text-size-adjust", "-webkit-text-stroke", "-webkit-text-stroke-color", "-webkit-text-stroke-width", - "-webkit-transform", "-webkit-transform-origin", "-webkit-transform-origin-x", "-webkit-transform-origin-y", - "-webkit-transform-origin-z", "-webkit-transform-style", "-webkit-transition", "-webkit-transition-delay", - "-webkit-transition-duration", "-webkit-transition-property", "-webkit-transition-timing-function", - "-webkit-user-drag", "-webkit-user-modify", "-webkit-user-select", "-webkit-variable-declaration-block" - ].keySet(); - + this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js index 01a8ec2..16b8e8d 100644 --- a/WebCore/inspector/front-end/SourceFrame.js +++ b/WebCore/inspector/front-end/SourceFrame.js @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate, continueToHereDelegate) +WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDelegate, continueToHereDelegate) { this._parentElement = parentElement; @@ -44,7 +44,6 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, remove this._continueToHereDelegate = continueToHereDelegate; this._addBreakpointDelegate = addBreakpointDelegate; - this._removeBreakpointDelegate = removeBreakpointDelegate; this._editDelegate = editDelegate; this._popoverObjectGroup = "popover"; } @@ -55,7 +54,7 @@ WebInspector.SourceFrame.prototype = { { this._visible = visible; this._createViewerIfNeeded(); - + if (visible) { if (this._textViewer && this._scrollTop) this._textViewer.element.scrollTop = this._scrollTop; @@ -99,19 +98,16 @@ WebInspector.SourceFrame.prototype = { addBreakpoint: function(breakpoint) { this.breakpoints.push(breakpoint); - breakpoint.addEventListener("enabled", this._breakpointChanged, this); - breakpoint.addEventListener("disabled", this._breakpointChanged, this); - breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); + breakpoint.addEventListener("removed", this._breakpointRemoved, this); if (this._textViewer) this._addBreakpointToSource(breakpoint); }, - removeBreakpoint: function(breakpoint) + _breakpointRemoved: function(event) { + var breakpoint = event.target; + this.breakpoints.remove(breakpoint); - breakpoint.removeEventListener("enabled", null, this); - breakpoint.removeEventListener("disabled", null, this); - breakpoint.removeEventListener("condition-changed", null, this); if (this._textViewer) this._removeBreakpointFromSource(breakpoint); }, @@ -384,6 +380,9 @@ WebInspector.SourceFrame.prototype = { _addBreakpointToSource: function(breakpoint) { + breakpoint.addEventListener("enable-changed", this._breakpointChanged, this); + breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); + var lineNumber = breakpoint.line - 1; if (lineNumber >= this._textModel.linesCount) return; @@ -402,6 +401,9 @@ WebInspector.SourceFrame.prototype = { _removeBreakpointFromSource: function(breakpoint) { + breakpoint.removeEventListener("enable-changed", null, this); + breakpoint.removeEventListener("condition-changed", null, this); + var lineNumber = breakpoint.line - 1; this._textViewer.beginUpdates(); this._textModel.removeAttribute(lineNumber, "breakpoint"); @@ -431,7 +433,7 @@ WebInspector.SourceFrame.prototype = { // 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._addBreakpointDelegate.bind(this, lineNumber + 1)); - function addConditionalBreakpoint() + function addConditionalBreakpoint() { this._addBreakpointDelegate(lineNumber + 1); var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); @@ -442,7 +444,7 @@ WebInspector.SourceFrame.prototype = { 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"), this._removeBreakpointDelegate.bind(this, breakpoint)); + contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint)); contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), this._editBreakpointCondition.bind(this, breakpoint)); if (breakpoint.enabled) contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; }); @@ -475,7 +477,7 @@ WebInspector.SourceFrame.prototype = { if (event.shiftKey) breakpoint.enabled = !breakpoint.enabled; else - this._removeBreakpointDelegate(breakpoint); + breakpoint.remove(); } else this._addBreakpointDelegate(lineNumber + 1); event.preventDefault(); diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js index 4d03ecd..240dca1 100644 --- a/WebCore/inspector/front-end/SourceView.js +++ b/WebCore/inspector/front-end/SourceView.js @@ -33,7 +33,7 @@ WebInspector.SourceView = function(resource) this.element.addStyleClass("source"); var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script; - this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); resource.addEventListener("finished", this._resourceLoadingFinished, this); this._frameNeedsSetup = true; } @@ -132,11 +132,6 @@ WebInspector.SourceView.prototype = { WebInspector.panels.scripts.toggleBreakpointsClicked(); }, - _removeBreakpoint: function(breakpoint) - { - WebInspector.breakpointManager.removeBreakpoint(breakpoint); - }, - _editLine: function(line, newContent, cancelEditingCallback) { var lines = []; @@ -213,7 +208,7 @@ WebInspector.SourceView.prototype = { this.localContentElement = document.createElement("div"); this.localContentElement.className = "resource-view-content"; this.tabbedPane.appendTab("local", WebInspector.UIString("Local"), this.localContentElement, this.selectLocalContentTab.bind(this)); - this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), null, this._continueToLine.bind(this)); + this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), null, this._continueToLine.bind(this)); } this.localSourceFrame.setContent(mimeType, content, ""); }, diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index 5f5a5ad..1dddde7 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -143,7 +143,7 @@ WebInspector.StylesSidebarPane.prototype = { { if (computedStyle) this._refreshUpdate(node, computedStyle, editedSection); - }; + } if (refresh) WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this)); @@ -160,17 +160,23 @@ WebInspector.StylesSidebarPane.prototype = { this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties); this._refreshSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, editedSection); } + // Trace the computed style. + this.sections[0][0].rebuildComputedTrace(this.sections[0]); }, _rebuildUpdate: function(node, styles) { this.bodyElement.removeChildren(); this._computedStylePane.bodyElement.removeChildren(); + var styleRules = this._rebuildStyleRules(node, styles); var usedProperties = {}; var disabledComputedProperties = {}; this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties); this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, 0); + var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement; + // Trace the computed style. + this.sections[0][0].rebuildComputedTrace(this.sections[0]); for (var i = 0; i < styles.pseudoElements.length; ++i) { var pseudoElementCSSRules = styles.pseudoElements[i]; @@ -189,7 +195,7 @@ WebInspector.StylesSidebarPane.prototype = { usedProperties = {}; disabledComputedProperties = {}; this._markUsedProperties(styleRules, usedProperties, disabledComputedProperties); - this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId); + this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement); } }, @@ -221,7 +227,6 @@ WebInspector.StylesSidebarPane.prototype = { var styleAttributes = {}; for (var name in styles.styleAttributes) { var attrStyle = { style: new WebInspector.CSSStyleDeclaration(styles.styleAttributes[name]), editable: false }; - attrStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", name); attrStyle.selectorText = WebInspector.panels.elements.treeOutline.nodeNameToCorrectCase(node.nodeName) + "[" + name; if (node.getAttribute(name)) attrStyle.selectorText += "=" + node.getAttribute(name); @@ -232,7 +237,6 @@ WebInspector.StylesSidebarPane.prototype = { // Show element's Style Attributes if (styles.inlineStyle && node.nodeType === Node.ELEMENT_NODE) { var inlineStyle = { selectorText: "element.style", style: new WebInspector.CSSStyleDeclaration(styles.inlineStyle), isAttribute: true }; - inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style"); styleRules.push(inlineStyle); } @@ -244,17 +248,6 @@ WebInspector.StylesSidebarPane.prototype = { styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule }); } - // Collect used properties first in order to identify inherited ones. - var userPropertyNames = {}; - for (var i = 0; i < styleRules.length; ++i) { - var styleRule = styleRules[i]; - if (styleRule.computedStyle || styleRule.isStyleSeparator) - continue; - var style = styleRule.style; - for (var j = 0; j < style.length; ++j) - userPropertyNames[style[j]] = true; - } - // Walk the node structure and identify styles with inherited properties. var parentStyles = styles.parent; var parentNode = node.parentNode; @@ -271,7 +264,6 @@ WebInspector.StylesSidebarPane.prototype = { if (parentStyles.inlineStyle) { if (this._containsInherited(parentStyles.inlineStyle)) { var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: new WebInspector.CSSStyleDeclaration(parentStyles.inlineStyle), isAttribute: true, isInherited: true }; - inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style"); if (!separatorInserted) { insertInheritedNodeSeparator(parentNode); separatorInserted = true; @@ -395,14 +387,18 @@ WebInspector.StylesSidebarPane.prototype = { for (var i = 0; i < styleRules.length; ++i) { var styleRule = styleRules[i]; var section = styleRule.section; - if (styleRule.computedStyle) - section.disabledComputedProperties = disabledComputedProperties; - section._usedProperties = (styleRule.usedProperties || usedProperties); - section.update((section === editedSection) || styleRule.computedStyle); + if (styleRule.computedStyle) { + section._disabledComputedProperties = disabledComputedProperties; + section._usedProperties = usedProperties; + section.update(); + } else { + section._usedProperties = styleRule.usedProperties; + section.update(section === editedSection); + } } }, - _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId) + _rebuildSectionsForStyleRules: function(styleRules, usedProperties, disabledComputedProperties, pseudoId, anchorElement) { // Make a property section for each style rule. var sections = []; @@ -416,6 +412,8 @@ WebInspector.StylesSidebarPane.prototype = { var link = WebInspector.panels.elements.linkifyNodeReference(styleRule.node); separatorElement.appendChild(document.createTextNode(WebInspector.UIString("Inherited from") + " ")); separatorElement.appendChild(link); + if (!sections.inheritedPropertiesSeparatorElement) + sections.inheritedPropertiesSeparatorElement = separatorElement; } else if ("pseudoId" in styleRule) { var pseudoName = WebInspector.StylesSidebarPane.PseudoIdNames[styleRule.pseudoId]; if (pseudoName) @@ -424,7 +422,7 @@ WebInspector.StylesSidebarPane.prototype = { separatorElement.textContent = WebInspector.UIString("Pseudo element"); } else separatorElement.textContent = styleRule.text; - this.bodyElement.appendChild(separatorElement); + this.bodyElement.insertBefore(separatorElement, anchorElement); lastWasSeparator = true; continue; } @@ -435,9 +433,10 @@ WebInspector.StylesSidebarPane.prototype = { if (typeof editable === "undefined") editable = true; - var section = new WebInspector.StylePropertiesSection(styleRule, styleRule.subtitle, styleRule.computedStyle, (styleRule.usedProperties || usedProperties), editable, styleRule.isInherited, lastWasSeparator); if (computedStyle) - section.disabledComputedProperties = disabledComputedProperties; + var section = new WebInspector.ComputedStylePropertiesSection(styleRule, usedProperties, disabledComputedProperties, styleRules); + else + var section = new WebInspector.StylePropertiesSection(styleRule, editable, styleRule.isInherited, lastWasSeparator); section.pane = this; section.expanded = true; @@ -445,7 +444,7 @@ WebInspector.StylesSidebarPane.prototype = { this._computedStylePane.bodyElement.appendChild(section.element); lastWasSeparator = true; } else { - this.bodyElement.appendChild(section.element); + this.bodyElement.insertBefore(section.element, anchorElement); lastWasSeparator = false; } sections.push(section); @@ -603,7 +602,7 @@ WebInspector.ComputedStyleSidebarPane = function() WebInspector.ComputedStyleSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; -WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyle, usedProperties, editable, isInherited, isFirstSection) +WebInspector.StylePropertiesSection = function(styleRule, editable, isInherited, isFirstSection) { WebInspector.PropertiesSection.call(this, ""); this.element.className = "styles-section monospace" + (isFirstSection ? " first-styles-section" : ""); @@ -612,23 +611,20 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl this._selectorElement.textContent = styleRule.selectorText; this.titleElement.appendChild(this._selectorElement); - if (!computedStyle) { - var openBrace = document.createElement("span"); - openBrace.textContent = " {"; - this.titleElement.appendChild(openBrace); + var openBrace = document.createElement("span"); + openBrace.textContent = " {"; + this.titleElement.appendChild(openBrace); - var closeBrace = document.createElement("div"); - closeBrace.textContent = "}"; - this.element.appendChild(closeBrace); - } + var closeBrace = document.createElement("div"); + closeBrace.textContent = "}"; + this.element.appendChild(closeBrace); this._selectorElement.addEventListener("dblclick", this._handleSelectorDoubleClick.bind(this), false); this.element.addEventListener("dblclick", this._handleEmptySpaceDoubleClick.bind(this), false); this.styleRule = styleRule; this.rule = this.styleRule.rule; - this.computedStyle = computedStyle; - this.editable = (editable && !computedStyle); + this.editable = editable; this.isInherited = isInherited; // Prevent editing the user agent and user rules. @@ -639,58 +635,45 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl if (isUserAgent || isUser) this.editable = false; - this._usedProperties = usedProperties; + this._usedProperties = styleRule.usedProperties; if (this.rule) this.titleElement.addStyleClass("styles-selector"); - if (computedStyle) { - this.element.addStyleClass("computed-style"); - this.headerElement.addStyleClass("hidden"); - } else { - if (!subtitle) { - function linkifyUncopyable(url, line) - { - var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1); - link.setAttribute("data-uncopyable", link.textContent); - link.textContent = ""; - return link; - } - - if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href) - this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.parentStyleSheet.href, this.rule.sourceLine)); - else if (isUserAgent) - subtitle = WebInspector.UIString("user agent stylesheet"); - else if (isUser) - subtitle = WebInspector.UIString("user stylesheet"); - else if (isViaInspector) - subtitle = WebInspector.UIString("via inspector"); - else - this.subtitleElement.appendChild(linkifyUncopyable(this.rule.documentURL, this.rule.sourceLine)); - } - if (isInherited) - this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style. - if (subtitle) - this.subtitle = subtitle; + function linkifyUncopyable(url, line) + { + var link = WebInspector.linkifyResourceAsNode(url, "resources", line + 1); + link.setAttribute("data-uncopyable", link.textContent); + link.textContent = ""; + return link; } + var subtitle = ""; + if (this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.href) + this.subtitleElement.appendChild(linkifyUncopyable(this.styleRule.parentStyleSheet.href, this.rule.sourceLine)); + else if (isUserAgent) + subtitle = WebInspector.UIString("user agent stylesheet"); + else if (isUser) + subtitle = WebInspector.UIString("user stylesheet"); + else if (isViaInspector) + subtitle = WebInspector.UIString("via inspector"); + else if (this.rule && this.rule.documentURL) + this.subtitleElement.appendChild(linkifyUncopyable(this.rule.documentURL, this.rule.sourceLine)); + + if (isInherited) + this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style. + if (subtitle) + this.subtitle = subtitle; + this.identifier = styleRule.selectorText; if (this.subtitle) this.identifier += ":" + this.subtitle; + + if (!this.editable) + this.element.addStyleClass("read-only"); } WebInspector.StylePropertiesSection.prototype = { - get usedProperties() - { - return this._usedProperties || {}; - }, - - set usedProperties(x) - { - this._usedProperties = x; - this.update(); - }, - collapse: function(dontRememberState) { // Overriding with empty body. @@ -703,17 +686,12 @@ WebInspector.StylePropertiesSection.prototype = { // Render truly inherited properties with black, i.e. return them as non-inherited. return !(property in WebInspector.StylesSidebarPane.InheritedProperties); } - - if (!this.computedStyle || !this._usedProperties || this.noAffect) - return false; - // These properties should always show for Computed Style. - var alwaysShowComputedProperties = { "display": true, "height": true, "width": true }; - return !(property in this.usedProperties) && !(property in alwaysShowComputedProperties) && !(property in this.disabledComputedProperties); + return false; }, isPropertyOverloaded: function(property, shorthand) { - if (this.computedStyle || !this._usedProperties || this.noAffect) + if (!this._usedProperties || this.noAffect) return false; if (this.isInherited && !(property in WebInspector.StylesSidebarPane.InheritedProperties)) { @@ -721,7 +699,7 @@ WebInspector.StylePropertiesSection.prototype = { return false; } - var used = (property in this.usedProperties); + var used = (property in this._usedProperties); if (used || !shorthand) return !used; @@ -730,16 +708,23 @@ WebInspector.StylePropertiesSection.prototype = { var longhandProperties = this.styleRule.style.getLonghandProperties(property); for (var j = 0; j < longhandProperties.length; ++j) { var individualProperty = longhandProperties[j]; - if (individualProperty in this.usedProperties) + if (individualProperty in this._usedProperties) return false; } return true; }, + isPropertyDisabled: function(property) + { + if (!this.styleRule.style.__disabledPropertyValues) + return false; + return property in this.styleRule.style.__disabledPropertyValues; + }, + update: function(full) { - if (full || this.computedStyle) { + if (full) { this.propertiesTreeOutline.removeChildren(); this.populated = false; } else { @@ -749,7 +734,6 @@ WebInspector.StylePropertiesSection.prototype = { child = child.traverseNextTreeElement(false, null, true); } } - this.afterUpdate(); }, @@ -768,21 +752,18 @@ WebInspector.StylePropertiesSection.prototype = { var foundShorthands = {}; var disabledProperties = style.__disabledPropertyValues || {}; - var uniqueProperties = []; + this.uniqueProperties = []; for (var i = 0; i < style.length; ++i) - uniqueProperties.push(style[i]); + this.uniqueProperties.push(style[i]); for (var name in disabledProperties) - uniqueProperties.push(name); + this.uniqueProperties.push(name); - uniqueProperties.sort(); + this.uniqueProperties.sort(); - for (var i = 0; i < uniqueProperties.length; ++i) { - var name = uniqueProperties[i]; + for (var i = 0; i < this.uniqueProperties.length; ++i) { + var name = this.uniqueProperties[i]; var disabled = name in disabledProperties; - if (!disabled && this.disabledComputedProperties && !(name in this.usedProperties) && name in this.disabledComputedProperties) - disabled = true; - var shorthand = !disabled ? style.getPropertyShorthand(name) : null; if (shorthand && shorthand in foundShorthands) @@ -924,10 +905,102 @@ WebInspector.StylePropertiesSection.prototype = { WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype; -WebInspector.BlankStylePropertiesSection = function(defaultSelectorText) +WebInspector.ComputedStylePropertiesSection = function(styleRule, usedProperties, disabledComputedProperties) { - WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, "", false, {}, false); + WebInspector.PropertiesSection.call(this, ""); + this.headerElement.addStyleClass("hidden"); + this.element.className = "styles-section monospace first-styles-section read-only computed-style"; + this.styleRule = styleRule; + this._usedProperties = usedProperties; + this._disabledComputedProperties = disabledComputedProperties; + this._alwaysShowComputedProperties = { "display": true, "height": true, "width": true }; + this.computedStyle = true; + this._propertyTreeElements = {}; + this._expandedPropertyNames = {}; +} + +WebInspector.ComputedStylePropertiesSection.prototype = { + collapse: function(dontRememberState) + { + // Overriding with empty body. + }, + + _isPropertyInherited: function(property) + { + return !(property in this._usedProperties) && !(property in this._alwaysShowComputedProperties) && !(property in this._disabledComputedProperties); + }, + + update: function() + { + this._expandedPropertyNames = {}; + for (var name in this._propertyTreeElements) { + if (this._propertyTreeElements[name].expanded) + this._expandedPropertyNames[name] = true; + } + this._propertyTreeElements = {}; + this.propertiesTreeOutline.removeChildren(); + this.populated = false; + }, + + onpopulate: function() + { + var style = this.styleRule.style; + var uniqueProperties = []; + for (var i = 0; i < style.length; ++i) + uniqueProperties.push(style[i]); + uniqueProperties.sort(); + this._propertyTreeElements = {}; + for (var i = 0; i < uniqueProperties.length; ++i) { + var name = uniqueProperties[i]; + var inherited = this._isPropertyInherited(name); + var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, name, false, inherited, false, false); + this.propertiesTreeOutline.appendChild(item); + this._propertyTreeElements[name] = item; + } + }, + + rebuildComputedTrace: function(sections) + { + for (var i = 0; i < sections.length; ++i) { + var section = sections[i]; + if (section.computedStyle || section instanceof WebInspector.BlankStylePropertiesSection) + continue; + + for (var j = 0; j < section.uniqueProperties.length; ++j) { + var name = section.uniqueProperties[j]; + if (section.isPropertyDisabled(name)) + continue; + if (section.isInherited && !(name in WebInspector.StylesSidebarPane.InheritedProperties)) + continue; + + var treeElement = this._propertyTreeElements[name]; + if (treeElement) { + var selectorText = section.styleRule.selectorText; + var value = section.styleRule.style.getPropertyValue(name); + var title = "<span style='color: gray'>" + selectorText + "</span> - " + value; + var subtitle = " <span style='float:right'>" + section.subtitleElement.innerHTML + "</span>"; + var childElement = new TreeElement(title + subtitle, null, false); + treeElement.appendChild(childElement); + if (section.isPropertyOverloaded(name)) + childElement.listItemElement.addStyleClass("overloaded"); + } + } + } + + // Restore expanded state after update. + for (var name in this._expandedPropertyNames) { + if (name in this._propertyTreeElements) + this._propertyTreeElements[name].expand(); + } + } +} + +WebInspector.ComputedStylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype; + +WebInspector.BlankStylePropertiesSection = function(defaultSelectorText) +{ + WebInspector.StylePropertiesSection.call(this, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, true, false, false); this.element.addStyleClass("blank-section"); } @@ -966,13 +1039,9 @@ WebInspector.BlankStylePropertiesSection.prototype = { makeNormal: function(styleRule) { this.element.removeStyleClass("blank-section"); - this.styleRule = styleRule; this.rule = styleRule.rule; - this.computedStyle = false; - this.editable = true; this.identifier = styleRule.selectorText + ":via inspector"; - this.__proto__ = WebInspector.StylePropertiesSection.prototype; } } diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 8c4a2ea..4319816 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -4079,6 +4079,10 @@ a.worker-item { border-top: 1px solid rgb(191, 191, 191); } +.styles-section.read-only { + background-color: rgb(240, 240, 240); +} + .styles-section .header { white-space: nowrap; -webkit-background-origin: padding; @@ -4103,7 +4107,7 @@ a.worker-item { color: inherit; } -.styles-section .subtitle::before, .styles-section .subtitle a::before { +.styles-section a::before { content: attr(data-uncopyable); } diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index fa57916..db89e20 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -197,6 +197,28 @@ var WebInspector = { } }, + createJSBreakpointsSidebarPane: function() + { + var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints")); + function breakpointAdded(event) + { + pane.addBreakpoint(new WebInspector.JSBreakpointItem(event.data)); + } + WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded); + return pane; + }, + + createDOMBreakpointsSidebarPane: function() + { + var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints")); + function breakpointAdded(event) + { + pane.addBreakpoint(new WebInspector.DOMBreakpointItem(event.data)); + } + WebInspector.domBreakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded); + return pane; + }, + _createPanels: function() { var hiddenPanels = (InspectorFrontendHost.hiddenPanels() || "").split(','); @@ -469,8 +491,9 @@ WebInspector.doLoadedDone = function() var port = WebInspector.port; document.body.addStyleClass("port-" + port); - this.applicationSettings = new WebInspector.Settings(false); - this.sessionSettings = new WebInspector.Settings(true); + InspectorFrontendHost.loaded(); + WebInspector.Settings.initialize(); + this._registerShortcuts(); // set order of some sections explicitly @@ -496,6 +519,7 @@ WebInspector.doLoadedDone = function() }; this.breakpointManager = new WebInspector.BreakpointManager(); + this.domBreakpointManager = new WebInspector.DOMBreakpointManager(); this.cssModel = new WebInspector.CSSStyleModel(); this.panels = {}; @@ -556,7 +580,10 @@ WebInspector.doLoadedDone = function() this.extensionServer.initExtensions(); - InspectorFrontendHost.loaded(); + InspectorBackend.populateScriptObjects(); + + // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available. + InspectorBackend.getSupportedCSSProperties(WebInspector.Callback.wrap(WebInspector.CSSCompletions._load)); } WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem) @@ -589,20 +616,12 @@ var windowLoaded = function() window.addEventListener("load", windowLoaded, false); -WebInspector.dispatch = function() { - var methodName = arguments[0]; - var parameters = Array.prototype.slice.call(arguments, 1); - +WebInspector.dispatch = function(message) { // We'd like to enforce asynchronous interaction between the inspector controller and the frontend. // This is important to LayoutTests. function delayDispatch() { - if (!(methodName in WebInspector)) { - console.error("Attempted to dispatch unimplemented WebInspector method: %s", methodName); - return; - } - - WebInspector[methodName].apply(WebInspector, parameters); + WebInspector_syncDispatch(message); WebInspector.pendingDispatches--; } WebInspector.pendingDispatches++; @@ -612,21 +631,41 @@ WebInspector.dispatch = function() { // This function is purposely put into the global scope for easy access. WebInspector_syncDispatch = function(message) { - var args = JSON.parse(message); - var methodName = args[0]; - var parameters = args.slice(1); - WebInspector[methodName].apply(WebInspector, parameters); + var messageObject = (typeof message === "string") ? JSON.parse(message) : message; + if (messageObject.type === "response" && !messageObject.success) { + WebInspector.removeResponseCallbackEntry(messageObject.seq) + WebInspector.reportProtocolError(messageObject); + return; + } + + var arguments = []; + if (messageObject.data) + for (var key in messageObject.data) + arguments.push(messageObject.data[key]); + + if (messageObject.type === "event") { + if (!messageObject.event in WebInspector) { + console.error("Attempted to dispatch unimplemented WebInspector method: %s", messageObject.event); + return; + } + WebInspector[messageObject.event].apply(WebInspector, arguments); + } + + if (messageObject.type === "response") + WebInspector.processResponse(messageObject.seq, arguments); } -WebInspector.dispatchMessageFromBackend = function(arguments) +WebInspector.dispatchMessageFromBackend = function(messageObject) { - WebInspector.dispatch.apply(this, arguments); + WebInspector.dispatch(messageObject); } -WebInspector.reportProtocolError = function(callId, methodName, errorText) +WebInspector.reportProtocolError = function(messageObject) { - WebInspector.log("InspectorBackend." + methodName + " failed with error text: '" + errorText + "'"); - WebInspector.removeResponseCallbackEntry(callId); + console.error("Error: InspectorBackend." + messageObject.command + " failed."); + for (var error in messageObject.errors) + console.error(" " + error); + WebInspector.removeResponseCallbackEntry(messageObject.seq); } WebInspector.windowResize = function(event) @@ -702,13 +741,13 @@ WebInspector.documentClick = function(event) function followLink() { // FIXME: support webkit-html-external-link links here. - if (WebInspector.canShowSourceLine(anchor.href, anchor.lineNumber, anchor.preferredPanel)) { + if (WebInspector.canShowSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel"))) { if (anchor.hasStyleClass("webkit-html-external-link")) { anchor.removeStyleClass("webkit-html-external-link"); anchor.addStyleClass("webkit-html-resource-link"); } - WebInspector.showSourceLine(anchor.href, anchor.lineNumber, anchor.preferredPanel); + WebInspector.showSourceLine(anchor.href, anchor.getAttribute("line_number"), anchor.getAttribute("preferred_panel")); return; } @@ -1412,15 +1451,6 @@ WebInspector.resumedScript = function() this.panels.scripts.debuggerResumed(); } -WebInspector.populateInterface = function() -{ - for (var panelName in this.panels) { - var panel = this.panels[panelName]; - if ("populateInterface" in panel) - panel.populateInterface(); - } -} - WebInspector.reset = function() { for (var panelName in this.panels) { @@ -1788,8 +1818,8 @@ WebInspector.linkifyResourceAsNode = function(url, preferredPanel, lineNumber, c if (lineNumber) linkText += ":" + lineNumber; var node = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText); - node.lineNumber = lineNumber; - node.preferredPanel = preferredPanel; + node.setAttribute("line_number", lineNumber); + node.setAttribute("preferred_panel", preferredPanel); return node; } |