This commit is contained in:
Tim Taubert 2012-04-13 12:22:37 +02:00
Родитель a21bc4661d dfedfcfbe5
Коммит 1e1f817f3e
49 изменённых файлов: 1999 добавлений и 1709 удалений

Просмотреть файл

@ -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) {