aboutsummaryrefslogtreecommitdiffstats
path: root/tests/visual/menu/flyoutmenu.js
blob: 0564120a2f7aa5487c68beb454291b6069012f98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * 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));