+2011-02-01 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: introduce new api for managing JavaScript breakpoints.
+ https://bugs.webkit.org/show_bug.cgi?id=53235
+
+ * inspector/report-protocol-errors.html:
+
2011-02-03 Philippe Normand <pnormand@igalia.com>
Unreviewed, skip flaky websocket tests on GTK
'{"seq":3,"command":"resourceContent","arguments":[]}',
'{"seq":4,"command":"resourceContent","arguments":{}}',
'{"seq":5,"command":"resourceContent","arguments":{"identifier":"not a number"}}',
- '{"seq":6,"command":"removeBreakpoint","arguments":{}}',
- '{"seq":7,"command":"removeBreakpoint","arguments":{"breakpointId":"someBreakpointId"}}',
+ '{"seq":6,"command":"removeJavaScriptBreakpoint","arguments":{}}',
+ '{"seq":7,"command":"removeJavaScriptBreakpoint","arguments":{"breakpointId":"someBreakpointId"}}',
];
var numberOfReports = 0;
+2011-02-01 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: introduce new api for managing JavaScript breakpoints.
+ https://bugs.webkit.org/show_bug.cgi?id=53235
+
+ Single protocol breakpoint (e.g. set by url) is mapped on zero or more VM breakpoints (set by sourceID).
+ removeJavaScriptBreakpoint(breakpointId) removes breakpoint and all linked VM breakpoints.
+ Since UI uses VM breakpoint location rather then protocol breakpoint location, all resolved breakpoints locations are passed to frontend.
+
+ SourceFrame is now aware of whether breakpoint is resolved or not and may display it accordingly.
+ JavaScriptBreakpointsSidebarPane filters out breakpoints set on nonexistent scripts to avoid UI cluttering.
+
+ * bindings/js/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::setBreakpoint):
+ (WebCore::ScriptDebugServer::removeBreakpoint):
+ * bindings/js/ScriptDebugServer.h:
+ * bindings/v8/DebuggerScript.js:
+ ():
+ * bindings/v8/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::setBreakpoint):
+ * bindings/v8/ScriptDebugServer.h:
+ * inspector/Inspector.idl:
+ * inspector/InspectorAgent.cpp: clear breakpoints from inspector state when new frontend is created
+ (WebCore::InspectorAgent::restoreInspectorStateFromCookie):
+ (WebCore::InspectorAgent::populateScriptObjects):
+ (WebCore::InspectorAgent::restoreDebugger):
+ (WebCore::InspectorAgent::showAndEnableDebugger):
+ (WebCore::InspectorAgent::enableDebugger):
+ * inspector/InspectorAgent.h:
+ * inspector/InspectorDebuggerAgent.cpp: manage relations between protocol breakpoints and VM breakpoints
+ (WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent):
+ (WebCore::InspectorDebuggerAgent::inspectedURLChanged):
+ (WebCore::InspectorDebuggerAgent::setJavaScriptBreakpoint):
+ (WebCore::InspectorDebuggerAgent::setJavaScriptBreakpointBySourceId):
+ (WebCore::InspectorDebuggerAgent::removeJavaScriptBreakpoint):
+ (WebCore::InspectorDebuggerAgent::continueToLocation):
+ (WebCore::InspectorDebuggerAgent::resolveBreakpoint):
+ (WebCore::InspectorDebuggerAgent::getScriptSource):
+ (WebCore::InspectorDebuggerAgent::didParseSource):
+ (WebCore::InspectorDebuggerAgent::didPause):
+ * inspector/InspectorDebuggerAgent.h:
+ (WebCore::InspectorDebuggerAgent::Script::Script):
+ * inspector/InspectorValues.cpp:
+ (WebCore::InspectorValue::asNumber):
+ (WebCore::InspectorBasicValue::asNumber):
+ (WebCore::InspectorObject::remove):
+ * inspector/InspectorValues.h:
+ (WebCore::InspectorObject::getNumber):
+ (WebCore::InspectorObject::find):
+ * inspector/ScriptBreakpoint.h:
+ (WebCore::ScriptBreakpoint::ScriptBreakpoint):
+ * inspector/front-end/Breakpoint.js:
+ (WebInspector.Breakpoint):
+ (WebInspector.Breakpoint.prototype.addLocation):
+ * inspector/front-end/BreakpointManager.js: remove all stuff related to JavaScript breakpoints from here
+ (WebInspector.BreakpointManager):
+ (WebInspector.BreakpointManager.prototype._projectChanged):
+ (WebInspector.BreakpointManager.prototype._saveBreakpoints):
+ (WebInspector.BreakpointManager.prototype._validateBreakpoints):
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.JavaScriptBreakpointsSidebarPane): filter breakpoints set on nonexistent scripts to avoid ui cluttering
+ * inspector/front-end/DebuggerModel.js:
+ (WebInspector.DebuggerModel): pull all JavaScript from localStorage and push them to fronted when debugger is enabled, save resolved breakpoints data
+ * inspector/front-end/Script.js:
+ (WebInspector.Script.prototype.sourceLine):
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel.prototype._toggleDebugging):
+ * inspector/front-end/Settings.js:
+ (WebInspector.Settings):
+ * inspector/front-end/SourceFrame.js: handle resolved and unresolved breakpoints differently
+ * inspector/front-end/inspector.js:
+
2011-02-03 Nikolas Zimmermann <nzimmermann@rim.com>
Reviewed by Dirk Schulze.
return m_pageListenersMap.contains(page);
}
-String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, long* actualLineNumber, long* actualColumnNumber)
+String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber)
{
intptr_t sourceIDValue = sourceID.toIntPtr();
if (!sourceIDValue)
SourceIdToBreakpointsMap::iterator it = m_sourceIdToBreakpoints.find(sourceIDValue);
if (it == m_sourceIdToBreakpoints.end())
it = m_sourceIdToBreakpoints.set(sourceIDValue, LineToBreakpointMap()).first;
- if (it->second.contains(scriptBreakpoint.lineNumber))
+ if (it->second.contains(scriptBreakpoint.lineNumber + 1))
return "";
- it->second.set(scriptBreakpoint.lineNumber, scriptBreakpoint);
+ it->second.set(scriptBreakpoint.lineNumber + 1, scriptBreakpoint);
*actualLineNumber = scriptBreakpoint.lineNumber;
// FIXME(WK53003): implement setting breakpoints by line:column.
- *actualColumnNumber = 1;
+ *actualColumnNumber = 0;
return makeString(sourceID, ":", String::number(scriptBreakpoint.lineNumber));
}
return;
SourceIdToBreakpointsMap::iterator it = m_sourceIdToBreakpoints.find(sourceIDValue);
if (it != m_sourceIdToBreakpoints.end())
- it->second.remove(lineNumber);
+ it->second.remove(lineNumber + 1);
}
bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, unsigned lineNumber) const
void addListener(ScriptDebugListener*, Page*);
void removeListener(ScriptDebugListener*, Page*);
- String setBreakpoint(const String& sourceID, const ScriptBreakpoint&, long* actualLineNumber, long* actualColumnNumber);
+ String setBreakpoint(const String& sourceID, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber);
void removeBreakpoint(const String& breakpointId);
void clearBreakpoints();
void setBreakpointsActivated(bool activated);
DebuggerScript.setBreakpoint = function(execState, args)
{
- var lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber);
- var columnNumber = DebuggerScript._webkitToV8LineNumber(args.columnNumber);
- var breakId = Debug.setScriptBreakPointById(args.scriptId, lineNumber, columnNumber, args.condition);
+ var breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, args.columnNumber, args.condition);
if (!args.enabled)
Debug.disableScriptBreakPoint(breakId);
var locations = Debug.findBreakPointActualLocations(breakId);
if (!locations.length)
return undefined;
- args.lineNumber = DebuggerScript._v8ToWebkitLineNumber(locations[0].line);
- args.columnNumber = DebuggerScript._v8ToWebkitLineNumber(locations[0].column);
+ args.lineNumber = locations[0].line;
+ args.columnNumber = locations[0].column;
return breakId.toString();
}
};
}
-DebuggerScript._webkitToV8LineNumber = function(line)
-{
- return line - 1;
-};
-
DebuggerScript._v8ToWebkitLineNumber = function(line)
{
return line + 1;
// FIXME: Remove all breakpoints set by the agent.
}
-String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, long* actualLineNumber, long* actualColumnNumber)
+String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber)
{
v8::HandleScope scope;
v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
void addListener(ScriptDebugListener*, Page*);
void removeListener(ScriptDebugListener*, Page*);
- String setBreakpoint(const String& sourceID, const ScriptBreakpoint&, long* actualLineNumber, long* actualColumnNumber);
+ String setBreakpoint(const String& sourceID, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber);
void removeBreakpoint(const String& breakpointId);
void clearBreakpoints();
void setBreakpointsActivated(bool activated);
[domain=Debugger] void activateBreakpoints();
[domain=Debugger] void deactivateBreakpoints();
- [domain=Debugger] void setAllJavaScriptBreakpoints(in Object breakpoints);
- [domain=Debugger] void setBreakpoint(in Object breakpoint, out String breakpointId, out long actualLineNumber, out long actualColumnNumber);
- [domain=Debugger] void removeBreakpoint(in String breakpointId);
+ [domain=Debugger] void setJavaScriptBreakpoint(in String url, in int lineNumber, in int columnNumber, in String condition, in boolean enabled, out String breakpointId, out Array locations);
+ [domain=Debugger] void setJavaScriptBreakpointBySourceId(in String sourceId, in int lineNumber, in int columnNumber, in String condition, in boolean enabled, out String breakpointId, out int actualLineNumber, out int actualColumnNumber);
+ [domain=Debugger] void removeJavaScriptBreakpoint(in String breakpointId);
+ [notify, domain=Debugger] void breakpointResolved(out String breakpointId, out String sourceId, out int lineNumber, out int columnNumber);
+ [domain=Debugger] void continueToLocation(in String sourceId, in int lineNumber, in int columnNumber);
[domain=BrowserDebugger] void setAllBrowserBreakpoints(in Object breakpoints);
[domain=BrowserDebugger] void setDOMBreakpoint(in long nodeId, in long type);
[domain=Debugger] void evaluateOnCallFrame(in Object callFrameId, in String expression, in String objectGroup, in boolean includeCommandLineAPI, out Value result);
[domain=Debugger] void getCompletionsOnCallFrame(in Object callFrameId, in String expression, in boolean includeCommandLineAPI, out Value result);
- [notify, domain=Debugger] void breakpointResolved(out String breakpointId, out Object breakpoint);
-
#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);
startTimelineProfiler();
#if ENABLE(JAVASCRIPT_DEBUGGER)
- restoreDebugger();
+ restoreDebugger(false);
restoreProfiler(ProfilerRestoreResetAgent);
if (m_state->getBoolean(InspectorState::userInitiatedProfiling))
startUserInitiatedProfiling();
m_frontend->evaluateForTestInFrontend((*it).first, (*it).second);
m_pendingEvaluateTestCommands.clear();
- restoreDebugger();
+ restoreDebugger(true);
restoreProfiler(ProfilerRestoreNoAction);
}
#endif
}
-void InspectorAgent::restoreDebugger()
+void InspectorAgent::restoreDebugger(bool eraseStickyBreakpoints)
{
ASSERT(m_frontend);
#if ENABLE(JAVASCRIPT_DEBUGGER)
if (m_state->getBoolean(InspectorState::debuggerEnabled))
- enableDebugger();
+ enableDebugger(eraseStickyBreakpoints);
#endif
}
m_state->setBoolean(InspectorState::debuggerEnabled, true);
showPanel(ScriptsPanel);
} else
- enableDebugger();
+ enableDebugger(true);
}
-void InspectorAgent::enableDebugger()
+void InspectorAgent::enableDebugger(bool eraseStickyBreakpoints)
{
if (debuggerEnabled())
return;
m_state->setBoolean(InspectorState::debuggerEnabled, true);
ASSERT(m_inspectedPage);
+ if (eraseStickyBreakpoints) {
+ m_state->setObject(InspectorState::javaScriptBreakpoints, InspectorObject::create());
+ m_state->setObject(InspectorState::browserBreakpoints, InspectorObject::create());
+ }
+
m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get());
m_browserDebuggerAgent = InspectorBrowserDebuggerAgent::create(this);
bool profilerEnabled() const;
void showAndEnableDebugger();
- void enableDebugger();
+ void enableDebugger() { enableDebugger(false); }
+ void enableDebugger(bool eraseStickyBreakpoints);
void disableDebugger();
bool debuggerEnabled() const { return m_debuggerAgent; }
void resume();
private:
void pushDataCollectedOffline();
- void restoreDebugger();
+ void restoreDebugger(bool eraseStickyBreakpoints);
enum ProfilerRestoreAction {
ProfilerRestoreNoAction = 0,
ProfilerRestoreResetAgent = 1
#include "InspectorValues.h"
#include "PlatformString.h"
#include "ScriptDebugServer.h"
+#include <wtf/text/StringConcatenate.h>
namespace WebCore {
, m_frontend(frontend)
, m_pausedScriptState(0)
, m_javaScriptPauseScheduled(false)
- , m_breakpointsRestored(false)
{
}
ScriptDebugServer::shared().deactivateBreakpoints();
}
-void InspectorDebuggerAgent::setAllJavaScriptBreakpoints(PassRefPtr<InspectorObject> breakpoints)
+void InspectorDebuggerAgent::inspectedURLChanged(const String&)
{
- m_inspectorAgent->state()->setObject(InspectorState::javaScriptBreakpoints, breakpoints);
- if (!m_breakpointsRestored) {
- restoreBreakpoints(m_inspectorAgent->inspectedURLWithoutFragment());
- m_breakpointsRestored = true;
- }
-}
-
-void InspectorDebuggerAgent::inspectedURLChanged(const String& url)
-{
- m_scriptIDToContent.clear();
- m_urlToSourceIDs.clear();
- restoreBreakpoints(url);
+ m_scripts.clear();
+ m_breakpointIdToDebugServerBreakpointIds.clear();
}
-void InspectorDebuggerAgent::restoreBreakpoints(const String& inspectedURL)
+void InspectorDebuggerAgent::setJavaScriptBreakpoint(const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, RefPtr<InspectorArray>* locations)
{
- m_stickyBreakpoints.clear();
-
- RefPtr<InspectorObject> allBreakpoints = m_inspectorAgent->state()->getObject(InspectorState::javaScriptBreakpoints);
- RefPtr<InspectorArray> breakpoints = allBreakpoints->getArray(inspectedURL);
- if (!breakpoints)
+ String breakpointId = makeString(url, ":", String::number(lineNumber), ":", String::number(columnNumber));
+ RefPtr<InspectorObject> breakpointsCookie = m_inspectorAgent->state()->getObject(InspectorState::javaScriptBreakpoints);
+ if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end())
return;
- for (unsigned i = 0; i < breakpoints->length(); ++i) {
- RefPtr<InspectorObject> breakpoint = breakpoints->get(i)->asObject();
- if (!breakpoint)
- continue;
- String url;
- if (!breakpoint->getString("url", &url))
- continue;
- double lineNumber;
- if (!breakpoint->getNumber("lineNumber", &lineNumber))
+ RefPtr<InspectorObject> breakpointObject = InspectorObject::create();
+ breakpointObject->setString("url", url);
+ breakpointObject->setNumber("lineNumber", lineNumber);
+ breakpointObject->setNumber("columnNumber", columnNumber);
+ breakpointObject->setString("condition", condition);
+ breakpointObject->setBoolean("enabled", enabled);
+ breakpointsCookie->setObject(breakpointId, breakpointObject);
+ m_inspectorAgent->state()->setObject(InspectorState::javaScriptBreakpoints, breakpointsCookie);
+
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
+ for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
+ if (it->second.url != url)
continue;
- double columnNumber;
- if (!breakpoint->getNumber("columnNumber", &columnNumber))
- return;
- String condition;
- if (!breakpoint->getString("condition", &condition))
+ int actualLineNumber = 0, actualColumnNumber = 0;
+ if (!resolveBreakpoint(breakpointId, it->first, breakpoint, &actualLineNumber, &actualColumnNumber))
continue;
- bool enabled;
- if (!breakpoint->getBoolean("enabled", &enabled))
- continue;
- ScriptBreakpoint scriptBreakpoint((long) lineNumber, (long) columnNumber, condition, enabled);
- setStickyBreakpoint(url, scriptBreakpoint);
+ RefPtr<InspectorObject> location = InspectorObject::create();
+ location->setString("sourceID", it->first);
+ location->setNumber("lineNumber", actualLineNumber);
+ location->setNumber("columnNumber", actualColumnNumber);
+ locations->get()->pushObject(location);
}
+ *outBreakpointId = breakpointId;
}
-void InspectorDebuggerAgent::setStickyBreakpoint(const String& url, const ScriptBreakpoint& breakpoint)
+void InspectorDebuggerAgent::setJavaScriptBreakpointBySourceId(const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* outBreakpointId, int* actualLineNumber, int* actualColumnNumber)
{
- InspectedURLToBreakpointsMap::iterator it = m_stickyBreakpoints.find(url);
- if (it == m_stickyBreakpoints.end())
- it = m_stickyBreakpoints.set(url, LocationToBreakpointMap()).first;
- it->second.set(Location(breakpoint.lineNumber, breakpoint.columnNumber), breakpoint);
-
- URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url);
- if (urlToSourceIDsIterator == m_urlToSourceIDs.end())
+ String breakpointId = makeString(sourceId, ":", String::number(lineNumber), ":", String::number(columnNumber));
+ if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end())
return;
- const Vector<String>& sourceIDs = urlToSourceIDsIterator->second;
- for (size_t i = 0; i < sourceIDs.size(); ++i)
- restoreBreakpoint(sourceIDs[i], breakpoint);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
+ if (!resolveBreakpoint(breakpointId, sourceId, breakpoint, actualLineNumber, actualColumnNumber))
+ return;
+ *outBreakpointId = breakpointId;
}
-void InspectorDebuggerAgent::setBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId, long* actualLineNumber, long* actualColumnNumber)
+void InspectorDebuggerAgent::removeJavaScriptBreakpoint(const String& breakpointId)
{
- String sourceID;
- if (!breakpoint->getString("sourceID", &sourceID))
- return;
- double lineNumber;
- if (!breakpoint->getNumber("lineNumber", &lineNumber))
- return;
- double columnNumber;
- if (!breakpoint->getNumber("columnNumber", &columnNumber))
- return;
- String condition;
- if (!breakpoint->getString("condition", &condition))
- return;
- bool enabled;
- if (!breakpoint->getBoolean("enabled", &enabled))
+ RefPtr<InspectorObject> breakpointsCookie = m_inspectorAgent->state()->getObject(InspectorState::javaScriptBreakpoints);
+ breakpointsCookie->remove(breakpointId);
+ m_inspectorAgent->state()->setObject(InspectorState::javaScriptBreakpoints, breakpointsCookie);
+
+ BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
+ if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
return;
- ScriptBreakpoint scriptBreakpoint((long) lineNumber, (long) columnNumber, condition, enabled);
- *breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, scriptBreakpoint, actualLineNumber, actualColumnNumber);
+ for (size_t i = 0; i < debugServerBreakpointIdsIterator->second.size(); ++i)
+ ScriptDebugServer::shared().removeBreakpoint(debugServerBreakpointIdsIterator->second[i]);
+ m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator);
}
-void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId)
+void InspectorDebuggerAgent::continueToLocation(const String& sourceId, int lineNumber, int columnNumber)
{
- ScriptDebugServer::shared().removeBreakpoint(breakpointId);
+ if (!m_continueToLocationBreakpointId.isEmpty()) {
+ ScriptDebugServer::shared().removeBreakpoint(m_continueToLocationBreakpointId);
+ m_continueToLocationBreakpointId = "";
+ }
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", true);
+ m_continueToLocationBreakpointId = ScriptDebugServer::shared().setBreakpoint(sourceId, breakpoint, &lineNumber, &columnNumber);
+ resume();
}
-void InspectorDebuggerAgent::restoreBreakpoint(const String& sourceID, const ScriptBreakpoint& breakpoint)
+bool InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint& breakpoint, int* actualLineNumber, int* actualColumnNumber)
{
- long actualLineNumber = 0, actualColumnNumber = 0;
- String breakpointId = ScriptDebugServer::shared().setBreakpoint(sourceID, breakpoint, &actualLineNumber, &actualColumnNumber);
- if (breakpointId.isEmpty())
- return;
- RefPtr<InspectorObject> breakpointData = InspectorObject::create();
- breakpointData->setString("id", breakpointId);
- breakpointData->setString("sourceID", sourceID);
- breakpointData->setNumber("lineNumber", actualLineNumber);
- breakpointData->setNumber("columnNumber", actualColumnNumber);
- breakpointData->setString("condition", breakpoint.condition);
- breakpointData->setBoolean("enabled", breakpoint.enabled);
- breakpointData->setNumber("originalLineNumber", breakpoint.lineNumber);
- breakpointData->setNumber("originalColumnNumber", breakpoint.columnNumber);
- m_frontend->breakpointResolved(breakpointId, breakpointData);
+ ScriptsMap::iterator scriptIterator = m_scripts.find(sourceId);
+ if (scriptIterator == m_scripts.end())
+ return false;
+ Script& script = scriptIterator->second;
+ if (breakpoint.lineNumber < script.lineOffset)
+ return false;
+ if (!script.linesCount) {
+ script.linesCount = 1;
+ for (size_t i = 0; i < script.data.length(); ++i) {
+ if (script.data[i] == '\n')
+ script.linesCount += 1;
+ }
+ }
+ if (breakpoint.lineNumber >= script.lineOffset + script.linesCount)
+ return false;
+
+ String debugServerBreakpointId = ScriptDebugServer::shared().setBreakpoint(sourceId, breakpoint, actualLineNumber, actualColumnNumber);
+ if (debugServerBreakpointId.isEmpty())
+ return false;
+
+ BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
+ if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
+ debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).first;
+ debugServerBreakpointIdsIterator->second.append(debugServerBreakpointId);
+
+ return true;
}
void InspectorDebuggerAgent::editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames)
void InspectorDebuggerAgent::getScriptSource(const String& sourceID, String* scriptSource)
{
- *scriptSource = m_scriptIDToContent.get(sourceID);
+ *scriptSource = m_scripts.get(sourceID).data;
}
void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data)
// Don't send script content to the front end until it's really needed.
m_frontend->parsedScriptSource(sourceID, url, lineOffset, columnOffset, data.length(), worldType);
- m_scriptIDToContent.set(sourceID, data);
+ m_scripts.set(sourceID, Script(url, data, lineOffset, columnOffset));
if (url.isEmpty())
return;
- URLToSourceIDsMap::iterator urlToSourceIDsIterator = m_urlToSourceIDs.find(url);
- if (urlToSourceIDsIterator == m_urlToSourceIDs.end())
- urlToSourceIDsIterator = m_urlToSourceIDs.set(url, Vector<String>()).first;
- urlToSourceIDsIterator->second.append(sourceID);
-
- InspectedURLToBreakpointsMap::iterator stickyBreakpointsIterator = m_stickyBreakpoints.find(url);
- if (stickyBreakpointsIterator == m_stickyBreakpoints.end())
- return;
-
- const LocationToBreakpointMap& breakpoints = stickyBreakpointsIterator->second;
- for (LocationToBreakpointMap::const_iterator it = breakpoints.begin(); it != breakpoints.end(); ++it)
- restoreBreakpoint(sourceID, it->second);
+ RefPtr<InspectorObject> breakpointsCookie = m_inspectorAgent->state()->getObject(InspectorState::javaScriptBreakpoints);
+ for (InspectorObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) {
+ RefPtr<InspectorObject> breakpointObject = it->second->asObject();
+ String breakpointURL;
+ breakpointObject->getString("url", &breakpointURL);
+ if (breakpointURL != url)
+ continue;
+ ScriptBreakpoint breakpoint;
+ breakpointObject->getNumber("lineNumber", &breakpoint.lineNumber);
+ breakpointObject->getNumber("columnNumber", &breakpoint.columnNumber);
+ breakpointObject->getString("condition", &breakpoint.condition);
+ breakpointObject->getBoolean("enabled", &breakpoint.enabled);
+ int actualLineNumber = 0, actualColumnNumber = 0;
+ if (resolveBreakpoint(it->first, sourceID, breakpoint, &actualLineNumber, &actualColumnNumber))
+ m_frontend->breakpointResolved(it->first, sourceID, actualLineNumber, actualColumnNumber);
+ }
}
void InspectorDebuggerAgent::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage)
m_frontend->pausedScript(m_breakProgramDetails);
m_javaScriptPauseScheduled = false;
+
+ if (!m_continueToLocationBreakpointId.isEmpty()) {
+ ScriptDebugServer::shared().removeBreakpoint(m_continueToLocationBreakpointId);
+ m_continueToLocationBreakpointId = "";
+ }
}
void InspectorDebuggerAgent::didContinue()
static PassOwnPtr<InspectorDebuggerAgent> create(InspectorAgent*, InspectorFrontend*);
virtual ~InspectorDebuggerAgent();
- void setAllJavaScriptBreakpoints(PassRefPtr<InspectorObject>);
void inspectedURLChanged(const String& url);
// Part of the protocol.
void activateBreakpoints();
void deactivateBreakpoints();
- void setStickyBreakpoint(const String& url, const WebCore::ScriptBreakpoint&);
- void setBreakpoint(PassRefPtr<InspectorObject> breakpoint, String* breakpointId, long* actualLineNumber, long* actualColumnNumber);
- void removeBreakpoint(const String& breakpointId);
+
+ void setJavaScriptBreakpoint(const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, RefPtr<InspectorArray>* locations);
+ void setJavaScriptBreakpointBySourceId(const String& sourceId, int lineNumber, int columnNumber, const String& condition, bool enabled, String* breakpointId, int* actualLineNumber, int* actualColumnNumber);
+ void removeJavaScriptBreakpoint(const String& breakpointId);
+ void continueToLocation(const String& sourceId, int lineNumber, int columnNumber);
+
void editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames);
void getScriptSource(const String& sourceID, String* scriptSource);
void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data);
virtual void didPause(ScriptState*);
virtual void didContinue();
- void restoreBreakpoints(const String& inspectedURL);
- void restoreBreakpoint(const String& sourceID, const ScriptBreakpoint&);
-
- typedef HashMap<String, Vector<String> > URLToSourceIDsMap;
- typedef std::pair<long, long> Location;
- typedef HashMap<Location, ScriptBreakpoint> LocationToBreakpointMap;
- typedef HashMap<String, LocationToBreakpointMap> InspectedURLToBreakpointsMap;
+ bool resolveBreakpoint(const String& breakpointId, const String& sourceId, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber);
+
+ class Script {
+ public:
+ Script()
+ : lineOffset(0)
+ , columnOffset(0)
+ , linesCount(0)
+ {
+ }
+
+ Script(const String& url, const String& data, int lineOffset, int columnOffset)
+ : url(url)
+ , data(data)
+ , lineOffset(lineOffset)
+ , columnOffset(columnOffset)
+ , linesCount(0)
+ {
+ }
+
+ String url;
+ String data;
+ int lineOffset;
+ int columnOffset;
+ int linesCount;
+ };
+
+ typedef HashMap<String, Script> ScriptsMap;
+ typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
InspectorAgent* m_inspectorAgent;
InspectorFrontend* m_frontend;
ScriptState* m_pausedScriptState;
- HashMap<String, String> m_scriptIDToContent;
- URLToSourceIDsMap m_urlToSourceIDs;
- InspectedURLToBreakpointsMap m_stickyBreakpoints;
+ ScriptsMap m_scripts;
+ BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
+ String m_continueToLocationBreakpointId;
RefPtr<InspectorObject> m_breakProgramDetails;
bool m_javaScriptPauseScheduled;
- bool m_breakpointsRestored;
};
} // namespace WebCore
return false;
}
+bool InspectorValue::asNumber(int*) const
+{
+ return false;
+}
+
bool InspectorValue::asNumber(unsigned long*) const
{
return false;
return true;
}
+bool InspectorBasicValue::asNumber(int* output) const
+{
+ if (type() != TypeNumber)
+ return false;
+ *output = static_cast<int>(m_doubleValue);
+ return true;
+}
+
bool InspectorBasicValue::asNumber(unsigned long* output) const
{
if (type() != TypeNumber)
return value->asBoolean(output);
}
-bool InspectorObject::getNumber(const String& name, long* output) const
-{
- RefPtr<InspectorValue> value = get(name);
- if (!value)
- return false;
- return value->asNumber(output);
-}
-
-bool InspectorObject::getNumber(const String& name, double* output) const
-{
- RefPtr<InspectorValue> value = get(name);
- if (!value)
- return false;
- return value->asNumber(output);
-}
-
bool InspectorObject::getString(const String& name, String* output) const
{
RefPtr<InspectorValue> value = get(name);
return it->second;
}
+void InspectorObject::remove(const String& name)
+{
+ m_data.remove(name);
+ for (size_t i = 0; i < m_order.size(); ++i) {
+ if (m_order[i] == name) {
+ m_order.remove(i);
+ break;
+ }
+ }
+}
+
void InspectorObject::writeJSON(Vector<UChar>* output) const
{
output->append('{');
virtual bool asBoolean(bool* output) const;
virtual bool asNumber(double* output) const;
virtual bool asNumber(long* output) const;
+ virtual bool asNumber(int* output) const;
virtual bool asNumber(unsigned long* output) const;
virtual bool asNumber(unsigned int* output) const;
virtual bool asString(String* output) const;
virtual bool asBoolean(bool* output) const;
virtual bool asNumber(double* output) const;
virtual bool asNumber(long* output) const;
+ virtual bool asNumber(int* output) const;
virtual bool asNumber(unsigned long* output) const;
virtual bool asNumber(unsigned int* output) const;
void setObject(const String& name, PassRefPtr<InspectorObject>);
void setArray(const String& name, PassRefPtr<InspectorArray>);
+ iterator find(const String& name);
const_iterator find(const String& name) const;
bool getBoolean(const String& name, bool* output) const;
- bool getNumber(const String& name, long* output) const;
- bool getNumber(const String& name, double* output) const;
+ template<class T> bool getNumber(const String& name, T* output) const
+ {
+ RefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asNumber(output);
+ }
bool getString(const String& name, String* output) const;
PassRefPtr<InspectorObject> getObject(const String& name) const;
PassRefPtr<InspectorArray> getArray(const String& name) const;
PassRefPtr<InspectorValue> get(const String& name) const;
+ void remove(const String& name);
+
virtual void writeJSON(Vector<UChar>* output) const;
iterator begin() { return m_data.begin(); }
Vector<RefPtr<InspectorValue> > m_data;
};
+inline InspectorObject::iterator InspectorObject::find(const String& name)
+{
+ return m_data.find(name);
+}
+
inline InspectorObject::const_iterator InspectorObject::find(const String& name) const
{
return m_data.find(name);
namespace WebCore {
struct ScriptBreakpoint {
- ScriptBreakpoint(long lineNumber, long columnNumber, const String& condition, bool enabled)
+ ScriptBreakpoint()
+ {
+ }
+
+ ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool enabled)
: lineNumber(lineNumber)
, columnNumber(columnNumber)
, condition(condition)
{
}
- ScriptBreakpoint()
- {
- }
-
- long lineNumber;
- long columnNumber;
+ int lineNumber;
+ int columnNumber;
String condition;
bool enabled;
};
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Breakpoint = function(debuggerModel, breakpointId, data)
+WebInspector.Breakpoint = function(id, url, sourceID, lineNumber, columnNumber, condition, enabled)
{
- this.id = breakpointId;
- this.sourceID = data.sourceID;
- this.line = data.lineNumber;
- this.column = data.columnNumber;
- this._condition = data.condition;
- this._enabled = data.enabled;
- this._debuggerModel = debuggerModel;
+ this.id = id;
+ this.url = url;
+ this.sourceID = sourceID;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ this.condition = condition;
+ this.enabled = enabled;
+ this.locations = [];
}
WebInspector.Breakpoint.prototype = {
- get enabled()
+ addLocation: function(sourceID, lineNumber, columnNumber)
{
- return this._enabled;
- },
-
- set enabled(enabled)
- {
- if (this._enabled === enabled)
- return;
- this.remove();
- WebInspector.debuggerModel.setBreakpoint(this.sourceID, this.line, enabled, this.condition);
- },
-
- get condition()
- {
- return this._condition;
- },
-
- get url()
- {
- if (!this._url)
- this._url = this._debuggerModel.scriptForSourceID(this.sourceID).sourceURL;
- return this._url;
- },
-
- get data()
- {
- return { id: this.id, url: this.url, sourceID: this.sourceID, lineNumber: this.line, condition: this.condition };
- },
-
- remove: function()
- {
- this._debuggerModel.removeBreakpoint(this.id);
- this.removeAllListeners();
- delete this._debuggerModel;
+ this.locations.push({ sourceID: sourceID, lineNumber: lineNumber, columnNumber: columnNumber });
}
}
-
-WebInspector.Breakpoint.prototype.__proto__ = WebInspector.Object.prototype;
this._breakpoints = {};
this._domBreakpointsRestored = false;
- this._scriptBreakpoints = {};
WebInspector.settings.addEventListener(WebInspector.Settings.Events.ProjectChanged, this._projectChanged, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._scriptBreakpointAdded, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._scriptBreakpointRemoved, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
}
WebInspector.BreakpointManager.BreakpointTypes = {
DOM: "DOM",
- JS: "JS",
EventListener: "EventListener",
XHR: "XHR"
}
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.EventListenerBreakpointAdded, breakpoint.view);
},
- _createJavaScriptBreakpoint: function(url, lineNumber, condition, enabled, restored)
- {
- var breakpointId = this._createJavaScriptBreakpointId(url, lineNumber);
- if (breakpointId in this._breakpoints)
- return;
-
- var breakpoint = new WebInspector.JavaScriptBreakpoint(url, lineNumber, condition);
- this._setBreakpoint(breakpointId, breakpoint, enabled, restored);
- },
-
- _scriptBreakpointAdded: function(event)
- {
- var scriptBreakpoint = event.data;
-
- if (!scriptBreakpoint.url)
- return;
-
- if (!scriptBreakpoint.restored)
- this._createJavaScriptBreakpoint(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber, scriptBreakpoint.condition, scriptBreakpoint.enabled, false);
- var breakpointId = this._createJavaScriptBreakpointId(scriptBreakpoint.url, scriptBreakpoint.originalLineNumber);
- this._scriptBreakpoints[scriptBreakpoint.id] = breakpointId;
- },
-
- _scriptBreakpointRemoved: function(event)
- {
- var scriptBreakpointId = event.data;
- var breakpointId = this._scriptBreakpoints[scriptBreakpointId];
- delete this._scriptBreakpoints[scriptBreakpointId];
- if (breakpointId in this._breakpoints)
- this._removeBreakpoint(breakpointId);
- },
-
createXHRBreakpoint: function(url)
{
this._createXHRBreakpoint(url, true, false);
{
this._breakpoints = {};
this._domBreakpointsRestored = false;
- this._scriptBreakpoints = {};
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.ProjectChanged);
var breakpoints = this._stickyBreakpoints[WebInspector.settings.projectId] || [];
var breakpoint = breakpoints[i];
if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.EventListener)
this._createEventListenerBreakpoint(breakpoint.condition.eventName, breakpoint.enabled, true);
- else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS)
- this._createJavaScriptBreakpoint(breakpoint.condition.url, breakpoint.condition.lineNumber, breakpoint.condition.condition, breakpoint.enabled, true);
else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR)
this._createXHRBreakpoint(breakpoint.condition.url, breakpoint.enabled, true);
}
if (!this._breakpointsPushedToFrontend) {
- this._pushBreakpointsToBackend();
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
this._breakpointsPushedToFrontend = true;
}
},
WebInspector.settings.nativeBreakpoints = breakpoints;
this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints;
- this._pushBreakpointsToBackend();
- },
-
- _pushBreakpointsToBackend: function()
- {
- var allJavaScriptBreakpoints = {};
- var allBrowserBreakpoints = {};
- for (var projectId in this._stickyBreakpoints) {
- var breakpoints = this._stickyBreakpoints[projectId];
- var javaScriptBreakpoints = [];
- var browserBreakpoints = [];
- for (var i = 0; i < breakpoints.length; ++i) {
- if (breakpoints[i].type == WebInspector.BreakpointManager.BreakpointTypes.JS) {
- var data = {};
- data.enabled = breakpoints[i].enabled;
- for (var p in breakpoints[i].condition)
- data[p] = breakpoints[i].condition[p];
- javaScriptBreakpoints.push(data);
- } else
- browserBreakpoints.push(breakpoints[i]);
- }
- if (javaScriptBreakpoints.length)
- allJavaScriptBreakpoints[projectId] = javaScriptBreakpoints;
- if (browserBreakpoints.length)
- allBrowserBreakpoints[projectId] = browserBreakpoints;
- }
- InspectorBackend.setAllJavaScriptBreakpoints(allJavaScriptBreakpoints);
- InspectorBackend.setAllBrowserBreakpoints(allBrowserBreakpoints);
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
},
_validateBreakpoints: function(persistentBreakpoints)
if (typeof condition.eventName !== "string")
continue;
id += condition.eventName;
- } else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.JS) {
- if (typeof condition.url !== "string" || typeof condition.lineNumber !== "number" || typeof condition.condition !== "string")
- continue;
- id += condition.url + ":" + condition.lineNumber;
} else if (breakpoint.type === WebInspector.BreakpointManager.BreakpointTypes.XHR) {
if (typeof condition.url !== "string")
continue;
id += condition.url;
- }
+ } else
+ continue;
if (id in breakpointsSet)
continue;
breakpointsSet[id] = true;
return "dom:" + nodeId + ":" + type;
},
- _createJavaScriptBreakpointId: function(url, lineNumber)
- {
- return "js:" + url + ":" + lineNumber;
- },
-
_createEventListenerBreakpointId: function(eventName)
{
return "eventListner:" + eventName;
}
}
-WebInspector.JavaScriptBreakpoint = function(url, lineNumber, condition)
-{
- this._url = url;
- this._lineNumber = lineNumber;
- this._condition = condition;
-}
-
-WebInspector.JavaScriptBreakpoint.prototype = {
- _enable: function()
- {
- },
-
- _disable: function()
- {
- },
-
- _serializeToJSON: function()
- {
- var type = WebInspector.BreakpointManager.BreakpointTypes.JS;
- return { type: type, condition: { url: this._url, lineNumber: this._lineNumber, columnNumber: 1, condition: this._condition } };
- }
-}
-
WebInspector.EventListenerBreakpoint = function(eventName)
{
this._eventName = eventName;
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
{
var breakpoint = event.data;
var breakpointId = breakpoint.id;
- var data = breakpoint.data;
+
+ if (breakpoint.url && !WebInspector.debuggerModel.scriptsForURL(breakpoint.url).length)
+ return;
var element = document.createElement("li");
var label = document.createElement("span");
element.appendChild(label);
- element._data = data;
+ element._data = breakpoint;
var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0)
element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointId), true);
- this._setupBreakpointElement(data, element);
+ this._setupBreakpointElement(breakpoint, element);
var breakpointItem = {};
- breakpointItem.data = data;
breakpointItem.element = element;
breakpointItem.checkbox = checkbox;
this._items[breakpointId] = breakpointItem;
}
},
+ _breakpointResolved: function(event)
+ {
+ var breakpoint = event.data;
+ this._breakpointRemoved({ data: breakpoint.id });
+ this._breakpointAdded({ data: breakpoint });
+ },
+
+ _parsedScriptSource: function(event)
+ {
+ var url = event.data.sourceURL;
+ var breakpoints = WebInspector.debuggerModel.breakpoints;
+ for (var id in breakpoints) {
+ if (!(id in this._items))
+ this._breakpointAdded({ data: breakpoints[id] });
+ }
+ },
+
_breakpointEnableChanged: function(enabled, event)
{
var breakpointId = event.data;
_breakpointItemCheckboxClicked: function(breakpointId, event)
{
- this._setBreakpointEnabled(breakpointId, event.target.checked);
+ var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId);
+ WebInspector.debuggerModel.updateBreakpoint(breakpointId, breakpoint.condition, event.target.checked);
// Breakpoint element may have it's own click handler.
event.stopPropagation();
_setupBreakpointElement: function(data, element)
{
+ var sourceID;
+ var lineNumber = data.lineNumber;
+ if (data.locations.length) {
+ sourceID = data.locations[0].sourceID;
+ lineNumber = data.locations[0].lineNumber;
+ }
+
var displayName = data.url ? WebInspector.displayNameForURL(data.url) : WebInspector.UIString("(program)");
- var labelElement = document.createTextNode(displayName + ":" + data.lineNumber);
+ var labelElement = document.createTextNode(displayName + ":" + (lineNumber + 1));
element.appendChild(labelElement);
var sourceTextElement = document.createElement("div");
sourceTextElement.className = "source-text monospace";
element.appendChild(sourceTextElement);
- function didGetSourceLine(text)
- {
- sourceTextElement.textContent = text;
+ if (sourceID) {
+ function didGetSourceLine(text)
+ {
+ sourceTextElement.textContent = text;
+ }
+ var script = WebInspector.debuggerModel.scriptForSourceID(sourceID);
+ script.sourceLine(lineNumber, didGetSourceLine.bind(this));
}
- var script = WebInspector.debuggerModel.scriptForSourceID(data.sourceID);
- script.sourceLine(data.lineNumber, didGetSourceLine.bind(this));
element.addStyleClass("cursor-pointer");
- var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, data.lineNumber);
+ var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, data.lineNumber + 1);
element.addEventListener("click", clickHandler, false);
},
return breakpoint.id;
},
- _setBreakpointEnabled: function(breakpointId, enabled)
- {
- var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId);
- WebInspector.debuggerModel.removeBreakpoint(breakpointId);
- WebInspector.debuggerModel.setBreakpoint(breakpoint.sourceID, breakpoint.line, enabled, breakpoint.condition);
- },
-
_removeBreakpoint: function(breakpointId)
{
WebInspector.debuggerModel.removeBreakpoint(breakpointId);
this._paused = false;
this._callFrames = [];
this._breakpoints = {};
- this._sourceIDAndLineToBreakpointId = {};
this._scripts = {};
InspectorBackend.registerDomainDispatcher("Debugger", new WebInspector.DebuggerDispatcher(this));
FailedToParseScriptSource: "failed-to-parse-script-source",
ScriptSourceChanged: "script-source-changed",
BreakpointAdded: "breakpoint-added",
- BreakpointRemoved: "breakpoint-removed"
+ BreakpointRemoved: "breakpoint-removed",
+ BreakpointResolved: "breakpoint-resolved"
}
WebInspector.DebuggerModel.prototype = {
+ enableDebugger: function()
+ {
+ InspectorBackend.enableDebugger();
+ if (this._breakpointsPushedToBackend)
+ return;
+ var breakpoints = WebInspector.settings.breakpoints;
+ for (var i = 0; i < breakpoints.length; ++i) {
+ var breakpoint = breakpoints[i];
+ if (typeof breakpoint.url !== "string" || typeof breakpoint.lineNumber !== "number" || typeof breakpoint.columnNumber !== "number" ||
+ typeof breakpoint.condition !== "string" || typeof breakpoint.enabled !== "boolean")
+ continue;
+ this.setBreakpoint(breakpoint.url, breakpoint.lineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled);
+ }
+ this._breakpointsPushedToBackend = true;
+ },
+
+ disableDebugger: function()
+ {
+ InspectorBackend.disableDebugger();
+ },
+
continueToLine: function(sourceID, lineNumber)
{
- function didSetBreakpoint(breakpointId, actualLineNumber)
+ InspectorBackend.continueToLocation(sourceID, lineNumber, 0);
+ },
+
+ setBreakpoint: function(url, lineNumber, columnNumber, condition, enabled)
+ {
+ function didSetBreakpoint(breakpointsPushedToBackend, breakpointId, locations)
{
if (!breakpointId)
return;
- if (this.findBreakpoint(sourceID, actualLineNumber)) {
- InspectorBackend.removeBreakpoint(breakpointId);
- return;
- }
- if ("_continueToLineBreakpointId" in this)
- InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId);
- this._continueToLineBreakpointId = breakpointId;
+ var breakpoint = new WebInspector.Breakpoint(breakpointId, url, "", lineNumber, columnNumber, condition, enabled);
+ breakpoint.locations = locations;
+ this._breakpoints[breakpointId] = breakpoint;
+ if (breakpointsPushedToBackend)
+ this._saveBreakpoints();
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint);
}
- var breakpoint = { sourceID: sourceID, lineNumber: lineNumber, columnNumber: 1, condition: "", enabled: true };
- InspectorBackend.setBreakpoint(breakpoint, didSetBreakpoint.bind(this));
- if (this._paused)
- InspectorBackend.resume();
+ InspectorBackend.setJavaScriptBreakpoint(url, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this, this._breakpointsPushedToBackend));
},
- setBreakpoint: function(sourceID, lineNumber, enabled, condition)
+ setBreakpointBySourceId: function(sourceID, lineNumber, columnNumber, condition, enabled)
{
function didSetBreakpoint(breakpointId, actualLineNumber, actualColumnNumber)
{
if (!breakpointId)
return;
- breakpoint.originalLineNumber = breakpoint.lineNumber;
- breakpoint.originalColumnumber = breakpoint.columnNumber;
- breakpoint.lineNumber = actualLineNumber;
- breakpoint.columnNumber = actualColumnNumber;
- this._breakpointSetOnBackend(breakpointId, breakpoint, false);
+ var breakpoint = new WebInspector.Breakpoint(breakpointId, "", sourceID, lineNumber, columnNumber, condition, enabled);
+ breakpoint.addLocation(sourceID, actualLineNumber, actualColumnNumber);
+ this._breakpoints[breakpointId] = breakpoint;
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint);
}
- var breakpoint = { sourceID: sourceID, lineNumber: lineNumber, columnNumber: 1, condition: condition, enabled: enabled };
- InspectorBackend.setBreakpoint(breakpoint, didSetBreakpoint.bind(this));
+ InspectorBackend.setJavaScriptBreakpointBySourceId(sourceID, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this));
},
removeBreakpoint: function(breakpointId)
{
- InspectorBackend.removeBreakpoint(breakpointId);
+ InspectorBackend.removeJavaScriptBreakpoint(breakpointId);
var breakpoint = this._breakpoints[breakpointId];
delete this._breakpoints[breakpointId];
- delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)];
+ this._saveBreakpoints();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId);
- breakpoint.dispatchEventToListeners("removed");
},
- _breakpointSetOnBackend: function(breakpointId, breakpointData, restored)
+ updateBreakpoint: function(breakpointId, condition, enabled)
+ {
+ var breakpoint = this._breakpoints[breakpointId];
+ this.removeBreakpoint(breakpointId);
+ if (breakpoint.url)
+ this.setBreakpoint(breakpoint.url, breakpoint.lineNumber, breakpoint.columnNumber, condition, enabled);
+ else
+ this.setBreakpointBySourceId(breakpoint.sourceID, breakpoint.lineNumber, breakpoint.columnNumber, condition, enabled);
+ },
+
+ _breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber)
{
- var sourceIDAndLine = this._encodeSourceIDAndLine(breakpointData.sourceID, breakpointData.lineNumber);
- if (sourceIDAndLine in this._sourceIDAndLineToBreakpointId) {
- InspectorBackend.removeBreakpoint(breakpointId);
+ var breakpoint = this._breakpoints[breakpointId];
+ if (!breakpoint)
return;
+ breakpoint.addLocation(sourceID, lineNumber, columnNumber);
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, breakpoint);
+ },
+
+ _saveBreakpoints: function()
+ {
+ var serializedBreakpoints = [];
+ for (var id in this._breakpoints) {
+ var breakpoint = this._breakpoints[id];
+ if (!breakpoint.url)
+ continue;
+ var serializedBreakpoint = {};
+ serializedBreakpoint.url = breakpoint.url;
+ serializedBreakpoint.lineNumber = breakpoint.lineNumber;
+ serializedBreakpoint.columnNumber = breakpoint.columnNumber;
+ serializedBreakpoint.condition = breakpoint.condition;
+ serializedBreakpoint.enabled = breakpoint.enabled;
+ serializedBreakpoints.push(serializedBreakpoint);
}
+ WebInspector.settings.breakpoints = serializedBreakpoints;
+ },
- var breakpoint = new WebInspector.Breakpoint(this, breakpointId, breakpointData);
- breakpoint.restored = restored;
- breakpoint.originalLineNumber = breakpointData.originalLineNumber;
- this._breakpoints[breakpointId] = breakpoint;
- this._sourceIDAndLineToBreakpointId[sourceIDAndLine] = breakpointId;
- this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint);
+ get breakpoints()
+ {
+ return this._breakpoints;
},
breakpointForId: function(breakpointId)
findBreakpoint: function(sourceID, lineNumber)
{
- var sourceIDAndLine = this._encodeSourceIDAndLine(sourceID, lineNumber);
- var breakpointId = this._sourceIDAndLineToBreakpointId[sourceIDAndLine];
- return this._breakpoints[breakpointId];
- },
-
- _encodeSourceIDAndLine: function(sourceID, lineNumber)
- {
- return sourceID + ":" + lineNumber;
+ for (var id in this._breakpoints) {
+ var locations = this._breakpoints[id].locations;
+ for (var i = 0; i < locations.length; ++i) {
+ if (locations[i].sourceID == sourceID && locations[i].lineNumber + 1 === lineNumber)
+ return this._breakpoints[id];
+ }
+ }
},
reset: function()
{
this._paused = false;
this._callFrames = [];
- this._breakpoints = {};
- delete this._oneTimeBreakpoint;
- this._sourceIDAndLineToBreakpointId = {};
+ for (var id in this._breakpoints) {
+ var breakpoint = this._breakpoints[id];
+ if (!breakpoint.url)
+ this.removeBreakpoint(id);
+ else
+ breakpoint.locations = [];
+ }
this._scripts = {};
},
var diff = Array.diff(oldSource.split("\n"), script.source.split("\n"));
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
- if (breakpoint.sourceID !== sourceID)
- continue;
- breakpoint.remove();
- var lineNumber = breakpoint.line - 1;
+ if (breakpoint.url) {
+ if (breakpoint.url !== script.sourceURL)
+ continue;
+ } else {
+ if (breakpoint.sourceID !== sourceID)
+ continue;
+ }
+ this.removeBreakpoint(breakpoint.id);
+ var lineNumber = breakpoint.lineNumber;
var newLineNumber = diff.left[lineNumber].row;
if (newLineNumber === undefined) {
for (var i = lineNumber - 1; i >= 0; --i) {
break;
}
}
- if (newLineNumber !== undefined)
- this.setBreakpoint(sourceID, newLineNumber + 1, breakpoint.enabled, breakpoint.condition);
+ if (newLineNumber === undefined)
+ continue;
+ if (breakpoint.url)
+ this.setBreakpoint(breakpoint.url, newLineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled);
+ else
+ this.setBreakpointBySourceId(sourceID, newLineNumber, breakpoint.columnNumber, breakpoint.condition, breakpoint.enabled);
}
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ScriptSourceChanged, { sourceID: sourceID, oldSource: oldSource });
{
this._paused = true;
this._callFrames = details.callFrames;
- if ("_continueToLineBreakpointId" in this) {
- InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId);
- delete this._continueToLineBreakpointId;
- }
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details);
},
this._debuggerModel._failedToParseScriptSource(sourceURL, source, startingLine, errorLine, errorMessage);
},
- breakpointResolved: function(breakpointId, breakpoint)
+ breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber)
{
- this._debuggerModel._breakpointSetOnBackend(breakpointId, breakpoint, true);
+ this._debuggerModel._breakpointResolved(breakpointId, sourceID, lineNumber, columnNumber);
},
didCreateWorker: function()
{
function extractSourceLine()
{
- lineNumber -= this.startingLine;
+ lineNumber -= this.lineOffset;
callback(this._source.substring(this._lineEndings[lineNumber - 1], this._lineEndings[lineNumber]));
}
if (this._debuggerEnabled) {
WebInspector.settings.debuggerEnabled = false;
- InspectorBackend.disableDebugger();
+ WebInspector.debuggerModel.disableDebugger();
} else {
WebInspector.settings.debuggerEnabled = !!optionalAlways;
- InspectorBackend.enableDebugger();
+ WebInspector.debuggerModel.enableDebugger();
}
},
this.installApplicationSetting("showInheritedComputedStyleProperties", false);
this.installApplicationSetting("showUserAgentStyles", true);
this.installApplicationSetting("watchExpressions", []);
+ this.installApplicationSetting("breakpoints", []);
- this.installProjectSetting("breakpoints", {});
this.installProjectSetting("nativeBreakpoints", []);
}
this._textViewer.endUpdates();
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
},
_setTextViewerDecorations: function()
if (this._executionLine)
this.setExecutionLine(this._executionLine);
- var breakpoints = this._breakpoints();
- for (var i = 0; i < breakpoints.length; ++i)
- this._addBreakpoint(breakpoints[i]);
+ this._breakpointIdToTextViewerLineNumber = {};
+ this._textViewerLineNumberToBreakpointId = {};
+ var breakpoints = WebInspector.debuggerModel.breakpoints;
+ for (var id in breakpoints)
+ this._breakpointAdded({ data: breakpoints[id] });
this._textViewer.resize();
this._textViewer.endUpdates();
},
+ _shouldDisplayBreakpoint: function(breakpoint)
+ {
+ if (this._url)
+ return this._url === breakpoint.url;
+ var scripts = this._contentProvider.scripts();
+ for (var i = 0; i < scripts.length; ++i) {
+ if (breakpoint.sourceID === scripts[i].sourceID)
+ return true;
+ }
+ return false;
+ },
+
performSearch: function(query, callback)
{
// Call searchCanceled since it will reset everything we need before doing a new search.
{
var breakpoint = event.data;
- if (breakpoint.sourceID in this._sourceIDSet())
- this._addBreakpoint(breakpoint);
- },
+ if (!this._shouldDisplayBreakpoint(breakpoint))
+ return;
- _addBreakpoint: function(breakpoint)
- {
- var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ var resolved = breakpoint.locations.length;
+ var breakpointLineNumber = breakpoint.lineNumber;
+ if (resolved)
+ breakpointLineNumber = breakpoint.locations[0].lineNumber;
+
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpointLineNumber);
if (textViewerLineNumber >= this._textModel.linesCount)
return;
- breakpoint.addEventListener("enable-changed", this._breakpointChanged, this);
- breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
- breakpoint.addEventListener("removed", this._breakpointRemoved, this);
+ var existingBreakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
+ if (existingBreakpointId) {
+ WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
+ return;
+ }
- this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
+ this._breakpointIdToTextViewerLineNumber[breakpoint.id] = textViewerLineNumber;
+ this._textViewerLineNumberToBreakpointId[textViewerLineNumber] = breakpoint.id;
+ this._setBreakpointDecoration(textViewerLineNumber, resolved, breakpoint.enabled, !!breakpoint.condition);
},
_breakpointRemoved: function(event)
{
- var breakpoint = event.target;
+ var breakpointId = event.data;
- breakpoint.removeEventListener("enable-changed", null, this);
- breakpoint.removeEventListener("condition-changed", null, this);
- breakpoint.removeEventListener("removed", null, this);
+ var textViewerLineNumber = this._breakpointIdToTextViewerLineNumber[breakpointId];
+ if (textViewerLineNumber === undefined)
+ return;
- var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ delete this._breakpointIdToTextViewerLineNumber[breakpointId];
+ delete this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
this._removeBreakpointDecoration(textViewerLineNumber);
},
- _breakpointChanged: function(event)
+ _breakpointResolved: function(event)
{
- var breakpoint = event.target;
- var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
- this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
+ var breakpoint = event.data;
+ this._breakpointRemoved({ data: breakpoint.id });
+ this._breakpointAdded({ data: breakpoint });
},
- _setBreakpointDecoration: function(lineNumber, enabled, hasCondition)
+ _setBreakpointDecoration: function(lineNumber, resolved, enabled, hasCondition)
{
this._textViewer.beginUpdates();
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
- if (enabled)
- this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
- else
+ if (!enabled)
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
if (hasCondition)
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
- else
- this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this._textViewer.endUpdates();
},
contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, originalLineNumber));
- var breakpoint = this._findBreakpoint(originalLineNumber);
+ var breakpoint = this._findBreakpoint(textViewerLineNumber);
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, originalLineNumber, "", true));
function addConditionalBreakpoint()
{
- this._setBreakpointDecoration(textViewerLineNumber, true, true);
+ this._setBreakpointDecoration(textViewerLineNumber, true, true, true);
function didEditBreakpointCondition(committed, condition)
{
this._removeBreakpointDecoration(textViewerLineNumber);
contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
} else {
// This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
- contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), breakpoint.remove.bind(breakpoint));
+ function removeBreakpoint()
+ {
+ WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
+ }
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint);
function editBreakpointCondition()
{
function didEditBreakpointCondition(committed, condition)
{
- if (committed) {
- breakpoint.remove();
- this._setBreakpoint(originalLineNumber, breakpoint.enabled, condition);
- }
+ if (committed)
+ WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, condition, breakpoint.enabled);
}
this._editBreakpointCondition(textViewerLineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
}
contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this));
function setBreakpointEnabled(enabled)
{
- breakpoint.remove();
- this._setBreakpoint(originalLineNumber, enabled, breakpoint.condition);
+ WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, enabled);
}
if (breakpoint.enabled)
contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false));
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
- var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(target.lineNumber);
+ var textViewerLineNumber = target.lineNumber;
+ var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(textViewerLineNumber);
- var breakpoint = this._findBreakpoint(originalLineNumber);
+ var breakpoint = this._findBreakpoint(textViewerLineNumber);
if (breakpoint) {
- breakpoint.remove();
if (event.shiftKey)
- this._setBreakpoint(originalLineNumber, !breakpoint.enabled, breakpoint.condition);
+ WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, !breakpoint.enabled);
+ else
+ WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
} else
this._setBreakpoint(originalLineNumber, true, "");
event.preventDefault();
var sourceID = this._sourceIDForLine(lineNumber);
if (!sourceID)
return;
- WebInspector.debuggerModel.continueToLine(sourceID, lineNumber + 1);
+ WebInspector.debuggerModel.continueToLine(sourceID, lineNumber);
},
_doubleClick: function(event)
_setBreakpoint: function(lineNumber, enabled, condition)
{
- var sourceID = this._sourceIDForLine(lineNumber);
- if (!sourceID)
- return;
- WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber + 1, enabled, condition);
+ if (this._url)
+ WebInspector.debuggerModel.setBreakpoint(this._url, lineNumber, 0, condition, enabled);
+ else {
+ var sourceID = this._sourceIDForLine(lineNumber);
+ if (!sourceID)
+ return;
+ WebInspector.debuggerModel.setBreakpointBySourceId(sourceID, lineNumber, 0, condition, enabled);
+ }
if (!WebInspector.panels.scripts.breakpointsActivated)
WebInspector.panels.scripts.toggleBreakpointsClicked();
},
- _breakpoints: function()
+ _findBreakpoint: function(textViewerLineNumber)
{
- var sourceIDSet = this._sourceIDSet();
- return WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID in sourceIDSet; });
- },
-
- _findBreakpoint: function(lineNumber)
- {
- var sourceID = this._sourceIDForLine(lineNumber);
- return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber + 1);
+ var breakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
+ return WebInspector.debuggerModel.breakpointForId(breakpointId);
},
_sourceIDForLine: function(lineNumber)
}
}
return sourceIDForLine;
- },
-
- _sourceIDSet: function()
- {
- var scripts = this._contentProvider.scripts();
- var sourceIDSet = {};
- for (var i = 0; i < scripts.length; ++i)
- sourceIDSet[scripts[i].sourceID] = true;
- return sourceIDSet;
}
}
InspectorBackend.populateScriptObjects(onPopulateScriptObjects);
if (Preferences.debuggerAlwaysEnabled || WebInspector.settings.debuggerEnabled)
- InspectorBackend.enableDebugger();
+ this.debuggerModel.enableDebugger();
if (Preferences.profilerAlwaysEnabled || WebInspector.settings.profilerEnabled)
InspectorBackend.enableProfiler();
if (WebInspector.settings.monitoringXHREnabled)
+2011-02-01 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: introduce new api for managing JavaScript breakpoints.
+ https://bugs.webkit.org/show_bug.cgi?id=53235
+
+ * src/WebDevToolsAgentImpl.cpp:
+ (WebKit::WebDevToolsAgent::shouldInterruptForMessage):
+
2011-02-02 Evan Martin <evan@chromium.org>
Unreviewed, DEPS change.
if (!InspectorBackendDispatcher::getCommandName(message, &commandName))
return false;
return commandName == InspectorBackendDispatcher::pauseCmd
- || commandName == InspectorBackendDispatcher::setBreakpointCmd
- || commandName == InspectorBackendDispatcher::removeBreakpointCmd
+ || commandName == InspectorBackendDispatcher::setJavaScriptBreakpointCmd
+ || commandName == InspectorBackendDispatcher::removeJavaScriptBreakpointCmd
|| commandName == InspectorBackendDispatcher::activateBreakpointsCmd
|| commandName == InspectorBackendDispatcher::deactivateBreakpointsCmd
|| commandName == InspectorBackendDispatcher::startProfilingCmd