зеркало из https://github.com/mozilla/pjs.git
merge m-c to fx-team
This commit is contained in:
Коммит
1e1f817f3e
|
@ -26,6 +26,11 @@ let gBrowserThumbnails = {
|
|||
_tabEvents: ["TabClose", "TabSelect"],
|
||||
|
||||
init: function Thumbnails_init() {
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled"))
|
||||
return;
|
||||
} catch (e) {}
|
||||
|
||||
gBrowser.addTabsProgressListener(this);
|
||||
|
||||
this._tabEvents.forEach(function (aEvent) {
|
||||
|
@ -93,6 +98,9 @@ let gBrowserThumbnails = {
|
|||
},
|
||||
|
||||
_shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
|
||||
if (gPrivateBrowsingUI.privateBrowsingEnabled)
|
||||
return false;
|
||||
|
||||
let doc = aBrowser.contentDocument;
|
||||
|
||||
// FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
|
||||
|
|
|
@ -1192,7 +1192,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
addAppTab: function GroupItem_addAppTab(xulTab, options) {
|
||||
GroupItems.getAppTabFavIconUrl(xulTab, function(iconUrl) {
|
||||
// The tab might have been removed or unpinned while waiting.
|
||||
if (xulTab.closing || !xulTab.parentNode || !xulTab.pinned)
|
||||
if (!Utils.isValidXULTab(xulTab) || !xulTab.pinned)
|
||||
return;
|
||||
|
||||
let self = this;
|
||||
|
|
|
@ -636,6 +636,15 @@ let Utils = {
|
|||
return object instanceof Ci.nsIDOMElement;
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: isValidXULTab
|
||||
// A xulTab is valid if it has not been closed,
|
||||
// and it has not been removed from the DOM
|
||||
// Returns true if the tab is valid.
|
||||
isValidXULTab: function Utils_isValidXULTab(xulTab) {
|
||||
return !xulTab.closing && xulTab.parentNode;
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: isNumber
|
||||
// Returns true if the argument is a valid number.
|
||||
|
|
|
@ -239,7 +239,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
// Store persistent for this object.
|
||||
save: function TabItem_save() {
|
||||
try {
|
||||
if (!this.tab || this.tab.parentNode == null || !this._reconnected) // too soon/late to save
|
||||
if (!this.tab || !Utils.isValidXULTab(this.tab) || !this._reconnected) // too soon/late to save
|
||||
return;
|
||||
|
||||
let data = this.getStorageData();
|
||||
|
@ -571,7 +571,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
|
||||
Utils.assert(Utils.isRect(this.bounds), 'TabItem.setBounds: this.bounds is not a real rectangle!');
|
||||
|
||||
if (!this.parent && this.tab.parentNode != null)
|
||||
if (!this.parent && Utils.isValidXULTab(this.tab))
|
||||
this.setTrenches(rect);
|
||||
|
||||
this.save();
|
||||
|
|
|
@ -60,7 +60,7 @@ let AllTabs = {
|
|||
},
|
||||
|
||||
get tabs() {
|
||||
return Array.filter(gBrowser.tabs, function (tab) !tab.closing);
|
||||
return Array.filter(gBrowser.tabs, function (tab) Utils.isValidXULTab(tab));
|
||||
},
|
||||
|
||||
register: function AllTabs_register(eventName, callback) {
|
||||
|
|
|
@ -791,7 +791,7 @@ let UI = {
|
|||
if (gBrowser.tabs.length > 1) {
|
||||
// Don't return to TabView if there are any app tabs
|
||||
for (let a = 0; a < gBrowser._numPinnedTabs; a++) {
|
||||
if (!gBrowser.tabs[a].closing)
|
||||
if (Utils.isValidXULTab(gBrowser.tabs[a]))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,545 +45,143 @@ const Cc = Components.classes;
|
|||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/source-editor.jsm");
|
||||
|
||||
let EXPORTED_SYMBOLS = ["DebuggerUI"];
|
||||
|
||||
/**
|
||||
* Creates a pane that will host the debugger UI.
|
||||
* Provides a simple mechanism of managing debugger instances per tab.
|
||||
*
|
||||
* @param nsIDOMWindow aWindow
|
||||
* The chrome window for which the DebuggerUI instance is created.
|
||||
*/
|
||||
function DebuggerPane(aTab) {
|
||||
this._tab = aTab;
|
||||
this._close = this.close.bind(this);
|
||||
this._debugTab = this.debugTab.bind(this);
|
||||
this.breakpoints = {};
|
||||
}
|
||||
|
||||
DebuggerPane.prototype = {
|
||||
/**
|
||||
* Skip editor breakpoint change events.
|
||||
*
|
||||
* This property tells the source editor event handler to skip handling of
|
||||
* the BREAKPOINT_CHANGE events. This is used when the debugger adds/removes
|
||||
* breakpoints from the editor. Typically, the BREAKPOINT_CHANGE event handler
|
||||
* adds/removes events from the debugger, but when breakpoints are added from
|
||||
* the public debugger API, we need to do things in reverse.
|
||||
*
|
||||
* This implementation relies on the fact that the source editor fires the
|
||||
* BREAKPOINT_CHANGE events synchronously.
|
||||
*
|
||||
* @private
|
||||
* @type boolean
|
||||
*/
|
||||
_skipEditorBreakpointChange: false,
|
||||
|
||||
/**
|
||||
* The list of breakpoints in the debugger as tracked by the current
|
||||
* DebuggerPane instance. This an object where the values are BreakpointActor
|
||||
* objects received from the client, while the keys are actor names, for
|
||||
* example "conn0.breakpoint3".
|
||||
*
|
||||
* @type object
|
||||
*/
|
||||
breakpoints: null,
|
||||
|
||||
/**
|
||||
* Creates and initializes the widgets contained in the debugger UI.
|
||||
*/
|
||||
create: function DP_create(gBrowser) {
|
||||
this._tab._scriptDebugger = this;
|
||||
|
||||
this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
|
||||
this._splitter = gBrowser.parentNode.ownerDocument.createElement("splitter");
|
||||
this._splitter.setAttribute("class", "hud-splitter");
|
||||
this.frame = gBrowser.parentNode.ownerDocument.createElement("iframe");
|
||||
this.frame.height = DebuggerUIPreferences.height;
|
||||
|
||||
this._nbox.appendChild(this._splitter);
|
||||
this._nbox.appendChild(this.frame);
|
||||
|
||||
let self = this;
|
||||
|
||||
this.frame.addEventListener("DOMContentLoaded", function initPane(aEvent) {
|
||||
if (aEvent.target != self.frame.contentDocument) {
|
||||
return;
|
||||
}
|
||||
self.frame.removeEventListener("DOMContentLoaded", initPane, true);
|
||||
// Initialize the source editor.
|
||||
self.frame.contentWindow.editor = self.editor = new SourceEditor();
|
||||
self.frame.contentWindow.updateEditorBreakpoints =
|
||||
self._updateEditorBreakpoints.bind(self);
|
||||
|
||||
let config = {
|
||||
mode: SourceEditor.MODES.JAVASCRIPT,
|
||||
showLineNumbers: true,
|
||||
readOnly: true,
|
||||
showAnnotationRuler: true,
|
||||
showOverviewRuler: true,
|
||||
};
|
||||
|
||||
let editorPlaceholder = self.frame.contentDocument.getElementById("editor");
|
||||
self.editor.init(editorPlaceholder, config, self._onEditorLoad.bind(self));
|
||||
}, true);
|
||||
this.frame.addEventListener("DebuggerClose", this._close, true);
|
||||
|
||||
this.frame.setAttribute("src", "chrome://browser/content/debugger.xul");
|
||||
},
|
||||
|
||||
/**
|
||||
* The load event handler for the source editor. This method does post-load
|
||||
* editor initialization.
|
||||
*/
|
||||
_onEditorLoad: function DP__onEditorLoad() {
|
||||
this.editor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
this._onEditorBreakpointChange.bind(this));
|
||||
// Connect to the debugger server.
|
||||
this.connect();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoint changes that happen in the editor. This
|
||||
* function syncs the breakpoint changes in the editor to those in the
|
||||
* debugger.
|
||||
*
|
||||
* @private
|
||||
* @param object aEvent
|
||||
* The SourceEditor.EVENTS.BREAKPOINT_CHANGE event object.
|
||||
*/
|
||||
_onEditorBreakpointChange: function DP__onEditorBreakpointChange(aEvent) {
|
||||
if (this._skipEditorBreakpointChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
aEvent.added.forEach(this._onEditorBreakpointAdd, this);
|
||||
aEvent.removed.forEach(this._onEditorBreakpointRemove, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the URL of the selected script in the debugger view.
|
||||
*
|
||||
* @private
|
||||
* @return string
|
||||
* The URL of the selected script.
|
||||
*/
|
||||
_selectedScript: function DP__selectedScript() {
|
||||
return this.debuggerWindow ?
|
||||
this.debuggerWindow.DebuggerView.Scripts.selected : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for new breakpoints that come from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object coming from the editor.
|
||||
*/
|
||||
_onEditorBreakpointAdd: function DP__onEditorBreakpointAdd(aBreakpoint) {
|
||||
let location = {
|
||||
url: this._selectedScript(),
|
||||
line: aBreakpoint.line + 1,
|
||||
};
|
||||
|
||||
if (location.url) {
|
||||
let callback = function (aClient, aError) {
|
||||
if (aError) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
let result = this.editor.removeBreakpoint(aBreakpoint.line);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}.bind(this);
|
||||
this.addBreakpoint(location, callback, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoints that are removed from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object that was removed from the editor.
|
||||
*/
|
||||
_onEditorBreakpointRemove: function DP__onEditorBreakpointRemove(aBreakpoint) {
|
||||
let url = this._selectedScript();
|
||||
let line = aBreakpoint.line + 1;
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
let breakpoint = this.getBreakpoint(url, line);
|
||||
if (breakpoint) {
|
||||
this.removeBreakpoint(breakpoint, null, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the breakpoints in the editor view. This function takes the list of
|
||||
* breakpoints in the debugger and adds them back into the editor view. This
|
||||
* is invoked when the selected script is changed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updateEditorBreakpoints: function DP__updateEditorBreakpoints()
|
||||
{
|
||||
let url = this._selectedScript();
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._skipEditorBreakpointChange = true;
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == url) {
|
||||
this.editor.addBreakpoint(breakpoint.location.line - 1);
|
||||
}
|
||||
}
|
||||
this._skipEditorBreakpointChange = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a breakpoint.
|
||||
*
|
||||
* @param object aLocation
|
||||
* The location where you want the breakpoint. This object must have
|
||||
* two properties:
|
||||
* - url - the URL of the script.
|
||||
* - line - the line number (starting from 1).
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is added. The
|
||||
* callback is invoked with two arguments:
|
||||
* - aBreakpointClient - the BreakpointActor client object, if the
|
||||
* breakpoint has been added successfully.
|
||||
* - aResponseError - if there was any error.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been added.
|
||||
*/
|
||||
addBreakpoint:
|
||||
function DP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate) {
|
||||
let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
|
||||
if (breakpoint) {
|
||||
aCallback && aCallback(breakpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
|
||||
if (!aResponse.error) {
|
||||
this.breakpoints[aBpClient.actor] = aBpClient;
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aLocation.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.addBreakpoint(aLocation.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBpClient, aResponse.error);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a breakpoint.
|
||||
*
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint you want to remove.
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is removed. The
|
||||
* callback is invoked with one argument: the breakpoint location
|
||||
* object which holds the url and line properties.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been removed.
|
||||
*/
|
||||
removeBreakpoint:
|
||||
function DP_removeBreakpoint(aBreakpoint, aCallback, aNoEditorUpdate) {
|
||||
if (!(aBreakpoint.actor in this.breakpoints)) {
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
return;
|
||||
}
|
||||
|
||||
aBreakpoint.remove(function() {
|
||||
delete this.breakpoints[aBreakpoint.actor];
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aBreakpoint.location.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.removeBreakpoint(aBreakpoint.location.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the breakpoint object at the given location.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The URL of where the breakpoint is.
|
||||
* @param number aLine
|
||||
* The line number where the breakpoint is.
|
||||
* @return object
|
||||
* The BreakpointActor object.
|
||||
*/
|
||||
getBreakpoint: function DP_getBreakpoint(aUrl, aLine) {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == aUrl && breakpoint.location.line == aLine) {
|
||||
return breakpoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the debugger UI removing child nodes and event listeners.
|
||||
*/
|
||||
close: function DP_close() {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
this.removeBreakpoint(breakpoint);
|
||||
}
|
||||
|
||||
if (this._tab) {
|
||||
this._tab._scriptDebugger = null;
|
||||
this._tab = null;
|
||||
}
|
||||
if (this.frame) {
|
||||
DebuggerUIPreferences.height = this.frame.height;
|
||||
|
||||
this.frame.removeEventListener("unload", this._close, true);
|
||||
this.frame.removeEventListener("DebuggerClose", this._close, true);
|
||||
if (this.frame.parentNode) {
|
||||
this.frame.parentNode.removeChild(this.frame);
|
||||
}
|
||||
this.frame = null;
|
||||
}
|
||||
if (this._nbox) {
|
||||
this._nbox.removeChild(this._splitter);
|
||||
this._nbox = null;
|
||||
}
|
||||
|
||||
this._splitter = null;
|
||||
|
||||
if (this._client) {
|
||||
this._client.removeListener("newScript", this.onNewScript);
|
||||
this._client.removeListener("tabDetached", this._close);
|
||||
this._client.removeListener("tabNavigated", this._debugTab);
|
||||
this._client.close();
|
||||
this._client = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes a debugger client and connects it to the debugger server,
|
||||
* wiring event handlers as necessary.
|
||||
*/
|
||||
connect: function DP_connect() {
|
||||
this.frame.addEventListener("unload", this._close, true);
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
this._client = new DebuggerClient(transport);
|
||||
// Store the new script handler locally, so when it's time to remove it we
|
||||
// don't need to go through the iframe, since it might be cleared.
|
||||
this.onNewScript = this.debuggerWindow.SourceScripts.onNewScript;
|
||||
let self = this;
|
||||
this._client.addListener("tabNavigated", this._debugTab);
|
||||
this._client.addListener("tabDetached", this._close);
|
||||
this._client.addListener("newScript", this.onNewScript);
|
||||
this._client.connect(function(aType, aTraits) {
|
||||
self._client.listTabs(function(aResponse) {
|
||||
let tab = aResponse.tabs[aResponse.selected];
|
||||
self.debuggerWindow.startDebuggingTab(self._client, tab);
|
||||
if (self.onConnected) {
|
||||
self.onConnected(self);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts debugging the current tab. This function is called on each location
|
||||
* change in this tab.
|
||||
*/
|
||||
debugTab: function DP_debugTab(aNotification, aPacket) {
|
||||
let self = this;
|
||||
this._client.activeThread.detach(function() {
|
||||
self._client.activeTab.detach(function() {
|
||||
self._client.listTabs(function(aResponse) {
|
||||
let tab = aResponse.tabs[aResponse.selected];
|
||||
self.debuggerWindow.startDebuggingTab(self._client, tab);
|
||||
if (self.onConnected) {
|
||||
self.onConnected(self);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
get debuggerWindow() {
|
||||
return this.frame ? this.frame.contentWindow : null;
|
||||
},
|
||||
|
||||
get debuggerClient() {
|
||||
return this._client;
|
||||
},
|
||||
|
||||
get activeThread() {
|
||||
try {
|
||||
return this.debuggerWindow.ThreadState.activeThread;
|
||||
} catch(ex) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function DebuggerUI(aWindow) {
|
||||
this.aWindow = aWindow;
|
||||
|
||||
aWindow.addEventListener("Debugger:LoadSource", this._onLoadSource.bind(this));
|
||||
this.chromeWindow = aWindow;
|
||||
}
|
||||
|
||||
DebuggerUI.prototype = {
|
||||
/**
|
||||
* Starts the debugger or stops it, if it is already started.
|
||||
*/
|
||||
toggleDebugger: function DebuggerUI_toggleDebugger() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let gBrowser = this.aWindow.gBrowser;
|
||||
let tab = gBrowser.selectedTab;
|
||||
/**
|
||||
* Starts a debugger for the current tab, or stops it if already started.
|
||||
* @return DebuggerPane if the debugger is started, null if it's stopped.
|
||||
*/
|
||||
toggleDebugger: function DUI_toggleDebugger() {
|
||||
let tab = this.chromeWindow.gBrowser.selectedTab;
|
||||
|
||||
if (tab._scriptDebugger) {
|
||||
// If the debugger is already open, just close it.
|
||||
tab._scriptDebugger.close();
|
||||
return tab._scriptDebugger;
|
||||
return null;
|
||||
}
|
||||
|
||||
let pane = new DebuggerPane(tab);
|
||||
pane.create(gBrowser);
|
||||
return pane;
|
||||
return new DebuggerPane(tab);
|
||||
},
|
||||
|
||||
getDebugger: function DebuggerUI_getDebugger(aTab) {
|
||||
/**
|
||||
* Get the debugger for a specified tab.
|
||||
* @return DebuggerPane if a debugger exists for the tab, null otherwise
|
||||
*/
|
||||
getDebugger: function DUI_getDebugger(aTab) {
|
||||
return aTab._scriptDebugger;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the preferences associated with the debugger frontend.
|
||||
* @return object
|
||||
*/
|
||||
get preferences() {
|
||||
return DebuggerUIPreferences;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a pane that will host the debugger.
|
||||
*
|
||||
* @param XULElement aTab
|
||||
* The tab in which to create the debugger.
|
||||
*/
|
||||
function DebuggerPane(aTab) {
|
||||
this._tab = aTab;
|
||||
this._create();
|
||||
}
|
||||
|
||||
DebuggerPane.prototype = {
|
||||
|
||||
/**
|
||||
* Creates and initializes the widgets containing the debugger UI.
|
||||
*/
|
||||
_create: function DP__create() {
|
||||
this._tab._scriptDebugger = this;
|
||||
|
||||
let gBrowser = this._tab.linkedBrowser.getTabBrowser();
|
||||
let ownerDocument = gBrowser.parentNode.ownerDocument;
|
||||
|
||||
this._splitter = ownerDocument.createElement("splitter");
|
||||
this._splitter.setAttribute("class", "hud-splitter");
|
||||
|
||||
this._frame = ownerDocument.createElement("iframe");
|
||||
this._frame.height = DebuggerUIPreferences.height;
|
||||
|
||||
this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
|
||||
this._nbox.appendChild(this._splitter);
|
||||
this._nbox.appendChild(this._frame);
|
||||
|
||||
this.close = this.close.bind(this);
|
||||
let self = this;
|
||||
|
||||
this._frame.addEventListener("Debugger:Loaded", function dbgLoaded() {
|
||||
self._frame.removeEventListener("Debugger:Loaded", dbgLoaded, true);
|
||||
self._frame.addEventListener("Debugger:Close", self.close, true);
|
||||
self._frame.addEventListener("unload", self.close, true);
|
||||
|
||||
// Bind shortcuts for accessing the breakpoint methods in the debugger.
|
||||
let bkp = self.debuggerWindow.DebuggerController.Breakpoints;
|
||||
self.addBreakpoint = bkp.addBreakpoint;
|
||||
self.removeBreakpoint = bkp.removeBreakpoint;
|
||||
self.getBreakpoint = bkp.getBreakpoint;
|
||||
}, true);
|
||||
|
||||
this._frame.setAttribute("src", "chrome://browser/content/debugger.xul");
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles notifications to load a source script from the cache or from a
|
||||
* local file.
|
||||
* XXX: it may be better to use nsITraceableChannel to get to the sources
|
||||
* without relying on caching when we can (not for eval, etc.):
|
||||
* http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
|
||||
* Closes the debugger, removing child nodes and event listeners.
|
||||
*/
|
||||
_onLoadSource: function DebuggerUI__onLoadSource(aEvent) {
|
||||
let gBrowser = this.aWindow.gBrowser;
|
||||
|
||||
let url = aEvent.detail.url;
|
||||
let showOptions = aEvent.detail.options;
|
||||
let scheme = Services.io.extractScheme(url);
|
||||
switch (scheme) {
|
||||
case "file":
|
||||
case "chrome":
|
||||
case "resource":
|
||||
try {
|
||||
NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) {
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
return this.logError(url, aStatus);
|
||||
}
|
||||
let source = NetUtil.readInputStreamToString(aStream, aStream.available());
|
||||
aStream.close();
|
||||
this._onSourceLoaded(url, source, showOptions);
|
||||
}.bind(this));
|
||||
} catch (ex) {
|
||||
return this.logError(url, ex.name);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
let channel = Services.io.newChannel(url, null, null);
|
||||
let chunks = [];
|
||||
let streamListener = { // nsIStreamListener inherits nsIRequestObserver
|
||||
onStartRequest: function (aRequest, aContext, aStatusCode) {
|
||||
if (!Components.isSuccessCode(aStatusCode)) {
|
||||
return this.logError(url, aStatusCode);
|
||||
}
|
||||
}.bind(this),
|
||||
onDataAvailable: function (aRequest, aContext, aStream, aOffset, aCount) {
|
||||
chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
|
||||
},
|
||||
onStopRequest: function (aRequest, aContext, aStatusCode) {
|
||||
if (!Components.isSuccessCode(aStatusCode)) {
|
||||
return this.logError(url, aStatusCode);
|
||||
}
|
||||
|
||||
this._onSourceLoaded(url, chunks.join(""), channel.contentType,
|
||||
showOptions);
|
||||
}.bind(this)
|
||||
};
|
||||
|
||||
channel.loadFlags = channel.LOAD_FROM_CACHE;
|
||||
channel.asyncOpen(streamListener, null);
|
||||
break;
|
||||
close: function DP_close() {
|
||||
if (!this._tab) {
|
||||
return;
|
||||
}
|
||||
this._tab._scriptDebugger = null;
|
||||
this._tab = null;
|
||||
|
||||
DebuggerUIPreferences.height = this._frame.height;
|
||||
this._frame.removeEventListener("Debugger:Close", this.close, true);
|
||||
this._frame.removeEventListener("unload", this.close, true);
|
||||
|
||||
this._nbox.removeChild(this._splitter);
|
||||
this._nbox.removeChild(this._frame);
|
||||
|
||||
this._splitter = null;
|
||||
this._frame = null;
|
||||
this._nbox = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Log an error message in the error console when a script fails to load.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The URL of the source script.
|
||||
* @param string aStatus
|
||||
* The failure status code.
|
||||
* Gets the debugger content window.
|
||||
* @return nsIDOMWindow if a debugger window exists, null otherwise
|
||||
*/
|
||||
logError: function DebuggerUI_logError(aUrl, aStatus) {
|
||||
let view = this.getDebugger(gBrowser.selectedTab).DebuggerView;
|
||||
Components.utils.reportError(view.getFormatStr("loadingError", [ aUrl, aStatus ]));
|
||||
get debuggerWindow() {
|
||||
return this._frame ? this._frame.contentWindow : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when source has been loaded.
|
||||
*
|
||||
* @private
|
||||
* @param string aSourceUrl
|
||||
* The URL of the source script.
|
||||
* @param string aSourceText
|
||||
* The text of the source script.
|
||||
* @param string aContentType
|
||||
* The content type of the source script.
|
||||
* @param object [aOptions]
|
||||
* Additional options for showing the script (optional). Supported
|
||||
* options:
|
||||
* - targetLine: place the editor at the given line number.
|
||||
* Shortcut for accessing the list of breakpoints in the debugger.
|
||||
* @return object if a debugger window exists, null otherwise
|
||||
*/
|
||||
_onSourceLoaded: function DebuggerUI__onSourceLoaded(aSourceUrl,
|
||||
aSourceText,
|
||||
aContentType,
|
||||
aOptions) {
|
||||
let dbg = this.getDebugger(this.aWindow.gBrowser.selectedTab);
|
||||
let doc = dbg.frame.contentDocument;
|
||||
let scripts = doc.getElementById("scripts");
|
||||
let elt = scripts.getElementsByAttribute("value", aSourceUrl)[0];
|
||||
let script = elt.getUserData("sourceScript");
|
||||
script.loaded = true;
|
||||
script.text = aSourceText;
|
||||
script.contentType = aContentType;
|
||||
elt.setUserData("sourceScript", script, null);
|
||||
|
||||
dbg.debuggerWindow.SourceScripts._onShowScript(script, aOptions);
|
||||
get breakpoints() {
|
||||
let debuggerWindow = this.debuggerWindow;
|
||||
if (debuggerWindow) {
|
||||
return debuggerWindow.DebuggerController.Breakpoints.store;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -592,16 +190,12 @@ DebuggerUI.prototype = {
|
|||
*/
|
||||
let DebuggerUIPreferences = {
|
||||
|
||||
_height: -1,
|
||||
|
||||
/**
|
||||
* Gets the preferred height of the debugger pane.
|
||||
*
|
||||
* @return number
|
||||
* The preferred height.
|
||||
*/
|
||||
get height() {
|
||||
if (this._height < 0) {
|
||||
if (this._height === undefined) {
|
||||
this._height = Services.prefs.getIntPref("devtools.debugger.ui.height");
|
||||
}
|
||||
return this._height;
|
||||
|
@ -609,9 +203,7 @@ let DebuggerUIPreferences = {
|
|||
|
||||
/**
|
||||
* Sets the preferred height of the debugger pane.
|
||||
*
|
||||
* @param number value
|
||||
* The new height.
|
||||
*/
|
||||
set height(value) {
|
||||
Services.prefs.setIntPref("devtools.debugger.ui.height", value);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,696 +0,0 @@
|
|||
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Panos Astithas <past@mozilla.com>
|
||||
* Victor Porof <vporof@mozilla.com>
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource:///modules/source-editor.jsm");
|
||||
|
||||
var gInitialized = false;
|
||||
var gClient = null;
|
||||
var gTabClient = null;
|
||||
|
||||
|
||||
function initDebugger()
|
||||
{
|
||||
window.removeEventListener("DOMContentLoaded", initDebugger, false);
|
||||
if (gInitialized) {
|
||||
return;
|
||||
}
|
||||
gInitialized = true;
|
||||
|
||||
DebuggerView.Stackframes.initialize();
|
||||
DebuggerView.Properties.initialize();
|
||||
DebuggerView.Scripts.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by chrome to set up a debugging session.
|
||||
*
|
||||
* @param DebuggerClient aClient
|
||||
* The debugger client.
|
||||
* @param object aTabGrip
|
||||
* The remote protocol grip of the tab.
|
||||
*/
|
||||
function startDebuggingTab(aClient, aTabGrip)
|
||||
{
|
||||
gClient = aClient;
|
||||
|
||||
gClient.attachTab(aTabGrip.actor, function(aResponse, aTabClient) {
|
||||
if (aTabClient) {
|
||||
gTabClient = aTabClient;
|
||||
gClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
|
||||
if (!aThreadClient) {
|
||||
Components.utils.reportError("Couldn't attach to thread: " +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
ThreadState.connect(aThreadClient, function() {
|
||||
StackFrames.connect(aThreadClient, function() {
|
||||
SourceScripts.connect(aThreadClient, function() {
|
||||
aThreadClient.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function shutdownDebugger()
|
||||
{
|
||||
window.removeEventListener("unload", shutdownDebugger, false);
|
||||
|
||||
SourceScripts.disconnect();
|
||||
StackFrames.disconnect();
|
||||
ThreadState.disconnect();
|
||||
ThreadState.activeThread = false;
|
||||
|
||||
DebuggerView.Stackframes.destroy();
|
||||
DebuggerView.Properties.destroy();
|
||||
DebuggerView.Scripts.destroy();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ThreadState keeps the UI up to date with the state of the
|
||||
* thread (paused/attached/etc.).
|
||||
*/
|
||||
var ThreadState = {
|
||||
activeThread: null,
|
||||
|
||||
/**
|
||||
* Connect to a thread client.
|
||||
* @param object aThreadClient
|
||||
* The thread client.
|
||||
* @param function aCallback
|
||||
* The next function in the initialization sequence.
|
||||
*/
|
||||
connect: function TS_connect(aThreadClient, aCallback) {
|
||||
this.activeThread = aThreadClient;
|
||||
aThreadClient.addListener("paused", ThreadState.update);
|
||||
aThreadClient.addListener("resumed", ThreadState.update);
|
||||
aThreadClient.addListener("detached", ThreadState.update);
|
||||
this.update();
|
||||
aCallback && aCallback();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the UI after a thread state change.
|
||||
*/
|
||||
update: function TS_update(aEvent) {
|
||||
DebuggerView.Stackframes.updateState(this.activeThread.state);
|
||||
if (aEvent == "detached") {
|
||||
ThreadState.activeThread = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnect from the client.
|
||||
*/
|
||||
disconnect: function TS_disconnect() {
|
||||
this.activeThread.removeListener("paused", ThreadState.update);
|
||||
this.activeThread.removeListener("resumed", ThreadState.update);
|
||||
this.activeThread.removeListener("detached", ThreadState.update);
|
||||
}
|
||||
};
|
||||
|
||||
ThreadState.update = ThreadState.update.bind(ThreadState);
|
||||
|
||||
/**
|
||||
* Keeps the stack frame list up-to-date, using the thread client's
|
||||
* stack frame cache.
|
||||
*/
|
||||
var StackFrames = {
|
||||
pageSize: 25,
|
||||
activeThread: null,
|
||||
selectedFrame: null,
|
||||
|
||||
/**
|
||||
* Watch a given thread client.
|
||||
* @param object aThreadClient
|
||||
* The thread client.
|
||||
* @param function aCallback
|
||||
* The next function in the initialization sequence.
|
||||
*/
|
||||
connect: function SF_connect(aThreadClient, aCallback) {
|
||||
DebuggerView.Stackframes.addClickListener(this.onClick);
|
||||
|
||||
this.activeThread = aThreadClient;
|
||||
aThreadClient.addListener("paused", this.onPaused);
|
||||
aThreadClient.addListener("resumed", this.onResume);
|
||||
aThreadClient.addListener("framesadded", this.onFrames);
|
||||
aThreadClient.addListener("framescleared", this.onFramesCleared);
|
||||
this.onFramesCleared();
|
||||
aCallback && aCallback();
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnect from the client.
|
||||
*/
|
||||
disconnect: function TS_disconnect() {
|
||||
this.activeThread.removeListener("paused", this.onPaused);
|
||||
this.activeThread.removeListener("resumed", this.onResume);
|
||||
this.activeThread.removeListener("framesadded", this.onFrames);
|
||||
this.activeThread.removeListener("framescleared", this.onFramesCleared);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's paused notification.
|
||||
*/
|
||||
onPaused: function SF_onPaused() {
|
||||
this.activeThread.fillFrames(this.pageSize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's resumed notification.
|
||||
*/
|
||||
onResume: function SF_onResume() {
|
||||
window.editor.setDebugLocation(-1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's framesadded notification.
|
||||
*/
|
||||
onFrames: function SF_onFrames() {
|
||||
DebuggerView.Stackframes.empty();
|
||||
|
||||
for each (let frame in this.activeThread.cachedFrames) {
|
||||
this._addFramePanel(frame);
|
||||
}
|
||||
|
||||
if (this.activeThread.moreFrames) {
|
||||
DebuggerView.Stackframes.dirty = true;
|
||||
}
|
||||
|
||||
if (!this.selectedFrame) {
|
||||
this.selectFrame(0);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's framescleared notification.
|
||||
*/
|
||||
onFramesCleared: function SF_onFramesCleared() {
|
||||
DebuggerView.Stackframes.emptyText();
|
||||
this.selectedFrame = null;
|
||||
// Clear the properties as well.
|
||||
DebuggerView.Properties.localScope.empty();
|
||||
DebuggerView.Properties.globalScope.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for clicks on stack frames.
|
||||
*/
|
||||
onClick: function SF_onClick(aEvent) {
|
||||
let target = aEvent.target;
|
||||
while (target) {
|
||||
if (target.stackFrame) {
|
||||
this.selectFrame(target.stackFrame.depth);
|
||||
return;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks the stack frame in the specified depth as selected and updates the
|
||||
* properties view with the stack frame's data.
|
||||
*
|
||||
* @param number aDepth
|
||||
* The depth of the frame in the stack.
|
||||
*/
|
||||
selectFrame: function SF_selectFrame(aDepth) {
|
||||
if (this.selectedFrame !== null) {
|
||||
DebuggerView.Stackframes.highlightFrame(this.selectedFrame, false);
|
||||
}
|
||||
|
||||
this.selectedFrame = aDepth;
|
||||
if (aDepth !== null) {
|
||||
DebuggerView.Stackframes.highlightFrame(this.selectedFrame, true);
|
||||
}
|
||||
|
||||
let frame = this.activeThread.cachedFrames[aDepth];
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the editor's caret to the proper line.
|
||||
if (DebuggerView.Scripts.isSelected(frame.where.url) && frame.where.line) {
|
||||
window.editor.setCaretPosition(frame.where.line - 1);
|
||||
window.editor.setDebugLocation(frame.where.line - 1);
|
||||
} else if (DebuggerView.Scripts.contains(frame.where.url)) {
|
||||
DebuggerView.Scripts.selectScript(frame.where.url);
|
||||
window.editor.setCaretPosition(frame.where.line - 1);
|
||||
} else {
|
||||
window.editor.setDebugLocation(-1);
|
||||
}
|
||||
|
||||
// Display the local variables.
|
||||
let localScope = DebuggerView.Properties.localScope;
|
||||
localScope.empty();
|
||||
// Add "this".
|
||||
if (frame["this"]) {
|
||||
let thisVar = localScope.addVar("this");
|
||||
thisVar.setGrip({ "type": frame["this"].type,
|
||||
"class": frame["this"].class });
|
||||
this._addExpander(thisVar, frame["this"]);
|
||||
}
|
||||
|
||||
if (frame.arguments && frame.arguments.length > 0) {
|
||||
// Add "arguments".
|
||||
let argsVar = localScope.addVar("arguments");
|
||||
argsVar.setGrip({ "type": "object", "class": "Arguments" });
|
||||
this._addExpander(argsVar, frame.arguments);
|
||||
|
||||
// Add variables for every argument.
|
||||
let objClient = this.activeThread.pauseGrip(frame.callee);
|
||||
objClient.getSignature(function SF_getSignature(aResponse) {
|
||||
for (let i = 0; i < aResponse.parameters.length; i++) {
|
||||
let param = aResponse.parameters[i];
|
||||
let paramVar = localScope.addVar(param);
|
||||
let paramVal = frame.arguments[i];
|
||||
paramVar.setGrip(paramVal);
|
||||
this._addExpander(paramVar, paramVal);
|
||||
}
|
||||
// Signal that call parameters have been fetched.
|
||||
let evt = document.createEvent("Event");
|
||||
evt.initEvent("Debugger:FetchedParameters", true, false);
|
||||
document.documentElement.dispatchEvent(evt);
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the source editor current debug location based on the selected frame
|
||||
* and script.
|
||||
*/
|
||||
updateEditor: function SF_updateEditor() {
|
||||
if (this.selectedFrame === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let frame = this.activeThread.cachedFrames[this.selectedFrame];
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the editor's caret to the proper line.
|
||||
if (DebuggerView.Scripts.isSelected(frame.where.url) && frame.where.line) {
|
||||
window.editor.setDebugLocation(frame.where.line - 1);
|
||||
} else {
|
||||
window.editor.setDebugLocation(-1);
|
||||
}
|
||||
},
|
||||
|
||||
_addExpander: function SF_addExpander(aVar, aObject) {
|
||||
// No need for expansion for null and undefined values, but we do need them
|
||||
// for frame.arguments which is a regular array.
|
||||
if (!aObject || typeof aObject != "object" ||
|
||||
(aObject.type != "object" && !Array.isArray(aObject))) {
|
||||
return;
|
||||
}
|
||||
// Add a dummy property to force the twisty to show up.
|
||||
aVar.addProperties({ " ": { value: " " }});
|
||||
aVar.onexpand = this._addVarProperties.bind(this, aVar, aObject);
|
||||
},
|
||||
|
||||
_addVarProperties: function SF_addVarProperties(aVar, aObject) {
|
||||
// Retrieve the properties only once.
|
||||
if (aVar.fetched) {
|
||||
return;
|
||||
}
|
||||
// Clear the placeholder property put in place to display the twisty.
|
||||
aVar.empty();
|
||||
|
||||
// For arrays we have to construct a grip-like object to pass into
|
||||
// addProperties.
|
||||
if (Array.isArray(aObject)) {
|
||||
let properties = { length: { writable: true, value: aObject.length } };
|
||||
for (let i = 0; i < aObject.length; i++) {
|
||||
properties[i + ""] = { value: aObject[i] };
|
||||
}
|
||||
aVar.addProperties(properties);
|
||||
// Expansion handlers must be set after the properties are added.
|
||||
for (let i = 0; i < aObject.length; i++) {
|
||||
this._addExpander(aVar[i + ""], aObject[i]);
|
||||
}
|
||||
aVar.fetched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let objClient = this.activeThread.pauseGrip(aObject);
|
||||
objClient.getPrototypeAndProperties(function SF_onProtoAndProps(aResponse) {
|
||||
// Add __proto__.
|
||||
if (aResponse.prototype.type != "null") {
|
||||
let properties = {};
|
||||
properties["__proto__ "] = { value: aResponse.prototype };
|
||||
aVar.addProperties(properties);
|
||||
// Expansion handlers must be set after the properties are added.
|
||||
this._addExpander(aVar["__proto__ "], aResponse.prototype);
|
||||
}
|
||||
|
||||
// Sort the rest of the properties before adding them, for better UX.
|
||||
let properties = {};
|
||||
for each (let prop in Object.keys(aResponse.ownProperties).sort()) {
|
||||
properties[prop] = aResponse.ownProperties[prop];
|
||||
}
|
||||
aVar.addProperties(properties);
|
||||
// Expansion handlers must be set after the properties are added.
|
||||
for (let prop in aResponse.ownProperties) {
|
||||
this._addExpander(aVar[prop], aResponse.ownProperties[prop].value);
|
||||
}
|
||||
|
||||
aVar.fetched = true;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the specified stack frame to the list.
|
||||
*
|
||||
* @param Debugger.Frame aFrame
|
||||
* The new frame to add.
|
||||
*/
|
||||
_addFramePanel: function SF_addFramePanel(aFrame) {
|
||||
let depth = aFrame.depth;
|
||||
let label = SourceScripts._getScriptLabel(aFrame.where.url);
|
||||
|
||||
let startText = this._frameTitle(aFrame);
|
||||
let endText = label + ":" + aFrame.where.line;
|
||||
|
||||
let panel = DebuggerView.Stackframes.addFrame(depth, startText, endText);
|
||||
|
||||
if (panel) {
|
||||
panel.stackFrame = aFrame;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads more stack frames from the debugger server cache.
|
||||
*/
|
||||
_addMoreFrames: function SF_addMoreFrames() {
|
||||
this.activeThread.fillFrames(
|
||||
this.activeThread.cachedFrames.length + this.pageSize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a textual representation for the stack frame specified, for
|
||||
* displaying in the stack frame list.
|
||||
*
|
||||
* @param Debugger.Frame aFrame
|
||||
* The stack frame to label.
|
||||
*/
|
||||
_frameTitle: function SF_frameTitle(aFrame) {
|
||||
if (aFrame.type == "call") {
|
||||
return aFrame["calleeName"] ? aFrame["calleeName"] : "(anonymous)";
|
||||
}
|
||||
|
||||
return "(" + aFrame.type + ")";
|
||||
}
|
||||
};
|
||||
|
||||
StackFrames.onPaused = StackFrames.onPaused.bind(StackFrames);
|
||||
StackFrames.onResume = StackFrames.onResume.bind(StackFrames);
|
||||
StackFrames.onFrames = StackFrames.onFrames.bind(StackFrames);
|
||||
StackFrames.onFramesCleared = StackFrames.onFramesCleared.bind(StackFrames);
|
||||
StackFrames.onClick = StackFrames.onClick.bind(StackFrames);
|
||||
|
||||
/**
|
||||
* Keeps the source script list up-to-date, using the thread client's
|
||||
* source script cache.
|
||||
*/
|
||||
var SourceScripts = {
|
||||
pageSize: 25,
|
||||
activeThread: null,
|
||||
_labelsCache: null,
|
||||
|
||||
/**
|
||||
* Watch a given thread client.
|
||||
* @param object aThreadClient
|
||||
* The thread client.
|
||||
* @param function aCallback
|
||||
* The next function in the initialization sequence.
|
||||
*/
|
||||
connect: function SS_connect(aThreadClient, aCallback) {
|
||||
DebuggerView.Scripts.addChangeListener(this.onChange);
|
||||
|
||||
this.activeThread = aThreadClient;
|
||||
aThreadClient.addListener("scriptsadded", this.onScripts);
|
||||
aThreadClient.addListener("scriptscleared", this.onScriptsCleared);
|
||||
this.clearLabelsCache();
|
||||
this.onScriptsCleared();
|
||||
// Retrieve the list of scripts known to the server from before the client
|
||||
// was ready to handle new script notifications.
|
||||
this.activeThread.fillScripts();
|
||||
aCallback && aCallback();
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnect from the client.
|
||||
*/
|
||||
disconnect: function TS_disconnect() {
|
||||
this.activeThread.removeListener("scriptsadded", this.onScripts);
|
||||
this.activeThread.removeListener("scriptscleared", this.onScriptsCleared);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the debugger client's unsolicited newScript notification.
|
||||
*/
|
||||
onNewScript: function SS_onNewScript(aNotification, aPacket) {
|
||||
this._addScript({ url: aPacket.url, startLine: aPacket.startLine });
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's scriptsadded notification.
|
||||
*/
|
||||
onScripts: function SS_onScripts() {
|
||||
for each (let script in this.activeThread.cachedScripts) {
|
||||
this._addScript(script);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the thread client's scriptscleared notification.
|
||||
*/
|
||||
onScriptsCleared: function SS_onScriptsCleared() {
|
||||
DebuggerView.Scripts.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for changes on the selected source script.
|
||||
*/
|
||||
onChange: function SS_onChange(aEvent) {
|
||||
let scripts = aEvent.target;
|
||||
if (!scripts.selectedItem) {
|
||||
return;
|
||||
}
|
||||
let script = scripts.selectedItem.getUserData("sourceScript");
|
||||
this.showScript(script);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the proper editor mode (JS or HTML) according to the specified
|
||||
* content type, or by determining the type from the URL.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The script URL.
|
||||
* @param string aContentType [optional]
|
||||
* The script content type.
|
||||
*/
|
||||
setEditorMode: function SS_setEditorMode(aUrl, aContentType) {
|
||||
if (aContentType) {
|
||||
if (/javascript/.test(aContentType)) {
|
||||
window.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
|
||||
} else {
|
||||
window.editor.setMode(SourceEditor.MODES.HTML);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._trimUrlQuery(aUrl).slice(-3) == ".js") {
|
||||
window.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
|
||||
} else {
|
||||
window.editor.setMode(SourceEditor.MODES.HTML);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trims the query part of a url string, if necessary.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The script url.
|
||||
* @return string
|
||||
*/
|
||||
_trimUrlQuery: function SS_trimUrlQuery(aUrl) {
|
||||
let q = aUrl.indexOf('?');
|
||||
if (q > -1) {
|
||||
return aUrl.slice(0, q);
|
||||
}
|
||||
return aUrl;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a unique, simplified label from a script url.
|
||||
* ex: a). ici://some.address.com/random/subrandom/
|
||||
* b). ni://another.address.org/random/subrandom/page.html
|
||||
* c). san://interesting.address.gro/random/script.js
|
||||
* d). si://interesting.address.moc/random/another/script.js
|
||||
* =>
|
||||
* a). subrandom/
|
||||
* b). page.html
|
||||
* c). script.js
|
||||
* d). another/script.js
|
||||
*
|
||||
* @param string aUrl
|
||||
* The script url.
|
||||
* @param string aHref
|
||||
* The content location href to be used. If unspecified, it will
|
||||
* defalult to debugged panrent window location.
|
||||
* @return string
|
||||
* The simplified label.
|
||||
*/
|
||||
_getScriptLabel: function SS_getScriptLabel(aUrl, aHref) {
|
||||
let url = this._trimUrlQuery(aUrl);
|
||||
|
||||
if (this._labelsCache[url]) {
|
||||
return this._labelsCache[url];
|
||||
}
|
||||
|
||||
let href = aHref || window.parent.content.location.href;
|
||||
let pathElements = url.split("/");
|
||||
let label = pathElements.pop() || (pathElements.pop() + "/");
|
||||
|
||||
// if the label as a leaf name is alreay present in the scripts list
|
||||
if (DebuggerView.Scripts.containsLabel(label)) {
|
||||
label = url.replace(href.substring(0, href.lastIndexOf("/") + 1), "");
|
||||
|
||||
// if the path/to/script is exactly the same, we're in different domains
|
||||
if (DebuggerView.Scripts.containsLabel(label)) {
|
||||
label = url;
|
||||
}
|
||||
}
|
||||
|
||||
return this._labelsCache[url] = label;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the labels cache, populated by SS_getScriptLabel().
|
||||
* This should be done every time the content location changes.
|
||||
*/
|
||||
clearLabelsCache: function SS_clearLabelsCache() {
|
||||
this._labelsCache = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the specified script to the list and display it in the editor if the
|
||||
* editor is empty.
|
||||
*/
|
||||
_addScript: function SS_addScript(aScript) {
|
||||
DebuggerView.Scripts.addScript(this._getScriptLabel(aScript.url), aScript);
|
||||
|
||||
if (window.editor.getCharCount() == 0) {
|
||||
this.showScript(aScript);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the editor with the script text if available, otherwise fire an event
|
||||
* to load and display the script text.
|
||||
*
|
||||
* @param object aScript
|
||||
* The script object coming from the active thread.
|
||||
* @param object [aOptions]
|
||||
* Additional options for showing the script (optional). Supported
|
||||
* options:
|
||||
* - targetLine: place the editor at the given line number.
|
||||
*/
|
||||
showScript: function SS_showScript(aScript, aOptions) {
|
||||
if (!aScript.loaded) {
|
||||
// Notify the chrome code that we need to load a script file.
|
||||
var evt = document.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("Debugger:LoadSource", true, false,
|
||||
{url: aScript.url, options: aOptions});
|
||||
document.documentElement.dispatchEvent(evt);
|
||||
window.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
window.editor.setText(DebuggerView.getStr("loadingText"));
|
||||
window.editor.resetUndo();
|
||||
} else {
|
||||
this._onShowScript(aScript, aOptions);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the script source once it loads.
|
||||
*
|
||||
* @private
|
||||
* @param object aScript
|
||||
* The script object coming from the active thread.
|
||||
* @param object [aOptions]
|
||||
* Additional options for showing the script (optional). Supported
|
||||
* options:
|
||||
* - targetLine: place the editor at the given line number.
|
||||
*/
|
||||
_onShowScript: function SS__onShowScript(aScript, aOptions) {
|
||||
aOptions = aOptions || {};
|
||||
this.setEditorMode(aScript.url, aScript.contentType);
|
||||
window.editor.setText(aScript.text);
|
||||
window.updateEditorBreakpoints();
|
||||
StackFrames.updateEditor();
|
||||
if (aOptions.targetLine) {
|
||||
window.editor.setCaretPosition(aOptions.targetLine - 1);
|
||||
}
|
||||
window.editor.resetUndo();
|
||||
|
||||
// Notify the chrome code that we shown script file.
|
||||
let evt = document.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("Debugger:ScriptShown", true, false,
|
||||
{url: aScript.url});
|
||||
document.documentElement.dispatchEvent(evt);
|
||||
},
|
||||
};
|
||||
|
||||
SourceScripts.onScripts = SourceScripts.onScripts.bind(SourceScripts);
|
||||
SourceScripts.onNewScript = SourceScripts.onNewScript.bind(SourceScripts);
|
||||
SourceScripts.onScriptsCleared = SourceScripts.onScriptsCleared.bind(SourceScripts);
|
||||
SourceScripts.onChange = SourceScripts.onChange.bind(SourceScripts);
|
||||
|
||||
window.addEventListener("DOMContentLoaded", initDebugger, false);
|
||||
window.addEventListener("unload", shutdownDebugger, false);
|
|
@ -47,54 +47,58 @@
|
|||
]>
|
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
|
||||
|
||||
<xul:window xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<xul:script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<xul:script type="text/javascript" src="debugger.js"/>
|
||||
<xul:script type="text/javascript" src="debugger-view.js"/>
|
||||
<xul:popupset id="debugger-popups">
|
||||
<xul:menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<xul:menuitem id="se-cMenu-copy"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-selectAll"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-find"/>
|
||||
<xul:menuitem id="se-cMenu-findAgain"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-gotoLine"/>
|
||||
</xul:menupopup>
|
||||
</xul:popupset>
|
||||
<xul:commandset id="editMenuCommands"/>
|
||||
<xul:commandset id="sourceEditorCommands"/>
|
||||
<xul:keyset id="sourceEditorKeys"/>
|
||||
|
||||
<div id="body" class="vbox flex">
|
||||
<xul:toolbar id="dbg-toolbar">
|
||||
<xul:button id="close">&debuggerUI.closeButton;</xul:button>
|
||||
<xul:button id="resume"/>
|
||||
<xul:button id="step-over">&debuggerUI.stepOverButton;</xul:button>
|
||||
<xul:button id="step-in">&debuggerUI.stepInButton;</xul:button>
|
||||
<xul:button id="step-out">&debuggerUI.stepOutButton;</xul:button>
|
||||
<xul:menulist id="scripts"/>
|
||||
</xul:toolbar>
|
||||
<div id="dbg-content" class="hbox flex">
|
||||
<div id="stack" class="vbox">
|
||||
<div class="title unselectable">&debuggerUI.stackTitle;</div>
|
||||
<div id="stackframes" class="vbox flex"></div>
|
||||
</div>
|
||||
<div id="script" class="vbox flex">
|
||||
<div class="title unselectable">&debuggerUI.scriptTitle;</div>
|
||||
<div id="editor" class="vbox flex"></div>
|
||||
</div>
|
||||
<div id="properties" class="vbox">
|
||||
<div class="title unselectable">&debuggerUI.propertiesTitle;</div>
|
||||
<div id="variables" class="vbox flex"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dbg-statusbar">
|
||||
<span id="status"></span>
|
||||
</div>
|
||||
<xul:script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<xul:script type="text/javascript" src="debugger-controller.js"/>
|
||||
<xul:script type="text/javascript" src="debugger-view.js"/>
|
||||
|
||||
<xul:popupset id="debugger-popups">
|
||||
<xul:menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<xul:menuitem id="se-cMenu-copy"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-selectAll"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-find"/>
|
||||
<xul:menuitem id="se-cMenu-findAgain"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-gotoLine"/>
|
||||
</xul:menupopup>
|
||||
</xul:popupset>
|
||||
|
||||
<xul:commandset id="editMenuCommands"/>
|
||||
<xul:commandset id="sourceEditorCommands"/>
|
||||
<xul:keyset id="sourceEditorKeys"/>
|
||||
|
||||
<div id="body" class="vbox flex">
|
||||
<xul:toolbar id="dbg-toolbar">
|
||||
<xul:button id="close">&debuggerUI.closeButton;</xul:button>
|
||||
<xul:button id="resume"/>
|
||||
<xul:button id="step-over">&debuggerUI.stepOverButton;</xul:button>
|
||||
<xul:button id="step-in">&debuggerUI.stepInButton;</xul:button>
|
||||
<xul:button id="step-out">&debuggerUI.stepOutButton;</xul:button>
|
||||
<xul:menulist id="scripts"/>
|
||||
</xul:toolbar>
|
||||
<div id="dbg-content" class="hbox flex">
|
||||
<div id="stack" class="vbox">
|
||||
<div class="title unselectable">&debuggerUI.stackTitle;</div>
|
||||
<div id="stackframes" class="vbox flex"></div>
|
||||
</div>
|
||||
<div id="script" class="vbox flex">
|
||||
<div class="title unselectable">&debuggerUI.scriptTitle;</div>
|
||||
<div id="editor" class="vbox flex"></div>
|
||||
</div>
|
||||
<div id="properties" class="vbox">
|
||||
<div class="title unselectable">&debuggerUI.propertiesTitle;</div>
|
||||
<div id="variables" class="vbox flex"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dbg-statusbar">
|
||||
<span id="status"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</xul:window>
|
||||
|
|
|
@ -29,7 +29,7 @@ function test()
|
|||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ function test()
|
|||
{
|
||||
gScripts = gDebugger.DebuggerView.Scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
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.");
|
||||
|
@ -66,7 +66,7 @@ function test()
|
|||
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
isnot(gScripts.selected, gScripts.scriptLocations()[0],
|
||||
isnot(gScripts.selected, gScripts.scriptLocations[0],
|
||||
"the correct script is selected");
|
||||
|
||||
gBreakpoints = gPane.breakpoints;
|
||||
|
@ -161,7 +161,7 @@ function test()
|
|||
ok(!gPane.getBreakpoint(gScripts.selected, 6),
|
||||
"getBreakpoint(selectedScript, 6) returns no breakpoint");
|
||||
|
||||
let script0 = gScripts.scriptLocations()[0];
|
||||
let script0 = gScripts.scriptLocations[0];
|
||||
isnot(script0, gScripts.selected,
|
||||
"first script location is not the currently selected script");
|
||||
|
||||
|
@ -187,7 +187,7 @@ function test()
|
|||
|
||||
ok(aBreakpointClient, "breakpoint2 added, client received");
|
||||
ok(!aResponseError, "breakpoint2 added without errors");
|
||||
is(aBreakpointClient.location.url, gScripts.scriptLocations()[0],
|
||||
is(aBreakpointClient.location.url, gScripts.scriptLocations[0],
|
||||
"breakpoint2 client url is correct");
|
||||
is(aBreakpointClient.location.line, 5,
|
||||
"breakpoint2 client line is correct");
|
||||
|
@ -196,7 +196,7 @@ function test()
|
|||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint2 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1, "one breakpoint in the debugger");
|
||||
is(gPane.getBreakpoint(gScripts.scriptLocations()[0], 5), aBreakpointClient,
|
||||
is(gPane.getBreakpoint(gScripts.scriptLocations[0], 5), aBreakpointClient,
|
||||
"getBreakpoint(scriptLocations[0], 5) returns the correct breakpoint");
|
||||
|
||||
// remove the trap listener
|
||||
|
@ -211,7 +211,7 @@ function test()
|
|||
info("switch to the second script");
|
||||
|
||||
gScripts._scripts.selectedIndex = 0;
|
||||
gDebugger.SourceScripts.onChange({ target: gScripts._scripts });
|
||||
gDebugger.DebuggerController.SourceScripts.onChange({ target: gScripts._scripts });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -267,13 +267,13 @@ function test()
|
|||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.StackFrames.activeThread.resume(finish);
|
||||
gDebugger.DebuggerController.activeThread.resume(finish);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations()[0], 5),
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
|
||||
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||
|
||||
removeTab(gTab);
|
||||
|
|
|
@ -28,7 +28,7 @@ function test()
|
|||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ function test()
|
|||
{
|
||||
let scripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(scripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
@ -107,7 +107,7 @@ function test()
|
|||
|
||||
executeSoon(function() {
|
||||
contextMenu.hidePopup();
|
||||
gDebugger.StackFrames.activeThread.resume(finish);
|
||||
gDebugger.DebuggerController.activeThread.resume(finish);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ function test() {
|
|||
}
|
||||
|
||||
function testCleanExit() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
closeDebuggerAndFinish(gTab);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><title>Browser Debugger Test Tab</title>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><title>Browser Debugger Test Tab</title>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -22,12 +22,12 @@ function test() {
|
|||
}
|
||||
|
||||
function testAnonCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
|
@ -44,7 +44,7 @@ function testAnonCall() {
|
|||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gDebuggee = null;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Debugger Function Call Parameter Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><title>Browser Debugger IFrame Test Tab</title>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger IFrame Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
|
|
|
@ -16,22 +16,22 @@ function test() {
|
|||
gPane = aPane;
|
||||
let gDebugger = gPane.debuggerWindow;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, false,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, true,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have one frame in the stack.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("resumed", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
|
|
|
@ -24,13 +24,13 @@ function test()
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({
|
||||
run: function() {
|
||||
var frames = gDebugger.DebuggerView.Stackframes._frames,
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames,
|
||||
childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
|
@ -49,10 +49,10 @@ function testSimpleCall() {
|
|||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gPane._client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
gPane._client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab again.");
|
||||
|
||||
closeDebuggerAndFinish(gTab);
|
||||
|
|
|
@ -22,19 +22,22 @@ function test() {
|
|||
ok(DebuggerUI.preferences.height,
|
||||
"The debugger preferences should have a saved height value.");
|
||||
|
||||
is(DebuggerUI.preferences.height, pane.frame.height,
|
||||
is(DebuggerUI.preferences.height, pane._frame.height,
|
||||
"The debugger pane height should be the same as the preferred value.");
|
||||
|
||||
pane.frame.height = someHeight;
|
||||
pane._frame.height = someHeight;
|
||||
ok(DebuggerUI.preferences.height !== someHeight,
|
||||
"Height preferences shouldn't have been updated yet.");
|
||||
|
||||
pane.onConnected = function() {
|
||||
pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
|
||||
pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
|
||||
|
||||
removeTab(tab1);
|
||||
finish();
|
||||
|
||||
is(DebuggerUI.preferences.height, someHeight,
|
||||
"Height preferences should have been updated by now.");
|
||||
};
|
||||
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,23 +19,23 @@ function test() {
|
|||
}
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.StackFrames.activeThread.paused, false,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
let button = gDebugger.document.getElementById("resume");
|
||||
is(button.label, gDebugger.DebuggerView.getStr("pauseLabel"),
|
||||
is(button.label, gDebugger.L10N.getStr("pauseLabel"),
|
||||
"Button label should be pause when running.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("paused", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("paused", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, true,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
is(button.label, gDebugger.DebuggerView.getStr("resumeLabel"),
|
||||
is(button.label, gDebugger.L10N.getStr("resumeLabel"),
|
||||
"Button label should be resume when paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
|
@ -51,14 +51,14 @@ function testPause() {
|
|||
}
|
||||
|
||||
function testResume() {
|
||||
gPane.activeThread.addOneTimeListener("resumed", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, false,
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
let button = gDebugger.document.getElementById("resume");
|
||||
is(button.label, gDebugger.DebuggerView.getStr("pauseLabel"),
|
||||
is(button.label, gDebugger.L10N.getStr("pauseLabel"),
|
||||
"Button label should be pause when running.");
|
||||
|
||||
closeDebuggerAndFinish(gTab);
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let globalScope = gDebugger.DebuggerView.Properties._globalScope;
|
||||
|
@ -82,10 +82,10 @@ function testSimpleCall() {
|
|||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
let vs = gDebugger.DebuggerView.Scripts;
|
||||
let ss = gDebugger.SourceScripts;
|
||||
ss.onScriptsCleared();
|
||||
let ss = gDebugger.DebuggerController.SourceScripts;
|
||||
ss._onScriptsCleared();
|
||||
|
||||
is(ss._trimUrlQuery("a/b/c.d?test=1&random=4"), "a/b/c.d",
|
||||
"Trimming the url query isn't done properly.");
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let testScope = gDebugger.DebuggerView.Properties._addScope("test");
|
||||
|
@ -116,7 +116,7 @@ function testSimpleCall() {
|
|||
ok(!testScope.expanded,
|
||||
"Clicking again the testScope tilte should collapse it.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let testScope = gDebugger.DebuggerView.Properties._addScope("test");
|
||||
|
@ -118,7 +118,7 @@ function testSimpleCall() {
|
|||
is(gDebugger.DebuggerView.Properties._vars.childNodes.length, 4,
|
||||
"The scope should have been removed from the parent container tree.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let testScope = gDebugger.DebuggerView.Properties._addScope("test");
|
||||
|
@ -73,7 +73,7 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let testScope = gDebugger.DebuggerView.Properties._addScope("test");
|
||||
|
@ -81,7 +81,7 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let globalScope = gDebugger.DebuggerView.Properties.globalScope;
|
||||
|
@ -117,7 +117,7 @@ function testSimpleCall() {
|
|||
is(localVar5.querySelector(".info").textContent, "[object Object]",
|
||||
"The grip information for the localVar5 wasn't set correctly.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -35,7 +35,7 @@ function testFrameParameters()
|
|||
|
||||
dump("After currentThread.dispatch!\n");
|
||||
|
||||
var frames = gDebugger.DebuggerView.Stackframes._frames,
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames,
|
||||
childNodes = frames.childNodes,
|
||||
localScope = gDebugger.DebuggerView.Properties.localScope,
|
||||
localNodes = localScope.querySelector(".details").childNodes;
|
||||
|
@ -46,7 +46,7 @@ function testFrameParameters()
|
|||
dump("localScope - " + localScope.constructor + "\n");
|
||||
dump("localNodes - " + localNodes.constructor + "\n");
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
|
@ -89,9 +89,9 @@ function testFrameParameters()
|
|||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gPane.activeThread.addOneTimeListener("framescleared", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framescleared", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
var frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
@ -100,7 +100,7 @@ function resumeAndFinish() {
|
|||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -35,7 +35,7 @@ function testFrameParameters()
|
|||
|
||||
dump("After currentThread.dispatch!\n");
|
||||
|
||||
var frames = gDebugger.DebuggerView.Stackframes._frames,
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames,
|
||||
localScope = gDebugger.DebuggerView.Properties.localScope,
|
||||
localNodes = localScope.querySelector(".details").childNodes;
|
||||
|
||||
|
@ -44,7 +44,7 @@ function testFrameParameters()
|
|||
dump("localScope - " + localScope.constructor + "\n");
|
||||
dump("localNodes - " + localNodes.constructor + "\n");
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
|
@ -104,9 +104,9 @@ function testFrameParameters()
|
|||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gPane.activeThread.addOneTimeListener("framescleared", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framescleared", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
var frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
var frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
@ -115,7 +115,7 @@ function resumeAndFinish() {
|
|||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Browser Debugger Script Switching Test</title>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Script Switching Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript" src="test-script-switching-01.js"></script>
|
||||
<script type="text/javascript" src="test-script-switching-02.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -29,7 +29,7 @@ function test()
|
|||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ function test()
|
|||
function testScriptsDisplay() {
|
||||
gScripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gScripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
@ -79,6 +79,8 @@ function testScriptsDisplay() {
|
|||
ok(gDebugger.DebuggerView.Scripts.containsLabel(
|
||||
label2), "Second script label is incorrect.");
|
||||
|
||||
dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
|
||||
|
||||
ok(gDebugger.editor.getText().search(/debugger/) != -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
|
@ -98,6 +100,8 @@ function testScriptsDisplay() {
|
|||
|
||||
function testSwitchPaused()
|
||||
{
|
||||
dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
|
||||
|
||||
ok(gDebugger.editor.getText().search(/debugger/) == -1,
|
||||
"The second script is no longer displayed.");
|
||||
|
||||
|
@ -107,7 +111,7 @@ function testSwitchPaused()
|
|||
is(gDebugger.editor.getDebugLocation(), -1,
|
||||
"editor debugger location has been cleared.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
if (url.indexOf("-02.js") != -1) {
|
||||
|
|
|
@ -31,11 +31,11 @@ function test()
|
|||
}
|
||||
|
||||
function testSelectLine() {
|
||||
gPane.activeThread.addOneTimeListener("scriptsadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("scriptsadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
gScripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gScripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
@ -67,7 +67,7 @@ function testSelectLine() {
|
|||
is(gDebugger.editor.getCaretPosition().line, 4,
|
||||
"The correct line is selected.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,13 +21,13 @@ function test() {
|
|||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
|
@ -36,7 +36,7 @@ function testSimpleCall() {
|
|||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -21,13 +21,13 @@ function test() {
|
|||
}
|
||||
|
||||
function testEvalCall() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 2,
|
||||
|
@ -67,7 +67,7 @@ function testEvalCall() {
|
|||
ok(!frames.querySelector("#stackframe-1").classList.contains("selected"),
|
||||
"Second frame should not be selected after click inside the first frame.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
|
|
|
@ -21,13 +21,13 @@ function test() {
|
|||
}
|
||||
|
||||
function testRecurse() {
|
||||
gDebuggee.gRecurseLimit = (gDebugger.StackFrames.pageSize * 2) + 1;
|
||||
gDebuggee.gRecurseLimit = (gDebugger.DebuggerController.StackFrames.pageSize * 2) + 1;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let pageSize = gDebugger.StackFrames.pageSize;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let pageSize = gDebugger.DebuggerController.StackFrames.pageSize;
|
||||
let recurseLimit = gDebuggee.gRecurseLimit;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
|
@ -38,16 +38,16 @@ function testRecurse() {
|
|||
"All children should be frames.");
|
||||
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, pageSize * 2,
|
||||
"Should now have twice the max limit of frames.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, recurseLimit,
|
||||
"Should have reached the recurse limit.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,13 +21,13 @@ function test() {
|
|||
}
|
||||
|
||||
function testEvalCallResume() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 2,
|
||||
|
@ -37,7 +37,7 @@ function testEvalCallResume() {
|
|||
"All children should be frames.");
|
||||
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framescleared", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framescleared", function() {
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames after resume");
|
||||
|
@ -51,7 +51,7 @@ function testEvalCallResume() {
|
|||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
|
||||
gPane.activeThread.resume();
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ function test() {
|
|||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
@ -51,7 +51,7 @@ function test() {
|
|||
|
||||
function testRecurse()
|
||||
{
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let frames = gDebugger.DebuggerView.StackFrames._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 4,
|
||||
|
@ -95,7 +95,7 @@ function testRecurse()
|
|||
is(gDebugger.editor.getDebugLocation(), 5,
|
||||
"editor debugger location is correct (frame 0 again).");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
is(gDebugger.editor.getDebugLocation(), -1,
|
||||
"editor debugger location is correct after resume.");
|
||||
closeDebuggerAndFinish(gTab);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><title>Browser Debugger Test Tab</title>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Browser Debugger Test Tab</title>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Browser Debugger Test Tab 2</title>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Test Tab 2</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Browser Debugger Update Editor Mode Test</title>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Update Editor Mode Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript" src="test-script-switching-01.js?q=a"></script>
|
||||
<script type="text/javascript" src="test-editor-mode?a=b"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -29,7 +29,7 @@ function test()
|
|||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
@ -56,7 +56,7 @@ function test()
|
|||
function testScriptsDisplay() {
|
||||
gScripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gScripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
@ -90,7 +90,7 @@ function testSwitchPaused()
|
|||
is(gDebugger.editor.getMode(), SourceEditor.MODES.JAVASCRIPT,
|
||||
"Found the expected editor mode.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ function removeTab(aTab) {
|
|||
}
|
||||
|
||||
function closeDebuggerAndFinish(aTab) {
|
||||
DebuggerUI.aWindow.addEventListener("Debugger:Shutdown", function cleanup() {
|
||||
DebuggerUI.aWindow.removeEventListener("Debugger:Shutdown", cleanup, false);
|
||||
DebuggerUI.chromeWindow.addEventListener("Debugger:Shutdown", function cleanup() {
|
||||
DebuggerUI.chromeWindow.removeEventListener("Debugger:Shutdown", cleanup, false);
|
||||
finish();
|
||||
}, false);
|
||||
DebuggerUI.getDebugger(aTab).close();
|
||||
|
@ -96,12 +96,13 @@ function debug_tab_pane(aURL, aOnDebugging)
|
|||
let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
|
||||
let pane = DebuggerUI.toggleDebugger();
|
||||
pane.onConnected = function() {
|
||||
pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
|
||||
pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
|
||||
|
||||
// Wait for the initial resume...
|
||||
pane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
|
||||
delete pane.onConnected;
|
||||
aOnDebugging(tab, debuggee, pane);
|
||||
});
|
||||
};
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* Kyle Simpson <ksimpson@mozilla.com>
|
||||
* Johan Charlez <johan.charlez@gmail.com>
|
||||
* Mike Ratcliffe <mratcliffe@mozilla.com>
|
||||
* Murali S R <murali.sr92@yahoo.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -1926,6 +1927,7 @@ HTMLBreadcrumbs.prototype = {
|
|||
}
|
||||
this.menu.appendChild(fragment);
|
||||
this.menu.openPopup(aButton, "before_start", 0, 0, true, false);
|
||||
aButton.setAttribute("siblings-menu-open", "true");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1936,7 +1938,7 @@ HTMLBreadcrumbs.prototype = {
|
|||
*/
|
||||
handleEvent: function BC_handleEvent(aEvent)
|
||||
{
|
||||
if (aEvent.type == "mousedown") {
|
||||
if (aEvent.type == "mousedown" && aEvent.button == 0) {
|
||||
// on Click and Hold, open the Siblings menu
|
||||
|
||||
let timer;
|
||||
|
@ -1948,7 +1950,6 @@ HTMLBreadcrumbs.prototype = {
|
|||
let target = aEvent.originalTarget;
|
||||
if (target.tagName == "button") {
|
||||
target.onBreadcrumbsHold();
|
||||
target.setAttribute("siblings-menu-open", "true");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,5 @@ browser.jar:
|
|||
* content/browser/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
|
||||
* content/browser/debugger.xul (debugger/debugger.xul)
|
||||
content/browser/debugger.css (debugger/debugger.css)
|
||||
content/browser/debugger.js (debugger/debugger.js)
|
||||
content/browser/debugger-controller.js (debugger/debugger-controller.js)
|
||||
content/browser/debugger-view.js (debugger/debugger-view.js)
|
||||
|
||||
|
|
|
@ -229,8 +229,8 @@ gcli.addCommand({
|
|||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
let files = [];
|
||||
if (dbg) {
|
||||
let scriptsView = dbg.frame.contentWindow.DebuggerView.Scripts;
|
||||
for each (let script in scriptsView.scriptLocations()) {
|
||||
let scriptsView = dbg.debuggerWindow.DebuggerView.Scripts;
|
||||
for each (let script in scriptsView.scriptLocations) {
|
||||
files.push(script);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,11 +69,12 @@ function testCreateCommands() {
|
|||
is(requisition.getStatus().toString(), "ERROR", "break add line is ERROR");
|
||||
|
||||
let pane = DebuggerUI.toggleDebugger();
|
||||
pane.onConnected = function test_onConnected(aPane) {
|
||||
pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
|
||||
pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
|
||||
|
||||
// Wait for the initial resume.
|
||||
aPane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
|
||||
delete aPane.onConnected;
|
||||
aPane.debuggerWindow.gClient.activeThread.addOneTimeListener("framesadded", function() {
|
||||
pane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
|
||||
pane.debuggerWindow.gClient.activeThread.addOneTimeListener("framesadded", function() {
|
||||
type("break add line " + TEST_URI + " " + content.wrappedJSObject.line0);
|
||||
is(requisition.getStatus().toString(), "VALID", "break add line is VALID");
|
||||
requisition.exec();
|
||||
|
@ -82,7 +83,7 @@ function testCreateCommands() {
|
|||
is(requisition.getStatus().toString(), "VALID", "break list is VALID");
|
||||
requisition.exec();
|
||||
|
||||
aPane.debuggerWindow.gClient.activeThread.resume(function() {
|
||||
pane.debuggerWindow.gClient.activeThread.resume(function() {
|
||||
type("break del 0");
|
||||
is(requisition.getStatus().toString(), "VALID", "break del 0 is VALID");
|
||||
requisition.exec();
|
||||
|
@ -94,7 +95,7 @@ function testCreateCommands() {
|
|||
// Trigger newScript notifications using eval.
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function type(command) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче