vendor: 19,671 bytes, lines 1-806
1/*! 2 * Masonry PACKAGED v4.0.0 3 * Cascading grid layout library 4 * http://masonry.desandro.com 5 * MIT License 6 * by David DeSandro 7 */ 8 9/** 10 * Bridget makes jQuery widgets 11 * v2.0.0 12 * MIT license 13 */ 14 15/* jshint browser: true, strict: true, undef: true, unused: true */ 16 17( function( window, factory ) { 18 'use strict'; 19 /* globals define: false, module: false, require: false */ 20 21 if ( typeof define == 'function' && define.amd ) { 22 // AMD 23 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 24 factory( window, jQuery ); 25 }); 26 } else if ( typeof module == 'object' && module.exports ) { 27 // CommonJS 28 module.exports = factory( 29 window, 30 require('jquery') 31 ); 32 } else { 33 // browser global 34 window.jQueryBridget = factory( 35 window, 36 window.jQuery 37 ); 38 } 39 40}( window, function factory( window, jQuery ) { 41'use strict'; 42 43// ----- utils ----- // 44 45var arraySlice = Array.prototype.slice; 46 47// helper function for logging errors 48// $.error breaks jQuery chaining 49var console = window.console; 50var logError = typeof console == 'undefined' ? function() {} : 51 function( message ) { 52 console.error( message ); 53 }; 54 55// ----- jQueryBridget ----- // 56 57function jQueryBridget( namespace, PluginClass, $ ) { 58 $ = $ || jQuery || window.jQuery; 59 if ( !$ ) { 60 return; 61 } 62 63 // add option method -> $().plugin('option', {...}) 64 if ( !PluginClass.prototype.option ) { 65 // option setter 66 PluginClass.prototype.option = function( opts ) { 67 // bail out if not an object 68 if ( !$.isPlainObject( opts ) ){ 69 return; 70 } 71 this.options = $.extend( true, this.options, opts ); 72 }; 73 } 74 75 // make jQuery plugin 76 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 77 if ( typeof arg0 == 'string' ) { 78 // method call $().plugin( 'methodName', { options } ) 79 // shift arguments by 1 80 var args = arraySlice.call( arguments, 1 ); 81 return methodCall( this, arg0, args ); 82 } 83 // just $().plugin({ options }) 84 plainCall( this, arg0 ); 85 return this; 86 }; 87 88 // $().plugin('methodName') 89 function methodCall( $elems, methodName, args ) { 90 var returnValue; 91 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 92 93 $elems.each( function( i, elem ) { 94 // get instance 95 var instance = $.data( elem, namespace ); 96 if ( !instance ) { 97 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 98 pluginMethodStr ); 99 return; 100 } 101 102 var method = instance[ methodName ]; 103 if ( !method || methodName.charAt(0) == '_' ) { 104 logError( pluginMethodStr + ' is not a valid method' ); 105 return; 106 } 107 108 // apply method, get return value 109 var value = method.apply( instance, args ); 110 // set return value if value is returned, use only first value 111 returnValue = returnValue === undefined ? value : returnValue; 112 }); 113 114 return returnValue !== undefined ? returnValue : $elems; 115 } 116 117 function plainCall( $elems, options ) { 118 $elems.each( function( i, elem ) { 119 var instance = $.data( elem, namespace ); 120 if ( instance ) { 121 // set options & init 122 instance.option( options ); 123 instance._init(); 124 } else { 125 // initialize new instance 126 instance = new PluginClass( elem, options ); 127 $.data( elem, namespace, instance ); 128 } 129 }); 130 } 131 132 updateJQuery( $ ); 133 134} 135 136// ----- updateJQuery ----- // 137 138// set $.bridget for v1 backwards compatibility 139function updateJQuery( $ ) { 140 if ( !$ || ( $ && $.bridget ) ) { 141 return; 142 } 143 $.bridget = jQueryBridget; 144} 145 146updateJQuery( jQuery || window.jQuery ); 147 148// ----- ----- // 149 150return jQueryBridget; 151 152})); 153 154/** 155 * EvEmitter v1.0.1 156 * Lil' event emitter 157 * MIT License 158 */ 159 160/* jshint unused: true, undef: true, strict: true */ 161 162( function( global, factory ) { 163 // universal module definition 164 /* jshint strict: false */ /* globals define, module */ 165 if ( typeof define == 'function' && define.amd ) { 166 // AMD - RequireJS 167 define( 'ev-emitter/ev-emitter',factory ); 168 } else if ( typeof module == 'object' && module.exports ) { 169 // CommonJS - Browserify, Webpack 170 module.exports = factory(); 171 } else { 172 // Browser globals 173 global.EvEmitter = factory(); 174 } 175 176}( this, function() { 177 178 179 180function EvEmitter() {} 181 182var proto = EvEmitter.prototype; 183 184proto.on = function( eventName, listener ) { 185 if ( !eventName || !listener ) { 186 return; 187 } 188 // set events hash 189 var events = this._events = this._events || {}; 190 // set listeners array 191 var listeners = events[ eventName ] = events[ eventName ] || []; 192 // only add once 193 if ( listeners.indexOf( listener ) == -1 ) { 194 listeners.push( listener ); 195 } 196 197 return this; 198}; 199 200proto.once = function( eventName, listener ) { 201 if ( !eventName || !listener ) { 202 return; 203 } 204 // add event 205 this.on( eventName, listener ); 206 // set once flag 207 // set onceEvents hash 208 var onceEvents = this._onceEvents = this._onceEvents || {}; 209 // set onceListeners array 210 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || []; 211 // set flag 212 onceListeners[ listener ] = true; 213 214 return this; 215}; 216 217proto.off = function( eventName, listener ) { 218 var listeners = this._events && this._events[ eventName ]; 219 if ( !listeners || !listeners.length ) { 220 return; 221 } 222 var index = listeners.indexOf( listener ); 223 if ( index != -1 ) { 224 listeners.splice( index, 1 ); 225 } 226 227 return this; 228}; 229 230proto.emitEvent = function( eventName, args ) { 231 var listeners = this._events && this._events[ eventName ]; 232 if ( !listeners || !listeners.length ) { 233 return; 234 } 235 var i = 0; 236 var listener = listeners[i]; 237 args = args || []; 238 // once stuff 239 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 240 241 while ( listener ) { 242 var isOnce = onceListeners && onceListeners[ listener ]; 243 if ( isOnce ) { 244 // remove listener 245 // remove before trigger to prevent recursion 246 this.off( eventName, listener ); 247 // unset once flag 248 delete onceListeners[ listener ]; 249 } 250 // trigger listener 251 listener.apply( this, args ); 252 // get next listener 253 i += isOnce ? 0 : 1; 254 listener = listeners[i]; 255 } 256 257 return this; 258}; 259 260return EvEmitter; 261 262})); 263 264/*! 265 * getSize v2.0.2 266 * measure size of elements 267 * MIT license 268 */ 269 270/*jshint browser: true, strict: true, undef: true, unused: true */ 271/*global define: false, module: false, console: false */ 272 273( function( window, factory ) { 274 'use strict'; 275 276 if ( typeof define == 'function' && define.amd ) { 277 // AMD 278 define( 'get-size/get-size',[],function() { 279 return factory(); 280 }); 281 } else if ( typeof module == 'object' && module.exports ) { 282 // CommonJS 283 module.exports = factory(); 284 } else { 285 // browser global 286 window.getSize = factory(); 287 } 288 289})( window, function factory() { 290'use strict'; 291 292// -------------------------- helpers -------------------------- // 293 294// get a number from a string, not a percentage 295function getStyleSize( value ) { 296 var num = parseFloat( value ); 297 // not a percent like '100%', and a number 298 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 299 return isValid && num; 300} 301 302function noop() {} 303 304var logError = typeof console == 'undefined' ? noop : 305 function( message ) { 306 console.error( message ); 307 }; 308 309// -------------------------- measurements -------------------------- // 310 311var measurements = [ 312 'paddingLeft', 313 'paddingRight', 314 'paddingTop', 315 'paddingBottom', 316 'marginLeft', 317 'marginRight', 318 'marginTop', 319 'marginBottom', 320 'borderLeftWidth', 321 'borderRightWidth', 322 'borderTopWidth', 323 'borderBottomWidth' 324]; 325 326var measurementsLength = measurements.length; 327 328function getZeroSize() { 329 var size = { 330 width: 0, 331 height: 0, 332 innerWidth: 0, 333 innerHeight: 0, 334 outerWidth: 0, 335 outerHeight: 0 336 }; 337 for ( var i=0; i < measurementsLength; i++ ) { 338 var measurement = measurements[i]; 339 size[ measurement ] = 0; 340 } 341 return size; 342} 343 344// -------------------------- getStyle -------------------------- // 345 346/** 347 * getStyle, get style of element, check for Firefox bug 348 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 349 */ 350function getStyle( elem ) { 351 var style = getComputedStyle( elem ); 352 if ( !style ) { 353 logError( 'Style returned ' + style + 354 '. Are you running this code in a hidden iframe on Firefox? ' + 355 'See http://bit.ly/getsizebug1' ); 356 } 357 return style; 358} 359 360// -------------------------- setup -------------------------- // 361 362var isSetup = false; 363 364var isBoxSizeOuter; 365 366/** 367 * setup 368 * check isBoxSizerOuter 369 * do on first getSize() rather than on page load for Firefox bug 370 */ 371function setup() { 372 // setup once 373 if ( isSetup ) { 374 return; 375 } 376 isSetup = true; 377 378 // -------------------------- box sizing -------------------------- // 379 380 /** 381 * WebKit measures the outer-width on style.width on border-box elems 382 * IE & Firefox<29 measures the inner-width 383 */ 384 var div = document.createElement('div'); 385 div.style.width = '200px'; 386 div.style.padding = '1px 2px 3px 4px'; 387 div.style.borderStyle = 'solid'; 388 div.style.borderWidth = '1px 2px 3px 4px'; 389 div.style.boxSizing = 'border-box'; 390 391 var body = document.body || document.documentElement; 392 body.appendChild( div ); 393 var style = getStyle( div ); 394 395 getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200; 396 body.removeChild( div ); 397 398} 399 400// -------------------------- getSize -------------------------- // 401 402function getSize( elem ) { 403 setup(); 404 405 // use querySeletor if elem is string 406 if ( typeof elem == 'string' ) { 407 elem = document.querySelector( elem ); 408 } 409 410 // do not proceed on non-objects 411 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 412 return; 413 } 414 415 var style = getStyle( elem ); 416 417 // if hidden, everything is 0 418 if ( style.display == 'none' ) { 419 return getZeroSize(); 420 } 421 422 var size = {}; 423 size.width = elem.offsetWidth; 424 size.height = elem.offsetHeight; 425 426 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 427 428 // get all measurements 429 for ( var i=0; i < measurementsLength; i++ ) { 430 var measurement = measurements[i]; 431 var value = style[ measurement ]; 432 var num = parseFloat( value ); 433 // any 'auto', 'medium' value will be 0 434 size[ measurement ] = !isNaN( num ) ? num : 0; 435 } 436 437 var paddingWidth = size.paddingLeft + size.paddingRight; 438 var paddingHeight = size.paddingTop + size.paddingBottom; 439 var marginWidth = size.marginLeft + size.marginRight; 440 var marginHeight = size.marginTop + size.marginBottom; 441 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 442 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 443 444 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 445 446 // overwrite width and height if we can get it from style 447 var styleWidth = getStyleSize( style.width ); 448 if ( styleWidth !== false ) { 449 size.width = styleWidth + 450 // add padding and border unless it's already including it 451 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 452 } 453 454 var styleHeight = getStyleSize( style.height ); 455 if ( styleHeight !== false ) { 456 size.height = styleHeight + 457 // add padding and border unless it's already including it 458 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 459 } 460 461 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 462 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 463 464 size.outerWidth = size.width + marginWidth; 465 size.outerHeight = size.height + marginHeight; 466 467 return size; 468} 469 470return getSize; 471 472}); 473 474/** 475 * matchesSelector v2.0.1 476 * matchesSelector( element, '.selector' ) 477 * MIT license 478 */ 479 480/*jshint browser: true, strict: true, undef: true, unused: true */ 481 482( function( window, factory ) { 483 /*global define: false, module: false */ 484 'use strict'; 485 // universal module definition 486 if ( typeof define == 'function' && define.amd ) { 487 // AMD 488 define( 'matches-selector/matches-selector',factory ); 489 } else if ( typeof module == 'object' && module.exports ) { 490 // CommonJS 491 module.exports = factory(); 492 } else { 493 // browser global 494 window.matchesSelector = factory(); 495 } 496 497}( window, function factory() { 498 'use strict'; 499 500 var matchesMethod = ( function() { 501 var ElemProto = Element.prototype; 502 // check for the standard method name first 503 if ( ElemProto.matches ) { 504 return 'matches'; 505 } 506 // check un-prefixed 507 if ( ElemProto.matchesSelector ) { 508 return 'matchesSelector'; 509 } 510 // check vendor prefixes 511 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 512 513 for ( var i=0; i < prefixes.length; i++ ) { 514 var prefix = prefixes[i]; 515 var method = prefix + 'MatchesSelector'; 516 if ( ElemProto[ method ] ) { 517 return method; 518 } 519 } 520 })(); 521 522 return function matchesSelector( elem, selector ) { 523 return elem[ matchesMethod ]( selector ); 524 }; 525 526})); 527 528/** 529 * Fizzy UI utils v2.0.0 530 * MIT license 531 */ 532 533/*jshint browser: true, undef: true, unused: true, strict: true */ 534 535( function( window, factory ) { 536 /*global define: false, module: false, require: false */ 537 'use strict'; 538 // universal module definition 539 540 if ( typeof define == 'function' && define.amd ) { 541 // AMD 542 define( 'fizzy-ui-utils/utils',[ 543 'matches-selector/matches-selector' 544 ], function( matchesSelector ) { 545 return factory( window, matchesSelector ); 546 }); 547 } else if ( typeof module == 'object' && module.exports ) { 548 // CommonJS 549 module.exports = factory( 550 window, 551 require('desandro-matches-selector') 552 ); 553 } else { 554 // browser global 555 window.fizzyUIUtils = factory( 556 window, 557 window.matchesSelector 558 ); 559 } 560 561}( window, function factory( window, matchesSelector ) { 562 563 564 565var utils = {}; 566 567// ----- extend ----- // 568 569// extends objects 570utils.extend = function( a, b ) { 571 for ( var prop in b ) { 572 a[ prop ] = b[ prop ]; 573 } 574 return a; 575}; 576 577// ----- modulo ----- // 578 579utils.modulo = function( num, div ) { 580 return ( ( num % div ) + div ) % div; 581}; 582 583// ----- makeArray ----- // 584 585// turn element or nodeList into an array 586utils.makeArray = function( obj ) { 587 var ary = []; 588 if ( Array.isArray( obj ) ) { 589 // use object if already an array 590 ary = obj; 591 } else if ( obj && typeof obj.length == 'number' ) { 592 // convert nodeList to array 593 for ( var i=0; i < obj.length; i++ ) { 594 ary.push( obj[i] ); 595 } 596 } else { 597 // array of single index 598 ary.push( obj ); 599 } 600 return ary; 601}; 602 603// ----- removeFrom ----- // 604 605utils.removeFrom = function( ary, obj ) { 606 var index = ary.indexOf( obj ); 607 if ( index != -1 ) { 608 ary.splice( index, 1 ); 609 } 610}; 611 612// ----- getParent ----- // 613 614utils.getParent = function( elem, selector ) { 615 while ( elem != document.body ) { 616 elem = elem.parentNode; 617 if ( matchesSelector( elem, selector ) ) { 618 return elem; 619 } 620 } 621}; 622 623// ----- getQueryElement ----- // 624 625// use element as selector string 626utils.getQueryElement = function( elem ) { 627 if ( typeof elem == 'string' ) { 628 return document.querySelector( elem ); 629 } 630 return elem; 631}; 632 633// ----- handleEvent ----- // 634 635// enable .ontype to trigger from .addEventListener( elem, 'type' ) 636utils.handleEvent = function( event ) { 637 var method = 'on' + event.type; 638 if ( this[ method ] ) { 639 this[ method ]( event ); 640 } 641}; 642 643// ----- filterFindElements ----- // 644 645utils.filterFindElements = function( elems, selector ) { 646 // make array of elems 647 elems = utils.makeArray( elems ); 648 var ffElems = []; 649 650 elems.forEach( function( elem ) { 651 // check that elem is an actual element 652 if ( !( elem instanceof HTMLElement ) ) { 653 return; 654 } 655 // add elem if no selector 656 if ( !selector ) { 657 ffElems.push( elem ); 658 return; 659 } 660 // filter & find items if we have a selector 661 // filter 662 if ( matchesSelector( elem, selector ) ) { 663 ffElems.push( elem ); 664 } 665 // find children 666 var childElems = elem.querySelectorAll( selector ); 667 // concat childElems to filterFound array 668 for ( var i=0; i < childElems.length; i++ ) { 669 ffElems.push( childElems[i] ); 670 } 671 }); 672 673 return ffElems; 674}; 675 676// ----- debounceMethod ----- // 677 678utils.debounceMethod = function( _class, methodName, threshold ) { 679 // original method 680 var method = _class.prototype[ methodName ]; 681 var timeoutName = methodName + 'Timeout'; 682 683 _class.prototype[ methodName ] = function() { 684 var timeout = this[ timeoutName ]; 685 if ( timeout ) { 686 clearTimeout( timeout ); 687 } 688 var args = arguments; 689 690 var _this = this; 691 this[ timeoutName ] = setTimeout( function() { 692 method.apply( _this, args ); 693 delete _this[ timeoutName ]; 694 }, threshold || 100 ); 695 }; 696}; 697 698// ----- docReady ----- // 699 700utils.docReady = function( callback ) { 701 if ( document.readyState == 'complete' ) { 702 callback(); 703 } else { 704 document.addEventListener( 'DOMContentLoaded', callback ); 705 } 706}; 707 708// ----- htmlInit ----- // 709 710// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 711utils.toDashed = function( str ) { 712 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 713 return $1 + '-' + $2; 714 }).toLowerCase(); 715}; 716 717var console = window.console; 718/** 719 * allow user to initialize classes via [data-namespace] or .js-namespace class 720 * htmlInit( Widget, 'widgetName' ) 721 * options are parsed from data-namespace-options 722 */ 723utils.htmlInit = function( WidgetClass, namespace ) { 724 utils.docReady( function() { 725 var dashedNamespace = utils.toDashed( namespace ); 726 var dataAttr = 'data-' + dashedNamespace; 727 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 728 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 729 var elems = utils.makeArray( dataAttrElems ) 730 .concat( utils.makeArray( jsDashElems ) ); 731 var dataOptionsAttr = dataAttr + '-options'; 732 var jQuery = window.jQuery; 733 734 elems.forEach( function( elem ) { 735 var attr = elem.getAttribute( dataAttr ) || 736 elem.getAttribute( dataOptionsAttr ); 737 var options; 738 try { 739 options = attr && JSON.parse( attr ); 740 } catch ( error ) { 741 // log error, do not initialize 742 if ( console ) { 743 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 744 ': ' + error ); 745 } 746 return; 747 } 748 // initialize 749 var instance = new WidgetClass( elem, options ); 750 // make available via $().data('layoutname') 751 if ( jQuery ) { 752 jQuery.data( elem, namespace, instance ); 753 } 754 }); 755 756 }); 757}; 758 759// ----- ----- // 760 761return utils; 762 763})); 764 765/** 766 * Outlayer Item 767 */ 768 769( function( window, factory ) { 770 // universal module definition 771 /* jshint strict: false */ /* globals define, module, require */ 772 if ( typeof define == 'function' && define.amd ) { 773 // AMD - RequireJS 774 define( 'outlayer/item',[ 775 'ev-emitter/ev-emitter', 776 'get-size/get-size' 777 ], 778 function( EvEmitter, getSize ) { 779 return factory( window, EvEmitter, getSize ); 780 } 781 ); 782 } else if ( typeof module == 'object' && module.exports ) { 783 // CommonJS - Browserify, Webpack 784 module.exports = factory( 785 window, 786 require('ev-emitter'), 787 require('get-size') 788 ); 789 } else { 790 // browser global 791 window.Outlayer = {}; 792 window.Outlayer.Item = factory( 793 window, 794 window.EvEmitter, 795 window.getSize 796 ); 797 } 798 799}( window, function factory( window, EvEmitter, getSize ) { 800'use strict'; 801 802// ----- helpers ----- // 803 804function isEmptyObj( obj ) { 805 for ( var prop in obj ) { 806 return false;
vendor: 4,257 bytes, lines 807-962
807 } 808 prop = null; 809 return true; 810} 811 812// -------------------------- CSS3 support -------------------------- // 813 814 815var docElemStyle = document.documentElement.style; 816 817var transitionProperty = typeof docElemStyle.transition == 'string' ? 818 'transition' : 'WebkitTransition'; 819var transformProperty = typeof docElemStyle.transform == 'string' ? 820 'transform' : 'WebkitTransform'; 821 822var transitionEndEvent = { 823 WebkitTransition: 'webkitTransitionEnd', 824 transition: 'transitionend' 825}[ transitionProperty ]; 826 827// cache all vendor properties 828var vendorProperties = [ 829 transformProperty, 830 transitionProperty, 831 transitionProperty + 'Duration', 832 transitionProperty + 'Property' 833]; 834 835// -------------------------- Item -------------------------- // 836 837function Item( element, layout ) { 838 if ( !element ) { 839 return; 840 } 841 842 this.element = element; 843 // parent layout class, i.e. Masonry, Isotope, or Packery 844 this.layout = layout; 845 this.position = { 846 x: 0, 847 y: 0 848 }; 849 850 this._create(); 851} 852 853// inherit EvEmitter 854var proto = Item.prototype = Object.create( EvEmitter.prototype ); 855proto.constructor = Item; 856 857proto._create = function() { 858 // transition objects 859 this._transn = { 860 ingProperties: {}, 861 clean: {}, 862 onEnd: {} 863 }; 864 865 this.css({ 866 position: 'absolute' 867 }); 868}; 869 870// trigger specified handler for event type 871proto.handleEvent = function( event ) { 872 var method = 'on' + event.type; 873 if ( this[ method ] ) { 874 this[ method ]( event ); 875 } 876}; 877 878proto.getSize = function() { 879 this.size = getSize( this.element ); 880}; 881 882/** 883 * apply CSS styles to element 884 * @param {Object} style 885 */ 886proto.css = function( style ) { 887 var elemStyle = this.element.style; 888 889 for ( var prop in style ) { 890 // use vendor property if available 891 var supportedProp = vendorProperties[ prop ] || prop; 892 elemStyle[ supportedProp ] = style[ prop ]; 893 } 894}; 895 896 // measure position, and sets it 897proto.getPosition = function() { 898 var style = getComputedStyle( this.element ); 899 var isOriginLeft = this.layout._getOption('originLeft'); 900 var isOriginTop = this.layout._getOption('originTop'); 901 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 902 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 903 // convert percent to pixels 904 var layoutSize = this.layout.size; 905 var x = xValue.indexOf('%') != -1 ? 906 ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 ); 907 var y = yValue.indexOf('%') != -1 ? 908 ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 ); 909 910 // clean up 'auto' or other non-integer values 911 x = isNaN( x ) ? 0 : x; 912 y = isNaN( y ) ? 0 : y; 913 // remove padding from measurement 914 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 915 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 916 917 this.position.x = x; 918 this.position.y = y; 919}; 920 921// set settled position, apply padding 922proto.layoutPosition = function() { 923 var layoutSize = this.layout.size; 924 var style = {}; 925 var isOriginLeft = this.layout._getOption('originLeft'); 926 var isOriginTop = this.layout._getOption('originTop'); 927 928 // x 929 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 930 var xProperty = isOriginLeft ? 'left' : 'right'; 931 var xResetProperty = isOriginLeft ? 'right' : 'left'; 932 933 var x = this.position.x + layoutSize[ xPadding ]; 934 // set in percentage or pixels 935 style[ xProperty ] = this.getXValue( x ); 936 // reset other property 937 style[ xResetProperty ] = ''; 938 939 // y 940 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 941 var yProperty = isOriginTop ? 'top' : 'bottom'; 942 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 943 944 var y = this.position.y + layoutSize[ yPadding ]; 945 // set in percentage or pixels 946 style[ yProperty ] = this.getYValue( y ); 947 // reset other property 948 style[ yResetProperty ] = ''; 949 950 this.css( style ); 951 this.emitEvent( 'layout', [ this ] ); 952}; 953 954proto.getXValue = function( x ) { 955 var isHorizontal = this.layout._getOption('horizontal'); 956 return this.layout.options.percentPosition && !isHorizontal ? 957 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 958}; 959 960proto.getYValue = function( y ) { 961 var isHorizontal = this.layout._getOption('horizontal'); 962 return this.layout.options.percentPosition && isHorizontal ?
vendor: 14,914 bytes, lines 963-1556
963 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 964}; 965 966proto._transitionTo = function( x, y ) { 967 this.getPosition(); 968 // get current x & y from top/left 969 var curX = this.position.x; 970 var curY = this.position.y; 971 972 var compareX = parseInt( x, 10 ); 973 var compareY = parseInt( y, 10 ); 974 var didNotMove = compareX === this.position.x && compareY === this.position.y; 975 976 // save end position 977 this.setPosition( x, y ); 978 979 // if did not move and not transitioning, just go to layout 980 if ( didNotMove && !this.isTransitioning ) { 981 this.layoutPosition(); 982 return; 983 } 984 985 var transX = x - curX; 986 var transY = y - curY; 987 var transitionStyle = {}; 988 transitionStyle.transform = this.getTranslate( transX, transY ); 989 990 this.transition({ 991 to: transitionStyle, 992 onTransitionEnd: { 993 transform: this.layoutPosition 994 }, 995 isCleaning: true 996 }); 997}; 998 999proto.getTranslate = function( x, y ) { 1000 // flip cooridinates if origin on right or bottom 1001 var isOriginLeft = this.layout._getOption('originLeft'); 1002 var isOriginTop = this.layout._getOption('originTop'); 1003 x = isOriginLeft ? x : -x; 1004 y = isOriginTop ? y : -y; 1005 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 1006}; 1007 1008// non transition + transform support 1009proto.goTo = function( x, y ) { 1010 this.setPosition( x, y ); 1011 this.layoutPosition(); 1012}; 1013 1014proto.moveTo = proto._transitionTo; 1015 1016proto.setPosition = function( x, y ) { 1017 this.position.x = parseInt( x, 10 ); 1018 this.position.y = parseInt( y, 10 ); 1019}; 1020 1021// ----- transition ----- // 1022 1023/** 1024 * @param {Object} style - CSS 1025 * @param {Function} onTransitionEnd 1026 */ 1027 1028// non transition, just trigger callback 1029proto._nonTransition = function( args ) { 1030 this.css( args.to ); 1031 if ( args.isCleaning ) { 1032 this._removeStyles( args.to ); 1033 } 1034 for ( var prop in args.onTransitionEnd ) { 1035 args.onTransitionEnd[ prop ].call( this ); 1036 } 1037}; 1038 1039/** 1040 * proper transition 1041 * @param {Object} args - arguments 1042 * @param {Object} to - style to transition to 1043 * @param {Object} from - style to start transition from 1044 * @param {Boolean} isCleaning - removes transition styles after transition 1045 * @param {Function} onTransitionEnd - callback 1046 */ 1047proto._transition = function( args ) { 1048 // redirect to nonTransition if no transition duration 1049 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 1050 this._nonTransition( args ); 1051 return; 1052 } 1053 1054 var _transition = this._transn; 1055 // keep track of onTransitionEnd callback by css property 1056 for ( var prop in args.onTransitionEnd ) { 1057 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 1058 } 1059 // keep track of properties that are transitioning 1060 for ( prop in args.to ) { 1061 _transition.ingProperties[ prop ] = true; 1062 // keep track of properties to clean up when transition is done 1063 if ( args.isCleaning ) { 1064 _transition.clean[ prop ] = true; 1065 } 1066 } 1067 1068 // set from styles 1069 if ( args.from ) { 1070 this.css( args.from ); 1071 // force redraw. http://blog.alexmaccaw.com/css-transitions 1072 var h = this.element.offsetHeight; 1073 // hack for JSHint to hush about unused var 1074 h = null; 1075 } 1076 // enable transition 1077 this.enableTransition( args.to ); 1078 // set styles that are transitioning 1079 this.css( args.to ); 1080 1081 this.isTransitioning = true; 1082 1083}; 1084 1085// dash before all cap letters, including first for 1086// WebkitTransform => -webkit-transform 1087function toDashedAll( str ) { 1088 return str.replace( /([A-Z])/g, function( $1 ) { 1089 return '-' + $1.toLowerCase(); 1090 }); 1091} 1092 1093var transitionProps = 'opacity,' + 1094 toDashedAll( vendorProperties.transform || 'transform' ); 1095 1096proto.enableTransition = function(/* style */) { 1097 // HACK changing transitionProperty during a transition 1098 // will cause transition to jump 1099 if ( this.isTransitioning ) { 1100 return; 1101 } 1102 1103 // make `transition: foo, bar, baz` from style object 1104 // HACK un-comment this when enableTransition can work 1105 // while a transition is happening 1106 // var transitionValues = []; 1107 // for ( var prop in style ) { 1108 // // dash-ify camelCased properties like WebkitTransition 1109 // prop = vendorProperties[ prop ] || prop; 1110 // transitionValues.push( toDashedAll( prop ) ); 1111 // } 1112 // enable transition styles 1113 this.css({ 1114 transitionProperty: transitionProps, 1115 transitionDuration: this.layout.options.transitionDuration 1116 }); 1117 // listen for transition end event 1118 this.element.addEventListener( transitionEndEvent, this, false ); 1119}; 1120 1121proto.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ]; 1122 1123// ----- events ----- // 1124 1125proto.onwebkitTransitionEnd = function( event ) { 1126 this.ontransitionend( event ); 1127}; 1128 1129proto.onotransitionend = function( event ) { 1130 this.ontransitionend( event ); 1131}; 1132 1133// properties that I munge to make my life easier 1134var dashedVendorProperties = { 1135 '-webkit-transform': 'transform' 1136}; 1137 1138proto.ontransitionend = function( event ) { 1139 // disregard bubbled events from children 1140 if ( event.target !== this.element ) { 1141 return; 1142 } 1143 var _transition = this._transn; 1144 // get property name of transitioned property, convert to prefix-free 1145 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 1146 1147 // remove property that has completed transitioning 1148 delete _transition.ingProperties[ propertyName ]; 1149 // check if any properties are still transitioning 1150 if ( isEmptyObj( _transition.ingProperties ) ) { 1151 // all properties have completed transitioning 1152 this.disableTransition(); 1153 } 1154 // clean style 1155 if ( propertyName in _transition.clean ) { 1156 // clean up style 1157 this.element.style[ event.propertyName ] = ''; 1158 delete _transition.clean[ propertyName ]; 1159 } 1160 // trigger onTransitionEnd callback 1161 if ( propertyName in _transition.onEnd ) { 1162 var onTransitionEnd = _transition.onEnd[ propertyName ]; 1163 onTransitionEnd.call( this ); 1164 delete _transition.onEnd[ propertyName ]; 1165 } 1166 1167 this.emitEvent( 'transitionEnd', [ this ] ); 1168}; 1169 1170proto.disableTransition = function() { 1171 this.removeTransitionStyles(); 1172 this.element.removeEventListener( transitionEndEvent, this, false ); 1173 this.isTransitioning = false; 1174}; 1175 1176/** 1177 * removes style property from element 1178 * @param {Object} style 1179**/ 1180proto._removeStyles = function( style ) { 1181 // clean up transition styles 1182 var cleanStyle = {}; 1183 for ( var prop in style ) { 1184 cleanStyle[ prop ] = ''; 1185 } 1186 this.css( cleanStyle ); 1187}; 1188 1189var cleanTransitionStyle = { 1190 transitionProperty: '', 1191 transitionDuration: '' 1192}; 1193 1194proto.removeTransitionStyles = function() { 1195 // remove transition 1196 this.css( cleanTransitionStyle ); 1197}; 1198 1199// ----- show/hide/remove ----- // 1200 1201// remove element from DOM 1202proto.removeElem = function() { 1203 this.element.parentNode.removeChild( this.element ); 1204 // remove display: none 1205 this.css({ display: '' }); 1206 this.emitEvent( 'remove', [ this ] ); 1207}; 1208 1209proto.remove = function() { 1210 // just remove element if no transition support or no transition 1211 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 1212 this.removeElem(); 1213 return; 1214 } 1215 1216 // start transition 1217 this.once( 'transitionEnd', function() { 1218 this.removeElem(); 1219 }); 1220 this.hide(); 1221}; 1222 1223proto.reveal = function() { 1224 delete this.isHidden; 1225 // remove display: none 1226 this.css({ display: '' }); 1227 1228 var options = this.layout.options; 1229 1230 var onTransitionEnd = {}; 1231 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 1232 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 1233 1234 this.transition({ 1235 from: options.hiddenStyle, 1236 to: options.visibleStyle, 1237 isCleaning: true, 1238 onTransitionEnd: onTransitionEnd 1239 }); 1240}; 1241 1242proto.onRevealTransitionEnd = function() { 1243 // check if still visible 1244 // during transition, item may have been hidden 1245 if ( !this.isHidden ) { 1246 this.emitEvent('reveal'); 1247 } 1248}; 1249 1250/** 1251 * get style property use for hide/reveal transition end 1252 * @param {String} styleProperty - hiddenStyle/visibleStyle 1253 * @returns {String} 1254 */ 1255proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 1256 var optionStyle = this.layout.options[ styleProperty ]; 1257 // use opacity 1258 if ( optionStyle.opacity ) { 1259 return 'opacity'; 1260 } 1261 // get first property 1262 for ( var prop in optionStyle ) { 1263 return prop; 1264 } 1265}; 1266 1267proto.hide = function() { 1268 // set flag 1269 this.isHidden = true; 1270 // remove display: none 1271 this.css({ display: '' }); 1272 1273 var options = this.layout.options; 1274 1275 var onTransitionEnd = {}; 1276 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 1277 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 1278 1279 this.transition({ 1280 from: options.visibleStyle, 1281 to: options.hiddenStyle, 1282 // keep hidden stuff hidden 1283 isCleaning: true, 1284 onTransitionEnd: onTransitionEnd 1285 }); 1286}; 1287 1288proto.onHideTransitionEnd = function() { 1289 // check if still hidden 1290 // during transition, item may have been un-hidden 1291 if ( this.isHidden ) { 1292 this.css({ display: 'none' }); 1293 this.emitEvent('hide'); 1294 } 1295}; 1296 1297proto.destroy = function() { 1298 this.css({ 1299 position: '', 1300 left: '', 1301 right: '', 1302 top: '', 1303 bottom: '', 1304 transition: '', 1305 transform: '' 1306 }); 1307}; 1308 1309return Item; 1310 1311})); 1312 1313/*! 1314 * Outlayer v2.0.0 1315 * the brains and guts of a layout library 1316 * MIT license 1317 */ 1318 1319( function( window, factory ) { 1320 'use strict'; 1321 // universal module definition 1322 /* jshint strict: false */ /* globals define, module, require */ 1323 if ( typeof define == 'function' && define.amd ) { 1324 // AMD - RequireJS 1325 define( 'outlayer/outlayer',[ 1326 'ev-emitter/ev-emitter', 1327 'get-size/get-size', 1328 'fizzy-ui-utils/utils', 1329 './item' 1330 ], 1331 function( EvEmitter, getSize, utils, Item ) { 1332 return factory( window, EvEmitter, getSize, utils, Item); 1333 } 1334 ); 1335 } else if ( typeof module == 'object' && module.exports ) { 1336 // CommonJS - Browserify, Webpack 1337 module.exports = factory( 1338 window, 1339 require('ev-emitter'), 1340 require('get-size'), 1341 require('fizzy-ui-utils'), 1342 require('./item') 1343 ); 1344 } else { 1345 // browser global 1346 window.Outlayer = factory( 1347 window, 1348 window.EvEmitter, 1349 window.getSize, 1350 window.fizzyUIUtils, 1351 window.Outlayer.Item 1352 ); 1353 } 1354 1355}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 1356'use strict'; 1357 1358// ----- vars ----- // 1359 1360var console = window.console; 1361var jQuery = window.jQuery; 1362var noop = function() {}; 1363 1364// -------------------------- Outlayer -------------------------- // 1365 1366// globally unique identifiers 1367var GUID = 0; 1368// internal store of all Outlayer intances 1369var instances = {}; 1370 1371 1372/** 1373 * @param {Element, String} element 1374 * @param {Object} options 1375 * @constructor 1376 */ 1377function Outlayer( element, options ) { 1378 var queryElement = utils.getQueryElement( element ); 1379 if ( !queryElement ) { 1380 if ( console ) { 1381 console.error( 'Bad element for ' + this.constructor.namespace + 1382 ': ' + ( queryElement || element ) ); 1383 } 1384 return; 1385 } 1386 this.element = queryElement; 1387 // add jQuery 1388 if ( jQuery ) { 1389 this.$element = jQuery( this.element ); 1390 } 1391 1392 // options 1393 this.options = utils.extend( {}, this.constructor.defaults ); 1394 this.option( options ); 1395 1396 // add id for Outlayer.getFromElement 1397 var id = ++GUID; 1398 this.element.outlayerGUID = id; // expando 1399 instances[ id ] = this; // associate via id 1400 1401 // kick it off 1402 this._create(); 1403 1404 var isInitLayout = this._getOption('initLayout'); 1405 if ( isInitLayout ) { 1406 this.layout(); 1407 } 1408} 1409 1410// settings are for internal use only 1411Outlayer.namespace = 'outlayer'; 1412Outlayer.Item = Item; 1413 1414// default options 1415Outlayer.defaults = { 1416 containerStyle: { 1417 position: 'relative' 1418 }, 1419 initLayout: true, 1420 originLeft: true, 1421 originTop: true, 1422 resize: true, 1423 resizeContainer: true, 1424 // item options 1425 transitionDuration: '0.4s', 1426 hiddenStyle: { 1427 opacity: 0, 1428 transform: 'scale(0.001)' 1429 }, 1430 visibleStyle: { 1431 opacity: 1, 1432 transform: 'scale(1)' 1433 } 1434}; 1435 1436var proto = Outlayer.prototype; 1437// inherit EvEmitter 1438utils.extend( proto, EvEmitter.prototype ); 1439 1440/** 1441 * set options 1442 * @param {Object} opts 1443 */ 1444proto.option = function( opts ) { 1445 utils.extend( this.options, opts ); 1446}; 1447 1448/** 1449 * get backwards compatible option value, check old name 1450 */ 1451proto._getOption = function( option ) { 1452 var oldOption = this.constructor.compatOptions[ option ]; 1453 return oldOption && this.options[ oldOption ] !== undefined ? 1454 this.options[ oldOption ] : this.options[ option ]; 1455}; 1456 1457Outlayer.compatOptions = { 1458 // currentName: oldName 1459 initLayout: 'isInitLayout', 1460 horizontal: 'isHorizontal', 1461 layoutInstant: 'isLayoutInstant', 1462 originLeft: 'isOriginLeft', 1463 originTop: 'isOriginTop', 1464 resize: 'isResizeBound', 1465 resizeContainer: 'isResizingContainer' 1466}; 1467 1468proto._create = function() { 1469 // get items from children 1470 this.reloadItems(); 1471 // elements that affect layout, but are not laid out 1472 this.stamps = []; 1473 this.stamp( this.options.stamp ); 1474 // set container style 1475 utils.extend( this.element.style, this.options.containerStyle ); 1476 1477 // bind resize method 1478 var canBindResize = this._getOption('resize'); 1479 if ( canBindResize ) { 1480 this.bindResize(); 1481 } 1482}; 1483 1484// goes through all children again and gets bricks in proper order 1485proto.reloadItems = function() { 1486 // collection of item elements 1487 this.items = this._itemize( this.element.children ); 1488}; 1489 1490 1491/** 1492 * turn elements into Outlayer.Items to be used in layout 1493 * @param {Array or NodeList or HTMLElement} elems 1494 * @returns {Array} items - collection of new Outlayer Items 1495 */ 1496proto._itemize = function( elems ) { 1497 1498 var itemElems = this._filterFindItemElements( elems ); 1499 var Item = this.constructor.Item; 1500 1501 // create new Outlayer Items for collection 1502 var items = []; 1503 for ( var i=0; i < itemElems.length; i++ ) { 1504 var elem = itemElems[i]; 1505 var item = new Item( elem, this ); 1506 items.push( item ); 1507 } 1508 1509 return items; 1510}; 1511 1512/** 1513 * get item elements to be used in layout 1514 * @param {Array or NodeList or HTMLElement} elems 1515 * @returns {Array} items - item elements 1516 */ 1517proto._filterFindItemElements = function( elems ) { 1518 return utils.filterFindElements( elems, this.options.itemSelector ); 1519}; 1520 1521/** 1522 * getter method for getting item elements 1523 * @returns {Array} elems - collection of item elements 1524 */ 1525proto.getItemElements = function() { 1526 return this.items.map( function( item ) { 1527 return item.element; 1528 }); 1529}; 1530 1531// ----- init & layout ----- // 1532 1533/** 1534 * lays out all items 1535 */ 1536proto.layout = function() { 1537 this._resetLayout(); 1538 this._manageStamps(); 1539 1540 // don't animate first layout 1541 var layoutInstant = this._getOption('layoutInstant'); 1542 var isInstant = layoutInstant !== undefined ? 1543 layoutInstant : !this._isLayoutInited; 1544 this.layoutItems( this.items, isInstant ); 1545 1546 // flag for initalized 1547 this._isLayoutInited = true; 1548}; 1549 1550// _init is alias for layout 1551proto._init = proto.layout; 1552 1553/** 1554 * logic before any new layout 1555 */ 1556proto._resetLayout = function() {
vendor: 2,902 bytes, lines 1557-1679
1557 this.getSize(); 1558}; 1559 1560 1561proto.getSize = function() { 1562 this.size = getSize( this.element ); 1563}; 1564 1565/** 1566 * get measurement from option, for columnWidth, rowHeight, gutter 1567 * if option is String -> get element from selector string, & get size of element 1568 * if option is Element -> get size of element 1569 * else use option as a number 1570 * 1571 * @param {String} measurement 1572 * @param {String} size - width or height 1573 * @private 1574 */ 1575proto._getMeasurement = function( measurement, size ) { 1576 var option = this.options[ measurement ]; 1577 var elem; 1578 if ( !option ) { 1579 // default to 0 1580 this[ measurement ] = 0; 1581 } else { 1582 // use option as an element 1583 if ( typeof option == 'string' ) { 1584 elem = this.element.querySelector( option ); 1585 } else if ( option instanceof HTMLElement ) { 1586 elem = option; 1587 } 1588 // use size of element, if element 1589 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 1590 } 1591}; 1592 1593/** 1594 * layout a collection of item elements 1595 * @api public 1596 */ 1597proto.layoutItems = function( items, isInstant ) { 1598 items = this._getItemsForLayout( items ); 1599 1600 this._layoutItems( items, isInstant ); 1601 1602 this._postLayout(); 1603}; 1604 1605/** 1606 * get the items to be laid out 1607 * you may want to skip over some items 1608 * @param {Array} items 1609 * @returns {Array} items 1610 */ 1611proto._getItemsForLayout = function( items ) { 1612 return items.filter( function( item ) { 1613 return !item.isIgnored; 1614 }); 1615}; 1616 1617/** 1618 * layout items 1619 * @param {Array} items 1620 * @param {Boolean} isInstant 1621 */ 1622proto._layoutItems = function( items, isInstant ) { 1623 this._emitCompleteOnItems( 'layout', items ); 1624 1625 if ( !items || !items.length ) { 1626 // no items, emit event with empty array 1627 return; 1628 } 1629 1630 var queue = []; 1631 1632 items.forEach( function( item ) { 1633 // get x/y object from method 1634 var position = this._getItemLayoutPosition( item ); 1635 // enqueue 1636 position.item = item; 1637 position.isInstant = isInstant || item.isLayoutInstant; 1638 queue.push( position ); 1639 }, this ); 1640 1641 this._processLayoutQueue( queue ); 1642}; 1643 1644/** 1645 * get item layout position 1646 * @param {Outlayer.Item} item 1647 * @returns {Object} x and y position 1648 */ 1649proto._getItemLayoutPosition = function( /* item */ ) { 1650 return { 1651 x: 0, 1652 y: 0 1653 }; 1654}; 1655 1656/** 1657 * iterate over array and position each item 1658 * Reason being - separating this logic prevents 'layout invalidation' 1659 * thx @paul_irish 1660 * @param {Array} queue 1661 */ 1662proto._processLayoutQueue = function( queue ) { 1663 queue.forEach( function( obj ) { 1664 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant ); 1665 }, this ); 1666}; 1667 1668/** 1669 * Sets position of item in DOM 1670 * @param {Outlayer.Item} item 1671 * @param {Number} x - horizontal position 1672 * @param {Number} y - vertical position 1673 * @param {Boolean} isInstant - disables transitions 1674 */ 1675proto._positionItem = function( item, x, y, isInstant ) { 1676 if ( isInstant ) { 1677 // if not transition, just set CSS 1678 item.goTo( x, y ); 1679 } else {
vendor: 8,286 bytes, lines 1679-2023
1679 1680 item.moveTo( x, y ); 1681 } 1682}; 1683 1684/** 1685 * Any logic you want to do after each layout, 1686 * i.e. size the container 1687 */ 1688proto._postLayout = function() { 1689 this.resizeContainer(); 1690}; 1691 1692proto.resizeContainer = function() { 1693 var isResizingContainer = this._getOption('resizeContainer'); 1694 if ( !isResizingContainer ) { 1695 return; 1696 } 1697 var size = this._getContainerSize(); 1698 if ( size ) { 1699 this._setContainerMeasure( size.width, true ); 1700 this._setContainerMeasure( size.height, false ); 1701 } 1702}; 1703 1704/** 1705 * Sets width or height of container if returned 1706 * @returns {Object} size 1707 * @param {Number} width 1708 * @param {Number} height 1709 */ 1710proto._getContainerSize = noop; 1711 1712/** 1713 * @param {Number} measure - size of width or height 1714 * @param {Boolean} isWidth 1715 */ 1716proto._setContainerMeasure = function( measure, isWidth ) { 1717 if ( measure === undefined ) { 1718 return; 1719 } 1720 1721 var elemSize = this.size; 1722 // add padding and border width if border box 1723 if ( elemSize.isBorderBox ) { 1724 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 1725 elemSize.borderLeftWidth + elemSize.borderRightWidth : 1726 elemSize.paddingBottom + elemSize.paddingTop + 1727 elemSize.borderTopWidth + elemSize.borderBottomWidth; 1728 } 1729 1730 measure = Math.max( measure, 0 ); 1731 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 1732}; 1733 1734/** 1735 * emit eventComplete on a collection of items events 1736 * @param {String} eventName 1737 * @param {Array} items - Outlayer.Items 1738 */ 1739proto._emitCompleteOnItems = function( eventName, items ) { 1740 var _this = this; 1741 function onComplete() { 1742 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 1743 } 1744 1745 var count = items.length; 1746 if ( !items || !count ) { 1747 onComplete(); 1748 return; 1749 } 1750 1751 var doneCount = 0; 1752 function tick() { 1753 doneCount++; 1754 if ( doneCount == count ) { 1755 onComplete(); 1756 } 1757 } 1758 1759 // bind callback 1760 items.forEach( function( item ) { 1761 item.once( eventName, tick ); 1762 }); 1763}; 1764 1765/** 1766 * emits events via EvEmitter and jQuery events 1767 * @param {String} type - name of event 1768 * @param {Event} event - original event 1769 * @param {Array} args - extra arguments 1770 */ 1771proto.dispatchEvent = function( type, event, args ) { 1772 // add original event to arguments 1773 var emitArgs = event ? [ event ].concat( args ) : args; 1774 this.emitEvent( type, emitArgs ); 1775 1776 if ( jQuery ) { 1777 // set this.$element 1778 this.$element = this.$element || jQuery( this.element ); 1779 if ( event ) { 1780 // create jQuery event 1781 var $event = jQuery.Event( event ); 1782 $event.type = type; 1783 this.$element.trigger( $event, args ); 1784 } else { 1785 // just trigger with type if no event available 1786 this.$element.trigger( type, args ); 1787 } 1788 } 1789}; 1790 1791// -------------------------- ignore & stamps -------------------------- // 1792 1793 1794/** 1795 * keep item in collection, but do not lay it out 1796 * ignored items do not get skipped in layout 1797 * @param {Element} elem 1798 */ 1799proto.ignore = function( elem ) { 1800 var item = this.getItem( elem ); 1801 if ( item ) { 1802 item.isIgnored = true; 1803 } 1804}; 1805 1806/** 1807 * return item to layout collection 1808 * @param {Element} elem 1809 */ 1810proto.unignore = function( elem ) { 1811 var item = this.getItem( elem ); 1812 if ( item ) { 1813 delete item.isIgnored; 1814 } 1815}; 1816 1817/** 1818 * adds elements to stamps 1819 * @param {NodeList, Array, Element, or String} elems 1820 */ 1821proto.stamp = function( elems ) { 1822 elems = this._find( elems ); 1823 if ( !elems ) { 1824 return; 1825 } 1826 1827 this.stamps = this.stamps.concat( elems ); 1828 // ignore 1829 elems.forEach( this.ignore, this ); 1830}; 1831 1832/** 1833 * removes elements to stamps 1834 * @param {NodeList, Array, or Element} elems 1835 */ 1836proto.unstamp = function( elems ) { 1837 elems = this._find( elems ); 1838 if ( !elems ){ 1839 return; 1840 } 1841 1842 elems.forEach( function( elem ) { 1843 // filter out removed stamp elements 1844 utils.removeFrom( this.stamps, elem ); 1845 this.unignore( elem ); 1846 }, this ); 1847}; 1848 1849/** 1850 * finds child elements 1851 * @param {NodeList, Array, Element, or String} elems 1852 * @returns {Array} elems 1853 */ 1854proto._find = function( elems ) { 1855 if ( !elems ) { 1856 return; 1857 } 1858 // if string, use argument as selector string 1859 if ( typeof elems == 'string' ) { 1860 elems = this.element.querySelectorAll( elems ); 1861 } 1862 elems = utils.makeArray( elems ); 1863 return elems; 1864}; 1865 1866proto._manageStamps = function() { 1867 if ( !this.stamps || !this.stamps.length ) { 1868 return; 1869 } 1870 1871 this._getBoundingRect(); 1872 1873 this.stamps.forEach( this._manageStamp, this ); 1874}; 1875 1876// update boundingLeft / Top 1877proto._getBoundingRect = function() { 1878 // get bounding rect for container element 1879 var boundingRect = this.element.getBoundingClientRect(); 1880 var size = this.size; 1881 this._boundingRect = { 1882 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 1883 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 1884 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 1885 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 1886 }; 1887}; 1888 1889/** 1890 * @param {Element} stamp 1891**/ 1892proto._manageStamp = noop; 1893 1894/** 1895 * get x/y position of element relative to container element 1896 * @param {Element} elem 1897 * @returns {Object} offset - has left, top, right, bottom 1898 */ 1899proto._getElementOffset = function( elem ) { 1900 var boundingRect = elem.getBoundingClientRect(); 1901 var thisRect = this._boundingRect; 1902 var size = getSize( elem ); 1903 var offset = { 1904 left: boundingRect.left - thisRect.left - size.marginLeft, 1905 top: boundingRect.top - thisRect.top - size.marginTop, 1906 right: thisRect.right - boundingRect.right - size.marginRight, 1907 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 1908 }; 1909 return offset; 1910}; 1911 1912// -------------------------- resize -------------------------- // 1913 1914// enable event handlers for listeners 1915// i.e. resize -> onresize 1916proto.handleEvent = utils.handleEvent; 1917 1918/** 1919 * Bind layout to window resizing 1920 */ 1921proto.bindResize = function() { 1922 window.addEventListener( 'resize', this ); 1923 this.isResizeBound = true; 1924}; 1925 1926/** 1927 * Unbind layout to window resizing 1928 */ 1929proto.unbindResize = function() { 1930 window.removeEventListener( 'resize', this ); 1931 this.isResizeBound = false; 1932}; 1933 1934proto.onresize = function() { 1935 this.resize(); 1936}; 1937 1938utils.debounceMethod( Outlayer, 'onresize', 100 ); 1939 1940proto.resize = function() { 1941 // don't trigger if size did not change 1942 // or if resize was unbound. See #9 1943 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 1944 return; 1945 } 1946 1947 this.layout(); 1948}; 1949 1950/** 1951 * check if layout is needed post layout 1952 * @returns Boolean 1953 */ 1954proto.needsResizeLayout = function() { 1955 var size = getSize( this.element ); 1956 // check that this.size and size are there 1957 // IE8 triggers resize on body size change, so they might not be 1958 var hasSizes = this.size && size; 1959 return hasSizes && size.innerWidth !== this.size.innerWidth; 1960}; 1961 1962// -------------------------- methods -------------------------- // 1963 1964/** 1965 * add items to Outlayer instance 1966 * @param {Array or NodeList or Element} elems 1967 * @returns {Array} items - Outlayer.Items 1968**/ 1969proto.addItems = function( elems ) { 1970 var items = this._itemize( elems ); 1971 // add items to collection 1972 if ( items.length ) { 1973 this.items = this.items.concat( items ); 1974 } 1975 return items; 1976}; 1977 1978/** 1979 * Layout newly-appended item elements 1980 * @param {Array or NodeList or Element} elems 1981 */ 1982proto.appended = function( elems ) { 1983 var items = this.addItems( elems ); 1984 if ( !items.length ) { 1985 return; 1986 } 1987 // layout and reveal just the new items 1988 this.layoutItems( items, true ); 1989 this.reveal( items ); 1990}; 1991 1992/** 1993 * Layout prepended elements 1994 * @param {Array or NodeList or Element} elems 1995 */ 1996proto.prepended = function( elems ) { 1997 var items = this._itemize( elems ); 1998 if ( !items.length ) { 1999 return; 2000 } 2001 // add items to beginning of collection 2002 var previousItems = this.items.slice(0); 2003 this.items = items.concat( previousItems ); 2004 // start new layout 2005 this._resetLayout(); 2006 this._manageStamps(); 2007 // layout new stuff without transition 2008 this.layoutItems( items, true ); 2009 this.reveal( items ); 2010 // layout previous items 2011 this.layoutItems( previousItems ); 2012}; 2013 2014/** 2015 * reveal a collection of items 2016 * @param {Array of Outlayer.Items} items 2017 */ 2018proto.reveal = function( items ) { 2019 this._emitCompleteOnItems( 'reveal', items ); 2020 if ( !items || !items.length ) { 2021 return; 2022 } 2023
vendor: 2,203 bytes, lines 2023-2125
2023items.forEach( function( item ) { 2024 item.reveal(); 2025 }); 2026}; 2027 2028/** 2029 * hide a collection of items 2030 * @param {Array of Outlayer.Items} items 2031 */ 2032proto.hide = function( items ) { 2033 this._emitCompleteOnItems( 'hide', items ); 2034 if ( !items || !items.length ) { 2035 return; 2036 } 2037 items.forEach( function( item ) { 2038 item.hide(); 2039 }); 2040}; 2041 2042/** 2043 * reveal item elements 2044 * @param {Array}, {Element}, {NodeList} items 2045 */ 2046proto.revealItemElements = function( elems ) { 2047 var items = this.getItems( elems ); 2048 this.reveal( items ); 2049}; 2050 2051/** 2052 * hide item elements 2053 * @param {Array}, {Element}, {NodeList} items 2054 */ 2055proto.hideItemElements = function( elems ) { 2056 var items = this.getItems( elems ); 2057 this.hide( items ); 2058}; 2059 2060/** 2061 * get Outlayer.Item, given an Element 2062 * @param {Element} elem 2063 * @param {Function} callback 2064 * @returns {Outlayer.Item} item 2065 */ 2066proto.getItem = function( elem ) { 2067 // loop through items to get the one that matches 2068 for ( var i=0; i < this.items.length; i++ ) { 2069 var item = this.items[i]; 2070 if ( item.element == elem ) { 2071 // return item 2072 return item; 2073 } 2074 } 2075}; 2076 2077/** 2078 * get collection of Outlayer.Items, given Elements 2079 * @param {Array} elems 2080 * @returns {Array} items - Outlayer.Items 2081 */ 2082proto.getItems = function( elems ) { 2083 elems = utils.makeArray( elems ); 2084 var items = []; 2085 elems.forEach( function( elem ) { 2086 var item = this.getItem( elem ); 2087 if ( item ) { 2088 items.push( item ); 2089 } 2090 }, this ); 2091 2092 return items; 2093}; 2094 2095/** 2096 * remove element(s) from instance and DOM 2097 * @param {Array or NodeList or Element} elems 2098 */ 2099proto.remove = function( elems ) { 2100 var removeItems = this.getItems( elems ); 2101 2102 this._emitCompleteOnItems( 'remove', removeItems ); 2103 2104 // bail if no items to remove 2105 if ( !removeItems || !removeItems.length ) { 2106 return; 2107 } 2108 2109 removeItems.forEach( function( item ) { 2110 item.remove(); 2111 // remove item from collection 2112 utils.removeFrom( this.items, item ); 2113 }, this ); 2114}; 2115 2116// ----- destroy ----- // 2117 2118// remove and disable Outlayer instance 2119proto.destroy = function() { 2120 // clean up dynamic styles 2121 var style = this.element.style; 2122 style.height = ''; 2123 style.position = ''; 2124 style.width = ''; 2125 // destroy items
vendor: 2,836 bytes, lines 2126-2251
2126 this.items.forEach( function( item ) { 2127 item.destroy(); 2128 }); 2129 2130 this.unbindResize(); 2131 2132 var id = this.element.outlayerGUID; 2133 delete instances[ id ]; // remove reference to instance by id 2134 delete this.element.outlayerGUID; 2135 // remove data for jQuery 2136 if ( jQuery ) { 2137 jQuery.removeData( this.element, this.constructor.namespace ); 2138 } 2139 2140}; 2141 2142// -------------------------- data -------------------------- // 2143 2144/** 2145 * get Outlayer instance from element 2146 * @param {Element} elem 2147 * @returns {Outlayer} 2148 */ 2149Outlayer.data = function( elem ) { 2150 elem = utils.getQueryElement( elem ); 2151 var id = elem && elem.outlayerGUID; 2152 return id && instances[ id ]; 2153}; 2154 2155 2156// -------------------------- create Outlayer class -------------------------- // 2157 2158/** 2159 * create a layout class 2160 * @param {String} namespace 2161 */ 2162Outlayer.create = function( namespace, options ) { 2163 // sub-class Outlayer 2164 var Layout = subclass( Outlayer ); 2165 // apply new options and compatOptions 2166 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 2167 utils.extend( Layout.defaults, options ); 2168 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 2169 2170 Layout.namespace = namespace; 2171 2172 Layout.data = Outlayer.data; 2173 2174 // sub-class Item 2175 Layout.Item = subclass( Item ); 2176 2177 // -------------------------- declarative -------------------------- // 2178 2179 utils.htmlInit( Layout, namespace ); 2180 2181 // -------------------------- jQuery bridge -------------------------- // 2182 2183 // make into jQuery plugin 2184 if ( jQuery && jQuery.bridget ) { 2185 jQuery.bridget( namespace, Layout ); 2186 } 2187 2188 return Layout; 2189}; 2190 2191function subclass( Parent ) { 2192 function SubClass() { 2193 Parent.apply( this, arguments ); 2194 } 2195 2196 SubClass.prototype = Object.create( Parent.prototype ); 2197 SubClass.prototype.constructor = SubClass; 2198 2199 return SubClass; 2200} 2201 2202// ----- fin ----- // 2203 2204// back in global 2205Outlayer.Item = Item; 2206 2207return Outlayer; 2208 2209})); 2210 2211/*! 2212 * Masonry v4.0.0 2213 * Cascading grid layout library 2214 * http://masonry.desandro.com 2215 * MIT License 2216 * by David DeSandro 2217 */ 2218 2219( function( window, factory ) { 2220 // universal module definition 2221 /* jshint strict: false */ /*globals define, module, require */ 2222 if ( typeof define == 'function' && define.amd ) { 2223 // AMD 2224 define( [ 2225 'outlayer/outlayer', 2226 'get-size/get-size' 2227 ], 2228 factory ); 2229 } else if ( typeof module == 'object' && module.exports ) { 2230 // CommonJS 2231 module.exports = factory( 2232 require('outlayer'), 2233 require('get-size') 2234 ); 2235 } else { 2236 // browser global 2237 window.Masonry = factory( 2238 window.Outlayer, 2239 window.getSize 2240 ); 2241 } 2242 2243}( window, function factory( Outlayer, getSize ) { 2244 2245 2246 2247// -------------------------- masonryDefinition -------------------------- // 2248 2249 // create an Outlayer layout class 2250 var Masonry = Outlayer.create('masonry'); 2251 // isFitWidth -> fitWidth
vendor: 5,487 bytes, lines 2252-2416
2252 Masonry.compatOptions.fitWidth = 'isFitWidth'; 2253 2254 Masonry.prototype._resetLayout = function() { 2255 this.getSize(); 2256 this._getMeasurement( 'columnWidth', 'outerWidth' ); 2257 this._getMeasurement( 'gutter', 'outerWidth' ); 2258 this.measureColumns(); 2259 2260 // reset column Y 2261 this.colYs = []; 2262 for ( var i=0; i < this.cols; i++ ) { 2263 this.colYs.push( 0 ); 2264 } 2265 2266 this.maxY = 0; 2267 }; 2268 2269 Masonry.prototype.measureColumns = function() { 2270 this.getContainerWidth(); 2271 // if columnWidth is 0, default to outerWidth of first item 2272 if ( !this.columnWidth ) { 2273 var firstItem = this.items[0]; 2274 var firstItemElem = firstItem && firstItem.element; 2275 // columnWidth fall back to item of first element 2276 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 2277 // if first elem has no width, default to size of container 2278 this.containerWidth; 2279 } 2280 2281 var columnWidth = this.columnWidth += this.gutter; 2282 2283 // calculate columns 2284 var containerWidth = this.containerWidth + this.gutter; 2285 var cols = containerWidth / columnWidth; 2286 // fix rounding errors, typically with gutters 2287 var excess = columnWidth - containerWidth % columnWidth; 2288 // if overshoot is less than a pixel, round up, otherwise floor it 2289 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 2290 cols = Math[ mathMethod ]( cols ); 2291 this.cols = Math.max( cols, 1 ); 2292 }; 2293 2294 Masonry.prototype.getContainerWidth = function() { 2295 // container is parent if fit width 2296 var isFitWidth = this._getOption('fitWidth'); 2297 var container = isFitWidth ? this.element.parentNode : this.element; 2298 // check that this.size and size are there 2299 // IE8 triggers resize on body size change, so they might not be 2300 var size = getSize( container ); 2301 this.containerWidth = size && size.innerWidth; 2302 }; 2303 2304 Masonry.prototype._getItemLayoutPosition = function( item ) { 2305 item.getSize(); 2306 // how many columns does this brick span 2307 var remainder = item.size.outerWidth % this.columnWidth; 2308 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 2309 // round if off by 1 pixel, otherwise use ceil 2310 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 2311 colSpan = Math.min( colSpan, this.cols ); 2312 2313 var colGroup = this._getColGroup( colSpan ); 2314 // get the minimum Y value from the columns 2315 var minimumY = Math.min.apply( Math, colGroup ); 2316 var shortColIndex = colGroup.indexOf( minimumY ); 2317 2318 // position the brick 2319 var position = { 2320 x: this.columnWidth * shortColIndex, 2321 y: minimumY 2322 }; 2323 2324 // apply setHeight to necessary columns 2325 var setHeight = minimumY + item.size.outerHeight; 2326 var setSpan = this.cols + 1 - colGroup.length; 2327 for ( var i = 0; i < setSpan; i++ ) { 2328 this.colYs[ shortColIndex + i ] = setHeight; 2329 } 2330 2331 return position; 2332 }; 2333 2334 /** 2335 * @param {Number} colSpan - number of columns the element spans 2336 * @returns {Array} colGroup 2337 */ 2338 Masonry.prototype._getColGroup = function( colSpan ) { 2339 if ( colSpan < 2 ) { 2340 // if brick spans only one column, use all the column Ys 2341 return this.colYs; 2342 } 2343 2344 var colGroup = []; 2345 // how many different places could this brick fit horizontally 2346 var groupCount = this.cols + 1 - colSpan; 2347 // for each group potential horizontal position 2348 for ( var i = 0; i < groupCount; i++ ) { 2349 // make an array of colY values for that one group 2350 var groupColYs = this.colYs.slice( i, i + colSpan ); 2351 // and get the max value of the array 2352 colGroup[i] = Math.max.apply( Math, groupColYs ); 2353 } 2354 return colGroup; 2355 }; 2356 2357 Masonry.prototype._manageStamp = function( stamp ) { 2358 var stampSize = getSize( stamp ); 2359 var offset = this._getElementOffset( stamp ); 2360 // get the columns that this stamp affects 2361 var isOriginLeft = this._getOption('originLeft'); 2362 var firstX = isOriginLeft ? offset.left : offset.right; 2363 var lastX = firstX + stampSize.outerWidth; 2364 var firstCol = Math.floor( firstX / this.columnWidth ); 2365 firstCol = Math.max( 0, firstCol ); 2366 var lastCol = Math.floor( lastX / this.columnWidth ); 2367 // lastCol should not go over if multiple of columnWidth #425 2368 lastCol -= lastX % this.columnWidth ? 0 : 1; 2369 lastCol = Math.min( this.cols - 1, lastCol ); 2370 // set colYs to bottom of the stamp 2371 2372 var isOriginTop = this._getOption('originTop'); 2373 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 2374 stampSize.outerHeight; 2375 for ( var i = firstCol; i <= lastCol; i++ ) { 2376 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 2377 } 2378 }; 2379 2380 Masonry.prototype._getContainerSize = function() { 2381 this.maxY = Math.max.apply( Math, this.colYs ); 2382 var size = { 2383 height: this.maxY 2384 }; 2385 2386 if ( this._getOption('fitWidth') ) { 2387 size.width = this._getContainerFitWidth(); 2388 } 2389 2390 return size; 2391 }; 2392 2393 Masonry.prototype._getContainerFitWidth = function() { 2394 var unusedCols = 0; 2395 // count unused columns 2396 var i = this.cols; 2397 while ( --i ) { 2398 if ( this.colYs[i] !== 0 ) { 2399 break; 2400 } 2401 unusedCols++; 2402 } 2403 // fit container to columns that have been used 2404 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 2405 }; 2406 2407 Masonry.prototype.needsResizeLayout = function() { 2408 var previousWidth = this.containerWidth; 2409 this.getContainerWidth(); 2410 return previousWidth != this.containerWidth; 2411 }; 2412 2413 return Masonry; 2414 2415})); 2416
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.