PageRenderTime 42ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/files/jquery.mmenu/4.2.5/js/jquery.mmenu.js

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