I am using the Tool
API to add a panel to Firefox DevTools.
I can define setup()
and dispose()
methods to handle initialization and teardown.
However I can’t figure out how to determine whether the panel is currently visible, or when it changes visibility. Is this event exposed somewhere?
To be clear, I only want to know that for my panel. So I want to know when my panel becomes visible, or when the user switches away to e.g. the Elements tab.
The dev/panel
API does not expose a method for you to be notified when the visibility of your panel changes. However, you can go around the API and be informed that the visibility has changed.
The code below calls the function panelVisibilityChangedState
when the visibility changes of the panel created by the extension within the Developer Tools Toolbox. As requested, this is only the state of the panel added by the extension. This add-on was tested while running multiprocess Firefox Developer Edition, version 50.0a2.
This code is based on the MDN repl-panel example available on GitHub.
main.js:
//This code is based on the MDN Dev Tools panel example available at:
// https://github.com/mdn/repl-panel
//Require the needed SDK modules
const { Panel } = require("dev/panel");
const { Tool } = require("dev/toolbox");
const { Class } = require("sdk/core/heritage");
const self = require("sdk/self");
var myRadio;
var devToolsToolbar;
var devToolsToolboxTabs;
var pickerContainer;
var panelIsVisible=false;
function panelVisibilityChangedState(isVisible){
//This function may be called slightly before the state change actually occurs.
panelIsVisible=isVisible;
console.log('Dev Tools Panel Changed State: visibility is now: ' + isVisible );
}
function devToolsClickHandler(event){
//The event fires before the value of the 'selected' attribute changes in response to
// this click, except when the event fires on the pick element. In that case, the
// 'selected' attribute is accurately 'false'.
let isSelected = myRadio.getAttribute('selected') === 'true';
let pickElementContains = pickerContainer.contains(event.target);
if(!devToolsToolboxTabs.contains(event.target) && !pickElementContains){
//Of the controls not in the devToolsToolboxTabs, only the pickElement changes
// the state of this panel being shown. The exception to this is the close
// button, but closing is detected via the panel's dispose method.
return;
}//else
let doesContain = myRadio.contains(event.target);
if((pickElementContains && panelIsVisible)
|| (doesContain && !isSelected) || (!doesContain && isSelected)) {
panelVisibilityChangedState(doesContain);
}
}
//Define a REPLPanel class that inherits from dev/panel
const REPLPanel = Class({
extends: Panel,
label: "Visi",
tooltip: "Demo Dev Tool Panel Visibility Notification",
icon: self.data.url("noIcon.png"),
url: self.data.url("blank-panel.html"),
setup: function(options) {
//Remember the button which was clicked to open this panel (actually a <radio>)
myRadio = require("sdk/window/utils").getFocusedElement()
//For convenience and to speed up the event handler, remember three elements.
// Obtain these elements using IDs, or unique class when no ID is available.
// This should be a bit more stable than using the location in the DOM
// relative to myRadio.
devToolsToolbar = myRadio.ownerDocument.querySelector('.devtools-tabbar');
//An alternate method of finding the Dev Tools toolbar:
//devToolsToolbar = myRadio.ownerDocument.getElementById('toolbox-tabs').parentNode;
//Another alternate method of finding the Dev Tools toolbar:
//devToolsToolbar = myRadio.parentNode.parentNode;
devToolsToolboxTabs = devToolsToolbar.querySelector('#toolbox-tabs');
pickerContainer = devToolsToolbar.querySelector('#toolbox-picker-container');
devToolsToolbar.addEventListener('click',devToolsClickHandler,false);
},
dispose: function() {
//Dev Tools panel is destroyed. Visibility is, obviously, false
if(panelIsVisible){
panelVisibilityChangedState(false);
}
},
onReady: function() {
//The panel is now visible and ready. If desired, this call to
// panelVisibilityChangedState could be placed in the 'setup' function.
panelVisibilityChangedState(true);
}
});
exports.REPLPanel = REPLPanel;
//Create a new tool, initialized with the REPLPanel's constructor
const replTool = new Tool({
panels: { repl: REPLPanel }
});
data/blank-panel.html:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
This is a blank panel
</body>
</html>
package.json:
{
"name": "dev-panel-visibility-notification",
"title": "dev-panel-visibility-notification",
"id": "dev-panel-visibility-notification@example",
"description": "Demonstrates calling a function when the visibillity of the add-on's Dev Tools panel changes.",
"author": "Makyen",
"license": "MPL 2.0",
"version": "0.1.0",
"main": "main.js"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With