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.
33 * @extends {WebInspector.Object}
35 WebInspector.DebuggerPresentationModel = function()
37 // FIXME: apply formatter from outside as a generic mapping.
38 this._formatter = new WebInspector.ScriptFormatter();
39 this._rawSourceCodeForScriptId = {};
40 this._rawSourceCodeForURL = {};
41 this._rawSourceCodeForDocumentURL = {};
42 this._presentationCallFrames = [];
44 this._breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this._breakpointAdded.bind(this), this._breakpointRemoved.bind(this), WebInspector.debuggerModel);
46 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
47 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this);
48 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
49 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
50 WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
52 WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
53 WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
55 new WebInspector.DebuggerPresentationModelResourceBinding(this);
58 WebInspector.DebuggerPresentationModel.Events = {
59 UISourceCodeAdded: "source-file-added",
60 UISourceCodeReplaced: "source-file-replaced",
61 UISourceCodeRemoved: "source-file-removed",
62 ConsoleMessageAdded: "console-message-added",
63 ConsoleMessagesCleared: "console-messages-cleared",
64 BreakpointAdded: "breakpoint-added",
65 BreakpointRemoved: "breakpoint-removed",
66 DebuggerPaused: "debugger-paused",
67 DebuggerResumed: "debugger-resumed",
68 DebuggerReset: "debugger-reset",
69 CallFrameSelected: "call-frame-selected",
70 ConsoleCommandEvaluatedInSelectedCallFrame: "console-command-evaluated-in-selected-call-frame",
71 ExecutionLineChanged: "execution-line-changed"
74 WebInspector.DebuggerPresentationModel.prototype = {
76 * @param {WebInspector.DebuggerPresentationModel.LinkifierFormatter=} formatter
78 createLinkifier: function(formatter)
80 return new WebInspector.DebuggerPresentationModel.Linkifier(this, formatter);
84 * @param {WebInspector.PresentationCallFrame} callFrame
85 * @return {WebInspector.Placard}
87 createPlacard: function(callFrame)
89 return new WebInspector.DebuggerPresentationModel.CallFramePlacard(callFrame);
93 * @param {DebuggerAgent.Location} rawLocation
94 * @return {?WebInspector.UILocation}
96 rawLocationToUILocation: function(rawLocation)
98 var rawSourceCode = this._rawSourceCodeForScriptId[rawLocation.scriptId];
99 if (!rawSourceCode.sourceMapping)
101 return rawSourceCode.sourceMapping.rawLocationToUILocation(rawLocation);
105 * @param {WebInspector.Event} event
107 _parsedScriptSource: function(event)
109 var script = /** @type {WebInspector.Script} */ event.data;
110 this._addScript(script);
114 * @param {WebInspector.Event} event
116 _failedToParseScriptSource: function(event)
118 var script = /** @type {WebInspector.Script} */ event.data;
119 this._addScript(script);
123 * @param {WebInspector.Script} script
125 _addScript: function(script)
128 var isInlineScript = false;
129 if (script.isInlineScript()) {
130 resource = WebInspector.networkManager.inflightResourceForURL(script.sourceURL) || WebInspector.resourceForURL(script.sourceURL);
131 if (resource && resource.type === WebInspector.Resource.Type.Document) {
132 isInlineScript = true;
133 var rawSourceCode = this._rawSourceCodeForDocumentURL[script.sourceURL];
135 rawSourceCode.addScript(script);
136 this._bindScriptToRawSourceCode(script, rawSourceCode);
142 rawSourceCode = new WebInspector.RawSourceCode(script.scriptId, script, resource, this._formatter, this._formatSource);
143 this._bindScriptToRawSourceCode(script, rawSourceCode);
146 this._rawSourceCodeForDocumentURL[script.sourceURL] = rawSourceCode;
148 if (rawSourceCode.sourceMapping)
149 this._updateSourceMapping(rawSourceCode, null);
150 rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._sourceMappingUpdated, this);
154 * @param {WebInspector.Script} script
155 * @param {WebInspector.RawSourceCode} rawSourceCode
157 _bindScriptToRawSourceCode: function(script, rawSourceCode)
159 this._rawSourceCodeForScriptId[script.scriptId] = rawSourceCode;
160 this._rawSourceCodeForURL[script.sourceURL] = rawSourceCode;
164 * @param {WebInspector.Event} event
166 _sourceMappingUpdated: function(event)
168 var rawSourceCode = /** @type {WebInspector.RawSourceCode} */ event.target;
169 var oldSourceMapping = /** @type {WebInspector.RawSourceCode.SourceMapping} */ event.data["oldSourceMapping"];
170 this._updateSourceMapping(rawSourceCode, oldSourceMapping);
174 * @return {Array.<WebInspector.UISourceCode>}
176 uiSourceCodes: function()
179 for (var id in this._rawSourceCodeForScriptId) {
180 var uiSourceCodeList = this._rawSourceCodeForScriptId[id].sourceMapping.uiSourceCodeList();
181 for (var i = 0; i < uiSourceCodeList.length; ++i)
182 result.push(uiSourceCodeList[i]);
188 * @param {WebInspector.RawSourceCode} rawSourceCode
189 * @param {WebInspector.RawSourceCode.SourceMapping} oldSourceMapping
191 _updateSourceMapping: function(rawSourceCode, oldSourceMapping)
193 if (oldSourceMapping) {
194 var oldUISourceCodeList = oldSourceMapping.uiSourceCodeList();
195 for (var i = 0; i < oldUISourceCodeList.length; ++i) {
196 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(oldUISourceCodeList[i]);
197 for (var lineNumber in breakpoints) {
198 var breakpoint = breakpoints[lineNumber];
199 this._breakpointRemoved(breakpoint);
200 delete breakpoint.uiSourceCode;
205 this._restoreBreakpoints(rawSourceCode);
206 this._restoreConsoleMessages(rawSourceCode);
208 if (!oldSourceMapping) {
209 var uiSourceCodeList = rawSourceCode.sourceMapping.uiSourceCodeList();
210 for (var i = 0; i < uiSourceCodeList.length; ++i)
211 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeAdded, uiSourceCodeList[i]);
213 var eventData = { uiSourceCodeList: rawSourceCode.sourceMapping.uiSourceCodeList(), oldUISourceCodeList: oldSourceMapping.uiSourceCodeList() };
214 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeReplaced, eventData);
219 * @param {WebInspector.RawSourceCode} rawSourceCode
221 _restoreBreakpoints: function(rawSourceCode)
223 var uiSourceCodeList = rawSourceCode.sourceMapping.uiSourceCodeList();
224 for (var i = 0; i < uiSourceCodeList.length; ++i) {
225 var uiSourceCode = uiSourceCodeList[i];
226 this._breakpointManager.uiSourceCodeAdded(uiSourceCode);
227 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(uiSourceCode);
228 for (var lineNumber in breakpoints)
229 this._breakpointAdded(breakpoints[lineNumber]);
235 * @param {WebInspector.RawSourceCode} rawSourceCode
237 _restoreConsoleMessages: function(rawSourceCode)
239 var messages = rawSourceCode.messages;
240 for (var i = 0; i < messages.length; ++i)
241 messages[i]._presentationMessage = this._createPresentationMessage(messages[i], rawSourceCode.sourceMapping);
245 * @param {WebInspector.UISourceCode} uiSourceCode
248 canEditScriptSource: function(uiSourceCode)
250 if (!WebInspector.debuggerModel.canSetScriptSource() || this._formatSource)
252 var rawSourceCode = uiSourceCode.rawSourceCode;
253 var script = this._scriptForRawSourceCode(rawSourceCode);
254 return script && !script.lineOffset && !script.columnOffset;
258 * @param {WebInspector.UISourceCode} uiSourceCode
259 * @param {string} newSource
260 * @param {function(?Protocol.Error)} callback
262 setScriptSource: function(uiSourceCode, newSource, callback)
264 var rawSourceCode = uiSourceCode.rawSourceCode;
265 var script = this._scriptForRawSourceCode(rawSourceCode);
268 * @this {WebInspector.DebuggerPresentationModel}
269 * @param {?Protocol.Error} error
271 function didEditScriptSource(error)
277 var resource = WebInspector.resourceForURL(rawSourceCode.url);
279 resource.addRevision(newSource);
281 uiSourceCode.contentChanged(newSource);
283 if (WebInspector.debuggerModel.callFrames)
284 this._debuggerPaused();
286 WebInspector.debuggerModel.setScriptSource(script.scriptId, newSource, didEditScriptSource.bind(this));
290 * @param {WebInspector.UISourceCode} uiSourceCode
291 * @param {string} oldSource
292 * @param {string} newSource
294 _updateBreakpointsAfterLiveEdit: function(uiSourceCode, oldSource, newSource)
296 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(uiSourceCode);
298 // Clear and re-create breakpoints according to text diff.
299 var diff = Array.diff(oldSource.split("\n"), newSource.split("\n"));
300 for (var lineNumber in breakpoints) {
301 var breakpoint = breakpoints[lineNumber];
303 this.removeBreakpoint(uiSourceCode, parseInt(lineNumber, 10));
305 var newLineNumber = diff.left[lineNumber].row;
306 if (newLineNumber === undefined) {
307 for (var i = lineNumber - 1; i >= 0; --i) {
308 if (diff.left[i].row === undefined)
310 var shiftedLineNumber = diff.left[i].row + lineNumber - i;
311 if (shiftedLineNumber < diff.right.length) {
312 var originalLineNumber = diff.right[shiftedLineNumber].row;
313 if (originalLineNumber === lineNumber || originalLineNumber === undefined)
314 newLineNumber = shiftedLineNumber;
319 if (newLineNumber !== undefined)
320 this.setBreakpoint(uiSourceCode, newLineNumber, breakpoint.condition, breakpoint.enabled);
325 * @param {boolean} formatSource
327 setFormatSource: function(formatSource)
329 if (this._formatSource === formatSource)
332 this._formatSource = formatSource;
333 this._breakpointManager.reset();
334 for (var id in this._rawSourceCodeForScriptId)
335 this._rawSourceCodeForScriptId[id].setFormatted(this._formatSource);
339 * @param {WebInspector.UISourceCode} uiSourceCode
340 * @param {string} sourceMappingURL
342 setCompilerSourceMapping: function(uiSourceCode, sourceMappingURL)
344 var sourceMapping = new WebInspector.ClosureCompilerSourceMapping(sourceMappingURL);
345 uiSourceCode.rawSourceCode.setCompilerSourceMapping(sourceMapping);
349 * @param {WebInspector.Event} event
351 _consoleMessageAdded: function(event)
353 var message = /** @type {WebInspector.ConsoleMessage} */ event.data;
354 if (!message.url || !message.isErrorOrWarning() || !message.message)
357 var rawSourceCode = this._rawSourceCodeForScriptWithURL(message.url);
361 rawSourceCode.messages.push(message);
362 if (rawSourceCode.sourceMapping) {
363 message._presentationMessage = this._createPresentationMessage(message, rawSourceCode.sourceMapping);
364 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ConsoleMessageAdded, message._presentationMessage);
369 * @param {WebInspector.ConsoleMessage} message
370 * @param {WebInspector.RawSourceCode.SourceMapping} sourceMapping
371 * @return {WebInspector.PresentationConsoleMessage}
373 _createPresentationMessage: function(message, sourceMapping)
375 // FIXME(62725): stack trace line/column numbers are one-based.
376 var lineNumber = message.stackTrace ? message.stackTrace[0].lineNumber - 1 : message.line - 1;
377 var columnNumber = message.stackTrace ? message.stackTrace[0].columnNumber - 1 : 0;
378 var uiLocation = sourceMapping.rawLocationToUILocation(/** @type {DebuggerAgent.Location} */ { lineNumber: lineNumber, columnNumber: columnNumber });
379 var presentationMessage = new WebInspector.PresentationConsoleMessage(uiLocation.uiSourceCode, uiLocation.lineNumber, message);
380 return presentationMessage;
383 _consoleCleared: function()
385 for (var id in this._rawSourceCodeForScriptId)
386 this._rawSourceCodeForScriptId[id].messages = [];
387 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ConsoleMessagesCleared);
391 * @param {WebInspector.UISourceCode} uiSourceCode
392 * @param {number} lineNumber
394 continueToLine: function(uiSourceCode, lineNumber)
396 // FIXME: use RawSourceCode.uiLocationToRawLocation.
397 var rawLocation = uiSourceCode.rawSourceCode.sourceMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, 0);
398 WebInspector.debuggerModel.continueToLocation(rawLocation);
402 * @param {WebInspector.UISourceCode} uiSourceCode
403 * @return {Array.<WebInspector.Breakpoint>}
405 breakpointsForUISourceCode: function(uiSourceCode)
407 var breakpointsMap = this._breakpointManager.breakpointsForUISourceCode(uiSourceCode);
408 var breakpointsList = [];
409 for (var lineNumber in breakpointsMap)
410 breakpointsList.push(breakpointsMap[lineNumber]);
411 return breakpointsList;
415 * @param {WebInspector.UISourceCode} uiSourceCode
416 * @return {Array.<WebInspector.ConsoleMessage>}
418 messagesForUISourceCode: function(uiSourceCode)
420 var rawSourceCode = uiSourceCode.rawSourceCode;
422 for (var i = 0; i < rawSourceCode.messages.length; ++i)
423 messages.push(rawSourceCode.messages[i]._presentationMessage);
428 * @param {WebInspector.UISourceCode} uiSourceCode
429 * @param {number} lineNumber
430 * @param {string} condition
431 * @param {boolean} enabled
433 setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
435 this._breakpointManager.setBreakpoint(uiSourceCode, lineNumber, condition, enabled);
439 * @param {WebInspector.UISourceCode} uiSourceCode
440 * @param {number} lineNumber
441 * @param {boolean} enabled
443 setBreakpointEnabled: function(uiSourceCode, lineNumber, enabled)
445 var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber);
448 this._breakpointManager.removeBreakpoint(uiSourceCode, lineNumber);
449 this._breakpointManager.setBreakpoint(uiSourceCode, lineNumber, breakpoint.condition, enabled);
453 * @param {WebInspector.UISourceCode} uiSourceCode
454 * @param {number} lineNumber
455 * @param {string} condition
456 * @param {boolean} enabled
458 updateBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
460 this._breakpointManager.removeBreakpoint(uiSourceCode, lineNumber);
461 this._breakpointManager.setBreakpoint(uiSourceCode, lineNumber, condition, enabled);
465 * @param {WebInspector.UISourceCode} uiSourceCode
466 * @param {number} lineNumber
468 removeBreakpoint: function(uiSourceCode, lineNumber)
470 this._breakpointManager.removeBreakpoint(uiSourceCode, lineNumber);
474 * @param {WebInspector.UISourceCode} uiSourceCode
475 * @param {number} lineNumber
476 * @return {WebInspector.Breakpoint|undefined}
478 findBreakpoint: function(uiSourceCode, lineNumber)
480 return this._breakpointManager.breakpointsForUISourceCode(uiSourceCode)[lineNumber];
484 * @param {WebInspector.Breakpoint} breakpoint
486 _breakpointAdded: function(breakpoint)
488 if (breakpoint.uiSourceCode)
489 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
493 * @param {WebInspector.Breakpoint} breakpoint
495 _breakpointRemoved: function(breakpoint)
497 if (breakpoint.uiSourceCode)
498 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointRemoved, breakpoint);
501 _debuggerPaused: function()
503 var callFrames = WebInspector.debuggerModel.callFrames;
504 this._presentationCallFrames = [];
505 for (var i = 0; i < callFrames.length; ++i) {
506 var callFrame = callFrames[i];
507 var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.location.scriptId);
510 var rawSourceCode = this._rawSourceCodeForScript(script);
511 this._presentationCallFrames.push(new WebInspector.PresentationCallFrame(callFrame, i, this, rawSourceCode));
513 var details = WebInspector.debuggerModel.debuggerPausedDetails;
514 this.selectedCallFrame = this._presentationCallFrames[0];
515 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.DebuggerPaused, { callFrames: this._presentationCallFrames, details: details });
518 _debuggerResumed: function()
520 this._presentationCallFrames = [];
521 this.selectedCallFrame = null;
522 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.DebuggerResumed);
527 return !!WebInspector.debuggerModel.debuggerPausedDetails;
530 set selectedCallFrame(callFrame)
532 if (this._selectedCallFrame)
533 this._selectedCallFrame.rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._dispatchExecutionLineChanged, this);
534 this._selectedCallFrame = callFrame;
535 if (!this._selectedCallFrame)
538 this._selectedCallFrame.rawSourceCode.forceUpdateSourceMapping();
539 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, callFrame);
541 this._selectedCallFrame.rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._dispatchExecutionLineChanged, this);
544 get selectedCallFrame()
546 return this._selectedCallFrame;
550 * @param {function(?WebInspector.RemoteObject, boolean, RuntimeAgent.RemoteObject=)} callback
552 evaluateInSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, returnByValue, callback)
555 * @param {?RuntimeAgent.RemoteObject} result
556 * @param {boolean} wasThrown
558 function didEvaluate(result, wasThrown)
561 callback(null, wasThrown, wasThrown ? null : result);
563 callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
565 if (objectGroup === "console")
566 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);
569 this.selectedCallFrame.evaluate(code, objectGroup, includeCommandLineAPI, returnByValue, didEvaluate.bind(this));
573 * @param {function(Object)} callback
575 getSelectedCallFrameVariables: function(callback)
577 var result = { this: true };
579 var selectedCallFrame = this.selectedCallFrame;
580 if (!selectedCallFrame)
583 var pendingRequests = 0;
585 function propertiesCollected(properties)
587 for (var i = 0; properties && i < properties.length; ++i)
588 result[properties[i].name] = true;
589 if (--pendingRequests == 0)
593 for (var i = 0; i < selectedCallFrame.scopeChain.length; ++i) {
594 var scope = selectedCallFrame.scopeChain[i];
595 var object = WebInspector.RemoteObject.fromPayload(scope.object);
597 object.getAllProperties(propertiesCollected);
602 * @param {WebInspector.Event} event
604 _dispatchExecutionLineChanged: function(event)
606 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.ExecutionLineChanged, this.executionLineLocation);
610 * @type {WebInspector.UILocation}
612 get executionLineLocation()
614 if (!this._selectedCallFrame.rawSourceCode.sourceMapping)
617 var rawLocation = this._selectedCallFrame._callFrame.location;
618 var uiLocation = this._selectedCallFrame.rawSourceCode.sourceMapping.rawLocationToUILocation(rawLocation);
623 * @param {string} sourceURL
625 _rawSourceCodeForScriptWithURL: function(sourceURL)
627 return this._rawSourceCodeForURL[sourceURL];
631 * @param {WebInspector.Script} script
633 _rawSourceCodeForScript: function(script)
635 return this._rawSourceCodeForScriptId[script.scriptId];
639 * @param {WebInspector.RawSourceCode} rawSourceCode
641 _scriptForRawSourceCode: function(rawSourceCode)
644 * @this {WebInspector.DebuggerPresentationModel}
645 * @param {WebInspector.Script} script
648 function filter(script)
650 return script.scriptId === rawSourceCode.id;
652 return WebInspector.debuggerModel.queryScripts(filter.bind(this))[0];
655 _debuggerReset: function()
657 for (var id in this._rawSourceCodeForScriptId) {
658 var rawSourceCode = this._rawSourceCodeForScriptId[id];
659 if (rawSourceCode.sourceMapping) {
660 var uiSourceCodeList = rawSourceCode.sourceMapping.uiSourceCodeList();
661 for (var i = 0; i < uiSourceCodeList.length; ++i)
662 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.UISourceCodeRemoved, uiSourceCodeList[i]);
664 rawSourceCode.removeAllListeners();
666 this._rawSourceCodeForScriptId = {};
667 this._rawSourceCodeForURL = {};
668 this._rawSourceCodeForDocumentURL = {};
669 this._presentationCallFrames = [];
670 this._selectedCallFrame = null;
671 this._breakpointManager.debuggerReset();
672 this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.DebuggerReset);
676 WebInspector.DebuggerPresentationModel.prototype.__proto__ = WebInspector.Object.prototype;
680 * @param {WebInspector.UISourceCode} uiSourceCode
681 * @param {number} lineNumber
682 * @param {WebInspector.ConsoleMessage} originalMessage
684 WebInspector.PresentationConsoleMessage = function(uiSourceCode, lineNumber, originalMessage)
686 this.uiSourceCode = uiSourceCode;
687 this.lineNumber = lineNumber;
688 this.originalMessage = originalMessage;
693 * @param {DebuggerAgent.CallFrame} callFrame
694 * @param {number} index
695 * @param {WebInspector.DebuggerPresentationModel} model
696 * @param {WebInspector.RawSourceCode} rawSourceCode
698 WebInspector.PresentationCallFrame = function(callFrame, index, model, rawSourceCode)
700 this._callFrame = callFrame;
703 this._rawSourceCode = rawSourceCode;
706 WebInspector.PresentationCallFrame.prototype = {
712 return this._callFrame.type;
716 * @return {Array.<DebuggerAgent.Scope>}
720 return this._callFrame.scopeChain;
724 * @return {RuntimeAgent.RemoteObject}
728 return this._callFrame.this;
740 * @return {WebInspector.RawSourceCode}
744 return this._rawSourceCode;
748 * @param {string} code
749 * @param {string} objectGroup
750 * @param {boolean} includeCommandLineAPI
751 * @param {boolean} returnByValue
752 * @param {function(?RuntimeAgent.RemoteObject, boolean)=} callback
754 evaluate: function(code, objectGroup, includeCommandLineAPI, returnByValue, callback)
757 * @this {WebInspector.PresentationCallFrame}
758 * @param {?Protocol.Error} error
759 * @param {RuntimeAgent.RemoteObject} result
760 * @param {boolean} wasThrown
762 function didEvaluateOnCallFrame(error, result, wasThrown)
765 console.error(error);
766 callback(null, false);
769 callback(result, wasThrown);
771 DebuggerAgent.evaluateOnCallFrame(this._callFrame.callFrameId, code, objectGroup, includeCommandLineAPI, returnByValue, didEvaluateOnCallFrame.bind(this));
775 * @param {function(WebInspector.UILocation)} callback
777 uiLocation: function(callback)
779 function sourceMappingReady()
781 this._rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingReady, this);
782 callback(this._rawSourceCode.sourceMapping.rawLocationToUILocation(this._callFrame.location));
784 if (this._rawSourceCode.sourceMapping)
785 sourceMappingReady.call(this);
787 this._rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, sourceMappingReady, this);
793 * @extends {WebInspector.Placard}
794 * @param {WebInspector.PresentationCallFrame} callFrame
796 WebInspector.DebuggerPresentationModel.CallFramePlacard = function(callFrame)
798 WebInspector.Placard.call(this, callFrame._callFrame.functionName || WebInspector.UIString("(anonymous function)"), "");
799 this._callFrame = callFrame;
800 var rawSourceCode = callFrame._rawSourceCode;
801 if (rawSourceCode.sourceMapping)
803 rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._update, this);
806 WebInspector.DebuggerPresentationModel.CallFramePlacard.prototype = {
809 this._callFrame._rawSourceCode.removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._update, this);
814 var rawSourceCode = this._callFrame._rawSourceCode;
815 var uiLocation = rawSourceCode.sourceMapping.rawLocationToUILocation(this._callFrame._callFrame.location);
816 this.subtitle = WebInspector.displayNameForURL(uiLocation.uiSourceCode.url) + ":" + (uiLocation.lineNumber + 1);
820 WebInspector.DebuggerPresentationModel.CallFramePlacard.prototype.__proto__ = WebInspector.Placard.prototype;
824 * @implements {WebInspector.ResourceDomainModelBinding}
825 * @param {WebInspector.DebuggerPresentationModel} model
827 WebInspector.DebuggerPresentationModelResourceBinding = function(model)
829 this._presentationModel = model;
830 WebInspector.Resource.registerDomainModelBinding(WebInspector.Resource.Type.Script, this);
833 WebInspector.DebuggerPresentationModelResourceBinding.prototype = {
835 * @param {WebInspector.Resource} resource
837 canSetContent: function(resource)
839 var rawSourceCode = this._presentationModel._rawSourceCodeForScriptWithURL(resource.url)
842 return this._presentationModel.canEditScriptSource(rawSourceCode.sourceMapping.uiSourceCodeList()[0]);
846 * @param {WebInspector.Resource} resource
847 * @param {string} content
848 * @param {boolean} majorChange
849 * @param {function(?Protocol.Error)} userCallback
851 setContent: function(resource, content, majorChange, userCallback)
856 var rawSourceCode = this._presentationModel._rawSourceCodeForScriptWithURL(resource.url);
857 if (!rawSourceCode) {
858 userCallback("Resource is not editable");
862 resource.requestContent(this._setContentWithInitialContent.bind(this, rawSourceCode.sourceMapping.uiSourceCodeList()[0], content, userCallback));
866 * @param {WebInspector.UISourceCode} uiSourceCode
867 * @param {string} content
868 * @param {function(?Protocol.Error)} userCallback
869 * @param {string} oldContent
871 _setContentWithInitialContent: function(uiSourceCode, content, userCallback, oldContent)
874 * @this {WebInspector.DebuggerPresentationModelResourceBinding}
875 * @param {?Protocol.Error} error
877 function callback(error)
882 this._presentationModel._updateBreakpointsAfterLiveEdit(uiSourceCode, oldContent, content);
884 this._presentationModel.setScriptSource(uiSourceCode, content, callback.bind(this));
891 WebInspector.DebuggerPresentationModel.LinkifierFormatter = function()
895 WebInspector.DebuggerPresentationModel.LinkifierFormatter.prototype = {
897 * @param {WebInspector.RawSourceCode} rawSourceCode
898 * @param {Element} anchor
900 formatRawSourceCodeAnchor: function(rawSourceCode, anchor) { },
905 * @implements {WebInspector.DebuggerPresentationModel.LinkifierFormatter}
906 * @param {number=} maxLength
908 WebInspector.DebuggerPresentationModel.DefaultLinkifierFormatter = function(maxLength)
910 this._maxLength = maxLength;
913 WebInspector.DebuggerPresentationModel.DefaultLinkifierFormatter.prototype = {
915 * @param {WebInspector.RawSourceCode} rawSourceCode
916 * @param {Element} anchor
918 formatRawSourceCodeAnchor: function(rawSourceCode, anchor)
920 var uiLocation = rawSourceCode.sourceMapping.rawLocationToUILocation(anchor.rawLocation);
922 anchor.textContent = WebInspector.formatLinkText(uiLocation.uiSourceCode.url, uiLocation.lineNumber);
924 var text = WebInspector.formatLinkText(uiLocation.uiSourceCode.url, uiLocation.lineNumber);
926 text = text.trimMiddle(this._maxLength);
927 anchor.textContent = text;
931 WebInspector.DebuggerPresentationModel.DefaultLinkifierFormatter.prototype.__proto__ = WebInspector.DebuggerPresentationModel.LinkifierFormatter.prototype;
935 * @param {WebInspector.DebuggerPresentationModel} model
936 * @param {WebInspector.DebuggerPresentationModel.LinkifierFormatter=} formatter
938 WebInspector.DebuggerPresentationModel.Linkifier = function(model, formatter)
941 this._formatter = formatter || new WebInspector.DebuggerPresentationModel.DefaultLinkifierFormatter();
942 this._anchorsForRawSourceCode = {};
945 WebInspector.DebuggerPresentationModel.Linkifier.prototype = {
947 * @param {string} sourceURL
948 * @param {number} lineNumber
949 * @param {number=} columnNumber
950 * @param {string=} classes
952 linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
954 var rawSourceCode = this._model._rawSourceCodeForScriptWithURL(sourceURL);
956 return this.linkifyResource(sourceURL, lineNumber, classes);
958 return this.linkifyRawSourceCode(rawSourceCode, lineNumber, columnNumber, classes);
962 * @param {string} sourceURL
963 * @param {number} lineNumber
964 * @param {string=} classes
966 linkifyResource: function(sourceURL, lineNumber, classes)
968 var linkText = WebInspector.formatLinkText(sourceURL, lineNumber);
969 var anchor = WebInspector.linkifyURLAsNode(sourceURL, linkText, classes, false);
970 anchor.setAttribute("preferred_panel", "resources");
971 anchor.setAttribute("line_number", lineNumber);
976 * @param {WebInspector.RawSourceCode} rawSourceCode
977 * @param {number=} lineNumber
978 * @param {number=} columnNumber
979 * @param {string=} classes
981 linkifyRawSourceCode: function(rawSourceCode, lineNumber, columnNumber, classes)
983 var anchor = WebInspector.linkifyURLAsNode(rawSourceCode.url, "", classes, false);
984 anchor.rawLocation = { lineNumber: lineNumber, columnNumber: columnNumber };
986 var anchors = this._anchorsForRawSourceCode[rawSourceCode.id];
989 this._anchorsForRawSourceCode[rawSourceCode.id] = anchors;
990 rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._updateSourceAnchors, this);
993 if (rawSourceCode.sourceMapping)
994 this._updateAnchor(rawSourceCode, anchor);
995 anchors.push(anchor);
1001 for (var id in this._anchorsForRawSourceCode) {
1002 if (this._model._rawSourceCodeForScriptId[id]) // In case of navigation the list of rawSourceCodes is empty.
1003 this._model._rawSourceCodeForScriptId[id].removeEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, this._updateSourceAnchors, this);
1005 this._anchorsForRawSourceCode = {};
1009 * @param {WebInspector.Event} event
1011 _updateSourceAnchors: function(event)
1013 var rawSourceCode = /** @type {WebInspector.RawSourceCode} */ event.target;
1014 var anchors = this._anchorsForRawSourceCode[rawSourceCode.id];
1015 for (var i = 0; i < anchors.length; ++i)
1016 this._updateAnchor(rawSourceCode, anchors[i]);
1020 * @param {WebInspector.RawSourceCode} rawSourceCode
1021 * @param {Element} anchor
1023 _updateAnchor: function(rawSourceCode, anchor)
1025 var uiLocation = rawSourceCode.sourceMapping.rawLocationToUILocation(anchor.rawLocation);
1026 anchor.setAttribute("preferred_panel", "scripts");
1027 anchor.uiSourceCode = uiLocation.uiSourceCode;
1028 anchor.lineNumber = uiLocation.lineNumber;
1030 this._formatter.formatRawSourceCodeAnchor(rawSourceCode, anchor);
1034 WebInspector.DebuggerPresentationModelResourceBinding.prototype.__proto__ = WebInspector.ResourceDomainModelBinding.prototype;
1037 * @type {?WebInspector.DebuggerPresentationModel}
1039 WebInspector.debuggerPresentationModel = null;