diff options
Diffstat (limited to 'WebCore/inspector')
45 files changed, 1045 insertions, 941 deletions
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm index 9d0af53..cd9052a 100644 --- a/WebCore/inspector/CodeGeneratorInspector.pm +++ b/WebCore/inspector/CodeGeneratorInspector.pm @@ -47,30 +47,27 @@ $typeTransform{"PassRefPtr"} = { }; $typeTransform{"Object"} = { "param" => "PassRefPtr<InspectorObject>", - "retVal" => "PassRefPtr<InspectorObject>", "variable" => "RefPtr<InspectorObject>", "defaultValue" => "InspectorObject::create()", "forward" => "InspectorObject", "header" => "InspectorValues.h", - "accessorSuffix" => "" + "accessorSuffix" => "Object" }; $typeTransform{"Array"} = { "param" => "PassRefPtr<InspectorArray>", - "retVal" => "PassRefPtr<InspectorArray>", "variable" => "RefPtr<InspectorArray>", "defaultValue" => "InspectorArray::create()", "forward" => "InspectorArray", "header" => "InspectorValues.h", - "accessorSuffix" => "" + "accessorSuffix" => "Array" }; $typeTransform{"Value"} = { "param" => "PassRefPtr<InspectorValue>", - "retVal" => "PassRefPtr<InspectorValue>", "variable" => "RefPtr<InspectorValue>", "defaultValue" => "InspectorValue::null()", "forward" => "InspectorValue", "header" => "InspectorValues.h", - "accessorSuffix" => "" + "accessorSuffix" => "Value" }; $typeTransform{"String"} = { "param" => "const String&", @@ -120,7 +117,6 @@ $typeTransform{"boolean"} = { "accessorSuffix" => "Bool" }; $typeTransform{"void"} = { - "retVal" => "void", "forward" => "", "header" => "" }; @@ -142,17 +138,23 @@ my $verbose; my $namespace; my $backendClassName; +my $backendJSStubName; my %backendTypes; my %backendMethods; my @backendMethodsImpl; my $backendConstructor; +my @backendConstantDeclarations; +my @backendConstantDefinitions; my $backendFooter; +my @backendStubJS; my $frontendClassName; my %frontendTypes; my %frontendMethods; my @frontendMethodsImpl; my $frontendConstructor; +my @frontendConstantDeclarations; +my @frontendConstantDefinitions; my $frontendFooter; my $callId = new domSignature(); # it is just structure for describing parameters from IDLStructure.pm. @@ -204,11 +206,12 @@ sub GenerateInterface $frontendTypes{"PassRefPtr"} = 1; $backendClassName = $className . "BackendDispatcher"; + $backendJSStubName = $className . "BackendStub"; my @backendHead; push(@backendHead, " ${backendClassName}(InspectorController* inspectorController) : m_inspectorController(inspectorController) { }"); push(@backendHead, " void reportProtocolError(const long callId, const String& method, const String& errorText) const;"); push(@backendHead, " void dispatch(const String& message);"); - push(@backendHead, "private:"); + push(@backendHead, " static bool getCommandName(const String& message, String* result);"); $backendConstructor = join("\n", @backendHead); $backendFooter = " InspectorController* m_inspectorController;"; $backendTypes{"Controller"} = 1; @@ -216,8 +219,13 @@ sub GenerateInterface $backendTypes{"PassRefPtr"} = 1; $backendTypes{"Array"} = 1; - generateBackendPrivateFunctions(); + push(@backendMethodsImpl, generateBackendPrivateFunctions()); + push(@backendMethodsImpl, generateBackendMessageParser()); generateFunctions($interface); + + # Make dispatcher methods private on the backend. + push(@backendConstantDeclarations, ""); + push(@backendConstantDeclarations, "private:"); } sub generateFunctions @@ -225,23 +233,25 @@ sub generateFunctions my $interface = shift; foreach my $function (@{$interface->functions}) { - generateFrontendFunction($function); - generateBackendFunction($function); + if ($function->signature->extendedAttributes->{"notify"}) { + generateFrontendFunction($function); + } else { + generateBackendFunction($function); + } } push(@backendMethodsImpl, generateBackendDispatcher()); push(@backendMethodsImpl, generateBackendReportProtocolError()); + + @backendStubJS = generateBackendStubJS($interface); } sub generateFrontendFunction { my $function = shift; - my $notify = $function->signature->extendedAttributes->{"notify"}; - return if !$notify; - my $functionName = $notify ? $function->signature->name : "did" . ucfirst($function->signature->name); + my $functionName = $function->signature->name; my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface. - unshift(@argsFiltered, $callId) if !$notify; # Add callId as the first argument for all frontend did* methods. 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); @@ -254,7 +264,7 @@ sub generateFrontendFunction push(@function, "void ${frontendClassName}::${functionName}(${arguments})"); push(@function, "{"); push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();"); - push(@function, " arguments->pushString(\"" . ($notify ? $functionName : "processResponse") . "\");"); + push(@function, " arguments->pushString(\"$functionName\");"); push(@function, @pushArguments); push(@function, " m_inspectorClient->sendMessageToFrontend(arguments->toJSONString());"); @@ -277,16 +287,18 @@ static String formatWrongArgumentTypeMessage(unsigned position, const char* name return String::format("Failed to convert parameter %d (%s) to %s", position, name, expectedType); } EOF - push(@backendMethodsImpl, $privateFunctions); + return split("\n", $privateFunctions); } sub generateBackendFunction { my $function = shift; - return if $function->signature->extendedAttributes->{"notify"}; my $functionName = $function->signature->name; + push(@backendConstantDeclarations, " static const char* ${functionName}Cmd;"); + 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 @outArgs = grep($_->direction eq "out", @{$function->parameters}); @@ -298,7 +310,6 @@ sub generateBackendFunction my @function; push(@function, "void ${backendClassName}::${functionName}(PassRefPtr<InspectorArray> args)"); push(@function, "{"); - push(@function, " DEFINE_STATIC_LOCAL(String, backendFunctionName, (\"$functionName\"));"); push(@function, " long callId = 0;"); push(@function, ""); @@ -306,7 +317,7 @@ sub generateBackendFunction my $expectedParametersCountWithMethodName = scalar(@inArgs) + 1; push(@function, " if (args->length() != $expectedParametersCountWithMethodName) {"); push(@function, " ASSERT_NOT_REACHED();"); - push(@function, " reportProtocolError(callId, backendFunctionName, formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount));"); + push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount));"); push(@function, " return;"); push(@function, " }"); push(@function, ""); @@ -314,11 +325,11 @@ sub generateBackendFunction my $i = 1; # zero element is the method name. foreach my $parameter (@inArgs) { my $type = $parameter->type; - my $argumentType = $typeTransform{$type}->{$typeTransform{$type}->{"retVal"} ? "retVal" : "variable"}; + 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 . ")) {"); push(@function, " ASSERT_NOT_REACHED();"); - push(@function, " reportProtocolError(callId, backendFunctionName, formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$type\"));"); + push(@function, " reportProtocolError(callId, ${functionName}Cmd, formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$type\"));"); push(@function, " return;"); push(@function, " }"); push(@function, ""); @@ -329,7 +340,7 @@ sub generateBackendFunction my $handlerAccessor = $typeTransform{$handler}->{"handlerAccessor"}; $backendTypes{$handler} = 1; push(@function, " if (!$handlerAccessor) {"); - push(@function, " reportProtocolError(callId, backendFunctionName, \"Error: $handler handler is not available.\");"); + push(@function, " reportProtocolError(callId, ${functionName}Cmd, \"Error: $handler handler is not available.\");"); push(@function, " return;"); push(@function, " }"); push(@function, ""); @@ -383,7 +394,7 @@ sub generateBackendDispatcher { my @body; my @methods = map($backendMethods{$_}, keys %backendMethods); - my @mapEntries = map(" dispatchMap.add(\"$_\", &${backendClassName}::$_);", @methods); + my @mapEntries = map(" dispatchMap.add(${_}Cmd, &${backendClassName}::$_);", @methods); my $mapEntries = join("\n", @mapEntries); my $backendDispatcherBody = << "EOF"; @@ -436,16 +447,72 @@ EOF return split("\n", $backendDispatcherBody); } +sub generateBackendMessageParser +{ + my $messageParserBody = << "EOF"; +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) + return false; + + if (!array->length()) + return false; + return array->get(0)->asString(result); +} +EOF + return split("\n", $messageParserBody); +} + +sub generateBackendStubJS +{ + my $interface = shift; + my @backendFunctions = grep(!$_->signature->extendedAttributes->{"notify"}, @{$interface->functions}); + my @JSStubs = map(" this._registerDelegate(\"" . $_->signature->name . "\");", @backendFunctions); + + my $JSStubs = join("\n", @JSStubs); + my $inspectorBackendStubJS = << "EOF"; +$licenseTemplate + +WebInspector.InspectorBackendStub = function() +{ +$JSStubs +} + +WebInspector.InspectorBackendStub.prototype = { + _registerDelegate: function(methodName) + { + this[methodName] = this.sendMessageToBackend.bind(this, methodName); + }, + + sendMessageToBackend: function() + { + var message = JSON.stringify(Array.prototype.slice.call(arguments)); + InspectorFrontendHost.sendMessageToBackend(message); + } +} + +InspectorBackend = new WebInspector.InspectorBackendStub(); + +EOF + return split("\n", $inspectorBackendStubJS); +} + sub generateHeader { my $className = shift; my $types = shift; my $constructor = shift; + my $constants = shift; my $methods = shift; my $footer = shift; my $forwardHeaders = join("\n", sort(map("#include <" . $typeTransform{$_}->{"forwardHeader"} . ">", grep($typeTransform{$_}->{"forwardHeader"}, keys %{$types})))); my $forwardDeclarations = join("\n", sort(map("class " . $typeTransform{$_}->{"forward"} . ";", grep($typeTransform{$_}->{"forward"}, keys %{$types})))); + my $constantDeclarations = join("\n", @{$constants}); my $methodsDeclarations = join("\n", keys %{$methods}); my $headerBody = << "EOF"; @@ -465,6 +532,7 @@ class $className { public: $constructor +$constantDeclarations $methodsDeclarations private: @@ -482,6 +550,7 @@ sub generateSource { my $className = shift; my $types = shift; + my $constants = shift; my $methods = shift; my @sourceContent = split("\r", $licenseTemplate); @@ -499,6 +568,8 @@ sub generateSource push(@sourceContent, ""); push(@sourceContent, "namespace $namespace {"); push(@sourceContent, ""); + push (@sourceContent, join("\n", @{$constants})); + push(@sourceContent, ""); push(@sourceContent, @{$methods}); push(@sourceContent, ""); push(@sourceContent, "} // namespace $namespace"); @@ -513,24 +584,29 @@ sub finish my $object = shift; open(my $SOURCE, ">$outputDir/$frontendClassName.cpp") || die "Couldn't open file $outputDir/$frontendClassName.cpp"; - print $SOURCE join("\n", generateSource($frontendClassName, \%frontendTypes, \@frontendMethodsImpl)); + print $SOURCE join("\n", generateSource($frontendClassName, \%frontendTypes, \@frontendConstantDefinitions, \@frontendMethodsImpl)); close($SOURCE); undef($SOURCE); open(my $HEADER, ">$outputHeadersDir/$frontendClassName.h") || die "Couldn't open file $outputHeadersDir/$frontendClassName.h"; - print $HEADER generateHeader($frontendClassName, \%frontendTypes, $frontendConstructor, \%frontendMethods, $frontendFooter); + print $HEADER generateHeader($frontendClassName, \%frontendTypes, $frontendConstructor, \@frontendConstantDeclarations, \%frontendMethods, $frontendFooter); close($HEADER); undef($HEADER); open($SOURCE, ">$outputDir/$backendClassName.cpp") || die "Couldn't open file $outputDir/$backendClassName.cpp"; - print $SOURCE join("\n", generateSource($backendClassName, \%backendTypes, \@backendMethodsImpl)); + print $SOURCE join("\n", generateSource($backendClassName, \%backendTypes, \@backendConstantDefinitions, \@backendMethodsImpl)); close($SOURCE); undef($SOURCE); open($HEADER, ">$outputHeadersDir/$backendClassName.h") || die "Couldn't open file $outputHeadersDir/$backendClassName.h"; - print $HEADER join("\n", generateHeader($backendClassName, \%backendTypes, $backendConstructor, \%backendMethods, $backendFooter)); + print $HEADER join("\n", generateHeader($backendClassName, \%backendTypes, $backendConstructor, \@backendConstantDeclarations, \%backendMethods, $backendFooter)); close($HEADER); undef($HEADER); + + open(my $JS_STUB, ">$outputDir/$backendJSStubName.js") || die "Couldn't open file $outputDir/$backendJSStubName.js"; + print $JS_STUB join("\n", @backendStubJS); + close($JS_STUB); + undef($JS_STUB); } 1; diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp index 059dea4..6f19d2a 100644 --- a/WebCore/inspector/ConsoleMessage.cpp +++ b/WebCore/inspector/ConsoleMessage.cpp @@ -126,23 +126,25 @@ void ConsoleMessage::addToFrontend(RemoteInspectorFrontend* frontend, InjectedSc jsonObj->setNumber("repeatCount", static_cast<int>(m_repeatCount)); jsonObj->setString("message", m_message); if (!m_arguments.isEmpty()) { - RefPtr<InspectorArray> jsonArgs = InspectorArray::create(); InjectedScript injectedScript = injectedScriptHost->injectedScriptFor(m_scriptState.get()); - for (unsigned i = 0; i < m_arguments.size(); ++i) { - RefPtr<InspectorValue> inspectorValue = injectedScript.wrapForConsole(m_arguments[i]); - if (!inspectorValue) { - ASSERT_NOT_REACHED(); - return; + if (!injectedScript.hasNoValue()) { + RefPtr<InspectorArray> jsonArgs = InspectorArray::create(); + for (unsigned i = 0; i < m_arguments.size(); ++i) { + RefPtr<InspectorValue> inspectorValue = injectedScript.wrapForConsole(m_arguments[i]); + if (!inspectorValue) { + ASSERT_NOT_REACHED(); + return; + } + jsonArgs->pushValue(inspectorValue); } - jsonArgs->push(inspectorValue); + jsonObj->setArray("parameters", jsonArgs); } - jsonObj->set("parameters", jsonArgs); } if (!m_frames.isEmpty()) { RefPtr<InspectorArray> frames = InspectorArray::create(); for (unsigned i = 0; i < m_frames.size(); i++) - frames->push(m_frames.at(i).buildInspectorObject()); - jsonObj->set("stackTrace", frames); + frames->pushObject(m_frames.at(i).buildInspectorObject()); + jsonObj->setArray("stackTrace", frames); } frontend->addConsoleMessage(jsonObj); } diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl index 9d3d102..1c66b59 100644 --- a/WebCore/inspector/Inspector.idl +++ b/WebCore/inspector/Inspector.idl @@ -67,6 +67,7 @@ module core { [notify] void updateConsoleMessageRepeatCount(out unsigned long count); [notify] void updateFocusedNode(out long nodeId); [notify] void updateResource(out Value resource); + [notify] void consoleMessagesCleared(); #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER [notify] void addProfileHeader(out Object header); @@ -176,10 +177,10 @@ module core { [handler=DOM] void searchCanceled(); [handler=DOM] void pushNodeByPathToFrontend(in long callId, in String path, out long nodeId); - [handler=Backend] void clearConsoleMessages(in long callId); - + [handler=Controller] void clearConsoleMessages(); [handler=Controller] void highlightDOMNode(in long nodeId); [handler=Controller] void hideDOMNodeHighlight(); + [handler=Controller] void openInInspectedWindow(in String url); [handler=DOM] void getStyles(in long callId, in long nodeId, in boolean authOnly, out Value styles); [handler=DOM] void getAllStyles(in long callId, out Array styles); @@ -216,6 +217,5 @@ module core { [handler=Controller] void setDOMStorageItem(in long callId, in long storageId, in String key, in String value, out boolean success); [handler=Controller] void removeDOMStorageItem(in long callId, in long storageId, in String key, out boolean success); #endif - }; } diff --git a/WebCore/inspector/InspectorApplicationCacheAgent.cpp b/WebCore/inspector/InspectorApplicationCacheAgent.cpp index b95c0e1..1206184 100644 --- a/WebCore/inspector/InspectorApplicationCacheAgent.cpp +++ b/WebCore/inspector/InspectorApplicationCacheAgent.cpp @@ -82,7 +82,7 @@ PassRefPtr<InspectorObject> InspectorApplicationCacheAgent::buildObjectForApplic value->setString("lastPathComponent", applicationCacheInfo.m_manifest.lastPathComponent()); value->setNumber("creationTime", applicationCacheInfo.m_creationTime); value->setNumber("updateTime", applicationCacheInfo.m_updateTime); - value->set("resources", buildArrayForApplicationCacheResources(applicationCacheResources)); + value->setArray("resources", buildArrayForApplicationCacheResources(applicationCacheResources)); return value; } @@ -93,7 +93,7 @@ PassRefPtr<InspectorArray> InspectorApplicationCacheAgent::buildArrayForApplicat ApplicationCacheHost::ResourceInfoList::const_iterator end = applicationCacheResources.end(); ApplicationCacheHost::ResourceInfoList::const_iterator it = applicationCacheResources.begin(); for (int i = 0; it != end; ++it, i++) - resources->push(buildObjectForApplicationCacheResource(*it)); + resources->pushObject(buildObjectForApplicationCacheResource(*it)); return resources; } diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp index 0a18e1c..f0ed94b 100644 --- a/WebCore/inspector/InspectorBackend.cpp +++ b/WebCore/inspector/InspectorBackend.cpp @@ -106,11 +106,6 @@ void InspectorBackend::dispatchOnInjectedScript(long injectedScriptId, const Str injectedScript.dispatch(methodName, arguments, result, hadException); } -void InspectorBackend::clearConsoleMessages() -{ - m_inspectorController->clearConsoleMessages(); -} - void InspectorBackend::releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup) { m_inspectorController->injectedScriptHost()->releaseWrapperObjectGroup(injectedScriptId, objectGroup); diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h index 63c4a09..27a93eb 100644 --- a/WebCore/inspector/InspectorBackend.h +++ b/WebCore/inspector/InspectorBackend.h @@ -67,7 +67,6 @@ public: void setInjectedScriptSource(const String& source); void dispatchOnInjectedScript(long injectedScriptId, const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException); - void clearConsoleMessages(); // Generic code called from custom implementations. void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup); diff --git a/WebCore/inspector/InspectorCSSStore.h b/WebCore/inspector/InspectorCSSStore.h index 2a05d71..ee435e5 100644 --- a/WebCore/inspector/InspectorCSSStore.h +++ b/WebCore/inspector/InspectorCSSStore.h @@ -29,10 +29,10 @@ #ifndef InspectorCSSStore_h #define InspectorCSSStore_h -#include "StringHash.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefPtr.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp index 0b59617..ac670cb 100644 --- a/WebCore/inspector/InspectorController.cpp +++ b/WebCore/inspector/InspectorController.cpp @@ -24,7 +24,7 @@ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -46,6 +46,7 @@ #include "FloatQuad.h" #include "FloatRect.h" #include "Frame.h" +#include "FrameLoadRequest.h" #include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" @@ -86,6 +87,7 @@ #include "SharedBuffer.h" #include "TextEncoding.h" #include "TextIterator.h" +#include "WindowFeatures.h" #include <wtf/text/CString.h> #include <wtf/CurrentTime.h> #include <wtf/ListHashSet.h> @@ -359,6 +361,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(); } void InspectorController::startGroup(MessageSource source, ScriptCallStack* callStack, bool collapsed) @@ -604,9 +608,12 @@ void InspectorController::releaseFrontendLifetimeAgents() if (m_domAgent) m_domAgent->reset(); m_domAgent.clear(); + +#if ENABLE(DATABASE) if (m_storageAgent) m_storageAgent->clearFrontend(); m_storageAgent.clear(); +#endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) m_applicationCacheAgent.clear(); @@ -1329,7 +1336,7 @@ PassRefPtr<InspectorArray> InspectorController::buildArrayForCookies(ListHashSet ListHashSet<Cookie>::iterator end = cookiesList.end(); ListHashSet<Cookie>::iterator it = cookiesList.begin(); for (int i = 0; it != end; ++it, i++) - cookies->push(buildObjectForCookie(*it)); + cookies->pushObject(buildObjectForCookie(*it)); return cookies; } @@ -1413,7 +1420,7 @@ void InspectorController::getDOMStorageEntries(long storageId, RefPtr<InspectorA RefPtr<InspectorArray> entry = InspectorArray::create(); entry->pushString(name); entry->pushString(value); - (*entries)->push(entry); + (*entries)->pushArray(entry); } } } @@ -1500,7 +1507,7 @@ void InspectorController::getProfileHeaders(RefPtr<InspectorArray>* headers) { ProfilesMap::iterator profilesEnd = m_profiles.end(); for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it) - (*headers)->push(createProfileHeader(*it->second)); + (*headers)->pushObject(createProfileHeader(*it->second)); } void InspectorController::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject) @@ -1508,7 +1515,7 @@ void InspectorController::getProfile(unsigned uid, RefPtr<InspectorObject>* prof ProfilesMap::iterator it = m_profiles.find(uid); if (it != m_profiles.end()) { *profileObject = createProfileHeader(*it->second); - (*profileObject)->set("head", it->second->buildInspectorObjectForHead()); + (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead()); } } @@ -1865,6 +1872,22 @@ void InspectorController::drawNodeHighlight(GraphicsContext& context) const } } +void InspectorController::openInInspectedWindow(const String& url) +{ + ResourceRequest request; + FrameLoadRequest frameRequest(request, "_blank"); + bool created; + Frame* mainFrame = m_inspectedPage->mainFrame(); + WindowFeatures windowFeatures; + Frame* newFrame = WebCore::createWindow(mainFrame, mainFrame, frameRequest, windowFeatures, created); + if (!newFrame) + return; + + newFrame->loader()->setOpener(mainFrame); + newFrame->page()->setOpenedByDOM(); + newFrame->loader()->changeLocation(newFrame->loader()->completeURL(url), "", false, false, true); +} + void InspectorController::count(const String& title, unsigned lineNumber, const String& sourceID) { String identifier = title + String::format("@%s:%d", sourceID.utf8().data(), lineNumber); diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h index faddedb..8d96005 100644 --- a/WebCore/inspector/InspectorController.h +++ b/WebCore/inspector/InspectorController.h @@ -35,13 +35,13 @@ #include "PlatformString.h" #include "ScriptProfile.h" #include "ScriptState.h" -#include "StringHash.h" #include "Timer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/ListHashSet.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> namespace WebCore { @@ -136,7 +136,7 @@ public: void connectFrontend(); void disconnectFrontend(); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, ScriptCallStack*, const String& message = String()); + void addMessageToConsole(MessageSource, MessageType, MessageLevel, ScriptCallStack*, const String& message); void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID); void clearConsoleMessages(); const Vector<OwnPtr<ConsoleMessage> >& consoleMessages() const { return m_consoleMessages; } @@ -212,6 +212,7 @@ public: bool hasFrontend() const { return m_remoteFrontend; } void drawNodeHighlight(GraphicsContext&) const; + void openInInspectedWindow(const String& url); void count(const String& title, unsigned lineNumber, const String& sourceID); @@ -252,6 +253,7 @@ public: void evaluateForTestInFrontend(long testCallId, const String& script); InjectedScript injectedScriptForNodeId(long id); + void addScriptToEvaluateOnLoad(const String& source); void removeAllScriptsToEvaluateOnLoad(); void setInspectorExtensionAPI(const String& source); diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp index 7cf0a82..6243299 100644 --- a/WebCore/inspector/InspectorDOMAgent.cpp +++ b/WebCore/inspector/InspectorDOMAgent.cpp @@ -33,7 +33,6 @@ #if ENABLE(INSPECTOR) -#include "AtomicString.h" #include "CSSComputedStyleDeclaration.h" #include "CSSMutableStyleDeclaration.h" #include "CSSRule.h" @@ -78,6 +77,7 @@ #include <wtf/ListHashSet.h> #include <wtf/OwnPtr.h> #include <wtf/Vector.h> +#include <wtf/text/AtomicString.h> namespace WebCore { @@ -600,7 +600,7 @@ void InspectorDOMAgent::getEventListenersForNode(long nodeId, long* outNodeId, R for (size_t j = 0; j < vector.size(); ++j) { const RegisteredEventListener& listener = vector[j]; if (listener.useCapture) - (*listenersArray)->push(buildObjectForEventListener(listener, info.eventType, info.node)); + (*listenersArray)->pushObject(buildObjectForEventListener(listener, info.eventType, info.node)); } } @@ -611,7 +611,7 @@ void InspectorDOMAgent::getEventListenersForNode(long nodeId, long* outNodeId, R for (size_t j = 0; j < vector.size(); ++j) { const RegisteredEventListener& listener = vector[j]; if (!listener.useCapture) - (*listenersArray)->push(buildObjectForEventListener(listener, info.eventType, info.node)); + (*listenersArray)->pushObject(buildObjectForEventListener(listener, info.eventType, info.node)); } } } @@ -630,7 +630,7 @@ void InspectorDOMAgent::performSearch(const String& whitespaceTrimmedQuery, bool // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result // is sufficient. - int queryLength = whitespaceTrimmedQuery.length(); + unsigned queryLength = whitespaceTrimmedQuery.length(); bool startTagFound = !whitespaceTrimmedQuery.find('<'); bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength; @@ -766,11 +766,11 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForNode(Node* node, in value->setNumber("childNodeCount", nodeCount); RefPtr<InspectorArray> children = buildArrayForContainerChildren(node, depth, nodesMap); if (children->length() > 0) - value->set("children", children.release()); + value->setArray("children", children.release()); if (node->nodeType() == Node::ELEMENT_NODE) { Element* element = static_cast<Element*>(node); - value->set("attributes", buildArrayForElementAttributes(element)); + value->setArray("attributes", buildArrayForElementAttributes(element)); if (node->isFrameOwnerElement()) { HTMLFrameOwnerElement* frameOwner = static_cast<HTMLFrameOwnerElement*>(node); value->setString("documentURL", documentURLString(frameOwner->contentDocument())); @@ -813,7 +813,7 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForContainerChildren(Nod if (innerChildNodeCount(container) == 1) { Node *child = innerFirstChild(container); if (child->nodeType() == Node::TEXT_NODE) - children->push(buildObjectForNode(child, 0, nodesMap)); + children->pushObject(buildObjectForNode(child, 0, nodesMap)); } return children.release(); } else if (depth > 0) { @@ -821,7 +821,7 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForContainerChildren(Nod } for (Node *child = innerFirstChild(container); child; child = innerNextSibling(child)) - children->push(buildObjectForNode(child, depth, nodesMap)); + children->pushObject(buildObjectForNode(child, depth, nodesMap)); return children.release(); } @@ -986,27 +986,27 @@ void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<Inspector RefPtr<InspectorObject> result = InspectorObject::create(); if (element->style()) - result->set("inlineStyle", buildObjectForStyle(element->style(), true)); - result->set("computedStyle", buildObjectForStyle(computedStyleInfo.get(), false)); + result->setObject("inlineStyle", buildObjectForStyle(element->style(), true)); + result->setObject("computedStyle", buildObjectForStyle(computedStyleInfo.get(), false)); CSSStyleSelector* selector = element->ownerDocument()->styleSelector(); RefPtr<CSSRuleList> matchedRules = selector->styleRulesForElement(element, authorOnly); - result->set("matchedCSSRules", buildArrayForCSSRules(node->ownerDocument(), matchedRules.get())); + result->setArray("matchedCSSRules", buildArrayForCSSRules(node->ownerDocument(), matchedRules.get())); - result->set("styleAttributes", buildObjectForAttributeStyles(element)); - result->set("pseudoElements", buildArrayForPseudoElements(element, authorOnly)); + result->setObject("styleAttributes", buildObjectForAttributeStyles(element)); + result->setArray("pseudoElements", buildArrayForPseudoElements(element, authorOnly)); RefPtr<InspectorObject> currentStyle = result; Element* parentElement = element->parentElement(); while (parentElement) { RefPtr<InspectorObject> parentStyle = InspectorObject::create(); - currentStyle->set("parent", parentStyle); + currentStyle->setObject("parent", parentStyle); if (parentElement->style() && parentElement->style()->length()) - parentStyle->set("inlineStyle", buildObjectForStyle(parentElement->style(), true)); + parentStyle->setObject("inlineStyle", buildObjectForStyle(parentElement->style(), true)); CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector(); RefPtr<CSSRuleList> parentMatchedRules = parentSelector->styleRulesForElement(parentElement, authorOnly); - parentStyle->set("matchedCSSRules", buildArrayForCSSRules(parentElement->ownerDocument(), parentMatchedRules.get())); + parentStyle->setArray("matchedCSSRules", buildArrayForCSSRules(parentElement->ownerDocument(), parentMatchedRules.get())); parentElement = parentElement->parentElement(); currentStyle = parentStyle; @@ -1021,7 +1021,7 @@ void InspectorDOMAgent::getAllStyles(RefPtr<InspectorArray>* styles) for (unsigned i = 0; i < list->length(); ++i) { StyleSheet* styleSheet = list->item(i); if (styleSheet->isCSSStyleSheet()) - (*styles)->push(buildObjectForStyleSheet((*it).get(), static_cast<CSSStyleSheet*>(styleSheet))); + (*styles)->pushObject(buildObjectForStyleSheet((*it).get(), static_cast<CSSStyleSheet*>(styleSheet))); } } } @@ -1044,9 +1044,9 @@ void InspectorDOMAgent::getRuleRanges(long styleSheetId, RefPtr<InspectorValue>* for (HashMap<long, SourceRange>::iterator it = ruleRanges.begin(); it != ruleRanges.end(); ++it) { if (it->second.second) { RefPtr<InspectorObject> ruleRange = InspectorObject::create(); - result->set(String::number(it->first).utf8().data(), ruleRange); + result->setObject(String::number(it->first).utf8().data(), ruleRange); RefPtr<InspectorObject> bodyRange = InspectorObject::create(); - ruleRange->set("bodyRange", bodyRange); + ruleRange->setObject("bodyRange", bodyRange); bodyRange->setNumber("start", it->second.first); bodyRange->setNumber("end", it->second.second); } @@ -1085,7 +1085,7 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForAttributeStyles(Ele Attribute* attribute = attributes->attributeItem(i); if (attribute->style()) { String attributeName = attribute->localName(); - styleAttributes->set(attributeName.utf8().data(), buildObjectForStyle(attribute->style(), true)); + styleAttributes->setObject(attributeName.utf8().data(), buildObjectForStyle(attribute->style(), true)); } } return styleAttributes; @@ -1097,7 +1097,7 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForCSSRules(Document* ow for (unsigned i = 0; matchedRules && i < matchedRules->length(); ++i) { CSSRule* rule = matchedRules->item(i); if (rule->type() == CSSRule::STYLE_RULE) - matchedCSSRules->push(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); + matchedCSSRules->pushObject(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); } return matchedCSSRules.release(); } @@ -1113,8 +1113,8 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForPseudoElements(Elemen if (matchedRules && matchedRules->length()) { RefPtr<InspectorObject> pseudoStyles = InspectorObject::create(); pseudoStyles->setNumber("pseudoId", static_cast<int>(pseudoId)); - pseudoStyles->set("rules", buildArrayForCSSRules(element->ownerDocument(), matchedRules.get())); - result->push(pseudoStyles.release()); + pseudoStyles->setArray("rules", buildArrayForCSSRules(element->ownerDocument(), matchedRules.get())); + result->pushObject(pseudoStyles.release()); } } return result.release(); @@ -1309,7 +1309,7 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyle(CSSStyleDecla DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, false); if (disabledStyle) - result->set("disabled", buildArrayForDisabledStyleProperties(disabledStyle)); + result->setArray("disabled", buildArrayForDisabledStyleProperties(disabledStyle)); } result->setString("width", style->getPropertyValue("width")); result->setString("height", style->getPropertyValue("height")); @@ -1336,10 +1336,10 @@ void InspectorDOMAgent::populateObjectWithStyleProperties(CSSStyleDeclaration* s shorthandValues->setString(shorthand, shorthandValue(style, shorthand)); } property->setString("value", style->getPropertyValue(name)); - properties->push(property.release()); + properties->pushObject(property.release()); } - result->set("properties", properties); - result->set("shorthandValues", shorthandValues); + result->setArray("properties", properties); + result->setObject("shorthandValues", shorthandValues); } PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForDisabledStyleProperties(DisabledStyleDeclaration* declaration) @@ -1350,7 +1350,7 @@ PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForDisabledStyleProperti property->setString("name", it->first); property->setString("value", it->second.first); property->setString("priority", it->second.second); - properties->push(property.release()); + properties->pushObject(property.release()); } return properties.release(); } @@ -1370,10 +1370,10 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyleSheet(Document for (unsigned i = 0; i < cssRuleList->length(); ++i) { CSSRule* rule = cssRuleList->item(i); if (rule->isStyleRule()) - cssRules->push(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); + cssRules->pushObject(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); } } - result->set("cssRules", cssRules.release()); + result->setArray("cssRules", cssRules.release()); return result.release(); } @@ -1390,7 +1390,7 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForRule(Document* owne RefPtr<InspectorObject> parentStyleSheetValue = InspectorObject::create(); parentStyleSheetValue->setString("href", parentStyleSheet->href()); parentStyleSheetValue->setNumber("id", cssStore()->bindStyleSheet(parentStyleSheet)); - result->set("parentStyleSheet", parentStyleSheetValue.release()); + result->setObject("parentStyleSheet", parentStyleSheetValue.release()); } bool isUserAgent = parentStyleSheet && !parentStyleSheet->ownerNode() && parentStyleSheet->href().isEmpty(); bool isUser = parentStyleSheet && parentStyleSheet->ownerNode() && parentStyleSheet->ownerNode()->nodeName() == "#document"; @@ -1400,7 +1400,7 @@ PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForRule(Document* owne // Bind editable scripts only. bool bind = !isUserAgent && !isUser; - result->set("style", buildObjectForStyle(rule->style(), bind)); + result->setObject("style", buildObjectForStyle(rule->style(), bind)); if (bind) result->setNumber("id", cssStore()->bindRule(rule)); diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h index bae65f5..5317a22 100644 --- a/WebCore/inspector/InspectorDOMAgent.h +++ b/WebCore/inspector/InspectorDOMAgent.h @@ -30,7 +30,6 @@ #ifndef InspectorDOMAgent_h #define InspectorDOMAgent_h -#include "AtomicString.h" #include "Document.h" #include "EventListener.h" #include "EventTarget.h" @@ -46,6 +45,7 @@ #include <wtf/HashSet.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> +#include <wtf/text/AtomicString.h> namespace WebCore { class ContainerNode; diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp index b70ddbf..e1c0dc0 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.cpp +++ b/WebCore/inspector/InspectorDebuggerAgent.cpp @@ -236,7 +236,7 @@ void InspectorDebuggerAgent::saveBreakpoints() if (it->second.isEmpty()) continue; RefPtr<InspectorObject> breakpointsForURL = ScriptBreakpoint::inspectorObjectFromSourceBreakpoints(it->second); - breakpoints->set(it->first, breakpointsForURL); + breakpoints->setObject(it->first, breakpointsForURL); } m_inspectorController->saveBreakpoints(breakpoints); } diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h index 5428eb2..2cfbf55 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.h +++ b/WebCore/inspector/InspectorDebuggerAgent.h @@ -34,10 +34,10 @@ #include "ScriptBreakpoint.h" #include "ScriptDebugListener.h" #include "ScriptState.h" -#include "StringHash.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/PassOwnPtr.h> +#include <wtf/text/StringHash.h> namespace WebCore { class InjectedScriptHost; diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp index 9259d79..a2b55b0 100644 --- a/WebCore/inspector/InspectorResource.cpp +++ b/WebCore/inspector/InspectorResource.cpp @@ -189,7 +189,7 @@ void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend) jsonObject->setString("path", m_requestURL.path()); jsonObject->setString("lastPathComponent", m_requestURL.lastPathComponent()); RefPtr<InspectorObject> requestHeaders = buildHeadersObject(m_requestHeaderFields); - jsonObject->set("requestHeaders", requestHeaders); + jsonObject->setObject("requestHeaders", requestHeaders); jsonObject->setBool("mainResource", m_isMainResource); jsonObject->setString("requestMethod", m_requestMethod); jsonObject->setString("requestFormData", m_requestFormData); @@ -203,12 +203,12 @@ void InspectorResource::updateScriptObject(RemoteInspectorFrontend* frontend) jsonObject->setNumber("statusCode", m_responseStatusCode); jsonObject->setString("statusText", m_responseStatusText); RefPtr<InspectorObject> responseHeaders = buildHeadersObject(m_responseHeaderFields); - jsonObject->set("responseHeaders", responseHeaders); + jsonObject->setObject("responseHeaders", responseHeaders); jsonObject->setNumber("connectionID", m_connectionID); jsonObject->setBool("connectionReused", m_connectionReused); jsonObject->setBool("cached", m_cached); if (m_loadTiming && !m_cached) - jsonObject->set("timing", buildObjectForTiming(m_loadTiming.get())); + jsonObject->setObject("timing", buildObjectForTiming(m_loadTiming.get())); jsonObject->setBool("didResponseChange", true); } diff --git a/WebCore/inspector/InspectorStorageAgent.cpp b/WebCore/inspector/InspectorStorageAgent.cpp index f95b392..66d3372 100644 --- a/WebCore/inspector/InspectorStorageAgent.cpp +++ b/WebCore/inspector/InspectorStorageAgent.cpp @@ -92,7 +92,7 @@ public: switch (value.type()) { case SQLValue::StringValue: values->pushString(value.string()); break; case SQLValue::NumberValue: values->pushNumber(value.number()); break; - case SQLValue::NullValue: values->push(InspectorValue::null()); break; + case SQLValue::NullValue: values->pushValue(InspectorValue::null()); break; } } m_agent->frontend()->sqlTransactionSucceeded(m_transactionId, columnNames, values); diff --git a/WebCore/inspector/InspectorTimelineAgent.cpp b/WebCore/inspector/InspectorTimelineAgent.cpp index b5cff68..aa42a54 100644 --- a/WebCore/inspector/InspectorTimelineAgent.cpp +++ b/WebCore/inspector/InspectorTimelineAgent.cpp @@ -63,7 +63,7 @@ void InspectorTimelineAgent::pushGCEventRecords() m_gcEvents.clear(); for (GCEvents::iterator i = events.begin(); i != events.end(); ++i) { RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(i->startTime); - record->set("data", TimelineRecordFactory::createGCEventData(i->collectedBytes)); + record->setObject("data", TimelineRecordFactory::createGCEventData(i->collectedBytes)); record->setNumber("endTime", i->endTime); addRecordToTimeline(record.release(), GCEventTimelineRecordType); } @@ -150,7 +150,7 @@ void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool sing { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot)); + record->setObject("data", TimelineRecordFactory::createTimerInstallData(timerId, timeout, singleShot)); addRecordToTimeline(record.release(), TimerInstallTimelineRecordType); } @@ -158,7 +158,7 @@ void InspectorTimelineAgent::didRemoveTimer(int timerId) { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createGenericTimerData(timerId)); + record->setObject("data", TimelineRecordFactory::createGenericTimerData(timerId)); addRecordToTimeline(record.release(), TimerRemoveTimelineRecordType); } @@ -206,7 +206,7 @@ void InspectorTimelineAgent::didScheduleResourceRequest(const String& url) { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createScheduleResourceRequestData(url)); + record->setObject("data", TimelineRecordFactory::createScheduleResourceRequestData(url)); record->setNumber("type", ScheduleResourceRequestTimelineRecordType); addRecordToTimeline(record.release(), ScheduleResourceRequestTimelineRecordType); } @@ -216,7 +216,7 @@ void InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, b { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createResourceSendRequestData(identifier, isMainResource, request)); + record->setObject("data", TimelineRecordFactory::createResourceSendRequestData(identifier, isMainResource, request)); record->setNumber("type", ResourceSendRequestTimelineRecordType); setHeapSizeStatistic(record.get()); m_frontend->addRecordToTimeline(record.release()); @@ -246,7 +246,7 @@ void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail)); + record->setObject("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail)); record->setNumber("type", ResourceFinishTimelineRecordType); setHeapSizeStatistic(record.get()); m_frontend->addRecordToTimeline(record.release()); @@ -256,7 +256,7 @@ void InspectorTimelineAgent::didMarkTimeline(const String& message) { pushGCEventRecords(); RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); - record->set("data", TimelineRecordFactory::createMarkTimelineData(message)); + record->setObject("data", TimelineRecordFactory::createMarkTimelineData(message)); addRecordToTimeline(record.release(), MarkTimelineRecordType); } @@ -295,7 +295,7 @@ void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<InspectorObject> prp m_frontend->addRecordToTimeline(record.release()); else { TimelineRecordEntry parent = m_recordStack.last(); - parent.children->push(record.release()); + parent.children->pushObject(record.release()); } } @@ -317,8 +317,8 @@ void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type) TimelineRecordEntry entry = m_recordStack.last(); m_recordStack.removeLast(); ASSERT(entry.type == type); - entry.record->set("data", entry.data); - entry.record->set("children", entry.children); + entry.record->setObject("data", entry.data); + entry.record->setArray("children", entry.children); entry.record->setNumber("endTime", WTF::currentTimeMS()); addRecordToTimeline(entry.record, type); } diff --git a/WebCore/inspector/InspectorValues.cpp b/WebCore/inspector/InspectorValues.cpp index dad84ac..a7c43a5 100644 --- a/WebCore/inspector/InspectorValues.cpp +++ b/WebCore/inspector/InspectorValues.cpp @@ -366,7 +366,7 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons RefPtr<InspectorValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1); if (!arrayNode) return 0; - array->push(arrayNode); + array->pushValue(arrayNode); // After a list value, we expect a comma or the end of the list. start = tokenEnd; @@ -406,7 +406,7 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, depth + 1); if (!value) return 0; - object->set(key, value); + object->setValue(key, value); start = tokenEnd; // After a key/value pair, we expect a comma or the end of the @@ -504,6 +504,22 @@ bool InspectorValue::asString(String*) const return false; } +bool InspectorValue::asValue(RefPtr<InspectorValue>* output) +{ + *output = this; + return true; +} + +bool InspectorValue::asObject(RefPtr<InspectorObject>*) +{ + return false; +} + +bool InspectorValue::asArray(RefPtr<InspectorArray>*) +{ + return false; +} + PassRefPtr<InspectorObject> InspectorValue::asObject() { return 0; @@ -606,6 +622,12 @@ void InspectorString::writeJSON(Vector<UChar>* output) const doubleQuoteString(m_stringValue, output); } +bool InspectorObject::asObject(RefPtr<InspectorObject>* output) +{ + *output = this; + return true; +} + PassRefPtr<InspectorObject> InspectorObject::asObject() { return this; @@ -674,6 +696,12 @@ void InspectorObject::writeJSON(Vector<UChar>* output) const output->append('}'); } +bool InspectorArray::asArray(RefPtr<InspectorArray>* output) +{ + *output = this; + return true; +} + PassRefPtr<InspectorArray> InspectorArray::asArray() { return this; diff --git a/WebCore/inspector/InspectorValues.h b/WebCore/inspector/InspectorValues.h index f6556d7..4bc36f2 100644 --- a/WebCore/inspector/InspectorValues.h +++ b/WebCore/inspector/InspectorValues.h @@ -34,12 +34,12 @@ #if ENABLE(INSPECTOR) #include "PlatformString.h" -#include "StringHash.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> namespace WebCore { @@ -73,6 +73,9 @@ public: virtual bool asNumber(unsigned long* output) const; virtual bool asNumber(unsigned int* output) const; virtual bool asString(String* output) const; + virtual bool asValue(RefPtr<InspectorValue>* output); + virtual bool asObject(RefPtr<InspectorObject>* output); + virtual bool asArray(RefPtr<InspectorArray>* output); virtual PassRefPtr<InspectorObject> asObject(); virtual PassRefPtr<InspectorArray> asArray(); @@ -163,12 +166,15 @@ public: } ~InspectorObject() { } + virtual bool asObject(RefPtr<InspectorObject>* output); virtual PassRefPtr<InspectorObject> asObject(); void setBool(const String& name, bool); void setNumber(const String& name, double); void setString(const String& name, const String&); - void set(const String& name, PassRefPtr<InspectorValue>); + void setValue(const String& name, PassRefPtr<InspectorValue>); + void setObject(const String& name, PassRefPtr<InspectorObject>); + void setArray(const String& name, PassRefPtr<InspectorArray>); bool getBool(const String& name, bool* output) const; bool getNumber(const String& name, double* output) const; @@ -198,12 +204,15 @@ public: } ~InspectorArray() { } + virtual bool asArray(RefPtr<InspectorArray>* output); virtual PassRefPtr<InspectorArray> asArray(); void pushBool(bool); void pushNumber(double); void pushString(const String&); - void push(PassRefPtr<InspectorValue>); + void pushValue(PassRefPtr<InspectorValue>); + void pushObject(PassRefPtr<InspectorObject>); + void pushArray(PassRefPtr<InspectorArray>); unsigned length() const { return m_data.size(); } PassRefPtr<InspectorValue> get(size_t index); @@ -217,20 +226,32 @@ private: inline void InspectorObject::setBool(const String& name, bool value) { - set(name, InspectorBasicValue::create(value)); + setValue(name, InspectorBasicValue::create(value)); } inline void InspectorObject::setNumber(const String& name, double value) { - set(name, InspectorBasicValue::create(value)); + setValue(name, InspectorBasicValue::create(value)); } inline void InspectorObject::setString(const String& name, const String& value) { - set(name, InspectorString::create(value)); + setValue(name, InspectorString::create(value)); } -inline void InspectorObject::set(const String& name, PassRefPtr<InspectorValue> value) +inline void InspectorObject::setValue(const String& name, PassRefPtr<InspectorValue> value) +{ + if (m_data.set(name, value).second) + m_order.append(name); +} + +inline void InspectorObject::setObject(const String& name, PassRefPtr<InspectorObject> value) +{ + if (m_data.set(name, value).second) + m_order.append(name); +} + +inline void InspectorObject::setArray(const String& name, PassRefPtr<InspectorArray> value) { if (m_data.set(name, value).second) m_order.append(name); @@ -251,7 +272,17 @@ inline void InspectorArray::pushString(const String& value) m_data.append(InspectorString::create(value)); } -inline void InspectorArray::push(PassRefPtr<InspectorValue> value) +inline void InspectorArray::pushValue(PassRefPtr<InspectorValue> value) +{ + m_data.append(value); +} + +inline void InspectorArray::pushObject(PassRefPtr<InspectorObject> value) +{ + m_data.append(value); +} + +inline void InspectorArray::pushArray(PassRefPtr<InspectorArray> value) { m_data.append(value); } diff --git a/WebCore/inspector/ScriptBreakpoint.cpp b/WebCore/inspector/ScriptBreakpoint.cpp index ce0d18a..24401f1 100644 --- a/WebCore/inspector/ScriptBreakpoint.cpp +++ b/WebCore/inspector/ScriptBreakpoint.cpp @@ -64,7 +64,7 @@ PassRefPtr<InspectorObject> ScriptBreakpoint::inspectorObjectFromSourceBreakpoin RefPtr<InspectorObject> breakpoint = InspectorObject::create(); breakpoint->setBool("enabled", it->second.enabled); breakpoint->setString("condition", it->second.condition); - breakpoints->set(String::number(it->first), breakpoint); + breakpoints->setObject(String::number(it->first), breakpoint); } return breakpoints.release(); } diff --git a/WebCore/inspector/TimelineRecordFactory.cpp b/WebCore/inspector/TimelineRecordFactory.cpp index ad9fdec..e1c2bbb 100644 --- a/WebCore/inspector/TimelineRecordFactory.cpp +++ b/WebCore/inspector/TimelineRecordFactory.cpp @@ -49,7 +49,7 @@ PassRefPtr<InspectorObject> TimelineRecordFactory::createGenericRecord(double st RefPtr<InspectorArray> stackTrace = InspectorArray::create(); if (ScriptCallStack::stackTrace(5, stackTrace)) - record->set("stackTrace", stackTrace); + record->setArray("stackTrace", stackTrace); return record.release(); } diff --git a/WebCore/inspector/front-end/AuditRules.js b/WebCore/inspector/front-end/AuditRules.js index 8519cf2..e28a364 100644 --- a/WebCore/inspector/front-end/AuditRules.js +++ b/WebCore/inspector/front-end/AuditRules.js @@ -724,9 +724,9 @@ WebInspector.AuditRules.CssInHeadRule = function() WebInspector.AuditRules.CssInHeadRule.prototype = { doRun: function(resources, result, callback) { - function evalCallback(evalResult, isException) + function evalCallback(evalResult) { - if (isException || !evalResult) + if (!evalResult) return callback(null); var summary = result.addChild(""); @@ -800,9 +800,9 @@ WebInspector.AuditRules.StylesScriptsOrderRule = function() WebInspector.AuditRules.StylesScriptsOrderRule.prototype = { doRun: function(resources, result, callback) { - function evalCallback(resultValue, isException) + function evalCallback(resultValue) { - if (isException || !resultValue) + if (!resultValue) return callback(null); var lateCssUrls = resultValue[0]; diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 6a4e0d3..474c362 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -296,7 +296,7 @@ WebInspector.ConsoleView.prototype = { requestClearMessages: function() { - InspectorBackend.clearConsoleMessages(WebInspector.Callback.wrap(this.clearMessages.bind(this))); + InspectorBackend.clearConsoleMessages(); }, clearMessages: function() @@ -342,7 +342,7 @@ WebInspector.ConsoleView.prototype = { var injectedScriptAccess; if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) { var selectedCallFrame = WebInspector.panels.scripts.sidebarPanes.callstack.selectedCallFrame; - injectedScriptAccess = InjectedScriptAccess.get(selectedCallFrame.injectedScriptId); + injectedScriptAccess = InjectedScriptAccess.get(selectedCallFrame.worldId); } else injectedScriptAccess = InjectedScriptAccess.getDefault(); injectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions); @@ -511,7 +511,7 @@ WebInspector.ConsoleView.prototype = { function evalCallback(result) { - callback(result.value, result.isException); + callback(WebInspector.RemoteObject.fromPayload(result)); }; InjectedScriptAccess.getDefault().evaluate(expression, objectGroup, evalCallback); }, @@ -534,7 +534,7 @@ WebInspector.ConsoleView.prototype = { this.addMessage(commandMessage); var self = this; - function printResult(result, exception) + function printResult(result) { self.prompt.history.push(str); self.prompt.historyOffset = 0; @@ -542,7 +542,7 @@ WebInspector.ConsoleView.prototype = { WebInspector.applicationSettings.consoleHistory = self.prompt.history.slice(-30); - self.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); + self.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage)); } this.evalInInspectedWindow(str, "console", printResult); }, @@ -550,7 +550,7 @@ WebInspector.ConsoleView.prototype = { _format: function(output, forceObjectFormat) { var isProxy = (output != null && typeof output === "object"); - var type = (forceObjectFormat ? "object" : Object.proxyType(output)); + var type = (forceObjectFormat ? "object" : WebInspector.RemoteObject.type(output)); var formatter = this._customFormatters[type]; if (!formatter || !isProxy) { @@ -589,12 +589,12 @@ WebInspector.ConsoleView.prototype = { elem.appendChild(treeOutline.element); } - InjectedScriptAccess.get(object.injectedScriptId).pushNodeToFrontend(object, printNode); + object.pushNodeToFrontend(printNode); }, _formatarray: function(arr, elem) { - InjectedScriptAccess.get(arr.injectedScriptId).getProperties(arr, false, false, this._printArray.bind(this, elem)); + arr.getOwnProperties(false, this._printArray.bind(this, elem)); }, _formatstring: function(output, elem) @@ -637,9 +637,8 @@ WebInspector.ConsoleView.prototype = { _formatAsArrayEntry: function(output) { - var type = Object.proxyType(output); // Prevent infinite expansion of cross-referencing arrays. - return this._format(output, type === "array"); + return this._format(output, WebInspector.RemoteObject.type(output) === "array"); } } @@ -728,12 +727,15 @@ WebInspector.ConsoleMessage.prototype = { // Formatting code below assumes that parameters are all wrappers whereas frontend console // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here. - for (var i = 0; i < parameters.length; ++i) - if (typeof parameters[i] !== "object" && typeof parameters[i] !== "function") - parameters[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(parameters[i]); + for (var i = 0; i < parameters.length; ++i) { + if (typeof parameters[i] === "object") + parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]); + else + parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]); + } // There can be string log and string eval result. We distinguish between them based on message type. - var shouldFormatMessage = Object.proxyType(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result; + var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result; // Multiple parameters with the first being a format string. Save unused substitutions. if (shouldFormatMessage) { @@ -1048,21 +1050,11 @@ WebInspector.ConsoleCommand.prototype = { } } -WebInspector.ConsoleCommandResult = function(result, exception, originatingCommand) +WebInspector.ConsoleCommandResult = function(result, originatingCommand) { - var level = (exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log); - var message = result; - if (exception) { - // Distinguish between strings and errors (no need to quote latter). - message = WebInspector.ObjectProxy.wrapPrimitiveValue(result); - message.type = "error"; - } - var line = (exception ? result.line : -1); - var url = (exception ? result.sourceURL : null); - + var level = (result.isError() ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log); this.originatingCommand = originatingCommand; - - WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, line, url, null, 1, null, [message]); + WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, null, 1, null, [result]); } WebInspector.ConsoleCommandResult.prototype = { diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js index c41d038..57422f6 100644 --- a/WebCore/inspector/front-end/DOMAgent.js +++ b/WebCore/inspector/front-end/DOMAgent.js @@ -33,10 +33,6 @@ WebInspector.DOMNode = function(doc, payload) { this.ownerDocument = doc; this.id = payload.id; - // injectedScriptId is a node is for DOM nodes which should be converted - // to corresponding InjectedScript by the inspector backend. We indicate - // this by making injectedScriptId negative. - this.injectedScriptId = -payload.id; this.nodeType = payload.nodeType; this.nodeName = payload.nodeName; this.localName = payload.localName; diff --git a/WebCore/inspector/front-end/DatabaseTableView.js b/WebCore/inspector/front-end/DatabaseTableView.js index 9e6d374..5440763 100644 --- a/WebCore/inspector/front-end/DatabaseTableView.js +++ b/WebCore/inspector/front-end/DatabaseTableView.js @@ -46,7 +46,7 @@ WebInspector.DatabaseTableView.prototype = { get statusBarItems() { - return [this.refreshButton]; + return [this.refreshButton.element]; }, update: function() diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js index 6713ddc..0296737 100644 --- a/WebCore/inspector/front-end/ElementsPanel.js +++ b/WebCore/inspector/front-end/ElementsPanel.js @@ -255,7 +255,7 @@ WebInspector.ElementsPanel.prototype = { this._matchesCountUpdateTimeout = null; this._searchQuery = query; - InspectorBackend.performSearch(whitespaceTrimmedQuery); + InspectorBackend.performSearch(whitespaceTrimmedQuery, false); }, searchingForNodeWasEnabled: function() diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index 87d85c1..c7d39f1 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -413,8 +413,8 @@ WebInspector.ElementsTreeElement.prototype = { else this.tooltip = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight); } - var objectProxy = new WebInspector.ObjectProxy(node.injectedScriptId, node.id); - WebInspector.ObjectProxy.getPropertiesAsync(objectProxy, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this)); + + InjectedScriptAccess.getForNode(node).getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this)); }, updateSelection: function() diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js index 6798845..2800d6e 100644 --- a/WebCore/inspector/front-end/EventListenersSidebarPane.js +++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js @@ -189,17 +189,21 @@ WebInspector.EventListenerBar = function(eventListener, nodeId) WebInspector.EventListenerBar.prototype = { update: function() { - var properties = []; - for (var propertyName in this.eventListener) { - // Just build properties in place - no need to reach out for injected script. - var value = this.eventListener[propertyName]; - if (value instanceof WebInspector.DOMNode) - value = new WebInspector.ObjectProxy(value.injectedScriptId, value.id, [], appropriateSelectorForNode(value), true); - else - value = WebInspector.ObjectProxy.wrapPrimitiveValue(value); - properties.push(new WebInspector.ObjectPropertyProxy(propertyName, value)); + function updateWithNodeObject(nodeObject) + { + var properties = []; + if (nodeObject) + properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject)); + + for (var propertyName in this.eventListener) { + var value = WebInspector.RemoteObject.fromPrimitiveValue(value); + properties.push(new WebInspector.RemoteObjectProperty(propertyName, value)); + } + this.updateProperties(properties); } - this.updateProperties(properties); + var node = this.eventListener.node; + delete this.eventListener.node; + WebInspector.RemoteObject.resolveNode(node, updateWithNodeObject.bind(this)); }, _setNodeTitle: function() diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js index 2abe1db..95f373f 100644 --- a/WebCore/inspector/front-end/ExtensionServer.js +++ b/WebCore/inspector/front-end/ExtensionServer.js @@ -139,7 +139,8 @@ WebInspector.ExtensionServer.prototype = { var lastToolbarItem = WebInspector.panelOrder[WebInspector.panelOrder.length - 1].toolbarItem; WebInspector.addPanelToolbarIcon(toolbarElement, panel, lastToolbarItem); WebInspector.panels[id] = panel; - this._createClientIframe(panel.element, message.url); + var iframe = this._createClientIframe(panel.element, message.url); + iframe.style.height = "100%"; return this._status.OK(); }, @@ -165,6 +166,7 @@ WebInspector.ExtensionServer.prototype = { iframe.src = url; iframe.style.width = "100%"; parent.appendChild(iframe); + return iframe; }, _onSetSidebarHeight: function(message) @@ -193,7 +195,17 @@ WebInspector.ExtensionServer.prototype = { _onEvaluateOnInspectedPage: function(message, port) { - InjectedScriptAccess.getDefault().evaluateAndStringify(message.expression, this._dispatchCallback.bind(this, message.requestId, port)); + var escapedMessage = escape(message.expression); + function callback(resultPayload) + { + var resultObject = WebInspector.RemoteObject.fromPayload(resultPayload); + var result = {}; + if (resultObject.isError()) + result.isException = true; + result.value = resultObject.description; + this._dispatchCallback(message.requestId, port, result); + } + InjectedScriptAccess.getDefault().evaluate("(function() { var a = window.eval(unescape(\"" + escapedMessage + "\")); return JSON.stringify(a); })();", "", callback.bind(this)); }, _onRevealAndSelect: function(message) diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js index b8bf9f2..d4e3d80 100644 --- a/WebCore/inspector/front-end/InjectedScript.js +++ b/WebCore/inspector/front-end/InjectedScript.js @@ -28,392 +28,517 @@ var injectedScriptConstructor = (function (InjectedScriptHost, inspectedWindow, injectedScriptId, jsEngine) { -var InjectedScript = {}; - -InjectedScript.lastBoundObjectId = 1; -InjectedScript.idToWrappedObject = {}; -InjectedScript.objectGroups = {}; - -InjectedScript.wrapObjectForConsole = function(object, canAccessInspectedWindow) +var InjectedScript = function() { - if (canAccessInspectedWindow) - return InjectedScript.wrapObject(object, "console"); - var result = {}; - result.type = typeof object; - result.description = InjectedScript._toString(object); - return result; + this._lastBoundObjectId = 1; + this._idToWrappedObject = {}; + this._objectGroups = {}; } -InjectedScript.wrapObject = function(object, objectGroupName) -{ - try { - var objectId; - if (typeof object === "object" || typeof object === "function" || InjectedScript._isHTMLAllCollection(object)) { - var id = InjectedScript.lastBoundObjectId++; - objectId = "object#" + id; - InjectedScript.idToWrappedObject[objectId] = object; - - var group = InjectedScript.objectGroups[objectGroupName]; - if (!group) { - group = []; - InjectedScript.objectGroups[objectGroupName] = group; +InjectedScript.prototype = { + wrapObjectForConsole: function(object, canAccessInspectedWindow) + { + if (canAccessInspectedWindow) + return this._wrapObject(object, "console"); + var result = {}; + result.type = typeof object; + result.description = this._toString(object); + return result; + }, + + _wrapObject: function(object, objectGroupName, abbreviate) + { + try { + var objectId; + if (typeof object === "object" || typeof object === "function" || this._isHTMLAllCollection(object)) { + var id = this._lastBoundObjectId++; + objectId = id; + this._idToWrappedObject[id] = object; + + var group = this._objectGroups[objectGroupName]; + if (!group) { + group = []; + this._objectGroups[objectGroupName] = group; + } + group.push(id); + objectId = this._serializeObjectId(id, objectGroupName); } - group.push(objectId); + return InjectedScript.RemoteObject.fromObject(object, objectId, abbreviate); + } catch (e) { + return InjectedScript.RemoteObject.fromObject("[ Exception: " + e.toString() + " ]"); } - return InjectedScript.createProxyObject(object, objectId); - } catch (e) { - return InjectedScript.createProxyObject("[ Exception: " + e.toString() + " ]"); - } - return InjectedScript.createProxyObject(object, objectId); -}; - -InjectedScript.unwrapObject = function(objectId) { - return InjectedScript.idToWrappedObject[objectId]; -}; - -InjectedScript.releaseWrapperObjectGroup = function(objectGroupName) { - var group = InjectedScript.objectGroups[objectGroupName]; - if (!group) - return; - for (var i = 0; i < group.length; i++) - delete InjectedScript.idToWrappedObject[group[i]]; - delete InjectedScript.objectGroups[objectGroupName]; -}; - -InjectedScript.dispatch = function(methodName, args, callId) -{ - var argsArray = eval("(" + args + ")"); - if (callId) - argsArray.splice(0, 0, callId); // Methods that run asynchronously have a call back id parameter. - var result = InjectedScript[methodName].apply(InjectedScript, argsArray); - if (typeof result === "undefined") { - inspectedWindow.console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName); - result = null; - } - return result; -} + }, -InjectedScript.getPrototypes = function(nodeId) -{ - var node = InjectedScript._nodeForId(nodeId); - if (!node) - return false; - - var result = []; - for (var prototype = node; prototype; prototype = prototype.__proto__) { - var title = InjectedScript._describe(prototype, true); - if (title.match(/Prototype$/)) { - title = title.replace(/Prototype$/, ""); + _serializeObjectId: function(id, groupName) + { + return injectedScriptId + ":" + id + ":" + groupName; + }, + + _parseObjectId: function(objectId) + { + var tokens = objectId.split(":"); + var parsedObjectId = {}; + parsedObjectId.id = parseInt(tokens[1]); + parsedObjectId.groupName = tokens[2]; + return parsedObjectId; + }, + + releaseWrapperObjectGroup: function(objectGroupName) + { + var group = this._objectGroups[objectGroupName]; + if (!group) + return; + for (var i = 0; i < group.length; i++) + delete this._idToWrappedObject[group[i]]; + delete this._objectGroups[objectGroupName]; + }, + + dispatch: function(methodName, args) + { + var argsArray = eval("(" + args + ")"); + var result = this[methodName].apply(this, argsArray); + if (typeof result === "undefined") { + inspectedWindow.console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName); + result = null; } - result.push(title); - } - return result; -} + return result; + }, -InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate) -{ - var object = InjectedScript._resolveObject(objectProxy); - if (!InjectedScript._isDefined(object)) - return false; - var properties = []; + getPrototypes: function(nodeId) + { + this.releaseWrapperObjectGroup("prototypes"); + var node = this._nodeForId(nodeId); + if (!node) + return false; + + var result = []; + var prototype = node; + do { + result.push(this._wrapObject(prototype, "prototypes")); + prototype = prototype.__proto__; + } while (prototype) + return result; + }, + + getProperties: function(objectId, ignoreHasOwnProperty, abbreviate) + { + var parsedObjectId = this._parseObjectId(objectId); + var object = this._objectForId(parsedObjectId); + if (!this._isDefined(object)) + return false; + var properties = []; + + var propertyNames = ignoreHasOwnProperty ? this._getPropertyNames(object) : Object.getOwnPropertyNames(object); + if (!ignoreHasOwnProperty && object.__proto__) + propertyNames.push("__proto__"); - var propertyNames = ignoreHasOwnProperty ? InjectedScript._getPropertyNames(object) : Object.getOwnPropertyNames(object); - if (!ignoreHasOwnProperty && object.__proto__) - propertyNames.push("__proto__"); - - // Go over properties, prepare results. - for (var i = 0; i < propertyNames.length; ++i) { - var propertyName = propertyNames[i]; - - var property = {}; - property.name = propertyName + ""; - property.parentObjectProxy = objectProxy; - var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName); - if (!isGetter) { - try { - var childObject = object[propertyName]; - var childObjectProxy = new InjectedScript.createProxyObject(childObject, objectProxy.objectId, abbreviate); - childObjectProxy.path = objectProxy.path ? objectProxy.path.slice() : []; - childObjectProxy.path.push(propertyName); - property.value = childObjectProxy; - } catch(e) { - property.value = { description: e.toString() }; - property.isError = true; + // Go over properties, prepare results. + for (var i = 0; i < propertyNames.length; ++i) { + var propertyName = propertyNames[i]; + + var property = {}; + property.name = propertyName + ""; + var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName); + if (!isGetter) { + try { + property.value = this._wrapObject(object[propertyName], parsedObjectId.groupName, abbreviate); + } catch(e) { + property.value = new InjectedScript.RemoteObject.fromException(e); + } + } else { + // FIXME: this should show something like "getter" (bug 16734). + property.value = new InjectedScript.RemoteObject.fromObject("\u2014"); // em dash + property.isGetter = true; } - } else { - // FIXME: this should show something like "getter" (bug 16734). - property.value = { description: "\u2014" }; // em dash - property.isGetter = true; + properties.push(property); } - properties.push(property); - } - return properties; -} - -InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression) -{ - var object = InjectedScript._resolveObject(objectProxy); - if (!InjectedScript._isDefined(object)) - return false; - - var expressionLength = expression.length; - if (!expressionLength) { - delete object[propertyName]; - return !(propertyName in object); - } + return properties; + }, - try { - // Surround the expression in parenthesis so the result of the eval is the result - // of the whole expression not the last potential sub-expression. - - // There is a regression introduced here: eval is now happening against global object, - // not call frame while on a breakpoint. - // TODO: bring evaluation against call frame back. - var result = inspectedWindow.eval("(" + expression + ")"); - // Store the result in the property. - object[propertyName] = result; - return true; - } catch(e) { + setPropertyValue: function(objectId, propertyName, expression) + { + var parsedObjectId = this._parseObjectId(objectId); + var object = this._objectForId(parsedObjectId); + if (!this._isDefined(object)) + return false; + + var expressionLength = expression.length; + if (!expressionLength) { + delete object[propertyName]; + return !(propertyName in object); + } + try { - var result = inspectedWindow.eval("\"" + expression.replace(/"/g, "\\\"") + "\""); + // Surround the expression in parenthesis so the result of the eval is the result + // of the whole expression not the last potential sub-expression. + + // There is a regression introduced here: eval is now happening against global object, + // not call frame while on a breakpoint. + // TODO: bring evaluation against call frame back. + var result = inspectedWindow.eval("(" + expression + ")"); + // Store the result in the property. object[propertyName] = result; return true; } catch(e) { - return false; + try { + var result = inspectedWindow.eval("\"" + expression.replace(/"/g, "\\\"") + "\""); + object[propertyName] = result; + return true; + } catch(e) { + return false; + } } - } -} + }, -InjectedScript._populatePropertyNames = function(object, resultSet) -{ - for (var o = object; o; o = o.__proto__) { - try { - var names = Object.getOwnPropertyNames(o); - for (var i = 0; i < names.length; ++i) - resultSet[names[i]] = true; - } catch (e) { + _populatePropertyNames: function(object, resultSet) + { + for (var o = object; o; o = o.__proto__) { + try { + var names = Object.getOwnPropertyNames(o); + for (var i = 0; i < names.length; ++i) + resultSet[names[i]] = true; + } catch (e) { + } } - } -} + }, -InjectedScript._getPropertyNames = function(object, resultSet) -{ - var propertyNameSet = {}; - InjectedScript._populatePropertyNames(object, propertyNameSet); - return Object.keys(propertyNameSet); -} + _getPropertyNames: function(object, resultSet) + { + var propertyNameSet = {}; + this._populatePropertyNames(object, propertyNameSet); + return Object.keys(propertyNameSet); + }, -InjectedScript.getCompletions = function(expression, includeInspectorCommandLineAPI, callFrameId) -{ - var props = {}; - try { - var expressionResult; - // Evaluate on call frame if call frame id is available. - if (typeof callFrameId === "number") { - var callFrame = InjectedScript._callFrameForId(callFrameId); - if (!callFrame) - return props; - if (expression) - expressionResult = InjectedScript._evaluateOn(callFrame.evaluate, callFrame, expression, true); - else { - // Evaluate into properties in scope of the selected call frame. - var scopeChain = callFrame.scopeChain; - for (var i = 0; i < scopeChain.length; ++i) - InjectedScript._populatePropertyNames(scopeChain[i], props); + getCompletions: function(expression, includeInspectorCommandLineAPI, callFrameId) + { + var props = {}; + try { + var expressionResult; + // Evaluate on call frame if call frame id is available. + if (typeof callFrameId === "number") { + var callFrame = this._callFrameForId(callFrameId); + if (!callFrame) + return props; + if (expression) + expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression); + else { + // Evaluate into properties in scope of the selected call frame. + var scopeChain = callFrame.scopeChain; + for (var i = 0; i < scopeChain.length; ++i) + this._populatePropertyNames(scopeChain[i], props); + } + } else { + if (!expression) + expression = "this"; + expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression); } - } else { - if (!expression) - expression = "this"; - expressionResult = InjectedScript._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false); + if (typeof expressionResult === "object") + this._populatePropertyNames(expressionResult, props); + + if (includeInspectorCommandLineAPI) { + for (var prop in this._commandLineAPI) + props[prop] = true; + } + } catch(e) { } - if (typeof expressionResult === "object") - InjectedScript._populatePropertyNames(expressionResult, props); + return props; + }, - if (includeInspectorCommandLineAPI) { - for (var prop in InjectedScript._commandLineAPI) - props[prop] = true; + evaluate: function(expression, objectGroup) + { + return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup); + }, + + _evaluateAndWrap: function(evalFunction, object, expression, objectGroup) + { + try { + return this._wrapObject(this._evaluateOn(evalFunction, object, expression), objectGroup); + } catch (e) { + return InjectedScript.RemoteObject.fromException(e); } - } catch(e) { - } - return props; -} + }, -InjectedScript.evaluateAndStringify = function(expression) -{ - var result = {}; - try { - var value = InjectedScript._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false); - result.value = JSON.stringify(value); - } catch (e) { - result.value = e.toString(); - result.isException = true; - } - return result; -} + _evaluateOn: function(evalFunction, object, expression) + { + // Only install command line api object for the time of evaluation. + // Surround the expression in with statements to inject our command line API so that + // the window object properties still take more precedent than our API functions. + inspectedWindow.console._commandLineAPI = this._commandLineAPI; + + expression = "with (window.console._commandLineAPI) { with (window) {\n" + expression + "\n} }"; + var value = evalFunction.call(object, expression); + + delete inspectedWindow.console._commandLineAPI; + + // When evaluating on call frame error is not thrown, but returned as a value. + if (this._type(value) === "error") + throw value.toString(); + + return value; + }, -InjectedScript.evaluate = function(expression, objectGroup) -{ - return InjectedScript._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup); -} + getNodeId: function(node) + { + return InjectedScriptHost.pushNodePathToFrontend(node, false, false); + }, -InjectedScript._evaluateAndWrap = function(evalFunction, object, expression, objectGroup, dontUseCommandLineAPI) -{ - var result = {}; - try { - result.value = InjectedScript.wrapObject(InjectedScript._evaluateOn(evalFunction, object, expression, dontUseCommandLineAPI), objectGroup); + callFrames: function() + { + var callFrame = InjectedScriptHost.currentCallFrame(); + if (!callFrame) + return false; + + injectedScript.releaseWrapperObjectGroup("backtrace"); + var result = []; + var depth = 0; + do { + result.push(new InjectedScript.CallFrameProxy(depth++, callFrame)); + callFrame = callFrame.caller; + } while (callFrame); + return result; + }, - // Handle error that might have happened while describing result. - if (result.value.errorText) { - result.value = result.value.errorText; - result.isException = true; - } - } catch (e) { - result.value = e.toString(); - result.isException = true; - } - return result; -} + evaluateInCallFrame: function(callFrameId, code, objectGroup) + { + var callFrame = this._callFrameForId(callFrameId); + if (!callFrame) + return false; + return this._evaluateAndWrap(callFrame.evaluate, callFrame, code, objectGroup); + }, -InjectedScript._evaluateOn = function(evalFunction, object, expression, dontUseCommandLineAPI) -{ - if (!dontUseCommandLineAPI) { - // Only install command line api object for the time of evaluation. + _callFrameForId: function(id) + { + var callFrame = InjectedScriptHost.currentCallFrame(); + while (--id >= 0 && callFrame) + callFrame = callFrame.caller; + return callFrame; + }, - // Surround the expression in with statements to inject our command line API so that - // the window object properties still take more precedent than our API functions. - inspectedWindow.console._commandLineAPI = InjectedScript._commandLineAPI; + _nodeForId: function(nodeId) + { + if (!nodeId) + return null; + return InjectedScriptHost.nodeForId(nodeId); + }, - expression = "with (window.console._commandLineAPI) { with (window) {\n" + expression + "\n} }"; - } + _objectForId: function(parsedObjectId) + { + return this._idToWrappedObject[parsedObjectId.id]; + }, - var value = evalFunction.call(object, expression); + resolveNode: function(nodeId) + { + var node = this._nodeForId(nodeId); + if (!node) + return false; + // FIXME: receive the object group from client. + return this._wrapObject(node, "prototype"); + }, - if (!dontUseCommandLineAPI) - delete inspectedWindow.console._commandLineAPI; + getNodeProperties: function(nodeId, properties) + { + var node = this._nodeForId(nodeId); + if (!node) + return false; + var result = {}; + for (var i = 0; i < properties.length; ++i) + result[properties[i]] = node[properties[i]]; + return result; + }, - // When evaluating on call frame error is not thrown, but returned as a value. - if (InjectedScript._type(value) === "error") - throw value.toString(); + pushNodeToFrontend: function(objectId) + { + var parsedObjectId = this._parseObjectId(objectId); + var object = this._objectForId(parsedObjectId); + if (!object || this._type(object) !== "node") + return false; + return InjectedScriptHost.pushNodePathToFrontend(object, false, false); + }, - return value; -} + evaluateOnSelf: function(funcBody, args) + { + var func = window.eval("(" + funcBody + ")"); + return func.apply(this, args || []); + }, -InjectedScript.getNodeId = function(node) -{ - return InjectedScriptHost.pushNodePathToFrontend(node, false, false); -} + _isDefined: function(object) + { + return object || this._isHTMLAllCollection(object); + }, -InjectedScript.openInInspectedWindow = function(url) -{ - // Don't call window.open on wrapper - popup blocker mutes it. - // URIs should have no double quotes. - inspectedWindow.eval("window.open(\"" + url + "\")"); - return true; -} + _isHTMLAllCollection: function(object) + { + // document.all is reported as undefined, but we still want to process it. + return (typeof object === "undefined") && inspectedWindow.HTMLAllCollection && object instanceof inspectedWindow.HTMLAllCollection; + }, -InjectedScript.callFrames = function() -{ - var callFrame = InjectedScriptHost.currentCallFrame(); - if (!callFrame) - return false; - - var result = []; - var depth = 0; - do { - result.push(new InjectedScript.CallFrameProxy(depth++, callFrame)); - callFrame = callFrame.caller; - } while (callFrame); - return result; -} + _type: function(obj) + { + if (obj === null) + return "null"; + + var type = typeof obj; + if (type !== "object" && type !== "function") { + // FIXME(33716): typeof document.all is always 'undefined'. + if (this._isHTMLAllCollection(obj)) + return "array"; + return type; + } -InjectedScript.evaluateInCallFrame = function(callFrameId, code, objectGroup) -{ - var callFrame = InjectedScript._callFrameForId(callFrameId); - if (!callFrame) - return false; - return InjectedScript._evaluateAndWrap(callFrame.evaluate, callFrame, code, objectGroup, true); -} + // If owning frame has navigated to somewhere else window properties will be undefined. + // In this case just return result of the typeof. + if (!inspectedWindow.document) + return type; -InjectedScript._callFrameForId = function(id) -{ - var callFrame = InjectedScriptHost.currentCallFrame(); - while (--id >= 0 && callFrame) - callFrame = callFrame.caller; - return callFrame; -} + if (obj instanceof inspectedWindow.Node) + return (obj.nodeType === undefined ? type : "node"); + if (obj instanceof inspectedWindow.String) + return "string"; + if (obj instanceof inspectedWindow.Array) + return "array"; + if (obj instanceof inspectedWindow.Boolean) + return "boolean"; + if (obj instanceof inspectedWindow.Number) + return "number"; + if (obj instanceof inspectedWindow.Date) + return "date"; + if (obj instanceof inspectedWindow.RegExp) + return "regexp"; + // FireBug's array detection. + if (isFinite(obj.length) && typeof obj.splice === "function") + return "array"; + if (isFinite(obj.length) && typeof obj.callee === "function") // arguments. + return "array"; + if (obj instanceof inspectedWindow.NodeList) + return "array"; + if (obj instanceof inspectedWindow.HTMLCollection) + return "array"; + if (obj instanceof inspectedWindow.Error) + return "error"; + return type; + }, -InjectedScript._resolveObject = function(objectProxy) -{ - var object = InjectedScript._objectForId(objectProxy.objectId); - var path = objectProxy.path; + _describe: function(obj, abbreviated) + { + var type = this._type(obj); + + switch (type) { + case "object": + case "node": + return this._className(obj); + case "array": + var className = this._className(obj); + if (typeof obj.length === "number") + className += "[" + obj.length + "]"; + return className; + case "string": + if (!abbreviated) + return obj; + if (obj.length > 100) + return "\"" + obj.substring(0, 100) + "\u2026\""; + return "\"" + obj + "\""; + case "function": + var objectText = this._toString(obj); + if (abbreviated) + objectText = /.*/.exec(objectText)[0].replace(/ +$/g, ""); + return objectText; + default: + return this._toString(obj); + } + }, - // Follow the property path. - for (var i = 0; InjectedScript._isDefined(object) && path && i < path.length; ++i) - object = object[path[i]]; + _toString: function(obj) + { + // We don't use String(obj) because inspectedWindow.String is undefined if owning frame navigated to another page. + return "" + obj; + }, - return object; -} + _className: function(obj) + { + // We can't use the same code for fetching class names of the dom bindings prototype chain. + // Both of the methods below result in "Object" names on the foreign engine bindings. + // I gave up and am using a check below to distinguish between the egine bingings. -InjectedScript._nodeForId = function(nodeId) -{ - if (!nodeId) - return null; - return InjectedScriptHost.nodeForId(nodeId); + if (jsEngine == "JSC") { + var str = inspectedWindow.Object ? inspectedWindow.Object.prototype.toString.call(obj) : this._toString(obj); + return str.replace(/^\[object (.*)\]$/i, "$1"); + } else { + // V8 + return obj.constructor && obj.constructor.name || "Object"; + } + }, + + _logEvent: function(event) + { + console.log(event.type, event); + }, + + _normalizeEventTypes: function(types) + { + if (typeof types === "undefined") + types = [ "mouse", "key", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll" ]; + else if (typeof types === "string") + types = [ types ]; + + var result = []; + for (var i = 0; i < types.length; i++) { + if (types[i] === "mouse") + result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout"); + else if (types[i] === "key") + result.splice(0, 0, "keydown", "keyup", "keypress"); + else + result.push(types[i]); + } + return result; + }, + + _inspectedNode: function(num) + { + var nodeId = InjectedScriptHost.inspectedNode(num); + return this._nodeForId(nodeId); + }, + + _bindToScript: function(func) + { + var args = Array.prototype.slice.call(arguments, 1); + function bound() + { + return func.apply(injectedScript, args.concat(Array.prototype.slice.call(arguments))); + } + bound.toString = function() { + return "bound: " + func; + }; + return bound; + } } -InjectedScript._objectForId = function(objectId) +var injectedScript = new InjectedScript(); + +InjectedScript.RemoteObject = function(objectId, type, description, hasChildren) { - // There are three types of object ids used: - // - numbers point to DOM Node via the InspectorDOMAgent mapping - // - strings point to console objects cached in InspectorController for lazy evaluation upon them - // - objects contain complex ids and are currently used for scoped objects - if (typeof objectId === "number") - return InjectedScript._nodeForId(objectId); - else if (typeof objectId === "string") - return InjectedScript.unwrapObject(objectId); - else if (typeof objectId === "object") { - var callFrame = InjectedScript._callFrameForId(objectId.callFrame); - if (objectId.thisObject) - return callFrame.thisObject; - else - return callFrame.scopeChain[objectId.chainIndex]; - } - return objectId; + this.objectId = objectId; + this.type = type; + this.description = description; + this.hasChildren = hasChildren; } -InjectedScript.pushNodeToFrontend = function(objectProxy) +InjectedScript.RemoteObject.fromException = function(e) { - var object = InjectedScript._resolveObject(objectProxy); - if (!object || InjectedScript._type(object) !== "node") - return false; - return InjectedScriptHost.pushNodePathToFrontend(object, false, false); + return new InjectedScript.RemoteObject(null, "error", e.toString()); } -// Called from within InspectorController on the 'inspected page' side. -InjectedScript.createProxyObject = function(object, objectId, abbreviate) +InjectedScript.RemoteObject.fromObject = function(object, objectId, abbreviate) { - var result = {}; - result.injectedScriptId = injectedScriptId; - result.objectId = objectId; - result.type = InjectedScript._type(object); - if (result.type === "array") - result.propertyLength = object.length; - - var type = typeof object; - - result.hasChildren = (type === "object" && object !== null && (Object.getOwnPropertyNames(object).length || !!object.__proto__)) || type === "function"; + var type = injectedScript._type(object); + var rawType = typeof object; + var hasChildren = (rawType === "object" && object !== null && (Object.getOwnPropertyNames(object).length || !!object.__proto__)) || rawType === "function"; + var description = ""; try { - result.description = InjectedScript._describe(object, abbreviate); + var description = injectedScript._describe(object, abbreviate); + return new InjectedScript.RemoteObject(objectId, type, description, hasChildren); } catch (e) { - result.errorText = e.toString(); + return InjectedScript.RemoteObject.fromException(e); } - return result; -} - -InjectedScript.evaluateOnSelf = function(funcBody, args) -{ - var func = window.eval("(" + funcBody + ")"); - return func.apply(this, args || []); } InjectedScript.CallFrameProxy = function(id, callFrame) @@ -424,7 +549,7 @@ InjectedScript.CallFrameProxy = function(id, callFrame) this.sourceID = callFrame.sourceID; this.line = callFrame.line; this.scopeChain = this._wrapScopeChain(callFrame); - this.injectedScriptId = injectedScriptId; + this.worldId = injectedScriptId; } InjectedScript.CallFrameProxy.prototype = { @@ -442,13 +567,13 @@ InjectedScript.CallFrameProxy.prototype = { for (var i = 0; i < scopeChain.length; i++) { var scopeType = callFrame.scopeType(i); var scopeObject = scopeChain[i]; - var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: i }, true); + var scopeObjectProxy = injectedScript._wrapObject(scopeObject, "backtrace", true); switch(scopeType) { case LOCAL_SCOPE: { foundLocalScope = true; scopeObjectProxy.isLocal = true; - scopeObjectProxy.thisObject = InjectedScript.createProxyObject(callFrame.thisObject, { callFrame: this.id, thisObject: true }, true); + scopeObjectProxy.thisObject = injectedScript._wrapObject(callFrame.thisObject, "backtrace", true); break; } case CLOSURE_SCOPE: { @@ -472,138 +597,10 @@ InjectedScript.CallFrameProxy.prototype = { } } -InjectedScript._isDefined = function(object) -{ - return object || InjectedScript._isHTMLAllCollection(object); -} - -InjectedScript._isHTMLAllCollection = function(object) -{ - // document.all is reported as undefined, but we still want to process it. - return (typeof object === "undefined") && inspectedWindow.HTMLAllCollection && object instanceof inspectedWindow.HTMLAllCollection; -} - -InjectedScript._type = function(obj) -{ - if (obj === null) - return "null"; - - var type = typeof obj; - if (type !== "object" && type !== "function") { - // FIXME(33716): typeof document.all is always 'undefined'. - if (InjectedScript._isHTMLAllCollection(obj)) - return "array"; - return type; - } - - // If owning frame has navigated to somewhere else window properties will be undefined. - // In this case just return result of the typeof. - if (!inspectedWindow.document) - return type; - - if (obj instanceof inspectedWindow.Node) - return (obj.nodeType === undefined ? type : "node"); - if (obj instanceof inspectedWindow.String) - return "string"; - if (obj instanceof inspectedWindow.Array) - return "array"; - if (obj instanceof inspectedWindow.Boolean) - return "boolean"; - if (obj instanceof inspectedWindow.Number) - return "number"; - if (obj instanceof inspectedWindow.Date) - return "date"; - if (obj instanceof inspectedWindow.RegExp) - return "regexp"; - if (obj instanceof inspectedWindow.NodeList) - return "array"; - if (obj instanceof inspectedWindow.HTMLCollection) - return "array"; - if (typeof inspectedWindow.jQuery === "function" && obj instanceof inspectedWindow.jQuery) - return "array"; - if (obj instanceof inspectedWindow.Error) - return "error"; - return type; -} - -InjectedScript._describe = function(obj, abbreviated) -{ - var type = InjectedScript._type(obj); - - switch (type) { - case "object": - case "node": - case "array": - return InjectedScript._className(obj); - case "string": - if (!abbreviated) - return obj; - if (obj.length > 100) - return "\"" + obj.substring(0, 100) + "\u2026\""; - return "\"" + obj + "\""; - case "function": - var objectText = InjectedScript._toString(obj); - if (abbreviated) - objectText = /.*/.exec(objectText)[0].replace(/ +$/g, ""); - return objectText; - default: - return InjectedScript._toString(obj); - } -} - -InjectedScript._toString = function(obj) -{ - // We don't use String(obj) because inspectedWindow.String is undefined if owning frame navigated to another page. - return "" + obj; -} - -InjectedScript._className = function(obj) -{ - // We can't use the same code for fetching class names of the dom bindings prototype chain. - // Both of the methods below result in "Object" names on the foreign engine bindings. - // I gave up and am using a check below to distinguish between the egine bingings. - - if (jsEngine == "JSC") { - var str = inspectedWindow.Object ? inspectedWindow.Object.prototype.toString.call(obj) : InjectedScript._toString(obj); - return str.replace(/^\[object (.*)\]$/i, "$1"); - } else { - // V8 - return obj.constructor && obj.constructor.name || "Object"; - } -} - -InjectedScript._logEvent = function(event) -{ - console.log(event.type, event); -} - -InjectedScript._normalizeEventTypes = function(types) -{ - if (typeof types === "undefined") - types = [ "mouse", "key", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll" ]; - else if (typeof types === "string") - types = [ types ]; - - var result = []; - for (var i = 0; i < types.length; i++) { - if (types[i] === "mouse") - result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout"); - else if (types[i] === "key") - result.splice(0, 0, "keydown", "keyup", "keypress"); - else - result.push(types[i]); - } - return result; -} - -InjectedScript._inspectedNode = function(num) -{ - var nodeId = InjectedScriptHost.inspectedNode(num); - return InjectedScript._nodeForId(nodeId); -} - function CommandLineAPI() { + for (var i = 0; i < 5; ++i) + this.__defineGetter__("$" + i, injectedScript._bindToScript(injectedScript._inspectedNode, i)); } CommandLineAPI.prototype = { @@ -670,10 +667,10 @@ CommandLineAPI.prototype = { { if (!object || !object.addEventListener || !object.removeEventListener) return; - types = InjectedScript._normalizeEventTypes(types); + types = injectedScript._normalizeEventTypes(types); for (var i = 0; i < types.length; ++i) { - object.removeEventListener(types[i], InjectedScript._logEvent, false); - object.addEventListener(types[i], InjectedScript._logEvent, false); + object.removeEventListener(types[i], injectedScript._logEvent, false); + object.addEventListener(types[i], injectedScript._logEvent, false); } }, @@ -681,9 +678,9 @@ CommandLineAPI.prototype = { { if (!object || !object.addEventListener || !object.removeEventListener) return; - types = InjectedScript._normalizeEventTypes(types); + types = injectedScript._normalizeEventTypes(types); for (var i = 0; i < types.length; ++i) - object.removeEventListener(types[i], InjectedScript._logEvent, false); + object.removeEventListener(types[i], injectedScript._logEvent, false); }, inspect: function(object) @@ -692,10 +689,10 @@ CommandLineAPI.prototype = { return; inspectedWindow.console.log(object); - if (InjectedScript._type(object) === "node") + if (injectedScript._type(object) === "node") InjectedScriptHost.pushNodePathToFrontend(object, false, true); else { - switch (InjectedScript._describe(object)) { + switch (injectedScript._describe(object)) { case "Database": InjectedScriptHost.selectDatabase(object); break; @@ -708,7 +705,7 @@ CommandLineAPI.prototype = { copy: function(object) { - if (InjectedScript._type(object) === "node") { + if (injectedScript._type(object) === "node") { var nodeId = InjectedScriptHost.pushNodePathToFrontend(object, false, false); InjectedScriptHost.copyNode(nodeId); } else @@ -718,35 +715,9 @@ CommandLineAPI.prototype = { clear: function() { InjectedScriptHost.clearConsoleMessages(); - }, - - get $0() - { - return InjectedScript._inspectedNode(0); - }, - - get $1() - { - return InjectedScript._inspectedNode(1); - }, - - get $2() - { - return InjectedScript._inspectedNode(2); - }, - - get $3() - { - return InjectedScript._inspectedNode(3); - }, - - get $4() - { - return InjectedScript._inspectedNode(4); } } -InjectedScript._commandLineAPI = new CommandLineAPI(); - -return InjectedScript; +injectedScript._commandLineAPI = new CommandLineAPI(); +return injectedScript; }); diff --git a/WebCore/inspector/front-end/InjectedScriptAccess.js b/WebCore/inspector/front-end/InjectedScriptAccess.js index b5aa9c7..ce264dd 100644 --- a/WebCore/inspector/front-end/InjectedScriptAccess.js +++ b/WebCore/inspector/front-end/InjectedScriptAccess.js @@ -29,17 +29,29 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -function InjectedScriptAccess(injectedScriptId) { - this._injectedScriptId = injectedScriptId; +function InjectedScriptAccess(worldId) { + this._worldId = worldId; } -InjectedScriptAccess.get = function(injectedScriptId) +InjectedScriptAccess.get = function(worldId) { - if (typeof injectedScriptId === "number") - return new InjectedScriptAccess(injectedScriptId); + if (typeof worldId === "number") + return new InjectedScriptAccess(worldId); - console.error("Access to injected script with no id"); - console.trace(); + console.assert(false, "Access to injected script with no id"); +} + +InjectedScriptAccess.getForNode = function(node) +{ + // FIXME: do something. + return InjectedScriptAccess.get(-node.id); +} + +InjectedScriptAccess.getForObjectId = function(objectId) +{ + // FIXME: move to native layer. + var tokens = objectId.split(":"); + return InjectedScriptAccess.get(parseInt(tokens[0])); } InjectedScriptAccess.getDefault = function() @@ -66,7 +78,7 @@ InjectedScriptAccess._installHandler = function(methodName, async) } var callId = WebInspector.Callback.wrap(myCallback); - InspectorBackend.dispatchOnInjectedScript(callId, this._injectedScriptId, methodName, argsString); + InspectorBackend.dispatchOnInjectedScript(callId, this._worldId, methodName, argsString); }; } @@ -75,12 +87,12 @@ InjectedScriptAccess._installHandler = function(methodName, async) // - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function. // We keep these sorted. InjectedScriptAccess._installHandler("evaluate"); -InjectedScriptAccess._installHandler("evaluateAndStringify"); InjectedScriptAccess._installHandler("evaluateInCallFrame"); InjectedScriptAccess._installHandler("evaluateOnSelf"); InjectedScriptAccess._installHandler("getCompletions"); InjectedScriptAccess._installHandler("getProperties"); InjectedScriptAccess._installHandler("getPrototypes"); -InjectedScriptAccess._installHandler("openInInspectedWindow"); InjectedScriptAccess._installHandler("pushNodeToFrontend"); +InjectedScriptAccess._installHandler("resolveNode"); +InjectedScriptAccess._installHandler("getNodeProperties"); InjectedScriptAccess._installHandler("setPropertyValue"); diff --git a/WebCore/inspector/front-end/InspectorBackendStub.js b/WebCore/inspector/front-end/InspectorBackendStub.js deleted file mode 100644 index c87cb81..0000000 --- a/WebCore/inspector/front-end/InspectorBackendStub.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.InspectorBackendStub = function() -{ - this._registerDelegate("addInspectedNode"); - this._registerDelegate("addScriptToEvaluateOnLoad"); - this._registerDelegate("changeTagName"); - this._registerDelegate("clearConsoleMessages"); - this._registerDelegate("copyNode"); - this._registerDelegate("deleteCookie"); - this._registerDelegate("didEvaluateForTestInFrontend"); - this._registerDelegate("disableMonitoringXHR"); - this._registerDelegate("disableResourceTracking"); - this._registerDelegate("disableSearchingForNode"); - this._registerDelegate("disableTimeline"); - this._registerDelegate("dispatchOnInjectedScript"); - this._registerDelegate("enableMonitoringXHR"); - this._registerDelegate("enableResourceTracking"); - this._registerDelegate("enableSearchingForNode"); - this._registerDelegate("enableTimeline"); - this._registerDelegate("getApplicationCaches"); - this._registerDelegate("getChildNodes"); - this._registerDelegate("getCookies"); - this._registerDelegate("getDatabaseTableNames"); - this._registerDelegate("getDOMStorageEntries"); - this._registerDelegate("getEventListenersForNode"); - this._registerDelegate("getOuterHTML"); - this._registerDelegate("getProfile"); - this._registerDelegate("getProfileHeaders"); - this._registerDelegate("removeProfile"); - this._registerDelegate("clearProfiles"); - this._registerDelegate("getResourceContent"); - this._registerDelegate("highlightDOMNode"); - this._registerDelegate("hideDOMNodeHighlight"); - this._registerDelegate("performSearch"); - this._registerDelegate("pushNodeByPathToFrontend"); - this._registerDelegate("releaseWrapperObjectGroup"); - this._registerDelegate("removeAllScriptsToEvaluateOnLoad"); - this._registerDelegate("reloadPage"); - this._registerDelegate("removeAttribute"); - this._registerDelegate("removeDOMStorageItem"); - this._registerDelegate("removeNode"); - this._registerDelegate("saveApplicationSettings"); - this._registerDelegate("saveSessionSettings"); - this._registerDelegate("searchCanceled"); - this._registerDelegate("setAttribute"); - this._registerDelegate("setDOMStorageItem"); - this._registerDelegate("setInjectedScriptSource"); - this._registerDelegate("setOuterHTML"); - this._registerDelegate("setTextNodeValue"); - this._registerDelegate("startProfiling"); - this._registerDelegate("startTimelineProfiler"); - this._registerDelegate("stopProfiling"); - this._registerDelegate("stopTimelineProfiler"); - this._registerDelegate("storeLastActivePanel"); - this._registerDelegate("takeHeapSnapshot"); - this._registerDelegate("getProfilerLogLines"); - - this._registerDelegate("getAllStyles"); - this._registerDelegate("getStyles"); - this._registerDelegate("getComputedStyle"); - this._registerDelegate("getInlineStyle"); - this._registerDelegate("getStyleSheet"); - this._registerDelegate("getRuleRanges"); - this._registerDelegate("applyStyleText"); - this._registerDelegate("setStyleText"); - this._registerDelegate("setStyleProperty"); - this._registerDelegate("toggleStyleEnabled"); - this._registerDelegate("setRuleSelector"); - this._registerDelegate("addRule"); - - this._registerDelegate("disableDebugger"); - this._registerDelegate("editScriptSource"); - this._registerDelegate("getScriptSource"); - this._registerDelegate("enableDebugger"); - this._registerDelegate("setBreakpoint"); - this._registerDelegate("removeBreakpoint"); - this._registerDelegate("activateBreakpoints"); - this._registerDelegate("deactivateBreakpoints"); - this._registerDelegate("pause"); - this._registerDelegate("resume"); - this._registerDelegate("stepIntoStatement"); - this._registerDelegate("stepOutOfFunction"); - this._registerDelegate("stepOverStatement"); - this._registerDelegate("setPauseOnExceptionsState"); -} - -WebInspector.InspectorBackendStub.prototype = { - _registerDelegate: function(methodName) - { - this[methodName] = this.sendMessageToBackend.bind(this, methodName); - }, - - sendMessageToBackend: function() - { - var message = JSON.stringify(Array.prototype.slice.call(arguments)); - InspectorFrontendHost.sendMessageToBackend(message); - } -} - -InspectorBackend = new WebInspector.InspectorBackendStub(); diff --git a/WebCore/inspector/front-end/InspectorBackendStub.qrc b/WebCore/inspector/front-end/InspectorBackendStub.qrc new file mode 100644 index 0000000..30f6d75 --- /dev/null +++ b/WebCore/inspector/front-end/InspectorBackendStub.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/webkit/inspector"> + <file>InspectorBackendStub.js</file> +</qresource> +</RCC> + diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js index a32e799..aab9546 100644 --- a/WebCore/inspector/front-end/ObjectPropertiesSection.js +++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js @@ -50,7 +50,7 @@ WebInspector.ObjectPropertiesSection.prototype = { return; self.updateProperties(properties); }; - InjectedScriptAccess.get(this.object.injectedScriptId).getProperties(this.object, this.ignoreHasOwnProperty, true, callback); + this.object.getProperties(this.ignoreHasOwnProperty, true, callback); }, updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer) @@ -69,8 +69,10 @@ WebInspector.ObjectPropertiesSection.prototype = { this.propertiesTreeOutline.removeChildren(); - for (var i = 0; i < properties.length; ++i) + for (var i = 0; i < properties.length; ++i) { + properties[i].parentObject = this.object; this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i])); + } if (!this.propertiesTreeOutline.children.length) { var title = "<div class=\"info\">" + this.emptyPlaceholder + "</div>"; @@ -152,7 +154,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = { this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i])); } }; - InjectedScriptAccess.get(this.property.value.injectedScriptId).getProperties(this.property.value, false, true, callback.bind(this)); + this.property.value.getOwnProperties(true, callback.bind(this)); }, ondblclick: function(event) @@ -178,11 +180,9 @@ WebInspector.ObjectPropertyTreeElement.prototype = { this.valueElement = document.createElement("span"); this.valueElement.className = "value"; this.valueElement.textContent = this.property.value.description; - if (typeof this.property.value.propertyLength !== "undefined") - this.valueElement.textContent += " (" + this.property.value.propertyLength + ")"; if (this.property.isGetter) this.valueElement.addStyleClass("dimmed"); - if (this.property.isError) + if (this.property.value.isError()) this.valueElement.addStyleClass("error"); this.listItemElement.removeChildren(); @@ -260,7 +260,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = { self.updateSiblings(); } }; - InjectedScriptAccess.get(this.property.parentObjectProxy.injectedScriptId).setPropertyValue(this.property.parentObjectProxy, this.property.name, expression.trim(), callback); + this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback); } } diff --git a/WebCore/inspector/front-end/ObjectProxy.js b/WebCore/inspector/front-end/ObjectProxy.js deleted file mode 100644 index ef139c6..0000000 --- a/WebCore/inspector/front-end/ObjectProxy.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.ObjectProxy = function(injectedScriptId, objectId, path, description, hasChildren) -{ - this.objectId = objectId; - this.injectedScriptId = injectedScriptId; - this.path = path || []; - this.description = description; - this.hasChildren = hasChildren; -} - -WebInspector.ObjectProxy.wrapPrimitiveValue = function(value) -{ - var proxy = new WebInspector.ObjectProxy(); - proxy.type = typeof value; - proxy.description = value; - return proxy; -} - -WebInspector.ObjectProxy.getPropertiesAsync = function(objectProxy, propertiesToQueryFor, callback) -{ - function createPropertiesMapThenCallback(propertiesPayload) - { - if (!propertiesPayload) { - callback(); - return; - } - - var result = []; - for (var i = 0; i < propertiesPayload.length; ++i) - if (propertiesToQueryFor.indexOf(propertiesPayload[i].name) !== -1) - result[propertiesPayload[i].name] = propertiesPayload[i].value.description; - callback(result); - }; - InjectedScriptAccess.get(objectProxy.injectedScriptId).getProperties(objectProxy, true, false, createPropertiesMapThenCallback); -} - -WebInspector.ObjectPropertyProxy = function(name, value) -{ - this.name = name; - this.value = value; -} diff --git a/WebCore/inspector/front-end/PropertiesSidebarPane.js b/WebCore/inspector/front-end/PropertiesSidebarPane.js index 9df6448..75d6a48 100644 --- a/WebCore/inspector/front-end/PropertiesSidebarPane.js +++ b/WebCore/inspector/front-end/PropertiesSidebarPane.js @@ -48,17 +48,18 @@ WebInspector.PropertiesSidebarPane.prototype = { body.removeChildren(); self.sections = []; - var path = []; // Get array of prototype user-friendly names. for (var i = 0; i < prototypes.length; ++i) { - var prototype = new WebInspector.ObjectProxy(node.injectedScriptId, node.id, path.slice()); - var section = new WebInspector.ObjectPropertiesSection(prototype, prototypes[i], WebInspector.UIString("Prototype")); + var prototype = WebInspector.RemoteObject.fromPayload(prototypes[i]); + var title = prototype.description; + if (title.match(/Prototype$/)) + title = title.replace(/Prototype$/, ""); + var section = new WebInspector.ObjectPropertiesSection(prototype, title, WebInspector.UIString("Prototype")); self.sections.push(section); body.appendChild(section.element); - path.push("__proto__"); } }; - InjectedScriptAccess.get(node.injectedScriptId).getPrototypes(node.id, callback); + InjectedScriptAccess.getForNode(node).getPrototypes(node.id, callback); } } diff --git a/WebCore/inspector/front-end/RemoteObject.js b/WebCore/inspector/front-end/RemoteObject.js new file mode 100644 index 0000000..003d483 --- /dev/null +++ b/WebCore/inspector/front-end/RemoteObject.js @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.RemoteObject = function(objectId, type, description, hasChildren) +{ + this._objectId = objectId; + this._type = type; + this._description = description; + this._hasChildren = hasChildren; +} + +WebInspector.RemoteObject.fromPrimitiveValue = function(value) +{ + return new WebInspector.RemoteObject(null, typeof value, value); +} + +WebInspector.RemoteObject.resolveNode = function(node, callback) +{ + function mycallback(object) + { + callback(object ? WebInspector.RemoteObject.fromPayload(object) : null); + } + InjectedScriptAccess.getForNode(node).resolveNode(node.id, mycallback); +} + +WebInspector.RemoteObject.fromPayload = function(payload) +{ + if (typeof payload === "object") + return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.description, payload.hasChildren); + // FIXME: make sure we only get here with real payloads in the new DebuggerAgent.js. + return payload; +} + +WebInspector.RemoteObject.type = function(remoteObject) +{ + if (remoteObject === null) + return "null"; + + var type = typeof remoteObject; + if (type !== "object" && type !== "function") + return type; + + return remoteObject.type; +} + +WebInspector.RemoteObject.prototype = { + get objectId() + { + return this._objectId; + }, + + get type() + { + return this._type; + }, + + get description() + { + return this._description; + }, + + get hasChildren() + { + return this._hasChildren; + }, + + isError: function() + { + return this._type === "error"; + }, + + getOwnProperties: function(abbreviate, callback) + { + this.getProperties(false, abbreviate, callback); + }, + + getProperties: function(ignoreHasOwnProperty, abbreviate, callback) + { + if (!this._objectId) { + callback([]); + return; + } + function remoteObjectBinder(properties) + { + for (var i = 0; properties && i < properties.length; ++i) + properties[i].value = WebInspector.RemoteObject.fromPayload(properties[i].value); + callback(properties); + } + InjectedScriptAccess.getForObjectId(this._objectId).getProperties(this._objectId, ignoreHasOwnProperty, abbreviate, remoteObjectBinder); + }, + + setPropertyValue: function(name, value, callback) + { + if (!this._objectId) { + callback(false); + return; + } + InjectedScriptAccess.getForObjectId(this._objectId).setPropertyValue(this._objectId, name, value, callback); + }, + + pushNodeToFrontend: function(callback) + { + InjectedScriptAccess.getForObjectId(this._objectId).pushNodeToFrontend(this._objectId, callback); + } +} + +WebInspector.RemoteObjectProperty = function(name, value) +{ + this.name = name; + this.value = value; +} diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js index 9785644..01eefc7 100644 --- a/WebCore/inspector/front-end/ResourcesPanel.js +++ b/WebCore/inspector/front-end/ResourcesPanel.js @@ -1186,7 +1186,7 @@ WebInspector.ResourceSidebarTreeElement.prototype = { ondblclick: function(event) { - InjectedScriptAccess.getDefault().openInInspectedWindow(this.resource.url, function() {}); + InspectorBackend.openInInspectedWindow(this.resource.url); }, ondragstart: function(event) { diff --git a/WebCore/inspector/front-end/ScopeChainSidebarPane.js b/WebCore/inspector/front-end/ScopeChainSidebarPane.js index fdfcd38..d3190a9 100644 --- a/WebCore/inspector/front-end/ScopeChainSidebarPane.js +++ b/WebCore/inspector/front-end/ScopeChainSidebarPane.js @@ -60,7 +60,7 @@ WebInspector.ScopeChainSidebarPane.prototype = { emptyPlaceholder = WebInspector.UIString("No Variables"); subtitle = null; if (scopeObjectProxy.thisObject) - extraProperties = [ new WebInspector.ObjectPropertyProxy("this", scopeObjectProxy.thisObject) ]; + extraProperties = [ new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(scopeObjectProxy.thisObject)) ]; } else if (scopeObjectProxy.isClosure) { title = WebInspector.UIString("Closure"); emptyPlaceholder = WebInspector.UIString("No Variables"); @@ -77,7 +77,7 @@ WebInspector.ScopeChainSidebarPane.prototype = { if (!title || title === subtitle) subtitle = null; - var section = new WebInspector.ObjectPropertiesSection(scopeObjectProxy, title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement); + var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scopeObjectProxy), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement); section.editInSelectedCallFrameWhenPaused = true; section.pane = this; diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 44c1dba..8675f79 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -387,9 +387,9 @@ WebInspector.ScriptsPanel.prototype = { updateInterface = true; var self = this; - function updatingCallbackWrapper(result, exception) + function updatingCallbackWrapper(result) { - callback(result, exception); + callback(result); if (updateInterface) self.sidebarPanes.scopechain.update(selectedCallFrame); } @@ -401,9 +401,9 @@ WebInspector.ScriptsPanel.prototype = { function evalCallback(result) { if (result) - callback(result.value, result.isException); + callback(WebInspector.RemoteObject.fromPayload(result)); } - InjectedScriptAccess.get(callFrame.injectedScriptId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); + InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); }, debuggerPaused: function(callFrames) diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js index 73c3e2a..01a8ec2 100644 --- a/WebCore/inspector/front-end/SourceFrame.js +++ b/WebCore/inspector/front-end/SourceFrame.js @@ -625,9 +625,9 @@ WebInspector.SourceFrame.prototype = { popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true); } - function evaluateCallback(result, exception) + function evaluateCallback(result) { - if (exception) + if (result.isError()) return; if (!WebInspector.panels.scripts.paused) return; @@ -699,11 +699,11 @@ WebInspector.SourceFrame.prototype = { return; var expression = selection.getRangeAt(0).toString().trim(); - WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) { + WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result) { WebInspector.showConsole(); var commandMessage = new WebInspector.ConsoleCommand(expression); WebInspector.console.addMessage(commandMessage); - WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); + WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage)); }); }, diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index b530ab6..28dad23 100644 --- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -90,24 +90,10 @@ WebInspector.WatchExpressionsSection.NewWatchExpression = "\xA0"; WebInspector.WatchExpressionsSection.prototype = { update: function() { - function appendResult(expression, watchIndex, result, exception) + function appendResult(expression, watchIndex, result) { - if (exception) { - // Exception results are not wrappers, but text messages. - result = WebInspector.ObjectProxy.wrapPrimitiveValue(result); - } else if (result.type === "string") { - // Evaluation result is intentionally not abbreviated. However, we'd like to distinguish between null and "null" - result.description = "\"" + result.description + "\""; - } - - var property = new WebInspector.ObjectPropertyProxy(expression, result); + var property = new WebInspector.RemoteObjectProperty(expression, result); property.watchIndex = watchIndex; - property.isException = exception; - - // For newly added, empty expressions, set description to "", - // since otherwise you get DOMWindow - if (property.name === WebInspector.WatchExpressionsSection.NewWatchExpression) - property.value.description = ""; // To clarify what's going on here: // In the outer function, we calculate the number of properties @@ -222,7 +208,7 @@ WebInspector.WatchExpressionTreeElement.prototype = { { WebInspector.ObjectPropertyTreeElement.prototype.update.call(this); - if (this.property.isException) + if (this.property.value.isError()) this.valueElement.addStyleClass("watch-expressions-error-level"); var deleteButton = document.createElement("input"); diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index a54936c..4901857 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -46,13 +46,11 @@ <file>InjectedScript.js</file> <file>InjectedScriptAccess.js</file> <file>inspector.js</file> - <file>InspectorBackendStub.js</file> <file>InspectorFrontendHostStub.js</file> <file>KeyboardShortcut.js</file> <file>MetricsSidebarPane.js</file> <file>Object.js</file> <file>ObjectPropertiesSection.js</file> - <file>ObjectProxy.js</file> <file>Panel.js</file> <file>PanelEnablerView.js</file> <file>Placard.js</file> @@ -62,6 +60,7 @@ <file>ProfileView.js</file> <file>PropertiesSection.js</file> <file>PropertiesSidebarPane.js</file> + <file>RemoteObject.js</file> <file>Resource.js</file> <file>ResourceCategory.js</file> <file>ResourcesPanel.js</file> diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html index 48e95bb..14e2cdc 100644 --- a/WebCore/inspector/front-end/inspector.html +++ b/WebCore/inspector/front-end/inspector.html @@ -73,7 +73,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="SidebarTreeElement.js"></script> <script type="text/javascript" src="Section.js"></script> <script type="text/javascript" src="PropertiesSection.js"></script> - <script type="text/javascript" src="ObjectProxy.js"></script> + <script type="text/javascript" src="RemoteObject.js"></script> <script type="text/javascript" src="ObjectPropertiesSection.js"></script> <script type="text/javascript" src="BreakpointsSidebarPane.js"></script> <script type="text/javascript" src="CallStackSidebarPane.js"></script> diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index 4e8e633..fa57916 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -28,7 +28,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -function preloadImages() +// Keep this ; so that concatenated version of the script worked. +;(function preloadImages() { (new Image()).src = "Images/clearConsoleButtonGlyph.png"; (new Image()).src = "Images/consoleButtonGlyph.png"; @@ -45,9 +46,7 @@ function preloadImages() (new Image()).src = "Images/recordToggledButtonGlyph.png"; (new Image()).src = "Images/reloadButtonGlyph.png"; (new Image()).src = "Images/undockButtonGlyph.png"; -} - -preloadImages(); +})(); var WebInspector = { resources: {}, @@ -427,10 +426,39 @@ WebInspector.PlatformFlavor = { MacTiger: "mac-tiger", MacLeopard: "mac-leopard", MacSnowLeopard: "mac-snowleopard" -} +}; + +(function parseQueryParameters() +{ + WebInspector.queryParamsObject = {}; + var queryParams = window.location.search; + if (!queryParams) + return; + var params = queryParams.substring(1).split("&"); + for (var i = 0; i < params.length; ++i) { + var pair = params[i].split("="); + WebInspector.queryParamsObject[pair[0]] = pair[1]; + } +})(); WebInspector.loaded = function() { + if ("page" in WebInspector.queryParamsObject) { + WebInspector.socket = new WebSocket("ws://" + window.location.host + "/devtools/page/" + WebInspector.queryParamsObject.page); + WebInspector.socket.onmessage = function(message) { WebInspector_syncDispatch(message.data); } + WebInspector.socket.onerror = function(error) { console.error(error); } + WebInspector.socket.onopen = function() { + InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket); + InspectorFrontendHost.loaded = WebInspector.socket.send.bind(WebInspector.socket, "loaded"); + WebInspector.doLoadedDone(); + } + return; + } + WebInspector.doLoadedDone(); +} + +WebInspector.doLoadedDone = function() +{ InspectorBackend.setInjectedScriptSource("(" + injectedScriptConstructor + ");"); var platform = WebInspector.platform; @@ -581,6 +609,15 @@ WebInspector.dispatch = function() { setTimeout(delayDispatch, 0); } +// 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); +} + WebInspector.dispatchMessageFromBackend = function(arguments) { WebInspector.dispatch.apply(this, arguments); @@ -1109,6 +1146,11 @@ WebInspector.selectDatabase = function(o) WebInspector.panels.storage.selectDatabase(o); } +WebInspector.consoleMessagesCleared = function() +{ + WebInspector.console.clearMessages(); +} + WebInspector.selectDOMStorage = function(o) { WebInspector.showPanel("storage"); @@ -1470,7 +1512,7 @@ WebInspector.log = function(message, messageLevel) // return indication if we can actually log a message function isLogAvailable() { - return WebInspector.ConsoleMessage && WebInspector.ObjectProxy && self.console; + return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console; } // flush the queue of pending messages @@ -1510,7 +1552,7 @@ WebInspector.log = function(message, messageLevel) WebInspector.log.repeatCount = repeatCount; // ConsoleMessage expects a proxy object - message = new WebInspector.ObjectProxy(null, null, [], message, false); + message = new WebInspector.RemoteObject.fromPrimitiveValue(message); // post the message var msg = new WebInspector.ConsoleMessage( diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js index dd3e761..66cf284 100644 --- a/WebCore/inspector/front-end/utilities.js +++ b/WebCore/inspector/front-end/utilities.js @@ -26,18 +26,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -Object.proxyType = function(objectProxy) -{ - if (objectProxy === null) - return "null"; - - var type = typeof objectProxy; - if (type !== "object" && type !== "function") - return type; - - return objectProxy.type; -} - Object.properties = function(obj) { var properties = []; @@ -847,7 +835,7 @@ String.tokenizeFormatString = function(format) String.standardFormatters = { d: function(substitution) { - if (typeof substitution == "object" && Object.proxyType(substitution) === "number") + if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number") substitution = substitution.description; substitution = parseInt(substitution); return !isNaN(substitution) ? substitution : 0; @@ -855,7 +843,7 @@ String.standardFormatters = { f: function(substitution, token) { - if (typeof substitution == "object" && Object.proxyType(substitution) === "number") + if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) === "number") substitution = substitution.description; substitution = parseFloat(substitution); if (substitution && token.precision > -1) @@ -865,7 +853,7 @@ String.standardFormatters = { s: function(substitution) { - if (typeof substitution == "object" && Object.proxyType(substitution) !== "null") + if (typeof substitution == "object" && WebInspector.RemoteObject.type(substitution) !== "null") substitution = substitution.description; return substitution; }, |