vendor: 9,863 bytes, lines 1-302
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){ 85 requestAnimationFrame(cb); 86 } else if (window.webkitRequestAnimationFrame) { 87 webkitRequestAnimationFrame(cb); 88 } else if (window.mozRequestAnimationFrame) { 89 mozRequestAnimationFrame(cb); 90 } else { 91 setTimeout(cb, 1000 / 60); 92 } 93 } 94 95 function toggleTransition($el, remove) { 96 if(!remove) { 97 $content.css({ 98 '-webkit-transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing, 99 'transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing 100 }); 101 } else { 102 $content.css({ 103 '-webkit-transition': '', 104 'transition': '' 105 }); 106 } 107 } 108 109 function calculateHeight($el) { 110 var height = 0; 111 112 $el.children().each(function() { 113 height = height + $(this).outerHeight(true); 114 }); 115 116 $el.data('oHeight', height); 117 } 118 119 function updateParentHeight($parentAccordion, $currentAccordion, qty, operation) { 120 var $content = $parentAccordion.filter('.open').find('> [data-content]'), 121 $childs = $content.find('[data-accordion].open > [data-content]'), 122 $matched; 123 124 if(!opts.singleOpen) { 125 $childs = $childs.not($currentAccordion.siblings('[data-accordion].open').find('> [data-content]')); 126 } 127 128 $matched = $content.add($childs); 129 130 if($parentAccordion.hasClass('open')) { 131 $matched.each(function() { 132 var currentHeight = $(this).data('oHeight'); 133 134 switch (operation) { 135 case '+': 136 $(this).data('oHeight', currentHeight + qty); 137 break; 138 case '-': 139 $(this).data('oHeight', currentHeight - qty); 140 break; 141 default: 142 throw 'updateParentHeight method needs an operation'; 143 } 144 145 $(this).css('max-height', $(this).data('oHeight')); 146 }); 147 } 148 } 149 150 function refreshHeight($accordion) { 151 if($accordion.hasClass('open')) { 152 var $content = $accordion.find('> [data-content]'), 153 $childs = $content.find('[data-accordion].open > [data-content]'), 154 $matched = $content.add($childs); 155 156 calculateHeight($matched); 157 158 $matched.css('max-height', $matched.data('oHeight')); 159 } 160 } 161 162 function closeAccordion($accordion, $content) { 163 $accordion.trigger('accordion.close'); 164 165 if(CSStransitions) { 166 if(accordionHasParent) { 167 var $parentAccordions = $accordion.parents('[data-accordion]'); 168 169 updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '-'); 170 } 171 172 $content.css(closedCSS); 173 174 $accordion.removeClass('open'); 175 } else { 176 $content.css('max-height', $content.data('oHeight')); 177 178 $content.animate(closedCSS, opts.transitionSpeed); 179 180 $accordion.removeClass('open'); 181 } 182 } 183 184 function openAccordion($accordion, $content) { 185 $accordion.trigger('accordion.open'); 186 if(CSStransitions) { 187 toggleTransition($content); 188 189 if(accordionHasParent) { 190 var $parentAccordions = $accordion.parents('[data-accordion]'); 191 192 updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '+'); 193 } 194 195 requestAnimFrame(function() { 196 $content.css('max-height', $content.data('oHeight')); 197 }); 198 199 $accordion.addClass('open'); 200 } else { 201 $content.animate({ 202 'max-height': $content.data('oHeight') 203 }, opts.transitionSpeed, function() { 204 $content.css({'max-height': 'none'}); 205 }); 206 207 $accordion.addClass('open'); 208 } 209 } 210 211 function closeSiblingAccordions($accordion) { 212 var $accordionGroup = $accordion.closest(opts.groupElement); 213 214 var $siblings = $accordion.siblings('[data-accordion]').filter('.open'), 215 $siblingsChildren = $siblings.find('[data-accordion]').filter('.open'); 216 217 var $otherAccordions = $siblings.add($siblingsChildren); 218 219 $otherAccordions.each(function() { 220 var $accordion = $(this), 221 $content = $accordion.find(opts.contentElement); 222 223 closeAccordion($accordion, $content); 224 }); 225 226 $otherAccordions.removeClass('open'); 227 } 228 229 function toggleAccordion() { 230 var isAccordionGroup = (opts.singleOpen) ? $accordion.parents(opts.groupElement).length > 0 : false; 231 232 calculateHeight($content); 233 234 if(isAccordionGroup) { 235 closeSiblingAccordions($accordion); 236 } 237 238 if($accordion.hasClass('open')) { 239 closeAccordion($accordion, $content); 240 } else { 241 openAccordion($accordion, $content); 242 } 243 } 244 245 function addEventListeners() { 246 $controls.on('click', toggleAccordion); 247 248 $controls.on('accordion.toggle', function() { 249 if(opts.singleOpen && $controls.length > 1) { 250 return false; 251 } 252 253 toggleAccordion(); 254 }); 255 256 $controls.on('accordion.refresh', function() { 257 refreshHeight($accordion); 258 }); 259 260 $(window).on('resize', debounce(function() { 261 refreshHeight($accordion); 262 })); 263 } 264 265 function setup() { 266 $content.each(function() { 267 var $curr = $(this); 268 269 if($curr.css('max-height') != 0) { 270 if(!$curr.closest('[data-accordion]').hasClass('open')) { 271 $curr.css({ 'max-height': 0, 'overflow': 'hidden' }); 272 } else { 273 toggleTransition($curr); 274 calculateHeight($curr); 275 276 $curr.css('max-height', $curr.data('oHeight')); 277 } 278 } 279 }); 280 281 282 if(!$accordion.attr('data-accordion')) { 283 $accordion.attr('data-accordion', ''); 284 $accordion.find(opts.controlElement).attr('data-control', ''); 285 $accordion.find(opts.contentElement).attr('data-content', ''); 286 } 287 } 288 289 setup(); 290 addEventListeners(); 291 }; 292 293 $.fn[pluginName] = function ( options ) { 294 return this.each(function () { 295 if (!$.data(this, 'plugin_' + pluginName)) { 296 $.data(this, 'plugin_' + pluginName, 297 new Accordion( this, options )); 298 } 299 }); 300 } 301 302})( 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.