%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);