From 057909b5cd975fadd92e0fd41157728ecaf92612 Mon Sep 17 00:00:00 2001 From: Rolux Date: Sun, 7 Feb 2010 20:31:22 +0530 Subject: [PATCH] use event delegation for menu --- build/js/ox.ui.js | 201 ++++++++++++++++++++++++---------------------- 1 file changed, 104 insertions(+), 97 deletions(-) diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 5ec82fd..b08eebc 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -292,12 +292,10 @@ requires var stack = []; return { focus: function(id) { - /* - if (stack.length) { - Ox.Event.unbindKeyboard(stack[stack.length - 1]); - } - */ var index = stack.indexOf(id); + if (stack.length) { + Ox.Event.unbindKeyboard(stack[stack.length - 1]) + } if (index > -1) { stack.splice(index, 1); } @@ -313,9 +311,7 @@ requires stack.splice(stack.length - 2, 0, stack.pop()); } Ox.Event.unbindKeyboard(id); - /* Ox.Event.bindKeyboard(stack[stack.length - 1]); - */ Ox.print("blur", stack); } }; @@ -734,7 +730,7 @@ requires .addClass("OxContent") .appendTo(that); return that; - } + }; /* ---------------------------------------------------------------------------- @@ -802,6 +798,9 @@ requires } else if (length == 4) { ret = that.$element[v](args[0], args[1], args[2], args[3]); } + if (v == "data") { + Ox.print("data ret", ret, $(ret)) + } // if the $element of an ox object was returned // then return the ox object instead // so we can do oxObj.jqFn().oxFn() @@ -813,7 +812,7 @@ requires // shared self.onChange = function() { - // self.onChange(option, value) + // self.onChange(key, value) // is called when an option changes // (to be implemented by widget) }; @@ -1180,8 +1179,8 @@ requires Ox.Toolbar = function(options, self) { var self = self || {}, that = new Ox.Bar({ - size: oxui.getBarSize(options.size) - }, self); + size: oxui.getBarSize(options.size) + }, self); return that; }; @@ -1755,7 +1754,7 @@ requires if (item.checked) { selected = i; } - }) + }); that.$button = new Ox.Button($.extend(self.options, { id: self.options.id, @@ -1826,7 +1825,11 @@ requires */ Ox.MainMenu = function(options, self) { - + + var self = self || {}, + that = new Ox.Bar({}, self) + .options + } Ox.Menu = function(options, self) { @@ -1850,11 +1853,16 @@ requires .addClass( "OxMenu Ox" + Ox.toTitleCase(self.options.side) + " Ox" + Ox.toTitleCase(self.options.size) - ), + ) + .click(click) + .mouseenter(mouseenter) + .mouseleave(mouseleave) + .mousemove(mousemove), itemHeight = self.options.size == "small" ? 12 : (self.options.size == "medium" ? 16 : 20), menuHeight, - scrollSpeed = 1, // fixme: should this be self.scrollSpeed? + scrollSpeed = 1, $item; // fixme: used? + // fixme: attach all private vars to self? // construct that.items = []; @@ -1874,12 +1882,10 @@ requires $.each(self.options.items, function(i, item) { var position; if (item.id) { - $.extend(item, { - menu: that, - }); that.items.push(new Ox.MenuItem($.extend(item, { + menu: that, position: position = that.items.length - })).appendTo(that.$content)); + })).data("position", position).appendTo(that.$content)); // fixme: jquery bug when passing {position: position}? does not return the object?; if (item.items) { that.submenus[item.id] = new Ox.Menu({ element: that.items[position], @@ -1907,12 +1913,35 @@ requires .appendTo(that.$element); function click(event) { - if (!$(event.target).is(".OxCell")) { - that.hideMenu(); + var item, + $target = $(event.target); + that.hideMenu(); + if ($target.is(".OxCell")) { + item = that.items[$target.parent().data("position")]; + if (!item.options("disabled")) { + if (that.options("parent")) { + that.options("parent").hideMenu(); + } + if (!item.options("items").length) { + if (item.options("checked") !== null && (!item.options("group") || !item.options("checked"))) { + item.options({ + checked: !item.options("checked") + }); + Ox.Event.trigger("click." + that.id, { + id: item.options("id"), + value: item.options("title")[0] // fixme: value or title? + }); + } + if (item.options("title").length == 2) { + item.toggleTitle(); + } + } + } } } function clickItem() { + // called on key.enter if (self.options.selected > -1) { that.items[self.options.selected].trigger("click"); } else { @@ -2004,6 +2033,31 @@ requires return ret; } + function mouseenter() { + that.gainFocus(); + } + + function mouseleave() { + if (self.options.selected > -1 && !that.items[self.options.selected].options("items").length) { + selectItem(-1); + } + } + + function mousemove(event) { + var item, + position, + $target = $(event.target); + if ($target.is(".OxCell")) { + position = $target.parent().data("position"); + item = that.items[position]; + if (!item.options("disabled") && position != self.options.selected) { + selectItem(position); + } + } else { + mouseleave(); + } + } + function scrollMenu(speed) { var containerHeight = that.$container.height(), contentHeight = that.$content.height(), @@ -2041,6 +2095,27 @@ requires } } + function selectItem(position) { + var item; + if (self.options.selected > -1) { + that.items[self.options.selected].removeClass("OxSelected"); + } + if (position > -1) { + item = that.items[position]; + $.each(that.submenus, function(id, submenu) { + if (!submenu.is(":hidden")) { + submenu.hideMenu(); + return false; + } + }); + item.options("items").length && that.submenus[item.options("id")].showMenu(); // fixme: do we want to switch to this style? + item.addClass("OxSelected"); + } + that.options({ + selected: position + }); + } + function selectNextItem() { var offset, selected = self.options.selected; @@ -2048,12 +2123,12 @@ requires if (selected == -1) { scrollMenuUp(); } else { - that.items[selected].trigger("mouseleave"); + that.items[selected].removeClass("OxSelected"); } do { selected++; } while (that.items[selected].options("disabled")) - that.items[selected].trigger("mouseenter"); + selectItem(selected); offset = that.items[selected].offset().top + itemHeight - that.$container.offset().top - that.$container.height(); if (offset > 0) { @@ -2079,11 +2154,11 @@ requires selected = self.options.selected; if (selected > - 1) { if (!isFirstEnabledItem()) { - that.items[selected].trigger("mouseleave"); + that.items[selected].removeClass("OxSelected"); do { selected--; } while (that.items[selected].options("disabled")) - that.items[selected].trigger("mouseenter"); + selectItem(selected); } offset = that.items[selected].offset().top - that.$container.offset().top; Ox.print(offset); @@ -2107,7 +2182,7 @@ requires if (self.options.selected > -1) { var submenu = that.submenus[that.items[self.options.selected].options("id")]; if (submenu && submenu.hasEnabledItems()) { - that.loseFocus(); + //that.loseFocus(); submenu.gainFocus(); submenu.selectFirstItem(); } @@ -2117,7 +2192,7 @@ requires function selectSupermenu() { if (self.options.parent) { that.items[self.options.selected].trigger("mouseleave"); - that.loseFocus(); + // that.loseFocus(); self.options.parent.gainFocus(); } } @@ -2243,13 +2318,9 @@ requires })) .addClass("OxItem" + (self.options.disabled ? " OxDisabled" : "")) .attr({ - id: Ox.toCamelCase(self.options.menu.id + "/" + self.options.id) + id: Ox.toCamelCase(self.options.menu.options("id") + "/" + self.options.id) }) - .click(click) - .data("group", self.options.group) // fixme: why? - .mouseenter(mouseenter) - .mouseleave(mouseleave) - .mousemove(mousemove); // in case selection has goes elsewhere via keyboard + .data("group", self.options.group); // fixme: why? // construct that.append( @@ -2290,70 +2361,6 @@ requires }) ); - function click() { - if (!that.hasClass("OxDisabled")) { - self.options.menu.hideMenu(); - if (self.options.menu.options("parent")) { - self.options.menu.options("parent").hideMenu(); - } - if (!self.options.items.length) { - if (self.options.checked !== null && (!self.options.group || !self.options.checked)) { - that.options({ - checked: !self.options.checked - }); - Ox.Event.trigger("click." + self.options.menu.id, { - id: self.options.id, - value: self.options.title[0] // fixme: value or title? - }); - } - if (self.options.title.length == 2) { - that.toggleTitle(); - } - } - } - } - - function isSelected() { - return self.options.position == self.options.menu.options("selected"); - } - - function mouseenter() { - if (!self.options.disabled && !isSelected()) { - $.each(self.options.menu.submenus, function(id, submenu) { - if (!submenu.is(":hidden")) { - submenu.hideMenu(); - return false; - } - }); - if (self.options.menu.options("selected") > -1) { - self.options.menu.items[self.options.menu.options("selected")].trigger("mouseleave"); - } - self.options.items.length && self.options.menu.submenus[self.options.id].showMenu(); // fixme: do we want to switch to this style? - that.addClass("OxSelected"); - self.options.menu.options({ - selected: self.options.position - }); - } - } - - function mouseleave() { - if (!self.options.disabled && !self.options.items.length) { - that.removeClass("OxSelected"); - self.options.menu.options({ - selected: -1 - }); - } - } - - function mousemove() { - var selected = self.options.menu.options("selected"); - if (!self.options.disabled && !isSelected()) { - self.options.menu.items[self.options.menu.options("selected")] - .trigger("mouseleave"); - mouseenter(); - } - } - function parseKeyboard(str) { var modifiers = str.split(' '), key = modifiers.pop();