1/* 2 * wsMenu 1.0.0 3 * 4 * Copyright (c) 2012 Sven Wappler, WapplerSystems 5 * Based on jdMenu by Jonathan Sharp (http://jdsharp.us) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 */ 10 11// This initializes the menu 12 13function wsMenuReposition() { 14 $('.wsm_clone').each(function() { 15 $(this).data('orig').css({'top' : $(this).offset().top , 'left' : $(this).offset().left, 'width' : $(this).width(), 'height' : $(this).height() }); 16 }); 17} 18 19(function($){ 20 function addEvents(ul) { 21 var opts = $.data( $(ul).parents().andSelf().filter('ul.ws_menu')[0], 'opts' ); 22 $('> li', ul) 23 .bind('mouseenter.wsmenu mouseleave.wsmenu', function(evt) { 24 $(this).toggleClass('wsm_hover'); 25 var ul = $('> ul', this); 26 if ( ul.length == 1 ) { 27 clearTimeout( this.$jdTimer ); 28 var enter = ( evt.type == 'mouseenter' ); 29 var fn = ( enter ? showMenu : hideMenu ); 30 this.$jdTimer = setTimeout(function() { 31 fn( ul[0], opts.onAnimate, opts.isVertical ); 32 }, enter ? opts.showDelay : opts.hideDelay ); 33 } 34 }) 35 .bind('click.wsmenu', function(evt) { 36 var ul = $('> ul', this); 37 if ( ul.length == 1 && 38 ( opts.disableLinks == true || $(this).hasClass('accessible') ) ) { 39 showMenu( ul, opts.onAnimate, opts.isVertical ); 40 return false; 41 } 42 43 // The user clicked the li and we need to trigger a click for the a 44 if ( evt.target == this ) { 45 var link = $('> a', evt.target).not('.accessible'); 46 if ( link.length > 0 ) { 47 var a = link[0]; 48 if ( !a.onclick ) { 49 window.open( a.href, a.target || '_self' ); 50 } else { 51 $(a).trigger('click'); 52 } 53 } 54 } 55 if ( opts.disableLinks || 56 ( !opts.disableLinks && !$(this).parent().hasClass('ws_menu') ) ) { 57 $(this).parent().wsMenuHide(); 58 evt.stopPropagation(); 59 } 60 }) 61 .find('> a') 62 .bind('focus.wsmenu blur.wsmenu', function(evt) { 63 var p = $(this).parents('li:eq(0)'); 64 if ( evt.type == 'focus' ) { 65 p.addClass('wsm_hover'); 66 } else { 67 p.removeClass('wsm_hover'); 68 } 69 }) 70 .filter('.accessible') 71 .bind('click.wsmenu', function(evt) { 72 evt.preventDefault(); 73 }); 74 } 75 76 function showMenu(ul, animate, vertical) { 77 var ul = $(ul); 78 if ( ul.is(':visible') ) { 79 return; 80 } 81 ul.bgiframe(); 82 var li = ul.parent(); 83 ul.trigger('wsMenuShow') 84 .positionBy({ 85 target: li[0], 86 targetPos: ( vertical === true || !li.parent().hasClass('ws_menu') ? 1 : 3 ), 87 elementPos: 0, 88 hideAfterPosition: true 89 }); 90 if ( !ul.hasClass('wsm_events') ) { 91 ul.addClass('wsm_events'); 92 addEvents(ul); 93 } 94 li.addClass('wsm_active') 95 // Hide any adjacent menus 96 .siblings('li').find('> ul:eq(0):visible') 97 .each(function(){ 98 hideMenu( this ); 99 }); 100 if ( animate === undefined ) { 101 ul.show(); 102 } else { 103 animate.apply( ul[0], [true] ); 104 } 105 } 106 107 function hideMenu(ul, animate) { 108 var ul = $(ul); 109 $('.bgiframe', ul).remove(); 110 ul .filter(':not(.ws_menu)') 111 .find('> li > ul:eq(0):visible') 112 .each(function() { 113 hideMenu( this ); 114 }) 115 .end(); 116 if ( animate === undefined ) { 117 ul.hide() 118 } else { 119 animate.apply( ul[0], [false] ); 120 } 121 122 ul.trigger('wsMenuHide') 123 .parents('li:eq(0)') 124 .removeClass('wsm_active wsm_hover') 125 .end() 126 .find('> li') 127 .removeClass('wsm_active wsm_hover'); 128 } 129 130 // Public methods 131 $.fn.wsMenu = function(opts) { 132 // Future opts: activateDelay 133 var opts = $.extend({ // Time in ms before menu shows 134 showDelay: 200, // Time in ms before menu hides 135 hideDelay: 500, // Should items that contain submenus not respond to clicks 136 disableLinks: false // This callback allows for you to animate menus 137 //onAnimate: null 138 }, opts); 139 if ( !$.isFunction( opts.onAnimate ) ) { 140 opts.onAnimate = undefined; 141 } 142 return this.each(function() { 143 144 var clone = $(this).clone().addClass('wsm_clone').appendTo($(this).parent()).data('orig',$(this)).css('visibility','hidden'); 145 146 $(this).addClass('ws_menu') 147 .appendTo($('body')).css({'position':'absolute','top' : clone.offset().top, 'left' : clone.offset().left}) 148 .data('clone',clone) 149 .wrap($('<div>').addClass('ym-hlist').css({'overflow':'visible','position':'static'})); 150 151 // store settings 152 $(this).data( 'opts', $.extend({ isVertical: $(this).hasClass('ws_menu_vertical') }, opts)); 153 154 addEvents(this); 155 }); 156 }; 157 158 $.fn.wsMenuUnbind = function() { 159 $('ul.wsm_events', this) 160 .unbind('.wsmenu') 161 .find('> a').unbind('.wsmenu'); 162 }; 163 $.fn.wsMenuHide = function() { 164 return this.filter('ul').each(function(){ 165 hideMenu( this ); 166 }); 167 }; 168 169 $(window).resize(wsMenuReposition); 170 $('img').load(wsMenuReposition); 171 172 // Private methods and logic 173 $(window) 174 // Bind a click event to hide all visible menus when the document is clicked 175 .bind('click.wsmenu', function(){ 176 $('ul.ws_menu ul:visible').wsMenuHide(); 177 }); 178})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.