%PDF- %PDF-
| Direktori : /home/tjamichg/intranet.tjamich.gob.mx/intranet/common/vendors/isotope/js/ |
| Current File : //home/tjamichg/intranet.tjamich.gob.mx/intranet/common/vendors/isotope/js/isotope.js |
/*!
* Isotope v2.0.0
* Filter & sort magical layouts
* http://isotope.metafizzy.co
*/
(function (window) {
'use strict';
// -------------------------- vars -------------------------- //
var jQuery = window.jQuery;
// -------------------------- helpers -------------------------- //
// extend objects
function extend(a, b) {
for (var prop in b) {
a[ prop ] = b[ prop ];
}
return a;
}
var trim = String.prototype.trim ?
function (str) {
return str.trim();
} :
function (str) {
return str.replace(/^\s+|\s+$/g, '');
};
var docElem = document.documentElement;
var getText = docElem.textContent ?
function (elem) {
return elem.textContent;
} :
function (elem) {
return elem.innerText;
};
var objToString = Object.prototype.toString;
function isArray(obj) {
return objToString.call(obj) === '[object Array]';
}
// index of helper cause IE8
var indexOf = Array.prototype.indexOf ? function (ary, obj) {
return ary.indexOf(obj);
} : function (ary, obj) {
for (var i = 0, len = ary.length; i < len; i++) {
if (ary[i] === obj) {
return i;
}
}
return -1;
};
// turn element or nodeList into an array
function makeArray(obj) {
var ary = [];
if (isArray(obj)) {
// use object if already an array
ary = obj;
} else if (obj && typeof obj.length === 'number') {
// convert nodeList to array
for (var i = 0, len = obj.length; i < len; i++) {
ary.push(obj[i]);
}
} else {
// array of single index
ary.push(obj);
}
return ary;
}
function removeFrom(obj, ary) {
var index = indexOf(ary, obj);
if (index !== -1) {
ary.splice(index, 1);
}
}
// -------------------------- isotopeDefinition -------------------------- //
// used for AMD definition and requires
function isotopeDefinition(Outlayer, getSize, matchesSelector, Item, LayoutMode) {
// create an Outlayer layout class
var Isotope = Outlayer.create('isotope', {
layoutMode: "masonry",
isJQueryFiltering: true,
sortAscending: true
});
Isotope.Item = Item;
Isotope.LayoutMode = LayoutMode;
Isotope.prototype._create = function () {
this.itemGUID = 0;
// functions that sort items
this._sorters = {};
this._getSorters();
// call super
Outlayer.prototype._create.call(this);
// create layout modes
this.modes = {};
// start filteredItems with all items
this.filteredItems = this.items;
// keep of track of sortBys
this.sortHistory = [ 'original-order' ];
// create from registered layout modes
for (var name in LayoutMode.modes) {
this._initLayoutMode(name);
}
};
Isotope.prototype.reloadItems = function () {
// reset item ID counter
this.itemGUID = 0;
// call super
Outlayer.prototype.reloadItems.call(this);
};
Isotope.prototype._itemize = function () {
var items = Outlayer.prototype._itemize.apply(this, arguments);
// assign ID for original-order
for (var i = 0, len = items.length; i < len; i++) {
var item = items[i];
item.id = this.itemGUID++;
}
this._updateItemsSortData(items);
return items;
};
// -------------------------- layout -------------------------- //
Isotope.prototype._initLayoutMode = function (name) {
var Mode = LayoutMode.modes[ name ];
// set mode options
// HACK extend initial options, back-fill in default options
var initialOpts = this.options[ name ] || {};
this.options[ name ] = Mode.options ?
extend(Mode.options, initialOpts) : initialOpts;
// init layout mode instance
this.modes[ name ] = new Mode(this);
};
Isotope.prototype.layout = function () {
// if first time doing layout, do all magic
if (!this._isLayoutInited && this.options.isInitLayout) {
this.arrange();
return;
}
this._layout();
};
// private method to be used in layout() & magic()
Isotope.prototype._layout = function () {
// don't animate first layout
var isInstant = this._getIsInstant();
// layout flow
this._resetLayout();
this._manageStamps();
this.layoutItems(this.filteredItems, isInstant);
// flag for initalized
this._isLayoutInited = true;
};
// filter + sort + layout
Isotope.prototype.arrange = function (opts) {
// set any options pass
this.option(opts);
this._getIsInstant();
// filter, sort, and layout
this.filteredItems = this._filter(this.items);
this._sort();
this._layout();
};
// alias to _init for main plugin method
Isotope.prototype._init = Isotope.prototype.arrange;
// HACK
// Don't animate/transition first layout
// Or don't animate/transition other layouts
Isotope.prototype._getIsInstant = function () {
var isInstant = this.options.isLayoutInstant !== undefined ?
this.options.isLayoutInstant : !this._isLayoutInited;
this._isInstant = isInstant;
return isInstant;
};
// -------------------------- filter -------------------------- //
Isotope.prototype._filter = function (items) {
var filter = this.options.filter;
filter = filter || '*';
var matches = [];
var hiddenMatched = [];
var visibleUnmatched = [];
var test = this._getFilterTest(filter);
// test each item
for (var i = 0, len = items.length; i < len; i++) {
var item = items[i];
if (item.isIgnored) {
continue;
}
// add item to either matched or unmatched group
var isMatched = test(item);
// item.isFilterMatched = isMatched;
// add to matches if its a match
if (isMatched) {
matches.push(item);
}
// add to additional group if item needs to be hidden or revealed
if (isMatched && item.isHidden) {
hiddenMatched.push(item);
} else if (!isMatched && !item.isHidden) {
visibleUnmatched.push(item);
}
}
var _this = this;
function hideReveal() {
_this.reveal(hiddenMatched);
_this.hide(visibleUnmatched);
}
if (this._isInstant) {
this._noTransition(hideReveal);
} else {
hideReveal();
}
return matches;
};
// get a jQuery, function, or a matchesSelector test given the filter
Isotope.prototype._getFilterTest = function (filter) {
if (jQuery && this.options.isJQueryFiltering) {
// use jQuery
return function (item) {
return jQuery(item.element).is(filter);
};
}
if (typeof filter === 'function') {
// use filter as function
return function (item) {
return filter(item.element);
};
}
// default, use filter as selector string
return function (item) {
return matchesSelector(item.element, filter);
};
};
// -------------------------- sorting -------------------------- //
/**
* @params {Array} elems
* @public
*/
Isotope.prototype.updateSortData = function (elems) {
this._getSorters();
// update item sort data
// default to all items if none are passed in
elems = makeArray(elems);
var items = this.getItems(elems);
// if no items found, update all items
items = items.length ? items : this.items;
this._updateItemsSortData(items);
};
Isotope.prototype._getSorters = function () {
var getSortData = this.options.getSortData;
for (var key in getSortData) {
var sorter = getSortData[ key ];
this._sorters[ key ] = mungeSorter(sorter);
}
};
/**
* @params {Array} items - of Isotope.Items
* @private
*/
Isotope.prototype._updateItemsSortData = function (items) {
for (var i = 0, len = items.length; i < len; i++) {
var item = items[i];
item.updateSortData();
}
};
// ----- munge sorter ----- //
// encapsulate this, as we just need mungeSorter
// other functions in here are just for munging
var mungeSorter = (function () {
// add a magic layer to sorters for convienent shorthands
// `.foo-bar` will use the text of .foo-bar querySelector
// `[foo-bar]` will use attribute
// you can also add parser
// `.foo-bar parseInt` will parse that as a number
function mungeSorter(sorter) {
// if not a string, return function or whatever it is
if (typeof sorter !== 'string') {
return sorter;
}
// parse the sorter string
var args = trim(sorter).split(' ');
var query = args[0];
// check if query looks like [an-attribute]
var attrMatch = query.match(/^\[(.+)\]$/);
var attr = attrMatch && attrMatch[1];
var getValue = getValueGetter(attr, query);
// use second argument as a parser
var parser = Isotope.sortDataParsers[ args[1] ];
// parse the value, if there was a parser
sorter = parser ? function (elem) {
return elem && parser(getValue(elem));
} :
// otherwise just return value
function (elem) {
return elem && getValue(elem);
};
return sorter;
}
// get an attribute getter, or get text of the querySelector
function getValueGetter(attr, query) {
var getValue;
// if query looks like [foo-bar], get attribute
if (attr) {
getValue = function (elem) {
return elem.getAttribute(attr);
};
} else {
// otherwise, assume its a querySelector, and get its text
getValue = function (elem) {
var child = elem.querySelector(query);
return child && getText(child);
};
}
return getValue;
}
return mungeSorter;
})();
// parsers used in getSortData shortcut strings
Isotope.sortDataParsers = {
'parseInt': function (val) {
return parseInt(val, 10);
},
'parseFloat': function (val) {
return parseFloat(val);
}
};
// ----- sort method ----- //
// sort filteredItem order
Isotope.prototype._sort = function () {
var sortByOpt = this.options.sortBy;
if (!sortByOpt) {
return;
}
// concat all sortBy and sortHistory
var sortBys = [].concat.apply(sortByOpt, this.sortHistory);
// sort magic
var itemSorter = getItemSorter(sortBys, this.options.sortAscending);
this.filteredItems.sort(itemSorter);
// keep track of sortBy History
if (sortByOpt !== this.sortHistory[0]) {
// add to front, oldest goes in last
this.sortHistory.unshift(sortByOpt);
}
};
// returns a function used for sorting
function getItemSorter(sortBys, sortAsc) {
return function sorter(itemA, itemB) {
// cycle through all sortKeys
for (var i = 0, len = sortBys.length; i < len; i++) {
var sortBy = sortBys[i];
var a = itemA.sortData[ sortBy ];
var b = itemB.sortData[ sortBy ];
if (a > b || a < b) {
// if sortAsc is an object, use the value given the sortBy key
var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
var direction = isAscending ? 1 : -1;
return ( a > b ? 1 : -1 ) * direction;
}
}
return 0;
};
}
// -------------------------- methods -------------------------- //
// get layout mode
Isotope.prototype._mode = function () {
var layoutMode = this.options.layoutMode;
var mode = this.modes[ layoutMode ];
if (!mode) {
// TODO console.error
throw new Error('No layout mode: ' + layoutMode);
}
// HACK sync mode's options
// any options set after init for layout mode need to be synced
mode.options = this.options[ layoutMode ];
return mode;
};
Isotope.prototype._resetLayout = function () {
// trigger original reset layout
Outlayer.prototype._resetLayout.call(this);
this._mode()._resetLayout();
};
Isotope.prototype._getItemLayoutPosition = function (item) {
return this._mode()._getItemLayoutPosition(item);
};
Isotope.prototype._manageStamp = function (stamp) {
this._mode()._manageStamp(stamp);
};
Isotope.prototype._getContainerSize = function () {
return this._mode()._getContainerSize();
};
Isotope.prototype.needsResizeLayout = function () {
return this._mode().needsResizeLayout();
};
// -------------------------- adding & removing -------------------------- //
// HEADS UP overwrites default Outlayer appended
Isotope.prototype.appended = function (elems) {
var items = this.addItems(elems);
if (!items.length) {
return;
}
var filteredItems = this._filterRevealAdded(items);
// add to filteredItems
this.filteredItems = this.filteredItems.concat(filteredItems);
};
// HEADS UP overwrites default Outlayer prepended
Isotope.prototype.prepended = function (elems) {
var items = this._itemize(elems);
if (!items.length) {
return;
}
// add items to beginning of collection
var previousItems = this.items.slice(0);
this.items = items.concat(previousItems);
// start new layout
this._resetLayout();
this._manageStamps();
// layout new stuff without transition
var filteredItems = this._filterRevealAdded(items);
// layout previous items
this.layoutItems(previousItems);
// add to filteredItems
this.filteredItems = filteredItems.concat(this.filteredItems);
};
Isotope.prototype._filterRevealAdded = function (items) {
var filteredItems = this._noTransition(function () {
return this._filter(items);
});
// layout and reveal just the new items
this.layoutItems(filteredItems, true);
this.reveal(filteredItems);
return items;
};
/**
* Filter, sort, and layout newly-appended item elements
* @param {Array or NodeList or Element} elems
*/
Isotope.prototype.insert = function (elems) {
var items = this.addItems(elems);
if (!items.length) {
return;
}
// append item elements
var i, item;
var len = items.length;
for (i = 0; i < len; i++) {
item = items[i];
this.element.appendChild(item.element);
}
// filter new stuff
/*
// this way adds hides new filtered items with NO transition
// so user can't see if new hidden items have been inserted
var filteredInsertItems;
this._noTransition( function() {
filteredInsertItems = this._filter( items );
// hide all new items
this.hide( filteredInsertItems );
});
// */
// this way hides new filtered items with transition
// so user at least sees that something has been added
var filteredInsertItems = this._filter(items);
// hide all newitems
this._noTransition(function () {
this.hide(filteredInsertItems);
});
// */
// set flag
for (i = 0; i < len; i++) {
items[i].isLayoutInstant = true;
}
this.arrange();
// reset flag
for (i = 0; i < len; i++) {
delete items[i].isLayoutInstant;
}
this.reveal(filteredInsertItems);
};
var _remove = Isotope.prototype.remove;
Isotope.prototype.remove = function (elems) {
elems = makeArray(elems);
var removeItems = this.getItems(elems);
// do regular thing
_remove.call(this, elems);
// bail if no items to remove
if (!removeItems || !removeItems.length) {
return;
}
// remove elems from filteredItems
for (var i = 0, len = removeItems.length; i < len; i++) {
var item = removeItems[i];
// remove item from collection
removeFrom(item, this.filteredItems);
}
};
/**
* trigger fn without transition
* kind of hacky to have this in the first place
* @param {Function} fn
* @returns ret
* @private
*/
Isotope.prototype._noTransition = function (fn) {
// save transitionDuration before disabling
var transitionDuration = this.options.transitionDuration;
// disable transition
this.options.transitionDuration = 0;
// do it
var returnValue = fn.call(this);
// re-enable transition for reveal
this.options.transitionDuration = transitionDuration;
return returnValue;
};
// ----- ----- //
return Isotope;
}
// -------------------------- transport -------------------------- //
if (typeof define === 'function' && define.amd) {
// AMD
define([
'outlayer/outlayer',
'get-size/get-size',
'matches-selector/matches-selector',
'./item',
'./layout-mode',
// include default layout modes
'./layout-modes/masonry',
'./layout-modes/fit-rows',
'./layout-modes/vertical'
],
isotopeDefinition);
} else {
// browser global
window.Isotope = isotopeDefinition(
window.Outlayer,
window.getSize,
window.matchesSelector,
window.Isotope.Item,
window.Isotope.LayoutMode
);
}
})(window);