OpenClose

Opening and Closing Popups

Popups and menus may be opened and closed by a script.

Opening Menus

Menus will display themselves automatically when needed without extra work. For instance, a menu's popup will open when the menu label is clicked, and a submenu will open when the mouse is hovered over the parent menu element.

However, there may be situations when you wish to open a menu manually. The menu element has an open property which may be set to true to open the menu, or false to close the menu. A simple example:

somemenu.open = true;

This single line of code will open a menu referenced by the variable 'somemenu'. Note that the open property applies to the menu or button, not to the menupopup. Here is a complete example which uses a button to open a menu:

<button label="Open Menu"
        oncommand="document.getElementById('editMenu').open = true;"/>

<menu id="editMenu" label="Edit">
  <menupopup>
    <menuitem label="Cut"/>
    <menuitem label="Copy"/>
    <menuitem label="Paste"/>
  </menupopup>
</menu>

This technique may be used for both menupopups that use the menu tag, the button tag and the toolbarbutton tag. For menupopups attached to other elements using the popup or context attributes, see Opening a Popup below.

As with other ways of opening a menu, the popupshowing event will be fired to provide an opportunity to customize the commands that appear on the menu.

There are several situations when opening a menu is not allowed. These are:

  • if the menu is already open, or already in the process of being opened. Naturally, attempting to open a menu that is already open doesn't have any effect.
  • if the menu is a child of another menu and the parent menu is not open. In this case, the parent menu must be opened first. If you do want to open a submenu, open the parent menu first, and then open the child menu in a popupshown event listener. See The popupshown event for an example of how to do this.
  • a menu in an unprivileged content window (such as a web page) can only open a popup while its window is focused, and it is in the currently active tab. That means that a document in a background tab cannot open a menu or popup.

Closing Menus

Menus will close automatically once the user has made a selection from the menu. When an menu item is selected, it fires a command event so that code may be used to perform an action. The user may cancel selecting a command from a menu by pressing the Escape key. This will close a single menu, but if this menu has a parent menu, the parent menu will remain open. A user may also cancel selecting from a menu by clicking outside the menu. In this case, not only will that menu close, but all parent menus will close as well.

A menu may be closed by a script by setting the open property to false, the reverse of what would be done to open the menu. The open property applies to the menu or button, not to the menupopup.

somemenu.open = false;

This command will close only a single level of menus, so any parent menus will need to be closed with a similar command if desired. However, any child menus of 'somemenu' in the example will be closed, as 'somemenu' will no longer be open. For instance, let's say that a File menu has a submenu containing a list of recent files. If both menus are open and the open property on the submenu is set to false, the submenu will close, yet the parent File menu will remain open. On the other hand, if the open property on the File menu is set to false, both menus will close.

This technique may be used for both menupopups that use the menu tag, the button tag and the toolbarbutton tag. For menupopups attached to other elements using the popup or context attributes, see Closing a Popup below.

When a menu is closed, the popuphiding event is fired at the menupopup. Attaching an event listener which listens for the popuphiding event can be used to remove any commands that were adding during the popupshowing event.

Menus and popups are also closed when the document or window they are contained within is closed, or if the menupopup element is removed from the document. These are situations when the popuphiding or popuphidden events may not fire as the element the events would be fired on are no longer available. If you need to perform uninitialization that would be done during these events, this could be done during an unload event.

Testing Menu Open State

To check if a menu is open, check the state of the menu's open property. If the open property is set to true, then the menu is open, otherwise the menu is closed.

var open = somemenu.open;

Opening a Popup

For opening menupopups that use the menu tag, the button tag and the toolbarbutton tag, see Opening Menus above.

Popups attached using the popup attribute will be opened when the user clicks the mouse with the left mouse button. There isn't a means of replicating this action with the keyboard, so you should always provide an alternate means of accessing the functionality of the menu. This can be done by either placing alternate commands elsewhere in the user interface, or by providing a keyboard shortcut to open the menu. Once the menu is open, the keyboard can be used to navigate and select items as usual.

Popups attached using the context attribute are opened when the user performs an action that attempts to open a context menu. This action will vary on each platform, but it general it involves clicking on the element with the right mouse button. On Macintosh systems with only one mouse button, a context menu may be opened by either holding down the mouse button or by pressing the Control key and clicking the mouse button. On Windows, the context menu can also be opened by pressing the menu key on the keyboard (the key on many keyboards next to Control with a menu image) or by pressing Shift+F10. For this reason, you should not assume that a user has used the mouse to open the context menu.

The openPopup method

Regardless of the type of popup, you may wish to open the popup programatically. To do this, use the popup's openPopup method. This method may be used for any type of popup, either a menupopup, a panel, or a tooltip, including ones that can be opened via other means, for instance, a popup attached via the context attribute.

The openPopup method takes six arguments which are used to specify how and where the popup should be positioned. These will be described below. The openPopup method is defined as follows:

void openPopup(in DOMElement anchorElement,
               in String position,
               in long x,
               in long y,
               in boolean isContextMenu,
               in boolean attributesOverride);

First an example:

somepopup.openPopup(anchor, "after_start", 0, 0, false, false);

This example will open a popup located just underneath another element referenced by 'anchor'. This emulates how a menu is opened, where 'anchor' is the menu element. It is possible to use the openPopup method with a menu, however, it is easier to just set the menu's open attribute to true, as that will handle the positioning of the menupopup for you. Note that while the open attribute applies to the parent menu or button, the openPopup method applies to the menupopup element.

The anchor of a popup is the element node that the popup is displayed next to. For instance, to have a popup appear next to a button, pass a reference to this button as the first argument to the openPopup method. In this next example, the popup is opened relative to the document element.

somepopup.openPopup(document.documentElement, "end_before", 0, 0, false, false);

The second argument to openPopup is the anchor position, which specifies which side of the anchor the popup is positioned on. For instance, the value 'end_before' as used in the above example, indicates to place the left edge of the popup along the right edge of the the anchor element, aligned along the top edge of both. This may be confusing to understand, so see Positioning a Popup which describes this process in more detail and provides images which show the possible values and how a popup would be aligned for each value.

The third and fourth arguments to openPopup are x and y offsets. After the popup is positioned, you can further position the popup by specifying non-zero values for these offsets. This allows the position of the popup to be precisely controlled while still being anchored to a specific element. You can use positive values to adjust the popup to the right or downwards and negative values to adjust the popup to the left or upwards.

In the following example, the popup is anchored below an element, yet is offset by 10 pixels to the right and 2 pixels upwards.

somepopup.openPopup(anchor, "after_start", 10, -2, false, false);

Note that the anchor and positioning only specifies the position when the popup is opened. If the anchor is moved or removed while the popup is open, the popup does not follow it. However, it is possible to move a popup while it is open, see Moving and Resizing a Popup.

The fifth argument to openPopup, isContextMenu, is a flag which indicates whether a popup is being opened as a context menu. Pass true if so, or false if not. It should be obvious from how you are calling openPopup what to set this argument to. Note that the same menu can be opened in either manner so this flag doesn't affect how the popup appears. What it does do is affect how the focus and highlighting of the menu is handled. As long as you pass the right value depending on the situation, it isn't too important to know the specifics of the difference between both cases.

However, you can see the effect of the flag when using the Firefox bookmarks. Try opening a submenu of a bookmark (a bookmark folder) and note how the highlighting still changes as the mouse is moved over other menus, and the submenu is closed when the mouse is moved away. Now try opening a context menu on the same bookmark and note how the other menus aren't affected by mouse movement. This difference is handled by the use of the isContextMenu flag.

Finally, the last argument to the openPopup method, attributesOverride indicates whether attributes placed on the popup element itself override the arguments supplied. This allows a popup to use specific positioning behaviour by using the position, left and top attributes instead. More details on these attributes can be found at Positioning a Popup.

Unanchored Popups with openPopup

If the first argument to the openPopup method is null, this creates an unanchored popup. In this case, the second argument, the position, is not used, so an empty string can be used. Here is an example:

somepopup.openPopup(null, "", 60, 50, false, false);

An unanchored popup uses the x and y offsets, in this case 60 and 50 as offsets from the edge of the window or frame. This way, a popup can be positioned relative to the window, rather than relative to a specific node. For example, you might wish to open a popup at the current mouse position when the mouse is clicked. Here is an example mouse click event listener:

function mouseClicked(event)
{
  var panel = document.getElementById("some-panel");
  panel.openPopup(null, "", event.clientX, event.clientY, false, false);
}
The openPopupAtScreen method

A second method, openPopupAtScreen, may be used to open up a popup and place it at a specific screen coordinate. In this case, the popup is not anchored to an element and just appears at a specific location specified by the x and y arguments to this method.

void openPopupAtScreen(in long x, in long y, in boolean isContextMenu);

The isContextMenu argument indicates that a context menu is being opened, and functions the same as the corresponding argument for the openPopup method. In the following example, the popup is opened at horizontal positon 100 and vertical position 200:

popup.openPopupAtScreen(100, 200, false);

Note that if the supplied coordinates would cause the popup to be partially or completely off screen, the popup will be moved such that it is fully visible, and may be resized if necessary.

Closing a Popup with the hidePopup method

A popup menu is closed by the user pressing the Escape key or by clicking somewhere outside the popup.

For closing menupopups that use the menu tag, the button tag and the toolbarbutton tag, see Closing Menus above.

To close a popup with a script, use the popup's hidePopup method. It takes no arguments.

popup.hidePopup();

Determining if a Popup is Open

For menus, you can check the open property of the menu, button or toolbarbutton. If true, the menu is open.

For other types of popups, the state property may be examined to determine whether a popup is open or not. This property is available for all types of popups, including menus, panels and tooltips. When a popup is closed, the state property has the value closed, whereas a popup that is visible has a value for the state property of open. This property is readonly and applies to the menupopup, panel or tooltip element.

The state property can also have two other values, used while a popup is transitioning from being closed to open and vice versa. When a popup is about to be shown, the state property has a value of showing while it has the value hiding when the popup is about to be hidden. The former will occur during the popupshowing event, while the latter will occur during the popuphiding event.

For example, you could use the state property to determine if a panel is already open. If the panel is open, you might want to avoid manipulating the user interface within the main window, as the user won't be directly interacting with it.