/*
YUI 3.17.2 (build 9c3c78e)
Copyright 2014 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
http://yuilibrary.com/license/
*/
YUI.add('node-menunav', function (Y, NAME) {
/**
*
The MenuNav Node Plugin makes it easy to transform existing list-based
* markup into traditional, drop down navigational menus that are both accessible
* and easy to customize, and only require a small set of dependencies.
*
*
* To use the MenuNav Node Plugin, simply pass a reference to the plugin to a
* Node instance's plug
method.
*
*
*
* <script type="text/javascript">
*
* // Call the "use" method, passing in "node-menunav". This will
* // load the script and CSS for the MenuNav Node Plugin and all of
* // the required dependencies.
*
* YUI().use("node-menunav", function(Y) {
*
* // Use the "contentready" event to initialize the menu when
* // the subtree of element representing the root menu
* // (<div id="menu-1">) is ready to be scripted.
*
* Y.on("contentready", function () {
*
* // The scope of the callback will be a Node instance
* // representing the root menu (<div id="menu-1">).
* // Therefore, since "this" represents a Node instance, it
* // is possible to just call "this.plug" passing in a
* // reference to the MenuNav Node Plugin.
*
* this.plug(Y.Plugin.NodeMenuNav);
*
* }, "#menu-1");
*
* });
*
* </script>
*
*
*
* The MenuNav Node Plugin has several configuration properties that can be
* set via an object literal that is passed as a second argument to a Node
* instance's plug
method.
*
*
*
*
* <script type="text/javascript">
*
* // Call the "use" method, passing in "node-menunav". This will
* // load the script and CSS for the MenuNav Node Plugin and all of
* // the required dependencies.
*
* YUI().use("node-menunav", function(Y) {
*
* // Use the "contentready" event to initialize the menu when
* // the subtree of element representing the root menu
* // (<div id="menu-1">) is ready to be scripted.
*
* Y.on("contentready", function () {
*
* // The scope of the callback will be a Node instance
* // representing the root menu (<div id="menu-1">).
* // Therefore, since "this" represents a Node instance, it
* // is possible to just call "this.plug" passing in a
* // reference to the MenuNav Node Plugin.
*
* this.plug(Y.Plugin.NodeMenuNav, { mouseOutHideDelay: 1000 });
*
* }, "#menu-1");
*
* });
*
* </script>
*
*
*
DEPRECATED. The MenuNav Node Plugin has been deprecated as of YUI 3.9.0. This module will be removed from the library in a future version. If you require functionality similar to the one provided by this module, consider taking a look at the various modules in the YUI Gallery .
@module node-menunav
@deprecated 3.9.0
*/
// Util shortcuts
var UA = Y.UA,
later = Y.later,
getClassName = Y.ClassNameManager.getClassName,
// Frequently used strings
MENU = "menu",
MENUITEM = "menuitem",
HIDDEN = "hidden",
PARENT_NODE = "parentNode",
CHILDREN = "children",
OFFSET_HEIGHT = "offsetHeight",
OFFSET_WIDTH = "offsetWidth",
PX = "px",
ID = "id",
PERIOD = ".",
HANDLED_MOUSEOUT = "handledMouseOut",
HANDLED_MOUSEOVER = "handledMouseOver",
ACTIVE = "active",
LABEL = "label",
LOWERCASE_A = "a",
MOUSEDOWN = "mousedown",
KEYDOWN = "keydown",
CLICK = "click",
EMPTY_STRING = "",
FIRST_OF_TYPE = "first-of-type",
ROLE = "role",
PRESENTATION = "presentation",
DESCENDANTS = "descendants",
UI = "UI",
ACTIVE_DESCENDANT = "activeDescendant",
USE_ARIA = "useARIA",
ARIA_HIDDEN = "aria-hidden",
CONTENT = "content",
HOST = "host",
ACTIVE_DESCENDANT_CHANGE = ACTIVE_DESCENDANT + "Change",
// Attribute keys
AUTO_SUBMENU_DISPLAY = "autoSubmenuDisplay",
MOUSEOUT_HIDE_DELAY = "mouseOutHideDelay",
// CSS class names
CSS_MENU = getClassName(MENU),
CSS_MENU_HIDDEN = getClassName(MENU, HIDDEN),
CSS_MENU_HORIZONTAL = getClassName(MENU, "horizontal"),
CSS_MENU_LABEL = getClassName(MENU, LABEL),
CSS_MENU_LABEL_ACTIVE = getClassName(MENU, LABEL, ACTIVE),
CSS_MENU_LABEL_MENUVISIBLE = getClassName(MENU, LABEL, (MENU + "visible")),
CSS_MENUITEM = getClassName(MENUITEM),
CSS_MENUITEM_ACTIVE = getClassName(MENUITEM, ACTIVE),
// CSS selectors
MENU_SELECTOR = PERIOD + CSS_MENU,
MENU_TOGGLE_SELECTOR = (PERIOD + getClassName(MENU, "toggle")),
MENU_CONTENT_SELECTOR = PERIOD + getClassName(MENU, CONTENT),
MENU_LABEL_SELECTOR = PERIOD + CSS_MENU_LABEL,
STANDARD_QUERY = ">" + MENU_CONTENT_SELECTOR + ">ul>li>a",
EXTENDED_QUERY = ">" + MENU_CONTENT_SELECTOR + ">ul>li>" + MENU_LABEL_SELECTOR + ">a:first-child";
// Utility functions
var getPreviousSibling = function (node) {
var oPrevious = node.previous(),
oChildren;
if (!oPrevious) {
oChildren = node.get(PARENT_NODE).get(CHILDREN);
oPrevious = oChildren.item(oChildren.size() - 1);
}
return oPrevious;
};
var getNextSibling = function (node) {
var oNext = node.next();
if (!oNext) {
oNext = node.get(PARENT_NODE).get(CHILDREN).item(0);
}
return oNext;
};
var isAnchor = function (node) {
var bReturnVal = false;
if (node) {
bReturnVal = node.get("nodeName").toLowerCase() === LOWERCASE_A;
}
return bReturnVal;
};
var isMenuItem = function (node) {
return node.hasClass(CSS_MENUITEM);
};
var isMenuLabel = function (node) {
return node.hasClass(CSS_MENU_LABEL);
};
var isHorizontalMenu = function (menu) {
return menu.hasClass(CSS_MENU_HORIZONTAL);
};
var hasVisibleSubmenu = function (menuLabel) {
return menuLabel.hasClass(CSS_MENU_LABEL_MENUVISIBLE);
};
var getItemAnchor = function (node) {
return isAnchor(node) ? node : node.one(LOWERCASE_A);
};
var getNodeWithClass = function (node, className, searchAncestors) {
var oItem;
if (node) {
if (node.hasClass(className)) {
oItem = node;
}
if (!oItem && searchAncestors) {
oItem = node.ancestor((PERIOD + className));
}
}
return oItem;
};
var getParentMenu = function (node) {
return node.ancestor(MENU_SELECTOR);
};
var getMenu = function (node, searchAncestors) {
return getNodeWithClass(node, CSS_MENU, searchAncestors);
};
var getMenuItem = function (node, searchAncestors) {
var oItem;
if (node) {
oItem = getNodeWithClass(node, CSS_MENUITEM, searchAncestors);
}
return oItem;
};
var getMenuLabel = function (node, searchAncestors) {
var oItem;
if (node) {
if (searchAncestors) {
oItem = getNodeWithClass(node, CSS_MENU_LABEL, searchAncestors);
}
else {
oItem = getNodeWithClass(node, CSS_MENU_LABEL) ||
node.one((PERIOD + CSS_MENU_LABEL));
}
}
return oItem;
};
var getItem = function (node, searchAncestors) {
var oItem;
if (node) {
oItem = getMenuItem(node, searchAncestors) ||
getMenuLabel(node, searchAncestors);
}
return oItem;
};
var getFirstItem = function (menu) {
return getItem(menu.one("li"));
};
var getActiveClass = function (node) {
return isMenuItem(node) ? CSS_MENUITEM_ACTIVE : CSS_MENU_LABEL_ACTIVE;
};
var handleMouseOverForNode = function (node, target) {
return node && !node[HANDLED_MOUSEOVER] &&
(node.compareTo(target) || node.contains(target));
};
var handleMouseOutForNode = function (node, relatedTarget) {
return node && !node[HANDLED_MOUSEOUT] &&
(!node.compareTo(relatedTarget) && !node.contains(relatedTarget));
};
/**
* The NodeMenuNav class is a plugin for a Node instance. The class is used via
* the plug
method of Node and
* should not be instantiated directly.
* @namespace plugin
* @class NodeMenuNav
*/
var NodeMenuNav = function () {
NodeMenuNav.superclass.constructor.apply(this, arguments);
};
NodeMenuNav.NAME = "nodeMenuNav";
NodeMenuNav.NS = "menuNav";
/**
* @property SHIM_TEMPLATE_TITLE
* @description String representing the value for the title
* attribute for the shim used to prevent <select>
elements
* from poking through menus in IE 6.
* @default "Menu Stacking Shim"
* @type String
*/
NodeMenuNav.SHIM_TEMPLATE_TITLE = "Menu Stacking Shim";
/**
* @property SHIM_TEMPLATE
* @description String representing the HTML used to create the
* <iframe>
shim used to prevent
* <select>
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>"
* @type String
*/
//