1/** 2 * Metro layout mode 3 */ 4 5( function( window, factory ) { 6 'use strict'; 7 // universal module definition 8 if ( typeof define == 'function' && define.amd ) { 9 // AMD 10 define( [ 11 '../layout-mode' 12 ], 13 factory ); 14 } else if ( typeof exports == 'object' ) { 15 // CommonJS 16 module.exports = factory( 17 require('../layout-mode') 18 ); 19 } else { 20 // browser global 21 factory( 22 window.ThegemIsotope.LayoutMode 23 ); 24 } 25 26}( window, function factory( LayoutMode ) { 27'use strict'; 28 29var Metro = LayoutMode.create('metro'); 30 31Metro.prototype._resetLayout = function() { 32 this.x = 0; 33 this.y = 0; 34 this.maxY = 0; 35 this._getMeasurement( 'gutter', 'outerWidth' ); 36 this.perColumn = 0; 37 this.rows = []; 38 this.rowIndex = 0; 39 40 var container = this.options.isFitWidth ? this.element.parentNode : this.element; 41 42 this.targetHeight = parseFloat(jQuery(container).data('max-row-height')) || 380; 43 this.minHeight = 150; 44 45 if (this.minHeight > this.targetHeight) { 46 this.minHeight = this.targetHeight * 0.8; 47 } 48 49 this.getColumnCount(); 50 this.initItems(); 51 this.buildRows(); 52}; 53 54Metro.prototype.getRowItemsHeight = function(rowItems, item, minHeight) { 55 var rowItemsInnerWidth = 0; 56 var rowItemsOuterWidth = 0; 57 58 rowItems.push(item); 59 60 rowItems.forEach(function(item, index) { 61 if (item.imageHeight > minHeight) { 62 var relHeight = minHeight / item.imageHeight; 63 } else { 64 var relHeight = 1; 65 } 66 rowItemsInnerWidth += item.size.innerWidth * relHeight; 67 rowItemsOuterWidth += item.size.innerWidth * relHeight + (item.size.outerWidth - item.size.innerWidth); 68 }); 69 70 if (rowItemsOuterWidth > this.containerWidth) { 71 return (this.containerWidth - (rowItemsOuterWidth - rowItemsInnerWidth)) * minHeight / rowItemsInnerWidth; 72 } else { 73 return minHeight; 74 } 75}; 76 77Metro.prototype.checkRowItemsFull = function(rowItems) { 78 var rowItemsMinHeight = -1; 79 80 rowItems.forEach(function(item, index) { 81 if (rowItemsMinHeight == -1 || item.imageHeight < rowItemsMinHeight) { 82 rowItemsMinHeight = item.imageHeight; 83 } 84 }); 85 86 if (rowItemsMinHeight == -1) { 87 return false; 88 } 89 90 var rowItemsHeight = this.getRowItemsHeight(rowItems.slice(0, rowItems.length - 1), rowItems.slice(-1)[0], rowItemsMinHeight); 91 92 if (rowItemsHeight < this.targetHeight * 1.3) { 93 var rowItemsInnerWidth = 0; 94 var rowItemsOuterWidth = 0; 95 96 rowItems.forEach(function(item, index) { 97 if (item.imageHeight > rowItemsHeight) { 98 var relHeight = rowItemsHeight / item.imageHeight; 99 } else { 100 var relHeight = 1; 101 } 102 103 rowItemsInnerWidth += item.size.innerWidth * relHeight; 104 rowItemsOuterWidth += item.size.innerWidth * relHeight + (item.size.outerWidth - item.size.innerWidth); 105 }); 106 107 return { 108 items: rowItems, 109 innerWidth: rowItemsInnerWidth, 110 outerWidth: rowItemsOuterWidth, 111 height: rowItemsHeight 112 }; 113 } 114 115 return false; 116}; 117 118Metro.prototype.getRowItems = function(targetHeight) { 119 var rowItems = []; 120 var rowItemsInnerWidth = 0; 121 var rowItemsOuterWidth = 0; 122 var defaultItemIndex = this.itemIndex; 123 var minHeight = targetHeight; 124 125 while ( (rowItemsOuterWidth < this.containerWidth || rowItems.length < this.perColumn) && this.itemIndex < this.items.length ) { 126 var item = this.items[ this.itemIndex ]; 127 item.getSize(); 128 129 if (rowItems.length >= this.perColumn) { 130 var canSizeResult = this.checkRowItemsFull(rowItems); 131 if (canSizeResult) { 132 return canSizeResult; 133 } 134 } 135 136 var rowHeight = this.getRowItemsHeight(rowItems.slice(0), item, minHeight); 137 if (rowHeight < this.minHeight && rowItems.length > 0) { 138 var canSizeResult = this.checkRowItemsFull(rowItems); 139 if (canSizeResult) { 140 return canSizeResult; 141 } 142 143 return { 144 items: rowItems, 145 innerWidth: rowItemsInnerWidth, 146 outerWidth: rowItemsOuterWidth, 147 height: targetHeight 148 }; 149 } 150 151 if (item.imageHeight > targetHeight) { 152 var relHeight = targetHeight / item.imageHeight; 153 } else { 154 var relHeight = 1; 155 } 156
157 rowItemsInnerWidth += item.size.innerWidth * relHeight; 158 rowItemsOuterWidth += item.size.innerWidth * relHeight + (item.size.outerWidth - item.size.innerWidth); 159 160 if (minHeight > item.imageHeight) { 161 minHeight = item.imageHeight; 162 } 163 164 rowItems.push(item); 165 this.itemIndex += 1; 166 167 if (minHeight < targetHeight) { 168 this.itemIndex = defaultItemIndex; 169 return this.getRowItems(minHeight); 170 } 171 } 172 173 if (rowItemsOuterWidth < this.containerWidth) { 174 var canSizeResult = this.checkRowItemsFull(rowItems); 175 if (canSizeResult) { 176 return canSizeResult; 177 } 178 } 179 180 return { 181 items: rowItems, 182 innerWidth: rowItemsInnerWidth, 183 outerWidth: rowItemsOuterWidth, 184 height: targetHeight 185 }; 186} 187 188Metro.prototype.buildRows = function() { 189 var self = this; 190 191 var container = this.options.isFitWidth ? this.element.parentNode : this.element; 192 jQuery(this.thegem_isotope.options.itemSelector + ' .caption', container).hide(); 193 194 this.getContainerWidth(); 195 196 this.itemIndex = 0; 197 198 while (this.itemIndex < this.items.length) { 199 var targetHeight = this.targetHeight; 200 var rowItems = this.getRowItems(this.targetHeight); 201 202 if (rowItems.outerWidth > this.containerWidth) { 203 var height = (this.containerWidth - (rowItems.outerWidth - rowItems.innerWidth)) * rowItems.height / rowItems.innerWidth; 204 } else { 205 var height = rowItems.height; 206 } 207 208 rowItems.items.forEach(function(item, index) { 209 var rel = 1; 210 if (item.imageHeight > height) { 211 rel = height / item.imageHeight; 212 } 213 214 var calculatedWidth = Math.round(item.size.innerWidth * rel - 0.5); 215 calculatedWidth += (item.size.outerWidth - item.size.innerWidth); 216 jQuery(item.element).css('width', calculatedWidth); 217 jQuery(self.thegem_isotope.options.itemImageWrapperSelector + ' img', item.element).css('height', height - 0.5); 218 }); 219 } 220 221 jQuery(this.thegem_isotope.options.itemSelector + ' .caption', container).show(); 222}; 223 224Metro.prototype.initItems = function() { 225 var self = this; 226 227 this.items = this.thegem_isotope.filteredItems; 228 var container = this.options.isFitWidth ? this.element.parentNode : this.element; 229 230 this.items.forEach(function(item, index) { 231 if (item.imageHeight == null || item.imageHeight == undefined) { 232 var maxHeight = 0, 233 maxHeightImage = null; 234 235 jQuery(self.thegem_isotope.options.itemImageWrapperSelector + ' img', item.element).each(function() { 236 if (jQuery(this).closest('.portfolio-image-slider').length) { 237 return; 238 } 239 var imageHeight = parseInt(jQuery(this).attr('height')); 240 if (!isNaN(imageHeight) && imageHeight > maxHeight) { 241 maxHeight = imageHeight; 242 maxHeightImage = this; 243 } 244 }); 245 var widthPercents = jQuery(maxHeightImage).outerWidth() / jQuery(maxHeightImage).parent().outerWidth(); 246 widthPercents = widthPercents && widthPercents < 100 ? widthPercents : 1; 247 248 if (maxHeightImage !== null) { 249 self.items[ index ].imageWidth = parseInt(jQuery(maxHeightImage).attr('width')); 250 self.items[ index ].imageHeight = parseInt(jQuery(maxHeightImage).attr('height')); 251 } 252 253 if (isNaN(self.items[ index ].imageHeight)) { 254 self.items[ index ].imageHeight = self.targetHeight; 255 } 256 } 257 258 var $element = jQuery(item.element); 259 if (!$element.data('original-width')) { 260 var original = self.items[ index ].imageWidth / widthPercents; 261 var padding = parseFloat($element.css('padding-left')); 262 if (isNaN(padding)) { 263 padding = 0; 264 } 265 $element.data('original-width', original + 2 * padding); 266 } 267 $element.css('width', $element.data('original-width')); 268 $element.find('img').css('height', ''); 269 });
270}; 271 272Metro.prototype.getColumnCount = function() { 273 var container = this.options.isFitWidth ? this.element.parentNode : this.element; 274 if (this.thegem_isotope.options.itemSelector == '.portfolio-item') { 275 var classes = jQuery(container).closest('.portfolio').attr('class'); 276 } else { 277 var classes = jQuery(container).closest('.gem-gallery-grid').attr('class'); 278 } 279 var m; 280 if (classes.match(/extended-products-grid/)) { 281 if (jQuery(window).width() < 768) { 282 m = classes.match(/columns-mobile-(\d)/); 283 if (m) { 284 this.perColumn = parseInt(m[1]); 285 } else { 286 this.perColumn = 1; 287 } 288 } else if (jQuery(window).width() < 992) { 289 m = classes.match(/columns-tablet-(\d)/); 290 if (m) { 291 this.perColumn = parseInt(m[1]); 292 } else { 293 this.perColumn = 2; 294 } 295 } else { 296 m = classes.match(/columns-desktop-(\d)/); 297 if (m) { 298 this.perColumn = parseInt(m[1]); 299 } else { 300 this.perColumn = 4; 301 } 302 } 303 } else { 304 m = classes.match(/columns-(\d)/); 305 if (m) { 306 this.perColumn = parseInt(m[1]); 307 } else { 308 this.perColumn = 4; 309 } 310 } 311}; 312 313Metro.prototype.getContainerWidth = function() { 314 // container is parent if fit width 315 var container = this.options.isFitWidth ? this.element.parentNode : this.element; 316 // check that this.size and size are there 317 // IE8 triggers resize on body size change, so they might not be 318 var size = getSize( container ); 319 this.containerWidth = size && size.innerWidth; 320};
321 322Metro.prototype._getItemLayoutPosition = function( item ) { 323 item.getSize(); 324 325 var itemWidth = item.size.outerWidth + this.gutter; 326 // if this element cannot fit in the current row 327 var containerWidth = this.thegem_isotope.size.innerWidth + this.gutter; 328 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 329 this.x = 0; 330 this.y = this.maxY; 331 } 332 333 var position = { 334 x: this.x, 335 y: this.y 336 }; 337 338 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 339 this.x += itemWidth; 340 341 return position; 342}; 343 344Metro.prototype._getContainerSize = function() { 345 return { height: this.maxY }; 346}; 347 348return Metro; 349 350}));
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.