1/** 2 * Mosaic Flow 3 * 4 * Pinterest like responsive image grid that doesnt suck 5 * 6 * @requires jQuery 7 * @author Artem Sapegin 8 * @copyright 2012 Artem Sapegin, http://sapegin.me 9 * @license MIT 10 */ 11(function(factory){if(typeof define==='function'&&define.amd){define(['jquery'],factory)}else{factory(jQuery)}}(function($){'use strict';var cnt=0;$.fn.mosaicflow=function(options){var args=Array.prototype.slice.call(arguments,0);return this.each(function(){var elm=$(this);var data=elm.data('mosaicflow');if(!data){options=$.extend({},$.fn.mosaicflow.defaults,options,dataToOptions(elm));data=new Mosaicflow(elm,options);elm.data('mosaicflow',data)}else if(typeof options==='string'){data[options](args[1])}})};$.fn.mosaicflow.defaults={itemSelector:'> *',columnClass:'mosaicflow__column',minItemWidth:240,minColumns:2,itemHeightCalculation:'auto',threshold:40,fallbackHTML:!1};function Mosaicflow(container,options){this.container=container;this.options=options;this.container.trigger('mosaicflow-start');this.init();this.container.trigger('mosaicflow-ready')} 12Mosaicflow.prototype={init:function(){this.__uid=cnt++;this.__uidItemCounter=0;this.items=this.container.find(this.options.itemSelector);this.columns=$([]);this.columnsHeights=[];this.itemsHeights={};this.tempContainer=$('<'+(this.options.fallbackHTML?'div':'li')+'>',{css:{'visibility':'hidden','width':'100%'},role:this.options.fallbackHTML?'listitem':null,});this.workOnTemp=!1;this.autoCalculation=this.options.itemHeightCalculation==='auto';this.container.append(this.tempContainer);var that=this;this.items.each(function(){var elm=$(this);var id=elm.attr('id');if(!id){id=that.generateUniqueId();elm.attr('id',id)}});this.container.css('visibility','hidden');if(this.autoCalculation){$(window).on('load',$.proxy(this.refill,this))}else{this.refill()} 13$(window).resize($.proxy(this.refill,this))},refill:function(){this.container.trigger('mosaicflow-fill');this.numberOfColumns=Math.floor(this.container.width()/this.options.minItemWidth);if(this.numberOfColumns<this.options.minColumns) 14this.numberOfColumns=this.options.minColumns;var needToRefill=this.ensureColumns();if(needToRefill){this.fillColumns();if(this.columns.filter(':visible').length>0){this.columns.filter(':hidden').remove()}} 15this.container.css('visibility','visible');this.container.trigger('mosaicflow-filled')},ensureColumns:function(){var createdCnt=this.columns.filter(':visible').length;var calculatedCnt=this.numberOfColumns;this.workingContainer=createdCnt===0?this.tempContainer:this.container;if(calculatedCnt>createdCnt){var neededCnt=calculatedCnt-createdCnt;for(var columnIdx=0;columnIdx<neededCnt;columnIdx++){var column=$('<'+(this.options.fallbackHTML?'div':'li')+'>',{class:this.options.columnClass,role:this.options.fallbackHTML?'listitem':null});this.workingContainer.append(column)}}else if(calculatedCnt<createdCnt){var lastColumn=createdCnt;while(calculatedCnt<=lastColumn){this.columns.eq(lastColumn).hide();lastColumn--} 16var diff=createdCnt-calculatedCnt;this.columnsHeights.splice(this.columnsHeights.length-diff,diff)} 17if(calculatedCnt!==createdCnt){this.columns=this.workingContainer.find('.'+this.options.columnClass);this.columns.css('width',(100/calculatedCnt)+'%');return!0} 18return!1},fillColumns:function(){var columnsCnt=this.numberOfColumns;var itemsCnt=this.items.length;for(var columnIdx=0;columnIdx<columnsCnt;columnIdx++){var column=this.columns.eq(columnIdx);this.columnsHeights[columnIdx]=0;for(var itemIdx=columnIdx;itemIdx<itemsCnt;itemIdx+=columnsCnt){var item=this.items.eq(itemIdx);var height=0;column.append(item);if(this.autoCalculation){height=item.outerHeight()}else{height=parseInt(item.find('img').attr('height'),10)} 19this.itemsHeights[item.attr('id')]=height;this.columnsHeights[columnIdx]+=height}} 20this.levelBottomEdge(this.itemsHeights,this.columnsHeights);if(this.workingContainer===this.tempContainer){this.container.append(this.tempContainer.children())} 21this.container.trigger('mosaicflow-layout')},levelBottomEdge:function(itemsHeights,columnsHeights){while(!0){var lowestColumn=$.inArray(Math.min.apply(null,columnsHeights),columnsHeights);var highestColumn=$.inArray(Math.max.apply(null,columnsHeights),columnsHeights);if(lowestColumn===highestColumn)return;
21var lastInHighestColumn=this.columns.eq(highestColumn).children().last();var lastInHighestColumnHeight=itemsHeights[lastInHighestColumn.attr('id')];var lowestHeight=columnsHeights[lowestColumn];var highestHeight=columnsHeights[highestColumn];var newLowestHeight=lowestHeight+lastInHighestColumnHeight;if(newLowestHeight>=highestHeight)return;if(highestHeight-newLowestHeight<this.options.threshold)return;this.columns.eq(lowestColumn).append(lastInHighestColumn);columnsHeights[highestColumn]-=lastInHighestColumnHeight;columnsHeights[lowestColumn]+=lastInHighestColumnHeight}},add:function(elm){this.container.trigger('mosaicflow-item-add',[elm]);var lowestColumn=$.inArray(Math.min.apply(null,this.columnsHeights),this.columnsHeights);var height=0;if(this.autoCalculation){elm.css({position:'static',visibility:'hidden',display:'block'}).appendTo(this.columns.eq(lowestColumn));height=elm.outerHeight();var inlineImages=elm.find('img');if(inlineImages.length!==0){inlineImages.each(function(){var image=$(this);var imageSizes=getImageSizes(image);var actualHeight=(image.width()*imageSizes.height)/imageSizes.width;height+=actualHeight})} 22elm.detach().css({position:'static',visibility:'visible'})}else{height=parseInt(elm.find('img').attr('height'),10)} 23if(!elm.attr('id')){elm.attr('id',this.generateUniqueId())} 24var itemsArr=this.items.toArray();itemsArr.push(elm);this.items=$(itemsArr);this.itemsHeights[elm.attr('id')]=height;this.columnsHeights[lowestColumn]+=height;this.columns.eq(lowestColumn).append(elm);this.levelBottomEdge(this.itemsHeights,this.columnsHeights);this.container.trigger('mosaicflow-layout');this.container.trigger('mosaicflow-item-added',[elm])},remove:function(elm){this.container.trigger('mosaicflow-item-remove',[elm]);var column=elm.parents('.'+this.options.columnClass);this.columnsHeights[column.index()-1]-=this.itemsHeights[elm.attr('id')];elm.detach();this.items=this.items.not(elm);this.levelBottomEdge(this.itemsHeights,this.columnsHeights);this.container.trigger('mosaicflow-layout');this.container.trigger('mosaicflow-item-removed',[elm])},empty:function(){var columnsCnt=this.numberOfColumns;this.items=$([]);this.itemsHeights={};for(var columnIdx=0;columnIdx<columnsCnt;columnIdx++){var column=this.columns.eq(columnIdx);this.columnsHeights[columnIdx]=0;column.empty()} 25this.container.trigger('mosaicflow-layout')},recomputeHeights:function(){function computeHeight(idx,item){item=$(item);var height=0;if(that.autoCalculation){height=item.outerHeight()}else{height=parseInt(item.find('img').attr('height'),10)} 26that.itemsHeights[item.attr('id')]=height;that.columnsHeights[columnIdx]+=height} 27var that=this;var columnsCnt=this.numberOfColumns;for(var columnIdx=0;columnIdx<columnsCnt;columnIdx++){var column=this.columns.eq(columnIdx);this.columnsHeights[columnIdx]=0;column.children().each(computeHeight)}},generateUniqueId:function(){this.__uidItemCounter++;return'mosaic-'+this.__uid+'-itemid-'+this.__uidItemCounter}};function dataToOptions(elem){function upper(m,l){return l.toUpper()} 28var options={};var data=elem.data();for(var key in data){options[key.replace(/-(\w)/g,upper)]=data[key]} 29return options} 30function getImageSizes(image){var sizes={};sizes.height=parseInt(image.attr('height'),10);sizes.width=parseInt(image.attr('width'),10);if(sizes.height===0||sizes.width===0){var utilImage=new Image();utilImage.src=image.attr('src');sizes.width=utilImage.width;sizes.height=utilImage.height} 31return sizes} 32$(function(){$('.mosaicflow').mosaicflow()})}))
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.