1/**! 2 * MixItUp v2.0.6 3 * 4 * @copyright Copyright 2014 KunkaLabs Limited. 5 * @author KunkaLabs Limited. 6 * @link https://mixitup.kunkalabs.com 7 * 8 * @license Commercial use requires a commercial license. 9 * https://mixitup.kunkalabs.com/licenses/ 10 * 11 * Non-commercial use permitted under terms of CC-BY-NC license. 12 * http://creativecommons.org/licenses/by-nc/3.0/ 13 */ 14 15(function($, undf){ 16 17 /** 18 * MixItUp Constructor Function 19 * @constructor 20 * @extends jQuery 21 */ 22 23 $.MixItUp = function(){ 24 var self = this; 25 26 self._execAction('_constructor', 0); 27 28 $.extend(self, { 29 30 /* Public Properties 31 ---------------------------------------------------------------------- */ 32 33 selectors: { 34 target: '.mix', 35 filter: '.filter', 36 sort: '.sort' 37 }, 38 39 animation: { 40 enable: true, 41 effects: 'fade scale', 42 duration: 600, 43 easing: 'ease', 44 perspectiveDistance: '3000', 45 perspectiveOrigin: '50% 50%', 46 queue: true, 47 queueLimit: 1, 48 animateChangeLayout: false, 49 animateResizeContainer: true, 50 animateResizeTargets: false, 51 staggerSequence: false, 52 reverseOut: false 53 }, 54 55 callbacks: { 56 onMixLoad: false, 57 onMixStart: false, 58 onMixBusy: false, 59 onMixEnd: false, 60 onMixFail: false, 61 _user: false 62 }, 63 64 controls: { 65 enable: true, 66 live: false, 67 toggleFilterButtons: false, 68 toggleLogic: 'or', 69 activeClass: 'active' 70 }, 71 72 layout: { 73 display: 'inline-block', 74 containerClass: '', 75 containerClassFail: 'fail' 76 }, 77 78 load: { 79 filter: 'all', 80 sort: false 81 }, 82 83 /* Private Properties 84 ---------------------------------------------------------------------- */ 85 86 _$body: null, 87 _$container: null, 88 _$targets: null, 89 _$parent: null, 90 _$sortButtons: null, 91 _$filterButtons: null, 92 93 _suckMode: false, 94 _mixing: false, 95 _sorting: false, 96 _clicking: false, 97 _loading: true, 98 _changingLayout: false, 99 _changingClass: false, 100 _changingDisplay: false, 101 102 _origOrder: [], 103 _startOrder: [], 104 _newOrder: [], 105 _activeFilter: null, 106 _toggleArray: [], 107 _toggleString: '', 108 _activeSort: 'default:asc', 109 _newSort: null, 110 _startHeight: null, 111 _newHeight: null, 112 _incPadding: true, 113 _newDisplay: null, 114 _newClass: null, 115 _targetsBound: 0, 116 _targetsDone: 0, 117 _queue: [], 118 119 _$show: $(), 120 _$hide: $() 121 }); 122 123 self._execAction('_constructor', 1); 124 }; 125 126 /** 127 * MixItUp Prototype 128 * @override 129 */ 130 131 $.MixItUp.prototype = { 132 constructor: $.MixItUp, 133 _instances: {}, 134 135 /* Extensible Actions 136 ---------------------------------------------------------------------- */ 137 138 _actions: {}, 139 140 /* Extensible Filters 141 ---------------------------------------------------------------------- */ 142 143 _filters: {}, 144 145 /* Private Methods 146 ---------------------------------------------------------------------- */ 147 148 /** 149 * Initialise 150 * @since 2.0.0 151 * @param {object} domNode 152 * @param {object} config 153 */ 154 155 _init: function(domNode, config){ 156 var self = this; 157 158 self._execAction('_init', 0, arguments); 159 160 config && $.extend(true, self, config); 161 162 self._$body = $('body'); 163 self._domNode = domNode; 164 self._$container = $(domNode); 165 self._$container.addClass(self.layout.containerClass); 166 self._id = domNode.id; 167 168 self._platformDetect(); 169 170 self._brake = self._getPrefixedCSS('transition', 'none'); 171 172 self._refresh(true); 173 174 self._$parent = self._$targets.parent().length ? self._$targets.parent() : self._$container; 175 176 if(self.load.sort){ 177 self._newSort = self._parseSort(self.load.sort); 178 self._newSortString = self.load.sort; 179 self._activeSort = self.load.sort; 180 self._sort(); 181 self._printSort(); 182 } 183 184 self._activeFilter = self.load.filter === 'all' ? 185 self.selectors.target : 186 self.load.filter === 'none' ? 187 '' : 188 self.load.filter; 189 190 self.controls.enable && self._bindHandlers(); 191 192 if(self.controls.toggleFilterButtons){ 193 self._buildToggleArray(); 194 195 for(var i = 0; i < self._toggleArray.length; i++){ 196 self._updateControls({filter: self._toggleArray[i], sort: self._activeSort}, true); 197 }; 198 } else if(self.controls.enable){ 199 self._updateControls({filter: self._activeFilter, sort: self._activeSort}); 200 } 201 202 self._filter(); 203 204 self._init = true; 205 206 self._$container.data('mixItUp',self); 207 208 self._execAction('_init', 1, arguments); 209 210 self._buildState(); 211 212 self._$targets.css(self._brake); 213 214 self._goMix(self.animation.enable); 215 }, 216 217 /** 218 * Platform Detect 219 * @since 2.0.0 220 */ 221 222 _platformDetect: function(){ 223 var self = this, 224 vendorsTrans = ['Webkit', 'Moz', 'O', 'ms'], 225 vendorsRAF = ['webkit', 'moz'], 226 chrome = window.navigator.appVersion.match(/Chrome\/(\d+)\./) || false, 227 ff = typeof InstallTrigger !== 'undefined', 228 prefix = function(el){ 229 for (var i = 0; i < vendorsTrans.length; i++){ 230 if (vendorsTrans[i] + 'Transition' in el.style){ 231 return { 232 prefix: '-'+vendorsTrans[i].toLowerCase()+'-', 233 vendor: vendorsTrans[i] 234 }; 235 }; 236 }; 237 return 'transition' in el.style ? '' : false;
238 }, 239 transPrefix = prefix(self._domNode); 240 241 self._execAction('_platformDetect', 0); 242 243 self._chrome = chrome ? parseInt(chrome[1], 10) : false; 244 self._ff = ff ? parseInt(window.navigator.userAgent.match(/rv:([^)]+)\)/)[1]) : false; 245 self._prefix = transPrefix.prefix; 246 self._vendor = transPrefix.vendor; 247 self._suckMode = window.atob && self._prefix ? false : true; 248 249 self._suckMode && (self.animation.enable = false); 250 (self._ff && self._ff <= 4) && (self.animation.enable = false); 251 252 /* Polyfills 253 ---------------------------------------------------------------------- */ 254 255 /** 256 * window.requestAnimationFrame 257 */ 258 259 for(var x = 0; x < vendorsRAF.length && !window.requestAnimationFrame; x++){ 260 window.requestAnimationFrame = window[vendorsRAF[x]+'RequestAnimationFrame']; 261 } 262 263 /** 264 * Object.getPrototypeOf 265 */ 266 267 if(typeof Object.getPrototypeOf !== 'function'){ 268 if(typeof 'test'.__proto__ === 'object'){ 269 Object.getPrototypeOf = function(object){ 270 return object.__proto__; 271 }; 272 } else { 273 Object.getPrototypeOf = function(object){ 274 return object.constructor.prototype; 275 }; 276 } 277 } 278 279 /** 280 * Element.nextElementSibling 281 */ 282 283 if(self._domNode.nextElementSibling === undf){ 284 Object.defineProperty(Element.prototype, 'nextElementSibling',{ 285 get: function(){ 286 var el = this.nextSibling; 287 288 while(el){ 289 if(el.nodeType ===1){ 290 return el; 291 } 292 el = el.nextSibling; 293 } 294 return null; 295 } 296 }); 297 } 298 299 self._execAction('_platformDetect', 1); 300 }, 301 302 /** 303 * Refresh 304 * @since 2.0.0 305 * @param {boolean} init 306 */ 307 308 _refresh: function(init){ 309 var self = this; 310 311 self._execAction('_refresh', 0, arguments); 312 313 self._$targets = self._$container.find(self.selectors.target); 314 315 for(var i = 0; i < self._$targets.length; i++){ 316 var target = self._$targets[i]; 317 318 if(target.dataset === undf){ 319 320 target.dataset = {}; 321 322 for(var j = 0; j < target.attributes.length; j++){ 323 324 var attr = target.attributes[j], 325 name = attr.name, 326 val = attr.nodeValue; 327 328 if(name.indexOf('data-') > -1){ 329 var dataName = self._helpers._camelCase(name.substring(5,name.length)); 330 target.dataset[dataName] = val; 331 } 332 } 333 } 334 335 if(target.mixParent === undf){ 336 target.mixParent = self._id; 337 } 338 } 339 340 if( 341 (self._$targets.length && init) || 342 (!self._origOrder.length && self._$targets.length) 343 ){ 344 self._origOrder = []; 345 346 for(var i = 0; i < self._$targets.length; i++){ 347 var target = self._$targets[i]; 348 349 self._origOrder.push(target); 350 } 351 } 352 353 self._execAction('_refresh', 1, arguments); 354 }, 355 356 /** 357 * Bind Handlers 358 * @since 2.0.0 359 */ 360 361 _bindHandlers: function(){ 362 var self = this; 363 364 self._execAction('_bindHandlers', 0); 365 366 if(self.controls.live){ 367 self._$body 368 .on('click.mixItUp.'+self._id, self.selectors.sort, function(){ 369 self._processClick($(this), 'sort'); 370 }) 371 .on('click.mixItUp.'+self._id, self.selectors.filter, function(){ 372 self._processClick($(this), 'filter'); 373 }); 374 } else { 375 self._$sortButtons = $(self.selectors.sort); 376 self._$filterButtons = $(self.selectors.filter); 377 378 self._$sortButtons.on('click.mixItUp.'+self._id, function(){ 379 self._processClick($(this), 'sort'); 380 }); 381 382 self._$filterButtons.on('click.mixItUp.'+self._id, function(){ 383 self._processClick($(this), 'filter'); 384 }); 385 } 386 387 self._execAction('_bindHandlers', 1); 388 }, 389 390 /** 391 * Process Click 392 * @since 2.0.0 393 * @param {object} $button 394 * @param {string} type 395 */ 396 397 _processClick: function($button, type){ 398 var self = this; 399 400 self._execAction('_processClick', 0, arguments); 401 402 if(!self._mixing || (self.animation.queue && self._queue.length < self.animation.queueLimit)){ 403 self._clicking = true; 404 405 if(type === 'sort'){ 406 var sort = $button.attr('data-sort'); 407 408 if(!$button.hasClass(self.controls.activeClass) || sort.indexOf('random') > -1){ 409 $(self.selectors.sort).removeClass(self.controls.activeClass); 410 $button.addClass(self.controls.activeClass); 411 self.sort(sort); 412 } 413 } 414 415 if(type === 'filter') { 416 var filter = $button.attr('data-filter'), 417 ndx, 418 seperator = self.controls.toggleLogic === 'or' ? ',' : ''; 419 420 if(!self.controls.toggleFilterButtons){ 421 if(!$button.hasClass(self.controls.activeClass)){ 422 $(self.selectors.filter).removeClass(self.controls.activeClass); 423 $button.addClass(self.controls.activeClass); 424 self.filter(filter); 425 } 426 } else { 427 self._buildToggleArray(); 428 429 if(!$button.hasClass(self.controls.activeClass)){ 430 $button.addClass(self.controls.activeClass); 431 432 self._toggleArray.push(filter); 433 } else { 434 $button.removeClass(self.controls.activeClass); 435 ndx = self._toggleArray.indexOf(filter); 436 self._toggleArray.splice(ndx, 1); 437 } 438 439 self._toggleArray = $.grep(self._toggleArray,function(n){return(n);}); 440 441 self._toggleString = self._toggleArray.join(seperator); 442 443 self.filter(self._toggleString); 444 } 445 } 446 447 self._execAction('_processClick', 1, arguments); 448 } else { 449 if(typeof self.callbacks.onMixBusy === 'function'){ 450 self.callbacks.onMixBusy.call(self._domNode, self._state, self); 451 } 452 self._execAction('_processClickBusy', 1, arguments); 453 } 454 }, 455 456 /** 457 * Build Toggle Array 458 * @since 2.0.0 459 */ 460 461 _buildToggleArray: function(){ 462 var self = this, 463 activeFilter = self._activeFilter.replace(/\s/g, ''); 464 465 self._execAction('_buildToggleArray', 0, arguments); 466 467 if(self.controls.toggleLogic === 'or'){ 468 self._toggleArray = activeFilter.split(','); 469 } else { 470 self._toggleArray = activeFilter.split('.'); 471 472 !self._toggleArray[0] && self._toggleArray.shift(); 473 474 for(var i = 0, filter; filter = self._toggleArray[i]; i++){ 475 self._toggleArray[i] = '.'+filter; 476 } 477 } 478 479 self._execAction('_buildToggleArray', 1, arguments); 480 }, 481 482 /** 483 * Update Controls 484 * @since 2.0.0 485 * @param {object} command 486 * @param {boolean} multi 487 */ 488 489 _updateControls: function(command, multi){ 490 var self = this, 491 output = { 492 filter: command.filter, 493 sort: command.sort 494 }, 495 update = function($el, filter){ 496 (multi && type == 'filter' && !(output.filter === 'none' || output.f
496ilter === '')) ? 497 $el.filter(filter).addClass(self.controls.activeClass) : 498 $el.removeClass(self.controls.activeClass).filter(filter).addClass(self.controls.activeClass); 499 }, 500 type = 'filter', 501 $el = null; 502 503 self._execAction('_updateControls', 0, arguments); 504 505 (command.filter === undf) && (output.filter = self._activeFilter); 506 (command.sort === undf) && (output.sort = self._activeSort); 507 (output.filter === self.selectors.target) && (output.filter = 'all'); 508 509 for(var i = 0; i < 2; i++){ 510 $el = self.controls.live ? $(self.selectors[type]) : self['_$'+type+'Buttons']; 511 $el && update($el, '[data-'+type+'="'+output[type]+'"]'); 512 type = 'sort'; 513 } 514 515 self._execAction('_updateControls', 1, arguments); 516 }, 517 518 /** 519 * Filter (private) 520 * @since 2.0.0 521 */ 522 523 _filter: function(){ 524 var self = this; 525 526 self._execAction('_filter', 0); 527 528 for(var i = 0; i < self._$targets.length; i++){ 529 var $target = $(self._$targets[i]); 530 531 if($target.is(self._activeFilter)){ 532 self._$show = self._$show.add($target); 533 } else { 534 self._$hide = self._$hide.add($target); 535 } 536 } 537 538 self._execAction('_filter', 1); 539 }, 540 541 /** 542 * Sort (private) 543 * @since 2.0.0 544 */ 545 546 _sort: function(){ 547 var self = this, 548 arrayShuffle = function(oldArray){ 549 var newArray = oldArray.slice(), 550 len = newArray.length, 551 i = len; 552 553 while(i--){ 554 var p = parseInt(Math.random()*len); 555 var t = newArray[i]; 556 newArray[i] = newArray[p]; 557 newArray[p] = t; 558 }; 559 return newArray; 560 }; 561 562 self._execAction('_sort', 0); 563 564 self._startOrder = []; 565 566 for(var i = 0; i < self._$targets.length; i++){ 567 var target = self._$targets[i]; 568 569 self._startOrder.push(target); 570 } 571 572 switch(self._newSort[0].sortBy){ 573 case 'default': 574 self._newOrder = self._origOrder; 575 break; 576 case 'random': 577 self._newOrder = arrayShuffle(self._startOrder); 578 break; 579 case 'custom': 580 self._newOrder = self._newSort[0].order; 581 break; 582 default: 583 self._newOrder = self._startOrder.concat().sort(function(a, b){ 584 return self._compare(a, b); 585 }); 586 } 587 588 self._execAction('_sort', 1); 589 }, 590 591 /** 592 * Compare Algorithm 593 * @since 2.0.0 594 * @param {string|number} a 595 * @param {string|number} b 596 * @param {number} depth (recursion) 597 * @return {number} 598 */ 599 600 _compare: function(a, b, depth){ 601 depth = depth ? depth : 0; 602 603 var self = this, 604 order = self._newSort[depth].order, 605 getData = function(el){ 606 return el.dataset[self._newSort[depth].sortBy] || 0; 607 }, 608 attrA = isNaN(getData(a) * 1) ? getData(a).toLowerCase() : getData(a) * 1, 609 attrB = isNaN(getData(b) * 1) ? getData(b).toLowerCase() : getData(b) * 1; 610 611 if(attrA < attrB) 612 return order == 'asc' ? -1 : 1; 613 if(attrA > attrB) 614 return order == 'asc' ? 1 : -1; 615 if(attrA == attrB && self._newSort.length > depth+1) 616 return self._compare(a, b, depth+1); 617 618 return 0; 619 }, 620 621 /** 622 * Print Sort 623 * @since 2.0.0 624 * @param {boolean} reset 625 */ 626 627 _printSort: function(reset){ 628 var self = this, 629 order = reset ? self._startOrder : self._newOrder, 630 targets = self._$parent[0].querySelectorAll(self.selectors.target), 631 nextSibling = targets[targets.length -1].nextElementSibling, 632 frag = document.createDocumentFragment(); 633 634 self._execAction('_printSort', 0, arguments); 635 636 for(var i = 0; i < targets.length; i++){ 637 var target = targets[i], 638 whiteSpace = target.nextSibling; 639 640 if(target.style.position === 'absolute') continue; 641 642 if(whiteSpace && whiteSpace.nodeName == '#text'){ 643 self._$parent[0].removeChild(whiteSpace); 644 } 645 646 self._$parent[0].removeChild(target); 647 } 648 649 for(var i = 0; i < order.length; i++){ 650 var el = order[i]; 651 652 if(self._newSort[0].sortBy == 'default' && self._newSort[0].order == 'desc' && !reset){ 653 var firstChild = frag.firstChild; 654 frag.insertBefore(el, firstChild); 655 frag.insertBefore(document.createTextNode(' '), el); 656 } else { 657 frag.appendChild(el); 658 frag.appendChild(document.createTextNode(' ')); 659 } 660 } 661 662 nextSibling ? 663 self._$parent[0].insertBefore(frag, nextSibling) : 664 self._$parent[0].appendChild(frag); 665
666 self._execAction('_printSort', 1, arguments); 667 }, 668 669 /** 670 * Parse Sort 671 * @since 2.0.0 672 * @param {string} sortString 673 * @return {array} newSort 674 */ 675 676 _parseSort: function(sortString){ 677 var self = this, 678 rules = typeof sortString === 'string' ? sortString.split(' ') : [sortString], 679 newSort = []; 680 681 for(var i = 0; i < rules.length; i++){ 682 var rule = typeof sortString === 'string' ? rules[i].split(':') : ['custom', rules[i]], 683 ruleObj = { 684 sortBy: self._helpers._camelCase(rule[0]), 685 order: rule[1] || 'asc' 686 }; 687 688 newSort.push(ruleObj); 689 690 if(ruleObj.sortBy == 'default' || ruleObj.sortBy == 'random') break; 691 } 692 693 return self._execFilter('_parseSort', newSort, arguments); 694 }, 695 696 /** 697 * Parse Effects 698 * @since 2.0.0 699 * @return {object} effects 700 */ 701 702 _parseEffects: function(){ 703 var self = this, 704 effects = { 705 opacity: '', 706 transformIn: '', 707 transformOut: '', 708 filter: '' 709 }, 710 parse = function(effect, extract, reverse){ 711 if(self.animation.effects.indexOf(effect) > -1){ 712 if(extract){ 713 var propIndex = self.animation.effects.indexOf(effect+'('); 714 if(propIndex > -1){ 715 var str = self.animation.effects.substring(propIndex), 716 match = /\(([^)]+)\)/.exec(str), 717 val = match[1]; 718 719 return {val: val}; 720 } 721 } 722 return true; 723 } else { 724 return false; 725 } 726 }, 727 negate = function(value, invert){ 728 if(invert){ 729 return value.charAt(0) === '-' ? value.substr(1, value.length) : '-'+value; 730 } else { 731 return value; 732 } 733 }, 734 buildTransform = function(key, invert){ 735 var transforms = [ 736 ['scale', '.01'], 737 ['translateX', '20px'], 738 ['translateY', '20px'], 739 ['translateZ', '20px'], 740 ['rotateX', '90deg'], 741 ['rotateY', '90deg'], 742 ['rotateZ', '180deg'], 743 ]; 744 745 for(var i = 0; i < transforms.length; i++){ 746 var prop = transforms[i][0], 747 def = transforms[i][1], 748 inverted = invert && prop !== 'scale'; 749 750 effects[key] += parse(prop) ? prop+'('+negate(parse(prop, true).val || def, inverted)+') ' : ''; 751 } 752 }; 753 754 effects.opacity = parse('fade') ? parse('fade',true).val || '0' : ''; 755 756 buildTransform('transformIn'); 757 758 self.animation.reverseOut ? buildTransform('transformOut', true) : (effects.transformOut = effects.transformIn); 759 760 effects.transition = {}; 761 762 effects.transition = self._getPrefixedCSS('transition','all '+self.animation.duration+'ms '+self.animation.easing+', opacity '+self.animation.duration+'ms linear'); 763 764 self.animation.stagger = parse('stagger') ? true : false; 765 self.animation.staggerDuration = parseInt(parse('stagger') ? (parse('stagger',true).val ? parse('stagger',true).val : 100) : 100); 766 767 return self._execFilter('_parseEffects', effects); 768 }, 769 770 /** 771 * Build State 772 * @since 2.0.0 773 * @param {boolean} future 774 * @return {object} futureState 775 */ 776 777 _buildState: function(future){ 778 var self = this, 779 state = {}; 780 781 self._execAction('_buildState', 0); 782 783 state = { 784 activeFilter: self._activeFilter === '' ? 'none' : self._activeFilter, 785 activeSort: self._activeSort, 786 fail: !self._$show.length && self._activeFilter !== '', 787 $targets: self._$targets, 788 $show: self._$show, 789 $hide: self._$hide, 790 totalTargets: self._$targets.length, 791 totalShow: self._$show.length, 792 totalHide: self._$hide.length, 793 display: self.layout.display 794 }; 795 796 self._execAction('_buildState', 1); 797 798 if(future){ 799 return self._execFilter('_buildState', state); 800 } else { 801 self._state = state; 802 } 803 }, 804 805 /** 806 * Go Mix 807 * @since 2.0.0 808 * @param {boolean} animate 809 */ 810 811 _goMix: function(animate){ 812 var self = this, 813 phase1 = function(){ 814 815 if(self._chrome && (self._chrome === 31)){ 816 chromeFix(self._$parent[0]); 817 } 818 819 self._setInter(); 820 821 phase2(); 822 }, 823 phase2 = function(){ 824 var scrollTop = window.scrollY, 825 scrollLeft = window.scrollX, 826 windowHeight = window.innerHeight; 827 828 self._getInterMixData(); 829 830 self._setFinal(); 831 832 self._getFinalMixData(); 833 834 (scrollTop + windowHeight > window.innerHeight) && window.scrollTo(scrollLeft, scrollTop); 835 836 self._prepTargets(); 837 838 if(window.requestAnimationFrame){ 839 requestAnimationFrame(phase3); 840 } else { 841 setTimeout(function(){
842 phase3(); 843 },20); 844 } 845 }, 846 phase3 = function(){ 847 self._animateTargets(); 848 849 if(self._targetsBound === 0){ 850 self._cleanUp(); 851 } 852 }, 853 chromeFix = function(grid){ 854 var parent = grid.parentElement, 855 placeholder = document.createElement('div'), 856 frag = document.createDocumentFragment(); 857 858 parent.insertBefore(placeholder, grid); 859 frag.appendChild(grid); 860 parent.replaceChild(grid, placeholder); 861 }, 862 futureState = self._buildState(true); 863 864 self._execAction('_goMix', 0, arguments); 865 866 !self.animation.duration && (animate = false); 867 868 self._mixing = true; 869 870 self._$container.removeClass(self.layout.containerClassFail); 871 872 if(typeof self.callbacks.onMixStart === 'function'){ 873 self.callbacks.onMixStart.call(self._domNode, self._state, futureState, self); 874 } 875 876 self._$container.trigger('mixStart', [self._state, futureState, self]); 877 878 self._getOrigMixData(); 879 880 if(animate && !self._suckMode){ 881 882 window.requestAnimationFrame ? 883 requestAnimationFrame(phase1) : 884 phase1(); 885 886 } else { 887 self._cleanUp(); 888 } 889 890 self._execAction('_goMix', 1, arguments); 891 }, 892 893 /** 894 * Get Target Data 895 * @since 2.0.0 896 */ 897 898 _getTargetData: function(el, stage){ 899 var self = this, 900 elStyle; 901 902 el.dataset[stage+'PosX'] = el.offsetLeft; 903 el.dataset[stage+'PosY'] = el.offsetTop; 904 905 if(self.animation.animateResizeTargets){ 906 elStyle = window.getComputedStyle(el); 907 908 el.dataset[stage+'MarginBottom'] = parseInt(elStyle.marginBottom); 909 el.dataset[stage+'MarginRight'] = parseInt(elStyle.marginRight); 910 el.dataset[stage+'Width'] = el.offsetWidth; 911 el.dataset[stage+'Height'] = el.offsetHeight; 912 } 913 }, 914 915 /** 916 * Get Original Mix Data 917 * @since 2.0.0 918 */ 919 920 _getOrigMixData: function(){ 921 var self = this, 922 parentStyle = !self._suckMode ? window.getComputedStyle(self._$parent[0]) : {boxSizing: ''}, 923 parentBS = parentStyle.boxSizing || parentStyle[self._vendor+'BoxSizing']; 924 925 self._incPadding = (parentBS === 'border-box'); 926 927 self._execAction('_getOrigMixData', 0); 928 929 !self._suckMode && (self.effects = self._parseEffects()); 930 931 self._$toHide = self._$hide.filter(':visible'); 932 self._$toShow = self._$show.filter(':hidden'); 933 self._$pre = self._$targets.filter(':visible'); 934 935 self._startHeight = self._incPadding ? 936 self._$parent.outerHeight() : 937 self._$parent.height(); 938 939 for(var i = 0; i < self._$pre.length; i++){ 940 var el = self._$pre[i]; 941 942 self._getTargetData(el, 'orig'); 943 } 944 945 self._execAction('_getOrigMixData', 1); 946 }, 947 948 /** 949 * Set Intermediate Positions 950 * @since 2.0.0 951 */ 952 953 _setInter: function(){ 954 var self = this; 955 956 self._execAction('_setInter', 0); 957 958 if(self._changingLayout && self.animation.animateChangeLayout){
959 self._$toShow.css('display',self._newDisplay); 960 961 if(self._changingClass){ 962 self._$container 963 .removeClass(self.layout.containerClass) 964 .addClass(self._newClass); 965 } 966 } else { 967 self._$toShow.css('display', self.layout.display); 968 } 969 970 self._execAction('_setInter', 1); 971 }, 972 973 /** 974 * Get Intermediate Mix Data 975 * @since 2.0.0 976 */ 977 978 _getInterMixData: function(){ 979 var self = this; 980 981 self._execAction('_getInterMixData', 0); 982 983 for(var i = 0; i < self._$toShow.length; i++){ 984 var el = self._$toShow[i]; 985 986 self._getTargetData(el, 'inter'); 987 } 988 989 for(var i = 0; i < self._$pre.length; i++){ 990 var el = self._$pre[i]; 991 992 self._getTargetData(el, 'inter'); 993 } 994 995 self._execAction('_getInterMixData', 1); 996 }, 997 998 /** 999 * Set Final Positions 1000 * @since 2.0.0 1001 */ 1002 1003 _setFinal: function(){ 1004 var self = this; 1005 1006 self._execAction('_setFinal', 0); 1007 1008 self._sorting && self._printSort(); 1009 1010 self._$toHide.removeStyle('display'); 1011 1012 if(self._changingLayout && self.animation.animateChangeLayout){
1013 self._$pre.css('display',self._newDisplay); 1014 } 1015 1016 self._execAction('_setFinal', 1); 1017 }, 1018 1019 /** 1020 * Get Final Mix Data 1021 * @since 2.0.0 1022 */ 1023 1024 _getFinalMixData: function(){ 1025 var self = this; 1026 1027 self._execAction('_getFinalMixData', 0); 1028 1029 for(var i = 0; i < self._$toShow.length; i++){ 1030 var el = self._$toShow[i]; 1031 1032 self._getTargetData(el, 'final'); 1033 } 1034 1035 for(var i = 0; i < self._$pre.length; i++){ 1036 var el = self._$pre[i]; 1037 1038 self._getTargetData(el, 'final'); 1039 } 1040 1041 self._newHeight = self._incPadding ? 1042 self._$parent.outerHeight() : 1043 self._$parent.height(); 1044 1045 self._sorting && self._printSort(true); 1046 1047 self._$toShow.removeStyle('display'); 1048 1049 self._$pre.css('display',self.layout.display); 1050 1051 if(self._changingClass && self.animation.animateChangeLayout){ 1052 self._$container 1053 .removeClass(self._newClass) 1054 .addClass(self.layout.containerClass); 1055 } 1056 1057 self._execAction('_getFinalMixData', 1); 1058 }, 1059 1060 /** 1061 * Prepare Targets 1062 * @since 2.0.0 1063 */ 1064 1065 _prepTargets: function(){ 1066 var self = this, 1067 transformCSS = { 1068 _in: self._getPrefixedCSS('transform', self.effects.transformIn), 1069 _out: self._getPrefixedCSS('transform', self.effects.transformOut) 1070 }; 1071 1072 self._execAction('_prepTargets', 0); 1073 1074 if(self.animation.animateResizeContainer){ 1075 self._$parent.css('height',self._startHeight+'px'); 1076 } 1077 1078 for(var i = 0; i < self._$toShow.length; i++){ 1079 var el = self._$toShow[i], 1080 $el = $(el); 1081 1082 el.style.opacity = self.effects.opacity; 1083 el.style.display = (self._changingLayout && self.animation.animateChangeLayout) ? 1084 self._newDisplay : 1085 self.layout.display; 1086 1087 $el.css(transformCSS._in); 1088 1089 if(self.animation.animateResizeTargets){ 1090 el.style.width = el.dataset.finalWidth+'px'; 1091 el.style.height = el.dataset.finalHeight+'px'; 1092 el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1)+'px'; 1093 el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1)+'px'; 1094 } 1095 } 1096 1097 for(var i = 0; i < self._$pre.length; i++){ 1098 var el = self._$pre[i], 1099 $el = $(el), 1100 translate = { 1101 x: el.dataset.origPosX - el.dataset.interPosX, 1102 y: el.dataset.origPosY - el.dataset.interPosY 1103 }, 1104 transformCSS = self._getPrefixedCSS('transform','translate('+translate.x+'px,'+translate.y+'px)'); 1105 1106 $el.css(transformCSS); 1107 1108 if(self.animation.animateResizeTargets){ 1109 el.style.width = el.dataset.origWidth+'px'; 1110 el.style.height = el.dataset.origHeight+'px'; 1111 1112 if(el.dataset.origWidth - el.dataset.finalWidth){ 1113 el.style.marginRight = -(el.dataset.origWidth - el.dataset.interWidth) + (el.dataset.origMarginRight * 1)+'px'; 1114 } 1115 1116 if(el.dataset.origHeight - el.dataset.finalHeight){ 1117 el.style.marginBottom = -(el.dataset.origHeight - el.dataset.interHeight) + (el.dataset.origMarginBottom * 1) +'px'; 1118 } 1119 } 1120 } 1121 1122 self._execAction('_prepTargets', 1); 1123 }, 1124 1125 /** 1126 * Animate Targets 1127 * @since 2.0.0 1128 */ 1129 1130 _animateTargets: function(){ 1131 var self = this; 1132 1133 self._execAction('_animateTargets', 0); 1134 1135 self._targetsDone = 0; 1136 self._targetsBound = 0; 1137 1138 self._$parent 1139 .css(self._getPrefixedCSS('perspective', self.animation.perspectiveDistance+'px')) 1140 .css(self._getPrefixedCSS('perspective-origin', self.animation.perspectiveOrigin)); 1141 1142 if(self.animation.animateResizeContainer){ 1143 self._$parent 1144 .css(self._getPrefixedCSS('transition','height '+self.animation.duration+'ms ease')) 1145 .css('height',self._newHeight+'px'); 1146 } 1147 1148 for(var i = 0; i < self._$toShow.length; i++){ 1149 var el = self._$toShow[i], 1150 $el = $(el), 1151 translate = { 1152 x: el.dataset.finalPosX - el.dataset.interPosX, 1153 y: el.dataset.finalPosY - el.dataset.interPosY 1154 },
1155 delay = self._getDelay(i), 1156 toShowCSS = {}; 1157 1158 el.style.opacity = ''; 1159 1160 for(var j = 0; j < 2; j++){ 1161 var a = j === 0 ? a = self._prefix : ''; 1162 1163 if(self._ff && self._ff <= 20){ 1164 toShowCSS[a+'transition-property'] = 'all'; 1165 toShowCSS[a+'transition-timing-function'] = self.animation.easing+'ms'; 1166 toShowCSS[a+'transition-duration'] = self.animation.duration+'ms'; 1167 } 1168 1169 toShowCSS[a+'transition-delay'] = delay+'ms'; 1170 toShowCSS[a+'transform'] = 'translate('+translate.x+'px,'+translate.y+'px)'; 1171 } 1172 1173 if(self.effects.transform || self.effects.opacity){ 1174 self._bindTargetDone($el); 1175 } 1176 1177 (self._ff && self._ff <= 20) ? 1178 $el.css(toShowCSS) : 1179 $el.css(self.effects.transition).css(toShowCSS); 1180 } 1181 1182 for(var i = 0; i < self._$pre.length; i++){ 1183 var el = self._$pre[i], 1184 $el = $(el), 1185 translate = { 1186 x: el.dataset.finalPosX - el.dataset.interPosX, 1187 y: el.dataset.finalPosY - el.dataset.interPosY 1188 }, 1189 delay = self._getDelay(i); 1190 1191 if(!( 1192 el.dataset.finalPosX === el.dataset.origPosX && 1193 el.dataset.finalPosY === el.dataset.origPosY 1194 )){ 1195 self._bindTargetDone($el); 1196 } 1197 1198 $el.css(self._getPrefixedCSS('transition', 'all '+self.animation.duration+'ms '+self.animation.easing+' '+delay+'ms')); 1199 $el.css(self._getPrefixedCSS('transform', 'translate('+translate.x+'px,'+translate.y+'px)')); 1200 1201 if(self.animation.animateResizeTargets){ 1202 if(el.dataset.origWidth - el.dataset.finalWidth && el.dataset.finalWidth * 1){ 1203 el.style.width = el.dataset.finalWidth+'px'; 1204 el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth)+(el.dataset.finalMarginRight * 1)+'px'; 1205 } 1206 1207 if(el.dataset.origHeight - el.dataset.finalHeight && el.dataset.finalHeight * 1){ 1208 el.style.height = el.dataset.finalHeight+'px'; 1209 el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight)+(el.dataset.finalMarginBottom * 1) +'px'; 1210 } 1211 } 1212 } 1213 1214 if(self._changingClass){ 1215 self._$container 1216 .removeClass(self.layout.containerClass) 1217 .addClass(self._newClass); 1218 } 1219 1220 for(var i = 0; i < self._$toHide.length; i++){ 1221 var el = self._$toHide[i], 1222 $el = $(el),
1223 delay = self._getDelay(i), 1224 toHideCSS = {}; 1225 1226 for(var j = 0; j<2; j++){ 1227 var a = j === 0 ? a = self._prefix : ''; 1228 1229 toHideCSS[a+'transition-delay'] = delay+'ms'; 1230 toHideCSS[a+'transform'] = self.effects.transformOut; 1231 toHideCSS.opacity = self.effects.opacity; 1232 } 1233 1234 $el.css(self.effects.transition).css(toHideCSS); 1235 1236 if(self.effects.transform || self.effects.opacity){ 1237 self._bindTargetDone($el); 1238 }; 1239 } 1240 1241 self._execAction('_animateTargets', 1); 1242 1243 }, 1244 1245 /** 1246 * Bind Targets TransitionEnd 1247 * @since 2.0.0 1248 * @param {object} $el 1249 */ 1250 1251 _bindTargetDone: function($el){ 1252 var self = this, 1253 el = $el[0]; 1254 1255 self._execAction('_bindTargetDone', 0, arguments); 1256 1257 if(!el.dataset.bound){ 1258 1259 el.dataset.bound = true; 1260 self._targetsBound++; 1261 1262 $el.on('webkitTransitionEnd.mixItUp transitionend.mixItUp',function(e){ 1263 if( 1264 (e.originalEvent.propertyName.indexOf('transform') > -1 || 1265 e.originalEvent.propertyName.indexOf('opacity') > -1) && 1266 $(e.originalEvent.target).is(self.selectors.target) 1267 ){ 1268 $el.off('.mixItUp'); 1269 delete el.dataset.bound; 1270 self._targetDone(); 1271 } 1272 }); 1273 } 1274 1275 self._execAction('_bindTargetDone', 1, arguments); 1276 }, 1277 1278 /** 1279 * Target Done 1280 * @since 2.0.0 1281 */ 1282 1283 _targetDone: function(){ 1284 var self = this; 1285 1286 self._execAction('_targetDone', 0); 1287 1288 self._targetsDone++; 1289 1290 (self._targetsDone === self._targetsBound) && self._cleanUp(); 1291 1292 self._execAction('_targetDone', 1); 1293 }, 1294 1295 /** 1296 * Clean Up 1297 * @since 2.0.0 1298 */ 1299 1300 _cleanUp: function(){ 1301 var self = this, 1302 targetStyles = self.animation.animateResizeTargets ? 'transform opacity width height margin-bottom margin-right' : 'transform opacity'; 1303 unBrake = function(){ 1304 self._$targets.removeStyle('transition', self._prefix); 1305 }; 1306 1307 self._execAction('_cleanUp', 0); 1308 1309 !self._changingLayout ?
1310 self._$show.css('display',self.layout.display) : 1311 self._$show.css('display',self._newDisplay); 1312 1313 self._$targets.css(self._brake); 1314 1315 self._$targets 1316 .removeStyle(targetStyles, self._prefix) 1317 .removeAttr('data-inter-pos-x data-inter-pos-y data-final-pos-x data-final-pos-y data-orig-pos-x data-orig-pos-y data-orig-height data-orig-width data-final-height data-final-width data-inter-width data-inter-height data-orig-margin-right data-orig-margin-bottom data-inter-margin-right data-inter-margin-bottom data-final-margin-right data-final-margin-bottom'); 1318 1319 self._$hide.removeStyle('display'); 1320 1321 self._$parent.removeStyle('height transition perspective-distance perspective perspective-origin-x perspective-origin-y perspective-origin perspectiveOrigin', self._prefix); 1322 1323 if(self._sorting){ 1324 self._printSort(); 1325 self._activeSort = self._newSortString; 1326 self._sorting = false; 1327 } 1328 1329 if(self._changingLayout){ 1330 if(self._changingDisplay){ 1331 self.layout.display = self._newDisplay; 1332 self._changingDisplay = false; 1333 } 1334 1335 if(self._changingClass){ 1336 self._$parent.removeClass(self.layout.containerClass).addClass(self._newClass); 1337 self.layout.containerClass = self._newClass; 1338 self._changingClass = false; 1339 } 1340 1341 self._changingLayout = false; 1342 } 1343 1344 self._refresh(); 1345 1346 self._buildState(); 1347 1348 if(self._state.fail){ 1349 self._$container.addClass(self.layout.containerClassFail); 1350 } 1351 1352 self._$show = $(); 1353 self._$hide = $(); 1354 1355 if(window.requestAnimationFrame){ 1356 requestAnimationFrame(unBrake); 1357 } 1358 1359 self._mixing = false; 1360 1361 if(typeof self.callbacks._user === 'function'){ 1362 self.callbacks._user.call(self._domNode, self._state, self); 1363 } 1364 1365 if(typeof self.callbacks.onMixEnd === 'function'){ 1366 self.callbacks.onMixEnd.call(self._domNode, self._state, self); 1367 } 1368 1369 self._$container.trigger('mixEnd', [self._state, self]); 1370 1371 if(self._state.fail){ 1372 (typeof self.callbacks.onMixFail === 'function') && self.callbacks.onMixFail.call(self._domNode, self._state, self); 1373 self._$container.trigger('mixFail', [self._state, self]); 1374 } 1375 1376 if(self._loading){ 1377 (typeof self.callbacks.onMixLoad === 'function') && self.callbacks.onMixLoad.call(self._domNode, self._state, self); 1378 self._$container.trigger('mixLoad', [self._state, self]); 1379 } 1380 1381 if(self._queue.length){ 1382 self._execAction('_queue', 0); 1383 1384 self.multiMix(self._queue[0][0],self._queue[0][1],self._queue[0][2]); 1385 self._queue.splice(0, 1); 1386 } 1387 1388 self._execAction('_cleanUp', 1); 1389 1390 self._loading = false; 1391 }, 1392 1393 /** 1394 * Get Prefixed CSS 1395 * @since 2.0.0 1396 * @param {string} property 1397 * @param {string} value 1398 * @param {boolean} prefixValue 1399 * @return {object} styles 1400 */ 1401 1402 _getPrefixedCSS: function(property, value, prefixValue){ 1403 var self = this, 1404 styles = {}; 1405 1406 for(i = 0; i < 2; i++){ 1407 var prefix = i === 0 ? self._prefix : ''; 1408 prefixValue ? styles[prefix+property] = prefix+value : styles[prefix+property] = value; 1409 } 1410 1411 return self._execFilter('_getPrefixedCSS', styles, arguments); 1412 }, 1413 1414 /** 1415 * Get Delay 1416 * @since 2.0.0 1417 * @param {number} i 1418 * @return {number} delay 1419 */ 1420 1421 _getDelay: function(i){ 1422 var self = this, 1423 n = typeof self.animation.staggerFunction === 'function' ? self.animation.staggerFunction.call(self._domNode, i, self._state) : i, 1424 delay = self.animation.stagger ? n * self.animation.staggerDuration : 0; 1425 1426 return self._execFilter('_getDelay', delay, arguments); 1427 }, 1428 1429 /** 1430 * Parse MultiMix Arguments 1431 * @since 2.0.0 1432 * @param {array} args 1433 * @return {object} output 1434 */ 1435 1436 _parseMultiMixArgs: function(args){ 1437 var self = this, 1438 output = { 1439 command: null, 1440 animate: self.animation.enable, 1441 callback: null 1442 }; 1443 1444 for(var i = 0; i < args.length; i++){ 1445 var arg = args[i]; 1446 1447 if(arg !== null){ 1448 if(typeof arg === 'object' || typeof arg === 'string'){ 1449 output.command = arg; 1450 } else if(typeof arg === 'boolean'){ 1451 output.animate = arg; 1452 } else if(typeof arg === 'function'){ 1453 output.callback = arg; 1454 } 1455 } 1456 } 1457 1458 return self._execFilter('_parseMultiMixArgs', output, arguments); 1459 }, 1460 1461 /** 1462 * Parse Insert Arguments 1463 * @since 2.0.0 1464 * @param {array} args 1465 * @return {object} output 1466 */ 1467 1468 _parseInsertArgs: function(args){ 1469 var self = this, 1470 output = { 1471 index: 0, 1472 $object: $(), 1473 multiMix: {filter: self._state.activeFilter}, 1474 callback: null 1475 }; 1476 1477 for(var i = 0; i < args.length; i++){ 1478 var arg = args[i]; 1479 1480 if(typeof arg === 'number'){ 1481 output.index = arg; 1482 } else if(typeof arg === 'object' && arg instanceof $){ 1483 output.$object = arg; 1484 } else if(typeof arg === 'object' && arg instanceof HTMLElement){ 1485 output.$object = $(arg); 1486 } else if(typeof arg === 'object' && arg !== null){ 1487 output.multiMix = arg;
1488 } else if(typeof arg === 'boolean' && !arg){ 1489 output.multiMix = false; 1490 } else if(typeof arg === 'function'){ 1491 output.callback = arg; 1492 } 1493 } 1494 1495 return self._execFilter('_parseInsertArgs', output, arguments); 1496 }, 1497 1498 /** 1499 * Execute Action 1500 * @since 2.0.0 1501 * @param {string} methodName 1502 * @param {boolean} isPost 1503 * @param {array} args 1504 */ 1505 1506 _execAction: function(methodName, isPost, args){ 1507 var self = this, 1508 context = isPost ? 'post' : 'pre'; 1509 1510 if(!self._actions.isEmptyObject && self._actions.hasOwnProperty(methodName)){ 1511 for(var key in self._actions[methodName][context]){ 1512 self._actions[methodName][context][key].call(self, args); 1513 } 1514 } 1515 }, 1516 1517 /** 1518 * Execute Filter 1519 * @since 2.0.0 1520 * @param {string} methodName 1521 * @param {mixed} value 1522 * @return {mixed} value 1523 */ 1524 1525 _execFilter: function(methodName, value, args){ 1526 var self = this; 1527 1528 if(!self._filters.isEmptyObject && self._filters.hasOwnProperty(methodName)){ 1529 for(var key in self._filters[methodName]){ 1530 return self._filters[methodName][key].call(self, args); 1531 } 1532 } else { 1533 return value; 1534 } 1535 }, 1536 1537 /* Helpers 1538 ---------------------------------------------------------------------- */ 1539 1540 _helpers: { 1541 1542 /** 1543 * CamelCase 1544 * @since 2.0.0 1545 * @param {string} 1546 * @return {string} 1547 */ 1548 1549 _camelCase: function(string){ 1550 return string.replace(/-([a-z])/g, function(g){ 1551 return g[1].toUpperCase(); 1552 }); 1553 } 1554 }, 1555 1556 /* Public Methods 1557 ---------------------------------------------------------------------- */ 1558 1559 /** 1560 * Is Mixing 1561 * @since 2.0.0 1562 * @return {boolean} 1563 */ 1564 1565 isMixing: function(){ 1566 var self = this; 1567 1568 return self._execFilter('isMixing', self._mixing); 1569 }, 1570 1571 /** 1572 * Filter (public) 1573 * @since 2.0.0 1574 * @param {array} arguments 1575 */ 1576 1577 filter: function(){ 1578 var self = this, 1579 args = self._parseMultiMixArgs(arguments); 1580 1581 self._clicking && (self._toggleString = ''); 1582 1583 self.multiMix({filter: args.command}, args.animate, args.callback); 1584 }, 1585 1586 /** 1587 * Sort (public) 1588 * @since 2.0.0 1589 * @param {array} arguments 1590 */ 1591 1592 sort: function(){ 1593 var self = this, 1594 args = self._parseMultiMixArgs(arguments); 1595 1596 self.multiMix({sort: args.command}, args.animate, args.callback); 1597 }, 1598 1599 /** 1600 * Change Layout (public) 1601 * @since 2.0.0 1602 * @param {array} arguments 1603 */ 1604 1605 changeLayout: function(){ 1606 var self = this, 1607 args = self._parseMultiMixArgs(arguments); 1608 1609 self.multiMix({changeLayout: args.command}, args.animate, args.callback); 1610 }, 1611 1612 /** 1613 * MultiMix 1614 * @since 2.0.0 1615 * @param {array} arguments 1616 */ 1617 1618 multiMix: function(){ 1619 var self = this, 1620 args = self._parseMultiMixArgs(arguments); 1621 1622 self._execAction('multiMix', 0, arguments); 1623 1624 if(!self._mixing){ 1625 if(self.controls.enable && !self._clicking){ 1626 self.controls.toggleFilterButtons && self._buildToggleArray(); 1627 self._updateControls(args.command, self.controls.toggleFilterButtons); 1628 } 1629 1630 (self._queue.length < 2) && (self._clicking = false); 1631 1632 delete self.callbacks._user; 1633 if(args.callback) self.callbacks._user = args.callback; 1634 1635 var sort = args.command.sort, 1636 filter = args.command.filter, 1637 changeLayout = args.command.changeLayout; 1638 1639 self._refresh(); 1640 1641 if(sort){ 1642 self._newSort = self._parseSort(sort); 1643 self._newSortString = sort; 1644 1645 self._sorting = true; 1646 self._sort(); 1647 } 1648 1649 if(filter !== undf){ 1650 filter = (filter === 'all') ? self.selectors.target : filter; 1651 1652 self._activeFilter = filter; 1653 } 1654 1655 self._filter(); 1656 1657 if(changeLayout){ 1658 self._newDisplay = (typeof changeLayout === 'string') ? changeLayout : changeLayout.display || self.layout.display; 1659 self._newClass = changeLayout.containerClass || ''; 1660 1661 if( 1662 self._newDisplay !== self.layout.display || 1663 self._newClass !== self.layout.containerClass 1664 ){ 1665 self._changingLayout = true; 1666 1667 self._changingClass = (self._newClass !== self.layout.containerClass); 1668 self._changingDisplay = (self._newDisplay !== self.layout.display); 1669 } 1670 } 1671 1672 self._$targets.css(self._brake); 1673 1674 self._goMix(args.animate ^ self.animation.enable ? args.animate : self.animation.enable); 1675 1676 self._execAction('multiMix', 1, arguments); 1677 1678 } else { 1679 if(self.animation.queue && self._queue.length < self.animation.queueLimit){ 1680 self._queue.push(arguments); 1681 1682 (self.controls.enable && !self._clicking) && self._updateControls(args.command); 1683 1684 self._execAction('multiMixQueue', 1, arguments); 1685 1686 } else { 1687 if(typeof self.callbacks.onMixBusy === 'function'){ 1688 self.callbacks.onMixBusy.call(self._domNode, self._state, self); 1689 } 1690 self._$container.trigger('mixBusy', [self._state, self]); 1691 1692 self._execAction('multiMixBusy', 1, arguments); 1693 } 1694 } 1695 }, 1696 1697 /** 1698 * Insert 1699 * @since 2.0.0 1700 * @param {array} arguments 1701 */ 1702 1703 insert: function(){ 1704 var self = this, 1705 args = self._parseInsertArgs(arguments), 1706 callback = (typeof args.callback === 'function') ? args.callback : null, 1707 frag = document.createDocumentFragment(), 1708 target = (args.index < self._$targets.length) ? 1709 self._$targets[args.index] : 1710 self._$targets[self._$targets.length-1].nextElementSibling; 1711 1712 self._execAction('insert', 0, arguments); 1713 1714 if(args.$object){ 1715 for(var i = 0; i < args.$object.length; i++){ 1716 var el = args.$object[i]; 1717 1718 frag.appendChild(el); 1719 frag.appendChild(document.createTextNode(' ')); 1720 } 1721 1722 self._$parent[0].insertBefore(frag, target); 1723 } 1724 1725 self._execAction('insert', 1, arguments); 1726 1727 if(typeof args.multiMix === 'object'){
1728 self.multiMix(args.multiMix, callback); 1729 } else { 1730 self._refresh(); 1731 } 1732 }, 1733 1734 /** 1735 * Prepend 1736 * @since 2.0.0 1737 * @param {array} arguments 1738 */ 1739 1740 prepend: function(){ 1741 var self = this, 1742 args = self._parseInsertArgs(arguments); 1743 1744 self.insert(0, args.$object, args.multiMix, args.callback); 1745 }, 1746 1747 /** 1748 * Append 1749 * @since 2.0.0 1750 * @param {array} arguments 1751 */ 1752 1753 append: function(){ 1754 var self = this, 1755 args = self._parseInsertArgs(arguments); 1756 1757 self.insert(self._state.totalTargets, args.$object, args.multiMix, args.callback); 1758 }, 1759 1760 /** 1761 * getOption 1762 * @since 2.0.0 1763 * @param {string} string 1764 * @return {mixed} value 1765 */ 1766 1767 getOption: function(string){ 1768 var self = this, 1769 getProperty = function(obj, prop){ 1770 var parts = prop.split('.'), 1771 last = parts.pop(), 1772 l = parts.length, 1773 i = 1, 1774 current = parts[0] || prop; 1775 1776 while((obj = obj[current]) && i < l){ 1777 current = parts[i]; 1778 i++; 1779 } 1780 1781 if(obj !== undf){ 1782 return obj[last] !== undf ? obj[last] : obj; 1783 } 1784 }; 1785 1786 return string ? self._execFilter('getOption', getProperty(self, string), arguments) : self; 1787 }, 1788 1789 /** 1790 * setOptions 1791 * @since 2.0.0 1792 * @param {object} config 1793 * @return {object} domNode 1794 */ 1795 1796 setOptions: function(config){ 1797 var self = this; 1798 1799 self._execAction('setOptions', 0, arguments); 1800 1801 typeof config === 'object' && $.extend(true, self, config); 1802 1803 self._execAction('setOptions', 1, arguments); 1804 }, 1805 1806 /** 1807 * getState 1808 * @since 2.0.0 1809 * @return {object} state 1810 */ 1811 1812 getState: function(){ 1813 var self = this; 1814 1815 return self._execFilter('getState', self._state, self); 1816 }, 1817 1818 /** 1819 * Destroy 1820 * @since 2.0.0 1821 * @param {boolean} hideAll 1822 * @return {object} domNode 1823 */ 1824 1825 destroy: function(hideAll){ 1826 var self = this; 1827 1828 self._execAction('destroy', 0, arguments); 1829 1830 self._$body 1831 .add($(self.selectors.sort)) 1832 .add($(self.selectors.filter)) 1833 .off('.mixItUp'); 1834 1835 for(var i = 0; i < self._$targets.length; i++){ 1836 var target = self._$targets[i]; 1837 1838 hideAll && (target.style.display = ''); 1839 1840 delete target.mixParent; 1841 } 1842 1843 self._execAction('destroy', 1, arguments); 1844 1845 delete $.MixItUp.prototype._instances[self._id]; 1846 } 1847 1848 }; 1849 1850 /* jQuery Methods 1851 ---------------------------------------------------------------------- */ 1852 1853 /** 1854 * jQuery .mixItUp() method 1855 * @since 2.0.0 1856 * @extends $.fn 1857 */ 1858 1859 $.fn.mixItUp = function(){ 1860 var args = arguments, 1861 dataReturn = [], 1862 eachReturn, 1863 _instantiate = function(domNode, settings){ 1864 var instance = new $.MixItUp(), 1865 rand = function(){ 1866 return ('00000'+(Math.random()*16777216<<0).toString(16)).substr(-6).toUpperCase(); 1867 }; 1868 1869 instance._execAction('_instantiate', 0, arguments); 1870 1871 domNode.id = !domNode.id ? 'MixItUp'+rand() : domNode.id; 1872 1873 if(!instance._instances[domNode.id]){ 1874 instance._instances[domNode.id] = instance; 1875 instance._init(domNode, settings); 1876 } 1877 1878 instance._execAction('_instantiate', 1, arguments); 1879 }; 1880 1881 eachReturn = this.each(function(){ 1882 if(args && typeof args[0] === 'string'){ 1883 var instance = $.MixItUp.prototype._instances[this.id]; 1884 if(args[0] == 'isLoaded'){ 1885 dataReturn.push(instance ? true : false); 1886 } else { 1887 var data = instance[args[0]](args[1], args[2], args[3]); 1888 if(data !== undf)dataReturn.push(data); 1889 } 1890 } else { 1891 _instantiate(this, args[0]); 1892 } 1893 }); 1894 1895 if(dataReturn.length){ 1896 return dataReturn.length > 1 ? dataReturn : dataReturn[0]; 1897 } else { 1898 return eachReturn; 1899 } 1900 }; 1901 1902 /** 1903 * jQuery .removeStyle() method 1904 * @since 2.0.0 1905 * @extends $.fn 1906 */ 1907 1908 $.fn.removeStyle = function(style, prefix){ 1909 prefix = prefix ? prefix : ''; 1910 1911 return this.each(function(){ 1912 var el = this, 1913 styles = style.split(' '); 1914 1915 for(var i = 0; i < styles.length; i++){ 1916 for(var j = 0; j < 2; j++){ 1917 var prop = j ? styles[i] : prefix+styles[i]; 1918 if( 1919 el.style[prop] !== undf && 1920 typeof el.style[prop] !== 'unknown' && 1921 el.style[prop].length > 0 1922 ){ 1923 el.style[prop] = ''; 1924 } 1925 if(!prefix)break; 1926 } 1927 } 1928 1929 if(el.attributes && el.attributes.style && el.attributes.style !== undf && el.attributes.style.nodeValue === ''){ 1930 el.attributes.removeNamedItem('style'); 1931 } 1932 }); 1933 }; 1934 1935})(jQuery);
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.