1/** 2 * ------------------------------------------------------------------------ 3 * JA University Template for J25 & J32 4 * ------------------------------------------------------------------------ 5 * Copyright (C) 2004-2011 J.O.O.M Solutions Co., Ltd. All Rights Reserved. 6 * @license - Copyrighted Commercial Software 7 * Author: J.O.O.M Solutions Co., Ltd 8 * Websites: http://www.joomlart.com - http://www.joomlancers.com 9 * This file may not be redistributed in whole or significant part. 10 * ------------------------------------------------------------------------ 11 */ 12var JRMenu = window.JRMenu || {}; 13var jaMegaMenuMoo = new Class({ 14 15 Implements: Options, 16 17 options: { 18 slide: 0, //enable slide 19 duration: 300, //slide speed. lower for slower, bigger for faster 20 fading: 0, //Enable fading 21 bgopacity: 0.9, //set the transparent background. 0 to disable, 0<bgopacity<1: the opacity of the background 22 delayHide: 500, 23 direction: 'down', 24 action: 'mouseenter', //mouseenter or click 25 hidestyle: 'normal', 26 offset: -5, 27 fixArrow: false 28 }, 29 30 toElement: function () { 31 return this.menu; 32 }, 33 34 initialize: function (menu, options) { 35 this.menu = $(menu); 36 if (!this.menu) { 37 return; 38 } 39 this.setOptions(options); 40 41 //ignore delayHide if no animation 42 if (!this.options.slide && !this.options.fading) { 43 this.options.delayHide = 10; 44 } 45 46 JRMenu.inst = this; 47 this.menu.addClass('mm-enable'); 48 this.childopen = []; 49 this.imgloaded = false; 50 this.loaded = false; 51 this.addnavbtn(); 52 this.prepare(); 53 }, 54 55 addnavbtn: function(){ 56 57 if (!(Browser.ie && Browser.version < 9)) { 58 var jlevel0 = this.menu.getElement('ul.level0'); 59 if(jlevel0){ 60 var jmega = this.menu, 61 jbutton = new Element ('div', {id:'ja-menu-button', html: 'Navigation', styles: { display: 'none'}}).inject (jmega, 'before'); 62 63 jbutton.addEvent('click', function(e){ 64 e.stop(); 65 66 if(jmega.getStyle('display') == 'block'){ 67 jmega.removeClass('active').setStyle('display', 'none'); 68 jbutton.removeClass('active'); 69 } else { 70 jmega.addClass('active').setStyle('display', 'block'); 71 jbutton.addClass('active'); 72 } 73 }); 74 75 $(document).addEvent('click', function(){ 76 if(!jmega.hasClass('mm-enable')){ 77 jmega.removeClass('active').setStyle('display', 'none'); 78 } 79 80 jbutton.removeClass('active'); 81 }); 82 } 83 84 JRMenu.mmenuid = null; 85 window.addEvent('resize', function(){ 86 clearTimeout(JRMenu.mmenuid); 87 JRMenu.mmenuid = setTimeout(function(){JRMenu.inst.start();}, 100); 88 }); 89 } 90 }, 91 92 prepare: function () { 93 //preload images 94 var imgElms = this.menu.getElements('img'); 95 if (imgElms.length && !this.imgloaded) { 96 var imgSrcs = []; 97 imgElms.each(function (image) { 98 imgSrcs.push(image.src) 99 }); 100 101 new Asset.images(imgSrcs, { 102 onComplete: function () { 103 this.imgloaded = true; 104 this.start(); 105 }.bind(this) 106 }); 107 108 //call this start if cannot load image after sometime 109 setTimeout(function(){ 110 this.imgloaded = true; 111 this.start(); 112 }.bind(this), 3000); 113 } else { 114 window.addEvent('load', function(){ 115 this.imgloaded = true; 116 this.start(); 117 }.bind(this)); 118 } 119 }, 120 121 detect: function(){ 122 var jbutton = $('ja-menu-button'), 123 rs = true; 124 125 if(jbutton){ 126 rs = jbutton.getComputedStyle('display') == 'none'; 127 if(rs != this.menu.hasClass('mm-enable')){ 128 this.menu[rs ? 'addClass' : 'removeClass']('mm-enable'); 129 this.menu.setStyle('display', rs ? 'block' : 'none'); 130 } 131 } 132 133 return rs; 134 }, 135 start: function () { 136 //init once 137 if (!this.detect() || !this.imgloaded || this.loaded) { 138 return; 139 } 140 141 this.loaded = true; 142 this.zindex = 1000; 143 144 //get wrapper 145 var pw = this.menu; 146 while (pw = pw.getParent()) { 147 if (pw.hasClass('main') || pw.hasClass('wrap')) { 148 this.wrapper = pw; 149 break; 150 } 151 } 152 153 this.items = this.menu.getElements('li.mega'); 154 this.items.each(function (li) { 155 //link item 156 var link = li.getChildren('a.mega')[0], 157 child = li.getChildren('.childcontent')[0], 158 level0 = li.getParent().hasClass('level0'), 159 parent = this.getParent(li), 160 item = { 161 stimer: null, 162 direction: ((level0 && this.options.direction == 'up') ? 0 : 1) 163 }; 164 165 //child content 166 if (child) { 167 var childwrap = child.getElement('.childcontent-inner-wrap'), 168 childinner = child.getElement('.childcontent-inner'), 169 width = childinner.getWidth(), 170 height = childinner.getHeight(), 171 padding = childwrap.getStyle('padding-left').toInt() + childwrap.getStyle('padding-right').toInt(), 172 overflow = false;
173 174 child.setStyles({ 175 width: width + 20, 176 height: height + 20 177 }); 178 179 childwrap.setStyle('width', width); 180 181 if (['auto', 'scroll'].contains(childinner.getStyle('overflow'))) { 182 overflow = true; 183 184 //fix for ie6/7 185 if (Browser.ie) { 186 if (Browser.version <= 7) { 187 childinner.setStyle('position', 'relative'); 188 } 189 190 if (Browser.version == 6) { 191 childinner.setStyle('height', childinner.getStyle('max-height') || 400); 192 } 193 } 194 } 195 196 //show direction 197 if (this.options.direction == 'up') { 198 if (level0) { 199 child.setStyle('top', -child.getHeight()); //ajust top position 200 } else { 201 child.setStyle('bottom', 0); 202 } 203 } 204 } 205 206 if (child && this.options.bgopacity) { 207 //Make transparent background 208 new Element('div', { 209 'class': 'childcontent-bg', 210 styles: { 211 width: '100%', 212 height: height, 213 opacity: this.options.bgopacity, 214 position: 'absolute', 215 top: 0, 216 left: 0, 217 zIndex: 1, 218 background: child.getStyle('background'), 219 backgroundImage: child.getStyle('background-image'), 220 backgroundRepeat: child.getStyle('background-repeat'), 221 backgroundColor: child.getStyle('background-color') 222 } 223 }).inject(childwrap, 'top'); 224 225 child.setStyle('background', 'none'); 226 childwrap.setStyles({ 227 position: 'relative', 228 zIndex: 2 229 }); 230 } 231 232 if (child && (this.options.slide || this.options.fading)) { 233 234 if (child.hasClass('right')) { 235 child.setStyle('right', 0); 236 } 237 238 //init Fx.Styles for childcontent 239 var fx = new Fx.Morph(childwrap, { 240 duration: this.options.duration, 241 transition: Fx.Transitions.linear, 242 onComplete: this.itemAnimDone.bind(this, item), 243 link: 'cancel' 244 }), 245 stylesOn = {}; 246 247 if (this.options.slide) { 248 if (level0) { 249 stylesOn[item.direction == 1 ? 'margin-top' : 'bottom'] = 0; 250 } else { 251 stylesOn[window.isRTL ? 'margin-right' : 'margin-left'] = 0; 252 } 253 } 254 if (this.options.fading) { 255 stylesOn['opacity'] = 1; 256 } 257 } 258 259 if (child && this.options.action == 'click') { 260 li.addEvent('click', function (e) { 261 e.stopPropagation(); 262 263 if (li.hasClass('group')) { 264 return; 265 } 266 267 if (item.status == 'open') { 268 if (this.cursorIn(li, e)) { 269 this.itemHide(item); 270 } else { 271 this.hideOthers(li); 272 } 273 } else { 274 this.itemShow(item); 275 } 276 }.bind(this)); 277 } 278 279 if (this.options.action == 'mouseover' || this.options.action == 'mouseenter') { 280 li.addEvent('mouseover', function (e) { 281 if (li.hasClass('group')) { 282 return; 283 } 284 285 e.stop(); 286 287 clearTimeout(item.stimer); 288 clearTimeout(this.atimer); 289 290 this.intent(item, 'open'); 291 this.itemShow(item); 292 293 }.bind(this)) 294 295 .addEvent('mouseleave', function (e) { 296 if (li.hasClass('group')) { 297 return; 298 } 299 300 clearTimeout(item.stimer); 301 302 this.intent(item, 'close'); 303 if (child) { 304 item.stimer = this.itemHide.delay(this.options.delayHide, this, [item]); 305 } else { 306 this.itemHide(item); 307 } 308 }.bind(this)); 309 310 //if has childcontent, don't goto link before open childcontent - fix for touch screen 311 if (link && child) { 312 link.addEvent('click', function (e) { 313 if (!item.clickable) { 314 e.stop(); 315 } 316 }); 317 } 318 319 //stop if click on menu item - prevent raise event to container => hide all open submenu 320 li.addEvent('click', function (e) { 321 e.stopPropagation() 322 }); 323 324 if (child) { 325 child.addEvent('mouseover', function () { 326 clearTimeout(item.stimer); 327 clearTimeout(this.atimer); 328 329 this.intent(item, 'open'); 330 this.itemShow(item); 331 }.bind(this)).addEvent('mouseleave', function (e) { 332 e.stop(); 333 334 this.intent(item, 'close'); 335 clearTimeout(item.stimer); 336 337 if (!this.cursorIn(item.el, e)) { 338 this.atimer = this.hideAlls.delay(this.options.delayHide, this); 339 } 340 }.bind(this)) 341 } 342 } 343 344 //when click on a link - close all open childcontent 345 if (link && !child) { 346 link.addEvent('click', function (e) { 347 e.stopPropagation(); //prevent to raise event up 348 this.hideOthers(null); 349 //Remove current class 350 this.menu.getElements('.active').removeClass('active'); 351 352 //Add current class 353 var p = li; 354 while (p) { 355 var idata = p.retrieve('item'); 356 357 p.addClass('active'); 358 idata.link.addClass('active'); 359 p = idata.parent; 360 } 361 }.bind(this)); 362 } 363 364 Object.append(item, { 365 el: li, 366 parent: parent, 367 link: link, 368 child: child, 369 childwrap: childwrap, 370 childinner: childinner, 371 width: width, 372 height: height, 373 padding: padding, 374 level0: level0, 375 fx: fx, 376 stylesOn: stylesOn, 377 overflow: overflow, 378 clickable: !(link && child) 379 }); 380 381 li.store('item', item); 382 }, this); 383 384 //click on windows will close all submenus 385 var container = $('ja-wrapper'); 386 if (!container) { 387 container = document.body; 388 } 389 390 container.addEvent('click', function (e) { 391 this.hideAlls(); 392 }.bind(this)); 393 394 this.menu.getElements('.childcontent').setStyle('display', 'none'); 395 }, 396 397 getParent: function (el) { 398 var p = el; 399 while ((p = p.getParent())) { 400 if (this.items.contains(p) && !p.hasClass('group')) { 401 return p; 402 } 403 404 if (!p || p == this.menu) { 405 return null; 406 } 407 } 408 }, 409 410 intent: function (item, action) { 411 item.intent = action; 412 413 while (item.parent && (item = item.parent.retrieve('item'))) { 414 item.intent = action; 415 } 416 }, 417 418 cursorIn: function (el, event) { 419 if (!el || !event) { 420 return false;
421 } 422 423 var pos = el.getPosition(), 424 cursor = event.page; 425 426 return (cursor.x > pos.x && cursor.x < pos.x + el.getWidth() && cursor.y > pos.y && cursor.y < pos.y + el.getHeight()); 427 }, 428 429 itemOver: function (item) { 430 item.el.addClass('over'); 431 432 if (item.el.hasClass('haschild')) { 433 item.el.removeClass('haschild').addClass('haschild-over'); 434 } 435 436 if (item.link) { 437 item.link.addClass('over'); 438 } 439 }, 440 441 itemOut: function (item) { 442 item.el.removeClass('over'); 443 444 if (item.el.hasClass('haschild-over')) { 445 item.el.removeClass('haschild-over').addClass('haschild'); 446 } 447 448 if (item.link) { 449 item.link.removeClass('over'); 450 } 451 }, 452 453 itemShow: function (item) { 454 if(!this.menu.hasClass('mm-enable')){ 455 return; 456 } 457 458 if(this.childopen.indexOf(item) < this.childopen.length -1){ 459 this.hideOthers(item.el); 460 } 461 if (item.status == 'open') { 462 return; //don't need do anything 463 } 464 465 //Setup the class 466 this.itemOver(item); 467 468 //push to show queue 469 if (item.level0) { 470 this.childopen.length = 0; 471 } 472 473 if (item.child) { 474 this.childopen.push(item); 475 } 476 477 item.intent = 'open'; 478 item.status = 'open'; 479 480 this.enableclick.delay(100, this, item); 481 482 if (item.child) { 483 //reposition the submenu 484 this.positionSubmenu(item); 485 486 if (item.fx && !item.stylesOff) { 487 item.stylesOff = {}; 488 if (this.options.slide) { 489 if (item.level0) { 490 item.stylesOff[item.direction == 1 ? 'margin-top' : 'bottom'] = -item.height; 491 } else { 492 item.stylesOff[window.isRTL ? 'margin-right' : 'margin-left'] = (item.direction == 1 ? -item.width : item.width); 493 } 494 } 495 if (this.options.fading) { 496 item.stylesOff['opacity'] = 0; 497 } 498 item.fx.set(item.stylesOff); 499 } 500 501 item.child.setStyles({ 502 display: 'block', 503 zIndex: this.zindex++ 504 }); 505 } 506 507 if (!item.fx || !item.child) { 508 return; 509 } 510 511 item.child.setStyle('overflow', 'hidden'); 512 if (item.overflow) { 513 item.childinner.setStyle('overflow', 'hidden'); 514 } 515 516 item.fx.start(item.stylesOn); 517 }, 518 519 itemHide: function (item) { 520 if(!this.menu.hasClass('mm-enable')){ 521 return; 522 } 523 524 clearTimeout(item.stimer); 525 526 item.status = 'close'; 527 item.intent = 'close'; 528 529 this.itemOut(item); 530 this.childopen.erase(item); 531 532 if (!item.fx && item.child) { 533 item.child.setStyle('display', 'none'); 534 } 535 536 if (!item.fx || !item.child || item.child.getStyle('opacity') == '0') { 537 return; 538 } 539 540 item.child.setStyle('overflow', 'hidden'); 541 if (item.overflow) { 542 item.childinner.setStyle('overflow', 'hidden'); 543 } 544 545 switch (this.options.hidestyle) { 546 case 'fast': 547 item.fx.options.duration = 100; 548 item.fx.start(item.stylesOff); 549 break; 550 case 'fastwhenshow': 551 item.fx.start(Object.merge(item.stylesOff, { 552 'opacity': 0 553 })); 554 break; 555 case 'normal': 556 default: 557 item.fx.start(item.stylesOff); 558 break; 559 } 560 }, 561 562 itemAnimDone: function (item) { 563 //hide done 564 if (item.status == 'close') { 565 //reset duration and enable opacity if not fading 566 if (this.options.hidestyle.test(/fast/)) { 567 item.fx.options.duration = this.options.duration; 568 if (!this.options.fading) { 569 item.childwrap.setStyle('opacity', 1); 570 } 571 } 572 //hide 573 item.child.setStyle('display', 'none'); 574 this.disableclick.delay(100, this, item); 575 576 var pitem = item.parent ? item.parent.retrieve('item') : null; 577 if (pitem && pitem.intent == 'close') { 578 this.itemHide(pitem); 579 } 580 } 581 582 //show done 583 if (item.status == 'open') { 584 item.child.setStyle('overflow', ''); 585 if (item.overflow) { 586 item.childinner.setStyle('overflow-y', 'auto'); 587 } 588 589 item.childwrap.setStyle('opacity', 1); 590 item.child.setStyle('display', 'block'); 591 } 592 }, 593 594 hideOthers: function (el) { 595 this.childopen.each(function (item) { 596 if (!el || (item.el != el && !item.el.contains(el))) { 597 item.intent = 'close'; 598 } 599 }); 600 601 var last = this.childopen.getLast(); 602 if (last && last.intent == 'close') { 603 this.itemHide(last); 604 } 605 }, 606 607 hideAlls: function (el) { 608 this.childopen.flatten().each(function (item) { 609 if (!item.fx) { 610 this.itemHide(item); 611 } else { 612 item.intent = 'close'; 613 } 614 }, this); 615 616 if (this.options.slide || this.options.fading) { 617 var last = this.childopen.getLast(); 618 if (last && last.intent == 'close') { 619 this.itemHide(last); 620 } 621 } 622 }, 623 624 enableclick: function (item) { 625 if (item.link && item.child) { 626 item.clickable = true; 627 } 628 }, 629 630 disableclick: function (item) { 631 item.clickable = false;
632 }, 633 634 positionSubmenu: function (item) { 635 var options = this.options, offsleft, offstop, left, top, stylesOff = {}, 636 icoord = item.el.getCoordinates(), 637 bodySize = $(document.body).getScrollSize(), 638 winRect = { 639 top: window.getScrollTop(), 640 left: window.getScrollLeft(), 641 width: window.getWidth(), 642 height: window.getHeight() 643 }, 644 wrapRect = this.wrapper ? this.wrapper.getCoordinates() : { 645 top: 0, 646 left: 0, 647 width: winRect.width, 648 height: winRect.height 649 }; 650 651 winRect.top = Math.max(winRect.top, wrapRect.top); 652 winRect.left = Math.max(winRect.left, wrapRect.left); 653 winRect.width = Math.min(winRect.width, wrapRect.width); 654 winRect.height = Math.min(winRect.height, $(document.body).getScrollHeight()); 655 winRect.right = winRect.left + winRect.width; 656 winRect.bottom = winRect.top + winRect.height; 657 658 if (!item.level0) { 659 var pitem = item.parent.retrieve('item'), 660 offsety = parseFloat(pitem.child.getFirst().getStyle('margin-top')), 661 offsetx = parseFloat(pitem.child.getFirst().getStyle(window.isRTL ? 'margin-right' : 'margin-left')); 662 663 item.direction = pitem.direction; 664 665 window.isRTL && (offsetx = 0 - offsetx); 666 icoord.top -= offsety; 667 icoord.bottom -= offsety; 668 icoord.left -= offsetx; 669 icoord.right -= offsetx; 670 } 671 672 if (item.level0) { 673 if (window.isRTL) { 674 offsleft = Math.max(winRect.left, icoord.right - item.width - 20); 675 left = Math.max(0, offsleft - winRect.left); 676 } else { 677 offsleft = Math.max(winRect.left, Math.min(winRect.right - item.width, icoord.left)); 678 left = Math.max(0, Math.min(winRect.right - item.width, icoord.left) - winRect.left); 679 } 680 } else { 681 if (window.isRTL) { 682 if (item.direction == 1) { 683 offsleft = icoord.left - item.width - 20 + options.offset; 684 left = -icoord.width - 20; 685 686 if (offsleft < winRect.left) { 687 item.direction = 0; 688 offsleft = Math.min(winRect.right, Math.max(winRect.left, icoord.right + item.padding - 20 - options.offset)); 689 left = icoord.width - 20; 690 stylesOff['margin-right'] = item.width; 691 } 692 } else { 693 offsleft = icoord.right + item.padding - 20; 694 left = icoord.width - 20; 695 696 if (offsleft + item.width > winRect.right) { 697 item.direction = 1; 698 offsleft = Math.max(winRect.left, icoord.left - item.width - 20); 699 left = -icoord.width - 20; 700 stylesOff['margin-right'] = -item.width; 701 } 702 } 703 } else { 704 705 if (item.direction == 1) { 706 offsleft = icoord.right - options.offset; 707 left = icoord.width; 708 709 if (offsleft + item.width > winRect.right) { 710 item.direction = 0; 711 offsleft = Math.max(winRect.left, icoord.left - item.width - item.padding + options.offset); 712 left = -icoord.width; 713 stylesOff['margin-left'] = item.width; 714 } 715 } else { 716 offsleft = icoord.left - item.width - item.padding + options.offset; 717 left = -icoord.width; 718 719 if (offsleft < winRect.left) { 720 item.direction = 1; 721 offsleft = Math.max(winRect.left, Math.min(winRect.right - item.width, icoord.right - options.offset)); 722 left = icoord.width; 723 stylesOff['margin-left'] = -item.width; 724 } 725 } 726 } 727 } 728 729 if (options.slide && item.fx && Object.getLength(stylesOff)) { 730 item.fx.set(stylesOff); 731 } 732 733 // Teline IV 734 if (options.fixArrow && item.childinner) { 735 item.childinner.setStyle('background-position', (icoord.left - offsleft + (icoord.width / 2 - 4.5)) + 'px top'); 736 } 737 738 var oldp = item.child.getStyle('display'); 739 item.child.setStyle('display', 'block'); 740 if (item.child.getOffsetParent()) { 741 left = offsleft - item.child.getOffsetParent().getCoordinates().left; 742 } 743 item.child.setStyles({ 744 'margin-left': 0, 745 'left': left, 746 'display': oldp 747 }); 748 } 749});
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.