1/* 2 * jQuery mmenu v4.1.0 3 * @requires jQuery 1.7.0 or later 4 * 5 * mmenu.frebsite.nl 6 * 7 * Copyright (c) Fred Heusschen 8 * www.frebsite.nl 9 * 10 * Dual licensed under the MIT and GPL licenses. 11 * http://en.wikipedia.org/wiki/MIT_License 12 * http://en.wikipedia.org/wiki/GNU_General_Public_License 13 */ 14 15 16(function( $ ) { 17 18 var _PLUGIN_ = 'mmenu', 19 _VERSION_ = '4.1.0'; 20 21 22 // Plugin already excists 23 if ( $[ _PLUGIN_ ] ) 24 { 25 return; 26 } 27 28 // Global variables 29 var glbl = { 30 $wndw: null, 31 $html: null, 32 $body: null, 33 $page: null, 34 $blck: null, 35 36 $allMenus: null, 37 $scrollTopNode: null 38 }; 39 40 var _c = {}, _e = {}, _d = {}, 41 _serialnr = 0; 42 43 44 $[ _PLUGIN_ ] = function( $menu, opts, conf ) 45 { 46 glbl.$allMenus = glbl.$allMenus.add( $menu ); 47 48 this.$menu = $menu; 49 this.opts = opts 50 this.conf = conf; 51 52 this.serialnr = _serialnr++; 53 54 this._init(); 55 56 return this; 57 }; 58 59 $[ _PLUGIN_ ].prototype = { 60 61 open: function() 62 { 63 this._openSetup(); 64 this._openFinish(); 65 return 'open'; 66 }, 67 _openSetup: function() 68 { 69 // Find scrolltop 70 var _scrollTop = findScrollTop(); 71 72 // Set opened 73 this.$menu.addClass( _c.current ); 74 75 // Close others 76 glbl.$allMenus.not( this.$menu ).trigger( _e.close ); 77 78 // Store style and position 79 glbl.$page 80 .data( _d.style, glbl.$page.attr( 'style' ) || '' ) 81 .data( _d.scrollTop, _scrollTop ) 82 .data( _d.offetLeft, glbl.$page.offset().left ); 83 84 // Resize page to window width 85 var _w = 0; 86 glbl.$wndw.off( _e.resize ) 87 .on( _e.resize, 88 function( e, force ) 89 { 90 if ( glbl.$html.hasClass( _c.opened ) || force ) 91 { 92 var nw = glbl.$wndw.width(); 93 if ( nw != _w ) 94 { 95 _w = nw; 96 glbl.$page.width( nw - glbl.$page.data( _d.offetLeft ) ); 97 } 98 } 99 } 100 ) 101 .trigger( _e.resize, [ true ] ); 102 103 // Prevent tabbing out of the menu 104 if ( this.conf.preventTabbing ) 105 { 106 glbl.$wndw.off( _e.keydown ) 107 .on( _e.keydown, 108 function( e ) 109 { 110 if ( e.keyCode == 9 ) 111 { 112 e.preventDefault(); 113 return false; 114 } 115 } 116 ); 117 } 118 119 // Add options 120 if ( this.opts.modal ) 121 { 122 glbl.$html.addClass( _c.modal ); 123 } 124 if ( this.opts.moveBackground ) 125 { 126 glbl.$html.addClass( _c.background ); 127 } 128 if ( this.opts.position != 'left' ) 129 { 130 glbl.$html.addClass( _c.mm( this.opts.position ) ); 131 } 132 if ( this.opts.zposition != 'back' ) 133 { 134 glbl.$html.addClass( _c.mm( this.opts.zposition ) ); 135 } 136 if ( this.opts.classes ) 137 { 138 glbl.$html.addClass( this.opts.classes ); 139 } 140 141 // Open 142 glbl.$html.addClass( _c.opened ); 143 this.$menu.addClass( _c.opened ); 144 145 // Scroll page to scrolltop 146 glbl.$page.scrollTop( _scrollTop ); 147 148 // Scroll menu to top 149 this.$menu.scrollTop( 0 ); 150 }, 151 _openFinish: function() 152 { 153 var that = this; 154 155 // Callback 156 transitionend( glbl.$page, 157 function() 158 { 159 that.$menu.trigger( _e.opened ); 160 }, this.conf.transitionDuration 161 ); 162 163 // Opening 164 glbl.$html.addClass( _c.opening ); 165 this.$menu.trigger( _e.opening ); 166 167 // Scroll window to top 168 window.scrollTo( 0, 1 ); 169 }, 170 close: function() 171 { 172 var that = this; 173 174 // Callback 175 transitionend( glbl.$page, 176 function() 177 { 178 that.$menu 179 .removeClass( _c.current ) 180 .removeClass( _c.opened ); 181 182 glbl.$html 183 .removeClass( _c.opened ) 184 .removeClass( _c.modal ) 185 .removeClass( _c.background ) 186 .removeClass( _c.mm( that.opts.position ) ) 187 .removeClass( _c.mm( that.opts.zposition ) ); 188 189 if ( that.opts.classes ) 190 { 191 glbl.$html.removeClass( that.opts.classes ); 192 } 193 194 glbl.$wndw 195 .off( _e.resize ) 196 .off( _e.keydown ); 197 198 // Restore style and position 199 glbl.$page.attr( 'style', glbl.$page.data( _d.style ) ); 200 201 if ( glbl.$scrollTopNode ) 202 { 203 glbl.$scrollTopNode.scrollTop( glbl.$page.data( _d.scrollTop ) ); 204 } 205 206 // Closed 207 that.$menu.trigger( _e.closed ); 208 209 }, this.conf.transitionDuration 210 ); 211 212 // Closing 213 glbl.$html.removeClass( _c.opening ); 214 this.$menu.trigger( _e.closing ); 215 216 return 'close'; 217 }, 218 219 _init: function() 220 { 221 this.opts = extendOptions( this.opts, this.conf, this.$menu ); 222 this.direction = ( this.opts.slidingSubmenus ) ? 'horizontal' : 'vertical'; 223 224 // INIT PAGE & MENU 225 this._initPage( glbl.$page ); 226 this._initMenu(); 227 this._initBlocker(); 228 this._initPanles(); 229 this._initLinks(); 230 this._initOpenClose(); 231 this._bindCustomEvents(); 232 233 if ( $[ _PLUGIN_ ].addons ) 234 { 235 for ( var a = 0; a < $[ _PLUGIN_ ].addons.length; a++ ) 236 { 237 if ( typeof this[ '_addon_' + $[ _PLUGIN_ ].addons[ a ] ] == 'function' ) 238 { 239 this[ '_addon_' + $[ _PLUGIN_ ].addons[ a ] ](); 240 } 241 } 242 } 243 }, 244 245 _bindCustomEvents: function() 246 { 247 var that = this; 248 249 this.$menu 250 .off( _e.open + ' ' + _e.close + ' ' + _e.setPage+ ' ' + _e.update ) 251 .on( _e.open + ' ' + _e.close + ' ' + _e.setPage+ ' ' + _e.update, 252 function( e ) 253 { 254 e.stopPropagation(); 255 } 256 ); 257 258 // Menu-events 259 this.$menu 260 .on( _e.open, 261 function( e ) 262 { 263 if ( $(this).hasClass( _c.current ) ) 264 { 265 e.stopImmediatePropagation(); 266 return false;
267 } 268 return that.open(); 269 } 270 ) 271 .on( _e.close, 272 function( e ) 273 { 274 if ( !$(this).hasClass( _c.current ) ) 275 { 276 e.stopImmediatePropagation(); 277 return false; 278 } 279 return that.close(); 280 } 281 ) 282 .on( _e.setPage, 283 function( e, $p ) 284 { 285 that._initPage( $p ); 286 that._initOpenClose(); 287 } 288 ); 289 290 // Panel-events 291 var $panels = this.$menu.find( this.opts.isMenu && this.direction != 'horizontal' ? 'ul, ol' : '.' + _c.panel ); 292 $panels 293 .off( _e.toggle + ' ' + _e.open + ' ' + _e.close ) 294 .on( _e.toggle + ' ' + _e.open + ' ' + _e.close, 295 function( e ) 296 { 297 e.stopPropagation(); 298 } 299 ); 300 301 if ( this.direction == 'horizontal' ) 302 { 303 $panels 304 .on( _e.open, 305 function( e ) 306 { 307 return openSubmenuHorizontal( $(this), that.$menu ); 308 } 309 ); 310 } 311 else 312 { 313 $panels 314 .on( _e.toggle, 315 function( e ) 316 { 317 var $t = $(this); 318 return $t.triggerHandler( $t.parent().hasClass( _c.opened ) ? _e.close : _e.open ); 319 } 320 ) 321 .on( _e.open, 322 function( e ) 323 { 324 $(this).parent().addClass( _c.opened ); 325 return 'open'; 326 } 327 ) 328 .on( _e.close, 329 function( e ) 330 { 331 $(this).parent().removeClass( _c.opened ); 332 return 'close'; 333 } 334 ); 335 } 336 }, 337 338 _initBlocker: function() 339 { 340 var that = this; 341 342 if ( !glbl.$blck ) 343 { 344 glbl.$blck = $( '<div id="' + _c.blocker + '" />' ).appendTo( glbl.$body ); 345 } 346 347 click( glbl.$blck, 348 function() 349 { 350 if ( !glbl.$html.hasClass( _c.modal ) ) 351 { 352 that.$menu.trigger( _e.close ); 353 } 354 }, true, true 355 ); 356 }, 357 _initPage: function( $p ) 358 { 359 if ( !$p ) 360 { 361 $p = $(this.conf.pageSelector, glbl.$body); 362 if ( $p.length > 1 ) 363 { 364 $[ _PLUGIN_ ].debug( 'Multiple nodes found for the page-node, all nodes are wrapped in one <' + this.conf.pageNodetype + '>.' ); 365 $p = $p.wrapAll( '<' + this.conf.pageNodetype + ' />' ).parent(); 366 } 367 } 368 369 $p.addClass( _c.page ); 370 glbl.$page = $p; 371 }, 372 _initMenu: function() 373 { 374 var that = this; 375 376 // Clone if needed 377 if ( this.conf.clone ) 378 { 379 this.$menu = this.$menu.clone( true ); 380 this.$menu.add( this.$menu.find( '*' ) ).filter( '[id]' ).each( 381 function() 382 { 383 $(this).attr( 'id', _c.mm( $(this).attr( 'id' ) ) ); 384 } 385 ); 386 } 387 388 // Strip whitespace 389 this.$menu.contents().each( 390 function() 391 { 392 if ( $(this)[ 0 ].nodeType == 3 ) 393 { 394 $(this).remove(); 395 } 396 } 397 ); 398 399 // Prepend to body 400 this.$menu 401 .prependTo( 'body' ) 402 .addClass( _c.menu ); 403 404 // Add direction class 405 this.$menu.addClass( _c.mm( this.direction ) ); 406 407 // Add options classes 408 if ( this.opts.classes ) 409 { 410 this.$menu.addClass( this.opts.classes ); 411 } 412 if ( this.opts.isMenu ) 413 { 414 this.$menu.addClass( _c.ismenu ); 415 } 416 if ( this.opts.position != 'left' ) 417 { 418 this.$menu.addClass( _c.mm( this.opts.position ) ); 419 } 420 if ( this.opts.zposition != 'back' ) 421 { 422 this.$menu.addClass( _c.mm( this.opts.zposition ) ); 423 } 424 }, 425 _initPanles: function() 426 { 427 var that = this; 428 429 430 // Refactor List class 431 this.__refactorClass( $('.' + this.conf.listClass, this.$menu), 'list' ); 432 433 // Add List class 434 if ( this.opts.isMenu ) 435 { 436 $('ul, ol', this.$menu) 437 .not( '.mm-nolist' ) 438 .addClass( _c.list ); 439 } 440 441 var $lis = $('.' + _c.list + ' > li', this.$menu); 442 443 // Refactor Selected class 444 this.__refactorClass( $lis.filter( '.' + this.conf.selectedClass ), 'selected' ); 445 446 // Refactor Label class 447 this.__refactorClass( $lis.filter( '.' + this.conf.labelClass ), 'label' ); 448 449 // Refactor Spacer class 450 this.__refactorClass( $lis.filter( '.' + this.conf.spacerClass ), 'spacer' ); 451 452 // setSelected-event 453 $lis 454 .off( _e.setSelected ) 455 .on( _e.setSelected, 456 function( e, selected ) 457 { 458 e.stopPropagation(); 459 460 $lis.removeClass( _c.selected ); 461 if ( typeof selected != 'boolean' ) 462 { 463 selected = true; 464 } 465 if ( selected ) 466 { 467 $(this).addClass( _c.selected ); 468 } 469 } 470 ); 471 472 // Refactor Panel class 473 this.__refactorClass( $('.' + this.conf.panelClass, this.$menu), 'panel' ); 474 475 // Add Panel class 476 this.$menu 477 .children() 478 .filter( this.conf.panelNodetype ) 479 .add( this.$menu.find( '.' + _c.list ).children().children().filter( this.conf.panelNodetype ) ) 480 .addClass( _c.panel ); 481 482 var $panels = $('.' + _c.panel, this.$menu); 483 484 // Add an ID to all panels 485 $panels 486 .each( 487 function( i ) 488 { 489 var $t = $(this), 490 id = $t.attr( 'id' ) || _c.mm( 'm' + that.serialnr + '-p' + i ); 491 492 $t.attr( 'id', id ); 493 } 494 ); 495 496 // Add open and close links to menu items 497 $panels 498 .find( '.' + _c.panel ) 499 .each( 500 function( i ) 501 { 502 var $t = $(this), 503 $u = $t.is( 'ul, ol' ) ? $t : $t.find( 'ul ,ol' ).first(), 504 $l = $t.parent(), 505 $a = $l.find( '> a, > span' ), 506 $p = $l.closest( '.' + _c.panel ); 507 508 $t.data( _d.parent, $l ); 509 510 if ( $l.parent().is( '.' + _c.list ) ) 511 { 512 var $btn = $( '<a class="' + _c.subopen + '" href="#' + $t.attr( 'id' ) + '" />' ).insertBefore( $a ); 513 if ( !$a.is( 'a' ) ) 514 { 515 $btn.addClass( _c.fullsubopen ); 516 } 517 if ( that.direction == 'horizontal' ) 518 {
519 $u.prepend( '<li class="' + _c.subtitle + '"><a class="' + _c.subclose + '" href="#' + $p.attr( 'id' ) + '">' + $a.text() + '</a></li>' ); 520 } 521 } 522 } 523 ); 524 525 // Link anchors to panels 526 var evt = this.direction == 'horizontal' ? _e.open : _e.toggle; 527 $panels 528 .each( 529 function( i ) 530 { 531 var $opening = $(this), 532 id = $opening.attr( 'id' ); 533 534 click( $('a[href="#' + id + '"]', that.$menu), 535 function( e ) 536 { 537 $opening.trigger( evt ); 538 } 539 ); 540 } 541 ); 542 543 if ( this.direction == 'horizontal' ) 544 { 545 // Add opened-classes 546 var $selected = $('.' + _c.list + ' > li.' + _c.selected, this.$menu); 547 $selected 548 .add( $selected.parents( 'li' ) ) 549 .parents( 'li' ).removeClass( _c.selected ) 550 .end().each( 551 function() 552 { 553 var $t = $(this), 554 $u = $t.find( '> .' + _c.panel ); 555 556 if ( $u.length ) 557 { 558 $t.parents( '.' + _c.panel ).addClass( _c.subopened ); 559 $u.addClass( _c.opened ); 560 } 561 } 562 ) 563 .closest( '.' + _c.panel ).addClass( _c.opened ) 564 .parents( '.' + _c.panel ).addClass( _c.subopened ); 565 } 566 else 567 { 568 // Replace Selected-class with opened-class in parents from .Selected 569 $('li.' + _c.selected, this.$menu) 570 .addClass( _c.opened ) 571 .parents( '.' + _c.selected ).removeClass( _c.selected ); 572 } 573 574 // Set current opened 575 var $current = $panels.filter( '.' + _c.opened ); 576 if ( !$current.length ) 577 { 578 $current = $panels.first(); 579 } 580 $current 581 .addClass( _c.opened ) 582 .last() 583 .addClass( _c.current ); 584 585 // Rearrange markup 586 if ( this.direction == 'horizontal' ) 587 { 588 $panels.find( '.' + _c.panel ).appendTo( this.$menu ); 589 } 590 }, 591 _initLinks: function() 592 { 593 var that = this; 594 595 var $a = $('.' + _c.list + ' > li > a', this.$menu) 596 .not( '.' + _c.subopen ) 597 .not( '.' + _c.subclose ) 598 .not( '[rel="external"]' ) 599 .not( '[target="_blank"]' ); 600 601 $a.off( _e.click ) 602 .on( _e.click, 603 function( e ) 604 { 605 var $t = $(this), 606 href = $t.attr( 'href' ); 607 608 609 // Set selected item 610 if ( that.__valueOrFn( that.opts.onClick.setSelected, $t ) ) 611 { 612 $t.parent().trigger( _e.setSelected ); 613 } 614 615 // Prevent default / don't follow link. Default: false 616 var preventDefault = that.__valueOrFn( that.opts.onClick.preventDefault, $t, href.slice( 0, 1 ) == '#' ); 617 if ( preventDefault ) 618 { 619 e.preventDefault(); 620 e.stopPropagation(); 621 } 622 623 // Block UI. Default: false if preventDefault, true otherwise 624 if ( that.__valueOrFn( that.opts.onClick.blockUI, $t, !preventDefault ) ) 625 { 626 glbl.$html.addClass( _c.blocking ); 627 } 628 629 // Close menu. Default: true if preventDefault, false otherwise 630 if ( that.__valueOrFn( that.opts.onClick.close, $t, preventDefault ) ) 631 { 632 that.$menu.triggerHandler( _e.close ); 633 } 634 } 635 ); 636 }, 637 _initOpenClose: function() 638 { 639 var that = this; 640 641 // Toggle menu 642 var id = this.$menu.attr( 'id' ); 643 if ( id && id.length ) 644 { 645 if ( this.conf.clone ) 646 { 647 id = _c.umm( id ); 648 } 649 650 click( $('a[href="#' + id + '"]'), 651 function() 652 { 653 that.$menu.trigger( _e.open ); 654 } 655 ); 656 } 657 658 // Close menu 659 var id = glbl.$page.attr( 'id' ); 660 if ( id && id.length ) 661 { 662 click( $('a[href="#' + id + '"]'), 663 function() 664 { 665 that.$menu.trigger( _e.close ); 666 }, false, true 667 ); 668 } 669 }, 670 671 __valueOrFn: function( o, $e, d ) 672 { 673 if ( typeof o == 'function' ) 674 { 675 return o.call( $e[ 0 ] ); 676 } 677 if ( typeof o == 'undefined' && typeof d != 'undefined' ) 678 { 679 return d; 680 } 681 return o; 682 }, 683 684 __refactorClass: function( $e, c ) 685 { 686 $e.removeClass( this.conf[ c + 'Class' ] ).addClass( _c[ c ] ); 687 } 688 }; 689 690 691 $.fn[ _PLUGIN_ ] = function( opts, conf ) 692 { 693 // First time plugin is fired 694 if ( !glbl.$wndw ) 695 { 696 _initPlugin(); 697 } 698 699 // Extend options 700 opts = extendOptions( opts, conf ); 701 conf = extendConfiguration( conf ); 702 703 return this.each( 704 function() 705 { 706 var $menu = $(this); 707 if ( $menu.data( _PLUGIN_ ) ) 708 { 709 return; 710 } 711 $menu.data( _PLUGIN_, new $[ _PLUGIN_ ]( $menu, opts, conf ) ); 712 } 713 ); 714 }; 715 716 $[ _PLUGIN_ ].version = _VERSION_; 717 718 $[ _PLUGIN_ ].defaults = { 719 position : 'left', 720 zposition : 'back',
721 moveBackground : true, 722 slidingSubmenus : true, 723 modal : false, 724 classes : '', 725 onClick : { 726// close : true, 727// blockUI : null, 728// preventDefault : null, 729 setSelected : true 730 } 731 }; 732 $[ _PLUGIN_ ].configuration = { 733 preventTabbing : true, 734 panelClass : 'Panel', 735 listClass : 'List', 736 selectedClass : 'Selected', 737 labelClass : 'Label', 738 spacerClass : 'Spacer', 739 pageNodetype : 'div', 740 panelNodetype : 'ul, ol, div', 741 transitionDuration : 400 742 }; 743 744 745 746 /* 747 SUPPORT 748 */ 749 (function() { 750 751 var wd = window.document, 752 ua = window.navigator.userAgent; 753 754 var _touch = 'ontouchstart' in wd, 755 _overflowscrolling = 'WebkitOverflowScrolling' in wd.documentElement.style, 756 _transition = (function() { 757 var s = document.createElement( 'div' ).style; 758 if ( 'webkitTransition' in s ) 759 { 760 return 'webkitTransition'; 761 } 762 return 'transition' in s; 763 })(), 764 _oldAndroidBrowser = (function() { 765 if ( ua.indexOf( 'Android' ) >= 0 ) 766 { 767 return 2.4 > parseFloat( ua.slice( ua.indexOf( 'Android' ) +8 ) ); 768 } 769 return false; 770 })(); 771 772 $[ _PLUGIN_ ].support = { 773 774 touch: _touch, 775 transition: _transition, 776 oldAndroidBrowser: _oldAndroidBrowser, 777 778 overflowscrolling: (function() { 779 if ( !_touch ) 780 { 781 return true; 782 } 783 if ( _overflowscrolling ) 784 { 785 return true; 786 } 787 if ( _oldAndroidBrowser ) 788 { 789 return false; 790 } 791 return true; 792 })() 793 }; 794 })(); 795 796 797 /* 798 BROWSER SPECIFIC FIXES 799 */ 800 $[ _PLUGIN_ ].useOverflowScrollingFallback = function( use ) 801 { 802 if ( glbl.$html ) 803 { 804 if ( typeof use == 'boolean' ) 805 { 806 glbl.$html[ use ? 'addClass' : 'removeClass' ]( _c.nooverflowscrolling ); 807 } 808 return glbl.$html.hasClass( _c.nooverflowscrolling ); 809 } 810 else 811 { 812 _useOverflowScrollingFallback = use; 813 return use; 814 } 815 }; 816 817 818 /* 819 DEBUG 820 */ 821 $[ _PLUGIN_ ].debug = function( msg ) {}; 822 $[ _PLUGIN_ ].deprecated = function( depr, repl ) 823 { 824 if ( typeof console != 'undefined' && typeof console.warn != 'undefined' ) 825 { 826 console.warn( 'MMENU: ' + depr + ' is deprecated, use ' + repl + ' instead.' ); 827 } 828 }; 829 830 831 // Global vars 832 var _useOverflowScrollingFallback = !$[ _PLUGIN_ ].support.overflowscrolling; 833 834 835 function extendOptions( o, c, $m ) 836 { 837 if ( typeof o != 'object' ) 838 { 839 o = {}; 840 } 841 842 if ( $m ) 843 { 844 if ( typeof o.isMenu != 'boolean' ) 845 { 846 var $c = $m.children(); 847 o.isMenu = ( $c.length == 1 && $c.is( c.panelNodetype ) ); 848 } 849 return o; 850 } 851 852 853 // Extend onClick 854 if ( typeof o.onClick != 'object' ) 855 { 856 o.onClick = {}; 857 } 858 859 860 // DEPRECATED 861 if ( typeof o.onClick.setLocationHref != 'undefined' ) 862 { 863 $[ _PLUGIN_ ].deprecated( 'onClick.setLocationHref option', '!onClick.preventDefault' ); 864 if ( typeof o.onClick.setLocationHref == 'boolean' ) 865 { 866 o.onClick.preventDefault = !o.onClick.setLocationHref; 867 } 868 } 869 // /DEPRECATED 870 871 872 // Extend from defaults 873 o = $.extend( true, {}, $[ _PLUGIN_ ].defaults, o ); 874 875 876 // Degration 877 if ( $[ _PLUGIN_ ].useOverflowScrollingFallback() ) 878 { 879 switch( o.position ) 880 { 881 case 'top': 882 case 'right': 883 case 'bottom': 884 $[ _PLUGIN_ ].debug( 'position: "' + o.position + '" not supported when using the overflowScrolling-fallback.' ); 885 o.position = 'left'; 886 break; 887 } 888 switch( o.zposition ) 889 { 890 case 'front': 891 case 'next': 892 $[ _PLUGIN_ ].debug( 'z-position: "' + o.zposition + '" not supported when using the overflowScrolling-fallback.' ); 893 o.zposition = 'back'; 894 break; 895 } 896 } 897 898 return o; 899 } 900 function extendConfiguration( c ) 901 { 902 if ( typeof c != 'object' ) 903 { 904 c = {}; 905 } 906 907 908 // DEPRECATED 909 if ( typeof c.panelNodeType != 'undefined' ) 910 { 911 $[ _PLUGIN_ ].deprecated( 'panelNodeType configuration option', 'panelNodetype' ); 912 c.panelNodetype = c.panelNodeType; 913 } 914 // /DEPRECATED 915 916 917 c = $.extend( true, {}, $[ _PLUGIN_ ].configuration, c ) 918 919 // Set pageSelector 920 if ( typeof c.pageSelector != 'string' ) 921 { 922 c.pageSelector = '> ' + c.pageNodetype; 923 } 924 925 return c; 926 } 927 928 function _initPlugin() 929 { 930 glbl.$wndw = $(window); 931 glbl.$html = $('html'); 932 glbl.$body = $('body'); 933 934 glbl.$allMenus = $(); 935 936 937 // Classnames, Datanames, Eventnames 938 $.each( [ _c, _d, _e ], 939 function( i, o ) 940 { 941 o.add = function( c ) 942 { 943 c = c.split( ' ' );
944 for ( var d in c ) 945 { 946 o[ c[ d ] ] = o.mm( c[ d ] ); 947 } 948 }; 949 } 950 ); 951 952 // Classnames 953 _c.mm = function( c ) { return 'mm-' + c; }; 954 _c.add( 'menu ismenu panel list subtitle selected label spacer current highest hidden page blocker modal background opened opening subopened subopen fullsubopen subclose nooverflowscrolling' ); 955 _c.umm = function( c ) 956 { 957 if ( c.slice( 0, 3 ) == 'mm-' ) 958 { 959 c = c.slice( 3 ); 960 } 961 return c; 962 }; 963 964 // Datanames 965 _d.mm = function( d ) { return 'mm-' + d; }; 966 _d.add( 'parent style scrollTop offetLeft' ); 967 968 // Eventnames 969 _e.mm = function( e ) { return e + '.mm'; }; 970 _e.add( 'toggle open opening opened close closing closed update setPage setSelected transitionend touchstart touchend click keydown keyup resize' ); 971 if ( !$[ _PLUGIN_ ].support.touch ) 972 { 973 _e.touchstart = _e.mm( 'mousedown' ); 974 _e.touchend = _e.mm( 'mouseup' ); 975 } 976 977 $[ _PLUGIN_ ]._c = _c; 978 $[ _PLUGIN_ ]._d = _d; 979 $[ _PLUGIN_ ]._e = _e; 980 981 $[ _PLUGIN_ ].glbl = glbl; 982 983 $[ _PLUGIN_ ].useOverflowScrollingFallback( _useOverflowScrollingFallback ); 984 } 985 986 function openSubmenuHorizontal( $opening, $m ) 987 { 988 if ( $opening.hasClass( _c.current ) ) 989 { 990 return false; 991 } 992 993 var $panels = $('.' + _c.panel, $m), 994 $current = $panels.filter( '.' + _c.current ); 995 996 $panels
997 .removeClass( _c.highest ) 998 .removeClass( _c.current ) 999 .not( $opening ) 1000 .not( $current ) 1001 .addClass( _c.hidden ); 1002 1003 if ( $opening.hasClass( _c.opened ) ) 1004 { 1005 $current 1006 .addClass( _c.highest ) 1007 .removeClass( _c.opened ) 1008 .removeClass( _c.subopened ); 1009 } 1010 else 1011 { 1012 $opening 1013 .addClass( _c.highest ); 1014 1015 $current 1016 .addClass( _c.subopened ); 1017 } 1018 1019 $opening 1020 .removeClass( _c.hidden ) 1021 .removeClass( _c.subopened ) 1022 .addClass( _c.current ) 1023 .addClass( _c.opened ); 1024 1025 return 'open'; 1026 } 1027 1028 function findScrollTop() 1029 { 1030 if ( !glbl.$scrollTopNode ) 1031 { 1032 if ( glbl.$html.scrollTop() != 0 ) 1033 { 1034 glbl.$scrollTopNode = glbl.$html; 1035 } 1036 else if ( glbl.$body.scrollTop() != 0 ) 1037 { 1038 glbl.$scrollTopNode = glbl.$body; 1039 } 1040 } 1041 return ( glbl.$scrollTopNode ) ? glbl.$scrollTopNode.scrollTop() : 0; 1042 } 1043 1044 function transitionend( $e, fn, duration ) 1045 { 1046 var s = $[ _PLUGIN_ ].support.transition; 1047 if ( s == 'webkitTransition' ) 1048 { 1049 $e.one( 'webkitTransitionEnd', fn ); 1050 } 1051 else if ( s ) 1052 { 1053 $e.one( _e.transitionend, fn ); 1054 } 1055 else 1056 { 1057 setTimeout( fn, duration ); 1058 } 1059 } 1060 function click( $b, fn, onTouchStart, add ) 1061 { 1062 if ( typeof $b == 'string' ) 1063 { 1064 $b = $( $b ); 1065 } 1066 1067 var event = ( onTouchStart ) 1068 ? _e.touchstart 1069 : _e.click; 1070 1071 if ( !add ) 1072 { 1073 $b.off( event ); 1074 } 1075 $b.on( event, 1076 function( e ) 1077 { 1078 e.preventDefault(); 1079 e.stopPropagation(); 1080 1081 fn.call( this, e ); 1082 } 1083 ); 1084 } 1085 1086})( 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.