PageRenderTime 34ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/jQuery.mmenu/4.1.9/js/jquery.mmenu.js

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