2013-05-03 23:31:07 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2013-06-20 13:18:56 -07:00
|
|
|
const {Cu, Cc, Ci} = require("chrome");
|
2014-04-03 01:19:42 -07:00
|
|
|
const Services = require("Services");
|
2014-03-17 11:11:00 -07:00
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
2014-04-03 01:19:42 -07:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
|
2013-05-03 23:31:07 -07:00
|
|
|
|
|
|
|
exports.OptionsPanel = OptionsPanel;
|
|
|
|
|
2013-05-28 12:36:16 -07:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "l10n", function() {
|
|
|
|
let bundle = Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
|
|
|
|
let l10n = function(aName, ...aArgs) {
|
|
|
|
try {
|
|
|
|
if (aArgs.length == 0) {
|
|
|
|
return bundle.GetStringFromName(aName);
|
|
|
|
} else {
|
|
|
|
return bundle.formatStringFromName(aName, aArgs, aArgs.length);
|
|
|
|
}
|
|
|
|
} catch (ex) {
|
|
|
|
Services.console.logStringMessage("Error reading '" + aName + "'");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return l10n;
|
|
|
|
});
|
|
|
|
|
2013-05-03 23:31:07 -07:00
|
|
|
/**
|
|
|
|
* Represents the Options Panel in the Toolbox.
|
|
|
|
*/
|
|
|
|
function OptionsPanel(iframeWindow, toolbox) {
|
|
|
|
this.panelDoc = iframeWindow.document;
|
|
|
|
this.panelWin = iframeWindow;
|
2013-05-31 08:52:06 -07:00
|
|
|
this.toolbox = toolbox;
|
2013-06-22 20:00:51 -07:00
|
|
|
this.isReady = false;
|
2013-05-03 23:31:07 -07:00
|
|
|
|
2014-04-03 01:19:42 -07:00
|
|
|
const EventEmitter = require("devtools/toolkit/event-emitter");
|
2013-05-03 23:31:07 -07:00
|
|
|
EventEmitter.decorate(this);
|
2013-12-18 01:34:49 -08:00
|
|
|
}
|
2013-05-03 23:31:07 -07:00
|
|
|
|
|
|
|
OptionsPanel.prototype = {
|
|
|
|
|
2013-05-28 12:36:16 -07:00
|
|
|
get target() {
|
|
|
|
return this.toolbox.target;
|
|
|
|
},
|
|
|
|
|
2013-06-20 13:18:56 -07:00
|
|
|
open: function() {
|
2013-12-18 01:34:49 -08:00
|
|
|
let targetPromise;
|
2013-05-03 23:31:07 -07:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
// For local debugging we need to make the target remote.
|
|
|
|
if (!this.target.isRemote) {
|
|
|
|
targetPromise = this.target.makeRemote();
|
|
|
|
} else {
|
|
|
|
targetPromise = promise.resolve(this.target);
|
|
|
|
}
|
2013-05-31 08:52:06 -07:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
return targetPromise.then(() => {
|
|
|
|
this.setupToolsList();
|
2014-03-06 14:02:11 -08:00
|
|
|
this.setupToolbarButtonsList();
|
2013-12-18 01:34:49 -08:00
|
|
|
this.populatePreferences();
|
2013-05-31 08:52:06 -07:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
this._disableJSClicked = this._disableJSClicked.bind(this);
|
|
|
|
this._disableCacheClicked = this._disableCacheClicked.bind(this);
|
2013-12-17 02:58:21 -08:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
let disableJSNode = this.panelDoc.getElementById("devtools-disable-javascript");
|
|
|
|
disableJSNode.addEventListener("click", this._disableJSClicked, false);
|
|
|
|
|
|
|
|
let disableCacheNode = this.panelDoc.getElementById("devtools-disable-cache");
|
|
|
|
disableCacheNode.addEventListener("click", this._disableCacheClicked, false);
|
|
|
|
}).then(() => {
|
|
|
|
this.isReady = true;
|
|
|
|
this.emit("ready");
|
|
|
|
return this;
|
|
|
|
}).then(null, function onError(aReason) {
|
|
|
|
Cu.reportError("OptionsPanel open failed. " +
|
|
|
|
aReason.error + ": " + aReason.message);
|
|
|
|
});
|
2013-05-03 23:31:07 -07:00
|
|
|
},
|
|
|
|
|
2014-03-06 14:02:11 -08:00
|
|
|
setupToolbarButtonsList: function() {
|
|
|
|
let enabledToolbarButtonsBox = this.panelDoc.getElementById("enabled-toolbox-buttons-box");
|
|
|
|
enabledToolbarButtonsBox.textContent = "";
|
|
|
|
|
|
|
|
let toggleableButtons = this.toolbox.toolboxButtons;
|
|
|
|
let setToolboxButtonsVisibility =
|
|
|
|
this.toolbox.setToolboxButtonsVisibility.bind(this.toolbox);
|
|
|
|
|
|
|
|
let onCheckboxClick = (checkbox) => {
|
|
|
|
let toolDefinition = toggleableButtons.filter(tool => tool.id === checkbox.id)[0];
|
|
|
|
Services.prefs.setBoolPref(toolDefinition.visibilityswitch, checkbox.checked);
|
|
|
|
setToolboxButtonsVisibility();
|
|
|
|
};
|
|
|
|
|
|
|
|
let createCommandCheckbox = tool => {
|
|
|
|
let checkbox = this.panelDoc.createElement("checkbox");
|
|
|
|
checkbox.setAttribute("id", tool.id);
|
|
|
|
checkbox.setAttribute("label", tool.label);
|
|
|
|
checkbox.setAttribute("checked", this.getBoolPref(tool.visibilityswitch));
|
|
|
|
checkbox.addEventListener("command", onCheckboxClick.bind(this, checkbox));
|
|
|
|
return checkbox;
|
|
|
|
};
|
|
|
|
|
|
|
|
for (let tool of toggleableButtons) {
|
|
|
|
enabledToolbarButtonsBox.appendChild(createCommandCheckbox(tool));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getBoolPref: function(key) {
|
|
|
|
try {
|
|
|
|
return Services.prefs.getBoolPref(key);
|
|
|
|
}
|
|
|
|
catch (ex) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-06-20 13:18:56 -07:00
|
|
|
setupToolsList: function() {
|
2013-05-03 23:31:07 -07:00
|
|
|
let defaultToolsBox = this.panelDoc.getElementById("default-tools-box");
|
|
|
|
let additionalToolsBox = this.panelDoc.getElementById("additional-tools-box");
|
2013-05-28 12:36:16 -07:00
|
|
|
let toolsNotSupportedLabel = this.panelDoc.getElementById("tools-not-supported-label");
|
|
|
|
let atleastOneToolNotSupported = false;
|
2013-05-03 23:31:07 -07:00
|
|
|
|
|
|
|
defaultToolsBox.textContent = "";
|
|
|
|
additionalToolsBox.textContent = "";
|
|
|
|
|
|
|
|
let onCheckboxClick = function(id) {
|
|
|
|
let toolDefinition = gDevTools._tools.get(id);
|
|
|
|
// Set the kill switch pref boolean to true
|
|
|
|
Services.prefs.setBoolPref(toolDefinition.visibilityswitch, this.checked);
|
|
|
|
if (this.checked) {
|
|
|
|
gDevTools.emit("tool-registered", id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
gDevTools.emit("tool-unregistered", toolDefinition);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-05-28 12:36:16 -07:00
|
|
|
let createToolCheckbox = tool => {
|
2013-05-03 23:31:07 -07:00
|
|
|
let checkbox = this.panelDoc.createElement("checkbox");
|
|
|
|
checkbox.setAttribute("id", tool.id);
|
|
|
|
checkbox.setAttribute("tooltiptext", tool.tooltip || "");
|
2013-05-28 12:36:16 -07:00
|
|
|
if (tool.isTargetSupported(this.target)) {
|
|
|
|
checkbox.setAttribute("label", tool.label);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
atleastOneToolNotSupported = true;
|
|
|
|
checkbox.setAttribute("label",
|
|
|
|
l10n("options.toolNotSupportedMarker", tool.label));
|
2013-10-04 12:44:09 -07:00
|
|
|
checkbox.setAttribute("unsupported", "");
|
2013-05-28 12:36:16 -07:00
|
|
|
}
|
2014-03-06 14:02:11 -08:00
|
|
|
checkbox.setAttribute("checked", this.getBoolPref(tool.visibilityswitch));
|
2013-05-03 23:31:07 -07:00
|
|
|
checkbox.addEventListener("command", onCheckboxClick.bind(checkbox, tool.id));
|
2013-05-28 12:36:16 -07:00
|
|
|
return checkbox;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Populating the default tools lists
|
2013-11-18 12:12:02 -08:00
|
|
|
let toggleableTools = gDevTools.getDefaultTools().filter(tool => {
|
2014-04-03 01:19:42 -07:00
|
|
|
return tool.visibilityswitch;
|
2013-11-18 12:12:02 -08:00
|
|
|
});
|
2014-04-03 01:19:42 -07:00
|
|
|
|
2013-11-18 12:12:02 -08:00
|
|
|
for (let tool of toggleableTools) {
|
2013-05-28 12:36:16 -07:00
|
|
|
defaultToolsBox.appendChild(createToolCheckbox(tool));
|
2013-05-03 23:31:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Populating the additional tools list that came from add-ons.
|
|
|
|
let atleastOneAddon = false;
|
|
|
|
for (let tool of gDevTools.getAdditionalTools()) {
|
|
|
|
atleastOneAddon = true;
|
2013-05-28 12:36:16 -07:00
|
|
|
additionalToolsBox.appendChild(createToolCheckbox(tool));
|
2013-05-03 23:31:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!atleastOneAddon) {
|
|
|
|
additionalToolsBox.style.display = "none";
|
|
|
|
additionalToolsBox.previousSibling.style.display = "none";
|
|
|
|
}
|
|
|
|
|
2013-05-28 12:36:16 -07:00
|
|
|
if (!atleastOneToolNotSupported) {
|
|
|
|
toolsNotSupportedLabel.style.display = "none";
|
|
|
|
}
|
|
|
|
|
2013-05-03 23:31:07 -07:00
|
|
|
this.panelWin.focus();
|
|
|
|
},
|
|
|
|
|
2013-06-20 13:18:56 -07:00
|
|
|
populatePreferences: function() {
|
2013-05-03 23:31:07 -07:00
|
|
|
let prefCheckboxes = this.panelDoc.querySelectorAll("checkbox[data-pref]");
|
|
|
|
for (let checkbox of prefCheckboxes) {
|
|
|
|
checkbox.checked = Services.prefs.getBoolPref(checkbox.getAttribute("data-pref"));
|
|
|
|
checkbox.addEventListener("command", function() {
|
|
|
|
let data = {
|
|
|
|
pref: this.getAttribute("data-pref"),
|
|
|
|
newValue: this.checked
|
|
|
|
};
|
|
|
|
data.oldValue = Services.prefs.getBoolPref(data.pref);
|
|
|
|
Services.prefs.setBoolPref(data.pref, data.newValue);
|
|
|
|
gDevTools.emit("pref-changed", data);
|
|
|
|
}.bind(checkbox));
|
|
|
|
}
|
|
|
|
let prefRadiogroups = this.panelDoc.querySelectorAll("radiogroup[data-pref]");
|
|
|
|
for (let radiogroup of prefRadiogroups) {
|
|
|
|
let selectedValue = Services.prefs.getCharPref(radiogroup.getAttribute("data-pref"));
|
|
|
|
for (let radio of radiogroup.childNodes) {
|
|
|
|
radiogroup.selectedIndex = -1;
|
|
|
|
if (radio.getAttribute("value") == selectedValue) {
|
|
|
|
radiogroup.selectedItem = radio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
radiogroup.addEventListener("select", function() {
|
|
|
|
let data = {
|
|
|
|
pref: this.getAttribute("data-pref"),
|
|
|
|
newValue: this.selectedItem.getAttribute("value")
|
|
|
|
};
|
|
|
|
data.oldValue = Services.prefs.getCharPref(data.pref);
|
|
|
|
Services.prefs.setCharPref(data.pref, data.newValue);
|
|
|
|
gDevTools.emit("pref-changed", data);
|
|
|
|
}.bind(radiogroup));
|
|
|
|
}
|
2013-09-16 03:01:25 -07:00
|
|
|
let prefMenulists = this.panelDoc.querySelectorAll("menulist[data-pref]");
|
|
|
|
for (let menulist of prefMenulists) {
|
|
|
|
let pref = Services.prefs.getCharPref(menulist.getAttribute("data-pref"));
|
|
|
|
let menuitems = menulist.querySelectorAll("menuitem");
|
|
|
|
for (let menuitem of menuitems) {
|
|
|
|
let value = menuitem.getAttribute("value");
|
|
|
|
if (value === pref) {
|
|
|
|
menulist.selectedItem = menuitem;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
menulist.addEventListener("command", function() {
|
|
|
|
let data = {
|
|
|
|
pref: this.getAttribute("data-pref"),
|
|
|
|
newValue: this.value
|
|
|
|
};
|
|
|
|
data.oldValue = Services.prefs.getCharPref(data.pref);
|
|
|
|
Services.prefs.setCharPref(data.pref, data.newValue);
|
|
|
|
gDevTools.emit("pref-changed", data);
|
|
|
|
}.bind(menulist));
|
|
|
|
}
|
2013-12-18 01:34:49 -08:00
|
|
|
|
Make the debugger frontend cope with an already connected target (bug 933212); r=jryans,fitzgen
* Made the DebuggerClient, which is actually the RootActor front, not consider one of the attached child fronts as "active". Since a single DebuggerClient (or RootFront) is kept around for the App Manager's lifetime, it makes sense to move the notion of "active" tab to the toolbox's target. As each toolbox gets destroyed, the fronts should be detaching from their actors (if they are stateful) so that the app is no longer in a debugging state. Debugging a new app (or reconnecting to a previous one) will create new fronts anyway.
* Slightly refactored the TabClient, ThreadClient, SourceClient and TracerClient towards a protocol.js-based architecture, by adding parent-child references and lifecycle management. Now a tab-scoped thread actor for instance has the tab as its parent, while a global-scoped thread actor (chrome debugger) has the DebuggerCLient (RootFront) as its parent. This lets parents reference their children, so that caching in the target object can work. It also allowed me to move some methods from the DebuggerClient to the actual front that should be responsible, like reconfigureTab, reconfigureThread and attachThread. These methods now use DebuggerClient.requester, too.
* Added some error handling in the debugger client requester around "before" and "after" callbacks, which exposed some errors in tests that are now fixed.
* Fixed the state handling in the thread actor so that merely detaching from a thread doesn't put it in the exited state. This is the part that what was necessary for Firebug's use case.
* Properly loading tracer and webgl actors now on b2g.
2014-01-14 07:39:40 -08:00
|
|
|
this.target.client.attachTab(this.target.activeTab._actor, (response) => {
|
2013-12-18 01:34:49 -08:00
|
|
|
this._origJavascriptEnabled = response.javascriptEnabled;
|
|
|
|
this._origCacheEnabled = response.cacheEnabled;
|
|
|
|
|
|
|
|
this._populateDisableJSCheckbox();
|
|
|
|
this._populateDisableCacheCheckbox();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
_populateDisableJSCheckbox: function() {
|
|
|
|
let cbx = this.panelDoc.getElementById("devtools-disable-javascript");
|
|
|
|
cbx.checked = !this._origJavascriptEnabled;
|
|
|
|
},
|
|
|
|
|
|
|
|
_populateDisableCacheCheckbox: function() {
|
|
|
|
let cbx = this.panelDoc.getElementById("devtools-disable-cache");
|
|
|
|
cbx.checked = !this._origCacheEnabled;
|
2013-05-03 23:31:07 -07:00
|
|
|
},
|
|
|
|
|
2013-05-31 08:52:06 -07:00
|
|
|
/**
|
|
|
|
* Disables JavaScript for the currently loaded tab. We force a page refresh
|
|
|
|
* here because setting docShell.allowJavascript to true fails to block JS
|
|
|
|
* execution from event listeners added using addEventListener(), AJAX calls
|
|
|
|
* and timers. The page refresh prevents these things from being added in the
|
|
|
|
* first place.
|
|
|
|
*
|
|
|
|
* @param {Event} event
|
|
|
|
* The event sent by checking / unchecking the disable JS checkbox.
|
|
|
|
*/
|
|
|
|
_disableJSClicked: function(event) {
|
|
|
|
let checked = event.target.checked;
|
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
let options = {
|
|
|
|
"javascriptEnabled": !checked
|
|
|
|
};
|
|
|
|
|
Make the debugger frontend cope with an already connected target (bug 933212); r=jryans,fitzgen
* Made the DebuggerClient, which is actually the RootActor front, not consider one of the attached child fronts as "active". Since a single DebuggerClient (or RootFront) is kept around for the App Manager's lifetime, it makes sense to move the notion of "active" tab to the toolbox's target. As each toolbox gets destroyed, the fronts should be detaching from their actors (if they are stateful) so that the app is no longer in a debugging state. Debugging a new app (or reconnecting to a previous one) will create new fronts anyway.
* Slightly refactored the TabClient, ThreadClient, SourceClient and TracerClient towards a protocol.js-based architecture, by adding parent-child references and lifecycle management. Now a tab-scoped thread actor for instance has the tab as its parent, while a global-scoped thread actor (chrome debugger) has the DebuggerCLient (RootFront) as its parent. This lets parents reference their children, so that caching in the target object can work. It also allowed me to move some methods from the DebuggerClient to the actual front that should be responsible, like reconfigureTab, reconfigureThread and attachThread. These methods now use DebuggerClient.requester, too.
* Added some error handling in the debugger client requester around "before" and "after" callbacks, which exposed some errors in tests that are now fixed.
* Fixed the state handling in the thread actor so that merely detaching from a thread doesn't put it in the exited state. This is the part that what was necessary for Firebug's use case.
* Properly loading tracer and webgl actors now on b2g.
2014-01-14 07:39:40 -08:00
|
|
|
this.target.activeTab.reconfigure(options);
|
2013-12-18 01:34:49 -08:00
|
|
|
},
|
2013-12-17 02:58:21 -08:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
/**
|
|
|
|
* Disables the cache for the currently loaded tab.
|
|
|
|
*
|
|
|
|
* @param {Event} event
|
|
|
|
* The event sent by checking / unchecking the disable cache checkbox.
|
|
|
|
*/
|
|
|
|
_disableCacheClicked: function(event) {
|
|
|
|
let checked = event.target.checked;
|
|
|
|
|
|
|
|
let options = {
|
|
|
|
"cacheEnabled": !checked
|
|
|
|
};
|
|
|
|
|
Make the debugger frontend cope with an already connected target (bug 933212); r=jryans,fitzgen
* Made the DebuggerClient, which is actually the RootActor front, not consider one of the attached child fronts as "active". Since a single DebuggerClient (or RootFront) is kept around for the App Manager's lifetime, it makes sense to move the notion of "active" tab to the toolbox's target. As each toolbox gets destroyed, the fronts should be detaching from their actors (if they are stateful) so that the app is no longer in a debugging state. Debugging a new app (or reconnecting to a previous one) will create new fronts anyway.
* Slightly refactored the TabClient, ThreadClient, SourceClient and TracerClient towards a protocol.js-based architecture, by adding parent-child references and lifecycle management. Now a tab-scoped thread actor for instance has the tab as its parent, while a global-scoped thread actor (chrome debugger) has the DebuggerCLient (RootFront) as its parent. This lets parents reference their children, so that caching in the target object can work. It also allowed me to move some methods from the DebuggerClient to the actual front that should be responsible, like reconfigureTab, reconfigureThread and attachThread. These methods now use DebuggerClient.requester, too.
* Added some error handling in the debugger client requester around "before" and "after" callbacks, which exposed some errors in tests that are now fixed.
* Fixed the state handling in the thread actor so that merely detaching from a thread doesn't put it in the exited state. This is the part that what was necessary for Firebug's use case.
* Properly loading tracer and webgl actors now on b2g.
2014-01-14 07:39:40 -08:00
|
|
|
this.target.activeTab.reconfigure(options);
|
2013-12-17 04:58:55 -08:00
|
|
|
},
|
2013-12-17 02:58:21 -08:00
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
destroy: function() {
|
|
|
|
if (this.destroyPromise) {
|
|
|
|
return this.destroyPromise;
|
|
|
|
}
|
|
|
|
|
|
|
|
let deferred = promise.defer();
|
|
|
|
|
|
|
|
this.destroyPromise = deferred.promise;
|
|
|
|
|
2013-05-31 08:52:06 -07:00
|
|
|
let disableJSNode = this.panelDoc.getElementById("devtools-disable-javascript");
|
|
|
|
disableJSNode.removeEventListener("click", this._disableJSClicked, false);
|
|
|
|
|
2013-12-18 01:34:49 -08:00
|
|
|
let disableCacheNode = this.panelDoc.getElementById("devtools-disable-cache");
|
|
|
|
disableCacheNode.removeEventListener("click", this._disableCacheClicked, false);
|
|
|
|
|
|
|
|
this.panelWin = this.panelDoc = null;
|
|
|
|
this._disableJSClicked = this._disableCacheClicked = null;
|
|
|
|
|
|
|
|
// If the cache or JavaScript is disabled we need to revert them to their
|
|
|
|
// original values.
|
|
|
|
let options = {
|
|
|
|
"cacheEnabled": this._origCacheEnabled,
|
|
|
|
"javascriptEnabled": this._origJavascriptEnabled
|
|
|
|
};
|
Make the debugger frontend cope with an already connected target (bug 933212); r=jryans,fitzgen
* Made the DebuggerClient, which is actually the RootActor front, not consider one of the attached child fronts as "active". Since a single DebuggerClient (or RootFront) is kept around for the App Manager's lifetime, it makes sense to move the notion of "active" tab to the toolbox's target. As each toolbox gets destroyed, the fronts should be detaching from their actors (if they are stateful) so that the app is no longer in a debugging state. Debugging a new app (or reconnecting to a previous one) will create new fronts anyway.
* Slightly refactored the TabClient, ThreadClient, SourceClient and TracerClient towards a protocol.js-based architecture, by adding parent-child references and lifecycle management. Now a tab-scoped thread actor for instance has the tab as its parent, while a global-scoped thread actor (chrome debugger) has the DebuggerCLient (RootFront) as its parent. This lets parents reference their children, so that caching in the target object can work. It also allowed me to move some methods from the DebuggerClient to the actual front that should be responsible, like reconfigureTab, reconfigureThread and attachThread. These methods now use DebuggerClient.requester, too.
* Added some error handling in the debugger client requester around "before" and "after" callbacks, which exposed some errors in tests that are now fixed.
* Fixed the state handling in the thread actor so that merely detaching from a thread doesn't put it in the exited state. This is the part that what was necessary for Firebug's use case.
* Properly loading tracer and webgl actors now on b2g.
2014-01-14 07:39:40 -08:00
|
|
|
this.target.activeTab.reconfigure(options, () => {
|
2013-12-18 01:34:49 -08:00
|
|
|
this.toolbox = null;
|
|
|
|
deferred.resolve();
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
return deferred.promise;
|
2013-05-03 23:31:07 -07:00
|
|
|
}
|
|
|
|
};
|