--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cm/media/js/lib/yui/yui3.0.0/examples/node-focusmanager/assets/menubutton.js Mon Nov 23 15:14:29 2009 +0100
@@ -0,0 +1,281 @@
+YUI().use("*", function (Y) {
+
+ var menuButton = Y.one("#button-1"),
+ menu;
+
+
+ var initMenu = function () {
+
+ menu = new Y.Overlay({
+ contentBox: "#menu-1",
+ visible: false,
+ tabIndex: null
+ });
+
+ menu.render();
+
+
+ Y.one("#menu-1").setStyle("display", "");
+
+ var boundingBox = menu.get("boundingBox"),
+ contentBox = menu.get("contentBox");
+
+ boundingBox.addClass("yui-buttonmenu");
+ contentBox.addClass("yui-buttonmenu-content");
+
+
+ // Append a decorator element to the bounding box to render the shadow.
+
+ boundingBox.append('<div class="yui-menu-shadow"></div>');
+
+
+ // Apply the ARIA roles, states and properties to the menu.
+
+ boundingBox.setAttrs({
+ role: "menu",
+ "aria-labelledby": menuButton.get("id")
+ });
+
+ boundingBox.all("input").set("role", "menuitem");
+
+
+ // For NVDA: Add the role of "presentation" to each LI
+ // element to prevent NVDA from announcing the
+ // "listitem" role.
+
+ boundingBox.all("div,ul,li").set("role", "presentation");
+
+
+ // Use the FocusManager Node Plugin to manage the focusability
+ // of each menuitem in the menu.
+
+ contentBox.plug(Y.Plugin.NodeFocusManager, {
+
+ descendants: "input",
+ keys: { next: "down:40", // Down arrow
+ previous: "down:38" }, // Up arrow
+ focusClass: {
+ className: "yui-menuitem-active",
+ fn: function (node) {
+ return node.get("parentNode");
+ }
+ },
+ circular: true
+
+ });
+
+
+ // Subscribe to the change event for the "focused" attribute
+ // to listen for when the menu initially gains focus, and
+ // when the menu has lost focus completely.
+
+ contentBox.focusManager.after("focusedChange", function (event) {
+
+ if (!event.newVal) { // The menu has lost focus
+
+ // Set the "activeDescendant" attribute to 0 when the
+ // menu is hidden so that the user can tab from the
+ // button to the first item in the menu the next time
+ // the menu is made visible.
+
+ this.set("activeDescendant", 0);
+
+ }
+
+ });
+
+
+ // Hide the button's menu if the user presses the escape key
+ // while focused either on the button or its menu.
+
+ Y.on("key", function () {
+
+ menu.hide();
+ menuButton.focus();
+
+ }, [menuButton, boundingBox] ,"down:27");
+
+
+ if (Y.UA.ie === 6) {
+
+ // Set the width and height of the menu's bounding box -
+ // this is necessary for IE 6 so that the CSS for the
+ // shadow element can simply set the shadow's width and
+ // height to 100% to ensure that dimensions of the shadow
+ // are always sync'd to the that of its parent menu.
+
+ menu.on("visibleChange", function (event) {
+
+ if (event.newVal) {
+
+ boundingBox.setStyles({ height: "", width: "" });
+
+ boundingBox.setStyles({
+ height: (boundingBox.get("offsetHeight") + "px"),
+ width: (boundingBox.get("offsetWidth") + "px") });
+
+ }
+
+ });
+
+ }
+
+
+ menu.after("visibleChange", function (event) {
+
+ var bVisible = event.newVal;
+
+ // Focus the first item when the menu is made visible
+ // to allow users to navigate the menu via the keyboard
+
+ if (bVisible) {
+
+ // Need to set focus via a timer for Webkit and Opera
+ Y.Lang.later(0, contentBox.focusManager, contentBox.focusManager.focus);
+
+ }
+
+ boundingBox.set("aria-hidden", (!bVisible));
+
+ });
+
+
+ // Hide the menu when one of menu items is clicked.
+
+ boundingBox.delegate("click", function (event) {
+
+ alert("You clicked " + this.query("input").get("value"));
+
+ contentBox.focusManager.blur();
+ menu.hide();
+
+ }, "li");
+
+
+ // Focus each menuitem as the user moves the mouse over
+ // the menu.
+
+ boundingBox.delegate("mouseenter", function (event) {
+
+ var focusManager = contentBox.focusManager;
+
+ if (focusManager.get("focused")) {
+ focusManager.focus(this.query("input"));
+ }
+
+ }, "li");
+
+
+ // Hide the menu if the user clicks outside of it or if the
+ // user doesn't click on the button
+
+ boundingBox.get("ownerDocument").on("mousedown", function (event) {
+
+ var oTarget = event.target;
+
+ if (!oTarget.compareTo(menuButton) &&
+ !menuButton.contains(oTarget) &&
+ !oTarget.compareTo(boundingBox) &&
+ !boundingBox.contains(oTarget)) {
+
+ menu.hide();
+
+ }
+
+ });
+
+ };
+
+
+ menuButton.addClass("yui-menubutton");
+
+
+ // Hide the list until it is transformed into a menu
+
+ Y.one("#menu-1").setStyle("display", "none");
+
+
+ // Remove the "yui-loading" class from the documentElement
+ // now that the necessary YUI dependencies are loaded and the
+ // menu button has been skinned.
+
+ menuButton.get("ownerDocument").get("documentElement").removeClass("yui-loading");
+
+
+ // Apply the ARIA roles, states and properties to the anchor.
+
+ menuButton.setAttrs({
+ role: "button",
+ "aria-haspopup": true
+ });
+
+
+ // Remove the "href" attribute from the anchor element to
+ // prevent JAWS and NVDA from reading the value of the "href"
+ // attribute when the anchor is focused.
+
+ if ((Y.UA.gecko || Y.UA.ie) && navigator.userAgent.indexOf("Windows") > -1) {
+
+ menuButton.removeAttribute("href");
+
+ // Since the anchor's "href" attribute has been removed, the
+ // element will not fire the click event in Firefox when the
+ // user presses the enter key. To fix this, dispatch the
+ // "click" event to the anchor when the user presses the
+ // enter key.
+
+ Y.on("key", function (event) {
+
+ menuButton.simulate("click");
+
+ }, menuButton, "down:13");
+
+ }
+
+
+ // Set the "tabIndex" attribute of the anchor element to 0 to
+ // place it in the browser's default tab flow. This is
+ // necessary since 1) anchor elements are not in the default
+ // tab flow in Opera and 2) removing the "href" attribute
+ // prevents the anchor from firing its "click" event
+ // in Firefox.
+
+ menuButton.set("tabIndex", 0);
+
+
+ var showMenu = function (event) {
+
+ // For performance: Defer the creation of the menu until
+ // the first time the button is clicked.
+
+ if (!menu) {
+ initMenu();
+ }
+
+
+ if (!menu.get("visible")) {
+
+ menu.set("align", {
+ node: menuButton,
+ points: [Y.WidgetPositionExt.TL, Y.WidgetPositionExt.BL]
+ });
+
+ menu.show();
+
+ }
+
+ // Prevent the anchor element from being focused
+ // when the users mouses down on it.
+ event.preventDefault();
+
+ };
+
+
+ // Bind both a "mousedown" and "click" event listener to
+ // ensure the button's menu can be invoked using both the
+ // mouse and the keyboard.
+
+ menuButton.on("mousedown", showMenu);
+ menuButton.on("click", showMenu);
+
+});