mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 723071 - Add a pane to display the list of breakpoints across all scripts in the debuggee; f=msucan,past r=past
This commit is contained in:
parent
d10808c6ce
commit
0a14cf5b14
@ -52,6 +52,7 @@ let DebuggerController = {
|
|||||||
DebuggerView.initializePanes();
|
DebuggerView.initializePanes();
|
||||||
DebuggerView.initializeEditor();
|
DebuggerView.initializeEditor();
|
||||||
DebuggerView.StackFrames.initialize();
|
DebuggerView.StackFrames.initialize();
|
||||||
|
DebuggerView.Breakpoints.initialize();
|
||||||
DebuggerView.Properties.initialize();
|
DebuggerView.Properties.initialize();
|
||||||
DebuggerView.Scripts.initialize();
|
DebuggerView.Scripts.initialize();
|
||||||
DebuggerView.showCloseButton(!this._isRemoteDebugger && !this._isChromeDebugger);
|
DebuggerView.showCloseButton(!this._isRemoteDebugger && !this._isChromeDebugger);
|
||||||
@ -75,6 +76,7 @@ let DebuggerController = {
|
|||||||
DebuggerView.destroyEditor();
|
DebuggerView.destroyEditor();
|
||||||
DebuggerView.Scripts.destroy();
|
DebuggerView.Scripts.destroy();
|
||||||
DebuggerView.StackFrames.destroy();
|
DebuggerView.StackFrames.destroy();
|
||||||
|
DebuggerView.Breakpoints.destroy();
|
||||||
DebuggerView.Properties.destroy();
|
DebuggerView.Properties.destroy();
|
||||||
|
|
||||||
DebuggerController.Breakpoints.destroy();
|
DebuggerController.Breakpoints.destroy();
|
||||||
@ -395,8 +397,6 @@ StackFrames.prototype = {
|
|||||||
connect: function SF_connect(aCallback) {
|
connect: function SF_connect(aCallback) {
|
||||||
window.addEventListener("Debugger:FetchedVariables", this._onFetchedVars, false);
|
window.addEventListener("Debugger:FetchedVariables", this._onFetchedVars, false);
|
||||||
|
|
||||||
this._onFramesCleared();
|
|
||||||
|
|
||||||
this.activeThread.addListener("paused", this._onPaused);
|
this.activeThread.addListener("paused", this._onPaused);
|
||||||
this.activeThread.addListener("resumed", this._onResume);
|
this.activeThread.addListener("resumed", this._onResume);
|
||||||
this.activeThread.addListener("framesadded", this._onFrames);
|
this.activeThread.addListener("framesadded", this._onFrames);
|
||||||
@ -506,12 +506,47 @@ StackFrames.prototype = {
|
|||||||
let line = frame.where.line;
|
let line = frame.where.line;
|
||||||
let editor = DebuggerView.editor;
|
let editor = DebuggerView.editor;
|
||||||
|
|
||||||
// Move the editor's caret to the proper line.
|
this.updateEditorToLocation(url, line, true);
|
||||||
if (DebuggerView.Scripts.isSelected(url) && line) {
|
},
|
||||||
editor.setDebugLocation(line - 1);
|
|
||||||
} else {
|
/**
|
||||||
editor.setDebugLocation(-1);
|
* Update the source editor's current caret and debug location based on
|
||||||
|
* a specified url and line.
|
||||||
|
*
|
||||||
|
* @param string aUrl
|
||||||
|
* The target source url.
|
||||||
|
* @param number aLine
|
||||||
|
* The target line number in the source.
|
||||||
|
* @param boolean aNoSwitch
|
||||||
|
* Pass true to not switch to the script if not currently selected.
|
||||||
|
* @param boolean aNoCaretFlag
|
||||||
|
* Pass true to not set the caret location at the specified line.
|
||||||
|
* @param boolean aNoDebugFlag
|
||||||
|
* Pass true to not set the debug location at the specified line.
|
||||||
|
*/
|
||||||
|
updateEditorToLocation:
|
||||||
|
function SF_updateEditorToLocation(aUrl, aLine, aNoSwitch, aNoCaretFlag, aNoDebugFlag) {
|
||||||
|
let editor = DebuggerView.editor;
|
||||||
|
|
||||||
|
function set() {
|
||||||
|
if (!aNoCaretFlag) {
|
||||||
|
editor.setCaretPosition(aLine - 1);
|
||||||
|
}
|
||||||
|
if (!aNoDebugFlag) {
|
||||||
|
editor.setDebugLocation(aLine - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move the editor's caret to the proper url and line.
|
||||||
|
if (DebuggerView.Scripts.isSelected(aUrl)) {
|
||||||
|
return set();
|
||||||
|
}
|
||||||
|
if (!aNoSwitch && DebuggerView.Scripts.contains(aUrl)) {
|
||||||
|
DebuggerView.Scripts.selectScript(aUrl);
|
||||||
|
return set();
|
||||||
|
}
|
||||||
|
editor.setCaretPosition(-1);
|
||||||
|
editor.setDebugLocation(-1);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -550,20 +585,9 @@ StackFrames.prototype = {
|
|||||||
|
|
||||||
let url = frame.where.url;
|
let url = frame.where.url;
|
||||||
let line = frame.where.line;
|
let line = frame.where.line;
|
||||||
let editor = DebuggerView.editor;
|
|
||||||
|
|
||||||
// Move the editor's caret to the proper line.
|
// Move the editor's caret to the proper line.
|
||||||
if (DebuggerView.Scripts.isSelected(url) && line) {
|
this.updateEditorToLocation(url, line);
|
||||||
editor.setCaretPosition(line - 1);
|
|
||||||
editor.setDebugLocation(line - 1);
|
|
||||||
}
|
|
||||||
else if (DebuggerView.Scripts.contains(url)) {
|
|
||||||
DebuggerView.Scripts.selectScript(url);
|
|
||||||
editor.setCaretPosition(line - 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
editor.setDebugLocation(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start recording any added variables or properties in any scope.
|
// Start recording any added variables or properties in any scope.
|
||||||
DebuggerView.Properties.createHierarchyStore();
|
DebuggerView.Properties.createHierarchyStore();
|
||||||
@ -755,7 +779,7 @@ StackFrames.prototype = {
|
|||||||
*/
|
*/
|
||||||
_addFrame: function SF__addFrame(aFrame) {
|
_addFrame: function SF__addFrame(aFrame) {
|
||||||
let depth = aFrame.depth;
|
let depth = aFrame.depth;
|
||||||
let label = DebuggerController.SourceScripts._getScriptLabel(aFrame.where.url);
|
let label = DebuggerController.SourceScripts.getScriptLabel(aFrame.where.url);
|
||||||
|
|
||||||
let startText = this._getFrameTitle(aFrame);
|
let startText = this._getFrameTitle(aFrame);
|
||||||
let endText = label + ":" + aFrame.where.line;
|
let endText = label + ":" + aFrame.where.line;
|
||||||
@ -882,10 +906,12 @@ SourceScripts.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
|
this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
|
||||||
// If there are any stored breakpoints for this script, display them again.
|
|
||||||
for each (let bp in DebuggerController.Breakpoints.store) {
|
// If there are any stored breakpoints for this script, display them again,
|
||||||
if (bp.location.url == aPacket.url) {
|
// both in the editor and the pane.
|
||||||
DebuggerController.Breakpoints.displayBreakpoint(bp.location);
|
for each (let breakpoint in DebuggerController.Breakpoints.store) {
|
||||||
|
if (breakpoint.location.url == aPacket.url) {
|
||||||
|
DebuggerController.Breakpoints.displayBreakpoint(breakpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -898,6 +924,7 @@ SourceScripts.prototype = {
|
|||||||
this._addScript(script, false);
|
this._addScript(script, false);
|
||||||
}
|
}
|
||||||
DebuggerView.Scripts.commitScripts();
|
DebuggerView.Scripts.commitScripts();
|
||||||
|
DebuggerController.Breakpoints.updatePaneBreakpoints();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -905,6 +932,7 @@ SourceScripts.prototype = {
|
|||||||
*/
|
*/
|
||||||
_onScriptsCleared: function SS__onScriptsCleared() {
|
_onScriptsCleared: function SS__onScriptsCleared() {
|
||||||
DebuggerView.Scripts.empty();
|
DebuggerView.Scripts.empty();
|
||||||
|
DebuggerView.Breakpoints.emptyText();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -967,7 +995,7 @@ SourceScripts.prototype = {
|
|||||||
* @return string
|
* @return string
|
||||||
* The resulting label at the final step.
|
* The resulting label at the final step.
|
||||||
*/
|
*/
|
||||||
_trimURL: function SS__trimURL(aUrl, aLabel, aSeq) {
|
_trimUrl: function SS__trimUrl(aUrl, aLabel, aSeq) {
|
||||||
if (!(aUrl instanceof Ci.nsIURL)) {
|
if (!(aUrl instanceof Ci.nsIURL)) {
|
||||||
try {
|
try {
|
||||||
// Use an nsIURL to parse all the url path parts.
|
// Use an nsIURL to parse all the url path parts.
|
||||||
@ -1012,7 +1040,7 @@ SourceScripts.prototype = {
|
|||||||
if (aSeq === 1) {
|
if (aSeq === 1) {
|
||||||
let query = aUrl.query;
|
let query = aUrl.query;
|
||||||
if (query) {
|
if (query) {
|
||||||
return this._trimURL(aUrl, aLabel + "?" + query, aSeq + 1);
|
return this._trimUrl(aUrl, aLabel + "?" + query, aSeq + 1);
|
||||||
}
|
}
|
||||||
aSeq++;
|
aSeq++;
|
||||||
}
|
}
|
||||||
@ -1020,7 +1048,7 @@ SourceScripts.prototype = {
|
|||||||
if (aSeq === 2) {
|
if (aSeq === 2) {
|
||||||
let ref = aUrl.ref;
|
let ref = aUrl.ref;
|
||||||
if (ref) {
|
if (ref) {
|
||||||
return this._trimURL(aUrl, aLabel + "#" + aUrl.ref, aSeq + 1);
|
return this._trimUrl(aUrl, aLabel + "#" + aUrl.ref, aSeq + 1);
|
||||||
}
|
}
|
||||||
aSeq++;
|
aSeq++;
|
||||||
}
|
}
|
||||||
@ -1028,7 +1056,7 @@ SourceScripts.prototype = {
|
|||||||
if (aSeq === 3) {
|
if (aSeq === 3) {
|
||||||
let dir = aUrl.directory;
|
let dir = aUrl.directory;
|
||||||
if (dir) {
|
if (dir) {
|
||||||
return this._trimURL(aUrl, dir.replace(/^\//, "") + aLabel, aSeq + 1);
|
return this._trimUrl(aUrl, dir.replace(/^\//, "") + aLabel, aSeq + 1);
|
||||||
}
|
}
|
||||||
aSeq++;
|
aSeq++;
|
||||||
}
|
}
|
||||||
@ -1036,13 +1064,13 @@ SourceScripts.prototype = {
|
|||||||
if (aSeq === 4) {
|
if (aSeq === 4) {
|
||||||
let host = aUrl.hostPort;
|
let host = aUrl.hostPort;
|
||||||
if (host) {
|
if (host) {
|
||||||
return this._trimURL(aUrl, host + "/" + aLabel, aSeq + 1);
|
return this._trimUrl(aUrl, host + "/" + aLabel, aSeq + 1);
|
||||||
}
|
}
|
||||||
aSeq++;
|
aSeq++;
|
||||||
}
|
}
|
||||||
// Use the whole url spec but ignoring the reference.
|
// Use the whole url spec but ignoring the reference.
|
||||||
if (aSeq === 5) {
|
if (aSeq === 5) {
|
||||||
return this._trimURL(aUrl, aUrl.specIgnoringRef, aSeq + 1);
|
return this._trimUrl(aUrl, aUrl.specIgnoringRef, aSeq + 1);
|
||||||
}
|
}
|
||||||
// Give up.
|
// Give up.
|
||||||
return aUrl.spec;
|
return aUrl.spec;
|
||||||
@ -1059,8 +1087,8 @@ SourceScripts.prototype = {
|
|||||||
* @return string
|
* @return string
|
||||||
* The simplified label.
|
* The simplified label.
|
||||||
*/
|
*/
|
||||||
_getScriptLabel: function SS__getScriptLabel(aUrl, aHref) {
|
getScriptLabel: function SS_getScriptLabel(aUrl, aHref) {
|
||||||
return this._labelsCache[aUrl] || (this._labelsCache[aUrl] = this._trimURL(aUrl));
|
return this._labelsCache[aUrl] || (this._labelsCache[aUrl] = this._trimUrl(aUrl));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1081,7 +1109,7 @@ SourceScripts.prototype = {
|
|||||||
*/
|
*/
|
||||||
_addScript: function SS__addScript(aScript, aForceFlag) {
|
_addScript: function SS__addScript(aScript, aForceFlag) {
|
||||||
DebuggerView.Scripts.addScript(
|
DebuggerView.Scripts.addScript(
|
||||||
this._getScriptLabel(aScript.url), aScript, aForceFlag);
|
this.getScriptLabel(aScript.url), aScript, aForceFlag);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1233,6 +1261,23 @@ SourceScripts.prototype = {
|
|||||||
this.showScript(script, aOptions);
|
this.showScript(script, aOptions);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the text in a source editor's specified line.
|
||||||
|
*
|
||||||
|
* @param number aLine [optional]
|
||||||
|
* The line to get the text from.
|
||||||
|
* If unspecified, it defaults to the current caret position line.
|
||||||
|
* @return string
|
||||||
|
* The specified line text
|
||||||
|
*/
|
||||||
|
getLineText: function SS_getLineText(aLine) {
|
||||||
|
let editor = DebuggerView.editor;
|
||||||
|
let line = aLine || editor.getCaretPosition().line;
|
||||||
|
let start = editor.getLineStart(line);
|
||||||
|
let end = editor.getLineEnd(line);
|
||||||
|
return editor.getText(start, end);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an error message in the error console when a script fails to load.
|
* Log an error message in the error console when a script fails to load.
|
||||||
*
|
*
|
||||||
@ -1395,6 +1440,25 @@ Breakpoints.prototype = {
|
|||||||
this._skipEditorBreakpointChange = false;
|
this._skipEditorBreakpointChange = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the breakpoints in the pane view. This function is invoked when the
|
||||||
|
* scripts are added (typically after a page navigation).
|
||||||
|
*/
|
||||||
|
updatePaneBreakpoints: function BP_updatePaneBreakpoints() {
|
||||||
|
let url = DebuggerView.Scripts.selected;
|
||||||
|
if (!url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._skipEditorBreakpointChange = true;
|
||||||
|
for each (let breakpoint in this.store) {
|
||||||
|
if (DebuggerView.Scripts.contains(breakpoint.location.url)) {
|
||||||
|
this.displayBreakpoint(breakpoint, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._skipEditorBreakpointChange = false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a breakpoint.
|
* Add a breakpoint.
|
||||||
*
|
*
|
||||||
@ -1412,9 +1476,11 @@ Breakpoints.prototype = {
|
|||||||
* @param boolean [aNoEditorUpdate=false]
|
* @param boolean [aNoEditorUpdate=false]
|
||||||
* Tells if you want to skip editor updates. Typically the editor is
|
* Tells if you want to skip editor updates. Typically the editor is
|
||||||
* updated to visually indicate that a breakpoint has been added.
|
* updated to visually indicate that a breakpoint has been added.
|
||||||
|
* @param boolean [aNoPaneUpdate=false]
|
||||||
|
* Tells if you want to skip any breakpoint pane updates.
|
||||||
*/
|
*/
|
||||||
addBreakpoint:
|
addBreakpoint:
|
||||||
function BP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate) {
|
function BP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate, aNoPaneUpdate) {
|
||||||
let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
|
let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
|
||||||
if (breakpoint) {
|
if (breakpoint) {
|
||||||
aCallback && aCallback(breakpoint);
|
aCallback && aCallback(breakpoint);
|
||||||
@ -1423,7 +1489,7 @@ Breakpoints.prototype = {
|
|||||||
|
|
||||||
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
|
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
|
||||||
this.store[aBpClient.actor] = aBpClient;
|
this.store[aBpClient.actor] = aBpClient;
|
||||||
this.displayBreakpoint(aLocation, aNoEditorUpdate);
|
this.displayBreakpoint(aBpClient, aNoEditorUpdate, aNoPaneUpdate);
|
||||||
aCallback && aCallback(aBpClient, aResponse.error);
|
aCallback && aCallback(aBpClient, aResponse.error);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
@ -1431,24 +1497,37 @@ Breakpoints.prototype = {
|
|||||||
/**
|
/**
|
||||||
* Update the editor to display the specified breakpoint in the gutter.
|
* Update the editor to display the specified breakpoint in the gutter.
|
||||||
*
|
*
|
||||||
* @param object aLocation
|
* @param object aBreakpoint
|
||||||
* The location where you want the breakpoint. This object must have
|
* The breakpoint you want to display.
|
||||||
* two properties:
|
|
||||||
* - url - the URL of the script.
|
|
||||||
* - line - the line number (starting from 1).
|
|
||||||
* @param boolean [aNoEditorUpdate=false]
|
* @param boolean [aNoEditorUpdate=false]
|
||||||
* Tells if you want to skip editor updates. Typically the editor is
|
* Tells if you want to skip editor updates. Typically the editor is
|
||||||
* updated to visually indicate that a breakpoint has been added.
|
* updated to visually indicate that a breakpoint has been added.
|
||||||
|
* @param boolean [aNoPaneUpdate=false]
|
||||||
|
* Tells if you want to skip any breakpoint pane updates.
|
||||||
*/
|
*/
|
||||||
displayBreakpoint: function BP_displayBreakpoint(aLocation, aNoEditorUpdate) {
|
displayBreakpoint:
|
||||||
|
function BP_displayBreakpoint(aBreakpoint, aNoEditorUpdate, aNoPaneUpdate) {
|
||||||
if (!aNoEditorUpdate) {
|
if (!aNoEditorUpdate) {
|
||||||
let url = DebuggerView.Scripts.selected;
|
let url = DebuggerView.Scripts.selected;
|
||||||
if (url == aLocation.url) {
|
if (url == aBreakpoint.location.url) {
|
||||||
this._skipEditorBreakpointChange = true;
|
this._skipEditorBreakpointChange = true;
|
||||||
this.editor.addBreakpoint(aLocation.line - 1);
|
this.editor.addBreakpoint(aBreakpoint.location.line - 1);
|
||||||
this._skipEditorBreakpointChange = false;
|
this._skipEditorBreakpointChange = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!aNoPaneUpdate) {
|
||||||
|
let { url: url, line: line } = aBreakpoint.location;
|
||||||
|
|
||||||
|
if (!aBreakpoint.lineText || !aBreakpoint.lineInfo) {
|
||||||
|
let scripts = DebuggerController.SourceScripts;
|
||||||
|
aBreakpoint.lineText = scripts.getLineText(line - 1);
|
||||||
|
aBreakpoint.lineInfo = scripts.getScriptLabel(url) + ":" + line;
|
||||||
|
}
|
||||||
|
DebuggerView.Breakpoints.addBreakpoint(
|
||||||
|
aBreakpoint.actor,
|
||||||
|
aBreakpoint.lineInfo,
|
||||||
|
aBreakpoint.lineText, url, line);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1463,9 +1542,11 @@ Breakpoints.prototype = {
|
|||||||
* @param boolean [aNoEditorUpdate=false]
|
* @param boolean [aNoEditorUpdate=false]
|
||||||
* Tells if you want to skip editor updates. Typically the editor is
|
* Tells if you want to skip editor updates. Typically the editor is
|
||||||
* updated to visually indicate that a breakpoint has been removed.
|
* updated to visually indicate that a breakpoint has been removed.
|
||||||
|
* @param boolean [aNoPaneUpdate=false]
|
||||||
|
* Tells if you want to skip any breakpoint pane updates.
|
||||||
*/
|
*/
|
||||||
removeBreakpoint:
|
removeBreakpoint:
|
||||||
function BP_removeBreakpoint(aBreakpoint, aCallback, aNoEditorUpdate) {
|
function BP_removeBreakpoint(aBreakpoint, aCallback, aNoEditorUpdate, aNoPaneUpdate) {
|
||||||
if (!(aBreakpoint.actor in this.store)) {
|
if (!(aBreakpoint.actor in this.store)) {
|
||||||
aCallback && aCallback(aBreakpoint.location);
|
aCallback && aCallback(aBreakpoint.location);
|
||||||
return;
|
return;
|
||||||
@ -1482,6 +1563,9 @@ Breakpoints.prototype = {
|
|||||||
this._skipEditorBreakpointChange = false;
|
this._skipEditorBreakpointChange = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!aNoPaneUpdate) {
|
||||||
|
DebuggerView.Breakpoints.removeBreakpoint(aBreakpoint.actor);
|
||||||
|
}
|
||||||
|
|
||||||
aCallback && aCallback(aBreakpoint.location);
|
aCallback && aCallback(aBreakpoint.location);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const PROPERTY_VIEW_FLASH_DURATION = 400; // ms
|
const PROPERTY_VIEW_FLASH_DURATION = 400; // ms
|
||||||
|
const BREAKPOINT_LINE_TOOLTIP_MAX_SIZE = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object mediating visual changes and event listeners between the debugger and
|
* Object mediating visual changes and event listeners between the debugger and
|
||||||
@ -22,7 +23,7 @@ let DebuggerView = {
|
|||||||
* Initializes UI properties for all the displayed panes.
|
* Initializes UI properties for all the displayed panes.
|
||||||
*/
|
*/
|
||||||
initializePanes: function DV_initializePanes() {
|
initializePanes: function DV_initializePanes() {
|
||||||
let stackframes = document.getElementById("stackframes");
|
let stackframes = document.getElementById("stackframes+breakpoints");
|
||||||
stackframes.setAttribute("width", Prefs.stackframesWidth);
|
stackframes.setAttribute("width", Prefs.stackframesWidth);
|
||||||
|
|
||||||
let variables = document.getElementById("variables");
|
let variables = document.getElementById("variables");
|
||||||
@ -51,7 +52,7 @@ let DebuggerView = {
|
|||||||
* Removes the displayed panes and saves any necessary state.
|
* Removes the displayed panes and saves any necessary state.
|
||||||
*/
|
*/
|
||||||
destroyPanes: function DV_destroyPanes() {
|
destroyPanes: function DV_destroyPanes() {
|
||||||
let stackframes = document.getElementById("stackframes");
|
let stackframes = document.getElementById("stackframes+breakpoints");
|
||||||
Prefs.stackframesWidth = stackframes.getAttribute("width");
|
Prefs.stackframesWidth = stackframes.getAttribute("width");
|
||||||
|
|
||||||
let variables = document.getElementById("variables");
|
let variables = document.getElementById("variables");
|
||||||
@ -807,6 +808,7 @@ StackFramesView.prototype = {
|
|||||||
window.addEventListener("resize", this._onFramesScroll, false);
|
window.addEventListener("resize", this._onFramesScroll, false);
|
||||||
|
|
||||||
this._frames = frames;
|
this._frames = frames;
|
||||||
|
this.emptyText();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -837,6 +839,545 @@ StackFramesView.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions handling the breakpoints view.
|
||||||
|
*/
|
||||||
|
function BreakpointsView() {
|
||||||
|
this._onBreakpointClick = this._onBreakpointClick.bind(this);
|
||||||
|
this._onBreakpointCheckboxChange = this._onBreakpointCheckboxChange.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
BreakpointsView.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all elements from the breakpoints container, leaving it empty.
|
||||||
|
*/
|
||||||
|
empty: function DVB_empty() {
|
||||||
|
let firstChild;
|
||||||
|
while (firstChild = this._breakpoints.firstChild) {
|
||||||
|
this._destroyContextMenu(firstChild);
|
||||||
|
this._breakpoints.removeChild(firstChild);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all elements from the breakpoints container, and adds a child node
|
||||||
|
* with an empty text note attached.
|
||||||
|
*/
|
||||||
|
emptyText: function DVB_emptyText() {
|
||||||
|
// Make sure the container is empty first.
|
||||||
|
this.empty();
|
||||||
|
|
||||||
|
let item = document.createElement("label");
|
||||||
|
|
||||||
|
// The empty node should look grayed out to avoid confusion.
|
||||||
|
item.className = "list-item empty";
|
||||||
|
item.setAttribute("value", L10N.getStr("emptyBreakpointsText"));
|
||||||
|
|
||||||
|
this._breakpoints.appendChild(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the breakpoint with the specified script URL and line is
|
||||||
|
* among the breakpoints known to the debugger and shown in the list, and
|
||||||
|
* returns the matched result or null if nothing is found.
|
||||||
|
*
|
||||||
|
* @param string aUrl
|
||||||
|
* The original breakpoint script url.
|
||||||
|
* @param number aLine
|
||||||
|
* The original breakpoint script line.
|
||||||
|
* @return object | null
|
||||||
|
* The queried breakpoint
|
||||||
|
*/
|
||||||
|
getBreakpoint: function DVB_getBreakpoint(aUrl, aLine) {
|
||||||
|
return this._breakpoints.getElementsByAttribute("location", aUrl + ":" + aLine)[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a breakpoint only from the breakpoints container.
|
||||||
|
* This doesn't remove the breakpoint from the DebuggerController!
|
||||||
|
*
|
||||||
|
* @param string aId
|
||||||
|
* A breakpoint identifier specified by the debugger.
|
||||||
|
*/
|
||||||
|
removeBreakpoint: function DVB_removeBreakpoint(aId) {
|
||||||
|
let breakpoint = document.getElementById("breakpoint-" + aId);
|
||||||
|
|
||||||
|
// Make sure we have something to remove.
|
||||||
|
if (!breakpoint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._destroyContextMenu(breakpoint);
|
||||||
|
this._breakpoints.removeChild(breakpoint);
|
||||||
|
|
||||||
|
if (!this.count) {
|
||||||
|
this.emptyText();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a breakpoint to the breakpoints container.
|
||||||
|
* If the breakpoint already exists (was previously added), null is returned.
|
||||||
|
* If it's already added but disabled, it will be enabled and null is returned.
|
||||||
|
* Otherwise, the newly created element is returned.
|
||||||
|
*
|
||||||
|
* @param string aId
|
||||||
|
* A breakpoint identifier specified by the debugger.
|
||||||
|
* @param string aLineInfo
|
||||||
|
* The script line information to be displayed in the list.
|
||||||
|
* @param string aLineText
|
||||||
|
* The script line text to be displayed in the list.
|
||||||
|
* @param string aUrl
|
||||||
|
* The original breakpoint script url.
|
||||||
|
* @param number aLine
|
||||||
|
* The original breakpoint script line.
|
||||||
|
* @return object
|
||||||
|
* The newly created html node representing the added breakpoint.
|
||||||
|
*/
|
||||||
|
addBreakpoint: function DVB_addBreakpoint(aId, aLineInfo, aLineText, aUrl, aLine) {
|
||||||
|
// Make sure we don't duplicate anything.
|
||||||
|
if (document.getElementById("breakpoint-" + aId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Remove the empty list text if it was there.
|
||||||
|
if (!this.count) {
|
||||||
|
this.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the breakpoint was already added but disabled, enable it now.
|
||||||
|
let breakpoint = this.getBreakpoint(aUrl, aLine);
|
||||||
|
if (breakpoint) {
|
||||||
|
breakpoint.id = "breakpoint-" + aId;
|
||||||
|
breakpoint.breakpointActor = aId;
|
||||||
|
breakpoint.getElementsByTagName("checkbox")[0].setAttribute("checked", "true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpoint = document.createElement("box");
|
||||||
|
let bkpCheckbox = document.createElement("checkbox");
|
||||||
|
let bkpLineInfo = document.createElement("label");
|
||||||
|
let bkpLineText = document.createElement("label");
|
||||||
|
|
||||||
|
// Create a list item to be added to the stackframes container.
|
||||||
|
breakpoint.id = "breakpoint-" + aId;
|
||||||
|
breakpoint.className = "dbg-breakpoint list-item";
|
||||||
|
breakpoint.setAttribute("location", aUrl + ":" + aLine);
|
||||||
|
breakpoint.breakpointUrl = aUrl;
|
||||||
|
breakpoint.breakpointLine = aLine;
|
||||||
|
breakpoint.breakpointActor = aId;
|
||||||
|
|
||||||
|
aLineInfo = aLineInfo.trim();
|
||||||
|
aLineText = aLineText.trim();
|
||||||
|
|
||||||
|
// A checkbox specifies if the breakpoint is enabled or not.
|
||||||
|
bkpCheckbox.setAttribute("checked", "true");
|
||||||
|
bkpCheckbox.addEventListener("click", this._onBreakpointCheckboxChange, false);
|
||||||
|
|
||||||
|
// This list should display the line info and text for the breakpoint.
|
||||||
|
bkpLineInfo.className = "dbg-breakpoint-info plain";
|
||||||
|
bkpLineText.className = "dbg-breakpoint-text plain";
|
||||||
|
bkpLineInfo.setAttribute("value", aLineInfo);
|
||||||
|
bkpLineText.setAttribute("value", aLineText);
|
||||||
|
bkpLineInfo.setAttribute("crop", "end");
|
||||||
|
bkpLineText.setAttribute("crop", "end");
|
||||||
|
bkpLineText.setAttribute("tooltiptext", aLineText.substr(0, BREAKPOINT_LINE_TOOLTIP_MAX_SIZE));
|
||||||
|
|
||||||
|
// Create a context menu for the breakpoint.
|
||||||
|
let menupopupId = this._createContextMenu(breakpoint);
|
||||||
|
breakpoint.setAttribute("contextmenu", menupopupId);
|
||||||
|
|
||||||
|
let state = document.createElement("vbox");
|
||||||
|
state.className = "state";
|
||||||
|
state.appendChild(bkpCheckbox);
|
||||||
|
|
||||||
|
let content = document.createElement("vbox");
|
||||||
|
content.className = "content";
|
||||||
|
content.setAttribute("flex", "1");
|
||||||
|
content.appendChild(bkpLineInfo);
|
||||||
|
content.appendChild(bkpLineText);
|
||||||
|
|
||||||
|
breakpoint.appendChild(state);
|
||||||
|
breakpoint.appendChild(content);
|
||||||
|
|
||||||
|
this._breakpoints.appendChild(breakpoint);
|
||||||
|
|
||||||
|
// Return the element for later use if necessary.
|
||||||
|
return breakpoint;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables a breakpoint.
|
||||||
|
*
|
||||||
|
* @param object aBreakpoint
|
||||||
|
* An element representing a breakpoint.
|
||||||
|
* @param function aCallback
|
||||||
|
* Optional function to invoke once the breakpoint is enabled.
|
||||||
|
* @param boolean aNoCheckboxUpdate
|
||||||
|
* Pass true to not update the checkbox checked state.
|
||||||
|
* This is usually necessary when the checked state will be updated
|
||||||
|
* automatically (e.g: on a checkbox click).
|
||||||
|
*/
|
||||||
|
enableBreakpoint:
|
||||||
|
function DVB_enableBreakpoint(aTarget, aCallback, aNoCheckboxUpdate) {
|
||||||
|
let { breakpointUrl: url, breakpointLine: line } = aTarget;
|
||||||
|
let breakpoint = DebuggerController.Breakpoints.getBreakpoint(url, line)
|
||||||
|
|
||||||
|
if (!breakpoint) {
|
||||||
|
if (!aNoCheckboxUpdate) {
|
||||||
|
aTarget.getElementsByTagName("checkbox")[0].setAttribute("checked", "true");
|
||||||
|
}
|
||||||
|
DebuggerController.Breakpoints.
|
||||||
|
addBreakpoint({ url: url, line: line }, aCallback);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a breakpoint.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* An element representing a breakpoint.
|
||||||
|
* @param function aCallback
|
||||||
|
* Optional function to invoke once the breakpoint is disabled.
|
||||||
|
* @param boolean aNoCheckboxUpdate
|
||||||
|
* Pass true to not update the checkbox checked state.
|
||||||
|
* This is usually necessary when the checked state will be updated
|
||||||
|
* automatically (e.g: on a checkbox click).
|
||||||
|
*/
|
||||||
|
disableBreakpoint:
|
||||||
|
function DVB_disableBreakpoint(aTarget, aCallback, aNoCheckboxUpdate) {
|
||||||
|
let { breakpointUrl: url, breakpointLine: line } = aTarget;
|
||||||
|
let breakpoint = DebuggerController.Breakpoints.getBreakpoint(url, line)
|
||||||
|
|
||||||
|
if (breakpoint) {
|
||||||
|
if (!aNoCheckboxUpdate) {
|
||||||
|
aTarget.getElementsByTagName("checkbox")[0].removeAttribute("checked");
|
||||||
|
}
|
||||||
|
DebuggerController.Breakpoints.
|
||||||
|
removeBreakpoint(breakpoint, aCallback, false, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current number of added breakpoints.
|
||||||
|
*/
|
||||||
|
get count() {
|
||||||
|
return this._breakpoints.getElementsByClassName("dbg-breakpoint").length;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates through all the added breakpoints.
|
||||||
|
*
|
||||||
|
* @param function aCallback
|
||||||
|
* Function called for each element.
|
||||||
|
*/
|
||||||
|
_iterate: function DVB_iterate(aCallback) {
|
||||||
|
Array.forEach(Array.slice(this._breakpoints.childNodes), aCallback);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the real breakpoint target when an event is handled.
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
_getBreakpointTarget: function DVB__getBreakpointTarget(aEvent) {
|
||||||
|
let target = aEvent.target;
|
||||||
|
|
||||||
|
while (target) {
|
||||||
|
if (target.breakpointActor) {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the breakpoint click event.
|
||||||
|
*/
|
||||||
|
_onBreakpointClick: function DVB__onBreakpointClick(aEvent) {
|
||||||
|
let target = this._getBreakpointTarget(aEvent);
|
||||||
|
let { breakpointUrl: url, breakpointLine: line } = target;
|
||||||
|
|
||||||
|
DebuggerController.StackFrames.updateEditorToLocation(url, line, 0, 0, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the breakpoint checkbox change event.
|
||||||
|
*/
|
||||||
|
_onBreakpointCheckboxChange: function DVB__onBreakpointCheckboxChange(aEvent) {
|
||||||
|
aEvent.stopPropagation();
|
||||||
|
|
||||||
|
let target = this._getBreakpointTarget(aEvent);
|
||||||
|
let { breakpointUrl: url, breakpointLine: line } = target;
|
||||||
|
|
||||||
|
if (aEvent.target.getAttribute("checked") === "true") {
|
||||||
|
this.disableBreakpoint(target, null, true);
|
||||||
|
} else {
|
||||||
|
this.enableBreakpoint(target, null, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "enableSelf" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onEnableSelf: function DVB__onEnableSelf(aTarget) {
|
||||||
|
if (!aTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.enableBreakpoint(aTarget)) {
|
||||||
|
aTarget.enableSelf.menuitem.setAttribute("hidden", "true");
|
||||||
|
aTarget.disableSelf.menuitem.removeAttribute("hidden");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "disableSelf" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDisableSelf: function DVB__onDisableSelf(aTarget) {
|
||||||
|
if (!aTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.disableBreakpoint(aTarget)) {
|
||||||
|
aTarget.enableSelf.menuitem.removeAttribute("hidden");
|
||||||
|
aTarget.disableSelf.menuitem.setAttribute("hidden", "true");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "deleteSelf" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDeleteSelf: function DVB__onDeleteSelf(aTarget) {
|
||||||
|
let { breakpointUrl: url, breakpointLine: line } = aTarget;
|
||||||
|
let breakpoint = DebuggerController.Breakpoints.getBreakpoint(url, line)
|
||||||
|
|
||||||
|
if (aTarget) {
|
||||||
|
this.removeBreakpoint(aTarget.breakpointActor);
|
||||||
|
}
|
||||||
|
if (breakpoint) {
|
||||||
|
DebuggerController.Breakpoints.removeBreakpoint(breakpoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "enableOthers" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onEnableOthers: function DVB__onEnableOthers(aTarget) {
|
||||||
|
this._iterate(function(element) {
|
||||||
|
if (element !== aTarget) {
|
||||||
|
this._onEnableSelf(element);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "disableOthers" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDisableOthers: function DVB__onDisableOthers(aTarget) {
|
||||||
|
this._iterate(function(element) {
|
||||||
|
if (element !== aTarget) {
|
||||||
|
this._onDisableSelf(element);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "deleteOthers" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDeleteOthers: function DVB__onDeleteOthers(aTarget) {
|
||||||
|
this._iterate(function(element) {
|
||||||
|
if (element !== aTarget) {
|
||||||
|
this._onDeleteSelf(element);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "disableAll" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onEnableAll: function DVB__onEnableAll(aTarget) {
|
||||||
|
this._onEnableOthers(aTarget);
|
||||||
|
this._onEnableSelf(aTarget);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "disableAll" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDisableAll: function DVB__onDisableAll(aTarget) {
|
||||||
|
this._onDisableOthers(aTarget);
|
||||||
|
this._onDisableSelf(aTarget);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener handling the "deleteAll" menuitem command.
|
||||||
|
*
|
||||||
|
* @param object aTarget
|
||||||
|
* The corresponding breakpoint element.
|
||||||
|
*/
|
||||||
|
_onDeleteAll: function DVB__onDeleteAll(aTarget) {
|
||||||
|
this._onDeleteOthers(aTarget);
|
||||||
|
this._onDeleteSelf(aTarget);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cached breakpoints container.
|
||||||
|
*/
|
||||||
|
_breakpoints: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a breakpoint context menu.
|
||||||
|
*
|
||||||
|
* @param object aBreakpoint
|
||||||
|
* An element representing a breakpoint.
|
||||||
|
* @return string
|
||||||
|
* The popup id.
|
||||||
|
*/
|
||||||
|
_createContextMenu: function DVB_createContextMenu(aBreakpoint) {
|
||||||
|
let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
|
||||||
|
let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
|
||||||
|
|
||||||
|
let commandsset = document.createElement("commandsset");
|
||||||
|
commandsset.setAttribute("id", commandsetId);
|
||||||
|
|
||||||
|
let menupopup = document.createElement("menupopup");
|
||||||
|
menupopup.setAttribute("id", menupopupId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a menu item specified by a name with the appropriate attributes
|
||||||
|
* (label and command handler).
|
||||||
|
*
|
||||||
|
* @param string aName
|
||||||
|
* A global identifier for the menu item.
|
||||||
|
* @param boolean aHiddenFlag
|
||||||
|
* True if this menuitem should be hidden.
|
||||||
|
*/
|
||||||
|
function createMenuItem(aName, aHiddenFlag) {
|
||||||
|
let menuitem = document.createElement("menuitem");
|
||||||
|
let command = document.createElement("command");
|
||||||
|
|
||||||
|
let func = this["_on" + aName.charAt(0).toUpperCase() + aName.slice(1)];
|
||||||
|
let label = L10N.getStr("breakpointMenuItem." + aName);
|
||||||
|
|
||||||
|
let prefix = "bp-cMenu-";
|
||||||
|
let commandId = prefix + aName + "-" + aBreakpoint.id + "-command";
|
||||||
|
let menuitemId = prefix + aName + "-" + aBreakpoint.id + "-menuitem";
|
||||||
|
|
||||||
|
command.setAttribute("id", commandId);
|
||||||
|
command.setAttribute("label", label);
|
||||||
|
command.addEventListener("command", func.bind(this, aBreakpoint), true);
|
||||||
|
|
||||||
|
menuitem.setAttribute("id", menuitemId);
|
||||||
|
menuitem.setAttribute("command", commandId);
|
||||||
|
menuitem.setAttribute("hidden", aHiddenFlag);
|
||||||
|
|
||||||
|
commandsset.appendChild(command);
|
||||||
|
menupopup.appendChild(menuitem);
|
||||||
|
|
||||||
|
aBreakpoint[aName] = {
|
||||||
|
menuitem: menuitem,
|
||||||
|
command: command
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a simple menu separator element and appends it to the current
|
||||||
|
* menupopup hierarchy.
|
||||||
|
*/
|
||||||
|
function createMenuSeparator() {
|
||||||
|
let menuseparator = document.createElement("menuseparator");
|
||||||
|
menupopup.appendChild(menuseparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
createMenuItem.call(this, "enableSelf", true);
|
||||||
|
createMenuItem.call(this, "disableSelf");
|
||||||
|
createMenuItem.call(this, "deleteSelf");
|
||||||
|
createMenuSeparator();
|
||||||
|
createMenuItem.call(this, "enableOthers");
|
||||||
|
createMenuItem.call(this, "disableOthers");
|
||||||
|
createMenuItem.call(this, "deleteOthers");
|
||||||
|
createMenuSeparator();
|
||||||
|
createMenuItem.call(this, "enableAll");
|
||||||
|
createMenuItem.call(this, "disableAll");
|
||||||
|
createMenuSeparator();
|
||||||
|
createMenuItem.call(this, "deleteAll");
|
||||||
|
|
||||||
|
let popupset = document.getElementById("debugger-popups");
|
||||||
|
popupset.appendChild(menupopup);
|
||||||
|
document.documentElement.appendChild(commandsset);
|
||||||
|
|
||||||
|
return menupopupId;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a breakpoint context menu.
|
||||||
|
*
|
||||||
|
* @param object aBreakpoint
|
||||||
|
* An element representing a breakpoint.
|
||||||
|
*/
|
||||||
|
_destroyContextMenu: function DVB__destroyContextMenu(aBreakpoint) {
|
||||||
|
let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
|
||||||
|
let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
|
||||||
|
|
||||||
|
let commandset = document.getElementById(commandsetId);
|
||||||
|
let menupopup = document.getElementById(menupopupId);
|
||||||
|
|
||||||
|
if (commandset) {
|
||||||
|
commandset.parentNode.removeChild(commandset);
|
||||||
|
}
|
||||||
|
if (menupopup) {
|
||||||
|
menupopup.parentNode.removeChild(menupopup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization function, called when the debugger is initialized.
|
||||||
|
*/
|
||||||
|
initialize: function DVB_initialize() {
|
||||||
|
let breakpoints = document.getElementById("breakpoints");
|
||||||
|
breakpoints.addEventListener("click", this._onBreakpointClick, false);
|
||||||
|
|
||||||
|
this._breakpoints = breakpoints;
|
||||||
|
this.emptyText();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destruction function, called when the debugger is shut down.
|
||||||
|
*/
|
||||||
|
destroy: function DVB_destroy() {
|
||||||
|
let breakpoints = this._breakpoints;
|
||||||
|
breakpoints.removeEventListener("click", this._onBreakpointClick, false);
|
||||||
|
|
||||||
|
this._breakpoints = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions handling the properties view.
|
* Functions handling the properties view.
|
||||||
*/
|
*/
|
||||||
@ -847,6 +1388,7 @@ function PropertiesView() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PropertiesView.prototype = {
|
PropertiesView.prototype = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A monotonically-increasing counter, that guarantees the uniqueness of scope
|
* A monotonically-increasing counter, that guarantees the uniqueness of scope
|
||||||
* IDs.
|
* IDs.
|
||||||
@ -1923,9 +2465,10 @@ PropertiesView.prototype = {
|
|||||||
* Initialization function, called when the debugger is initialized.
|
* Initialization function, called when the debugger is initialized.
|
||||||
*/
|
*/
|
||||||
initialize: function DVP_initialize() {
|
initialize: function DVP_initialize() {
|
||||||
this.createHierarchyStore();
|
|
||||||
|
|
||||||
this._vars = document.getElementById("variables");
|
this._vars = document.getElementById("variables");
|
||||||
|
|
||||||
|
this.emptyText();
|
||||||
|
this.createHierarchyStore();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1943,6 +2486,7 @@ PropertiesView.prototype = {
|
|||||||
*/
|
*/
|
||||||
DebuggerView.Scripts = new ScriptsView();
|
DebuggerView.Scripts = new ScriptsView();
|
||||||
DebuggerView.StackFrames = new StackFramesView();
|
DebuggerView.StackFrames = new StackFramesView();
|
||||||
|
DebuggerView.Breakpoints = new BreakpointsView();
|
||||||
DebuggerView.Properties = new PropertiesView();
|
DebuggerView.Properties = new PropertiesView();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,20 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breakpoints view
|
||||||
|
*/
|
||||||
|
|
||||||
|
#breakpoints {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint > .state,
|
||||||
|
.dbg-breakpoint > .content {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties elements
|
* Properties elements
|
||||||
*/
|
*/
|
||||||
|
@ -80,10 +80,14 @@
|
|||||||
#endif
|
#endif
|
||||||
</toolbar>
|
</toolbar>
|
||||||
<hbox id="dbg-content" flex="1">
|
<hbox id="dbg-content" flex="1">
|
||||||
<vbox id="stackframes"/>
|
<vbox id="stackframes+breakpoints">
|
||||||
<splitter id="stack-script-splitter" class="devtools-side-splitter"/>
|
<vbox id="stackframes" flex="1"/>
|
||||||
|
<splitter class="devtools-horizontal-splitter"/>
|
||||||
|
<vbox id="breakpoints"/>
|
||||||
|
</vbox>
|
||||||
|
<splitter class="devtools-side-splitter"/>
|
||||||
<vbox id="editor" flex="1"/>
|
<vbox id="editor" flex="1"/>
|
||||||
<splitter id="script-properties-splitter" class="devtools-side-splitter"/>
|
<splitter class="devtools-side-splitter"/>
|
||||||
<vbox id="variables"/>
|
<vbox id="variables"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
@ -51,6 +51,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||||||
$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
|
$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
|
||||||
browser_dbg_clean-exit.js \
|
browser_dbg_clean-exit.js \
|
||||||
browser_dbg_bug723069_editor-breakpoints.js \
|
browser_dbg_bug723069_editor-breakpoints.js \
|
||||||
|
browser_dbg_bug723071_editor-breakpoints-pane.js \
|
||||||
browser_dbg_bug731394_editor-contextmenu.js \
|
browser_dbg_bug731394_editor-contextmenu.js \
|
||||||
browser_dbg_displayName.js \
|
browser_dbg_displayName.js \
|
||||||
browser_dbg_iframes.js \
|
browser_dbg_iframes.js \
|
||||||
|
@ -21,6 +21,7 @@ function test()
|
|||||||
let tempScope = {};
|
let tempScope = {};
|
||||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||||
let SourceEditor = tempScope.SourceEditor;
|
let SourceEditor = tempScope.SourceEditor;
|
||||||
|
|
||||||
let scriptShown = false;
|
let scriptShown = false;
|
||||||
let framesAdded = false;
|
let framesAdded = false;
|
||||||
let resumed = false;
|
let resumed = false;
|
||||||
|
@ -0,0 +1,281 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bug 723071: test adding a pane to display the list of breakpoints across
|
||||||
|
* all scripts in the debuggee.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||||
|
|
||||||
|
let gPane = null;
|
||||||
|
let gTab = null;
|
||||||
|
let gDebuggee = null;
|
||||||
|
let gDebugger = null;
|
||||||
|
let gScripts = null;
|
||||||
|
let gBreakpoints = null;
|
||||||
|
let gBreakpointsElement = null;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
let scriptShown = false;
|
||||||
|
let framesAdded = false;
|
||||||
|
let resumed = false;
|
||||||
|
let testStarted = false;
|
||||||
|
|
||||||
|
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||||
|
gTab = aTab;
|
||||||
|
gDebuggee = aDebuggee;
|
||||||
|
gPane = aPane;
|
||||||
|
gDebugger = gPane.contentWindow;
|
||||||
|
resumed = true;
|
||||||
|
|
||||||
|
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||||
|
framesAdded = true;
|
||||||
|
executeSoon(startTest);
|
||||||
|
});
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
gDebuggee.firstCall();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function onScriptShown(aEvent)
|
||||||
|
{
|
||||||
|
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||||
|
executeSoon(startTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("Debugger:ScriptShown", onScriptShown);
|
||||||
|
|
||||||
|
function startTest()
|
||||||
|
{
|
||||||
|
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||||
|
window.removeEventListener("Debugger:ScriptShown", onScriptShown);
|
||||||
|
testStarted = true;
|
||||||
|
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let breakpointsAdded = 0;
|
||||||
|
let breakpointsDisabled = 0;
|
||||||
|
let breakpointsRemoved = 0;
|
||||||
|
|
||||||
|
function performTest()
|
||||||
|
{
|
||||||
|
gScripts = gDebugger.DebuggerView.Scripts;
|
||||||
|
|
||||||
|
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||||
|
"Should only be getting stack frames while paused.");
|
||||||
|
|
||||||
|
is(gScripts._scripts.itemCount, 2, "Found the expected number of scripts.");
|
||||||
|
|
||||||
|
let editor = gDebugger.editor;
|
||||||
|
|
||||||
|
isnot(editor.getText().indexOf("debugger"), -1,
|
||||||
|
"The correct script was loaded initially.");
|
||||||
|
isnot(gScripts.selected, gScripts.scriptLocations[0],
|
||||||
|
"the correct script is selected");
|
||||||
|
|
||||||
|
gBreakpoints = gPane.breakpoints;
|
||||||
|
is(Object.keys(gBreakpoints), 0, "no breakpoints");
|
||||||
|
ok(!gPane.getBreakpoint("chocolate", 3), "getBreakpoint('chocolate', 3) returns falsey");
|
||||||
|
|
||||||
|
is(editor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||||
|
|
||||||
|
gBreakpointsElement = gDebugger.DebuggerView.Breakpoints._breakpoints;
|
||||||
|
is(gBreakpointsElement.childNodes.length, 1,
|
||||||
|
"The breakpoints pane should be empty, but showing a " +
|
||||||
|
"'no breakpoints' information message.");
|
||||||
|
is(gBreakpointsElement.childNodes.length,
|
||||||
|
gBreakpointsElement.querySelectorAll(".list-item.empty").length,
|
||||||
|
"Found junk in the breakpoints container.");
|
||||||
|
|
||||||
|
addBreakpoints(function() {
|
||||||
|
is(breakpointsAdded, 3,
|
||||||
|
"Should have added 3 breakpoints so far.");
|
||||||
|
is(breakpointsDisabled, 0,
|
||||||
|
"Shouldn't have disabled anything so far.");
|
||||||
|
is(breakpointsRemoved, 0,
|
||||||
|
"Shouldn't have removed anything so far.");
|
||||||
|
|
||||||
|
is(gBreakpointsElement.childNodes.length,
|
||||||
|
gBreakpointsElement.querySelectorAll(".dbg-breakpoint").length,
|
||||||
|
"Found junk in the breakpoints container.");
|
||||||
|
|
||||||
|
disableBreakpoints(function() {
|
||||||
|
is(breakpointsAdded, 3,
|
||||||
|
"Should still have 3 breakpoints added so far.");
|
||||||
|
is(breakpointsDisabled, 3,
|
||||||
|
"Should have 3 disabled breakpoints.");
|
||||||
|
is(breakpointsRemoved, 0,
|
||||||
|
"Shouldn't have removed anything so far.");
|
||||||
|
|
||||||
|
is(gBreakpointsElement.childNodes.length, breakpointsAdded,
|
||||||
|
"Should have the same number of breakpoints in the pane.");
|
||||||
|
is(gBreakpointsElement.childNodes.length, breakpointsDisabled,
|
||||||
|
"Should have the same number of disabled breakpoints.");
|
||||||
|
|
||||||
|
addBreakpoints(function() {
|
||||||
|
is(breakpointsAdded, 3,
|
||||||
|
"Should still have only 3 breakpoints added so far.");
|
||||||
|
is(breakpointsDisabled, 3,
|
||||||
|
"Should still have 3 disabled breakpoints.");
|
||||||
|
is(breakpointsRemoved, 0,
|
||||||
|
"Shouldn't have removed anything so far.");
|
||||||
|
|
||||||
|
is(gBreakpointsElement.childNodes.length, breakpointsAdded,
|
||||||
|
"Since half of the breakpoints already existed, but disabled, " +
|
||||||
|
"only half of the added breakpoints are actually in the pane.");
|
||||||
|
is(gBreakpointsElement.childNodes.length,
|
||||||
|
gBreakpointsElement.querySelectorAll(".dbg-breakpoint").length,
|
||||||
|
"Found junk in the breakpoints container.");
|
||||||
|
|
||||||
|
removeBreakpoints(function() {
|
||||||
|
is(breakpointsRemoved, 3,
|
||||||
|
"Should have 3 removed breakpoints.");
|
||||||
|
|
||||||
|
is(gBreakpointsElement.childNodes.length, 1,
|
||||||
|
"The breakpoints pane should be empty, but showing a " +
|
||||||
|
"'no breakpoints' information message.");
|
||||||
|
is(gBreakpointsElement.childNodes.length,
|
||||||
|
gBreakpointsElement.querySelectorAll(".list-item.empty").length,
|
||||||
|
"Found junk in the breakpoints container.");
|
||||||
|
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
function addBreakpoints(callback, increment)
|
||||||
|
{
|
||||||
|
let line;
|
||||||
|
|
||||||
|
executeSoon(function()
|
||||||
|
{
|
||||||
|
line = 4;
|
||||||
|
gPane.addBreakpoint({url: gScripts.selected, line: line},
|
||||||
|
function(cl, err) {
|
||||||
|
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||||
|
|
||||||
|
line = 5;
|
||||||
|
gPane.addBreakpoint({url: gScripts.selected, line: line},
|
||||||
|
function(cl, err) {
|
||||||
|
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||||
|
|
||||||
|
line = 6;
|
||||||
|
gPane.addBreakpoint({url: gScripts.selected, line: line},
|
||||||
|
function(cl, err) {
|
||||||
|
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableBreakpoints(callback)
|
||||||
|
{
|
||||||
|
let nodes = Array.slice(gBreakpointsElement.childNodes);
|
||||||
|
info("Nodes to disable: " + breakpointsAdded);
|
||||||
|
is(nodes.length, breakpointsAdded,
|
||||||
|
"The number of nodes to disable is incorrect.");
|
||||||
|
|
||||||
|
Array.forEach(nodes, function(bkp) {
|
||||||
|
info("Disabling breakpoint: " + bkp.id);
|
||||||
|
|
||||||
|
gDebugger.DebuggerView.Breakpoints.disableBreakpoint(bkp, function() {
|
||||||
|
if (++breakpointsDisabled !== breakpointsAdded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
executeSoon(function() {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeBreakpoints(callback)
|
||||||
|
{
|
||||||
|
let nodes = Array.slice(gBreakpointsElement.childNodes);
|
||||||
|
info("Nodes to remove: " + breakpointsAdded);
|
||||||
|
is(nodes.length, breakpointsAdded,
|
||||||
|
"The number of nodes to remove is incorrect.");
|
||||||
|
|
||||||
|
Array.forEach(nodes, function(bkp) {
|
||||||
|
info("Removing breakpoint: " + bkp.id);
|
||||||
|
|
||||||
|
let [url, line, actor] =
|
||||||
|
[bkp.breakpointUrl, bkp.breakpointLine, bkp.breakpointActor];
|
||||||
|
|
||||||
|
gDebugger.DebuggerView.Breakpoints.removeBreakpoint(actor);
|
||||||
|
gPane.removeBreakpoint(gPane.getBreakpoint(url, line), function() {
|
||||||
|
if (++breakpointsRemoved !== breakpointsAdded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
executeSoon(function() {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBreakpointAdd(aBreakpointClient, aResponseError)
|
||||||
|
{
|
||||||
|
if (this.increment) {
|
||||||
|
breakpointsAdded++;
|
||||||
|
}
|
||||||
|
|
||||||
|
is(gBreakpointsElement.childNodes.length, breakpointsAdded, this.increment
|
||||||
|
? "Should have added a breakpoint in the pane."
|
||||||
|
: "Should have the same number of breakpoints in the pane.");
|
||||||
|
|
||||||
|
let id = "breakpoint-" + aBreakpointClient.actor;
|
||||||
|
let bkp = gDebugger.document.getElementById(id);
|
||||||
|
let info = bkp.getElementsByClassName("dbg-breakpoint-info")[0];
|
||||||
|
let text = bkp.getElementsByClassName("dbg-breakpoint-text")[0];
|
||||||
|
let check = bkp.querySelector("checkbox");
|
||||||
|
|
||||||
|
is(bkp.id, id,
|
||||||
|
"Breakpoint element " + id + " found succesfully.");
|
||||||
|
is(info.getAttribute("value"), getExpectedBreakpointInfo(this.line),
|
||||||
|
"The expected information wasn't found in the breakpoint element.");
|
||||||
|
is(text.getAttribute("value"), getExpectedLineText(this.line).trim(),
|
||||||
|
"The expected line text wasn't found in the breakpoint element.");
|
||||||
|
is(check.getAttribute("checked"), "true",
|
||||||
|
"The breakpoint enable checkbox is checked as expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpectedBreakpointInfo(line) {
|
||||||
|
let url = gDebugger.DebuggerView.Scripts.selected;
|
||||||
|
let label = gDebugger.DebuggerController.SourceScripts.getScriptLabel(url);
|
||||||
|
return label + ":" + line;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpectedLineText(line) {
|
||||||
|
return gDebugger.DebuggerController.SourceScripts.getLineText(line - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCleanupFunction(function() {
|
||||||
|
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||||
|
ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
|
||||||
|
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||||
|
|
||||||
|
is(breakpointsAdded, 3, "correct number of breakpoints have been added");
|
||||||
|
is(breakpointsDisabled, 3, "correct number of breakpoints have been disabled");
|
||||||
|
is(breakpointsRemoved, 3, "correct number of breakpoints have been removed");
|
||||||
|
removeTab(gTab);
|
||||||
|
gPane = null;
|
||||||
|
gTab = null;
|
||||||
|
gDebuggee = null;
|
||||||
|
gDebugger = null;
|
||||||
|
gScripts = null;
|
||||||
|
gBreakpoints = null;
|
||||||
|
gBreakpointsElement = null;
|
||||||
|
});
|
||||||
|
}
|
@ -33,7 +33,7 @@ function test() {
|
|||||||
ok(content.Prefs.variablesWidth,
|
ok(content.Prefs.variablesWidth,
|
||||||
"The debugger preferences should have a saved variablesWidth value.");
|
"The debugger preferences should have a saved variablesWidth value.");
|
||||||
|
|
||||||
stackframes = content.document.getElementById("stackframes");
|
stackframes = content.document.getElementById("stackframes+breakpoints");
|
||||||
variables = content.document.getElementById("variables");
|
variables = content.document.getElementById("variables");
|
||||||
|
|
||||||
is(content.Prefs.stackframesWidth, stackframes.getAttribute("width"),
|
is(content.Prefs.stackframesWidth, stackframes.getAttribute("width"),
|
||||||
|
@ -68,7 +68,7 @@ function testScriptLabelShortening() {
|
|||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
executeSoon(function() {
|
executeSoon(function() {
|
||||||
let loc = url.href + url.leaf;
|
let loc = url.href + url.leaf;
|
||||||
vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
|
vs.addScript(ss.getScriptLabel(loc, url.href), { url: loc }, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ function addScriptsAndCheckOrder(method, callback) {
|
|||||||
case 1:
|
case 1:
|
||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
let loc = url.href + url.leaf;
|
let loc = url.href + url.leaf;
|
||||||
vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
|
vs.addScript(ss.getScriptLabel(loc, url.href), { url: loc });
|
||||||
});
|
});
|
||||||
vs.commitScripts();
|
vs.commitScripts();
|
||||||
break;
|
break;
|
||||||
@ -75,7 +75,7 @@ function addScriptsAndCheckOrder(method, callback) {
|
|||||||
case 2:
|
case 2:
|
||||||
urls.forEach(function(url) {
|
urls.forEach(function(url) {
|
||||||
let loc = url.href + url.leaf;
|
let loc = url.href + url.leaf;
|
||||||
vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
|
vs.addScript(ss.getScriptLabel(loc, url.href), { url: loc }, true);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ function addScriptsAndCheckOrder(method, callback) {
|
|||||||
for (; i < urls.length / 2; i++) {
|
for (; i < urls.length / 2; i++) {
|
||||||
let url = urls[i];
|
let url = urls[i];
|
||||||
let loc = url.href + url.leaf;
|
let loc = url.href + url.leaf;
|
||||||
vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
|
vs.addScript(ss.getScriptLabel(loc, url.href), { url: loc });
|
||||||
}
|
}
|
||||||
vs.commitScripts();
|
vs.commitScripts();
|
||||||
|
|
||||||
for (; i < urls.length; i++) {
|
for (; i < urls.length; i++) {
|
||||||
let url = urls[i];
|
let url = urls[i];
|
||||||
let loc = url.href + url.leaf;
|
let loc = url.href + url.leaf;
|
||||||
vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
|
vs.addScript(ss.getScriptLabel(loc, url.href), { url: loc }, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,22 @@ resumeTooltip=Click to resume
|
|||||||
# frames list when there are no frames to display.
|
# frames list when there are no frames to display.
|
||||||
emptyStackText=No stacks to display.
|
emptyStackText=No stacks to display.
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (emptyBreakpointsText): The text that is displayed in the
|
||||||
|
# breakpoints list when there are no breakpoints to display.
|
||||||
|
emptyBreakpointsText=No breakpoints to display.
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that
|
||||||
|
# are displayed in the breakpoints menu item popup.
|
||||||
|
breakpointMenuItem.enableSelf=Enable breakpoint
|
||||||
|
breakpointMenuItem.disableSelf=Disable breakpoint
|
||||||
|
breakpointMenuItem.deleteSelf=Remove breakpoint
|
||||||
|
breakpointMenuItem.enableOthers=Enable others
|
||||||
|
breakpointMenuItem.disableOthers=Disable others
|
||||||
|
breakpointMenuItem.deleteOthers=Remove others
|
||||||
|
breakpointMenuItem.enableAll=Enable all breakpoints
|
||||||
|
breakpointMenuItem.disableAll=Disable all breakpoints
|
||||||
|
breakpointMenuItem.deleteAll=Remove all breakpoints
|
||||||
|
|
||||||
# LOCALIZATION NOTE (loadingText): The text that is displayed in the script
|
# LOCALIZATION NOTE (loadingText): The text that is displayed in the script
|
||||||
# editor when the laoding process has started but there is no file to display
|
# editor when the laoding process has started but there is no file to display
|
||||||
# yet.
|
# yet.
|
||||||
|
@ -28,6 +28,10 @@
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item:not(.selected):not(.empty):hover {
|
||||||
|
background: #cddae5;
|
||||||
|
}
|
||||||
|
|
||||||
.list-item.selected {
|
.list-item.selected {
|
||||||
background: Highlight;
|
background: Highlight;
|
||||||
color: HighlightText;
|
color: HighlightText;
|
||||||
@ -35,6 +39,7 @@
|
|||||||
|
|
||||||
.list-item.empty {
|
.list-item.empty {
|
||||||
color: GrayText;
|
color: GrayText;
|
||||||
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,6 +60,22 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breakpoints view
|
||||||
|
*/
|
||||||
|
|
||||||
|
#breakpoints {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-info {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-text {
|
||||||
|
font: 8pt monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties view
|
* Properties view
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item:not(.selected):not(.empty):hover {
|
||||||
|
background: #cddae5;
|
||||||
|
}
|
||||||
|
|
||||||
.list-item.selected {
|
.list-item.selected {
|
||||||
background: Highlight;
|
background: Highlight;
|
||||||
color: HighlightText;
|
color: HighlightText;
|
||||||
@ -37,6 +41,7 @@
|
|||||||
|
|
||||||
.list-item.empty {
|
.list-item.empty {
|
||||||
color: GrayText;
|
color: GrayText;
|
||||||
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +62,22 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breakpoints view
|
||||||
|
*/
|
||||||
|
|
||||||
|
#breakpoints {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-info {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-text {
|
||||||
|
font: 8pt monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties view
|
* Properties view
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item:not(.selected):not(.empty):hover {
|
||||||
|
background: #cddae5;
|
||||||
|
}
|
||||||
|
|
||||||
.list-item.selected {
|
.list-item.selected {
|
||||||
background: Highlight;
|
background: Highlight;
|
||||||
color: HighlightText;
|
color: HighlightText;
|
||||||
@ -43,6 +47,7 @@
|
|||||||
|
|
||||||
.list-item.empty {
|
.list-item.empty {
|
||||||
color: GrayText;
|
color: GrayText;
|
||||||
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,6 +68,22 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breakpoints view
|
||||||
|
*/
|
||||||
|
|
||||||
|
#breakpoints {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-info {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbg-breakpoint-text {
|
||||||
|
font: 8pt monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties view
|
* Properties view
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user