node-menunav.js revision dcc27ab1cda56d7ad286e36c57f451db77894301
2400N/A* <p>The MenuNav Node Plugin makes it easy to transform existing list-based 2400N/A* markup into traditional, drop down navigational menus that are both accessible 2400N/A* and easy to customize, and only require a small set of dependencies.</p> 2400N/A* <p>To use the MenuNav Node Plugin, simply pass a reference to the plugin to a 2400N/A* Node instance's <code>plug</code> method.</p> 2400N/A* // Call the "use" method, passing in "node-menunav". This will <br> 2400N/A* // load the script and CSS for the MenuNav Node Plugin and all of <br> 2400N/A* // the required dependencies. <br> 2400N/A* YUI().use("node-menunav", function(Y) { <br> 2400N/A* // Use the "contentready" event to initialize the menu when <br> 3817N/A* // the subtree of element representing the root menu <br> 2400N/A* // (<div id="menu-1">) is ready to be scripted. <br> 2400N/A* Y.on("contentready", function () { <br> 3998N/A* // The scope of the callback will be a Node instance <br> 2400N/A* // representing the root menu (<div id="menu-1">). <br> 2400N/A* // Therefore, since "this" represents a Node instance, it <br> 2400N/A* // is possible to just call "this.plug" passing in a <br> 3998N/A* // reference to the MenuNav Node Plugin. <br> 2400N/A* this.plug(Y.Plugin.NodeMenuNav); <br> 2400N/A* <p>The MenuNav Node Plugin has several configuration properties that can be 2400N/A* set via an object literal that is passed as a second argument to a Node 2400N/A* instance's <code>plug</code> method. 2400N/A* // Call the "use" method, passing in "node-menunav". This will <br> 2400N/A* // load the script and CSS for the MenuNav Node Plugin and all of <br> 2400N/A* // the required dependencies. <br> 4337N/A* YUI().use("node-menunav", function(Y) { <br> 3817N/A* // Use the "contentready" event to initialize the menu when <br> 3817N/A* // the subtree of element representing the root menu <br> 3817N/A* // (<div id="menu-1">) is ready to be scripted. <br> * Y.on("contentready", function () { <br> * // The scope of the callback will be a Node instance <br> * // representing the root menu (<div id="menu-1">). <br> * // Therefore, since "this" represents a Node instance, it <br> * // is possible to just call "this.plug" passing in a <br> * // reference to the MenuNav Node Plugin. <br> * this.plug(Y.Plugin.NodeMenuNav, { mouseOutHideDelay: 1000 }); // Frequently used strings EXTENDED_QUERY =
">.yui-menu-content>ul>li>.yui-menu-label>a:first-child",
// TO DO: Remove once Node implements circular functionality // TO DO: Remove once Node implements circular functionality * The NodeMenuNav class is a plugin for a Node instance. The class is used via * the <a href="Node.html#method_plug"><code>plug</code></a> method of Node and * should not be instantiated directly. * @property NodeMenuNav.SHIM_TEMPLATE_TITLE * @description String representing the value for the <code>title</code> * attribute for the shim used to prevent <code><select></code> elements * from poking through menus in IE 6. * @default "Menu Stacking Shim" * @property NodeMenuNav.SHIM_TEMPLATE * @description String representing the HTML used to create the * <code><iframe></code> shim used to prevent * <code><select></code> elements from poking through menus in IE 6. * @default "<iframe frameborder="0" tabindex="-1" * class="yui-shim" title="Menu Stacking Shim" * src="javascript:false;"></iframe>" // 1) Need to set the "frameBorder" property to 0 to suppress the default // <iframe> border in IE. (Setting the CSS "border" property alone doesn't // 2) The "src" attribute of the <iframe> is set to "javascript:false;" so // warning in IE when using HTTPS. // 3) Since the role of the <iframe> shim is completely presentational, its // "tabindex" attribute is set to "-1" and its title attribute is set to // "Menu Stacking Shim". Both strategies help users of screen readers to // avoid mistakenly interacting with the <iframe> shim. '" src="javascript:false;"></iframe>';
* Boolean indicating if use of the WAI-ARIA Roles and States should be * enabled for the NodeMenuNav. * Boolean indicating if submenus are automatically made visible when the * user mouses over the menu's items. * @attribute autoSubmenuDisplay * Number indicating the time (in milliseconds) that should expire before a * submenu is made visible when the user mouses over the menu's label. * @attribute submenuShowDelay * Number indicating the time (in milliseconds) that should expire before a * submenu is hidden when the user mouses out of a menu label heading in the * direction of a submenu. * @attribute submenuHideDelay * Number indicating the time (in milliseconds) that should expire before a * submenu is hidden when the user mouses out of it. * @attribute mouseOutHideDelay * @description Node instance representing the root menu in the NodeMenuNav. * @description Node instance representing the NodeMenuNav's active descendent: * the menuitem or menu label the user is currently interacting with. * @description Node instance representing the menu that is the parent of * the NodeMenuNav's active descendent. * @description Boolean indicating if the NodeMenuNav has focus. // In gecko-based browsers a mouseover and mouseout event will fire even // if a DOM element moves out from under the mouse without the user // actually moving the mouse. This bug affects NodeMenuNav because the user // can hit the Esc key to hide a menu, and if the mouse is over the menu // when the user presses Esc, the _onMenuMouseOut handler will be called. // To fix this bug the following flag (_blockMouseEvent) is used to block // the code in the _onMenuMouseOut handler from executing. * @property _blockMouseEvent * @description Boolean indicating whether or not to handle the * @property _currentMouseX * @description Number representing the current x coordinate of the mouse * inside the NodeMenuNav. * @property _movingToSubmenu * @description Boolean indicating if the mouse is moving from a menu * label to its corresponding submenu. * @property _showSubmenuTimer * @description Timer used to show a submenu. * @property _hideSubmenuTimer * @description Timer used to hide a submenu. * @property _hideAllSubmenusTimer * @description Timer used to hide a all submenus. * @description Node instance representing the first item (menuitem or menu * label) in the root menu of a NodeMenuNav. * @description Returns a boolean indicating if the specified menu is the * root menu in the NodeMenuNav. * @param {Node} menu Node instance representing a menu. * @return {Boolean} Boolean indicating if the specified menu is the root * menu in the NodeMenuNav. * @method _getTopmostSubmenu * @description Returns the topmost submenu of a submenu hierarchy. * @param {Node} menu Node instance representing a menu. * @return {Node} Node instance representing a menu. * @method _clearActiveItem * @description Clears the NodeMenuNav's active descendent. * @description Sets the specified menuitem or menu label as the NodeMenuNav's * @param {Node} item Node instance representing a menuitem or menu label. * @description Focuses the specified menuitem or menu label. * @param {Node} item Node instance representing a menuitem or menu label. * @description Shows the specified menu. * @param {Node} menu Node instance representing a menu. // Clear previous values for height and width // Set the width and height of the menu's bounding box - this is // necessary for IE 6 so that the CSS for the <iframe> shim can // simply set the <iframe>'s width and height to 100% to ensure // that dimensions of an <iframe> shim are always sync'd to the // that of its parent menu. Specifying a width and height also // helps when positioning decorator elements (for creating effects // like rounded corners) inside a menu's bounding box in IE 7. * @description Hides the specified menu. * @param {Node} menu Node instance representing a menu. * @param {Boolean} activateAndFocusLabel Boolean indicating if the label * menu should be focused and set as active. // Clear the values for top and left that were set by the call to // "setXY" when the menu was shown so that the hidden position // specified in the core CSS file will take affect. * @method _hideAllSubmenus * @description Hides all submenus of the specified menu. * @param {Node} menu Node instance representing a menu. * @method _cancelShowSubmenuTimer * @description Cancels the timer used to show a submenu. * @method _cancelHideSubmenuTimer * @description Cancels the timer used to hide a submenu. // Event handlers for discrete pieces of pieces of the menu else {
// The root menu, or one of its submenus has lost focus * @method _onMenuMouseOver * @description "mouseover" event handler for a menu. * @param {Node} menu Node instance representing a menu. * @param {Object} event Object representing the DOM event. // Need to update the FocusManager in advance of focus a new // Menu in order to avoid the FocusManager thinking that * @method _hideAndFocusLabel * @description Hides all of the submenus of the root menu and focuses the * label of the topmost submenu // Focus the label element for the topmost submenu * @method _onMenuMouseOut * @description "mouseout" event handler for a menu. * @param {Node} menu Node instance representing a menu. * @param {Object} event Object representing the DOM event. * @method _onMenuLabelMouseOver * @description "mouseover" event handler for a menu label. * @param {Node} menuLabel Node instance representing a menu label. * @param {Object} event Object representing the DOM event. * @method _onMenuLabelMouseOut * @description "mouseout" event handler for a menu label. * @param {Node} menuLabel Node instance representing a menu label. * @param {Object} event Object representing the DOM event. // If the mouse is moving diagonally toward the submenu and // another submenu isn't in the process of being displayed // (via a timer), then hide the submenu via a timer to give // the user some time to reach the submenu. // If the mouse is not moving toward the submenu, cancel any // submenus that might be in the process of being displayed // (via a timer) and hide this submenu immediately. * @method _onMenuItemMouseOver * @description "mouseover" event handler for a menuitem. * @param {Node} menuItem Node instance representing a menuitem. * @param {Object} event Object representing the DOM event. * @method _onMenuItemMouseOut * @description "mouseout" event handler for a menuitem. * @param {Node} menuItem Node instance representing a menuitem. * @param {Object} event Object representing the DOM event. * @method _onVerticalMenuKeyDown * @description "keydown" event handler for vertical menus of a NodeMenuNav. * @param {Object} event Object representing the DOM event. // Prevent the browser from scrolling the window * @method _onHorizontalMenuKeyDown * @description "keydown" event handler for horizontal menus of a NodeMenuNav. * @param {Object} event Object representing the DOM event. // Prevent the browser from scrolling the window // Generic DOM Event handlers * @description "mousemove" event handler for the NodeMenuNav. * @param {Object} event Object representing the DOM event. // Using a timer to set the value of the "_currentMouseX" property // helps improve the reliability of the calculation used to set the // value of the "_movingToSubmenu" property - especially in Opera. * @description "mouseover" event handler for the NodeMenuNav. * @param {Object} event Object representing the DOM event. * @description "mouseout" event handler for the NodeMenuNav. * @param {Object} event Object representing the DOM event. * @method _toggleSubmenuDisplay * @description "mousedown," "keydown," and "click" event handler for the * NodeMenuNav used to toggle the display of a submenu. * @param {Object} event Object representing the DOM event. // Need to pass "2" as a second argument to "getAttribute" for // IE otherwise IE will return a fully qualified URL for the // value of the "href" attribute. // Prevent the target from getting focused by // default, since the element to be focused will // be determined by weather or not the submenu // For Webkit--By default FocusManager will try // to focus one of its descendants onMouseDown // since Webkit doesn't do that by default. Since // we want to explicitly control where focus is // going, we need to call // "stopImmediatePropagation" to stop the // FocusManager from doing its thing. // The "_focusItem" method relies on the // "_hasFocus" property being set to true. The // "_hasFocus" property is normally set via a // "focus" event listener, but since we've // blocked focus from happening, we need to set // this property manually. // Prevent the browser from following the URL of * @description "keypress" event handler for the NodeMenuNav. * @param {Object} event Object representing the DOM event. // Prevent the browser from scrolling the window * @description "keydown" event handler for the NodeMenuNav. * @param {Object} event Object representing the DOM event. * @method _onDocMouseDown * @description "mousedown" event handler for the owner document of * @param {Object} event Object representing the DOM event. // Hide all visible submenus // Wire up all event handlers },
'@VERSION@' ,{
requires:[
'node',
'classnamemanager',
'node-focusmanager']});