2011-04-07 Pavel Feldman <pfeldman@google.com>
authorpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Apr 2011 18:24:52 +0000 (18:24 +0000)
committerpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Apr 2011 18:24:52 +0000 (18:24 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: remove "enabled" from the setBreakpoint protocol.
        https://bugs.webkit.org/show_bug.cgi?id=58047

        * bindings/js/ScriptDebugServer.cpp:
        (WebCore::ScriptDebugServer::hasBreakpoint):
        * bindings/v8/DebuggerScript.js:
        ():
        * bindings/v8/ScriptDebugServer.cpp:
        (WebCore::ScriptDebugServer::setBreakpoint):
        * inspector/Inspector.json:
        * inspector/InspectorDebuggerAgent.cpp:
        (WebCore::buildObjectForBreakpointCookie):
        (WebCore::InspectorDebuggerAgent::setBreakpointByUrl):
        (WebCore::InspectorDebuggerAgent::setBreakpoint):
        (WebCore::InspectorDebuggerAgent::continueToLocation):
        (WebCore::InspectorDebuggerAgent::didParseSource):
        * inspector/InspectorDebuggerAgent.h:
        * inspector/ScriptBreakpoint.h:
        (WebCore::ScriptBreakpoint::ScriptBreakpoint):
        * inspector/front-end/DebuggerModel.js:
        (WebInspector.DebuggerModel.prototype.setBreakpoint):
        (WebInspector.DebuggerModel.prototype.setBreakpointBySourceId):
        * inspector/front-end/DebuggerPresentationModel.js:
        (WebInspector.DebuggerPresentationModel):
        (WebInspector.DebuggerPresentationModel.prototype._restoreBreakpoints):
        (WebInspector.DebuggerPresentationModel.prototype._updateBreakpointsAfterLiveEdit):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint.callback):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint):
        (WebInspector.DebuggerPresentationModel.prototype._setBreakpointInDebugger):
        (WebInspector.DebuggerPresentationModel.prototype._setBreakpointInDebugger.didRequestSourceMapping):
        (WebInspector.DebuggerPresentationModel.prototype._removeBreakpointFromDebugger):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled.afterUpdate):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled):
        (WebInspector.DebuggerPresentationModel.prototype.updateBreakpoint):
        (WebInspector.DebuggerPresentationModel.prototype.removeBreakpoint):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded.didRequestSourceMapping):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointRemoved):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointResolved):
        (WebInspector.DebuggerPresentationModel.prototype._restoreBreakpointsFromSettings):
        (WebInspector.DebuggerPresentationModel.prototype._saveBreakpoints):
        (WebInspector.DebuggerPresentationModel.prototype._reset):
        (WebInspector.PresentationBreakpoint):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@83190 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ScriptDebugServer.cpp
Source/WebCore/bindings/v8/DebuggerScript.js
Source/WebCore/bindings/v8/ScriptDebugServer.cpp
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorDebuggerAgent.cpp
Source/WebCore/inspector/InspectorDebuggerAgent.h
Source/WebCore/inspector/ScriptBreakpoint.h
Source/WebCore/inspector/front-end/DebuggerModel.js
Source/WebCore/inspector/front-end/DebuggerPresentationModel.js

index 0588133..7a6d578 100644 (file)
@@ -1,3 +1,51 @@
+2011-04-07  Pavel Feldman  <pfeldman@google.com>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: remove "enabled" from the setBreakpoint protocol.
+        https://bugs.webkit.org/show_bug.cgi?id=58047
+
+        * bindings/js/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::hasBreakpoint):
+        * bindings/v8/DebuggerScript.js:
+        ():
+        * bindings/v8/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::setBreakpoint):
+        * inspector/Inspector.json:
+        * inspector/InspectorDebuggerAgent.cpp:
+        (WebCore::buildObjectForBreakpointCookie):
+        (WebCore::InspectorDebuggerAgent::setBreakpointByUrl):
+        (WebCore::InspectorDebuggerAgent::setBreakpoint):
+        (WebCore::InspectorDebuggerAgent::continueToLocation):
+        (WebCore::InspectorDebuggerAgent::didParseSource):
+        * inspector/InspectorDebuggerAgent.h:
+        * inspector/ScriptBreakpoint.h:
+        (WebCore::ScriptBreakpoint::ScriptBreakpoint):
+        * inspector/front-end/DebuggerModel.js:
+        (WebInspector.DebuggerModel.prototype.setBreakpoint):
+        (WebInspector.DebuggerModel.prototype.setBreakpointBySourceId):
+        * inspector/front-end/DebuggerPresentationModel.js:
+        (WebInspector.DebuggerPresentationModel):
+        (WebInspector.DebuggerPresentationModel.prototype._restoreBreakpoints):
+        (WebInspector.DebuggerPresentationModel.prototype._updateBreakpointsAfterLiveEdit):
+        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint.callback):
+        (WebInspector.DebuggerPresentationModel.prototype.setBreakpoint):
+        (WebInspector.DebuggerPresentationModel.prototype._setBreakpointInDebugger):
+        (WebInspector.DebuggerPresentationModel.prototype._setBreakpointInDebugger.didRequestSourceMapping):
+        (WebInspector.DebuggerPresentationModel.prototype._removeBreakpointFromDebugger):
+        (WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled.afterUpdate):
+        (WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled):
+        (WebInspector.DebuggerPresentationModel.prototype.updateBreakpoint):
+        (WebInspector.DebuggerPresentationModel.prototype.removeBreakpoint):
+        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded.didRequestSourceMapping):
+        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
+        (WebInspector.DebuggerPresentationModel.prototype._breakpointRemoved):
+        (WebInspector.DebuggerPresentationModel.prototype._breakpointResolved):
+        (WebInspector.DebuggerPresentationModel.prototype._restoreBreakpointsFromSettings):
+        (WebInspector.DebuggerPresentationModel.prototype._saveBreakpoints):
+        (WebInspector.DebuggerPresentationModel.prototype._reset):
+        (WebInspector.PresentationBreakpoint):
+
 2011-04-07  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Adam Roben.
index 5b0eb58..2dd1ec2 100644 (file)
@@ -112,7 +112,7 @@ bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, const TextPosition0& po
     if (lineNumber <= 0)
         return false;
     LineToBreakpointMap::const_iterator breakIt = it->second.find(lineNumber);
-    if (breakIt == it->second.end() || !breakIt->second.enabled)
+    if (breakIt == it->second.end())
         return false;
 
     // An empty condition counts as no condition which is equivalent to "true".
index fe6e8ab..636c106 100644 (file)
@@ -92,8 +92,6 @@ DebuggerScript._formatScript = function(script)
 DebuggerScript.setBreakpoint = function(execState, args)
 {
     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)
index d153850..c702164 100644 (file)
@@ -71,7 +71,6 @@ String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBrea
     args->Set(v8::String::New("lineNumber"), v8::Integer::New(scriptBreakpoint.lineNumber));
     args->Set(v8::String::New("columnNumber"), v8::Integer::New(scriptBreakpoint.columnNumber));
     args->Set(v8::String::New("condition"), v8String(scriptBreakpoint.condition));
-    args->Set(v8::String::New("enabled"), v8::Boolean::New(scriptBreakpoint.enabled));
 
     v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint")));
     v8::Handle<v8::Value> breakpointId = v8::Debug::Call(setBreakpointFunction, args);
index 8877c31..68453b3 100644 (file)
                     { "name": "url", "type": "string", "description": "URL of the resource to set breakpoint on." },
                     { "name": "lineNumber", "type": "integer", "description": "Line number to set breakpoint at." },
                     { "name": "columnNumber", "type": "integer", "optional": true, "description": "Offset in the line to set breakpoint at." },
-                    { "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": "enabled", "type": "boolean", "optional": true, "description": "Determines initial state for the breakpoint." }
+                    { "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." }
                 ],
                 "returns": [
                     { "name": "breakpointId", "type": "string", "description": "Id of the created breakpoint for further manipulations." },
                     { "name": "sourceId", "type": "string", "description": "Source ID of the resource to set breakpoint on (as reported by <code>scriptParsed</code>)." },
                     { "name": "lineNumber", "type": "integer", "description": "Line number to set breakpoint at." },
                     { "name": "columnNumber", "type": "integer", "optional": true, "description": "Offset in the line to set breakpoint at." },
-                    { "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": "enabled", "type": "boolean", "optional": true, "description": "Determines initial state for the breakpoint." }
+                    { "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." }
                 ],
                 "returns": [
                     { "name": "breakpointId", "type": "string", "description": "Id of the created breakpoint for further manipulations." },
index 9f28851..6ceb77d 100644 (file)
@@ -141,31 +141,29 @@ void InspectorDebuggerAgent::inspectedURLChanged(const String&)
     m_breakpointIdToDebugServerBreakpointIds.clear();
 }
 
-static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, bool enabled)
+static PassRefPtr<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition)
 {
     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);
     return breakpointObject;
 }
 
-void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* const optionalEnabled, String* outBreakpointId, RefPtr<InspectorArray>* locations)
+void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* outBreakpointId, RefPtr<InspectorArray>* locations)
 {
     int columnNumber = optionalColumnNumber ? *optionalColumnNumber : 0;
     String condition = optionalCondition ? *optionalCondition : "";
-    bool enabled = optionalEnabled ? *optionalEnabled : true;
 
     String breakpointId = makeString(url, ":", String::number(lineNumber), ":", String::number(columnNumber));
     RefPtr<InspectorObject> breakpointsCookie = m_inspectorState->getObject(DebuggerAgentState::javaScriptBreakpoints);
     if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end())
         return;
-    breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, enabled));
+    breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition));
     m_inspectorState->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
 
-    ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
+    ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
     for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
         if (it->second.url != url)
             continue;
@@ -176,16 +174,15 @@ void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString*, const String& url,
     *outBreakpointId = breakpointId;
 }
 
-void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const String& sourceId, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* const optionalEnabled, String* outBreakpointId, RefPtr<InspectorObject>* location)
+void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const String& sourceId, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* outBreakpointId, RefPtr<InspectorObject>* location)
 {
     int columnNumber = optionalColumnNumber ? *optionalColumnNumber : 0;
     String condition = optionalCondition ? *optionalCondition : "";
-    bool enabled = optionalEnabled ? *optionalEnabled : true;
 
     String breakpointId = makeString(sourceId, ":", String::number(lineNumber), ":", String::number(columnNumber));
     if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end())
         return;
-    ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, enabled);
+    ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
     *location = resolveBreakpoint(breakpointId, sourceId, breakpoint);
     if (*location)
         *outBreakpointId = breakpointId;
@@ -213,7 +210,7 @@ void InspectorDebuggerAgent::continueToLocation(ErrorString* error, const String
         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
         m_continueToLocationBreakpointId = "";
     }
-    ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", true);
+    ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
     m_continueToLocationBreakpointId = scriptDebugServer().setBreakpoint(sourceId, breakpoint, &lineNumber, &columnNumber);
     resume(error);
 }
@@ -371,7 +368,6 @@ void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String
         breakpointObject->getNumber("lineNumber", &breakpoint.lineNumber);
         breakpointObject->getNumber("columnNumber", &breakpoint.columnNumber);
         breakpointObject->getString("condition", &breakpoint.condition);
-        breakpointObject->getBoolean("enabled", &breakpoint.enabled);
         RefPtr<InspectorObject> location = resolveBreakpoint(it->first, sourceID, breakpoint);
         if (location)
             m_frontend->breakpointResolved(it->first, location);
index 48eba09..47e8e5d 100644 (file)
@@ -80,8 +80,8 @@ public:
     // Part of the protocol.
     void setBreakpointsActive(ErrorString*, bool active);
 
-    void setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* const optionalEnabled, String* breakpointId, RefPtr<InspectorArray>* locations);
-    void setBreakpoint(ErrorString*, const String& sourceId, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* const optionalEnabled, String* breakpointId, RefPtr<InspectorObject>* location);
+    void setBreakpointByUrl(ErrorString*, const String& url, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* breakpointId, RefPtr<InspectorArray>* locations);
+    void setBreakpoint(ErrorString*, const String& sourceId, int lineNumber, const int* const optionalColumnNumber, const String* const optionalCondition, String* breakpointId, RefPtr<InspectorObject>* location);
     void removeBreakpoint(ErrorString*, const String& breakpointId);
     void continueToLocation(ErrorString*, const String& sourceId, int lineNumber, int columnNumber);
 
index 4917aef..920fb3f 100644 (file)
@@ -39,18 +39,16 @@ struct ScriptBreakpoint {
     {
     }
 
-    ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool enabled)
+    ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition)
         : lineNumber(lineNumber)
         , columnNumber(columnNumber)
         , condition(condition)
-        , enabled(enabled)
     {
     }
 
     int lineNumber;
     int columnNumber;
     String condition;
-    bool enabled;
 };
 
 } // namespace WebCore
index d96ffdf..bd62332 100644 (file)
@@ -73,7 +73,7 @@ WebInspector.DebuggerModel.prototype = {
         DebuggerAgent.continueToLocation(sourceID, lineNumber, columnNumber);
     },
 
-    setBreakpoint: function(url, lineNumber, columnNumber, condition, enabled, callback)
+    setBreakpoint: function(url, lineNumber, columnNumber, condition, callback)
     {
         // Adjust column if needed.
         var minColumnNumber = 0;
@@ -89,22 +89,22 @@ WebInspector.DebuggerModel.prototype = {
             if (callback)
                 callback(error ? null : breakpointId, locations);
         }
-        DebuggerAgent.setBreakpointByUrl(url, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+        DebuggerAgent.setBreakpointByUrl(url, lineNumber, columnNumber, condition, didSetBreakpoint.bind(this));
     },
 
-    setBreakpointBySourceId: function(sourceID, lineNumber, columnNumber, condition, enabled, callback)
+    setBreakpointBySourceId: function(sourceID, lineNumber, columnNumber, condition, callback)
     {
         function didSetBreakpoint(error, breakpointId, location)
         {
             if (callback)
                 callback(error ? null : breakpointId, [location]);
         }
-        DebuggerAgent.setBreakpoint(sourceID, lineNumber, columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+        DebuggerAgent.setBreakpoint(sourceID, lineNumber, columnNumber, condition, didSetBreakpoint.bind(this));
     },
 
-    removeBreakpoint: function(breakpointId)
+    removeBreakpoint: function(breakpointId, callback)
     {
-        DebuggerAgent.removeBreakpoint(breakpointId);
+        DebuggerAgent.removeBreakpoint(breakpointId, callback);
     },
 
     _breakpointResolved: function(breakpointId, location)
index 75edb08..47720a2 100644 (file)
@@ -32,8 +32,9 @@ WebInspector.DebuggerPresentationModel = function()
 {
     this._sourceFiles = {};
     this._messages = [];
-    this._presentationBreakpoints = {};
+    this._breakpointsByDebuggerId = {};
     this._breakpointsWithoutSourceFile = {};
+
     this._presentationCallFrames = [];
     this._selectedCallFrameIndex = 0;
 
@@ -117,10 +118,12 @@ WebInspector.DebuggerPresentationModel.prototype = {
         var pendingBreakpoints = this._breakpointsWithoutSourceFile[sourceFile.id];
         for (var i = 0; pendingBreakpoints && i < pendingBreakpoints.length; ++i) {
             var breakpointData = pendingBreakpoints[i];
-            if ("debuggerId" in breakpointData)
-                this._breakpointAdded(new WebInspector.PresentationBreakpoint(sourceFile, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled, breakpointData.debuggerId));
-            else
-                this.setBreakpoint(sourceFile.id, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled, false);
+            if ("debuggerId" in breakpointData) {
+                var breakpoint = new WebInspector.PresentationBreakpoint(sourceFile, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled);
+                this._bindDebuggerId(breakpoint, breakpointData.debuggerId);
+                this._breakpointAdded(breakpoint);
+            } else
+                this.setBreakpoint(sourceFile.id, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled, true);
         }
         delete this._breakpointsWithoutSourceFile[sourceFile.id];
     },
@@ -160,12 +163,13 @@ WebInspector.DebuggerPresentationModel.prototype = {
 
     _updateBreakpointsAfterLiveEdit: function(sourceFileId, oldSource, newSource)
     {
+        var sourceFile = this._sourceFiles[sourceFileId];
+
         // Clear and re-create breakpoints according to text diff.
         var diff = Array.diff(oldSource.split("\n"), newSource.split("\n"));
-        for (var id in this._presentationBreakpoints) {
-            var breakpoint = this._presentationBreakpoints[id];
-            if (breakpoint.sourceFileId !== sourceFileId)
-                continue;
+        for (var lineNumber in sourceFile.breakpoints) {
+            var breakpoint = sourceFile.breakpoints[lineNumber];
+
             var lineNumber = breakpoint.lineNumber;
             this.removeBreakpoint(sourceFileId, lineNumber);
 
@@ -184,7 +188,7 @@ WebInspector.DebuggerPresentationModel.prototype = {
                 }
             }
             if (newLineNumber !== undefined)
-                this.setBreakpoint(sourceFileId, newLineNumber, breakpoint.condition, breakpoint.enabled, false);
+                this.setBreakpoint(sourceFileId, newLineNumber, breakpoint.condition, breakpoint.enabled);
         }
     },
 
@@ -256,53 +260,122 @@ WebInspector.DebuggerPresentationModel.prototype = {
         return breakpoints;
     },
 
-    setBreakpoint: function(sourceFileId, lineNumber, condition, enabled, saveBreakpoints)
+    setBreakpoint: function(sourceFileId, lineNumber, condition, enabled, dontSaveBreakpoints)
     {
         var sourceFile = this._sourceFiles[sourceFileId];
         if (!sourceFile) 
             return;
 
+        var breakpoint = new WebInspector.PresentationBreakpoint(sourceFile, lineNumber, condition, enabled);
+        if (!enabled) {
+            this._breakpointAdded(breakpoint);
+            if (!dontSaveBreakpoints)
+                this._saveBreakpoints();
+            return;
+        }
+
+        function callback()
+        {
+            this._breakpointAdded(breakpoint);
+            if (!dontSaveBreakpoints)
+                this._saveBreakpoints();
+        }
+        this._setBreakpointInDebugger(breakpoint, callback.bind(this));
+    },
+
+    _setBreakpointInDebugger: function(breakpoint, callback)
+    {
         function didSetBreakpoint(breakpointId, locations)
         {
             if (!breakpointId)
                 return;
-            this._breakpointAdded(new WebInspector.PresentationBreakpoint(sourceFile, lineNumber, condition, enabled, breakpointId, locations[0]));
 
-            if (saveBreakpoints)
-                this._saveBreakpoints();
+            this._bindDebuggerId(breakpoint, breakpointId);
+            breakpoint.location = locations[0];
+            callback();
         }
 
         function didRequestSourceMapping(mapping)
         {
-            var location = mapping.sourceLocationToScriptLocation(lineNumber, 0);
+            var location = mapping.sourceLocationToScriptLocation(breakpoint.lineNumber, 0);
             var script = WebInspector.debuggerModel.scriptForSourceID(location.scriptId);
             if (script.sourceURL)
-                WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+                WebInspector.debuggerModel.setBreakpoint(script.sourceURL, location.lineNumber, location.columnNumber, breakpoint.condition, didSetBreakpoint.bind(this));
             else
-                WebInspector.debuggerModel.setBreakpointBySourceId(script.sourceID, location.lineNumber, location.columnNumber, condition, enabled, didSetBreakpoint.bind(this));
+                WebInspector.debuggerModel.setBreakpointBySourceId(script.sourceID, location.lineNumber, location.columnNumber, breakpoint.condition, didSetBreakpoint.bind(this));
         }
-        sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
+        breakpoint.sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
+    },
+
+    _removeBreakpointFromDebugger: function(breakpoint, callback)
+    {
+        if (!("debuggerId" in breakpoint)) {
+            if (callback)
+                callback();
+            return;
+        }
+
+        function didRemoveBreakpoint()
+        {
+            this._unbindDebuggerId(breakpoint);
+            if (callback)
+                callback();
+        }
+        WebInspector.debuggerModel.removeBreakpoint(breakpoint.debuggerId, didRemoveBreakpoint.bind(this));
+    },
+
+    _bindDebuggerId: function(breakpoint, debuggerId)
+    {
+        breakpoint.debuggerId = debuggerId;
+        this._breakpointsByDebuggerId[debuggerId] = breakpoint;
+    },
+
+    _unbindDebuggerId: function(breakpoint)
+    {
+        delete this._breakpointsByDebuggerId[breakpoint.debuggerId];
+        delete breakpoint.debuggerId;
     },
 
     setBreakpointEnabled: function(sourceFileId, lineNumber, enabled)
     {
-        var breakpoint = this.removeBreakpoint(sourceFileId, lineNumber);
-        this.setBreakpoint(sourceFileId, lineNumber, breakpoint.condition, enabled, true);
+        var breakpoint = this.findBreakpoint(sourceFileId, lineNumber);
+        if (!breakpoint)
+            return;
+
+        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+
+        breakpoint.enabled = enabled;
+
+        function afterUpdate()
+        {
+            this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
+            this._saveBreakpoints();
+        }
+
+        if (!enabled)
+            this._removeBreakpointFromDebugger(breakpoint, afterUpdate.call(this));
+        else
+            this._setBreakpointInDebugger(breakpoint, afterUpdate.bind(this));
     },
 
     updateBreakpoint: function(sourceFileId, lineNumber, condition, enabled)
     {
         this.removeBreakpoint(sourceFileId, lineNumber);
-        this.setBreakpoint(sourceFileId, lineNumber, condition, enabled, true);
+        this.setBreakpoint(sourceFileId, lineNumber, condition, enabled);
     },
 
     removeBreakpoint: function(sourceFileId, lineNumber)
     {
         var breakpoint = this.findBreakpoint(sourceFileId, lineNumber);
-        WebInspector.debuggerModel.removeBreakpoint(breakpoint.debuggerId);
-        this._breakpointRemoved(breakpoint.debuggerId);
-        this._saveBreakpoints();
-        return breakpoint;
+        if (!breakpoint)
+            return;
+
+        function callback()
+        {
+            this._breakpointRemoved(breakpoint);
+            this._saveBreakpoints();
+        }
+        this._removeBreakpointFromDebugger(breakpoint, callback.bind(this));
     },
 
     findBreakpoint: function(sourceFileId, lineNumber)
@@ -326,36 +399,37 @@ WebInspector.DebuggerPresentationModel.prototype = {
                 breakpoint.lineNumber = sourceLocation.lineNumber;
             }
 
-            if (this.findBreakpoint(sourceFile.id, breakpoint.lineNumber)) {
+            var existingBreakpoint = this.findBreakpoint(sourceFile.id, breakpoint.lineNumber);
+            if (existingBreakpoint) {
                 // We can't show more than one breakpoint on a single source file line.
-                WebInspector.debuggerModel.removeBreakpoint(breakpoint.debuggerId);
+                this._removeBreakpointFromDebugger(breakpoint);
                 return;
             }
-            this._presentationBreakpoints[breakpoint.debuggerId] = breakpoint;
             sourceFile.breakpoints[breakpoint.lineNumber] = breakpoint;
             this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
         }
         sourceFile.requestSourceMapping(didRequestSourceMapping.bind(this));
     },
 
-    _breakpointRemoved: function(debuggerId)
+    _breakpointRemoved: function(breakpoint)
     {
-        var breakpoint = this._presentationBreakpoints[debuggerId];
-        if (!breakpoint)
-            return;
-        delete this._presentationBreakpoints[debuggerId];
-        var sourceFile = this.sourceFile(breakpoint.sourceFileId);
-        delete sourceFile.breakpoints[breakpoint.lineNumber];
-        this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+        var sourceFile = breakpoint.sourceFile;
+        if (sourceFile.breakpoints[breakpoint.lineNumber] === breakpoint) {
+            // There can already be a newer breakpoint;
+            delete sourceFile.breakpoints[breakpoint.lineNumber];
+            this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
+        }
     },
 
     _breakpointResolved: function(event)
     {
         var debuggerId = event.data.breakpointId;
-        if (!(debuggerId in this._presentationBreakpoints))
+        if (!(debuggerId in this._breakpointsByDebuggerId))
             return;
-        var breakpoint = this._presentationBreakpoints[debuggerId];
-        this._breakpointRemoved(debuggerId);
+        var breakpoint = this._breakpointsByDebuggerId[debuggerId];
+
+        this._breakpointRemoved(breakpoint);
+        breakpoint.location = event.data.location;
         this._breakpointAdded(breakpoint);
     },
 
@@ -369,7 +443,7 @@ WebInspector.DebuggerPresentationModel.prototype = {
                 continue;
             var sourceFile = this._sourceFiles[sourceFileId];
             if (sourceFile) {
-                this.setBreakpoint(sourceFileId, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled, false);
+                this.setBreakpoint(sourceFileId, breakpointData.lineNumber, breakpointData.condition, breakpointData.enabled);
                 continue;
             }
 
@@ -387,14 +461,17 @@ WebInspector.DebuggerPresentationModel.prototype = {
     {
         var serializedBreakpoints = [];
 
-        // Store active breakpoints.
-        for (var id in this._presentationBreakpoints) {
-            var breakpoint = this._presentationBreakpoints[id];
-            if (breakpoint.sourceFile && breakpoint.sourceFile.url)
-                serializedBreakpoints.push(breakpoint.serialize());
+        // Store added breakpoints.
+        for (var sourceFileId in this._sourceFiles) {
+            var sourceFile = this._sourceFiles[sourceFileId];
+            if (!sourceFile.url)
+                continue;
+
+            for (var lineNumber in sourceFile.breakpoints)
+                serializedBreakpoints.push(sourceFile.breakpoints[lineNumber].serialize());
         }
 
-        // Store inactive breakpoints.
+        // Store not added breakpoints.
         for (var sourceFileId in this._breakpointsWithoutSourceFile)
             serializedBreakpoints = serializedBreakpoints.concat(this._breakpointsWithoutSourceFile[sourceFileId]);
 
@@ -477,7 +554,7 @@ WebInspector.DebuggerPresentationModel.prototype = {
 
         this._sourceFiles = {};
         this._messages = [];
-        this._presentationBreakpoints = {};
+        this._breakpointsByDebuggerId = {};
     },
 
     _debuggerReset: function()
@@ -490,15 +567,13 @@ WebInspector.DebuggerPresentationModel.prototype = {
 
 WebInspector.DebuggerPresentationModel.prototype.__proto__ = WebInspector.Object.prototype;
 
-WebInspector.PresentationBreakpoint = function(sourceFile, lineNumber, condition, enabled, debuggerId, location)
+WebInspector.PresentationBreakpoint = function(sourceFile, lineNumber, condition, enabled)
 {
     this.sourceFile = sourceFile;
     this.sourceFileId = sourceFile.id;
     this.lineNumber = lineNumber;
     this.condition = condition;
     this.enabled = enabled;
-    this.debuggerId = debuggerId;
-    this.location = location;
 }
 
 WebInspector.PresentationBreakpoint.prototype = {