2010-12-13 Ilya Tikhonovsky <loislo@chromium.org>
[WebKit-https.git] / WebCore / inspector / front-end / DebuggerModel.js
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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
13  * distribution.
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.
17  *
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.
29  */
30
31 WebInspector.DebuggerModel = function()
32 {
33     this._breakpoints = {};
34     InspectorBackend.registerDomainDispatcher("Debugger", this);
35 }
36
37 WebInspector.DebuggerModel.prototype = {
38     setOneTimeBreakpoint: function(sourceID, line)
39     {
40         var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined);
41         if (this._breakpoints[breakpoint.id])
42             return;
43         if (this._oneTimeBreakpoint)
44             InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
45         this._oneTimeBreakpoint = breakpoint;
46         // FIXME(40669): one time breakpoint will be persisted in inspector settings if not hit.
47         this._setBreakpointOnBackend(breakpoint, true);
48     },
49
50     removeOneTimeBreakpoint: function()
51     {
52         if (this._oneTimeBreakpoint) {
53             InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
54             delete this._oneTimeBreakpoint;
55         }
56     },
57
58     setBreakpoint: function(sourceID, url, line, enabled, condition)
59     {
60         var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition);
61         if (breakpoint)
62             this._setBreakpointOnBackend(breakpoint);
63     },
64
65     breakpointRestored: function(sourceID, url, line, enabled, condition)
66     {
67         this._setBreakpoint(sourceID, url, line, enabled, condition);
68     },
69
70     queryBreakpoints: function(filter)
71     {
72         var breakpoints = [];
73         for (var id in this._breakpoints) {
74            var breakpoint = this._breakpoints[id];
75            if (filter(breakpoint))
76                breakpoints.push(breakpoint);
77         }
78         return breakpoints;
79     },
80
81     findBreakpoint: function(sourceID, lineNumber)
82     {
83         var breakpointId = WebInspector.Breakpoint.jsBreakpointId(sourceID, lineNumber);
84         return this._breakpoints[breakpointId];
85     },
86
87     reset: function()
88     {
89         this._breakpoints = {};
90         delete this._oneTimeBreakpoint;
91     },
92
93     _setBreakpoint: function(sourceID, url, line, enabled, condition)
94     {
95         var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition);
96         if (this._breakpoints[breakpoint.id])
97             return;
98         if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id))
99             delete this._oneTimeBreakpoint;
100         this._breakpoints[breakpoint.id] = breakpoint;
101         breakpoint.addEventListener("removed", this._breakpointRemoved, this);
102         this.dispatchEventToListeners("breakpoint-added", breakpoint);
103         return breakpoint;
104     },
105
106     _breakpointRemoved: function(event)
107     {
108         delete this._breakpoints[event.target.id];
109     },
110
111     _setBreakpointOnBackend: function(breakpoint, isOneTime)
112     {
113         function didSetBreakpoint(success, line)
114         {
115             if (success && line == breakpoint.line)
116                 return;
117             if (isOneTime) {
118                 if (success)
119                     this._oneTimeBreakpoint.line = line;
120                 else
121                     delete this._oneTimeBreakpoint;
122             } else {
123                 breakpoint.remove();
124                 if (success)
125                     this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition);
126             }
127         }
128         InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this));
129     },
130
131     pausedScript: function(details)
132     {
133         this.dispatchEventToListeners("debugger-paused", details.callFrames);
134
135         if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause)
136             return;
137         if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
138             this.dispatchEventToListeners("native-breakpoint-hit", details.eventData);
139             return;
140         }
141
142         var breakpointId = WebInspector.Breakpoint.jsBreakpointId(details.callFrames[0].sourceID, details.callFrames[0].line);
143         var breakpoint = this._breakpoints[breakpointId];
144         if (!breakpoint)
145             return;
146         breakpoint.hit = true;
147         this._lastHitBreakpoint = breakpoint;
148         this.dispatchEventToListeners("script-breakpoint-hit", breakpoint);
149     },
150
151     resumedScript: function()
152     {
153         this.dispatchEventToListeners("debugger-resumed");
154
155         if (!this._lastHitBreakpoint)
156             return;
157         this._lastHitBreakpoint.hit = false;
158         delete this._lastHitBreakpoint;
159     },
160
161     attachDebuggerWhenShown: function()
162     {
163         WebInspector.panels.scripts.attachDebuggerWhenShown();
164     },
165
166     debuggerWasEnabled: function()
167     {
168         WebInspector.panels.scripts.debuggerWasEnabled();
169     },
170
171     debuggerWasDisabled: function()
172     {
173         WebInspector.panels.scripts.debuggerWasDisabled();
174     },
175
176     parsedScriptSource: function(sourceID, sourceURL, source, startingLine, scriptWorldType)
177     {
178         WebInspector.panels.scripts.addScript(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType);
179     },
180
181     failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage)
182     {
183         WebInspector.panels.scripts.addScript(null, sourceURL, source, startingLine, errorLine, errorMessage);
184     },
185
186     didCreateWorker: function()
187     {
188         var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
189         workersPane.addWorker.apply(workersPane, arguments);
190     },
191
192     didDestroyWorker: function()
193     {
194         var workersPane = WebInspector.panels.scripts.sidebarPanes.workers;
195         workersPane.removeWorker.apply(workersPane, arguments);
196     }
197 }
198
199 WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype;
200
201 WebInspector.DebuggerEventTypes = {
202     JavaScriptPause: 0,
203     JavaScriptBreakpoint: 1,
204     NativeBreakpoint: 2
205 };