/** * Isotope LayoutMode */ ( function( window, factory ) { // universal module definition /* jshint strict: false */ /*globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ 'get-size/get-size', 'outlayer/outlayer' ], factory ); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('get-size'), require('outlayer') ); } else { // browser global window.Isotope = window.Isotope || {}; window.Isotope.LayoutMode = factory( window.getSize, window.Outlayer ); } }( window, function factory( getSize, Outlayer ) { 'use strict'; // layout mode class function LayoutMode( isotope ) { this.isotope = isotope; // link properties if ( isotope ) { this.options = isotope.options[ this.namespace ]; this.element = isotope.element; this.items = isotope.filteredItems; this.size = isotope.size; } } var proto = LayoutMode.prototype; /** * some methods should just defer to default Outlayer method * and reference the Isotope instance as `this` **/ var facadeMethods = [ '_resetLayout', '_getItemLayoutPosition', '_manageStamp', '_getContainerSize', '_getElementOffset', 'needsResizeLayout', '_getOption' ]; facadeMethods.forEach( function( methodName ) { proto[ methodName ] = function() { return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); }; }); // ----- ----- // // for horizontal layout modes, check vertical size proto.needsVerticalResizeLayout = function() { // don't trigger if size did not change var size = getSize( this.isotope.element ); // check that this.size and size are there // IE8 triggers resize on body size change, so they might not be var hasSizes = this.isotope.size && size; return hasSizes && size.innerHeight != this.isotope.size.innerHeight; }; // ----- measurements ----- // proto._getMeasurement = function() { this.isotope._getMeasurement.apply( this, arguments ); }; proto.getColumnWidth = function() { this.getSegmentSize( 'column', 'Width' ); }; proto.getRowHeight = function() { this.getSegmentSize( 'row', 'Height' ); }; /** * get columnWidth or rowHeight * segment: 'column' or 'row' * size 'Width' or 'Height' **/ proto.getSegmentSize = function( segment, size ) { var segmentName = segment + size; var outerSize = 'outer' + size; // columnWidth / outerWidth // rowHeight / outerHeight this._getMeasurement( segmentName, outerSize ); // got rowHeight or columnWidth, we can chill if ( this[ segmentName ] ) { return; } // fall back to item of first element var firstItemSize = this.getFirstItemSize(); this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || // or size of container this.isotope.size[ 'inner' + size ]; }; proto.getFirstItemSize = function() { var firstItem = this.isotope.filteredItems[0]; return firstItem && firstItem.element && getSize( firstItem.element ); }; // ----- methods that should reference isotope ----- // proto.layout = function() { this.isotope.layout.apply( this.isotope, arguments ); }; proto.getSize = function() { this.isotope.getSize(); this.size = this.isotope.size; }; // -------------------------- create -------------------------- // LayoutMode.modes = {}; LayoutMode.create = function( namespace, options ) { function Mode() { LayoutMode.apply( this, arguments ); } Mode.prototype = Object.create( proto ); Mode.prototype.constructor = Mode; // default options if ( options ) { Mode.options = options; } Mode.prototype.namespace = namespace; // register in Isotope LayoutMode.modes[ namespace ] = Mode; return Mode; }; return LayoutMode; }));