diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..9c793ac --- /dev/null +++ b/.babelrc @@ -0,0 +1,18 @@ +{ + "moduleId": "MosaicFlow", + + "presets": [ + ["es2015", { + "loose": true + }] + ], + + "plugins": [ + ["transform-es2015-modules-umd", { + "loose": true, + "globals": { + "jquery": "jQuery" + } + }] + ] +} diff --git a/.jshintrc b/.jshintrc index 4e2e573..d96593a 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,5 +1,6 @@ { "browser": true, + "esnext": true, "jquery": true, "white": false, "smarttabs": true, @@ -10,6 +11,8 @@ "undef": true, "camelcase": true, "globals": { - "Modernizr": true + "Modernizr": true, + "define": true, + "require": true } } diff --git a/Gruntfile.coffee b/Gruntfile.coffee index c99857e..3cd18c9 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -5,23 +5,24 @@ module.exports = (grunt) -> require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks) - source = "jquery.mosaicflow.js" + es6 = "jquery.mosaicflow.m.js" + umd = "jquery.mosaicflow.js" grunt.initConfig cmpnt: grunt.file.readJSON('bower.json'), jshint: options: jshintrc: ".jshintrc" - files: [source] + files: [es6] jscs: - main: [source] + main: [es6] uglify: options: banner: "/*! jQuery Mosaic Flow v<%= cmpnt.version %> by Artem Sapegin - " + "http://sapegin.github.io/jquery.mosaicflow/ - Licensed MIT */\n" main: files: - "jquery.mosaicflow.min.js": source + "jquery.mosaicflow.min.js": umd grunt.registerTask "default", ["jshint", "jscs", "uglify"] grunt.registerTask "test", ["jshint", "jscs"] diff --git a/bower.json b/bower.json index 7a3fb5d..1475884 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,9 @@ { "name": "jquery.mosaicflow", "version": "0.2.5", - "main": ["./jquery.mosaicflow.js"], + "main": "./jquery.mosaicflow.js", + "module": "jquery.mosaicflow.m.js", + "jsnext:main": "jquery.mosaicflow.m.js", "dependencies": { "jquery": ">=1.7" } diff --git a/jquery.mosaicflow.js b/jquery.mosaicflow.js index 05c4c91..7d1f2f5 100644 --- a/jquery.mosaicflow.js +++ b/jquery.mosaicflow.js @@ -1,46 +1,53 @@ -/** - * Mosaic Flow - * - * Pinterest like responsive image grid that doesn’t sucks - * - * @requires jQuery - * @author Artem Sapegin - * @copyright 2012 Artem Sapegin, http://sapegin.me - * @license MIT - */ - -/*jshint browser:true, jquery:true, white:false, smarttabs:true */ -/*global jQuery:false, define:false*/ -(function(factory) { // Try to register as an anonymous AMD module - if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define('MosaicFlow', ['jquery'], factory); + } else if (typeof exports !== "undefined") { + factory(require('jquery')); + } else { + var mod = { + exports: {} + }; + factory(global.jQuery); + global.MosaicFlow = mod.exports; } - else { - factory(jQuery); - } -}(function($) { +})(this, function (_jquery) { 'use strict'; - var cnt = 0; - $.fn.mosaicflow = function(options) { + var _jquery2 = _interopRequireDefault(_jquery); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + _jquery2.default.fn.mosaicflow = function (options) { var args = Array.prototype.slice.call(arguments, 0); - return this.each(function() { - var elm = $(this); + return this.each(function () { + var elm = (0, _jquery2.default)(this); var data = elm.data('mosaicflow'); if (!data) { - options = $.extend({}, $.fn.mosaicflow.defaults, options, dataToOptions(elm)); + options = _jquery2.default.extend({}, _jquery2.default.fn.mosaicflow.defaults, options, dataToOptions(elm)); data = new Mosaicflow(elm, options); elm.data('mosaicflow', data); - } - else if (typeof options === 'string') { + } else if (typeof options === 'string') { data[options](args[1]); } }); - }; - - $.fn.mosaicflow.defaults = { + }; /** + * Mosaic Flow + * + * Pinterest like responsive image grid that doesn’t sucks + * + * @requires jQuery + * @author Artem Sapegin + * @copyright 2012 Artem Sapegin, http://sapegin.me + * @license MIT + */ + + _jquery2.default.fn.mosaicflow.defaults = { itemSelector: '> *', columnClass: 'mosaicflow__column', minItemWidth: 240, @@ -49,6 +56,8 @@ threshold: 40 }; + var cnt = 0; + function Mosaicflow(container, options) { this.container = container; this.options = options; @@ -59,22 +68,22 @@ } Mosaicflow.prototype = { - init: function() { + init: function init() { this.__uid = cnt++; this.__uidItemCounter = 0; this.items = this.container.find(this.options.itemSelector); - this.columns = $([]); + this.columns = (0, _jquery2.default)([]); this.columnsHeights = []; this.itemsHeights = {}; - this.tempContainer = $('
').css({'visibility': 'hidden', 'width': '100%'}); + this.tempContainer = (0, _jquery2.default)('
').css({ 'visibility': 'hidden', 'width': '100%' }); this.workOnTemp = false; this.autoCalculation = this.options.itemHeightCalculation === 'auto'; this.container.append(this.tempContainer); var that = this; - this.items.each(function() { - var elm = $(this); + this.items.each(function () { + var elm = (0, _jquery2.default)(this); var id = elm.attr('id'); if (!id) { // Generate an unique id @@ -85,20 +94,18 @@ this.container.css('visibility', 'hidden'); if (this.autoCalculation) { - $(window).on('load', $.proxy(this.refill, this)); - } - else { + (0, _jquery2.default)(window).on('load', _jquery2.default.proxy(this.refill, this)); + } else { this.refill(); } - $(window).resize($.proxy(this.refill, this)); + (0, _jquery2.default)(window).resize(_jquery2.default.proxy(this.refill, this)); }, - refill: function() { + refill: function refill() { this.container.trigger('mosaicflow-fill'); this.numberOfColumns = Math.floor(this.container.width() / this.options.minItemWidth); // Always keep min columns number - if (this.numberOfColumns < this.options.minColumns) - this.numberOfColumns = this.options.minColumns; + if (this.numberOfColumns < this.options.minColumns) this.numberOfColumns = this.options.minColumns; var needToRefill = this.ensureColumns(); if (needToRefill) { @@ -113,7 +120,7 @@ this.container.trigger('mosaicflow-filled'); }, - ensureColumns: function() { + ensureColumns: function ensureColumns() { var createdCnt = this.columns.filter(':visible').length; var calculatedCnt = this.numberOfColumns; @@ -122,14 +129,13 @@ if (calculatedCnt > createdCnt) { var neededCnt = calculatedCnt - createdCnt; for (var columnIdx = 0; columnIdx < neededCnt; columnIdx++) { - var column = $('
', { + var column = (0, _jquery2.default)('
', { 'class': this.options.columnClass }); this.workingContainer.append(column); } - } - else if (calculatedCnt < createdCnt) { + } else if (calculatedCnt < createdCnt) { var lastColumn = createdCnt; while (calculatedCnt <= lastColumn) { // We can't remove columns here becase it will remove items to. So we hide it and will remove later. @@ -143,14 +149,14 @@ if (calculatedCnt !== createdCnt) { this.columns = this.workingContainer.find('.' + this.options.columnClass); - this.columns.css('width', (100 / calculatedCnt) + '%'); + this.columns.css('width', 100 / calculatedCnt + '%'); return true; } return false; }, - fillColumns: function() { + fillColumns: function fillColumns() { var columnsCnt = this.numberOfColumns; var itemsCnt = this.items.length; @@ -165,8 +171,7 @@ if (this.autoCalculation) { // Check height after being placed in its column height = item.outerHeight(); - } - else { + } else { // Read img height attribute height = parseInt(item.find('img').attr('height'), 10); } @@ -184,10 +189,10 @@ this.container.trigger('mosaicflow-layout'); }, - levelBottomEdge: function(itemsHeights, columnsHeights) { + levelBottomEdge: function levelBottomEdge(itemsHeights, columnsHeights) { while (true) { - var lowestColumn = $.inArray(Math.min.apply(null, columnsHeights), columnsHeights); - var highestColumn = $.inArray(Math.max.apply(null, columnsHeights), columnsHeights); + var lowestColumn = _jquery2.default.inArray(Math.min.apply(null, columnsHeights), columnsHeights); + var highestColumn = _jquery2.default.inArray(Math.max.apply(null, columnsHeights), columnsHeights); if (lowestColumn === highestColumn) return; var lastInHighestColumn = this.columns.eq(highestColumn).children().last(); @@ -206,9 +211,9 @@ } }, - add: function(elm) { + add: function add(elm) { this.container.trigger('mosaicflow-item-add', [elm]); - var lowestColumn = $.inArray(Math.min.apply(null, this.columnsHeights), this.columnsHeights); + var lowestColumn = _jquery2.default.inArray(Math.min.apply(null, this.columnsHeights), this.columnsHeights); var height = 0; if (this.autoCalculation) { @@ -224,10 +229,10 @@ var inlineImages = elm.find('img'); if (inlineImages.length !== 0) { - inlineImages.each(function() { - var image = $(this); + inlineImages.each(function () { + var image = (0, _jquery2.default)(this); var imageSizes = getImageSizes(image); - var actualHeight = (image.width() * imageSizes.height) / imageSizes.width; + var actualHeight = image.width() * imageSizes.height / imageSizes.width; height += actualHeight; }); @@ -237,8 +242,7 @@ position: 'static', visibility: 'visible' }); - } - else { + } else { height = parseInt(elm.find('img').attr('height'), 10); } @@ -251,7 +255,7 @@ // Item needs to be placed at the end of this.items to keep order of elements var itemsArr = this.items.toArray(); itemsArr.push(elm); - this.items = $(itemsArr); + this.items = (0, _jquery2.default)(itemsArr); this.itemsHeights[elm.attr('id')] = height; this.columnsHeights[lowestColumn] += height; @@ -262,7 +266,7 @@ this.container.trigger('mosaicflow-item-added', [elm]); }, - remove: function(elm) { + remove: function remove(elm) { this.container.trigger('mosaicflow-item-remove', [elm]); var column = elm.parents('.' + this.options.columnClass); @@ -278,10 +282,10 @@ this.container.trigger('mosaicflow-item-removed', [elm]); }, - empty: function() { + empty: function empty() { var columnsCnt = this.numberOfColumns; - this.items = $([]); + this.items = (0, _jquery2.default)([]); this.itemsHeights = {}; for (var columnIdx = 0; columnIdx < columnsCnt; columnIdx++) { @@ -292,15 +296,14 @@ this.container.trigger('mosaicflow-layout'); }, - recomputeHeights: function() { + recomputeHeights: function recomputeHeights() { function computeHeight(idx, item) { - item = $(item); + item = (0, _jquery2.default)(item); var height = 0; if (that.autoCalculation) { // Check height after being placed in its column height = item.outerHeight(); - } - else { + } else { // Read img height attribute height = parseInt(item.find('img').attr('height'), 10); } @@ -320,7 +323,7 @@ } }, - generateUniqueId: function() { + generateUniqueId: function generateUniqueId() { // Increment the counter this.__uidItemCounter++; @@ -360,6 +363,7 @@ } // Auto init - $(function() { $('.mosaicflow').mosaicflow(); }); - -})); + (0, _jquery2.default)(function () { + (0, _jquery2.default)('.mosaicflow').mosaicflow(); + }); +}); diff --git a/jquery.mosaicflow.m.js b/jquery.mosaicflow.m.js new file mode 100644 index 0000000..1456e97 --- /dev/null +++ b/jquery.mosaicflow.m.js @@ -0,0 +1,354 @@ +/** + * Mosaic Flow + * + * Pinterest like responsive image grid that doesn’t sucks + * + * @requires jQuery + * @author Artem Sapegin + * @copyright 2012 Artem Sapegin, http://sapegin.me + * @license MIT + */ + +import $ from 'jquery'; + +$.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 +}; + +var cnt = 0; + +function Mosaicflow(container, options) { + this.container = container; + this.options = options; + + this.container.trigger('mosaicflow-start'); + this.init(); + this.container.trigger('mosaicflow-ready'); +} + +Mosaicflow.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 = $('
').css({'visibility': 'hidden', 'width': '100%'}); + this.workOnTemp = false; + 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) { + // Generate an unique 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(); + } + $(window).resize($.proxy(this.refill, this)); + }, + + refill: function() { + this.container.trigger('mosaicflow-fill'); + this.numberOfColumns = Math.floor(this.container.width() / this.options.minItemWidth); + // Always keep min columns number + if (this.numberOfColumns < this.options.minColumns) + this.numberOfColumns = this.options.minColumns; + + var needToRefill = this.ensureColumns(); + if (needToRefill) { + this.fillColumns(); + + // Remove excess columns, only if there are visible columns remaining + if (this.columns.filter(':visible').length > 0) { + this.columns.filter(':hidden').remove(); + } + } + this.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 = $('
', { + 'class': this.options.columnClass + }); + + this.workingContainer.append(column); + } + } + else if (calculatedCnt < createdCnt) { + var lastColumn = createdCnt; + while (calculatedCnt <= lastColumn) { + // We can't remove columns here becase it will remove items to. So we hide it and will remove later. + this.columns.eq(lastColumn).hide(); + lastColumn--; + } + + var diff = createdCnt - calculatedCnt; + this.columnsHeights.splice(this.columnsHeights.length - diff, diff); + } + + if (calculatedCnt !== createdCnt) { + this.columns = this.workingContainer.find('.' + this.options.columnClass); + this.columns.css('width', (100 / calculatedCnt) + '%'); + return true; + } + + return false; + }, + + 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) { + // Check height after being placed in its column + height = item.outerHeight(); + } + else { + // Read img height attribute + height = parseInt(item.find('img').attr('height'), 10); + } + + this.itemsHeights[item.attr('id')] = height; + this.columnsHeights[columnIdx] += height; + } + } + + this.levelBottomEdge(this.itemsHeights, this.columnsHeights); + + if (this.workingContainer === this.tempContainer) { + this.container.append(this.tempContainer.children()); + } + this.container.trigger('mosaicflow-layout'); + }, + + levelBottomEdge: function(itemsHeights, columnsHeights) { + while (true) { + var lowestColumn = $.inArray(Math.min.apply(null, columnsHeights), columnsHeights); + var highestColumn = $.inArray(Math.max.apply(null, columnsHeights), columnsHeights); + if (lowestColumn === highestColumn) return; + + var 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) { + + // Get height of elm + 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; + }); + } + + elm.detach().css({ + position: 'static', + visibility: 'visible' + }); + } + else { + height = parseInt(elm.find('img').attr('height'), 10); + } + + if (!elm.attr('id')) { + // Generate a unique id + elm.attr('id', this.generateUniqueId()); + } + + // Update item collection. + // Item needs to be placed at the end of this.items to keep order of elements + var 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); + + // Update column height + this.columnsHeights[column.index() - 1] -= this.itemsHeights[elm.attr('id')]; + + elm.detach(); + + // Update item collection + 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(); + } + this.container.trigger('mosaicflow-layout'); + }, + + recomputeHeights: function() { + function computeHeight(idx, item) { + item = $(item); + var height = 0; + if (that.autoCalculation) { + // Check height after being placed in its column + height = item.outerHeight(); + } + else { + // Read img height attribute + height = parseInt(item.find('img').attr('height'), 10); + } + + that.itemsHeights[item.attr('id')] = height; + that.columnsHeights[columnIdx] += height; + } + + var 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() { + // Increment the counter + this.__uidItemCounter++; + + // Return an unique ID + return 'mosaic-' + this.__uid + '-itemid-' + this.__uidItemCounter; + } +}; + +// Camelize data-attributes +function dataToOptions(elem) { + function upper(m, l) { + return l.toUpper(); + } + var options = {}; + var data = elem.data(); + for (var key in data) { + options[key.replace(/-(\w)/g, upper)] = data[key]; + } + return options; +} + +function 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; + } + + return sizes; +} + +// Auto init +$(function() { $('.mosaicflow').mosaicflow(); }); diff --git a/jquery.mosaicflow.min.js b/jquery.mosaicflow.min.js index 9bc517b..ad9d8fd 100644 --- a/jquery.mosaicflow.min.js +++ b/jquery.mosaicflow.min.js @@ -1,2 +1,2 @@ /*! jQuery Mosaic Flow v0.2.5 by Artem Sapegin - http://sapegin.github.io/jquery.mosaicflow/ - Licensed MIT */ -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";function b(a,b){this.container=a,this.options=b,this.container.trigger("mosaicflow-start"),this.init(),this.container.trigger("mosaicflow-ready")}function c(a){function b(a,b){return b.toUpper()}var c={},d=a.data();for(var e in d)c[e.replace(/-(\w)/g,b)]=d[e];return c}function d(a){var b={};if(b.height=parseInt(a.attr("height"),10),b.width=parseInt(a.attr("width"),10),0===b.height||0===b.width){var c=new Image;c.src=a.attr("src"),b.width=c.width,b.height=c.height}return b}var e=0;a.fn.mosaicflow=function(d){var e=Array.prototype.slice.call(arguments,0);return this.each(function(){var f=a(this),g=f.data("mosaicflow");g?"string"==typeof d&&g[d](e[1]):(d=a.extend({},a.fn.mosaicflow.defaults,d,c(f)),g=new b(f,d),f.data("mosaicflow",g))})},a.fn.mosaicflow.defaults={itemSelector:"> *",columnClass:"mosaicflow__column",minItemWidth:240,minColumns:2,itemHeightCalculation:"auto",threshold:40},b.prototype={init:function(){this.__uid=e++,this.__uidItemCounter=0,this.items=this.container.find(this.options.itemSelector),this.columns=a([]),this.columnsHeights=[],this.itemsHeights={},this.tempContainer=a("
").css({visibility:"hidden",width:"100%"}),this.workOnTemp=!1,this.autoCalculation="auto"===this.options.itemHeightCalculation,this.container.append(this.tempContainer);var b=this;this.items.each(function(){var c=a(this),d=c.attr("id");d||(d=b.generateUniqueId(),c.attr("id",d))}),this.container.css("visibility","hidden"),this.autoCalculation?a(window).load(a.proxy(this.refill,this)):this.refill(),a(window).resize(a.proxy(this.refill,this))},refill:function(){this.container.trigger("mosaicflow-fill"),this.numberOfColumns=Math.floor(this.container.width()/this.options.minItemWidth),this.numberOfColumns0&&this.columns.filter(":hidden").remove()),this.container.css("visibility","visible"),this.container.trigger("mosaicflow-filled")},ensureColumns:function(){var b=this.columns.filter(":visible").length,c=this.numberOfColumns;if(this.workingContainer=0===b?this.tempContainer:this.container,c>b)for(var d=c-b,e=0;d>e;e++){var f=a("
",{"class":this.options.columnClass});this.workingContainer.append(f)}else if(b>c){for(var g=b;g>=c;)this.columns.eq(g).hide(),g--;var h=b-c;this.columnsHeights.splice(this.columnsHeights.length-h,h)}return c!==b?(this.columns=this.workingContainer.find("."+this.options.columnClass),this.columns.css("width",100/c+"%"),!0):!1},fillColumns:function(){for(var a=this.numberOfColumns,b=this.items.length,c=0;a>c;c++){var d=this.columns.eq(c);this.columnsHeights[c]=0;for(var e=c;b>e;e+=a){var f=this.items.eq(e),g=0;d.append(f),g=this.autoCalculation?f.outerHeight():parseInt(f.find("img").attr("height"),10),this.itemsHeights[f.attr("id")]=g,this.columnsHeights[c]+=g}}this.levelBottomEdge(this.itemsHeights,this.columnsHeights),this.workingContainer===this.tempContainer&&this.container.append(this.tempContainer.children()),this.container.trigger("mosaicflow-layout")},levelBottomEdge:function(b,c){for(;;){var d=a.inArray(Math.min.apply(null,c),c),e=a.inArray(Math.max.apply(null,c),c);if(d===e)return;var f=this.columns.eq(e).children().last(),g=b[f.attr("id")],h=c[d],i=c[e],j=h+g;if(j>=i)return;if(i-jc;c++){var d=this.columns.eq(c);this.columnsHeights[c]=0,d.empty()}this.container.trigger("mosaicflow-layout")},recomputeHeights:function(){function b(b,d){d=a(d);var f=0;f=c.autoCalculation?d.outerHeight():parseInt(d.find("img").attr("height"),10),c.itemsHeights[d.attr("id")]=f,c.columnsHeights[e]+=f}for(var c=this,d=this.numberOfColumns,e=0;d>e;e++){var f=this.columns.eq(e);this.columnsHeights[e]=0,f.children().each(b)}},generateUniqueId:function(){return this.__uidItemCounter++,"mosaic-"+this.__uid+"-itemid-"+this.__uidItemCounter}},a(function(){a(".mosaicflow").mosaicflow()})}); \ No newline at end of file +!function(a,b){if("function"==typeof define&&define.amd)define("MosaicFlow",["jquery"],b);else if("undefined"!=typeof exports)b(require("jquery"));else{var c={exports:{}};b(a.jQuery),a.MosaicFlow=c.exports}}(this,function(a){"use strict";function b(a){return a&&a.__esModule?a:{"default":a}}function c(a,b){this.container=a,this.options=b,this.container.trigger("mosaicflow-start"),this.init(),this.container.trigger("mosaicflow-ready")}function d(a){function b(a,b){return b.toUpper()}var c={},d=a.data();for(var e in d)c[e.replace(/-(\w)/g,b)]=d[e];return c}function e(a){var b={};if(b.height=parseInt(a.attr("height"),10),b.width=parseInt(a.attr("width"),10),0===b.height||0===b.width){var c=new Image;c.src=a.attr("src"),b.width=c.width,b.height=c.height}return b}var f=b(a);f["default"].fn.mosaicflow=function(a){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var e=f["default"](this),g=e.data("mosaicflow");g?"string"==typeof a&&g[a](b[1]):(a=f["default"].extend({},f["default"].fn.mosaicflow.defaults,a,d(e)),g=new c(e,a),e.data("mosaicflow",g))})},f["default"].fn.mosaicflow.defaults={itemSelector:"> *",columnClass:"mosaicflow__column",minItemWidth:240,minColumns:2,itemHeightCalculation:"auto",threshold:40};var g=0;c.prototype={init:function(){this.__uid=g++,this.__uidItemCounter=0,this.items=this.container.find(this.options.itemSelector),this.columns=f["default"]([]),this.columnsHeights=[],this.itemsHeights={},this.tempContainer=f["default"]("
").css({visibility:"hidden",width:"100%"}),this.workOnTemp=!1,this.autoCalculation="auto"===this.options.itemHeightCalculation,this.container.append(this.tempContainer);var a=this;this.items.each(function(){var b=f["default"](this),c=b.attr("id");c||(c=a.generateUniqueId(),b.attr("id",c))}),this.container.css("visibility","hidden"),this.autoCalculation?f["default"](window).on("load",f["default"].proxy(this.refill,this)):this.refill(),f["default"](window).resize(f["default"].proxy(this.refill,this))},refill:function(){this.container.trigger("mosaicflow-fill"),this.numberOfColumns=Math.floor(this.container.width()/this.options.minItemWidth),this.numberOfColumns0&&this.columns.filter(":hidden").remove()),this.container.css("visibility","visible"),this.container.trigger("mosaicflow-filled")},ensureColumns:function(){var a=this.columns.filter(":visible").length,b=this.numberOfColumns;if(this.workingContainer=0===a?this.tempContainer:this.container,b>a)for(var c=b-a,d=0;c>d;d++){var e=f["default"]("
",{"class":this.options.columnClass});this.workingContainer.append(e)}else if(a>b){for(var g=a;g>=b;)this.columns.eq(g).hide(),g--;var h=a-b;this.columnsHeights.splice(this.columnsHeights.length-h,h)}return b!==a?(this.columns=this.workingContainer.find("."+this.options.columnClass),this.columns.css("width",100/b+"%"),!0):!1},fillColumns:function(){for(var a=this.numberOfColumns,b=this.items.length,c=0;a>c;c++){var d=this.columns.eq(c);this.columnsHeights[c]=0;for(var e=c;b>e;e+=a){var f=this.items.eq(e),g=0;d.append(f),g=this.autoCalculation?f.outerHeight():parseInt(f.find("img").attr("height"),10),this.itemsHeights[f.attr("id")]=g,this.columnsHeights[c]+=g}}this.levelBottomEdge(this.itemsHeights,this.columnsHeights),this.workingContainer===this.tempContainer&&this.container.append(this.tempContainer.children()),this.container.trigger("mosaicflow-layout")},levelBottomEdge:function(a,b){for(;;){var c=f["default"].inArray(Math.min.apply(null,b),b),d=f["default"].inArray(Math.max.apply(null,b),b);if(c===d)return;var e=this.columns.eq(d).children().last(),g=a[e.attr("id")],h=b[c],i=b[d],j=h+g;if(j>=i)return;if(i-jb;b++){var c=this.columns.eq(b);this.columnsHeights[b]=0,c.empty()}this.container.trigger("mosaicflow-layout")},recomputeHeights:function(){function a(a,c){c=f["default"](c);var e=0;e=b.autoCalculation?c.outerHeight():parseInt(c.find("img").attr("height"),10),b.itemsHeights[c.attr("id")]=e,b.columnsHeights[d]+=e}for(var b=this,c=this.numberOfColumns,d=0;c>d;d++){var e=this.columns.eq(d);this.columnsHeights[d]=0,e.children().each(a)}},generateUniqueId:function(){return this.__uidItemCounter++,"mosaic-"+this.__uid+"-itemid-"+this.__uidItemCounter}},f["default"](function(){f["default"](".mosaicflow").mosaicflow()})}); \ No newline at end of file diff --git a/package.json b/package.json index ba22270..5b88e9c 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,29 @@ "name": "mosaic-flow", "version": "0.0.0", "private": true, + "main": "jquery.mosaicflow.js", + "module": "jquery.mosaicflow.m.js", + "jsnext:main": "jquery.mosaicflow.m.js", "scripts": { - "test": "grunt test" + "build": "babel ./jquery.mosaicflow.m.js --out-file ./jquery.mosaicflow.js", + "postbuild": "grunt build", + "test": "grunt test", + "pretest": "npm run build" + }, + "dependencies": { + "jquery": ">=1.7" }, "devDependencies": { + "babel-cli": "6.24.1", + "babel-core": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-preset-es2015": "6.24.1", "grunt": "~0.4.1", - "matchdep": "~0.3.0", + "grunt-cli": "~1.2.0", "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-uglify": "~0.2.4", "grunt-contrib-jshint": "~0.6.4", - "grunt-jscs-checker": "~0.2.0" + "grunt-contrib-uglify": "~0.2.4", + "grunt-jscs-checker": "~0.2.0", + "matchdep": "~0.3.0" } }