diff options
author | jzaefferer <joern.zaefferer@gmail.com> | 2011-02-24 15:51:51 +0100 |
---|---|---|
committer | jzaefferer <joern.zaefferer@gmail.com> | 2011-02-24 15:51:51 +0100 |
commit | 0ddf677e40a7feaaeefcc44f2a4910923f1bc258 (patch) | |
tree | 385812d1fbb9f0e0bafc40457330ec5b6d1d98e7 | |
parent | 38cfcfffe92f2ac2572ab7ebc51e860de9312baf (diff) | |
download | jquery-ui-0ddf677e40a7feaaeefcc44f2a4910923f1bc258.tar.gz jquery-ui-0ddf677e40a7feaaeefcc44f2a4910923f1bc258.zip |
Menu: Integrated flyoutmenu into menu, and moved flyoutmenu.html
testmenu into contextmenu.html
-rw-r--r-- | tests/visual/menu/contextmenu.html | 74 | ||||
-rw-r--r-- | tests/visual/menu/flyoutmenu.html | 127 | ||||
-rw-r--r-- | tests/visual/menu/flyoutmenu.js | 110 | ||||
-rw-r--r-- | tests/visual/menu/menu.html | 12 | ||||
-rw-r--r-- | themes/base/jquery.ui.menu.css | 2 | ||||
-rw-r--r-- | ui/jquery.ui.menu.js | 103 |
6 files changed, 169 insertions, 259 deletions
diff --git a/tests/visual/menu/contextmenu.html b/tests/visual/menu/contextmenu.html index dae366158..c91b4ea1b 100644 --- a/tests/visual/menu/contextmenu.html +++ b/tests/visual/menu/contextmenu.html @@ -20,15 +20,28 @@ top: 10 }).appendTo(document.body).themeswitcher(); + // TODO close other menus when opening a new one $("button").each(function() { $(this).next().menu({ + /* top-alignment + position: function(item) { + return { + my: "left top", + at: "right top", + of: item.parent() + } + }, + */ select: function(event, ui) { $(this).hide().prev().focus(); $("#log").append("<div>Selected " + ui.item.text() + "</div>"); } }).hide(); + + // equal height + //menu.find("ul").height(menu.height()); }).click(function(event) { - // TODO required to prevent the click handler below from handling this event + // required to prevent the click handler below from handling this event event.stopPropagation(); var menu = $("#menu" + this.id).menu("blur").show().position({ my: "left top", @@ -36,7 +49,7 @@ of: event.pageX > 0 ? event : this }).focus(); $(document).one("click", function() { - menu.hide(); + menu.menu("closeAll").menu("widget").hide(); }) }).next().keydown(function(event) { var menu = $(this).data("menu"); @@ -45,10 +58,14 @@ event.stopPropagation(); switch (event.keyCode) { case $.ui.keyCode.TAB: + menu.closeAll(); menu.widget().hide(); + $(this).prev().focus() break; case $.ui.keyCode.ESCAPE: + menu.closeAll(); menu.widget().hide(); + $(this).prev().focus() break; default: @@ -59,7 +76,7 @@ <style> body { font-size:62.5%; } .ui-menu { width: 200px; position: absolute; } - #menu2 { height: 200px; overflow: auto; } + #menu3 { height: 200px; overflow: auto; } </style> </head> <body> @@ -76,13 +93,60 @@ <li><a href="#">Zurich</a></li> </ul> +<button id="2">Show context menu 2</button> +<ul id="menu2"> + <li> + <a id="a1" href="#">Amsterdam</a> + <ul> + <li><a id="b1" href="#">Aberdeen</a></li> + <li><a id="b2" href="#">Ada</a></li> + <li> + <a href="#">Adamsville</a> + <ul> + <li><a href="#">Anaheim</a></li> + <li> + <a href="#">Cologne</a> + <ul> + <li><a href="#">Mberdeen</a></li> + <li><a href="#">Mda</a></li> + <li><a href="#">Mdamsville</a></li> + <li><a href="#">Mddyston</a></li> + <li><a href="#">Mmesville</a></li> + </ul> + </li> + <li><a href="#">Frankfurt</a></li> + </ul> + </li> + <li><a href="#">Addyston</a></li> + <li><a href="#">Amesville</a></li> + </ul> + </li> + <li><a id="a2" href="#">Anaheim</a></li> + <li><a id="a3" href="#">Cologne</a></li> + <li><a href="#">Frankfurt</a></li> + <li> + <a href="#">Magdeburg</a> + <ul> + <li><a href="#">Mberdeen</a></li> + <li><a href="#">Mda</a></li> + <li><a href="#">Mdamsville</a></li> + <li><a href="#">Mddyston</a></li> + <li><a href="#">Mmesville</a></li> + </ul> + </li> + <li><a href="#">Munich</a></li> + <li><a href="#">Utrecht</a></li> + <li><a href="#">Zurich</a></li> +</ul> + + <div class="ui-widget" style="margin-top:2em; font-family:Arial"> Log: <div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div> </div> -<button id="2">Show context menu 2</button> -<ul id="menu2"> +<button id="3">Show context menu 3</button> +<ul id="menu3"> <li><a href="#">Aberdeen</a></li> <li><a href="#">Ada</a></li> <li><a href="#">Adamsville</a></li> diff --git a/tests/visual/menu/flyoutmenu.html b/tests/visual/menu/flyoutmenu.html deleted file mode 100644 index 150a20731..000000000 --- a/tests/visual/menu/flyoutmenu.html +++ /dev/null @@ -1,127 +0,0 @@ -<!doctype html> -<html> -<head> - <title>Menu Visual Test: Default</title> - <link rel="stylesheet" href="../visual.css" type="text/css" /> - <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" /> - <script type="text/javascript" src="../../../jquery-1.4.4.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="../../../external/jquery.bgiframe-2.1.2.js"></script> - <script type="text/javascript" src="flyoutmenu.js"></script> - <!-- - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> - --> - <script type="text/javascript"> - $(function() { - $.fn.themeswitcher && $('<div/>').css({ - position: "absolute", - right: 10, - top: 10 - }).appendTo(document.body).themeswitcher(); - - var menu = $("#menu"); - - var button = $("button").click(function(event) { - // TODO required to prevent the click handler below from handling this event - event.stopPropagation(); - menu.flyoutmenu("show") - .focus() - .position({ - my: "left top", - at: "right top", - of: this - }); - $(document).one("click", function() { - menu.flyoutmenu("hide"); - }); - }); - - menu.flyoutmenu({ - /* top-alignment - position: function(item) { - return { - my: "left top", - at: "right top", - of: item.parent() - } - }, - */ - select: function(event, ui) { - $("#log").append("<div>Selected " + ui.item.children("a").text() + "(" + ui.item.children("a").attr("id") + ")</div>"); - button.focus(); - } - }).hide(); - - // equal height - //menu.find("ul").height(menu.height()); - }); - </script> - <style> - body { font-size:62.5%; } - .ui-menu { width: 200px; position: absolute; outline: none; } - .ui-menu .ui-icon { float: right; } - </style> -</head> -<body> - -<button>Show context menu</button> -<br/> -<select> - <option>some option with some text</option> -</select> - -<ul id="menu"> - <li> - <a id="a1" href="#">Amsterdam</a> - <ul> - <li><a id="b1" href="#">Aberdeen</a></li> - <li><a id="b2" href="#">Ada</a></li> - <li> - <a href="#">Adamsville</a> - <ul> - <li><a href="#">Anaheim</a></li> - <li> - <a href="#">Cologne</a> - <ul> - <li><a href="#">Mberdeen</a></li> - <li><a href="#">Mda</a></li> - <li><a href="#">Mdamsville</a></li> - <li><a href="#">Mddyston</a></li> - <li><a href="#">Mmesville</a></li> - </ul> - </li> - <li><a href="#">Frankfurt</a></li> - </ul> - </li> - <li><a href="#">Addyston</a></li> - <li><a href="#">Amesville</a></li> - </ul> - </li> - <li><a id="a2" href="#">Anaheim</a></li> - <li><a id="a3" href="#">Cologne</a></li> - <li><a href="#">Frankfurt</a></li> - <li> - <a href="#">Magdeburg</a> - <ul> - <li><a href="#">Mberdeen</a></li> - <li><a href="#">Mda</a></li> - <li><a href="#">Mdamsville</a></li> - <li><a href="#">Mddyston</a></li> - <li><a href="#">Mmesville</a></li> - </ul> - </li> - <li><a href="#">Munich</a></li> - <li><a href="#">Utrecht</a></li> - <li><a href="#">Zurich</a></li> -</ul> - -<div class="ui-widget" style="margin-top:2em; font-family:Arial"> - Log: - <div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div> -</div> - -</body> -</html> diff --git a/tests/visual/menu/flyoutmenu.js b/tests/visual/menu/flyoutmenu.js deleted file mode 100644 index 0564120a2..000000000 --- a/tests/visual/menu/flyoutmenu.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - * jQuery UI flyoutmenu - * - * backported from Michael Lang's fork: http://www.nexul.com/prototypes/toolbar/demo.html - */ -(function($) { - -$.widget("ui.flyoutmenu", { - - options: { - position: { - my: "left top", - at: "right top" - } - }, - - _create: function() { - var self = this; - this.activeItem = this.element.children("li").first(); - // hide submenus and create indicator icons - this.element.find("ul").addClass("ui-menu-flyout").hide().prev("a").prepend('<span class="ui-icon ui-icon-carat-1-e"></span>'); - - this.element.find("ul").andSelf().menu({ - select: function(event) { - self._select(event); - }, - focus: function(event, ui) { - self.activeItem = ui.item; - ui.item.parent().focus(); - ui.item.parent().find("ul").hide(); - var nested = $(">ul", ui.item); - if (nested.length && event.originalEvent && /^mouse/.test(event.originalEvent.type)) { - self._open(nested); - nested.focus(); - } - } - }).keydown(function(event) { - if (self.element.is(":hidden")) - return; - switch (event.keyCode) { - case $.ui.keyCode.LEFT: - if (self.left(event)) { - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.RIGHT: - if (self.right(event)) { - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.ESCAPE: - self.hide(); - break; - } - }); - }, - - _open: function(submenu) { - // TODO restrict to widget - //only one menu can have items open at a time. - $(document).find(".ui-menu-flyout").not(submenu.parents()).hide().data("menu").blur(); - - var position = $.extend({}, { - of: this.activeItem - }, $.type(this.options.position) == "function" - ? this.options.position(this.activeItem) - : this.options.position - ); - - submenu.show().position(position); - }, - _select: function(event) { - event.stopPropagation(); - // TODO make _select cancelable? - this._trigger( "select", event, { item: this.activeItem } ); - this.hide(); - }, - left: function(event) { - var newItem = this.activeItem.parents("li").first(); - if (newItem.length) { - this.activate(event, newItem); - return true; - } - }, - right: function(event) { - var newItem = this.activeItem.children("ul").children("li").first(); - if (newItem.length) { - this._open(newItem.parent()); - this.activate(event, newItem); - return true; - } - }, - activate: function(event, item) { - var parent = item.parent(); - parent.data("menu").focus(event, item); - this.activeItem = item; - parent.focus(); - }, - show: function() { - this.element.show(); - }, - hide: function() { - this.activeItem = this.element.children("li").first(); - this.element.find("ul").andSelf().menu("blur").hide(); - } -}); - -}(jQuery)); diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index 32fb98ea8..b5fdf938b 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -7,6 +7,7 @@ <script type="text/javascript" src="../../../jquery-1.4.4.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> + <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> <script type="text/javascript"> $(function() { @@ -40,7 +41,7 @@ <style> body { font-size:62.5%; } .ui-menu { width: 200px; } - #menu2 { height: 200px; overflow: auto; } + #menu3 { height: 200px; overflow: auto; } </style> </head> <body> @@ -69,7 +70,14 @@ </ul> </li> <li><a href="#">Saarland</a></li> - <li><a href="#">Salzburg</a></li> + <li> + <a href="#">Salzburg</a> + <ul> + <li><a href="#">Alliance</a></li> + <li><a href="#">Krombach</a></li> + <li><a href="#">Perch</a></li> + </ul> + </li> </ul> <ul id="menu3"> diff --git a/themes/base/jquery.ui.menu.css b/themes/base/jquery.ui.menu.css index 63299aea4..7854fe232 100644 --- a/themes/base/jquery.ui.menu.css +++ b/themes/base/jquery.ui.menu.css @@ -39,3 +39,5 @@ } .ui-menu .ui-icon { float: right; } + +.ui-menu .ui-menu { position: absolute; } diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index cba42d17f..3915c3301 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -25,6 +25,7 @@ $.widget("ui.menu", { }, _create: function() { var self = this; + this.activeMenu = this.element; this.menuId = this.element.attr( "id" ) || "ui-menu-" + idIncrement++; this.element .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) @@ -48,7 +49,7 @@ $.widget("ui.menu", { return; } var target = $( event.target ).closest( ".ui-menu-item" ); - if ( target.length && target.parent()[0] === self.element[0] ) { + if ( target.length ) { self.focus( event, target ); } }) @@ -57,7 +58,7 @@ $.widget("ui.menu", { return; } var target = $( event.target ).closest( ".ui-menu-item" ); - if ( target.length && target.parent()[0] === self.element[0] ) { + if ( target.length ) { self.blur( event ); } }); @@ -69,25 +70,37 @@ $.widget("ui.menu", { } switch ( event.keyCode ) { case $.ui.keyCode.PAGE_UP: - self.previousPage(); + self.previousPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.PAGE_DOWN: - self.nextPage(); + self.nextPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.UP: - self.previous(); + self.previous( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.DOWN: - self.next(); + self.next( event ); event.preventDefault(); event.stopImmediatePropagation(); break; + case $.ui.keyCode.LEFT: + if (self.left( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + if (self.right( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; case $.ui.keyCode.ENTER: self.select(); event.preventDefault(); @@ -174,7 +187,9 @@ $.widget("ui.menu", { focus: function( event, item ) { var self = this; + this.blur(); + if ( this._hasScroll() ) { var borderTop = parseFloat( $.curCSS( this.element[0], "borderTopWidth", true) ) || 0, paddingtop = parseFloat( $.curCSS( this.element[0], "paddingTop", true) ) || 0, @@ -188,6 +203,7 @@ $.widget("ui.menu", { this.element.attr( "scrollTop", scroll + offset - elementHeight + itemHeight ); } } + this.active = item.first() .children( "a" ) .addClass( "ui-state-focus" ) @@ -198,6 +214,14 @@ $.widget("ui.menu", { // need to remove the attribute before adding it for the screenreader to pick up the change // see http://groups.google.com/group/jquery-a11y/msg/929e0c1e8c5efc8f this.element.removeAttr("aria-activedescendant").attr("aria-activedescendant", self.itemId); + + self._close(); + var nested = $(">ul", item); + if (nested.length && /^mouse/.test(event.type)) { + self._open(nested); + } + this.activeMenu = item.parent(); + this._trigger( "focus", event, { item: item } ); }, @@ -206,15 +230,59 @@ $.widget("ui.menu", { return; } - var self = this; this.active.children( "a" ).removeClass( "ui-state-focus" ); // remove only generated id - $( "#" + self.menuId + "-activedescendant" ).removeAttr( "id" ); + $( "#" + this.menuId + "-activedescendant" ).removeAttr( "id" ); this.element.removeAttr( "aria-activedescenant" ); this._trigger( "blur", event ); this.active = null; }, + _open: function(submenu) { + // TODO restrict to widget + //only one menu can have items open at a time. + //$(document).find(".ui-menu").not(submenu.parents()).hide().data("menu").blur(); + this.element.find(".ui-menu").not(submenu.parents()).hide(); + + var position = $.extend({}, { + of: this.active + }, $.type(this.options.position) == "function" + ? this.options.position(this.active) + : this.options.position + ); + + submenu.show().position(position); + }, + + closeAll: function() { + this.element.find("ul").hide(); + this.blur(); + this.activeMenu = this.element; + }, + + _close: function() { + this.active.parent().find("ul").hide(); + }, + + left: function(event) { + var newItem = this.active && this.active.parents("li").first(); + if (newItem && newItem.length) { + this.active.parent().hide(); + this.focus(event, newItem); + return true; + } + }, + + right: function(event) { + var newItem = this.active && this.active.children("ul").children("li").first(); + if (newItem && newItem.length) { + this._open(newItem.parent()); + var current = this.active; + this.focus(event, newItem); + return true; + } + }, + next: function(event) { this._move( "next", ".ui-menu-item", "first", event ); }, @@ -233,21 +301,21 @@ $.widget("ui.menu", { _move: function(direction, edge, filter, event) { if ( !this.active ) { - this.focus( event, this.element.children(edge)[filter]() ); + this.focus( event, this.activeMenu.children(edge)[filter]() ); return; } var next = this.active[ direction + "All" ]( ".ui-menu-item" ).eq( 0 ); if ( next.length ) { this.focus( event, next ); } else { - this.focus( event, this.element.children(edge)[filter]() ); + this.focus( event, this.activeMenu.children(edge)[filter]() ); } }, nextPage: function( event ) { if ( this._hasScroll() ) { if ( !this.active || this.last() ) { - this.focus( event, this.element.children( ".ui-menu-item" ).first() ); + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); return; } var base = this.active.offset().top, @@ -260,7 +328,7 @@ $.widget("ui.menu", { this.focus( event, result ); } else { - this.focus( event, this.element.children( ".ui-menu-item" ) + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active || this.last() ? "first" : "last" ]() ); } }, @@ -268,7 +336,7 @@ $.widget("ui.menu", { previousPage: function( event ) { if ( this._hasScroll() ) { if ( !this.active || this.first() ) { - this.focus( event, this.element.children( ".ui-menu-item" ).last() ); + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).last() ); return; } @@ -282,7 +350,7 @@ $.widget("ui.menu", { this.focus( event, result ); } else { - this.focus( event, this.element.children( ".ui-menu-item" ) + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active || this.first() ? ":last" : ":first" ]() ); } }, @@ -292,7 +360,12 @@ $.widget("ui.menu", { }, select: function( event ) { - this._trigger( "select", event, { item: this.active } ); + // save active reference before closeAll triggers blur + var ui = { + item: this.active + }; + this.closeAll(); + this._trigger( "select", event, ui ); } }); |