XUL:Popups: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
 
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
==How XUL Popups Work Now==
==Popups and Menus==


There are several typs of popups in XUL.
[[XUL:Popups:Issues|How Popups Work in 1.8]]


#Menus use a frame type of 'menu' (nsMenuFrame.cpp). Elements that use this type are <menu>, <menulist> and <button>, the latter when the type attribute is 'menu' or 'menu-button'. A <menupopup> is expected to be a child of this element.
==Menupopups==
#Attached popups use a popup or context attribute on an element to attach a <popup> to be opened when the mouse button is pressed. The popup attribute is used for normal clicking with the first button, and the context attribute is used for context clicking. The attribute should be set to the id of a <popup> or <menupopup> attribute within the same document.
#Tooltips are attached popups using the tooltip attribute set to a <tooltip> element. The tooltiptext attribute may also be used. This is similar except a default <tooltip> element is used. This default tooltip container can be specified by setting the default attribute to true on a <tooltip> element. In the absense of such an element, a default tooltip is automatically anonymously inserted into the document by the root XUL frame. Tooltips appear while the mouse is hovered over an element.


When a menu popup (the first type in the list above) needs to be opened, the layout code does a variety of initialization steps, and sends the poppshowing event. It then sets the menugenerated attribute on the popup element. Setting this attribute causes a style change, due to the following rule in xul.css:
The <menupopup> element is used for creating popup menus. Popup menus may contain menu-related elements such as <menu>, <menuitem> and <menuseparator>. The <menupopup> element creates a popup which provides special behaviour such that items on the menu highlight, open and close as necessary when they are hovered over. Keyboard navigation between items is provided. The cursor keys navigate between items and other characters may be used for accesskey navigation. In addition, when the mouse is clicked outside the popup, the entire chain of menus and submenus that are currently open is closed.


menupopup[menugenerated="true"],
There are two ways of use a menupopup, either a popup associated with a menu, or a standalone popup. The former should be a child of a <menu>, or an element with a resolved tag of menu. The latter is usually used for context menus and is attached to an element via either the popup or contextmenu attributes.
popup[menugenerated="true"],
tooltip[menugenerated="true"] {
  display: -moz-popup;
}


Without the attribute, the popup has a display of 'none'. With the menugenerated attribute set to true, the display of -moz-popup causes a popup frame (nsMenuPopupFrame.cpp) to be created.
<pre>
&lt;menupopup position="position"
          left="left"
          top="top"/&gt;
</pre>


One key is that a special case is used when the menugenerated attribute is changed, causing the style change to be done synchronously, rather than waiting for the normal asynchronous behaviour.
Possible values are listed below.
; ignorekeys : set to true to disable keyboard navigation on the menu. The default is false.
; left : the horizontal screen position of the menupopup. Should rarely be used.
; popupalign : (deprecated) the edge of the popup to anchor to the parent menu. Use position instead.
; popupanchor : (deprecated) the edge of the parent menu to anchor to. Use position instead.
; position : the alignment of the menupopup in relation to its parent menu.
; top : the vertical screen position of the menupopup. Should rarely be used.


However, just setting this attribute doesn't cause the popup to open. In order to do that, the popup has an attached 'view' which is shown and hidden as necessary. For menus, the view is made visible by the menu only once it is clear that the menu should be displayed. This is in contrast to the menugenerated attribute which is set regardless, even if the menu shouldn't be opened, for example, because the popupshowing event was cancelled. Thus, a popup frame is created even when no menu will be displayed.
The descriptions below are for a locale where the UI is displayed left to right and top to bottom. In this case, before is the top, after is the bottom, start is the left and end is the right. For right to left locales, start is the right and end is the left.


For non-menu types (attached popups and tooltips), a special element is inserted anonymously into the document by the root box which serves as a container for all of those popups. This is because popups need a parent in order to open. For menus, the menu, menulist or button serves as this parent. For other popups, the special popup container (nsPopupSetFrame.cpp) is used.
Possible values for the position attribute are:


Again, when opening the menu, the menugenerated attribute is set, causing a popup frame to be created. Note that is done by different code in nsPopupSetFrame.cpp. In this case, the popup set marks itself as dirty so that a reflow/relayout is needed. During layout, the view is marked as visible, showing the popup.
; before_start : the popup appears above the anchor, aligned on the left.
; before_end : the popup appears above the anchor, aligned on the right.
; after_start : the popup appears below the anchor, aligned on the left.
; after_end : the popup appears below the anchor, aligned on the right.
; start_before : the popup appears to the left of the anchor, aligned on the top.
; start_after : the popup appears to the left of the anchor, aligned on the bottom.
; end_before : the popup appears to the right of the anchor, aligned on the top.
; end_after : the popup appears to the right of the anchor, aligned on the bottom.
; overlap : the popup overlaps the anchor, with the topleft corners of both the anchor and popup aligned
; after_pointer : the popup appears with the top aligned with the bottom of the anchor, with the topleft corner of the popup at the horizontal position of the mouse pointer


The menugenerated attribute is not necessarly removed when the popup is closed. It appears that popups and tooltips do clear this attribute, but menus do not. Thus, the popup frame, and its children are still present. The only thing that makes the popup disappear is hiding the view.
The default value is overlap.


==Issues with Menus==
==Panels==


*code duplication between the two types of menus
==Tooltips==
*menus tend to be crashy due to the strange behaviour described above.
 
The usual way of using a tooltip is to use the tooltiptext attribute on an element. For example:
 
<pre>
  &lt;button label="Save" tooltiptext="Save all changes"/&gt;
</pre>
 
This will create a popup tooltip using the default tooltip appearance. For a custom tooltip, the tooltip attribute may be used instead. It should be set to the id of a &lt;tooltip&gt; element within the same document.
 
<pre>
  &lt;tooltip id="custom-tooltip"&gt;
    &lt;label="Save all changes"/&gt;
  &lt;tooltip&gt;
 
  &lt;button label="Save" tooltip="custom-tooltip"/&gt;
</pre>
 
Tooltips always appear just next to the mouse pointer.
 
==New Popup API==
 
<pre>
  /**
  * Open the popup relative to a specified node at a specific location.
  *
  * The popup may be either anchored to another node or opened freely.
  * To anchor a popup to a node, supply an anchor node and set the position
  * to a string indicating the manner in which the popup should be anchored.
  * Possible values for position are:
  *    before_start, before_end, after_start, after_end,
  *    start_before, start_after, end_before, end_after,
  *    overlap, after_pointer
  *
  * If the aAttributesOverride argument is true, the popupanchor, popupalign
  * and position attributes on the popup node override the position value
  * argument. If aAttributesOverride is false, the attributes are only used
  * if the values passed to this method are empty.
  *
  * For an anchored popup, the x and y arguments may be used to offset the
  * popup from its anchored position by some number, measured in pixels.
  *
  * Unanchored popups may be created by supplying null as the anchor node.
  * An unanchored popup appears at the position specified by x and y,
  * relative to the viewport of the document containing the popup node.
  *
  * @param anchorElement the node to anchor the popup to, may be null
  * @param position manner is which to anchor the popup to node
  * @param x horizontal offset
  * @param y vertical offset
  * @param isContextMenu true for context menus, false for other popups
  * @param attributesOverride true if popup node attributes override position
  */
  void openPopup(in nsIDOMElement anchorElement,
                in AString position,
                in long x, in long y,
                in boolean isContextMenu,
                in boolean attributesOverride);
 
  /**
  * Open the popup at a specific screen position specified by x and y. This
  * position may be adjusted if it would cause the popup to be off of the
  * screen.
  *
  * @param x horizontal screen position
  * @param y vertical screen position
  * @param isContextMenu true for context menus, false for other popups
  */
  void openPopupAtScreen(in long x, in long y, in isContextMenu);
 
  /**
  *  Hide the popup if it is open.
  */
  void hidePopup();
</pre>

Latest revision as of 21:23, 28 August 2006

Popups and Menus

How Popups Work in 1.8

Menupopups

The <menupopup> element is used for creating popup menus. Popup menus may contain menu-related elements such as <menu>, <menuitem> and <menuseparator>. The <menupopup> element creates a popup which provides special behaviour such that items on the menu highlight, open and close as necessary when they are hovered over. Keyboard navigation between items is provided. The cursor keys navigate between items and other characters may be used for accesskey navigation. In addition, when the mouse is clicked outside the popup, the entire chain of menus and submenus that are currently open is closed.

There are two ways of use a menupopup, either a popup associated with a menu, or a standalone popup. The former should be a child of a <menu>, or an element with a resolved tag of menu. The latter is usually used for context menus and is attached to an element via either the popup or contextmenu attributes.

<menupopup position="position"
           left="left"
           top="top"/>

Possible values are listed below.

ignorekeys
set to true to disable keyboard navigation on the menu. The default is false.
left
the horizontal screen position of the menupopup. Should rarely be used.
popupalign
(deprecated) the edge of the popup to anchor to the parent menu. Use position instead.
popupanchor
(deprecated) the edge of the parent menu to anchor to. Use position instead.
position
the alignment of the menupopup in relation to its parent menu.
top
the vertical screen position of the menupopup. Should rarely be used.

The descriptions below are for a locale where the UI is displayed left to right and top to bottom. In this case, before is the top, after is the bottom, start is the left and end is the right. For right to left locales, start is the right and end is the left.

Possible values for the position attribute are:

before_start
the popup appears above the anchor, aligned on the left.
before_end
the popup appears above the anchor, aligned on the right.
after_start
the popup appears below the anchor, aligned on the left.
after_end
the popup appears below the anchor, aligned on the right.
start_before
the popup appears to the left of the anchor, aligned on the top.
start_after
the popup appears to the left of the anchor, aligned on the bottom.
end_before
the popup appears to the right of the anchor, aligned on the top.
end_after
the popup appears to the right of the anchor, aligned on the bottom.
overlap
the popup overlaps the anchor, with the topleft corners of both the anchor and popup aligned
after_pointer
the popup appears with the top aligned with the bottom of the anchor, with the topleft corner of the popup at the horizontal position of the mouse pointer

The default value is overlap.

Panels

Tooltips

The usual way of using a tooltip is to use the tooltiptext attribute on an element. For example:

  <button label="Save" tooltiptext="Save all changes"/>

This will create a popup tooltip using the default tooltip appearance. For a custom tooltip, the tooltip attribute may be used instead. It should be set to the id of a <tooltip> element within the same document.

  <tooltip id="custom-tooltip">
    <label="Save all changes"/>
  <tooltip>

  <button label="Save" tooltip="custom-tooltip"/>

Tooltips always appear just next to the mouse pointer.

New Popup API

  /**
   * Open the popup relative to a specified node at a specific location.
   *
   * The popup may be either anchored to another node or opened freely.
   * To anchor a popup to a node, supply an anchor node and set the position
   * to a string indicating the manner in which the popup should be anchored.
   * Possible values for position are:
   *    before_start, before_end, after_start, after_end,
   *    start_before, start_after, end_before, end_after,
   *    overlap, after_pointer
   *
   * If the aAttributesOverride argument is true, the popupanchor, popupalign
   * and position attributes on the popup node override the position value
   * argument. If aAttributesOverride is false, the attributes are only used
   * if the values passed to this method are empty.
   *
   * For an anchored popup, the x and y arguments may be used to offset the 
   * popup from its anchored position by some number, measured in pixels.
   *
   * Unanchored popups may be created by supplying null as the anchor node.
   * An unanchored popup appears at the position specified by x and y,
   * relative to the viewport of the document containing the popup node.
   *
   * @param anchorElement the node to anchor the popup to, may be null
   * @param position manner is which to anchor the popup to node
   * @param x horizontal offset
   * @param y vertical offset
   * @param isContextMenu true for context menus, false for other popups
   * @param attributesOverride true if popup node attributes override position
   */
  void openPopup(in nsIDOMElement anchorElement,
                 in AString position,
                 in long x, in long y,
                 in boolean isContextMenu,
                 in boolean attributesOverride);

  /**
   * Open the popup at a specific screen position specified by x and y. This
   * position may be adjusted if it would cause the popup to be off of the
   * screen.
   *
   * @param x horizontal screen position
   * @param y vertical screen position
   * @param isContextMenu true for context menus, false for other popups
   */
  void openPopupAtScreen(in long x, in long y, in isContextMenu);

  /**
   *  Hide the popup if it is open.
   */
  void hidePopup();