2sandaljepit

mixitup.js

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