diff options
author | Ben Murdoch <benm@google.com> | 2011-05-05 14:36:32 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-10 15:38:30 +0100 |
commit | f05b935882198ccf7d81675736e3aeb089c5113a (patch) | |
tree | 4ea0ca838d9ef1b15cf17ddb3928efb427c7e5a1 /WebCore/inspector | |
parent | 60fbdcc62bced8db2cb1fd233cc4d1e4ea17db1b (diff) | |
download | external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.zip external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.gz external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.bz2 |
Merge WebKit at r74534: Initial merge by git.
Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb
Diffstat (limited to 'WebCore/inspector')
81 files changed, 2993 insertions, 3216 deletions
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm index 177ca3b..e960ed6 100644 --- a/WebCore/inspector/CodeGeneratorInspector.pm +++ b/WebCore/inspector/CodeGeneratorInspector.pm @@ -19,16 +19,16 @@ $typeTransform{"Backend"} = { "header" => "InspectorBackend.h", "domainAccessor" => "m_inspectorController->inspectorBackend()", }; -$typeTransform{"Controller"} = { +$typeTransform{"Inspector"} = { "forwardHeader" => "InspectorController.h", "domainAccessor" => "m_inspectorController", }; -$typeTransform{"Debug"} = { +$typeTransform{"Debugger"} = { "forward" => "InspectorDebuggerAgent", "header" => "InspectorDebuggerAgent.h", "domainAccessor" => "m_inspectorController->debuggerAgent()", }; -$typeTransform{"Resource"} = { +$typeTransform{"Resources"} = { "forward" => "InspectorResourceAgent", "header" => "InspectorResourceAgent.h", "domainAccessor" => "m_inspectorController->m_resourceAgent", @@ -240,7 +240,7 @@ sub GenerateInterface push(@backendHead, " static bool getCommandName(const String& message, String* result);"); $backendConstructor = join("\n", @backendHead); $backendFooter = " InspectorController* m_inspectorController;"; - $backendTypes{"Controller"} = 1; + $backendTypes{"Inspector"} = 1; $backendTypes{"InspectorClient"} = 1; $backendTypes{"PassRefPtr"} = 1; $backendTypes{"Object"} = 1; @@ -282,6 +282,7 @@ sub generateFrontendFunction my $functionName = $function->signature->name; + my $domain = $function->signature->extendedAttributes->{"domain"} || "Inspector"; my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface. map($frontendTypes{$_->type} = 1, @argsFiltered); # register required types. my $arguments = join(", ", map($typeTransform{$_->type}->{"param"} . " " . $_->name, @argsFiltered)); # prepare arguments for function signature. @@ -295,6 +296,7 @@ sub generateFrontendFunction push(@function, "{"); push(@function, " RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();"); push(@function, " ${functionName}Message->setString(\"type\", \"event\");"); + push(@function, " ${functionName}Message->setString(\"domain\", \"$domain\");"); push(@function, " ${functionName}Message->setString(\"event\", \"$functionName\");"); push(@function, " RefPtr<InspectorObject> payloadDataObject = InspectorObject::create();"); my @pushArguments = map(" payloadDataObject->set" . $typeTransform{$_->type}->{"JSONType"} . "(\"" . $_->name . "\", " . $_->name . ");", @argsFiltered); @@ -340,7 +342,7 @@ sub generateBackendFunction push(@function, " RefPtr<InspectorArray> protocolErrors = InspectorArray::create();"); push(@function, ""); - my $domain = $function->signature->extendedAttributes->{"handler"} || "Controller"; + my $domain = $function->signature->extendedAttributes->{"domain"} || "Inspector"; my $domainAccessor = $typeTransform{$domain}->{"domainAccessor"}; $backendTypes{$domain} = 1; push(@function, " if (!$domainAccessor)"); @@ -377,6 +379,7 @@ sub generateBackendFunction push(@function, " if ((callId || protocolErrors->length()) && m_inspectorController->hasFrontend()) {"); push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();"); push(@function, " responseMessage->setNumber(\"seq\", callId);"); + push(@function, " responseMessage->setString(\"domain\", \"$domain\");"); push(@function, " responseMessage->setBoolean(\"success\", !protocolErrors->length());"); push(@function, ""); push(@function, " if (protocolErrors->length())"); @@ -547,7 +550,7 @@ sub generateBackendStubJS foreach my $function (@backendFunctions) { my $name = $function->signature->name; - my $domain = $function->signature->extendedAttributes->{"handler"}; + my $domain = $function->signature->extendedAttributes->{"domain"}; my $argumentNames = join(",", map("\"" . $_->name . "\": \"" . lc($typeTransform{$_->type}->{"JSONType"}) . "\"", grep($_->direction eq "in", @{$function->parameters}))); push(@JSStubs, " this._registerDelegate('{" . "\"seq\": 0, " . @@ -561,12 +564,34 @@ sub generateBackendStubJS my $inspectorBackendStubJS = << "EOF"; $licenseTemplate -WebInspector.InspectorBackendStub = function() +InspectorBackendStub = function() { + this._lastCallbackId = 1; + this._callbacks = {}; + this._domainDispatchers = {}; $JSStubs } -WebInspector.InspectorBackendStub.prototype = { +InspectorBackendStub.prototype = { + _wrap: function(callback) + { + var callbackId = this._lastCallbackId++; + this._callbacks[callbackId] = callback || function() {}; + return callbackId; + }, + + _processResponse: function(callbackId, args) + { + var callback = this._callbacks[callbackId]; + callback.apply(null, args); + delete this._callbacks[callbackId]; + }, + + _removeResponseCallbackEntry: function(callbackId) + { + delete this._callbacks[callbackId]; + }, + _registerDelegate: function(commandInfo) { var commandObject = JSON.parse(commandInfo); @@ -596,7 +621,7 @@ WebInspector.InspectorBackendStub.prototype = { console.error("Protocol Error: Optional callback argument for 'InspectorBackend.%s' call should be a function but its type is '%s'.", request.command, typeof args[0]); return; } - request.seq = WebInspector.Callback.wrap(args[0]); + request.seq = this._wrap(args[0]); } if (window.dumpInspectorProtocolMessages) @@ -604,10 +629,59 @@ WebInspector.InspectorBackendStub.prototype = { var message = JSON.stringify(request); InspectorFrontendHost.sendMessageToBackend(message); + }, + + registerDomainDispatcher: function(domain, dispatcher) + { + this._domainDispatchers[domain] = dispatcher; + }, + + dispatch: function(message) + { + if (window.dumpInspectorProtocolMessages) + console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message))); + + var messageObject = (typeof message === "string") ? JSON.parse(message) : message; + + var arguments = []; + if (messageObject.data) + for (var key in messageObject.data) + arguments.push(messageObject.data[key]); + + if ("seq" in messageObject) { // just a response for some request + if (messageObject.success) + this._processResponse(messageObject.seq, arguments); + else { + this._removeResponseCallbackEntry(messageObject.seq) + this.reportProtocolError(messageObject); + } + return; + } + + if (messageObject.type === "event") { + if (!(messageObject.domain in this._domainDispatchers)) { + console.error("Protocol Error: the message is for non-existing domain '%s'", messageObject.domain); + return; + } + var dispatcher = this._domainDispatchers[messageObject.domain]; + if (!(messageObject.event in dispatcher)) { + console.error("Protocol Error: Attempted to dispatch an unimplemented method '%s.%s'", messageObject.domain, messageObject.event); + return; + } + dispatcher[messageObject.event].apply(dispatcher, arguments); + } + }, + + reportProtocolError: function(messageObject) + { + console.error("Protocol Error: InspectorBackend request with seq = %d failed.", messageObject.seq); + for (var i = 0; i < messageObject.errors.length; ++i) + console.error(" " + messageObject.errors[i]); + this._removeResponseCallbackEntry(messageObject.seq); } } -InspectorBackend = new WebInspector.InspectorBackendStub(); +InspectorBackend = new InspectorBackendStub(); EOF return split("\n", $inspectorBackendStubJS); diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp index a5e9ec6..b22a6ef 100644 --- a/WebCore/inspector/ConsoleMessage.cpp +++ b/WebCore/inspector/ConsoleMessage.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009 Google Inc. All rights reserved. + * 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 @@ -33,6 +33,7 @@ #if ENABLE(INSPECTOR) +#include "Console.h" #include "InjectedScript.h" #include "InjectedScriptHost.h" #include "InspectorFrontend.h" @@ -40,40 +41,45 @@ #include "ScriptArguments.h" #include "ScriptCallStack.h" #include "ScriptValue.h" -#include <wtf/PassOwnPtr.h> namespace WebCore { -ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g) +ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, unsigned li, const String& u) : m_source(s) , m_type(t) , m_level(l) , m_message(m) , m_line(li) , m_url(u) - , m_groupLevel(g) , m_repeatCount(1) + , m_requestId(0) { } -ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, unsigned g) +ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack) : m_source(s) , m_type(t) , m_level(l) , m_message(m) , m_arguments(arguments) , m_callStack(callStack) - , m_groupLevel(g) + , m_line(0) + , m_url() , m_repeatCount(1) + , m_requestId(0) { - const ScriptCallFrame& lastCaller = m_callStack->at(0); - m_line = lastCaller.lineNumber(); - m_url = lastCaller.sourceURL(); - +} - bool storeTrace = (t == TraceMessageType || t == UncaughtExceptionMessageType || t == AssertMessageType); - if (!storeTrace) - m_callStack.clear(); +ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, const String& m, const String& responseUrl, unsigned long identifier) + : m_source(s) + , m_type(t) + , m_level(l) + , m_message(m) + , m_line(0) + , m_url(responseUrl) + , m_repeatCount(1) + , m_requestId(identifier) +{ } void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHost* injectedScriptHost) @@ -84,9 +90,10 @@ void ConsoleMessage::addToFrontend(InspectorFrontend* frontend, InjectedScriptHo jsonObj->setNumber("level", static_cast<int>(m_level)); jsonObj->setNumber("line", static_cast<int>(m_line)); jsonObj->setString("url", m_url); - jsonObj->setNumber("groupLevel", static_cast<int>(m_groupLevel)); jsonObj->setNumber("repeatCount", static_cast<int>(m_repeatCount)); jsonObj->setString("message", m_message); + if (m_type == NetworkErrorMessageType) + jsonObj->setNumber("requestId", m_requestId); if (m_arguments && m_arguments->argumentCount()) { InjectedScript injectedScript = injectedScriptHost->injectedScriptFor(m_arguments->globalState()); if (!injectedScript.hasNoValue()) { @@ -132,7 +139,7 @@ bool ConsoleMessage::isEqual(ConsoleMessage* msg) const && msg->m_message == m_message && msg->m_line == m_line && msg->m_url == m_url - && msg->m_groupLevel == m_groupLevel; + && msg->m_requestId == m_requestId; } } // namespace WebCore diff --git a/WebCore/inspector/ConsoleMessage.h b/WebCore/inspector/ConsoleMessage.h index 4e88bec..06a17d4 100644 --- a/WebCore/inspector/ConsoleMessage.h +++ b/WebCore/inspector/ConsoleMessage.h @@ -48,8 +48,9 @@ class ScriptValue; class ConsoleMessage : public Noncopyable { public: - ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u, unsigned g); - ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack>, unsigned g); + ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u); + ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack>); + ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, const String& responseUrl, unsigned long identifier); void addToFrontend(InspectorFrontend*, InjectedScriptHost*); void updateRepeatCountInConsole(InspectorFrontend* frontend); @@ -64,12 +65,12 @@ private: MessageType m_type; MessageLevel m_level; String m_message; - OwnPtr<ScriptArguments> m_arguments; - OwnPtr<ScriptCallStack> m_callStack; + RefPtr<ScriptArguments> m_arguments; + RefPtr<ScriptCallStack> m_callStack; unsigned m_line; String m_url; - unsigned m_groupLevel; unsigned m_repeatCount; + unsigned int m_requestId; }; } // namespace WebCore diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl index 8e48bfd..a593857 100644 --- a/WebCore/inspector/Inspector.idl +++ b/WebCore/inspector/Inspector.idl @@ -1,7 +1,6 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,225 +31,252 @@ module core { interface [Conditional=INSPECTOR] Inspector { - [notify] void addRecordToTimeline(out Object record); - [notify] void addNodesToSearchResult(out Array nodeIds); - [notify] void attributesUpdated(out long id, out Array attributes); - [notify] void bringToFront(); - [notify] void characterDataModified(out long id, out String newValue); - [notify] void childNodeCountUpdated(out long id, out int newValue); - [notify] void childNodeInserted(out long parentId, out long prevId, out Object node); - [notify] void childNodeRemoved(out long parentId, out long id); - [notify] void didCommitLoad(); - [notify] void evaluateForTestInFrontend(out long testCallId, out String script); - [notify] void disconnectFromBackend(); - [notify] void domContentEventFired(out double time); - [notify] void inspectedURLChanged(out String url); - [notify] void loadEventFired(out double time); - [notify] void reset(); - [notify] void resetProfilesPanel(); - [notify] void setChildNodes(out long parentId, out Array nodes); - [notify] void setDetachedRoot(out Object root); - [notify] void setDocument(out Value root); - [notify] void showPanel(out String panel); - [notify] void timelineProfilerWasStarted(); - [notify] void timelineProfilerWasStopped(); - [notify] void updateFocusedNode(out long nodeId); -#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER - [notify] void addProfileHeader(out Object header); - [notify] void attachDebuggerWhenShown(); - [notify] void debuggerWasEnabled(); - [notify] void debuggerWasDisabled(); - [notify] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage); - [notify] void parsedScriptSource(out String sourceID, out String url, out String data, out int firstLine, out int scriptWorldType); - [notify] void pausedScript(out Object details); - [notify] void profilerWasEnabled(); - [notify] void profilerWasDisabled(); - [notify] void restoredBreakpoint(out String sourceID, out String url, out int line, out boolean enabled, out String condition); - [notify] void resumedScript(); - [notify] void setRecordingProfile(out boolean isProfiling); - [notify] void updatePauseOnExceptionsState(out long state); -#endif + /////////////////////////////////////////////////////////////////////// + // generic Inspector's methods + /////////////////////////////////////////////////////////////////////// + + [domain=Backend] void setInjectedScriptSource(in String scriptSource); + // HUGE FIXME: we need to expose InjectedScript methods here. Or document InjectedScript capabilities. + [domain=Backend] void dispatchOnInjectedScript(in long injectedScriptId, in String methodName, in String arguments, out Value result, out boolean isException); + [domain=Inspector] void addScriptToEvaluateOnLoad(in String scriptSource); + [domain=Inspector] void removeAllScriptsToEvaluateOnLoad(); + [domain=Backend] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup); + [domain=Inspector] void getInspectorState(out Object state); + [domain=Inspector] void setMonitoringXHREnabled(in boolean enable, out boolean newState); + [domain=Inspector] void reloadPage(); + [domain=Inspector] void populateScriptObjects(); + + [domain=Inspector] void openInInspectedWindow(in String url); + [domain=Inspector] void setSearchingForNode(in boolean enabled, out boolean newState); + [notify, domain=Inspector] void addNodesToSearchResult(out Array nodeIds); + [notify, domain=Inspector] void bringToFront(); + [notify, domain=Inspector] void disconnectFromBackend(); + [notify, domain=Inspector] void inspectedURLChanged(out String url); + [notify, domain=Inspector] void domContentEventFired(out double time); + [notify, domain=Inspector] void loadEventFired(out double time); + [notify, domain=Inspector] void reset(); + [notify, domain=Inspector] void showPanel(out String panel); + + [notify, domain=Inspector] void evaluateForTestInFrontend(out long testCallId, out String script); + [domain=Inspector] void didEvaluateForTestInFrontend(in long testCallId, in String jsonResult); + + [domain=Inspector] void highlightDOMNode(in long nodeId); + [domain=Inspector] void hideDOMNodeHighlight(); + [domain=Inspector] void highlightFrame(in unsigned long frameId); + [domain=Inspector] void hideFrameHighlight(); + [notify, domain=Inspector] void updateFocusedNode(out long nodeId); + + /////////////////////////////////////////////////////////////////////// + // Console API + /////////////////////////////////////////////////////////////////////// + + [domain=Inspector] void setConsoleMessagesEnabled(in boolean enabled, out boolean newState); + [notify, domain=Inspector] void addConsoleMessage(out Object messageObj); + [notify, domain=Inspector] void updateConsoleMessageExpiredCount(out unsigned long count); + [notify, domain=Inspector] void updateConsoleMessageRepeatCount(out unsigned long count); + [domain=Inspector] void clearConsoleMessages(); + [notify, domain=Inspector] void consoleMessagesCleared(); + + /////////////////////////////////////////////////////////////////////// + // Resources API + /////////////////////////////////////////////////////////////////////// + + // FIXME: Network domain + [notify, domain=Resources] void identifierForInitialRequest(out long identifier, out String url, out Object loader, out Value callStack); + [notify, domain=Resources] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse); + [notify, domain=Resources] void markResourceAsCached(out long identifier); + [notify, domain=Resources] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response); + [notify, domain=Resources] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived); + [notify, domain=Resources] void didFinishLoading(out long identifier, out double finishTime); + [notify, domain=Resources] void didFailLoading(out long identifier, out double time, out String localizedDescription); + [notify, domain=Resources] void didLoadResourceFromMemoryCache(out double time, out Object resource); + [notify, domain=Resources] void setInitialContent(out long identifier, out String sourceString, out String type); + [notify, domain=Resources] void didCommitLoadForFrame(out Object frame, out Object loader); + [notify, domain=Resources] void frameDetachedFromParent(out unsigned long frameId); + + [domain=Inspector] void setExtraHeaders(in Object headers); + + [domain=Resources] void cachedResources(out Object resources); + [domain=Resources] void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out String content); + + [notify, domain=Resources] void didCreateWebSocket(out unsigned long identifier, out String requestURL); + [notify, domain=Resources] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request); + [notify, domain=Resources] void didReceiveWebSocketHandshakeResponse(out unsigned long identifier, out double time, out Object response); + [notify, domain=Resources] void didCloseWebSocket(out unsigned long identifier, out double time); + + // FIXME: Introduce new StorageDomain. + [domain=Inspector] void getCookies(out Array cookies, out String cookiesString); + [domain=Inspector] void deleteCookie(in String cookieName, in String domain); #if defined(ENABLE_DATABASE) && ENABLE_DATABASE - [notify] void addDatabase(out Object database); - [notify] void selectDatabase(out int databaseId); + [notify, domain=Resources] void addDatabase(out Object database); + [notify, domain=Resources] void selectDatabase(out int databaseId); + [domain=Backend] void getDatabaseTableNames(in long databaseId, out Array tableNames); + [domain=Backend] void executeSQL(in long databaseId, in String query, out boolean success, out long transactionId); + [notify, domain=Resources] void sqlTransactionSucceeded(out long transactionId, out Value columnNames, out Value values); + [notify, domain=Resources] void sqlTransactionFailed(out long transactionId, out Value sqlError); #endif #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE - [notify] void addDOMStorage(out Object storage); - [notify] void updateDOMStorage(out int storageId); - [notify] void selectDOMStorage(out int storageId); + [domain=Inspector] void getDOMStorageEntries(in long storageId, out Array entries); + [domain=Inspector] void setDOMStorageItem(in long storageId, in String key, in String value, out boolean success); + [domain=Inspector] void removeDOMStorageItem(in long storageId, in String key, out boolean success); + // FIXME: nuke these from resource manager asap, dispatch on StorageDomain. + [notify, domain=Resources] void addDOMStorage(out Object storage); + [notify, domain=Resources] void updateDOMStorage(out int storageId); + [notify, domain=Resources] void selectDOMStorage(out int storageId); #endif #if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS - [notify] void updateApplicationCacheStatus(out int status); - [notify] void updateNetworkState(out boolean isNowOnline); + [notify, domain=Resources] void updateApplicationCacheStatus(out int status); + [notify, domain=Resources] void updateNetworkState(out boolean isNowOnline); #endif -#if defined(ENABLE_WORKERS) && ENABLE_WORKERS - [notify] void didCreateWorker(out long id, out String url, out boolean isShared); - [notify] void didDestroyWorker(out long id); +#if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS + [domain=ApplicationCache] void getApplicationCaches(out Value applicationCaches); #endif +#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM + [domain=FileSystem] void getFileSystemPathAsync(in unsigned int type, in String origin); + [domain=FileSystem] void revealFolderInOS(in String path); - // This method is going to be broken down into smaller parts. - [handler=Controller] void populateScriptObjects(); - - [handler=Controller] void getInspectorState(out Object state); - - [handler=Controller] void setSearchingForNode(in boolean enabled, out boolean newState); - - [handler=Controller] void setMonitoringXHREnabled(in boolean enable, out boolean newState); - - [handler=Controller] void reloadPage(); - - [handler=Controller] void startTimelineProfiler(); - [handler=Controller] void stopTimelineProfiler(); - - [handler=Resource] void cachedResources(out Object resources); - [handler=Resource] void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out String content); - [notify] void identifierForInitialRequest(out long identifier, out String url, out Object loader); - [notify] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse); - [notify] void markResourceAsCached(out long identifier); - [notify] void didReceiveResponse(out long identifier, out double time, out String resourceType, out Object response); - [notify] void didReceiveContentLength(out long identifier, out double time, out long lengthReceived); - [notify] void didFinishLoading(out long identifier, out double finishTime); - [notify] void didFailLoading(out long identifier, out double time, out String localizedDescription); - [notify] void didLoadResourceFromMemoryCache(out double time, out Object resource); - [notify] void setInitialContent(out long identifier, out String sourceString, out String type); - [notify] void didCommitLoadForFrame(out Object frame, out Object loader); - [notify] void frameDetachedFromParent(out unsigned long frameId); + // FIXME: nuke these from resource manager asap, dispatch on FileSystem. + [notify, domain=Resources] void didGetFileSystemPath(out String root, out int type, out String origin); + [notify, domain=Resources] void didGetFileSystemError(out int type, out String origin); + [notify, domain=Resources] void didGetFileSystemDisabled(); +#endif - [notify] void didCreateWebSocket(out unsigned long identifier, out String requestURL); - [notify] void willSendWebSocketHandshakeRequest(out unsigned long identifier, out double time, out Object request); - [notify] void didReceiveWebSocketHandshakeResponse(out unsigned long identifier, out double time, out Object response); - [notify] void didCloseWebSocket(out unsigned long identifier, out double time); + /////////////////////////////////////////////////////////////////////// + // DOM API + /////////////////////////////////////////////////////////////////////// + + [domain=DOM] void getChildNodes(in long nodeId); + [domain=DOM] void setAttribute(in long elementId, in String name, in String value, out boolean success); + [domain=DOM] void removeAttribute(in long elementId, in String name, out boolean success); + [domain=DOM] void setTextNodeValue(in long nodeId, in String value, out boolean success); + [domain=DOM] void getEventListenersForNode(in long nodeId, out long outNodeId, out Array listenersArray); + [domain=DOM] void copyNode(in long nodeId); + [domain=DOM] void removeNode(in long nodeId, out long outNodeId); + [domain=DOM] void changeTagName(in long nodeId, in String newTagName, out long outNodeId); + [domain=DOM] void getOuterHTML(in long nodeId, out String outerHTML); + [domain=DOM] void setOuterHTML(in long nodeId, in String outerHTML, out long outNodeId); + [domain=DOM] void addInspectedNode(in long nodeId); + [domain=DOM] void performSearch(in String query, in boolean runSynchronously); + [domain=DOM] void searchCanceled(); + [domain=DOM] void pushNodeByPathToFrontend(in String path, out long nodeId); + + [notify, domain=DOM] void setDocument(out Value root); // FIXME: should be requested from the front-end as getDocument. + [notify, domain=DOM] void attributesUpdated(out long id, out Array attributes); + [notify, domain=DOM] void characterDataModified(out long id, out String newValue); + [notify, domain=DOM] void setChildNodes(out long parentId, out Array nodes); + [notify, domain=DOM] void setDetachedRoot(out Object root); + [notify, domain=DOM] void childNodeCountUpdated(out long id, out int newValue); + [notify, domain=DOM] void childNodeInserted(out long parentId, out long prevId, out Object node); + [notify, domain=DOM] void childNodeRemoved(out long parentId, out long id); + [notify, domain=DOM] void didCommitLoad(); + + /////////////////////////////////////////////////////////////////////// + // CSS API + /////////////////////////////////////////////////////////////////////// + + [domain=CSS] void getStylesForNode2(in long nodeId, out Value styles); + [domain=CSS] void getComputedStyleForNode2(in long nodeId, out Value style); + [domain=CSS] void getInlineStyleForNode2(in long nodeId, out Value style); + [domain=CSS] void getAllStyles2(out Array styleSheetIds); + [domain=CSS] void getStyleSheet2(in String styleSheetId, out Value styleSheet); + [domain=CSS] void getStyleSheetText2(in String styleSheetId, out String url, out String text); + [domain=CSS] void setStyleSheetText2(in String styleSheetId, in String text, out boolean success); + [domain=CSS] void setPropertyText2(in Object styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style); + [domain=CSS] void toggleProperty2(in Object styleId, in long propertyIndex, in boolean disable, out Value style); + [domain=CSS] void setRuleSelector2(in Object ruleId, in String selector, out Value rule); + [domain=CSS] void addRule2(in long contextNodeId, in String selector, out Value rule); + [domain=CSS] void getSupportedCSSProperties(out Array cssProperties); + [domain=CSS] void querySelectorAll(in long documentId, in String selector, out Array result); + + /////////////////////////////////////////////////////////////////////// + // Timeline API + /////////////////////////////////////////////////////////////////////// + + [domain=Inspector] void startTimelineProfiler(); + [domain=Inspector] void stopTimelineProfiler(); + [notify, domain=Timeline] void timelineProfilerWasStarted(); + [notify, domain=Timeline] void timelineProfilerWasStopped(); + [notify, domain=Timeline] void addRecordToTimeline(out Object record); #if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER - [handler=Backend] void enableDebugger(in boolean always); - [handler=Controller] void disableDebugger(in boolean always); - [handler=Debug] void setBreakpoint(in String sourceID, in unsigned int lineNumber, in boolean enabled, in String condition, out boolean success, out unsigned int actualLineNumber); - [handler=Debug] void removeBreakpoint(in String sourceID, in unsigned long lineNumber); - [handler=Debug] void activateBreakpoints(); - [handler=Debug] void deactivateBreakpoints(); + /////////////////////////////////////////////////////////////////////// + // Debugger API + /////////////////////////////////////////////////////////////////////// - [handler=Debug] void pause(); - [handler=Debug] void resume(); + [domain=Backend] void enableDebugger(in boolean always); + [domain=Inspector] void disableDebugger(in boolean always); // FIXME: should be on the same domain as enableDebugger. + [notify, domain=Debugger] void debuggerWasEnabled(); + [notify, domain=Debugger] void debuggerWasDisabled(); - [handler=Debug] void stepOverStatement(); - [handler=Debug] void stepIntoStatement(); - [handler=Debug] void stepOutOfFunction(); + [notify, domain=Debugger] void attachDebuggerWhenShown(); // FIXME: do something with this eventually. - [handler=Debug] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState); + [notify, domain=Debugger] void parsedScriptSource(out String sourceID, out String url, out String data, out int firstLine, out int scriptWorldType); + [notify, domain=Debugger] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage); - [handler=Debug] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames); - [handler=Debug] void getScriptSource(in String sourceID, out String scriptSource); + [domain=Debugger] void activateBreakpoints(); + [domain=Debugger] void deactivateBreakpoints(); - [handler=Controller] void setNativeBreakpoint(in Object breakpoint, out String breakpointId); - [handler=Controller] void removeNativeBreakpoint(in String breakpointId); + [domain=Debugger] void setBreakpoint(in String sourceID, in unsigned int lineNumber, in String condition, in boolean enabled, out String breakpointId, out unsigned int actualLineNumber); + [domain=Debugger] void removeBreakpoint(in String breakpointId); - [handler=Controller] void enableProfiler(in boolean always); - [handler=Controller] void disableProfiler(in boolean always); + [domain=Inspector] void setStickyBreakpoints(in Object breakpoints); // FIXME: Move to newly introduced BrowserDebugger. - [handler=Controller] void startProfiling(); - [handler=Controller] void stopProfiling(); + [domain=DOM] void setDOMBreakpoint(in long nodeId, in long type); // FIXME: Move to newly introduced BrowserDebugger. + [domain=DOM] void removeDOMBreakpoint(in long nodeId, in long type); // FIXME: Move to newly introduced BrowserDebugger. - [handler=Profiler] void getProfileHeaders(out Array headers); - [handler=Profiler] void getProfile(in String type, in unsigned long uid, out Object profile); + [domain=Inspector] void setEventListenerBreakpoint(in String eventName); // FIXME: Move to newly introduced BrowserDebugger. + [domain=Inspector] void removeEventListenerBreakpoint(in String eventName); // FIXME: Move to newly introduced BrowserDebugger. - [handler=Profiler] void removeProfile(in String type, in unsigned long uid); - [handler=Profiler] void clearProfiles(); + [domain=Inspector] void setXHRBreakpoint(in String url); // FIXME: Move to newly introduced BrowserDebugger. + [domain=Inspector] void removeXHRBreakpoint(in String url); // FIXME: Move to newly introduced BrowserDebugger. - [handler=Profiler] void takeHeapSnapshot(); -#endif - [handler=Backend] void setInjectedScriptSource(in String scriptSource); - [handler=Backend] void dispatchOnInjectedScript(in long injectedScriptId, in String methodName, in String arguments, out Value result, out boolean isException); - [handler=Controller] void addScriptToEvaluateOnLoad(in String scriptSource); - [handler=Controller] void removeAllScriptsToEvaluateOnLoad(); - - [handler=DOM] void getChildNodes(in long nodeId); - [handler=DOM] void setAttribute(in long elementId, in String name, in String value, out boolean success); - [handler=DOM] void removeAttribute(in long elementId, in String name, out boolean success); - [handler=DOM] void setTextNodeValue(in long nodeId, in String value, out boolean success); - [handler=DOM] void getEventListenersForNode(in long nodeId, out long outNodeId, out Array listenersArray); - [handler=DOM] void copyNode(in long nodeId); - [handler=DOM] void removeNode(in long nodeId, out long outNodeId); - [handler=DOM] void changeTagName(in long nodeId, in String newTagName, out long outNodeId); - [handler=DOM] void getOuterHTML(in long nodeId, out String outerHTML); - [handler=DOM] void setOuterHTML(in long nodeId, in String outerHTML, out long outNodeId); - [handler=DOM] void addInspectedNode(in long nodeId); - [handler=DOM] void performSearch(in String query, in boolean runSynchronously); - [handler=DOM] void searchCanceled(); - [handler=DOM] void pushNodeByPathToFrontend(in String path, out long nodeId); - - [handler=Controller] void setConsoleMessagesEnabled(in boolean enabled, out boolean newState); - [notify] void addConsoleMessage(out Object messageObj); - [notify] void updateConsoleMessageExpiredCount(out unsigned long count); - [notify] void updateConsoleMessageRepeatCount(out unsigned long count); - - [handler=Controller] void clearConsoleMessages(); - [notify] void consoleMessagesCleared(); - - [handler=Controller] void highlightDOMNode(in long nodeId); - [handler=Controller] void hideDOMNodeHighlight(); - [handler=Controller] void openInInspectedWindow(in String url); - - [handler=Controller] void highlightFrame(in unsigned long frameId); - [handler=Controller] void hideFrameHighlight(); - - [handler=DOM] void getStyles(in long nodeId, in boolean authOnly, out Value styles); - [handler=DOM] void getAllStyles(out Array styles); - [handler=DOM] void getInlineStyle(in long nodeId, out Value style); - [handler=DOM] void getComputedStyle(in long nodeId, out Value style); - [handler=DOM] void getStyleSheet(in long styleSheetId, out Object styleSheet); - [handler=DOM] void getStyleSourceData(in long styleSheetId, out Object styleSourceData); - [handler=DOM] void applyStyleText(in long styleId, in String styleText, in String propertyName, out boolean success, out Value style); - [handler=DOM] void setStyleText(in long styleId, in String styleText, out boolean success); - [handler=DOM] void setStyleProperty(in long styleId, in String name, in String value, out boolean success); - [handler=DOM] void toggleStyleEnabled(in long styleId, in String propertyName, in boolean disabled, out Value style); - [handler=DOM] void setRuleSelector(in long ruleId, in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode); - [handler=DOM] void addRule(in String selector, in long selectedNodeId, out Value rule, out boolean selectorAffectsNode); - - [handler=CSS] void getStylesForNode2(in long nodeId, out Value styles); - [handler=CSS] void getComputedStyleForNode2(in long nodeId, out Value style); - [handler=CSS] void getInlineStyleForNode2(in long nodeId, out Value style); - [handler=CSS] void getAllStyles2(out Array styleSheetIds); - [handler=CSS] void getStyleSheet2(in String styleSheetId, out Value styleSheet); - [handler=CSS] void getStyleSheetText2(in String styleSheetId, out String url, out String text); - [handler=CSS] void setStyleSheetText2(in String styleSheetId, in String text, out boolean success); - [handler=CSS] void setPropertyText2(in Object styleId, in long propertyIndex, in String text, in boolean overwrite, out Value style); - [handler=CSS] void toggleProperty2(in Object styleId, in long propertyIndex, in boolean disable, out Value style); - [handler=CSS] void setRuleSelector2(in Object ruleId, in String selector, out Value rule); - [handler=CSS] void addRule2(in long contextNodeId, in String selector, out Value rule); - [handler=CSS] void getSupportedCSSProperties(out Array cssProperties); - [handler=CSS] void querySelectorAll(in long documentId, in String selector, out Array result); - - [handler=Controller] void getCookies(out Array cookies, out String cookiesString); - [handler=Controller] void deleteCookie(in String cookieName, in String domain); + [domain=Debugger] void stepOverStatement(); // FIXME: rename to stepOver + [domain=Debugger] void stepIntoStatement(); // FIXME: rename to stepInto + [domain=Debugger] void stepOutOfFunction(); // FIXME: rename to stepOut + [domain=Debugger] void pause(); + [notify, domain=Debugger] void pausedScript(out Object details); + [domain=Debugger] void resume(); + [notify, domain=Debugger] void resumedScript(); // FIXME: Make this out parameter fo resume if possible. -#if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS - [handler=ApplicationCache] void getApplicationCaches(out Value applicationCaches); -#endif + [domain=Debugger] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState); -#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM - [handler=FileSystem] void getFileSystemPathAsync(in unsigned int type, in String origin); - [handler=FileSystem] void revealFolderInOS(in String path); - [notify] void didGetFileSystemPath(out String root, out int type, out String origin); - [notify] void didGetFileSystemError(out int type, out String origin); - [notify] void didGetFileSystemDisabled(); -#endif + [domain=Debugger] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames); + [domain=Debugger] void getScriptSource(in String sourceID, out String scriptSource); - [handler=Backend] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup); - [handler=Controller] void didEvaluateForTestInFrontend(in long testCallId, in String jsonResult); + [notify, domain=Debugger] void breakpointResolved(out String breakpointId, out String sourceID, out unsigned int lineNumber, out String condition, out boolean enabled, out unsigned int originalLineNumber); -#if defined(ENABLE_DATABASE) && ENABLE_DATABASE - [handler=Backend] void getDatabaseTableNames(in long databaseId, out Array tableNames); - [handler=Backend] void executeSQL(in long databaseId, in String query, out boolean success, out long transactionId); - [notify] void sqlTransactionSucceeded(out long transactionId, out Value columnNames, out Value values); - [notify] void sqlTransactionFailed(out long transactionId, out Value sqlError); -#endif - -#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE - [handler=Controller] void getDOMStorageEntries(in long storageId, out Array entries); - [handler=Controller] void setDOMStorageItem(in long storageId, in String key, in String value, out boolean success); - [handler=Controller] void removeDOMStorageItem(in long storageId, in String key, out boolean success); -#endif +#if defined(ENABLE_WORKERS) && ENABLE_WORKERS + [notify, domain=Debugger] void didCreateWorker(out long id, out String url, out boolean isShared); + [notify, domain=Debugger] void didDestroyWorker(out long id); +#endif // ENABLE_WORKERS + + /////////////////////////////////////////////////////////////////////// + // Profiler API + /////////////////////////////////////////////////////////////////////// + + [domain=Inspector] void enableProfiler(in boolean always); // FIXME: preferrable with Inspector domain, dispatched on backend. + [domain=Inspector] void disableProfiler(in boolean always); + [notify, domain=Profiler] void profilerWasEnabled(); + [notify, domain=Profiler] void profilerWasDisabled(); + + [domain=Inspector] void startProfiling(); // FIXME: dispatch on profiler agent. + [domain=Inspector] void stopProfiling(); // FIXME: dispatch on profiler agent. + + [domain=Profiler] void getProfileHeaders(out Array headers); + [domain=Profiler] void getProfile(in String type, in unsigned long uid, out Object profile); + [domain=Profiler] void removeProfile(in String type, in unsigned long uid); + [domain=Profiler] void clearProfiles(); + + // FIXME: split into Profiler and HeapProfiler. + [domain=Profiler] void takeHeapSnapshot(); + [notify, domain=Profiler] void addProfileHeader(out Object header); + [notify, domain=Profiler] void addHeapSnapshotChunk(out unsigned long uid, out String chunk); + [notify, domain=Profiler] void finishHeapSnapshot(out unsigned long uid); + [notify, domain=Profiler] void setRecordingProfile(out boolean isProfiling); + [notify, domain=Profiler] void resetProfiles(); + +#endif // ENABLE_JAVASCRIPT_DEBUGGER }; } diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp index 791e3a6..eb4c0e7 100644 --- a/WebCore/inspector/InspectorBackend.cpp +++ b/WebCore/inspector/InspectorBackend.cpp @@ -42,7 +42,6 @@ #include "InspectorDOMAgent.h" #include "InspectorFrontend.h" #include "InspectorStorageAgent.h" -#include "ScriptBreakpoint.h" #include "ScriptProfiler.h" #include "SerializedScriptValue.h" diff --git a/WebCore/inspector/InspectorCSSAgent.cpp b/WebCore/inspector/InspectorCSSAgent.cpp index ee06e54..31d951a 100644 --- a/WebCore/inspector/InspectorCSSAgent.cpp +++ b/WebCore/inspector/InspectorCSSAgent.cpp @@ -186,7 +186,7 @@ void InspectorCSSAgent::getStylesForNode2(long nodeId, RefPtr<InspectorValue>* r resultObject->setObject("inlineStyle", styleSheet->buildObjectForStyle(element->style())); RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true); // Support the viewing of :visited information in computed style. - RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0); + RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo.get(), 0); resultObject->setObject("computedStyle", computedInspectorStyle->buildObjectForStyle()); CSSStyleSelector* selector = element->ownerDocument()->styleSelector(); @@ -248,7 +248,7 @@ void InspectorCSSAgent::getComputedStyleForNode2(long nodeId, RefPtr<InspectorVa return; RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true); - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0); + RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo.get(), 0); *style = inspectorStyle->buildObjectForStyle(); } diff --git a/WebCore/inspector/InspectorCSSAgent.h b/WebCore/inspector/InspectorCSSAgent.h index 2d2efb5..f67d57d 100644 --- a/WebCore/inspector/InspectorCSSAgent.h +++ b/WebCore/inspector/InspectorCSSAgent.h @@ -46,6 +46,7 @@ class Element; class InspectorFrontend; class NameNodeMap; class Node; +class StyleBase; #if ENABLE(INSPECTOR) diff --git a/WebCore/inspector/InspectorCSSStore.cpp b/WebCore/inspector/InspectorCSSStore.cpp deleted file mode 100644 index 08634cb..0000000 --- a/WebCore/inspector/InspectorCSSStore.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "InspectorCSSStore.h" - -#if ENABLE(INSPECTOR) - -#include "CSSMutableStyleDeclaration.h" -#include "CSSParser.h" -#include "CSSRuleList.h" -#include "CSSStyleDeclaration.h" -#include "CSSStyleRule.h" -#include "CSSStyleSheet.h" -#include "CachedResource.h" -#include "DocumentLoader.h" -#include "Element.h" -#include "Frame.h" -#include "HTMLHeadElement.h" -#include "InspectorController.h" -#include "InspectorResourceAgent.h" -#include "Node.h" -#include "PlatformString.h" -#include "SharedBuffer.h" -#include "StyleSheetList.h" -#include "TextEncoding.h" - -namespace WebCore { - -InspectorCSSStore::InspectorCSSStore(InspectorController* inspectorController) - : m_inspectorController(inspectorController) - , m_lastStyleId(1) - , m_lastStyleSheetId(1) - , m_lastRuleId(1) -{ -} - -InspectorCSSStore::~InspectorCSSStore() -{ -} - -void InspectorCSSStore::reset() -{ - m_styleToId.clear(); - m_idToStyle.clear(); - m_ruleToId.clear(); - m_idToRule.clear(); - deleteAllValues(m_styleSheetToOffsets); - m_styleSheetToOffsets.clear(); - m_styleSheetToId.clear(); - m_idToStyleSheet.clear(); - m_idToStyleSheetText.clear(); - m_idToDisabledStyle.clear(); - m_documentNodeToInspectorStyleSheetMap.clear(); - - m_lastStyleId = 1; - m_lastStyleSheetId = 1; - m_lastRuleId = 1; -} - -void InspectorCSSStore::removeDocument(Document* doc) -{ - m_documentNodeToInspectorStyleSheetMap.remove(doc); -} - -CSSStyleSheet* InspectorCSSStore::inspectorStyleSheet(Document* ownerDocument, bool createIfAbsent) -{ - DocumentToStyleSheetMap::iterator it = m_documentNodeToInspectorStyleSheetMap.find(ownerDocument); - if (it != m_documentNodeToInspectorStyleSheetMap.end()) - return it->second.get(); - if (!createIfAbsent) - return 0; - ExceptionCode ec = 0; - RefPtr<Element> styleElement = ownerDocument->createElement("style", ec); - if (!ec) - styleElement->setAttribute("type", "text/css", ec); - if (!ec) - ownerDocument->head()->appendChild(styleElement, ec); - if (ec) - return 0; - StyleSheetList* styleSheets = ownerDocument->styleSheets(); - StyleSheet* styleSheet = styleSheets->item(styleSheets->length() - 1); - if (!styleSheet->isCSSStyleSheet()) - return 0; - CSSStyleSheet* inspectorStyleSheet = static_cast<CSSStyleSheet*>(styleSheet); - m_documentNodeToInspectorStyleSheetMap.set(ownerDocument, inspectorStyleSheet); - return inspectorStyleSheet; -} - -String InspectorCSSStore::styleSheetText(long styleSheetId) -{ - IdToStyleSheetTextMap::iterator it = m_idToStyleSheetText.find(styleSheetId); - if (it != m_idToStyleSheetText.end()) - return it->second; - - CSSStyleSheet* styleSheet = styleSheetForId(styleSheetId); - if (!styleSheet) - return String(); - - String result; - bool success = false; - Node* ownerNode = styleSheet->ownerNode(); - if (ownerNode && ownerNode->nodeType() == Node::ELEMENT_NODE) { - Element* ownerElement = static_cast<Element*>(ownerNode); - if (ownerElement->tagName().lower() == "style") { - result = inlineStyleSheetText(styleSheet); - success = true; - } - } - if (!success) - success = resourceStyleSheetText(styleSheet, &result); - - if (success) - m_idToStyleSheetText.set(styleSheetId, result); - return result; -} - -bool InspectorCSSStore::resourceStyleSheetText(CSSStyleSheet* styleSheet, String* result) -{ - return InspectorResourceAgent::resourceContent(styleSheet->document()->frame(), styleSheet->finalURL(), result); -} - -String InspectorCSSStore::inlineStyleSheetText(CSSStyleSheet* styleSheet) -{ - Node* ownerNode = styleSheet->ownerNode(); - if (!ownerNode || ownerNode->nodeType() != Node::ELEMENT_NODE || m_styleSheetToId.find(styleSheet) == m_styleSheetToId.end()) - return String(); - Element* ownerElement = static_cast<Element*>(ownerNode); - if (ownerElement->tagName().lower() != "style") - return String(); - return ownerElement->innerText(); -} - - -// All ranges are: [start; end) (start - inclusive, end - exclusive). -bool InspectorCSSStore::getRuleSourceData(CSSStyleDeclaration* style, RefPtr<CSSRuleSourceData>* result) -{ - if (!style) - return false; - - Element* element = inlineStyleElement(style); - if (element) { - // Inline: style="...". - RefPtr<CSSRuleSourceData> ruleSourceData = CSSRuleSourceData::create(); - RefPtr<CSSStyleSourceData> styleSourceData = CSSStyleSourceData::create(); - bool success = getStyleAttributeRanges(element, &styleSourceData); - if (!success) - return false; - ruleSourceData->styleSourceData = styleSourceData.release(); - *result = ruleSourceData; - return true; - } - - CSSStyleSheet* styleSheet = getParentStyleSheet(style); - if (!styleSheet) - return false; - - Vector<RefPtr<CSSRuleSourceData> >* rangesVector = 0; - StyleSheetToOffsetsMap::iterator it = m_styleSheetToOffsets.find(styleSheet); - if (it == m_styleSheetToOffsets.end()) { - String text = styleSheetText(bindStyleSheet(styleSheet)); - if (!text.isEmpty()) { - RefPtr<CSSStyleSheet> newStyleSheet = CSSStyleSheet::create(styleSheet->ownerNode()); - CSSParser p; - StyleRuleRangeMap ruleRangeMap; - p.parseSheet(newStyleSheet.get(), text, 0, &ruleRangeMap); - rangesVector = new Vector<RefPtr<CSSRuleSourceData> >; - extractRanges(newStyleSheet.get(), ruleRangeMap, rangesVector); - m_styleSheetToOffsets.set(styleSheet, rangesVector); - } - } else - rangesVector = it->second; - if (!rangesVector) - return false; - - unsigned ruleIndex = 0; - for (unsigned i = 0, length = styleSheet->length(); i < length; ++i) { - CSSStyleRule* rule = asCSSStyleRule(styleSheet->item(i)); - if (!rule) - continue; - if (rule->style() == style) { - ASSERT(ruleIndex < rangesVector->size()); - *result = rangesVector->at(ruleIndex); - return true; - } - ruleIndex++; - } - return false; -} - -void InspectorCSSStore::extractRanges(CSSStyleSheet* styleSheet, const StyleRuleRangeMap& ruleRangeMap, Vector<RefPtr<CSSRuleSourceData> >* rangesVector) -{ - for (unsigned i = 0, length = styleSheet->length(); i < length; ++i) { - CSSStyleRule* rule = asCSSStyleRule(styleSheet->item(i)); - if (!rule) - continue; - StyleRuleRangeMap::const_iterator it = ruleRangeMap.find(rule); - if (it != ruleRangeMap.end()) - rangesVector->append(it->second); - } -} - -bool InspectorCSSStore::getStyleAttributeRanges(Node* node, RefPtr<CSSStyleSourceData>* result) -{ - if (!node || !node->isStyledElement()) - return false; - - String styleText = static_cast<StyledElement*>(node)->getAttribute("style"); - if (styleText.isEmpty()) { - (*result)->styleBodyRange.start = 0; - (*result)->styleBodyRange.end = 0; - return true; - } - - RefPtr<CSSMutableStyleDeclaration> tempDeclaration = CSSMutableStyleDeclaration::create(); - CSSParser p; - p.parseDeclaration(tempDeclaration.get(), styleText, result); - return true; -} - -CSSStyleSheet* InspectorCSSStore::getParentStyleSheet(CSSStyleDeclaration* style) -{ - if (!style) - return 0; - - StyleSheet* styleSheet = style->stylesheet(); - if (styleSheet && styleSheet->isCSSStyleSheet()) - return static_cast<CSSStyleSheet*>(styleSheet); - - return 0; -} - -CSSStyleRule* InspectorCSSStore::asCSSStyleRule(StyleBase* styleBase) -{ - if (!styleBase->isStyleRule()) - return 0; - CSSRule* rule = static_cast<CSSRule*>(styleBase); - if (rule->type() != CSSRule::STYLE_RULE) - return 0; - return static_cast<CSSStyleRule*>(rule); -} - -DisabledStyleDeclaration* InspectorCSSStore::disabledStyleForId(long styleId, bool createIfAbsent) -{ - IdToDisabledStyleMap::iterator it = m_idToDisabledStyle.find(styleId); - if (it == m_idToDisabledStyle.end() && createIfAbsent) - it = m_idToDisabledStyle.set(styleId, DisabledStyleDeclaration()).first; - return it == m_idToDisabledStyle.end() ? 0 : &(it->second); -} - -CSSStyleDeclaration* InspectorCSSStore::styleForId(long styleId) -{ - IdToStyleMap::iterator it = m_idToStyle.find(styleId); - return it == m_idToStyle.end() ? 0 : it->second.get(); -} - -CSSStyleSheet* InspectorCSSStore::styleSheetForId(long styleSheetId) -{ - IdToStyleSheetMap::iterator it = m_idToStyleSheet.find(styleSheetId); - return it == m_idToStyleSheet.end() ? 0 : it->second.get(); -} - -CSSStyleRule* InspectorCSSStore::ruleForId(long ruleId) -{ - IdToRuleMap::iterator it = m_idToRule.find(ruleId); - return it == m_idToRule.end() ? 0 : it->second.get(); -} - -long InspectorCSSStore::bindStyle(CSSStyleDeclaration* style) -{ - long id = m_styleToId.get(style); - if (!id) { - id = m_lastStyleId++; - m_idToStyle.set(id, style); - m_styleToId.set(style, id); - } - return id; -} - -long InspectorCSSStore::bindStyleSheet(CSSStyleSheet* styleSheet) -{ - long id = m_styleSheetToId.get(styleSheet); - if (!id) { - id = m_lastStyleSheetId++; - m_idToStyleSheet.set(id, styleSheet); - m_styleSheetToId.set(styleSheet, id); - } - return id; -} - -long InspectorCSSStore::bindRule(CSSStyleRule* rule) -{ - long id = m_ruleToId.get(rule); - if (!id) { - id = m_lastRuleId++; - m_idToRule.set(id, rule); - m_ruleToId.set(rule, id); - } - return id; -} - -// static -Element* InspectorCSSStore::inlineStyleElement(CSSStyleDeclaration* style) -{ - if (!style || !style->isMutableStyleDeclaration()) - return 0; - Node* node = static_cast<CSSMutableStyleDeclaration*>(style)->node(); - if (!node || !node->isStyledElement() || static_cast<StyledElement*>(node)->getInlineStyleDecl() != style) - return 0; - return static_cast<Element*>(node); -} - -} // namespace WebCore - -#endif // ENABLE(INSPECTOR) diff --git a/WebCore/inspector/InspectorCSSStore.h b/WebCore/inspector/InspectorCSSStore.h deleted file mode 100644 index 0414b58..0000000 --- a/WebCore/inspector/InspectorCSSStore.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InspectorCSSStore_h -#define InspectorCSSStore_h - -#include "CSSPropertySourceData.h" -#include "MemoryCache.h" - -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/RefPtr.h> - -namespace WebCore { - -class CSSMutableStyleDeclaration; -class CSSStyleDeclaration; -class CSSRuleList; -class CSSStyleRule; -class CSSStyleSheet; -class Document; -class Element; -class InspectorController; -class Node; -class StyleBase; - -typedef std::pair<String, String> PropertyValueAndPriority; -typedef HashMap<String, PropertyValueAndPriority> DisabledStyleDeclaration; -typedef HashMap<CSSStyleDeclaration*, long> StyleToIdMap; -typedef HashMap<long, RefPtr<CSSStyleDeclaration> > IdToStyleMap; -typedef HashMap<CSSStyleRule*, long> RuleToIdMap; -typedef HashMap<long, RefPtr<CSSStyleRule> > IdToRuleMap; -typedef HashMap<CSSStyleSheet*, Vector<RefPtr<CSSRuleSourceData> >* > StyleSheetToOffsetsMap; -typedef HashMap<CSSStyleSheet*, long> StyleSheetToIdMap; -typedef HashMap<long, RefPtr<CSSStyleSheet> > IdToStyleSheetMap; -typedef HashMap<long, String> IdToStyleSheetTextMap; -typedef HashMap<long, DisabledStyleDeclaration> IdToDisabledStyleMap; -typedef HashMap<RefPtr<Document>, RefPtr<CSSStyleSheet> > DocumentToStyleSheetMap; - -class InspectorCSSStore { - -public: - static CSSStyleSheet* getParentStyleSheet(CSSStyleDeclaration*); - static Element* inlineStyleElement(CSSStyleDeclaration*); - - InspectorCSSStore(InspectorController* inspectorController); - ~InspectorCSSStore(); - void reset(); - bool getRuleSourceData(CSSStyleDeclaration*, RefPtr<CSSRuleSourceData>* result); - CSSStyleDeclaration* styleForId(long styleId); - CSSStyleSheet* styleSheetForId(long styleSheetId); - CSSStyleRule* ruleForId(long styleRuleId); - DisabledStyleDeclaration* disabledStyleForId(long styleId, bool createIfAbsent); - String styleSheetText(long styleSheetId); - CSSStyleSheet* inspectorStyleSheet(Document* ownerDocument, bool createIfAbsent); - void removeDocument(Document*); - - long bindRule(CSSStyleRule* rule); - long bindStyle(CSSStyleDeclaration* style); - long bindStyleSheet(CSSStyleSheet* styleSheet); - -private: - static CSSStyleRule* asCSSStyleRule(StyleBase*); - String inlineStyleSheetText(CSSStyleSheet*); - bool resourceStyleSheetText(CSSStyleSheet*, String* result); - void extractRanges(CSSStyleSheet*, const StyleRuleRangeMap&, Vector<RefPtr<CSSRuleSourceData> >* rangesVector); - bool getStyleAttributeRanges(Node* parentNode, RefPtr<CSSStyleSourceData>* result); - - StyleToIdMap m_styleToId; - IdToStyleMap m_idToStyle; - RuleToIdMap m_ruleToId; - IdToRuleMap m_idToRule; - StyleSheetToOffsetsMap m_styleSheetToOffsets; - StyleSheetToIdMap m_styleSheetToId; - IdToDisabledStyleMap m_idToDisabledStyle; - IdToStyleSheetMap m_idToStyleSheet; - IdToStyleSheetTextMap m_idToStyleSheetText; - DocumentToStyleSheetMap m_documentNodeToInspectorStyleSheetMap; - - InspectorController* m_inspectorController; - long m_lastStyleId; - long m_lastStyleSheetId; - long m_lastRuleId; -}; - -} // namespace WebCore - -#endif // !defined(InspectorCSSStore_h) diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp index d0ae442..8355cdf 100644 --- a/WebCore/inspector/InspectorController.cpp +++ b/WebCore/inspector/InspectorController.cpp @@ -53,13 +53,13 @@ #include "FrameView.h" #include "GraphicsContext.h" #include "HTMLFrameOwnerElement.h" +#include "HTTPHeaderMap.h" #include "HitTestResult.h" #include "InjectedScript.h" #include "InjectedScriptHost.h" #include "InspectorBackend.h" #include "InspectorBackendDispatcher.h" #include "InspectorCSSAgent.h" -#include "InspectorCSSStore.h" #include "InspectorClient.h" #include "InspectorDOMAgent.h" #include "InspectorDOMStorageResource.h" @@ -125,10 +125,6 @@ using namespace std; namespace WebCore { -static const char* const domNativeBreakpointType = "DOM"; -static const char* const eventListenerNativeBreakpointType = "EventListener"; -static const char* const xhrNativeBreakpointType = "XHR"; - const char* const InspectorController::ElementsPanel = "elements"; const char* const InspectorController::ConsolePanel = "console"; const char* const InspectorController::ScriptsPanel = "scripts"; @@ -144,10 +140,8 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_client(client) , m_openingFrontend(false) , m_cssAgent(new InspectorCSSAgent()) - , m_cssStore(new InspectorCSSStore(this)) , m_mainResourceIdentifier(0) , m_expiredConsoleMessageCount(0) - , m_groupLevel(0) , m_previousMessage(0) , m_settingsLoaded(false) , m_inspectorBackend(InspectorBackend::create(this)) @@ -155,7 +149,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client) , m_injectedScriptHost(InjectedScriptHost::create(this)) #if ENABLE(JAVASCRIPT_DEBUGGER) , m_attachDebuggerWhenShown(false) - , m_lastBreakpointId(0) + , m_hasXHRBreakpointWithEmptyURL(false) , m_profilerAgent(InspectorProfilerAgent::create(this)) #endif { @@ -330,12 +324,12 @@ void InspectorController::setConsoleMessagesEnabled(bool enabled) m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get()); } -void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack) +void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack) { if (!enabled()) return; - addConsoleMessage(new ConsoleMessage(source, type, level, message, arguments, callStack, m_groupLevel)); + addConsoleMessage(new ConsoleMessage(source, type, level, message, arguments, callStack)); } void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID) @@ -343,7 +337,7 @@ void InspectorController::addMessageToConsole(MessageSource source, MessageType if (!enabled()) return; - addConsoleMessage(new ConsoleMessage(source, type, level, message, lineNumber, sourceID, m_groupLevel)); + addConsoleMessage(new ConsoleMessage(source, type, level, message, lineNumber, sourceID)); } void InspectorController::addConsoleMessage(PassOwnPtr<ConsoleMessage> consoleMessage) @@ -373,7 +367,6 @@ void InspectorController::clearConsoleMessages() m_consoleMessages.clear(); m_expiredConsoleMessageCount = 0; m_previousMessage = 0; - m_groupLevel = 0; m_injectedScriptHost->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console"); if (m_domAgent) m_domAgent->releaseDanglingNodes(); @@ -381,21 +374,14 @@ void InspectorController::clearConsoleMessages() m_frontend->consoleMessagesCleared(); } -void InspectorController::startGroup(PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack> callStack, bool collapsed) +void InspectorController::startGroup(PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack, bool collapsed) { - ++m_groupLevel; - - addConsoleMessage(new ConsoleMessage(JSMessageSource, collapsed ? StartGroupCollapsedMessageType : StartGroupMessageType, LogMessageLevel, "", arguments, callStack, m_groupLevel)); + addConsoleMessage(new ConsoleMessage(JSMessageSource, collapsed ? StartGroupCollapsedMessageType : StartGroupMessageType, LogMessageLevel, "", arguments, callStack)); } void InspectorController::endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL) { - if (!m_groupLevel) - return; - - --m_groupLevel; - - addConsoleMessage(new ConsoleMessage(source, EndGroupMessageType, LogMessageLevel, String(), lineNumber, sourceURL, m_groupLevel)); + addConsoleMessage(new ConsoleMessage(source, EndGroupMessageType, LogMessageLevel, String(), lineNumber, sourceURL)); } void InspectorController::markTimeline(const String& message) @@ -484,7 +470,7 @@ void InspectorController::connectFrontend() m_openingFrontend = false; releaseFrontendLifetimeAgents(); m_frontend = new InspectorFrontend(m_client); - m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), m_frontend.get()); + m_domAgent = InspectorDOMAgent::create(m_frontend.get()); m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get()); m_cssAgent->setDOMAgent(m_domAgent.get()); @@ -575,7 +561,6 @@ void InspectorController::disconnectFrontend() bool debuggerWasEnabled = debuggerEnabled(); disableDebugger(); m_attachDebuggerWhenShown = debuggerWasEnabled; - clearNativeBreakpoints(); #endif setSearchingForNode(false); unbindAllResources(); @@ -590,6 +575,7 @@ void InspectorController::disconnectFrontend() releaseFrontendLifetimeAgents(); m_timelineAgent.clear(); + m_extraHeaders.clear(); } void InspectorController::releaseFrontendLifetimeAgents() @@ -653,7 +639,7 @@ void InspectorController::populateScriptObjects() for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) it->second->bind(m_frontend.get()); #endif -#if ENABLE(WORKERS) +#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS) WorkersMap::iterator workersEnd = m_workers.end(); for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it) { InspectorWorkerResource* worker = it->second.get(); @@ -732,10 +718,10 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) m_counts.clear(); #if ENABLE(JAVASCRIPT_DEBUGGER) - if (m_debuggerAgent) + if (m_debuggerAgent) { m_debuggerAgent->clearForPageNavigation(); - - clearNativeBreakpoints(); + restoreStickyBreakpoints(); + } #endif #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) @@ -747,7 +733,6 @@ void InspectorController::didCommitLoad(DocumentLoader* loader) // resources are cleared so that it has a chance to unbind them. unbindAllResources(); - m_cssStore->reset(); if (m_frontend) { m_frontend->reset(); m_domAgent->reset(); @@ -839,15 +824,21 @@ void InspectorController::willSendRequest(unsigned long identifier, ResourceRequ if (!enabled()) return; - // Only enable load timing and raw headers if front-end is attached, as otherwise we may produce overhead. - // permissions to fetch the headers. + request.setReportLoadTiming(true); + if (m_frontend) { - request.setReportLoadTiming(true); + // Only enable raw headers if front-end is attached, as otherwise we may lack + // permissions to fetch the headers. request.setReportRawHeaders(true); + + if (m_extraHeaders) { + HTTPHeaderMap::const_iterator end = m_extraHeaders->end(); + for (HTTPHeaderMap::const_iterator it = m_extraHeaders->begin(); it != end; ++it) + request.setHTTPHeaderField(it->first, it->second); + } } bool isMainResource = m_mainResourceIdentifier == identifier; - if (m_timelineAgent) m_timelineAgent->willSendResourceRequest(identifier, isMainResource, request); @@ -874,7 +865,7 @@ void InspectorController::didReceiveResponse(unsigned long identifier, DocumentL if (response.httpStatusCode() >= 400) { String message = makeString("Failed to load resource: the server responded with a status of ", String::number(response.httpStatusCode()), " (", response.httpStatusText(), ')'); - addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, response.url().string()); + addConsoleMessage(new ConsoleMessage(OtherMessageSource, NetworkErrorMessageType, ErrorMessageLevel, message, response.url().string(), identifier)); } } @@ -910,7 +901,7 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc String message = "Failed to load resource"; if (!error.localizedDescription().isEmpty()) message += ": " + error.localizedDescription(); - addMessageToConsole(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 0, error.failingURL()); + addConsoleMessage(new ConsoleMessage(OtherMessageSource, NetworkErrorMessageType, ErrorMessageLevel, message, error.failingURL(), identifier)); if (m_resourceAgent) m_resourceAgent->didFailLoading(identifier, error); @@ -1006,6 +997,7 @@ void InspectorController::postWorkerNotificationToFrontend(const InspectorWorker { if (!m_frontend) return; +#if ENABLE(JAVASCRIPT_DEBUGGER) switch (action) { case InspectorController::WorkerCreated: m_frontend->didCreateWorker(worker.id(), worker.url(), worker.isSharedWorker()); @@ -1014,6 +1006,7 @@ void InspectorController::postWorkerNotificationToFrontend(const InspectorWorker m_frontend->didDestroyWorker(worker.id()); break; } +#endif } void InspectorController::didCreateWorker(intptr_t id, const String& url, bool isSharedWorker) @@ -1355,6 +1348,7 @@ void InspectorController::enableDebuggerFromFrontend(bool always) ASSERT(m_inspectedPage); m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get()); + restoreStickyBreakpoints(); m_frontend->debuggerWasEnabled(); } @@ -1399,82 +1393,118 @@ void InspectorController::resume() m_debuggerAgent->resume(); } -void InspectorController::setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId) +void InspectorController::setStickyBreakpoints(PassRefPtr<InspectorObject> breakpoints) +{ + m_state->setObject(InspectorState::stickyBreakpoints, breakpoints); +} + +void InspectorController::restoreStickyBreakpoints() { - *breakpointId = ""; + m_eventListenerBreakpoints.clear(); + m_XHRBreakpoints.clear(); + m_hasXHRBreakpointWithEmptyURL = false; + + RefPtr<InspectorObject> allBreakpoints = m_state->getObject(InspectorState::stickyBreakpoints); + KURL url = m_inspectedPage->mainFrame()->loader()->url(); + url.removeFragmentIdentifier(); + RefPtr<InspectorArray> breakpoints = allBreakpoints->getArray(url); + if (!breakpoints) + return; + for (unsigned i = 0; i < breakpoints->length(); ++i) + restoreStickyBreakpoint(breakpoints->get(i)->asObject()); +} + +void InspectorController::restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint) +{ + DEFINE_STATIC_LOCAL(String, eventListenerBreakpointType, ("EventListener")); + DEFINE_STATIC_LOCAL(String, javaScriptBreakpointType, ("JS")); + DEFINE_STATIC_LOCAL(String, xhrBreakpointType, ("XHR")); + + if (!breakpoint) + return; String type; if (!breakpoint->getString("type", &type)) return; + bool enabled; + if (!breakpoint->getBoolean("enabled", &enabled)) + return; RefPtr<InspectorObject> condition = breakpoint->getObject("condition"); if (!condition) return; - if (type == xhrNativeBreakpointType) { - String url; - if (!condition->getString("url", &url)) + + if (type == eventListenerBreakpointType) { + if (!enabled) return; - *breakpointId = String::number(++m_lastBreakpointId); - m_XHRBreakpoints.set(*breakpointId, url); - m_nativeBreakpoints.set(*breakpointId, type); - } else if (type == eventListenerNativeBreakpointType) { String eventName; - if (!condition->getString("eventName", &eventName)) - return; - if (m_eventListenerBreakpoints.contains(eventName)) + if (condition->getString("eventName", &eventName)) + setEventListenerBreakpoint(eventName); + } else if (type == javaScriptBreakpointType) { + String url; + if (!condition->getString("url", &url)) return; - *breakpointId = eventName; - m_eventListenerBreakpoints.add(eventName); - m_nativeBreakpoints.set(*breakpointId, type); - } else if (type == domNativeBreakpointType) { - if (!m_domAgent) + double lineNumber; + if (!condition->getNumber("lineNumber", &lineNumber)) return; - double nodeIdNumber; - if (!condition->getNumber("nodeId", &nodeIdNumber)) + String javaScriptCondition; + if (!condition->getString("condition", &javaScriptCondition)) return; - double domBreakpointTypeNumber; - if (!condition->getNumber("type", &domBreakpointTypeNumber)) + if (m_debuggerAgent) + m_debuggerAgent->setStickyBreakpoint(url, static_cast<unsigned>(lineNumber), javaScriptCondition, enabled); + } else if (type == xhrBreakpointType) { + if (!enabled) return; - long nodeId = (long) nodeIdNumber; - long domBreakpointType = (long) domBreakpointTypeNumber; - *breakpointId = m_domAgent->setDOMBreakpoint(nodeId, domBreakpointType); - if (!breakpointId->isEmpty()) - m_nativeBreakpoints.set(*breakpointId, type); + String url; + if (condition->getString("url", &url)) + setXHRBreakpoint(url); } } -void InspectorController::removeNativeBreakpoint(const String& breakpointId) +void InspectorController::setEventListenerBreakpoint(const String& eventName) { - String type = m_nativeBreakpoints.take(breakpointId); - if (type == xhrNativeBreakpointType) - m_XHRBreakpoints.remove(breakpointId); - else if (type == eventListenerNativeBreakpointType) - m_eventListenerBreakpoints.remove(breakpointId); - else if (type == domNativeBreakpointType) { - if (m_domAgent) - m_domAgent->removeDOMBreakpoint(breakpointId); - } + m_eventListenerBreakpoints.add(eventName); } -String InspectorController::findEventListenerBreakpoint(const String& eventName) +void InspectorController::removeEventListenerBreakpoint(const String& eventName) { - return m_eventListenerBreakpoints.contains(eventName) ? eventName : ""; + m_eventListenerBreakpoints.remove(eventName); } -String InspectorController::findXHRBreakpoint(const String& url) +bool InspectorController::hasEventListenerBreakpoint(const String& eventName) { - for (HashMap<String, String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) { - if (url.contains(it->second)) - return it->first; - } - return ""; + return m_eventListenerBreakpoints.contains(eventName); } -void InspectorController::clearNativeBreakpoints() +void InspectorController::setXHRBreakpoint(const String& url) { - m_nativeBreakpoints.clear(); - m_eventListenerBreakpoints.clear(); - m_XHRBreakpoints.clear(); - m_lastBreakpointId = 0; + if (url.isEmpty()) + m_hasXHRBreakpointWithEmptyURL = true; + else + m_XHRBreakpoints.add(url); +} + +void InspectorController::removeXHRBreakpoint(const String& url) +{ + if (url.isEmpty()) + m_hasXHRBreakpointWithEmptyURL = false; + else + m_XHRBreakpoints.remove(url); } + +bool InspectorController::hasXHRBreakpoint(const String& url, String* breakpointURL) +{ + if (m_hasXHRBreakpointWithEmptyURL) { + *breakpointURL = ""; + return true; + } + for (HashSet<String>::iterator it = m_XHRBreakpoints.begin(); it != m_XHRBreakpoints.end(); ++it) { + if (url.contains(*it)) { + *breakpointURL = *it; + return true; + } + } + return false; +} + #endif void InspectorController::evaluateForTestInFrontend(long callId, const String& script) @@ -1496,26 +1526,6 @@ void InspectorController::didEvaluateForTestInFrontend(long callId, const String function.call(); } -#if ENABLE(JAVASCRIPT_DEBUGGER) -String InspectorController::breakpointsSettingKey() -{ - DEFINE_STATIC_LOCAL(String, keyPrefix, ("breakpoints:")); - return keyPrefix + InspectorDebuggerAgent::md5Base16(m_inspectedPage->mainFrame()->loader()->url().string()); -} - -PassRefPtr<InspectorValue> InspectorController::loadBreakpoints() -{ - String jsonString; - m_client->populateSetting(breakpointsSettingKey(), &jsonString); - return InspectorValue::parseJSON(jsonString); -} - -void InspectorController::saveBreakpoints(PassRefPtr<InspectorObject> breakpoints) -{ - m_client->storeSetting(breakpointsSettingKey(), breakpoints->toJSONString()); -} -#endif - static Path quadToPath(const FloatQuad& quad) { Path quadPath; @@ -1538,21 +1548,18 @@ static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, co // of outline (because inflating a quad is hard) { context.save(); - context.addPath(quadPath); context.clipOut(quadPath); - context.addPath(quadPath); context.setStrokeThickness(outlineThickness); context.setStrokeColor(outlineColor, ColorSpaceDeviceRGB); - context.strokePath(); + context.strokePath(quadPath); context.restore(); } // Now do the fill - context.addPath(quadPath); context.setFillColor(fillColor, ColorSpaceDeviceRGB); - context.fillPath(); + context.fillPath(quadPath); } static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor) @@ -1764,19 +1771,20 @@ void InspectorController::drawElementTitle(GraphicsContext& context, const IntRe void InspectorController::openInInspectedWindow(const String& url) { - ResourceRequest request; - FrameLoadRequest frameRequest(request, "_blank"); - bool created; Frame* mainFrame = m_inspectedPage->mainFrame(); + + FrameLoadRequest request(mainFrame->document()->securityOrigin(), ResourceRequest(), "_blank"); + + bool created; WindowFeatures windowFeatures; - Frame* newFrame = WebCore::createWindow(mainFrame, mainFrame, frameRequest, windowFeatures, created); + Frame* newFrame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created); if (!newFrame) return; UserGestureIndicator indicator(DefinitelyProcessingUserGesture); newFrame->loader()->setOpener(mainFrame); newFrame->page()->setOpenedByDOM(); - newFrame->loader()->changeLocation(newFrame->loader()->completeURL(url), "", false, false); + newFrame->loader()->changeLocation(mainFrame->document()->securityOrigin(), newFrame->loader()->completeURL(url), "", false, false); } void InspectorController::count(const String& title, unsigned lineNumber, const String& sourceID) @@ -1858,6 +1866,18 @@ void InspectorController::reloadPage() m_inspectedPage->mainFrame()->navigationScheduler()->scheduleRefresh(); } +void InspectorController::setExtraHeaders(PassRefPtr<InspectorObject> headers) +{ + m_extraHeaders = adoptPtr(new HTTPHeaderMap()); + InspectorObject::const_iterator end = headers->end(); + for (InspectorObject::const_iterator it = headers->begin(); it != end; ++it) { + String value; + if (!it->second->asString(&value)) + continue; + m_extraHeaders->add(it->first, value); + } +} + } // namespace WebCore #endif // ENABLE(INSPECTOR) diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h index ca5a9d9..e570c98 100644 --- a/WebCore/inspector/InspectorController.h +++ b/WebCore/inspector/InspectorController.h @@ -51,6 +51,7 @@ class Document; class DocumentLoader; class FloatRect; class GraphicsContext; +class HTTPHeaderMap; class HitTestResult; class InjectedScript; class InjectedScriptHost; @@ -59,7 +60,6 @@ class InspectorBackend; class InspectorBackendDispatcher; class InspectorClient; class InspectorCSSAgent; -class InspectorCSSStore; class InspectorDOMAgent; class InspectorDOMStorageResource; class InspectorDatabaseResource; @@ -146,7 +146,7 @@ public: void disconnectFrontend(); void setConsoleMessagesEnabled(bool enabled, bool* newState); - void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassOwnPtr<ScriptArguments> arguments, PassOwnPtr<ScriptCallStack>); + void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack>); void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String&); void clearConsoleMessages(); const Vector<OwnPtr<ConsoleMessage> >& consoleMessages() const { return m_consoleMessages; } @@ -174,6 +174,8 @@ public: void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber); void scriptImported(unsigned long identifier, const String& sourceString); + void setExtraHeaders(PassRefPtr<InspectorObject>); + void ensureSettingsLoaded(); void startTimelineProfiler(); @@ -230,7 +232,7 @@ public: void startTiming(const String& title); bool stopTiming(const String& title, double& elapsed); - void startGroup(PassOwnPtr<ScriptArguments>, PassOwnPtr<ScriptCallStack> callFrame, bool collapsed = false); + void startGroup(PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack> callFrame, bool collapsed = false); void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL); void markTimeline(const String& message); @@ -256,8 +258,13 @@ public: InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); } void resume(); - void setNativeBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId); - void removeNativeBreakpoint(const String& breakpointId); + void setStickyBreakpoints(PassRefPtr<InspectorObject> breakpoints); + void setEventListenerBreakpoint(const String& eventName); + void removeEventListenerBreakpoint(const String& eventName); + bool hasEventListenerBreakpoint(const String& eventName); + void setXHRBreakpoint(const String& url); + void removeXHRBreakpoint(const String& url); + bool hasXHRBreakpoint(const String& url, String* breakpointURL); #endif void evaluateForTestInFrontend(long testCallId, const String& script); @@ -306,10 +313,8 @@ private: #if ENABLE(JAVASCRIPT_DEBUGGER) void toggleRecordButton(bool); void enableDebuggerFromFrontend(bool always); - - String findEventListenerBreakpoint(const String& eventName); - String findXHRBreakpoint(const String& url); - void clearNativeBreakpoints(); + void restoreStickyBreakpoints(); + void restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint); #endif #if ENABLE(DATABASE) void selectDatabase(Database* database); @@ -330,13 +335,6 @@ private: void didEvaluateForTestInFrontend(long callId, const String& jsonResult); -#if ENABLE(JAVASCRIPT_DEBUGGER) - friend class InspectorDebuggerAgent; - String breakpointsSettingKey(); - PassRefPtr<InspectorValue> loadBreakpoints(); - void saveBreakpoints(PassRefPtr<InspectorObject> breakpoints); -#endif - Page* m_inspectedPage; InspectorClient* m_client; OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient; @@ -345,7 +343,6 @@ private: OwnPtr<InspectorCSSAgent> m_cssAgent; RefPtr<InspectorDOMAgent> m_domAgent; RefPtr<InspectorStorageAgent> m_storageAgent; - OwnPtr<InspectorCSSStore> m_cssStore; OwnPtr<InspectorTimelineAgent> m_timelineAgent; OwnPtr<InspectorState> m_state; @@ -372,7 +369,6 @@ private: #endif String m_showAfterVisible; RefPtr<Node> m_highlightedNode; - unsigned m_groupLevel; ConsoleMessage* m_previousMessage; bool m_settingsLoaded; RefPtr<InspectorBackend> m_inspectorBackend; @@ -389,14 +385,13 @@ private: bool m_attachDebuggerWhenShown; OwnPtr<InspectorDebuggerAgent> m_debuggerAgent; - HashMap<String, String> m_nativeBreakpoints; HashSet<String> m_eventListenerBreakpoints; - HashMap<String, String> m_XHRBreakpoints; - - unsigned int m_lastBreakpointId; + HashSet<String> m_XHRBreakpoints; + bool m_hasXHRBreakpointWithEmptyURL; OwnPtr<InspectorProfilerAgent> m_profilerAgent; #endif + OwnPtr<HTTPHeaderMap> m_extraHeaders; #if ENABLE(WORKERS) typedef HashMap<intptr_t, RefPtr<InspectorWorkerResource> > WorkersMap; diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp index 894e4b2..cbba75f 100644 --- a/WebCore/inspector/InspectorDOMAgent.cpp +++ b/WebCore/inspector/InspectorDOMAgent.cpp @@ -216,9 +216,8 @@ const int domBreakpointDerivedTypeShift = 16; } -InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend) +InspectorDOMAgent::InspectorDOMAgent(InspectorFrontend* frontend) : EventListener(InspectorDOMAgentType) - , m_cssStore(cssStore) , m_frontend(frontend) , m_domListener(0) , m_lastNodeId(1) @@ -339,7 +338,6 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap) stopListening(frameOwner->contentDocument()); if (m_domListener) m_domListener->didRemoveDocument(frameOwner->contentDocument()); - cssStore()->removeDocument(frameOwner->contentDocument()); } long id = nodesMap->get(node); @@ -762,17 +760,11 @@ void InspectorDOMAgent::searchCanceled() m_searchResults.clear(); } -String InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type) +void InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type) { Node* node = nodeForId(nodeId); if (!node) - return ""; - - String breakpointId = createBreakpointId(nodeId, type); - if (m_idToBreakpoint.contains(breakpointId)) - return ""; - - m_idToBreakpoint.set(breakpointId, std::make_pair(nodeId, type)); + return; uint32_t rootBit = 1 << type; m_breakpoints.set(node, m_breakpoints.get(node) | rootBit); @@ -780,19 +772,15 @@ String InspectorDOMAgent::setDOMBreakpoint(long nodeId, long type) for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child)) updateSubtreeBreakpoints(child, rootBit, true); } - - return breakpointId; } -void InspectorDOMAgent::removeDOMBreakpoint(const String& breakpointId) +void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type) { - Breakpoint breakpoint = m_idToBreakpoint.take(breakpointId); - - Node* node = nodeForId(breakpoint.first); + Node* node = nodeForId(nodeId); if (!node) return; - uint32_t rootBit = 1 << breakpoint.second; + uint32_t rootBit = 1 << type; uint32_t mask = m_breakpoints.get(node) & ~rootBit; if (mask) m_breakpoints.set(node, mask); @@ -805,42 +793,41 @@ void InspectorDOMAgent::removeDOMBreakpoint(const String& breakpointId) } } -bool InspectorDOMAgent::shouldBreakOnNodeInsertion(Node*, Node* parent, PassRefPtr<InspectorValue>* details) +bool InspectorDOMAgent::shouldBreakOnNodeInsertion(Node*, Node* parent, PassRefPtr<InspectorObject> details) { if (hasBreakpoint(parent, SubtreeModified)) { - *details = descriptionForDOMEvent(parent, SubtreeModified, true); + descriptionForDOMEvent(parent, SubtreeModified, true, details); return true; } return false; } -bool InspectorDOMAgent::shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details) +bool InspectorDOMAgent::shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details) { if (hasBreakpoint(node, NodeRemoved)) { - *details = descriptionForDOMEvent(node, NodeRemoved, false); + descriptionForDOMEvent(node, NodeRemoved, false, details); return true; } if (hasBreakpoint(innerParentNode(node), SubtreeModified)) { - *details = descriptionForDOMEvent(node, SubtreeModified, false); + descriptionForDOMEvent(node, SubtreeModified, false, details); return true; } return false; } -bool InspectorDOMAgent::shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details) +bool InspectorDOMAgent::shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details) { if (hasBreakpoint(element, AttributeModified)) { - *details = descriptionForDOMEvent(element, AttributeModified, false); + descriptionForDOMEvent(element, AttributeModified, false, details); return true; } return false; } -PassRefPtr<InspectorValue> InspectorDOMAgent::descriptionForDOMEvent(Node* target, long breakpointType, bool insertion) +void InspectorDOMAgent::descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description) { ASSERT(hasBreakpoint(target, breakpointType)); - RefPtr<InspectorObject> description = InspectorObject::create(); Node* breakpointOwner = target; if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) { // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint. @@ -864,9 +851,8 @@ PassRefPtr<InspectorValue> InspectorDOMAgent::descriptionForDOMEvent(Node* targe long breakpointOwnerNodeId = m_documentNodeToIdMap.get(breakpointOwner); ASSERT(breakpointOwnerNodeId); - description->setString("breakpointId", createBreakpointId(breakpointOwnerNodeId, breakpointType)); - - return description; + description->setNumber("nodeId", breakpointOwnerNodeId); + description->setNumber("type", breakpointType); } String InspectorDOMAgent::documentURLString(Document* document) const @@ -1108,14 +1094,14 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node) if (m_breakpoints.size()) { // Remove subtree breakpoints. - removeBreakpointsForNode(node); + m_breakpoints.remove(node); Vector<Node*> stack(1, innerFirstChild(node)); do { Node* node = stack.last(); stack.removeLast(); if (!node) continue; - removeBreakpointsForNode(node); + m_breakpoints.remove(node); stack.append(innerFirstChild(node)); stack.append(innerNextSibling(node)); } while (!stack.isEmpty()); @@ -1182,551 +1168,6 @@ void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, updateSubtreeBreakpoints(child, newRootMask, set); } -void InspectorDOMAgent::removeBreakpointsForNode(Node* node) -{ - uint32_t mask = m_breakpoints.take(node); - if (!mask) - return; - long nodeId = m_documentNodeToIdMap.get(node); - if (!nodeId) - return; - for (int type = 0; type < DOMBreakpointTypesCount; ++type) { - if (mask && (1 << type)) - m_idToBreakpoint.remove(createBreakpointId(nodeId, type)); - } -} - -String InspectorDOMAgent::createBreakpointId(long nodeId, long type) -{ - return makeString("dom:", String::number(nodeId), ':', String::number(type)); -} - -void InspectorDOMAgent::getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles) -{ - Node* node = nodeForId(nodeId); - if (!node || node->nodeType() != Node::ELEMENT_NODE) - return; - - DOMWindow* defaultView = node->ownerDocument()->defaultView(); - if (!defaultView) - return; - - Element* element = static_cast<Element*>(node); - RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(node, true); // Support the viewing of :visited information in computed style. - - RefPtr<InspectorObject> result = InspectorObject::create(); - if (element->style()) - 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, true); - result->setArray("matchedCSSRules", buildArrayForCSSRules(node->ownerDocument(), matchedRules.get())); - - result->setObject("styleAttributes", buildObjectForAttributeStyles(element)); - result->setArray("pseudoElements", buildArrayForPseudoElements(element, authorOnly)); - - RefPtr<InspectorArray> inheritedStyles = InspectorArray::create(); - Element* parentElement = element->parentElement(); - while (parentElement) { - RefPtr<InspectorObject> parentStyle = InspectorObject::create(); - inheritedStyles->pushObject(parentStyle); - if (parentElement->style() && parentElement->style()->length()) - parentStyle->setObject("inlineStyle", buildObjectForStyle(parentElement->style(), true)); - - CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector(); - RefPtr<CSSRuleList> parentMatchedRules = parentSelector->styleRulesForElement(parentElement, authorOnly, true); - parentStyle->setArray("matchedCSSRules", buildArrayForCSSRules(parentElement->ownerDocument(), parentMatchedRules.get())); - - parentElement = parentElement->parentElement(); - } - result->setArray("inherited", inheritedStyles); - *styles = result.release(); -} - -void InspectorDOMAgent::getAllStyles(RefPtr<InspectorArray>* styles) -{ - for (ListHashSet<RefPtr<Document> >::iterator it = m_documents.begin(); it != m_documents.end(); ++it) { - StyleSheetList* list = (*it)->styleSheets(); - for (unsigned i = 0; i < list->length(); ++i) { - StyleSheet* styleSheet = list->item(i); - if (styleSheet->isCSSStyleSheet()) - (*styles)->pushObject(buildObjectForStyleSheet((*it).get(), static_cast<CSSStyleSheet*>(styleSheet))); - } - } -} - -void InspectorDOMAgent::getStyleSheet(long styleSheetId, RefPtr<InspectorObject>* styleSheetObject) -{ - CSSStyleSheet* styleSheet = cssStore()->styleSheetForId(styleSheetId); - if (styleSheet && styleSheet->document()) - *styleSheetObject = buildObjectForStyleSheet(styleSheet->document(), styleSheet); -} - -void InspectorDOMAgent::getStyleSourceData(long styleId, RefPtr<InspectorObject>* dataObject) -{ - CSSStyleDeclaration* style = cssStore()->styleForId(styleId); - if (!style) - return; - RefPtr<CSSRuleSourceData> sourceData = CSSRuleSourceData::create(); - bool success = cssStore()->getRuleSourceData(style, &sourceData); - if (!success) - return; - RefPtr<InspectorObject> result = InspectorObject::create(); - - RefPtr<InspectorObject> bodyRange = InspectorObject::create(); - result->setObject("bodyRange", bodyRange); - bodyRange->setNumber("start", sourceData->styleSourceData->styleBodyRange.start); - bodyRange->setNumber("end", sourceData->styleSourceData->styleBodyRange.end); - - RefPtr<InspectorObject> selectorRange = InspectorObject::create(); - result->setObject("selectorRange", selectorRange); - selectorRange->setNumber("start", sourceData->selectorListRange.start); - selectorRange->setNumber("end", sourceData->selectorListRange.end); - - RefPtr<InspectorArray> propertyRanges = InspectorArray::create(); - result->setArray("propertyData", propertyRanges); - Vector<CSSPropertySourceData>& propertyData = sourceData->styleSourceData->propertyData; - for (Vector<CSSPropertySourceData>::iterator it = propertyData.begin(); it != propertyData.end(); ++it) { - RefPtr<InspectorObject> propertyRange = InspectorObject::create(); - propertyRange->setString("name", it->name); - propertyRange->setString("value", it->value); - propertyRange->setBoolean("important", it->important); - propertyRange->setBoolean("parsed", it->parsedOk); - propertyRange->setNumber("start", it->range.start); - propertyRange->setNumber("end", it->range.end); - propertyRanges->pushObject(propertyRange); - } - *dataObject = result.release(); -} - -void InspectorDOMAgent::getInlineStyle(long nodeId, RefPtr<InspectorValue>* style) -{ - Node* node = nodeForId(nodeId); - if (!node || node->nodeType() != Node::ELEMENT_NODE) - return; - *style = buildObjectForStyle(static_cast<Element*>(node)->style(), true); -} - -void InspectorDOMAgent::getComputedStyle(long nodeId, RefPtr<InspectorValue>* style) -{ - Node* node = nodeForId(nodeId); - if (!node || node->nodeType() != Node::ELEMENT_NODE) - return; - - DOMWindow* defaultView = node->ownerDocument()->defaultView(); - if (!defaultView) - return; - - Element* element = static_cast<Element*>(node); - *style = buildObjectForStyle(defaultView->getComputedStyle(element, "").get(), false); -} - -PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForAttributeStyles(Element* element) -{ - RefPtr<InspectorObject> styleAttributes = InspectorObject::create(); - NamedNodeMap* attributes = element->attributes(); - for (unsigned i = 0; attributes && i < attributes->length(); ++i) { - Attribute* attribute = attributes->attributeItem(i); - if (attribute->style()) { - String attributeName = attribute->localName(); - styleAttributes->setObject(attributeName.utf8().data(), buildObjectForStyle(attribute->style(), true)); - } - } - return styleAttributes; -} - -PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForCSSRules(Document* ownerDocument, CSSRuleList* matchedRules) -{ - RefPtr<InspectorArray> matchedCSSRules = InspectorArray::create(); - for (unsigned i = 0; matchedRules && i < matchedRules->length(); ++i) { - CSSRule* rule = matchedRules->item(i); - if (rule->type() == CSSRule::STYLE_RULE) - matchedCSSRules->pushObject(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); - } - return matchedCSSRules.release(); -} - -PassRefPtr<InspectorArray> InspectorDOMAgent::buildArrayForPseudoElements(Element* element, bool authorOnly) -{ - RefPtr<InspectorArray> result = InspectorArray::create(); - CSSStyleSelector* selector = element->ownerDocument()->styleSelector(); - RefPtr<RenderStyle> renderStyle = element->styleForRenderer(); - - for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { - RefPtr<CSSRuleList> matchedRules = selector->pseudoStyleRulesForElement(element, pseudoId, authorOnly, true); - if (matchedRules && matchedRules->length()) { - RefPtr<InspectorObject> pseudoStyles = InspectorObject::create(); - pseudoStyles->setNumber("pseudoId", static_cast<int>(pseudoId)); - pseudoStyles->setArray("rules", buildArrayForCSSRules(element->ownerDocument(), matchedRules.get())); - result->pushObject(pseudoStyles.release()); - } - } - return result.release(); -} - -void InspectorDOMAgent::applyStyleText(long styleId, const String& styleText, const String& propertyName, bool* success, RefPtr<InspectorValue>* styleObject) -{ - CSSStyleDeclaration* style = cssStore()->styleForId(styleId); - if (!style) - return; - - // Remove disabled property entry for property with given name. - DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, false); - if (disabledStyle) - disabledStyle->remove(propertyName); - - int styleTextLength = styleText.length(); - - RefPtr<CSSMutableStyleDeclaration> tempMutableStyle = CSSMutableStyleDeclaration::create(); - tempMutableStyle->parseDeclaration(styleText); - CSSStyleDeclaration* tempStyle = static_cast<CSSStyleDeclaration*>(tempMutableStyle.get()); - - if (tempStyle->length() || !styleTextLength) { - ExceptionCode ec = 0; - // The input was parsable or the user deleted everything, so remove the - // original property from the real style declaration. If this represents - // a shorthand remove all the longhand properties. - if (style->getPropertyShorthand(propertyName).isEmpty()) { - Vector<String> longhandProps = longhandProperties(style, propertyName); - for (unsigned i = 0; !ec && i < longhandProps.size(); ++i) - style->removeProperty(longhandProps[i], ec); - } - // Explicitly delete properties with no shorthands as well as shorthands themselves. - if (!ec) - style->removeProperty(propertyName, ec); - - if (ec) - return; - } - - // Notify caller that the property was successfully deleted. - if (!styleTextLength) { - *success = true; - *styleObject = buildObjectForStyle(style, true); - return; - } - - if (!tempStyle->length()) - return; - - // Iterate of the properties on the test element's style declaration and - // add them to the real style declaration. We take care to move shorthands. - HashSet<String> foundShorthands; - - for (unsigned i = 0; i < tempStyle->length(); ++i) { - String name = tempStyle->item(i); - String shorthand = tempStyle->getPropertyShorthand(name); - - if (!shorthand.isEmpty() && foundShorthands.contains(shorthand)) - continue; - - String value; - String priority; - if (!shorthand.isEmpty()) { - value = shorthandValue(tempStyle, shorthand); - priority = shorthandPriority(tempStyle, shorthand); - foundShorthands.add(shorthand); - name = shorthand; - } else { - value = tempStyle->getPropertyValue(name); - priority = tempStyle->getPropertyPriority(name); - } - - // Set the property on the real style declaration. - ExceptionCode ec = 0; - style->setProperty(name, value, priority, ec); - // Remove disabled property entry for property with this name. - if (disabledStyle) - disabledStyle->remove(name); - } - *success = true; - *styleObject = buildObjectForStyle(style, true); -} - -void InspectorDOMAgent::setStyleText(long styleId, const String& cssText, bool* success) -{ - CSSStyleDeclaration* style = cssStore()->styleForId(styleId); - if (!style) - return; - ExceptionCode ec = 0; - style->setCssText(cssText, ec); - *success = !ec; -} - -void InspectorDOMAgent::setStyleProperty(long styleId, const String& name, const String& value, bool* success) -{ - CSSStyleDeclaration* style = cssStore()->styleForId(styleId); - if (!style) - return; - - ExceptionCode ec = 0; - style->setProperty(name, value, ec); - *success = !ec; -} - -void InspectorDOMAgent::toggleStyleEnabled(long styleId, const String& propertyName, bool disabled, RefPtr<InspectorValue>* styleObject) -{ - CSSStyleDeclaration* style = cssStore()->styleForId(styleId); - if (!style) - return; - - DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, true); - - // TODO: make sure this works with shorthands right. - ExceptionCode ec = 0; - if (disabled) { - disabledStyle->set(propertyName, std::make_pair(style->getPropertyValue(propertyName), style->getPropertyPriority(propertyName))); - if (!ec) - style->removeProperty(propertyName, ec); - } else if (disabledStyle->contains(propertyName)) { - PropertyValueAndPriority valueAndPriority = disabledStyle->get(propertyName); - style->setProperty(propertyName, valueAndPriority.first, valueAndPriority.second, ec); - if (!ec) - disabledStyle->remove(propertyName); - } - if (ec) - return; - *styleObject = buildObjectForStyle(style, true); -} - -void InspectorDOMAgent::setRuleSelector(long ruleId, const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode) -{ - CSSStyleRule* rule = cssStore()->ruleForId(ruleId); - if (!rule) - return; - - Node* node = nodeForId(selectedNodeId); - - CSSStyleSheet* styleSheet = rule->parentStyleSheet(); - ExceptionCode ec = 0; - styleSheet->addRule(selector, rule->style()->cssText(), ec); - if (ec) - return; - - CSSStyleRule* newRule = static_cast<CSSStyleRule*>(styleSheet->item(styleSheet->length() - 1)); - for (unsigned i = 0; i < styleSheet->length(); ++i) { - if (styleSheet->item(i) == rule) { - styleSheet->deleteRule(i, ec); - break; - } - } - - if (ec) - return; - - *selectorAffectsNode = ruleAffectsNode(newRule, node); - *ruleObject = buildObjectForRule(node->ownerDocument(), newRule); -} - -void InspectorDOMAgent::addRule(const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode) -{ - Node* node = nodeForId(selectedNodeId); - if (!node) - return; - - CSSStyleSheet* styleSheet = cssStore()->inspectorStyleSheet(node->ownerDocument(), true); - if (!styleSheet) - return; // could not add a stylesheet to the ownerDocument - - ExceptionCode ec = 0; - styleSheet->addRule(selector, "", ec); - if (ec) - return; - - CSSStyleRule* newRule = static_cast<CSSStyleRule*>(styleSheet->item(styleSheet->length() - 1)); - *selectorAffectsNode = ruleAffectsNode(newRule, node); - *ruleObject = buildObjectForRule(node->ownerDocument(), newRule); -} - -PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyle(CSSStyleDeclaration* style, bool bind) -{ - RefPtr<InspectorObject> result = InspectorObject::create(); - if (bind) { - result->setNumber("styleId", cssStore()->bindStyle(style)); - CSSStyleSheet* styleSheet = InspectorCSSStore::getParentStyleSheet(style); - if (styleSheet) - result->setNumber("styleSheetId", cssStore()->bindStyleSheet(styleSheet)); - } - RefPtr<InspectorObject> properties = InspectorObject::create(); - properties->setString("width", style->getPropertyValue("width")); - properties->setString("height", style->getPropertyValue("height")); - result->setObject("properties", properties); - populateObjectWithStyleProperties(style, result.get()); - return result.release(); -} - -void InspectorDOMAgent::populateObjectWithStyleProperties(CSSStyleDeclaration* style, InspectorObject* result) -{ - RefPtr<InspectorArray> properties = InspectorArray::create(); - RefPtr<InspectorObject> shorthandValues = InspectorObject::create(); - - HashSet<String> foundShorthands; - for (unsigned i = 0; i < style->length(); ++i) { - RefPtr<InspectorObject> property = InspectorObject::create(); - String name = style->item(i); - String value = style->getPropertyValue(name); - String priority = style->getPropertyPriority(name); - property->setString("name", name); - property->setString("value", value); - property->setString("priority", priority); - property->setString("text", name + ": " + value + (priority.length() ? " !" + priority : "") + ";"); - property->setBoolean("implicit", style->isPropertyImplicit(name)); - property->setBoolean("parsedOk", true); - property->setString("status", "style"); - String shorthand = style->getPropertyShorthand(name); - property->setString("shorthandName", shorthand); - if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) { - foundShorthands.add(shorthand); - shorthandValues->setString(shorthand, shorthandValue(style, shorthand)); - } - properties->pushObject(property.release()); - } - result->setArray("cssProperties", properties); - result->setString("cssText", style->cssText()); - result->setObject("shorthandValues", shorthandValues); - - DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(cssStore()->bindStyle(style), false); - if (!disabledStyle) - return; - - for (DisabledStyleDeclaration::iterator it = disabledStyle->begin(); it != disabledStyle->end(); ++it) { - RefPtr<InspectorObject> property = InspectorObject::create(); - String name = it->first; - String value = it->second.first; - String priority = it->second.second; - property->setString("name", name); - property->setString("value", value); - property->setString("priority", priority); - property->setString("text", name + ": " + value + (priority.length() ? " !" + priority : "") + ";"); - property->setBoolean("implicit", false); - property->setBoolean("parsedOk", true); - property->setString("status", "disabled"); - properties->pushObject(property.release()); - } -} - -PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForStyleSheet(Document* ownerDocument, CSSStyleSheet* styleSheet) -{ - RefPtr<InspectorObject> result = InspectorObject::create(); - long id = cssStore()->bindStyleSheet(styleSheet); - result->setNumber("styleSheetId", id); - result->setString("sourceURL", styleSheet->href()); - result->setString("title", styleSheet->title()); - result->setBoolean("disabled", styleSheet->disabled()); - RefPtr<InspectorArray> cssRules = InspectorArray::create(); - PassRefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true); - if (cssRuleList) { - for (unsigned i = 0; i < cssRuleList->length(); ++i) { - CSSRule* rule = cssRuleList->item(i); - if (rule->isStyleRule()) - cssRules->pushObject(buildObjectForRule(ownerDocument, static_cast<CSSStyleRule*>(rule))); - } - } - result->setArray("rules", cssRules.release()); - return result.release(); -} - -PassRefPtr<InspectorObject> InspectorDOMAgent::buildObjectForRule(Document* ownerDocument, CSSStyleRule* rule) -{ - CSSStyleSheet* parentStyleSheet = rule->parentStyleSheet(); - - RefPtr<InspectorObject> result = InspectorObject::create(); - result->setString("selectorText", rule->selectorText()); - result->setNumber("sourceLine", rule->sourceLine()); - - String origin; - bool canBind = true; - if (parentStyleSheet && !parentStyleSheet->ownerNode() && parentStyleSheet->href().isEmpty()) { - origin = "user-agent"; - canBind = false; - } else if (parentStyleSheet && parentStyleSheet->ownerNode() && parentStyleSheet->ownerNode()->nodeName() == "#document") { - origin = "user"; - canBind = false; - } else if (rule->parentStyleSheet() == cssStore()->inspectorStyleSheet(ownerDocument, false)) - origin = "inspector"; - result->setString("origin", origin); - - if (origin.isEmpty()) - result->setString("sourceURL", parentStyleSheet && !parentStyleSheet->href().isEmpty() ? parentStyleSheet->href() : (ownerDocument ? ownerDocument->url().string() : "")); - - // Bind editable scripts only. - result->setObject("style", buildObjectForStyle(rule->style(), canBind)); - - if (canBind) - result->setNumber("ruleId", cssStore()->bindRule(rule)); - return result.release(); -} - -Vector<String> InspectorDOMAgent::longhandProperties(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - Vector<String> properties; - HashSet<String> foundProperties; - - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (foundProperties.contains(individualProperty) || style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - foundProperties.add(individualProperty); - properties.append(individualProperty); - } - - return properties; -} - -String InspectorDOMAgent::shorthandValue(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - String value = style->getPropertyValue(shorthandProperty); - if (value.isEmpty()) { - // Some shorthands (like border) return a null value, so compute a shorthand value. - // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 is fixed. - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - if (style->isPropertyImplicit(individualProperty)) - continue; - String individualValue = style->getPropertyValue(individualProperty); - if (individualValue == "initial") - continue; - if (value.length()) - value.append(" "); - value.append(individualValue); - } - } - return value; -} - -String InspectorDOMAgent::shorthandPriority(CSSStyleDeclaration* style, const String& shorthandProperty) -{ - String priority = style->getPropertyPriority(shorthandProperty); - if (priority.isEmpty()) { - for (unsigned i = 0; i < style->length(); ++i) { - String individualProperty = style->item(i); - if (style->getPropertyShorthand(individualProperty) != shorthandProperty) - continue; - priority = style->getPropertyPriority(individualProperty); - break; - } - } - return priority; -} - -bool InspectorDOMAgent::ruleAffectsNode(CSSStyleRule* rule, Node* node) -{ - if (!node) - return false; - ExceptionCode ec = 0; - RefPtr<NodeList> nodes = node->ownerDocument()->querySelectorAll(rule->selectorText(), ec); - if (ec) - return false; - for (unsigned i = 0; i < nodes->length(); ++i) { - if (nodes->item(i) == node) - return true; - } - return false; -} - Node* InspectorDOMAgent::nodeForPath(const String& path) { // The path is of form "1,HTML,2,BODY,1,DIV" diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h index 84ca027..5347090 100644 --- a/WebCore/inspector/InspectorDOMAgent.h +++ b/WebCore/inspector/InspectorDOMAgent.h @@ -33,7 +33,6 @@ #include "Document.h" #include "EventListener.h" #include "EventTarget.h" -#include "InspectorCSSStore.h" #include "InspectorValues.h" #include "NodeList.h" #include "Timer.h" @@ -88,9 +87,9 @@ namespace WebCore { virtual void didRemoveDOMNode(Node*) = 0; }; - static PassRefPtr<InspectorDOMAgent> create(InspectorCSSStore* cssStore, InspectorFrontend* frontend) + static PassRefPtr<InspectorDOMAgent> create(InspectorFrontend* frontend) { - return adoptRef(new InspectorDOMAgent(cssStore, frontend)); + return adoptRef(new InspectorDOMAgent(frontend)); } static const InspectorDOMAgent* cast(const EventListener* listener) @@ -100,7 +99,7 @@ namespace WebCore { : 0; } - InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend); + InspectorDOMAgent(InspectorFrontend* frontend); ~InspectorDOMAgent(); void reset(); @@ -120,23 +119,9 @@ namespace WebCore { void addInspectedNode(long nodeId); void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously); void searchCanceled(); - bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorValue>* details); - bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details); - bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details); - - // Methods called from the frontend for CSS styles inspection. - void getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles); - void getAllStyles(RefPtr<InspectorArray>* styles); - void getInlineStyle(long nodeId, RefPtr<InspectorValue>* styles); - void getComputedStyle(long nodeId, RefPtr<InspectorValue>* styles); - void getStyleSheet(long styleSheetId, RefPtr<InspectorObject>* styleSheetObject); - void getStyleSourceData(long styleId, RefPtr<InspectorObject>* dataObject); - void applyStyleText(long styleId, const String& styleText, const String& propertyName, bool* success, RefPtr<InspectorValue>* styleObject); - void setStyleText(long styleId, const String& cssText, bool* success); - void setStyleProperty(long styleId, const String& name, const String& value, bool* success); - void toggleStyleEnabled(long styleId, const String& propertyName, bool disabled, RefPtr<InspectorValue>* styleObject); - void setRuleSelector(long ruleId, const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode); - void addRule(const String& selector, long selectedNodeId, RefPtr<InspectorValue>* ruleObject, bool* selectorAffectsNode); + bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorObject> details); + bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details); + bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details); // Methods called from the InspectorController. void setDocument(Document* document); @@ -158,8 +143,8 @@ namespace WebCore { String documentURLString(Document* document) const; - String setDOMBreakpoint(long nodeId, long type); - void removeDOMBreakpoint(const String& breakpointId); + void setDOMBreakpoint(long nodeId, long type); + void removeDOMBreakpoint(long nodeId, long type); private: void startListening(Document* document); @@ -176,13 +161,7 @@ namespace WebCore { bool hasBreakpoint(Node* node, long type); void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value); - void removeBreakpointsForNode(Node* node); - PassRefPtr<InspectorValue> descriptionForDOMEvent(Node* target, long breakpointType, bool insertion); - String createBreakpointId(long nodeId, long type); - - PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element); - PassRefPtr<InspectorArray> buildArrayForCSSRules(Document* ownerDocument, CSSRuleList*); - PassRefPtr<InspectorArray> buildArrayForPseudoElements(Element* element, bool authorOnly); + void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description); PassRefPtr<InspectorObject> buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap); PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element* element); @@ -199,25 +178,15 @@ namespace WebCore { bool isWhitespace(Node* node); Document* mainFrameDocument() const; - InspectorCSSStore* cssStore() { return m_cssStore; } void onMatchJobsTimer(Timer<InspectorDOMAgent>*); void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector); - PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*, bool bind); - void populateObjectWithStyleProperties(CSSStyleDeclaration*, InspectorObject* result); - PassRefPtr<InspectorObject> buildObjectForRule(Document* ownerDocument, CSSStyleRule*); - PassRefPtr<InspectorObject> buildObjectForStyleSheet(Document* ownerDocument, CSSStyleSheet*); - Vector<String> longhandProperties(CSSStyleDeclaration*, const String& shorthandProperty); - String shorthandValue(CSSStyleDeclaration*, const String& shorthandProperty); - String shorthandPriority(CSSStyleDeclaration*, const String& shorthandProperty); - bool ruleAffectsNode(CSSStyleRule*, Node*); Node* nodeForPath(const String& path); PassRefPtr<InspectorArray> toArray(const Vector<String>& data); void discardBindings(); - InspectorCSSStore* m_cssStore; InspectorFrontend* m_frontend; DOMListener* m_domListener; NodeToIdMap m_documentNodeToIdMap; @@ -233,8 +202,6 @@ namespace WebCore { HashSet<RefPtr<Node> > m_searchResults; Vector<long> m_inspectedNodes; HashMap<Node*, uint32_t> m_breakpoints; - typedef pair<long, long> Breakpoint; - HashMap<String, Breakpoint> m_idToBreakpoint; }; #endif diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp index b3caa2e..0046989 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.cpp +++ b/WebCore/inspector/InspectorDebuggerAgent.cpp @@ -37,16 +37,9 @@ #include "InspectorValues.h" #include "PlatformString.h" #include "ScriptDebugServer.h" -#include <wtf/MD5.h> -#include <wtf/text/StringConcatenate.h> namespace WebCore { -static String formatBreakpointId(const String& sourceID, unsigned lineNumber) -{ - return makeString(sourceID, ':', String::number(lineNumber)); -} - PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorController* inspectorController, InspectorFrontend* frontend) { OwnPtr<InspectorDebuggerAgent> agent = adoptPtr(new InspectorDebuggerAgent(inspectorController, frontend)); @@ -61,7 +54,6 @@ InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorCon : m_inspectorController(inspectorController) , m_frontend(frontend) , m_pausedScriptState(0) - , m_breakpointsLoaded(false) , m_javaScriptPauseScheduled(false) { } @@ -87,49 +79,37 @@ void InspectorDebuggerAgent::deactivateBreakpoints() ScriptDebugServer::shared().deactivateBreakpoints(); } -void InspectorDebuggerAgent::setBreakpoint(const String& sourceID, unsigned lineNumber, bool enabled, const String& condition, bool* success, unsigned int* actualLineNumber) +void InspectorDebuggerAgent::setStickyBreakpoint(const String& url, unsigned lineNumber, const String& condition, bool enabled) { - ScriptBreakpoint breakpoint(enabled, condition); - *success = ScriptDebugServer::shared().setBreakpoint(sourceID, breakpoint, lineNumber, actualLineNumber); - if (!*success) - return; + HashMap<String, ScriptBreakpoints>::iterator it = m_stickyBreakpoints.find(url); + if (it == m_stickyBreakpoints.end()) + it = m_stickyBreakpoints.set(url, ScriptBreakpoints()).first; + it->second.set(lineNumber, Breakpoint(condition, enabled)); - String url = m_sourceIDToURL.get(sourceID); - if (url.isEmpty()) + URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url); + if (urlToSourceIDsIterator == m_urlToSourceIDs.end()) return; - - String breakpointId = formatBreakpointId(sourceID, *actualLineNumber); - m_breakpointsMapping.set(breakpointId, *actualLineNumber); - - String key = md5Base16(url); - HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(key); - if (it == m_stickyBreakpoints.end()) - it = m_stickyBreakpoints.set(key, SourceBreakpoints()).first; - it->second.set(*actualLineNumber, breakpoint); - saveBreakpoints(); + const Vector<String>& sourceIDs = urlToSourceIDsIterator->second; + for (size_t i = 0; i < sourceIDs.size(); ++i) + restoreBreakpoint(sourceIDs[i], lineNumber, condition, enabled); } -void InspectorDebuggerAgent::removeBreakpoint(const String& sourceID, unsigned lineNumber) +void InspectorDebuggerAgent::setBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled, String* breakpointId, unsigned int* actualLineNumber) { - ScriptDebugServer::shared().removeBreakpoint(sourceID, lineNumber); - - String url = m_sourceIDToURL.get(sourceID); - if (url.isEmpty()) - return; - - String breakpointId = formatBreakpointId(sourceID, lineNumber); - HashMap<String, unsigned>::iterator mappingIt = m_breakpointsMapping.find(breakpointId); - if (mappingIt == m_breakpointsMapping.end()) - return; - unsigned stickyLine = mappingIt->second; - m_breakpointsMapping.remove(mappingIt); + *breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, lineNumber, condition, enabled, actualLineNumber); +} - HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(md5Base16(url)); - if (it == m_stickyBreakpoints.end()) - return; +void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId) +{ + ScriptDebugServer::shared().removeBreakpoint(breakpointId); +} - it->second.remove(stickyLine); - saveBreakpoints(); +void InspectorDebuggerAgent::restoreBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled) +{ + unsigned actualLineNumber = 0; + String breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, lineNumber, condition, enabled, &actualLineNumber); + if (!breakpointId.isEmpty()) + m_frontend->breakpointResolved(breakpointId, sourceID, actualLineNumber, condition, enabled, lineNumber); } void InspectorDebuggerAgent::editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames) @@ -200,28 +180,9 @@ long InspectorDebuggerAgent::pauseOnExceptionsState() void InspectorDebuggerAgent::clearForPageNavigation() { - m_sourceIDToURL.clear(); m_scriptIDToContent.clear(); + m_urlToSourceIDs.clear(); m_stickyBreakpoints.clear(); - m_breakpointsMapping.clear(); - m_breakpointsLoaded = false; -} - -String InspectorDebuggerAgent::md5Base16(const String& string) -{ - static const char digits[] = "0123456789abcdef"; - - MD5 md5; - md5.addBytes(reinterpret_cast<const uint8_t*>(string.characters()), string.length() * 2); - Vector<uint8_t, 16> digest; - md5.checksum(digest); - - Vector<char, 32> result; - for (int i = 0; i < 16; ++i) { - result.append(digits[(digest[i] >> 4) & 0xf]); - result.append(digits[digest[i] & 0xf]); - } - return String(result.data(), result.size()); } PassRefPtr<InspectorValue> InspectorDebuggerAgent::currentCallFrames() @@ -236,39 +197,6 @@ PassRefPtr<InspectorValue> InspectorDebuggerAgent::currentCallFrames() return injectedScript.callFrames(); } -void InspectorDebuggerAgent::loadBreakpoints() -{ - if (m_breakpointsLoaded) - return; - m_breakpointsLoaded = true; - - RefPtr<InspectorValue> parsedSetting = m_inspectorController->loadBreakpoints(); - if (!parsedSetting) - return; - RefPtr<InspectorObject> breakpoints = parsedSetting->asObject(); - if (!breakpoints) - return; - for (InspectorObject::iterator it = breakpoints->begin(); it != breakpoints->end(); ++it) { - RefPtr<InspectorObject> breakpointsForURL = it->second->asObject(); - if (!breakpointsForURL) - continue; - HashMap<String, SourceBreakpoints>::iterator sourceBreakpointsIt = m_stickyBreakpoints.set(it->first, SourceBreakpoints()).first; - ScriptBreakpoint::sourceBreakpointsFromInspectorObject(breakpointsForURL, &sourceBreakpointsIt->second); - } -} - -void InspectorDebuggerAgent::saveBreakpoints() -{ - RefPtr<InspectorObject> breakpoints = InspectorObject::create(); - for (HashMap<String, SourceBreakpoints>::iterator it(m_stickyBreakpoints.begin()); it != m_stickyBreakpoints.end(); ++it) { - if (it->second.isEmpty()) - continue; - RefPtr<InspectorObject> breakpointsForURL = ScriptBreakpoint::inspectorObjectFromSourceBreakpoints(it->second); - breakpoints->setObject(it->first, breakpointsForURL); - } - m_inspectorController->saveBreakpoints(breakpoints); -} - // JavaScriptDebugListener functions void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType worldType) @@ -281,23 +209,20 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String if (url.isEmpty()) return; - loadBreakpoints(); - HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(md5Base16(url)); - if (it != m_stickyBreakpoints.end()) { - for (SourceBreakpoints::iterator breakpointIt = it->second.begin(); breakpointIt != it->second.end(); ++breakpointIt) { - int lineNumber = breakpointIt->first; - if (firstLine > lineNumber) - continue; - unsigned actualLineNumber = 0; - bool success = ScriptDebugServer::shared().setBreakpoint(sourceID, breakpointIt->second, lineNumber, &actualLineNumber); - if (!success) - continue; - m_frontend->restoredBreakpoint(sourceID, url, actualLineNumber, breakpointIt->second.enabled, breakpointIt->second.condition); - String breakpointId = formatBreakpointId(sourceID, actualLineNumber); - m_breakpointsMapping.set(breakpointId, lineNumber); - } + URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url); + if (urlToSourceIDsIterator == m_urlToSourceIDs.end()) + urlToSourceIDsIterator = m_urlToSourceIDs.set(url, Vector<String>()).first; + urlToSourceIDsIterator->second.append(sourceID); + + HashMap<String, ScriptBreakpoints>::iterator stickyBreakpointsIterator = m_stickyBreakpoints.find(url); + if (stickyBreakpointsIterator == m_stickyBreakpoints.end()) + return; + + const ScriptBreakpoints& breakpoints = stickyBreakpointsIterator->second; + for (ScriptBreakpoints::const_iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { + const Breakpoint& breakpoint = it->second; + restoreBreakpoint(sourceID, it->first, breakpoint.first, breakpoint.second); } - m_sourceIDToURL.set(sourceID, url); } void InspectorDebuggerAgent::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h index adc925a..6e45e59 100644 --- a/WebCore/inspector/InspectorDebuggerAgent.h +++ b/WebCore/inspector/InspectorDebuggerAgent.h @@ -31,12 +31,12 @@ #define InspectorDebuggerAgent_h #if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR) -#include "ScriptBreakpoint.h" #include "ScriptDebugListener.h" #include "ScriptState.h" #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> #include <wtf/text/StringHash.h> namespace WebCore { @@ -61,8 +61,9 @@ public: void activateBreakpoints(); void deactivateBreakpoints(); - void setBreakpoint(const String& sourceID, unsigned lineNumber, bool enabled, const String& condition, bool* success, unsigned int* actualLineNumber); - void removeBreakpoint(const String& sourceID, unsigned lineNumber); + void setStickyBreakpoint(const String& url, unsigned lineNumber, const String& condition, bool enabled); + void setBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled, String* breakpointId, unsigned int* actualLineNumber); + void removeBreakpoint(const String& breakpointId); void editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames); void getScriptSource(const String& sourceID, String* scriptSource); @@ -81,30 +82,27 @@ public: void clearForPageNavigation(); - static String md5Base16(const String& string); - private: InspectorDebuggerAgent(InspectorController*, InspectorFrontend*); PassRefPtr<InspectorValue> currentCallFrames(); - void loadBreakpoints(); - void saveBreakpoints(); - virtual void didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType); virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage); virtual void didPause(ScriptState*); virtual void didContinue(); + void restoreBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled); + InspectorController* m_inspectorController; InspectorFrontend* m_frontend; ScriptState* m_pausedScriptState; - HashMap<String, String> m_sourceIDToURL; HashMap<String, String> m_scriptIDToContent; - HashMap<String, SourceBreakpoints> m_stickyBreakpoints; - HashMap<String, unsigned> m_breakpointsMapping; - bool m_breakpointsLoaded; - static InspectorDebuggerAgent* s_debuggerAgentOnBreakpoint; + typedef HashMap<String, Vector<String> > URLToSourceIDsMap; + URLToSourceIDsMap m_urlToSourceIDs; + typedef std::pair<String, bool> Breakpoint; + typedef HashMap<unsigned, Breakpoint> ScriptBreakpoints; + HashMap<String, ScriptBreakpoints> m_stickyBreakpoints; RefPtr<InspectorObject> m_breakProgramDetails; bool m_javaScriptPauseScheduled; }; diff --git a/WebCore/inspector/InspectorInstrumentation.cpp b/WebCore/inspector/InspectorInstrumentation.cpp index cf41527..f3a73ba 100644 --- a/WebCore/inspector/InspectorInstrumentation.cpp +++ b/WebCore/inspector/InspectorInstrumentation.cpp @@ -45,6 +45,10 @@ namespace WebCore { +static const char* const domNativeBreakpointType = "DOM"; +static const char* const eventListenerNativeBreakpointType = "EventListener"; +static const char* const xhrNativeBreakpointType = "XHR"; + static const char* const listenerEventCategoryType = "listener"; static const char* const instrumentationEventCategoryType = "instrumentation"; @@ -80,9 +84,11 @@ void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspec InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get(); if (!domAgent) return; - PassRefPtr<InspectorValue> eventData; - if (domAgent->shouldBreakOnNodeInsertion(node, parent, &eventData)) + RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (domAgent->shouldBreakOnNodeInsertion(node, parent, eventData)) { + eventData->setString("breakpointType", domNativeBreakpointType); debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); + } #endif } @@ -101,9 +107,11 @@ void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspec InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get(); if (!domAgent) return; - PassRefPtr<InspectorValue> eventData; - if (domAgent->shouldBreakOnNodeRemoval(node, &eventData)) + RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (domAgent->shouldBreakOnNodeRemoval(node, eventData)) { + eventData->setString("breakpointType", domNativeBreakpointType); debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); + } #endif } @@ -122,9 +130,11 @@ void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorController* inspec InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get(); if (!domAgent) return; - PassRefPtr<InspectorValue> eventData; - if (domAgent->shouldBreakOnAttributeModification(element, &eventData)) + RefPtr<InspectorObject> eventData = InspectorObject::create(); + if (domAgent->shouldBreakOnAttributeModification(element, eventData)) { + eventData->setString("breakpointType", domNativeBreakpointType); debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); + } #endif } @@ -147,12 +157,13 @@ void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* i if (!debuggerAgent) return; - String breakpointId = inspectorController->findXHRBreakpoint(url); - if (breakpointId.isEmpty()) + String breakpointURL; + if (!inspectorController->hasXHRBreakpoint(url, &breakpointURL)) return; RefPtr<InspectorObject> eventData = InspectorObject::create(); - eventData->setString("breakpointId", breakpointId); + eventData->setString("breakpointType", xhrNativeBreakpointType); + eventData->setString("breakpointURL", breakpointURL); eventData->setString("url", url); debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); #endif @@ -446,11 +457,11 @@ void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorController* i if (!debuggerAgent) return; String fullEventName = String::format("%s:%s", categoryType.utf8().data(), eventName.utf8().data()); - String breakpointId = inspectorController->findEventListenerBreakpoint(fullEventName); - if (breakpointId.isEmpty()) + if (!inspectorController->hasEventListenerBreakpoint(fullEventName)) return; RefPtr<InspectorObject> eventData = InspectorObject::create(); - eventData->setString("breakpointId", breakpointId); + eventData->setString("breakpointType", eventListenerNativeBreakpointType); + eventData->setString("eventName", fullEventName); if (synchronous) debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData); else diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp index 1248677..ac67a1a 100644 --- a/WebCore/inspector/InspectorProfilerAgent.cpp +++ b/WebCore/inspector/InspectorProfilerAgent.cpp @@ -156,6 +156,21 @@ void InspectorProfilerAgent::getProfileHeaders(RefPtr<InspectorArray>* headers) (*headers)->pushObject(createSnapshotHeader(*it->second)); } +namespace { + +class OutputStream : public ScriptHeapSnapshot::OutputStream { +public: + OutputStream(InspectorFrontend* frontend, unsigned long uid) + : m_frontend(frontend), m_uid(uid) { } + void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(m_uid, chunk); } + void Close() { m_frontend->finishHeapSnapshot(m_uid); } +private: + InspectorFrontend* m_frontend; + unsigned long m_uid; +}; + +} // namespace + void InspectorProfilerAgent::getProfile(const String& type, unsigned uid, RefPtr<InspectorObject>* profileObject) { if (type == CPUProfileType) { @@ -167,8 +182,12 @@ void InspectorProfilerAgent::getProfile(const String& type, unsigned uid, RefPtr } else if (type == HeapProfileType) { HeapSnapshotsMap::iterator it = m_snapshots.find(uid); if (it != m_snapshots.end()) { - *profileObject = createSnapshotHeader(*it->second); - (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead()); + RefPtr<ScriptHeapSnapshot> snapshot = it->second; + *profileObject = createSnapshotHeader(*snapshot); + if (m_frontend) { + OutputStream stream(m_frontend, uid); + snapshot->writeJSON(&stream); + } } } } @@ -192,7 +211,7 @@ void InspectorProfilerAgent::resetState() m_nextUserInitiatedProfileNumber = 1; m_nextUserInitiatedHeapSnapshotNumber = 1; if (m_frontend) - m_frontend->resetProfilesPanel(); + m_frontend->resetProfiles(); } void InspectorProfilerAgent::startUserInitiatedProfiling() diff --git a/WebCore/inspector/InspectorResourceAgent.cpp b/WebCore/inspector/InspectorResourceAgent.cpp index 9dab24a..8f54578 100644 --- a/WebCore/inspector/InspectorResourceAgent.cpp +++ b/WebCore/inspector/InspectorResourceAgent.cpp @@ -52,6 +52,8 @@ #include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" #include "SharedBuffer.h" #include "TextEncoding.h" #include "WebSocketHandshakeRequest.h" @@ -128,10 +130,9 @@ PassRefPtr<SharedBuffer> InspectorResourceAgent::resourceData(Frame* frame, cons CachedResource* InspectorResourceAgent::cachedResource(Frame* frame, const KURL& url) { - const String& urlString = url.string(); - CachedResource* cachedResource = frame->document()->cachedResourceLoader()->cachedResource(urlString); + CachedResource* cachedResource = frame->document()->cachedResourceLoader()->cachedResource(url); if (!cachedResource) - cachedResource = cache()->resourceForURL(urlString); + cachedResource = cache()->resourceForURL(url); return cachedResource; } @@ -285,7 +286,13 @@ InspectorResourceAgent::~InspectorResourceAgent() void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader) { RefPtr<InspectorObject> loaderObject = buildObjectForDocumentLoader(loader); - m_frontend->identifierForInitialRequest(identifier, url.string(), loaderObject); + RefPtr<ScriptCallStack> callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); + RefPtr<InspectorValue> callStackValue; + if (callStack) + callStackValue = callStack->buildInspectorObject(); + else + callStackValue = InspectorValue::null(); + m_frontend->identifierForInitialRequest(identifier, url.string(), loaderObject, callStackValue); } void InspectorResourceAgent::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) diff --git a/WebCore/inspector/InspectorState.cpp b/WebCore/inspector/InspectorState.cpp index ab900e7..0865648 100644 --- a/WebCore/inspector/InspectorState.cpp +++ b/WebCore/inspector/InspectorState.cpp @@ -40,15 +40,16 @@ InspectorState::InspectorState(InspectorClient* client) : m_client(client) { registerBoolean(monitoringXHR, false, "monitoringXHREnabled", "xhrMonitor"); - registerBoolean(timelineProfilerEnabled, false, "timelineProfilerEnabled", (const char*)0); - registerBoolean(searchingForNode, false, "searchingForNodeEnabled", (const char*)0); - registerBoolean(profilerAlwaysEnabled, false, (const char*)0, "profilerEnabled"); - registerBoolean(debuggerAlwaysEnabled, false, (const char*)0, "debuggerEnabled"); - registerBoolean(inspectorStartsAttached, true, (const char*)0, "InspectorStartsAttached"); - registerLong(inspectorAttachedHeight, InspectorController::defaultAttachedHeight, (const char*)0, "inspectorAttachedHeight"); - registerLong(pauseOnExceptionsState, 0, "pauseOnExceptionsState", (const char*)0); - registerBoolean(consoleMessagesEnabled, false, "consoleMessagesEnabled", (const char*)0); - registerBoolean(userInitiatedProfiling, false, "userInitiatedProfiling", (const char*)0); + registerBoolean(timelineProfilerEnabled, false, "timelineProfilerEnabled", String()); + registerBoolean(searchingForNode, false, "searchingForNodeEnabled", String()); + registerBoolean(profilerAlwaysEnabled, false, String(), "profilerEnabled"); + registerBoolean(debuggerAlwaysEnabled, false, String(), "debuggerEnabled"); + registerBoolean(inspectorStartsAttached, true, String(), "InspectorStartsAttached"); + registerLong(inspectorAttachedHeight, InspectorController::defaultAttachedHeight, String(), "inspectorAttachedHeight"); + registerLong(pauseOnExceptionsState, 0, "pauseOnExceptionsState", String()); + registerBoolean(consoleMessagesEnabled, false, "consoleMessagesEnabled", String()); + registerBoolean(userInitiatedProfiling, false, "userInitiatedProfiling", String()); + registerObject(stickyBreakpoints, String(), String()); } void InspectorState::restoreFromInspectorCookie(const String& json) @@ -152,6 +153,24 @@ long InspectorState::getLong(InspectorPropertyId id) return value; } +PassRefPtr<InspectorObject> InspectorState::getObject(InspectorPropertyId id) +{ + PropertyMap::iterator i = m_properties.find(id); + ASSERT(i != m_properties.end()); + return i->second.m_value->asObject(); +} + +void InspectorState::setObject(InspectorPropertyId id, PassRefPtr<InspectorObject> value) +{ + PropertyMap::iterator i = m_properties.find(id); + ASSERT(i != m_properties.end()); + Property& property = i->second; + property.m_value = value; + if (property.m_preferenceName.length()) + m_client->storeSetting(property.m_preferenceName, value->toJSONString()); + updateCookie(); +} + void InspectorState::registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias, const String& preferenceName) { m_properties.set(propertyId, Property::create(InspectorBasicValue::create(value), frontendAlias, preferenceName)); @@ -167,6 +186,11 @@ void InspectorState::registerLong(InspectorPropertyId propertyId, long value, co m_properties.set(propertyId, Property::create(InspectorBasicValue::create((double)value), frontendAlias, preferenceName)); } +void InspectorState::registerObject(InspectorPropertyId propertyId, const String& frontendAlias, const String& preferenceName) +{ + m_properties.set(propertyId, Property::create(InspectorObject::create(), frontendAlias, preferenceName)); +} + InspectorState::Property InspectorState::Property::create(PassRefPtr<InspectorValue> value, const String& frontendAlias, const String& preferenceName) { Property property; diff --git a/WebCore/inspector/InspectorState.h b/WebCore/inspector/InspectorState.h index aa2f1ec..4f57da7 100644 --- a/WebCore/inspector/InspectorState.h +++ b/WebCore/inspector/InspectorState.h @@ -55,6 +55,7 @@ public: pauseOnExceptionsState, consoleMessagesEnabled, userInitiatedProfiling, + stickyBreakpoints, lastPropertyId }; @@ -68,10 +69,12 @@ public: bool getBoolean(InspectorPropertyId propertyId); String getString(InspectorPropertyId propertyId); long getLong(InspectorPropertyId propertyId); + PassRefPtr<InspectorObject> getObject(InspectorPropertyId id); void setBoolean(InspectorPropertyId propertyId, bool value) { setValue(propertyId, InspectorBasicValue::create(value), value ? "true" : "false"); } void setString(InspectorPropertyId propertyId, const String& value) { setValue(propertyId, InspectorString::create(value), value); } void setLong(InspectorPropertyId propertyId, long value) { setValue(propertyId, InspectorBasicValue::create((double)value), String::number(value)); } + void setObject(InspectorPropertyId propertyId, PassRefPtr<InspectorObject> value); private: void updateCookie(); @@ -89,6 +92,7 @@ private: void registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias, const String& preferenceName); void registerString(InspectorPropertyId propertyId, const String& value, const String& frontendAlias, const String& preferenceName); void registerLong(InspectorPropertyId propertyId, long value, const String& frontendAlias, const String& preferenceName); + void registerObject(InspectorPropertyId propertyId, const String& frontendAlias, const String& preferenceName); InspectorClient* m_client; }; diff --git a/WebCore/inspector/InspectorStyleSheet.cpp b/WebCore/inspector/InspectorStyleSheet.cpp index b115d85..6e3ebe8 100644 --- a/WebCore/inspector/InspectorStyleSheet.cpp +++ b/WebCore/inspector/InspectorStyleSheet.cpp @@ -131,19 +131,6 @@ static PassRefPtr<CSSRuleList> asCSSRuleList(StyleBase* styleBase) return 0; } -PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet) -{ - return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet)); -} - -InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet) - : m_styleId(styleId) - , m_style(style) - , m_parentStyleSheet(parentStyleSheet) -{ - ASSERT(m_style); -} - PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const { RefPtr<InspectorObject> result = InspectorObject::create(); @@ -154,7 +141,7 @@ PassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const propertiesObject->setString("width", m_style->getPropertyValue("width")); propertiesObject->setString("height", m_style->getPropertyValue("height")); - RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0; + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0; if (sourceData) { propertiesObject->setNumber("startOffset", sourceData->styleSourceData->styleBodyRange.start); propertiesObject->setNumber("endOffset", sourceData->styleSourceData->styleBodyRange.end); @@ -191,7 +178,9 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, p.parseDeclaration(tempMutableStyle.get(), propertyText + " -webkit-boguz-propertee: none", &sourceData); Vector<CSSPropertySourceData>& propertyData = sourceData->propertyData; unsigned propertyCount = propertyData.size(); - if (!propertyCount) + + // At least one property + the bogus property added just above should be present. + if (propertyCount < 2) return false; // Check for a proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state). @@ -228,7 +217,7 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, } } else { // Insert at index. - RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get()); + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); if (!sourceData) return false; String text; @@ -268,7 +257,7 @@ bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, } text.insert(textToSet, propertyStart); - m_parentStyleSheet->setStyleText(m_style.get(), text); + m_parentStyleSheet->setStyleText(m_style, text); } // Recompute subsequent disabled property ranges if acting on a non-disabled property. @@ -282,7 +271,7 @@ bool InspectorStyle::toggleProperty(unsigned index, bool disable) ASSERT(m_parentStyleSheet); if (!m_parentStyleSheet->ensureParsedDataReady()) return false; // Can toggle only source-based properties. - RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get()); + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); if (!sourceData) return false; // No source data for the style. @@ -323,7 +312,7 @@ unsigned InspectorStyle::disabledIndexByOrdinal(unsigned ordinal, bool canUseSub bool InspectorStyle::styleText(String* result) const { // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully. - RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get()); + RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style); if (!sourceData) return false; @@ -392,7 +381,7 @@ bool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* resul if (disabledIndex < disabledLength) disabledProperty = m_disabledProperties.at(disabledIndex); - RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0; + RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style) : 0; Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0; if (sourcePropertyData) { String styleDeclaration; @@ -519,7 +508,7 @@ bool InspectorStyle::replacePropertyInStyleText(const InspectorStyleProperty& pr return false; const SourceRange& range = property.sourceData.range; text.replace(range.start, range.end - range.start, newText); - success = m_parentStyleSheet->setStyleText(m_style.get(), text); + success = m_parentStyleSheet->setStyleText(m_style, text); return success; } @@ -574,12 +563,7 @@ Vector<String> InspectorStyle::longhandProperties(const String& shorthandPropert return properties; } -PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL) -{ - return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL)); -} - -InspectorStyleSheet::InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL) +InspectorStyleSheet::InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL) : m_id(id) , m_pageStyleSheet(pageStyleSheet) , m_origin(origin) @@ -1108,17 +1092,12 @@ void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, Vec } } -PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(const String& id, PassRefPtr<Element> element, const String& origin) -{ - return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, origin)); -} - -InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin) +InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin) : InspectorStyleSheet(id, 0, origin, "") , m_element(element) , m_ruleSourceData(0) { - ASSERT(m_element); + ASSERT(element); m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id, 0), inlineStyle(), this); } @@ -1175,7 +1154,7 @@ bool InspectorStyleSheetForInlineStyle::getStyleAttributeRanges(RefPtr<CSSStyleS if (!m_element->isStyledElement()) return false; - String styleText = static_cast<StyledElement*>(m_element.get())->getAttribute(styleAttributeName); + String styleText = static_cast<StyledElement*>(m_element)->getAttribute(styleAttributeName); if (styleText.isEmpty()) { (*result)->styleBodyRange.start = 0; (*result)->styleBodyRange.end = 0; diff --git a/WebCore/inspector/InspectorStyleSheet.h b/WebCore/inspector/InspectorStyleSheet.h index 2e5f2bc..b649bed 100644 --- a/WebCore/inspector/InspectorStyleSheet.h +++ b/WebCore/inspector/InspectorStyleSheet.h @@ -26,7 +26,6 @@ #define InspectorStyleSheet_h #include "CSSPropertySourceData.h" -#include "CSSStyleDeclaration.h" #include "InspectorValues.h" #include "PlatformString.h" @@ -41,6 +40,7 @@ class ParsedStyleSheet; namespace WebCore { class CSSRuleList; +class CSSStyleDeclaration; class CSSStyleSheet; class Document; class Element; @@ -121,17 +121,26 @@ struct InspectorStyleProperty { class InspectorStyle : public RefCounted<InspectorStyle> { public: - static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); + static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet) + { + return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet)); + } + + InspectorStyle(const InspectorCSSId& styleId, CSSStyleDeclaration* style, InspectorStyleSheet* parentStyleSheet) + : m_styleId(styleId) + , m_style(style) + , m_parentStyleSheet(parentStyleSheet) + { + ASSERT(style); + } - CSSStyleDeclaration* cssStyle() const { return m_style.get(); } + CSSStyleDeclaration* cssStyle() const { return m_style; } PassRefPtr<InspectorObject> buildObjectForStyle() const; bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); } bool setPropertyText(unsigned index, const String& text, bool overwrite); bool toggleProperty(unsigned index, bool disable); private: - InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); - static unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties); bool styleText(String* result) const; @@ -146,7 +155,7 @@ private: Vector<String> longhandProperties(const String& shorthandProperty) const; InspectorCSSId m_styleId; - RefPtr<CSSStyleDeclaration> m_style; + CSSStyleDeclaration* m_style; InspectorStyleSheet* m_parentStyleSheet; Vector<InspectorStyleProperty> m_disabledProperties; }; @@ -154,13 +163,17 @@ private: class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> { public: typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap; - static PassRefPtr<InspectorStyleSheet> create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL); + static PassRefPtr<InspectorStyleSheet> create(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL) + { + return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL)); + } + InspectorStyleSheet(const String& id, CSSStyleSheet* pageStyleSheet, const String& origin, const String& documentURL); virtual ~InspectorStyleSheet(); String id() const { return m_id; } String finalURL() const; - CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); } + CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet; } void reparseStyleSheet(const String&); bool setText(const String&); bool setRuleSelector(const InspectorCSSId&, const String& selector); @@ -176,8 +189,6 @@ public: virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const; protected: - InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL); - bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; } InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const; virtual Document* ownerDocument() const; @@ -207,7 +218,7 @@ private: PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*); String m_id; - RefPtr<CSSStyleSheet> m_pageStyleSheet; + CSSStyleSheet* m_pageStyleSheet; String m_origin; String m_documentURL; bool m_isRevalidating; @@ -220,14 +231,16 @@ private: class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet { public: - static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtr<Element> element, const String& origin); + static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, Element* element, const String& origin) + { + return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, origin)); + } + InspectorStyleSheetForInlineStyle(const String& id, Element* element, const String& origin); virtual bool text(String* result) const; virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); } protected: - InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin); - virtual Document* ownerDocument() const; virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; } virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; } @@ -243,7 +256,7 @@ private: CSSStyleDeclaration* inlineStyle() const; bool getStyleAttributeRanges(RefPtr<CSSStyleSourceData>* result); - RefPtr<Element> m_element; + Element* m_element; RefPtr<CSSRuleSourceData> m_ruleSourceData; RefPtr<InspectorStyle> m_inspectorStyle; }; diff --git a/WebCore/inspector/InspectorTimelineAgent.cpp b/WebCore/inspector/InspectorTimelineAgent.cpp index 645b692..74739e1 100644 --- a/WebCore/inspector/InspectorTimelineAgent.cpp +++ b/WebCore/inspector/InspectorTimelineAgent.cpp @@ -244,8 +244,8 @@ void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, { pushGCEventRecords(); // Sometimes network stack can provide for us exact finish loading time. In the other case we will use currentTime. - RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(finishTime ? finishTime * 1000 : WTF::currentTimeMS()); - record->setObject("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail)); + RefPtr<InspectorObject> record = TimelineRecordFactory::createGenericRecord(WTF::currentTimeMS()); + record->setObject("data", TimelineRecordFactory::createResourceFinishData(identifier, didFail, finishTime * 1000)); record->setNumber("type", ResourceFinishTimelineRecordType); setHeapSizeStatistic(record.get()); m_frontend->addRecordToTimeline(record.release()); diff --git a/WebCore/inspector/ScriptArguments.cpp b/WebCore/inspector/ScriptArguments.cpp index e30e135..b0fe554 100644 --- a/WebCore/inspector/ScriptArguments.cpp +++ b/WebCore/inspector/ScriptArguments.cpp @@ -35,6 +35,11 @@ namespace WebCore { +PassRefPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments) +{ + return adoptRef(new ScriptArguments(scriptState, arguments)); +} + ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>& arguments) : m_scriptState(scriptState) { diff --git a/WebCore/inspector/ScriptArguments.h b/WebCore/inspector/ScriptArguments.h index fdf05ab..26549b6 100644 --- a/WebCore/inspector/ScriptArguments.h +++ b/WebCore/inspector/ScriptArguments.h @@ -33,15 +33,18 @@ #include "PlatformString.h" #include "ScriptState.h" +#include <wtf/Forward.h> +#include <wtf/RefCounted.h> #include <wtf/Vector.h> namespace WebCore { class ScriptValue; -class ScriptArguments { +class ScriptArguments : public RefCounted<ScriptArguments> { public: - ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments); + static PassRefPtr<ScriptArguments> create(ScriptState*, Vector<ScriptValue>& arguments); + ~ScriptArguments(); const ScriptValue& argumentAt(size_t) const; @@ -53,6 +56,8 @@ public: bool isEqual(ScriptArguments*) const; private: + ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments); + ScriptStateProtectedPtr m_scriptState; Vector<ScriptValue> m_arguments; }; diff --git a/WebCore/inspector/ScriptCallFrame.cpp b/WebCore/inspector/ScriptCallFrame.cpp index c4dab3c..0b5204b 100644 --- a/WebCore/inspector/ScriptCallFrame.cpp +++ b/WebCore/inspector/ScriptCallFrame.cpp @@ -36,10 +36,11 @@ namespace WebCore { -ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, unsigned lineNumber) +ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column) : m_functionName(functionName) - , m_sourceURL(urlString) + , m_scriptName(scriptName) , m_lineNumber(lineNumber) + , m_column(column) { } @@ -50,7 +51,7 @@ ScriptCallFrame::~ScriptCallFrame() bool ScriptCallFrame::isEqual(const ScriptCallFrame& o) const { return m_functionName == o.m_functionName - && m_sourceURL == o.m_sourceURL + && m_scriptName == o.m_scriptName && m_lineNumber == o.m_lineNumber; } @@ -59,8 +60,9 @@ PassRefPtr<InspectorObject> ScriptCallFrame::buildInspectorObject() const { RefPtr<InspectorObject> frame = InspectorObject::create(); frame->setString("functionName", m_functionName); - frame->setString("sourceURL", m_sourceURL); + frame->setString("scriptName", m_scriptName); frame->setNumber("lineNumber", m_lineNumber); + frame->setNumber("column", m_column); return frame; } #endif diff --git a/WebCore/inspector/ScriptCallFrame.h b/WebCore/inspector/ScriptCallFrame.h index 60d77e1..2c025dc 100644 --- a/WebCore/inspector/ScriptCallFrame.h +++ b/WebCore/inspector/ScriptCallFrame.h @@ -32,7 +32,7 @@ #define ScriptCallFrame_h #include "PlatformString.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Forward.h> namespace WebCore { @@ -40,11 +40,11 @@ class InspectorObject; class ScriptCallFrame { public: - ScriptCallFrame(const String& functionName, const String& urlString, unsigned lineNumber); + ScriptCallFrame(const String& functionName, const String& scriptName, unsigned lineNumber, unsigned column = 0); ~ScriptCallFrame(); const String& functionName() const { return m_functionName; } - const String& sourceURL() const { return m_sourceURL; } + const String& sourceURL() const { return m_scriptName; } unsigned lineNumber() const { return m_lineNumber; } bool isEqual(const ScriptCallFrame&) const; @@ -52,8 +52,9 @@ public: private: String m_functionName; - String m_sourceURL; + String m_scriptName; unsigned m_lineNumber; + unsigned m_column; }; } // namespace WebCore diff --git a/WebCore/inspector/ScriptCallStack.cpp b/WebCore/inspector/ScriptCallStack.cpp index 31ec1c1..70229e5 100644 --- a/WebCore/inspector/ScriptCallStack.cpp +++ b/WebCore/inspector/ScriptCallStack.cpp @@ -35,6 +35,11 @@ namespace WebCore { +PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames) +{ + return adoptRef(new ScriptCallStack(frames)); +} + ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames) { m_frames.swap(frames); @@ -44,13 +49,13 @@ ScriptCallStack::~ScriptCallStack() { } -const ScriptCallFrame &ScriptCallStack::at(size_t index) +const ScriptCallFrame &ScriptCallStack::at(size_t index) const { ASSERT(m_frames.size() > index); return m_frames[index]; } -size_t ScriptCallStack::size() +size_t ScriptCallStack::size() const { return m_frames.size(); } diff --git a/WebCore/inspector/ScriptCallStack.h b/WebCore/inspector/ScriptCallStack.h index 54c6bba..4cb152f 100644 --- a/WebCore/inspector/ScriptCallStack.h +++ b/WebCore/inspector/ScriptCallStack.h @@ -32,28 +32,31 @@ #define ScriptCallStack_h #include "ScriptCallFrame.h" -#include <wtf/Noncopyable.h> +#include <wtf/Forward.h> +#include <wtf/RefCounted.h> #include <wtf/Vector.h> namespace WebCore { class InspectorArray; -class ScriptCallStack : public Noncopyable { +class ScriptCallStack : public RefCounted<ScriptCallStack> { public: static const size_t maxCallStackSizeToCapture = 200; + + static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&); - ScriptCallStack(Vector<ScriptCallFrame>&); ~ScriptCallStack(); - const ScriptCallFrame &at(size_t); - size_t size(); - static bool stackTrace(int, const RefPtr<InspectorArray>&); + const ScriptCallFrame &at(size_t) const; + size_t size() const; bool isEqual(ScriptCallStack*) const; PassRefPtr<InspectorArray> buildInspectorObject() const; private: + ScriptCallStack(Vector<ScriptCallFrame>&); + Vector<ScriptCallFrame> m_frames; }; diff --git a/WebCore/inspector/TimelineRecordFactory.cpp b/WebCore/inspector/TimelineRecordFactory.cpp index 713d6bc..7f339cd 100644 --- a/WebCore/inspector/TimelineRecordFactory.cpp +++ b/WebCore/inspector/TimelineRecordFactory.cpp @@ -39,6 +39,7 @@ #include "ResourceRequest.h" #include "ResourceResponse.h" #include "ScriptCallStack.h" +#include "ScriptCallStackFactory.h" namespace WebCore { @@ -47,9 +48,9 @@ PassRefPtr<InspectorObject> TimelineRecordFactory::createGenericRecord(double st RefPtr<InspectorObject> record = InspectorObject::create(); record->setNumber("startTime", startTime); - RefPtr<InspectorArray> stackTrace = InspectorArray::create(); - if (ScriptCallStack::stackTrace(5, stackTrace)) - record->setArray("stackTrace", stackTrace); + RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(5, true); + if (stackTrace && stackTrace->size()) + record->setArray("stackTrace", stackTrace->buildInspectorObject()); return record.release(); } @@ -148,11 +149,13 @@ PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceReceiveResponse return data.release(); } -PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceFinishData(unsigned long identifier, bool didFail) +PassRefPtr<InspectorObject> TimelineRecordFactory::createResourceFinishData(unsigned long identifier, bool didFail, double finishTime) { RefPtr<InspectorObject> data = InspectorObject::create(); data->setNumber("identifier", identifier); data->setBoolean("didFail", didFail); + if (finishTime) + data->setNumber("networkTime", finishTime); return data.release(); } diff --git a/WebCore/inspector/TimelineRecordFactory.h b/WebCore/inspector/TimelineRecordFactory.h index 52dda25..5d4cb77 100644 --- a/WebCore/inspector/TimelineRecordFactory.h +++ b/WebCore/inspector/TimelineRecordFactory.h @@ -73,7 +73,7 @@ namespace WebCore { static PassRefPtr<InspectorObject> createReceiveResourceData(unsigned long identifier); - static PassRefPtr<InspectorObject> createResourceFinishData(unsigned long identifier, bool didFail); + static PassRefPtr<InspectorObject> createResourceFinishData(unsigned long identifier, bool didFail, double finishTime); static PassRefPtr<InspectorObject> createPaintData(const IntRect&); diff --git a/WebCore/inspector/front-end/AuditLauncherView.js b/WebCore/inspector/front-end/AuditLauncherView.js index 3ec4ba2..d4bbf90 100644 --- a/WebCore/inspector/front-end/AuditLauncherView.js +++ b/WebCore/inspector/front-end/AuditLauncherView.js @@ -53,6 +53,24 @@ WebInspector.AuditLauncherView = function(runnerCallback) } WebInspector.AuditLauncherView.prototype = { + updateResourceTrackingState: function(isTracking) + { + if (!this._auditPresentStateLabelElement) + return; + + if (isTracking) { + this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State"); + this._auditPresentStateElement.disabled = false; + this._auditPresentStateElement.parentElement.removeStyleClass("disabled"); + } else { + this._resetResourceCount(); + this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State (Resource Tracking must be enabled)"); + this._auditPresentStateElement.disabled = true; + this._auditPresentStateElement.parentElement.addStyleClass("disabled"); + this.auditReloadedStateElement.checked = true; + } + }, + get totalResources() { return this._totalResources; @@ -219,7 +237,7 @@ WebInspector.AuditLauncherView.prototype = { this._auditPresentStateElement.name = "audit-mode"; this._auditPresentStateElement.type = "radio"; this._auditPresentStateElement.checked = true; - this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State")); + this._auditPresentStateLabelElement = document.createTextNode(""); labelElement.appendChild(this._auditPresentStateElement); labelElement.appendChild(this._auditPresentStateLabelElement); this._buttonContainerElement.appendChild(labelElement); @@ -249,6 +267,7 @@ WebInspector.AuditLauncherView.prototype = { this._contentElement.appendChild(this._buttonContainerElement); this._selectAllClicked(this._selectAllCheckboxElement.checked); + this.updateResourceTrackingState(); this._updateButton(); this._updateResourceProgress(); }, diff --git a/WebCore/inspector/front-end/AuditsPanel.js b/WebCore/inspector/front-end/AuditsPanel.js index c42077f..096f8ce 100644 --- a/WebCore/inspector/front-end/AuditsPanel.js +++ b/WebCore/inspector/front-end/AuditsPanel.js @@ -248,6 +248,12 @@ WebInspector.AuditsPanel.prototype = { x.show(this.viewsContainerElement); }, + show: function() + { + WebInspector.Panel.prototype.show.call(this); + this._updateLauncherViewControls(!WebInspector.panels.resources || WebInspector.panels.resources.resourceTrackingEnabled); + }, + reset: function() { this._launcherView.reset(); @@ -265,6 +271,12 @@ WebInspector.AuditsPanel.prototype = { this.viewsContainerElement.style.left = width + "px"; }, + _updateLauncherViewControls: function(isTracking) + { + if (this._launcherView) + this._launcherView.updateResourceTrackingState(isTracking); + }, + _clearButtonClicked: function() { this.auditsItemTreeElement.reveal(); diff --git a/WebCore/inspector/front-end/Breakpoint.js b/WebCore/inspector/front-end/Breakpoint.js new file mode 100644 index 0000000..dd0ce12 --- /dev/null +++ b/WebCore/inspector/front-end/Breakpoint.js @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.Breakpoint = function(debuggerModel, breakpointId, sourceID, url, line, enabled, condition) +{ + this.id = breakpointId; + this.url = url; + this.line = line; + this.sourceID = sourceID; + this._enabled = enabled; + this._condition = condition || ""; + this._sourceText = ""; + this._hit = false; + this._debuggerModel = debuggerModel; +} + +WebInspector.Breakpoint.prototype = { + get enabled() + { + return this._enabled; + }, + + get sourceText() + { + return this._sourceText; + }, + + set sourceText(text) + { + this._sourceText = text; + this.dispatchEventToListeners("label-changed"); + }, + + get condition() + { + return this._condition; + }, + + get hit() + { + return this._hit; + }, + + set hit(hit) + { + this._hit = hit; + this.dispatchEventToListeners("hit-state-changed"); + }, + + click: function(event) + { + WebInspector.panels.scripts.showSourceLine(this.url, this.line); + }, + + compareTo: function(other) + { + if (this.url != other.url) + return this.url < other.url ? -1 : 1; + if (this.line != other.line) + return this.line < other.line ? -1 : 1; + return 0; + }, + + populateLabelElement: function(element) + { + var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"); + var labelElement = document.createTextNode(displayName + ":" + this.line); + element.appendChild(labelElement); + + var sourceTextElement = document.createElement("div"); + sourceTextElement.textContent = this.sourceText; + sourceTextElement.className = "source-text monospace"; + element.appendChild(sourceTextElement); + }, + + remove: function() + { + this._debuggerModel.removeBreakpoint(this.id); + this.dispatchEventToListeners("removed"); + this.removeAllListeners(); + delete this._debuggerModel; + } +} + +WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js index 3d51092..67ef112 100644 --- a/WebCore/inspector/front-end/BreakpointManager.js +++ b/WebCore/inspector/front-end/BreakpointManager.js @@ -1,273 +1,249 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * modification, are permitted provided that the following conditions are + * met: * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ WebInspector.BreakpointManager = function() { + this._stickyBreakpoints = {}; + var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints"); + for (var projectId in breakpoints) + this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]); + InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints); + this._breakpoints = {}; - this._nativeBreakpoints = {}; + this._domBreakpointsRestored = false; + this._scriptBreakpoints = {}; + + WebInspector.settings.addEventListener(WebInspector.Settings.Events.ProjectChanged, this._projectChanged, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._scriptBreakpointAdded, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._scriptBreakpointRemoved, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); +} + +WebInspector.BreakpointManager.BreakpointTypes = { + DOM: "DOM", + JS: "JS", + EventListener: "EventListener", + XHR: "XHR" +} + +WebInspector.BreakpointManager.Events = { + DOMBreakpointAdded: "dom-breakpoint-added", + EventListenerBreakpointAdded: "event-listener-breakpoint-added", + XHRBreakpointAdded: "xhr-breakpoint-added", + ProjectChanged: "project-changed" } WebInspector.BreakpointManager.prototype = { - setOneTimeBreakpoint: function(sourceID, line) + createDOMBreakpoint: function(nodeId, type) { - var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined); - if (this._breakpoints[breakpoint.id]) - return; - if (this._oneTimeBreakpoint) - InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line); - this._oneTimeBreakpoint = breakpoint; - // FIXME(40669): one time breakpoint will be persisted in inspector settings if not hit. - this._setBreakpointOnBackend(breakpoint, true); + this._createDOMBreakpoint(nodeId, type, true, false); }, - removeOneTimeBreakpoint: function() + _createDOMBreakpoint: function(nodeId, type, enabled, restored) { - if (this._oneTimeBreakpoint) { - InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line); - delete this._oneTimeBreakpoint; - } - }, + var node = WebInspector.domAgent.nodeForId(nodeId); + if (!node) + return; - setBreakpoint: function(sourceID, url, line, enabled, condition) - { - var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition); - if (breakpoint) - this._setBreakpointOnBackend(breakpoint); - }, + var breakpointId = this._createDOMBreakpointId(nodeId, type); + if (breakpointId in this._breakpoints) + return; - restoredBreakpoint: function(sourceID, url, line, enabled, condition) - { - this._setBreakpoint(sourceID, url, line, enabled, condition); - }, + var breakpoint = new WebInspector.DOMBreakpoint(node, type); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + if (enabled && restored) + breakpoint._enable(); - breakpointsForSourceID: function(sourceID) - { - var breakpoints = []; - for (var id in this._breakpoints) { - if (this._breakpoints[id].sourceID === sourceID) - breakpoints.push(this._breakpoints[id]); - } - return breakpoints; + breakpoint.view = new WebInspector.DOMBreakpointView(this, breakpointId, enabled, node, type); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpoint.view); }, - breakpointsForURL: function(url) + createEventListenerBreakpoint: function(eventName) { - var breakpoints = []; - for (var id in this._breakpoints) { - if (this._breakpoints[id].url === url) - breakpoints.push(this._breakpoints[id]); - } - return breakpoints; + this._createEventListenerBreakpoint(eventName, true, false); }, - reset: function() + _createEventListenerBreakpoint: function(eventName, enabled, restored) { - this._breakpoints = {}; - delete this._oneTimeBreakpoint; - this._nativeBreakpoints = {}; + var breakpointId = this._createEventListenerBreakpointId(eventName); + if (breakpointId in this._breakpoints) + return; + + var breakpoint = new WebInspector.EventListenerBreakpoint(eventName); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + + breakpoint.view = new WebInspector.EventListenerBreakpointView(this, breakpointId, enabled, eventName); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, breakpoint.view); }, - _setBreakpoint: function(sourceID, url, line, enabled, condition) + _createJavaScriptBreakpoint: function(url, lineNumber, condition, enabled, restored) { - var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition); - if (this._breakpoints[breakpoint.id]) + var breakpointId = this._createJavaScriptBreakpointId(url, lineNumber); + if (breakpointId in this._breakpoints) return; - if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id)) - delete this._oneTimeBreakpoint; - this._breakpoints[breakpoint.id] = breakpoint; - breakpoint.addEventListener("removed", this._breakpointRemoved, this); - this.dispatchEventToListeners("breakpoint-added", breakpoint); - return breakpoint; - }, - _breakpointRemoved: function(event) - { - delete this._breakpoints[event.target.id]; + var breakpoint = new WebInspector.JavaScriptBreakpoint(url, lineNumber, condition); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); }, - _setBreakpointOnBackend: function(breakpoint, isOneTime) + _scriptBreakpointAdded: function(event) { - function didSetBreakpoint(success, line) - { - if (success && line == breakpoint.line) - return; - if (isOneTime) { - if (success) - this._oneTimeBreakpoint.line = line; - else - delete this._oneTimeBreakpoint; - } else { - breakpoint.remove(); - if (success) - this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition); - } - } - InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this)); - }, + var scriptBreakpoint = event.data; - createDOMBreakpoint: function(nodeId, domEventType, disabled) - { - var frontendId = "dom:" + nodeId + ":" + domEventType; - if (frontendId in this._nativeBreakpoints) + if (!scriptBreakpoint.url) return; - var breakpoint = new WebInspector.DOMBreakpoint(this, frontendId, nodeId, domEventType); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("dom-breakpoint-added", breakpoint); - breakpoint.enabled = !disabled; - return breakpoint; + if (!scriptBreakpoint.restored) + this._createJavaScriptBreakpoint(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber, scriptBreakpoint.condition, scriptBreakpoint.enabled, false); + var breakpointId = this._createJavaScriptBreakpointId(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber); + this._scriptBreakpoints[scriptBreakpoint.id] = breakpointId; }, - createEventListenerBreakpoint: function(eventName) + _scriptBreakpointRemoved: function(event) { - var frontendId = eventName; - if (frontendId in this._nativeBreakpoints) - return; + var scriptBreakpointId = event.data; + var breakpointId = this._scriptBreakpoints[scriptBreakpointId]; + delete this._scriptBreakpoints[scriptBreakpointId]; + if (breakpointId in this._breakpoints) + this._removeBreakpoint(breakpointId); + }, - var breakpoint = new WebInspector.EventListenerBreakpoint(this, frontendId, eventName); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("event-listener-breakpoint-added", { breakpoint: breakpoint, eventName: eventName }); - breakpoint.enabled = true; - return breakpoint; + createXHRBreakpoint: function(url) + { + this._createXHRBreakpoint(url, true, false); }, - createXHRBreakpoint: function(url, disabled) + _createXHRBreakpoint: function(url, enabled, restored) { - var frontendId = url; - if (frontendId in this._nativeBreakpoints) + var breakpointId = this._createXHRBreakpointId(url); + if (breakpointId in this._breakpoints) return; - var breakpoint = new WebInspector.XHRBreakpoint(this, frontendId, url); - this._nativeBreakpoints[frontendId] = breakpoint; - this.dispatchEventToListeners("xhr-breakpoint-added", breakpoint); - breakpoint.enabled = !disabled - return breakpoint; + var breakpoint = new WebInspector.XHRBreakpoint(url); + this._setBreakpoint(breakpointId, breakpoint, enabled, restored); + + breakpoint.view = new WebInspector.XHRBreakpointView(this, breakpointId, enabled, url); + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.XHRBreakpointAdded, breakpoint.view); }, - _removeNativeBreakpoint: function(breakpoint) + _setBreakpoint: function(breakpointId, breakpoint, enabled, restored) { - if (breakpoint._beingSetOnBackend) + this._breakpoints[breakpointId] = breakpoint; + breakpoint.enabled = enabled; + if (restored) return; - if (breakpoint.enabled) - this._removeNativeBreakpointFromBackend(breakpoint); - delete this._nativeBreakpoints[breakpoint._frontendId]; - this._updateNativeBreakpointsInSettings(); - breakpoint.dispatchEventToListeners("removed"); + if (enabled) + breakpoint._enable(); + this._saveBreakpoints(); }, - _setNativeBreakpointEnabled: function(breakpoint, enabled) + _setBreakpointEnabled: function(breakpointId, enabled) { - if (breakpoint._beingSetOnBackend) - return; + var breakpoint = this._breakpoints[breakpointId]; if (breakpoint.enabled === enabled) return; if (enabled) - this._setNativeBreakpointOnBackend(breakpoint); + breakpoint._enable(); else - this._removeNativeBreakpointFromBackend(breakpoint); + breakpoint._disable(); + breakpoint.enabled = enabled; + this._saveBreakpoints(); }, - _setNativeBreakpointOnBackend: function(breakpoint) + _removeBreakpoint: function(breakpointId) { - breakpoint._beingSetOnBackend = true; - var data = { type: breakpoint._type, condition: breakpoint._condition }; - InspectorBackend.setNativeBreakpoint(data, didSetNativeBreakpoint.bind(this)); - - function didSetNativeBreakpoint(backendBreakpointId) - { - breakpoint._beingSetOnBackend = false; - if (backendBreakpointId !== "") { - breakpoint._backendId = backendBreakpointId; - this._breakpoints[backendBreakpointId] = breakpoint; - } - breakpoint.dispatchEventToListeners("enable-changed"); - this._updateNativeBreakpointsInSettings(); - } + var breakpoint = this._breakpoints[breakpointId]; + if (breakpoint.enabled) + breakpoint._disable(); + delete this._breakpoints[breakpointId]; + this._saveBreakpoints(); }, - _removeNativeBreakpointFromBackend: function(breakpoint) + breakpointViewForEventData: function(eventData) { - InspectorBackend.removeNativeBreakpoint(breakpoint._backendId); - delete this._breakpoints[breakpoint._backendId] - delete breakpoint._backendId; - breakpoint.dispatchEventToListeners("enable-changed"); - this._updateNativeBreakpointsInSettings(); - }, + var breakpointId; + if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.DOM) + breakpointId = this._createDOMBreakpointId(eventData.nodeId, eventData.type); + else if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.EventListener) + breakpointId = this._createEventListenerBreakpointId(eventData.eventName); + else if (eventData.breakpointType === WebInspector.BreakpointManager.BreakpointTypes.XHR) + breakpointId = this._createXHRBreakpointId(eventData.breakpointURL); + else + return; - _updateNativeBreakpointsInSettings: function() - { - var persistentBreakpoints = []; - for (var id in this._nativeBreakpoints) { - var breakpoint = this._nativeBreakpoints[id]; - if (breakpoint._persistentCondition) - persistentBreakpoints.push({ type: breakpoint._type, enabled: breakpoint.enabled, condition: breakpoint._persistentCondition }); - } - WebInspector.settings.nativeBreakpoints = persistentBreakpoints; + var breakpoint = this._breakpoints[breakpointId]; + if (breakpoint) + return breakpoint.view; }, - debuggerPaused: function(details) + _debuggerPaused: function(event) { - if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause) - return; + var eventType = event.data.eventType; + var eventData = event.data.eventData; - if (details.eventData && details.eventData.breakpointId) - var breakpointId = details.eventData.breakpointId; - else if (details.callFrames && details.callFrames.length) - var breakpointId = WebInspector.Breakpoint.jsBreakpointId(details.callFrames[0].sourceID, details.callFrames[0].line); - else + if (eventType !== WebInspector.DebuggerEventTypes.NativeBreakpoint) return; - var breakpoint = this._breakpoints[breakpointId]; - if (!breakpoint) + var breakpointView = this.breakpointViewForEventData(eventData); + if (!breakpointView) return; - breakpoint.hit = true; - breakpoint.dispatchEventToListeners("hit-state-changed"); - this._lastHitBreakpoint = breakpoint; - - this.dispatchEventToListeners("breakpoint-hit", { breakpoint: breakpoint, eventData: details.eventData }); + breakpointView.hit = true; + this._lastHitBreakpointView = breakpointView; }, - debuggerResumed: function() + _debuggerResumed: function(event) { - if (!this._lastHitBreakpoint) + if (!this._lastHitBreakpointView) return; - this._lastHitBreakpoint.hit = false; - this._lastHitBreakpoint.dispatchEventToListeners("hit-state-changed"); - delete this._lastHitBreakpoint; + this._lastHitBreakpointView.hit = false; + delete this._lastHitBreakpointView; }, - restoreBreakpoints: function() + _projectChanged: function(event) { - var breakpoints = this._persistentBreakpoints(); + this._breakpoints = {}; + this._domBreakpointsRestored = false; + this._scriptBreakpoints = {}; + this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.ProjectChanged); + + var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; for (var i = 0; i < breakpoints.length; ++i) { - if (breakpoints[i].type === "EventListener") - this.createEventListenerBreakpoint(breakpoints[i].condition.eventName); - else if (breakpoints[i].type === "XHR") - this.createXHRBreakpoint(breakpoints[i].condition.url, !breakpoints[i].enabled); + var breakpoint = breakpoints[i]; + if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener) + this._createEventListenerBreakpoint(breakpoint.condition.eventName, breakpoint.enabled, true); + else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) + this._createJavaScriptBreakpoint(breakpoint.condition.url, breakpoint.condition.lineNumber, breakpoint.condition.condition, breakpoint.enabled, true); + else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) + this._createXHRBreakpoint(breakpoint.condition.url, breakpoint.enabled, true); } }, @@ -281,17 +257,21 @@ WebInspector.BreakpointManager.prototype = { return; for (var i = 0; i < breakpoints.length; ++i) { var breakpoint = breakpoints[i]; + if (breakpoint.type !== WebInspector.BreakpointManager.BreakpointTypes.DOM) + continue; var nodeId = pathToNodeId[breakpoint.condition.path]; if (nodeId) - this.createDOMBreakpoint(nodeId, breakpoint.condition.type, !breakpoint.enabled); + this._createDOMBreakpoint(nodeId, breakpoint.condition.type, breakpoint.enabled, true); } + this._domBreakpointsRestored = true; + this._saveBreakpoints(); } - var breakpoints = this._persistentBreakpoints(); + var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; var pathToNodeId = {}; var pendingCalls = 0; for (var i = 0; i < breakpoints.length; ++i) { - if (breakpoints[i].type !== "DOM") + if (breakpoints[i].type !== WebInspector.BreakpointManager.BreakpointTypes.DOM) continue; var path = breakpoints[i].condition.path; if (path in pathToNodeId) @@ -300,159 +280,223 @@ WebInspector.BreakpointManager.prototype = { pendingCalls += 1; InspectorBackend.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path)); } + if (!pendingCalls) + this._domBreakpointsRestored = true; }, - _persistentBreakpoints: function() + _saveBreakpoints: function() { - var result = []; - var breakpoints = WebInspector.settings.nativeBreakpoints; - if (breakpoints instanceof Array) { - for (var i = 0; i < breakpoints.length; ++i) { - var breakpoint = breakpoints[i]; - if ("type" in breakpoint && "condition" in breakpoint) - result.push(breakpoint) + var breakpoints = []; + for (var breakpointId in this._breakpoints) { + var breakpoint = this._breakpoints[breakpointId]; + var persistentBreakpoint = breakpoint._serializeToJSON(); + persistentBreakpoint.enabled = breakpoint.enabled; + breakpoints.push(persistentBreakpoint); + } + if (!this._domBreakpointsRestored) { + var stickyBreakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || []; + for (var i = 0; i < stickyBreakpoints.length; ++i) { + if (stickyBreakpoints[i].type === WebInspector.BreakpointManager.BreakpointTypes.DOM) + breakpoints.push(stickyBreakpoints[i]); } } - return result; + WebInspector.settings.nativeBreakpoints = breakpoints; + + this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints; + InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints); + }, + + _validateBreakpoints: function(persistentBreakpoints) + { + var breakpoints = []; + var breakpointsSet = {}; + for (var i = 0; i < persistentBreakpoints.length; ++i) { + var breakpoint = persistentBreakpoints[i]; + if (!("type" in breakpoint && "enabled" in breakpoint && "condition" in breakpoint)) + continue; + var id = breakpoint.type + ":"; + var condition = breakpoint.condition; + if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.DOM) { + if (typeof condition.path !== "string" || typeof condition.type !== "number") + continue; + id += condition.path + ":" + condition.type; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener) { + if (typeof condition.eventName !== "string") + continue; + id += condition.eventName; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) { + if (typeof condition.url !== "string" || typeof condition.lineNumber !== "number" || typeof condition.condition !== "string") + continue; + id += condition.url + ":" + condition.lineNumber; + } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) { + if (typeof condition.url !== "string") + continue; + id += condition.url; + } + if (id in breakpointsSet) + continue; + breakpointsSet[id] = true; + breakpoints.push(breakpoint); + } + return breakpoints; + }, + + _createDOMBreakpointId: function(nodeId, type) + { + return "dom:" + nodeId + ":" + type; + }, + + _createJavaScriptBreakpointId: function(url, lineNumber) + { + return "js:" + url + ":" + lineNumber; + }, + + _createEventListenerBreakpointId: function(eventName) + { + return "eventListner:" + eventName; + }, + + _createXHRBreakpointId: function(url) + { + return "xhr:" + url; } } WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.Breakpoint = function(breakpointManager, sourceID, url, line, enabled, condition) +WebInspector.DOMBreakpoint = function(node, type) { - this.url = url; - this.line = line; - this.sourceID = sourceID; - this._enabled = enabled; - this._condition = condition || ""; - this._sourceText = ""; - this._breakpointManager = breakpointManager; + this._nodeId = node.id; + this._path = node.path(); + this._type = type; } -WebInspector.Breakpoint.jsBreakpointId = function(sourceID, line) -{ - return sourceID + ":" + line; -} +WebInspector.DOMBreakpoint.prototype = { + _enable: function() + { + InspectorBackend.setDOMBreakpoint(this._nodeId, this._type); + }, -WebInspector.Breakpoint.prototype = { - get enabled() + _disable: function() { - return this._enabled; + InspectorBackend.removeDOMBreakpoint(this._nodeId, this._type); }, - set enabled(x) + _serializeToJSON: function() { - if (this._enabled === x) - return; + var type = WebInspector.BreakpointManager.BreakpointTypes.DOM; + return { type: type, condition: { path: this._path, type: this._type } }; + } +} - this._enabled = x; - this._breakpointManager._setBreakpointOnBackend(this); - this.dispatchEventToListeners("enable-changed"); - }, +WebInspector.JavaScriptBreakpoint = function(url, lineNumber, condition) +{ + this._url = url; + this._lineNumber = lineNumber; + this._condition = condition; +} - get sourceText() +WebInspector.JavaScriptBreakpoint.prototype = { + _enable: function() { - return this._sourceText; }, - set sourceText(text) + _disable: function() { - this._sourceText = text; - this.dispatchEventToListeners("label-changed"); }, - get id() + _serializeToJSON: function() { - return WebInspector.Breakpoint.jsBreakpointId(this.sourceID, this.line); - }, + var type = WebInspector.BreakpointManager.BreakpointTypes.JS; + return { type: type, condition: { url: this._url, lineNumber: this._lineNumber, condition: this._condition } }; + } +} + +WebInspector.EventListenerBreakpoint = function(eventName) +{ + this._eventName = eventName; +} - get condition() +WebInspector.EventListenerBreakpoint.prototype = { + _enable: function() { - return this._condition; + InspectorBackend.setEventListenerBreakpoint(this._eventName); }, - set condition(c) + _disable: function() { - c = c || ""; - if (this._condition === c) - return; - - this._condition = c; - if (this.enabled) - this._breakpointManager._setBreakpointOnBackend(this); - this.dispatchEventToListeners("condition-changed"); + InspectorBackend.removeEventListenerBreakpoint(this._eventName); }, - click: function(event) + _serializeToJSON: function() { - WebInspector.panels.scripts.showSourceLine(this.url, this.line); - }, + var type = WebInspector.BreakpointManager.BreakpointTypes.EventListener; + return { type: type, condition: { eventName: this._eventName } }; + } +} - compareTo: function(other) +WebInspector.XHRBreakpoint = function(url) +{ + this._url = url; +} + +WebInspector.XHRBreakpoint.prototype = { + _enable: function() { - if (this.url != other.url) - return this.url < other.url ? -1 : 1; - if (this.line != other.line) - return this.line < other.line ? -1 : 1; - return 0; + InspectorBackend.setXHRBreakpoint(this._url); }, - populateLabelElement: function(element) + _disable: function() { - var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"); - var labelElement = document.createTextNode(displayName + ":" + this.line); - element.appendChild(labelElement); - - var sourceTextElement = document.createElement("div"); - sourceTextElement.textContent = this.sourceText; - sourceTextElement.className = "source-text monospace"; - element.appendChild(sourceTextElement); + InspectorBackend.removeXHRBreakpoint(this._url); }, - remove: function() + _serializeToJSON: function() { - InspectorBackend.removeBreakpoint(this.sourceID, this.line); - this.dispatchEventToListeners("removed"); - this.removeAllListeners(); - delete this._breakpointManager; + var type = WebInspector.BreakpointManager.BreakpointTypes.XHR; + return { type: type, condition: { url: this._url } }; } } -WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.NativeBreakpoint = function(manager, frontendId, type) + +WebInspector.NativeBreakpointView = function(manager, id, enabled) { this._manager = manager; - this.__frontendId = frontendId; - this.__type = type; + this._id = id; + this._enabled = enabled; + this._hit = false; } -WebInspector.NativeBreakpoint.prototype = { +WebInspector.NativeBreakpointView.prototype = { get enabled() { - return "_backendId" in this; + return this._enabled; }, set enabled(enabled) { - this._manager._setNativeBreakpointEnabled(this, enabled); + this._manager._setBreakpointEnabled(this._id, enabled); + this._enabled = enabled; + this.dispatchEventToListeners("enable-changed"); }, - remove: function() + get hit() { - this._manager._removeNativeBreakpoint(this); - this._onRemove(); + return this._hit; }, - get _frontendId() + set hit(hit) { - return this.__frontendId; + this._hit = hit; + this.dispatchEventToListeners("hit-state-changed"); }, - get _type() + remove: function() { - return this.__type; + this._manager._removeBreakpoint(this._id); + this._onRemove(); + this.dispatchEventToListeners("removed"); }, _compare: function(x, y) @@ -467,26 +511,21 @@ WebInspector.NativeBreakpoint.prototype = { } } -WebInspector.NativeBreakpoint.prototype.__proto__ = WebInspector.Object.prototype; +WebInspector.NativeBreakpointView.prototype.__proto__ = WebInspector.Object.prototype; -WebInspector.DOMBreakpoint = function(manager, frontendId, nodeId, domEventType) +WebInspector.DOMBreakpointView = function(manager, id, enabled, node, type) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "DOM"); - this._nodeId = nodeId; - this._domEventType = domEventType; - this._condition = { nodeId: this._nodeId, type: this._domEventType }; - - var node = WebInspector.domAgent.nodeForId(this._nodeId); - if (node) { - node.breakpoints[this._domEventType] = this; - this._persistentCondition = { path: node.path(), type: this._domEventType }; - } + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); + this._node = node; + this._nodeId = node.id; + this._type = type; + node.breakpoints[this._type] = this; } -WebInspector.DOMBreakpoint.prototype = { +WebInspector.DOMBreakpointView.prototype = { compareTo: function(other) { - return this._compare(this._domEventType, other._domEventType); + return this._compare(this._type, other._type); }, populateLabelElement: function(element) @@ -497,13 +536,13 @@ WebInspector.DOMBreakpoint.prototype = { element.appendChild(linkifiedNode); var description = document.createElement("div"); description.className = "source-text"; - description.textContent = WebInspector.domBreakpointTypeLabel(this._domEventType); + description.textContent = WebInspector.domBreakpointTypeLabel(this._type); element.appendChild(description); }, populateStatusMessageElement: function(element, eventData) { - var substitutions = [WebInspector.domBreakpointTypeLabel(this._domEventType), WebInspector.panels.elements.linkifyNodeById(this._nodeId)]; + var substitutions = [WebInspector.domBreakpointTypeLabel(this._type), WebInspector.panels.elements.linkifyNodeById(this._nodeId)]; var formatters = { s: function(substitution) { @@ -516,7 +555,7 @@ WebInspector.DOMBreakpoint.prototype = { b = document.createTextNode(b); element.appendChild(b); } - if (this._domEventType === WebInspector.DOMBreakpointTypes.SubtreeModified) { + if (this._type === WebInspector.DOMBreakpointTypes.SubtreeModified) { var targetNode = WebInspector.panels.elements.linkifyNodeById(eventData.targetNodeId); if (eventData.insertion) { if (eventData.targetNodeId !== this._nodeId) @@ -531,35 +570,36 @@ WebInspector.DOMBreakpoint.prototype = { _onRemove: function() { - var node = WebInspector.domAgent.nodeForId(this._nodeId); - if (node) - delete node.breakpoints[this._domEventType]; + delete this._node.breakpoints[this._type]; } } -WebInspector.DOMBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; +WebInspector.DOMBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; -WebInspector.EventListenerBreakpoint = function(manager, frontendId, eventName) +WebInspector.EventListenerBreakpointView = function(manager, id, enabled, eventName) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "EventListener"); + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); this._eventName = eventName; - this._condition = { eventName: this._eventName }; - this._persistentCondition = this._condition; } -WebInspector.EventListenerBreakpoint.eventNameForUI = function(eventName) +WebInspector.EventListenerBreakpointView.eventNameForUI = function(eventName) { - if (!WebInspector.EventListenerBreakpoint._eventNamesForUI) { - WebInspector.EventListenerBreakpoint._eventNamesForUI = { + if (!WebInspector.EventListenerBreakpointView._eventNamesForUI) { + WebInspector.EventListenerBreakpointView._eventNamesForUI = { "instrumentation:setTimer": WebInspector.UIString("Set Timer"), "instrumentation:clearTimer": WebInspector.UIString("Clear Timer"), "instrumentation:timerFired": WebInspector.UIString("Timer Fired") }; } - return WebInspector.EventListenerBreakpoint._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); + return WebInspector.EventListenerBreakpointView._eventNamesForUI[eventName] || eventName.substring(eventName.indexOf(":") + 1); } -WebInspector.EventListenerBreakpoint.prototype = { +WebInspector.EventListenerBreakpointView.prototype = { + get eventName() + { + return this._eventName; + }, + compareTo: function(other) { return this._compare(this._eventName, other._eventName); @@ -578,21 +618,19 @@ WebInspector.EventListenerBreakpoint.prototype = { _uiEventName: function() { - return WebInspector.EventListenerBreakpoint.eventNameForUI(this._eventName); + return WebInspector.EventListenerBreakpointView.eventNameForUI(this._eventName); } } -WebInspector.EventListenerBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; +WebInspector.EventListenerBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; -WebInspector.XHRBreakpoint = function(manager, frontendId, url) +WebInspector.XHRBreakpointView = function(manager, id, enabled, url) { - WebInspector.NativeBreakpoint.call(this, manager, frontendId, "XHR"); + WebInspector.NativeBreakpointView.call(this, manager, id, enabled); this._url = url; - this._condition = { url: this._url }; - this._persistentCondition = this._condition; } -WebInspector.XHRBreakpoint.prototype = { +WebInspector.XHRBreakpointView.prototype = { compareTo: function(other) { return this._compare(this._url, other._url); @@ -621,13 +659,7 @@ WebInspector.XHRBreakpoint.prototype = { } } -WebInspector.XHRBreakpoint.prototype.__proto__ = WebInspector.NativeBreakpoint.prototype; - -WebInspector.DebuggerEventTypes = { - JavaScriptPause: 0, - JavaScriptBreakpoint: 1, - NativeBreakpoint: 2 -}; +WebInspector.XHRBreakpointView.prototype.__proto__ = WebInspector.NativeBreakpointView.prototype; WebInspector.DOMBreakpointTypes = { SubtreeModified: 0, diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js index 47194da..619525c 100644 --- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js +++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js @@ -35,18 +35,11 @@ WebInspector.BreakpointsSidebarPane = function(title) this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); this.bodyElement.appendChild(this.emptyElement); + + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this); } WebInspector.BreakpointsSidebarPane.prototype = { - reset: function() - { - this.listElement.removeChildren(); - if (this.listElement.parentElement) { - this.bodyElement.removeChild(this.listElement); - this.bodyElement.appendChild(this.emptyElement); - } - }, - addBreakpointItem: function(breakpointItem) { var element = breakpointItem.element; @@ -97,6 +90,15 @@ WebInspector.BreakpointsSidebarPane.prototype = { this.bodyElement.removeChild(this.listElement); this.bodyElement.appendChild(this.emptyElement); } + }, + + _projectChanged: function() + { + this.listElement.removeChildren(); + if (this.listElement.parentElement) { + this.bodyElement.removeChild(this.listElement); + this.bodyElement.appendChild(this.emptyElement); + } } } @@ -145,7 +147,10 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = { var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem); var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem); - WebInspector.startEditing(inputElement, commitHandler, cancelHandler); + WebInspector.startEditing(inputElement, { + commitHandler: commitHandler, + cancelHandler: cancelHandler + }); }, _hideEditBreakpointDialog: function(inputElement, accept, breakpointItem) @@ -256,7 +261,8 @@ WebInspector.EventListenerBreakpointsSidebarPane = function() this.categoriesTreeOutline = new TreeOutline(this.categoriesElement); this.bodyElement.appendChild(this.categoriesElement); - WebInspector.breakpointManager.addEventListener("event-listener-breakpoint-added", this._breakpointAdded, this); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, this._breakpointAdded, this); this._breakpointItems = {}; this._createCategory("Keyboard", "listener", ["keydown", "keyup", "keypress", "textInput"]); @@ -289,7 +295,7 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { var eventName = type + ":" + eventNames[i]; var breakpointItem = {}; - var title = WebInspector.EventListenerBreakpoint.eventNameForUI(eventName); + var title = WebInspector.EventListenerBreakpointView.eventNameForUI(eventName); breakpointItem.element = new TreeElement(title); categoryItem.element.appendChild(breakpointItem.element); var hitMarker = document.createElement("div"); @@ -339,10 +345,9 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { _breakpointAdded: function(event) { - var breakpoint = event.data.breakpoint; - var eventName = event.data.eventName; + var breakpoint = event.data; - var breakpointItem = this._breakpointItems[eventName]; + var breakpointItem = this._breakpointItems[breakpoint.eventName]; breakpointItem.breakpoint = breakpoint; breakpoint.addEventListener("hit-state-changed", this._breakpointHitStateChanged.bind(this, breakpointItem)); breakpoint.addEventListener("removed", this._breakpointRemoved.bind(this, breakpointItem)); @@ -383,7 +388,7 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = { categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled; }, - reset: function() + _projectChanged: function() { for (var eventName in this._breakpointItems) { var breakpointItem = this._breakpointItems[eventName]; diff --git a/WebCore/inspector/front-end/CSSCompletions.js b/WebCore/inspector/front-end/CSSCompletions.js index 9480467..e8d7556 100644 --- a/WebCore/inspector/front-end/CSSCompletions.js +++ b/WebCore/inspector/front-end/CSSCompletions.js @@ -1,88 +1,124 @@ -WebInspector.CSSCompletions = []; - -WebInspector.CSSCompletions.startsWith = function(prefix) -{ - var firstIndex = this._firstIndexOfPrefix(prefix); - if (firstIndex === -1) - return []; - - var results = []; - while (this[firstIndex].indexOf(prefix) === 0) - results.push(this[firstIndex++]); - return results; -} - -WebInspector.CSSCompletions.firstStartsWith = function(prefix) +/* + * Copyright (C) 2010 Nikita Vasilyev. All rights reserved. + * Copyright (C) 2010 Joseph Pecoraro. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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.CSSCompletions = function(values) { - var foundIndex = this._firstIndexOfPrefix(prefix); - return (foundIndex === -1 ? "" : this[foundIndex]); + this._values = values.slice(); + this._values.sort(); } -WebInspector.CSSCompletions._firstIndexOfPrefix = function(prefix) -{ - if (!prefix) - return -1; - if (!this.length) - return -1; - - var maxIndex = this.length - 1; - var minIndex = 0; - var foundIndex; - - do { - var middleIndex = (maxIndex + minIndex) >> 1; - if (this[middleIndex].indexOf(prefix) === 0) { - foundIndex = middleIndex; - break; +WebInspector.CSSCompletions.prototype = { + startsWith: function(prefix) + { + var firstIndex = this._firstIndexOfPrefix(prefix); + if (firstIndex === -1) + return []; + + var results = []; + while (this._values[firstIndex].indexOf(prefix) === 0) + results.push(this._values[firstIndex++]); + return results; + }, + + firstStartsWith: function(prefix) + { + var foundIndex = this._firstIndexOfPrefix(prefix); + return (foundIndex === -1 ? "" : this._values[foundIndex]); + }, + + _firstIndexOfPrefix: function(prefix) + { + if (!prefix) + return -1; + if (!this._values.length) + return -1; + + var maxIndex = this._values.length - 1; + var minIndex = 0; + var foundIndex; + + do { + var middleIndex = (maxIndex + minIndex) >> 1; + if (this._values[middleIndex].indexOf(prefix) === 0) { + foundIndex = middleIndex; + break; + } + if (this._values[middleIndex] < prefix) + minIndex = middleIndex + 1; + else + maxIndex = middleIndex - 1; + } while (minIndex <= maxIndex); + + if (foundIndex === undefined) + return -1; + + while (foundIndex && this._values[foundIndex - 1].indexOf(prefix) === 0) + foundIndex--; + + return foundIndex; + }, + + keySet: function() + { + return this._values.keySet(); + }, + + next: function(str, prefix) + { + return this._closest(str, prefix, 1); + }, + + previous: function(str, prefix) + { + return this._closest(str, prefix, -1); + }, + + _closest: function(str, prefix, shift) + { + if (!str) + return ""; + + var index = this._values.indexOf(str); + if (index === -1) + return ""; + + if (!prefix) { + index = (index + this._values.length + shift) % this._values.length; + return this._values[index]; } - if (this[middleIndex] < prefix) - minIndex = middleIndex + 1; - else - maxIndex = middleIndex - 1; - } while (minIndex <= maxIndex); - - if (!foundIndex) - return -1; - - while (foundIndex && this[foundIndex - 1].indexOf(prefix) === 0) - foundIndex--; - - return foundIndex; -} - -WebInspector.CSSCompletions.next = function(str, prefix) -{ - return WebInspector.CSSCompletions._closest(str, prefix, 1); -} - -WebInspector.CSSCompletions.previous = function(str, prefix) -{ - return WebInspector.CSSCompletions._closest(str, prefix, -1); -} - -WebInspector.CSSCompletions._closest = function(str, prefix, shift) -{ - if (!str) - return ""; - var index = this.indexOf(str); - if (index === -1) - return ""; - - if (!prefix) { - index = (index + this.length + shift) % this.length; - return this[index]; + var propertiesWithPrefix = this.startsWith(prefix); + var j = propertiesWithPrefix.indexOf(str); + j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; + return propertiesWithPrefix[j]; } - - var propertiesWithPrefix = this.startsWith(prefix); - var j = propertiesWithPrefix.indexOf(str); - j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length; - return propertiesWithPrefix[j]; -} - -WebInspector.CSSCompletions._load = function(properties) -{ - for (var i = 0; i < properties.length; ++i) - WebInspector.CSSCompletions.push(properties[i]); - WebInspector.CSSCompletions.sort(); } diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js index 23ed7a8..2d15582 100644 --- a/WebCore/inspector/front-end/CSSStyleModel.js +++ b/WebCore/inspector/front-end/CSSStyleModel.js @@ -174,11 +174,14 @@ WebInspector.CSSStyleModel.prototype = { function callback(success) { this._styleSheetChanged(styleSheetId, true); + this.dispatchEventToListeners("stylesheet changed"); } InspectorBackend.setStyleSheetText2(styleSheetId, contentToRevertTo, callback.bind(this)); } } +WebInspector.CSSStyleModel.prototype.__proto__ = WebInspector.Object.prototype; + WebInspector.CSSStyleDeclaration = function(payload) { this.id = payload.styleId; diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js index b2e6a5c..432260e 100644 --- a/WebCore/inspector/front-end/CallStackSidebarPane.js +++ b/WebCore/inspector/front-end/CallStackSidebarPane.js @@ -26,11 +26,10 @@ WebInspector.CallStackSidebarPane = function() { WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack")); - WebInspector.breakpointManager.addEventListener("breakpoint-hit", this._breakpointHit, this); } WebInspector.CallStackSidebarPane.prototype = { - update: function(callFrames, sourceIDMap) + update: function(callFrames, eventType, eventData) { this.bodyElement.removeChildren(); @@ -47,7 +46,7 @@ WebInspector.CallStackSidebarPane.prototype = { var title; var subtitle; - var scriptOrResource; + var script; for (var i = 0; i < callFrames.length; ++i) { var callFrame = callFrames[i]; @@ -60,9 +59,9 @@ WebInspector.CallStackSidebarPane.prototype = { break; } - scriptOrResource = sourceIDMap[callFrame.sourceID]; - if (scriptOrResource) - subtitle = WebInspector.displayNameForURL(scriptOrResource.sourceURL || scriptOrResource.url); + script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID); + if (script) + subtitle = WebInspector.displayNameForURL(script.sourceURL); else subtitle = WebInspector.UIString("(internal script)"); @@ -81,6 +80,19 @@ WebInspector.CallStackSidebarPane.prototype = { this.placards.push(placard); this.bodyElement.appendChild(placard.element); } + + if (eventType === WebInspector.DebuggerEventTypes.JavaScriptPause) + return; + + var statusMessageElement = document.createElement("div"); + statusMessageElement.className = "info"; + if (eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) { + var breakpoint = WebInspector.breakpointManager.breakpointViewForEventData(eventData); + if (breakpoint) + breakpoint.populateStatusMessageElement(statusMessageElement, eventData); + } else + statusMessageElement.appendChild(document.createTextNode(WebInspector.UIString("Paused on a JavaScript breakpoint."))); + this.bodyElement.appendChild(statusMessageElement); }, get selectedCallFrame() @@ -168,17 +180,6 @@ WebInspector.CallStackSidebarPane.prototype = { this._shortcuts[prevCallFrame.key] = this._selectPreviousCallFrameOnStack.bind(this); section.addRelatedKeys([ nextCallFrame.name, prevCallFrame.name ], WebInspector.UIString("Next/previous call frame")); - }, - - _breakpointHit: function(event) - { - var breakpoint = event.data.breakpoint; - if (breakpoint.populateStatusMessageElement) { - var statusMessageElement = document.createElement("div"); - statusMessageElement.className = "info"; - breakpoint.populateStatusMessageElement(statusMessageElement, event.data.eventData); - this.bodyElement.appendChild(statusMessageElement); - } } } diff --git a/WebCore/inspector/front-end/Callback.js b/WebCore/inspector/front-end/Callback.js deleted file mode 100644 index 0621fd1..0000000 --- a/WebCore/inspector/front-end/Callback.js +++ /dev/null @@ -1,61 +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.Callback = function() -{ - this._lastCallbackId = 1; - this._callbacks = {}; -} - -WebInspector.Callback.prototype = { - wrap: function(callback) - { - var callbackId = this._lastCallbackId++; - this._callbacks[callbackId] = callback || function() {}; - return callbackId; - }, - - processResponse: function(callbackId, args) - { - var callback = this._callbacks[callbackId]; - callback.apply(null, args); - delete this._callbacks[callbackId]; - }, - - removeResponseCallbackEntry: function(callbackId) - { - delete this._callbacks[callbackId]; - } -} - -WebInspector.Callback._INSTANCE = new WebInspector.Callback(); -WebInspector.Callback.wrap = WebInspector.Callback._INSTANCE.wrap.bind(WebInspector.Callback._INSTANCE); -WebInspector.processResponse = WebInspector.Callback._INSTANCE.processResponse.bind(WebInspector.Callback._INSTANCE); -WebInspector.removeResponseCallbackEntry = WebInspector.Callback._INSTANCE.removeResponseCallbackEntry.bind(WebInspector.Callback._INSTANCE); diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js index 737b84f..03fe14a 100644 --- a/WebCore/inspector/front-end/ConsoleView.js +++ b/WebCore/inspector/front-end/ConsoleView.js @@ -7,13 +7,13 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -50,9 +50,8 @@ WebInspector.ConsoleView = function(drawer) this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + "."); this.prompt.history = WebInspector.settings.consoleHistory; - this.topGroup = new WebInspector.ConsoleGroup(null, 0); + this.topGroup = new WebInspector.ConsoleGroup(null); this.messagesElement.insertBefore(this.topGroup.element, this.promptElement); - this.groupLevel = 0; this.currentGroup = this.topGroup; this.toggleConsoleButton = document.getElementById("console-status-bar-item"); @@ -69,30 +68,29 @@ WebInspector.ConsoleView = function(drawer) } var updateFilterHandler = this._updateFilter.bind(this); - function createFilterElement(category) { + function createFilterElement(category, label) { var categoryElement = document.createElement("li"); categoryElement.category = category; - categoryElement.addStyleClass(categoryElement.category); + categoryElement.className = category; categoryElement.addEventListener("click", updateFilterHandler, false); - - var label = category.toString(); - categoryElement.appendChild(document.createTextNode(label)); + categoryElement.textContent = label; this.filterBarElement.appendChild(categoryElement); + return categoryElement; } - - this.allElement = createFilterElement.call(this, WebInspector.UIString("All")); + + this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All")); createDividerElement.call(this); - this.errorElement = createFilterElement.call(this, WebInspector.UIString("Errors")); - this.warningElement = createFilterElement.call(this, WebInspector.UIString("Warnings")); - this.logElement = createFilterElement.call(this, WebInspector.UIString("Logs")); + this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors")); + this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings")); + this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs")); this.filter(this.allElement, false); this._registerShortcuts(); this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true); - + this._customFormatters = { "object": this._formatobject, "array": this._formatarray, @@ -113,7 +111,7 @@ WebInspector.ConsoleView.prototype = { this.filter(e.target, selectMultiple); }, - + filter: function(target, selectMultiple) { function unselectAll() @@ -122,16 +120,16 @@ WebInspector.ConsoleView.prototype = { this.errorElement.removeStyleClass("selected"); this.warningElement.removeStyleClass("selected"); this.logElement.removeStyleClass("selected"); - + this.messagesElement.removeStyleClass("filter-all"); this.messagesElement.removeStyleClass("filter-errors"); this.messagesElement.removeStyleClass("filter-warnings"); this.messagesElement.removeStyleClass("filter-logs"); } - - var targetFilterClass = "filter-" + target.category.toLowerCase(); - if (target.category == "All") { + var targetFilterClass = "filter-" + target.category; + + if (target.category === "all") { if (target.hasStyleClass("selected")) { // We can't unselect all, so we break early here return; @@ -145,18 +143,18 @@ WebInspector.ConsoleView.prototype = { this.messagesElement.removeStyleClass("filter-all"); } } - + if (!selectMultiple) { // If multiple selection is off, we want to unselect everything else // and just select ourselves. unselectAll.call(this); - + target.addStyleClass("selected"); this.messagesElement.addStyleClass(targetFilterClass); - + return; } - + if (target.hasStyleClass("selected")) { // If selectMultiple is turned on, and we were selected, we just // want to unselect ourselves. @@ -169,7 +167,7 @@ WebInspector.ConsoleView.prototype = { this.messagesElement.addStyleClass(targetFilterClass); } }, - + _toggleConsoleButtonClicked: function() { this.drawer.visibleView = this; @@ -192,7 +190,7 @@ WebInspector.ConsoleView.prototype = { afterShow: function() { - WebInspector.currentFocusElement = this.promptElement; + WebInspector.currentFocusElement = this.promptElement; }, hide: function() @@ -208,7 +206,7 @@ WebInspector.ConsoleView.prototype = { function scrollIntoView() { - this.promptElement.scrollIntoView(false); + this.promptElement.scrollIntoView(true); delete this._scrollIntoViewTimer; } this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20); @@ -216,6 +214,8 @@ WebInspector.ConsoleView.prototype = { addMessage: function(msg) { + var shouldScrollToLastMessage = this.messagesElement.isScrolledToBottom(); + if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) { this._incrementErrorWarningCount(msg); WebInspector.resourceManager.addConsoleMessage(msg); @@ -230,17 +230,12 @@ WebInspector.ConsoleView.prototype = { this.messages.push(msg); if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) { - if (this.groupLevel < 1) - return; - - this.groupLevel--; - - this.currentGroup = this.currentGroup.parentGroup; + var parentGroup = this.currentGroup.parentGroup + if (parentGroup) + this.currentGroup = parentGroup; } else { if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) { - this.groupLevel++; - - var group = new WebInspector.ConsoleGroup(this.currentGroup, this.groupLevel); + var group = new WebInspector.ConsoleGroup(this.currentGroup); this.currentGroup.messagesElement.appendChild(group.element); this.currentGroup = group; } @@ -248,14 +243,15 @@ WebInspector.ConsoleView.prototype = { this.currentGroup.addMessage(msg); } - this._scheduleScrollIntoView(); + if (shouldScrollToLastMessage) + this._scheduleScrollIntoView(); }, updateMessageRepeatCount: function(count) { var msg = this.previousMessage; var prevRepeatCount = msg.totalRepeatCount; - + if (!this.commandSincePreviousMessage) { msg.repeatDelta = count - prevRepeatCount; msg.repeatCount = msg.repeatCount + msg.repeatDelta; @@ -263,7 +259,7 @@ WebInspector.ConsoleView.prototype = { msg._updateRepeatCount(); this._incrementErrorWarningCount(msg); } else { - var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, msg.groupLevel, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace); + var msgCopy = new WebInspector.ConsoleMessage(msg.source, msg.type, msg.level, msg.line, msg.url, count - prevRepeatCount, msg._messageText, msg._parameters, msg._stackTrace, msg._requestId); msgCopy.totalRepeatCount = count; msgCopy._formatMessage(); this.addMessage(msgCopy); @@ -293,7 +289,6 @@ WebInspector.ConsoleView.prototype = { this.messages = []; - this.groupLevel = 0; this.currentGroup = this.topGroup; this.topGroup.messagesElement.removeChildren(); @@ -568,8 +563,12 @@ WebInspector.ConsoleView.prototype = { { function printNode(nodeId) { - if (!nodeId) + if (!nodeId) { + // Sometimes DOM is loaded after the sync message is being formatted, so we get no + // nodeId here. So we fall back to object formatting here. + this._formatobject(object, elem); return; + } var treeOutline = new WebInspector.ElementsTreeOutline(); treeOutline.showInElementsPanelEnabled = true; treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId); @@ -578,8 +577,7 @@ WebInspector.ConsoleView.prototype = { treeOutline.element.addStyleClass("single-node"); elem.appendChild(treeOutline.element); } - - object.pushNodeToFrontend(printNode); + object.pushNodeToFrontend(printNode.bind(this)); }, _formatarray: function(arr, elem) @@ -634,70 +632,117 @@ WebInspector.ConsoleView.prototype = { WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype; -WebInspector.ConsoleMessage = function(source, type, level, line, url, groupLevel, repeatCount, message, parameters, stackTrace) +WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCount, message, parameters, stackTrace, requestId) { this.source = source; this.type = type; this.level = level; this.line = line; this.url = url; - this.groupLevel = groupLevel; this.repeatCount = repeatCount; this.repeatDelta = repeatCount; this.totalRepeatCount = repeatCount; this._messageText = message; this._parameters = parameters; this._stackTrace = stackTrace; + this._requestId = requestId; this._formatMessage(); } WebInspector.ConsoleMessage.createTextMessage = function(text, level) { level = level || WebInspector.ConsoleMessage.MessageLevel.Log; - return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, null, 1, null, [text], null); + return new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, 0, null, 1, null, [text], null); } WebInspector.ConsoleMessage.prototype = { _formatMessage: function() { + var stackTrace = this._stackTrace; + var messageText; switch (this.type) { - case WebInspector.ConsoleMessage.MessageType.Assert: case WebInspector.ConsoleMessage.MessageType.Trace: + messageText = document.createTextNode("console.trace()"); + break; case WebInspector.ConsoleMessage.MessageType.UncaughtException: - var ol = document.createElement("ol"); - ol.className = "outline-disclosure"; - var treeOutline = new TreeOutline(ol); - var messageText; - if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) - messageText = this._format(this._parameters); - else if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) - messageText = document.createTextNode("console.trace()"); - else - messageText = document.createTextNode(this._messageText); - - var content = document.createElement("div"); - this._addMessageHeader(content, messageText); - var root = new TreeElement(content, null, true); - content.treeElementForTest = root; - treeOutline.appendChild(root); - if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) - root.expand(); - - this._populateStackTraceTreeElement(root); - this.formattedMessage = ol; + messageText = document.createTextNode(this._messageText); + break; + case WebInspector.ConsoleMessage.MessageType.NetworkError: + var resource = this._requestId && WebInspector.panels.network.resources[this._requestId]; + if (resource) { + stackTrace = resource.stackTrace; + + messageText = document.createElement("span"); + messageText.appendChild(document.createTextNode(resource.requestMethod + " ")); + messageText.appendChild(WebInspector.linkifyURLAsNode(resource.url)); + if (resource.failed) + messageText.appendChild(document.createTextNode(" " + resource.localizedFailDescription)); + else + messageText.appendChild(document.createTextNode(" " + resource.statusCode + " (" + resource.statusText + ")")); + } else + messageText = this._format([this._messageText]); + break; + case WebInspector.ConsoleMessage.MessageType.Assert: + var args = [WebInspector.UIString("Assertion failed:")]; + if (this._parameters) + args = args.concat(this._parameters); + messageText = this._format(args); break; case WebInspector.ConsoleMessage.MessageType.Object: var obj = this._parameters ? this._parameters[0] : undefined; - this.formattedMessage = this._format(["%O", obj]); + var args = ["%O", obj]; + messageText = this._format(args); break; default: var args = this._parameters || [this._messageText]; - this.formattedMessage = this._format(args); + messageText = this._format(args); break; } + this._formattedMessage = document.createElement("span"); + this._formattedMessage.className = "console-message-text source-code"; + + if (stackTrace && stackTrace.length) { + var topCallFrame = stackTrace[0]; + var sourceName = topCallFrame.scriptName; + var sourceLine = topCallFrame.lineNumber; + } else { + var sourceName = this.url; + var sourceLine = this.line; + } + + if (sourceName && sourceName !== "undefined") { + var urlElement = WebInspector.linkifyResourceAsNode(sourceName, "scripts", sourceLine, "console-message-url"); + this._formattedMessage.appendChild(urlElement); + } + + this._formattedMessage.appendChild(messageText); + + if (this._stackTrace) { + switch (this.type) { + case WebInspector.ConsoleMessage.MessageType.Trace: + case WebInspector.ConsoleMessage.MessageType.UncaughtException: + case WebInspector.ConsoleMessage.MessageType.NetworkError: + case WebInspector.ConsoleMessage.MessageType.Assert: { + var ol = document.createElement("ol"); + ol.className = "outline-disclosure"; + var treeOutline = new TreeOutline(ol); + + var content = this._formattedMessage; + var root = new TreeElement(content, null, true); + content.treeElementForTest = root; + treeOutline.appendChild(root); + if (this.type === WebInspector.ConsoleMessage.MessageType.Trace) + root.expand(); + + this._populateStackTraceTreeElement(root); + this._formattedMessage = ol; + } + } + } + // This is used for inline message bubbles in SourceFrames, or other plain-text representations. - this.message = this.formattedMessage.textContent; + this.message = this._formattedMessage.textContent; }, isErrorOrWarning: function() @@ -790,27 +835,6 @@ WebInspector.ConsoleMessage.prototype = { this._element = element; - switch (this.source) { - case WebInspector.ConsoleMessage.MessageSource.HTML: - element.addStyleClass("console-html-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.WML: - element.addStyleClass("console-wml-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.XML: - element.addStyleClass("console-xml-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.JS: - element.addStyleClass("console-js-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.CSS: - element.addStyleClass("console-css-source"); - break; - case WebInspector.ConsoleMessage.MessageSource.Other: - element.addStyleClass("console-other-source"); - break; - } - switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: element.addStyleClass("console-tip-level"); @@ -838,12 +862,7 @@ WebInspector.ConsoleMessage.prototype = { return element; } - if (this.type === WebInspector.ConsoleMessage.MessageType.Trace || - this.type === WebInspector.ConsoleMessage.MessageType.Assert || - this.type === WebInspector.ConsoleMessage.MessageType.UncaughtException) - element.appendChild(this.formattedMessage); - else - this._addMessageHeader(element, this.formattedMessage); + element.appendChild(this._formattedMessage); if (this.repeatCount > 1) this._updateRepeatCount(); @@ -863,7 +882,7 @@ WebInspector.ConsoleMessage.prototype = { messageTextElement.appendChild(document.createTextNode(functionName)); content.appendChild(messageTextElement); - var urlElement = WebInspector.linkifyResourceAsNode(frame.sourceURL, "scripts", frame.lineNumber, "console-message-url"); + var urlElement = WebInspector.linkifyResourceAsNode(frame.scriptName, "scripts", frame.lineNumber, "console-message-url"); content.appendChild(urlElement); var treeElement = new TreeElement(content); @@ -871,26 +890,11 @@ WebInspector.ConsoleMessage.prototype = { } }, - _addMessageHeader: function(parentElement, formattedMessage) - { - if (this.url && this.url !== "undefined") { - var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url"); - parentElement.appendChild(urlElement); - } - - var messageTextElement = document.createElement("span"); - messageTextElement.className = "console-message-text source-code"; - if (this.type === WebInspector.ConsoleMessage.MessageType.Assert) - messageTextElement.appendChild(document.createTextNode(WebInspector.UIString("Assertion failed: "))); - messageTextElement.appendChild(formattedMessage); - parentElement.appendChild(messageTextElement); - }, - _updateRepeatCount: function() { if (!this.repeatCountElement) { this.repeatCountElement = document.createElement("span"); this.repeatCountElement.className = "bubble"; - + this._element.insertBefore(this.repeatCountElement, this._element.firstChild); this._element.addStyleClass("repeated-message"); } @@ -925,6 +929,7 @@ WebInspector.ConsoleMessage.prototype = { switch (this.type) { case WebInspector.ConsoleMessage.MessageType.Log: case WebInspector.ConsoleMessage.MessageType.UncaughtException: + case WebInspector.ConsoleMessage.MessageType.NetworkError: typeString = "Log"; break; case WebInspector.ConsoleMessage.MessageType.Object: @@ -947,7 +952,7 @@ WebInspector.ConsoleMessage.prototype = { typeString = "Result"; break; } - + var levelString; switch (this.level) { case WebInspector.ConsoleMessage.MessageLevel.Tip: @@ -967,22 +972,35 @@ WebInspector.ConsoleMessage.prototype = { break; } - return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line; + return sourceString + " " + typeString + " " + levelString + ": " + this._formattedMessage.textContent + "\n" + this.url + " line " + this.line; }, - isEqual: function(msg, disreguardGroup) + isEqual: function(msg) { if (!msg) return false; - var ret = (this.source == msg.source) - && (this.type == msg.type) - && (this.level == msg.level) - && (this.line == msg.line) - && (this.url == msg.url) - && (this.message == msg.message); + if (this._stackTrace) { + if (!msg._stackTrace) + return false; + var l = this._stackTrace; + var r = msg._stackTrace; + for (var i = 0; i < l.length; i++) { + if (l[i].scriptName !== r[i].scriptName || + l[i].functionName !== r[i].functionName || + l[i].lineNumber !== r[i].lineNumber || + l[i].column !== r[i].column) + return false; + } + } - return (disreguardGroup ? ret : (ret && (this.groupLevel == msg.groupLevel))); + return (this.source === msg.source) + && (this.type === msg.type) + && (this.level === msg.level) + && (this.line === msg.line) + && (this.url === msg.url) + && (this.message === msg.message) + && (this._requestId === msg._requestId); } } @@ -1005,7 +1023,8 @@ WebInspector.ConsoleMessage.MessageType = { EndGroup: 5, Assert: 6, UncaughtException: 7, - Result: 8 + NetworkError:8, + Result: 9 } WebInspector.ConsoleMessage.MessageLevel = { @@ -1041,7 +1060,7 @@ WebInspector.ConsoleCommandResult = function(result, originatingCommand) { 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, -1, null, null, 1, null, [result]); + WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Result, level, -1, null, 1, null, [result]); } WebInspector.ConsoleCommandResult.prototype = { @@ -1055,10 +1074,9 @@ WebInspector.ConsoleCommandResult.prototype = { WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype; -WebInspector.ConsoleGroup = function(parentGroup, level) +WebInspector.ConsoleGroup = function(parentGroup) { this.parentGroup = parentGroup; - this.level = level; var element = document.createElement("div"); element.className = "console-group"; diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js index 37bf549..432ac3f 100644 --- a/WebCore/inspector/front-end/DOMAgent.js +++ b/WebCore/inspector/front-end/DOMAgent.js @@ -300,6 +300,7 @@ WebInspector.DOMAgent = function() { this._window = new WebInspector.DOMWindow(this); this._idToDOMNode = null; this.document = null; + InspectorBackend.registerDomainDispatcher("DOM", this); } WebInspector.DOMAgent.prototype = { @@ -350,7 +351,7 @@ WebInspector.DOMAgent.prototype = { elem.updateTitle(); }, - _attributesUpdated: function(nodeId, attrsArray) + attributesUpdated: function(nodeId, attrsArray) { var node = this._idToDOMNode[nodeId]; node._setAttributesPayload(attrsArray); @@ -358,7 +359,7 @@ WebInspector.DOMAgent.prototype = { this.document._fireDomEvent("DOMAttrModified", event); }, - _characterDataModified: function(nodeId, newValue) + characterDataModified: function(nodeId, newValue) { var node = this._idToDOMNode[nodeId]; node._nodeValue = newValue; @@ -372,7 +373,13 @@ WebInspector.DOMAgent.prototype = { return this._idToDOMNode[nodeId]; }, - _setDocument: function(payload) + didCommitLoad: function() + { + // Cleanup elements panel early on inspected page refresh. + this.setDocument(null); + }, + + setDocument: function(payload) { this._idToDOMNode = {}; if (payload && "id" in payload) { @@ -385,13 +392,13 @@ WebInspector.DOMAgent.prototype = { WebInspector.panels.elements.setDocument(this.document); }, - _setDetachedRoot: function(payload) + setDetachedRoot: function(payload) { var root = new WebInspector.DOMNode(this.document, payload); this._idToDOMNode[payload.id] = root; }, - _setChildNodes: function(parentId, payloads) + setChildNodes: function(parentId, payloads) { var parent = this._idToDOMNode[parentId]; parent._setChildrenPayload(payloads); @@ -408,7 +415,7 @@ WebInspector.DOMAgent.prototype = { } }, - _childNodeCountUpdated: function(nodeId, newValue) + childNodeCountUpdated: function(nodeId, newValue) { var node = this._idToDOMNode[nodeId]; node._childNodeCount = newValue; @@ -418,7 +425,7 @@ WebInspector.DOMAgent.prototype = { treeElement.hasChildren = newValue; }, - _childNodeInserted: function(parentId, prevId, payload) + childNodeInserted: function(parentId, prevId, payload) { var parent = this._idToDOMNode[parentId]; var prev = this._idToDOMNode[prevId]; @@ -428,7 +435,7 @@ WebInspector.DOMAgent.prototype = { this.document._fireDomEvent("DOMNodeInserted", event); }, - _childNodeRemoved: function(parentId, nodeId) + childNodeRemoved: function(parentId, nodeId) { var parent = this._idToDOMNode[parentId]; var node = this._idToDOMNode[nodeId]; @@ -523,43 +530,3 @@ WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callb return; InspectorBackend.getEventListenersForNode(node.id, callback); } - -WebInspector.attributesUpdated = function() -{ - this.domAgent._attributesUpdated.apply(this.domAgent, arguments); -} - -WebInspector.characterDataModified = function() -{ - this.domAgent._characterDataModified.apply(this.domAgent, arguments); -} - -WebInspector.setDocument = function() -{ - this.domAgent._setDocument.apply(this.domAgent, arguments); -} - -WebInspector.setDetachedRoot = function() -{ - this.domAgent._setDetachedRoot.apply(this.domAgent, arguments); -} - -WebInspector.setChildNodes = function() -{ - this.domAgent._setChildNodes.apply(this.domAgent, arguments); -} - -WebInspector.childNodeCountUpdated = function() -{ - this.domAgent._childNodeCountUpdated.apply(this.domAgent, arguments); -} - -WebInspector.childNodeInserted = function() -{ - this.domAgent._childNodeInserted.apply(this.domAgent, arguments); -} - -WebInspector.childNodeRemoved = function() -{ - this.domAgent._childNodeRemoved.apply(this.domAgent, arguments); -} diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js index 902062c..5831d1e 100644 --- a/WebCore/inspector/front-end/DataGrid.js +++ b/WebCore/inspector/front-end/DataGrid.js @@ -169,7 +169,11 @@ WebInspector.DataGrid.prototype = { this._editingNode.select(); var element = this._editingNode._element.children[column]; - WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); + WebInspector.startEditing(element, { + context: element.textContent, + commitHandler: this._editingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, @@ -191,7 +195,11 @@ WebInspector.DataGrid.prototype = { return this._startEditingColumnOfDataGridNode(this._editingNode, 0); this._editing = true; - WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent); + WebInspector.startEditing(element, { + context: element.textContent, + commitHandler: this._editingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, @@ -487,7 +495,7 @@ WebInspector.DataGrid.prototype = { isScrolledToLastRow: function() { - return this._scrollContainer.scrollTop === this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight; + return this._scrollContainer.isScrolledToBottom(); }, scrollToLastRow: function() diff --git a/WebCore/inspector/front-end/Database.js b/WebCore/inspector/front-end/Database.js index ca3e968..7aac7d1 100644 --- a/WebCore/inspector/front-end/Database.js +++ b/WebCore/inspector/front-end/Database.js @@ -101,21 +101,3 @@ WebInspector.Database.prototype = { InspectorBackend.executeSQL(this._id, query, callback); } } - -WebInspector.sqlTransactionSucceeded = function(transactionId, columnNames, values) -{ - var callback = WebInspector.Database.successCallbacks[transactionId]; - if (!callback) - return; - delete WebInspector.Database.successCallbacks[transactionId]; - callback(columnNames, values); -} - -WebInspector.sqlTransactionFailed = function(transactionId, errorObj) -{ - var callback = WebInspector.Database.errorCallbacks[transactionId]; - if (!callback) - return; - delete WebInspector.Database.errorCallbacks[transactionId]; - callback(errorObj); -} diff --git a/WebCore/inspector/front-end/DebuggerModel.js b/WebCore/inspector/front-end/DebuggerModel.js new file mode 100644 index 0000000..5ab0e2d --- /dev/null +++ b/WebCore/inspector/front-end/DebuggerModel.js @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.DebuggerModel = function() +{ + InspectorBackend.registerDomainDispatcher("Debugger", this); + + this._paused = false; + this._breakpoints = {}; + this._sourceIDAndLineToBreakpointId = {}; + this._scripts = {}; +} + +WebInspector.DebuggerModel.Events = { + DebuggerPaused: "debugger-paused", + DebuggerResumed: "debugger-resumed", + ParsedScriptSource: "parsed-script-source", + FailedToParseScriptSource: "failed-to-parse-script-source", + BreakpointAdded: "breakpoint-added", + BreakpointRemoved: "breakpoint-removed" +} + +WebInspector.DebuggerModel.prototype = { + continueToLine: function(sourceID, lineNumber) + { + function didSetBreakpoint(breakpointId, actualLineNumber) + { + if (!breakpointId) + return; + if (this.findBreakpoint(sourceID, actualLineNumber)) { + InspectorBackend.removeBreakpoint(breakpointId); + return; + } + if ("_continueToLineBreakpointId" in this) + InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); + this._continueToLineBreakpointId = breakpointId; + } + InspectorBackend.setBreakpoint(sourceID, lineNumber, "", true, didSetBreakpoint.bind(this)); + if (this._paused) + InspectorBackend.resume(); + }, + + setBreakpoint: function(sourceID, lineNumber, enabled, condition) + { + function didSetBreakpoint(breakpointId, actualLineNumber) + { + if (breakpointId) + this._breakpointSetOnBackend(breakpointId, sourceID, actualLineNumber, condition, enabled, lineNumber, false); + } + InspectorBackend.setBreakpoint(sourceID, lineNumber, condition, enabled, didSetBreakpoint.bind(this)); + }, + + removeBreakpoint: function(breakpointId) + { + InspectorBackend.removeBreakpoint(breakpointId); + var breakpoint = this._breakpoints[breakpointId]; + delete this._breakpoints[breakpointId]; + delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)]; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId); + }, + + breakpointResolved: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber) + { + this._breakpointSetOnBackend(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, true); + }, + + _breakpointSetOnBackend: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, restored) + { + var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); + if (sourceIDAndLine in this._sourceIDAndLineToBreakpointId) { + InspectorBackend.removeBreakpoint(breakpointId); + return; + } + + var url = this._scripts[sourceID].sourceURL; + var breakpoint = new WebInspector.Breakpoint(this, breakpointId, sourceID, url, lineNumber, enabled, condition); + breakpoint.restored = restored; + breakpoint.originalLineNumber = originalLineNumber; + this._breakpoints[breakpointId] = breakpoint; + this._sourceIDAndLineToBreakpointId[sourceIDAndLine] = breakpointId; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint); + }, + + queryBreakpoints: function(filter) + { + var breakpoints = []; + for (var id in this._breakpoints) { + var breakpoint = this._breakpoints[id]; + if (filter(breakpoint)) + breakpoints.push(breakpoint); + } + return breakpoints; + }, + + findBreakpoint: function(sourceID, lineNumber) + { + var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber); + var breakpointId = this._sourceIDAndLineToBreakpointId[sourceIDAndLine]; + return this._breakpoints[breakpointId]; + }, + + _encodeSourceIDAndLine: function(sourceID, lineNumber) + { + return sourceID + ":" + lineNumber; + }, + + reset: function() + { + this._paused = false; + this._breakpoints = {}; + delete this._oneTimeBreakpoint; + this._sourceIDAndLineToBreakpointId = {}; + this._scripts = {}; + }, + + scriptForSourceID: function(sourceID) + { + return this._scripts[sourceID]; + }, + + scriptsForURL: function(url) + { + return this.queryScripts(function(s) { return s.sourceURL === url; }); + }, + + queryScripts: function(filter) + { + var scripts = []; + for (var sourceID in this._scripts) { + var script = this._scripts[sourceID]; + if (filter(script)) + scripts.push(script); + } + return scripts; + }, + + // All the methods below are InspectorBackend notification handlers. + + pausedScript: function(details) + { + this._paused = true; + if ("_continueToLineBreakpointId" in this) { + InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId); + delete this._continueToLineBreakpointId; + } + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details); + + if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause || details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) + return; + + var breakpoint = this.findBreakpoint(details.callFrames[0].sourceID, details.callFrames[0].line); + if (!breakpoint) + return; + breakpoint.hit = true; + this._lastHitBreakpoint = breakpoint; + }, + + resumedScript: function() + { + this._paused = false; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed); + + if (!this._lastHitBreakpoint) + return; + this._lastHitBreakpoint.hit = false; + delete this._lastHitBreakpoint; + }, + + attachDebuggerWhenShown: function() + { + WebInspector.panels.scripts.attachDebuggerWhenShown(); + }, + + debuggerWasEnabled: function() + { + WebInspector.panels.scripts.debuggerWasEnabled(); + }, + + debuggerWasDisabled: function() + { + WebInspector.panels.scripts.debuggerWasDisabled(); + }, + + parsedScriptSource: function(sourceID, sourceURL, source, startingLine, scriptWorldType) + { + var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType); + this._scripts[sourceID] = script; + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, sourceID); + }, + + failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage) + { + var script = new WebInspector.Script(null, sourceURL, source, startingLine, errorLine, errorMessage, undefined); + this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script); + }, + + didCreateWorker: function() + { + var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; + workersPane.addWorker.apply(workersPane, arguments); + }, + + didDestroyWorker: function() + { + var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; + workersPane.removeWorker.apply(workersPane, arguments); + } +} + +WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype; + +WebInspector.DebuggerEventTypes = { + JavaScriptPause: 0, + JavaScriptBreakpoint: 1, + NativeBreakpoint: 2 +}; diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js index 61ba33e..9299479 100644 --- a/WebCore/inspector/front-end/ElementsPanel.js +++ b/WebCore/inspector/front-end/ElementsPanel.js @@ -88,6 +88,7 @@ WebInspector.ElementsPanel = function() this.sidebarPanes.styles.addEventListener("style edited", this._stylesPaneEdited, this); this.sidebarPanes.styles.addEventListener("style property toggled", this._stylesPaneEdited, this); this.sidebarPanes.metrics.addEventListener("metrics edited", this._metricsPaneEdited, this); + WebInspector.cssModel.addEventListener("stylesheet changed", this._styleSheetChanged, this); this.sidebarElement = document.createElement("div"); this.sidebarElement.id = "elements-sidebar"; @@ -169,9 +170,6 @@ WebInspector.ElementsPanel.prototype = { this.recentlyModifiedNodes = []; delete this.currentQuery; - - if (Preferences.nativeInstrumentationEnabled) - this.sidebarPanes.domBreakpoints.reset(); }, setDocument: function(inspectedRootDocument) @@ -447,16 +445,24 @@ WebInspector.ElementsPanel.prototype = { _stylesPaneEdited: function() { + // Once styles are edited, the Metrics pane should be updated. this.sidebarPanes.metrics.needsUpdate = true; this.updateMetrics(); }, _metricsPaneEdited: function() { + // Once metrics are edited, the Styles pane should be updated. this.sidebarPanes.styles.needsUpdate = true; this.updateStyles(true); }, + _styleSheetChanged: function() + { + this._metricsPaneEdited(); + this._stylesPaneEdited(); + }, + _mouseMovedInCrumbs: function(event) { var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js index f893ca0..f25f858 100644 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ b/WebCore/inspector/front-end/ElementsTreeOutline.js @@ -268,6 +268,7 @@ WebInspector.ElementsTreeOutline.prototype = { if (this.showInElementsPanelEnabled) { function focusElement() { + WebInspector.currentPanel = WebInspector.panels.elements; WebInspector.panels.elements.focusedDOMNode = listItem.treeElement.representedObject; } contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this)); @@ -871,7 +872,11 @@ WebInspector.ElementsTreeElement.prototype = { // Remove zero-width spaces that were added by nodeTitleInfo. removeZeroWidthSpaceRecursive(attribute); - this._editing = WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName); + this._editing = WebInspector.startEditing(attribute, { + context: attributeName, + commitHandler: this._attributeEditingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1); return true; @@ -882,7 +887,11 @@ WebInspector.ElementsTreeElement.prototype = { if (WebInspector.isBeingEdited(textNode)) return true; - this._editing = WebInspector.startEditing(textNode, this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this)); + this._editing = WebInspector.startEditing(textNode, { + context: null, + commitHandler: this._textNodeEditingCommitted.bind(this), + cancelHandler: this._editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1); return true; @@ -925,7 +934,11 @@ WebInspector.ElementsTreeElement.prototype = { tagNameElement.addEventListener('keyup', keyupListener, false); - this._editing = WebInspector.startEditing(tagNameElement, editingComitted.bind(this), editingCancelled.bind(this), tagName); + this._editing = WebInspector.startEditing(tagNameElement, { + context: tagName, + commitHandler: editingComitted.bind(this), + cancelHandler: editingCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1); return true; }, @@ -979,7 +992,12 @@ WebInspector.ElementsTreeElement.prototype = { this.updateSelection(); } - this._editing = WebInspector.startEditing(this._htmlEditElement, commit.bind(this), dispose.bind(this), null, true); + this._editing = WebInspector.startEditing(this._htmlEditElement, { + context: null, + commitHandler: commit.bind(this), + cancelHandler: dispose.bind(this), + multiline: true + }); }, _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection) @@ -1015,8 +1033,12 @@ WebInspector.ElementsTreeElement.prototype = { if (!found) { if (moveDirection === "backward" && attributes.length > 0) moveToAttribute = attributes[attributes.length - 1].name; - else if (moveDirection === "forward" && !/^\s*$/.test(newText)) - moveToNewAttribute = true; + else if (moveDirection === "forward") { + if (!/^\s*$/.test(newText)) + moveToNewAttribute = true; + else + moveToTagName = true; + } } } @@ -1094,8 +1116,10 @@ WebInspector.ElementsTreeElement.prototype = { function moveToNextAttributeIfNeeded() { - if (moveDirection !== "forward") + if (moveDirection !== "forward") { + this._addNewAttribute(); return; + } var attributes = this.representedObject.attributes; if (attributes.length > 0) diff --git a/WebCore/inspector/front-end/ExtensionAPI.js b/WebCore/inspector/front-end/ExtensionAPI.js index 0234994..a9a2423 100644 --- a/WebCore/inspector/front-end/ExtensionAPI.js +++ b/WebCore/inspector/front-end/ExtensionAPI.js @@ -126,6 +126,11 @@ Resources.prototype = { callback(result); } return extensionServer.sendRequest({ command: "getHAR" }, callback && callbackWrapper); + }, + + addRequestHeaders: function(headers) + { + return extensionServer.sendRequest({ command: "addRequestHeaders", headers: headers, extensionId: location.hostname }); } } diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js index 1050c6f..373c855 100644 --- a/WebCore/inspector/front-end/ExtensionServer.js +++ b/WebCore/inspector/front-end/ExtensionServer.js @@ -33,8 +33,10 @@ WebInspector.ExtensionServer = function() this._clientObjects = {}; this._handlers = {}; this._subscribers = {}; + this._extraHeaders = {}; this._status = new WebInspector.ExtensionStatus(); + this._registerHandler("addRequestHeaders", this._onAddRequestHeaders.bind(this)); this._registerHandler("addAuditCategory", this._onAddAuditCategory.bind(this)); this._registerHandler("addAuditResult", this._onAddAuditResult.bind(this)); this._registerHandler("createPanel", this._onCreatePanel.bind(this)); @@ -144,6 +146,29 @@ WebInspector.ExtensionServer.prototype = { delete this._subscribers[message.type]; }, + _onAddRequestHeaders: function(message) + { + var id = message.extensionId; + if (typeof id !== "string") + return this._status.E_BADARGTYPE("extensionId", typeof id, "string"); + var extensionHeaders = this._extraHeaders[id]; + if (!extensionHeaders) { + extensionHeaders = {}; + this._extraHeaders[id] = extensionHeaders; + } + for (name in message.headers) + extensionHeaders[name] = message.headers[name]; + var allHeaders = {}; + for (extension in this._extraHeaders) { + var headers = this._extraHeaders[extension]; + for (name in headers) { + if (typeof headers[name] === "string") + allHeaders[name] = headers[name]; + } + } + InspectorBackend.setExtraHeaders(allHeaders); + }, + _onCreatePanel: function(message, port) { var id = message.id; diff --git a/WebCore/inspector/front-end/HeapSnapshotView.js b/WebCore/inspector/front-end/HeapSnapshotView.js index 6bcc0ff..f349361 100644 --- a/WebCore/inspector/front-end/HeapSnapshotView.js +++ b/WebCore/inspector/front-end/HeapSnapshotView.js @@ -27,6 +27,154 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +WebInspector.HeapSnapshotEdgesIterator = function(snapshot, edges) +{ + this._snapshot = snapshot; + this._edges = edges; + this._edgeIndex = 0; +} + +WebInspector.HeapSnapshotEdgesIterator.prototype = { + get done() + { + return this._edgeIndex >= this._edges.length; + }, + + get isElement() + { + return this._getType() === this._snapshot._edgeElementType; + }, + + get isHidden() + { + return this._getType() === this._snapshot._edgeHiddenType; + }, + + get name() + { + return this.isElement || this.isHidden ? this._getNameOrIndex() : this._snapshot._strings[this._getNameOrIndex()]; + }, + + next: function() + { + this._edgeIndex += this._snapshot._edgeFieldsCount; + }, + + get node() + { + return new WebInspector.HeapSnapshotNodeWrapper(this._snapshot, this.nodeIndex); + }, + + get nodeIndex() + { + return this._edges[this._edgeIndex + this._snapshot._edgeToNodeOffset]; + }, + + _getNameOrIndex: function() + { + return this._edges[this._edgeIndex + this._snapshot._edgeNameOffset]; + }, + + _getType: function() + { + return this._edges[this._edgeIndex + this._snapshot._edgeTypeOffset]; + } +}; + +WebInspector.HeapSnapshotNodeWrapper = function(snapshot, nodeIndex) +{ + this._snapshot = snapshot; + this._nodes = snapshot._nodes; + this._nodeIndex = nodeIndex; +} + +WebInspector.HeapSnapshotNodeWrapper.prototype = { + get edges() + { + return new WebInspector.HeapSnapshotEdgesIterator(this._snapshot, this._getEdges()); + }, + + get edgesCount() + { + return this._nodes[this._nodeIndex + this._snapshot._edgesCountOffset]; + }, + + get instancesCount() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeInstancesCountOffset]; + }, + + get isHidden() + { + return this._getType() === this._snapshot._nodeHiddenType; + }, + + get name() + { + return this._snapshot._strings[this._getName()]; + }, + + get selfSize() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeSelfSizeOffset]; + }, + + _getName: function() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeNameOffset]; + }, + + _getEdges: function() + { + var firstEdgeIndex = this._nodeIndex + this._snapshot._firstEdgeOffset; + return this._nodes.slice(firstEdgeIndex, firstEdgeIndex + this.edgesCount * this._snapshot._edgeFieldsCount); + }, + + _getType: function() + { + return this._nodes[this._nodeIndex + this._snapshot._nodeTypeOffset]; + } +}; + +WebInspector.HeapSnapshot = function(profile) +{ + this._profile = profile; + this._nodes = profile.nodes; + this._strings = profile.strings; + + this._init(); +} + +WebInspector.HeapSnapshot.prototype = { + _init: function() + { + this._metaNodeIndex = 0; + this._rootNodeIndex = 1; + var meta = this._nodes[this._metaNodeIndex]; + this._nodeTypeOffset = meta.fields.indexOf("type"); + this._nodeNameOffset = meta.fields.indexOf("name"); + this._nodeIdOffset = meta.fields.indexOf("id"); + this._nodeInstancesCountOffset = this._nodeIdOffset; + this._nodeSelfSizeOffset = meta.fields.indexOf("self_size"); + this._edgesCountOffset = meta.fields.indexOf("children_count"); + this._firstEdgeOffset = meta.fields.indexOf("children"); + this._nodeTypes = meta.types[this._nodeTypeOffset]; + this._nodeHiddenType = this._nodeTypes.indexOf("hidden"); + var edgesMeta = meta.types[this._firstEdgeOffset]; + this._edgeFieldsCount = edgesMeta.fields.length; + this._edgeTypeOffset = edgesMeta.fields.indexOf("type"); + this._edgeNameOffset = edgesMeta.fields.indexOf("name_or_index"); + this._edgeToNodeOffset = edgesMeta.fields.indexOf("to_node"); + this._edgeTypes = edgesMeta.types[this._edgeTypeOffset]; + this._edgeElementType = this._edgeTypes.indexOf("element"); + this._edgeHiddenType = this._edgeTypes.indexOf("hidden"); + }, + + get rootEdges() + { + return (new WebInspector.HeapSnapshotNodeWrapper(this, this._rootNodeIndex)).edges; + } +}; WebInspector.HeapSnapshotView = function(parent, profile) { @@ -327,22 +475,16 @@ WebInspector.HeapSnapshotView.prototype = { _loadProfile: function(profile, callback) { - if (profile._loaded) { - callback(profile); - return; - } - - InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this)); + WebInspector.panels.profiles.loadHeapSnapshot(profile.uid, callback); + }, - function loadedCallback(loadedSnapshot) { - profile.children = loadedSnapshot.head.children; - profile.entries = loadedSnapshot.head.entries; - profile.lowlevels = loadedSnapshot.head.lowlevels; - this._prepareProfile(profile); - profile._loaded = true; - this.parent.updateProfile(profile); - callback(profile); - } + processLoadedSnapshot: function(profile, loadedSnapshot) + { + var snapshot = WebInspector.HeapSnapshotView.prototype._convertSnapshot(loadedSnapshot); + profile.children = snapshot.children; + profile.entries = snapshot.entries; + profile.lowlevels = snapshot.lowlevels; + WebInspector.HeapSnapshotView.prototype._prepareProfile(profile); }, _mouseDownInDataGrid: function(event) @@ -384,6 +526,26 @@ WebInspector.HeapSnapshotView.prototype = { this.refreshShowAsPercents(); }, + _convertSnapshot: function(loadedSnapshot) + { + var snapshot = new WebInspector.HeapSnapshot(loadedSnapshot); + var result = {lowlevels: {}, entries: {}, children: {}}; + for (var rootEdges = snapshot.rootEdges; !rootEdges.done; rootEdges.next()) { + var node = rootEdges.node; + if (node.isHidden) + result.lowlevels[node.name] = {count: node.instancesCount, size: node.selfSize, type: node.name}; + else if (node.instancesCount) + result.entries[node.name] = {constructorName: node.name, count: node.instancesCount, size: node.selfSize}; + else { + var entry = {constructorName: node.name}; + for (var edges = node.edges; !edges.done; edges.next()) + entry[edges.nodeIndex] = {constructorName: edges.node.name, count: edges.name}; + result.children[rootEdges.nodeIndex] = entry; + } + } + return result; + }, + _prepareProfile: function(profile) { for (var profileEntry in profile.entries) @@ -392,12 +554,12 @@ WebInspector.HeapSnapshotView.prototype = { for (var addr in profile.children) { var retainer = profile.children[addr]; - var retainerId = retainer.constructorName + ':' + addr; + var retainerId = retainer.constructorName + ":" + addr; for (var childAddr in retainer) { - if (childAddr === 'constructorName') continue; + if (childAddr === "constructorName") continue; var item = retainer[childAddr]; - var itemId = item.constructorName + ':' + childAddr; - if ((item.constructorName === 'Object' || item.constructorName === 'Array')) { + var itemId = item.constructorName + ":" + childAddr; + if ((item.constructorName === "Object" || item.constructorName === "Array")) { if (!(itemId in profile.clusters)) profile.clusters[itemId] = { constructorName: itemId, retainers: {} }; mergeRetainers(profile.clusters[itemId], item); @@ -412,7 +574,7 @@ WebInspector.HeapSnapshotView.prototype = { entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} }; var retainerEntry = entry.retainers[retainer.constructorName]; retainerEntry.count += item.count; - if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array') + if (retainer.constructorName === "Object" || retainer.constructorName === "Array") retainerEntry.clusters[retainerId] = true; } }, @@ -438,7 +600,7 @@ WebInspector.HeapSnapshotView.prototype = { var sortAscending = this.dataGrid.sortOrder === "ascending"; var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; var sortProperty = { - cons: ["cons", null], + cons: ["constructorName", null], count: ["count", null], size: ["size", "count"], countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null], diff --git a/WebCore/inspector/front-end/MetricsSidebarPane.js b/WebCore/inspector/front-end/MetricsSidebarPane.js index 3784ce8..3c0f315 100644 --- a/WebCore/inspector/front-end/MetricsSidebarPane.js +++ b/WebCore/inspector/front-end/MetricsSidebarPane.js @@ -175,7 +175,11 @@ WebInspector.MetricsSidebarPane.prototype = { var context = { box: box, styleProperty: styleProperty }; - WebInspector.startEditing(targetElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(targetElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingCancelled: function(element, context) diff --git a/WebCore/inspector/front-end/NetworkItemView.js b/WebCore/inspector/front-end/NetworkItemView.js index 927e840..48e3b19 100644 --- a/WebCore/inspector/front-end/NetworkItemView.js +++ b/WebCore/inspector/front-end/NetworkItemView.js @@ -37,7 +37,6 @@ WebInspector.NetworkItemView = function(resource) this._headersView = new WebInspector.ResourceHeadersView(resource); // Do not store reference to content view - it can be recreated. var contentView = WebInspector.ResourceManager.resourceViewForResource(resource); - this._cookiesView = new WebInspector.ResourceCookiesView(resource); this._tabbedPane = new WebInspector.TabbedPane(this.element); this._tabbedPane.appendTab("headers", WebInspector.UIString("Headers"), this._headersView); @@ -46,8 +45,10 @@ WebInspector.NetworkItemView = function(resource) contentView.visible = false; this._tabbedPane.appendTab("content", WebInspector.UIString("Content"), contentView); } - this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView); - + if (Preferences.showCookiesTab) { + this._cookiesView = new WebInspector.ResourceCookiesView(resource); + this._tabbedPane.appendTab("cookies", WebInspector.UIString("Cookies"), this._cookiesView); + } if (Preferences.showTimingTab) { var timingView = new WebInspector.ResourceTimingView(resource); this._tabbedPane.appendTab("timing", WebInspector.UIString("Timing"), timingView); @@ -82,7 +83,7 @@ WebInspector.NetworkItemView.prototype = { resize: function() { - if (this._cookiesView.visible) + if (this._cookiesView && this._cookiesView.visible) this._cookiesView.resize(); } } diff --git a/WebCore/inspector/front-end/NetworkPanel.js b/WebCore/inspector/front-end/NetworkPanel.js index 8f3cfd6..9941dbf 100644 --- a/WebCore/inspector/front-end/NetworkPanel.js +++ b/WebCore/inspector/front-end/NetworkPanel.js @@ -8,13 +8,13 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -210,6 +210,7 @@ WebInspector.NetworkPanel.prototype = { columns.timeline.sort = "ascending"; this._dataGrid = new WebInspector.DataGrid(columns); + this._dataGrid.element.addEventListener("contextmenu", this._contextMenu.bind(this), true); this.containerElement.appendChild(this._dataGrid.element); this._dataGrid.addEventListener("sorting changed", this._sortItems, this); this._dataGrid.addEventListener("width changed", this._updateDividersIfNeeded, this); @@ -397,7 +398,7 @@ WebInspector.NetworkPanel.prototype = { transferSize += (resource.cached || !resource.transferSize) ? 0 : resource.transferSize; if (resource.isMainResource) baseTime = resource.startTime; - if (resource.endTime > maxTime) + if (resource.endTime > maxTime) maxTime = resource.endTime; } var text = String.sprintf(WebInspector.UIString("%d requests"), numRequests); @@ -517,7 +518,7 @@ WebInspector.NetworkPanel.prototype = { proceed = false; } else proceed = this._timelineGrid.updateDividers(force, this.calculator); - + if (!proceed) return; @@ -545,13 +546,13 @@ WebInspector.NetworkPanel.prototype = { loadDividerPadding.style.left = percent + "%"; this._timelineGrid.addEventDivider(loadDividerPadding); } - + if (this._mainResourceDOMContentTime !== -1) { var percent = this.calculator.computePercentageFromEventTime(this._mainResourceDOMContentTime); var domContentDivider = document.createElement("div"); domContentDivider.className = "network-event-divider network-blue-divider"; - + var domContentDividerPadding = document.createElement("div"); domContentDividerPadding.className = "network-event-divider-padding"; domContentDividerPadding.title = WebInspector.UIString("DOMContent event fired"); @@ -625,7 +626,7 @@ WebInspector.NetworkPanel.prototype = { { if (this._mainResourceLoadTime === x) return; - + this._mainResourceLoadTime = x || -1; // Update the dividers to draw the new line this._updateDividersIfNeeded(true); @@ -762,7 +763,7 @@ WebInspector.NetworkPanel.prototype = { this._mainResourceLoadTime = -1; this._mainResourceDOMContentTime = -1; - + this._viewsContainerElement.removeChildren(); this._viewsContainerElement.appendChild(this._closeButtonElement); this._resetSummaryBar(); @@ -792,7 +793,7 @@ WebInspector.NetworkPanel.prototype = { this._staleResources.push(resource); this._scheduleRefresh(); - + if (!resource) return; @@ -972,6 +973,35 @@ WebInspector.NetworkPanel.prototype = { var widths = {}; widths.name = 100; this._dataGrid.applyColumnWidthsMap(widths); + }, + + _contextMenu: function(event) + { + // createBlobURL is enabled conditionally, do not expose resource export if it's not available. + if (typeof window.createObjectURL !== "function" || !Preferences.resourceExportEnabled) + return; + + var contextMenu = new WebInspector.ContextMenu(); + var gridNode = this._dataGrid.dataGridNodeFromNode(event.target); + var resource = gridNode && gridNode._resource; + if (resource) + contextMenu.appendItem(WebInspector.UIString("Export to HAR"), this._exportResource.bind(this, resource)); + contextMenu.appendItem(WebInspector.UIString("Export all to HAR"), this._exportAll.bind(this)); + contextMenu.show(event); + }, + + _exportAll: function() + { + var harArchive = { + log: (new WebInspector.HARLog()).build() + } + offerFileForDownload(JSON.stringify(harArchive)); + }, + + _exportResource: function(resource) + { + var har = (new WebInspector.HAREntry(resource)).build(); + offerFileForDownload(JSON.stringify(har)); } } @@ -1134,7 +1164,7 @@ WebInspector.NetworkTimeCalculator.prototype = { return {start: start, middle: middle, end: end}; }, - + computePercentageFromEventTime: function(eventTime) { // This function computes a percentage in terms of the total loading time @@ -1364,6 +1394,7 @@ WebInspector.NetworkDataGridNode.prototype = { if (this._resource.cached) this._graphElement.addStyleClass("resource-cached"); + this._element.addStyleClass("network-item"); if (!this._element.hasStyleClass("network-category-" + this._resource.category.name)) { this._element.removeMatchingStyleClasses("network-category-\\w+"); this._element.addStyleClass("network-category-" + this._resource.category.name); diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js index e13e5eb..e4794f3 100644 --- a/WebCore/inspector/front-end/ObjectPropertiesSection.js +++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js @@ -202,8 +202,10 @@ WebInspector.ObjectPropertyTreeElement.prototype = { { function selectNode(nodeId) { - if (nodeId) + if (nodeId) { + WebInspector.currentPanel = WebInspector.panels.elements; WebInspector.panels.elements.focusedDOMNode = WebInspector.domAgent.nodeForId(nodeId); + } } function revealElement() @@ -236,7 +238,11 @@ WebInspector.ObjectPropertyTreeElement.prototype = { this.listItemElement.addStyleClass("editing-sub-part"); - WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(this.valueElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingEnded: function(context) diff --git a/WebCore/inspector/front-end/Placard.js b/WebCore/inspector/front-end/Placard.js index 69a168e..9a415c4 100644 --- a/WebCore/inspector/front-end/Placard.js +++ b/WebCore/inspector/front-end/Placard.js @@ -67,7 +67,7 @@ WebInspector.Placard.prototype = { if (this._subtitle === x) return; this._subtitle = x; - this.subtitleElement.innerHTML = x; + this.subtitleElement.textContent = x; }, get selected() diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js index 0aa4174..3e31ba5 100644 --- a/WebCore/inspector/front-end/ProfilesPanel.js +++ b/WebCore/inspector/front-end/ProfilesPanel.js @@ -124,6 +124,7 @@ WebInspector.ProfilesPanel = function() this._profiles = []; this._profilerEnabled = Preferences.profilerAlwaysEnabled; this._reset(); + InspectorBackend.registerDomainDispatcher("Profiler", this); } WebInspector.ProfilesPanel.prototype = { @@ -411,6 +412,50 @@ WebInspector.ProfilesPanel.prototype = { } }, + loadHeapSnapshot: function(uid, callback) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile) + return; + + if (profile._loaded) + callback(profile); + else if (profile._is_loading) + profile._callbacks.push(callback); + else { + profile._is_loading = true; + profile._callbacks = [callback]; + profile._json = ""; + InspectorBackend.getProfile(profile.typeId, profile.uid); + } + }, + + addHeapSnapshotChunk: function(uid, chunk) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile || profile._loaded || !profile._is_loading) + return; + + profile._json += chunk; + }, + + finishHeapSnapshot: function(uid) + { + var profile = this._profilesIdMap[this._makeKey(uid, WebInspector.HeapSnapshotProfileType.TypeId)]; + if (!profile || profile._loaded || !profile._is_loading) + return; + + var callbacks = profile._callbacks; + delete profile._callbacks; + var loadedSnapshot = JSON.parse(profile._json); + delete profile._json; + delete profile._is_loading; + profile._loaded = true; + WebInspector.HeapSnapshotView.prototype.processLoadedSnapshot(profile, loadedSnapshot); + for (var i = 0; i < callbacks.length; ++i) + callbacks[i](profile); + }, + showView: function(view) { this.showProfile(view.profile); @@ -553,7 +598,7 @@ WebInspector.ProfilesPanel.prototype = { var profileHeadersLength = profileHeaders.length; for (var i = 0; i < profileHeadersLength; ++i) if (!this.hasProfile(profileHeaders[i])) - WebInspector.addProfileHeader(profileHeaders[i]); + WebInspector.panels.profiles.addProfileHeader(profileHeaders[i]); } InspectorBackend.getProfileHeaders(populateCallback.bind(this)); @@ -567,6 +612,26 @@ WebInspector.ProfilesPanel.prototype = { this.profileViews.style.left = width + "px"; this.profileViewStatusBarItemsContainer.style.left = Math.max(155, width) + "px"; this.resize(); + }, + + setRecordingProfile: function(isProfiling) + { + this.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling); + if (this.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) { + if (!this._temporaryRecordingProfile) { + this._temporaryRecordingProfile = { + typeId: WebInspector.CPUProfileType.TypeId, + title: WebInspector.UIString("Recording"), + uid: -1, + isTemporary: true + }; + } + if (isProfiling) + this.addProfileHeader(this._temporaryRecordingProfile); + else + this.removeProfileHeader(this._temporaryRecordingProfile); + } + this.updateProfileTypeButtons(); } } diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js index aefdd6c..da21092 100644 --- a/WebCore/inspector/front-end/Resource.js +++ b/WebCore/inspector/front-end/Resource.js @@ -497,48 +497,6 @@ WebInspector.Resource.prototype = { } }, - get scripts() - { - if (!("_scripts" in this)) - this._scripts = []; - return this._scripts; - }, - - addScript: function(script) - { - if (!script) - return; - this.scripts.unshift(script); - script.resource = this; - }, - - removeAllScripts: function() - { - if (!this._scripts) - return; - - for (var i = 0; i < this._scripts.length; ++i) { - if (this._scripts[i].resource === this) - delete this._scripts[i].resource; - } - - delete this._scripts; - }, - - removeScript: function(script) - { - if (!script) - return; - - if (script.resource === this) - delete script.resource; - - if (!this._scripts) - return; - - this._scripts.remove(script); - }, - get errors() { return this._errors || 0; @@ -608,7 +566,6 @@ WebInspector.Resource.prototype = { WebInspector.ConsoleMessage.MessageLevel.Warning, -1, this.url, - null, 1, String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toUIString(this.type), this.mimeType), null, diff --git a/WebCore/inspector/front-end/ResourceManager.js b/WebCore/inspector/front-end/ResourceManager.js index 992d8c7..7f1c574 100644 --- a/WebCore/inspector/front-end/ResourceManager.js +++ b/WebCore/inspector/front-end/ResourceManager.js @@ -30,39 +30,17 @@ WebInspector.ResourceManager = function() { - this._registerNotifyHandlers( - "identifierForInitialRequest", - "willSendRequest", - "markResourceAsCached", - "didReceiveResponse", - "didReceiveContentLength", - "didFinishLoading", - "didFailLoading", - "didLoadResourceFromMemoryCache", - "setInitialContent", - "didCommitLoadForFrame", - "frameDetachedFromParent", - "didCreateWebSocket", - "willSendWebSocketHandshakeRequest", - "didReceiveWebSocketHandshakeResponse", - "didCloseWebSocket"); - this._resourcesById = {}; this._resourcesByURL = {}; this._resourceTreeModel = new WebInspector.ResourceTreeModel(); InspectorBackend.cachedResources(this._processCachedResources.bind(this)); + InspectorBackend.registerDomainDispatcher("Resources", this); } WebInspector.ResourceManager.prototype = { - _registerNotifyHandlers: function() - { - for (var i = 0; i < arguments.length; ++i) - WebInspector[arguments[i]] = this[arguments[i]].bind(this); - }, - - identifierForInitialRequest: function(identifier, url, loader) + identifierForInitialRequest: function(identifier, url, loader, callStack) { - var resource = this._createResource(identifier, url, loader); + var resource = this._createResource(identifier, url, loader, callStack); // It is important to bind resource url early (before scripts compile). this._bindResourceURL(resource); @@ -71,12 +49,13 @@ WebInspector.ResourceManager.prototype = { WebInspector.panels.audits.resourceStarted(resource); }, - _createResource: function(identifier, url, loader) + _createResource: function(identifier, url, loader, stackTrace) { var resource = new WebInspector.Resource(identifier, url); resource.loader = loader; if (loader) resource.documentURL = loader.url; + resource.stackTrace = stackTrace; this._resourcesById[identifier] = resource; return resource; @@ -119,7 +98,7 @@ WebInspector.ResourceManager.prototype = { var originalResource = this._resourcesById[identifier]; originalResource.identifier = null; - var newResource = this._createResource(identifier, redirectURL, originalResource.loader); + var newResource = this._createResource(identifier, redirectURL, originalResource.loader, originalResource.stackTrace); newResource.redirects = originalResource.redirects || []; delete originalResource.redirects; newResource.redirects.push(originalResource); @@ -268,7 +247,6 @@ WebInspector.ResourceManager.prototype = { if (mainResource) { WebInspector.mainResource = mainResource; mainResource.isMainResource = true; - WebInspector.panels.network.refreshResource(mainResource); } } }, @@ -428,6 +406,89 @@ WebInspector.ResourceManager.prototype = { } delete this._resourcesByURL[resource.url]; + }, + + updateDOMStorage: function(storageId) + { + WebInspector.panels.resources.updateDOMStorage(storageId); + }, + + updateApplicationCacheStatus: function(status) + { + WebInspector.panels.resources.updateApplicationCacheStatus(status); + }, + + didGetFileSystemPath: function(root, type, origin) + { + WebInspector.panels.resources.updateFileSystemPath(root, type, origin); + }, + + didGetFileSystemError: function(type, origin) + { + WebInspector.panels.resources.updateFileSystemError(type, origin); + }, + + didGetFileSystemDisabled: function() + { + WebInspector.panels.resources.setFileSystemDisabled(); + }, + + updateNetworkState: function(isNowOnline) + { + WebInspector.panels.resources.updateNetworkState(isNowOnline); + }, + + addDOMStorage: function(payload) + { + if (!WebInspector.panels.resources) + return; + var domStorage = new WebInspector.DOMStorage( + payload.id, + payload.host, + payload.isLocalStorage); + WebInspector.panels.resources.addDOMStorage(domStorage); + }, + + selectDOMStorage: function(o) + { + WebInspector.showPanel("resources"); + WebInspector.panels.resources.selectDOMStorage(o); + }, + + addDatabase: function(payload) + { + if (!WebInspector.panels.resources) + return; + var database = new WebInspector.Database( + payload.id, + payload.domain, + payload.name, + payload.version); + WebInspector.panels.resources.addDatabase(database); + }, + + selectDatabase: function(o) + { + WebInspector.showPanel("resources"); + WebInspector.panels.resources.selectDatabase(o); + }, + + sqlTransactionSucceeded: function(transactionId, columnNames, values) + { + var callback = WebInspector.Database.successCallbacks[transactionId]; + if (!callback) + return; + delete WebInspector.Database.successCallbacks[transactionId]; + callback(columnNames, values); + }, + + sqlTransactionFailed: function(transactionId, errorObj) + { + var callback = WebInspector.Database.errorCallbacks[transactionId]; + if (!callback) + return; + delete WebInspector.Database.errorCallbacks[transactionId]; + callback(errorObj); } } diff --git a/WebCore/inspector/front-end/Script.js b/WebCore/inspector/front-end/Script.js index be3f020..184fe97 100644 --- a/WebCore/inspector/front-end/Script.js +++ b/WebCore/inspector/front-end/Script.js @@ -27,7 +27,7 @@ WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorL { this.sourceID = sourceID; this.sourceURL = sourceURL; - this.source = source; + this._source = source; this.startingLine = startingLine; this.errorLine = errorLine; this.errorMessage = errorMessage; @@ -57,6 +57,10 @@ WebInspector.Script.WorldType = { EXTENSIONS_WORLD: 1 } +WebInspector.Script.Events = { + SourceChanged: "source-changed" +} + WebInspector.Script.prototype = { get linesCount() { @@ -71,5 +75,18 @@ WebInspector.Script.prototype = { this._linesCount++; } return this._linesCount; + }, + + get source() + { + return this._source; + }, + + set source(source) + { + this._source = source; + this.dispatchEventToListeners(WebInspector.Script.Events.SourceChanged); } } + +WebInspector.Script.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/ScriptView.js b/WebCore/inspector/front-end/ScriptView.js index d878e9b..39dae55 100644 --- a/WebCore/inspector/front-end/ScriptView.js +++ b/WebCore/inspector/front-end/ScriptView.js @@ -30,11 +30,11 @@ WebInspector.ScriptView = function(script) this.element.addStyleClass("script-view"); this.script = script; + this.script.addEventListener(WebInspector.Script.Events.SourceChanged, this._scriptSourceChanged, this); this._frameNeedsSetup = true; this._sourceFrameSetup = false; - var canEditScripts = WebInspector.panels.scripts.canEditScripts(); - this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + this.sourceFrame = new WebInspector.SourceFrame(this.element, [script], WebInspector.panels.scripts.canEditScripts()); } WebInspector.ScriptView.prototype = { @@ -85,29 +85,9 @@ WebInspector.ScriptView.prototype = { document.getElementById("script-resource-views").appendChild(this.element); }, - _continueToLine: function(line) + _scriptSourceChanged: function(event) { - var scriptsPanel = WebInspector.panels.scripts; - if (scriptsPanel) - scriptsPanel.continueToLine(this.script.sourceID, line); - }, - - _addBreakpoint: function(line) - { - WebInspector.breakpointManager.setBreakpoint(this.script.sourceID, this.script.sourceURL, line, true, ""); - if (!WebInspector.panels.scripts.breakpointsActivated) - WebInspector.panels.scripts.toggleBreakpointsClicked(); - }, - - _editLineComplete: function(newBody) - { - this.script.source = newBody; - this.sourceFrame.updateContent(this._prependWhitespace(newBody)); - }, - - _sourceIDForLine: function(line) - { - return this.script.sourceID; + this.sourceFrame.updateContent(this._prependWhitespace(this.script.source)); }, // The following methods are pulled from SourceView, since they are @@ -127,9 +107,7 @@ WebInspector.ScriptView.prototype = { showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult, showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult, _jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult, - _editLine: WebInspector.SourceView.prototype._editLine, resize: WebInspector.SourceView.prototype.resize } WebInspector.ScriptView.prototype.__proto__ = WebInspector.View.prototype; - diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js index 30bd513..56facf2 100644 --- a/WebCore/inspector/front-end/ScriptsPanel.js +++ b/WebCore/inspector/front-end/ScriptsPanel.js @@ -175,9 +175,12 @@ WebInspector.ScriptsPanel = function() this._debuggerEnabled = Preferences.debuggerAlwaysEnabled; - WebInspector.breakpointManager.addEventListener("breakpoint-added", this._breakpointAdded, this); - this.reset(); + + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); } // Keep these in sync with WebCore::ScriptDebugServer @@ -234,17 +237,28 @@ WebInspector.ScriptsPanel.prototype = { return this.toggleBreakpointsButton.toggled; }, - addScript: function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType) + _parsedScriptSource: function(event) { - var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType); - this._sourceIDMap[sourceID] = script; + var sourceID = event.data; + var script = WebInspector.debuggerModel.scriptForSourceID(sourceID); + this._addScript(script); + }, - var resource = WebInspector.resourceForURL(sourceURL); + _failedToParseScriptSource: function(event) + { + this._addScript(event.data); + }, + + _addScript: function(script) + { + var resource = WebInspector.resourceForURL(script.sourceURL); if (resource) { if (resource.finished) { // Resource is finished, bind the script right away. - resource.addScript(script); - this._sourceIDMap[sourceID] = resource; + script.resource = resource; + var view = WebInspector.ResourceManager.existingResourceViewForResource(resource); + if (view && view.sourceFrame) + view.sourceFrame.addScript(script); } else { // Resource is not finished, bind the script later. if (!resource._scriptsPendingResourceLoad) { @@ -257,21 +271,13 @@ WebInspector.ScriptsPanel.prototype = { this._addScriptToFilesMenu(script); }, - continueToLine: function(sourceID, line) - { - WebInspector.breakpointManager.setOneTimeBreakpoint(sourceID, line); - if (this.paused) - this._togglePause(); - }, - _resourceLoadingFinished: function(e) { var resource = e.target; for (var i = 0; i < resource._scriptsPendingResourceLoad.length; ++i) { // Bind script to resource. var script = resource._scriptsPendingResourceLoad[i]; - resource.addScript(script); - this._sourceIDMap[script.sourceID] = resource; + script.resource = resource; // Remove script from the files list. script.filesSelectOption.parentElement.removeChild(script.filesSelectOption); @@ -281,26 +287,6 @@ WebInspector.ScriptsPanel.prototype = { delete resource._scriptsPendingResourceLoad; }, - _breakpointAdded: function(event) - { - var breakpoint = event.data; - - var sourceFrame; - if (breakpoint.url) { - var resource = WebInspector.resourceForURL(breakpoint.url); - if (resource && resource.finished) - sourceFrame = this._sourceFrameForScriptOrResource(resource); - } - - if (breakpoint.sourceID && !sourceFrame) { - var object = this._sourceIDMap[breakpoint.sourceID] - sourceFrame = this._sourceFrameForScriptOrResource(object); - } - - if (sourceFrame) - sourceFrame.addBreakpoint(breakpoint); - }, - canEditScripts: function() { return Preferences.canEditScriptSource; @@ -312,7 +298,7 @@ WebInspector.ScriptsPanel.prototype = { return; // Need to clear breakpoints and re-create them later when editing source. - var breakpoints = WebInspector.breakpointManager.breakpointsForSourceID(editData.sourceID); + var breakpoints = WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID === editData.sourceID }); for (var i = 0; i < breakpoints.length; ++i) breakpoints[i].remove(); @@ -321,7 +307,7 @@ WebInspector.ScriptsPanel.prototype = { if (success) { commitEditingCallback(newBodyOrErrorMessage); if (callFrames && callFrames.length) - this.debuggerPaused(callFrames); + this._debuggerPaused({ data: { callFrames: callFrames } }); } else { if (cancelEditingCallback) cancelEditingCallback(); @@ -332,7 +318,7 @@ WebInspector.ScriptsPanel.prototype = { var newLine = breakpoint.line; if (success && breakpoint.line >= editData.line) newLine += editData.linesCountToShift; - WebInspector.breakpointManager.setBreakpoint(editData.sourceID, breakpoint.url, newLine, breakpoint.enabled, breakpoint.condition); + WebInspector.debuggerModel.setBreakpoint(editData.sourceID, newLine, breakpoint.enabled, breakpoint.condition); } }; InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this)); @@ -375,9 +361,10 @@ WebInspector.ScriptsPanel.prototype = { InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback); }, - debuggerPaused: function(callFrames) + _debuggerPaused: function(event) { - WebInspector.breakpointManager.removeOneTimeBreakpoint(); + var callFrames = event.data.callFrames; + this._paused = true; this._waitingToPause = false; this._stepping = false; @@ -386,13 +373,14 @@ WebInspector.ScriptsPanel.prototype = { WebInspector.currentPanel = this; - this.sidebarPanes.callstack.update(callFrames, this._sourceIDMap); + this.sidebarPanes.callstack.update(callFrames, event.data.eventType, event.data.eventData); this.sidebarPanes.callstack.selectedCallFrame = callFrames[0]; window.focus(); + InspectorFrontendHost.bringToFront(); }, - debuggerResumed: function() + _debuggerResumed: function() { this._paused = false; this._waitingToPause = false; @@ -435,7 +423,7 @@ WebInspector.ScriptsPanel.prototype = { delete this.currentQuery; this.searchCanceled(); - this.debuggerResumed(); + this._debuggerResumed(); this._backForwardList = []; this._currentBackForwardIndex = -1; @@ -446,26 +434,13 @@ WebInspector.ScriptsPanel.prototype = { this.functionsSelectElement.removeChildren(); this.viewsContainerElement.removeChildren(); - if (this._sourceIDMap) { - for (var sourceID in this._sourceIDMap) { - var object = this._sourceIDMap[sourceID]; - if (object instanceof WebInspector.Resource) - object.removeAllScripts(); - } - } - - this._sourceIDMap = {}; + var scripts = WebInspector.debuggerModel.queryScripts(function(s) { return !!s.resource; }); + for (var i = 0; i < scripts.length; ++i) + delete scripts[i].resource._resourcesView; this.sidebarPanes.watchExpressions.refreshExpressions(); - if (!preserveItems) { - this.sidebarPanes.jsBreakpoints.reset(); - if (Preferences.nativeInstrumentationEnabled) { - this.sidebarPanes.domBreakpoints.reset(); - this.sidebarPanes.xhrBreakpoints.reset(); - this.sidebarPanes.eventListenerBreakpoints.reset(); - } + if (!preserveItems) this.sidebarPanes.workers.reset(); - } }, get visibleView() @@ -508,22 +483,15 @@ WebInspector.ScriptsPanel.prototype = { _scriptOrResourceForURLAndLine: function(url, line) { - var scriptWithMatchingUrl = null; - for (var sourceID in this._sourceIDMap) { - var scriptOrResource = this._sourceIDMap[sourceID]; - if (scriptOrResource instanceof WebInspector.Script) { - if (scriptOrResource.sourceURL !== url) - continue; - scriptWithMatchingUrl = scriptOrResource; - if (scriptWithMatchingUrl.startingLine <= line && scriptWithMatchingUrl.startingLine + scriptWithMatchingUrl.linesCount > line) - return scriptWithMatchingUrl; - } else { - var resource = scriptOrResource; - if (resource.url === url) - return resource; - } + var scripts = WebInspector.debuggerModel.scriptsForURL(url); + for (var i = 0; i < scripts.length; ++i) { + var script = scripts[i]; + if (script.resource) + return script.resource; + if (script.startingLine <= line && script.startingLine + script.linesCount > line) + return script; } - return scriptWithMatchingUrl; + return null; }, showView: function(view) @@ -742,7 +710,8 @@ WebInspector.ScriptsPanel.prototype = { this.sidebarPanes.scopechain.update(currentFrame); this.sidebarPanes.watchExpressions.refreshExpressions(); - var scriptOrResource = this._sourceIDMap[currentFrame.sourceID]; + var script = WebInspector.debuggerModel.scriptForSourceID(currentFrame.sourceID); + var scriptOrResource = script.resource || script; this._showScriptOrResource(scriptOrResource, {line: currentFrame.line}); this._executionSourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource); @@ -1096,4 +1065,3 @@ WebInspector.ScriptsPanel.prototype = { } WebInspector.ScriptsPanel.prototype.__proto__ = WebInspector.Panel.prototype; - diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js index a186d43..5caa78b 100644 --- a/WebCore/inspector/front-end/Section.js +++ b/WebCore/inspector/front-end/Section.js @@ -31,7 +31,7 @@ WebInspector.Section = function(title, subtitle) { this.element = document.createElement("div"); this.element.className = "section"; - this.element.sectionForTest = this; + this.element._section = this; this.headerElement = document.createElement("div"); this.headerElement.className = "header"; @@ -85,15 +85,15 @@ WebInspector.Section.prototype = { this.subtitleElement.textContent = x; }, - get subtitleAsTextForTest()
- {
- var result = this.subtitleElement.textContent;
- var child = this.subtitleElement.querySelector("[data-uncopyable]");
- if (child) {
- var linkData = child.getAttribute("data-uncopyable");
- if (linkData)
- result += linkData;
- }
+ get subtitleAsTextForTest() + { + var result = this.subtitleElement.textContent; + var child = this.subtitleElement.querySelector("[data-uncopyable]"); + if (child) { + var linkData = child.getAttribute("data-uncopyable"); + if (linkData) + result += linkData; + } return result; }, @@ -124,6 +124,26 @@ WebInspector.Section.prototype = { } }, + get nextSibling() + { + var curElement = this.element; + do { + curElement = curElement.nextSibling; + } while (curElement && !curElement._section); + + return curElement ? curElement._section : null; + }, + + get previousSibling() + { + var curElement = this.element; + do { + curElement = curElement.previousSibling; + } while (curElement && !curElement._section); + + return curElement ? curElement._section : null; + }, + expand: function() { if (this._expanded) diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js index 9aac626..bc50ce9 100644 --- a/WebCore/inspector/front-end/Settings.js +++ b/WebCore/inspector/front-end/Settings.js @@ -48,6 +48,7 @@ var Preferences = { fileSystemEnabled: false, useDataURLForResourceImageIcons: true, showTimingTab: false, + showCookiesTab: false, debugMode: false } @@ -69,6 +70,10 @@ WebInspector.Settings = function() this.installProjectSetting("nativeBreakpoints", []); } +WebInspector.Settings.Events = { + ProjectChanged: "project-changed" +} + WebInspector.Settings.prototype = { installApplicationSetting: function(key, defaultValue) { @@ -90,7 +95,31 @@ WebInspector.Settings.prototype = { var fragmentIndex = url.indexOf("#"); if (fragmentIndex !== -1) url = url.substring(0, fragmentIndex); - this._inspectedURL = url; + this._projectId = url; + this.dispatchEventToListeners(WebInspector.Settings.Events.ProjectChanged); + }, + + get projectId() + { + return this._projectId; + }, + + findSettingForAllProjects: function(key) + { + var result = {}; + var regexp = "^" + key + ":(.*)"; + for (var i = 0; i < window.localStorage.length; ++i) { + var fullKey = window.localStorage.key(i); + var match = fullKey.match(regexp); + if (!match) + continue; + try { + result[match[1]] = JSON.parse(window.localStorage[fullKey]); + } catch(e) { + window.localStorage.removeItem(fullKey); + } + } + return result; }, _get: function(key, defaultValue) @@ -122,7 +151,7 @@ WebInspector.Settings.prototype = { _formatProjectKey: function(key) { - return key + ":" + this._inspectedURL; + return key + ":" + this._projectId; } } diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.js b/WebCore/inspector/front-end/SourceCSSTokenizer.js index 82149e0..7259dc1 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.js @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Thu Feb 25 21:44:55 2010 */ +/* Generated by re2c 0.13.5 on Mon Dec 20 18:44:30 2010 */ /* * Copyright (C) 2009 Google Inc. All rights reserved. * @@ -45,11 +45,11 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._propertyKeywords = WebInspector.cssNameCompletions.keySet(); this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", - "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", + "alternate", "always","amharic", "amharic-abegede", "antialiased", "appworkspace", "aqua", "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "black", "blink", "block", "block-axis", "blue", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button", "button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator", @@ -62,16 +62,16 @@ WebInspector.SourceCSSTokenizer = function() "ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded", - "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "forwards", "from", "fuchsia", "geometricPrecision", + "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "fuchsia", "geometricPrecision", "georgian", "gray", "graytext", "green", "grey", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help", "hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "lime", "line-through", "linear", "lines", - "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-greek", "lower-hexadecimal", "lower-latin", - "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", + "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek", + "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", + "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", + "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", @@ -88,8 +88,8 @@ WebInspector.SourceCSSTokenizer = function() "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "teal", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede", - "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-greek", - "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", + "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian", + "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext", "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle", "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing", diff --git a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js index f4628d2..1b84b43 100644 --- a/WebCore/inspector/front-end/SourceCSSTokenizer.re2js +++ b/WebCore/inspector/front-end/SourceCSSTokenizer.re2js @@ -44,7 +44,7 @@ WebInspector.SourceCSSTokenizer = function() { WebInspector.SourceTokenizer.call(this); - this._propertyKeywords = WebInspector.CSSCompletions.keySet(); + this._propertyKeywords = WebInspector.cssNameCompletions.keySet(); this._valueKeywords = [ "above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll", @@ -67,10 +67,10 @@ WebInspector.SourceCSSTokenizer = function() "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "lime", "line-through", "linear", "lines", - "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-greek", "lower-hexadecimal", "lower-latin", - "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", + "list-button", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek", + "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "maroon", "match", "media-controls-background", + "media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button", + "media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none", @@ -87,8 +87,8 @@ WebInspector.SourceCSSTokenizer = function() "sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "teal", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede", - "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-greek", - "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", + "tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian", + "upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext", "x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle", "-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing", diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js index 8e077cd..fa8441d 100644 --- a/WebCore/inspector/front-end/SourceFrame.js +++ b/WebCore/inspector/front-end/SourceFrame.js @@ -28,9 +28,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDelegate, continueToHereDelegate) +WebInspector.SourceFrame = function(parentElement, scripts, canEditScripts) { this._parentElement = parentElement; + this._scripts = {}; + for (var i = 0; i < scripts.length; ++i) + this._scripts[scripts[i].sourceID] = scripts[i]; + this._canEditScripts = canEditScripts; this._textModel = new WebInspector.TextEditorModel(); this._textModel.replaceTabsWithSpaces = true; @@ -38,13 +42,8 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, editDe this._messages = []; this._rowMessages = {}; this._messageBubbles = {}; - this.breakpoints = []; this._loaded = false; - - this._continueToHereDelegate = continueToHereDelegate; - this._addBreakpointDelegate = addBreakpointDelegate; - this._editDelegate = editDelegate; this._popoverObjectGroup = "popover"; } @@ -105,23 +104,6 @@ WebInspector.SourceFrame.prototype = { this._lineNumberToReveal = lineNumber; }, - addBreakpoint: function(breakpoint) - { - this.breakpoints.push(breakpoint); - breakpoint.addEventListener("removed", this._breakpointRemoved, this); - if (this._textViewer) - this._addBreakpointToSource(breakpoint); - }, - - _breakpointRemoved: function(event) - { - var breakpoint = event.target; - - this.breakpoints.remove(breakpoint); - if (this._textViewer) - this._removeBreakpointFromSource(breakpoint); - }, - addMessage: function(msg) { // Don't add the message if there is no message or valid line or if the msg isn't an error or warning. @@ -132,6 +114,11 @@ WebInspector.SourceFrame.prototype = { this._addMessageToSource(msg); }, + addScript: function(script) + { + this._scripts[script.sourceID] = script; + }, + clearMessages: function() { for (var line in this._messageBubbles) { @@ -211,14 +198,10 @@ WebInspector.SourceFrame.prototype = { element.addEventListener("scroll", this._scroll.bind(this), true); this._parentElement.appendChild(element); - this._needsProgramCounterImage = true; - this._needsBreakpointImages = true; - this._textViewer.beginUpdates(); this._textViewer.mimeType = this._mimeType; this._addExistingMessagesToSource(); - this._addExistingBreakpointsToSource(); this._updateExecutionLine(); this._updateDiffDecorations(); this._textViewer.resize(); @@ -238,9 +221,16 @@ WebInspector.SourceFrame.prototype = { this.highlightLine(this._lineToHighlight); delete this._lineToHighlight; } + + var breakpoints = this._breakpoints(); + for (var i = 0; i < breakpoints.length; ++i) + this._addBreakpoint(breakpoints[i]); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this); + this._textViewer.endUpdates(); - if (this._editDelegate) - this._textViewer.editCallback = this._editDelegate; + + if (this._canEditScripts) + this._textViewer.editCallback = this._editLine.bind(this); }, findSearchMatches: function(query) @@ -309,24 +299,6 @@ WebInspector.SourceFrame.prototype = { msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount); }, - _breakpointChanged: function(event) - { - var breakpoint = event.target; - var lineNumber = breakpoint.line - 1; - if (lineNumber >= this._textModel.linesCount) - return; - - if (breakpoint.enabled) - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); - else - this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled"); - - if (breakpoint.condition) - this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional"); - else - this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); - }, - _updateExecutionLine: function(previousLine) { if (previousLine) { @@ -395,7 +367,7 @@ WebInspector.SourceFrame.prototype = { } for (var i = 0; i < rowMessages.length; ++i) { - if (rowMessages[i].isEqual(msg, true)) { + if (rowMessages[i].isEqual(msg)) { this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta); return; } @@ -429,41 +401,64 @@ WebInspector.SourceFrame.prototype = { msg._resourceMessageLineElement = messageLineElement; }, - _addExistingBreakpointsToSource: function() + _breakpointAdded: function(event) { - for (var i = 0; i < this.breakpoints.length; ++i) - this._addBreakpointToSource(this.breakpoints[i]); + var breakpoint = event.data; + + if (breakpoint.sourceID in this._scripts) + this._addBreakpoint(breakpoint); }, - _addBreakpointToSource: function(breakpoint) + _addBreakpoint: function(breakpoint) { + if (breakpoint.line > this._textModel.linesCount) + return; + breakpoint.addEventListener("enable-changed", this._breakpointChanged, this); breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); + breakpoint.addEventListener("removed", this._breakpointRemoved, this); - var lineNumber = breakpoint.line - 1; - if (lineNumber >= this._textModel.linesCount) - return; - - this._textModel.setAttribute(lineNumber, "breakpoint", breakpoint); breakpoint.sourceText = this._textModel.line(breakpoint.line - 1); + this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition); + }, + + _breakpointRemoved: function(event) + { + var breakpoint = event.target; + + breakpoint.removeEventListener("enable-changed", null, this); + breakpoint.removeEventListener("condition-changed", null, this); + breakpoint.removeEventListener("removed", null, this); + this._removeBreakpointDecoration(breakpoint.line); + }, + + _breakpointChanged: function(event) + { + var breakpoint = event.target; + this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition); + }, + + _setBreakpointDecoration: function(lineNumber, enabled, hasCondition) + { + lineNumber -= 1; this._textViewer.beginUpdates(); this._textViewer.addDecoration(lineNumber, "webkit-breakpoint"); - if (!breakpoint.enabled) + if (enabled) + this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); + else this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled"); - if (breakpoint.condition) + if (hasCondition) this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional"); + else + this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); this._textViewer.endUpdates(); }, - _removeBreakpointFromSource: function(breakpoint) + _removeBreakpointDecoration: function(lineNumber) { - breakpoint.removeEventListener("enable-changed", null, this); - breakpoint.removeEventListener("condition-changed", null, this); - - var lineNumber = breakpoint.line - 1; + lineNumber -= 1; this._textViewer.beginUpdates(); - this._textModel.removeAttribute(lineNumber, "breakpoint"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled"); this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional"); @@ -472,41 +467,59 @@ WebInspector.SourceFrame.prototype = { _contextMenu: function(event) { - var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); - if (!target) + if (!WebInspector.panels.scripts) return; - var row = target.parentElement; - if (!WebInspector.panels.scripts) + var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); + if (!target) return; + var lineNumber = target.parentElement.lineNumber + 1; - var lineNumber = row.lineNumber; var contextMenu = new WebInspector.ContextMenu(); - contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToHereDelegate.bind(this, lineNumber + 1)); + contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, lineNumber)); - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + var breakpoint = this._findBreakpoint(lineNumber); if (!breakpoint) { // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. - contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._addBreakpointDelegate.bind(this, lineNumber + 1)); + contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, "", true)); function addConditionalBreakpoint() { - this._addBreakpointDelegate(lineNumber + 1); - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); - if (breakpoint) - this._editBreakpointCondition(breakpoint); + this._setBreakpointDecoration(lineNumber, true, true); + function didEditBreakpointCondition(committed, condition) + { + this._removeBreakpointDecoration(lineNumber); + if (committed) + this._setBreakpoint(lineNumber, true, condition); + } + this._editBreakpointCondition(lineNumber, "", didEditBreakpointCondition.bind(this)); } - contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this)); } else { // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint)); - contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), this._editBreakpointCondition.bind(this, breakpoint)); + function editBreakpointCondition() + { + function didEditBreakpointCondition(committed, condition) + { + if (committed) { + breakpoint.remove(); + this._setBreakpoint(breakpoint.line, breakpoint.enabled, condition); + } + } + this._editBreakpointCondition(lineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this)); + } + contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this)); + function setBreakpointEnabled(enabled) + { + breakpoint.remove(); + this._setBreakpoint(breakpoint.line, enabled, breakpoint.condition); + } if (breakpoint.enabled) - contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; }); + contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false)); else - contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; }); + contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), setBreakpointEnabled.bind(this, true)); } contextMenu.show(event); }, @@ -525,18 +538,15 @@ WebInspector.SourceFrame.prototype = { var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number"); if (!target) return; - var row = target.parentElement; - - var lineNumber = row.lineNumber; + var lineNumber = target.parentElement.lineNumber + 1; - var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); + var breakpoint = this._findBreakpoint(lineNumber); if (breakpoint) { + breakpoint.remove(); if (event.shiftKey) - breakpoint.enabled = !breakpoint.enabled; - else - breakpoint.remove(); + this._setBreakpoint(breakpoint.line, !breakpoint.enabled, breakpoint.condition); } else - this._addBreakpointDelegate(lineNumber + 1); + this._setBreakpoint(lineNumber, true, ""); event.preventDefault(); }, @@ -698,38 +708,29 @@ WebInspector.SourceFrame.prototype = { WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, evaluateCallback.bind(this)); }, - _editBreakpointCondition: function(breakpoint) + _editBreakpointCondition: function(lineNumber, condition, callback) { - this._showBreakpointConditionPopup(breakpoint.line); - - function committed(element, newText) - { - breakpoint.condition = newText; - dismissed.call(this); - } + lineNumber -= 1; + this._conditionElement = this._createConditionElement(lineNumber); + this._textViewer.addDecoration(lineNumber, this._conditionElement); - function dismissed() + function finishEditing(committed, element, newText) { - if (this._conditionElement) - this._textViewer.removeDecoration(breakpoint.line - 1, this._conditionElement); + this._textViewer.removeDecoration(lineNumber, this._conditionElement); delete this._conditionEditorElement; delete this._conditionElement; + callback(committed, newText); } - var dismissedHandler = dismissed.bind(this); - this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); - - WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); - this._conditionEditorElement.value = breakpoint.condition; + WebInspector.startEditing(this._conditionEditorElement, { + context: null, + commitHandler: finishEditing.bind(this, true), + cancelHandler: finishEditing.bind(this, false) + }); + this._conditionEditorElement.value = condition; this._conditionEditorElement.select(); }, - _showBreakpointConditionPopup: function(lineNumber) - { - this._conditionElement = this._createConditionElement(lineNumber); - this._textViewer.addDecoration(lineNumber - 1, this._conditionElement); - }, - _createConditionElement: function(lineNumber) { var conditionElement = document.createElement("div"); @@ -773,8 +774,96 @@ WebInspector.SourceFrame.prototype = { { if (this._textViewer) this._textViewer.resize(); + }, + + _continueToLine: function(lineNumber) + { + var sourceID = this._sourceIDForLine(lineNumber); + if (!sourceID) + return; + WebInspector.debuggerModel.continueToLine(sourceID, lineNumber); + }, + + _editLine: function(lineNumber, newContent, cancelEditingCallback) + { + lineNumber += 1; + + var lines = []; + for (var i = 0; i < this._textModel.linesCount; ++i) { + if (i === lineNumber - 1) + lines.push(newContent); + else + lines.push(this._textModel.line(i)); + } + + var editData = {}; + editData.sourceID = this._sourceIDForLine(lineNumber); + editData.content = lines.join("\n"); + editData.line = lineNumber; + editData.linesCountToShift = newContent.split("\n").length - 1; + this._doEditLine(editData, cancelEditingCallback); + }, + + _revertEditLine: function(editData, contentToRevertTo) + { + var newEditData = {}; + newEditData.sourceID = editData.sourceID; + newEditData.content = contentToRevertTo; + newEditData.line = editData.line; + newEditData.linesCountToShift = -editData.linesCountToShift; + this._doEditLine(newEditData); + }, + + _doEditLine: function(editData, cancelEditingCallback) + { + var revertEditingCallback = this._revertEditLine.bind(this, editData); + var commitEditingCallback = this._commitEditLine.bind(this, editData, revertEditingCallback); + WebInspector.panels.scripts.editScriptSource(editData, commitEditingCallback, cancelEditingCallback); + }, + + _commitEditLine: function(editData, revertEditLineCallback, newContent) + { + var script = this._scripts[editData.sourceID]; + script.source = newContent; + if (script.resource) + script.resource.setContent(newContent, revertEditLineCallback); + }, + + _setBreakpoint: function(lineNumber, enabled, condition) + { + var sourceID = this._sourceIDForLine(lineNumber); + if (!sourceID) + return; + WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber, enabled, condition); + if (!WebInspector.panels.scripts.breakpointsActivated) + WebInspector.panels.scripts.toggleBreakpointsClicked(); + }, + + _breakpoints: function() + { + var scripts = this._scripts; + return WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID in scripts; }); + }, + + _findBreakpoint: function(lineNumber) + { + var sourceID = this._sourceIDForLine(lineNumber); + return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber); + }, + + _sourceIDForLine: function(lineNumber) + { + var sourceIDForLine = null; + var closestStartingLine = 0; + for (var sourceID in this._scripts) { + var script = this._scripts[sourceID]; + if (script.startingLine <= lineNumber && script.startingLine >= closestStartingLine) { + closestStartingLine = script.startingLine; + sourceIDForLine = sourceID; + } + } + return sourceIDForLine; } } - WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js index 9616321..7a97db2 100644 --- a/WebCore/inspector/front-end/SourceView.js +++ b/WebCore/inspector/front-end/SourceView.js @@ -32,8 +32,9 @@ WebInspector.SourceView = function(resource) this.element.addStyleClass("source"); - var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script; - this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this)); + var scripts = WebInspector.debuggerModel.scriptsForURL(resource.url); + var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script; + this.sourceFrame = new WebInspector.SourceFrame(this.element, scripts, canEditScripts); resource.addEventListener("finished", this._resourceLoadingFinished, this); this._frameNeedsSetup = true; } @@ -100,9 +101,6 @@ WebInspector.SourceView.prototype = { var mimeType = this._canonicalMimeType(this.resource); this.sourceFrame.setContent(mimeType, content, this.resource.url); this._sourceFrameSetupFinished(); - var breakpoints = WebInspector.breakpointManager.breakpointsForURL(this.resource.url); - for (var i = 0; i < breakpoints.length; ++i) - this.sourceFrame.addBreakpoint(breakpoints[i]); }, _canonicalMimeType: function(resource) @@ -119,73 +117,6 @@ WebInspector.SourceView.prototype = { this.resource.removeEventListener("finished", this._resourceLoadingFinished, this); }, - _continueToLine: function(line) - { - var scriptsPanel = WebInspector.panels.scripts; - if (scriptsPanel) { - var sourceID = this._sourceIDForLine(line); - scriptsPanel.continueToLine(sourceID, line); - } - }, - - _addBreakpoint: function(line) - { - var sourceID = this._sourceIDForLine(line); - WebInspector.breakpointManager.setBreakpoint(sourceID, this.resource.url, line, true, ""); - if (!WebInspector.panels.scripts.breakpointsActivated) - WebInspector.panels.scripts.toggleBreakpointsClicked(); - }, - - _editLine: function(line, newContent, cancelEditingCallback) - { - var lines = []; - var textModel = this.sourceFrame.textModel; - for (var i = 0; i < textModel.linesCount; ++i) { - if (i === line) - lines.push(newContent); - else - lines.push(textModel.line(i)); - } - - var editData = {}; - editData.sourceID = this._sourceIDForLine(line); - editData.content = lines.join("\n"); - editData.line = line; - editData.linesCountToShift = newContent.split("\n").length - 1; - - WebInspector.panels.scripts.editScriptSource(editData, this._editLineComplete.bind(this, editData), cancelEditingCallback); - }, - - _editLineComplete: function(editData, newContent) - { - this.resource.setContent(newContent, this._revertEditLine.bind(this, editData)); - }, - - _revertEditLine: function(editData, contentToRevertTo) - { - var newEditData = {}; - newEditData.sourceID = editData.sourceID; - newEditData.content = editData.content; - newEditData.line = editData.line; - newEditData.linesCountToShift = -editData.linesCountToShift; - WebInspector.panels.scripts.editScriptSource(newEditData, this._editLineComplete.bind(this, newEditData)); - }, - - _sourceIDForLine: function(line) - { - var sourceID = null; - var closestStartingLine = 0; - var scripts = this.resource.scripts; - for (var i = 0; i < scripts.length; ++i) { - var script = scripts[i]; - if (script.startingLine <= line && script.startingLine >= closestStartingLine) { - closestStartingLine = script.startingLine; - sourceID = script.sourceID; - } - } - return sourceID; - }, - // The rest of the methods in this prototype need to be generic enough to work with a ScriptView. // The ScriptView prototype pulls these methods into it's prototype to avoid duplicate code. diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js index 5399953..c89e452 100644 --- a/WebCore/inspector/front-end/StylesSidebarPane.js +++ b/WebCore/inspector/front-end/StylesSidebarPane.js @@ -704,6 +704,26 @@ WebInspector.StylePropertiesSection.prototype = { return true; }, + nextEditableSibling: function() + { + var curSection = this; + do { + curSection = curSection.nextSibling; + } while (curSection && !curSection.editable); + + return curSection; + }, + + previousEditableSibling: function() + { + var curSection = this; + do { + curSection = curSection.previousSibling; + } while (curSection && !curSection.editable); + + return curSection; + }, + update: function(full) { if (full) { @@ -795,6 +815,7 @@ WebInspector.StylePropertiesSection.prototype = { this.propertiesTreeOutline.appendChild(item); item.listItemElement.textContent = ""; item._newProperty = true; + item.updateTitle(); return item; }, @@ -875,22 +896,35 @@ WebInspector.StylePropertiesSection.prototype = { if (WebInspector.isBeingEdited(element)) return; - WebInspector.startEditing(this._selectorElement, this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), null); + WebInspector.startEditing(this._selectorElement, { + context: null, + commitHandler: this.editingSelectorCommitted.bind(this), + cancelHandler: this.editingSelectorCancelled.bind(this) + }); window.getSelection().setBaseAndExtent(element, 0, element, 1); }, editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection) { function moveToNextIfNeeded() { - if (!moveDirection || moveDirection !== "forward") + if (!moveDirection) return; - this.expand(); - if (this.propertiesTreeOutline.children.length === 0) - this.addNewBlankProperty().startEditing(); - else { - var item = this.propertiesTreeOutline.children[0] - item.startEditing(item.valueElement); + if (moveDirection === "forward") { + this.expand(); + if (this.propertiesTreeOutline.children.length === 0) + this.addNewBlankProperty().startEditing(); + else { + var item = this.propertiesTreeOutline.children[0] + item.startEditing(item.nameElement); + } + } else { + var previousSection = this.previousEditableSibling(); + if (!previousSection) + return; + + previousSection.expand(); + previousSection.addNewBlankProperty().startEditing(); } } @@ -1202,8 +1236,6 @@ WebInspector.StylePropertyTreeElement.prototype = { this.valueElement = valueElement; if (value) { - var self = this; - function processValue(regex, processor, nextProcessor, valueText) { var container = document.createDocumentFragment(); @@ -1227,19 +1259,10 @@ WebInspector.StylePropertyTreeElement.prototype = { function linkifyURL(url) { - var hrefUrl = url; - var match = hrefUrl.match(/['"]?([^'"]+)/); - if (match) - hrefUrl = match[1]; var container = document.createDocumentFragment(); container.appendChild(document.createTextNode("url(")); - if (self._styleRule.sourceURL) - hrefUrl = WebInspector.completeURL(self._styleRule.sourceURL, hrefUrl); - else if (WebInspector.panels.elements.focusedDOMNode) - hrefUrl = WebInspector.resourceURLForRelatedNode(WebInspector.panels.elements.focusedDOMNode, hrefUrl); - var hasResource = !!WebInspector.resourceForURL(hrefUrl); - // FIXME: WebInspector.linkifyURLAsNode() should really use baseURI. - container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl, url, null, hasResource)); + var hasResource = !!WebInspector.resourceForURL(url); + container.appendChild(WebInspector.linkifyURLAsNode(url, url, null, hasResource)); container.appendChild(document.createTextNode(")")); return container; } @@ -1341,7 +1364,7 @@ WebInspector.StylePropertyTreeElement.prototype = { var colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g; var colorProcessor = processValue.bind(window, colorRegex, processColor, null); - valueElement.appendChild(processValue(/url\(\s*([^)\s]+)\s*\)/g, linkifyURL, colorProcessor, value)); + valueElement.appendChild(processValue(/url\(([^)]+)\)/g, linkifyURL, colorProcessor, value)); } this.listItemElement.removeChildren(); @@ -1357,8 +1380,11 @@ WebInspector.StylePropertyTreeElement.prototype = { this.listItemElement.appendChild(valueElement); this.listItemElement.appendChild(document.createTextNode(";")); - if (!this.parsedOk) + if (!this.parsedOk) { + // Avoid having longhands under an invalid shorthand. + this.hasChildren = false; this.listItemElement.addStyleClass("not-parsed-ok"); + } if (this.property.inactive) this.listItemElement.addStyleClass("inactive"); @@ -1471,60 +1497,147 @@ WebInspector.StylePropertyTreeElement.prototype = { if (this.parent.shorthand) return; - if (WebInspector.isBeingEdited(this.listItemElement) || (this.treeOutline.section && !this.treeOutline.section.editable)) + if (this.treeOutline.section && !this.treeOutline.section.editable) + return; + + if (!selectElement) + selectElement = this.nameElement; // No arguments passed in - edit the name element by default. + else + selectElement = selectElement.enclosingNodeOrSelfWithClass("webkit-css-property") || selectElement.enclosingNodeOrSelfWithClass("value"); + + var isEditingName = selectElement === this.nameElement; + if (!isEditingName && selectElement !== this.valueElement) { + // Double-click in the LI - start editing value. + isEditingName = false; + selectElement = this.valueElement; + } + + if (WebInspector.isBeingEdited(selectElement)) return; var context = { expanded: this.expanded, hasChildren: this.hasChildren, - keyDownListener: this.editingKeyDown.bind(this), - keyPressListener: this.editingKeyPress.bind(this) + keyDownListener: isEditingName ? this.editingNameKeyDown.bind(this) : this.editingValueKeyDown.bind(this), + keyPressListener: isEditingName ? this.editingNameKeyPress.bind(this) : this.editingValueKeyPress.bind(this), + isEditingName: isEditingName, }; // Lie about our children to prevent expanding on double click and to collapse shorthands. this.hasChildren = false; - if (!selectElement) - selectElement = this.listItemElement; + selectElement.addEventListener("keydown", context.keyDownListener, false); + selectElement.addEventListener("keypress", context.keyPressListener, false); + if (selectElement.parentElement) + selectElement.parentElement.addStyleClass("child-editing"); + selectElement.textContent = selectElement.textContent; // remove color swatch and the like + + function shouldCommitValueSemicolon(text, cursorPosition) + { + // FIXME: should this account for semicolons inside comments? + var openQuote = ""; + for (var i = 0; i < cursorPosition; ++i) { + var ch = text[i]; + if (ch === "\\" && openQuote !== "") + ++i; // skip next character inside string + else if (!openQuote && (ch === "\"" || ch === "'")) + openQuote = ch; + else if (openQuote === ch) + openQuote = ""; + } + return !openQuote; + } - this.listItemElement.addEventListener("keydown", context.keyDownListener, false); - this.listItemElement.addEventListener("keypress", context.keyPressListener, false); + function nameValueFinishHandler(context, isEditingName, event) + { + // FIXME: the ":"/";" detection does not work for non-US layouts due to the event being keydown rather than keypress. + var isFieldInputTerminated = (event.keyCode === WebInspector.KeyboardShortcut.Keys.Semicolon.code) && + (isEditingName ? event.shiftKey : (!event.shiftKey && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset))); + if (isEnterKey(event) || isFieldInputTerminated) { + // Enter or colon (for name)/semicolon outside of string (for value). + event.preventDefault(); + return "move-forward"; + } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) + return "cancel"; + else if (event.keyIdentifier === "U+0009") // Tab key. + return "move-" + (event.shiftKey ? "backward" : "forward"); + } - WebInspector.startEditing(this.listItemElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(selectElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this), + customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName) + }); window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1); }, - editingKeyPress: function(event) + editingNameKeyPress: function(event) { - var selection = window.getSelection(); - var colonIndex = this.listItemElement.textContent.indexOf(":"); - var selectionLeftOffset = event.target.selectionLeftOffset; - - if (colonIndex < 0 || selectionLeftOffset <= colonIndex) { - // Complete property names. - var character = event.data.toLowerCase(); - if (character && /[a-z-]/.test(character)) { - var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset); - var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character); - - if (!selection.isCollapsed) - selection.deleteFromDocument(); - - this.restoreNameElement(); - - if (property) { - if (property !== this.nameElement.textContent) - this.nameElement.textContent = property; - this.nameElement.firstChild.select(prefix.length + 1); - event.preventDefault(); - } + // Complete property names. + var character = event.data.toLowerCase(); + if (character && /[a-z-]/.test(character)) { + var selection = window.getSelection(); + var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset); + var property = WebInspector.cssNameCompletions.firstStartsWith(prefix + character); + + if (!selection.isCollapsed) + selection.deleteFromDocument(); + + this.restoreNameElement(); + + if (property) { + if (property !== this.nameElement.textContent) + this.nameElement.textContent = property; + this.nameElement.firstChild.select(prefix.length + 1); + event.preventDefault(); } - } else { - // FIXME: This should complete property values. } }, - editingKeyDown: function(event) + editingValueKeyPress: function(event) + { + // FIXME: This should complete property values. + }, + + editingNameKeyDown: function(event) + { + var showNext; + if (event.keyIdentifier === "Up") + showNext = false; + else if (event.keyIdentifier === "Down") + showNext = true; + else + return; + + var selection = window.getSelection(); + if (!selection.rangeCount) + return; + + var selectionRange = selection.getRangeAt(0); + if (selectionRange.commonAncestorContainer !== this.nameElement && !selectionRange.commonAncestorContainer.isDescendant(this.nameElement)) + return; + + const styleValueDelimeters = " \t\n\"':;,/()"; + var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.nameElement); + var wordString = wordRange.toString(); + var cursorPosition = selectionRange.startOffset != selectionRange.endOffset ? selectionRange.startOffset : 0; + var prefix = selectionRange.startContainer.textContent.substring(0, cursorPosition); + var property; + + if (showNext) + property = WebInspector.cssNameCompletions.next(wordString, prefix); + else + property = WebInspector.cssNameCompletions.previous(wordString, prefix); + + if (property) { + this.nameElement.textContent = property; + this.nameElement.firstChild.select(cursorPosition); + } + event.preventDefault(); + }, + + editingValueKeyDown: function(event) { var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down"); var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown"); @@ -1536,33 +1649,11 @@ WebInspector.StylePropertyTreeElement.prototype = { return; var selectionRange = selection.getRangeAt(0); - if (selectionRange.commonAncestorContainer !== this.listItemElement && !selectionRange.commonAncestorContainer.isDescendant(this.listItemElement)) + if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement)) return; - // If there are several properties in the text, do not handle increments/decrements. - var text = event.target.textContent.trim(); - var openQuote; - var wasEscape = false; - // Exclude the last character from the check since it is allowed to be ";". - for (var i = 0; i < text.length - 1; ++i) { - var ch = text.charAt(i); - if (ch === "\\") { - wasEscape = true; - continue; - } - if (ch === ";" && !openQuote) - return; // Do not handle name/value shifts if the property is compound. - if ((ch === "'" || ch === "\"") && !wasEscape) { - if (!openQuote) - openQuote = ch; - else if (ch === openQuote) - openQuote = null; - } - wasEscape = false; - } - const styleValueDelimeters = " \t\n\"':;,/()"; - var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.listItemElement); + var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.valueElement); var wordString = wordRange.toString(); var replacementString = wordString; @@ -1604,22 +1695,6 @@ WebInspector.StylePropertyTreeElement.prototype = { } replacementString = prefix + number + suffix; - } else if (selection.containsNode(this.nameElement, true)) { - var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset); - var property; - - if (event.keyIdentifier === "Up") - property = WebInspector.CSSCompletions.previous(wordString, prefix); - else if (event.keyIdentifier === "Down") - property = WebInspector.CSSCompletions.next(wordString, prefix); - - var startOffset = selectionRange.startOffset; - if (property) { - this.nameElement.textContent = property; - this.nameElement.firstChild.select(startOffset); - } - event.preventDefault(); - return; } else { // FIXME: this should cycle through known keywords for the current property value. } @@ -1643,7 +1718,9 @@ WebInspector.StylePropertyTreeElement.prototype = { // if the editing is canceled and before each apply. this.originalPropertyText = this.property.propertyText; } - this.applyStyleText(this.listItemElement.textContent); + + // Synthesize property text disregarding any comments, custom whitespace etc. + this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent); }, editingEnded: function(context) @@ -1651,8 +1728,12 @@ WebInspector.StylePropertyTreeElement.prototype = { this.hasChildren = context.hasChildren; if (context.expanded) this.expand(); - this.listItemElement.removeEventListener("keydown", context.keyDownListener, false); - this.listItemElement.removeEventListener("keypress", context.keyPressListener, false); + var editedElement = context.isEditingName ? this.nameElement : this.valueElement; + editedElement.removeEventListener("keydown", context.keyDownListener, false); + editedElement.removeEventListener("keypress", context.keyPressListener, false); + if (editedElement.parentElement) + editedElement.parentElement.removeStyleClass("child-editing"); + delete this.originalPropertyText; }, @@ -1672,61 +1753,96 @@ WebInspector.StylePropertyTreeElement.prototype = { editingCommitted: function(element, userInput, previousContent, context, moveDirection) { this.editingEnded(context); + var isEditingName = context.isEditingName; // Determine where to move to before making changes - var newProperty, moveToPropertyName, moveToSelector; + var createNewProperty, moveToPropertyName, moveToSelector; var moveTo = this; - do { - moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling); - } while(moveTo && !moveTo.selectable); - - if (moveTo) - moveToPropertyName = moveTo.name; - else if (moveDirection === "forward") - newProperty = true; - else if (moveDirection === "backward" && this.treeOutline.section.rule) - moveToSelector = true; + var moveToOther = (isEditingName ^ (moveDirection === "forward")); + var abandonNewProperty = this._newProperty && !userInput && (moveToOther || isEditingName); + if (moveDirection === "forward" && !isEditingName || moveDirection === "backward" && isEditingName) { + do { + moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling); + } while(moveTo && !moveTo.selectable); + + if (moveTo) + moveToPropertyName = moveTo.name; + else if (moveDirection === "forward" && (!this._newProperty || userInput)) + createNewProperty = true; + else if (moveDirection === "backward" && this.treeOutline.section.rule) + moveToSelector = true; + } - // Make the Changes and trigger the moveToNextCallback after updating + // Make the Changes and trigger the moveToNextCallback after updating. var blankInput = /^\s*$/.test(userInput); - if (userInput !== previousContent || (this._newProperty && blankInput)) { // only if something changed, or adding a new style and it was blank - this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput); - this.applyStyleText(userInput, true); - } else - moveToNextCallback(this._newProperty, false, this.treeOutline.section, false); + var shouldCommitNewProperty = this._newProperty && (moveToOther || (!moveDirection && !isEditingName) || (isEditingName && blankInput)); - // The Callback to start editing the next property + if ((userInput !== previousContent && !this._newProperty) || shouldCommitNewProperty) { + this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput, this.treeOutline.section); + var propertyText; + if (blankInput || (this._newProperty && /^\s*$/.test(this.valueElement.textContent))) + propertyText = ""; + else { + if (isEditingName) + propertyText = userInput + ": " + this.valueElement.textContent; + else + propertyText = this.nameElement.textContent + ": " + userInput; + } + this.applyStyleText(propertyText, true); + } else { + if (!this._newProperty) + this.updateTitle(); + moveToNextCallback(this._newProperty, false, this.treeOutline.section); + } + + var moveToIndex = moveTo && this.treeOutline ? this.treeOutline.children.indexOf(moveTo) : -1; + + // The Callback to start editing the next/previous property/selector. function moveToNextCallback(alreadyNew, valueChanged, section) { if (!moveDirection) return; - // User just tabbed through without changes + // User just tabbed through without changes. if (moveTo && moveTo.parent) { - moveTo.startEditing(moveTo.valueElement); + moveTo.startEditing(!isEditingName ? moveTo.nameElement : moveTo.valueElement); return; } - // User has made a change then tabbed, wiping all the original treeElements, - // recalculate the new treeElement for the same property we were going to edit next - // FIXME(apavlov): this will not work for multiple same-named properties in a style - // (the first one will always be returned). + // User has made a change then tabbed, wiping all the original treeElements. + // Recalculate the new treeElement for the same property we were going to edit next. if (moveTo && !moveTo.parent) { - var treeElement = section.findTreeElementWithName(moveToPropertyName); - if (treeElement) - treeElement.startEditing(treeElement.valueElement); - return; + var propertyElements = section.propertiesTreeOutline.children; + if (moveDirection === "forward" && blankInput && !isEditingName) + --moveToIndex; + if (moveToIndex >= propertyElements.length && !this._newProperty) + createNewProperty = true; + else { + var treeElement = moveToIndex >= 0 ? propertyElements[moveToIndex] : null; + if (treeElement) { + treeElement.startEditing(!isEditingName ? treeElement.nameElement : treeElement.valueElement); + return; + } else if (!alreadyNew) + moveToSelector = true; + } } - // Create a new attribute in this section - if (newProperty) { - if (alreadyNew && !valueChanged) + // Create a new attribute in this section (or move to next editable selector if possible). + if (createNewProperty) { + if (alreadyNew && !valueChanged && (isEditingName ^ (moveDirection === "backward"))) return; section.addNewBlankProperty().startEditing(); return; } + if (abandonNewProperty) { + var sectionToEdit = moveDirection === "backward" ? section : section.nextEditableSibling(); + if (sectionToEdit && sectionToEdit.rule) + sectionToEdit.startEditingSelector(); + return; + } + if (moveToSelector) section.startEditingSelector(); } @@ -1736,16 +1852,13 @@ WebInspector.StylePropertyTreeElement.prototype = { { var section = this.treeOutline.section; var elementsPanel = WebInspector.panels.elements; - styleText = styleText.replace(/\s/g, " ").trim(); // replace with whitespace. + styleText = styleText.replace(/\s/g, " ").trim(); // Replace with whitespace. var styleTextLength = styleText.length; - if (!styleTextLength && updateInterface) { - if (this._newProperty) { - // The user deleted everything, so remove the tree element and update. - this.parent.removeChild(this); - section.afterUpdate(); - return; - } else - delete section._afterUpdate; + if (!styleTextLength && updateInterface && this._newProperty) { + // The user deleted everything, so remove the tree element and update. + this.parent.removeChild(this); + section.afterUpdate(); + return; } function callback(newStyle) diff --git a/WebCore/inspector/front-end/TextPrompt.js b/WebCore/inspector/front-end/TextPrompt.js index e9a73fe..21a5bde 100644 --- a/WebCore/inspector/front-end/TextPrompt.js +++ b/WebCore/inspector/front-end/TextPrompt.js @@ -419,7 +419,7 @@ WebInspector.TextPrompt.prototype = { ++this.historyOffset; this.text = this.history[this.history.length - this.historyOffset]; - this.element.scrollIntoViewIfNeeded(); + this.element.scrollIntoView(true); var firstNewlineIndex = this.text.indexOf("\n"); if (firstNewlineIndex === -1) this.moveCaretToEndOfPrompt(); @@ -451,6 +451,6 @@ WebInspector.TextPrompt.prototype = { } this.text = this.history[this.history.length - this.historyOffset]; - this.element.scrollIntoViewIfNeeded(); + this.element.scrollIntoView(); } } diff --git a/WebCore/inspector/front-end/TextViewer.js b/WebCore/inspector/front-end/TextViewer.js index 9ad5e49..f116dea 100644 --- a/WebCore/inspector/front-end/TextViewer.js +++ b/WebCore/inspector/front-end/TextViewer.js @@ -268,7 +268,12 @@ WebInspector.TextViewer.prototype = { var oldContent = lineRow.lastChild.innerHTML; var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent); var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback); - this._editingLine = WebInspector.startEditing(lineRow.lastChild, commitEditingCallback, cancelEditingCallback, null, true); + this._editingLine = WebInspector.startEditing(lineRow.lastChild, { + context: null, + commitHandler: commitEditingCallback, + cancelHandler: cancelEditingCallback, + multiline: true + }); }, _commitEditingLine: function(lineNumber, element, cancelEditingCallback) diff --git a/WebCore/inspector/front-end/TimelineAgent.js b/WebCore/inspector/front-end/TimelineAgent.js index d44c2d0..97b8e42 100644 --- a/WebCore/inspector/front-end/TimelineAgent.js +++ b/WebCore/inspector/front-end/TimelineAgent.js @@ -56,18 +56,3 @@ WebInspector.TimelineAgent.RecordType = { MarkLoadEventType : 19, ScheduleResourceRequest : 20 }; - -WebInspector.addRecordToTimeline = function(record) { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.addRecordToTimeline(record); -} - -WebInspector.timelineProfilerWasStarted = function() { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.timelineWasStarted(); -} - -WebInspector.timelineProfilerWasStopped = function() { - if (WebInspector.panels.timeline) - WebInspector.panels.timeline.timelineWasStopped(); -} diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js index 8900d8d..a661b75 100644 --- a/WebCore/inspector/front-end/TimelinePanel.js +++ b/WebCore/inspector/front-end/TimelinePanel.js @@ -98,6 +98,8 @@ WebInspector.TimelinePanel = function() this._calculator._showShortEvents = this.toggleFilterButton.toggled; this._markTimelineRecords = []; this._expandOffset = 15; + + InspectorBackend.registerDomainDispatcher("Timeline", this); } // Define row height, should be in sync with styles for timeline graphs. @@ -283,12 +285,12 @@ WebInspector.TimelinePanel.prototype = { this._scheduleRefresh(true); }, - timelineWasStarted: function() + timelineProfilerWasStarted: function() { this.toggleTimelineButton.toggled = true; }, - timelineWasStopped: function() + timelineProfilerWasStopped: function() { this.toggleTimelineButton.toggled = false; }, @@ -961,7 +963,7 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = { contentHelper._appendLinkRow(WebInspector.UIString("Script"), this.data.url, this.data.lineNumber); break; case recordTypes.Paint: - contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("%d × %d", this.data.x, this.data.y)); + contentHelper._appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data.x, this.data.y)); contentHelper._appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", this.data.width, this.data.height)); case recordTypes.RecalculateStyles: // We don't want to see default details. break; diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js index 44063a3..a01046b 100644 --- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js +++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js @@ -240,7 +240,11 @@ WebInspector.WatchExpressionTreeElement.prototype = { this.listItemElement.addStyleClass("editing-sub-part"); - WebInspector.startEditing(this.nameElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context); + WebInspector.startEditing(this.nameElement, { + context: context, + commitHandler: this.editingCommitted.bind(this), + cancelHandler: this.editingCancelled.bind(this) + }); }, editingCancelled: function(element, context) diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc index 2db0182..90c4317 100644 --- a/WebCore/inspector/front-end/WebKit.qrc +++ b/WebCore/inspector/front-end/WebKit.qrc @@ -9,9 +9,9 @@ <file>AuditRules.js</file> <file>AuditsPanel.js</file> <file>BottomUpProfileDataGridTree.js</file> + <file>Breakpoint.js</file> <file>BreakpointManager.js</file> <file>BreakpointsSidebarPane.js</file> - <file>Callback.js</file> <file>CallStackSidebarPane.js</file> <file>ChangesView.js</file> <file>Checkbox.js</file> @@ -28,6 +28,7 @@ <file>DatabaseQueryView.js</file> <file>DatabaseTableView.js</file> <file>DataGrid.js</file> + <file>DebuggerModel.js</file> <file>DOMAgent.js</file> <file>DOMStorage.js</file> <file>DOMStorageItemsView.js</file> diff --git a/WebCore/inspector/front-end/WorkersSidebarPane.js b/WebCore/inspector/front-end/WorkersSidebarPane.js index 658d57c..b254f3c 100644 --- a/WebCore/inspector/front-end/WorkersSidebarPane.js +++ b/WebCore/inspector/front-end/WorkersSidebarPane.js @@ -100,15 +100,3 @@ WebInspector.Worker = function(id, url, shared) this.url = url; this.shared = shared; } - -WebInspector.didCreateWorker = function() -{ - var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; - workersPane.addWorker.apply(workersPane, arguments); -} - -WebInspector.didDestroyWorker = function() -{ - var workersPane = WebInspector.panels.scripts.sidebarPanes.workers; - workersPane.removeWorker.apply(workersPane, arguments); -} diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css index 965689b..c908427 100644 --- a/WebCore/inspector/front-end/inspector.css +++ b/WebCore/inspector/front-end/inspector.css @@ -1424,6 +1424,12 @@ body.inactive .placard.selected { text-decoration: none !important; } +.child-editing { + color: black !important; + text-decoration: none !important; + overflow: visible !important; +} + .editing br { display: none; } diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html index 67fd081..9ed5019 100644 --- a/WebCore/inspector/front-end/inspector.html +++ b/WebCore/inspector/front-end/inspector.html @@ -55,7 +55,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="TabbedPane.js"></script> <script type="text/javascript" src="Placard.js"></script> <script type="text/javascript" src="View.js"></script> - <script type="text/javascript" src="Callback.js"></script> <script type="text/javascript" src="Drawer.js"></script> <script type="text/javascript" src="ChangesView.js"></script> <script type="text/javascript" src="ConsoleView.js"></script> @@ -73,6 +72,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="ApplicationCacheItemsView.js"></script> <script type="text/javascript" src="FileSystemView.js"></script> <script type="text/javascript" src="Script.js"></script> + <script type="text/javascript" src="Breakpoint.js"></script> <script type="text/javascript" src="BreakpointManager.js"></script> <script type="text/javascript" src="SidebarPane.js"></script> <script type="text/javascript" src="ElementsTreeOutline.js"></script> @@ -139,6 +139,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <script type="text/javascript" src="TopDownProfileDataGridTree.js"></script> <script type="text/javascript" src="ProfileView.js"></script> <script type="text/javascript" src="HeapSnapshotView.js"></script> + <script type="text/javascript" src="DebuggerModel.js"></script> <script type="text/javascript" src="DOMAgent.js"></script> <script type="text/javascript" src="InjectedScript.js"></script> <script type="text/javascript" src="InjectedScriptAccess.js"></script> diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js index 212f41a..a57f0f4 100644 --- a/WebCore/inspector/front-end/inspector.js +++ b/WebCore/inspector/front-end/inspector.js @@ -192,7 +192,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("breakpoint-added", breakpointAdded); + WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpointAdded); return pane; }, @@ -203,7 +203,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("dom-breakpoint-added", breakpointAdded); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.DOMBreakpointAdded, breakpointAdded); return pane; }, @@ -214,7 +214,7 @@ var WebInspector = { { pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data)); } - WebInspector.breakpointManager.addEventListener("xhr-breakpoint-added", breakpointAdded); + WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.XHRBreakpointAdded, breakpointAdded); return pane; }, @@ -478,7 +478,7 @@ 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.onmessage = function(message) { InspectorBackend.dispatch(message.data); } WebInspector.socket.onerror = function(error) { console.error(error); } WebInspector.socket.onopen = function() { InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket); @@ -520,6 +520,8 @@ WebInspector.doLoadedDone = function() this.resourceManager = new WebInspector.ResourceManager(); this.domAgent = new WebInspector.DOMAgent(); + InspectorBackend.registerDomainDispatcher("Inspector", this); + this.resourceCategories = { documents: new WebInspector.ResourceCategory("documents", WebInspector.UIString("Documents"), "rgb(47,102,236)"), stylesheets: new WebInspector.ResourceCategory("stylesheets", WebInspector.UIString("Stylesheets"), "rgb(157,231,119)"), @@ -531,8 +533,10 @@ WebInspector.doLoadedDone = function() other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)") }; - this.breakpointManager = new WebInspector.BreakpointManager(); this.cssModel = new WebInspector.CSSStyleModel(); + this.debuggerModel = new WebInspector.DebuggerModel(); + + this.breakpointManager = new WebInspector.BreakpointManager(); this.panels = {}; this._createPanels(); @@ -609,8 +613,13 @@ WebInspector.doLoadedDone = function() InspectorBackend.setConsoleMessagesEnabled(true); + function propertyNamesCallback(names) + { + WebInspector.cssNameCompletions = new WebInspector.CSSCompletions(names); + } + // As a DOMAgent method, this needs to happen after the frontend has loaded and the agent is available. - InspectorBackend.getSupportedCSSProperties(WebInspector.CSSCompletions._load); + InspectorBackend.getSupportedCSSProperties(propertyNamesCallback); } WebInspector.addPanelToolbarIcon = function(toolbarElement, panel, previousToolbarItem) @@ -648,58 +657,18 @@ WebInspector.dispatch = function(message) { // This is important to LayoutTests. function delayDispatch() { - WebInspector_syncDispatch(message); + InspectorBackend.dispatch(message); WebInspector.pendingDispatches--; } WebInspector.pendingDispatches++; setTimeout(delayDispatch, 0); } -// This function is purposely put into the global scope for easy access. -WebInspector_syncDispatch = function(message) -{ - if (window.dumpInspectorProtocolMessages) - console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message))); - - var messageObject = (typeof message === "string") ? JSON.parse(message) : message; - - var arguments = []; - if (messageObject.data) - for (var key in messageObject.data) - arguments.push(messageObject.data[key]); - - if ("seq" in messageObject) { // just a response for some request - if (messageObject.success) - WebInspector.processResponse(messageObject.seq, arguments); - else { - WebInspector.removeResponseCallbackEntry(messageObject.seq) - WebInspector.reportProtocolError(messageObject); - } - return; - } - - if (messageObject.type === "event") { - if (!(messageObject.event in WebInspector)) { - console.error("Protocol Error: Attempted to dispatch an unimplemented WebInspector method '%s'", messageObject.event); - return; - } - WebInspector[messageObject.event].apply(WebInspector, arguments); - } -} - WebInspector.dispatchMessageFromBackend = function(messageObject) { WebInspector.dispatch(messageObject); } -WebInspector.reportProtocolError = function(messageObject) -{ - console.error("Protocol Error: InspectorBackend request with seq = %d failed.", messageObject.seq); - for (var i = 0; i < messageObject.errors.length; ++i) - console.error(" " + messageObject.errors[i]); - WebInspector.removeResponseCallbackEntry(messageObject.seq); -} - WebInspector.windowResize = function(event) { if (this.currentPanel) @@ -1205,23 +1174,11 @@ WebInspector.showPanel = function(panel) this.currentPanel = this.panels[panel]; } -WebInspector.selectDatabase = function(o) -{ - WebInspector.showPanel("resources"); - WebInspector.panels.resources.selectDatabase(o); -} - WebInspector.consoleMessagesCleared = function() { WebInspector.console.clearMessages(); } -WebInspector.selectDOMStorage = function(o) -{ - WebInspector.showPanel("resources"); - WebInspector.panels.resources.selectDOMStorage(o); -} - WebInspector.domContentEventFired = function(time) { this.panels.audits.mainResourceDOMContentTime = time; @@ -1240,59 +1197,6 @@ WebInspector.loadEventFired = function(time) this.mainResourceLoadTime = time; } -WebInspector.addDatabase = function(payload) -{ - if (!this.panels.resources) - return; - var database = new WebInspector.Database( - payload.id, - payload.domain, - payload.name, - payload.version); - this.panels.resources.addDatabase(database); -} - -WebInspector.addDOMStorage = function(payload) -{ - if (!this.panels.resources) - return; - var domStorage = new WebInspector.DOMStorage( - payload.id, - payload.host, - payload.isLocalStorage); - this.panels.resources.addDOMStorage(domStorage); -} - -WebInspector.updateDOMStorage = function(storageId) -{ - this.panels.resources.updateDOMStorage(storageId); -} - -WebInspector.updateApplicationCacheStatus = function(status) -{ - this.panels.resources.updateApplicationCacheStatus(status); -} - -WebInspector.didGetFileSystemPath = function(root, type, origin) -{ - this.panels.resources.updateFileSystemPath(root, type, origin); -} - -WebInspector.didGetFileSystemError = function(type, origin) -{ - this.panels.resources.updateFileSystemError(type, origin); -} - -WebInspector.didGetFileSystemDisabled = function() -{ - this.panels.resources.setFileSystemDisabled(); -} - -WebInspector.updateNetworkState = function(isNowOnline) -{ - this.panels.resources.updateNetworkState(isNowOnline); -} - WebInspector.searchingForNodeWasEnabled = function() { this.panels.elements.searchingForNodeWasEnabled(); @@ -1303,62 +1207,9 @@ WebInspector.searchingForNodeWasDisabled = function() this.panels.elements.searchingForNodeWasDisabled(); } -WebInspector.attachDebuggerWhenShown = function() -{ - this.panels.scripts.attachDebuggerWhenShown(); -} - -WebInspector.debuggerWasEnabled = function() -{ - this.panels.scripts.debuggerWasEnabled(); -} - -WebInspector.debuggerWasDisabled = function() -{ - this.panels.scripts.debuggerWasDisabled(); -} - -WebInspector.profilerWasEnabled = function() -{ - this.panels.profiles.profilerWasEnabled(); -} - -WebInspector.profilerWasDisabled = function() -{ - this.panels.profiles.profilerWasDisabled(); -} - -WebInspector.parsedScriptSource = function(sourceID, sourceURL, source, startingLine, scriptWorldType) -{ - this.panels.scripts.addScript(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType); -} - -WebInspector.restoredBreakpoint = function(sourceID, sourceURL, line, enabled, condition) -{ - this.breakpointManager.restoredBreakpoint(sourceID, sourceURL, line, enabled, condition); -} - -WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLine, errorLine, errorMessage) -{ - this.panels.scripts.addScript(null, sourceURL, source, startingLine, errorLine, errorMessage); -} - -WebInspector.pausedScript = function(details) -{ - this.panels.scripts.debuggerPaused(details.callFrames); - this.breakpointManager.debuggerPaused(details); - InspectorFrontendHost.bringToFront(); -} - -WebInspector.resumedScript = function() -{ - this.breakpointManager.debuggerResumed(); - this.panels.scripts.debuggerResumed(); -} - WebInspector.reset = function() { - this.breakpointManager.reset(); + this.debuggerModel.reset(); for (var panelName in this.panels) { var panel = this.panels[panelName]; @@ -1371,14 +1222,6 @@ WebInspector.reset = function() this.console.clearMessages(); this.extensionServer.notifyInspectorReset(); - - this.breakpointManager.restoreBreakpoints(); -} - -WebInspector.resetProfilesPanel = function() -{ - if (WebInspector.panels.profiles) - WebInspector.panels.profiles.resetProfiles(); } WebInspector.bringToFront = function() @@ -1391,16 +1234,6 @@ WebInspector.inspectedURLChanged = function(url) InspectorFrontendHost.inspectedURLChanged(url); this.settings.inspectedURLChanged(url); this.extensionServer.notifyInspectedURLChanged(); - if (!this._breakpointsRestored) { - this.breakpointManager.restoreBreakpoints(); - this._breakpointsRestored = true; - } -} - -WebInspector.didCommitLoad = function() -{ - // Cleanup elements panel early on inspected page refresh. - WebInspector.setDocument(null); } WebInspector.updateConsoleMessageExpiredCount = function(count) @@ -1417,11 +1250,11 @@ WebInspector.addConsoleMessage = function(payload) payload.level, payload.line, payload.url, - payload.groupLevel, payload.repeatCount, payload.message, payload.parameters, - payload.stackTrace); + payload.stackTrace, + payload.requestId); this.console.addMessage(consoleMessage); } @@ -1487,7 +1320,6 @@ WebInspector.log = function(message, messageLevel) messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug, -1, null, - null, repeatCount, null, [message], @@ -1516,31 +1348,6 @@ WebInspector.log = function(message, messageLevel) logMessage(message); } -WebInspector.addProfileHeader = function(profile) -{ - this.panels.profiles.addProfileHeader(profile); -} - -WebInspector.setRecordingProfile = function(isProfiling) -{ - this.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).setRecordingProfile(isProfiling); - if (this.panels.profiles.hasTemporaryProfile(WebInspector.CPUProfileType.TypeId) !== isProfiling) { - if (!this._temporaryRecordingProfile) { - this._temporaryRecordingProfile = { - typeId: WebInspector.CPUProfileType.TypeId, - title: WebInspector.UIString("Recording…"), - uid: -1, - isTemporary: true - }; - } - if (isProfiling) - this.panels.profiles.addProfileHeader(this._temporaryRecordingProfile); - else - this.panels.profiles.removeProfileHeader(this._temporaryRecordingProfile); - } - this.panels.profiles.updateProfileTypeButtons(); -} - WebInspector.drawLoadingPieChart = function(canvas, percent) { var g = canvas.getContext("2d"); var darkColor = "rgb(122, 168, 218)"; @@ -1940,13 +1747,23 @@ WebInspector.isEditingAnyField = function() return this.__editing; } -WebInspector.startEditing = function(element, committedCallback, cancelledCallback, context, multiline) +// Available config fields (all optional): +// context: Object - an arbitrary context object to be passed to the commit and cancel handlers +// commitHandler: Function - handles editing "commit" outcome +// cancelHandler: Function - handles editing "cancel" outcome +// customFinishHandler: Function - custom finish handler for the editing session (invoked on keydown) +// multiline: Boolean - whether the edited element is multiline +WebInspector.startEditing = function(element, config) { if (element.__editing) return; element.__editing = true; WebInspector.__editing = true; + config = config || {}; + var committedCallback = config.commitHandler; + var cancelledCallback = config.cancelHandler; + var context = config.context; var oldText = getContent(element); var moveDirection = ""; @@ -2002,20 +1819,36 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba committedCallback(this, getContent(this), oldText, context, moveDirection); } - function keyDownEventListener(event) { + function defaultFinishHandler(event) + { var isMetaOrCtrl = WebInspector.isMac() ? event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey : event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey; - if (isEnterKey(event) && (!multiline || isMetaOrCtrl)) { + if (isEnterKey(event) && (!config.multiline || isMetaOrCtrl)) + return "commit"; + else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) + return "cancel"; + else if (event.keyIdentifier === "U+0009") // Tab key + return "move-" + (event.shiftKey ? "backward" : "forward"); + } + + function keyDownEventListener(event) + { + var handler = config.customFinishHandler || defaultFinishHandler; + var result = handler(event); + if (result === "commit") { editingCommitted.call(element); event.preventDefault(); event.stopPropagation(); - } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) { + } else if (result === "cancel") { editingCancelled.call(element); event.preventDefault(); event.stopPropagation(); - } else if (event.keyIdentifier === "U+0009") // Tab key - moveDirection = (event.shiftKey ? "backward" : "forward"); + } else if (result && result.indexOf("move-") === 0) { + moveDirection = result.substring(5); + if (event.keyIdentifier !== "U+0009") + blurEventListener(); + } } element.addEventListener("blur", blurEventListener, false); diff --git a/WebCore/inspector/front-end/networkPanel.css b/WebCore/inspector/front-end/networkPanel.css index 70ebe56..95ed1bf 100644 --- a/WebCore/inspector/front-end/networkPanel.css +++ b/WebCore/inspector/front-end/networkPanel.css @@ -159,13 +159,6 @@ content: ""; } -.network-sidebar .network-category-images .icon { - position: relative; - background-image: url(Images/resourcePlainIcon.png); - background-repeat: no-repeat; - content: ""; -} - .network-sidebar .data-grid.small .network-category-images .icon { background-image: url(Images/resourcePlainIconSmall.png); content: ""; @@ -473,21 +466,19 @@ margin-top: 1px; } -.data-grid table.data tr.revealed.network-category-documents, .data-grid table.data tr.revealed.network-category-stylesheets, -.data-grid table.data tr.revealed.network-category-images, .data-grid table.data tr.revealed.network-category-scripts, -.data-grid table.data tr.revealed.network-category-xhr, .data-grid table.data tr.revealed.network-category-fonts, -.data-grid table.data tr.revealed.network-category-websockets, .data-grid table.data tr.revealed.network-category-other { +.data-grid table.data tr.revealed.network-item { display: none; } -.data-grid.filter-all table.data tr.revealed.network-category-documents, .data-grid.filter-documents table.data tr.revealed.network-category-documents, -.data-grid.filter-all table.data tr.revealed.network-category-stylesheets, .data-grid.filter-stylesheets table.data tr.revealed.network-category-stylesheets, -.data-grid.filter-all table.data tr.revealed.network-category-images, .data-grid.filter-images table.data tr.revealed.network-category-images, -.data-grid.filter-all table.data tr.revealed.network-category-scripts, .data-grid.filter-scripts table.data tr.revealed.network-category-scripts, -.data-grid.filter-all table.data tr.revealed.network-category-xhr, .data-grid.filter-xhr table.data tr.revealed.network-category-xhr, -.data-grid.filter-all table.data tr.revealed.network-category-fonts, .data-grid.filter-fonts table.data tr.revealed.network-category-fonts, -.data-grid.filter-all table.data tr.revealed.network-category-websockets, .data-grid.filter-websockets table.data tr.revealed.network-category-websockets, -.data-grid.filter-all table.data tr.revealed.network-category-other, .data-grid.filter-other table.data tr.revealed.network-category-other { +.data-grid.filter-all table.data tr.revealed.network-item, +.data-grid.filter-documents table.data tr.revealed.network-category-documents, +.data-grid.filter-stylesheets table.data tr.revealed.network-category-stylesheets, +.data-grid.filter-images table.data tr.revealed.network-category-images, +.data-grid.filter-scripts table.data tr.revealed.network-category-scripts, +.data-grid.filter-xhr table.data tr.revealed.network-category-xhr, +.data-grid.filter-fonts table.data tr.revealed.network-category-fonts, +.data-grid.filter-websockets table.data tr.revealed.network-category-websockets, +.data-grid.filter-other table.data tr.revealed.network-category-other { display: table-row; } diff --git a/WebCore/inspector/front-end/treeoutline.js b/WebCore/inspector/front-end/treeoutline.js index a1e052f..27bc839 100644 --- a/WebCore/inspector/front-end/treeoutline.js +++ b/WebCore/inspector/front-end/treeoutline.js @@ -821,6 +821,10 @@ TreeElement.prototype.select = function(supressOnSelect, selectedByUser) this.selected = true; this.treeOutline._childrenListNode.focus(); + + // Focusing on another node may detach "this" from tree. + if (!this.treeOutline) + return; this.treeOutline.selectedTreeElement = this; if (this._listItemNode) this._listItemNode.addStyleClass("selected"); diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js index f978c6f..688e080 100644 --- a/WebCore/inspector/front-end/utilities.js +++ b/WebCore/inspector/front-end/utilities.js @@ -216,6 +216,11 @@ Element.prototype.pruneEmptyTextNodes = function() } } +Element.prototype.isScrolledToBottom = function() +{ + return this.scrollTop === this.scrollHeight - this.offsetHeight; +} + Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) { for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) |