Diff
Modified: trunk/LayoutTests/ChangeLog (155131 => 155132)
--- trunk/LayoutTests/ChangeLog 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/LayoutTests/ChangeLog 2013-09-05 18:00:53 UTC (rev 155132)
@@ -1,3 +1,18 @@
+2013-09-05 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Breakpoint Actions
+ https://bugs.webkit.org/show_bug.cgi?id=120576
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector-protocol/debugger/resources/breakpoint.js:
+ * inspector-protocol/debugger/setBreakpoint-actions-expected.txt: Added.
+ * inspector-protocol/debugger/setBreakpoint-actions.html: Added.
+ * inspector-protocol/debugger/setBreakpoint-options-exception-expected.txt: Added.
+ * inspector-protocol/debugger/setBreakpoint-options-exception.html: Added.
+ * inspector-protocol/resources/console-helper.js: Added.
+ (ConsoleHelper.simplifiedConsoleMessage):
+
2013-09-05 Simon Fraser <[email protected]>
Fix repaint issue on "paints into ancestor" filtered layers
Modified: trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js (155131 => 155132)
--- trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js 2013-09-05 18:00:53 UTC (rev 155132)
@@ -12,3 +12,8 @@
{
log("inside breakpointAutomaticallyContinue");
}
+
+function breakpointActions(a, b)
+{
+ log("inside breakpointActions a:(" + a + ") b:(" + b + ")");
+}
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions-expected.txt (0 => 155132)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions-expected.txt 2013-09-05 18:00:53 UTC (rev 155132)
@@ -0,0 +1,24 @@
+CONSOLE MESSAGE: log-action-before
+CONSOLE MESSAGE: line 1: eval-action
+CONSOLE MESSAGE: log-action-after
+CONSOLE MESSAGE: log-action-before
+CONSOLE MESSAGE: line 1: eval-action
+CONSOLE MESSAGE: log-action-after
+Debugger.setBreakpoint options.actions
+
+Breakpoints Enabled
+Found breakpoint.js
+Running breakpointActions a few times that should not trigger
+inside breakpointActions a:(1) b:(undefined)
+inside breakpointActions a:(2) b:(12)
+inside breakpointActions a:(2) b:([object Object])
+Running breakpointActions to triggering the breakpoint actions
+inside breakpointActions a:(12) b:([object Object])
+PASS: Console Message: {"source":"_javascript_","level":"log","text":"log-action-before","location":"breakpoint.js:19:1"}
+PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object"}]}
+PASS: Console Message: {"source":"_javascript_","level":"log","text":"log-action-after","location":"breakpoint.js:19:1"}
+inside breakpointActions a:(100) b:([object HTMLBodyElement])
+PASS: Console Message: {"source":"_javascript_","level":"log","text":"log-action-before","location":"breakpoint.js:19:1"}
+PASS: Console Message: {"source":"console-api","level":"log","text":"eval-action","location":"???:1:26","parameters":[{"type":"string"},{"type":"number"},{"type":"object","subtype":"node"}]}
+PASS: Console Message: {"source":"_javascript_","level":"log","text":"log-action-after","location":"breakpoint.js:19:1"}
+
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions.html (0 => 155132)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions.html (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-actions.html 2013-09-05 18:00:53 UTC (rev 155132)
@@ -0,0 +1,82 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function test()
+{
+ InspectorTest.importScript("../../../../inspector-protocol/resources/console-helper.js");
+
+ InspectorTest.sendCommand("Console.enable", {});
+ InspectorTest.sendCommand("Debugger.enable", {});
+ InspectorTest.sendCommand("Debugger.setBreakpointsActive", {active: true}, function() {
+ InspectorTest.log("Breakpoints Enabled");
+ });
+
+ var expectLogs = false;
+ var logsSeen = 0;
+ const expectedLogs = 6;
+
+ InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
+ {
+ if (/resources\/breakpoint\.js$/.test(messageObject.params.url)) {
+ InspectorTest.log("Found breakpoint.js");
+ var scriptIdentifier = messageObject.params.scriptId;
+ var location = {scriptId: scriptIdentifier, lineNumber: 18, columnNumber: 0};
+ var options = {
+ condition: "a > 10",
+ autoContinue: true,
+ actions: [
+ {"type": "log", "data": "log-action-before"},
+ {"type": "sound"},
+ {"type": "evaluate", "data": "(function() { console.log('eval-action', a, b); })()"},
+ {"type": "log", "data": "log-action-after"}
+ ]
+ };
+
+ InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location, options: options}, function(responseObject) {
+ InspectorTest.checkForError(responseObject);
+ breakpointIdentifier = responseObject.result.breakpointId;
+ InspectorTest.log("Running breakpointActions a few times that should not trigger");
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(1)"});
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(2, 12)"});
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(2, {x:1,y:2})"}, function() {
+ expectLogs = true;
+ InspectorTest.log("Running breakpointActions to triggering the breakpoint actions");
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(12, {x:1,y:2})"}, function() {
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(100, document.body)"});
+ });
+ });
+ });
+ }
+ }
+
+ InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
+ {
+ InspectorTest.log("Hit Breakpoint!");
+
+ InspectorTest.log("FAIL: should not have hit breakpoint, autoContinue was true");
+ InspectorTest.completeTest();
+ }
+
+ InspectorTest.eventHandler["Console.messageAdded"] = function(messageObject)
+ {
+ if (!expectLogs) {
+ InspectorTest.log("FAIL: unexpected log, logs should only have come from breakpoint actions.");
+ InspectorTest.completeTest();
+ return;
+ }
+
+ var simplifiedMessage = ConsoleHelper.simplifiedConsoleMessage(messageObject);
+ InspectorTest.log("PASS: Console Message: " + JSON.stringify(simplifiedMessage));
+
+ if (++logsSeen === expectedLogs)
+ InspectorTest.completeTest();
+ }
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Debugger.setBreakpoint options.actions</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception-expected.txt (0 => 155132)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception-expected.txt 2013-09-05 18:00:53 UTC (rev 155132)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 1: TypeError: undefined is not an object (evaluating 'this.will.cause')
+CONSOLE MESSAGE: line 1: TypeError: undefined is not an object (evaluating 'this.will.cause')
+Debugger.setBreakpoint options.condition or options.action with exception
+
+Breakpoints Enabled
+Found breakpoint.js
+Running breakpointWithCondition to trigger condition exception.
+inside breakpointWithCondition a:(1) b:(2) a+b:(3)
+PASS: Console Message: {"source":"_javascript_","level":"error","text":"TypeError: undefined is not an object (evaluating 'this.will.cause')","location":"undefined:1:10"}
+Running breakpointActions to trigger actions exception.
+inside breakpointActions a:(1) b:(2)
+PASS: Console Message: {"source":"_javascript_","level":"error","text":"TypeError: undefined is not an object (evaluating 'this.will.cause')","location":"undefined:1:10"}
+
Added: trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception.html (0 => 155132)
--- trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception.html (rev 0)
+++ trunk/LayoutTests/inspector-protocol/debugger/setBreakpoint-options-exception.html 2013-09-05 18:00:53 UTC (rev 155132)
@@ -0,0 +1,63 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function test()
+{
+ InspectorTest.importScript("../../../../inspector-protocol/resources/console-helper.js");
+
+ InspectorTest.sendCommand("Console.enable", {});
+ InspectorTest.sendCommand("Debugger.enable", {});
+ InspectorTest.sendCommand("Debugger.setBreakpointsActive", {active: true}, function() {
+ InspectorTest.log("Breakpoints Enabled");
+ });
+
+ var logsSeen = 0;
+ const expectedLogs = 2;
+
+ InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
+ {
+ if (/resources\/breakpoint\.js$/.test(messageObject.params.url)) {
+ InspectorTest.log("Found breakpoint.js");
+ var scriptIdentifier = messageObject.params.scriptId;
+ var location = {scriptId: scriptIdentifier, lineNumber: 8, columnNumber: 0};
+ var options = {condition: "this.will.cause.exception", autoContinue: true};
+ InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location, options: options}, function(responseObject) {
+ InspectorTest.checkForError(responseObject);
+ InspectorTest.log("Running breakpointWithCondition to trigger condition exception.");
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointWithCondition(1,2)"}, function() {
+ location = {scriptId: scriptIdentifier, lineNumber: 18, columnNumber: 0};
+ options = {actions: [{"type": "evaluate", "data": "this.will.cause.exception"}], autoContinue: true};
+ InspectorTest.sendCommand("Debugger.setBreakpoint", {location: location, options: options}, function(responseObject) {
+ InspectorTest.log("Running breakpointActions to trigger actions exception.");
+ InspectorTest.sendCommand("Runtime.evaluate", {_expression_: "breakpointActions(1,2)"});
+ });
+ });
+ });
+ }
+ }
+
+ InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
+ {
+ InspectorTest.log("Hit Breakpoint!");
+
+ InspectorTest.log("FAIL: should not have hit breakpoint, autoContinue was true");
+ InspectorTest.completeTest();
+ }
+
+ InspectorTest.eventHandler["Console.messageAdded"] = function(messageObject)
+ {
+ var simplifiedMessage = ConsoleHelper.simplifiedConsoleMessage(messageObject);
+ InspectorTest.log("PASS: Console Message: " + JSON.stringify(simplifiedMessage));
+
+ if (++logsSeen === expectedLogs)
+ InspectorTest.completeTest();
+ }
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Debugger.setBreakpoint options.condition or options.action with exception</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector-protocol/resources/console-helper.js (0 => 155132)
--- trunk/LayoutTests/inspector-protocol/resources/console-helper.js (rev 0)
+++ trunk/LayoutTests/inspector-protocol/resources/console-helper.js 2013-09-05 18:00:53 UTC (rev 155132)
@@ -0,0 +1,31 @@
+window.ConsoleHelper = {};
+
+ConsoleHelper.simplifiedConsoleMessage = function(messageObject)
+{
+ function basename(url)
+ {
+ return url.substring(url.lastIndexOf("/") + 1) || "???";
+ }
+
+ var message = messageObject.params.message;
+ var obj = {
+ source: message.source,
+ level: message.level,
+ text: message.text,
+ location: basename(message.url) + ":" + message.line + ":" + message.column
+ };
+
+ if (message.parameters) {
+ var params = [];
+ for (var i = 0; i < message.parameters.length; ++i) {
+ var param = message.parameters[i];
+ var o = {type: param.type};
+ if (param.subtype)
+ o.subtype = param.subtype;
+ params.push(o);
+ }
+ obj.parameters = params;
+ }
+
+ return obj;
+}
Modified: trunk/Source/WebCore/ChangeLog (155131 => 155132)
--- trunk/Source/WebCore/ChangeLog 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/ChangeLog 2013-09-05 18:00:53 UTC (rev 155132)
@@ -1,3 +1,41 @@
+2013-09-05 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: Breakpoint Actions
+ https://bugs.webkit.org/show_bug.cgi?id=120576
+
+ Reviewed by Timothy Hatcher.
+
+ Tests: inspector-protocol/debugger/setBreakpoint-actions.html
+ inspector-protocol/debugger/setBreakpoint-options-exception.html
+
+ * inspector/ScriptBreakpoint.h:
+ (WebCore::ScriptBreakpointAction::ScriptBreakpointAction):
+ (WebCore::ScriptBreakpoint::ScriptBreakpoint):
+ Struct for a breakpoint action. Type and string of data.
+
+ * bindings/js/ScriptDebugServer.h:
+ * bindings/js/ScriptDebugServer.cpp:
+ (WebCore::ScriptDebugServer::hasBreakpoint):
+ (WebCore::ScriptDebugServer::evaluateBreakpointAction):
+ (WebCore::ScriptDebugServer::evaluateBreakpointActions):
+ (WebCore::ScriptDebugServer::updateCallFrameAndPauseIfNeeded):
+ (WebCore::ScriptDebugServer::pauseIfNeeded):
+ When a breakpoint is triggered evaluate each of its breakpoint
+ actions in order. If there are exceptions, log them.
+
+ * inspector/Inspector.json:
+ * inspector/InspectorDebuggerAgent.cpp:
+ (WebCore::buildObjectForBreakpointCookie):
+ (WebCore::InspectorDebuggerAgent::didParseSource):
+ Save and restore breakpoint actions where needed.
+
+ (WebCore::breakpointActionTypeForString):
+ (WebCore::breakpointActionsFromProtocol):
+ (WebCore::InspectorDebuggerAgent::setBreakpointByUrl):
+ (WebCore::InspectorDebuggerAgent::setBreakpoint):
+ Parse optional breakpoint actions from the protocol into
+ ScriptBreakpointAction objects.
+
2013-09-05 Simon Fraser <[email protected]>
Fix repaint issue on "paints into ancestor" filtered layers
Modified: trunk/Source/WebCore/bindings/js/ScriptDebugServer.cpp (155131 => 155132)
--- trunk/Source/WebCore/bindings/js/ScriptDebugServer.cpp 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/bindings/js/ScriptDebugServer.cpp 2013-09-05 18:00:53 UTC (rev 155132)
@@ -35,11 +35,14 @@
#include "ContentSearchUtils.h"
#include "Frame.h"
+#include "JSDOMWindowCustom.h"
#include "JSJavaScriptCallFrame.h"
#include "_javascript_CallFrame.h"
+#include "PageConsole.h"
#include "ScriptBreakpoint.h"
#include "ScriptDebugListener.h"
#include "ScriptValue.h"
+#include "Sound.h"
#include <debugger/DebuggerCallFrame.h>
#include <parser/SourceProvider.h>
#include <runtime/JSLock.h>
@@ -174,11 +177,46 @@
JSValue result = m_currentCallFrame->evaluate(breaksVector.at(i).condition, exception);
if (exception) {
// An erroneous condition counts as "false".
+ reportException(m_currentCallFrame->exec(), exception);
return false;
}
return result.toBoolean(m_currentCallFrame->exec());
}
+bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& breakpointAction) const
+{
+ switch (breakpointAction.type) {
+ case ScriptBreakpointActionTypeLog: {
+ DOMWindow* window = asJSDOMWindow(m_currentCallFrame->dynamicGlobalObject())->impl();
+ if (PageConsole* console = window->pageConsole())
+ console->addMessage(JSMessageSource, LogMessageLevel, breakpointAction.data);
+ break;
+ }
+ case ScriptBreakpointActionTypeEvaluate: {
+ JSValue exception;
+ JSValue result = m_currentCallFrame->evaluate(breakpointAction.data, exception);
+ if (exception)
+ reportException(m_currentCallFrame->exec(), exception);
+ break;
+ }
+ case ScriptBreakpointActionTypeSound:
+ systemBeep();
+ break;
+ }
+
+ return true;
+}
+
+bool ScriptDebugServer::evaluateBreakpointActions(const ScriptBreakpoint& breakpoint) const
+{
+ for (size_t i = 0; i < breakpoint.actions.size(); ++i) {
+ if (!evaluateBreakpointAction(breakpoint.actions[i]))
+ return false;
+ }
+
+ return true;
+}
+
void ScriptDebugServer::clearBreakpoints()
{
m_sourceIdToBreakpoints.clear();
@@ -403,7 +441,7 @@
void ScriptDebugServer::updateCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
{
- ASSERT(m_currentCallFrame);
+ // ASSERT(m_currentCallFrame);
if (!m_currentCallFrame)
return;
@@ -430,7 +468,7 @@
return;
if (didHitBreakpoint) {
- // FIXME: Evaluate breakpoint actions here.
+ evaluateBreakpointActions(breakpoint);
if (breakpoint.autoContinue)
return;
}
Modified: trunk/Source/WebCore/bindings/js/ScriptDebugServer.h (155131 => 155132)
--- trunk/Source/WebCore/bindings/js/ScriptDebugServer.h 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/bindings/js/ScriptDebugServer.h 2013-09-05 18:00:53 UTC (rev 155132)
@@ -125,6 +125,8 @@
virtual bool isContentScript(JSC::ExecState*);
bool hasBreakpoint(intptr_t sourceID, const TextPosition&, ScriptBreakpoint* hitBreakpoint) const;
+ bool evaluateBreakpointAction(const ScriptBreakpointAction&) const;
+ bool evaluateBreakpointActions(const ScriptBreakpoint&) const;
void dispatchFunctionToListeners(_javascript_ExecutionCallback, JSC::JSGlobalObject*);
void dispatchFunctionToListeners(const ListenerSet& listeners, _javascript_ExecutionCallback callback);
Modified: trunk/Source/WebCore/inspector/Inspector.json (155131 => 155132)
--- trunk/Source/WebCore/inspector/Inspector.json 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/inspector/Inspector.json 2013-09-05 18:00:53 UTC (rev 155132)
@@ -2661,10 +2661,20 @@
"description": "Location in the source code."
},
{
+ "id": "BreakpointAction",
+ "type": "object",
+ "properties": [
+ { "name": "type", "type": "string", "enum": ["log", "evaluate", "sound"], "description": "Different kinds of breakpoint actions." },
+ { "name": "data", "type": "string", "optional": true, "description": "Data associated with this breakpoint type (e.g. for type \"eval\" this is the _javascript_ string to evalulate)." }
+ ],
+ "description": "Action to perform when a breakpoint is triggered."
+ },
+ {
"id": "BreakpointOptions",
"type": "object",
"properties": [
{ "name": "condition", "type": "string", "optional": true, "description": "_expression_ to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this _expression_ evaluates to true." },
+ { "name": "actions", "type": "array", "optional": true, "items": { "$ref": "BreakpointAction" }, "description": "Actions to perform automatically when the breakpoint is triggered." },
{ "name": "autoContinue", "type": "boolean", "optional": true, "description": "Automatically continue after hitting this breakpoint and running actions." }
],
"description": "Extra options that modify breakpoint behavior."
Modified: trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp (155131 => 155132)
--- trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp 2013-09-05 18:00:53 UTC (rev 155132)
@@ -202,7 +202,7 @@
breakProgram(InspectorFrontend::Debugger::Reason::Assert, 0);
}
-static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, bool isRegex, bool autoContinue)
+static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue)
{
RefPtr<InspectorObject> breakpointObject = InspectorObject::create();
breakpointObject->setString("url", url);
@@ -211,6 +211,9 @@
breakpointObject->setString("condition", condition);
breakpointObject->setBoolean("isRegex", isRegex);
breakpointObject->setBoolean("autoContinue", autoContinue);
+ if (actions)
+ breakpointObject->setArray("actions", actions);
+
return breakpointObject;
}
@@ -223,6 +226,63 @@
return url == pattern;
}
+static bool breakpointActionTypeForString(const String& typeString, ScriptBreakpointActionType* output)
+{
+ if (typeString == TypeBuilder::getEnumConstantValue(TypeBuilder::Debugger::BreakpointAction::Type::Log)) {
+ *output = ScriptBreakpointActionTypeLog;
+ return true;
+ }
+ if (typeString == TypeBuilder::getEnumConstantValue(TypeBuilder::Debugger::BreakpointAction::Type::Evaluate)) {
+ *output = ScriptBreakpointActionTypeEvaluate;
+ return true;
+ }
+ if (typeString == TypeBuilder::getEnumConstantValue(TypeBuilder::Debugger::BreakpointAction::Type::Sound)) {
+ *output = ScriptBreakpointActionTypeSound;
+ return true;
+ }
+
+ return false;
+}
+
+static bool breakpointActionsFromProtocol(ErrorString* errorString, RefPtr<InspectorArray>& actions, Vector<ScriptBreakpointAction>* result)
+{
+ if (!actions)
+ return true;
+
+ unsigned actionsLength = actions->length();
+ if (!actionsLength)
+ return true;
+
+ result->reserveCapacity(actionsLength);
+ for (unsigned i = 0; i < actionsLength; ++i) {
+ RefPtr<InspectorValue> value = actions->get(i);
+ RefPtr<InspectorObject> object;
+ if (!value->asObject(&object)) {
+ *errorString = "BreakpointAction of incorrect type, expected object";
+ return false;
+ }
+
+ String typeString;
+ if (!object->getString("type", &typeString)) {
+ *errorString = "BreakpointAction had type missing";
+ return false;
+ }
+
+ ScriptBreakpointActionType type;
+ if (!breakpointActionTypeForString(typeString, &type)) {
+ *errorString = "BreakpointAction had unknown type";
+ return false;
+ }
+
+ String data;
+ object->getString("data", &data);
+
+ result->append(ScriptBreakpointAction(type, data));
+ }
+
+ return true;
+}
+
void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const RefPtr<InspectorObject>* options, TypeBuilder::Debugger::BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations)
{
locations = Array<TypeBuilder::Debugger::Location>::create();
@@ -244,15 +304,21 @@
String condition = emptyString();
bool autoContinue = false;
+ RefPtr<InspectorArray> actions;
if (options) {
(*options)->getString("condition", &condition);
(*options)->getBoolean("autoContinue", &autoContinue);
+ actions = (*options)->getArray("actions");
}
- breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, isRegex, autoContinue));
+ Vector<ScriptBreakpointAction> breakpointActions;
+ if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions))
+ return;
+
+ breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, actions, isRegex, autoContinue));
m_state->setObject(DebuggerAgentState::_javascript_Breakpoints, breakpointsCookie);
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, autoContinue);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue);
for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
if (!matches(it->value.url, url, isRegex))
continue;
@@ -286,17 +352,23 @@
String condition = emptyString();
bool autoContinue = false;
+ RefPtr<InspectorArray> actions;
if (options) {
(*options)->getString("condition", &condition);
(*options)->getBoolean("autoContinue", &autoContinue);
+ actions = (*options)->getArray("actions");
}
+ Vector<ScriptBreakpointAction> breakpointActions;
+ if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions))
+ return;
+
String breakpointId = scriptId + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end()) {
*errorString = "Breakpoint at specified location already exists.";
return;
}
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, autoContinue);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue);
actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint);
if (actualLocation)
*outBreakpointId = breakpointId;
@@ -655,7 +727,7 @@
sourceMapHeader = resource->response().httpHeaderField(sourceMapHTTPHeaderDeprecated);
if (!sourceMapHeader.isEmpty())
- return sourceMapHeader;
+ return sourceMapHeader;
}
}
}
@@ -698,6 +770,13 @@
breakpointObject->getNumber("columnNumber", &breakpoint.columnNumber);
breakpointObject->getString("condition", &breakpoint.condition);
breakpointObject->getBoolean("autoContinue", &breakpoint.autoContinue);
+ ErrorString errorString;
+ RefPtr<InspectorArray> actions = breakpointObject->getArray("actions");
+ if (!breakpointActionsFromProtocol(&errorString, actions, &breakpoint.actions)) {
+ ASSERT_NOT_REACHED();
+ continue;
+ }
+
RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(it->key, scriptId, breakpoint);
if (location)
m_frontend->breakpointResolved(it->key, location);
Modified: trunk/Source/WebCore/inspector/ScriptBreakpoint.h (155131 => 155132)
--- trunk/Source/WebCore/inspector/ScriptBreakpoint.h 2013-09-05 17:56:58 UTC (rev 155131)
+++ trunk/Source/WebCore/inspector/ScriptBreakpoint.h 2013-09-05 18:00:53 UTC (rev 155132)
@@ -30,10 +30,28 @@
#ifndef ScriptBreakpoint_h
#define ScriptBreakpoint_h
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
+typedef enum {
+ ScriptBreakpointActionTypeLog,
+ ScriptBreakpointActionTypeEvaluate,
+ ScriptBreakpointActionTypeSound
+} ScriptBreakpointActionType;
+
+struct ScriptBreakpointAction {
+ ScriptBreakpointAction(ScriptBreakpointActionType type, const String& data)
+ : type(type)
+ , data(data)
+ {
+ }
+
+ ScriptBreakpointActionType type;
+ String data;
+};
+
struct ScriptBreakpoint {
ScriptBreakpoint()
{
@@ -47,9 +65,19 @@
{
}
+ ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, Vector<ScriptBreakpointAction>& actions, bool autoContinue)
+ : lineNumber(lineNumber)
+ , columnNumber(columnNumber)
+ , condition(condition)
+ , actions(actions)
+ , autoContinue(autoContinue)
+ {
+ }
+
int lineNumber;
int columnNumber;
String condition;
+ Vector<ScriptBreakpointAction> actions;
bool autoContinue;
};