1/* 2#------------------------------------------------------------------------ 3# Copyright (C) 2007-2010 Gavick.com. All Rights Reserved. 4# License: Copyrighted Commercial Software 5# Website: http://www.gavick.com 6# Support: [email protected] 7#------------------------------------------------------------------------ 8# Based on T3 Framework 9#------------------------------------------------------------------------ 10# Copyright (C) 2004-2009 J.O.O.M Solutions Co., Ltd. All Rights Reserved. 11# @license - GNU/GPL, http://www.gnu.org/copyleft/gpl.html 12# Author: J.O.O.M Solutions Co., Ltd 13# Websites: http://www.joomlart.com - http://www.joomlancers.com 14#------------------------------------------------------------------------ 15*/ 16 17var gkMegaMenuMoo = new Class({ 18 options: { 19 slide: true, //enable slide 20 duration: 300, //slide speed. lower for slower, bigger for faster 21 transition: Fx.Transitions.Sine.easeOut, 22 fading: false, //Enable fading 23 action: 'mouseenter', //mouseenter or click 24 hidestyle: 'fastwhenshow', 25 //events 26 onItemShow: null, //function (li) {} 27 onItemHide: null, //function (li) {} 28 onItemShowComplete: null, //function (li) {} 29 onItemHideComplete: null, //function (li) {} 30 onFirstShow: null, //First child show 31 onLastHide: null, //All child hidden 32 onLoad: null //Load done 33 }, 34 35 initialize: function(menu, options){ 36 this.setOptions(options); 37 this.menu = menu; 38 this.childopen = new Array(); 39 this.items = null; 40 this.start(); 41 this.options.delayHide = 150; 42 }, 43 44 start: function () { 45 this.menu = $(this.menu); 46 if (this.items) return; //started already 47 this.items = this.menu.getElements ('li.mega'); 48 this.items.each (function(li) { 49 //link item 50 if ((a = li.getElement('a.mega')) && this.isChild (a, li)) li.a = a; 51 else li.a = null; 52 //parent 53 li._parent = this.getParent (li); 54 //child content 55 if ((childcontent = li.getElement('.childcontent')) && this.isChild (childcontent, li)) { 56 li.childcontent = childcontent; 57 li.childcontent_inner = li.childcontent.getElement ('.childcontent-inner-wrap'); 58 var coor = li.getElement('.childcontent-inner').getCoordinates(); 59 li._w = coor.width; 60 li._h = coor.height; 61 li._ml = li.childcontent.getStyle('margin-left').toInt(); 62 li._mt = li.childcontent.getStyle('margin-top').toInt(); 63 li.level0 = li.getParent().hasClass('level0'); 64 // 65 if (li._w) { 66 li.childcontent.setStyles ({'width':li._w}); 67 li.childcontent_inner.setStyles ({'width':li._w}); 68 } 69 //fix for overflow 70 li.childcontent_inner1 = li.childcontent.getElement ('.childcontent-inner'); 71 li.childcontent_inner1.ol = false; 72 //Fix for IE: correct render at the first show 73 li.childcontent_inner1.setStyle ('min-height', li.childcontent_inner1.offsetHeight); 74 if (li.childcontent_inner1.getStyle ('overflow') == 'auto' || li.childcontent_inner1.getStyle ('overflow') == 'scroll') { 75 li.childcontent_inner1.ol = true; 76 } 77 } 78 else li.childcontent = null; 79 80 if (li.childcontent && (this.options.slide || this.options.fading)) { 81 //li.childcontent.setStyles ({'width': li._w}); 82 li.childcontent.setStyles ({'left':'auto'}); 83 if (li.childcontent.hasClass ('right')) li.childcontent.setStyle ('right', 0); 84 if (this.options.slide) { 85 li.childcontent.setStyles ({'left':'auto', 'overflow':'hidden'}); 86 //if (li.level0) { 87 // li.childcontent_inner.setStyle ('margin-top', -li._h-20); 88 //} else { 89 li.childcontent_inner.setStyle ('margin-left', -li._w-20); 90 //} 91 } 92 if (this.options.fading) { 93 li.childcontent_inner.setStyle ('opacity', 0); 94 } 95 //Init Fx.Styles for childcontent 96 li.fx = new Fx.Styles(li.childcontent_inner, {duration: this.options.duration, transition: this.options.transition, onComplete: this.itemAnimDone.bind(this, li)}); 97 //effect 98 li.eff_on = {}; 99 li.eff_off = {}; 100 if (this.options.slide) { 101 //if (li.level0) { 102 // li.eff_on ['margin-top'] = 0; 103 // li.eff_off ['margin-top'] = -li._h; 104 //} else { 105 li.eff_on['margin-left'] = 0; 106 li.eff_off['margin-left'] = -li._w; 107 //} 108 } 109 if (this.options.fading) { 110 li.eff_on['opacity'] = 1; 111 li.eff_off['opacity'] = 0; 112 } 113 } 114 115 if (this.options.action=='click') { 116 if (li.childcontent) { 117 li.addEvent('click', function(e) { 118 var event = new Event (e); 119 if (li.hasClass ('group')) return; 120 if (li.childcontent) { 121 if (li.status == 'open') { 122 if (this.cursorIn (li, event)) { 123 this.itemHide (li); 124 } else { 125 this.itemHideOthers(li); 126 } 127 } else { 128 this.itemShow (li); 129 } 130 } else { 131 if (li.a) location.href = li.a.href; 132 } 133 if(!window.ie) event.stop(); 134 }.bind (this)); 135 //If action is click, click on windows will close all submenus 136 this.windowClickFn = function (e) { 137 this.itemHideOthers(null); 138 }.bind (this); 139 } 140 li.addEvent('mouseenter', function(e) { 141 if (li.hasClass ('group')) return; 142 this.itemOver (li); 143 if(!window.ie) e.stop(); 144 }.bind (this)); 145 146 li.addEvent('mouseleave', function(e) { 147 if (li.hasClass ('group')) return; 148 this.itemOut (li); 149 if(!window.ie) e.stop(); 150 }.bind (this)); 151 } 152 153 if (this.options.action == 'mouseover' || this.options.action == 'mouseenter') { 154 li.addEvent('mouseenter', function(e) { 155 if (li.hasClass ('group')) return; 156 $clear (li.timer); 157 this.itemShow (li); 158 if(!window.ie) e.stop(); 159 }.bind (this)); 160 161 li.addEvent('mouseleave', function(e) { 162 if (li.hasClass ('group')) return; 163 $clear (li.timer); 164 if (li.childcontent) li.timer = setTimeout(this.itemHide.bind(this, [li, e]), this.options.delayHide); 165 else this.itemHide (li, e); 166 if(!window.ie) e.stop(); 167 }.bind (this)); 168 } 169 170 //when click on a link - close all open childcontent 171 if (li.a && !li.childcontent) { 172 li.a.addEvent ('click',function (e){ 173 this.itemHideOthers (null); 174 //Remove current class 175 this.menu.getElements ('.active').removeClass ('active'); 176 //Add current class 177 var p = li; 178 while (p) { 179 p.addClass ('active'); 180 p.a.addClass ('active'); 181 p = p._parent; 182 } 183 //new Event (e).stop(); 184 }.bind (this)); 185 } 186 },this); 187 188 if (this.options.slide || this.options.fading) { 189 //hide all content child 190 //this.menu.getElements('.childcontent').setStyle ('display', 'none'); 191 this.menu.getElements('.childcontent').setStyle ('left', -9999); 192 } 193 //Call onLoad 194 if (typeof (this.options.onLoad) == 'function') this.options.onLoad.call (this); 195 }, 196 197 position: function (li) { 198 //fix position for level0 / show it 199 li.childcontent.setStyle ('left', 'auto'); 200 //reposition 201 if (li.childcontent) { 202 var pos = $merge (li.getPosition(), {'w':li.childcontent.offsetWidth, 'h':li.childcontent.offsetHeight}); 203 var win = {'x': window.getWidth(), 'y': window.getHeight()}; 204 var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()}; 205 206 //if (li.level0) { 207 // li.childcontent.setStyle ('margin-left', (pos['x'] + pos['w'] + li._ml > win['x'] + scroll ['x']) ? win['x'] + scroll ['x'] - pos['w'] - pos['x']:li._ml); 208 //} else { 209 //sub level 210 li.childcontent.setStyle ('margin-top', (pos['y'] + pos['h'] + 20 + li._mt > win['y'] + scroll ['y'])?win['y'] + scroll ['y'] - pos['y'] - pos['h'] - 20 : li._mt); 211 //} 212 } 213 }, 214 215 getParent: function (li) { 216 var p = li; 217 while ((p=p.getParent())) { 218 if (this.items.contains (p) && !p.hasClass ('group')) return p; 219 if (!p || p == this.menu) return null; 220 } 221 }, 222
223 cursorIn: function (el, event) { 224 if (!el || !event) return false; 225 var pos = $merge (el.getPosition(), {'w':el.offsetWidth, 'h': el.offsetHeight});; 226 var cursor = {'x': event.page.x, 'y': event.page.y}; 227 228 if (cursor.x>pos.x && cursor.x<pos.x+el.offsetWidth 229 && cursor.y>pos.y && cursor.y<pos.y+el.offsetHeight) return true; 230 return false; 231 }, 232 233 isChild: function (child, parent) { 234 return !!parent.getChildren().contains (child); 235 }, 236 237 itemOver: function (li) { 238 if (li.hasClass ('haschild')) 239 li.removeClass ('haschild').addClass ('haschild-over'); 240 li.addClass ('over'); 241 if (li.a) { 242 li.a.addClass ('over'); 243 } 244 }, 245 246 itemOut: function (li) { 247 li = (li[0]) ? li[0] : li; 248 if (li.hasClass ('haschild-over')) 249 li.removeClass ('haschild-over').addClass ('haschild'); 250 li.removeClass ('over'); 251 if (li.a) { 252 li.a.removeClass ('over'); 253 } 254 }, 255 256 itemShow: function (li) { 257 clearTimeout(li.timer); 258 if (li.status == 'open') return; //don't need do anything 259 //Adjust position 260 //Setup the class 261 this.itemOver (li); 262 //Check if this is the first show 263 if (li.childcontent) { 264 var firstshow = true; 265 this.childopen.each (function (li) { 266 if (li.childcontent) firstshow = false; 267 }); 268 if (firstshow && typeof (this.options.onFirstShow) == 'function') { 269 this.options.onFirstShow.call (this, li); 270 } 271 } 272 //push to show queue 273 li.status = 'open'; 274 this.childopen.push (li); 275 //hide other 276 this.itemHideOthers (li); 277 if (li.childcontent) { 278 if (this.options.action=='click' && this.childopen.length && !this.windowClickEventAdded) { 279 //addEvent click for window 280 $(document.body).addEvent ('click', this.windowClickFn); 281 this.windowClickEventAdded = true; 282 } 283 //call event 284 if (typeof (this.options.onItemHide) == 'function') this.options.onItemHide.call (this, li); 285 } 286 287 if (!$defined(li.fx) || !$defined(li.childcontent)) return; 288 289 li.childcontent.setStyle ('display', 'block'); 290 this.position (li); 291 292 li.childcontent.setStyles ({'overflow': 'hidden'}); 293 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'}); 294 li.fx.stop(); 295 li.fx.start (li.eff_on); 296 }, 297 298 itemHide: function (li, e) { 299 li = (li[0]) ? li[0] : li; 300 301 if (e && e.page) { //if event 302 if (this.cursorIn (li, e) || this.cursorIn (li.childcontent, e)) { 303 return; 304 } //cursor in li 305 var p=li._parent; 306 if (p && !this.cursorIn (p, e) && !this.cursorIn(p.childcontent, e)) { 307 p.fireEvent ('mouseleave', e); //fire mouseleave event 308 } 309 } 310 clearTimeout(li.timer); 311 this.itemOut(li); 312 li.status = 'close'; 313 this.childopen.remove (li); 314 if (li.childcontent) { 315 if (this.options.action=='click' && !this.childopen.length && this.windowClickEventAdded) { 316 //removeEvent click for window 317 $(document.body).removeEvent ('click', this.windowClickFn); 318 this.windowClickEventAdded = false; 319 } 320 //call event 321 if (typeof (this.options.onItemShow) == 'function') this.options.onItemShow.call (this, li); 322 } 323 324 if (!$defined(li.fx) || !$defined(li.childcontent)) return; 325 326 if (li.childcontent.getStyle ('opacity') == 0) return; 327 li.childcontent.setStyles ({'overflow': 'hidden'}); 328 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'}); 329 li.fx.stop(); 330 switch (this.options.hidestyle) { 331 case 'fast': 332 li.fx.options.duration = 100; 333 li.fx.start ($merge(li.eff_off,{'opacity':0})); 334 break; 335 case 'fastwhenshow': //when other show 336 if (!e) { //force hide, not because of event => hide fast 337 li.fx.options.duration = 100; 338 li.fx.start ($merge(li.eff_off,{'opacity':0})); 339 } else { //hide as normal 340 li.fx.start (li.eff_off); 341 } 342 break; 343 case 'normal': 344 default: 345 li.fx.start (li.eff_off); 346 break; 347 } 348 }, 349 350 itemAnimDone: function (li) { 351 //hide done 352 if (li.status == 'close'){ 353 //reset duration and enable opacity if not fading 354 if (this.options.hidestyle.test (/fast/)) { 355 li.fx.options.duration = this.options.duration; 356 if (!this.options.fading) li.childcontent_inner.setStyle ('opacity', 1); 357 } 358 //hide 359 li.childcontent.setStyle ('left', -9999); 360 //call event 361 if (typeof (this.options.onItemHideComplete) == 'function') this.options.onItemHideComplete.call (this, li); 362 //Check if there's no child content shown, raise event onLastHide 363 var lasthide = true; 364 this.childopen.each (function (li) { 365 if (li.childcontent) lasthide = false;
366 }); 367 if (lasthide && typeof (this.options.onLastHide) == 'function') this.options.onLastHide.call (this, li); 368 } 369 //show done 370 if (li.status == 'open'){ 371 li.childcontent.setStyles ({'overflow': ''}); 372 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow-y': 'auto'}); 373 if (typeof (this.options.onItemShowComplete) == 'function') this.options.onItemShowComplete.call (this, li); 374 } 375 }, 376 377 itemHideOthers: function (el) { 378 var fakeevent = null 379 if (el && !el.childcontent) fakeevent = {}; 380 var curopen = this.childopen.copy(); 381 curopen.each (function(li) { 382 if (li && typeof (li.status) != 'undefined' && (!el || (li != el && !li.hasChild (el)))) { 383 this.itemHide(li, fakeevent); 384 } 385 },this); 386 } 387}); 388 389gkMegaMenuMoo.implement(new Options);
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.