PageSourceSearch

https://my.cazloyd.com/Content/isg/Content/js/jquery.mmenu.js

js cazloyd.com collected 2026-10-01 14:47:59 UTC 22,290 bytes, 1,086 lines download raw bytes

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.