2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 WebInspector.BreakpointManager = function(breakpointStorage, breakpointAddedDelegate, breakpointRemovedDelegate, debuggerModel)
36 this._breakpointStorage = breakpointStorage;
37 this._breakpointAddedDelegate = breakpointAddedDelegate;
38 this._breakpointRemovedDelegate = breakpointRemovedDelegate;
39 this._breakpointsByUILocation = {};
41 this._debuggerModel = debuggerModel;
42 this._breakpointsByDebuggerId = {};
43 this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
45 var breakpoints = this._breakpointStorage.get();
46 for (var i = 0; i < breakpoints.length; ++i) {
47 var breakpoint = WebInspector.Breakpoint.deserialize(breakpoints[i]);
48 if (!this._breakpoint(breakpoint.uiSourceCodeId, breakpoint.lineNumber))
49 this._addBreakpointToUI(breakpoint);
53 WebInspector.BreakpointManager.prototype = {
54 uiSourceCodeAdded: function(uiSourceCode)
56 var breakpoints = this._breakpoints(uiSourceCode.id);
57 for (var lineNumber in breakpoints) {
58 var breakpoint = breakpoints[lineNumber];
59 breakpoint.uiSourceCode = uiSourceCode;
60 this._materializeBreakpoint(breakpoint);
61 if (breakpoint._debuggerLocation)
62 this._breakpointDebuggerLocationChanged(breakpoint, breakpoint._debuggerLocation);
66 breakpointsForUISourceCode: function(uiSourceCode)
68 return this._breakpoints(uiSourceCode.id);
71 setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
73 if (this._breakpoint(uiSourceCode.id, lineNumber))
76 var persistent = !!uiSourceCode.url;
77 var breakpoint = new WebInspector.Breakpoint(uiSourceCode.id, lineNumber, condition, enabled, persistent);
78 breakpoint.uiSourceCode = uiSourceCode;
79 this._addBreakpointToUI(breakpoint);
80 this._materializeBreakpoint(breakpoint);
83 removeBreakpoint: function(uiSourceCode, lineNumber)
85 var breakpoint = this._breakpoint(uiSourceCode.id, lineNumber);
88 this._deleteBreakpointFromUI(breakpoint);
89 this._removeBreakpointFromDebugger(breakpoint);
92 _materializeBreakpoint: function(breakpoint)
94 if (!breakpoint.enabled || breakpoint._materialized)
97 breakpoint._materialized = true;
98 var rawLocation = breakpoint.uiSourceCode.rawSourceCode.uiLocationToRawLocation(breakpoint.lineNumber, 0);
99 this._setBreakpointInDebugger(breakpoint, rawLocation);
102 _breakpointDebuggerLocationChanged: function(breakpoint)
104 if (!breakpoint.uiSourceCode)
106 var uiLocation = breakpoint.uiSourceCode.rawSourceCode.rawLocationToUILocation(breakpoint._debuggerLocation);
107 if (uiLocation.lineNumber === breakpoint.lineNumber)
110 if (!this._moveBreakpointInUI(breakpoint, uiLocation.lineNumber))
111 this._removeBreakpointFromDebugger(breakpoint);
114 _addBreakpointToUI: function(breakpoint)
116 console.assert(!this._breakpoint(breakpoint.uiSourceCodeId, breakpoint.lineNumber));
117 this._breakpoints(breakpoint.uiSourceCodeId)[breakpoint.lineNumber] = breakpoint;
118 this._saveBreakpoints();
119 this._breakpointAddedDelegate(breakpoint);
122 _deleteBreakpointFromUI: function(breakpoint)
124 console.assert(this._breakpoint(breakpoint.uiSourceCodeId, breakpoint.lineNumber) === breakpoint);
125 delete this._breakpoints(breakpoint.uiSourceCodeId)[breakpoint.lineNumber];
126 this._saveBreakpoints();
127 this._breakpointRemovedDelegate(breakpoint);
130 _moveBreakpointInUI: function(breakpoint, lineNumber)
132 this._deleteBreakpointFromUI(breakpoint);
133 if (this._breakpoint(breakpoint.uiSourceCodeId, lineNumber))
135 breakpoint.lineNumber = lineNumber;
136 this._addBreakpointToUI(breakpoint);
140 _breakpoints: function(uiSourceCodeId)
142 if (!this._breakpointsByUILocation[uiSourceCodeId])
143 this._breakpointsByUILocation[uiSourceCodeId] = {};
144 return this._breakpointsByUILocation[uiSourceCodeId];
147 _breakpoint: function(uiSourceCodeId, lineNumber)
149 return this._breakpoints(uiSourceCodeId)[lineNumber];
152 _forEachBreakpoint: function(handler)
154 for (var uiSourceCodeId in this._breakpointsByUILocation) {
155 var breakpoints = this._breakpointsByUILocation[uiSourceCodeId];
156 for (var lineNumber in breakpoints)
157 handler(breakpoints[lineNumber]);
161 _setBreakpointInDebugger: function(breakpoint, rawLocation)
163 function didSetBreakpoint(breakpointId, locations)
165 if (breakpoint === this._breakpoint(breakpoint.uiSourceCodeId, breakpoint.lineNumber)) {
167 this._deleteBreakpointFromUI(breakpoint);
172 this._debuggerModel.removeBreakpoint(breakpointId);
176 this._breakpointsByDebuggerId[breakpointId] = breakpoint;
177 breakpoint._debuggerId = breakpointId;
178 breakpoint._debuggerLocation = locations[0];
179 if (breakpoint._debuggerLocation)
180 this._breakpointDebuggerLocationChanged(breakpoint);
182 this._debuggerModel.setBreakpointByScriptLocation(rawLocation, breakpoint.condition, didSetBreakpoint.bind(this));
185 _removeBreakpointFromDebugger: function(breakpoint)
187 if (!("_debuggerId" in breakpoint))
189 this._debuggerModel.removeBreakpoint(breakpoint._debuggerId);
190 delete this._breakpointsByDebuggerId[breakpoint._debuggerId];
191 delete breakpoint._debuggerId;
192 delete breakpoint._debuggerLocation;
195 _breakpointResolved: function(event)
197 var breakpoint = this._breakpointsByDebuggerId[event.data.breakpointId];
198 breakpoint._debuggerLocation = event.data.location;
199 this._breakpointDebuggerLocationChanged(breakpoint);
202 _saveBreakpoints: function()
204 var serializedBreakpoints = [];
205 function serializePersistent(breakpoint)
207 if (breakpoint.persistent)
208 serializedBreakpoints.push(breakpoint.serialize());
210 this._forEachBreakpoint(serializePersistent.bind(this));
211 this._breakpointStorage.set(serializedBreakpoints);
216 function resetBreakpoint(breakpoint)
218 this._removeBreakpointFromDebugger(breakpoint);
219 delete breakpoint._materialized;
221 this._forEachBreakpoint(resetBreakpoint.bind(this));
224 debuggerReset: function()
226 function resetOrDeleteBreakpoint(breakpoint)
228 if (breakpoint.persistent) {
229 delete breakpoint.uiSourceCode;
230 delete breakpoint._debuggerLocation;
232 this._deleteBreakpointFromUI(breakpoint);
233 delete this._breakpointsByDebuggerId[breakpoint._debuggerId];
236 this._forEachBreakpoint(resetOrDeleteBreakpoint.bind(this));
238 for (var id in this._breakpointsByUILocation) {
240 for (var lineNumber in this._breakpointsByUILocation[id]) {
245 delete this._breakpointsByUILocation[id];
253 WebInspector.Breakpoint = function(uiSourceCodeId, lineNumber, condition, enabled, persistent)
255 this.uiSourceCodeId = uiSourceCodeId;
256 this.lineNumber = lineNumber;
257 this.condition = condition;
258 this.enabled = enabled;
259 this.persistent = persistent;
262 WebInspector.Breakpoint.prototype = {
263 serialize: function()
265 var serializedBreakpoint = {};
266 serializedBreakpoint.sourceFileId = this.uiSourceCodeId;
267 serializedBreakpoint.lineNumber = this.lineNumber;
268 serializedBreakpoint.condition = this.condition;
269 serializedBreakpoint.enabled = this.enabled;
270 return serializedBreakpoint;
274 WebInspector.Breakpoint.deserialize = function(serializedBreakpoint)
276 return new WebInspector.Breakpoint(
277 serializedBreakpoint.sourceFileId,
278 serializedBreakpoint.lineNumber,
279 serializedBreakpoint.condition,
280 serializedBreakpoint.enabled,