• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
31WebInspector.DebuggerModel = function()
32{
33    this._debuggerPausedDetails = {};
34    this._scripts = {};
35
36    InspectorBackend.registerDomainDispatcher("Debugger", new WebInspector.DebuggerDispatcher(this));
37}
38
39WebInspector.DebuggerModel.Events = {
40    DebuggerWasEnabled: "debugger-was-enabled",
41    DebuggerWasDisabled: "debugger-was-disabled",
42    DebuggerPaused: "debugger-paused",
43    DebuggerResumed: "debugger-resumed",
44    ParsedScriptSource: "parsed-script-source",
45    FailedToParseScriptSource: "failed-to-parse-script-source",
46    BreakpointResolved: "breakpoint-resolved",
47    Reset: "reset"
48}
49
50WebInspector.DebuggerModel.prototype = {
51    enableDebugger: function()
52    {
53        DebuggerAgent.enable();
54    },
55
56    disableDebugger: function()
57    {
58        DebuggerAgent.disable();
59    },
60
61    _debuggerWasEnabled: function()
62    {
63        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasEnabled);
64    },
65
66    _debuggerWasDisabled: function()
67    {
68        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
69    },
70
71    continueToLocation: function(location)
72    {
73        DebuggerAgent.continueToLocation(location);
74    },
75
76    setBreakpoint: function(url, lineNumber, columnNumber, condition, callback)
77    {
78        // Adjust column if needed.
79        var minColumnNumber = 0;
80        for (var id in this._scripts) {
81            var script = this._scripts[id];
82            if (url === script.sourceURL && lineNumber === script.lineOffset)
83                minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.columnOffset) : script.columnOffset;
84        }
85        columnNumber = Math.max(columnNumber, minColumnNumber);
86
87        function didSetBreakpoint(error, breakpointId, locations)
88        {
89            if (callback)
90                callback(error ? null : breakpointId, locations);
91        }
92        DebuggerAgent.setBreakpointByUrl(url, lineNumber, columnNumber, condition, didSetBreakpoint.bind(this));
93    },
94
95    setBreakpointBySourceId: function(location, condition, callback)
96    {
97        function didSetBreakpoint(error, breakpointId, actualLocation)
98        {
99            if (callback)
100                callback(error ? null : breakpointId, [actualLocation]);
101        }
102        DebuggerAgent.setBreakpoint(location, condition, didSetBreakpoint.bind(this));
103    },
104
105    removeBreakpoint: function(breakpointId, callback)
106    {
107        DebuggerAgent.removeBreakpoint(breakpointId, callback);
108    },
109
110    _breakpointResolved: function(breakpointId, location)
111    {
112        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, {breakpointId: breakpointId, location: location});
113    },
114
115    reset: function()
116    {
117        this._debuggerPausedDetails = {};
118        this._scripts = {};
119        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.Reset);
120    },
121
122    get scripts()
123    {
124        return this._scripts;
125    },
126
127    scriptForSourceID: function(sourceID)
128    {
129        return this._scripts[sourceID];
130    },
131
132    scriptsForURL: function(url)
133    {
134        return this.queryScripts(function(s) { return s.sourceURL === url; });
135    },
136
137    queryScripts: function(filter)
138    {
139        var scripts = [];
140        for (var sourceID in this._scripts) {
141            var script = this._scripts[sourceID];
142            if (filter(script))
143                scripts.push(script);
144        }
145        return scripts;
146    },
147
148    editScriptSource: function(sourceID, newSource, callback)
149    {
150        this._scripts[sourceID].editSource(newSource, this._didEditScriptSource.bind(this, sourceID, newSource, callback));
151    },
152
153    _didEditScriptSource: function(sourceID, newSource, callback, error, callFrames)
154    {
155        if (!error && callFrames && callFrames.length)
156            this._debuggerPausedDetails.callFrames = callFrames;
157        callback(error);
158    },
159
160    get callFrames()
161    {
162        return this._debuggerPausedDetails.callFrames;
163    },
164
165    get debuggerPausedDetails()
166    {
167        return this._debuggerPausedDetails;
168    },
169
170    _pausedScript: function(details)
171    {
172        this._debuggerPausedDetails = details;
173        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details);
174    },
175
176    _resumedScript: function()
177    {
178        this._debuggerPausedDetails = {};
179        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
180    },
181
182    _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript)
183    {
184        var script = new WebInspector.Script(sourceID, sourceURL, lineOffset, columnOffset, length, undefined, undefined, isContentScript);
185        this._scripts[sourceID] = script;
186        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
187    },
188
189    _failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage)
190    {
191        var script = new WebInspector.Script(null, sourceURL, startingLine, errorLine, errorMessage, undefined);
192        this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script);
193    }
194}
195
196WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype;
197
198WebInspector.DebuggerEventTypes = {
199    JavaScriptPause: 0,
200    JavaScriptBreakpoint: 1,
201    NativeBreakpoint: 2
202};
203
204WebInspector.DebuggerDispatcher = function(debuggerModel)
205{
206    this._debuggerModel = debuggerModel;
207}
208
209WebInspector.DebuggerDispatcher.prototype = {
210    paused: function(details)
211    {
212        this._debuggerModel._pausedScript(details);
213    },
214
215    resumed: function()
216    {
217        this._debuggerModel._resumedScript();
218    },
219
220    debuggerWasEnabled: function()
221    {
222        this._debuggerModel._debuggerWasEnabled();
223    },
224
225    debuggerWasDisabled: function()
226    {
227        this._debuggerModel._debuggerWasDisabled();
228    },
229
230    scriptParsed: function(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript)
231    {
232        this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, length, isContentScript);
233    },
234
235    scriptFailedToParse: function(sourceURL, source, startingLine, errorLine, errorMessage)
236    {
237        this._debuggerModel._failedToParseScriptSource(sourceURL, source, startingLine, errorLine, errorMessage);
238    },
239
240    breakpointResolved: function(breakpointId, sourceID, lineNumber, columnNumber)
241    {
242        this._debuggerModel._breakpointResolved(breakpointId, sourceID, lineNumber, columnNumber);
243    }
244}
245