vendor: 9,722 bytes, lines 1-296
1/*! 2 * jQuery Accordion 0.0.1 3 * (c) 2014 Victor Fernandez <[email protected]> 4 * MIT Licensed. 5 */ 6 7;(function ( $, window, document, undefined ) { 8 9 var pluginName = 'accordion', 10 defaults = { 11 transitionSpeed: 300, 12 transitionEasing: 'ease', 13 controlElement: '[data-control]', 14 contentElement: '[data-content]', 15 groupElement: '[data-accordion-group]', 16 singleOpen: true 17 }; 18 19 function Accordion(element, options) { 20 this.element = element; 21 this.options = $.extend({}, defaults, options); 22 this._defaults = defaults; 23 this._name = pluginName; 24 this.init(); 25 } 26 27 Accordion.prototype.init = function () { 28 var self = this, 29 opts = self.options; 30 31 var $accordion = $(self.element), 32 $controls = $accordion.find('> ' + opts.controlElement), 33 $content = $accordion.find('> ' + opts.contentElement); 34 35 var accordionParentsQty = $accordion.parents('[data-accordion]').length, 36 accordionHasParent = accordionParentsQty > 0; 37 38 var closedCSS = { 'max-height': 0, 'overflow': 'hidden' }; 39 40 var CSStransitions = supportsTransitions(); 41 42 function debounce(func, threshold, execAsap) { 43 var timeout; 44 45 return function debounced() { 46 var obj = this, 47 args = arguments; 48 49 function delayed() { 50 if (!execAsap) func.apply(obj, args); 51 timeout = null; 52 }; 53 54 if (timeout) clearTimeout(timeout); 55 else if (execAsap) func.apply(obj, args); 56 57 timeout = setTimeout(delayed, threshold || 100); 58 }; 59 } 60 61 function supportsTransitions() { 62 var b = document.body || document.documentElement, 63 s = b.style, 64 p = 'transition'; 65 66 if (typeof s[p] == 'string') { 67 return true; 68 } 69 70 var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms']; 71 72 p = 'Transition'; 73 74 for (var i=0; i<v.length; i++) { 75 if (typeof s[v[i] + p] == 'string') { 76 return true; 77 } 78 } 79 80 return false; 81 } 82 83 function requestAnimFrame(cb) { 84 if(window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame) { 85 return requestAnimationFrame(cb) || 86 webkitRequestAnimationFrame(cb) || 87 mozRequestAnimationFrame(cb); 88 } else { 89 return setTimeout(cb, 1000 / 60); 90 } 91 } 92 93 function toggleTransition($el, remove) { 94 if(!remove) { 95 $content.css({ 96 '-webkit-transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing, 97 'transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing 98 }); 99 } else { 100 $content.css({ 101 '-webkit-transition': '', 102 'transition': '' 103 }); 104 } 105 } 106 107 function calculateHeight($el) { 108 var height = 0; 109 110 $el.children().each(function() { 111 height = height + $(this).outerHeight(true); 112 }); 113 114 $el.data('oHeight', height); 115 } 116 117 function updateParentHeight($parentAccordion, $currentAccordion, qty, operation) { 118 var $content = $parentAccordion.filter('.open').find('> [data-content]'), 119 $childs = $content.find('[data-accordion].open > [data-content]'), 120 $matched; 121 122 if(!opts.singleOpen) { 123 $childs = $childs.not($currentAccordion.siblings('[data-accordion].open').find('> [data-content]')); 124 } 125 126 $matched = $content.add($childs); 127 128 if($parentAccordion.hasClass('open')) { 129 $matched.each(function() { 130 var currentHeight = $(this).data('oHeight'); 131 132 switch (operation) { 133 case '+': 134 $(this).data('oHeight', currentHeight + qty); 135 break; 136 case '-': 137 $(this).data('oHeight', currentHeight - qty); 138 break; 139 default: 140 throw 'updateParentHeight method needs an operation'; 141 } 142 143 $(this).css('max-height', $(this).data('oHeight')); 144 }); 145 } 146 } 147 148 function refreshHeight($accordion) { 149 if($accordion.hasClass('open')) { 150 var $content = $accordion.find('> [data-content]'), 151 $childs = $content.find('[data-accordion].open > [data-content]'), 152 $matched = $content.add($childs); 153 154 calculateHeight($matched); 155 156 $matched.css('max-height', $matched.data('oHeight')); 157 } 158 } 159 160 function closeAccordion($accordion, $content) { 161 $accordion.trigger('accordion.close'); 162 163 if(CSStransitions) { 164 if(accordionHasParent) { 165 var $parentAccordions = $accordion.parents('[data-accordion]'); 166 167 updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '-'); 168 } 169 170 $content.css(closedCSS); 171 172 $accordion.removeClass('open'); 173 } else { 174 $content.css('max-height', $content.data('oHeight')); 175 176 $content.animate(closedCSS, opts.transitionSpeed); 177 178 $accordion.removeClass('open'); 179 } 180 } 181 182 function openAccordion($accordion, $content) { 183 $accordion.trigger('accordion.open'); 184 if(CSStransitions) { 185 toggleTransition($content); 186 187 if(accordionHasParent) { 188 var $parentAccordions = $accordion.parents('[data-accordion]'); 189 190 updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '+'); 191 } 192 193 requestAnimFrame(function() { 194 $content.css('max-height', $content.data('oHeight')); 195 }); 196 197 $accordion.addClass('open'); 198 } else { 199 $content.animate({ 200 'max-height': $content.data('oHeight') 201 }, opts.transitionSpeed, function() { 202 $content.css({'max-height': 'none'}); 203 }); 204 205 $accordion.addClass('open'); 206 } 207 } 208 209 function closeSiblingAccordions($accordion) { 210 var $accordionGroup = $accordion.closest(opts.groupElement); 211 212 var $siblings = $accordion.siblings('[data-accordion]').filter('.open'), 213 $siblingsChildren = $siblings.find('[data-accordion]').filter('.open'); 214 215 var $otherAccordions = $siblings.add($siblingsChildren); 216 217 $otherAccordions.each(function() { 218 var $accordion = $(this), 219 $content = $accordion.find(opts.contentElement); 220 221 closeAccordion($accordion, $content); 222 }); 223 224 $otherAccordions.removeClass('open'); 225 } 226 227 function toggleAccordion() { 228 var isAccordionGroup = (opts.singleOpen) ? $accordion.parents(opts.groupElement).length > 0 : false; 229 230 calculateHeight($content); 231 232 if(isAccordionGroup) { 233 closeSiblingAccordions($accordion); 234 } 235 236 if($accordion.hasClass('open')) { 237 closeAccordion($accordion, $content); 238 } else { 239 openAccordion($accordion, $content); 240 } 241 } 242 243 function addEventListeners() { 244 $controls.on('click', toggleAccordion); 245 246 $controls.on('accordion.toggle', function() { 247 if(opts.singleOpen && $controls.length > 1) { 248 return false; 249 } 250 251 toggleAccordion(); 252 }); 253 254 $(window).on('resize', debounce(function() { 255 refreshHeight($accordion); 256 })); 257 } 258 259 function setup() { 260 $content.each(function() { 261 var $curr = $(this); 262 263 if($curr.css('max-height') != 0) { 264 if(!$curr.closest('[data-accordion]').hasClass('open')) { 265 $curr.css({ 'max-height': 0, 'overflow': 'hidden' }); 266 } else { 267 toggleTransition($curr); 268 calculateHeight($curr); 269 270 $curr.css('max-height', $curr.data('oHeight')); 271 } 272 } 273 }); 274 275 276 if(!$accordion.attr('data-accordion')) { 277 $accordion.attr('data-accordion', ''); 278 $accordion.find(opts.controlElement).attr('data-control', ''); 279 $accordion.find(opts.contentElement).attr('data-content', ''); 280 } 281 } 282 283 setup(); 284 addEventListeners(); 285 }; 286 287 $.fn[pluginName] = function ( options ) { 288 return this.each(function () { 289 if (!$.data(this, 'plugin_' + pluginName)) { 290 $.data(this, 'plugin_' + pluginName, 291 new Accordion( this, options )); 292 } 293 }); 294 } 295 296})( jQuery, window, document );
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.