reservation plugin - unbound request (unclean
[unfold.git] / portal / static / unbound_reservation_static / js / contextmenu / contextMenu.js
1 /*
2  *contextMenu.js v 1.3.0
3  *Author: Sudhanshu Yadav
4  *s-yadav.github.com
5  *Copyright (c) 2013 Sudhanshu Yadav.
6  *Dual licensed under the MIT and GPL licenses
7  */
8 ;(function ($, window, document, undefined) {
9     "use strict";
10
11     $.fn.contextMenu = function (method, selector, option) {
12
13         //parameter fix
14         if (!methods[method]) {
15             option = selector;
16             selector = method;
17             method = 'popup';
18         }
19
20
21         //need to check for array object
22         else if (selector) {
23             if (!((selector instanceof Array) || (typeof selector === 'string') || (selector.nodeType) || (selector.jquery))) {
24                 option = selector;
25                 selector = null;
26             }
27         }
28
29         if ((selector instanceof Array) && (method != 'update')) {
30             method = 'menu';
31         }
32
33         var myoptions = option;
34         if (method != 'update') {
35             option = iMethods.optionOtimizer(method, option);
36             myoptions = $.extend({}, $.fn.contextMenu.defaults, option);
37             if (!myoptions.baseTrigger) {
38                 myoptions.baseTrigger = this;
39             }
40         }
41         methods[method].call(this, selector, myoptions);
42         return this;
43     };
44     $.fn.contextMenu.defaults = {
45         triggerOn: 'click', //avaliable options are all event related mouse plus enter option
46         displayAround: 'cursor', // cursor or trigger
47         mouseClick: 'left',
48         verAdjust: 0,
49         horAdjust: 0,
50         top: 'auto',
51         left: 'auto',
52         closeOther: true, //to close other already opened context menu
53         containment: window,
54         winEventClose: true,
55         sizeStyle: 'auto', //allowed values are auto and content (popup size will be according content size)
56         position: 'auto', //allowed values are top, left, bottom and right
57         closeOnClick: true, //close context menu on click/ trigger of any item in menu
58
59         //callback
60         onOpen: function (data, event) {},
61         afterOpen: function (data, event) {},
62         onClose: function (data, event) {}
63     };
64
65     var methods = {
66         menu: function (selector, option) {
67             var trigger = $(this);
68             selector = iMethods.createMenuList(trigger, selector, option);
69             iMethods.contextMenuBind.call(this, selector, option, 'menu');
70         },
71         popup: function (selector, option) {
72             $(selector).addClass('iw-contextMenu');
73             iMethods.contextMenuBind.call(this, selector, option, 'popup');
74         },
75         update: function (selector, option) {
76             var self = this;
77             this.each(function () {
78                 var trgr = $(this),
79                     menuData = trgr.data('iw-menuData');
80                 //refresh if any new element is added
81                 if (!menuData) {
82                     self.contextMenu('refresh');
83                     menuData = trgr.data('iw-menuData');
84                 }
85
86                 var menu = menuData.menu;
87                 if (typeof selector === 'object') {
88
89                     for (var i = 0; i < selector.length; i++) {
90                         var name = selector[i].name,
91                             disable = selector[i].disable,
92                             fun = selector[i].fun,
93                             img = selector[i].img,
94                             title = selector[i].title,
95                             className = selector[i].className,
96                             elm = menu.children('li').filter(function () {
97                                 return $(this).contents().filter(function () {
98                                     return this.nodeType == 3;
99                                 }).text() == name;
100                             }),
101                             subMenu = selector[i].subMenu;
102
103                         //toggle disable if provided on update method
104                         disable != undefined && (disable ? elm.addClass('iw-mDisable') : elm.removeClass('iw-mDisable'));
105                         
106                         //bind new function if provided
107                         fun && elm.unbind('click.contextMenu').bind('click.contextMenu',fun);
108                         
109                         //update title
110                         title != undefined && elm.attr('title',title);
111                         
112                         //update class name
113                         className!= undefined && elm.attr('class',className);
114                         
115                         //update image
116                         if(img){
117                             var imgIcon = elm.find('.iw-mIcon');
118                             if(imgIcon.length){
119                                 imgIcon[0].src = img;
120                             }
121                             else{
122                                 elm.prepend('<img src="' + img + '" align="absmiddle" class="iw-mIcon" />');
123                             }
124                         }
125                         
126                         //to change submenus
127                         if (subMenu) {
128                             elm.contextMenu('update', subMenu);
129                         }
130                     }
131
132                 }
133
134                 iMethods.onOff(menu);
135                 menuData.option = $.extend({}, menuData.option, option);
136                 trgr.data('iw-menuData', menuData);
137
138                 //bind event again if trigger option has changed.
139                 var eventType = menuData.option.triggerOn;
140                 if (option) {
141                     if (eventType != option.triggerOn) {
142                         trgr.unbind('.contextMenu');
143                         //to bind event
144                         trgr.bind(eventType + '.contextMenu', iMethods.eventHandler);
145                     }
146                 }
147             });
148         },
149         refresh: function () {
150             var menuData = this.filter(function () {
151                     return !!$(this).data('iw-menuData');
152                 }).data('iw-menuData'),
153                 newElm = this.filter(function () {
154                     return !$(this).data('iw-menuData');
155                 });
156             //to change basetrigger on refresh  
157             menuData.option.baseTrigger = this;
158             iMethods.contextMenuBind.call(newElm, menuData.menuSelector, menuData.option);
159         },
160         open: function(sel,data){
161                 data = data || {};
162                 var e = data.event || new Event('click');
163                 if(data.top) e.clientY = data.top;
164                 if(data.left) e.clientX = data.left;
165             this.each(function(){
166                 iMethods.eventHandler.call(this,e);
167             });
168         },
169         //to force context menu to close
170         close: function () {
171             var menuData = this.data('iw-menuData');
172             if (menuData) {
173                 iMethods.closeContextMenu(menuData.option, this, menuData.menu, null);
174             }
175         },
176         //to get value of a key
177         value: function (key) {
178             var menuData = this.data('iw-menuData');
179             if (menuData[key]) {
180                 return menuData[key];
181             } else if (menuData.option) {
182                 return menuData.option[key];
183             }
184             return null;
185         },
186         destroy: function () {
187             this.each(function () {
188                 var trgr = $(this),
189                     menuId = trgr.data('iw-menuData').menuId,
190                     menu = $('.iw-contextMenu[menuId=' + menuId + ']'),
191                     menuData = menu.data('iw-menuData');
192
193                 //Handle the situation of dynamically added element.
194                 if (!menuData) return;
195
196
197                 if (menuData.noTrigger == 1) {
198                     if (menu.hasClass('iw-created')) {
199                         menu.remove();
200                     } else {
201                         menu.removeClass('iw-contextMenu ' + menuId)
202                             .removeAttr('menuId').removeData('iw-menuData');
203                         //to destroy submenus
204                         menu.find('li.iw-mTrigger').contextMenu('destroy');
205                     }
206                 } else {
207                     menuData.noTrigger--;
208                     menu.data('iw-menuData', menuData);
209                 }
210                 trgr.unbind('.contextMenu').removeClass('iw-mTrigger').removeData('iw-menuData');
211             });
212         }
213     };
214     var iMethods = {
215         contextMenuBind: function (selector, option, method) {
216             var trigger = this,
217                 menu = $(selector),
218                 menuData = menu.data('iw-menuData');
219
220             //fallback
221             if (menu.length == 0) {
222                 menu = trigger.find(selector);
223                 if (menu.length == 0) {
224                     return;
225                 }
226             }
227
228             if (method == 'menu') {
229                 iMethods.menuHover(menu);
230             }
231             //get base trigger
232             var baseTrigger = option.baseTrigger;
233
234
235             if (!menuData) {
236                 var menuId;
237                 if (!baseTrigger.data('iw-menuData')) {
238                     menuId = Math.ceil(Math.random() * 100000);
239                     baseTrigger.data('iw-menuData', {
240                         'menuId': menuId
241                     });
242                 } else {
243                     menuId = baseTrigger.data('iw-menuData').menuId;
244                 }
245                 //create clone menu to calculate exact height and width.
246                 var cloneMenu = menu.clone();
247                 cloneMenu.appendTo('body');
248
249                 menuData = {
250                     'menuId': menuId,
251                     'menuWidth': cloneMenu.outerWidth(true),
252                     'menuHeight': cloneMenu.outerHeight(true),
253                     'noTrigger': 1,
254                     'trigger': trigger
255                 };
256
257
258                 //to set data on selector
259                 menu.data('iw-menuData', menuData).attr('menuId', menuId);
260                 //remove clone menu
261                 cloneMenu.remove();
262             } else {
263                 menuData.noTrigger++;
264                 menu.data('iw-menuData', menuData);
265             }
266
267             //to set data on trigger
268             trigger.addClass('iw-mTrigger').data('iw-menuData', {
269                 'menuId': menuData.menuId,
270                 'option': option,
271                 'menu': menu,
272                 'menuSelector': selector,
273                 'method': method
274             });
275
276             //hover fix
277             var eventType;
278             if (option.triggerOn == 'hover') {
279                 eventType = 'mouseenter';
280                 //hover out if display is of context menu is on hover
281                 if (baseTrigger.index(trigger) != -1) {
282                     baseTrigger.add(menu).bind('mouseleave.contextMenu', function (e) {
283                         if ($(e.relatedTarget).closest('.iw-contextMenu').length == 0) {
284                             $('.iw-contextMenu[menuId="' + menuData.menuId + '"]').hide(100);
285                         }
286                     });
287                 }
288
289             } else {
290                 eventType = option.triggerOn;
291             }
292
293            trigger.delegate('input,a,.needs-click','click',function(e){ e.stopImmediatePropagation()});
294
295             //to bind event
296             trigger.bind(eventType + '.contextMenu', iMethods.eventHandler);
297
298             //to stop bubbling in menu
299             menu.bind('click mouseenter', function (e) {
300                 e.stopPropagation();
301             });
302
303             menu.delegate('li', 'click', function (e) {
304                 if (option.closeOnClick) iMethods.closeContextMenu(option, trigger, menu, e);
305             });
306         },
307         eventHandler: function (e) {
308             e.preventDefault();
309             var trigger = $(this),
310                 trgrData = trigger.data('iw-menuData'),
311                 menu = trgrData.menu,
312                 menuData = menu.data('iw-menuData'),
313                 option = trgrData.option,
314                 cntnmnt = option.containment,
315                 clbckData = {
316                     trigger: trigger,
317                     menu: menu
318                 },
319                 //check conditions
320                 cntWin = cntnmnt == window,
321                 btChck = option.baseTrigger.index(trigger) == -1;
322
323             //to close previous open menu.
324             if (!btChck && option.closeOther) {
325                 $('.iw-contextMenu').css('display', 'none');
326             }
327
328             //to reset already selected menu item
329             menu.find('.iw-mSelected').removeClass('iw-mSelected');
330
331             //call open callback
332             option.onOpen.call(this, clbckData, e);
333
334
335             var cObj = $(cntnmnt),
336                 cHeight = cObj.innerHeight(),
337                 cWidth = cObj.innerWidth(),
338                 cTop = 0,
339                 cLeft = 0,
340                 menuHeight = menuData.menuHeight,
341                 menuWidth = menuData.menuWidth,
342                 va, ha,
343                 left = 0,
344                 top = 0,
345                 bottomMenu,
346                 rightMenu,
347                 verAdjust = va = parseInt(option.verAdjust),
348                 horAdjust = ha = parseInt(option.horAdjust);
349
350             if (!cntWin) {
351                 cTop = cObj.offset().top;
352                 cLeft = cObj.offset().left;
353
354                 //to add relative position if no position is defined on containment
355                 if (cObj.css('position') == 'static') {
356                     cObj.css('position', 'relative');
357                 }
358
359             }
360
361             if (option.sizeStyle == 'auto') {
362                 menuHeight = Math.min(menuHeight, cHeight);
363                 menuWidth = Math.min(menuWidth, cWidth);
364                 menuWidth = menuWidth + 20;
365             }
366
367             if (option.displayAround == 'cursor') {
368                 left = cntWin ? e.clientX : e.clientX + $(window).scrollLeft() - cLeft;
369                 top = cntWin ? e.clientY : e.clientY + $(window).scrollTop() - cTop;
370                 bottomMenu = top + menuHeight;
371                 rightMenu = left + menuWidth;
372                 //max height and width of context menu
373                 if (bottomMenu > cHeight) {
374                     if ((top - menuHeight) < 0) {
375                         if ((bottomMenu - cHeight) < (menuHeight - top)) {
376                             top = cHeight - menuHeight;
377                             va = -1 * va;
378                         } else {
379                             top = 0;
380                             va = 0;
381                         }
382                     } else {
383                         top = top - menuHeight;
384                         va = -1 * va;
385                     }
386                 }
387                 if (rightMenu > cWidth) {
388                     if ((left - menuWidth) < 0) {
389                         if ((rightMenu - cWidth) < (menuWidth - left)) {
390                             left = cWidth - menuWidth;
391                             ha = -1 * ha;
392                         } else {
393                             left = 0;
394                             ha = 0;
395                         }
396                     } else {
397                         left = left - menuWidth;
398                         ha = -1 * ha;
399                     }
400                 }
401             } else if (option.displayAround == 'trigger') {
402                 var triggerHeight = trigger.outerHeight(true),
403                     triggerWidth = trigger.outerWidth(true),
404                     triggerLeft = cntWin ? trigger.offset().left - cObj.scrollLeft() : trigger.offset().left - cLeft,
405                     triggerTop = cntWin ? trigger.offset().top - cObj.scrollTop() : trigger.offset().top - cTop,
406                     leftShift = triggerWidth;
407
408                 left = triggerLeft + triggerWidth;
409                 top = triggerTop;
410
411
412                 bottomMenu = top + menuHeight;
413                 rightMenu = left + menuWidth;
414                 //max height and width of context menu
415                 if (bottomMenu > cHeight) {
416                     if ((top - menuHeight) < 0) {
417                         if ((bottomMenu - cHeight) < (menuHeight - top)) {
418                             top = cHeight - menuHeight;
419                             va = -1 * va;
420                         } else {
421                             top = 0;
422                             va = 0;
423                         }
424                     } else {
425                         top = top - menuHeight + triggerHeight;
426                         va = -1 * va;
427                     }
428                 }
429                 if (rightMenu > cWidth) {
430                     if ((left - menuWidth) < 0) {
431                         if ((rightMenu - cWidth) < (menuWidth - left)) {
432                             left = cWidth - menuWidth;
433                             ha = -1 * ha;
434                             leftShift = -triggerWidth;
435                         } else {
436                             left = 0;
437                             ha = 0;
438                             leftShift = 0;
439                         }
440                     } else {
441                         left = left - menuWidth - triggerWidth;
442                         ha = -1 * ha;
443                         leftShift = -triggerWidth;
444                     }
445                 }
446                 //test end
447                 if (option.position == 'top') {
448                     menuHeight = Math.min(menuData.menuHeight, triggerTop);
449                     top = triggerTop - menuHeight;
450                     va = verAdjust;
451                     left = left - leftShift;
452                 } else if (option.position == 'left') {
453                     menuWidth = Math.min(menuData.menuWidth, triggerLeft);
454                     left = triggerLeft - menuWidth;
455                     ha = horAdjust;
456                 } else if (option.position == 'bottom') {
457                     menuHeight = Math.min(menuData.menuHeight, (cHeight - triggerTop - triggerHeight));
458                     top = triggerTop + triggerHeight;
459                     va = verAdjust;
460                     left = left - leftShift;
461                 } else if (option.position == 'right') {
462                     menuWidth = Math.min(menuData.menuWidth, (cWidth - triggerLeft - triggerWidth));
463                     left = triggerLeft + triggerWidth;
464                     ha = horAdjust;
465                 }
466             }
467             //to draw contextMenu
468             var outerLeftRight = menu.outerWidth(true) - menu.width(),
469                 outerTopBottom = menu.outerHeight(true) - menu.height();
470
471
472             //applying css property
473             var cssObj = {
474                 'position': (cntWin || btChck) ? 'fixed' : 'absolute',
475                 'display': 'inline-block',
476                 'height': '',
477                 'width': '',
478                 'overflow-y': menuHeight != menuData.menuHeight ? 'auto' : 'hidden',
479                 'overflow-x': menuWidth != menuData.menuWidth ? 'auto' : 'hidden'
480             };
481
482             if (option.sizeStyle == 'auto') {
483                 cssObj.height = menuHeight - outerTopBottom + 'px';
484                 cssObj.width = menuWidth - outerLeftRight + 'px';
485             }
486
487             //to get position from offset parent
488             if (option.left != 'auto') {
489                 left = iMethods.getPxSize(option.left, cWidth);
490             }
491             if (option.top != 'auto') {
492                 top = iMethods.getPxSize(option.top, cHeight);
493             }
494             if (!cntWin) {
495                 var oParPos = trigger.offsetParent().offset();
496                 if (btChck) {
497                     left = left + cLeft - $(window).scrollLeft();
498                     top = top + cTop - $(window).scrollTop();
499                 } else {
500                     left = left - (cLeft - oParPos.left);
501                     top = top - (cTop - oParPos.top);
502                 }
503             }
504             cssObj.left = left + ha + 'px';
505             cssObj.top = top + va + 'px';
506
507             menu.css(cssObj);
508
509             //to call after open call back
510             option.afterOpen.call(this, clbckData, e);
511
512
513             //to add current menu class
514             if (trigger.closest('.iw-contextMenu').length == 0) {
515                 $('.iw-curMenu').removeClass('iw-curMenu');
516                 menu.addClass('iw-curMenu');
517             }
518
519
520             var dataParm = {
521                 trigger: trigger,
522                 menu: menu,
523                 option: option,
524                 method: trgrData.method
525             };
526             $('html').unbind('click', iMethods.clickEvent).click(dataParm, iMethods.clickEvent);
527             $(document).unbind('keydown', iMethods.keyEvent).keydown(dataParm, iMethods.keyEvent);
528             if (option.winEventClose) {
529                 $(window).bind('scroll resize', dataParm, iMethods.scrollEvent);
530             }
531         },
532
533         scrollEvent: function (e) {
534             iMethods.closeContextMenu(e.data.option, e.data.trigger, e.data.menu, e);
535         },
536
537         clickEvent: function (e) {
538             var button = e.data.trigger.get(0);
539
540             if ((button !== e.target) && ($(e.target).closest('.iw-contextMenu').length == 0)) {
541                 iMethods.closeContextMenu(e.data.option, e.data.trigger, e.data.menu, e);
542             }
543         },
544         keyEvent: function (e) {
545             e.preventDefault();
546             var menu = e.data.menu,
547                 option = e.data.option,
548                 keyCode = e.keyCode;
549             // handle cursor keys
550             if (keyCode == 27) {
551                 iMethods.closeContextMenu(option, e.data.trigger, menu, e);
552             }
553             if (e.data.method == 'menu') {
554                 var curMenu = $('.iw-curMenu'),
555                     optList = curMenu.children('li:not(.iw-mDisable)'),
556                     selected = optList.filter('.iw-mSelected'),
557                     index = optList.index(selected),
558                     focusOn = function (elm) {
559                         selected.removeClass('iw-mSelected');
560                         elm.addClass('iw-mSelected');
561                     },
562                     first = function () {
563                         focusOn(optList.filter(':first'));
564                     },
565                     last = function () {
566                         focusOn(optList.filter(':last'));
567                     },
568                     next = function () {
569                         focusOn(optList.filter(':eq(' + (index + 1) + ')'));
570                     },
571                     prev = function () {
572                         focusOn(optList.filter(':eq(' + (index - 1) + ')'));
573                     },
574                     subMenu = function () {
575                         var menuData = selected.data('iw-menuData');
576                         if (menuData) {
577                             selected.triggerHandler('mouseenter.contextMenu');
578                             var selector = menuData.menu;
579                             selector.addClass('iw-curMenu');
580                             curMenu.removeClass('iw-curMenu');
581                             curMenu = selector;
582                             optList = curMenu.children('li:not(.iw-mDisable)');
583                             selected = optList.filter('.iw-mSelected');
584                             first();
585                         }
586                     },
587                     parMenu = function () {
588                         var selector = curMenu.data('iw-menuData').trigger;
589                         var parMenu = selector.closest('.iw-contextMenu');
590                         if (parMenu.length != 0) {
591                             curMenu.removeClass('iw-curMenu').css('display', 'none');
592                             parMenu.addClass('iw-curMenu');
593                         }
594                     };
595                 switch (keyCode) {
596                 case 13:
597                     selected.click();
598                     break;
599                 case 40:
600                     (index == optList.length - 1 || selected.length == 0) ? first(): next();
601                     break;
602                 case 38:
603                     (index == 0 || selected.length == 0) ? last(): prev();
604                     break;
605                 case 33:
606                     first();
607                     break;
608                 case 34:
609                     last();
610                     break;
611                 case 37:
612                     parMenu();
613                     break;
614                 case 39:
615                     subMenu();
616                     break;
617                 }
618             }
619         },
620         closeContextMenu: function (option, trigger, menu, e) {
621
622             //unbind all events from top DOM
623             $(document).unbind('keydown', iMethods.keyEvent);
624             $('html').unbind('click', iMethods.clickEvent);
625             $(window).unbind('scroll resize', iMethods.scrollEvent);
626             $('.iw-contextMenu').hide();
627             $(document).focus();
628
629             //call close function
630             option.onClose.call(this, {
631                 trigger: trigger,
632                 menu: menu
633             }, e);
634         },
635         getPxSize: function (size, of) {
636             if (!isNaN(size)) {
637                 return size;
638             }
639             if (size.indexOf('%') != -1) {
640                 return parseInt(size) * of / 100;
641             } else {
642                 return parseInt(size);
643             }
644         },
645         menuHover: function (menu) {
646             menu.children('li').bind('mouseenter', function (e) {
647                 //to make curmenu
648                 $('.iw-curMenu').removeClass('iw-curMenu');
649                 menu.addClass('iw-curMenu');
650                 //to select the list
651                 var selected = menu.find('li.iw-mSelected'),
652                     submenu = selected.find('.iw-contextMenu');
653                 if ((submenu.length != 0) && (selected[0] != this)) {
654                     submenu.hide(100);
655                 }
656                 selected.removeClass('iw-mSelected');
657                 $(this).addClass('iw-mSelected');
658             });
659         },
660         createMenuList: function (trgr, selector, option) {
661             var baseTrigger = option.baseTrigger,
662                 randomNum = Math.floor(Math.random() * 10000);
663             if ((typeof selector == 'object') && (!selector.nodeType) && (!selector.jquery)) {
664                 var menuList = $('<ul class="iw-contextMenu iw-created iw-cm-menu" id="iw-contextMenu' + randomNum + '"></ul>');
665                 for (var i = 0; i < selector.length; i++) {
666                     var selObj = selector[i],
667                         name = selObj.name,
668                         fun = selObj.fun,
669                         subMenu = selObj.subMenu,
670                         img = selObj.img || '',
671                         title = selObj.title || "",
672                         className = selObj.className || "",
673                         disable = selObj.disable,
674                         list = $('<li title="' + title + '" class="' + className + '">' + name + '</li>');
675                     if (img) {
676                         list.prepend('<img src="' + img + '" align="absmiddle" class="iw-mIcon" />');
677                     }
678
679                     //to add disable
680                     if (disable) {
681                         list.addClass('iw-mDisable');
682                     }
683
684                     list.bind('click.contextMenu', fun);
685
686                     //to create sub menu
687                     menuList.append(list);
688                     if (subMenu) {
689                         list.append('<div class="iw-cm-arrow-right" />');
690                         iMethods.subMenu(list, subMenu, baseTrigger, option);
691                     }
692                 }
693                 if (baseTrigger.index(trgr[0]) == -1) {
694                     trgr.append(menuList);
695                 } else {
696                     var par = option.containment == window ? 'body' : option.containment;
697                     $(par).append(menuList);
698                 }
699
700                 iMethods.onOff($('#iw-contextMenu' + randomNum));
701                 return '#iw-contextMenu' + randomNum;
702             } else if ($(selector).length != 0) {
703                 var element = $(selector);
704                 element.removeClass('iw-contextMenuCurrent')
705                     .addClass('iw-contextMenu iw-cm-menu iw-contextMenu' + randomNum)
706                     .attr('menuId', 'iw-contextMenu' + randomNum)
707                     .css('display', 'none');
708
709                 //to create subMenu
710                 element.find('ul').each(function (index, element) {
711                     var subMenu = $(this),
712                         parent = subMenu.parent('li');
713                     parent.append('<div class="iw-cm-arrow-right" />');
714                     subMenu.addClass('iw-contextMenuCurrent');
715                     iMethods.subMenu(parent, '.iw-contextMenuCurrent', baseTrigger, option);
716                 });
717                 iMethods.onOff($('.iw-contextMenu' + randomNum));
718                 return '.iw-contextMenu' + randomNum;
719             }
720         },
721         subMenu: function (trigger, selector, baseTrigger, option) {
722             trigger.contextMenu('menu', selector, {
723                 triggerOn: 'hover',
724                 displayAround: 'trigger',
725                 position: 'auto',
726                 baseTrigger: baseTrigger,
727                 containment: option.containment
728             });
729         },
730         onOff: function (menu) {
731
732             menu.find('.iw-mOverlay').remove();
733             menu.find('.iw-mDisable').each(function () {
734                 var list = $(this);
735                 list.append('<div class="iw-mOverlay"/>');
736                 list.find('.iw-mOverlay').bind('click mouseenter', function (event) {
737                     event.stopPropagation();
738                 });
739
740             });
741
742         },
743         optionOtimizer: function (method, option) {
744             if (!option) {
745                 return;
746             }
747             if (method == 'menu') {
748                 if (!option.mouseClick) {
749                     option.mouseClick = 'right';
750                 }
751             }
752             if ((option.mouseClick == 'right') && (option.triggerOn == 'click')) {
753                 option.triggerOn = 'contextmenu';
754             }
755
756             if ($.inArray(option.triggerOn, ['hover', 'mouseenter', 'mouseover', 'mouseleave', 'mouseout', 'focusin', 'focusout']) != -1) {
757                 option.displayAround = 'trigger';
758             }
759             return option;
760         }
761     };
762 })(jQuery, window, document);