1/* 2#------------------------------------------------------------------------ 3 JA Purity II for Joomla 1.5 4#------------------------------------------------------------------------ 5#Copyright (C) 2004-2009 J.O.O.M Solutions Co., Ltd. All Rights Reserved. 6#@license - GNU/GPL, http://www.gnu.org/copyleft/gpl.html 7#Author: J.O.O.M Solutions Co., Ltd 8#Websites: http://www.joomlart.com - http://www.joomlancers.com 9#------------------------------------------------------------------------ 10*/ 11 12var jaMegaMenuMoo = new Class({ 13 initialize: function(menu, options){ 14 this.options = Object.extend({ 15 slide: true, //enable slide 16 duration: 300, //slide speed. lower for slower, bigger for faster 17 transition: Fx.Transitions.Sine.easeOut, 18 fading: false, //Enable fading 19 bgopacity: 0.9, //set the transparent background. 0 to disable, 0<bgopacity<1: the opacity of the background 20 delayHide: 500, 21 position: 'bottom', //position of toolbar. 22 rtl: 0, //right to left mode 23 direction: 'down', 24 action: 'mouseenter', //mouseenter or click 25 tips: true, //enable jatooltips 26 hidestyle: 'fastwhenshow', 27 //events 28 onItemShow: null, //function (li) {} 29 onItemHide: null, //function (li) {} 30 onItemShowComplete: null, //function (li) {} 31 onItemHideComplete: null, //function (li) {} 32 onFirstShow: null, //First child show 33 onLastHide: null, //All child hidden 34 onLoad: null //Load done 35 }, options || {}); 36 this.menu = menu; 37 this.childopen = new Array(); 38 39 this.items = null; 40 this.imageloaded = false; 41 //window.addEvent('load', this.start.bind(this)); 42 this.start(); 43 44 }, 45 46 startedcheck: function () { 47 this.imageloaded = true; 48 if (!this.items) this.start(); 49 }, 50 51 start: function () { 52 this.menu = $(this.menu); 53 //preload images 54 var images = this.menu.getElements ('img'); 55 if (images && images.length && !this.imageloaded) { 56 var imgs = []; 57 images.each (function (image) {imgs.push(image.src)}); 58 if (imgs.length) { 59 new Asset.images(imgs, { 60 onComplete: function(){ 61 this.imageloaded = true; 62 this.start(); 63 }.bind(this) 64 }); 65 66 this.starttimeout = setTimeout (this.startedcheck.bind(this), 3000); //check if start after 10 seconds. If not, call start manual 67 return ; 68 } 69 } 70 clearTimeout (this.starttimeout); 71 if (this.items) return; //started already 72 this.items = this.menu.getElements ('li.mega'); 73 //this.items.setStyle ('position', 'relative'); 74 this.items.each (function(li) { 75 //link item 76 if ((a = li.getElement('a.mega')) && this.isChild (a, li)) li.a = a; 77 else li.a = null; 78 //parent 79 li._parent = this.getParent (li); 80 //child content 81 if ((childcontent = li.getElement('.childcontent')) && this.isChild (childcontent, li)) { 82 li.childcontent = childcontent; 83 li.childcontent_inner = li.childcontent.getElement ('.childcontent-inner-wrap'); 84 var coor = li.getElement('.childcontent-inner').getCoordinates (); 85 li._w = coor.width; 86 li._h = coor.height; 87 li._ml = li.childcontent.getStyle('margin-left').toInt(); 88 li._mt = li.childcontent.getStyle('margin-top').toInt(); 89 li.level0 = li.getParent().hasClass('level0'); 90 // 91 //li.childcontent.setStyles ({'width':li._w+50, 'height':li._h}); 92 if (li._w) { 93 li.childcontent.setStyles ({'width':li._w+50}); 94 li.childcontent_inner.setStyles ({'width':li._w}); 95 } 96 //fix for overflow 97 li.childcontent_inner1 = li.childcontent.getElement ('.childcontent-inner'); 98 li.childcontent_inner1.ol = false; 99 //Fix for IE: correct render at the first show 100 li.childcontent_inner1.setStyle ('min-height', li.childcontent_inner1.offsetHeight); 101 if (li.childcontent_inner1.getStyle ('overflow') == 'auto' || li.childcontent_inner1.getStyle ('overflow') == 'scroll') { 102 li.childcontent_inner1.ol = true; 103 //fix for ie6/7 104 if (window.ie6 || window.ie7) { 105 //li.childcontent_inner1.setStyle ('position', 'relative'); 106 } 107 108 if (window.ie6) { 109 li.childcontent_inner1.setStyle ('height', li.childcontent_inner1.getStyle ('max-height') || 400); 110 } 111 } 112 113 //show direction 114 if (this.options.direction == 'up') { 115 if (li.level0) { 116 //li.childcontent.setStyle ('top', -li.childcontent.offsetHeight); //ajust top position 117 li.childcontent.setStyle ('bottom', li.offsetHeight); 118 } else { 119 li.childcontent.setStyle ('bottom', 0); 120 } 121 } 122 } 123 else li.childcontent = null; 124 125 if (li.childcontent && this.options.bgopacity) { 126 //Make transparent background 127 var bg = new Element ('div', {'class':'childcontent-bg'}); 128 bg.injectTop (li.childcontent_inner); 129 bg.setStyles ({'width':'100%', 'height':li._h, 'opacity':this.options.bgopacity, 130 'position': 'absolute', 'top': 0, 'left': 0, 'z-index': 1 131 });
132 if (li.childcontent.getStyle('background')) bg.setStyle ('background', li.childcontent.getStyle('background')); 133 if (li.childcontent.getStyle('background-image')) bg.setStyle ('background-image', li.childcontent.getStyle('background-image')); 134 if (li.childcontent.getStyle('background-repeat')) bg.setStyle ('background-repeat', li.childcontent.getStyle('background-repeat')); 135 if (li.childcontent.getStyle('background-color')) bg.setStyle ('background-color', li.childcontent.getStyle('background-color')); 136 li.childcontent.setStyle ('background', 'none'); 137 li.childcontent_inner.setStyles ({'position':'relative', 'z-index': 2}); 138 } 139 140 if (li.childcontent && (this.options.slide || this.options.fading)) { 141 //li.childcontent.setStyles ({'width': li._w}); 142 li.childcontent.setStyles ({'left':'auto'}); 143 if (li.childcontent.hasClass ('right')) li.childcontent.setStyle ('right', 0); 144 if (this.options.slide) { 145 li.childcontent.setStyles ({'left':'auto', 'overflow':'hidden'}); 146 if (li.level0) { 147 if (this.options.direction == 'up') { 148 li.childcontent_inner.setStyle ('bottom', -li._h-20); 149 } else { 150 li.childcontent_inner.setStyle ('margin-top', -li._h-20); 151 } 152 153 } else { 154 li.childcontent_inner.setStyle ('margin-left', -li._w-20); 155 } 156 } 157 if (this.options.fading) { 158 li.childcontent_inner.setStyle ('opacity', 0); 159 } 160 //Init Fx.Styles for childcontent 161 li.fx = new Fx.Styles(li.childcontent_inner, {duration: this.options.duration, transition: this.options.transition, onComplete: this.itemAnimDone.bind(this, li)}); 162 //effect 163 li.eff_on = {}; 164 li.eff_off = {}; 165 if (this.options.slide) { 166 if (li.level0) { 167 if (this.options.direction == 'up') { 168 li.eff_on ['bottom'] = 0; 169 li.eff_off ['bottom'] = -li._h; 170 } else { 171 li.eff_on ['margin-top'] = 0; 172 li.eff_off ['margin-top'] = -li._h; 173 } 174 } else { 175 li.eff_on['margin-left'] = 0; 176 li.eff_off['margin-left'] = -li._w; 177 } 178 } 179 if (this.options.fading) { 180 li.eff_on['opacity'] = 1; 181 li.eff_off['opacity'] = 0; 182 //li.eff_off['margin-top'] = -li._h; 183 } 184 } 185 186 if (this.options.action=='click') { 187 if (li.childcontent) { 188 li.addEvent('click', function(e) { 189 var event = new Event (e); 190 if (li.hasClass ('group')) return; 191 if (li.childcontent) { 192 if (li.status == 'open') { 193 if (this.cursorIn (li, event)) { 194 this.itemHide (li); 195 } else { 196 this.itemHideOthers(li); 197 } 198 } else { 199 this.itemShow (li); 200 } 201 } else { 202 if (li.a) location.href = li.a.href; 203 } 204 event.stop(); 205 }.bind (this)); 206 207 //If action is click, click on windows will close all submenus 208 this.windowClickFn = function (e) { 209 this.itemHideOthers(null); 210 }.bind (this); 211 } 212 li.addEvent('mouseenter', function(e) { 213 if (li.hasClass ('group')) return; 214 this.itemOver (li); 215 //e.stop(); 216 }.bind (this)); 217 218 li.addEvent('mouseleave', function(e) { 219 if (li.hasClass ('group')) return; 220 this.itemOut (li); 221 //e.stop(); 222 }.bind (this)); 223 } 224 225 if (this.options.action == 'mouseover' || this.options.action == 'mouseenter') { 226 li.addEvent('mouseenter', function(e) { 227 if (li.hasClass ('group')) return; 228 $clear (li.timer); 229 this.itemShow (li); 230 e.stop(); 231 }.bind (this)); 232 233 li.addEvent('mouseleave', function(e) { 234 if (li.hasClass ('group')) return; 235 $clear (li.timer); 236 if (li.childcontent) li.timer = setTimeout(this.itemHide.bind(this, [li, e]), this.options.delayHide); 237 else this.itemHide (li, e); 238 e.stop(); 239 }.bind (this)); 240 } 241 242 //when click on a link - close all open childcontent 243 if (li.a && !li.childcontent) { 244 li.a.addEvent ('click',function (e){ 245 this.itemHideOthers (null); 246 //Remove current class 247 this.menu.getElements ('.active').removeClass ('active'); 248 //Add current class 249 var p = li; 250 while (p) { 251 p.addClass ('active'); 252 p.a.addClass ('active'); 253 p = p._parent; 254 } 255 //new Event (e).stop(); 256 }.bind (this)); 257 } 258 },this); 259 260 if (this.options.slide || this.options.fading) { 261 //hide all content child 262 //this.menu.getElements('.childcontent').setStyle ('display', 'none'); 263 this.menu.getElements('.childcontent').setStyle ('left', -9999); 264 } 265 266 //tooltips 267 if (this.options.tips) { 268 this.options.tips = this.buildTooltips (); 269 } 270 271 //Call onLoad 272 if (typeof (this.options.onLoad) == 'function') this.options.onLoad.call (this); 273 }, 274 275 position: function (li) { 276 if (li.childcontent) { 277 //fix position for level0 278 //hide it 279 if (li.status == 'close' && !this.options.slide && !this.options.fading) { 280 li.childcontent.setStyle ('left', -9999); 281 return ; 282 } 283 //show it 284 li.childcontent.setStyle ('left', 'auto'); 285 //reposition 286 287 var pos = $merge (li.getPosition(), {'w':li._w, 'h':li.childcontent.offsetHeight});
288 var maxx = window.getWidth(); //window width 289 //get x from content region 290 var main = $E('#ja-mainnav .main'); 291 var mainx = main.getPosition().x + main.offsetWidth; 292 if (maxx > mainx) maxx = mainx; 293 294 var win = {'x': maxx, 'y': window.getHeight()}; 295 var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()}; 296 297 if (li.level0) { 298 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); 299 } else { 300 //sub level 301 if (this.options.direction == 'up') { 302 li.childcontent.setStyle ('bottom', pos['y']+li.offsetHeight-pos['h'] - 20 < scroll ['y']?pos['y']+li.offsetHeight-pos['h'] - scroll ['y'] - 20:0); 303 } else { 304 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); 305 } 306 } 307 308 } 309 310 }, 311 312 getParent: function (li) { 313 var p = li; 314 while ((p=p.getParent())) { 315 if (this.items.contains (p) && !p.hasClass ('group')) return p; 316 if (!p || p == this.menu) return null; 317 } 318 }, 319 320 cursorIn: function (el, event) { 321 if (!el || !event) return false; 322 var pos = $merge (el.getPosition(), {'w':el.offsetWidth, 'h': el.offsetHeight});; 323 var cursor = {'x': event.page.x, 'y': event.page.y}; 324 325 if (cursor.x>pos.x && cursor.x<pos.x+el.offsetWidth 326 && cursor.y>pos.y && cursor.y<pos.y+el.offsetHeight) return true; 327 return false; 328 }, 329 330 isChild: function (child, parent) { 331 return !!parent.getChildren().contains (child); 332 }, 333 334 itemOver: function (li) { 335 if (li.hasClass ('haschild')) 336 li.removeClass ('haschild').addClass ('haschild-over'); 337 li.addClass ('over'); 338 if (li.a) { 339 li.a.addClass ('over'); 340 } 341 }, 342 343 itemOut: function (li) { 344 if (li.hasClass ('haschild-over')) 345 li.removeClass ('haschild-over').addClass ('haschild'); 346 li.removeClass ('over'); 347 if (li.a) { 348 li.a.removeClass ('over'); 349 } 350 }, 351 352 itemShow: function (li) { 353 clearTimeout(li.timer); 354 if (li.status == 'open') return; //don't need do anything 355 //Adjust position 356 //Setup the class 357 this.itemOver (li); 358 //Check if this is the first show 359 if (li.childcontent) { 360 var firstshow = true; 361 this.childopen.each (function (li) { 362 if (li.childcontent) firstshow = false; 363 }); 364 if (firstshow && typeof (this.options.onFirstShow) == 'function') { 365 this.options.onFirstShow.call (this, li); 366 } 367 } 368 //push to show queue 369 li.status = 'open'; 370 this.childopen.push (li); 371 //hide other 372 this.itemHideOthers (li); 373 if (li.childcontent) { 374 if (this.options.action=='click' && this.childopen.length && !this.windowClickEventAdded) { 375 //addEvent click for window 376 $(document.body).addEvent ('click', this.windowClickFn); 377 this.windowClickEventAdded = true; 378 } 379 //call event 380 if (typeof (this.options.onItemHide) == 'function') this.options.onItemHide.call (this, li); 381 } 382 383 this.position (li); 384 if (!$defined(li.fx) || !$defined(li.childcontent)) return; 385 386 li.childcontent.setStyle ('display', 'block'); 387 388 li.childcontent.setStyles ({'overflow': 'hidden'}); 389 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'}); 390 li.fx.stop(); 391 li.fx.start (li.eff_on); 392 //disable tooltip for this item 393 this.disableTooltip (li); 394 //if (li._parent) this.itemShow (li._parent); 395 }, 396 397 itemHide: function (li, e) { 398 if (e && e.page) { //if event 399 if (this.cursorIn (li, e) || this.cursorIn (li.childcontent, e)) { 400 return; 401 } //cursor in li 402 var p=li._parent; 403 if (p && !this.cursorIn (p, e) && !this.cursorIn(p.childcontent, e)) { 404 p.fireEvent ('mouseleave', e); //fire mouseleave event 405 } 406 } 407 clearTimeout(li.timer); 408 this.itemOut(li); 409 li.status = 'close'; 410 this.childopen.remove (li); 411 if (li.childcontent) { 412 if (this.options.action=='click' && !this.childopen.length && this.windowClickEventAdded) { 413 //removeEvent click for window 414 $(document.body).removeEvent ('click', this.windowClickFn); 415 this.windowClickEventAdded = false; 416 } 417 //call event 418 if (typeof (this.options.onItemShow) == 'function') this.options.onItemShow.call (this, li); 419 } 420 this.position (li); 421 if (!$defined(li.fx) || !$defined(li.childcontent)) return; 422 423 if (li.childcontent.getStyle ('opacity') == 0) return; 424 li.childcontent.setStyles ({'overflow': 'hidden'}); 425 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow': 'hidden'}); 426 li.fx.stop(); 427 switch (this.options.hidestyle) { 428 case 'fast': 429 li.fx.options.duration = 100;
430 li.fx.start ($merge(li.eff_off,{'opacity':0})); 431 break; 432 case 'fastwhenshow': //when other show 433 if (!e) { //force hide, not because of event => hide fast 434 li.fx.options.duration = 100; 435 li.fx.start ($merge(li.eff_off,{'opacity':0})); 436 } else { //hide as normal 437 li.fx.start (li.eff_off); 438 } 439 break; 440 case 'normal': 441 default: 442 li.fx.start (li.eff_off); 443 break; 444 } 445 //li.fx.start (li.eff_off); 446 }, 447 448 itemAnimDone: function (li) { 449 //hide done 450 if (li.status == 'close'){ 451 //reset duration and enable opacity if not fading 452 if (this.options.hidestyle.test (/fast/)) { 453 li.fx.options.duration = this.options.duration; 454 if (!this.options.fading) li.childcontent_inner.setStyle ('opacity', 1); 455 } 456 //hide 457 //li.childcontent.setStyles ({'display': 'none'}); 458 li.childcontent.setStyle ('left', -9999); 459 //enable tooltip 460 this.enableTooltip (li); 461 //call event 462 if (typeof (this.options.onItemHideComplete) == 'function') this.options.onItemHideComplete.call (this, li); 463 //Check if there's no child content shown, raise event onLastHide 464 var lasthide = true; 465 this.childopen.each (function (li) { 466 if (li.childcontent) lasthide = false; 467 }); 468 if (lasthide && typeof (this.options.onLastHide) == 'function') this.options.onLastHide.call (this, li); 469 } 470 471 //show done 472 if (li.status == 'open'){ 473 li.childcontent.setStyles ({'overflow': ''}); 474 if (li.childcontent_inner1.ol) li.childcontent_inner1.setStyles ({'overflow-y': 'auto'}); 475 if (typeof (this.options.onItemShowComplete) == 'function') this.options.onItemShowComplete.call (this, li); 476 } 477 }, 478 479 itemHideOthers: function (el) { 480 var fakeevent = null 481 if (el && !el.childcontent) fakeevent = {}; 482 var curopen = this.childopen.copy(); 483 curopen.each (function(li) { 484 if (li && typeof (li.status) != 'undefined' && (!el || (li != el && !li.hasChild (el)))) { 485 this.itemHide(li, fakeevent); 486 } 487 },this); 488 }, 489 490 buildTooltips: function () { 491 this.tooltips = new Tips (this.menu.getElements ('.hasTipThumb'), {'className':'ja-toolbar-thumb', 'fixed':true, offsets:{'x':100, 'y': this.options.direction=='up'?-180:20}, 'direction': this.options.direction}); 492 this.tooltips2 = new Tips (this.menu.getElements ('.hasTipThumb2'), {'className':'ja-toolbar-thumb2', 'fixed':true, offsets:{'x':100, 'y': 20}, 'direction': this.options.direction}); 493 this.tooltips3 = new Tips (this.menu.getElements ('.hasTipThumb3'), {'className':'ja-toolbar-thumb3', 'fixed':true, offsets:{'x':100, 'y': 20}, 'direction': this.options.direction}); 494 return true; 495 }, 496 497 disableTooltip: function (el) { 498 if (this.options.tips) this.tooltips.disableTip(el); 499 return; 500 }, 501 502 enableTooltip: function (el) { 503 if (this.options.tips) this.tooltips.enableTip(el); 504 return; 505 } 506 507});
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.