index.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*!
  2. * metismenu https://github.com/onokumus/metismenu#readme
  3. * A jQuery menu plugin
  4. * @version 3.0.6
  5. * @author Osman Nuri Okumus <onokumus@gmail.com> (https://github.com/onokumus)
  6. * @license: MIT
  7. */
  8. 'use strict';
  9. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  10. var $ = _interopDefault(require('jquery'));
  11. function _extends() {
  12. _extends = Object.assign || function (target) {
  13. for (var i = 1; i < arguments.length; i++) {
  14. var source = arguments[i];
  15. for (var key in source) {
  16. if (Object.prototype.hasOwnProperty.call(source, key)) {
  17. target[key] = source[key];
  18. }
  19. }
  20. }
  21. return target;
  22. };
  23. return _extends.apply(this, arguments);
  24. }
  25. var Util = function ($) {
  26. // eslint-disable-line no-shadow
  27. var TRANSITION_END = 'transitionend';
  28. var Util = {
  29. // eslint-disable-line no-shadow
  30. TRANSITION_END: 'mmTransitionEnd',
  31. triggerTransitionEnd: function triggerTransitionEnd(element) {
  32. $(element).trigger(TRANSITION_END);
  33. },
  34. supportsTransitionEnd: function supportsTransitionEnd() {
  35. return Boolean(TRANSITION_END);
  36. }
  37. };
  38. function getSpecialTransitionEndEvent() {
  39. return {
  40. bindType: TRANSITION_END,
  41. delegateType: TRANSITION_END,
  42. handle: function handle(event) {
  43. if ($(event.target).is(this)) {
  44. return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
  45. }
  46. return undefined;
  47. }
  48. };
  49. }
  50. function transitionEndEmulator(duration) {
  51. var _this = this;
  52. var called = false;
  53. $(this).one(Util.TRANSITION_END, function () {
  54. called = true;
  55. });
  56. setTimeout(function () {
  57. if (!called) {
  58. Util.triggerTransitionEnd(_this);
  59. }
  60. }, duration);
  61. return this;
  62. }
  63. function setTransitionEndSupport() {
  64. $.fn.mmEmulateTransitionEnd = transitionEndEmulator; // eslint-disable-line no-param-reassign
  65. // eslint-disable-next-line no-param-reassign
  66. $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
  67. }
  68. setTransitionEndSupport();
  69. return Util;
  70. }($);
  71. var NAME = 'metisMenu';
  72. var DATA_KEY = 'metisMenu';
  73. var EVENT_KEY = "." + DATA_KEY;
  74. var DATA_API_KEY = '.data-api';
  75. var JQUERY_NO_CONFLICT = $.fn[NAME];
  76. var TRANSITION_DURATION = 350;
  77. var Default = {
  78. toggle: true,
  79. preventDefault: true,
  80. triggerElement: 'a',
  81. parentTrigger: 'li',
  82. subMenu: 'ul'
  83. };
  84. var Event = {
  85. SHOW: "show" + EVENT_KEY,
  86. SHOWN: "shown" + EVENT_KEY,
  87. HIDE: "hide" + EVENT_KEY,
  88. HIDDEN: "hidden" + EVENT_KEY,
  89. CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
  90. };
  91. var ClassName = {
  92. METIS: 'metismenu',
  93. ACTIVE: 'mm-active',
  94. SHOW: 'mm-show',
  95. COLLAPSE: 'mm-collapse',
  96. COLLAPSING: 'mm-collapsing',
  97. COLLAPSED: 'mm-collapsed'
  98. };
  99. var MetisMenu = /*#__PURE__*/function () {
  100. // eslint-disable-line no-shadow
  101. function MetisMenu(element, config) {
  102. this.element = element;
  103. this.config = _extends({}, Default, {}, config);
  104. this.transitioning = null;
  105. this.init();
  106. }
  107. var _proto = MetisMenu.prototype;
  108. _proto.init = function init() {
  109. var self = this;
  110. var conf = this.config;
  111. var el = $(this.element);
  112. el.addClass(ClassName.METIS); // add metismenu class to element
  113. el.find(conf.parentTrigger + "." + ClassName.ACTIVE).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the trigger element
  114. el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).addClass(ClassName.ACTIVE);
  115. el.find(conf.parentTrigger + "." + ClassName.ACTIVE).parents(conf.parentTrigger).children(conf.triggerElement).attr('aria-expanded', 'true'); // add attribute aria-expanded=true the triggers of all parents
  116. el.find(conf.parentTrigger + "." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW);
  117. el.find(conf.parentTrigger).not("." + ClassName.ACTIVE).has(conf.subMenu).children(conf.subMenu).addClass(ClassName.COLLAPSE);
  118. el.find(conf.parentTrigger) // .has(conf.subMenu)
  119. .children(conf.triggerElement).on(Event.CLICK_DATA_API, function (e) {
  120. // eslint-disable-line func-names
  121. var eTar = $(this);
  122. if (eTar.attr('aria-disabled') === 'true') {
  123. return;
  124. }
  125. if (conf.preventDefault && eTar.attr('href') === '#') {
  126. e.preventDefault();
  127. }
  128. var paRent = eTar.parent(conf.parentTrigger);
  129. var sibLi = paRent.siblings(conf.parentTrigger);
  130. var sibTrigger = sibLi.children(conf.triggerElement);
  131. if (paRent.hasClass(ClassName.ACTIVE)) {
  132. eTar.attr('aria-expanded', 'false');
  133. self.removeActive(paRent);
  134. } else {
  135. eTar.attr('aria-expanded', 'true');
  136. self.setActive(paRent);
  137. if (conf.toggle) {
  138. self.removeActive(sibLi);
  139. sibTrigger.attr('aria-expanded', 'false');
  140. }
  141. }
  142. if (conf.onTransitionStart) {
  143. conf.onTransitionStart(e);
  144. }
  145. });
  146. };
  147. _proto.setActive = function setActive(li) {
  148. $(li).addClass(ClassName.ACTIVE);
  149. var ul = $(li).children(this.config.subMenu);
  150. if (ul.length > 0 && !ul.hasClass(ClassName.SHOW)) {
  151. this.show(ul);
  152. }
  153. };
  154. _proto.removeActive = function removeActive(li) {
  155. $(li).removeClass(ClassName.ACTIVE);
  156. var ul = $(li).children(this.config.subMenu + "." + ClassName.SHOW);
  157. if (ul.length > 0) {
  158. this.hide(ul);
  159. }
  160. };
  161. _proto.show = function show(element) {
  162. var _this = this;
  163. if (this.transitioning || $(element).hasClass(ClassName.COLLAPSING)) {
  164. return;
  165. }
  166. var elem = $(element);
  167. var startEvent = $.Event(Event.SHOW);
  168. elem.trigger(startEvent);
  169. if (startEvent.isDefaultPrevented()) {
  170. return;
  171. }
  172. elem.parent(this.config.parentTrigger).addClass(ClassName.ACTIVE);
  173. if (this.config.toggle) {
  174. var toggleElem = elem.parent(this.config.parentTrigger).siblings().children(this.config.subMenu + "." + ClassName.SHOW);
  175. this.hide(toggleElem);
  176. }
  177. elem.removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING).height(0);
  178. this.setTransitioning(true);
  179. var complete = function complete() {
  180. // check if disposed
  181. if (!_this.config || !_this.element) {
  182. return;
  183. }
  184. elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE + " " + ClassName.SHOW).height('');
  185. _this.setTransitioning(false);
  186. elem.trigger(Event.SHOWN);
  187. };
  188. elem.height(element[0].scrollHeight).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
  189. };
  190. _proto.hide = function hide(element) {
  191. var _this2 = this;
  192. if (this.transitioning || !$(element).hasClass(ClassName.SHOW)) {
  193. return;
  194. }
  195. var elem = $(element);
  196. var startEvent = $.Event(Event.HIDE);
  197. elem.trigger(startEvent);
  198. if (startEvent.isDefaultPrevented()) {
  199. return;
  200. }
  201. elem.parent(this.config.parentTrigger).removeClass(ClassName.ACTIVE); // eslint-disable-next-line no-unused-expressions
  202. elem.height(elem.height())[0].offsetHeight;
  203. elem.addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
  204. this.setTransitioning(true);
  205. var complete = function complete() {
  206. // check if disposed
  207. if (!_this2.config || !_this2.element) {
  208. return;
  209. }
  210. if (_this2.transitioning && _this2.config.onTransitionEnd) {
  211. _this2.config.onTransitionEnd();
  212. }
  213. _this2.setTransitioning(false);
  214. elem.trigger(Event.HIDDEN);
  215. elem.removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE);
  216. };
  217. if (elem.height() === 0 || elem.css('display') === 'none') {
  218. complete();
  219. } else {
  220. elem.height(0).one(Util.TRANSITION_END, complete).mmEmulateTransitionEnd(TRANSITION_DURATION);
  221. }
  222. };
  223. _proto.setTransitioning = function setTransitioning(isTransitioning) {
  224. this.transitioning = isTransitioning;
  225. };
  226. _proto.dispose = function dispose() {
  227. $.removeData(this.element, DATA_KEY);
  228. $(this.element).find(this.config.parentTrigger) // .has(this.config.subMenu)
  229. .children(this.config.triggerElement).off(Event.CLICK_DATA_API);
  230. this.transitioning = null;
  231. this.config = null;
  232. this.element = null;
  233. };
  234. MetisMenu.jQueryInterface = function jQueryInterface(config) {
  235. // eslint-disable-next-line func-names
  236. return this.each(function () {
  237. var $this = $(this);
  238. var data = $this.data(DATA_KEY);
  239. var conf = _extends({}, Default, {}, $this.data(), {}, typeof config === 'object' && config ? config : {});
  240. if (!data) {
  241. data = new MetisMenu(this, conf);
  242. $this.data(DATA_KEY, data);
  243. }
  244. if (typeof config === 'string') {
  245. if (data[config] === undefined) {
  246. throw new Error("No method named \"" + config + "\"");
  247. }
  248. data[config]();
  249. }
  250. });
  251. };
  252. return MetisMenu;
  253. }();
  254. /**
  255. * ------------------------------------------------------------------------
  256. * jQuery
  257. * ------------------------------------------------------------------------
  258. */
  259. $.fn[NAME] = MetisMenu.jQueryInterface; // eslint-disable-line no-param-reassign
  260. $.fn[NAME].Constructor = MetisMenu; // eslint-disable-line no-param-reassign
  261. $.fn[NAME].noConflict = function () {
  262. // eslint-disable-line no-param-reassign
  263. $.fn[NAME] = JQUERY_NO_CONFLICT; // eslint-disable-line no-param-reassign
  264. return MetisMenu.jQueryInterface;
  265. };
  266. module.exports = MetisMenu;