first commit

This commit is contained in:
2025-09-16 01:40:08 +03:00
commit d9969e1394
252 changed files with 41184 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
/**!
* {{title}} v{{version}}
* {{description}}
* Build {{buildId}}
*
* @copyright Copyright {{beginCopyrightYear}}-{{currentYear}} {{author}}.
* @author {{author}}.
* @link {{websiteUrl}}
*
* @license Commercial use requires a commercial license.
* {{commercialLicenseUrl}}
*
* Non-commercial use permitted under same terms as CC BY-NC 3.0 license.
* {{nonCommercialLicenseUrl}}
*/

View File

@@ -0,0 +1,68 @@
/* global mixitup, h */
/**
* The BaseStatic class holds a set of static methods which are then added to all other
* extensible MixItUp classes as a means of integrating extensions via the addition of new
* methods and/or actions and hooks.
*
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.BaseStatic = function() {
this.actions = {};
this.filters = {};
/**
* Performs a shallow extend on the class's prototype, adding one or more new members to
* the class in a single operation.
*
* @memberof mixitup.BaseStatic
* @public
* @static
* @since 2.1.0
* @param {object} extension
* @return {void}
*/
this.extend = function(extension) {
h.extend(this.prototype, extension);
};
/**
* Registers a function to be called on the action hook of the provided name.
*
* @memberof mixitup.BaseStatic
* @public
* @static
* @since 2.1.0
* @param {string} hookName
* @param {string} extensionName
* @param {function} func
* @return {void}
*/
this.registerAction = function(hookName, extensionName, func) {
(this.actions[hookName] = this.actions[hookName] || {})[extensionName] = func;
};
/**
* Registers a function to be called on the filter of the provided name.
*
* @memberof mixitup.BaseStatic
* @public
* @static
* @since 2.1.0
* @param {string} hookName
* @param {string} extensionName
* @param {function} func
* @return {void}
*/
this.registerFilter = function(hookName, extensionName, func) {
(this.filters[hookName] = this.filters[hookName] || {})[extensionName] = func;
};
};

76
mixitup-3.3.1/src/base.js Normal file
View File

@@ -0,0 +1,76 @@
/* global mixitup, h */
/**
* The Base class adds instance methods to all other extensible MixItUp classes,
* enabling the calling of any registered hooks.
*
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Base = function() {};
mixitup.Base.prototype = {
constructor: mixitup.Base,
/**
* Calls any registered hooks for the provided action.
*
* @memberof mixitup.Base
* @private
* @instance
* @since 2.0.0
* @param {string} actionName
* @param {Array<*>} args
* @return {void}
*/
callActions: function(actionName, args) {
var self = this,
hooks = self.constructor.actions[actionName],
extensionName = '';
if (!hooks || h.isEmptyObject(hooks)) return;
for (extensionName in hooks) {
hooks[extensionName].apply(self, args);
}
},
/**
* Calls any registered hooks for the provided filter.
*
* @memberof mixitup.Base
* @private
* @instance
* @since 2.0.0
* @param {string} filterName
* @param {*} input
* @param {Array<*>} args
* @return {*}
*/
callFilters: function(filterName, input, args) {
var self = this,
hooks = self.constructor.filters[filterName],
output = input,
extensionName = '';
if (!hooks || h.isEmptyObject(hooks)) return output;
args = args || [];
for (extensionName in hooks) {
args = h.arrayFromList(args);
args.unshift(output);
output = hooks[extensionName].apply(self, args);
}
return output;
}
};

View File

@@ -0,0 +1,86 @@
/* global mixitup, h */
/**
* A jQuery-collection-like wrapper around one or more `mixitup.Mixer` instances
* allowing simultaneous control of said instances similar to the MixItUp 2 API.
*
* @example
* new mixitup.Collection(instances)
*
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
* @param {mixitup.Mixer[]} instances
*/
mixitup.Collection = function(instances) {
var instance = null,
i = -1;
this.callActions('beforeConstruct');
for (i = 0; instance = instances[i]; i++) {
this[i] = instance;
}
this.length = instances.length;
this.callActions('afterConstruct');
h.freeze(this);
};
mixitup.BaseStatic.call(mixitup.Collection);
mixitup.Collection.prototype = Object.create(mixitup.Base.prototype);
h.extend(mixitup.Collection.prototype,
/** @lends mixitup.Collection */
{
constructor: mixitup.Collection,
/**
* Calls a method on all instances in the collection by passing the method
* name as a string followed by any applicable parameters to be curried into
* to the method.
*
* @example
* .mixitup(methodName[,arg1][,arg2..]);
*
* @example
* var collection = new Collection([mixer1, mixer2]);
*
* return collection.mixitup('filter', '.category-a')
* .then(function(states) {
* state.forEach(function(state) {
* console.log(state.activeFilter.selector); // .category-a
* });
* });
*
* @public
* @instance
* @since 3.0.0
* @param {string} methodName
* @return {Promise<Array<mixitup.State>>}
*/
mixitup: function(methodName) {
var self = this,
instance = null,
args = Array.prototype.slice.call(arguments),
tasks = [],
i = -1;
this.callActions('beforeMixitup');
args.shift();
for (i = 0; instance = self[i]; i++) {
tasks.push(instance[methodName].apply(instance, args));
}
return self.callFilters('promiseMixitup', h.all(tasks, mixitup.libraries), arguments);
}
});

View File

@@ -0,0 +1,28 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.changeLayout()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandChangeLayout = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.containerClassName = '';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandChangeLayout);
mixitup.CommandChangeLayout.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandChangeLayout.prototype.constructor = mixitup.CommandChangeLayout;

View File

@@ -0,0 +1,28 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.dataset()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandDataset = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.dataset = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandDataset);
mixitup.CommandDataset.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandDataset.prototype.constructor = mixitup.CommandDataset;

View File

@@ -0,0 +1,30 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.filter()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandFilter = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.selector = '';
this.collection = null;
this.action = 'show'; // enum: ['show', 'hide']
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandFilter);
mixitup.CommandFilter.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandFilter.prototype.constructor = mixitup.CommandFilter;

View File

@@ -0,0 +1,31 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.insert()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandInsert = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.index = 0;
this.collection = [];
this.position = 'before'; // enum: ['before', 'after']
this.sibling = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandInsert);
mixitup.CommandInsert.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandInsert.prototype.constructor = mixitup.CommandInsert;

View File

@@ -0,0 +1,32 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.multimix()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandMultimix = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.filter = null;
this.sort = null;
this.insert = null;
this.remove = null;
this.changeLayout = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandMultimix);
mixitup.CommandMultimix.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandMultimix.prototype.constructor = mixitup.CommandMultimix;

View File

@@ -0,0 +1,29 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.remove()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandRemove = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.targets = [];
this.collection = [];
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandRemove);
mixitup.CommandRemove.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandRemove.prototype.constructor = mixitup.CommandRemove;

View File

@@ -0,0 +1,32 @@
/* global mixitup, h */
/**
* An object into which all arbitrary arguments sent to '.sort()' are mapped.
*
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.CommandSort = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.sortString = '';
this.attribute = '';
this.order = 'asc';
this.collection = null;
this.next = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.CommandSort);
mixitup.CommandSort.prototype = Object.create(mixitup.Base.prototype);
mixitup.CommandSort.prototype.constructor = mixitup.CommandSort;

View File

@@ -0,0 +1,491 @@
/* global mixitup, h */
/**
* A group of properties defining the mixer's animation and effects settings.
*
* @constructor
* @memberof mixitup.Config
* @name animation
* @namespace
* @public
* @since 2.0.0
*/
mixitup.ConfigAnimation = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A boolean dictating whether or not animation should be enabled for the MixItUp instance.
* If `false`, all operations will occur instantly and syncronously, although callback
* functions and any returned promises will still be fulfilled.
*
* @example <caption>Example: Create a mixer with all animations disabled</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* enable: false
* }
* });
*
* @name enable
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.enable = true;
/**
* A string of one or more space-seperated properties to which transitions will be
* applied for all filtering animations.
*
* Properties can be listed any order or combination, although they will be applied in a specific
* predefined order to produce consistent results.
*
* To learn more about available effects, experiment with our <a href="https://www.kunkalabs.com/mixitup/">
* sandbox demo</a> and try out the "Export config" button in the Animation options drop down.
*
* @example <caption>Example: Apply "fade" and "translateZ" effects to all animations</caption>
* // As targets are filtered in and out, they will fade between
* // opacity 1 and 0 and transform between translateZ(-100px) and
* // translateZ(0).
*
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'fade translateZ(-100px)'
* }
* });
*
* @name effects
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default 'fade scale'
*/
this.effects = 'fade scale';
/**
* A string of one or more space-seperated effects to be applied only to filter-in
* animations, overriding `config.animation.effects` if set.
*
* @example <caption>Example: Apply downwards vertical translate to targets being filtered in</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* effectsIn: 'fade translateY(-100%)'
* }
* });
*
* @name effectsIn
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default ''
*/
this.effectsIn = '';
/**
* A string of one or more space-seperated effects to be applied only to filter-out
* animations, overriding `config.animation.effects` if set.
*
* @example <caption>Example: Apply upwards vertical translate to targets being filtered out</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* effectsOut: 'fade translateY(-100%)'
* }
* });
*
* @name effectsOut
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default ''
*/
this.effectsOut = '';
/**
* An integer dictating the duration of all MixItUp animations in milliseconds, not
* including any additional delay apllied via the `'stagger'` effect.
*
* @example <caption>Example: Apply an animation duration of 200ms to all mixitup animations</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* duration: 200
* }
* });
*
* @name duration
* @memberof mixitup.Config.animation
* @instance
* @type {number}
* @default 600
*/
this.duration = 600;
/**
* A valid CSS3 transition-timing function or shorthand. For a full list of accepted
* values, visit <a href="http://easings.net" target="_blank">easings.net</a>.
*
* @example <caption>Example 1: Apply "ease-in-out" easing to all animations</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* easing: 'ease-in-out'
* }
* });
*
* @example <caption>Example 2: Apply a custom "cubic-bezier" easing function to all animations</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* easing: 'cubic-bezier(0.645, 0.045, 0.355, 1)'
* }
* });
*
* @name easing
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default 'ease'
*/
this.easing = 'ease';
/**
* A boolean dictating whether or not to apply perspective to the MixItUp container
* during animations. By default, perspective is always applied and creates the
* illusion of three-dimensional space for effects such as `translateZ`, `rotateX`,
* and `rotateY`.
*
* You may wish to disable this and define your own perspective settings via CSS.
*
* @example <caption>Example: Prevent perspective from being applied to any 3D transforms</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* applyPerspective: false
* }
* });
*
* @name applyPerspective
* @memberof mixitup.Config.animation
* @instance
* @type {bolean}
* @default true
*/
this.applyPerspective = true;
/**
* The perspective distance value to be applied to the container during animations,
* affecting any 3D-transform-based effects.
*
* @example <caption>Example: Set a perspective distance of 2000px</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'rotateY(-25deg)',
* perspectiveDistance: '2000px'
* }
* });
*
* @name perspectiveDistance
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default '3000px'
*/
this.perspectiveDistance = '3000px';
/**
* The perspective-origin value to be applied to the container during animations,
* affecting any 3D-transform-based effects.
*
* @example <caption>Example: Set a perspective origin in the top-right of the container</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'transateZ(-200px)',
* perspectiveOrigin: '100% 0'
* }
* });
*
* @name perspectiveOrigin
* @memberof mixitup.Config.animation
* @instance
* @type {string}
* @default '50% 50%'
*/
this.perspectiveOrigin = '50% 50%';
/**
* A boolean dictating whether or not to enable the queuing of operations.
*
* If `true` (default), and a control is clicked or an API call is made while another
* operation is progress, the operation will go into the queue and will be automatically exectuted
* when the previous operaitons is finished.
*
* If `false`, any requested operations will be ignored, and the `onMixBusy` callback and `mixBusy`
* event will be fired. If `debug.showWarnings` is enabled, a console warning will also occur.
*
* @example <caption>Example: Disable queuing</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* queue: false
* }
* });
*
* @name queue
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.queue = true;
/**
* An integer dictacting the maximum number of operations allowed in the queue at
* any time, when queuing is enabled.
*
* @example <caption>Example: Allow a maximum of 5 operations in the queue at any time</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* queueLimit: 5
* }
* });
*
* @name queueLimit
* @memberof mixitup.Config.animation
* @instance
* @type {number}
* @default 3
*/
this.queueLimit = 3;
/**
* A boolean dictating whether or not to transition the height and width of the
* container as elements are filtered in and out. If disabled, the container height
* will change abruptly.
*
* It may be desirable to disable this on mobile devices as the CSS `height` and
* `width` properties do not receive GPU-acceleration and can therefore cause stuttering.
*
* @example <caption>Example 1: Disable the transitioning of the container height and/or width</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* animateResizeContainer: false
* }
* });
*
* @example <caption>Example 2: Disable the transitioning of the container height and/or width for mobile devices only</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* animateResizeContainer: myFeatureTests.isMobile ? false : true
* }
* });
*
* @name animateResizeContainer
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.animateResizeContainer = true;
/**
* A boolean dictating whether or not to transition the height and width of target
* elements as they change throughout the course of an animation.
*
* This is often a must for flex-box grid layouts where the size of target elements may change
* depending on final their position in relation to their siblings, or for `.changeLayout()`
* operations where the size of targets change between layouts.
*
* NB: This feature requires additional calculations and manipulation to non-hardware-accelerated
* properties which may adversely affect performance on slower devices, and is therefore
* disabled by default.
*
* @example <caption>Example: Enable the transitioning of target widths and heights</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* animateResizeTargets: true
* }
* });
*
* @name animateResizeTargets
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default false
*/
this.animateResizeTargets = false;
/**
* A custom function used to manipulate the order in which the stagger delay is
* incremented when using the stagger effect.
*
* When using the 'stagger' effect, the delay applied to each target element is incremented
* based on its index. You may create a custom function to manipulate the order in which the
* delay is incremented and create engaging non-linear stagger effects.
*
* The function receives the index of the target element as a parameter, and must
* return an integer which serves as the multiplier for the stagger delay.
*
* @example <caption>Example 1: Stagger target elements by column in a 3-column grid</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'fade stagger(100ms)',
* staggerSequence: function(i) {
* return i % 3;
* }
* }
* });
*
* @example <caption>Example 2: Using an algorithm to produce a more complex sequence</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'fade stagger(100ms)',
* staggerSequence: function(i) {
* return (2*i) - (5*((i/3) - ((1/3) * (i%3))));
* }
* }
* });
*
* @name staggerSequence
* @memberof mixitup.Config.animation
* @instance
* @type {function}
* @default null
*/
this.staggerSequence = null;
/**
* A boolean dictating whether or not to reverse the direction of `translate`
* and `rotate` transforms for elements being filtered out.
*
* It can be used to create carousel-like animations where elements enter and exit
* from opposite directions. If enabled, the effect `translateX(-100%)` for elements
* being filtered in would become `translateX(100%)` for targets being filtered out.
*
* This functionality can also be achieved by providing seperate effects
* strings for `config.animation.effectsIn` and `config.animation.effectsOut`.
*
* @example <caption>Example: Reverse the desired direction on any translate/rotate effect for targets being filtered out</caption>
* // Elements being filtered in will be translated from '100%' to '0' while
* // elements being filtered out will be translated from 0 to '-100%'
*
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'fade translateX(100%)',
* reverseOut: true,
* nudge: false // Disable nudging to create a carousel-like effect
* }
* });
*
* @name reverseOut
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default false
*/
this.reverseOut = false;
/**
* A boolean dictating whether or not to "nudge" the animation path of targets
* when they are being filtered in and out simulatenously.
*
* This has been the default behavior of MixItUp since version 1, but it
* may be desirable to disable this effect when filtering directly from
* one exclusive set of targets to a different exclusive set of targets,
* to create a carousel-like effect, or a generally more subtle animation.
*
* @example <caption>Example: Disable the "nudging" of targets being filtered in and out simulatenously</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* nudge: false
* }
* });
*
* @name nudge
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.nudge = true;
/**
* A boolean dictating whether or not to clamp the height of the container while MixItUp's
* geometry tests are carried out before an operation.
*
* To prevent scroll-bar flicker, clamping is turned on by default. But in the case where the
* height of the container might affect its vertical positioning in the viewport
* (e.g. a vertically-centered container), this should be turned off to ensure accurate
* test results and a smooth animation.
*
* @example <caption>Example: Disable container height-clamping</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* clampHeight: false
* }
* });
*
* @name clampHeight
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.clampHeight = true;
/**
* A boolean dictating whether or not to clamp the width of the container while MixItUp's
* geometry tests are carried out before an operation.
*
* To prevent scroll-bar flicker, clamping is turned on by default. But in the case where the
* width of the container might affect its horitzontal positioning in the viewport
* (e.g. a horizontall-centered container), this should be turned off to ensure accurate
* test results and a smooth animation.
*
* @example <caption>Example: Disable container width-clamping</caption>
*
* var mixer = mixitup(containerEl, {
* animation: {
* clampWidth: false
* }
* });
*
* @name clampWidth
* @memberof mixitup.Config.animation
* @instance
* @type {boolean}
* @default true
*/
this.clampWidth = true;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigAnimation);
mixitup.ConfigAnimation.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigAnimation.prototype.constructor = mixitup.ConfigAnimation;

View File

@@ -0,0 +1,73 @@
/* global mixitup, h */
/**
* A group of properties relating to the behavior of the Mixer.
*
* @constructor
* @memberof mixitup.Config
* @name behavior
* @namespace
* @public
* @since 3.1.12
*/
mixitup.ConfigBehavior = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A boolean dictating whether to allow "live" sorting of the mixer.
*
* Because of the expensive nature of sorting, MixItUp makes use of several
* internal optimizations to skip redundant sorting operations, such as when
* the newly requested sort command is the same as the active one. The caveat
* to this optimization is that "live" edits to the value of a target's sorting
* attribute will be ignored when requesting a re-sort by the same attribute.
*
* By setting to `behavior.liveSort` to `true`, the mixer will always re-sort
* regardless of whether or not the sorting attribute and order have changed.
*
* @example <caption>Example: Enabling `liveSort` to allow for re-sorting</caption>
*
* var mixer = mixitup(containerEl, {
* behavior: {
* liveSort: true
* },
* load: {
* sort: 'edited:desc'
* }
* });
*
* var target = containerEl.children[3];
*
* console.log(target.getAttribute('data-edited')); // '2015-04-24'
*
* target.setAttribute('data-edited', '2017-08-10'); // Update the target's edited date
*
* mixer.sort('edited:desc')
* .then(function(state) {
* // The target is now at the top of the list
*
* console.log(state.targets[0] === target); // true
* });
*
* @name liveSort
* @memberof mixitup.Config.behavior
* @instance
* @type {boolean}
* @default false
*/
this.liveSort = false;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigBehavior);
mixitup.ConfigBehavior.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigBehavior.prototype.constructor = mixitup.ConfigBehavior;

View File

@@ -0,0 +1,184 @@
/* global mixitup, h */
/**
* A group of optional callback functions to be invoked at various
* points within the lifecycle of a mixer operation.
*
* Each function is analogous to an event of the same name triggered from the
* container element, and is invoked immediately after it.
*
* All callback functions receive the current `state` object as their first
* argument, as well as other more specific arguments described below.
*
* @constructor
* @memberof mixitup.Config
* @name callbacks
* @namespace
* @public
* @since 2.0.0
*/
mixitup.ConfigCallbacks = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A callback function invoked immediately after any MixItUp operation is requested
* and before animations have begun.
*
* A second `futureState` argument is passed to the function which represents the final
* state of the mixer once the requested operation has completed.
*
* @example <caption>Example: Adding an `onMixStart` callback function</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixStart: function(state, futureState) {
* console.log('Starting operation...');
* }
* }
* });
*
* @name onMixStart
* @memberof mixitup.Config.callbacks
* @instance
* @type {function}
* @default null
*/
this.onMixStart = null;
/**
* A callback function invoked when a MixItUp operation is requested while another
* operation is in progress, and the animation queue is full, or queueing
* is disabled.
*
* @example <caption>Example: Adding an `onMixBusy` callback function</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixBusy: function(state) {
* console.log('Mixer busy');
* }
* }
* });
*
* @name onMixBusy
* @memberof mixitup.Config.callbacks
* @instance
* @type {function}
* @default null
*/
this.onMixBusy = null;
/**
* A callback function invoked after any MixItUp operation has completed, and the
* state has been updated.
*
* @example <caption>Example: Adding an `onMixEnd` callback function</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixEnd: function(state) {
* console.log('Operation complete');
* }
* }
* });
*
* @name onMixEnd
* @memberof mixitup.Config.callbacks
* @instance
* @type {function}
* @default null
*/
this.onMixEnd = null;
/**
* A callback function invoked whenever an operation "fails", i.e. no targets
* could be found matching the requested filter.
*
* @example <caption>Example: Adding an `onMixFail` callback function</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixFail: function(state) {
* console.log('No items could be found matching the requested filter');
* }
* }
* });
*
* @name onMixFail
* @memberof mixitup.Config.callbacks
* @instance
* @type {function}
* @default null
*/
this.onMixFail = null;
/**
* A callback function invoked whenever a MixItUp control is clicked, and before its
* respective operation is requested.
*
* The clicked element is assigned to the `this` keyword within the function. The original
* click event is passed to the function as the second argument, which can be useful if
* using `<a>` tags as controls where the default behavior needs to be prevented.
*
* Returning `false` from the callback will prevent the control click from triggering
* an operation.
*
* @example <caption>Example 1: Adding an `onMixClick` callback function</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixClick: function(state, originalEvent) {
* console.log('The control "' + this.innerText + '" was clicked');
* }
* }
* });
*
* @example <caption>Example 2: Using `onMixClick` to manipulate the original click event</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixClick: function(state, originalEvent) {
* // Prevent original click event from bubbling up:
* originalEvent.stopPropagation();
*
* // Prevent default behavior of clicked element:
* originalEvent.preventDefault();
* }
* }
* });
*
* @example <caption>Example 3: Using `onMixClick` to conditionally cancel operations</caption>
* var mixer = mixitup(containerEl, {
* callbacks: {
* onMixClick: function(state, originalEvent) {
* // Perform some conditional check:
*
* if (myApp.isLoading) {
* // By returning false, we can prevent the control click from triggering an operation.
*
* return false;
* }
* }
* }
* });
*
* @name onMixClick
* @memberof mixitup.Config.callbacks
* @instance
* @type {function}
* @default null
*/
this.onMixClick = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigCallbacks);
mixitup.ConfigCallbacks.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigCallbacks.prototype.constructor = mixitup.ConfigCallbacks;

View File

@@ -0,0 +1,300 @@
/* global mixitup, h */
/**
* A group of properties defining the output and structure of class names programmatically
* added to controls and containers to reflect the state of the mixer.
*
* Most commonly, class names are added to controls by MixItUp to indicate that
* the control is active so that it can be styled accordingly - `'mixitup-control-active'` by default.
*
* Using a "BEM" like structure, each classname is broken into the three parts:
* a block namespace (`'mixitup'`), an element name (e.g. `'control'`), and an optional modifier
* name (e.g. `'active'`) reflecting the state of the element.
*
* By default, each part of the classname is concatenated together using single hyphens as
* delineators, but this can be easily customised to match the naming convention and style of
* your project.
*
* @constructor
* @memberof mixitup.Config
* @name classNames
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigClassNames = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* The "block" portion, or top-level namespace added to the start of any class names created by MixItUp.
*
* @example <caption>Example 1: changing the `config.classNames.block` value</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: 'portfolio'
* }
* });
*
* // Active control output: "portfolio-control-active"
*
* @example <caption>Example 2: Removing `config.classNames.block`</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: ''
* }
* });
*
* // Active control output: "control-active"
*
* @name block
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'mixitup'
*/
this.block = 'mixitup';
/**
* The "element" portion of the class name added to container.
*
* @name elementContainer
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'container'
*/
this.elementContainer = 'container';
/**
* The "element" portion of the class name added to filter controls.
*
* By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but
* each type's element value can be individually overwritten to match the unique classNames of your controls as needed.
*
* @example <caption>Example 1: changing the `config.classNames.elementFilter` value</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* elementFilter: 'filter'
* }
* });
*
* // Active filter output: "mixitup-filter-active"
*
* @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementFilter` values</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: 'portfolio',
* elementFilter: 'filter'
* }
* });
*
* // Active filter output: "portfolio-filter-active"
*
* @name elementFilter
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'control'
*/
this.elementFilter = 'control';
/**
* The "element" portion of the class name added to sort controls.
*
* By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but
* each type's element value can be individually overwritten to match the unique classNames of your controls as needed.
*
* @example <caption>Example 1: changing the `config.classNames.elementSort` value</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* elementSort: 'sort'
* }
* });
*
* // Active sort output: "mixitup-sort-active"
*
* @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementSort` values</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: 'portfolio',
* elementSort: 'sort'
* }
* });
*
* // Active sort output: "portfolio-sort-active"
*
* @name elementSort
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'control'
*/
this.elementSort = 'control';
/**
* The "element" portion of the class name added to multimix controls.
*
* By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but
* each type's element value can be individually overwritten to match the unique classNames of your controls as needed.
*
* @example <caption>Example 1: changing the `config.classNames.elementMultimix` value</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* elementMultimix: 'multimix'
* }
* });
*
* // Active multimix output: "mixitup-multimix-active"
*
* @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementMultimix` values</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: 'portfolio',
* elementSort: 'multimix'
* }
* });
*
* // Active multimix output: "portfolio-multimix-active"
*
* @name elementMultimix
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'control'
*/
this.elementMultimix = 'control';
/**
* The "element" portion of the class name added to toggle controls.
*
* By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but
* each type's element value can be individually overwritten to match the unique classNames of your controls as needed.
*
* @example <caption>Example 1: changing the `config.classNames.elementToggle` value</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* elementToggle: 'toggle'
* }
* });
*
* // Active toggle output: "mixitup-toggle-active"
*
* @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementToggle` values</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* block: 'portfolio',
* elementToggle: 'toggle'
* }
* });
*
* // Active toggle output: "portfolio-toggle-active"
*
* @name elementToggle
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'control'
*/
this.elementToggle = 'control';
/**
* The "modifier" portion of the class name added to active controls.
* @name modifierActive
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'active'
*/
this.modifierActive = 'active';
/**
* The "modifier" portion of the class name added to disabled controls.
*
* @name modifierDisabled
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'disabled'
*/
this.modifierDisabled = 'disabled';
/**
* The "modifier" portion of the class name added to the container when in a "failed" state.
*
* @name modifierFailed
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default 'failed'
*/
this.modifierFailed = 'failed';
/**
* The delineator used between the "block" and "element" portions of any class name added by MixItUp.
*
* If the block portion is ommited by setting it to an empty string, no delineator will be added.
*
* @example <caption>Example: changing the delineator to match BEM convention</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* delineatorElement: '__'
* }
* });
*
* // example active control output: "mixitup__control-active"
*
* @name delineatorElement
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default '-'
*/
this.delineatorElement = '-';
/**
* The delineator used between the "element" and "modifier" portions of any class name added by MixItUp.
*
* If the element portion is ommited by setting it to an empty string, no delineator will be added.
*
* @example <caption>Example: changing both delineators to match BEM convention</caption>
* var mixer = mixitup(containerEl, {
* classNames: {
* delineatorElement: '__'
* delineatorModifier: '--'
* }
* });
*
* // Active control output: "mixitup__control--active"
*
* @name delineatorModifier
* @memberof mixitup.Config.classNames
* @instance
* @type {string}
* @default '-'
*/
this.delineatorModifier = '-';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigClassNames);
mixitup.ConfigClassNames.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigClassNames.prototype.constructor = mixitup.ConfigClassNames;

View File

@@ -0,0 +1,220 @@
/* global mixitup, h */
/**
* A group of properties relating to clickable control elements.
*
* @constructor
* @memberof mixitup.Config
* @name controls
* @namespace
* @public
* @since 2.0.0
*/
mixitup.ConfigControls = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A boolean dictating whether or not controls should be enabled for the mixer instance.
*
* If `true` (default behavior), MixItUp will search the DOM for any clickable elements with
* `data-filter`, `data-sort` or `data-toggle` attributes, and bind them for click events.
*
* If `false`, no click handlers will be bound, and all functionality must therefore be performed
* via the mixer's API methods.
*
* If you do not intend to use the default controls, setting this property to `false` will
* marginally improve the startup time of your mixer instance, and will also prevent any other active
* mixer instances in the DOM which are bound to controls from controlling the instance.
*
* @example <caption>Example: Disabling controls</caption>
* var mixer = mixitup(containerEl, {
* controls: {
* enable: false
* }
* });
*
* // With the default controls disabled, we can only control
* // the mixer via its API methods, e.g.:
*
* mixer.filter('.cat-1');
*
* @name enable
* @memberof mixitup.Config.controls
* @instance
* @type {boolean}
* @default true
*/
this.enable = true;
/**
* A boolean dictating whether or not to use event delegation when binding click events
* to the default controls.
*
* If `false` (default behavior), each control button in the DOM will be found and
* individually bound when a mixer is instantiated, with their corresponding actions
* cached for performance.
*
* If `true`, a single click handler will be applied to the `window` (or container element - see
* `config.controls.scope`), and any click events triggered by elements with `data-filter`,
* `data-sort` or `data-toggle` attributes present will be handled as they propagate upwards.
*
* If you require a user interface where control buttons may be added, removed, or changed during the
* lifetime of a mixer, `controls.live` should be set to `true`. There is a marginal but unavoidable
* performance deficit when using live controls, as the value of each control button must be read
* from the DOM in real time once the click event has propagated.
*
* @example <caption>Example: Setting live controls</caption>
* var mixer = mixitup(containerEl, {
* controls: {
* live: true
* }
* });
*
* // Control buttons can now be added, remove and changed without breaking
* // the mixer's UI
*
* @name live
* @memberof mixitup.Config.controls
* @instance
* @type {boolean}
* @default true
*/
this.live = false;
/**
* A string dictating the "scope" to use when binding or querying the default controls. The available
* values are `'global'` or `'local'`.
*
* When set to `'global'` (default behavior), MixItUp will query the entire document for control buttons
* to bind, or delegate click events from (see `config.controls.live`).
*
* When set to `'local'`, MixItUp will only query (or bind click events to) its own container element.
* This may be desireable if you require multiple active mixer instances within the same document, with
* controls that would otherwise intefere with each other if scoped globally.
*
* Conversely, if you wish to control multiple instances with a single UI, you would create one
* set of controls and keep the controls scope of each mixer set to `global`.
*
* @example <caption>Example: Setting 'local' scoped controls</caption>
* var mixerOne = mixitup(containerOne, {
* controls: {
* scope: 'local'
* }
* });
*
* var mixerTwo = mixitup(containerTwo, {
* controls: {
* scope: 'local'
* }
* });
*
* // Both mixers can now exist within the same document with
* // isolated controls placed within their container elements.
*
* @name scope
* @memberof mixitup.Config.controls
* @instance
* @type {string}
* @default 'global'
*/
this.scope = 'global'; // enum: ['local' ,'global']
/**
* A string dictating the type of logic to apply when concatenating the filter selectors of
* active toggle buttons (i.e. any clickable element with a `data-toggle` attribute).
*
* If set to `'or'` (default behavior), selectors will be concatenated together as
* a comma-seperated list. For example:
*
* `'.cat-1, .cat-2'` (shows any elements matching `'.cat-1'` OR `'.cat-2'`)
*
* If set to `'and'`, selectors will be directly concatenated together. For example:
*
* `'.cat-1.cat-2'` (shows any elements which match both `'.cat-1'` AND `'.cat-2'`)
*
* @example <caption>Example: Setting "and" toggle logic</caption>
* var mixer = mixitup(containerEl, {
* controls: {
* toggleLogic: 'and'
* }
* });
*
* @name toggleLogic
* @memberof mixitup.Config.controls
* @instance
* @type {string}
* @default 'or'
*/
this.toggleLogic = 'or'; // enum: ['or', 'and']
/**
* A string dictating the filter behavior when all toggles are inactive.
*
* When set to `'all'` (default behavior), *all* targets will be shown by default
* when no toggles are active, or at the moment all active toggles are toggled off.
*
* When set to `'none'`, no targets will be shown by default when no toggles are
* active, or at the moment all active toggles are toggled off.
*
* @example <caption>Example 1: Setting the default toggle behavior to `'all'`</caption>
* var mixer = mixitup(containerEl, {
* controls: {
* toggleDefault: 'all'
* }
* });
*
* mixer.toggleOn('.cat-2')
* .then(function() {
* // Deactivate all active toggles
*
* return mixer.toggleOff('.cat-2')
* })
* .then(function(state) {
* console.log(state.activeFilter.selector); // 'all'
* console.log(state.totalShow); // 12
* });
*
* @example <caption>Example 2: Setting the default toggle behavior to `'none'`</caption>
* var mixer = mixitup(containerEl, {
* controls: {
* toggleDefault: 'none'
* }
* });
*
* mixer.toggleOn('.cat-2')
* .then(function() {
* // Deactivate all active toggles
*
* return mixer.toggleOff('.cat-2')
* })
* .then(function(state) {
* console.log(state.activeFilter.selector); // 'none'
* console.log(state.totalShow); // 0
* });
*
* @name toggleDefault
* @memberof mixitup.Config.controls
* @instance
* @type {string}
* @default 'all'
*/
this.toggleDefault = 'all'; // enum: ['all', 'none']
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigControls);
mixitup.ConfigControls.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigControls.prototype.constructor = mixitup.ConfigControls;

View File

@@ -0,0 +1,118 @@
/* global mixitup, h */
/**
* A group of properties relating to MixItUp's dataset API.
*
* @constructor
* @memberof mixitup.Config
* @name data
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigData = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A string specifying the name of the key containing your data model's unique
* identifier (UID). To use the dataset API, a UID key must be specified and
* be present and unique on all objects in the dataset you provide to MixItUp.
*
* For example, if your dataset is made up of MongoDB documents, the UID
* key would be `'id'` or `'_id'`.
*
* @example <caption>Example: Setting the UID to `'id'`</caption>
* var mixer = mixitup(containerEl, {
* data: {
* uidKey: 'id'
* }
* });
*
* @name uidKey
* @memberof mixitup.Config.data
* @instance
* @type {string}
* @default ''
*/
this.uidKey = '';
/**
* A boolean dictating whether or not MixItUp should "dirty check" each object in
* your dataset for changes whenever `.dataset()` is called, and re-render any targets
* for which a change is found.
*
* Depending on the complexity of your data model, dirty checking can be expensive
* and is therefore disabled by default.
*
* NB: For changes to be detected, a new immutable instance of the edited model must be
* provided to mixitup, rather than manipulating properties on the existing instance.
* If your changes are a result of a DB write and read, you will most likely be calling
* `.dataset()` with a clean set of objects each time, so this will not be an issue.
*
* @example <caption>Example: Enabling dirty checking</caption>
*
* var myDataset = [
* {
* id: 0,
* title: "Blog Post Title 0"
* ...
* },
* {
* id: 1,
* title: "Blog Post Title 1"
* ...
* }
* ];
*
* // Instantiate a mixer with a pre-loaded dataset, and a target renderer
* // function defined
*
* var mixer = mixitup(containerEl, {
* data: {
* uidKey: 'id',
* dirtyCheck: true
* },
* load: {
* dataset: myDataset
* },
* render: {
* target: function() { ... }
* }
* });
*
* // For illustration, we will clone and edit the second object in the dataset.
* // NB: this would typically be done server-side in response to a DB update,
* and then re-queried via an API.
*
* myDataset[1] = Object.assign({}, myDataset[1]);
*
* myDataset[1].title = 'Blog Post Title 11';
*
* mixer.dataset(myDataset)
* .then(function() {
* // the target with ID "1", will be re-rendered reflecting its new title
* });
*
* @name dirtyCheck
* @memberof mixitup.Config.data
* @instance
* @type {boolean}
* @default false
*/
this.dirtyCheck = false;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigData);
mixitup.ConfigData.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigData.prototype.constructor = mixitup.ConfigData;

View File

@@ -0,0 +1,106 @@
/* global mixitup, h */
/**
* A group of properties allowing the toggling of various debug features.
*
* @constructor
* @memberof mixitup.Config
* @name debug
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigDebug = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A boolean dictating whether or not the mixer instance returned by the
* `mixitup()` factory function should expose private properties and methods.
*
* By default, mixer instances only expose their public API, but enabling
* debug mode will give you access to various mixer internals which may aid
* in debugging, or the authoring of extensions.
*
* @example <caption>Example: Enabling debug mode</caption>
*
* var mixer = mixitup(containerEl, {
* debug: {
* enable: true
* }
* });
*
* // Private properties and methods will now be visible on the mixer instance:
*
* console.log(mixer);
*
* @name enable
* @memberof mixitup.Config.debug
* @instance
* @type {boolean}
* @default false
*/
this.enable = false;
/**
* A boolean dictating whether or not warnings should be shown when various
* common gotchas occur.
*
* Warnings are intended to provide insights during development when something
* occurs that is not a fatal, but may indicate an issue with your integration,
* and are therefore turned on by default. However, you may wish to disable
* them in production.
*
* @example <caption>Example 1: Disabling warnings</caption>
*
* var mixer = mixitup(containerEl, {
* debug: {
* showWarnings: false
* }
* });
*
* @example <caption>Example 2: Disabling warnings based on environment</caption>
*
* var showWarnings = myAppConfig.environment === 'development' ? true : false;
*
* var mixer = mixitup(containerEl, {
* debug: {
* showWarnings: showWarnings
* }
* });
*
* @name showWarnings
* @memberof mixitup.Config.debug
* @instance
* @type {boolean}
* @default true
*/
this.showWarnings = true;
/**
* Used for server-side testing only.
*
* @private
* @name fauxAsync
* @memberof mixitup.Config.debug
* @instance
* @type {boolean}
* @default false
*/
this.fauxAsync = false;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigDebug);
mixitup.ConfigDebug.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigDebug.prototype.constructor = mixitup.ConfigDebug;

View File

@@ -0,0 +1,144 @@
/* global mixitup, h */
/**
* A group of properties relating to the layout of the container.
*
* @constructor
* @memberof mixitup.Config
* @name layout
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigLayout = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A boolean dictating whether or not mixitup should query all descendants
* of the container for targets, or only immediate children.
*
* By default, mixitup will query all descendants matching the
* `selectors.target` selector when indexing targets upon instantiation.
* This allows for targets to be nested inside a sub-container which is
* useful when ring-fencing targets from locally scoped controls in your
* markup (see `controls.scope`).
*
* However, if you are building a more complex UI requiring the nesting
* of mixers within mixers, you will most likely want to limit targets to
* immediate children of the container by setting this property to `false`.
*
* @example <caption>Example: Restricting targets to immediate children</caption>
*
* var mixer = mixitup(containerEl, {
* layout: {
* allowNestedTargets: false
* }
* });
*
* @name allowNestedTargets
* @memberof mixitup.Config.layout
* @instance
* @type {boolean}
* @default true
*/
this.allowNestedTargets = true;
/**
* A string specifying an optional class name to apply to the container when in
* its default state.
*
* By changing this class name or adding a class name to the container via the
* `.changeLayout()` API method, the CSS layout of the container can be changed,
* and MixItUp will attemp to gracefully animate the container and its targets
* between states.
*
* @example <caption>Example 1: Specifying a container class name</caption>
*
* var mixer = mixitup(containerEl, {
* layout: {
* containerClassName: 'grid'
* }
* });
*
* @example <caption>Example 2: Changing the default class name with `.changeLayout()`</caption>
*
* var mixer = mixitup(containerEl, {
* layout: {
* containerClassName: 'grid'
* }
* });
*
* mixer.changeLayout('list')
* .then(function(state) {
* console.log(state.activeContainerClass); // "list"
* });
*
* @name containerClassName
* @memberof mixitup.Config.layout
* @instance
* @type {string}
* @default ''
*/
this.containerClassName = '';
/**
* A reference to a non-target sibling element after which to insert targets
* when there are no targets in the container.
*
* @example <caption>Example: Setting a `siblingBefore` reference element</caption>
*
* var addButton = containerEl.querySelector('button');
*
* var mixer = mixitup(containerEl, {
* layout: {
* siblingBefore: addButton
* }
* });
*
* @name siblingBefore
* @memberof mixitup.Config.layout
* @instance
* @type {HTMLElement}
* @default null
*/
this.siblingBefore = null;
/**
* A reference to a non-target sibling element before which to insert targets
* when there are no targets in the container.
*
* @example <caption>Example: Setting an `siblingAfter` reference element</caption>
*
* var gap = containerEl.querySelector('.gap');
*
* var mixer = mixitup(containerEl, {
* layout: {
* siblingAfter: gap
* }
* });
*
* @name siblingAfter
* @memberof mixitup.Config.layout
* @instance
* @type {HTMLElement}
* @default null
*/
this.siblingAfter = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigLayout);
mixitup.ConfigLayout.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigLayout.prototype.constructor = mixitup.ConfigLayout;

View File

@@ -0,0 +1,127 @@
/* global mixitup, h */
/**
* A group of properties defining the initial state of the mixer on load (instantiation).
*
* @constructor
* @memberof mixitup.Config
* @name load
* @namespace
* @public
* @since 2.0.0
*/
mixitup.ConfigLoad = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A string defining any filtering to be statically applied to the mixer on load.
* As per the `.filter()` API, this can be any valid selector string, or the
* values `'all'` or `'none'`.
*
* @example <caption>Example 1: Defining an initial filter selector to be applied on load</caption>
*
* // The mixer will show only those targets matching '.category-a' on load.
*
* var mixer = mixitup(containerEl, {
* load: {
* filter: '.category-a'
* }
* });
*
* @example <caption>Example 2: Hiding all targets on load</caption>
*
* // The mixer will show hide all targets on load.
*
* var mixer = mixitup(containerEl, {
* load: {
* filter: 'none'
* }
* });
*
* @name filter
* @memberof mixitup.Config.load
* @instance
* @type {string}
* @default 'all'
*/
this.filter = 'all';
/**
* A string defining any sorting to be statically applied to the mixer on load.
* As per the `.sort()` API, this should be a valid "sort string" made up of
* an attribute to sort by (or `'default'`) followed by an optional sorting
* order, or the value `'random'`;
*
* @example <caption>Example: Defining sorting to be applied on load</caption>
*
* // The mixer will sort the container by the value of the `data-published-date`
* // attribute, in descending order.
*
* var mixer = mixitup(containerEl, {
* load: {
* sort: 'published-date:desc'
* }
* });
*
* @name sort
* @memberof mixitup.Config.load
* @instance
* @type {string}
* @default 'default:asc'
*/
this.sort = 'default:asc';
/**
* An array of objects representing the underlying data of any pre-rendered targets,
* when using the `.dataset()` API.
*
* NB: If targets are pre-rendered when the mixer is instantiated, this must be set.
*
* @example <caption>Example: Defining the initial underyling dataset</caption>
*
* var myDataset = [
* {
* id: 0,
* title: "Blog Post Title 0",
* ...
* },
* {
* id: 1,
* title: "Blog Post Title 1",
* ...
* }
* ];
*
* var mixer = mixitup(containerEl, {
* data: {
* uidKey: 'id'
* },
* load: {
* dataset: myDataset
* }
* });
*
* @name dataset
* @memberof mixitup.Config.load
* @instance
* @type {Array.<object>}
* @default null
*/
this.dataset = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigLoad);
mixitup.ConfigLoad.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigLoad.prototype.constructor = mixitup.ConfigLoad;

View File

@@ -0,0 +1,100 @@
/* global mixitup, h */
/**
* A group of optional render functions for creating and updating elements.
*
* All render functions receive a data object, and should return a valid HTML string.
*
* @constructor
* @memberof mixitup.Config
* @name render
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigRender = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A function returning an HTML string representing a target element, or a reference to a
* single DOM element.
*
* The function is invoked as part of the `.dataset()` API, whenever a new item is added
* to the dataset, or an item in the dataset changes (if `dataset.dirtyCheck` is enabled).
*
* The function receives the relevant dataset item as its first parameter.
*
* @example <caption>Example 1: Using string concatenation</caption>
*
* var mixer = mixitup(containerEl, {
* render: {
* target: function(item) {
* return (
* '&lt;div class="mix"&gt;' +
* '&lt;h2&gt;' + item.title + '&lt;/h2&gt;' +
* '&lt;/div&gt;'
* );
* }
* }
* });
*
* @example <caption>Example 2: Using an ES2015 template literal</caption>
*
* var mixer = mixitup(containerEl, {
* render: {
* target: function(item) {
* return (
* `&lt;div class="mix"&gt;
* &lt;h2&gt;${item.title}&lt;/h2&gt;
* &lt;/div&gt;`
* );
* }
* }
* });
*
* @example <caption>Example 3: Using a Handlebars template</caption>
* {{{{raw}}}}
* var targetTemplate = Handlebars.compile('&lt;div class="mix"&gt;&lt;h2&gt;{{title}}&lt;/h2&gt;&lt;/div&gt;');
* {{{{/raw}}}}
* var mixer = mixitup(containerEl, {
* render: {
* target: targetTemplate
* }
* });
*
* @example <caption>Example 4: Returning a DOM element</caption>
*
* var mixer = mixitup(containerEl, {
* render: {
* target: function(item) {
* // Create a single element using your framework's built-in renderer
*
* var el = ...
*
* return el;
* }
* }
* });
*
* @name target
* @memberof mixitup.Config.render
* @instance
* @type {function}
* @default 'null'
*/
this.target = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigRender);
mixitup.ConfigRender.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigRender.prototype.constructor = mixitup.ConfigRender;

View File

@@ -0,0 +1,93 @@
/* global mixitup, h */
/**
* A group of properties defining the selectors used to query elements within a mixitup container.
*
* @constructor
* @memberof mixitup.Config
* @name selectors
* @namespace
* @public
* @since 3.0.0
*/
mixitup.ConfigSelectors = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A selector string used to query and index target elements within the container.
*
* By default, the class selector `'.mix'` is used, but this can be changed to an
* attribute or element selector to match the style of your project.
*
* @example <caption>Example 1: Changing the target selector</caption>
*
* var mixer = mixitup(containerEl, {
* selectors: {
* target: '.portfolio-item'
* }
* });
*
* @example <caption>Example 2: Using an attribute selector as a target selector</caption>
*
* // The mixer will search for any children with the attribute `data-ref="mix"`
*
* var mixer = mixitup(containerEl, {
* selectors: {
* target: '[data-ref="mix"]'
* }
* });
*
* @name target
* @memberof mixitup.Config.selectors
* @instance
* @type {string}
* @default '.mix'
*/
this.target = '.mix';
/**
* A optional selector string used to add further specificity to the querying of control elements,
* in addition to their mandatory data attribute (e.g. `data-filter`, `data-toggle`, `data-sort`).
*
* This can be used if other elements in your document must contain the above attributes
* (e.g. for use in third-party scripts), and would otherwise interfere with MixItUp. Adding
* an additional `control` selector of your choice allows MixItUp to restrict event handling
* to only those elements matching the defined selector.
*
* @name control
* @memberof mixitup.Config.selectors
* @instance
* @type {string}
* @default ''
*
* @example <caption>Example 1: Adding a `selectors.control` selector</caption>
*
* var mixer = mixitup(containerEl, {
* selectors: {
* control: '.mixitup-control'
* }
* });
*
* // Will not be handled:
* // <button data-filter=".category-a"></button>
*
* // Will be handled:
* // <button class="mixitup-control" data-filter=".category-a"></button>
*/
this.control = '';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigSelectors);
mixitup.ConfigSelectors.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigSelectors.prototype.constructor = mixitup.ConfigSelectors;

View File

@@ -0,0 +1,24 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.ConfigTemplates = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ConfigTemplates);
mixitup.ConfigTemplates.prototype = Object.create(mixitup.Base.prototype);
mixitup.ConfigTemplates.prototype.constructor = mixitup.ConfigTemplates;

View File

@@ -0,0 +1,77 @@
/* global mixitup, h */
/**
* `mixitup.Config` is an interface used for customising the functionality of a
* mixer instance. It is organised into several semantically distinct sub-objects,
* each one pertaining to a particular aspect of MixItUp functionality.
*
* An object literal containing any or all of the available properies,
* known as the "configuration object", can be passed as the second parameter to
* the `mixitup` factory function when creating a mixer instance to customise its
* functionality as needed.
*
* If no configuration object is passed, the mixer instance will take on the default
* configuration values detailed below.
*
* @example <caption>Example 1: Creating and passing the configuration object</caption>
* // Create a configuration object with desired values
*
* var config = {
* animation: {
* enable: false
* },
* selectors: {
* target: '.item'
* }
* };
*
* // Pass the configuration object to the mixitup factory function
*
* var mixer = mixitup(containerEl, config);
*
* @example <caption>Example 2: Passing the configuration object inline</caption>
* // Typically, the configuration object is passed inline for brevity.
*
* var mixer = mixitup(containerEl, {
* controls: {
* live: true,
* toggleLogic: 'and'
* }
* });
*
*
* @constructor
* @memberof mixitup
* @namespace
* @public
* @since 2.0.0
*/
mixitup.Config = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.animation = new mixitup.ConfigAnimation();
this.behavior = new mixitup.ConfigBehavior();
this.callbacks = new mixitup.ConfigCallbacks();
this.controls = new mixitup.ConfigControls();
this.classNames = new mixitup.ConfigClassNames();
this.data = new mixitup.ConfigData();
this.debug = new mixitup.ConfigDebug();
this.layout = new mixitup.ConfigLayout();
this.load = new mixitup.ConfigLoad();
this.selectors = new mixitup.ConfigSelectors();
this.render = new mixitup.ConfigRender();
this.templates = new mixitup.ConfigTemplates();
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Config);
mixitup.Config.prototype = Object.create(mixitup.Base.prototype);
mixitup.Config.prototype.constructor = mixitup.Config;

View File

@@ -0,0 +1,42 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
* @param {string} type
* @param {string} selector
* @param {boolean} [live]
* @param {string} [parent]
* An optional string representing the name of the mixer.dom property containing a reference to a parent element.
*/
mixitup.ControlDefinition = function(type, selector, live, parent) {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.type = type;
this.selector = selector;
this.live = live || false;
this.parent = parent || '';
this.callActions('afterConstruct');
h.freeze(this);
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.ControlDefinition);
mixitup.ControlDefinition.prototype = Object.create(mixitup.Base.prototype);
mixitup.ControlDefinition.prototype.constructor = mixitup.ControlDefinition;
mixitup.controlDefinitions = [];
mixitup.controlDefinitions.push(new mixitup.ControlDefinition('multimix', '[data-filter][data-sort]'));
mixitup.controlDefinitions.push(new mixitup.ControlDefinition('filter', '[data-filter]'));
mixitup.controlDefinitions.push(new mixitup.ControlDefinition('sort', '[data-sort]'));
mixitup.controlDefinitions.push(new mixitup.ControlDefinition('toggle', '[data-toggle]'));

View File

@@ -0,0 +1,514 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Control = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.el = null;
this.selector = '';
this.bound = [];
this.pending = -1;
this.type = '';
this.status = 'inactive'; // enum: ['inactive', 'active', 'disabled', 'live']
this.filter = '';
this.sort = '';
this.canDisable = false;
this.handler = null;
this.classNames = new mixitup.UiClassNames();
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Control);
mixitup.Control.prototype = Object.create(mixitup.Base.prototype);
h.extend(mixitup.Control.prototype,
/** @lends mixitup.Control */
{
constructor: mixitup.Control,
/**
* @private
* @param {HTMLElement} el
* @param {string} type
* @param {string} selector
*/
init: function(el, type, selector) {
var self = this;
this.callActions('beforeInit', arguments);
self.el = el;
self.type = type;
self.selector = selector;
if (self.selector) {
self.status = 'live';
} else {
self.canDisable = typeof self.el.disable === 'boolean';
switch (self.type) {
case 'filter':
self.filter = self.el.getAttribute('data-filter');
break;
case 'toggle':
self.filter = self.el.getAttribute('data-toggle');
break;
case 'sort':
self.sort = self.el.getAttribute('data-sort');
break;
case 'multimix':
self.filter = self.el.getAttribute('data-filter');
self.sort = self.el.getAttribute('data-sort');
break;
}
}
self.bindClick();
mixitup.controls.push(self);
this.callActions('afterInit', arguments);
},
/**
* @private
* @param {mixitup.Mixer} mixer
* @return {boolean}
*/
isBound: function(mixer) {
var self = this,
isBound = false;
this.callActions('beforeIsBound', arguments);
isBound = self.bound.indexOf(mixer) > -1;
return self.callFilters('afterIsBound', isBound, arguments);
},
/**
* @private
* @param {mixitup.Mixer} mixer
* @return {void}
*/
addBinding: function(mixer) {
var self = this;
this.callActions('beforeAddBinding', arguments);
if (!self.isBound()) {
self.bound.push(mixer);
}
this.callActions('afterAddBinding', arguments);
},
/**
* @private
* @param {mixitup.Mixer} mixer
* @return {void}
*/
removeBinding: function(mixer) {
var self = this,
removeIndex = -1;
this.callActions('beforeRemoveBinding', arguments);
if ((removeIndex = self.bound.indexOf(mixer)) > -1) {
self.bound.splice(removeIndex, 1);
}
if (self.bound.length < 1) {
// No bindings exist, unbind event click handlers
self.unbindClick();
// Remove from `mixitup.controls` list
removeIndex = mixitup.controls.indexOf(self);
mixitup.controls.splice(removeIndex, 1);
if (self.status === 'active') {
self.renderStatus(self.el, 'inactive');
}
}
this.callActions('afterRemoveBinding', arguments);
},
/**
* @private
* @return {void}
*/
bindClick: function() {
var self = this;
this.callActions('beforeBindClick', arguments);
self.handler = function(e) {
self.handleClick(e);
};
h.on(self.el, 'click', self.handler);
this.callActions('afterBindClick', arguments);
},
/**
* @private
* @return {void}
*/
unbindClick: function() {
var self = this;
this.callActions('beforeUnbindClick', arguments);
h.off(self.el, 'click', self.handler);
self.handler = null;
this.callActions('afterUnbindClick', arguments);
},
/**
* @private
* @param {MouseEvent} e
* @return {void}
*/
handleClick: function(e) {
var self = this,
button = null,
mixer = null,
isActive = false,
returnValue = void(0),
command = {},
clone = null,
commands = [],
i = -1;
this.callActions('beforeHandleClick', arguments);
this.pending = 0;
mixer = self.bound[0];
if (!self.selector) {
button = self.el;
} else {
button = h.closestParent(e.target, mixer.config.selectors.control + self.selector, true, mixer.dom.document);
}
if (!button) {
self.callActions('afterHandleClick', arguments);
return;
}
switch (self.type) {
case 'filter':
command.filter = self.filter || button.getAttribute('data-filter');
break;
case 'sort':
command.sort = self.sort || button.getAttribute('data-sort');
break;
case 'multimix':
command.filter = self.filter || button.getAttribute('data-filter');
command.sort = self.sort || button.getAttribute('data-sort');
break;
case 'toggle':
command.filter = self.filter || button.getAttribute('data-toggle');
if (self.status === 'live') {
isActive = h.hasClass(button, self.classNames.active);
} else {
isActive = self.status === 'active';
}
break;
}
for (i = 0; i < self.bound.length; i++) {
// Create a clone of the command for each bound mixer instance
clone = new mixitup.CommandMultimix();
h.extend(clone, command);
commands.push(clone);
}
commands = self.callFilters('commandsHandleClick', commands, arguments);
self.pending = self.bound.length;
for (i = 0; mixer = self.bound[i]; i++) {
command = commands[i];
if (!command) {
// An extension may set a command null to indicate that the click should not be handled
continue;
}
if (!mixer.lastClicked) {
mixer.lastClicked = button;
}
mixitup.events.fire('mixClick', mixer.dom.container, {
state: mixer.state,
instance: mixer,
originalEvent: e,
control: mixer.lastClicked
}, mixer.dom.document);
if (typeof mixer.config.callbacks.onMixClick === 'function') {
returnValue = mixer.config.callbacks.onMixClick.call(mixer.lastClicked, mixer.state, e, mixer);
if (returnValue === false) {
// User has returned `false` from the callback, so do not handle click
continue;
}
}
if (self.type === 'toggle') {
isActive ? mixer.toggleOff(command.filter) : mixer.toggleOn(command.filter);
} else {
mixer.multimix(command);
}
}
this.callActions('afterHandleClick', arguments);
},
/**
* @param {object} command
* @param {Array<string>} toggleArray
* @return {void}
*/
update: function(command, toggleArray) {
var self = this,
actions = new mixitup.CommandMultimix();
self.callActions('beforeUpdate', arguments);
self.pending--;
self.pending = Math.max(0, self.pending);
if (self.pending > 0) return;
if (self.status === 'live') {
// Live control (status unknown)
self.updateLive(command, toggleArray);
} else {
// Static control
actions.sort = self.sort;
actions.filter = self.filter;
self.callFilters('actionsUpdate', actions, arguments);
self.parseStatusChange(self.el, command, actions, toggleArray);
}
self.callActions('afterUpdate', arguments);
},
/**
* @param {mixitup.CommandMultimix} command
* @param {Array<string>} toggleArray
* @return {void}
*/
updateLive: function(command, toggleArray) {
var self = this,
controlButtons = null,
actions = null,
button = null,
i = -1;
self.callActions('beforeUpdateLive', arguments);
if (!self.el) return;
controlButtons = self.el.querySelectorAll(self.selector);
for (i = 0; button = controlButtons[i]; i++) {
actions = new mixitup.CommandMultimix();
switch (self.type) {
case 'filter':
actions.filter = button.getAttribute('data-filter');
break;
case 'sort':
actions.sort = button.getAttribute('data-sort');
break;
case 'multimix':
actions.filter = button.getAttribute('data-filter');
actions.sort = button.getAttribute('data-sort');
break;
case 'toggle':
actions.filter = button.getAttribute('data-toggle');
break;
}
actions = self.callFilters('actionsUpdateLive', actions, arguments);
self.parseStatusChange(button, command, actions, toggleArray);
}
self.callActions('afterUpdateLive', arguments);
},
/**
* @param {HTMLElement} button
* @param {mixitup.CommandMultimix} command
* @param {mixitup.CommandMultimix} actions
* @param {Array<string>} toggleArray
* @return {void}
*/
parseStatusChange: function(button, command, actions, toggleArray) {
var self = this,
alias = '',
toggle = '',
i = -1;
self.callActions('beforeParseStatusChange', arguments);
switch (self.type) {
case 'filter':
if (command.filter === actions.filter) {
self.renderStatus(button, 'active');
} else {
self.renderStatus(button, 'inactive');
}
break;
case 'multimix':
if (command.sort === actions.sort && command.filter === actions.filter) {
self.renderStatus(button, 'active');
} else {
self.renderStatus(button, 'inactive');
}
break;
case 'sort':
if (command.sort.match(/:asc/g)) {
alias = command.sort.replace(/:asc/g, '');
}
if (command.sort === actions.sort || alias === actions.sort) {
self.renderStatus(button, 'active');
} else {
self.renderStatus(button, 'inactive');
}
break;
case 'toggle':
if (toggleArray.length < 1) self.renderStatus(button, 'inactive');
if (command.filter === actions.filter) {
self.renderStatus(button, 'active');
}
for (i = 0; i < toggleArray.length; i++) {
toggle = toggleArray[i];
if (toggle === actions.filter) {
// Button matches one active toggle
self.renderStatus(button, 'active');
break;
}
self.renderStatus(button, 'inactive');
}
break;
}
self.callActions('afterParseStatusChange', arguments);
},
/**
* @param {HTMLElement} button
* @param {string} status
* @return {void}
*/
renderStatus: function(button, status) {
var self = this;
self.callActions('beforeRenderStatus', arguments);
switch (status) {
case 'active':
h.addClass(button, self.classNames.active);
h.removeClass(button, self.classNames.disabled);
if (self.canDisable) self.el.disabled = false;
break;
case 'inactive':
h.removeClass(button, self.classNames.active);
h.removeClass(button, self.classNames.disabled);
if (self.canDisable) self.el.disabled = false;
break;
case 'disabled':
if (self.canDisable) self.el.disabled = true;
h.addClass(button, self.classNames.disabled);
h.removeClass(button, self.classNames.active);
break;
}
if (self.status !== 'live') {
// Update the control's status propery if not live
self.status = status;
}
self.callActions('afterRenderStatus', arguments);
}
});
mixitup.controls = [];

166
mixitup-3.3.1/src/events.js Normal file
View File

@@ -0,0 +1,166 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.EventDetail = function() {
this.state = null;
this.futureState = null;
this.instance = null;
this.originalEvent = null;
};
/**
* The `mixitup.Events` class contains all custom events dispatched by MixItUp at various
* points within the lifecycle of a mixer operation.
*
* Each event is analogous to the callback function of the same name defined in
* the `callbacks` configuration object, and is triggered immediately before it.
*
* Events are always triggered from the container element on which MixItUp is instantiated
* upon.
*
* As with any event, registered event handlers receive the event object as a parameter
* which includes a `detail` property containting references to the current `state`,
* the `mixer` instance, and other event-specific properties described below.
*
* @constructor
* @namespace
* @memberof mixitup
* @public
* @since 3.0.0
*/
mixitup.Events = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* A custom event triggered immediately after any MixItUp operation is requested
* and before animations have begun.
*
* The `mixStart` event also exposes a `futureState` property via the
* `event.detail` object, which represents the final state of the mixer once
* the requested operation has completed.
*
* @name mixStart
* @memberof mixitup.Events
* @static
* @type {CustomEvent}
*/
this.mixStart = null;
/**
* A custom event triggered when a MixItUp operation is requested while another
* operation is in progress, and the animation queue is full, or queueing
* is disabled.
*
* @name mixBusy
* @memberof mixitup.Events
* @static
* @type {CustomEvent}
*/
this.mixBusy = null;
/**
* A custom event triggered after any MixItUp operation has completed, and the
* state has been updated.
*
* @name mixEnd
* @memberof mixitup.Events
* @static
* @type {CustomEvent}
*/
this.mixEnd = null;
/**
* A custom event triggered whenever a filter operation "fails", i.e. no targets
* could be found matching the requested filter.
*
* @name mixFail
* @memberof mixitup.Events
* @static
* @type {CustomEvent}
*/
this.mixFail = null;
/**
* A custom event triggered whenever a MixItUp control is clicked, and before its
* respective operation is requested.
*
* This event also exposes an `originalEvent` property via the `event.detail`
* object, which holds a reference to the original click event.
*
* @name mixClick
* @memberof mixitup.Events
* @static
* @type {CustomEvent}
*/
this.mixClick = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Events);
mixitup.Events.prototype = Object.create(mixitup.Base.prototype);
mixitup.Events.prototype.constructor = mixitup.Events;
/**
* @private
* @param {string} eventType
* @param {Element} el
* @param {object} detail
* @param {Document} [doc]
*/
mixitup.Events.prototype.fire = function(eventType, el, detail, doc) {
var self = this,
event = null,
eventDetail = new mixitup.EventDetail();
self.callActions('beforeFire', arguments);
if (typeof self[eventType] === 'undefined') {
throw new Error('Event type "' + eventType + '" not found.');
}
eventDetail.state = new mixitup.State();
h.extend(eventDetail.state, detail.state);
if (detail.futureState) {
eventDetail.futureState = new mixitup.State();
h.extend(eventDetail.futureState, detail.futureState);
}
eventDetail.instance = detail.instance;
if (detail.originalEvent) {
eventDetail.originalEvent = detail.originalEvent;
}
event = h.getCustomEvent(eventType, eventDetail, doc);
self.callFilters('eventFire', event, arguments);
el.dispatchEvent(event);
};
// Asign a singleton instance to `mixitup.events`:
mixitup.events = new mixitup.Events();

View File

@@ -0,0 +1,51 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
* @param {mixitup.Mixer} mixer
*/
mixitup.Facade = function Mixer(mixer) {
mixitup.Base.call(this);
this.callActions('beforeConstruct', arguments);
this.configure = mixer.configure.bind(mixer);
this.show = mixer.show.bind(mixer);
this.hide = mixer.hide.bind(mixer);
this.filter = mixer.filter.bind(mixer);
this.toggleOn = mixer.toggleOn.bind(mixer);
this.toggleOff = mixer.toggleOff.bind(mixer);
this.sort = mixer.sort.bind(mixer);
this.changeLayout = mixer.changeLayout.bind(mixer);
this.multimix = mixer.multimix.bind(mixer);
this.dataset = mixer.dataset.bind(mixer);
this.tween = mixer.tween.bind(mixer);
this.insert = mixer.insert.bind(mixer);
this.insertBefore = mixer.insertBefore.bind(mixer);
this.insertAfter = mixer.insertAfter.bind(mixer);
this.prepend = mixer.prepend.bind(mixer);
this.append = mixer.append.bind(mixer);
this.remove = mixer.remove.bind(mixer);
this.destroy = mixer.destroy.bind(mixer);
this.forceRefresh = mixer.forceRefresh.bind(mixer);
this.forceRender = mixer.forceRender.bind(mixer);
this.isMixing = mixer.isMixing.bind(mixer);
this.getOperation = mixer.getOperation.bind(mixer);
this.getConfig = mixer.getConfig.bind(mixer);
this.getState = mixer.getState.bind(mixer);
this.callActions('afterConstruct', arguments);
h.freeze(this);
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Facade);
mixitup.Facade.prototype = Object.create(mixitup.Base.prototype);
mixitup.Facade.prototype.constructor = mixitup.Facade;

View File

@@ -0,0 +1,187 @@
/* global mixitup:true, h */
/**
* The `mixitup()` "factory" function creates and returns individual instances
* of MixItUp, known as "mixers", on which API methods can be called.
*
* When loading MixItUp via a script tag, the factory function is accessed
* via the global variable `mixitup`. When using a module loading
* system (e.g. ES2015, CommonJS, RequireJS), the factory function is
* exported into your module when you require the MixItUp library.
*
* @example
* mixitup(container [,config] [,foreignDoc])
*
* @example <caption>Example 1: Creating a mixer instance with an element reference</caption>
* var containerEl = document.querySelector('.container');
*
* var mixer = mixitup(containerEl);
*
* @example <caption>Example 2: Creating a mixer instance with a selector string</caption>
* var mixer = mixitup('.container');
*
* @example <caption>Example 3: Passing a configuration object</caption>
* var mixer = mixitup(containerEl, {
* animation: {
* effects: 'fade scale(0.5)'
* }
* });
*
* @example <caption>Example 4: Passing an iframe reference</caption>
* var mixer = mixitup(containerEl, config, foreignDocument);
*
* @global
* @namespace
* @public
* @kind function
* @since 3.0.0
* @param {(Element|string)} container
* A DOM element or selector string representing the container(s) on which to instantiate MixItUp.
* @param {object} [config]
* An optional "configuration object" used to customize the behavior of the MixItUp instance.
* @param {object} [foreignDoc]
* An optional reference to a `document`, which can be used to control a MixItUp instance in an iframe.
* @return {mixitup.Mixer}
* A "mixer" object holding the MixItUp instance.
*/
mixitup = function(container, config, foreignDoc) {
var el = null,
returnCollection = false,
instance = null,
facade = null,
doc = null,
output = null,
instances = [],
id = '',
elements = [],
i = -1;
doc = foreignDoc || window.document;
if (returnCollection = arguments[3]) {
// A non-documented 4th paramater enabling control of multiple instances
returnCollection = typeof returnCollection === 'boolean';
}
if (typeof container === 'string') {
elements = doc.querySelectorAll(container);
} else if (container && typeof container === 'object' && h.isElement(container, doc)) {
elements = [container];
} else if (container && typeof container === 'object' && container.length) {
// Although not documented, the container may also be an array-like list of
// elements such as a NodeList or jQuery collection, is returnCollection is true
elements = container;
} else {
throw new Error(mixitup.messages.errorFactoryInvalidContainer());
}
if (elements.length < 1) {
throw new Error(mixitup.messages.errorFactoryContainerNotFound());
}
for (i = 0; el = elements[i]; i++) {
if (i > 0 && !returnCollection) break;
if (!el.id) {
id = 'MixItUp' + h.randomHex();
el.id = id;
} else {
id = el.id;
}
if (mixitup.instances[id] instanceof mixitup.Mixer) {
instance = mixitup.instances[id];
if (!config || (config && config.debug && config.debug.showWarnings !== false)) {
console.warn(mixitup.messages.warningFactoryPreexistingInstance());
}
} else {
instance = new mixitup.Mixer();
instance.attach(el, doc, id, config);
mixitup.instances[id] = instance;
}
facade = new mixitup.Facade(instance);
if (config && config.debug && config.debug.enable) {
instances.push(instance);
} else {
instances.push(facade);
}
}
if (returnCollection) {
output = new mixitup.Collection(instances);
} else {
// Return the first instance regardless
output = instances[0];
}
return output;
};
/**
* The `.use()` static method is used to extend the functionality of mixitup with compatible
* extensions and libraries in an environment with modular scoping e.g. ES2015, CommonJS, or RequireJS.
*
* You need only call the `.use()` function once per project, per extension, as module loaders
* will cache a single reference to MixItUp inclusive of all changes made.
*
* @example
* mixitup.use(extension)
*
* @example <caption>Example 1: Extending MixItUp with the Pagination Extension</caption>
*
* import mixitup from 'mixitup';
* import mixitupPagination from 'mixitup-pagination';
*
* mixitup.use(mixitupPagination);
*
* // All mixers created by the factory function in all modules will now
* // have pagination functionality
*
* var mixer = mixitup('.container');
*
* @public
* @name use
* @memberof mixitup
* @kind function
* @static
* @since 3.0.0
* @param {*} extension A reference to the extension or library to be used.
* @return {void}
*/
mixitup.use = function(extension) {
mixitup.Base.prototype.callActions.call(mixitup, 'beforeUse', arguments);
// Call the extension's factory function, passing
// the mixitup factory as a paramater
if (typeof extension === 'function' && extension.TYPE === 'mixitup-extension') {
// Mixitup extension
if (typeof mixitup.extensions[extension.NAME] === 'undefined') {
extension(mixitup);
mixitup.extensions[extension.NAME] = extension;
}
} else if (extension.fn && extension.fn.jquery) {
// jQuery
mixitup.libraries.$ = extension;
}
mixitup.Base.prototype.callActions.call(mixitup, 'afterUse', arguments);
};
mixitup.instances = {};
mixitup.extensions = {};
mixitup.libraries = {};

View File

@@ -0,0 +1,156 @@
/* global mixitup, h */
/**
* The `mixitup.Features` class performs all feature and CSS prefix detection
* neccessary for MixItUp to function correctly, as well as storing various
* string and array constants. All feature decection is on evaluation of the
* library and stored in a singleton instance for use by other internal classes.
*
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Features = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.boxSizingPrefix = '';
this.transformPrefix = '';
this.transitionPrefix = '';
this.boxSizingPrefix = '';
this.transformProp = '';
this.transformRule = '';
this.transitionProp = '';
this.perspectiveProp = '';
this.perspectiveOriginProp = '';
this.has = new mixitup.Has();
this.canary = null;
this.BOX_SIZING_PROP = 'boxSizing';
this.TRANSITION_PROP = 'transition';
this.TRANSFORM_PROP = 'transform';
this.PERSPECTIVE_PROP = 'perspective';
this.PERSPECTIVE_ORIGIN_PROP = 'perspectiveOrigin';
this.VENDORS = ['Webkit', 'moz', 'O', 'ms'];
this.TWEENABLE = [
'opacity',
'width', 'height',
'marginRight', 'marginBottom',
'x', 'y',
'scale',
'translateX', 'translateY', 'translateZ',
'rotateX', 'rotateY', 'rotateZ'
];
this.callActions('afterConstruct');
};
mixitup.BaseStatic.call(mixitup.Features);
mixitup.Features.prototype = Object.create(mixitup.Base.prototype);
h.extend(mixitup.Features.prototype,
/** @lends mixitup.Features */
{
constructor: mixitup.Features,
/**
* @private
* @return {void}
*/
init: function() {
var self = this;
self.callActions('beforeInit', arguments);
self.canary = document.createElement('div');
self.setPrefixes();
self.runTests();
self.callActions('beforeInit', arguments);
},
/**
* @private
* @return {void}
*/
runTests: function() {
var self = this;
self.callActions('beforeRunTests', arguments);
self.has.promises = typeof window.Promise === 'function';
self.has.transitions = self.transitionPrefix !== 'unsupported';
self.callActions('afterRunTests', arguments);
h.freeze(self.has);
},
/**
* @private
* @return {void}
*/
setPrefixes: function() {
var self = this;
self.callActions('beforeSetPrefixes', arguments);
self.transitionPrefix = h.getPrefix(self.canary, 'Transition', self.VENDORS);
self.transformPrefix = h.getPrefix(self.canary, 'Transform', self.VENDORS);
self.boxSizingPrefix = h.getPrefix(self.canary, 'BoxSizing', self.VENDORS);
self.boxSizingProp = self.boxSizingPrefix ?
self.boxSizingPrefix + h.pascalCase(self.BOX_SIZING_PROP) : self.BOX_SIZING_PROP;
self.transitionProp = self.transitionPrefix ?
self.transitionPrefix + h.pascalCase(self.TRANSITION_PROP) : self.TRANSITION_PROP;
self.transformProp = self.transformPrefix ?
self.transformPrefix + h.pascalCase(self.TRANSFORM_PROP) : self.TRANSFORM_PROP;
self.transformRule = self.transformPrefix ?
'-' + self.transformPrefix + '-' + self.TRANSFORM_PROP : self.TRANSFORM_PROP;
self.perspectiveProp = self.transformPrefix ?
self.transformPrefix + h.pascalCase(self.PERSPECTIVE_PROP) : self.PERSPECTIVE_PROP;
self.perspectiveOriginProp = self.transformPrefix ?
self.transformPrefix + h.pascalCase(self.PERSPECTIVE_ORIGIN_PROP) :
self.PERSPECTIVE_ORIGIN_PROP;
self.callActions('afterSetPrefixes', arguments);
}
});
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Has = function() {
this.transitions = false;
this.promises = false;
h.seal(this);
};
// Assign a singleton instance to `mixitup.features` and initialise:
mixitup.features = new mixitup.Features();
mixitup.features.init();

1013
mixitup-3.3.1/src/h.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.IMoveData = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.posIn = null;
this.posOut = null;
this.operation = null;
this.callback = null;
this.statusChange = '';
this.duration = -1;
this.staggerIndex = -1;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.IMoveData);
mixitup.IMoveData.prototype = Object.create(mixitup.Base.prototype);
mixitup.IMoveData.prototype.constructor = mixitup.IMoveData;

View File

@@ -0,0 +1,122 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Messages = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/* Errors
----------------------------------------------------------------------------- */
this.ERROR_FACTORY_INVALID_CONTAINER =
'[MixItUp] An invalid selector or element reference was passed to the mixitup factory function';
this.ERROR_FACTORY_CONTAINER_NOT_FOUND =
'[MixItUp] The provided selector yielded no container element';
this.ERROR_CONFIG_INVALID_ANIMATION_EFFECTS =
'[MixItUp] Invalid value for `animation.effects`';
this.ERROR_CONFIG_INVALID_CONTROLS_SCOPE =
'[MixItUp] Invalid value for `controls.scope`';
this.ERROR_CONFIG_INVALID_PROPERTY =
'[MixitUp] Invalid configuration object property "${erroneous}"${suggestion}';
this.ERROR_CONFIG_INVALID_PROPERTY_SUGGESTION =
'. Did you mean "${probableMatch}"?';
this.ERROR_CONFIG_DATA_UID_KEY_NOT_SET =
'[MixItUp] To use the dataset API, a UID key must be specified using `data.uidKey`';
this.ERROR_DATASET_INVALID_UID_KEY =
'[MixItUp] The specified UID key "${uidKey}" is not present on one or more dataset items';
this.ERROR_DATASET_DUPLICATE_UID =
'[MixItUp] The UID "${uid}" was found on two or more dataset items. UIDs must be unique.';
this.ERROR_INSERT_INVALID_ARGUMENTS =
'[MixItUp] Please provider either an index or a sibling and position to insert, not both';
this.ERROR_INSERT_PREEXISTING_ELEMENT =
'[MixItUp] An element to be inserted already exists in the container';
this.ERROR_FILTER_INVALID_ARGUMENTS =
'[MixItUp] Please provide either a selector or collection `.filter()`, not both';
this.ERROR_DATASET_NOT_SET =
'[MixItUp] To use the dataset API with pre-rendered targets, a starting dataset must be set using `load.dataset`';
this.ERROR_DATASET_PRERENDERED_MISMATCH =
'[MixItUp] `load.dataset` does not match pre-rendered targets';
this.ERROR_DATASET_RENDERER_NOT_SET =
'[MixItUp] To insert an element via the dataset API, a target renderer function must be provided to `render.target`';
this.ERROR_SORT_NON_EXISTENT_ELEMENT =
'[MixItUp] An element to be sorted does not already exist in the container';
/* Warnings
----------------------------------------------------------------------------- */
this.WARNING_FACTORY_PREEXISTING_INSTANCE =
'[MixItUp] WARNING: This element already has an active MixItUp instance. The provided configuration object will be ignored.' +
' If you wish to perform additional methods on this instance, please create a reference.';
this.WARNING_INSERT_NO_ELEMENTS =
'[MixItUp] WARNING: No valid elements were passed to `.insert()`';
this.WARNING_REMOVE_NO_ELEMENTS =
'[MixItUp] WARNING: No valid elements were passed to `.remove()`';
this.WARNING_MULTIMIX_INSTANCE_QUEUE_FULL =
'[MixItUp] WARNING: An operation was requested but the MixItUp instance was busy. The operation was rejected because the ' +
'queue is full or queuing is disabled.';
this.WARNING_GET_OPERATION_INSTANCE_BUSY =
'[MixItUp] WARNING: Operations can be be created while the MixItUp instance is busy.';
this.WARNING_NO_PROMISE_IMPLEMENTATION =
'[MixItUp] WARNING: No Promise implementations could be found. If you wish to use promises with MixItUp please install' +
' an ES6 Promise polyfill.';
this.WARNING_INCONSISTENT_SORTING_ATTRIBUTES =
'[MixItUp] WARNING: The requested sorting data attribute "${attribute}" was not present on one or more target elements' +
' which may product unexpected sort output';
this.callActions('afterConstruct');
this.compileTemplates();
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Messages);
mixitup.Messages.prototype = Object.create(mixitup.Base.prototype);
mixitup.Messages.prototype.constructor = mixitup.Messages;
/**
* @return {void}
*/
mixitup.Messages.prototype.compileTemplates = function() {
var errorKey = '';
var errorMessage = '';
for (errorKey in this) {
if (typeof (errorMessage = this[errorKey]) !== 'string') continue;
this[h.camelCase(errorKey)] = h.template(errorMessage);
}
};
mixitup.messages = new mixitup.Messages();

View File

@@ -0,0 +1,30 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.MixerDom = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.document = null;
this.body = null;
this.container = null;
this.parent = null;
this.targets = [];
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.MixerDom);
mixitup.MixerDom.prototype = Object.create(mixitup.Base.prototype);
mixitup.MixerDom.prototype.constructor = mixitup.MixerDom;

4363
mixitup-3.3.1/src/mixer.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
/* global module, mixitup, define */
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = mixitup;
} else if (typeof define === 'function' && define.amd) {
define(function() {
return mixitup;
});
} else if (typeof window.mixitup === 'undefined' || typeof window.mixitup !== 'function') {
window.mixitup = mixitup;
}

View File

@@ -0,0 +1,77 @@
/* global mixitup, h */
/**
* `mixitup.Operation` objects contain all data neccessary to describe the full
* lifecycle of any MixItUp operation. They can be used to compute and store an
* operation for use at a later time (e.g. programmatic tweening).
*
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Operation = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.id = '';
this.args = [];
this.command = null;
this.showPosData = [];
this.toHidePosData = [];
this.startState = null;
this.newState = null;
this.docState = null;
this.willSort = false;
this.willChangeLayout = false;
this.hasEffect = false;
this.hasFailed = false;
this.triggerElement = null;
this.show = [];
this.hide = [];
this.matching = [];
this.toShow = [];
this.toHide = [];
this.toMove = [];
this.toRemove = [];
this.startOrder = [];
this.newOrder = [];
this.startSort = null;
this.newSort = null;
this.startFilter = null;
this.newFilter = null;
this.startDataset = null;
this.newDataset = null;
this.viewportDeltaX = 0;
this.viewportDeltaY = 0;
this.startX = 0;
this.startY = 0;
this.startHeight = 0;
this.startWidth = 0;
this.newX = 0;
this.newY = 0;
this.newHeight = 0;
this.newWidth = 0;
this.startContainerClassName = '';
this.startDisplay = '';
this.newContainerClassName = '';
this.newDisplay = '';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Operation);
mixitup.Operation.prototype = Object.create(mixitup.Base.prototype);
mixitup.Operation.prototype.constructor = mixitup.Operation;

View File

@@ -0,0 +1,237 @@
(function() {
var VENDORS = ['webkit', 'moz', 'o', 'ms'],
canary = window.document.createElement('div'),
i = -1;
// window.requestAnimationFrame
for (i = 0; i < VENDORS.length && !window.requestAnimationFrame; i++) {
window.requestAnimationFrame = window[VENDORS[i] + 'RequestAnimationFrame'];
}
// Element.nextElementSibling
if (typeof canary.nextElementSibling === 'undefined') {
Object.defineProperty(window.Element.prototype, 'nextElementSibling', {
get: function() {
var el = this.nextSibling;
while (el) {
if (el.nodeType === 1) {
return el;
}
el = el.nextSibling;
}
return null;
}
});
}
// Element.matches
(function(ElementPrototype) {
ElementPrototype.matches =
ElementPrototype.matches ||
ElementPrototype.machesSelector ||
ElementPrototype.mozMatchesSelector ||
ElementPrototype.msMatchesSelector ||
ElementPrototype.oMatchesSelector ||
ElementPrototype.webkitMatchesSelector ||
function (selector) {
return Array.prototype.indexOf.call(this.parentElement.querySelectorAll(selector), this) > -1;
};
})(window.Element.prototype);
// Object.keys
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = false,
dontEnums = [],
dontEnumsLength = -1;
hasDontEnumBug = !({
toString: null
})
.propertyIsEnumerable('toString');
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
];
dontEnumsLength = dontEnums.length;
return function(obj) {
var result = [],
prop = '',
i = -1;
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
// Array.isArray
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
// Object.create
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create
if (typeof Object.create !== 'function') {
Object.create = (function(undefined) {
var Temp = function() {};
return function (prototype, propertiesObject) {
if (prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object, or null');
}
Temp.prototype = prototype || {};
var result = new Temp();
Temp.prototype = null;
if (propertiesObject !== undefined) {
Object.defineProperties(result, propertiesObject);
}
if (prototype === null) {
/* jshint ignore:start */
result.__proto__ = null;
/* jshint ignore:end */
}
return result;
};
})();
}
// String.prototyoe.trim
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
// Array.prototype.indexOf
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement) {
var n, k, t, len;
if (this === null) {
throw new TypeError();
}
t = Object(this);
len = t.length >>> 0;
if (len === 0) {
return -1;
}
n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
// Function.prototype.bind
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
var aArgs, self, FNOP, fBound;
if (typeof this !== 'function') {
throw new TypeError();
}
aArgs = Array.prototype.slice.call(arguments, 1);
self = this;
FNOP = function() {};
fBound = function() {
return self.apply(this instanceof FNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
};
if (this.prototype) {
FNOP.prototype = this.prototype;
}
fBound.prototype = new FNOP();
return fBound;
};
}
// Element.prototype.dispatchEvent
if (!window.Element.prototype.dispatchEvent) {
window.Element.prototype.dispatchEvent = function(event) {
try {
return this.fireEvent('on' + event.type, event);
} catch (err) {}
};
}
})();

View File

@@ -0,0 +1,30 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.QueueItem = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.args = [];
this.instruction = null;
this.triggerElement = null;
this.deferred = null;
this.isToggling = false;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.QueueItem);
mixitup.QueueItem.prototype = Object.create(mixitup.Base.prototype);
mixitup.QueueItem.prototype.constructor = mixitup.QueueItem;

233
mixitup-3.3.1/src/state.js Normal file
View File

@@ -0,0 +1,233 @@
/* global mixitup, h */
/**
* `mixitup.State` objects expose various pieces of data detailing the state of
* a MixItUp instance. They are provided at the start and end of any operation via
* callbacks and events, with the most recent state stored between operations
* for retrieval at any time via the API.
*
* @constructor
* @namespace
* @memberof mixitup
* @public
* @since 3.0.0
*/
mixitup.State = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
/**
* The ID of the mixer instance.
*
* @name id
* @memberof mixitup.State
* @instance
* @type {string}
* @default ''
*/
this.id = '';
/**
* The currently active filter command as set by a control click or API call.
*
* @name activeFilter
* @memberof mixitup.State
* @instance
* @type {mixitup.CommandFilter}
* @default null
*/
this.activeFilter = null;
/**
* The currently active sort command as set by a control click or API call.
*
* @name activeSort
* @memberof mixitup.State
* @instance
* @type {mixitup.CommandSort}
* @default null
*/
this.activeSort = null;
/**
* The current layout-specific container class name, if applied.
*
* @name activeContainerClassName
* @memberof mixitup.State
* @instance
* @type {string}
* @default ''
*/
this.activeContainerClassName = '';
/**
* A reference to the container element that the mixer is instantiated on.
*
* @name container
* @memberof mixitup.State
* @instance
* @type {Element}
* @default null
*/
this.container = null;
/**
* An array of all target elements indexed by the mixer.
*
* @name targets
* @memberof mixitup.State
* @instance
* @type {Array.<Element>}
* @default []
*/
this.targets = [];
/**
* An array of all target elements not matching the current filter.
*
* @name hide
* @memberof mixitup.State
* @instance
* @type {Array.<Element>}
* @default []
*/
this.hide = [];
/**
* An array of all target elements matching the current filter and any additional
* limits applied such as pagination.
*
* @name show
* @memberof mixitup.State
* @instance
* @type {Array.<Element>}
* @default []
*/
this.show = [];
/**
* An array of all target elements matching the current filter irrespective of
* any additional limits applied such as pagination.
*
* @name matching
* @memberof mixitup.State
* @instance
* @type {Array.<Element>}
* @default []
*/
this.matching = [];
/**
* An integer representing the total number of target elements indexed by the
* mixer. Equivalent to `state.targets.length`.
*
* @name totalTargets
* @memberof mixitup.State
* @instance
* @type {number}
* @default -1
*/
this.totalTargets = -1;
/**
* An integer representing the total number of target elements matching the
* current filter and any additional limits applied such as pagination.
* Equivalent to `state.show.length`.
*
* @name totalShow
* @memberof mixitup.State
* @instance
* @type {number}
* @default -1
*/
this.totalShow = -1;
/**
* An integer representing the total number of target elements not matching
* the current filter. Equivalent to `state.hide.length`.
*
* @name totalHide
* @memberof mixitup.State
* @instance
* @type {number}
* @default -1
*/
this.totalHide = -1;
/**
* An integer representing the total number of target elements matching the
* current filter irrespective of any other limits applied such as pagination.
* Equivalent to `state.matching.length`.
*
* @name totalMatching
* @memberof mixitup.State
* @instance
* @type {number}
* @default -1
*/
this.totalMatching = -1;
/**
* A boolean indicating whether the last operation "failed", i.e. no targets
* could be found matching the filter.
*
* @name hasFailed
* @memberof mixitup.State
* @instance
* @type {boolean}
* @default false
*/
this.hasFailed = false;
/**
* The DOM element that was clicked if the last operation was triggered by the
* clicking of a control and not an API call.
*
* @name triggerElement
* @memberof mixitup.State
* @instance
* @type {Element|null}
* @default null
*/
this.triggerElement = null;
/**
* The currently active dataset underlying the rendered targets, if the
* dataset API is in use.
*
* @name activeDataset
* @memberof mixitup.State
* @instance
* @type {Array.<object>}
* @default null
*/
this.activeDataset = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.State);
mixitup.State.prototype = Object.create(mixitup.Base.prototype);
mixitup.State.prototype.constructor = mixitup.State;

View File

@@ -0,0 +1,43 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.StyleData = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.x = 0;
this.y = 0;
this.top = 0;
this.right = 0;
this.bottom = 0;
this.left = 0;
this.width = 0;
this.height = 0;
this.marginRight = 0;
this.marginBottom = 0;
this.opacity = 0;
this.scale = new mixitup.TransformData();
this.translateX = new mixitup.TransformData();
this.translateY = new mixitup.TransformData();
this.translateZ = new mixitup.TransformData();
this.rotateX = new mixitup.TransformData();
this.rotateY = new mixitup.TransformData();
this.rotateZ = new mixitup.TransformData();
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.StyleData);
mixitup.StyleData.prototype = Object.create(mixitup.Base.prototype);
mixitup.StyleData.prototype.constructor = mixitup.StyleData;

View File

@@ -0,0 +1,26 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.TargetDom = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.el = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.TargetDom);
mixitup.TargetDom.prototype = Object.create(mixitup.Base.prototype);
mixitup.TargetDom.prototype.constructor = mixitup.TargetDom;

730
mixitup-3.3.1/src/target.js Normal file
View File

@@ -0,0 +1,730 @@
/* global mixitup, h */
/**
* @constructor
* @namespace
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.Target = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.id = '';
this.sortString = '';
this.mixer = null;
this.callback = null;
this.isShown = false;
this.isBound = false;
this.isExcluded = false;
this.isInDom = false;
this.handler = null;
this.operation = null;
this.data = null;
this.dom = new mixitup.TargetDom();
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.Target);
mixitup.Target.prototype = Object.create(mixitup.Base.prototype);
h.extend(mixitup.Target.prototype, {
constructor: mixitup.Target,
/**
* Initialises a newly instantiated Target.
*
* @private
* @instance
* @since 3.0.0
* @param {(Element|null)} el
* @param {object} mixer
* @param {object} [data]
* @return {void}
*/
init: function(el, mixer, data) {
var self = this,
id = '';
self.callActions('beforeInit', arguments);
self.mixer = mixer;
if (!el) {
// If no element is provided, render it
el = self.render(data);
}
self.cacheDom(el);
self.bindEvents();
if (self.dom.el.style.display !== 'none') {
self.isShown = true;
}
if (data && mixer.config.data.uidKey) {
if (typeof (id = data[mixer.config.data.uidKey]) === 'undefined' || id.toString().length < 1) {
throw new TypeError(mixitup.messages.errorDatasetInvalidUidKey({
uidKey: mixer.config.data.uidKey
}));
}
self.id = id;
self.data = data;
mixer.cache[id] = self;
}
self.callActions('afterInit', arguments);
},
/**
* Renders the target element using a user-defined renderer function.
*
* @private
* @instance
* @since 3.1.4
* @param {object} data
* @return {void}
*/
render: function(data) {
var self = this,
render = null,
el = null,
temp = null,
output = '';
self.callActions('beforeRender', arguments);
render = self.callFilters('renderRender', self.mixer.config.render.target, arguments);
if (typeof render !== 'function') {
throw new TypeError(mixitup.messages.errorDatasetRendererNotSet());
}
output = render(data);
if (output && typeof output === 'object' && h.isElement(output)) {
el = output;
} else if (typeof output === 'string') {
temp = document.createElement('div');
temp.innerHTML = output;
el = temp.firstElementChild;
}
return self.callFilters('elRender', el, arguments);
},
/**
* Caches references of DOM elements neccessary for the target's functionality.
*
* @private
* @instance
* @since 3.0.0
* @param {Element} el
* @return {void}
*/
cacheDom: function(el) {
var self = this;
self.callActions('beforeCacheDom', arguments);
self.dom.el = el;
self.callActions('afterCacheDom', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {string} attributeName
* @return {void}
*/
getSortString: function(attributeName) {
var self = this,
value = self.dom.el.getAttribute('data-' + attributeName) || '';
self.callActions('beforeGetSortString', arguments);
value = isNaN(value * 1) ?
value.toLowerCase() :
value * 1;
self.sortString = value;
self.callActions('afterGetSortString', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @return {void}
*/
show: function() {
var self = this;
self.callActions('beforeShow', arguments);
if (!self.isShown) {
self.dom.el.style.display = '';
self.isShown = true;
}
self.callActions('afterShow', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @return {void}
*/
hide: function() {
var self = this;
self.callActions('beforeHide', arguments);
if (self.isShown) {
self.dom.el.style.display = 'none';
self.isShown = false;
}
self.callActions('afterHide', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {mixitup.IMoveData} moveData
* @return {void}
*/
move: function(moveData) {
var self = this;
self.callActions('beforeMove', arguments);
if (!self.isExcluded) {
self.mixer.targetsMoved++;
}
self.applyStylesIn(moveData);
requestAnimationFrame(function() {
self.applyStylesOut(moveData);
});
self.callActions('afterMove', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {object} posData
* @param {number} multiplier
* @return {void}
*/
applyTween: function(posData, multiplier) {
var self = this,
propertyName = '',
tweenData = null,
posIn = posData.posIn,
currentTransformValues = [],
currentValues = new mixitup.StyleData(),
i = -1;
self.callActions('beforeApplyTween', arguments);
currentValues.x = posIn.x;
currentValues.y = posIn.y;
if (multiplier === 0) {
self.hide();
} else if (!self.isShown) {
self.show();
}
for (i = 0; propertyName = mixitup.features.TWEENABLE[i]; i++) {
tweenData = posData.tweenData[propertyName];
if (propertyName === 'x') {
if (!tweenData) continue;
currentValues.x = posIn.x + (tweenData * multiplier);
} else if (propertyName === 'y') {
if (!tweenData) continue;
currentValues.y = posIn.y + (tweenData * multiplier);
} else if (tweenData instanceof mixitup.TransformData) {
if (!tweenData.value) continue;
currentValues[propertyName].value =
posIn[propertyName].value + (tweenData.value * multiplier);
currentValues[propertyName].unit = tweenData.unit;
currentTransformValues.push(
propertyName + '(' + currentValues[propertyName].value + tweenData.unit + ')'
);
} else {
if (!tweenData) continue;
currentValues[propertyName] = posIn[propertyName] + (tweenData * multiplier);
self.dom.el.style[propertyName] = currentValues[propertyName];
}
}
if (currentValues.x || currentValues.y) {
currentTransformValues.unshift('translate(' + currentValues.x + 'px, ' + currentValues.y + 'px)');
}
if (currentTransformValues.length) {
self.dom.el.style[mixitup.features.transformProp] = currentTransformValues.join(' ');
}
self.callActions('afterApplyTween', arguments);
},
/**
* Applies the initial styling to a target element before any transition
* is applied.
*
* @private
* @instance
* @param {mixitup.IMoveData} moveData
* @return {void}
*/
applyStylesIn: function(moveData) {
var self = this,
posIn = moveData.posIn,
isFading = self.mixer.effectsIn.opacity !== 1,
transformValues = [];
self.callActions('beforeApplyStylesIn', arguments);
transformValues.push('translate(' + posIn.x + 'px, ' + posIn.y + 'px)');
if (self.mixer.config.animation.animateResizeTargets) {
if (moveData.statusChange !== 'show') {
// Don't apply posIn width or height or showing, as will be 0
self.dom.el.style.width = posIn.width + 'px';
self.dom.el.style.height = posIn.height + 'px';
}
self.dom.el.style.marginRight = posIn.marginRight + 'px';
self.dom.el.style.marginBottom = posIn.marginBottom + 'px';
}
isFading && (self.dom.el.style.opacity = posIn.opacity);
if (moveData.statusChange === 'show') {
transformValues = transformValues.concat(self.mixer.transformIn);
}
self.dom.el.style[mixitup.features.transformProp] = transformValues.join(' ');
self.callActions('afterApplyStylesIn', arguments);
},
/**
* Applies a transition followed by the final styles for the element to
* transition towards.
*
* @private
* @instance
* @param {mixitup.IMoveData} moveData
* @return {void}
*/
applyStylesOut: function(moveData) {
var self = this,
transitionRules = [],
transformValues = [],
isResizing = self.mixer.config.animation.animateResizeTargets,
isFading = typeof self.mixer.effectsIn.opacity !== 'undefined';
self.callActions('beforeApplyStylesOut', arguments);
// Build the transition rules
transitionRules.push(self.writeTransitionRule(
mixitup.features.transformRule,
moveData.staggerIndex
));
if (moveData.statusChange !== 'none') {
transitionRules.push(self.writeTransitionRule(
'opacity',
moveData.staggerIndex,
moveData.duration
));
}
if (isResizing) {
transitionRules.push(self.writeTransitionRule(
'width',
moveData.staggerIndex,
moveData.duration
));
transitionRules.push(self.writeTransitionRule(
'height',
moveData.staggerIndex,
moveData.duration
));
transitionRules.push(self.writeTransitionRule(
'margin',
moveData.staggerIndex,
moveData.duration
));
}
// If no callback was provided, the element will
// not transition in any way so tag it as "immovable"
if (!moveData.callback) {
self.mixer.targetsImmovable++;
if (self.mixer.targetsMoved === self.mixer.targetsImmovable) {
// If the total targets moved is equal to the
// number of immovable targets, the operation
// should be considered finished
self.mixer.cleanUp(moveData.operation);
}
return;
}
// If the target will transition in some fasion,
// assign a callback function
self.operation = moveData.operation;
self.callback = moveData.callback;
// As long as the target is not excluded, increment
// the total number of targets bound
!self.isExcluded && self.mixer.targetsBound++;
// Tag the target as bound to differentiate from transitionEnd
// events that may come from stylesheet driven effects
self.isBound = true;
// Apply the transition
self.applyTransition(transitionRules);
// Apply width, height and margin negation
if (isResizing && moveData.posOut.width > 0 && moveData.posOut.height > 0) {
self.dom.el.style.width = moveData.posOut.width + 'px';
self.dom.el.style.height = moveData.posOut.height + 'px';
self.dom.el.style.marginRight = moveData.posOut.marginRight + 'px';
self.dom.el.style.marginBottom = moveData.posOut.marginBottom + 'px';
}
if (!self.mixer.config.animation.nudge && moveData.statusChange === 'hide') {
// If we're not nudging, the translation should be
// applied before any other transforms to prevent
// lateral movement
transformValues.push('translate(' + moveData.posOut.x + 'px, ' + moveData.posOut.y + 'px)');
}
// Apply fade
switch (moveData.statusChange) {
case 'hide':
isFading && (self.dom.el.style.opacity = self.mixer.effectsOut.opacity);
transformValues = transformValues.concat(self.mixer.transformOut);
break;
case 'show':
isFading && (self.dom.el.style.opacity = 1);
}
if (
self.mixer.config.animation.nudge ||
(!self.mixer.config.animation.nudge && moveData.statusChange !== 'hide')
) {
// Opposite of above - apply translate after
// other transform
transformValues.push('translate(' + moveData.posOut.x + 'px, ' + moveData.posOut.y + 'px)');
}
// Apply transforms
self.dom.el.style[mixitup.features.transformProp] = transformValues.join(' ');
self.callActions('afterApplyStylesOut', arguments);
},
/**
* Combines the name of a CSS property with the appropriate duration and delay
* values to created a valid transition rule.
*
* @private
* @instance
* @since 3.0.0
* @param {string} property
* @param {number} staggerIndex
* @param {number} duration
* @return {string}
*/
writeTransitionRule: function(property, staggerIndex, duration) {
var self = this,
delay = self.getDelay(staggerIndex),
rule = '';
rule = property + ' ' +
(duration > 0 ? duration : self.mixer.config.animation.duration) + 'ms ' +
delay + 'ms ' +
(property === 'opacity' ? 'linear' : self.mixer.config.animation.easing);
return self.callFilters('ruleWriteTransitionRule', rule, arguments);
},
/**
* Calculates the transition delay for each target element based on its index, if
* staggering is applied. If defined, A custom `animation.staggerSeqeuence`
* function can be used to manipulate the order of indices to produce custom
* stagger effects (e.g. for use in a grid with irregular row lengths).
*
* @private
* @instance
* @since 2.0.0
* @param {number} index
* @return {number}
*/
getDelay: function(index) {
var self = this,
delay = -1;
if (typeof self.mixer.config.animation.staggerSequence === 'function') {
index = self.mixer.config.animation.staggerSequence.call(self, index, self.state);
}
delay = !!self.mixer.staggerDuration ? index * self.mixer.staggerDuration : 0;
return self.callFilters('delayGetDelay', delay, arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {string[]} rules
* @return {void}
*/
applyTransition: function(rules) {
var self = this,
transitionString = rules.join(', ');
self.callActions('beforeApplyTransition', arguments);
self.dom.el.style[mixitup.features.transitionProp] = transitionString;
self.callActions('afterApplyTransition', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {Event} e
* @return {void}
*/
handleTransitionEnd: function(e) {
var self = this,
propName = e.propertyName,
canResize = self.mixer.config.animation.animateResizeTargets;
self.callActions('beforeHandleTransitionEnd', arguments);
if (
self.isBound &&
e.target.matches(self.mixer.config.selectors.target) &&
(
propName.indexOf('transform') > -1 ||
propName.indexOf('opacity') > -1 ||
canResize && propName.indexOf('height') > -1 ||
canResize && propName.indexOf('width') > -1 ||
canResize && propName.indexOf('margin') > -1
)
) {
self.callback.call(self, self.operation);
self.isBound = false;
self.callback = null;
self.operation = null;
}
self.callActions('afterHandleTransitionEnd', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {Event} e
* @return {void}
*/
eventBus: function(e) {
var self = this;
self.callActions('beforeEventBus', arguments);
switch (e.type) {
case 'webkitTransitionEnd':
case 'transitionend':
self.handleTransitionEnd(e);
}
self.callActions('afterEventBus', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @return {void}
*/
unbindEvents: function() {
var self = this;
self.callActions('beforeUnbindEvents', arguments);
h.off(self.dom.el, 'webkitTransitionEnd', self.handler);
h.off(self.dom.el, 'transitionend', self.handler);
self.callActions('afterUnbindEvents', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @return {void}
*/
bindEvents: function() {
var self = this,
transitionEndEvent = '';
self.callActions('beforeBindEvents', arguments);
transitionEndEvent = mixitup.features.transitionPrefix === 'webkit' ? 'webkitTransitionEnd' : 'transitionend';
self.handler = function(e) {
return self.eventBus(e);
};
h.on(self.dom.el, transitionEndEvent, self.handler);
self.callActions('afterBindEvents', arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @param {boolean} [getBox]
* @return {PosData}
*/
getPosData: function(getBox) {
var self = this,
styles = {},
rect = null,
posData = new mixitup.StyleData();
self.callActions('beforeGetPosData', arguments);
posData.x = self.dom.el.offsetLeft;
posData.y = self.dom.el.offsetTop;
if (self.mixer.config.animation.animateResizeTargets || getBox) {
rect = self.dom.el.getBoundingClientRect();
posData.top = rect.top;
posData.right = rect.right;
posData.bottom = rect.bottom;
posData.left = rect.left;
posData.width = rect.width;
posData.height = rect.height;
}
if (self.mixer.config.animation.animateResizeTargets) {
styles = window.getComputedStyle(self.dom.el);
posData.marginBottom = parseFloat(styles.marginBottom);
posData.marginRight = parseFloat(styles.marginRight);
}
return self.callFilters('posDataGetPosData', posData, arguments);
},
/**
* @private
* @instance
* @since 3.0.0
* @return {void}
*/
cleanUp: function() {
var self = this;
self.callActions('beforeCleanUp', arguments);
self.dom.el.style[mixitup.features.transformProp] = '';
self.dom.el.style[mixitup.features.transitionProp] = '';
self.dom.el.style.opacity = '';
if (self.mixer.config.animation.animateResizeTargets) {
self.dom.el.style.width = '';
self.dom.el.style.height = '';
self.dom.el.style.marginRight = '';
self.dom.el.style.marginBottom = '';
}
self.callActions('afterCleanUp', arguments);
}
});

View File

@@ -0,0 +1,27 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.TransformData = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.value = 0;
this.unit = '';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.TransformData);
mixitup.TransformData.prototype = Object.create(mixitup.Base.prototype);
mixitup.TransformData.prototype.constructor = mixitup.TransformData;

View File

@@ -0,0 +1,57 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.TransformDefaults = function() {
mixitup.StyleData.apply(this);
this.callActions('beforeConstruct');
this.scale.value = 0.01;
this.scale.unit = '';
this.translateX.value = 20;
this.translateX.unit = 'px';
this.translateY.value = 20;
this.translateY.unit = 'px';
this.translateZ.value = 20;
this.translateZ.unit = 'px';
this.rotateX.value = 90;
this.rotateX.unit = 'deg';
this.rotateY.value = 90;
this.rotateY.unit = 'deg';
this.rotateX.value = 90;
this.rotateX.unit = 'deg';
this.rotateZ.value = 180;
this.rotateZ.unit = 'deg';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.TransformDefaults);
mixitup.TransformDefaults.prototype = Object.create(mixitup.StyleData.prototype);
mixitup.TransformDefaults.prototype.constructor = mixitup.TransformDefaults;
/**
* @private
* @static
* @since 3.0.0
* @type {mixitup.TransformDefaults}
*/
mixitup.transformDefaults = new mixitup.TransformDefaults();

View File

@@ -0,0 +1,28 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.UiClassNames = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.base = '';
this.active = '';
this.disabled = '';
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.UiClassNames);
mixitup.UiClassNames.prototype = Object.create(mixitup.Base.prototype);
mixitup.UiClassNames.prototype.constructor = mixitup.UiClassNames;

View File

@@ -0,0 +1,28 @@
/* global mixitup, h */
/**
* @constructor
* @memberof mixitup
* @private
* @since 3.0.0
*/
mixitup.UserInstruction = function() {
mixitup.Base.call(this);
this.callActions('beforeConstruct');
this.command = {};
this.animate = false;
this.callback = null;
this.callActions('afterConstruct');
h.seal(this);
};
mixitup.BaseStatic.call(mixitup.UserInstruction);
mixitup.UserInstruction.prototype = Object.create(mixitup.Base.prototype);
mixitup.UserInstruction.prototype.constructor = mixitup.UserInstruction;

View File

@@ -0,0 +1,105 @@
{{>banner}}
(function(window) {
'use strict';
var mixitup = null,
h = null;
{{>polyfills}}
{{>factory}}
{{>h}}
{{>base}}
{{>base-static}}
{{>features}}
{{>config-animation}}
{{>config-behavior}}
{{>config-callbacks}}
{{>config-controls}}
{{>config-class-names}}
{{>config-data}}
{{>config-debug}}
{{>config-layout}}
{{>config-load}}
{{>config-selectors}}
{{>config-render}}
{{>config-templates}}
{{>config}}
{{>mixer-dom}}
{{>ui-class-names}}
{{>command-dataset}}
{{>command-multimix}}
{{>command-filter}}
{{>command-sort}}
{{>command-insert}}
{{>command-remove}}
{{>command-change-layout}}
{{>control-definition}}
{{>control}}
{{>style-data}}
{{>transform-data}}
{{>transform-defaults}}
{{>events}}
{{>queue-item}}
{{>mixer}}
{{>i-move-data}}
{{>target-dom}}
{{>target}}
{{>collection}}
{{>operation}}
{{>state}}
{{>user-instruction}}
{{>messages}}
{{>facade}}
{{>module-definitions}}
mixitup.BaseStatic.call(mixitup.constructor);
mixitup.NAME = '{{name}}';
mixitup.CORE_VERSION = '{{version}}';
})(window);