a337f5c7b0a0e9c7ca4c85fa4c39a53236078868
[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 }
35
36 WebInspector.DebuggerModel.prototype = {
37     setOneTimeBreakpoint: function(sourceID, line)
38     {
39         var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined);
40         if (this._breakpoints[breakpoint.id])
41             return;
42         if (this._oneTimeBreakpoint)
43             InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
44         this._oneTimeBreakpoint = breakpoint;
45         // FIXME(40669): one time breakpoint will be persisted in inspector settings if not hit.
46         this._setBreakpointOnBackend(breakpoint, true);
47     },
48
49     removeOneTimeBreakpoint: function()
50     {
51         if (this._oneTimeBreakpoint) {
52             InspectorBackend.removeBreakpoint(this._oneTimeBreakpoint.sourceID, this._oneTimeBreakpoint.line);
53             delete this._oneTimeBreakpoint;
54         }
55     },
56
57     setBreakpoint: function(sourceID, url, line, enabled, condition)
58     {
59         var breakpoint = this._setBreakpoint(sourceID, url, line, enabled, condition);
60         if (breakpoint)
61             this._setBreakpointOnBackend(breakpoint);
62     },
63
64     breakpointRestored: function(sourceID, url, line, enabled, condition)
65     {
66         this._setBreakpoint(sourceID, url, line, enabled, condition);
67     },
68
69     queryBreakpoints: function(filter)
70     {
71         var breakpoints = [];
72         for (var id in this._breakpoints) {
73            var breakpoint = this._breakpoints[id];
74            if (filter(breakpoint))
75                breakpoints.push(breakpoint);
76         }
77         return breakpoints;
78     },
79
80     findBreakpoint: function(sourceID, lineNumber)
81     {
82         var breakpointId = WebInspector.Breakpoint.jsBreakpointId(sourceID, lineNumber);
83         return this._breakpoints[breakpointId];
84     },
85
86     reset: function()
87     {
88         this._breakpoints = {};
89         delete this._oneTimeBreakpoint;
90     },
91
92     _setBreakpoint: function(sourceID, url, line, enabled, condition)
93     {
94         var breakpoint = new WebInspector.Breakpoint(this, sourceID, url, line, enabled, condition);
95         if (this._breakpoints[breakpoint.id])
96             return;
97         if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id))
98             delete this._oneTimeBreakpoint;
99         this._breakpoints[breakpoint.id] = breakpoint;
100         breakpoint.addEventListener("removed", this._breakpointRemoved, this);
101         this.dispatchEventToListeners("breakpoint-added", breakpoint);
102         return breakpoint;
103     },
104
105     _breakpointRemoved: function(event)
106     {
107         delete this._breakpoints[event.target.id];
108     },
109
110     _setBreakpointOnBackend: function(breakpoint, isOneTime)
111     {
112         function didSetBreakpoint(success, line)
113         {
114             if (success && line == breakpoint.line)
115                 return;
116             if (isOneTime) {
117                 if (success)
118                     this._oneTimeBreakpoint.line = line;
119                 else
120                     delete this._oneTimeBreakpoint;
121             } else {
122                 breakpoint.remove();
123                 if (success)
124                     this._setBreakpoint(breakpoint.sourceID, breakpoint.url, line, breakpoint.enabled, breakpoint.condition);
125             }
126         }
127         InspectorBackend.setBreakpoint(breakpoint.sourceID, breakpoint.line, breakpoint.enabled, breakpoint.condition, didSetBreakpoint.bind(this));
128     },
129
130     debuggerPaused: function(details)
131     {
132         this.dispatchEventToListeners("debugger-paused", details.callFrames);
133
134         if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause)
135             return;
136         if (details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint) {
137             this.dispatchEventToListeners("native-breakpoint-hit", details.eventData);
138             return;
139         }
140
141         var breakpointId = WebInspector.Breakpoint.jsBreakpointId(details.callFrames[0].sourceID, details.callFrames[0].line);
142         var breakpoint = this._breakpoints[breakpointId];
143         if (!breakpoint)
144             return;
145         breakpoint.hit = true;
146         this._lastHitBreakpoint = breakpoint;
147         this.dispatchEventToListeners("script-breakpoint-hit", breakpoint);
148     },
149
150     debuggerResumed: function()
151     {
152         this.dispatchEventToListeners("debugger-resumed");
153
154         if (!this._lastHitBreakpoint)
155             return;
156         this._lastHitBreakpoint.hit = false;
157         delete this._lastHitBreakpoint;
158     }
159 }
160
161 WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype;
162
163 WebInspector.DebuggerEventTypes = {
164     JavaScriptPause: 0,
165     JavaScriptBreakpoint: 1,
166     NativeBreakpoint: 2
167 };