2011-03-09 Pavel Podivilov <podivilov@chromium.org>

        Reviewed by Pavel Feldman.

        Web Inspector: re-implement breakpoints sidebar pane based on debugger presentation model.
        https://bugs.webkit.org/show_bug.cgi?id=55823

        * inspector/front-end/BreakpointsSidebarPane.js:
        (WebInspector.JavaScriptBreakpointsSidebarPane):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.addBreakpoint.didLoadSnippet):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.addBreakpoint):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.removeBreakpoint):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.highlightBreakpoint):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.clearBreakpointHighlight):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype._createBreakpointItemId):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype._breakpointClicked):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype._breakpointCheckboxClicked):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype._contextMenu):
        (WebInspector.JavaScriptBreakpointsSidebarPane.prototype.reset):
        * inspector/front-end/DebuggerPresentationModel.js:
        (WebInspector.DebuggerPresentationModel):
        (WebInspector.DebuggerPresentationModel.prototype._parsedScriptSource):
        (WebInspector.DebuggerPresentationModel.prototype._failedToParseScriptSource):
        (WebInspector.DebuggerPresentationModel.prototype._revealHiddenBreakpoints):
        (WebInspector.DebuggerPresentationModel.prototype.breakpointsForSourceFileId):
        (WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled):
        (WebInspector.DebuggerPresentationModel.prototype.removeBreakpoint):
        (WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
        (WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
        (WebInspector.DebuggerPresentationModel.prototype._actualLocationToSourceLocation):
        (WebInspector.DebuggerPresentationModel.prototype.reset):
        * inspector/front-end/ScriptsPanel.js:
        (WebInspector.ScriptsPanel):
        (WebInspector.ScriptsPanel.prototype._breakpointAdded):
        (WebInspector.ScriptsPanel.prototype._breakpointRemoved):
        (WebInspector.ScriptsPanel.prototype._debuggerPaused):
        (WebInspector.ScriptsPanel.prototype.reset):
        (WebInspector.ScriptsPanel.prototype._clearInterface):

git-svn-id: svn://svn.chromium.org/blink/trunk@80705 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 84100674
2011-03-09 Pavel Podivilov <podivilov@chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: re-implement breakpoints sidebar pane based on debugger presentation model.
https://bugs.webkit.org/show_bug.cgi?id=55823
* inspector/front-end/BreakpointsSidebarPane.js:
(WebInspector.JavaScriptBreakpointsSidebarPane):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.addBreakpoint.didLoadSnippet):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.addBreakpoint):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.removeBreakpoint):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.highlightBreakpoint):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.clearBreakpointHighlight):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype._createBreakpointItemId):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype._breakpointClicked):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype._breakpointCheckboxClicked):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype._contextMenu):
(WebInspector.JavaScriptBreakpointsSidebarPane.prototype.reset):
* inspector/front-end/DebuggerPresentationModel.js:
(WebInspector.DebuggerPresentationModel):
(WebInspector.DebuggerPresentationModel.prototype._parsedScriptSource):
(WebInspector.DebuggerPresentationModel.prototype._failedToParseScriptSource):
(WebInspector.DebuggerPresentationModel.prototype._revealHiddenBreakpoints):
(WebInspector.DebuggerPresentationModel.prototype.breakpointsForSourceFileId):
(WebInspector.DebuggerPresentationModel.prototype.setBreakpointEnabled):
(WebInspector.DebuggerPresentationModel.prototype.removeBreakpoint):
(WebInspector.DebuggerPresentationModel.prototype._breakpointAdded):
(WebInspector.DebuggerPresentationModel.prototype.set selectedCallFrame):
(WebInspector.DebuggerPresentationModel.prototype._actualLocationToSourceLocation):
(WebInspector.DebuggerPresentationModel.prototype.reset):
* inspector/front-end/ScriptsPanel.js:
(WebInspector.ScriptsPanel):
(WebInspector.ScriptsPanel.prototype._breakpointAdded):
(WebInspector.ScriptsPanel.prototype._breakpointRemoved):
(WebInspector.ScriptsPanel.prototype._debuggerPaused):
(WebInspector.ScriptsPanel.prototype.reset):
(WebInspector.ScriptsPanel.prototype._clearInterface):
2011-03-10 Andrey Adaikin <aandrey@google.com>
Reviewed by Pavel Feldman.
......
......@@ -23,10 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.JavaScriptBreakpointsSidebarPane = function(title)
WebInspector.JavaScriptBreakpointsSidebarPane = function(model)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
this._model = model;
this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";
......@@ -37,36 +39,37 @@ WebInspector.JavaScriptBreakpointsSidebarPane = function(title)
this.bodyElement.appendChild(this.emptyElement);
this._items = {};
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
}
WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
_breakpointAdded: function(event)
addBreakpoint: function(breakpoint)
{
var breakpoint = event.data;
var breakpointId = breakpoint.id;
if (breakpoint.url && !WebInspector.debuggerModel.scriptsForURL(breakpoint.url).length)
return;
var element = document.createElement("li");
element.addStyleClass("cursor-pointer");
element.addEventListener("contextmenu", this._contextMenu.bind(this, breakpoint), true);
element.addEventListener("click", this._breakpointClicked.bind(this, breakpoint), false);
var checkbox = document.createElement("input");
checkbox.className = "checkbox-elem";
checkbox.type = "checkbox";
checkbox.checked = breakpoint.enabled;
checkbox.addEventListener("click", this._breakpointItemCheckboxClicked.bind(this, breakpointId), false);
checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, breakpoint), false);
element.appendChild(checkbox);
var label = document.createElement("span");
element.appendChild(label);
var displayName = breakpoint.url ? WebInspector.displayNameForURL(breakpoint.url) : WebInspector.UIString("(program)");
var labelElement = document.createTextNode(displayName + ":" + (breakpoint.lineNumber + 1));
element.appendChild(labelElement);
var snippetElement = document.createElement("div");
snippetElement.className = "source-text monospace";
element.appendChild(snippetElement);
if (breakpoint.loadSnippet) {
function didLoadSnippet(snippet)
{
snippetElement.textContent = snippet;
}
breakpoint.loadSnippet(didLoadSnippet);
}
element._data = breakpoint;
var currentElement = this.listElement.firstChild;
......@@ -77,88 +80,68 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
}
this._addListElement(element, currentElement);
element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointId), true);
this._setupBreakpointElement(breakpoint, element);
var breakpointItem = {};
breakpointItem.element = element;
breakpointItem.checkbox = checkbox;
this._items[breakpointId] = breakpointItem;
this._items[this._createBreakpointItemId(breakpoint.sourceFileId, breakpoint.lineNumber)] = breakpointItem;
if (!this.expanded)
this.expanded = true;
},
_breakpointRemoved: function(event)
removeBreakpoint: function(sourceFileId, lineNumber)
{
var breakpointId = event.data;
var breakpointItem = this._items[breakpointId];
if (breakpointItem) {
delete this._items[breakpointId];
var breakpointItemId = this._createBreakpointItemId(sourceFileId, lineNumber);
var breakpointItem = this._items[breakpointItemId];
if (!breakpointItem)
return;
delete this._items[breakpointItemId];
this._removeListElement(breakpointItem.element);
}
},
_breakpointResolved: function(event)
highlightBreakpoint: function(sourceFileId, lineNumber)
{
var breakpoint = event.data;
this._breakpointRemoved({ data: breakpoint.id });
this._breakpointAdded({ data: breakpoint });
var breakpointItem = this._items[this._createBreakpointItemId(sourceFileId, lineNumber)];
if (!breakpointItem)
return;
breakpointItem.element.addStyleClass("breakpoint-hit");
this._highlightedBreakpointItem = breakpointItem;
},
_parsedScriptSource: function(event)
clearBreakpointHighlight: function()
{
var url = event.data.sourceURL;
var breakpoints = WebInspector.debuggerModel.breakpoints;
for (var id in breakpoints) {
if (!(id in this._items))
this._breakpointAdded({ data: breakpoints[id] });
if (this._highlightedBreakpointItem) {
this._highlightedBreakpointItem.element.removeStyleClass("breakpoint-hit");
delete this._highlightedBreakpointItem;
}
},
_breakpointEnableChanged: function(enabled, event)
_createBreakpointItemId: function(sourceFileId, lineNumber)
{
var breakpointId = event.data;
var breakpointItem = this._items[breakpointId];
if (breakpointItem)
breakpointItem.checkbox.checked = enabled;
return sourceFileId + ":" + lineNumber;
},
_breakpointItemCheckboxClicked: function(breakpointId, event)
_breakpointClicked: function(breakpoint, event)
{
var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId);
WebInspector.debuggerModel.updateBreakpoint(breakpointId, breakpoint.condition, event.target.checked);
WebInspector.panels.scripts.showSourceLine(breakpoint.sourceFileId, breakpoint.lineNumber + 1);
},
// Breakpoint element may have it's own click handler.
_breakpointCheckboxClicked: function(breakpoint, event)
{
// Breakpoint element has it's own click handler.
event.stopPropagation();
this._model.setBreakpointEnabled(breakpoint.sourceFileId, breakpoint.lineNumber, event.target.checked);
},
_contextMenuEventFired: function(breakpointId, event)
_contextMenu: function(breakpoint, event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), this._removeBreakpoint.bind(this, breakpointId));
contextMenu.show(event);
},
_debuggerPaused: function(event)
{
var breakpoint = event.data.breakpoint;
if (!breakpoint)
return;
var breakpointItem = this._items[breakpoint.id];
if (!breakpointItem)
return;
breakpointItem.element.addStyleClass("breakpoint-hit");
this._lastHitBreakpointItem = breakpointItem;
},
var removeHandler = this._model.removeBreakpoint.bind(this._model, breakpoint.sourceFileId, breakpoint.lineNumber);
contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeHandler);
_debuggerResumed: function()
{
if (this._lastHitBreakpointItem) {
this._lastHitBreakpointItem.element.removeStyleClass("breakpoint-hit");
delete this._lastHitBreakpointItem;
}
contextMenu.show(event);
},
_addListElement: function(element, beforeElement)
......@@ -183,16 +166,6 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
}
},
_projectChanged: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
this._items = {};
},
_compare: function(x, y)
{
if (x !== y)
......@@ -205,40 +178,14 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
return this._compare(b1.url, b2.url) || this._compare(b1.lineNumber, b2.lineNumber);
},
_setupBreakpointElement: function(data, element)
reset: function()
{
var sourceID;
var lineNumber = data.lineNumber;
if (data.locations.length) {
sourceID = data.locations[0].sourceID;
lineNumber = data.locations[0].lineNumber;
}
var displayName = data.url ? WebInspector.displayNameForURL(data.url) : WebInspector.UIString("(program)");
var labelElement = document.createTextNode(displayName + ":" + (lineNumber + 1));
element.appendChild(labelElement);
var sourceTextElement = document.createElement("div");
sourceTextElement.className = "source-text monospace";
element.appendChild(sourceTextElement);
if (sourceID) {
function didGetSourceLine(text)
{
sourceTextElement.textContent = text;
}
var script = WebInspector.debuggerModel.scriptForSourceID(sourceID);
script.sourceLine(lineNumber, didGetSourceLine.bind(this));
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
element.addStyleClass("cursor-pointer");
var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, lineNumber + 1);
element.addEventListener("click", clickHandler, false);
},
_removeBreakpoint: function(breakpointId)
{
WebInspector.debuggerModel.removeBreakpoint(breakpointId);
this._items = {};
}
}
......
......@@ -33,6 +33,8 @@ WebInspector.DebuggerPresentationModel = function()
this._breakpoints = {};
this._sourceLocationToBreakpointId = {};
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
......@@ -44,17 +46,60 @@ WebInspector.DebuggerPresentationModel.Events = {
}
WebInspector.DebuggerPresentationModel.prototype = {
_parsedScriptSource: function(event)
{
var script = event.data;
if (script.sourceURL)
this._revealHiddenBreakpoints(script.sourceURL);
},
_failedToParseScriptSource: function(event)
{
var script = event.data;
if (script.sourceURL)
this._revealHiddenBreakpoints(script.sourceURL);
},
_revealHiddenBreakpoints: function(url)
{
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
if (breakpoint._hidden && breakpoint.url === url) {
delete breakpoint._hidden;
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, breakpoint);
}
}
},
breakpointsForSourceFileId: function(sourceFileId)
{
var breakpoints = [];
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
if (breakpoint.sourceFileId === sourceFileId)
if (!breakpoint._hidden && breakpoint.sourceFileId === sourceFileId)
breakpoints.push(breakpoint);
}
return breakpoints;
},
setBreakpointEnabled: function(sourceFileId, lineNumber, enabled)
{
var encodedSourceLocation = this._encodeSourceLocation(sourceFileId, lineNumber);
var breakpointId = this._sourceLocationToBreakpointId[encodedSourceLocation];
if (!breakpointId)
return;
var breakpoint = this._breakpoints[breakpointId];
WebInspector.debuggerModel.updateBreakpoint(breakpointId, breakpoint.condition, enabled);
},
removeBreakpoint: function(sourceFileId, lineNumber)
{
var encodedSourceLocation = this._encodeSourceLocation(sourceFileId, lineNumber);
var breakpointId = this._sourceLocationToBreakpointId[encodedSourceLocation];
if (breakpointId)
WebInspector.debuggerModel.removeBreakpoint(breakpointId);
},
_breakpointAdded: function(event)
{
var breakpoint = event.data;
......@@ -76,10 +121,17 @@ WebInspector.DebuggerPresentationModel.prototype = {
condition: breakpoint.condition,
enabled: breakpoint.enabled
};
if (location.sourceID) {
var script = WebInspector.debuggerModel.scriptForSourceID(location.sourceID);
presentationBreakpoint.loadSnippet = script.sourceLine.bind(script, location.lineNumber);
}
this._sourceLocationToBreakpointId[encodedSourceLocation] = breakpoint.id;
this._breakpoints[breakpoint.id] = presentationBreakpoint;
if (!WebInspector.debuggerModel.scriptsForURL(breakpoint.url).length)
presentationBreakpoint._hidden = true;
else
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.BreakpointAdded, presentationBreakpoint);
},
......@@ -110,7 +162,6 @@ WebInspector.DebuggerPresentationModel.prototype = {
this._selectedCallFrame = callFrame;
if (!callFrame)
return;
var script = WebInspector.debuggerModel.scriptForSourceID(callFrame.sourceID);
callFrame.sourceLocation = this._actualLocationToSourceLocation(script.sourceURL || script.sourceID, callFrame.line, callFrame.column);
this.dispatchEventToListeners(WebInspector.DebuggerPresentationModel.Events.CallFrameSelected, callFrame);
......@@ -125,6 +176,15 @@ WebInspector.DebuggerPresentationModel.prototype = {
{
// TODO: use source mapping to obtain source location.
return { sourceFileId: sourceID, lineNumber: lineNumber, columnNumber: columnNumber };
},
reset: function()
{
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
breakpoint._hidden = true;
}
this._sourceLocationToBreakpointId = {};
}
}
......
......@@ -142,7 +142,7 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(this._presentationModel);
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane();
this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(this._presentationModel);
if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.xhrBreakpoints = WebInspector.createXHRBreakpointsSidebarPane();
......@@ -392,6 +392,8 @@ WebInspector.ScriptsPanel.prototype = {
var sourceFrame = this._sourceFileIdToSourceFrame[breakpoint.sourceFileId];
if (sourceFrame && sourceFrame.loaded)
sourceFrame.addBreakpoint(breakpoint.lineNumber, breakpoint.resolved, breakpoint.condition, breakpoint.enabled);
this.sidebarPanes.jsBreakpoints.addBreakpoint(breakpoint);
},
_breakpointRemoved: function(event)
......@@ -401,6 +403,8 @@ WebInspector.ScriptsPanel.prototype = {
var sourceFrame = this._sourceFileIdToSourceFrame[breakpoint.sourceFileId];
if (sourceFrame && sourceFrame.loaded)
sourceFrame.removeBreakpoint(breakpoint.lineNumber);
this.sidebarPanes.jsBreakpoints.removeBreakpoint(breakpoint.sourceFileId, breakpoint.lineNumber);
},
evaluateInSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, callback)
......@@ -432,6 +436,9 @@ WebInspector.ScriptsPanel.prototype = {
this.sidebarPanes.callstack.update(event.data);
this.sidebarPanes.callstack.selectedCallFrame = callFrames[0];
var sourceLocation = this._presentationModel.selectedCallFrame.sourceLocation;
this.sidebarPanes.jsBreakpoints.highlightBreakpoint(sourceLocation.sourceFileId, sourceLocation.lineNumber);
window.focus();
InspectorFrontendHost.bringToFront();
},
......@@ -468,6 +475,8 @@ WebInspector.ScriptsPanel.prototype = {
reset: function(preserveItems)
{
this._presentationModel.reset();
this.visibleView = null;
delete this.currentQuery;
......@@ -486,6 +495,7 @@ WebInspector.ScriptsPanel.prototype = {
this.functionsSelectElement.removeChildren();
this.viewsContainerElement.removeChildren();
this.sidebarPanes.jsBreakpoints.reset();
this.sidebarPanes.watchExpressions.refreshExpressions();
if (!preserveItems)
this.sidebarPanes.workers.reset();
......@@ -786,6 +796,7 @@ WebInspector.ScriptsPanel.prototype = {
{
this.sidebarPanes.callstack.update(null);
this.sidebarPanes.scopechain.update(null);
this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
this._clearCurrentExecutionLine();
this._updateDebuggerButtons();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment