mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 876277 - Rewrite head.js to use promises and remove useless cruft, r=past
This commit is contained in:
parent
a33ccba979
commit
a0d28d5edf
@ -1714,12 +1714,6 @@ DebuggerController.Breakpoints = new Breakpoints();
|
||||
* Export some properties to the global scope for easier access.
|
||||
*/
|
||||
Object.defineProperties(window, {
|
||||
"dispatchEvent": {
|
||||
get: function() ViewHelpers.dispatchEvent,
|
||||
},
|
||||
"editor": {
|
||||
get: function() DebuggerView.editor
|
||||
},
|
||||
"gTarget": {
|
||||
get: function() DebuggerController._target
|
||||
},
|
||||
@ -1729,18 +1723,6 @@ Object.defineProperties(window, {
|
||||
"gThreadClient": {
|
||||
get: function() DebuggerController.activeThread
|
||||
},
|
||||
"gThreadState": {
|
||||
get: function() DebuggerController.ThreadState
|
||||
},
|
||||
"gStackFrames": {
|
||||
get: function() DebuggerController.StackFrames
|
||||
},
|
||||
"gSourceScripts": {
|
||||
get: function() DebuggerController.SourceScripts
|
||||
},
|
||||
"gBreakpoints": {
|
||||
get: function() DebuggerController.Breakpoints
|
||||
},
|
||||
"gCallStackPageSize": {
|
||||
get: function() CALL_STACK_PAGE_SIZE
|
||||
}
|
||||
|
@ -2,48 +2,45 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource://gre/modules/Services.jsm", tempScope);
|
||||
let Services = tempScope.Services;
|
||||
// Disable logging for faster test runs. Set this pref to true if you want to
|
||||
// debug a test in your try runs.
|
||||
// debug a test in your try runs. Both the debugger server and frontend will
|
||||
// be affected by this pref.
|
||||
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
let DebuggerServer = tempScope.DebuggerServer;
|
||||
let DebuggerTransport = tempScope.DebuggerTransport;
|
||||
let DebuggerClient = tempScope.DebuggerClient;
|
||||
let AddonManager = tempScope.AddonManager;
|
||||
let gDevTools = tempScope.gDevTools;
|
||||
let devtools = tempScope.devtools;
|
||||
let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
let { Promise: promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
|
||||
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
let { BrowserDebuggerProcess } = Cu.import("resource:///modules/devtools/DebuggerProcess.jsm", {});
|
||||
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
|
||||
let { SourceEditor } = Cu.import("resource:///modules/source-editor.jsm", {});
|
||||
let { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
let Toolbox = devtools.Toolbox;
|
||||
|
||||
const EXAMPLE_URL = "http://example.com/browser/browser/devtools/debugger/test/";
|
||||
|
||||
// All tests are asynchronous.
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
info("finish() was called, cleaning up...");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
|
||||
|
||||
// Properly shut down the server to avoid memory leaks.
|
||||
DebuggerServer.destroy();
|
||||
});
|
||||
|
||||
// Import the GCLI test helper
|
||||
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
||||
Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
|
||||
|
||||
const EXAMPLE_URL = "http://example.com/browser/browser/devtools/debugger/test/";
|
||||
const TAB1_URL = EXAMPLE_URL + "browser_dbg_tab1.html";
|
||||
const TAB2_URL = EXAMPLE_URL + "browser_dbg_tab2.html";
|
||||
const ADDON1_URL = EXAMPLE_URL + "browser_dbg_addon1.xpi";
|
||||
const ADDON2_URL = EXAMPLE_URL + "browser_dbg_addon2.xpi";
|
||||
const STACK_URL = EXAMPLE_URL + "browser_dbg_stack.html";
|
||||
|
||||
// Enable remote debugging for the relevant tests.
|
||||
let gEnableRemote = Services.prefs.getBoolPref("devtools.debugger.remote-enabled");
|
||||
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
|
||||
|
||||
// Redeclare dbg_assert with a fatal behavior.
|
||||
function dbg_assert(cond, e) {
|
||||
if (!cond) {
|
||||
@ -51,197 +48,461 @@ function dbg_assert(cond, e) {
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", gEnableRemote);
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
|
||||
|
||||
// Properly shut down the server to avoid memory leaks.
|
||||
DebuggerServer.destroy();
|
||||
});
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(function() true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
function addWindow(aUrl) {
|
||||
info("Adding window: " + aUrl);
|
||||
return promise.resolve(getDOMWindow(window.open(aUrl)));
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
function addWindow() {
|
||||
let windowReference = window.open();
|
||||
let chromeWindow = windowReference
|
||||
function getDOMWindow(aReference) {
|
||||
return aReference
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
return chromeWindow;
|
||||
}
|
||||
|
||||
function addTab(aURL, aOnload, aWindow) {
|
||||
function addTab(aUrl, aWindow) {
|
||||
info("Adding tab: " + aUrl);
|
||||
|
||||
let deferred = promise.defer();
|
||||
let targetWindow = aWindow || window;
|
||||
let targetBrowser = targetWindow.gBrowser;
|
||||
|
||||
targetWindow.focus();
|
||||
targetBrowser.selectedTab = targetBrowser.addTab(aURL);
|
||||
let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
|
||||
let linkedBrowser = tab.linkedBrowser;
|
||||
|
||||
let tab = targetBrowser.selectedTab;
|
||||
let browser = tab.linkedBrowser;
|
||||
let win = browser.contentWindow;
|
||||
let expectedReadyState = aURL == "about:blank" ? ["interactive", "complete"] : ["complete"];
|
||||
linkedBrowser.addEventListener("load", function onLoad() {
|
||||
linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
deferred.resolve(tab);
|
||||
}, true);
|
||||
|
||||
if (aOnload) {
|
||||
let handler = function() {
|
||||
if (browser.currentURI.spec != aURL ||
|
||||
expectedReadyState.indexOf((win.document || {}).readyState) == -1) {
|
||||
return;
|
||||
}
|
||||
browser.removeEventListener("load", handler, true);
|
||||
executeSoon(aOnload);
|
||||
}
|
||||
browser.addEventListener("load", handler, true);
|
||||
}
|
||||
|
||||
return tab;
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeTab(aTab, aWindow) {
|
||||
info("Removing tab.");
|
||||
|
||||
let deferred = promise.defer();
|
||||
let targetWindow = aWindow || window;
|
||||
let targetBrowser = targetWindow.gBrowser;
|
||||
let tabContainer = targetBrowser.tabContainer;
|
||||
|
||||
tabContainer.addEventListener("TabClose", function onClose(aEvent) {
|
||||
tabContainer.removeEventListener("TabClose", onClose, false);
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
|
||||
targetBrowser.removeTab(aTab);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function addAddon(aURL, aOnInstallEnded) {
|
||||
AddonManager.getInstallForURL(aURL, function(aInstall) {
|
||||
aInstall.install();
|
||||
var listener = {
|
||||
function addAddon(aUrl) {
|
||||
info("Installing addon: " + aUrl);
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
AddonManager.getInstallForURL(aUrl, aInstaller => {
|
||||
aInstaller.install();
|
||||
let listener = {
|
||||
onInstallEnded: function(aAddon, aAddonInstall) {
|
||||
aInstall.removeListener(listener);
|
||||
aOnInstallEnded(aAddonInstall);
|
||||
aInstaller.removeListener(listener);
|
||||
deferred.resolve(aAddonInstall);
|
||||
}
|
||||
};
|
||||
aInstall.addListener(listener);
|
||||
aInstaller.addListener(listener);
|
||||
}, "application/x-xpinstall");
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeAddon(aAddon, aOnUninstalled) {
|
||||
var listener = {
|
||||
function removeAddon(aAddon) {
|
||||
info("Removing addon.");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
let listener = {
|
||||
onUninstalled: function(aUninstalledAddon) {
|
||||
if (aUninstalledAddon != aAddon)
|
||||
if (aUninstalledAddon != aAddon) {
|
||||
return;
|
||||
}
|
||||
AddonManager.removeAddonListener(listener);
|
||||
aOnUninstalled();
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
aAddon.uninstall();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function closeDebuggerAndFinish(aRemoteFlag, aCallback, aWindow) {
|
||||
let debuggerClosed = false;
|
||||
let debuggerDisconnected = false;
|
||||
function getTabActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
ok(gTab, "There is a gTab to use for getting a toolbox reference");
|
||||
let target = TargetFactory.forTab(gTab);
|
||||
|
||||
window.addEventListener("Debugger:Shutdown", function cleanup() {
|
||||
window.removeEventListener("Debugger:Shutdown", cleanup, false);
|
||||
debuggerDisconnected = true;
|
||||
maybeFinish();
|
||||
}, false);
|
||||
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
toolbox.destroy().then(function() {
|
||||
debuggerClosed = true;
|
||||
maybeFinish();
|
||||
aClient.listTabs(aResponse => {
|
||||
let tabActor = aResponse.tabs.filter(aGrip => aGrip.url == aUrl).pop();
|
||||
deferred.resolve(tabActor);
|
||||
});
|
||||
|
||||
function maybeFinish() {
|
||||
if (debuggerClosed && debuggerDisconnected) {
|
||||
(finish || aCallback)();
|
||||
}
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function get_tab_actor_for_url(aClient, aURL, aCallback) {
|
||||
aClient.listTabs(function(aResponse) {
|
||||
for each (let tab in aResponse.tabs) {
|
||||
if (tab.url == aURL) {
|
||||
aCallback(tab);
|
||||
return;
|
||||
}
|
||||
}
|
||||
function getAddonActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
aClient.listAddons(aResponse => {
|
||||
let addonActor = aResponse.addons.filter(aGrip => aGrip.url == aUrl).pop();
|
||||
deferred.resolve(addonActor);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function attach_tab_actor_for_url(aClient, aURL, aCallback) {
|
||||
get_tab_actor_for_url(aClient, aURL, function(actor) {
|
||||
aClient.attachTab(actor.actor, function(aResponse) {
|
||||
aCallback(actor, aResponse);
|
||||
function attachTabActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
getTabActorForUrl(aClient, aUrl).then(aGrip => {
|
||||
aClient.attachTab(aGrip.actor, aResponse => {
|
||||
deferred.resolve([aGrip, aResponse]);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function attach_thread_actor_for_url(aClient, aURL, aCallback) {
|
||||
attach_tab_actor_for_url(aClient, aURL, function(aTabActor, aResponse) {
|
||||
aClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
|
||||
// We don't care about the pause right now (use
|
||||
// get_actor_for_url() if you do), so resume it.
|
||||
aThreadClient.resume(function(aResponse) {
|
||||
aCallback(aThreadClient);
|
||||
function attachThreadActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
attachTabActorForUrl(aClient, aUrl).then(([aGrip, aResponse]) => {
|
||||
aClient.attachThread(aResponse.threadActor, (aResponse, aThreadClient) => {
|
||||
aThreadClient.resume(aResponse => {
|
||||
deferred.resolve(aThreadClient);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function wait_for_connect_and_resume(aOnDebugging, aTab) {
|
||||
let target = TargetFactory.forTab(aTab);
|
||||
function once(aTarget, aEventName, aUseCapture = false) {
|
||||
info("Waiting for event: '" + aEventName + "' on " + aTarget + ".");
|
||||
|
||||
gDevTools.showToolbox(target, "jsdebugger").then(function(toolbox) {
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Wait for the initial resume...
|
||||
dbg.panelWin.gClient.addOneTimeListener("resumed", function() {
|
||||
aOnDebugging();
|
||||
});
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in aTarget) && (remove in aTarget)) {
|
||||
aTarget[add](aEventName, function onEvent(...aArgs) {
|
||||
aTarget[remove](aEventName, onEvent, aUseCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}, aUseCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForSourceShown(aPanel, aUrl) {
|
||||
return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.SOURCE_SHOWN).then(aSource => {
|
||||
let sourceUrl = aSource.url;
|
||||
info("Source shown: " + sourceUrl);
|
||||
|
||||
if (!sourceUrl.contains(aUrl)) {
|
||||
return waitForSourceShown(aPanel, aUrl);
|
||||
} else {
|
||||
ok(true, "The correct source has been shown.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function debug_tab_pane(aURL, aOnDebugging, aBeforeTabAdded) {
|
||||
// Make any necessary preparations (start the debugger server etc.)
|
||||
if (aBeforeTabAdded) {
|
||||
aBeforeTabAdded();
|
||||
function ensureSourceIs(aPanel, aUrl, aWaitFlag = false) {
|
||||
if (aPanel.panelWin.DebuggerView.Sources.selectedValue.contains(aUrl)) {
|
||||
ok(true, "Expected source is shown: " + aUrl);
|
||||
return promise.resolve(null);
|
||||
}
|
||||
if (aWaitFlag) {
|
||||
return waitForSourceShown(aPanel, aUrl);
|
||||
}
|
||||
ok(false, "Expected source was not already shown: " + aUrl);
|
||||
return promise.reject(null);
|
||||
}
|
||||
|
||||
let tab = addTab(aURL, function() {
|
||||
let debuggee = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
function waitForCaretUpdated(aPanel, aLine, aCol = 1) {
|
||||
return waitForEditorEvents(aPanel, SourceEditor.EVENTS.SELECTION).then(() => {
|
||||
let caret = aPanel.panelWin.DebuggerView.editor.getCaretPosition();
|
||||
info("Caret updated: " + (caret.line + 1) + ", " + (caret.col + 1));
|
||||
|
||||
info("Opening Debugger");
|
||||
gDevTools.showToolbox(target, "jsdebugger").then(function(toolbox) {
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
if (!isCaretPos(aPanel, aLine, aCol)) {
|
||||
return waitForCaretUpdated(aPanel, aLine, aCol);
|
||||
} else {
|
||||
ok(true, "The correct caret position has been set.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ensureCaretAt(aPanel, aLine, aCol = 1, aWaitFlag = false) {
|
||||
if (isCaretPos(aPanel, aLine, aCol)) {
|
||||
ok(true, "Expected caret position is set: " + aLine + "," + aCol);
|
||||
return promise.resolve(null);
|
||||
}
|
||||
if (aWaitFlag) {
|
||||
return waitForCaretUpdated(aPanel, aLine, aCol);
|
||||
}
|
||||
ok(false, "Expected caret position was not already set: " + aLine + "," + aCol);
|
||||
return promise.reject(null);
|
||||
}
|
||||
|
||||
function isCaretPos(aPanel, aLine, aCol = 1) {
|
||||
let editor = aPanel.panelWin.DebuggerView.editor;
|
||||
let caret = editor.getCaretPosition();
|
||||
|
||||
// Source editor starts counting line and column numbers from 0.
|
||||
info("Current editor caret position: " + (caret.line + 1) + ", " + (caret.col + 1));
|
||||
return caret.line == (aLine - 1) && caret.col == (aCol - 1);
|
||||
}
|
||||
|
||||
function isEditorSel(aPanel, [start, end]) {
|
||||
let editor = aPanel.panelWin.DebuggerView.editor;
|
||||
let range = editor.getSelection();
|
||||
|
||||
// Source editor starts counting line and column numbers from 0.
|
||||
info("Current editor selection: " + (range.start + 1) + ", " + (range.end + 1));
|
||||
return range.start == (start - 1) && range.end == (end - 1);
|
||||
}
|
||||
|
||||
function waitForSourceAndCaret(aPanel, aUrl, aLine, aCol) {
|
||||
return promise.all([
|
||||
waitForSourceShown(aPanel, aUrl),
|
||||
waitForCaretUpdated(aPanel, aLine, aCol)
|
||||
]);
|
||||
}
|
||||
|
||||
function waitForCaretAndScopes(aPanel, aLine, aCol) {
|
||||
return promise.all([
|
||||
waitForCaretUpdated(aPanel, aLine, aCol),
|
||||
waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.FETCHED_SCOPES)
|
||||
]);
|
||||
}
|
||||
|
||||
function waitForSourceAndCaretAndScopes(aPanel, aUrl, aLine, aCol) {
|
||||
return promise.all([
|
||||
waitForSourceAndCaret(aPanel, aUrl, aLine, aCol),
|
||||
waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.FETCHED_SCOPES)
|
||||
]);
|
||||
}
|
||||
|
||||
function waitForDebuggerEvents(aPanel, aEventName, aEventRepeat = 1) {
|
||||
info("Waiting for debugger event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s).");
|
||||
|
||||
let deferred = promise.defer();
|
||||
let panelWin = aPanel.panelWin;
|
||||
let count = 0;
|
||||
|
||||
panelWin.on(aEventName, function onEvent(aEventName, ...aArgs) {
|
||||
info("Debugger event '" + aEventName + "' fired: " + (++count) + " time(s).");
|
||||
|
||||
if (count == aEventRepeat) {
|
||||
ok(true, "Enough '" + aEventName + "' panel events have been fired.");
|
||||
panelWin.off(aEventName, onEvent);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForEditorEvents(aPanel, aEventName, aEventRepeat = 1) {
|
||||
info("Waiting for editor event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s).");
|
||||
|
||||
let deferred = promise.defer();
|
||||
let editor = aPanel.panelWin.DebuggerView.editor;
|
||||
let count = 0;
|
||||
|
||||
editor.addEventListener(aEventName, function onEvent(...aArgs) {
|
||||
info("Editor event '" + aEventName + "' fired: " + (++count) + " time(s).");
|
||||
|
||||
if (count == aEventRepeat) {
|
||||
ok(true, "Enough '" + aEventName + "' editor events have been fired.");
|
||||
editor.removeEventListener(aEventName, onEvent);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForThreadEvents(aPanel, aEventName, aEventRepeat = 1) {
|
||||
info("Waiting for thread event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s).");
|
||||
|
||||
let deferred = promise.defer();
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
let count = 0;
|
||||
|
||||
thread.addListener(aEventName, function onEvent(aEventName, ...aArgs) {
|
||||
info("Thread event '" + aEventName + "' fired: " + (++count) + " time(s).");
|
||||
|
||||
if (count == aEventRepeat) {
|
||||
ok(true, "Enough '" + aEventName + "' thread events have been fired.");
|
||||
thread.removeListener(aEventName, onEvent);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function ensureThreadClientState(aPanel, aState) {
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
let state = thread.state;
|
||||
|
||||
info("Thread is: '" + state + "'.");
|
||||
|
||||
if (state == aState) {
|
||||
return promise.resolve(null);
|
||||
} else {
|
||||
return waitForThreadEvents(aPanel, aState);
|
||||
}
|
||||
}
|
||||
|
||||
function navigateActiveTabTo(aPanel, aUrl, aWaitForEventName, aEventRepeat) {
|
||||
let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat);
|
||||
let activeTab = aPanel.panelWin.gClient.activeTab;
|
||||
aUrl ? activeTab.navigateTo(aUrl) : activeTab.reload();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function navigateActiveTabInHistory(aPanel, aDirection, aWaitForEventName, aEventRepeat) {
|
||||
let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat);
|
||||
content.history[aDirection]();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function reloadActiveTab(aPanel, aWaitForEventName, aEventRepeat) {
|
||||
return navigateActiveTabTo(aPanel, null, aWaitForEventName, aEventRepeat);
|
||||
}
|
||||
|
||||
function clearText(aElement) {
|
||||
info("Clearing text...");
|
||||
aElement.focus();
|
||||
aElement.value = "";
|
||||
}
|
||||
|
||||
function setText(aElement, aText) {
|
||||
clearText(aElement);
|
||||
info("Setting text: " + aText);
|
||||
aElement.value = aText;
|
||||
}
|
||||
|
||||
function typeText(aElement, aText) {
|
||||
info("Typing text: " + aText);
|
||||
aElement.focus();
|
||||
EventUtils.sendString(aText, aElement.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
function backspaceText(aElement, aTimes) {
|
||||
info("Pressing backspace " + aTimes + " times.");
|
||||
for (let i = 0; i < aTimes; i++) {
|
||||
aElement.focus();
|
||||
EventUtils.sendKey("BACK_SPACE", aElement.ownerDocument.defaultView);
|
||||
}
|
||||
}
|
||||
|
||||
function getTab(aTarget) {
|
||||
if (aTarget instanceof XULElement) {
|
||||
return promise.resolve(aTarget);
|
||||
} else {
|
||||
return addTab(aTarget);
|
||||
}
|
||||
}
|
||||
|
||||
function initDebugger(aTarget, aWindow) {
|
||||
info("Initializing a debugger panel.");
|
||||
|
||||
return getTab(aTarget).then(aTab => {
|
||||
info("Debugee tab added successfully: " + aTarget);
|
||||
|
||||
let deferred = promise.defer();
|
||||
let debuggee = aTab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
let target = TargetFactory.forTab(aTab);
|
||||
|
||||
gDevTools.showToolbox(target, "jsdebugger").then(aToolbox => {
|
||||
info("Debugger panel shown successfully.");
|
||||
|
||||
let debuggerPanel = aToolbox.getCurrentPanel();
|
||||
let panelWin = debuggerPanel.panelWin;
|
||||
|
||||
// Wait for the initial resume...
|
||||
dbg.panelWin.gClient.addOneTimeListener("resumed", function() {
|
||||
info("Debugger has started");
|
||||
dbg._view.Variables.lazyEmpty = false;
|
||||
dbg._view.Variables.lazyAppend = false;
|
||||
dbg._view.Variables.lazyExpand = false;
|
||||
aOnDebugging(tab, debuggee, dbg);
|
||||
panelWin.gClient.addOneTimeListener("resumed", () => {
|
||||
info("Debugger client resumed successfully.");
|
||||
|
||||
prepareDebugger(debuggerPanel);
|
||||
deferred.resolve([aTab, debuggee, debuggerPanel]);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
}
|
||||
|
||||
function debug_chrome(aURL, aOnClosing, aOnDebugging) {
|
||||
let tab = addTab(aURL, function() {
|
||||
let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
function initChromeDebugger(aOnClose) {
|
||||
info("Initializing a chrome debugger process.");
|
||||
|
||||
info("Opening Browser Debugger");
|
||||
let win = BrowserDebuggerProcess.init(aOnClosing, function(process) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// The remote debugging process has started...
|
||||
info("Browser Debugger has started");
|
||||
aOnDebugging(tab, debuggee, process);
|
||||
});
|
||||
// Wait for the debugger process to start...
|
||||
BrowserDebuggerProcess.init(aOnClose, aProcess => {
|
||||
info("Chrome debugger process started successfully.");
|
||||
|
||||
prepareDebugger(aProcess);
|
||||
deferred.resolve(aProcess);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function prepareDebugger(aDebugger) {
|
||||
if ("target" in aDebugger) {
|
||||
let variables = aDebugger.panelWin.DebuggerView.Variables;
|
||||
variables.lazyEmpty = false;
|
||||
variables.lazyAppend = false;
|
||||
variables.lazyExpand = false;
|
||||
variables.lazySearch = false;
|
||||
} else {
|
||||
// Nothing to do here yet.
|
||||
}
|
||||
}
|
||||
|
||||
function teardown(aPanel, aFlags = {}) {
|
||||
info("Destroying the specified debugger.");
|
||||
|
||||
let toolbox = aPanel._toolbox;
|
||||
let tab = aPanel.target.tab;
|
||||
let debuggerRootActorDisconnected = once(window, "Debugger:Shutdown");
|
||||
let debuggerPanelDestroyed = once(aPanel, "destroyed");
|
||||
let devtoolsToolboxDestroyed = toolbox.destroy();
|
||||
|
||||
return promise.all([
|
||||
debuggerRootActorDisconnected,
|
||||
debuggerPanelDestroyed,
|
||||
devtoolsToolboxDestroyed
|
||||
]).then(() => aFlags.noTabRemoval ? null : removeTab(tab));
|
||||
}
|
||||
|
||||
function closeDebuggerAndFinish(aPanel, aFlags = {}) {
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
if (thread.state == "paused" && !aFlags.whilePaused) {
|
||||
ok(false, "You should use 'resumeDebuggerThenCloseAndFinish' instead, " +
|
||||
"unless you're absolutely sure about what you're doing.");
|
||||
}
|
||||
return teardown(aPanel, aFlags).then(finish);
|
||||
}
|
||||
|
||||
function resumeDebuggerThenCloseAndFinish(aPanel, aFlags = {}) {
|
||||
let deferred = promise.defer();
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
thread.resume(() => closeDebuggerAndFinish(aPanel, aFlags).then(deferred.resolve));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user