diff --git a/dist/shuffle.js b/dist/shuffle.js index de69b3b..41fd4b0 100644 --- a/dist/shuffle.js +++ b/dist/shuffle.js @@ -965,7 +965,11 @@ var Shuffle = function () { var keys = this.options.delimeter ? attr.split(this.options.delimeter) : JSON.parse(attr); if (Array.isArray(category)) { - return category.some(arrayIncludes(keys)); + if (this.options.filterMode != Shuffle.filterMode.EXCLUSIVE) { + return category.every(arrayIncludes(keys)); + } else { + return category.some(arrayIncludes(keys)); + } } return arrayIncludes(keys, category); @@ -1918,6 +1922,14 @@ Shuffle.EventType = { /** @enum {string} */ Shuffle.Classes = Classes; +/** + * @enum {string} + */ +Shuffle.filterMode = { + EXCLUSIVE: 'exclusive', + ADDITIVE: 'additive' +}; + // Overrideable options Shuffle.options = { // Initial filter group. @@ -1974,7 +1986,10 @@ Shuffle.options = { staggerAmountMax: 250, // Whether to use transforms or absolute positioning. - useTransforms: true + useTransforms: true, + + // Filters elements with "some" when 'exclusive' and with every on 'additive' + filterMode: Shuffle.filterMode.EXCLUSIVE }; // Expose for testing. Hack at your own risk. diff --git a/dist/shuffle.js.map b/dist/shuffle.js.map index a4d7812..75c0c11 100644 --- a/dist/shuffle.js.map +++ b/dist/shuffle.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.js","sources":["../node_modules/custom-event-polyfill/custom-event-polyfill.js","../node_modules/matches-selector/index.js","../node_modules/array-uniq/index.js","../node_modules/xtend/immutable.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/shuffle.js"],"sourcesContent":["// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n","'use strict';\n\nvar proto = Element.prototype;\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}","'use strict';\n\n// there's 3 implementations written in increasing order of efficiency\n\n// 1 - no Set type is defined\nfunction uniqNoSet(arr) {\n\tvar ret = [];\n\n\tfor (var i = 0; i < arr.length; i++) {\n\t\tif (ret.indexOf(arr[i]) === -1) {\n\t\t\tret.push(arr[i]);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n// 2 - a simple Set type is defined\nfunction uniqSet(arr) {\n\tvar seen = new Set();\n\treturn arr.filter(function (el) {\n\t\tif (!seen.has(el)) {\n\t\t\tseen.add(el);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n}\n\n// 3 - a standard Set type is defined and it has a forEach method\nfunction uniqSetWithForEach(arr) {\n\tvar ret = [];\n\n\t(new Set(arr)).forEach(function (el) {\n\t\tret.push(el);\n\t});\n\n\treturn ret;\n}\n\n// V8 currently has a broken implementation\n// https://github.com/joyent/node/issues/8449\nfunction doesForEachActuallyWork() {\n\tvar ret = false;\n\n\t(new Set([true])).forEach(function (el) {\n\t\tret = el;\n\t});\n\n\treturn ret === true;\n}\n\nif ('Set' in global) {\n\tif (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) {\n\t\tmodule.exports = uniqSetWithForEach;\n\t} else {\n\t\tmodule.exports = uniqSet;\n\t}\n} else {\n\tmodule.exports = uniqNoSet;\n}\n","module.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n var target = {}\n\n for (var i = 0; i < arguments.length; i++) {\n var source = arguments[i]\n\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n\n return target\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n this.isVisible = true;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {},\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst width = window.getComputedStyle(e, null).width;\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style,\n styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","import xtend from 'xtend';\n\n/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = xtend(defaults, options);\n const original = [].slice.call(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 0]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 0]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(\n Math.round(gridSize * shortColumnIndex),\n Math.round(setY[shortColumnIndex]));\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n","import 'custom-event-polyfill';\nimport matches from 'matches-selector';\nimport arrayUnique from 'array-uniq';\nimport xtend from 'xtend';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\nimport Point from './point';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn } from './layout';\nimport arrayMax from './array-max';\n\nfunction toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n}\n\nfunction arrayIncludes(array, obj) {\n if (arguments.length === 2) {\n return arrayIncludes(array)(obj);\n }\n\n return obj => array.indexOf(obj) > -1;\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle {\n\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n this.options = xtend(Shuffle.options, options);\n\n this.useSizer = false;\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n if (this.options.sizer) {\n this.useSizer = true;\n }\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems();\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this._setTransitions();\n this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {Function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string} [category] Category to filter by. If it's given, the last\n * category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|Function} category Category or function to filter by.\n * @param {Array.} items A collection of items to filter.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|Function} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n\n // Check each element's data-groups attribute against the given category.\n }\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimeter ?\n attr.split(this.options.delimeter) :\n JSON.parse(attr);\n\n if (Array.isArray(category)) {\n return category.some(arrayIncludes(keys));\n }\n\n return arrayIncludes(keys, category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {Array.} [items] Optionally specifiy at set to initialize.\n * @private\n */\n _initItems(items = this.items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @private\n */\n _disposeItems(items = this.items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of Shuffle.\n * @param {Array.} items Shuffle items to set transitions on.\n * @private\n */\n _setTransitions(items = this.items) {\n const speed = this.options.speed;\n const easing = this.options.easing;\n\n const str = this.options.useTransforms ?\n `transform ${speed}ms ${easing}, opacity ${speed}ms ${easing}` :\n `top ${speed}ms ${easing}, left ${speed}ms ${easing}, opacity ${speed}ms ${easing}`;\n\n items.forEach((item) => {\n item.element.style.transition = str;\n });\n }\n\n _getItems() {\n return toArray(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * When new elements are added to the shuffle container, update the array of\n * items because that is the order `_layout` calls them.\n */\n _updateItemsOrder() {\n const children = this.element.children;\n this.items = sorter(this.items, {\n by(element) {\n return Array.prototype.indexOf.call(children, element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.useSizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.useSizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * @return {boolean} Whether the event was prevented or not.\n */\n _dispatch(name, details = {}) {\n if (this.isDestroyed) {\n return false;\n }\n\n details.shuffle = this;\n return !this.element.dispatchEvent(new CustomEvent(name, {\n bubbles: true,\n cancelable: false,\n detail: details,\n }));\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {Array.} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n let count = 0;\n items.forEach((item) => {\n const currPos = item.point;\n const currScale = item.scale;\n const itemSize = Shuffle.getSize(item.element, true);\n const pos = this._getItemPosition(itemSize);\n\n function callback() {\n item.element.style.transitionDelay = '';\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(currPos, pos) && currScale === ShuffleItem.Scale.VISIBLE) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = pos;\n item.scale = ShuffleItem.Scale.VISIBLE;\n\n // Use xtend here to clone the object so that the `before` object isn't\n // modified when the transition delay is added.\n const styles = xtend(ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {Array.} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.scale === ShuffleItem.Scale.HIDDEN) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n\n const styles = xtend(ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n // Will need to check height in the future if it's layed out horizontaly\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // containerWidth hasn't changed, don't do anything\n if (containerWidth === this.containerWidth) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {Object} obj Transition options.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @private\n */\n _getStylesForTransition({ item, styles }) {\n if (!styles.transitionDelay) {\n styles.transitionDelay = '0ms';\n }\n\n const x = item.point.x;\n const y = item.point.y;\n\n if (this.options.useTransforms) {\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = x + 'px';\n styles.top = y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {Function} itemCallback Callback for the item.\n * @param {Function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {Function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(this._getStylesForTransition(opts));\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatchLayout();\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatchLayout();\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Array.} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Array.} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(this._getStylesForTransition(obj));\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatchLayout();\n }\n\n _dispatchLayout() {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|Function|Array.} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} opts the options object for the sorted plugin\n */\n sort(opts = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n let items = this._getFilteredItems();\n items = sorter(items, opts);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = opts;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} isOnlyLayout If true, column and gutter widths won't be\n * recalculated.\n */\n update(isOnlyLayout) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Array.} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Add transition to each item.\n this._setTransitions(items);\n\n // Update the list of items.\n this.items = this.items.concat(items);\n this._updateItemsOrder();\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout) {\n this.isEnabled = true;\n if (isUpdateLayout !== false) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items\n * @param {Array.} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle object\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this.element.removeEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !arrayIncludes(oldItems, item));\n this._updateItemCount();\n\n this.element.addEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or null if it's not found.\n */\n getItemByElement(element) {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (this.items[i].element === element) {\n return this.items[i];\n }\n }\n\n return null;\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems();\n\n // Null DOM references\n this.items = null;\n this.options.sizer = null;\n this.element = null;\n this._transitions = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins] Whether to include margins. Default is false.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Array.} elements DOM elements that won't be transitioned.\n * @param {Function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const style = element.style;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause reflow.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/**\n * @enum {string}\n */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'ease',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimeter\n // to ','.\n delimeter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 250,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n};\n\n// Expose for testing. Hack at your own risk.\nShuffle.__Point = Point;\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\n\nexport default Shuffle;\n"],"names":["CustomEvent","global","getNumber","value","parseFloat","Point","x","y","a","b","id","ShuffleItem","element","isVisible","classList","remove","Classes","HIDDEN","add","VISIBLE","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","keys","key","style","removeClasses","removeAttribute","document","body","documentElement","e","createElement","cssText","appendChild","width","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","xtend","original","slice","call","revert","by","sort","valA","valB","undefined","reverse","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","height","toArray","arrayLike","Array","prototype","arrayIncludes","arguments","indexOf","Shuffle","useSizer","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","items","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","containerCss","containerWidth","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","_setTransitions","transition","speed","easing","resizeFunction","_handleResize","bind","throttle","throttleTime","option","querySelector","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","isArray","some","show","hide","init","dispose","visibleItems","_getFilteredItems","str","useTransforms","children","matches","itemSelector","map","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","details","shuffle","dispatchEvent","currPos","currScale","pos","_getItemPosition","transitionDelay","after","equals","before","_getStaggerAmount","_getConcealedItems","update","transform","left","top","itemCallback","done","_getStylesForTransition","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatchLayout","callbacks","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","_dispatch","EventType","LAYOUT","sortObj","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","arrayUnique","concat","_updateItemsOrder","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","data","duration","transitionDuration","delay","__Point","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.js","sources":["../node_modules/custom-event-polyfill/custom-event-polyfill.js","../node_modules/matches-selector/index.js","../node_modules/array-uniq/index.js","../node_modules/xtend/immutable.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/shuffle.js"],"sourcesContent":["// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n","'use strict';\n\nvar proto = Element.prototype;\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}","'use strict';\n\n// there's 3 implementations written in increasing order of efficiency\n\n// 1 - no Set type is defined\nfunction uniqNoSet(arr) {\n\tvar ret = [];\n\n\tfor (var i = 0; i < arr.length; i++) {\n\t\tif (ret.indexOf(arr[i]) === -1) {\n\t\t\tret.push(arr[i]);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n// 2 - a simple Set type is defined\nfunction uniqSet(arr) {\n\tvar seen = new Set();\n\treturn arr.filter(function (el) {\n\t\tif (!seen.has(el)) {\n\t\t\tseen.add(el);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n}\n\n// 3 - a standard Set type is defined and it has a forEach method\nfunction uniqSetWithForEach(arr) {\n\tvar ret = [];\n\n\t(new Set(arr)).forEach(function (el) {\n\t\tret.push(el);\n\t});\n\n\treturn ret;\n}\n\n// V8 currently has a broken implementation\n// https://github.com/joyent/node/issues/8449\nfunction doesForEachActuallyWork() {\n\tvar ret = false;\n\n\t(new Set([true])).forEach(function (el) {\n\t\tret = el;\n\t});\n\n\treturn ret === true;\n}\n\nif ('Set' in global) {\n\tif (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) {\n\t\tmodule.exports = uniqSetWithForEach;\n\t} else {\n\t\tmodule.exports = uniqSet;\n\t}\n} else {\n\tmodule.exports = uniqNoSet;\n}\n","module.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n var target = {}\n\n for (var i = 0; i < arguments.length; i++) {\n var source = arguments[i]\n\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n\n return target\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n this.isVisible = true;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {},\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst width = window.getComputedStyle(e, null).width;\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style,\n styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","import xtend from 'xtend';\n\n/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = xtend(defaults, options);\n const original = [].slice.call(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 0]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 0]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(\n Math.round(gridSize * shortColumnIndex),\n Math.round(setY[shortColumnIndex]));\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n","import 'custom-event-polyfill';\nimport matches from 'matches-selector';\nimport arrayUnique from 'array-uniq';\nimport xtend from 'xtend';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\nimport Point from './point';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn } from './layout';\nimport arrayMax from './array-max';\n\nfunction toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n}\n\nfunction arrayIncludes(array, obj) {\n if (arguments.length === 2) {\n return arrayIncludes(array)(obj);\n }\n\n return obj => array.indexOf(obj) > -1;\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle {\n\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n this.options = xtend(Shuffle.options, options);\n\n this.useSizer = false;\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n if (this.options.sizer) {\n this.useSizer = true;\n }\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems();\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this._setTransitions();\n this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {Function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string} [category] Category to filter by. If it's given, the last\n * category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|Function} category Category or function to filter by.\n * @param {Array.} items A collection of items to filter.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|Function} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n\n // Check each element's data-groups attribute against the given category.\n }\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimeter ?\n attr.split(this.options.delimeter) :\n JSON.parse(attr);\n\n if (Array.isArray(category)) {\n if(this.options.filterMode!=Shuffle.filterMode.EXCLUSIVE){\n return category.every(arrayIncludes(keys));\n } else {\n return category.some(arrayIncludes(keys));\n }\n }\n\n return arrayIncludes(keys, category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {Array.} [items] Optionally specifiy at set to initialize.\n * @private\n */\n _initItems(items = this.items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @private\n */\n _disposeItems(items = this.items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of Shuffle.\n * @param {Array.} items Shuffle items to set transitions on.\n * @private\n */\n _setTransitions(items = this.items) {\n const speed = this.options.speed;\n const easing = this.options.easing;\n\n const str = this.options.useTransforms ?\n `transform ${speed}ms ${easing}, opacity ${speed}ms ${easing}` :\n `top ${speed}ms ${easing}, left ${speed}ms ${easing}, opacity ${speed}ms ${easing}`;\n\n items.forEach((item) => {\n item.element.style.transition = str;\n });\n }\n\n _getItems() {\n return toArray(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * When new elements are added to the shuffle container, update the array of\n * items because that is the order `_layout` calls them.\n */\n _updateItemsOrder() {\n const children = this.element.children;\n this.items = sorter(this.items, {\n by(element) {\n return Array.prototype.indexOf.call(children, element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.useSizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.useSizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * @return {boolean} Whether the event was prevented or not.\n */\n _dispatch(name, details = {}) {\n if (this.isDestroyed) {\n return false;\n }\n\n details.shuffle = this;\n return !this.element.dispatchEvent(new CustomEvent(name, {\n bubbles: true,\n cancelable: false,\n detail: details,\n }));\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {Array.} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n let count = 0;\n items.forEach((item) => {\n const currPos = item.point;\n const currScale = item.scale;\n const itemSize = Shuffle.getSize(item.element, true);\n const pos = this._getItemPosition(itemSize);\n\n function callback() {\n item.element.style.transitionDelay = '';\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(currPos, pos) && currScale === ShuffleItem.Scale.VISIBLE) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = pos;\n item.scale = ShuffleItem.Scale.VISIBLE;\n\n // Use xtend here to clone the object so that the `before` object isn't\n // modified when the transition delay is added.\n const styles = xtend(ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {Array.} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.scale === ShuffleItem.Scale.HIDDEN) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n\n const styles = xtend(ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n // Will need to check height in the future if it's layed out horizontaly\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // containerWidth hasn't changed, don't do anything\n if (containerWidth === this.containerWidth) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {Object} obj Transition options.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @private\n */\n _getStylesForTransition({ item, styles }) {\n if (!styles.transitionDelay) {\n styles.transitionDelay = '0ms';\n }\n\n const x = item.point.x;\n const y = item.point.y;\n\n if (this.options.useTransforms) {\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = x + 'px';\n styles.top = y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {Function} itemCallback Callback for the item.\n * @param {Function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {Function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(this._getStylesForTransition(opts));\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatchLayout();\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatchLayout();\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Array.} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Array.} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(this._getStylesForTransition(obj));\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatchLayout();\n }\n\n _dispatchLayout() {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|Function|Array.} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} opts the options object for the sorted plugin\n */\n sort(opts = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n let items = this._getFilteredItems();\n items = sorter(items, opts);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = opts;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} isOnlyLayout If true, column and gutter widths won't be\n * recalculated.\n */\n update(isOnlyLayout) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Array.} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Add transition to each item.\n this._setTransitions(items);\n\n // Update the list of items.\n this.items = this.items.concat(items);\n this._updateItemsOrder();\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout) {\n this.isEnabled = true;\n if (isUpdateLayout !== false) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items\n * @param {Array.} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle object\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this.element.removeEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !arrayIncludes(oldItems, item));\n this._updateItemCount();\n\n this.element.addEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or null if it's not found.\n */\n getItemByElement(element) {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (this.items[i].element === element) {\n return this.items[i];\n }\n }\n\n return null;\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems();\n\n // Null DOM references\n this.items = null;\n this.options.sizer = null;\n this.element = null;\n this._transitions = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins] Whether to include margins. Default is false.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Array.} elements DOM elements that won't be transitioned.\n * @param {Function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const style = element.style;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause reflow.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/**\n * @enum {string}\n */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/**\n * @enum {string}\n */\nShuffle.filterMode = {\n EXCLUSIVE: 'exclusive',\n ADDITIVE: 'additive',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'ease',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimeter\n // to ','.\n delimeter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 250,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Filters elements with \"some\" when 'exclusive' and with every on 'additive'\n filterMode : Shuffle.filterMode.EXCLUSIVE,\n};\n\n// Expose for testing. Hack at your own risk.\nShuffle.__Point = Point;\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\n\nexport default Shuffle;\n"],"names":["CustomEvent","global","getNumber","value","parseFloat","Point","x","y","a","b","id","ShuffleItem","element","isVisible","classList","remove","Classes","HIDDEN","add","VISIBLE","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","keys","key","style","removeClasses","removeAttribute","document","body","documentElement","e","createElement","cssText","appendChild","width","window","getComputedStyle","ret","removeChild","getNumberStyle","styles","COMPUTED_SIZE_INCLUDES_PADDING","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","sorter","arr","options","opts","xtend","original","slice","call","revert","by","sort","valA","valB","undefined","reverse","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","height","toArray","arrayLike","Array","prototype","arrayIncludes","arguments","indexOf","Shuffle","useSizer","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","items","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","containerCss","containerWidth","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","_setTransitions","transition","speed","easing","resizeFunction","_handleResize","bind","throttle","throttleTime","option","querySelector","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","isArray","filterMode","EXCLUSIVE","every","some","show","hide","init","dispose","visibleItems","_getFilteredItems","str","useTransforms","children","matches","itemSelector","map","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","details","shuffle","dispatchEvent","currPos","currScale","pos","_getItemPosition","transitionDelay","after","equals","before","_getStaggerAmount","_getConcealedItems","update","transform","left","top","itemCallback","done","_getStylesForTransition","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatchLayout","callbacks","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","_dispatch","EventType","LAYOUT","sortObj","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","arrayUnique","concat","_updateItemsOrder","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","data","duration","transitionDuration","delay","__Point","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn"],"mappings":"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"} \ No newline at end of file diff --git a/dist/shuffle.min.js b/dist/shuffle.min.js index 5cfaf56..8ab6535 100644 --- a/dist/shuffle.min.js +++ b/dist/shuffle.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.shuffle=e()}(this,function(){"use strict";function t(t,e){if(b)return b.call(t,e);for(var i=t.parentNode.querySelectorAll(e),n=0;n=e?i():r=setTimeout(i,e-t)),o}}function n(){}function s(t){return parseFloat(t)||0}function o(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=s(i[e]);return N||"width"!==e?N||"height"!==e||(n+=s(i.paddingTop)+s(i.paddingBottom)+s(i.borderTopWidth)+s(i.borderBottomWidth)):n+=s(i.paddingLeft)+s(i.paddingRight)+s(i.borderLeftWidth)+s(i.borderRightWidth),n}function r(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}function l(t,e){var i=w(R,e),n=[].slice.call(t),s=!1;return t.length?i.randomize?r(t):("function"==typeof i.by&&t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}),s?n:(i.reverse&&t.reverse(),t)):[]}function a(){return P+=1,q+P}function u(t){return!!H[t]&&(H[t].element.removeEventListener(q,H[t].listener),H[t]=null,!0)}function h(t,e){var i=a(),n=function(t){t.currentTarget===t.target&&(u(i),e(t))};return t.addEventListener(q,n),H[i]={element:t,listener:n},i}function f(t){return Math.max.apply(Math,t)}function c(t){return Math.min.apply(Math,t)}function d(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=i-e&&t[n]<=i+e)return n;return 0}function p(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=d(e.width,n,s,o),a=m(i,l,s),u=v(a,r),h=new F(Math.round(n*u),Math.round(a[u])),f=a[u]+e.height,c=0;c-1}}try{var _=new window.CustomEvent("test");if(_.preventDefault(),!0!==_.defaultPrevented)throw new Error("Could not prevent default")}catch(t){var E=function(t,e){var i,n;return e=e||{bubbles:!1,cancelable:!1,detail:void 0},i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n=i.preventDefault,i.preventDefault=function(){n.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(t){this.defaultPrevented=!0}},i};E.prototype=window.Event.prototype,window.CustomEvent=E}var S=Element.prototype,b=S.matches||S.matchesSelector||S.webkitMatchesSelector||S.mozMatchesSelector||S.msMatchesSelector||S.oMatchesSelector,I=t,k="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},T=function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t){function e(t){for(var e=[],i=0;i1&&void 0!==arguments[1]?arguments[1]:{};D(this,t),this.options=w(t.options,i),this.useSizer=!1,this.lastSort={},this.group=t.ALL_ITEMS,this.lastFilter=t.ALL_ITEMS,this.isEnabled=!0,this.isDestroyed=!1,this.isInitialized=!1,this._transitions=[],this.isTransitioning=!1,this._queue=[];var n=this._getElementOption(e);if(!n)throw new TypeError("Shuffle needs to be initialized with an element.");this.element=n,this.id="shuffle_"+U,U+=1,this._init(),this.isInitialized=!0}return M(t,[{key:"_init",value:function(){this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.options.sizer&&(this.useSizer=!0),this.element.classList.add(t.Classes.BASE),this._initItems(),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize);var e=window.getComputedStyle(this.element,null),i=t.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this._setTransitions(),this.element.style.transition="height "+this.options.speed+"ms "+this.options.easing}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(e,i){var n=this,s=[],o=[];return e===t.ALL_ITEMS?s=i:i.forEach(function(t){n._doesPassFilter(e,t.element)?s.push(t):o.push(t)}),{visible:s,hidden:o}}},{key:"_doesPassFilter",value:function(e,i){if("function"==typeof e)return e.call(i,i,this);var n=i.getAttribute("data-"+t.FILTER_ATTRIBUTE_KEY),s=this.options.delimeter?n.split(this.options.delimeter):JSON.parse(n);return Array.isArray(e)?e.some(g(s)):g(s,e)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items).forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items).forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"_setTransitions",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items,e=this.options.speed,i=this.options.easing,n=this.options.useTransforms?"transform "+e+"ms "+i+", opacity "+e+"ms "+i:"top "+e+"ms "+i+", left "+e+"ms "+i+", opacity "+e+"ms "+i;t.forEach(function(t){t.element.style.transition=n})}},{key:"_getItems",value:function(){var t=this;return y(this.element.children).filter(function(e){return I(e,t.options.itemSelector)}).map(function(t){return new B(t)})}},{key:"_updateItemsOrder",value:function(){var t=this.element.children;this.items=l(this.items,{by:function(e){return Array.prototype.indexOf.call(t,e)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(e,i){var n=void 0;return n="function"==typeof this.options.columnWidth?this.options.columnWidth(e):this.useSizer?t.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?t.getSize(this.items[0].element,!0).width:e,0===n&&(n=e),n+i}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.useSizer?o(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t.getSize(this.element).width,i=this._getGutterSize(e),n=this._getColumnSize(e,i),s=(e+i)/n;Math.abs(Math.round(s)-s)1&&void 0!==arguments[1]?arguments[1]:{};return!this.isDestroyed&&(e.shuffle=this,!this.element.dispatchEvent(new CustomEvent(t,{bubbles:!0,cancelable:!1,detail:e})))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(e){var i=this,n=0;e.forEach(function(e){function s(){e.element.style.transitionDelay="",e.applyCss(B.Css.VISIBLE.after)}var o=e.point,r=e.scale,l=t.getSize(e.element,!0),a=i._getItemPosition(l);if(F.equals(o,a)&&r===B.Scale.VISIBLE)return e.applyCss(B.Css.VISIBLE.before),void s();e.point=a,e.scale=B.Scale.VISIBLE;var u=w(B.Css.VISIBLE.before);u.transitionDelay=i._getStaggerAmount(n)+"ms",i._queue.push({item:e,styles:u,callback:s}),n+=1})}},{key:"_getItemPosition",value:function(t){return p({itemSize:t,positions:this.positions,gridSize:this.colWidth,total:this.cols,threshold:this.options.columnThreshold,buffer:this.options.buffer})}},{key:"_shrink",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(B.Css.HIDDEN.after)}if(e.scale===B.Scale.HIDDEN)return e.applyCss(B.Css.HIDDEN.before),void n();e.scale=B.Scale.HIDDEN;var s=w(B.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){if(this.isEnabled&&!this.isDestroyed){t.getSize(this.element).width!==this.containerWidth&&this.update()}}},{key:"_getStylesForTransition",value:function(t){var e=t.item,i=t.styles;i.transitionDelay||(i.transitionDelay="0ms");var n=e.point.x,s=e.point.y;return this.options.useTransforms?i.transform="translate("+n+"px, "+s+"px) scale("+e.scale+")":(i.left=n+"px",i.top=s+"px"),i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=h(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(e._getStylesForTransition(t)),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatchLayout()):this._dispatchLayout(),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0;var i=t.map(function(t){return e._getTransitionFunction(t)});z(i,this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(u),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(e){var i=this;if(e.length){var n=e.map(function(t){return t.item.element});t._skipTransitions(n,function(){e.forEach(function(t){t.item.applyCss(i._getStylesForTransition(t)),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatchLayout()}},{key:"_dispatchLayout",value:function(){this._dispatch(t.EventType.LAYOUT)}},{key:"filter",value:function(e,i){this.isEnabled&&((!e||e&&0===e.length)&&(e=t.ALL_ITEMS),this._filter(e),this._shrink(),this._updateItemCount(),this.sort(i))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=this._getFilteredItems();e=l(e,t),this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(t){this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=T(t).map(function(t){return new B(t)});this._initItems(e),this._setTransitions(e),this.items=this.items.concat(e),this._updateItemsOrder(),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(t){this.isEnabled=!0,!1!==t&&this.update()}},{key:"remove",value:function(e){var i=this;if(e.length){var n=T(e),s=n.map(function(t){return i.getItemByElement(t)}).filter(function(t){return!!t}),o=function e(){i.element.removeEventListener(t.EventType.LAYOUT,e),i._disposeItems(s),n.forEach(function(t){t.parentNode.removeChild(t)}),i._dispatch(t.EventType.REMOVED,{collection:n})};this._toggleFilterClasses({visible:[],hidden:s}),this._shrink(s),this.sort(),this.items=this.items.filter(function(t){return!g(s,t)}),this._updateItemCount(),this.element.addEventListener(t.EventType.LAYOUT,o)}}},{key:"getItemByElement",value:function(t){for(var e=this.items.length-1;e>=0;e--)if(this.items[e].element===t)return this.items[e];return null}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(),this.items=null,this.options.sizer=null,this.element=null,this._transitions=null,this.isDestroyed=!0}}],[{key:"getSize",value:function(t,e){var i=window.getComputedStyle(t,null),n=o(t,"width",i),s=o(t,"height",i);if(e){var r=o(t,"marginLeft",i),l=o(t,"marginRight",i),a=o(t,"marginTop",i),u=o(t,"marginBottom",i);n+=r+l,s+=a+u}return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),t}();return j.ShuffleItem=B,j.ALL_ITEMS="all",j.FILTER_ATTRIBUTE_KEY="groups",j.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},j.Classes=A,j.options={group:j.ALL_ITEMS,speed:250,easing:"ease",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimeter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:C,throttleTime:300,staggerAmount:15,staggerAmountMax:250,useTransforms:!0},j.__Point=F,j.__sorter=l,j.__getColumnSpan=d,j.__getAvailablePositions=m,j.__getShortColumn=v,j}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.shuffle=e()}(this,function(){"use strict";function t(t,e){if(I)return I.call(t,e);for(var i=t.parentNode.querySelectorAll(e),n=0;n=e?i():r=setTimeout(i,e-t)),o}}function n(){}function s(t){return parseFloat(t)||0}function o(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=s(i[e]);return N||"width"!==e?N||"height"!==e||(n+=s(i.paddingTop)+s(i.paddingBottom)+s(i.borderTopWidth)+s(i.borderBottomWidth)):n+=s(i.paddingLeft)+s(i.paddingRight)+s(i.borderLeftWidth)+s(i.borderRightWidth),n}function r(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}function l(t,e){var i=L(R,e),n=[].slice.call(t),s=!1;return t.length?i.randomize?r(t):("function"==typeof i.by&&t.sort(function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0}),s?n:(i.reverse&&t.reverse(),t)):[]}function a(){return P+=1,q+P}function u(t){return!!H[t]&&(H[t].element.removeEventListener(q,H[t].listener),H[t]=null,!0)}function h(t,e){var i=a(),n=function(t){t.currentTarget===t.target&&(u(i),e(t))};return t.addEventListener(q,n),H[i]={element:t,listener:n},i}function f(t){return Math.max.apply(Math,t)}function c(t){return Math.min.apply(Math,t)}function d(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=i-e&&t[n]<=i+e)return n;return 0}function p(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=d(e.width,n,s,o),a=m(i,l,s),u=v(a,r),h=new A(Math.round(n*u),Math.round(a[u])),f=a[u]+e.height,c=0;c-1}}try{var _=new window.CustomEvent("test");if(_.preventDefault(),!0!==_.defaultPrevented)throw new Error("Could not prevent default")}catch(t){var E=function(t,e){var i,n;return e=e||{bubbles:!1,cancelable:!1,detail:void 0},i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n=i.preventDefault,i.preventDefault=function(){n.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(t){this.defaultPrevented=!0}},i};E.prototype=window.Event.prototype,window.CustomEvent=E}var S=Element.prototype,I=S.matches||S.matchesSelector||S.webkitMatchesSelector||S.mozMatchesSelector||S.msMatchesSelector||S.oMatchesSelector,b=t,k="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},T=function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t){function e(t){for(var e=[],i=0;i1&&void 0!==arguments[1]?arguments[1]:{};z(this,t),this.options=L(t.options,i),this.useSizer=!1,this.lastSort={},this.group=t.ALL_ITEMS,this.lastFilter=t.ALL_ITEMS,this.isEnabled=!0,this.isDestroyed=!1,this.isInitialized=!1,this._transitions=[],this.isTransitioning=!1,this._queue=[];var n=this._getElementOption(e);if(!n)throw new TypeError("Shuffle needs to be initialized with an element.");this.element=n,this.id="shuffle_"+U,U+=1,this._init(),this.isInitialized=!0}return M(t,[{key:"_init",value:function(){this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.options.sizer&&(this.useSizer=!0),this.element.classList.add(t.Classes.BASE),this._initItems(),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize);var e=window.getComputedStyle(this.element,null),i=t.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this._setTransitions(),this.element.style.transition="height "+this.options.speed+"ms "+this.options.easing}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(e,i){var n=this,s=[],o=[];return e===t.ALL_ITEMS?s=i:i.forEach(function(t){n._doesPassFilter(e,t.element)?s.push(t):o.push(t)}),{visible:s,hidden:o}}},{key:"_doesPassFilter",value:function(e,i){if("function"==typeof e)return e.call(i,i,this);var n=i.getAttribute("data-"+t.FILTER_ATTRIBUTE_KEY),s=this.options.delimeter?n.split(this.options.delimeter):JSON.parse(n);return Array.isArray(e)?this.options.filterMode!=t.filterMode.EXCLUSIVE?e.every(g(s)):e.some(g(s)):g(s,e)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach(function(t){t.show()}),i.forEach(function(t){t.hide()})}},{key:"_initItems",value:function(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items).forEach(function(t){t.init()})}},{key:"_disposeItems",value:function(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items).forEach(function(t){t.dispose()})}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"_setTransitions",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.items,e=this.options.speed,i=this.options.easing,n=this.options.useTransforms?"transform "+e+"ms "+i+", opacity "+e+"ms "+i:"top "+e+"ms "+i+", left "+e+"ms "+i+", opacity "+e+"ms "+i;t.forEach(function(t){t.element.style.transition=n})}},{key:"_getItems",value:function(){var t=this;return y(this.element.children).filter(function(e){return b(e,t.options.itemSelector)}).map(function(t){return new V(t)})}},{key:"_updateItemsOrder",value:function(){var t=this.element.children;this.items=l(this.items,{by:function(e){return Array.prototype.indexOf.call(t,e)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter(function(t){return t.isVisible})}},{key:"_getConcealedItems",value:function(){return this.items.filter(function(t){return!t.isVisible})}},{key:"_getColumnSize",value:function(e,i){var n=void 0;return n="function"==typeof this.options.columnWidth?this.options.columnWidth(e):this.useSizer?t.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?t.getSize(this.items[0].element,!0).width:e,0===n&&(n=e),n+i}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.useSizer?o(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t.getSize(this.element).width,i=this._getGutterSize(e),n=this._getColumnSize(e,i),s=(e+i)/n;Math.abs(Math.round(s)-s)1&&void 0!==arguments[1]?arguments[1]:{};return!this.isDestroyed&&(e.shuffle=this,!this.element.dispatchEvent(new CustomEvent(t,{bubbles:!0,cancelable:!1,detail:e})))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(e){var i=this,n=0;e.forEach(function(e){function s(){e.element.style.transitionDelay="",e.applyCss(V.Css.VISIBLE.after)}var o=e.point,r=e.scale,l=t.getSize(e.element,!0),a=i._getItemPosition(l);if(A.equals(o,a)&&r===V.Scale.VISIBLE)return e.applyCss(V.Css.VISIBLE.before),void s();e.point=a,e.scale=V.Scale.VISIBLE;var u=L(V.Css.VISIBLE.before);u.transitionDelay=i._getStaggerAmount(n)+"ms",i._queue.push({item:e,styles:u,callback:s}),n+=1})}},{key:"_getItemPosition",value:function(t){return p({itemSize:t,positions:this.positions,gridSize:this.colWidth,total:this.cols,threshold:this.options.columnThreshold,buffer:this.options.buffer})}},{key:"_shrink",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach(function(e){function n(){e.applyCss(V.Css.HIDDEN.after)}if(e.scale===V.Scale.HIDDEN)return e.applyCss(V.Css.HIDDEN.before),void n();e.scale=V.Scale.HIDDEN;var s=L(V.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1})}},{key:"_handleResize",value:function(){if(this.isEnabled&&!this.isDestroyed){t.getSize(this.element).width!==this.containerWidth&&this.update()}}},{key:"_getStylesForTransition",value:function(t){var e=t.item,i=t.styles;i.transitionDelay||(i.transitionDelay="0ms");var n=e.point.x,s=e.point.y;return this.options.useTransforms?i.transform="translate("+n+"px, "+s+"px) scale("+e.scale+")":(i.left=n+"px",i.top=s+"px"),i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=h(t,function(t){e(),i(null,t)});this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(e._getStylesForTransition(t)),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatchLayout()):this._dispatchLayout(),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0;var i=t.map(function(t){return e._getTransitionFunction(t)});D(i,this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(u),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(e){var i=this;if(e.length){var n=e.map(function(t){return t.item.element});t._skipTransitions(n,function(){e.forEach(function(t){t.item.applyCss(i._getStylesForTransition(t)),t.callback()})})}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatchLayout()}},{key:"_dispatchLayout",value:function(){this._dispatch(t.EventType.LAYOUT)}},{key:"filter",value:function(e,i){this.isEnabled&&((!e||e&&0===e.length)&&(e=t.ALL_ITEMS),this._filter(e),this._shrink(),this._updateItemCount(),this.sort(i))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=this._getFilteredItems();e=l(e,t),this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(t){this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=T(t).map(function(t){return new V(t)});this._initItems(e),this._setTransitions(e),this.items=this.items.concat(e),this._updateItemsOrder(),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(t){this.isEnabled=!0,!1!==t&&this.update()}},{key:"remove",value:function(e){var i=this;if(e.length){var n=T(e),s=n.map(function(t){return i.getItemByElement(t)}).filter(function(t){return!!t}),o=function e(){i.element.removeEventListener(t.EventType.LAYOUT,e),i._disposeItems(s),n.forEach(function(t){t.parentNode.removeChild(t)}),i._dispatch(t.EventType.REMOVED,{collection:n})};this._toggleFilterClasses({visible:[],hidden:s}),this._shrink(s),this.sort(),this.items=this.items.filter(function(t){return!g(s,t)}),this._updateItemCount(),this.element.addEventListener(t.EventType.LAYOUT,o)}}},{key:"getItemByElement",value:function(t){for(var e=this.items.length-1;e>=0;e--)if(this.items[e].element===t)return this.items[e];return null}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(),this.items=null,this.options.sizer=null,this.element=null,this._transitions=null,this.isDestroyed=!0}}],[{key:"getSize",value:function(t,e){var i=window.getComputedStyle(t,null),n=o(t,"width",i),s=o(t,"height",i);if(e){var r=o(t,"marginLeft",i),l=o(t,"marginRight",i),a=o(t,"marginTop",i),u=o(t,"marginBottom",i);n+=r+l,s+=a+u}return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map(function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}});e(),t[0].offsetWidth,t.forEach(function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay})}}]),t}();return j.ShuffleItem=V,j.ALL_ITEMS="all",j.FILTER_ATTRIBUTE_KEY="groups",j.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},j.Classes=F,j.filterMode={EXCLUSIVE:"exclusive",ADDITIVE:"additive"},j.options={group:j.ALL_ITEMS,speed:250,easing:"ease",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimeter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:C,throttleTime:300,staggerAmount:15,staggerAmountMax:250,useTransforms:!0,filterMode:j.filterMode.EXCLUSIVE},j.__Point=A,j.__sorter=l,j.__getColumnSpan=d,j.__getAvailablePositions=m,j.__getShortColumn=v,j}); //# sourceMappingURL=shuffle.min.js.map diff --git a/dist/shuffle.min.js.map b/dist/shuffle.min.js.map index f992e85..25a2331 100644 --- a/dist/shuffle.min.js.map +++ b/dist/shuffle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.min.js","sources":["../node_modules/matches-selector/index.js","../node_modules/xtend/immutable.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/shuffle.js","../node_modules/custom-event-polyfill/custom-event-polyfill.js","../node_modules/array-uniq/index.js","../src/point.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js"],"sourcesContent":["'use strict';\n\nvar proto = Element.prototype;\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}","module.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n var target = {}\n\n for (var i = 0; i < arguments.length; i++) {\n var source = arguments[i]\n\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n\n return target\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style,\n styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","import xtend from 'xtend';\n\n/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = xtend(defaults, options);\n const original = [].slice.call(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 0]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 0]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(\n Math.round(gridSize * shortColumnIndex),\n Math.round(setY[shortColumnIndex]));\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n","import 'custom-event-polyfill';\nimport matches from 'matches-selector';\nimport arrayUnique from 'array-uniq';\nimport xtend from 'xtend';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\nimport Point from './point';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn } from './layout';\nimport arrayMax from './array-max';\n\nfunction toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n}\n\nfunction arrayIncludes(array, obj) {\n if (arguments.length === 2) {\n return arrayIncludes(array)(obj);\n }\n\n return obj => array.indexOf(obj) > -1;\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle {\n\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n this.options = xtend(Shuffle.options, options);\n\n this.useSizer = false;\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n if (this.options.sizer) {\n this.useSizer = true;\n }\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems();\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this._setTransitions();\n this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {Function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string} [category] Category to filter by. If it's given, the last\n * category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|Function} category Category or function to filter by.\n * @param {Array.} items A collection of items to filter.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|Function} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n\n // Check each element's data-groups attribute against the given category.\n }\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimeter ?\n attr.split(this.options.delimeter) :\n JSON.parse(attr);\n\n if (Array.isArray(category)) {\n return category.some(arrayIncludes(keys));\n }\n\n return arrayIncludes(keys, category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {Array.} [items] Optionally specifiy at set to initialize.\n * @private\n */\n _initItems(items = this.items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @private\n */\n _disposeItems(items = this.items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of Shuffle.\n * @param {Array.} items Shuffle items to set transitions on.\n * @private\n */\n _setTransitions(items = this.items) {\n const speed = this.options.speed;\n const easing = this.options.easing;\n\n const str = this.options.useTransforms ?\n `transform ${speed}ms ${easing}, opacity ${speed}ms ${easing}` :\n `top ${speed}ms ${easing}, left ${speed}ms ${easing}, opacity ${speed}ms ${easing}`;\n\n items.forEach((item) => {\n item.element.style.transition = str;\n });\n }\n\n _getItems() {\n return toArray(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * When new elements are added to the shuffle container, update the array of\n * items because that is the order `_layout` calls them.\n */\n _updateItemsOrder() {\n const children = this.element.children;\n this.items = sorter(this.items, {\n by(element) {\n return Array.prototype.indexOf.call(children, element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.useSizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.useSizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * @return {boolean} Whether the event was prevented or not.\n */\n _dispatch(name, details = {}) {\n if (this.isDestroyed) {\n return false;\n }\n\n details.shuffle = this;\n return !this.element.dispatchEvent(new CustomEvent(name, {\n bubbles: true,\n cancelable: false,\n detail: details,\n }));\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {Array.} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n let count = 0;\n items.forEach((item) => {\n const currPos = item.point;\n const currScale = item.scale;\n const itemSize = Shuffle.getSize(item.element, true);\n const pos = this._getItemPosition(itemSize);\n\n function callback() {\n item.element.style.transitionDelay = '';\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(currPos, pos) && currScale === ShuffleItem.Scale.VISIBLE) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = pos;\n item.scale = ShuffleItem.Scale.VISIBLE;\n\n // Use xtend here to clone the object so that the `before` object isn't\n // modified when the transition delay is added.\n const styles = xtend(ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {Array.} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.scale === ShuffleItem.Scale.HIDDEN) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n\n const styles = xtend(ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n // Will need to check height in the future if it's layed out horizontaly\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // containerWidth hasn't changed, don't do anything\n if (containerWidth === this.containerWidth) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {Object} obj Transition options.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @private\n */\n _getStylesForTransition({ item, styles }) {\n if (!styles.transitionDelay) {\n styles.transitionDelay = '0ms';\n }\n\n const x = item.point.x;\n const y = item.point.y;\n\n if (this.options.useTransforms) {\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = x + 'px';\n styles.top = y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {Function} itemCallback Callback for the item.\n * @param {Function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {Function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(this._getStylesForTransition(opts));\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatchLayout();\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatchLayout();\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Array.} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Array.} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(this._getStylesForTransition(obj));\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatchLayout();\n }\n\n _dispatchLayout() {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|Function|Array.} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} opts the options object for the sorted plugin\n */\n sort(opts = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n let items = this._getFilteredItems();\n items = sorter(items, opts);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = opts;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} isOnlyLayout If true, column and gutter widths won't be\n * recalculated.\n */\n update(isOnlyLayout) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Array.} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Add transition to each item.\n this._setTransitions(items);\n\n // Update the list of items.\n this.items = this.items.concat(items);\n this._updateItemsOrder();\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout) {\n this.isEnabled = true;\n if (isUpdateLayout !== false) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items\n * @param {Array.} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle object\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this.element.removeEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !arrayIncludes(oldItems, item));\n this._updateItemCount();\n\n this.element.addEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or null if it's not found.\n */\n getItemByElement(element) {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (this.items[i].element === element) {\n return this.items[i];\n }\n }\n\n return null;\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems();\n\n // Null DOM references\n this.items = null;\n this.options.sizer = null;\n this.element = null;\n this._transitions = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins] Whether to include margins. Default is false.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Array.} elements DOM elements that won't be transitioned.\n * @param {Function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const style = element.style;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause reflow.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/**\n * @enum {string}\n */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'ease',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimeter\n // to ','.\n delimeter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 250,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n};\n\n// Expose for testing. Hack at your own risk.\nShuffle.__Point = Point;\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\n\nexport default Shuffle;\n","// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n","'use strict';\n\n// there's 3 implementations written in increasing order of efficiency\n\n// 1 - no Set type is defined\nfunction uniqNoSet(arr) {\n\tvar ret = [];\n\n\tfor (var i = 0; i < arr.length; i++) {\n\t\tif (ret.indexOf(arr[i]) === -1) {\n\t\t\tret.push(arr[i]);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n// 2 - a simple Set type is defined\nfunction uniqSet(arr) {\n\tvar seen = new Set();\n\treturn arr.filter(function (el) {\n\t\tif (!seen.has(el)) {\n\t\t\tseen.add(el);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n}\n\n// 3 - a standard Set type is defined and it has a forEach method\nfunction uniqSetWithForEach(arr) {\n\tvar ret = [];\n\n\t(new Set(arr)).forEach(function (el) {\n\t\tret.push(el);\n\t});\n\n\treturn ret;\n}\n\n// V8 currently has a broken implementation\n// https://github.com/joyent/node/issues/8449\nfunction doesForEachActuallyWork() {\n\tvar ret = false;\n\n\t(new Set([true])).forEach(function (el) {\n\t\tret = el;\n\t});\n\n\treturn ret === true;\n}\n\nif ('Set' in global) {\n\tif (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) {\n\t\tmodule.exports = uniqSetWithForEach;\n\t} else {\n\t\tmodule.exports = uniqSet;\n\t}\n} else {\n\tmodule.exports = uniqNoSet;\n}\n","import getNumber from './get-number';\n\nclass Point {\n\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n this.isVisible = true;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {},\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst width = window.getComputedStyle(e, null).width;\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n"],"names":["match","el","selector","vendor","call","nodes","parentNode","querySelectorAll","i","length","extend","target","arguments","source","key","hasOwnProperty","throttle","func","wait","timeoutID","last","Date","rtn","apply","ctx","args","this","delta","setTimeout","noop","getNumber","value","parseFloat","getNumberStyle","element","style","styles","window","getComputedStyle","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","randomize","array","n","Math","floor","random","temp","sorter","arr","options","opts","xtend","defaults","original","slice","revert","by","sort","a","b","valA","valB","undefined","reverse","uniqueId","eventName","count","cancelTransitionEnd","id","transitions","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","addEventListener","arrayMax","max","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","width","setY","shortColumnIndex","point","Point","setHeight","height","toArray","arrayLike","Array","prototype","arrayIncludes","obj","indexOf","ce","CustomEvent","preventDefault","defaultPrevented","Error","e","event","params","origPrevent","bubbles","cancelable","detail","document","createEvent","initCustomEvent","Object","defineProperty","get","Event","proto","Element","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","uniqNoSet","ret","uniqSet","seen","Set","filter","has","add","uniqSetWithForEach","forEach","global","module","fns","context","maybeDone","err","result","finished","results","pending","fn","x","y","ShuffleItem","isVisible","classList","remove","Classes","HIDDEN","VISIBLE","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","classes","className","keys","removeClasses","removeAttribute","body","documentElement","createElement","cssText","appendChild","removeChild","Shuffle","useSizer","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","items","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","containerCss","containerWidth","getSize","_validateStyles","_setColumns","initialSort","offsetWidth","_setTransitions","transition","speed","easing","resizeFunction","_handleResize","bind","throttleTime","option","querySelector","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_this","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","isArray","some","show","hide","init","dispose","visibleItems","_getFilteredItems","str","useTransforms","children","_this2","itemSelector","map","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","details","shuffle","dispatchEvent","transitionDelay","after","currPos","currScale","pos","_this3","_getItemPosition","equals","before","_getStaggerAmount","_getConcealedItems","_this4","update","transform","left","top","itemCallback","done","_this5","_getStylesForTransition","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatchLayout","callbacks","_this6","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","_this7","_dispatch","EventType","LAYOUT","sortObj","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","arrayUnique","concat","_updateItemsOrder","isUpdateLayout","oldItems","_this8","getItemByElement","handleLayout","_disposeItems","REMOVED","includeMargins","marginLeft","marginRight","marginTop","marginBottom","data","duration","transitionDuration","delay","__Point","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.min.js","sources":["../node_modules/matches-selector/index.js","../node_modules/xtend/immutable.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/shuffle.js","../node_modules/custom-event-polyfill/custom-event-polyfill.js","../node_modules/array-uniq/index.js","../src/point.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js"],"sourcesContent":["'use strict';\n\nvar proto = Element.prototype;\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}","module.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n var target = {}\n\n for (var i = 0; i < arguments.length; i++) {\n var source = arguments[i]\n\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n\n return target\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\nimport COMPUTED_SIZE_INCLUDES_PADDING from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(element, style,\n styles = window.getComputedStyle(element, null)) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'width') {\n value += getNumber(styles.paddingLeft) +\n getNumber(styles.paddingRight) +\n getNumber(styles.borderLeftWidth) +\n getNumber(styles.borderRightWidth);\n } else if (!COMPUTED_SIZE_INCLUDES_PADDING && style === 'height') {\n value += getNumber(styles.paddingTop) +\n getNumber(styles.paddingBottom) +\n getNumber(styles.borderTopWidth) +\n getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","import xtend from 'xtend';\n\n/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n// You can return `undefined` from the `by` function to revert to DOM order.\nexport default function sorter(arr, options) {\n const opts = xtend(defaults, options);\n const original = [].slice.call(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 0]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 0]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({ itemSize, positions, gridSize, total, threshold, buffer }) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(\n Math.round(gridSize * shortColumnIndex),\n Math.round(setY[shortColumnIndex]));\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n","import 'custom-event-polyfill';\nimport matches from 'matches-selector';\nimport arrayUnique from 'array-uniq';\nimport xtend from 'xtend';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\nimport Point from './point';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport { getItemPosition, getColumnSpan, getAvailablePositions, getShortColumn } from './layout';\nimport arrayMax from './array-max';\n\nfunction toArray(arrayLike) {\n return Array.prototype.slice.call(arrayLike);\n}\n\nfunction arrayIncludes(array, obj) {\n if (arguments.length === 2) {\n return arrayIncludes(array)(obj);\n }\n\n return obj => array.indexOf(obj) > -1;\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle {\n\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n this.options = xtend(Shuffle.options, options);\n\n this.useSizer = false;\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n if (this.options.sizer) {\n this.useSizer = true;\n }\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems();\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this._setTransitions();\n this.element.style.transition = 'height ' + this.options.speed + 'ms ' + this.options.easing;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {Function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle ?\n this.options.throttle(resizeFunction, this.options.throttleTime) :\n resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n\n // Check for an element\n } else if (option && option.nodeType && option.nodeType === 1) {\n return option;\n\n // Check for jQuery object\n } else if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string} [category] Category to filter by. If it's given, the last\n * category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|Function} category Category or function to filter by.\n * @param {Array.} items A collection of items to filter.\n * @return {!{visible: Array, hidden: Array}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|Function} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n\n // Check each element's data-groups attribute against the given category.\n }\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimeter ?\n attr.split(this.options.delimeter) :\n JSON.parse(attr);\n\n if (Array.isArray(category)) {\n if(this.options.filterMode!=Shuffle.filterMode.EXCLUSIVE){\n return category.every(arrayIncludes(keys));\n } else {\n return category.some(arrayIncludes(keys));\n }\n }\n\n return arrayIncludes(keys, category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {Array.} [items] Optionally specifiy at set to initialize.\n * @private\n */\n _initItems(items = this.items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @private\n */\n _disposeItems(items = this.items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of Shuffle.\n * @param {Array.} items Shuffle items to set transitions on.\n * @private\n */\n _setTransitions(items = this.items) {\n const speed = this.options.speed;\n const easing = this.options.easing;\n\n const str = this.options.useTransforms ?\n `transform ${speed}ms ${easing}, opacity ${speed}ms ${easing}` :\n `top ${speed}ms ${easing}, left ${speed}ms ${easing}, opacity ${speed}ms ${easing}`;\n\n items.forEach((item) => {\n item.element.style.transition = str;\n });\n }\n\n _getItems() {\n return toArray(this.element.children)\n .filter(el => matches(el, this.options.itemSelector))\n .map(el => new ShuffleItem(el));\n }\n\n /**\n * When new elements are added to the shuffle container, update the array of\n * items because that is the order `_layout` calls them.\n */\n _updateItemsOrder() {\n const children = this.element.children;\n this.items = sorter(this.items, {\n by(element) {\n return Array.prototype.indexOf.call(children, element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter(item => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter(item => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.useSizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.useSizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) <\n this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * @return {boolean} Whether the event was prevented or not.\n */\n _dispatch(name, details = {}) {\n if (this.isDestroyed) {\n return false;\n }\n\n details.shuffle = this;\n return !this.element.dispatchEvent(new CustomEvent(name, {\n bubbles: true,\n cancelable: false,\n detail: details,\n }));\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {Array.} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n let count = 0;\n items.forEach((item) => {\n const currPos = item.point;\n const currScale = item.scale;\n const itemSize = Shuffle.getSize(item.element, true);\n const pos = this._getItemPosition(itemSize);\n\n function callback() {\n item.element.style.transitionDelay = '';\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(currPos, pos) && currScale === ShuffleItem.Scale.VISIBLE) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = pos;\n item.scale = ShuffleItem.Scale.VISIBLE;\n\n // Use xtend here to clone the object so that the `before` object isn't\n // modified when the transition delay is added.\n const styles = xtend(ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {Array.} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.scale === ShuffleItem.Scale.HIDDEN) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n\n const styles = xtend(ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n // Will need to check height in the future if it's layed out horizontaly\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // containerWidth hasn't changed, don't do anything\n if (containerWidth === this.containerWidth) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {Object} obj Transition options.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @private\n */\n _getStylesForTransition({ item, styles }) {\n if (!styles.transitionDelay) {\n styles.transitionDelay = '0ms';\n }\n\n const x = item.point.x;\n const y = item.point.y;\n\n if (this.options.useTransforms) {\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = x + 'px';\n styles.top = y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {Function} itemCallback Callback for the item.\n * @param {Function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {Function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(this._getStylesForTransition(opts));\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatchLayout();\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatchLayout();\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Array.} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map(obj => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Array.} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map(obj => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(this._getStylesForTransition(obj));\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatchLayout();\n }\n\n _dispatchLayout() {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|Function|Array.} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {Object} [sortObj] A sort object which can sort the visible set\n */\n filter(category, sortObj) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortObj);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {Object} opts the options object for the sorted plugin\n */\n sort(opts = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n let items = this._getFilteredItems();\n items = sorter(items, opts);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = opts;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} isOnlyLayout If true, column and gutter widths won't be\n * recalculated.\n */\n update(isOnlyLayout) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Array.} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map(el => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Add transition to each item.\n this._setTransitions(items);\n\n // Update the list of items.\n this.items = this.items.concat(items);\n this._updateItemsOrder();\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout) {\n this.isEnabled = true;\n if (isUpdateLayout !== false) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items\n * @param {Array.} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle object\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map(element => this.getItemByElement(element))\n .filter(item => !!item);\n\n const handleLayout = () => {\n this.element.removeEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter(item => !arrayIncludes(oldItems, item));\n this._updateItemCount();\n\n this.element.addEventListener(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or null if it's not found.\n */\n getItemByElement(element) {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (this.items[i].element === element) {\n return this.items[i];\n }\n }\n\n return null;\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems();\n\n // Null DOM references\n this.items = null;\n this.options.sizer = null;\n this.element = null;\n this._transitions = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins] Whether to include margins. Default is false.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Array.} elements DOM elements that won't be transitioned.\n * @param {Function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const style = element.style;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause reflow.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/**\n * @enum {string}\n */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/**\n * @enum {string}\n */\nShuffle.filterMode = {\n EXCLUSIVE: 'exclusive',\n ADDITIVE: 'additive',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'ease',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimeter\n // to ','.\n delimeter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 250,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Filters elements with \"some\" when 'exclusive' and with every on 'additive'\n filterMode : Shuffle.filterMode.EXCLUSIVE,\n};\n\n// Expose for testing. Hack at your own risk.\nShuffle.__Point = Point;\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\n\nexport default Shuffle;\n","// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n","'use strict';\n\n// there's 3 implementations written in increasing order of efficiency\n\n// 1 - no Set type is defined\nfunction uniqNoSet(arr) {\n\tvar ret = [];\n\n\tfor (var i = 0; i < arr.length; i++) {\n\t\tif (ret.indexOf(arr[i]) === -1) {\n\t\t\tret.push(arr[i]);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n// 2 - a simple Set type is defined\nfunction uniqSet(arr) {\n\tvar seen = new Set();\n\treturn arr.filter(function (el) {\n\t\tif (!seen.has(el)) {\n\t\t\tseen.add(el);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n}\n\n// 3 - a standard Set type is defined and it has a forEach method\nfunction uniqSetWithForEach(arr) {\n\tvar ret = [];\n\n\t(new Set(arr)).forEach(function (el) {\n\t\tret.push(el);\n\t});\n\n\treturn ret;\n}\n\n// V8 currently has a broken implementation\n// https://github.com/joyent/node/issues/8449\nfunction doesForEachActuallyWork() {\n\tvar ret = false;\n\n\t(new Set([true])).forEach(function (el) {\n\t\tret = el;\n\t});\n\n\treturn ret === true;\n}\n\nif ('Set' in global) {\n\tif (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) {\n\t\tmodule.exports = uniqSetWithForEach;\n\t} else {\n\t\tmodule.exports = uniqSet;\n\t}\n} else {\n\tmodule.exports = uniqNoSet;\n}\n","import getNumber from './get-number';\n\nclass Point {\n\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n this.isVisible = true;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n 'will-change': 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {},\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","const element = document.body || document.documentElement;\nconst e = document.createElement('div');\ne.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\nelement.appendChild(e);\n\nconst width = window.getComputedStyle(e, null).width;\nconst ret = width === '10px';\n\nelement.removeChild(e);\n\nexport default ret;\n"],"names":["match","el","selector","vendor","call","nodes","parentNode","querySelectorAll","i","length","extend","target","arguments","source","key","hasOwnProperty","throttle","func","wait","timeoutID","last","Date","rtn","apply","ctx","args","this","delta","setTimeout","noop","getNumber","value","parseFloat","getNumberStyle","element","style","styles","window","getComputedStyle","COMPUTED_SIZE_INCLUDES_PADDING","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","randomize","array","n","Math","floor","random","temp","sorter","arr","options","opts","xtend","defaults","original","slice","revert","by","sort","a","b","valA","valB","undefined","reverse","uniqueId","eventName","count","cancelTransitionEnd","id","transitions","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","addEventListener","arrayMax","max","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","width","setY","shortColumnIndex","point","Point","setHeight","height","toArray","arrayLike","Array","prototype","arrayIncludes","obj","indexOf","ce","CustomEvent","preventDefault","defaultPrevented","Error","e","event","params","origPrevent","bubbles","cancelable","detail","document","createEvent","initCustomEvent","Object","defineProperty","get","Event","proto","Element","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","uniqNoSet","ret","uniqSet","seen","Set","filter","has","add","uniqSetWithForEach","forEach","global","module","fns","context","maybeDone","err","result","finished","results","pending","fn","x","y","ShuffleItem","isVisible","classList","remove","Classes","HIDDEN","VISIBLE","addClasses","SHUFFLE_ITEM","applyCss","Css","INITIAL","scale","Scale","classes","className","keys","removeClasses","removeAttribute","body","documentElement","createElement","cssText","appendChild","removeChild","Shuffle","useSizer","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","items","_getItems","sizer","BASE","_initItems","_onResize","_getResizeFunction","containerCss","containerWidth","getSize","_validateStyles","_setColumns","initialSort","offsetWidth","_setTransitions","transition","speed","easing","resizeFunction","_handleResize","bind","throttleTime","option","querySelector","nodeType","jquery","position","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_this","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","delimeter","split","JSON","parse","isArray","filterMode","EXCLUSIVE","every","some","show","hide","init","dispose","visibleItems","_getFilteredItems","str","useTransforms","children","_this2","itemSelector","map","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","details","shuffle","dispatchEvent","transitionDelay","after","currPos","currScale","pos","_this3","_getItemPosition","equals","before","_getStaggerAmount","_getConcealedItems","_this4","update","transform","left","top","itemCallback","done","_this5","_getStylesForTransition","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatchLayout","callbacks","_this6","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","_this7","_dispatch","EventType","LAYOUT","sortObj","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","arrayUnique","concat","_updateItemsOrder","isUpdateLayout","oldItems","_this8","getItemByElement","handleLayout","_disposeItems","REMOVED","includeMargins","marginLeft","marginRight","marginTop","marginBottom","data","duration","transitionDuration","delay","__Point","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn"],"mappings":"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"} \ No newline at end of file diff --git a/src/shuffle.js b/src/shuffle.js index d019975..e3d21a7 100644 --- a/src/shuffle.js +++ b/src/shuffle.js @@ -239,6 +239,9 @@ class Shuffle { JSON.parse(attr); if (Array.isArray(category)) { + if (this.options.filterMode !== Shuffle.filterMode.EXCLUSIVE) { + return category.every(arrayIncludes(keys)); + } return category.some(arrayIncludes(keys)); } @@ -1029,6 +1032,14 @@ Shuffle.EventType = { /** @enum {string} */ Shuffle.Classes = Classes; +/** + * @enum {string} + */ +Shuffle.filterMode = { + EXCLUSIVE: 'exclusive', + ADDITIVE: 'additive', +}; + // Overrideable options Shuffle.options = { // Initial filter group. @@ -1086,6 +1097,9 @@ Shuffle.options = { // Whether to use transforms or absolute positioning. useTransforms: true, + + // Filters elements with "some" when 'exclusive' and with every on 'additive' + filterMode: Shuffle.filterMode.EXCLUSIVE, }; // Expose for testing. Hack at your own risk.