I'm developing a Firefox extension, and I have a toolbar button that displays an overlay in which I put some XUL code inside ToolbarDisplayManager
:
<overlay id="custombutton-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="boycottToolbarButton" label="Label" tooltiptext="Label" type="menu" popup="ToolbarPopup" />
</toolbarpalette>
<popupset>
<panel id="ToolbarPopup" position="after_start" onpopupshowing="Refresh();">
<vbox class="ToolbarBody">
<box id="ToolbarDisplayManager" />
</vbox>
</panel>
</popupset>
</overlay>
Inside "ToolbarDisplayManager" I create a menulist with a menupopup with javascript (like a "combobox") with this structure:
<menulist id="combo">
<menupopup>
<menuitem>
<menuitem>
...
</menupopup>
</menulist>
Here's the problem:
When I click ToolbarPopup
I run a "Refresh" function in the popupshowing
event. But when the overlay is displayed, and I click on the "combo" to select an item, the popupshowing
event of ToolbarPopup
is fired again.
In other words: it's like the two "popups" are having troubles with each other.
I need to run the "Refresh" function just before the overlay is shown. Is my structure wrong somewhere? How do I handle two nested popups and their popupshowing
events?
The popupshowing
event bubbles up meaning that it can be intercepted by event handlers higher in the DOM hierarchy than the element triggering the event. So your event handler first receives the popupshowing
event from the <panel>
and later another one from the <menulist>
element (because it is located inside the <panel>
). You can easily distinguish the two cases using the event.eventPhase
property:
<panel ... onpopupshowing="if (event.eventPhase == Event.AT_TARGET) Refresh();">
This will make sure that you ignore events bubbling up and only call Refresh()
for events that originated in the <panel>
itself. The other option would have been looking at the event.target
property.