PageSourceSearch

https://orthopt.ca/assets/js/jquery-mmenu.js

js orthopt.ca collected 2026-10-04 10:12:07 UTC 22,199 bytes, 1,084 lines download raw bytes

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