1/* 2 * SmartMenus jQuery Bootstrap 4 Addon - v0.1.0+ 3 * http://www.smartmenus.org/ 4 * 5 * Copyright Vasil Dinkov, Vadikom Web Ltd. 6 * http://vadikom.com/ 7 * 8 * Released under the MIT license: 9 * http://www.opensource.org/licenses/MIT 10 */ 11 12(function(factory) { 13 if (typeof define === 'function' && define.amd) { 14 // AMD 15 define(['jquery', 'smartmenus'], factory); 16 } else if (typeof module === 'object' && typeof module.exports === 'object') { 17 // CommonJS 18 module.exports = factory(require('jquery')); 19 } else { 20 // Global jQuery 21 factory(jQuery); 22 } 23} (function($) { 24 25 $.extend($.SmartMenus.Bootstrap = {}, { 26 keydownFix: false, 27 init: function() { 28 // init all navbars that don't have the "data-sm-skip" attribute set 29 var $navbars = $('ul.navbar-nav:not([data-sm-skip])'); 30 $navbars.each(function() { 31 var $this = $(this), 32 obj = $this.data('smartmenus'); 33 // if this navbar is not initialized 34 if (!obj) { 35 var skipBehavior = $this.is('[data-sm-skip-collapsible-behavior]'), 36 rightAligned = $this.hasClass('ml-auto') || $this.prevAll('.mr-auto').length > 0; 37 38 $this.smartmenus({ 39 // these are some good default options that should work for all 40 subMenusSubOffsetX: 2, 41 subMenusSubOffsetY: -9, 42 subIndicators: !skipBehavior, 43 collapsibleShowFunction: null, 44 collapsibleHideFunction: null, 45 rightToLeftSubMenus: rightAligned, 46 bottomToTopSubMenus: $this.closest('.fixed-bottom').length > 0, 47 // custom option(s) for the Bootstrap 4 addon 48 bootstrapHighlightClasses: 'text-dark bg-light' 49 }) 50 .on({ 51 // set/unset proper Bootstrap classes for some menu elements 52 'show.smapi': function(e, menu) { 53 var $menu = $(menu), 54 $scrollArrows = $menu.dataSM('scroll-arrows'); 55 if ($scrollArrows) { 56 $scrollArrows.css('background-color', $menu.css('background-color')); 57 } 58 $menu.parent().addClass('show'); 59 if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { 60 $menu.prevAll('a').addClass(obj.opts.bootstrapHighlightClasses); 61 } 62 }, 63 'hide.smapi': function(e, menu) { 64 var $menu = $(menu); 65 $menu.parent().removeClass('show'); 66 if (obj.opts.keepHighlighted && $menu.dataSM('level') > 2) { 67 $menu.prevAll('a').removeClass(obj.opts.bootstrapHighlightClasses); 68 } 69 } 70 }); 71 72 obj = $this.data('smartmenus'); 73 74 function onInit() { 75 // set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true) 76 $this.find('a.current').each(function() { 77 var $this = $(this); 78 // dropdown items require the class to be set to the A's while for nav items it should be set to the parent LI's 79 ($this.hasClass('dropdown-item') ? $this : $this.parent()).addClass('active'); 80 }); 81 // parent items fixes 82 $this.find('a.has-submenu').each(function() { 83 var $this = $(this); 84 // remove Bootstrap required attributes that might cause conflicting issues with the SmartMenus script 85 if ($this.is('[data-toggle="dropdown"]')) { 86 $this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle'); 87 } 88 // remove Bootstrap's carets generating class 89 if (!skipBehavior && $this.hasClass('dropdown-toggle')) { 90 $this.dataSM('bs-dropdown-toggle', true).removeClass('dropdown-toggle'); 91 } 92 }); 93 } 94 95 onInit(); 96 97 function onBeforeDestroy() { 98 $this.find('a.current').each(function() { 99 var $this = $(this); 100 ($this.hasClass('active') ? $this : $this.parent()).removeClass('active'); 101 }); 102 $this.find('a.has-submenu').each(function() { 103 var $this = $(this); 104 if ($this.dataSM('bs-dropdown-toggle')) { 105 $this.addClass('dropdown-toggle').removeDataSM('bs-dropdown-toggle'); 106 } 107 if ($this.dataSM('bs-data-toggle-dropdown')) { 108 $this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown'); 109 } 110 });
111 } 112 113 // custom "refresh" method for Bootstrap 114 obj.refresh = function() { 115 $.SmartMenus.prototype.refresh.call(this); 116 onInit(); 117 // update collapsible detection 118 detectCollapsible(true); 119 }; 120 121 // custom "destroy" method for Bootstrap 122 obj.destroy = function(refresh) { 123 onBeforeDestroy(); 124 $.SmartMenus.prototype.destroy.call(this, refresh); 125 }; 126 127 // keep Bootstrap's default behavior (i.e. use the whole item area just as a sub menu toggle) 128 if (skipBehavior) { 129 obj.opts.collapsibleBehavior = 'toggle'; 130 } 131 132 // onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class 133 var winW; 134 function detectCollapsible(force) { 135 var newW = obj.getViewportWidth(); 136 if (newW != winW || force) { 137 if (obj.isCollapsible()) { 138 $this.addClass('sm-collapsible'); 139 } else { 140 $this.removeClass('sm-collapsible'); 141 } 142 winW = newW; 143 } 144 } 145 detectCollapsible(); 146 $(window).on('resize.smartmenus' + obj.rootId, detectCollapsible); 147 } 148 }); 149 // keydown fix for Bootstrap 4 conflict 150 if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) { 151 // unhook BS keydown handler for all dropdowns 152 $(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu'); 153 // restore BS keydown handler for dropdowns that are not inside SmartMenus navbars 154 // SmartMenus won't add the "show" class so it's handy here 155 if ($.fn.dropdown && $.fn.dropdown.Constructor && typeof $.fn.dropdown.Constructor._dataApiKeydownHandler == 'function') { 156 $(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu.show', $.fn.dropdown.Constructor._dataApiKeydownHandler); 157 } 158 $.SmartMenus.Bootstrap.keydownFix = true; 159 } 160 } 161 }); 162 163 // init ondomready 164 $($.SmartMenus.Bootstrap.init); 165 166 return $; 167}));
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.