Bug 1398734 - Fix devtools toolbox issues while removing extension sidebar panels. r=jdescottes

Depends on D5421

Differential Revision: https://phabricator.services.mozilla.com/D5422

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2018-10-03 18:29:30 +00:00
Родитель c0768c8f7c
Коммит 27d0727740
4 изменённых файлов: 50 добавлений и 8 удалений

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

@ -1628,6 +1628,13 @@ Toolbox.prototype = {
* An unique sidebar id
*/
unregisterInspectorExtensionSidebar(id) {
// Unregister the sidebar from the toolbox if the toolbox is not already
// being destroyed (otherwise we would trigger a re-rendering of the
// inspector sidebar tabs while the toolbox is going away).
if (this._destroyer) {
return;
}
const sidebarDef = this._inspectorExtensionSidebars.get(id);
if (!sidebarDef) {
return;
@ -2811,6 +2818,12 @@ Toolbox.prototype = {
return this._destroyer;
}
this._destroyer = this._destroyToolbox();
return this._destroyer;
},
_destroyToolbox: async function() {
this.emit("destroy");
this._target.off("inspect-object", this._onInspectObject);
@ -2929,7 +2942,7 @@ Toolbox.prototype = {
// Finish all outstanding tasks (which means finish destroying panels and
// then destroying the host, successfully or not) before destroying the
// target.
this._destroyer = new Promise(resolve => {
const onceDestroyed = new Promise(resolve => {
resolve(settleAll(outstanding)
.catch(console.error)
.then(() => {
@ -2985,16 +2998,15 @@ Toolbox.prototype = {
const leakCheckObserver = ({wrappedJSObject: barrier}) => {
// Make the leak detector wait until this toolbox is properly destroyed.
barrier.client.addBlocker("DevTools: Wait until toolbox is destroyed",
this._destroyer);
onceDestroyed);
};
const topic = "shutdown-leaks-before-check";
Services.obs.addObserver(leakCheckObserver, topic);
this._destroyer.then(() => {
Services.obs.removeObserver(leakCheckObserver, topic);
});
return this._destroyer;
await onceDestroyed;
Services.obs.removeObserver(leakCheckObserver, topic);
},
_highlighterReady: function() {

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

@ -266,3 +266,29 @@ add_task(async function teardownExtensionSidebar() {
inspector = null;
extension = null;
});
add_task(async function testActiveTabOnNonExistingSidebar() {
// Set a fake non existing sidebar id in the activeSidebar pref,
// to simulate the scenario where an extension has installed a sidebar
// which has been saved in the preference but it doesn't exist anymore.
await SpecialPowers.pushPrefEnv({
set: [["devtools.inspector.activeSidebar"], "unexisting-sidebar-id"],
});
const res = await openInspectorForURL("about:blank");
inspector = res.inspector;
toolbox = res.toolbox;
const onceSidebarCreated = toolbox.once(`extension-sidebar-created-${SIDEBAR_ID}`);
toolbox.registerInspectorExtensionSidebar(SIDEBAR_ID, {title: SIDEBAR_TITLE});
// Wait the extension sidebar to be created and then unregister it to force the tabbar
// to select a new one.
await onceSidebarCreated;
toolbox.unregisterInspectorExtensionSidebar(SIDEBAR_ID);
is(inspector.sidebar.getCurrentTabID(), "layoutview",
"Got the expected inspector sidebar tab selected");
await SpecialPowers.popPrefEnv();
});

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

@ -894,6 +894,8 @@ Inspector.prototype = {
hideTabstripe: true
});
// defaultTab may also be an empty string or a tab id that doesn't exist anymore
// (e.g. it was a tab registered by an addon that has been uninstalled).
let defaultTab = Services.prefs.getCharPref("devtools.inspector.activeSidebar");
if (this.is3PaneModeEnabled && defaultTab === "ruleview") {

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

@ -139,8 +139,10 @@ class Tabbar extends Component {
}
const tabs = this.state.tabs.slice();
let activeId;
let activeTab;
// Preselect the first sidebar tab if none was explicitly selected.
let activeTab = 0;
let activeId = this.queuedTabs[0].id;
for (const { id, index, panel, selected, title, url } of this.queuedTabs) {
if (index >= 0) {