1 /**
  2  * @fileOverview menu item ,child component for menu
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("menu/menuitem", function (S, Component, MenuItemRender) {
  6 
  7     var $ = S.all;
  8 
  9     /**
 10      * @class
 11      * A menu item component which menu is consisted of.
 12      * xclass: 'menuitem'.
 13      * @name Item
 14      * @memberOf Menu
 15      * @extends Component.Controller
 16      */
 17     var MenuItem = Component.Controller.extend(
 18         /**
 19          * @lends Menu.Item#
 20          */
 21         {
 22 
 23             /**
 24              * Handle mouseenter event. Make parent menu to highlight itself.
 25              * Protected, should only be overridden by subclasses.
 26              * @param {Event.Object} e Mouseenter event object.
 27              * @protected
 28              * @override
 29              */
 30             handleMouseEnter:function (e) {
 31                 // 父亲不允许自己处理
 32                 if (MenuItem.superclass.handleMouseEnter.call(this, e)) {
 33                     return true;
 34                 }
 35                 this.get("parent").set("highlightedItem", this);
 36             },
 37 
 38             /**
 39              * Handle mouseleave event. Make parent menu to unhighlight itself.
 40              * Protected, should only be overridden by subclasses.
 41              * @param {Event.Object} e Mouseleave event object.
 42              * @protected
 43              * @override
 44              */
 45             handleMouseLeave:function (e) {
 46                 // 父亲不允许自己处理
 47                 if (MenuItem.superclass.handleMouseLeave.call(this, e)) {
 48                     return true;
 49                 }
 50                 this.get("parent").set("highlightedItem", null);
 51             },
 52 
 53             /**
 54              * Perform default action when click on enter on this menuitem.
 55              * If selectable, then make it selected.
 56              * If checkable, then toggle it.
 57              * Finally fire click on its parent menu.
 58              * @protected
 59              * @override
 60              */
 61             performActionInternal:function () {
 62                 var self = this;
 63                 // 可选
 64                 if (self.get("selectable")) {
 65                     self.set("selected", true);
 66                 }
 67                 // 可选中,取消选中
 68                 if (self.get("checkable")) {
 69                     self.set("checked", !self.get("checked"));
 70                 }
 71                 self.get("parent").fire("click", {
 72                     target:self
 73                 });
 74                 return true;
 75             },
 76 
 77             _uiSetHighlighted:function (v) {
 78                 // 是否要滚动到当前菜单项(横向,纵向)
 79                 if (v) {
 80                     var el = this.get("el"),
 81                     // 找到向上路径上第一个可以滚动的容器,直到父组件节点(包括)
 82                     // 找不到就放弃,为效率考虑不考虑 parent 的嵌套可滚动 div
 83                         p = el.parent(function (e) {
 84                             return $(e).css("overflow") != "visible";
 85                         }, this.get("parent").get("el").parent());
 86                     if (!p) {
 87                         return;
 88                     }
 89                     el.scrollIntoView(p, undefined, undefined, true);
 90                 }
 91             },
 92 
 93             /**
 94              * Check whether this menu item contains specified element.
 95              * @param {NodeList} element Element to be tested.
 96              */
 97             containsElement:function (element) {
 98                 return this.get('view') && this.get('view').containsElement(element);
 99             }
100 
101         }, {
102             ATTRS:/**
103              * @lends Menu.Item#
104              */
105             {
106 
107                 focusable:{
108                     value:false
109                 },
110 
111                 visibleMode:{
112                     value:"display"
113                 },
114 
115                 handleMouseEvents:{
116                     value:false
117                 },
118 
119                 /**
120                  * Whether the menu item is selectable or not.
121                  * Set to true for option.
122                  * @type Boolean
123                  */
124                 selectable:{
125                     view:1
126                 },
127 
128                 /**
129                  * Whether the menu item is checkable or not.
130                  * Set to true for checkbox option.
131                  * @type Boolean
132                  */
133                 checkable:{
134                     view:1
135                 },
136 
137                 /**
138                  * The value associated with the menu item.
139                  */
140                 value:{},
141 
142                 /**
143                  * Whether the menu item is checked.
144                  * @type Boolean
145                  */
146                 checked:{
147                     view:1
148                 },
149 
150                 /**
151                  * Whether the menu item is selected.
152                  * @type Boolean
153                  */
154                 selected:{
155                     view:1
156                 },
157 
158                 xrender:{
159                     value:MenuItemRender
160                 }
161             }
162         }, {
163             xclass:"menuitem",
164             priority:10
165         });
166 
167     return MenuItem;
168 }, {
169     requires:['component', './menuitemRender']
170 });