Produced by Araxis Merge on 2021-05-13 09:09:00 +0000. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
| # | Location | File | Last Modified |
|---|---|---|---|
| 1 | /Applications/Ampps/www/Porto 3.2.2/Theme Files/Magento 2.x/Porto Theme/app/code/Smartwave/Porto/view/frontend/web/js | packery.pkgd.js | 2016-01-16 15:06:58 +0000 |
| 2 | /Applications/Ampps/www/Porto v4.0.0/Theme Files/Magento 2.x/Porto Theme/app/code/Smartwave/Porto/view/frontend/web/js | packery.pkgd.js | 2016-01-16 15:06:58 +0000 |
| Description | Between Files 1 and 2 | |
|---|---|---|
| Text Blocks | Lines | |
| Unchanged | 1 | 8178 |
| Changed | 0 | 0 |
| Inserted | 0 | 0 |
| Removed | 0 | 0 |
| Whitespace | Consecutive whitespace is treated as a single space |
|---|---|
| Character case | Differences in character case are significant |
| Line endings | Differences in line endings (CR and LF characters) are ignored |
| CR/LF characters | Not shown in the comparison detail |
| Active line-pairing rules |
No regular expressions were active.
| 1 | /*! | 1 | /*! | |||
| 2 | * Packery PACKAGED v1.4.3 | 2 | * Packery PACKAGED v1.4.3 | |||
| 3 | * bin-packing layout library | 3 | * bin-packing layout library | |||
| 4 | * | 4 | * | |||
| 5 | * Licensed GPLv3 for open source use | 5 | * Licensed GPLv3 for open source use | |||
| 6 | * or Flickity Commercial License for commercial use | 6 | * or Flickity Commercial License for commercial use | |||
| 7 | * | 7 | * | |||
| 8 | * http://packery.metafizzy.co | 8 | * http://packery.metafizzy.co | |||
| 9 | * Copyright 2015 Metafizzy | 9 | * Copyright 2015 Metafizzy | |||
| 10 | */ | 10 | */ | |||
| 11 | 11 | |||||
| 12 | /** | 12 | /** | |||
| 13 | * Bridget makes jQuery widgets | 13 | * Bridget makes jQuery widgets | |||
| 14 | * v1.1.0 | 14 | * v1.1.0 | |||
| 15 | * MIT license | 15 | * MIT license | |||
| 16 | */ | 16 | */ | |||
| 17 | 17 | |||||
| 18 | ( function( window ) { | 18 | ( function( window ) { | |||
| 19 | 19 | |||||
| 20 | 20 | |||||
| 21 | 21 | |||||
| 22 | // -------------------------- utils -------------------------- // | 22 | // -------------------------- utils -------------------------- // | |||
| 23 | 23 | |||||
| 24 | var slice = Array.prototype.slice; | 24 | var slice = Array.prototype.slice; | |||
| 25 | 25 | |||||
| 26 | function noop() {} | 26 | function noop() {} | |||
| 27 | 27 | |||||
| 28 | // -------------------------- definition -------------------------- // | 28 | // -------------------------- definition -------------------------- // | |||
| 29 | 29 | |||||
| 30 | function defineBridget( $ ) { | 30 | function defineBridget( $ ) { | |||
| 31 | 31 | |||||
| 32 | // bail if no jQuery | 32 | // bail if no jQuery | |||
| 33 | if ( !$ ) { | 33 | if ( !$ ) { | |||
| 34 | return; | 34 | return; | |||
| 35 | } | 35 | } | |||
| 36 | 36 | |||||
| 37 | // -------------------------- addOptionMethod -------------------------- // | 37 | // -------------------------- addOptionMethod -------------------------- // | |||
| 38 | 38 | |||||
| 39 | /** | 39 | /** | |||
| 40 | * adds option method -> $().plugin('option', {...}) | 40 | * adds option method -> $().plugin('option', {...}) | |||
| 41 | * @param {Function} PluginClass - constructor class | 41 | * @param {Function} PluginClass - constructor class | |||
| 42 | */ | 42 | */ | |||
| 43 | function addOptionMethod( PluginClass ) { | 43 | function addOptionMethod( PluginClass ) { | |||
| 44 | // don't overwrite original option method | 44 | // don't overwrite original option method | |||
| 45 | if ( PluginClass.prototype.option ) { | 45 | if ( PluginClass.prototype.option ) { | |||
| 46 | return; | 46 | return; | |||
| 47 | } | 47 | } | |||
| 48 | 48 | |||||
| 49 | // option setter | 49 | // option setter | |||
| 50 | PluginClass.prototype.option = function( opts ) { | 50 | PluginClass.prototype.option = function( opts ) { | |||
| 51 | // bail out if not an object | 51 | // bail out if not an object | |||
| 52 | if ( !$.isPlainObject( opts ) ){ | 52 | if ( !$.isPlainObject( opts ) ){ | |||
| 53 | return; | 53 | return; | |||
| 54 | } | 54 | } | |||
| 55 | this.options = $.extend( true, this.options, opts ); | 55 | this.options = $.extend( true, this.options, opts ); | |||
| 56 | }; | 56 | }; | |||
| 57 | } | 57 | } | |||
| 58 | 58 | |||||
| 59 | // -------------------------- plugin bridge -------------------------- // | 59 | // -------------------------- plugin bridge -------------------------- // | |||
| 60 | 60 | |||||
| 61 | // helper function for logging errors | 61 | // helper function for logging errors | |||
| 62 | // $.error breaks jQuery chaining | 62 | // $.error breaks jQuery chaining | |||
| 63 | var logError = typeof console === 'undefined' ? noop : | 63 | var logError = typeof console === 'undefined' ? noop : | |||
| 64 | function( message ) { | 64 | function( message ) { | |||
| 65 | console.error( message ); | 65 | console.error( message ); | |||
| 66 | }; | 66 | }; | |||
| 67 | 67 | |||||
| 68 | /** | 68 | /** | |||
| 69 | * jQuery plugin bridge, access methods like $elem.plugin('method') | 69 | * jQuery plugin bridge, access methods like $elem.plugin('method') | |||
| 70 | * @param {String} namespace - plugin name | 70 | * @param {String} namespace - plugin name | |||
| 71 | * @param {Function} PluginClass - constructor class | 71 | * @param {Function} PluginClass - constructor class | |||
| 72 | */ | 72 | */ | |||
| 73 | function bridge( namespace, PluginClass ) { | 73 | function bridge( namespace, PluginClass ) { | |||
| 74 | // add to jQuery fn namespace | 74 | // add to jQuery fn namespace | |||
| 75 | $.fn[ namespace ] = function( options ) { | 75 | $.fn[ namespace ] = function( options ) { | |||
| 76 | if ( typeof options === 'string' ) { | 76 | if ( typeof options === 'string' ) { | |||
| 77 | // call plugin method when first argument is a string | 77 | // call plugin method when first argument is a string | |||
| 78 | // get arguments for method | 78 | // get arguments for method | |||
| 79 | var args = slice.call( arguments, 1 ); | 79 | var args = slice.call( arguments, 1 ); | |||
| 80 | 80 | |||||
| 81 | for ( var i=0, len = this.length; i < len; i++ ) { | 81 | for ( var i=0, len = this.length; i < len; i++ ) { | |||
| 82 | var elem = this[i]; | 82 | var elem = this[i]; | |||
| 83 | var instance = $.data( elem, namespace ); | 83 | var instance = $.data( elem, namespace ); | |||
| 84 | if ( !instance ) { | 84 | if ( !instance ) { | |||
| 85 | logError( "cannot call methods on " + namespace + " prior to initialization; " + | 85 | logError( "cannot call methods on " + namespace + " prior to initialization; " + | |||
| 86 | "attempted to call '" + options + "'" ); | 86 | "attempted to call '" + options + "'" ); | |||
| 87 | continue; | 87 | continue; | |||
| 88 | } | 88 | } | |||
| 89 | if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) { | 89 | if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) { | |||
| 90 | logError( "no such method '" + options + "' for " + namespace + " instance" ); | 90 | logError( "no such method '" + options + "' for " + namespace + " instance" ); | |||
| 91 | continue; | 91 | continue; | |||
| 92 | } | 92 | } | |||
| 93 | 93 | |||||
| 94 | // trigger method with arguments | 94 | // trigger method with arguments | |||
| 95 | var returnValue = instance[ options ].apply( instance, args ); | 95 | var returnValue = instance[ options ].apply( instance, args ); | |||
| 96 | 96 | |||||
| 97 | // break look and return first value if provided | 97 | // break look and return first value if provided | |||
| 98 | if ( returnValue !== undefined ) { | 98 | if ( returnValue !== undefined ) { | |||
| 99 | return returnValue; | 99 | return returnValue; | |||
| 100 | } | 100 | } | |||
| 101 | } | 101 | } | |||
| 102 | // return this if no return value | 102 | // return this if no return value | |||
| 103 | return this; | 103 | return this; | |||
| 104 | } else { | 104 | } else { | |||
| 105 | return this.each( function() { | 105 | return this.each( function() { | |||
| 106 | var instance = $.data( this, namespace ); | 106 | var instance = $.data( this, namespace ); | |||
| 107 | if ( instance ) { | 107 | if ( instance ) { | |||
| 108 | // apply options & init | 108 | // apply options & init | |||
| 109 | instance.option( options ); | 109 | instance.option( options ); | |||
| 110 | instance._init(); | 110 | instance._init(); | |||
| 111 | } else { | 111 | } else { | |||
| 112 | // initialize new instance | 112 | // initialize new instance | |||
| 113 | instance = new PluginClass( this, options ); | 113 | instance = new PluginClass( this, options ); | |||
| 114 | $.data( this, namespace, instance ); | 114 | $.data( this, namespace, instance ); | |||
| 115 | } | 115 | } | |||
| 116 | }); | 116 | }); | |||
| 117 | } | 117 | } | |||
| 118 | }; | 118 | }; | |||
| 119 | 119 | |||||
| 120 | } | 120 | } | |||
| 121 | 121 | |||||
| 122 | // -------------------------- bridget -------------------------- // | 122 | // -------------------------- bridget -------------------------- // | |||
| 123 | 123 | |||||
| 124 | /** | 124 | /** | |||
| 125 | * converts a Prototypical class into a proper jQuery plugin | 125 | * converts a Prototypical class into a proper jQuery plugin | |||
| 126 | * the class must have a ._init method | 126 | * the class must have a ._init method | |||
| 127 | * @param {String} namespace - plugin name, used in $().pluginName | 127 | * @param {String} namespace - plugin name, used in $().pluginName | |||
| 128 | * @param {Function} PluginClass - constructor class | 128 | * @param {Function} PluginClass - constructor class | |||
| 129 | */ | 129 | */ | |||
| 130 | $.bridget = function( namespace, PluginClass ) { | 130 | $.bridget = function( namespace, PluginClass ) { | |||
| 131 | addOptionMethod( PluginClass ); | 131 | addOptionMethod( PluginClass ); | |||
| 132 | bridge( namespace, PluginClass ); | 132 | bridge( namespace, PluginClass ); | |||
| 133 | }; | 133 | }; | |||
| 134 | 134 | |||||
| 135 | return $.bridget; | 135 | return $.bridget; | |||
| 136 | 136 | |||||
| 137 | } | 137 | } | |||
| 138 | 138 | |||||
| 139 | // transport | 139 | // transport | |||
| 140 | if ( typeof define === 'function' && define.amd ) { | 140 | if ( typeof define === 'function' && define.amd ) { | |||
| 141 | // AMD | 141 | // AMD | |||
| 142 | define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget ); | 142 | define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget ); | |||
| 143 | } else if ( typeof exports === 'object' ) { | 143 | } else if ( typeof exports === 'object' ) { | |||
| 144 | defineBridget( require('jquery') ); | 144 | defineBridget( require('jquery') ); | |||
| 145 | } else { | 145 | } else { | |||
| 146 | // get jquery from browser global | 146 | // get jquery from browser global | |||
| 147 | defineBridget( window.jQuery ); | 147 | defineBridget( window.jQuery ); | |||
| 148 | } | 148 | } | |||
| 149 | defineBridget( window.jQuery ); | 149 | defineBridget( window.jQuery ); | |||
| 150 | })( window ); | 150 | })( window ); | |||
| 151 | 151 | |||||
| 152 | /*! | 152 | /*! | |||
| 153 | * classie v1.0.1 | 153 | * classie v1.0.1 | |||
| 154 | * class helper functions | 154 | * class helper functions | |||
| 155 | * from bonzo https://github.com/ded/bonzo | 155 | * from bonzo https://github.com/ded/bonzo | |||
| 156 | * MIT license | 156 | * MIT license | |||
| 157 | * | 157 | * | |||
| 158 | * classie.has( elem, 'my-class' ) -> true/false | 158 | * classie.has( elem, 'my-class' ) -> true/false | |||
| 159 | * classie.add( elem, 'my-new-class' ) | 159 | * classie.add( elem, 'my-new-class' ) | |||
| 160 | * classie.remove( elem, 'my-unwanted-class' ) | 160 | * classie.remove( elem, 'my-unwanted-class' ) | |||
| 161 | * classie.toggle( elem, 'my-class' ) | 161 | * classie.toggle( elem, 'my-class' ) | |||
| 162 | */ | 162 | */ | |||
| 163 | 163 | |||||
| 164 | /*jshint browser: true, strict: true, undef: true, unused: true */ | 164 | /*jshint browser: true, strict: true, undef: true, unused: true */ | |||
| 165 | /*global define: false, module: false */ | 165 | /*global define: false, module: false */ | |||
| 166 | 166 | |||||
| 167 | ( function( window ) { | 167 | ( function( window ) { | |||
| 168 | 168 | |||||
| 169 | 169 | |||||
| 170 | 170 | |||||
| 171 | // class helper functions from bonzo https://github.com/ded/bonzo | 171 | // class helper functions from bonzo https://github.com/ded/bonzo | |||
| 172 | 172 | |||||
| 173 | function classReg( className ) { | 173 | function classReg( className ) { | |||
| 174 | return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); | 174 | return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); | |||
| 175 | } | 175 | } | |||
| 176 | 176 | |||||
| 177 | // classList support for class management | 177 | // classList support for class management | |||
| 178 | // altho to be fair, the api sucks because it won't accept multiple classes at once | 178 | // altho to be fair, the api sucks because it won't accept multiple classes at once | |||
| 179 | var hasClass, addClass, removeClass; | 179 | var hasClass, addClass, removeClass; | |||
| 180 | 180 | |||||
| 181 | if ( 'classList' in document.documentElement ) { | 181 | if ( 'classList' in document.documentElement ) { | |||
| 182 | hasClass = function( elem, c ) { | 182 | hasClass = function( elem, c ) { | |||
| 183 | return elem.classList.contains( c ); | 183 | return elem.classList.contains( c ); | |||
| 184 | }; | 184 | }; | |||
| 185 | addClass = function( elem, c ) { | 185 | addClass = function( elem, c ) { | |||
| 186 | elem.classList.add( c ); | 186 | elem.classList.add( c ); | |||
| 187 | }; | 187 | }; | |||
| 188 | removeClass = function( elem, c ) { | 188 | removeClass = function( elem, c ) { | |||
| 189 | elem.classList.remove( c ); | 189 | elem.classList.remove( c ); | |||
| 190 | }; | 190 | }; | |||
| 191 | } | 191 | } | |||
| 192 | else { | 192 | else { | |||
| 193 | hasClass = function( elem, c ) { | 193 | hasClass = function( elem, c ) { | |||
| 194 | return classReg( c ).test( elem.className ); | 194 | return classReg( c ).test( elem.className ); | |||
| 195 | }; | 195 | }; | |||
| 196 | addClass = function( elem, c ) { | 196 | addClass = function( elem, c ) { | |||
| 197 | if ( !hasClass( elem, c ) ) { | 197 | if ( !hasClass( elem, c ) ) { | |||
| 198 | elem.className = elem.className + ' ' + c; | 198 | elem.className = elem.className + ' ' + c; | |||
| 199 | } | 199 | } | |||
| 200 | }; | 200 | }; | |||
| 201 | removeClass = function( elem, c ) { | 201 | removeClass = function( elem, c ) { | |||
| 202 | elem.className = elem.className.replace( classReg( c ), ' ' ); | 202 | elem.className = elem.className.replace( classReg( c ), ' ' ); | |||
| 203 | }; | 203 | }; | |||
| 204 | } | 204 | } | |||
| 205 | 205 | |||||
| 206 | function toggleClass( elem, c ) { | 206 | function toggleClass( elem, c ) { | |||
| 207 | var fn = hasClass( elem, c ) ? removeClass : addClass; | 207 | var fn = hasClass( elem, c ) ? removeClass : addClass; | |||
| 208 | fn( elem, c ); | 208 | fn( elem, c ); | |||
| 209 | } | 209 | } | |||
| 210 | 210 | |||||
| 211 | var classie = { | 211 | var classie = { | |||
| 212 | // full names | 212 | // full names | |||
| 213 | hasClass: hasClass, | 213 | hasClass: hasClass, | |||
| 214 | addClass: addClass, | 214 | addClass: addClass, | |||
| 215 | removeClass: removeClass, | 215 | removeClass: removeClass, | |||
| 216 | toggleClass: toggleClass, | 216 | toggleClass: toggleClass, | |||
| 217 | // short names | 217 | // short names | |||
| 218 | has: hasClass, | 218 | has: hasClass, | |||
| 219 | add: addClass, | 219 | add: addClass, | |||
| 220 | remove: removeClass, | 220 | remove: removeClass, | |||
| 221 | toggle: toggleClass | 221 | toggle: toggleClass | |||
| 222 | }; | 222 | }; | |||
| 223 | 223 | |||||
| 224 | // transport | 224 | // transport | |||
| 225 | if ( typeof define === 'function' && define.amd ) { | 225 | if ( typeof define === 'function' && define.amd ) { | |||
| 226 | // AMD | 226 | // AMD | |||
| 227 | define( 'classie/classie',classie ); | 227 | define( 'classie/classie',classie ); | |||
| 228 | } else if ( typeof exports === 'object' ) { | 228 | } else if ( typeof exports === 'object' ) { | |||
| 229 | // CommonJS | 229 | // CommonJS | |||
| 230 | module.exports = classie; | 230 | module.exports = classie; | |||
| 231 | } else { | 231 | } else { | |||
| 232 | // browser global | 232 | // browser global | |||
| 233 | window.classie = classie; | 233 | window.classie = classie; | |||
| 234 | } | 234 | } | |||
| 235 | 235 | |||||
| 236 | })( window ); | 236 | })( window ); | |||
| 237 | 237 | |||||
| 238 | /*! | 238 | /*! | |||
| 239 | * getStyleProperty v1.0.4 | 239 | * getStyleProperty v1.0.4 | |||
| 240 | * original by kangax | 240 | * original by kangax | |||
| 241 | * http://perfectionkills.com/feature-testing-css-properties/ | 241 | * http://perfectionkills.com/feature-testing-css-properties/ | |||
| 242 | * MIT license | 242 | * MIT license | |||
| 243 | */ | 243 | */ | |||
| 244 | 244 | |||||
| 245 | /*jshint browser: true, strict: true, undef: true */ | 245 | /*jshint browser: true, strict: true, undef: true */ | |||
| 246 | /*global define: false, exports: false, module: false */ | 246 | /*global define: false, exports: false, module: false */ | |||
| 247 | 247 | |||||
| 248 | ( function( window ) { | 248 | ( function( window ) { | |||
| 249 | 249 | |||||
| 250 | 250 | |||||
| 251 | 251 | |||||
| 252 | var prefixes = 'Webkit Moz ms Ms O'.split(' '); | 252 | var prefixes = 'Webkit Moz ms Ms O'.split(' '); | |||
| 253 | var docElemStyle = document.documentElement.style; | 253 | var docElemStyle = document.documentElement.style; | |||
| 254 | 254 | |||||
| 255 | function getStyleProperty( propName ) { | 255 | function getStyleProperty( propName ) { | |||
| 256 | if ( !propName ) { | 256 | if ( !propName ) { | |||
| 257 | return; | 257 | return; | |||
| 258 | } | 258 | } | |||
| 259 | 259 | |||||
| 260 | // test standard property first | 260 | // test standard property first | |||
| 261 | if ( typeof docElemStyle[ propName ] === 'string' ) { | 261 | if ( typeof docElemStyle[ propName ] === 'string' ) { | |||
| 262 | return propName; | 262 | return propName; | |||
| 263 | } | 263 | } | |||
| 264 | 264 | |||||
| 265 | // capitalize | 265 | // capitalize | |||
| 266 | propName = propName.charAt(0).toUpperCase() + propName.slice(1); | 266 | propName = propName.charAt(0).toUpperCase() + propName.slice(1); | |||
| 267 | 267 | |||||
| 268 | // test vendor specific properties | 268 | // test vendor specific properties | |||
| 269 | var prefixed; | 269 | var prefixed; | |||
| 270 | for ( var i=0, len = prefixes.length; i < len; i++ ) { | 270 | for ( var i=0, len = prefixes.length; i < len; i++ ) { | |||
| 271 | prefixed = prefixes[i] + propName; | 271 | prefixed = prefixes[i] + propName; | |||
| 272 | if ( typeof docElemStyle[ prefixed ] === 'string' ) { | 272 | if ( typeof docElemStyle[ prefixed ] === 'string' ) { | |||
| 273 | return prefixed; | 273 | return prefixed; | |||
| 274 | } | 274 | } | |||
| 275 | } | 275 | } | |||
| 276 | } | 276 | } | |||
| 277 | 277 | |||||
| 278 | // transport | 278 | // transport | |||
| 279 | if ( typeof define === 'function' && define.amd ) { | 279 | if ( typeof define === 'function' && define.amd ) { | |||
| 280 | // AMD | 280 | // AMD | |||
| 281 | define( 'get-style-property/get-style-property',[],function() { | 281 | define( 'get-style-property/get-style-property',[],function() { | |||
| 282 | return getStyleProperty; | 282 | return getStyleProperty; | |||
| 283 | }); | 283 | }); | |||
| 284 | } else if ( typeof exports === 'object' ) { | 284 | } else if ( typeof exports === 'object' ) { | |||
| 285 | // CommonJS for Component | 285 | // CommonJS for Component | |||
| 286 | module.exports = getStyleProperty; | 286 | module.exports = getStyleProperty; | |||
| 287 | } else { | 287 | } else { | |||
| 288 | // browser global | 288 | // browser global | |||
| 289 | window.getStyleProperty = getStyleProperty; | 289 | window.getStyleProperty = getStyleProperty; | |||
| 290 | } | 290 | } | |||
| 291 | 291 | |||||
| 292 | })( window ); | 292 | })( window ); | |||
| 293 | 293 | |||||
| 294 | /*! | 294 | /*! | |||
| 295 | * getSize v1.2.2 | 295 | * getSize v1.2.2 | |||
| 296 | * measure size of elements | 296 | * measure size of elements | |||
| 297 | * MIT license | 297 | * MIT license | |||
| 298 | */ | 298 | */ | |||
| 299 | 299 | |||||
| 300 | /*jshint browser: true, strict: true, undef: true, unused: true */ | 300 | /*jshint browser: true, strict: true, undef: true, unused: true */ | |||
| 301 | /*global define: false, exports: false, require: false, module: false, console: false */ | 301 | /*global define: false, exports: false, require: false, module: false, console: false */ | |||
| 302 | 302 | |||||
| 303 | ( function( window, undefined ) { | 303 | ( function( window, undefined ) { | |||
| 304 | 304 | |||||
| 305 | 305 | |||||
| 306 | 306 | |||||
| 307 | // -------------------------- helpers -------------------------- // | 307 | // -------------------------- helpers -------------------------- // | |||
| 308 | 308 | |||||
| 309 | // get a number from a string, not a percentage | 309 | // get a number from a string, not a percentage | |||
| 310 | function getStyleSize( value ) { | 310 | function getStyleSize( value ) { | |||
| 311 | var num = parseFloat( value ); | 311 | var num = parseFloat( value ); | |||
| 312 | // not a percent like '100%', and a number | 312 | // not a percent like '100%', and a number | |||
| 313 | var isValid = value.indexOf('%') === -1 && !isNaN( num ); | 313 | var isValid = value.indexOf('%') === -1 && !isNaN( num ); | |||
| 314 | return isValid && num; | 314 | return isValid && num; | |||
| 315 | } | 315 | } | |||
| 316 | 316 | |||||
| 317 | function noop() {} | 317 | function noop() {} | |||
| 318 | 318 | |||||
| 319 | var logError = typeof console === 'undefined' ? noop : | 319 | var logError = typeof console === 'undefined' ? noop : | |||
| 320 | function( message ) { | 320 | function( message ) { | |||
| 321 | console.error( message ); | 321 | console.error( message ); | |||
| 322 | }; | 322 | }; | |||
| 323 | 323 | |||||
| 324 | // -------------------------- measurements -------------------------- // | 324 | // -------------------------- measurements -------------------------- // | |||
| 325 | 325 | |||||
| 326 | var measurements = [ | 326 | var measurements = [ | |||
| 327 | 'paddingLeft', | 327 | 'paddingLeft', | |||
| 328 | 'paddingRight', | 328 | 'paddingRight', | |||
| 329 | 'paddingTop', | 329 | 'paddingTop', | |||
| 330 | 'paddingBottom', | 330 | 'paddingBottom', | |||
| 331 | 'marginLeft', | 331 | 'marginLeft', | |||
| 332 | 'marginRight', | 332 | 'marginRight', | |||
| 333 | 'marginTop', | 333 | 'marginTop', | |||
| 334 | 'marginBottom', | 334 | 'marginBottom', | |||
| 335 | 'borderLeftWidth', | 335 | 'borderLeftWidth', | |||
| 336 | 'borderRightWidth', | 336 | 'borderRightWidth', | |||
| 337 | 'borderTopWidth', | 337 | 'borderTopWidth', | |||
| 338 | 'borderBottomWidth' | 338 | 'borderBottomWidth' | |||
| 339 | ]; | 339 | ]; | |||
| 340 | 340 | |||||
| 341 | function getZeroSize() { | 341 | function getZeroSize() { | |||
| 342 | var size = { | 342 | var size = { | |||
| 343 | width: 0, | 343 | width: 0, | |||
| 344 | height: 0, | 344 | height: 0, | |||
| 345 | innerWidth: 0, | 345 | innerWidth: 0, | |||
| 346 | innerHeight: 0, | 346 | innerHeight: 0, | |||
| 347 | outerWidth: 0, | 347 | outerWidth: 0, | |||
| 348 | outerHeight: 0 | 348 | outerHeight: 0 | |||
| 349 | }; | 349 | }; | |||
| 350 | for ( var i=0, len = measurements.length; i < len; i++ ) { | 350 | for ( var i=0, len = measurements.length; i < len; i++ ) { | |||
| 351 | var measurement = measurements[i]; | 351 | var measurement = measurements[i]; | |||
| 352 | size[ measurement ] = 0; | 352 | size[ measurement ] = 0; | |||
| 353 | } | 353 | } | |||
| 354 | return size; | 354 | return size; | |||
| 355 | } | 355 | } | |||
| 356 | 356 | |||||
| 357 | 357 | |||||
| 358 | 358 | |||||
| 359 | function defineGetSize( getStyleProperty ) { | 359 | function defineGetSize( getStyleProperty ) { | |||
| 360 | 360 | |||||
| 361 | // -------------------------- setup -------------------------- // | 361 | // -------------------------- setup -------------------------- // | |||
| 362 | 362 | |||||
| 363 | var isSetup = false; | 363 | var isSetup = false; | |||
| 364 | 364 | |||||
| 365 | var getStyle, boxSizingProp, isBoxSizeOuter; | 365 | var getStyle, boxSizingProp, isBoxSizeOuter; | |||
| 366 | 366 | |||||
| 367 | /** | 367 | /** | |||
| 368 | * setup vars and functions | 368 | * setup vars and functions | |||
| 369 | * do it on initial getSize(), rather than on script load | 369 | * do it on initial getSize(), rather than on script load | |||
| 370 | * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397 | 370 | * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397 | |||
| 371 | */ | 371 | */ | |||
| 372 | function setup() { | 372 | function setup() { | |||
| 373 | // setup once | 373 | // setup once | |||
| 374 | if ( isSetup ) { | 374 | if ( isSetup ) { | |||
| 375 | return; | 375 | return; | |||
| 376 | } | 376 | } | |||
| 377 | isSetup = true; | 377 | isSetup = true; | |||
| 378 | 378 | |||||
| 379 | var getComputedStyle = window.getComputedStyle; | 379 | var getComputedStyle = window.getComputedStyle; | |||
| 380 | getStyle = ( function() { | 380 | getStyle = ( function() { | |||
| 381 | var getStyleFn = getComputedStyle ? | 381 | var getStyleFn = getComputedStyle ? | |||
| 382 | function( elem ) { | 382 | function( elem ) { | |||
| 383 | return getComputedStyle( elem, null ); | 383 | return getComputedStyle( elem, null ); | |||
| 384 | } : | 384 | } : | |||
| 385 | function( elem ) { | 385 | function( elem ) { | |||
| 386 | return elem.currentStyle; | 386 | return elem.currentStyle; | |||
| 387 | }; | 387 | }; | |||
| 388 | 388 | |||||
| 389 | return function getStyle( elem ) { | 389 | return function getStyle( elem ) { | |||
| 390 | var style = getStyleFn( elem ); | 390 | var style = getStyleFn( elem ); | |||
| 391 | if ( !style ) { | 391 | if ( !style ) { | |||
| 392 | logError( 'Style returned ' + style + | 392 | logError( 'Style returned ' + style + | |||
| 393 | '. Are you running this code in a hidden iframe on Firefox? ' + | 393 | '. Are you running this code in a hidden iframe on Firefox? ' + | |||
| 394 | 'See http://bit.ly/getsizebug1' ); | 394 | 'See http://bit.ly/getsizebug1' ); | |||
| 395 | } | 395 | } | |||
| 396 | return style; | 396 | return style; | |||
| 397 | }; | 397 | }; | |||
| 398 | })(); | 398 | })(); | |||
| 399 | 399 | |||||
| 400 | // -------------------------- box sizing -------------------------- // | 400 | // -------------------------- box sizing -------------------------- // | |||
| 401 | 401 | |||||
| 402 | boxSizingProp = getStyleProperty('boxSizing'); | 402 | boxSizingProp = getStyleProperty('boxSizing'); | |||
| 403 | 403 | |||||
| 404 | /** | 404 | /** | |||
| 405 | * WebKit measures the outer-width on style.width on border-box elems | 405 | * WebKit measures the outer-width on style.width on border-box elems | |||
| 406 | * IE & Firefox measures the inner-width | 406 | * IE & Firefox measures the inner-width | |||
| 407 | */ | 407 | */ | |||
| 408 | if ( boxSizingProp ) { | 408 | if ( boxSizingProp ) { | |||
| 409 | var div = document.createElement('div'); | 409 | var div = document.createElement('div'); | |||
| 410 | div.style.width = '200px'; | 410 | div.style.width = '200px'; | |||
| 411 | div.style.padding = '1px 2px 3px 4px'; | 411 | div.style.padding = '1px 2px 3px 4px'; | |||
| 412 | div.style.borderStyle = 'solid'; | 412 | div.style.borderStyle = 'solid'; | |||
| 413 | div.style.borderWidth = '1px 2px 3px 4px'; | 413 | div.style.borderWidth = '1px 2px 3px 4px'; | |||
| 414 | div.style[ boxSizingProp ] = 'border-box'; | 414 | div.style[ boxSizingProp ] = 'border-box'; | |||
| 415 | 415 | |||||
| 416 | var body = document.body || document.documentElement; | 416 | var body = document.body || document.documentElement; | |||
| 417 | body.appendChild( div ); | 417 | body.appendChild( div ); | |||
| 418 | var style = getStyle( div ); | 418 | var style = getStyle( div ); | |||
| 419 | 419 | |||||
| 420 | isBoxSizeOuter = getStyleSize( style.width ) === 200; | 420 | isBoxSizeOuter = getStyleSize( style.width ) === 200; | |||
| 421 | body.removeChild( div ); | 421 | body.removeChild( div ); | |||
| 422 | } | 422 | } | |||
| 423 | 423 | |||||
| 424 | } | 424 | } | |||
| 425 | 425 | |||||
| 426 | // -------------------------- getSize -------------------------- // | 426 | // -------------------------- getSize -------------------------- // | |||
| 427 | 427 | |||||
| 428 | function getSize( elem ) { | 428 | function getSize( elem ) { | |||
| 429 | setup(); | 429 | setup(); | |||
| 430 | 430 | |||||
| 431 | // use querySeletor if elem is string | 431 | // use querySeletor if elem is string | |||
| 432 | if ( typeof elem === 'string' ) { | 432 | if ( typeof elem === 'string' ) { | |||
| 433 | elem = document.querySelector( elem ); | 433 | elem = document.querySelector( elem ); | |||
| 434 | } | 434 | } | |||
| 435 | 435 | |||||
| 436 | // do not proceed on non-objects | 436 | // do not proceed on non-objects | |||
| 437 | if ( !elem || typeof elem !== 'object' || !elem.nodeType ) { | 437 | if ( !elem || typeof elem !== 'object' || !elem.nodeType ) { | |||
| 438 | return; | 438 | return; | |||
| 439 | } | 439 | } | |||
| 440 | 440 | |||||
| 441 | var style = getStyle( elem ); | 441 | var style = getStyle( elem ); | |||
| 442 | 442 | |||||
| 443 | // if hidden, everything is 0 | 443 | // if hidden, everything is 0 | |||
| 444 | if ( style.display === 'none' ) { | 444 | if ( style.display === 'none' ) { | |||
| 445 | return getZeroSize(); | 445 | return getZeroSize(); | |||
| 446 | } | 446 | } | |||
| 447 | 447 | |||||
| 448 | var size = {}; | 448 | var size = {}; | |||
| 449 | size.width = elem.offsetWidth; | 449 | size.width = elem.offsetWidth; | |||
| 450 | size.height = elem.offsetHeight; | 450 | size.height = elem.offsetHeight; | |||
| 451 | 451 | |||||
| 452 | var isBorderBox = size.isBorderBox = !!( boxSizingProp && | 452 | var isBorderBox = size.isBorderBox = !!( boxSizingProp && | |||
| 453 | style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' ); | 453 | style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' ); | |||
| 454 | 454 | |||||
| 455 | // get all measurements | 455 | // get all measurements | |||
| 456 | for ( var i=0, len = measurements.length; i < len; i++ ) { | 456 | for ( var i=0, len = measurements.length; i < len; i++ ) { | |||
| 457 | var measurement = measurements[i]; | 457 | var measurement = measurements[i]; | |||
| 458 | var value = style[ measurement ]; | 458 | var value = style[ measurement ]; | |||
| 459 | value = mungeNonPixel( elem, value ); | 459 | value = mungeNonPixel( elem, value ); | |||
| 460 | var num = parseFloat( value ); | 460 | var num = parseFloat( value ); | |||
| 461 | // any 'auto', 'medium' value will be 0 | 461 | // any 'auto', 'medium' value will be 0 | |||
| 462 | size[ measurement ] = !isNaN( num ) ? num : 0; | 462 | size[ measurement ] = !isNaN( num ) ? num : 0; | |||
| 463 | } | 463 | } | |||
| 464 | 464 | |||||
| 465 | var paddingWidth = size.paddingLeft + size.paddingRight; | 465 | var paddingWidth = size.paddingLeft + size.paddingRight; | |||
| 466 | var paddingHeight = size.paddingTop + size.paddingBottom; | 466 | var paddingHeight = size.paddingTop + size.paddingBottom; | |||
| 467 | var marginWidth = size.marginLeft + size.marginRight; | 467 | var marginWidth = size.marginLeft + size.marginRight; | |||
| 468 | var marginHeight = size.marginTop + size.marginBottom; | 468 | var marginHeight = size.marginTop + size.marginBottom; | |||
| 469 | var borderWidth = size.borderLeftWidth + size.borderRightWidth; | 469 | var borderWidth = size.borderLeftWidth + size.borderRightWidth; | |||
| 470 | var borderHeight = size.borderTopWidth + size.borderBottomWidth; | 470 | var borderHeight = size.borderTopWidth + size.borderBottomWidth; | |||
| 471 | 471 | |||||
| 472 | var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; | 472 | var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; | |||
| 473 | 473 | |||||
| 474 | // overwrite width and height if we can get it from style | 474 | // overwrite width and height if we can get it from style | |||
| 475 | var styleWidth = getStyleSize( style.width ); | 475 | var styleWidth = getStyleSize( style.width ); | |||
| 476 | if ( styleWidth !== false ) { | 476 | if ( styleWidth !== false ) { | |||
| 477 | size.width = styleWidth + | 477 | size.width = styleWidth + | |||
| 478 | // add padding and border unless it's already including it | 478 | // add padding and border unless it's already including it | |||
| 479 | ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); | 479 | ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); | |||
| 480 | } | 480 | } | |||
| 481 | 481 | |||||
| 482 | var styleHeight = getStyleSize( style.height ); | 482 | var styleHeight = getStyleSize( style.height ); | |||
| 483 | if ( styleHeight !== false ) { | 483 | if ( styleHeight !== false ) { | |||
| 484 | size.height = styleHeight + | 484 | size.height = styleHeight + | |||
| 485 | // add padding and border unless it's already including it | 485 | // add padding and border unless it's already including it | |||
| 486 | ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); | 486 | ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); | |||
| 487 | } | 487 | } | |||
| 488 | 488 | |||||
| 489 | size.innerWidth = size.width - ( paddingWidth + borderWidth ); | 489 | size.innerWidth = size.width - ( paddingWidth + borderWidth ); | |||
| 490 | size.innerHeight = size.height - ( paddingHeight + borderHeight ); | 490 | size.innerHeight = size.height - ( paddingHeight + borderHeight ); | |||
| 491 | 491 | |||||
| 492 | size.outerWidth = size.width + marginWidth; | 492 | size.outerWidth = size.width + marginWidth; | |||
| 493 | size.outerHeight = size.height + marginHeight; | 493 | size.outerHeight = size.height + marginHeight; | |||
| 494 | 494 | |||||
| 495 | return size; | 495 | return size; | |||
| 496 | } | 496 | } | |||
| 497 | 497 | |||||
| 498 | // IE8 returns percent values, not pixels | 498 | // IE8 returns percent values, not pixels | |||
| 499 | // taken from jQuery's curCSS | 499 | // taken from jQuery's curCSS | |||
| 500 | function mungeNonPixel( elem, value ) { | 500 | function mungeNonPixel( elem, value ) { | |||
| 501 | // IE8 and has percent value | 501 | // IE8 and has percent value | |||
| 502 | if ( window.getComputedStyle || value.indexOf('%') === -1 ) { | 502 | if ( window.getComputedStyle || value.indexOf('%') === -1 ) { | |||
| 503 | return value; | 503 | return value; | |||
| 504 | } | 504 | } | |||
| 505 | var style = elem.style; | 505 | var style = elem.style; | |||
| 506 | // Remember the original values | 506 | // Remember the original values | |||
| 507 | var left = style.left; | 507 | var left = style.left; | |||
| 508 | var rs = elem.runtimeStyle; | 508 | var rs = elem.runtimeStyle; | |||
| 509 | var rsLeft = rs && rs.left; | 509 | var rsLeft = rs && rs.left; | |||
| 510 | 510 | |||||
| 511 | // Put in the new values to get a computed value out | 511 | // Put in the new values to get a computed value out | |||
| 512 | if ( rsLeft ) { | 512 | if ( rsLeft ) { | |||
| 513 | rs.left = elem.currentStyle.left; | 513 | rs.left = elem.currentStyle.left; | |||
| 514 | } | 514 | } | |||
| 515 | style.left = value; | 515 | style.left = value; | |||
| 516 | value = style.pixelLeft; | 516 | value = style.pixelLeft; | |||
| 517 | 517 | |||||
| 518 | // Revert the changed values | 518 | // Revert the changed values | |||
| 519 | style.left = left; | 519 | style.left = left; | |||
| 520 | if ( rsLeft ) { | 520 | if ( rsLeft ) { | |||
| 521 | rs.left = rsLeft; | 521 | rs.left = rsLeft; | |||
| 522 | } | 522 | } | |||
| 523 | 523 | |||||
| 524 | return value; | 524 | return value; | |||
| 525 | } | 525 | } | |||
| 526 | 526 | |||||
| 527 | return getSize; | 527 | return getSize; | |||
| 528 | 528 | |||||
| 529 | } | 529 | } | |||
| 530 | 530 | |||||
| 531 | // transport | 531 | // transport | |||
| 532 | if ( typeof define === 'function' && define.amd ) { | 532 | if ( typeof define === 'function' && define.amd ) { | |||
| 533 | // AMD for RequireJS | 533 | // AMD for RequireJS | |||
| 534 | define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize ); | 534 | define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize ); | |||
| 535 | } else if ( typeof exports === 'object' ) { | 535 | } else if ( typeof exports === 'object' ) { | |||
| 536 | // CommonJS for Component | 536 | // CommonJS for Component | |||
| 537 | module.exports = defineGetSize( require('desandro-get-style-property') ); | 537 | module.exports = defineGetSize( require('desandro-get-style-property') ); | |||
| 538 | } else { | 538 | } else { | |||
| 539 | // browser global | 539 | // browser global | |||
| 540 | window.getSize = defineGetSize( window.getStyleProperty ); | 540 | window.getSize = defineGetSize( window.getStyleProperty ); | |||
| 541 | } | 541 | } | |||
| 542 | 542 | |||||
| 543 | })( window ); | 543 | })( window ); | |||
| 544 | 544 | |||||
| 545 | /*! | 545 | /*! | |||
| 546 | * eventie v1.0.6 | 546 | * eventie v1.0.6 | |||
| 547 | * event binding helper | 547 | * event binding helper | |||
| 548 | * eventie.bind( elem, 'click', myFn ) | 548 | * eventie.bind( elem, 'click', myFn ) | |||
| 549 | * eventie.unbind( elem, 'click', myFn ) | 549 | * eventie.unbind( elem, 'click', myFn ) | |||
| 550 | * MIT license | 550 | * MIT license | |||
| 551 | */ | 551 | */ | |||
| 552 | 552 | |||||
| 553 | /*jshint browser: true, undef: true, unused: true */ | 553 | /*jshint browser: true, undef: true, unused: true */ | |||
| 554 | /*global define: false, module: false */ | 554 | /*global define: false, module: false */ | |||
| 555 | 555 | |||||
| 556 | ( function( window ) { | 556 | ( function( window ) { | |||
| 557 | 557 | |||||
| 558 | 558 | |||||
| 559 | 559 | |||||
| 560 | var docElem = document.documentElement; | 560 | var docElem = document.documentElement; | |||
| 561 | 561 | |||||
| 562 | var bind = function() {}; | 562 | var bind = function() {}; | |||
| 563 | 563 | |||||
| 564 | function getIEEvent( obj ) { | 564 | function getIEEvent( obj ) { | |||
| 565 | var event = window.event; | 565 | var event = window.event; | |||
| 566 | // add event.target | 566 | // add event.target | |||
| 567 | event.target = event.target || event.srcElement || obj; | 567 | event.target = event.target || event.srcElement || obj; | |||
| 568 | return event; | 568 | return event; | |||
| 569 | } | 569 | } | |||
| 570 | 570 | |||||
| 571 | if ( docElem.addEventListener ) { | 571 | if ( docElem.addEventListener ) { | |||
| 572 | bind = function( obj, type, fn ) { | 572 | bind = function( obj, type, fn ) { | |||
| 573 | obj.addEventListener( type, fn, false ); | 573 | obj.addEventListener( type, fn, false ); | |||
| 574 | }; | 574 | }; | |||
| 575 | } else if ( docElem.attachEvent ) { | 575 | } else if ( docElem.attachEvent ) { | |||
| 576 | bind = function( obj, type, fn ) { | 576 | bind = function( obj, type, fn ) { | |||
| 577 | obj[ type + fn ] = fn.handleEvent ? | 577 | obj[ type + fn ] = fn.handleEvent ? | |||
| 578 | function() { | 578 | function() { | |||
| 579 | var event = getIEEvent( obj ); | 579 | var event = getIEEvent( obj ); | |||
| 580 | fn.handleEvent.call( fn, event ); | 580 | fn.handleEvent.call( fn, event ); | |||
| 581 | } : | 581 | } : | |||
| 582 | function() { | 582 | function() { | |||
| 583 | var event = getIEEvent( obj ); | 583 | var event = getIEEvent( obj ); | |||
| 584 | fn.call( obj, event ); | 584 | fn.call( obj, event ); | |||
| 585 | }; | 585 | }; | |||
| 586 | obj.attachEvent( "on" + type, obj[ type + fn ] ); | 586 | obj.attachEvent( "on" + type, obj[ type + fn ] ); | |||
| 587 | }; | 587 | }; | |||
| 588 | } | 588 | } | |||
| 589 | 589 | |||||
| 590 | var unbind = function() {}; | 590 | var unbind = function() {}; | |||
| 591 | 591 | |||||
| 592 | if ( docElem.removeEventListener ) { | 592 | if ( docElem.removeEventListener ) { | |||
| 593 | unbind = function( obj, type, fn ) { | 593 | unbind = function( obj, type, fn ) { | |||
| 594 | obj.removeEventListener( type, fn, false ); | 594 | obj.removeEventListener( type, fn, false ); | |||
| 595 | }; | 595 | }; | |||
| 596 | } else if ( docElem.detachEvent ) { | 596 | } else if ( docElem.detachEvent ) { | |||
| 597 | unbind = function( obj, type, fn ) { | 597 | unbind = function( obj, type, fn ) { | |||
| 598 | obj.detachEvent( "on" + type, obj[ type + fn ] ); | 598 | obj.detachEvent( "on" + type, obj[ type + fn ] ); | |||
| 599 | try { | 599 | try { | |||
| 600 | delete obj[ type + fn ]; | 600 | delete obj[ type + fn ]; | |||
| 601 | } catch ( err ) { | 601 | } catch ( err ) { | |||
| 602 | // can't delete window object properties | 602 | // can't delete window object properties | |||
| 603 | obj[ type + fn ] = undefined; | 603 | obj[ type + fn ] = undefined; | |||
| 604 | } | 604 | } | |||
| 605 | }; | 605 | }; | |||
| 606 | } | 606 | } | |||
| 607 | 607 | |||||
| 608 | var eventie = { | 608 | var eventie = { | |||
| 609 | bind: bind, | 609 | bind: bind, | |||
| 610 | unbind: unbind | 610 | unbind: unbind | |||
| 611 | }; | 611 | }; | |||
| 612 | 612 | |||||
| 613 | // ----- module definition ----- // | 613 | // ----- module definition ----- // | |||
| 614 | 614 | |||||
| 615 | if ( typeof define === 'function' && define.amd ) { | 615 | if ( typeof define === 'function' && define.amd ) { | |||
| 616 | // AMD | 616 | // AMD | |||
| 617 | define( 'eventie/eventie',eventie ); | 617 | define( 'eventie/eventie',eventie ); | |||
| 618 | } else if ( typeof exports === 'object' ) { | 618 | } else if ( typeof exports === 'object' ) { | |||
| 619 | // CommonJS | 619 | // CommonJS | |||
| 620 | module.exports = eventie; | 620 | module.exports = eventie; | |||
| 621 | } else { | 621 | } else { | |||
| 622 | // browser global | 622 | // browser global | |||
| 623 | window.eventie = eventie; | 623 | window.eventie = eventie; | |||
| 624 | } | 624 | } | |||
| 625 | window.eventie = eventie; | 625 | window.eventie = eventie; | |||
| 626 | })( window ); | 626 | })( window ); | |||
| 627 | 627 | |||||
| 628 | /*! | 628 | /*! | |||
| 629 | * EventEmitter v4.2.11 - git.io/ee | 629 | * EventEmitter v4.2.11 - git.io/ee | |||
| 630 | * Unlicense - http://unlicense.org/ | 630 | * Unlicense - http://unlicense.org/ | |||
| 631 | * Oliver Caldwell - http://oli.me.uk/ | 631 | * Oliver Caldwell - http://oli.me.uk/ | |||
| 632 | * @preserve | 632 | * @preserve | |||
| 633 | */ | 633 | */ | |||
| 634 | 634 | |||||
| 635 | ;(function () { | 635 | ;(function () { | |||
| 636 | 636 | |||||
| 637 | 637 | |||||
| 638 | /** | 638 | /** | |||
| 639 | * Class for managing events. | 639 | * Class for managing events. | |||
| 640 | * Can be extended to provide event functionality in other classes. | 640 | * Can be extended to provide event functionality in other classes. | |||
| 641 | * | 641 | * | |||
| 642 | * @class EventEmitter Manages event registering and emitting. | 642 | * @class EventEmitter Manages event registering and emitting. | |||
| 643 | */ | 643 | */ | |||
| 644 | function EventEmitter() {} | 644 | function EventEmitter() {} | |||
| 645 | 645 | |||||
| 646 | // Shortcuts to improve speed and size | 646 | // Shortcuts to improve speed and size | |||
| 647 | var proto = EventEmitter.prototype; | 647 | var proto = EventEmitter.prototype; | |||
| 648 | var exports = this; | 648 | var exports = this; | |||
| 649 | var originalGlobalValue = exports.EventEmitter; | 649 | var originalGlobalValue = exports.EventEmitter; | |||
| 650 | 650 | |||||
| 651 | /** | 651 | /** | |||
| 652 | * Finds the index of the listener for the event in its storage array. | 652 | * Finds the index of the listener for the event in its storage array. | |||
| 653 | * | 653 | * | |||
| 654 | * @param {Function[]} listeners Array of listeners to search through. | 654 | * @param {Function[]} listeners Array of listeners to search through. | |||
| 655 | * @param {Function} listener Method to look for. | 655 | * @param {Function} listener Method to look for. | |||
| 656 | * @return {Number} Index of the specified listener, -1 if not found | 656 | * @return {Number} Index of the specified listener, -1 if not found | |||
| 657 | * @api private | 657 | * @api private | |||
| 658 | */ | 658 | */ | |||
| 659 | function indexOfListener(listeners, listener) { | 659 | function indexOfListener(listeners, listener) { | |||
| 660 | var i = listeners.length; | 660 | var i = listeners.length; | |||
| 661 | while (i--) { | 661 | while (i--) { | |||
| 662 | if (listeners[i].listener === listener) { | 662 | if (listeners[i].listener === listener) { | |||
| 663 | return i; | 663 | return i; | |||
| 664 | } | 664 | } | |||
| 665 | } | 665 | } | |||
| 666 | 666 | |||||
| 667 | return -1; | 667 | return -1; | |||
| 668 | } | 668 | } | |||
| 669 | 669 | |||||
| 670 | /** | 670 | /** | |||
| 671 | * Alias a method while keeping the context correct, to allow for overwriting of target method. | 671 | * Alias a method while keeping the context correct, to allow for overwriting of target method. | |||
| 672 | * | 672 | * | |||
| 673 | * @param {String} name The name of the target method. | 673 | * @param {String} name The name of the target method. | |||
| 674 | * @return {Function} The aliased method | 674 | * @return {Function} The aliased method | |||
| 675 | * @api private | 675 | * @api private | |||
| 676 | */ | 676 | */ | |||
| 677 | function alias(name) { | 677 | function alias(name) { | |||
| 678 | return function aliasClosure() { | 678 | return function aliasClosure() { | |||
| 679 | return this[name].apply(this, arguments); | 679 | return this[name].apply(this, arguments); | |||
| 680 | }; | 680 | }; | |||
| 681 | } | 681 | } | |||
| 682 | 682 | |||||
| 683 | /** | 683 | /** | |||
| 684 | * Returns the listener array for the specified event. | 684 | * Returns the listener array for the specified event. | |||
| 685 | * Will initialise the event object and listener arrays if required. | 685 | * Will initialise the event object and listener arrays if required. | |||
| 686 | * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. | 686 | * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. | |||
| 687 | * Each property in the object response is an array of listener functions. | 687 | * Each property in the object response is an array of listener functions. | |||
| 688 | * | 688 | * | |||
| 689 | * @param {String|RegExp} evt Name of the event to return the listeners from. | 689 | * @param {String|RegExp} evt Name of the event to return the listeners from. | |||
| 690 | * @return {Function[]|Object} All listener functions for the event. | 690 | * @return {Function[]|Object} All listener functions for the event. | |||
| 691 | */ | 691 | */ | |||
| 692 | proto.getListeners = function getListeners(evt) { | 692 | proto.getListeners = function getListeners(evt) { | |||
| 693 | var events = this._getEvents(); | 693 | var events = this._getEvents(); | |||
| 694 | var response; | 694 | var response; | |||
| 695 | var key; | 695 | var key; | |||
| 696 | 696 | |||||
| 697 | // Return a concatenated array of all matching events if | 697 | // Return a concatenated array of all matching events if | |||
| 698 | // the selector is a regular expression. | 698 | // the selector is a regular expression. | |||
| 699 | if (evt instanceof RegExp) { | 699 | if (evt instanceof RegExp) { | |||
| 700 | response = {}; | 700 | response = {}; | |||
| 701 | for (key in events) { | 701 | for (key in events) { | |||
| 702 | if (events.hasOwnProperty(key) && evt.test(key)) { | 702 | if (events.hasOwnProperty(key) && evt.test(key)) { | |||
| 703 | response[key] = events[key]; | 703 | response[key] = events[key]; | |||
| 704 | } | 704 | } | |||
| 705 | } | 705 | } | |||
| 706 | } | 706 | } | |||
| 707 | else { | 707 | else { | |||
| 708 | response = events[evt] || (events[evt] = []); | 708 | response = events[evt] || (events[evt] = []); | |||
| 709 | } | 709 | } | |||
| 710 | 710 | |||||
| 711 | return response; | 711 | return response; | |||
| 712 | }; | 712 | }; | |||
| 713 | 713 | |||||
| 714 | /** | 714 | /** | |||
| 715 | * Takes a list of listener objects and flattens it into a list of listener functions. | 715 | * Takes a list of listener objects and flattens it into a list of listener functions. | |||
| 716 | * | 716 | * | |||
| 717 | * @param {Object[]} listeners Raw listener objects. | 717 | * @param {Object[]} listeners Raw listener objects. | |||
| 718 | * @return {Function[]} Just the listener functions. | 718 | * @return {Function[]} Just the listener functions. | |||
| 719 | */ | 719 | */ | |||
| 720 | proto.flattenListeners = function flattenListeners(listeners) { | 720 | proto.flattenListeners = function flattenListeners(listeners) { | |||
| 721 | var flatListeners = []; | 721 | var flatListeners = []; | |||
| 722 | var i; | 722 | var i; | |||
| 723 | 723 | |||||
| 724 | for (i = 0; i < listeners.length; i += 1) { | 724 | for (i = 0; i < listeners.length; i += 1) { | |||
| 725 | flatListeners.push(listeners[i].listener); | 725 | flatListeners.push(listeners[i].listener); | |||
| 726 | } | 726 | } | |||
| 727 | 727 | |||||
| 728 | return flatListeners; | 728 | return flatListeners; | |||
| 729 | }; | 729 | }; | |||
| 730 | 730 | |||||
| 731 | /** | 731 | /** | |||
| 732 | * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. | 732 | * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. | |||
| 733 | * | 733 | * | |||
| 734 | * @param {String|RegExp} evt Name of the event to return the listeners from. | 734 | * @param {String|RegExp} evt Name of the event to return the listeners from. | |||
| 735 | * @return {Object} All listener functions for an event in an object. | 735 | * @return {Object} All listener functions for an event in an object. | |||
| 736 | */ | 736 | */ | |||
| 737 | proto.getListenersAsObject = function getListenersAsObject(evt) { | 737 | proto.getListenersAsObject = function getListenersAsObject(evt) { | |||
| 738 | var listeners = this.getListeners(evt); | 738 | var listeners = this.getListeners(evt); | |||
| 739 | var response; | 739 | var response; | |||
| 740 | 740 | |||||
| 741 | if (listeners instanceof Array) { | 741 | if (listeners instanceof Array) { | |||
| 742 | response = {}; | 742 | response = {}; | |||
| 743 | response[evt] = listeners; | 743 | response[evt] = listeners; | |||
| 744 | } | 744 | } | |||
| 745 | 745 | |||||
| 746 | return response || listeners; | 746 | return response || listeners; | |||
| 747 | }; | 747 | }; | |||
| 748 | 748 | |||||
| 749 | /** | 749 | /** | |||
| 750 | * Adds a listener function to the specified event. | 750 | * Adds a listener function to the specified event. | |||
| 751 | * The listener will not be added if it is a duplicate. | 751 | * The listener will not be added if it is a duplicate. | |||
| 752 | * If the listener returns true then it will be removed after it is called. | 752 | * If the listener returns true then it will be removed after it is called. | |||
| 753 | * If you pass a regular expression as the event name then the listener will be added to all events that match it. | 753 | * If you pass a regular expression as the event name then the listener will be added to all events that match it. | |||
| 754 | * | 754 | * | |||
| 755 | * @param {String|RegExp} evt Name of the event to attach the listener to. | 755 | * @param {String|RegExp} evt Name of the event to attach the listener to. | |||
| 756 | * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. | 756 | * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. | |||
| 757 | * @return {Object} Current instance of EventEmitter for chaining. | 757 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 758 | */ | 758 | */ | |||
| 759 | proto.addListener = function addListener(evt, listener) { | 759 | proto.addListener = function addListener(evt, listener) { | |||
| 760 | var listeners = this.getListenersAsObject(evt); | 760 | var listeners = this.getListenersAsObject(evt); | |||
| 761 | var listenerIsWrapped = typeof listener === 'object'; | 761 | var listenerIsWrapped = typeof listener === 'object'; | |||
| 762 | var key; | 762 | var key; | |||
| 763 | 763 | |||||
| 764 | for (key in listeners) { | 764 | for (key in listeners) { | |||
| 765 | if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { | 765 | if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { | |||
| 766 | listeners[key].push(listenerIsWrapped ? listener : { | 766 | listeners[key].push(listenerIsWrapped ? listener : { | |||
| 767 | listener: listener, | 767 | listener: listener, | |||
| 768 | once: false | 768 | once: false | |||
| 769 | }); | 769 | }); | |||
| 770 | } | 770 | } | |||
| 771 | } | 771 | } | |||
| 772 | 772 | |||||
| 773 | return this; | 773 | return this; | |||
| 774 | }; | 774 | }; | |||
| 775 | 775 | |||||
| 776 | /** | 776 | /** | |||
| 777 | * Alias of addListener | 777 | * Alias of addListener | |||
| 778 | */ | 778 | */ | |||
| 779 | proto.on = alias('addListener'); | 779 | proto.on = alias('addListener'); | |||
| 780 | 780 | |||||
| 781 | /** | 781 | /** | |||
| 782 | * Semi-alias of addListener. It will add a listener that will be | 782 | * Semi-alias of addListener. It will add a listener that will be | |||
| 783 | * automatically removed after its first execution. | 783 | * automatically removed after its first execution. | |||
| 784 | * | 784 | * | |||
| 785 | * @param {String|RegExp} evt Name of the event to attach the listener to. | 785 | * @param {String|RegExp} evt Name of the event to attach the listener to. | |||
| 786 | * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. | 786 | * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. | |||
| 787 | * @return {Object} Current instance of EventEmitter for chaining. | 787 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 788 | */ | 788 | */ | |||
| 789 | proto.addOnceListener = function addOnceListener(evt, listener) { | 789 | proto.addOnceListener = function addOnceListener(evt, listener) { | |||
| 790 | return this.addListener(evt, { | 790 | return this.addListener(evt, { | |||
| 791 | listener: listener, | 791 | listener: listener, | |||
| 792 | once: true | 792 | once: true | |||
| 793 | }); | 793 | }); | |||
| 794 | }; | 794 | }; | |||
| 795 | 795 | |||||
| 796 | /** | 796 | /** | |||
| 797 | * Alias of addOnceListener. | 797 | * Alias of addOnceListener. | |||
| 798 | */ | 798 | */ | |||
| 799 | proto.once = alias('addOnceListener'); | 799 | proto.once = alias('addOnceListener'); | |||
| 800 | 800 | |||||
| 801 | /** | 801 | /** | |||
| 802 | * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. | 802 | * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. | |||
| 803 | * You need to tell it what event names should be matched by a regex. | 803 | * You need to tell it what event names should be matched by a regex. | |||
| 804 | * | 804 | * | |||
| 805 | * @param {String} evt Name of the event to create. | 805 | * @param {String} evt Name of the event to create. | |||
| 806 | * @return {Object} Current instance of EventEmitter for chaining. | 806 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 807 | */ | 807 | */ | |||
| 808 | proto.defineEvent = function defineEvent(evt) { | 808 | proto.defineEvent = function defineEvent(evt) { | |||
| 809 | this.getListeners(evt); | 809 | this.getListeners(evt); | |||
| 810 | return this; | 810 | return this; | |||
| 811 | }; | 811 | }; | |||
| 812 | 812 | |||||
| 813 | /** | 813 | /** | |||
| 814 | * Uses defineEvent to define multiple events. | 814 | * Uses defineEvent to define multiple events. | |||
| 815 | * | 815 | * | |||
| 816 | * @param {String[]} evts An array of event names to define. | 816 | * @param {String[]} evts An array of event names to define. | |||
| 817 | * @return {Object} Current instance of EventEmitter for chaining. | 817 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 818 | */ | 818 | */ | |||
| 819 | proto.defineEvents = function defineEvents(evts) { | 819 | proto.defineEvents = function defineEvents(evts) { | |||
| 820 | for (var i = 0; i < evts.length; i += 1) { | 820 | for (var i = 0; i < evts.length; i += 1) { | |||
| 821 | this.defineEvent(evts[i]); | 821 | this.defineEvent(evts[i]); | |||
| 822 | } | 822 | } | |||
| 823 | return this; | 823 | return this; | |||
| 824 | }; | 824 | }; | |||
| 825 | 825 | |||||
| 826 | /** | 826 | /** | |||
| 827 | * Removes a listener function from the specified event. | 827 | * Removes a listener function from the specified event. | |||
| 828 | * When passed a regular expression as the event name, it will remove the listener from all events that match it. | 828 | * When passed a regular expression as the event name, it will remove the listener from all events that match it. | |||
| 829 | * | 829 | * | |||
| 830 | * @param {String|RegExp} evt Name of the event to remove the listener from. | 830 | * @param {String|RegExp} evt Name of the event to remove the listener from. | |||
| 831 | * @param {Function} listener Method to remove from the event. | 831 | * @param {Function} listener Method to remove from the event. | |||
| 832 | * @return {Object} Current instance of EventEmitter for chaining. | 832 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 833 | */ | 833 | */ | |||
| 834 | proto.removeListener = function removeListener(evt, listener) { | 834 | proto.removeListener = function removeListener(evt, listener) { | |||
| 835 | var listeners = this.getListenersAsObject(evt); | 835 | var listeners = this.getListenersAsObject(evt); | |||
| 836 | var index; | 836 | var index; | |||
| 837 | var key; | 837 | var key; | |||
| 838 | 838 | |||||
| 839 | for (key in listeners) { | 839 | for (key in listeners) { | |||
| 840 | if (listeners.hasOwnProperty(key)) { | 840 | if (listeners.hasOwnProperty(key)) { | |||
| 841 | index = indexOfListener(listeners[key], listener); | 841 | index = indexOfListener(listeners[key], listener); | |||
| 842 | 842 | |||||
| 843 | if (index !== -1) { | 843 | if (index !== -1) { | |||
| 844 | listeners[key].splice(index, 1); | 844 | listeners[key].splice(index, 1); | |||
| 845 | } | 845 | } | |||
| 846 | } | 846 | } | |||
| 847 | } | 847 | } | |||
| 848 | 848 | |||||
| 849 | return this; | 849 | return this; | |||
| 850 | }; | 850 | }; | |||
| 851 | 851 | |||||
| 852 | /** | 852 | /** | |||
| 853 | * Alias of removeListener | 853 | * Alias of removeListener | |||
| 854 | */ | 854 | */ | |||
| 855 | proto.off = alias('removeListener'); | 855 | proto.off = alias('removeListener'); | |||
| 856 | 856 | |||||
| 857 | /** | 857 | /** | |||
| 858 | * Adds listeners in bulk using the manipulateListeners method. | 858 | * Adds listeners in bulk using the manipulateListeners method. | |||
| 859 | * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. | 859 | * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. | |||
| 860 | * You can also pass it a regular expression to add the array of listeners to all events that match it. | 860 | * You can also pass it a regular expression to add the array of listeners to all events that match it. | |||
| 861 | * Yeah, this function does quite a bit. That's probably a bad thing. | 861 | * Yeah, this function does quite a bit. That's probably a bad thing. | |||
| 862 | * | 862 | * | |||
| 863 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. | 863 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. | |||
| 864 | * @param {Function[]} [listeners] An optional array of listener functions to add. | 864 | * @param {Function[]} [listeners] An optional array of listener functions to add. | |||
| 865 | * @return {Object} Current instance of EventEmitter for chaining. | 865 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 866 | */ | 866 | */ | |||
| 867 | proto.addListeners = function addListeners(evt, listeners) { | 867 | proto.addListeners = function addListeners(evt, listeners) { | |||
| 868 | // Pass through to manipulateListeners | 868 | // Pass through to manipulateListeners | |||
| 869 | return this.manipulateListeners(false, evt, listeners); | 869 | return this.manipulateListeners(false, evt, listeners); | |||
| 870 | }; | 870 | }; | |||
| 871 | 871 | |||||
| 872 | /** | 872 | /** | |||
| 873 | * Removes listeners in bulk using the manipulateListeners method. | 873 | * Removes listeners in bulk using the manipulateListeners method. | |||
| 874 | * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. | 874 | * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. | |||
| 875 | * You can also pass it an event name and an array of listeners to be removed. | 875 | * You can also pass it an event name and an array of listeners to be removed. | |||
| 876 | * You can also pass it a regular expression to remove the listeners from all events that match it. | 876 | * You can also pass it a regular expression to remove the listeners from all events that match it. | |||
| 877 | * | 877 | * | |||
| 878 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. | 878 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. | |||
| 879 | * @param {Function[]} [listeners] An optional array of listener functions to remove. | 879 | * @param {Function[]} [listeners] An optional array of listener functions to remove. | |||
| 880 | * @return {Object} Current instance of EventEmitter for chaining. | 880 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 881 | */ | 881 | */ | |||
| 882 | proto.removeListeners = function removeListeners(evt, listeners) { | 882 | proto.removeListeners = function removeListeners(evt, listeners) { | |||
| 883 | // Pass through to manipulateListeners | 883 | // Pass through to manipulateListeners | |||
| 884 | return this.manipulateListeners(true, evt, listeners); | 884 | return this.manipulateListeners(true, evt, listeners); | |||
| 885 | }; | 885 | }; | |||
| 886 | 886 | |||||
| 887 | /** | 887 | /** | |||
| 888 | * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. | 888 | * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. | |||
| 889 | * The first argument will determine if the listeners are removed (true) or added (false). | 889 | * The first argument will determine if the listeners are removed (true) or added (false). | |||
| 890 | * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. | 890 | * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. | |||
| 891 | * You can also pass it an event name and an array of listeners to be added/removed. | 891 | * You can also pass it an event name and an array of listeners to be added/removed. | |||
| 892 | * You can also pass it a regular expression to manipulate the listeners of all events that match it. | 892 | * You can also pass it a regular expression to manipulate the listeners of all events that match it. | |||
| 893 | * | 893 | * | |||
| 894 | * @param {Boolean} remove True if you want to remove listeners, false if you want to add. | 894 | * @param {Boolean} remove True if you want to remove listeners, false if you want to add. | |||
| 895 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. | 895 | * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. | |||
| 896 | * @param {Function[]} [listeners] An optional array of listener functions to add/remove. | 896 | * @param {Function[]} [listeners] An optional array of listener functions to add/remove. | |||
| 897 | * @return {Object} Current instance of EventEmitter for chaining. | 897 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 898 | */ | 898 | */ | |||
| 899 | proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { | 899 | proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { | |||
| 900 | var i; | 900 | var i; | |||
| 901 | var value; | 901 | var value; | |||
| 902 | var single = remove ? this.removeListener : this.addListener; | 902 | var single = remove ? this.removeListener : this.addListener; | |||
| 903 | var multiple = remove ? this.removeListeners : this.addListeners; | 903 | var multiple = remove ? this.removeListeners : this.addListeners; | |||
| 904 | 904 | |||||
| 905 | // If evt is an object then pass each of its properties to this method | 905 | // If evt is an object then pass each of its properties to this method | |||
| 906 | if (typeof evt === 'object' && !(evt instanceof RegExp)) { | 906 | if (typeof evt === 'object' && !(evt instanceof RegExp)) { | |||
| 907 | for (i in evt) { | 907 | for (i in evt) { | |||
| 908 | if (evt.hasOwnProperty(i) && (value = evt[i])) { | 908 | if (evt.hasOwnProperty(i) && (value = evt[i])) { | |||
| 909 | // Pass the single listener straight through to the singular method | 909 | // Pass the single listener straight through to the singular method | |||
| 910 | if (typeof value === 'function') { | 910 | if (typeof value === 'function') { | |||
| 911 | single.call(this, i, value); | 911 | single.call(this, i, value); | |||
| 912 | } | 912 | } | |||
| 913 | else { | 913 | else { | |||
| 914 | // Otherwise pass back to the multiple function | 914 | // Otherwise pass back to the multiple function | |||
| 915 | multiple.call(this, i, value); | 915 | multiple.call(this, i, value); | |||
| 916 | } | 916 | } | |||
| 917 | } | 917 | } | |||
| 918 | } | 918 | } | |||
| 919 | } | 919 | } | |||
| 920 | else { | 920 | else { | |||
| 921 | // So evt must be a string | 921 | // So evt must be a string | |||
| 922 | // And listeners must be an array of listeners | 922 | // And listeners must be an array of listeners | |||
| 923 | // Loop over it and pass each one to the multiple method | 923 | // Loop over it and pass each one to the multiple method | |||
| 924 | i = listeners.length; | 924 | i = listeners.length; | |||
| 925 | while (i--) { | 925 | while (i--) { | |||
| 926 | single.call(this, evt, listeners[i]); | 926 | single.call(this, evt, listeners[i]); | |||
| 927 | } | 927 | } | |||
| 928 | } | 928 | } | |||
| 929 | 929 | |||||
| 930 | return this; | 930 | return this; | |||
| 931 | }; | 931 | }; | |||
| 932 | 932 | |||||
| 933 | /** | 933 | /** | |||
| 934 | * Removes all listeners from a specified event. | 934 | * Removes all listeners from a specified event. | |||
| 935 | * If you do not specify an event then all listeners will be removed. | 935 | * If you do not specify an event then all listeners will be removed. | |||
| 936 | * That means every event will be emptied. | 936 | * That means every event will be emptied. | |||
| 937 | * You can also pass a regex to remove all events that match it. | 937 | * You can also pass a regex to remove all events that match it. | |||
| 938 | * | 938 | * | |||
| 939 | * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. | 939 | * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. | |||
| 940 | * @return {Object} Current instance of EventEmitter for chaining. | 940 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 941 | */ | 941 | */ | |||
| 942 | proto.removeEvent = function removeEvent(evt) { | 942 | proto.removeEvent = function removeEvent(evt) { | |||
| 943 | var type = typeof evt; | 943 | var type = typeof evt; | |||
| 944 | var events = this._getEvents(); | 944 | var events = this._getEvents(); | |||
| 945 | var key; | 945 | var key; | |||
| 946 | 946 | |||||
| 947 | // Remove different things depending on the state of evt | 947 | // Remove different things depending on the state of evt | |||
| 948 | if (type === 'string') { | 948 | if (type === 'string') { | |||
| 949 | // Remove all listeners for the specified event | 949 | // Remove all listeners for the specified event | |||
| 950 | delete events[evt]; | 950 | delete events[evt]; | |||
| 951 | } | 951 | } | |||
| 952 | else if (evt instanceof RegExp) { | 952 | else if (evt instanceof RegExp) { | |||
| 953 | // Remove all events matching the regex. | 953 | // Remove all events matching the regex. | |||
| 954 | for (key in events) { | 954 | for (key in events) { | |||
| 955 | if (events.hasOwnProperty(key) && evt.test(key)) { | 955 | if (events.hasOwnProperty(key) && evt.test(key)) { | |||
| 956 | delete events[key]; | 956 | delete events[key]; | |||
| 957 | } | 957 | } | |||
| 958 | } | 958 | } | |||
| 959 | } | 959 | } | |||
| 960 | else { | 960 | else { | |||
| 961 | // Remove all listeners in all events | 961 | // Remove all listeners in all events | |||
| 962 | delete this._events; | 962 | delete this._events; | |||
| 963 | } | 963 | } | |||
| 964 | 964 | |||||
| 965 | return this; | 965 | return this; | |||
| 966 | }; | 966 | }; | |||
| 967 | 967 | |||||
| 968 | /** | 968 | /** | |||
| 969 | * Alias of removeEvent. | 969 | * Alias of removeEvent. | |||
| 970 | * | 970 | * | |||
| 971 | * Added to mirror the node API. | 971 | * Added to mirror the node API. | |||
| 972 | */ | 972 | */ | |||
| 973 | proto.removeAllListeners = alias('removeEvent'); | 973 | proto.removeAllListeners = alias('removeEvent'); | |||
| 974 | 974 | |||||
| 975 | /** | 975 | /** | |||
| 976 | * Emits an event of your choice. | 976 | * Emits an event of your choice. | |||
| 977 | * When emitted, every listener attached to that event will be executed. | 977 | * When emitted, every listener attached to that event will be executed. | |||
| 978 | * If you pass the optional argument array then those arguments will be passed to every listener upon execution. | 978 | * If you pass the optional argument array then those arguments will be passed to every listener upon execution. | |||
| 979 | * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. | 979 | * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. | |||
| 980 | * So they will not arrive within the array on the other side, they will be separate. | 980 | * So they will not arrive within the array on the other side, they will be separate. | |||
| 981 | * You can also pass a regular expression to emit to all events that match it. | 981 | * You can also pass a regular expression to emit to all events that match it. | |||
| 982 | * | 982 | * | |||
| 983 | * @param {String|RegExp} evt Name of the event to emit and execute listeners for. | 983 | * @param {String|RegExp} evt Name of the event to emit and execute listeners for. | |||
| 984 | * @param {Array} [args] Optional array of arguments to be passed to each listener. | 984 | * @param {Array} [args] Optional array of arguments to be passed to each listener. | |||
| 985 | * @return {Object} Current instance of EventEmitter for chaining. | 985 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 986 | */ | 986 | */ | |||
| 987 | proto.emitEvent = function emitEvent(evt, args) { | 987 | proto.emitEvent = function emitEvent(evt, args) { | |||
| 988 | var listeners = this.getListenersAsObject(evt); | 988 | var listeners = this.getListenersAsObject(evt); | |||
| 989 | var listener; | 989 | var listener; | |||
| 990 | var i; | 990 | var i; | |||
| 991 | var key; | 991 | var key; | |||
| 992 | var response; | 992 | var response; | |||
| 993 | 993 | |||||
| 994 | for (key in listeners) { | 994 | for (key in listeners) { | |||
| 995 | if (listeners.hasOwnProperty(key)) { | 995 | if (listeners.hasOwnProperty(key)) { | |||
| 996 | i = listeners[key].length; | 996 | i = listeners[key].length; | |||
| 997 | 997 | |||||
| 998 | while (i--) { | 998 | while (i--) { | |||
| 999 | // If the listener returns true then it shall be removed from the event | 999 | // If the listener returns true then it shall be removed from the event | |||
| 1000 | // The function is executed either with a basic call or an apply if there is an args array | 1000 | // The function is executed either with a basic call or an apply if there is an args array | |||
| 1001 | listener = listeners[key][i]; | 1001 | listener = listeners[key][i]; | |||
| 1002 | 1002 | |||||
| 1003 | if (listener.once === true) { | 1003 | if (listener.once === true) { | |||
| 1004 | this.removeListener(evt, listener.listener); | 1004 | this.removeListener(evt, listener.listener); | |||
| 1005 | } | 1005 | } | |||
| 1006 | 1006 | |||||
| 1007 | response = listener.listener.apply(this, args || []); | 1007 | response = listener.listener.apply(this, args || []); | |||
| 1008 | 1008 | |||||
| 1009 | if (response === this._getOnceReturnValue()) { | 1009 | if (response === this._getOnceReturnValue()) { | |||
| 1010 | this.removeListener(evt, listener.listener); | 1010 | this.removeListener(evt, listener.listener); | |||
| 1011 | } | 1011 | } | |||
| 1012 | } | 1012 | } | |||
| 1013 | } | 1013 | } | |||
| 1014 | } | 1014 | } | |||
| 1015 | 1015 | |||||
| 1016 | return this; | 1016 | return this; | |||
| 1017 | }; | 1017 | }; | |||
| 1018 | 1018 | |||||
| 1019 | /** | 1019 | /** | |||
| 1020 | * Alias of emitEvent | 1020 | * Alias of emitEvent | |||
| 1021 | */ | 1021 | */ | |||
| 1022 | proto.trigger = alias('emitEvent'); | 1022 | proto.trigger = alias('emitEvent'); | |||
| 1023 | 1023 | |||||
| 1024 | /** | 1024 | /** | |||
| 1025 | * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. | 1025 | * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. | |||
| 1026 | * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. | 1026 | * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. | |||
| 1027 | * | 1027 | * | |||
| 1028 | * @param {String|RegExp} evt Name of the event to emit and execute listeners for. | 1028 | * @param {String|RegExp} evt Name of the event to emit and execute listeners for. | |||
| 1029 | * @param {...*} Optional additional arguments to be passed to each listener. | 1029 | * @param {...*} Optional additional arguments to be passed to each listener. | |||
| 1030 | * @return {Object} Current instance of EventEmitter for chaining. | 1030 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 1031 | */ | 1031 | */ | |||
| 1032 | proto.emit = function emit(evt) { | 1032 | proto.emit = function emit(evt) { | |||
| 1033 | var args = Array.prototype.slice.call(arguments, 1); | 1033 | var args = Array.prototype.slice.call(arguments, 1); | |||
| 1034 | return this.emitEvent(evt, args); | 1034 | return this.emitEvent(evt, args); | |||
| 1035 | }; | 1035 | }; | |||
| 1036 | 1036 | |||||
| 1037 | /** | 1037 | /** | |||
| 1038 | * Sets the current value to check against when executing listeners. If a | 1038 | * Sets the current value to check against when executing listeners. If a | |||
| 1039 | * listeners return value matches the one set here then it will be removed | 1039 | * listeners return value matches the one set here then it will be removed | |||
| 1040 | * after execution. This value defaults to true. | 1040 | * after execution. This value defaults to true. | |||
| 1041 | * | 1041 | * | |||
| 1042 | * @param {*} value The new value to check for when executing listeners. | 1042 | * @param {*} value The new value to check for when executing listeners. | |||
| 1043 | * @return {Object} Current instance of EventEmitter for chaining. | 1043 | * @return {Object} Current instance of EventEmitter for chaining. | |||
| 1044 | */ | 1044 | */ | |||
| 1045 | proto.setOnceReturnValue = function setOnceReturnValue(value) { | 1045 | proto.setOnceReturnValue = function setOnceReturnValue(value) { | |||
| 1046 | this._onceReturnValue = value; | 1046 | this._onceReturnValue = value; | |||
| 1047 | return this; | 1047 | return this; | |||
| 1048 | }; | 1048 | }; | |||
| 1049 | 1049 | |||||
| 1050 | /** | 1050 | /** | |||
| 1051 | * Fetches the current value to check against when executing listeners. If | 1051 | * Fetches the current value to check against when executing listeners. If | |||
| 1052 | * the listeners return value matches this one then it should be removed | 1052 | * the listeners return value matches this one then it should be removed | |||
| 1053 | * automatically. It will return true by default. | 1053 | * automatically. It will return true by default. | |||
| 1054 | * | 1054 | * | |||
| 1055 | * @return {*|Boolean} The current value to check for or the default, true. | 1055 | * @return {*|Boolean} The current value to check for or the default, true. | |||
| 1056 | * @api private | 1056 | * @api private | |||
| 1057 | */ | 1057 | */ | |||
| 1058 | proto._getOnceReturnValue = function _getOnceReturnValue() { | 1058 | proto._getOnceReturnValue = function _getOnceReturnValue() { | |||
| 1059 | if (this.hasOwnProperty('_onceReturnValue')) { | 1059 | if (this.hasOwnProperty('_onceReturnValue')) { | |||
| 1060 | return this._onceReturnValue; | 1060 | return this._onceReturnValue; | |||
| 1061 | } | 1061 | } | |||
| 1062 | else { | 1062 | else { | |||
| 1063 | return true; | 1063 | return true; | |||
| 1064 | } | 1064 | } | |||
| 1065 | }; | 1065 | }; | |||
| 1066 | 1066 | |||||
| 1067 | /** | 1067 | /** | |||
| 1068 | * Fetches the events object and creates one if required. | 1068 | * Fetches the events object and creates one if required. | |||
| 1069 | * | 1069 | * | |||
| 1070 | * @return {Object} The events storage object. | 1070 | * @return {Object} The events storage object. | |||
| 1071 | * @api private | 1071 | * @api private | |||
| 1072 | */ | 1072 | */ | |||
| 1073 | proto._getEvents = function _getEvents() { | 1073 | proto._getEvents = function _getEvents() { | |||
| 1074 | return this._events || (this._events = {}); | 1074 | return this._events || (this._events = {}); | |||
| 1075 | }; | 1075 | }; | |||
| 1076 | 1076 | |||||
| 1077 | /** | 1077 | /** | |||
| 1078 | * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. | 1078 | * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. | |||
| 1079 | * | 1079 | * | |||
| 1080 | * @return {Function} Non conflicting EventEmitter class. | 1080 | * @return {Function} Non conflicting EventEmitter class. | |||
| 1081 | */ | 1081 | */ | |||
| 1082 | EventEmitter.noConflict = function noConflict() { | 1082 | EventEmitter.noConflict = function noConflict() { | |||
| 1083 | exports.EventEmitter = originalGlobalValue; | 1083 | exports.EventEmitter = originalGlobalValue; | |||
| 1084 | return EventEmitter; | 1084 | return EventEmitter; | |||
| 1085 | }; | 1085 | }; | |||
| 1086 | 1086 | |||||
| 1087 | // Expose the class either via AMD, CommonJS or the global object | 1087 | // Expose the class either via AMD, CommonJS or the global object | |||
| 1088 | if (typeof define === 'function' && define.amd) { | 1088 | if (typeof define === 'function' && define.amd) { | |||
| 1089 | define('eventEmitter/EventEmitter',[],function () { | 1089 | define('eventEmitter/EventEmitter',[],function () { | |||
| 1090 | return EventEmitter; | 1090 | return EventEmitter; | |||
| 1091 | }); | 1091 | }); | |||
| 1092 | } | 1092 | } | |||
| 1093 | else if (typeof module === 'object' && module.exports){ | 1093 | else if (typeof module === 'object' && module.exports){ | |||
| 1094 | module.exports = EventEmitter; | 1094 | module.exports = EventEmitter; | |||
| 1095 | } | 1095 | } | |||
| 1096 | else { | 1096 | else { | |||
| 1097 | exports.EventEmitter = EventEmitter; | 1097 | exports.EventEmitter = EventEmitter; | |||
| 1098 | } | 1098 | } | |||
| 1099 | }.call(this)); | 1099 | }.call(this)); | |||
| 1100 | 1100 | |||||
| 1101 | /*! | 1101 | /*! | |||
| 1102 | * docReady v1.0.4 | 1102 | * docReady v1.0.4 | |||
| 1103 | * Cross browser DOMContentLoaded event emitter | 1103 | * Cross browser DOMContentLoaded event emitter | |||
| 1104 | * MIT license | 1104 | * MIT license | |||
| 1105 | */ | 1105 | */ | |||
| 1106 | 1106 | |||||
| 1107 | /*jshint browser: true, strict: true, undef: true, unused: true*/ | 1107 | /*jshint browser: true, strict: true, undef: true, unused: true*/ | |||
| 1108 | /*global define: false, require: false, module: false */ | 1108 | /*global define: false, require: false, module: false */ | |||
| 1109 | 1109 | |||||
| 1110 | ( function( window ) { | 1110 | ( function( window ) { | |||
| 1111 | 1111 | |||||
| 1112 | 1112 | |||||
| 1113 | 1113 | |||||
| 1114 | var document = window.document; | 1114 | var document = window.document; | |||
| 1115 | // collection of functions to be triggered on ready | 1115 | // collection of functions to be triggered on ready | |||
| 1116 | var queue = []; | 1116 | var queue = []; | |||
| 1117 | 1117 | |||||
| 1118 | function docReady( fn ) { | 1118 | function docReady( fn ) { | |||
| 1119 | // throw out non-functions | 1119 | // throw out non-functions | |||
| 1120 | if ( typeof fn !== 'function' ) { | 1120 | if ( typeof fn !== 'function' ) { | |||
| 1121 | return; | 1121 | return; | |||
| 1122 | } | 1122 | } | |||
| 1123 | 1123 | |||||
| 1124 | if ( docReady.isReady ) { | 1124 | if ( docReady.isReady ) { | |||
| 1125 | // ready now, hit it | 1125 | // ready now, hit it | |||
| 1126 | fn(); | 1126 | fn(); | |||
| 1127 | } else { | 1127 | } else { | |||
| 1128 | // queue function when ready | 1128 | // queue function when ready | |||
| 1129 | queue.push( fn ); | 1129 | queue.push( fn ); | |||
| 1130 | } | 1130 | } | |||
| 1131 | } | 1131 | } | |||
| 1132 | 1132 | |||||
| 1133 | docReady.isReady = false; | 1133 | docReady.isReady = false; | |||
| 1134 | 1134 | |||||
| 1135 | // triggered on various doc ready events | 1135 | // triggered on various doc ready events | |||
| 1136 | function onReady( event ) { | 1136 | function onReady( event ) { | |||
| 1137 | // bail if already triggered or IE8 document is not ready just yet | 1137 | // bail if already triggered or IE8 document is not ready just yet | |||
| 1138 | var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete'; | 1138 | var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete'; | |||
| 1139 | if ( docReady.isReady || isIE8NotReady ) { | 1139 | if ( docReady.isReady || isIE8NotReady ) { | |||
| 1140 | return; | 1140 | return; | |||
| 1141 | } | 1141 | } | |||
| 1142 | 1142 | |||||
| 1143 | trigger(); | 1143 | trigger(); | |||
| 1144 | } | 1144 | } | |||
| 1145 | 1145 | |||||
| 1146 | function trigger() { | 1146 | function trigger() { | |||
| 1147 | docReady.isReady = true; | 1147 | docReady.isReady = true; | |||
| 1148 | // process queue | 1148 | // process queue | |||
| 1149 | for ( var i=0, len = queue.length; i < len; i++ ) { | 1149 | for ( var i=0, len = queue.length; i < len; i++ ) { | |||
| 1150 | var fn = queue[i]; | 1150 | var fn = queue[i]; | |||
| 1151 | fn(); | 1151 | fn(); | |||
| 1152 | } | 1152 | } | |||
| 1153 | } | 1153 | } | |||
| 1154 | 1154 | |||||
| 1155 | function defineDocReady( eventie ) { | 1155 | function defineDocReady( eventie ) { | |||
| 1156 | // trigger ready if page is ready | 1156 | // trigger ready if page is ready | |||
| 1157 | if ( document.readyState === 'complete' ) { | 1157 | if ( document.readyState === 'complete' ) { | |||
| 1158 | trigger(); | 1158 | trigger(); | |||
| 1159 | } else { | 1159 | } else { | |||
| 1160 | // listen for events | 1160 | // listen for events | |||
| 1161 | window.eventie.bind( document, 'DOMContentLoaded', onReady ); | 1161 | window.eventie.bind( document, 'DOMContentLoaded', onReady ); | |||
| 1162 | window.eventie.bind( document, 'readystatechange', onReady ); | 1162 | window.eventie.bind( document, 'readystatechange', onReady ); | |||
| 1163 | window.eventie.bind( window, 'load', onReady ); | 1163 | window.eventie.bind( window, 'load', onReady ); | |||
| 1164 | } | 1164 | } | |||
| 1165 | 1165 | |||||
| 1166 | return docReady; | 1166 | return docReady; | |||
| 1167 | } | 1167 | } | |||
| 1168 | 1168 | |||||
| 1169 | // transport | 1169 | // transport | |||
| 1170 | if ( typeof define === 'function' && define.amd ) { | 1170 | if ( typeof define === 'function' && define.amd ) { | |||
| 1171 | // AMD | 1171 | // AMD | |||
| 1172 | define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady ); | 1172 | define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady ); | |||
| 1173 | } else if ( typeof exports === 'object' ) { | 1173 | } else if ( typeof exports === 'object' ) { | |||
| 1174 | module.exports = defineDocReady( require('eventie') ); | 1174 | module.exports = defineDocReady( require('eventie') ); | |||
| 1175 | } else { | 1175 | } else { | |||
| 1176 | // browser global | 1176 | // browser global | |||
| 1177 | window.docReady = defineDocReady( window.eventie ); | 1177 | window.docReady = defineDocReady( window.eventie ); | |||
| 1178 | } | 1178 | } | |||
| 1179 | 1179 | |||||
| 1180 | })( window ); | 1180 | })( window ); | |||
| 1181 | 1181 | |||||
| 1182 | /** | 1182 | /** | |||
| 1183 | * matchesSelector v1.0.3 | 1183 | * matchesSelector v1.0.3 | |||
| 1184 | * matchesSelector( element, '.selector' ) | 1184 | * matchesSelector( element, '.selector' ) | |||
| 1185 | * MIT license | 1185 | * MIT license | |||
| 1186 | */ | 1186 | */ | |||
| 1187 | 1187 | |||||
| 1188 | /*jshint browser: true, strict: true, undef: true, unused: true */ | 1188 | /*jshint browser: true, strict: true, undef: true, unused: true */ | |||
| 1189 | /*global define: false, module: false */ | 1189 | /*global define: false, module: false */ | |||
| 1190 | 1190 | |||||
| 1191 | ( function( ElemProto ) { | 1191 | ( function( ElemProto ) { | |||
| 1192 | 1192 | |||||
| 1193 | 1193 | |||||
| 1194 | 1194 | |||||
| 1195 | var matchesMethod = ( function() { | 1195 | var matchesMethod = ( function() { | |||
| 1196 | // check for the standard method name first | 1196 | // check for the standard method name first | |||
| 1197 | if ( ElemProto.matches ) { | 1197 | if ( ElemProto.matches ) { | |||
| 1198 | return 'matches'; | 1198 | return 'matches'; | |||
| 1199 | } | 1199 | } | |||
| 1200 | // check un-prefixed | 1200 | // check un-prefixed | |||
| 1201 | if ( ElemProto.matchesSelector ) { | 1201 | if ( ElemProto.matchesSelector ) { | |||
| 1202 | return 'matchesSelector'; | 1202 | return 'matchesSelector'; | |||
| 1203 | } | 1203 | } | |||
| 1204 | // check vendor prefixes | 1204 | // check vendor prefixes | |||
| 1205 | var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; | 1205 | var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; | |||
| 1206 | 1206 | |||||
| 1207 | for ( var i=0, len = prefixes.length; i < len; i++ ) { | 1207 | for ( var i=0, len = prefixes.length; i < len; i++ ) { | |||
| 1208 | var prefix = prefixes[i]; | 1208 | var prefix = prefixes[i]; | |||
| 1209 | var method = prefix + 'MatchesSelector'; | 1209 | var method = prefix + 'MatchesSelector'; | |||
| 1210 | if ( ElemProto[ method ] ) { | 1210 | if ( ElemProto[ method ] ) { | |||
| 1211 | return method; | 1211 | return method; | |||
| 1212 | } | 1212 | } | |||
| 1213 | } | 1213 | } | |||
| 1214 | })(); | 1214 | })(); | |||
| 1215 | 1215 | |||||
| 1216 | // ----- match ----- // | 1216 | // ----- match ----- // | |||
| 1217 | 1217 | |||||
| 1218 | function match( elem, selector ) { | 1218 | function match( elem, selector ) { | |||
| 1219 | return elem[ matchesMethod ]( selector ); | 1219 | return elem[ matchesMethod ]( selector ); | |||
| 1220 | } | 1220 | } | |||
| 1221 | 1221 | |||||
| 1222 | // ----- appendToFragment ----- // | 1222 | // ----- appendToFragment ----- // | |||
| 1223 | 1223 | |||||
| 1224 | function checkParent( elem ) { | 1224 | function checkParent( elem ) { | |||
| 1225 | // not needed if already has parent | 1225 | // not needed if already has parent | |||
| 1226 | if ( elem.parentNode ) { | 1226 | if ( elem.parentNode ) { | |||
| 1227 | return; | 1227 | return; | |||
| 1228 | } | 1228 | } | |||
| 1229 | var fragment = document.createDocumentFragment(); | 1229 | var fragment = document.createDocumentFragment(); | |||
| 1230 | fragment.appendChild( elem ); | 1230 | fragment.appendChild( elem ); | |||
| 1231 | } | 1231 | } | |||
| 1232 | 1232 | |||||
| 1233 | // ----- query ----- // | 1233 | // ----- query ----- // | |||
| 1234 | 1234 | |||||
| 1235 | // fall back to using QSA | 1235 | // fall back to using QSA | |||
| 1236 | // thx @jonathantneal https://gist.github.com/3062955 | 1236 | // thx @jonathantneal https://gist.github.com/3062955 | |||
| 1237 | function query( elem, selector ) { | 1237 | function query( elem, selector ) { | |||
| 1238 | // append to fragment if no parent | 1238 | // append to fragment if no parent | |||
| 1239 | checkParent( elem ); | 1239 | checkParent( elem ); | |||
| 1240 | 1240 | |||||
| 1241 | // match elem with all selected elems of parent | 1241 | // match elem with all selected elems of parent | |||
| 1242 | var elems = elem.parentNode.querySelectorAll( selector ); | 1242 | var elems = elem.parentNode.querySelectorAll( selector ); | |||
| 1243 | for ( var i=0, len = elems.length; i < len; i++ ) { | 1243 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 1244 | // return true if match | 1244 | // return true if match | |||
| 1245 | if ( elems[i] === elem ) { | 1245 | if ( elems[i] === elem ) { | |||
| 1246 | return true; | 1246 | return true; | |||
| 1247 | } | 1247 | } | |||
| 1248 | } | 1248 | } | |||
| 1249 | // otherwise return false | 1249 | // otherwise return false | |||
| 1250 | return false; | 1250 | return false; | |||
| 1251 | } | 1251 | } | |||
| 1252 | 1252 | |||||
| 1253 | // ----- matchChild ----- // | 1253 | // ----- matchChild ----- // | |||
| 1254 | 1254 | |||||
| 1255 | function matchChild( elem, selector ) { | 1255 | function matchChild( elem, selector ) { | |||
| 1256 | checkParent( elem ); | 1256 | checkParent( elem ); | |||
| 1257 | return match( elem, selector ); | 1257 | return match( elem, selector ); | |||
| 1258 | } | 1258 | } | |||
| 1259 | 1259 | |||||
| 1260 | // ----- matchesSelector ----- // | 1260 | // ----- matchesSelector ----- // | |||
| 1261 | 1261 | |||||
| 1262 | var matchesSelector; | 1262 | var matchesSelector; | |||
| 1263 | 1263 | |||||
| 1264 | if ( matchesMethod ) { | 1264 | if ( matchesMethod ) { | |||
| 1265 | // IE9 supports matchesSelector, but doesn't work on orphaned elems | 1265 | // IE9 supports matchesSelector, but doesn't work on orphaned elems | |||
| 1266 | // check for that | 1266 | // check for that | |||
| 1267 | var div = document.createElement('div'); | 1267 | var div = document.createElement('div'); | |||
| 1268 | var supportsOrphans = match( div, 'div' ); | 1268 | var supportsOrphans = match( div, 'div' ); | |||
| 1269 | matchesSelector = supportsOrphans ? match : matchChild; | 1269 | matchesSelector = supportsOrphans ? match : matchChild; | |||
| 1270 | } else { | 1270 | } else { | |||
| 1271 | matchesSelector = query; | 1271 | matchesSelector = query; | |||
| 1272 | } | 1272 | } | |||
| 1273 | 1273 | |||||
| 1274 | // transport | 1274 | // transport | |||
| 1275 | if ( typeof define === 'function' && define.amd ) { | 1275 | if ( typeof define === 'function' && define.amd ) { | |||
| 1276 | // AMD | 1276 | // AMD | |||
| 1277 | define( 'matches-selector/matches-selector',[],function() { | 1277 | define( 'matches-selector/matches-selector',[],function() { | |||
| 1278 | return matchesSelector; | 1278 | return matchesSelector; | |||
| 1279 | }); | 1279 | }); | |||
| 1280 | } else if ( typeof exports === 'object' ) { | 1280 | } else if ( typeof exports === 'object' ) { | |||
| 1281 | module.exports = matchesSelector; | 1281 | module.exports = matchesSelector; | |||
| 1282 | } | 1282 | } | |||
| 1283 | else { | 1283 | else { | |||
| 1284 | // browser global | 1284 | // browser global | |||
| 1285 | window.matchesSelector = matchesSelector; | 1285 | window.matchesSelector = matchesSelector; | |||
| 1286 | } | 1286 | } | |||
| 1287 | 1287 | |||||
| 1288 | })( Element.prototype ); | 1288 | })( Element.prototype ); | |||
| 1289 | 1289 | |||||
| 1290 | /** | 1290 | /** | |||
| 1291 | * Fizzy UI utils v1.0.1 | 1291 | * Fizzy UI utils v1.0.1 | |||
| 1292 | * MIT license | 1292 | * MIT license | |||
| 1293 | */ | 1293 | */ | |||
| 1294 | 1294 | |||||
| 1295 | /*jshint browser: true, undef: true, unused: true, strict: true */ | 1295 | /*jshint browser: true, undef: true, unused: true, strict: true */ | |||
| 1296 | 1296 | |||||
| 1297 | ( function( window, factory ) { | 1297 | ( function( window, factory ) { | |||
| 1298 | /*global define: false, module: false, require: false */ | 1298 | /*global define: false, module: false, require: false */ | |||
| 1299 | 1299 | |||||
| 1300 | // universal module definition | 1300 | // universal module definition | |||
| 1301 | 1301 | |||||
| 1302 | if ( typeof define == 'function' && define.amd ) { | 1302 | if ( typeof define == 'function' && define.amd ) { | |||
| 1303 | // AMD | 1303 | // AMD | |||
| 1304 | define( 'fizzy-ui-utils/utils',[ | 1304 | define( 'fizzy-ui-utils/utils',[ | |||
| 1305 | 'doc-ready/doc-ready', | 1305 | 'doc-ready/doc-ready', | |||
| 1306 | 'matches-selector/matches-selector' | 1306 | 'matches-selector/matches-selector' | |||
| 1307 | ], function( docReady, matchesSelector ) { | 1307 | ], function( docReady, matchesSelector ) { | |||
| 1308 | return factory( window, docReady, matchesSelector ); | 1308 | return factory( window, docReady, matchesSelector ); | |||
| 1309 | }); | 1309 | }); | |||
| 1310 | } else if ( typeof exports == 'object' ) { | 1310 | } else if ( typeof exports == 'object' ) { | |||
| 1311 | // CommonJS | 1311 | // CommonJS | |||
| 1312 | module.exports = factory( | 1312 | module.exports = factory( | |||
| 1313 | window, | 1313 | window, | |||
| 1314 | require('doc-ready'), | 1314 | require('doc-ready'), | |||
| 1315 | require('desandro-matches-selector') | 1315 | require('desandro-matches-selector') | |||
| 1316 | ); | 1316 | ); | |||
| 1317 | } else { | 1317 | } else { | |||
| 1318 | // browser global | 1318 | // browser global | |||
| 1319 | window.fizzyUIUtils = factory( | 1319 | window.fizzyUIUtils = factory( | |||
| 1320 | window, | 1320 | window, | |||
| 1321 | window.docReady, | 1321 | window.docReady, | |||
| 1322 | window.matchesSelector | 1322 | window.matchesSelector | |||
| 1323 | ); | 1323 | ); | |||
| 1324 | } | 1324 | } | |||
| 1325 | 1325 | |||||
| 1326 | }( window, function factory( window, docReady, matchesSelector ) { | 1326 | }( window, function factory( window, docReady, matchesSelector ) { | |||
| 1327 | 1327 | |||||
| 1328 | 1328 | |||||
| 1329 | 1329 | |||||
| 1330 | var utils = {}; | 1330 | var utils = {}; | |||
| 1331 | 1331 | |||||
| 1332 | // ----- extend ----- // | 1332 | // ----- extend ----- // | |||
| 1333 | 1333 | |||||
| 1334 | // extends objects | 1334 | // extends objects | |||
| 1335 | utils.extend = function( a, b ) { | 1335 | utils.extend = function( a, b ) { | |||
| 1336 | for ( var prop in b ) { | 1336 | for ( var prop in b ) { | |||
| 1337 | a[ prop ] = b[ prop ]; | 1337 | a[ prop ] = b[ prop ]; | |||
| 1338 | } | 1338 | } | |||
| 1339 | return a; | 1339 | return a; | |||
| 1340 | }; | 1340 | }; | |||
| 1341 | 1341 | |||||
| 1342 | // ----- modulo ----- // | 1342 | // ----- modulo ----- // | |||
| 1343 | 1343 | |||||
| 1344 | utils.modulo = function( num, div ) { | 1344 | utils.modulo = function( num, div ) { | |||
| 1345 | return ( ( num % div ) + div ) % div; | 1345 | return ( ( num % div ) + div ) % div; | |||
| 1346 | }; | 1346 | }; | |||
| 1347 | 1347 | |||||
| 1348 | // ----- isArray ----- // | 1348 | // ----- isArray ----- // | |||
| 1349 | 1349 | |||||
| 1350 | var objToString = Object.prototype.toString; | 1350 | var objToString = Object.prototype.toString; | |||
| 1351 | utils.isArray = function( obj ) { | 1351 | utils.isArray = function( obj ) { | |||
| 1352 | return objToString.call( obj ) == '[object Array]'; | 1352 | return objToString.call( obj ) == '[object Array]'; | |||
| 1353 | }; | 1353 | }; | |||
| 1354 | 1354 | |||||
| 1355 | // ----- makeArray ----- // | 1355 | // ----- makeArray ----- // | |||
| 1356 | 1356 | |||||
| 1357 | // turn element or nodeList into an array | 1357 | // turn element or nodeList into an array | |||
| 1358 | utils.makeArray = function( obj ) { | 1358 | utils.makeArray = function( obj ) { | |||
| 1359 | var ary = []; | 1359 | var ary = []; | |||
| 1360 | if ( utils.isArray( obj ) ) { | 1360 | if ( utils.isArray( obj ) ) { | |||
| 1361 | // use object if already an array | 1361 | // use object if already an array | |||
| 1362 | ary = obj; | 1362 | ary = obj; | |||
| 1363 | } else if ( obj && typeof obj.length == 'number' ) { | 1363 | } else if ( obj && typeof obj.length == 'number' ) { | |||
| 1364 | // convert nodeList to array | 1364 | // convert nodeList to array | |||
| 1365 | for ( var i=0, len = obj.length; i < len; i++ ) { | 1365 | for ( var i=0, len = obj.length; i < len; i++ ) { | |||
| 1366 | ary.push( obj[i] ); | 1366 | ary.push( obj[i] ); | |||
| 1367 | } | 1367 | } | |||
| 1368 | } else { | 1368 | } else { | |||
| 1369 | // array of single index | 1369 | // array of single index | |||
| 1370 | ary.push( obj ); | 1370 | ary.push( obj ); | |||
| 1371 | } | 1371 | } | |||
| 1372 | return ary; | 1372 | return ary; | |||
| 1373 | }; | 1373 | }; | |||
| 1374 | 1374 | |||||
| 1375 | // ----- indexOf ----- // | 1375 | // ----- indexOf ----- // | |||
| 1376 | 1376 | |||||
| 1377 | // index of helper cause IE8 | 1377 | // index of helper cause IE8 | |||
| 1378 | utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) { | 1378 | utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) { | |||
| 1379 | return ary.indexOf( obj ); | 1379 | return ary.indexOf( obj ); | |||
| 1380 | } : function( ary, obj ) { | 1380 | } : function( ary, obj ) { | |||
| 1381 | for ( var i=0, len = ary.length; i < len; i++ ) { | 1381 | for ( var i=0, len = ary.length; i < len; i++ ) { | |||
| 1382 | if ( ary[i] === obj ) { | 1382 | if ( ary[i] === obj ) { | |||
| 1383 | return i; | 1383 | return i; | |||
| 1384 | } | 1384 | } | |||
| 1385 | } | 1385 | } | |||
| 1386 | return -1; | 1386 | return -1; | |||
| 1387 | }; | 1387 | }; | |||
| 1388 | 1388 | |||||
| 1389 | // ----- removeFrom ----- // | 1389 | // ----- removeFrom ----- // | |||
| 1390 | 1390 | |||||
| 1391 | utils.removeFrom = function( ary, obj ) { | 1391 | utils.removeFrom = function( ary, obj ) { | |||
| 1392 | var index = utils.indexOf( ary, obj ); | 1392 | var index = utils.indexOf( ary, obj ); | |||
| 1393 | if ( index != -1 ) { | 1393 | if ( index != -1 ) { | |||
| 1394 | ary.splice( index, 1 ); | 1394 | ary.splice( index, 1 ); | |||
| 1395 | } | 1395 | } | |||
| 1396 | }; | 1396 | }; | |||
| 1397 | 1397 | |||||
| 1398 | // ----- isElement ----- // | 1398 | // ----- isElement ----- // | |||
| 1399 | 1399 | |||||
| 1400 | // http://stackoverflow.com/a/384380/182183 | 1400 | // http://stackoverflow.com/a/384380/182183 | |||
| 1401 | utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ? | 1401 | utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ? | |||
| 1402 | function isElementDOM2( obj ) { | 1402 | function isElementDOM2( obj ) { | |||
| 1403 | return obj instanceof HTMLElement; | 1403 | return obj instanceof HTMLElement; | |||
| 1404 | } : | 1404 | } : | |||
| 1405 | function isElementQuirky( obj ) { | 1405 | function isElementQuirky( obj ) { | |||
| 1406 | return obj && typeof obj == 'object' && | 1406 | return obj && typeof obj == 'object' && | |||
| 1407 | obj.nodeType == 1 && typeof obj.nodeName == 'string'; | 1407 | obj.nodeType == 1 && typeof obj.nodeName == 'string'; | |||
| 1408 | }; | 1408 | }; | |||
| 1409 | 1409 | |||||
| 1410 | // ----- setText ----- // | 1410 | // ----- setText ----- // | |||
| 1411 | 1411 | |||||
| 1412 | utils.setText = ( function() { | 1412 | utils.setText = ( function() { | |||
| 1413 | var setTextProperty; | 1413 | var setTextProperty; | |||
| 1414 | function setText( elem, text ) { | 1414 | function setText( elem, text ) { | |||
| 1415 | // only check setTextProperty once | 1415 | // only check setTextProperty once | |||
| 1416 | setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' ); | 1416 | setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' ); | |||
| 1417 | elem[ setTextProperty ] = text; | 1417 | elem[ setTextProperty ] = text; | |||
| 1418 | } | 1418 | } | |||
| 1419 | return setText; | 1419 | return setText; | |||
| 1420 | })(); | 1420 | })(); | |||
| 1421 | 1421 | |||||
| 1422 | // ----- getParent ----- // | 1422 | // ----- getParent ----- // | |||
| 1423 | 1423 | |||||
| 1424 | utils.getParent = function( elem, selector ) { | 1424 | utils.getParent = function( elem, selector ) { | |||
| 1425 | while ( elem != document.body ) { | 1425 | while ( elem != document.body ) { | |||
| 1426 | elem = elem.parentNode; | 1426 | elem = elem.parentNode; | |||
| 1427 | if ( matchesSelector( elem, selector ) ) { | 1427 | if ( matchesSelector( elem, selector ) ) { | |||
| 1428 | return elem; | 1428 | return elem; | |||
| 1429 | } | 1429 | } | |||
| 1430 | } | 1430 | } | |||
| 1431 | }; | 1431 | }; | |||
| 1432 | 1432 | |||||
| 1433 | // ----- getQueryElement ----- // | 1433 | // ----- getQueryElement ----- // | |||
| 1434 | 1434 | |||||
| 1435 | // use element as selector string | 1435 | // use element as selector string | |||
| 1436 | utils.getQueryElement = function( elem ) { | 1436 | utils.getQueryElement = function( elem ) { | |||
| 1437 | if ( typeof elem == 'string' ) { | 1437 | if ( typeof elem == 'string' ) { | |||
| 1438 | return document.querySelector( elem ); | 1438 | return document.querySelector( elem ); | |||
| 1439 | } | 1439 | } | |||
| 1440 | return elem; | 1440 | return elem; | |||
| 1441 | }; | 1441 | }; | |||
| 1442 | 1442 | |||||
| 1443 | // ----- handleEvent ----- // | 1443 | // ----- handleEvent ----- // | |||
| 1444 | 1444 | |||||
| 1445 | // enable .ontype to trigger from .addEventListener( elem, 'type' ) | 1445 | // enable .ontype to trigger from .addEventListener( elem, 'type' ) | |||
| 1446 | utils.handleEvent = function( event ) { | 1446 | utils.handleEvent = function( event ) { | |||
| 1447 | var method = 'on' + event.type; | 1447 | var method = 'on' + event.type; | |||
| 1448 | if ( this[ method ] ) { | 1448 | if ( this[ method ] ) { | |||
| 1449 | this[ method ]( event ); | 1449 | this[ method ]( event ); | |||
| 1450 | } | 1450 | } | |||
| 1451 | }; | 1451 | }; | |||
| 1452 | 1452 | |||||
| 1453 | // ----- filterFindElements ----- // | 1453 | // ----- filterFindElements ----- // | |||
| 1454 | 1454 | |||||
| 1455 | utils.filterFindElements = function( elems, selector ) { | 1455 | utils.filterFindElements = function( elems, selector ) { | |||
| 1456 | // make array of elems | 1456 | // make array of elems | |||
| 1457 | elems = utils.makeArray( elems ); | 1457 | elems = utils.makeArray( elems ); | |||
| 1458 | var ffElems = []; | 1458 | var ffElems = []; | |||
| 1459 | 1459 | |||||
| 1460 | for ( var i=0, len = elems.length; i < len; i++ ) { | 1460 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 1461 | var elem = elems[i]; | 1461 | var elem = elems[i]; | |||
| 1462 | // check that elem is an actual element | 1462 | // check that elem is an actual element | |||
| 1463 | if ( !utils.isElement( elem ) ) { | 1463 | if ( !utils.isElement( elem ) ) { | |||
| 1464 | continue; | 1464 | continue; | |||
| 1465 | } | 1465 | } | |||
| 1466 | // filter & find items if we have a selector | 1466 | // filter & find items if we have a selector | |||
| 1467 | if ( selector ) { | 1467 | if ( selector ) { | |||
| 1468 | // filter siblings | 1468 | // filter siblings | |||
| 1469 | if ( matchesSelector( elem, selector ) ) { | 1469 | if ( matchesSelector( elem, selector ) ) { | |||
| 1470 | ffElems.push( elem ); | 1470 | ffElems.push( elem ); | |||
| 1471 | } | 1471 | } | |||
| 1472 | // find children | 1472 | // find children | |||
| 1473 | var childElems = elem.querySelectorAll( selector ); | 1473 | var childElems = elem.querySelectorAll( selector ); | |||
| 1474 | // concat childElems to filterFound array | 1474 | // concat childElems to filterFound array | |||
| 1475 | for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { | 1475 | for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { | |||
| 1476 | ffElems.push( childElems[j] ); | 1476 | ffElems.push( childElems[j] ); | |||
| 1477 | } | 1477 | } | |||
| 1478 | } else { | 1478 | } else { | |||
| 1479 | ffElems.push( elem ); | 1479 | ffElems.push( elem ); | |||
| 1480 | } | 1480 | } | |||
| 1481 | } | 1481 | } | |||
| 1482 | 1482 | |||||
| 1483 | return ffElems; | 1483 | return ffElems; | |||
| 1484 | }; | 1484 | }; | |||
| 1485 | 1485 | |||||
| 1486 | // ----- debounceMethod ----- // | 1486 | // ----- debounceMethod ----- // | |||
| 1487 | 1487 | |||||
| 1488 | utils.debounceMethod = function( _class, methodName, threshold ) { | 1488 | utils.debounceMethod = function( _class, methodName, threshold ) { | |||
| 1489 | // original method | 1489 | // original method | |||
| 1490 | var method = _class.prototype[ methodName ]; | 1490 | var method = _class.prototype[ methodName ]; | |||
| 1491 | var timeoutName = methodName + 'Timeout'; | 1491 | var timeoutName = methodName + 'Timeout'; | |||
| 1492 | 1492 | |||||
| 1493 | _class.prototype[ methodName ] = function() { | 1493 | _class.prototype[ methodName ] = function() { | |||
| 1494 | var timeout = this[ timeoutName ]; | 1494 | var timeout = this[ timeoutName ]; | |||
| 1495 | if ( timeout ) { | 1495 | if ( timeout ) { | |||
| 1496 | clearTimeout( timeout ); | 1496 | clearTimeout( timeout ); | |||
| 1497 | } | 1497 | } | |||
| 1498 | var args = arguments; | 1498 | var args = arguments; | |||
| 1499 | 1499 | |||||
| 1500 | var _this = this; | 1500 | var _this = this; | |||
| 1501 | this[ timeoutName ] = setTimeout( function() { | 1501 | this[ timeoutName ] = setTimeout( function() { | |||
| 1502 | method.apply( _this, args ); | 1502 | method.apply( _this, args ); | |||
| 1503 | delete _this[ timeoutName ]; | 1503 | delete _this[ timeoutName ]; | |||
| 1504 | }, threshold || 100 ); | 1504 | }, threshold || 100 ); | |||
| 1505 | }; | 1505 | }; | |||
| 1506 | }; | 1506 | }; | |||
| 1507 | 1507 | |||||
| 1508 | // ----- htmlInit ----- // | 1508 | // ----- htmlInit ----- // | |||
| 1509 | 1509 | |||||
| 1510 | // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ | 1510 | // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ | |||
| 1511 | utils.toDashed = function( str ) { | 1511 | utils.toDashed = function( str ) { | |||
| 1512 | return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { | 1512 | return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { | |||
| 1513 | return $1 + '-' + $2; | 1513 | return $1 + '-' + $2; | |||
| 1514 | }).toLowerCase(); | 1514 | }).toLowerCase(); | |||
| 1515 | }; | 1515 | }; | |||
| 1516 | 1516 | |||||
| 1517 | var console = window.console; | 1517 | var console = window.console; | |||
| 1518 | /** | 1518 | /** | |||
| 1519 | * allow user to initialize classes via .js-namespace class | 1519 | * allow user to initialize classes via .js-namespace class | |||
| 1520 | * htmlInit( Widget, 'widgetName' ) | 1520 | * htmlInit( Widget, 'widgetName' ) | |||
| 1521 | * options are parsed from data-namespace-option attribute | 1521 | * options are parsed from data-namespace-option attribute | |||
| 1522 | */ | 1522 | */ | |||
| 1523 | utils.htmlInit = function( WidgetClass, namespace ) { | 1523 | utils.htmlInit = function( WidgetClass, namespace ) { | |||
| 1524 | docReady( function() { | 1524 | docReady( function() { | |||
| 1525 | var dashedNamespace = utils.toDashed( namespace ); | 1525 | var dashedNamespace = utils.toDashed( namespace ); | |||
| 1526 | var elems = document.querySelectorAll( '.js-' + dashedNamespace ); | 1526 | var elems = document.querySelectorAll( '.js-' + dashedNamespace ); | |||
| 1527 | var dataAttr = 'data-' + dashedNamespace + '-options'; | 1527 | var dataAttr = 'data-' + dashedNamespace + '-options'; | |||
| 1528 | 1528 | |||||
| 1529 | for ( var i=0, len = elems.length; i < len; i++ ) { | 1529 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 1530 | var elem = elems[i]; | 1530 | var elem = elems[i]; | |||
| 1531 | var attr = elem.getAttribute( dataAttr ); | 1531 | var attr = elem.getAttribute( dataAttr ); | |||
| 1532 | var options; | 1532 | var options; | |||
| 1533 | try { | 1533 | try { | |||
| 1534 | options = attr && JSON.parse( attr ); | 1534 | options = attr && JSON.parse( attr ); | |||
| 1535 | } catch ( error ) { | 1535 | } catch ( error ) { | |||
| 1536 | // log error, do not initialize | 1536 | // log error, do not initialize | |||
| 1537 | if ( console ) { | 1537 | if ( console ) { | |||
| 1538 | console.error( 'Error parsing ' + dataAttr + ' on ' + | 1538 | console.error( 'Error parsing ' + dataAttr + ' on ' + | |||
| 1539 | elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' + | 1539 | elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' + | |||
| 1540 | error ); | 1540 | error ); | |||
| 1541 | } | 1541 | } | |||
| 1542 | continue; | 1542 | continue; | |||
| 1543 | } | 1543 | } | |||
| 1544 | // initialize | 1544 | // initialize | |||
| 1545 | var instance = new WidgetClass( elem, options ); | 1545 | var instance = new WidgetClass( elem, options ); | |||
| 1546 | // make available via $().data('layoutname') | 1546 | // make available via $().data('layoutname') | |||
| 1547 | var jQuery = window.jQuery; | 1547 | var jQuery = window.jQuery; | |||
| 1548 | if ( jQuery ) { | 1548 | if ( jQuery ) { | |||
| 1549 | jQuery.data( elem, namespace, instance ); | 1549 | jQuery.data( elem, namespace, instance ); | |||
| 1550 | } | 1550 | } | |||
| 1551 | } | 1551 | } | |||
| 1552 | }); | 1552 | }); | |||
| 1553 | }; | 1553 | }; | |||
| 1554 | 1554 | |||||
| 1555 | // ----- ----- // | 1555 | // ----- ----- // | |||
| 1556 | 1556 | |||||
| 1557 | return utils; | 1557 | return utils; | |||
| 1558 | 1558 | |||||
| 1559 | })); | 1559 | })); | |||
| 1560 | 1560 | |||||
| 1561 | /** | 1561 | /** | |||
| 1562 | * Outlayer Item | 1562 | * Outlayer Item | |||
| 1563 | */ | 1563 | */ | |||
| 1564 | 1564 | |||||
| 1565 | ( function( window, factory ) { | 1565 | ( function( window, factory ) { | |||
| 1566 | 1566 | |||||
| 1567 | // universal module definition | 1567 | // universal module definition | |||
| 1568 | if ( typeof define === 'function' && define.amd ) { | 1568 | if ( typeof define === 'function' && define.amd ) { | |||
| 1569 | // AMD | 1569 | // AMD | |||
| 1570 | define( 'outlayer/item',[ | 1570 | define( 'outlayer/item',[ | |||
| 1571 | 'eventEmitter/EventEmitter', | 1571 | 'eventEmitter/EventEmitter', | |||
| 1572 | 'get-size/get-size', | 1572 | 'get-size/get-size', | |||
| 1573 | 'get-style-property/get-style-property', | 1573 | 'get-style-property/get-style-property', | |||
| 1574 | 'fizzy-ui-utils/utils' | 1574 | 'fizzy-ui-utils/utils' | |||
| 1575 | ], | 1575 | ], | |||
| 1576 | function( EventEmitter, getSize, getStyleProperty, utils ) { | 1576 | function( EventEmitter, getSize, getStyleProperty, utils ) { | |||
| 1577 | return factory( window, EventEmitter, getSize, getStyleProperty, utils ); | 1577 | return factory( window, EventEmitter, getSize, getStyleProperty, utils ); | |||
| 1578 | } | 1578 | } | |||
| 1579 | ); | 1579 | ); | |||
| 1580 | } else if (typeof exports === 'object') { | 1580 | } else if (typeof exports === 'object') { | |||
| 1581 | // CommonJS | 1581 | // CommonJS | |||
| 1582 | module.exports = factory( | 1582 | module.exports = factory( | |||
| 1583 | window, | 1583 | window, | |||
| 1584 | require('wolfy87-eventemitter'), | 1584 | require('wolfy87-eventemitter'), | |||
| 1585 | require('get-size'), | 1585 | require('get-size'), | |||
| 1586 | require('desandro-get-style-property'), | 1586 | require('desandro-get-style-property'), | |||
| 1587 | require('fizzy-ui-utils') | 1587 | require('fizzy-ui-utils') | |||
| 1588 | ); | 1588 | ); | |||
| 1589 | } else { | 1589 | } else { | |||
| 1590 | // browser global | 1590 | // browser global | |||
| 1591 | window.Outlayer = {}; | 1591 | window.Outlayer = {}; | |||
| 1592 | window.Outlayer.Item = factory( | 1592 | window.Outlayer.Item = factory( | |||
| 1593 | window, | 1593 | window, | |||
| 1594 | window.EventEmitter, | 1594 | window.EventEmitter, | |||
| 1595 | window.getSize, | 1595 | window.getSize, | |||
| 1596 | window.getStyleProperty, | 1596 | window.getStyleProperty, | |||
| 1597 | window.fizzyUIUtils | 1597 | window.fizzyUIUtils | |||
| 1598 | ); | 1598 | ); | |||
| 1599 | } | 1599 | } | |||
| 1600 | 1600 | |||||
| 1601 | }( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) { | 1601 | }( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) { | |||
| 1602 | 1602 | |||||
| 1603 | 1603 | |||||
| 1604 | // ----- helpers ----- // | 1604 | // ----- helpers ----- // | |||
| 1605 | 1605 | |||||
| 1606 | var getComputedStyle = window.getComputedStyle; | 1606 | var getComputedStyle = window.getComputedStyle; | |||
| 1607 | var getStyle = getComputedStyle ? | 1607 | var getStyle = getComputedStyle ? | |||
| 1608 | function( elem ) { | 1608 | function( elem ) { | |||
| 1609 | return getComputedStyle( elem, null ); | 1609 | return getComputedStyle( elem, null ); | |||
| 1610 | } : | 1610 | } : | |||
| 1611 | function( elem ) { | 1611 | function( elem ) { | |||
| 1612 | return elem.currentStyle; | 1612 | return elem.currentStyle; | |||
| 1613 | }; | 1613 | }; | |||
| 1614 | 1614 | |||||
| 1615 | 1615 | |||||
| 1616 | function isEmptyObj( obj ) { | 1616 | function isEmptyObj( obj ) { | |||
| 1617 | for ( var prop in obj ) { | 1617 | for ( var prop in obj ) { | |||
| 1618 | return false; | 1618 | return false; | |||
| 1619 | } | 1619 | } | |||
| 1620 | prop = null; | 1620 | prop = null; | |||
| 1621 | return true; | 1621 | return true; | |||
| 1622 | } | 1622 | } | |||
| 1623 | 1623 | |||||
| 1624 | // -------------------------- CSS3 support -------------------------- // | 1624 | // -------------------------- CSS3 support -------------------------- // | |||
| 1625 | 1625 | |||||
| 1626 | var transitionProperty = getStyleProperty('transition'); | 1626 | var transitionProperty = getStyleProperty('transition'); | |||
| 1627 | var transformProperty = getStyleProperty('transform'); | 1627 | var transformProperty = getStyleProperty('transform'); | |||
| 1628 | var supportsCSS3 = transitionProperty && transformProperty; | 1628 | var supportsCSS3 = transitionProperty && transformProperty; | |||
| 1629 | var is3d = !!getStyleProperty('perspective'); | 1629 | var is3d = !!getStyleProperty('perspective'); | |||
| 1630 | 1630 | |||||
| 1631 | var transitionEndEvent = { | 1631 | var transitionEndEvent = { | |||
| 1632 | WebkitTransition: 'webkitTransitionEnd', | 1632 | WebkitTransition: 'webkitTransitionEnd', | |||
| 1633 | MozTransition: 'transitionend', | 1633 | MozTransition: 'transitionend', | |||
| 1634 | OTransition: 'otransitionend', | 1634 | OTransition: 'otransitionend', | |||
| 1635 | transition: 'transitionend' | 1635 | transition: 'transitionend' | |||
| 1636 | }[ transitionProperty ]; | 1636 | }[ transitionProperty ]; | |||
| 1637 | 1637 | |||||
| 1638 | // properties that could have vendor prefix | 1638 | // properties that could have vendor prefix | |||
| 1639 | var prefixableProperties = [ | 1639 | var prefixableProperties = [ | |||
| 1640 | 'transform', | 1640 | 'transform', | |||
| 1641 | 'transition', | 1641 | 'transition', | |||
| 1642 | 'transitionDuration', | 1642 | 'transitionDuration', | |||
| 1643 | 'transitionProperty' | 1643 | 'transitionProperty' | |||
| 1644 | ]; | 1644 | ]; | |||
| 1645 | 1645 | |||||
| 1646 | // cache all vendor properties | 1646 | // cache all vendor properties | |||
| 1647 | var vendorProperties = ( function() { | 1647 | var vendorProperties = ( function() { | |||
| 1648 | var cache = {}; | 1648 | var cache = {}; | |||
| 1649 | for ( var i=0, len = prefixableProperties.length; i < len; i++ ) { | 1649 | for ( var i=0, len = prefixableProperties.length; i < len; i++ ) { | |||
| 1650 | var prop = prefixableProperties[i]; | 1650 | var prop = prefixableProperties[i]; | |||
| 1651 | var supportedProp = getStyleProperty( prop ); | 1651 | var supportedProp = getStyleProperty( prop ); | |||
| 1652 | if ( supportedProp && supportedProp !== prop ) { | 1652 | if ( supportedProp && supportedProp !== prop ) { | |||
| 1653 | cache[ prop ] = supportedProp; | 1653 | cache[ prop ] = supportedProp; | |||
| 1654 | } | 1654 | } | |||
| 1655 | } | 1655 | } | |||
| 1656 | return cache; | 1656 | return cache; | |||
| 1657 | })(); | 1657 | })(); | |||
| 1658 | 1658 | |||||
| 1659 | // -------------------------- Item -------------------------- // | 1659 | // -------------------------- Item -------------------------- // | |||
| 1660 | 1660 | |||||
| 1661 | function Item( element, layout ) { | 1661 | function Item( element, layout ) { | |||
| 1662 | if ( !element ) { | 1662 | if ( !element ) { | |||
| 1663 | return; | 1663 | return; | |||
| 1664 | } | 1664 | } | |||
| 1665 | 1665 | |||||
| 1666 | this.element = element; | 1666 | this.element = element; | |||
| 1667 | // parent layout class, i.e. Masonry, Isotope, or Packery | 1667 | // parent layout class, i.e. Masonry, Isotope, or Packery | |||
| 1668 | this.layout = layout; | 1668 | this.layout = layout; | |||
| 1669 | this.position = { | 1669 | this.position = { | |||
| 1670 | x: 0, | 1670 | x: 0, | |||
| 1671 | y: 0 | 1671 | y: 0 | |||
| 1672 | }; | 1672 | }; | |||
| 1673 | 1673 | |||||
| 1674 | this._create(); | 1674 | this._create(); | |||
| 1675 | } | 1675 | } | |||
| 1676 | 1676 | |||||
| 1677 | // inherit EventEmitter | 1677 | // inherit EventEmitter | |||
| 1678 | utils.extend( Item.prototype, EventEmitter.prototype ); | 1678 | utils.extend( Item.prototype, EventEmitter.prototype ); | |||
| 1679 | 1679 | |||||
| 1680 | Item.prototype._create = function() { | 1680 | Item.prototype._create = function() { | |||
| 1681 | // transition objects | 1681 | // transition objects | |||
| 1682 | this._transn = { | 1682 | this._transn = { | |||
| 1683 | ingProperties: {}, | 1683 | ingProperties: {}, | |||
| 1684 | clean: {}, | 1684 | clean: {}, | |||
| 1685 | onEnd: {} | 1685 | onEnd: {} | |||
| 1686 | }; | 1686 | }; | |||
| 1687 | 1687 | |||||
| 1688 | this.css({ | 1688 | this.css({ | |||
| 1689 | position: 'absolute' | 1689 | position: 'absolute' | |||
| 1690 | }); | 1690 | }); | |||
| 1691 | }; | 1691 | }; | |||
| 1692 | 1692 | |||||
| 1693 | // trigger specified handler for event type | 1693 | // trigger specified handler for event type | |||
| 1694 | Item.prototype.handleEvent = function( event ) { | 1694 | Item.prototype.handleEvent = function( event ) { | |||
| 1695 | var method = 'on' + event.type; | 1695 | var method = 'on' + event.type; | |||
| 1696 | if ( this[ method ] ) { | 1696 | if ( this[ method ] ) { | |||
| 1697 | this[ method ]( event ); | 1697 | this[ method ]( event ); | |||
| 1698 | } | 1698 | } | |||
| 1699 | }; | 1699 | }; | |||
| 1700 | 1700 | |||||
| 1701 | Item.prototype.getSize = function() { | 1701 | Item.prototype.getSize = function() { | |||
| 1702 | this.size = getSize( this.element ); | 1702 | this.size = getSize( this.element ); | |||
| 1703 | }; | 1703 | }; | |||
| 1704 | 1704 | |||||
| 1705 | /** | 1705 | /** | |||
| 1706 | * apply CSS styles to element | 1706 | * apply CSS styles to element | |||
| 1707 | * @param {Object} style | 1707 | * @param {Object} style | |||
| 1708 | */ | 1708 | */ | |||
| 1709 | Item.prototype.css = function( style ) { | 1709 | Item.prototype.css = function( style ) { | |||
| 1710 | var elemStyle = this.element.style; | 1710 | var elemStyle = this.element.style; | |||
| 1711 | 1711 | |||||
| 1712 | for ( var prop in style ) { | 1712 | for ( var prop in style ) { | |||
| 1713 | // use vendor property if available | 1713 | // use vendor property if available | |||
| 1714 | var supportedProp = vendorProperties[ prop ] || prop; | 1714 | var supportedProp = vendorProperties[ prop ] || prop; | |||
| 1715 | elemStyle[ supportedProp ] = style[ prop ]; | 1715 | elemStyle[ supportedProp ] = style[ prop ]; | |||
| 1716 | } | 1716 | } | |||
| 1717 | }; | 1717 | }; | |||
| 1718 | 1718 | |||||
| 1719 | // measure position, and sets it | 1719 | // measure position, and sets it | |||
| 1720 | Item.prototype.getPosition = function() { | 1720 | Item.prototype.getPosition = function() { | |||
| 1721 | var style = getStyle( this.element ); | 1721 | var style = getStyle( this.element ); | |||
| 1722 | var layoutOptions = this.layout.options; | 1722 | var layoutOptions = this.layout.options; | |||
| 1723 | var isOriginLeft = layoutOptions.isOriginLeft; | 1723 | var isOriginLeft = layoutOptions.isOriginLeft; | |||
| 1724 | var isOriginTop = layoutOptions.isOriginTop; | 1724 | var isOriginTop = layoutOptions.isOriginTop; | |||
| 1725 | var xValue = style[ isOriginLeft ? 'left' : 'right' ]; | 1725 | var xValue = style[ isOriginLeft ? 'left' : 'right' ]; | |||
| 1726 | var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; | 1726 | var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; | |||
| 1727 | // convert percent to pixels | 1727 | // convert percent to pixels | |||
| 1728 | var layoutSize = this.layout.size; | 1728 | var layoutSize = this.layout.size; | |||
| 1729 | var x = xValue.indexOf('%') != -1 ? | 1729 | var x = xValue.indexOf('%') != -1 ? | |||
| 1730 | ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 ); | 1730 | ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 ); | |||
| 1731 | var y = yValue.indexOf('%') != -1 ? | 1731 | var y = yValue.indexOf('%') != -1 ? | |||
| 1732 | ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 ); | 1732 | ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 ); | |||
| 1733 | 1733 | |||||
| 1734 | // clean up 'auto' or other non-integer values | 1734 | // clean up 'auto' or other non-integer values | |||
| 1735 | x = isNaN( x ) ? 0 : x; | 1735 | x = isNaN( x ) ? 0 : x; | |||
| 1736 | y = isNaN( y ) ? 0 : y; | 1736 | y = isNaN( y ) ? 0 : y; | |||
| 1737 | // remove padding from measurement | 1737 | // remove padding from measurement | |||
| 1738 | x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; | 1738 | x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; | |||
| 1739 | y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; | 1739 | y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; | |||
| 1740 | 1740 | |||||
| 1741 | this.position.x = x; | 1741 | this.position.x = x; | |||
| 1742 | this.position.y = y; | 1742 | this.position.y = y; | |||
| 1743 | }; | 1743 | }; | |||
| 1744 | 1744 | |||||
| 1745 | // set settled position, apply padding | 1745 | // set settled position, apply padding | |||
| 1746 | Item.prototype.layoutPosition = function() { | 1746 | Item.prototype.layoutPosition = function() { | |||
| 1747 | var layoutSize = this.layout.size; | 1747 | var layoutSize = this.layout.size; | |||
| 1748 | var layoutOptions = this.layout.options; | 1748 | var layoutOptions = this.layout.options; | |||
| 1749 | var style = {}; | 1749 | var style = {}; | |||
| 1750 | 1750 | |||||
| 1751 | // x | 1751 | // x | |||
| 1752 | var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight'; | 1752 | var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight'; | |||
| 1753 | var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right'; | 1753 | var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right'; | |||
| 1754 | var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left'; | 1754 | var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left'; | |||
| 1755 | 1755 | |||||
| 1756 | var x = this.position.x + layoutSize[ xPadding ]; | 1756 | var x = this.position.x + layoutSize[ xPadding ]; | |||
| 1757 | // set in percentage or pixels | 1757 | // set in percentage or pixels | |||
| 1758 | style[ xProperty ] = this.getXValue( x ); | 1758 | style[ xProperty ] = this.getXValue( x ); | |||
| 1759 | // reset other property | 1759 | // reset other property | |||
| 1760 | style[ xResetProperty ] = ''; | 1760 | style[ xResetProperty ] = ''; | |||
| 1761 | 1761 | |||||
| 1762 | // y | 1762 | // y | |||
| 1763 | var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom'; | 1763 | var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom'; | |||
| 1764 | var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom'; | 1764 | var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom'; | |||
| 1765 | var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top'; | 1765 | var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top'; | |||
| 1766 | 1766 | |||||
| 1767 | var y = this.position.y + layoutSize[ yPadding ]; | 1767 | var y = this.position.y + layoutSize[ yPadding ]; | |||
| 1768 | // set in percentage or pixels | 1768 | // set in percentage or pixels | |||
| 1769 | style[ yProperty ] = this.getYValue( y ); | 1769 | style[ yProperty ] = this.getYValue( y ); | |||
| 1770 | // reset other property | 1770 | // reset other property | |||
| 1771 | style[ yResetProperty ] = ''; | 1771 | style[ yResetProperty ] = ''; | |||
| 1772 | 1772 | |||||
| 1773 | this.css( style ); | 1773 | this.css( style ); | |||
| 1774 | this.emitEvent( 'layout', [ this ] ); | 1774 | this.emitEvent( 'layout', [ this ] ); | |||
| 1775 | }; | 1775 | }; | |||
| 1776 | 1776 | |||||
| 1777 | Item.prototype.getXValue = function( x ) { | 1777 | Item.prototype.getXValue = function( x ) { | |||
| 1778 | var layoutOptions = this.layout.options; | 1778 | var layoutOptions = this.layout.options; | |||
| 1779 | return layoutOptions.percentPosition && !layoutOptions.isHorizontal ? | 1779 | return layoutOptions.percentPosition && !layoutOptions.isHorizontal ? | |||
| 1780 | ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; | 1780 | ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; | |||
| 1781 | }; | 1781 | }; | |||
| 1782 | 1782 | |||||
| 1783 | Item.prototype.getYValue = function( y ) { | 1783 | Item.prototype.getYValue = function( y ) { | |||
| 1784 | var layoutOptions = this.layout.options; | 1784 | var layoutOptions = this.layout.options; | |||
| 1785 | return layoutOptions.percentPosition && layoutOptions.isHorizontal ? | 1785 | return layoutOptions.percentPosition && layoutOptions.isHorizontal ? | |||
| 1786 | ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; | 1786 | ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; | |||
| 1787 | }; | 1787 | }; | |||
| 1788 | 1788 | |||||
| 1789 | 1789 | |||||
| 1790 | Item.prototype._transitionTo = function( x, y ) { | 1790 | Item.prototype._transitionTo = function( x, y ) { | |||
| 1791 | this.getPosition(); | 1791 | this.getPosition(); | |||
| 1792 | // get current x & y from top/left | 1792 | // get current x & y from top/left | |||
| 1793 | var curX = this.position.x; | 1793 | var curX = this.position.x; | |||
| 1794 | var curY = this.position.y; | 1794 | var curY = this.position.y; | |||
| 1795 | 1795 | |||||
| 1796 | var compareX = parseInt( x, 10 ); | 1796 | var compareX = parseInt( x, 10 ); | |||
| 1797 | var compareY = parseInt( y, 10 ); | 1797 | var compareY = parseInt( y, 10 ); | |||
| 1798 | var didNotMove = compareX === this.position.x && compareY === this.position.y; | 1798 | var didNotMove = compareX === this.position.x && compareY === this.position.y; | |||
| 1799 | 1799 | |||||
| 1800 | // save end position | 1800 | // save end position | |||
| 1801 | this.setPosition( x, y ); | 1801 | this.setPosition( x, y ); | |||
| 1802 | 1802 | |||||
| 1803 | // if did not move and not transitioning, just go to layout | 1803 | // if did not move and not transitioning, just go to layout | |||
| 1804 | if ( didNotMove && !this.isTransitioning ) { | 1804 | if ( didNotMove && !this.isTransitioning ) { | |||
| 1805 | this.layoutPosition(); | 1805 | this.layoutPosition(); | |||
| 1806 | return; | 1806 | return; | |||
| 1807 | } | 1807 | } | |||
| 1808 | 1808 | |||||
| 1809 | var transX = x - curX; | 1809 | var transX = x - curX; | |||
| 1810 | var transY = y - curY; | 1810 | var transY = y - curY; | |||
| 1811 | var transitionStyle = {}; | 1811 | var transitionStyle = {}; | |||
| 1812 | transitionStyle.transform = this.getTranslate( transX, transY ); | 1812 | transitionStyle.transform = this.getTranslate( transX, transY ); | |||
| 1813 | 1813 | |||||
| 1814 | this.transition({ | 1814 | this.transition({ | |||
| 1815 | to: transitionStyle, | 1815 | to: transitionStyle, | |||
| 1816 | onTransitionEnd: { | 1816 | onTransitionEnd: { | |||
| 1817 | transform: this.layoutPosition | 1817 | transform: this.layoutPosition | |||
| 1818 | }, | 1818 | }, | |||
| 1819 | isCleaning: true | 1819 | isCleaning: true | |||
| 1820 | }); | 1820 | }); | |||
| 1821 | }; | 1821 | }; | |||
| 1822 | 1822 | |||||
| 1823 | Item.prototype.getTranslate = function( x, y ) { | 1823 | Item.prototype.getTranslate = function( x, y ) { | |||
| 1824 | // flip cooridinates if origin on right or bottom | 1824 | // flip cooridinates if origin on right or bottom | |||
| 1825 | var layoutOptions = this.layout.options; | 1825 | var layoutOptions = this.layout.options; | |||
| 1826 | x = layoutOptions.isOriginLeft ? x : -x; | 1826 | x = layoutOptions.isOriginLeft ? x : -x; | |||
| 1827 | y = layoutOptions.isOriginTop ? y : -y; | 1827 | y = layoutOptions.isOriginTop ? y : -y; | |||
| 1828 | 1828 | |||||
| 1829 | if ( is3d ) { | 1829 | if ( is3d ) { | |||
| 1830 | return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; | 1830 | return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; | |||
| 1831 | } | 1831 | } | |||
| 1832 | 1832 | |||||
| 1833 | return 'translate(' + x + 'px, ' + y + 'px)'; | 1833 | return 'translate(' + x + 'px, ' + y + 'px)'; | |||
| 1834 | }; | 1834 | }; | |||
| 1835 | 1835 | |||||
| 1836 | // non transition + transform support | 1836 | // non transition + transform support | |||
| 1837 | Item.prototype.goTo = function( x, y ) { | 1837 | Item.prototype.goTo = function( x, y ) { | |||
| 1838 | this.setPosition( x, y ); | 1838 | this.setPosition( x, y ); | |||
| 1839 | this.layoutPosition(); | 1839 | this.layoutPosition(); | |||
| 1840 | }; | 1840 | }; | |||
| 1841 | 1841 | |||||
| 1842 | // use transition and transforms if supported | 1842 | // use transition and transforms if supported | |||
| 1843 | Item.prototype.moveTo = supportsCSS3 ? | 1843 | Item.prototype.moveTo = supportsCSS3 ? | |||
| 1844 | Item.prototype._transitionTo : Item.prototype.goTo; | 1844 | Item.prototype._transitionTo : Item.prototype.goTo; | |||
| 1845 | 1845 | |||||
| 1846 | Item.prototype.setPosition = function( x, y ) { | 1846 | Item.prototype.setPosition = function( x, y ) { | |||
| 1847 | this.position.x = parseInt( x, 10 ); | 1847 | this.position.x = parseInt( x, 10 ); | |||
| 1848 | this.position.y = parseInt( y, 10 ); | 1848 | this.position.y = parseInt( y, 10 ); | |||
| 1849 | }; | 1849 | }; | |||
| 1850 | 1850 | |||||
| 1851 | // ----- transition ----- // | 1851 | // ----- transition ----- // | |||
| 1852 | 1852 | |||||
| 1853 | /** | 1853 | /** | |||
| 1854 | * @param {Object} style - CSS | 1854 | * @param {Object} style - CSS | |||
| 1855 | * @param {Function} onTransitionEnd | 1855 | * @param {Function} onTransitionEnd | |||
| 1856 | */ | 1856 | */ | |||
| 1857 | 1857 | |||||
| 1858 | // non transition, just trigger callback | 1858 | // non transition, just trigger callback | |||
| 1859 | Item.prototype._nonTransition = function( args ) { | 1859 | Item.prototype._nonTransition = function( args ) { | |||
| 1860 | this.css( args.to ); | 1860 | this.css( args.to ); | |||
| 1861 | if ( args.isCleaning ) { | 1861 | if ( args.isCleaning ) { | |||
| 1862 | this._removeStyles( args.to ); | 1862 | this._removeStyles( args.to ); | |||
| 1863 | } | 1863 | } | |||
| 1864 | for ( var prop in args.onTransitionEnd ) { | 1864 | for ( var prop in args.onTransitionEnd ) { | |||
| 1865 | args.onTransitionEnd[ prop ].call( this ); | 1865 | args.onTransitionEnd[ prop ].call( this ); | |||
| 1866 | } | 1866 | } | |||
| 1867 | }; | 1867 | }; | |||
| 1868 | 1868 | |||||
| 1869 | /** | 1869 | /** | |||
| 1870 | * proper transition | 1870 | * proper transition | |||
| 1871 | * @param {Object} args - arguments | 1871 | * @param {Object} args - arguments | |||
| 1872 | * @param {Object} to - style to transition to | 1872 | * @param {Object} to - style to transition to | |||
| 1873 | * @param {Object} from - style to start transition from | 1873 | * @param {Object} from - style to start transition from | |||
| 1874 | * @param {Boolean} isCleaning - removes transition styles after transition | 1874 | * @param {Boolean} isCleaning - removes transition styles after transition | |||
| 1875 | * @param {Function} onTransitionEnd - callback | 1875 | * @param {Function} onTransitionEnd - callback | |||
| 1876 | */ | 1876 | */ | |||
| 1877 | Item.prototype._transition = function( args ) { | 1877 | Item.prototype._transition = function( args ) { | |||
| 1878 | // redirect to nonTransition if no transition duration | 1878 | // redirect to nonTransition if no transition duration | |||
| 1879 | if ( !parseFloat( this.layout.options.transitionDuration ) ) { | 1879 | if ( !parseFloat( this.layout.options.transitionDuration ) ) { | |||
| 1880 | this._nonTransition( args ); | 1880 | this._nonTransition( args ); | |||
| 1881 | return; | 1881 | return; | |||
| 1882 | } | 1882 | } | |||
| 1883 | 1883 | |||||
| 1884 | var _transition = this._transn; | 1884 | var _transition = this._transn; | |||
| 1885 | // keep track of onTransitionEnd callback by css property | 1885 | // keep track of onTransitionEnd callback by css property | |||
| 1886 | for ( var prop in args.onTransitionEnd ) { | 1886 | for ( var prop in args.onTransitionEnd ) { | |||
| 1887 | _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; | 1887 | _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; | |||
| 1888 | } | 1888 | } | |||
| 1889 | // keep track of properties that are transitioning | 1889 | // keep track of properties that are transitioning | |||
| 1890 | for ( prop in args.to ) { | 1890 | for ( prop in args.to ) { | |||
| 1891 | _transition.ingProperties[ prop ] = true; | 1891 | _transition.ingProperties[ prop ] = true; | |||
| 1892 | // keep track of properties to clean up when transition is done | 1892 | // keep track of properties to clean up when transition is done | |||
| 1893 | if ( args.isCleaning ) { | 1893 | if ( args.isCleaning ) { | |||
| 1894 | _transition.clean[ prop ] = true; | 1894 | _transition.clean[ prop ] = true; | |||
| 1895 | } | 1895 | } | |||
| 1896 | } | 1896 | } | |||
| 1897 | 1897 | |||||
| 1898 | // set from styles | 1898 | // set from styles | |||
| 1899 | if ( args.from ) { | 1899 | if ( args.from ) { | |||
| 1900 | this.css( args.from ); | 1900 | this.css( args.from ); | |||
| 1901 | // force redraw. http://blog.alexmaccaw.com/css-transitions | 1901 | // force redraw. http://blog.alexmaccaw.com/css-transitions | |||
| 1902 | var h = this.element.offsetHeight; | 1902 | var h = this.element.offsetHeight; | |||
| 1903 | // hack for JSHint to hush about unused var | 1903 | // hack for JSHint to hush about unused var | |||
| 1904 | h = null; | 1904 | h = null; | |||
| 1905 | } | 1905 | } | |||
| 1906 | // enable transition | 1906 | // enable transition | |||
| 1907 | this.enableTransition( args.to ); | 1907 | this.enableTransition( args.to ); | |||
| 1908 | // set styles that are transitioning | 1908 | // set styles that are transitioning | |||
| 1909 | this.css( args.to ); | 1909 | this.css( args.to ); | |||
| 1910 | 1910 | |||||
| 1911 | this.isTransitioning = true; | 1911 | this.isTransitioning = true; | |||
| 1912 | 1912 | |||||
| 1913 | }; | 1913 | }; | |||
| 1914 | 1914 | |||||
| 1915 | // dash before all cap letters, including first for | 1915 | // dash before all cap letters, including first for | |||
| 1916 | // WebkitTransform => -webkit-transform | 1916 | // WebkitTransform => -webkit-transform | |||
| 1917 | function toDashedAll( str ) { | 1917 | function toDashedAll( str ) { | |||
| 1918 | return str.replace( /([A-Z])/g, function( $1 ) { | 1918 | return str.replace( /([A-Z])/g, function( $1 ) { | |||
| 1919 | return '-' + $1.toLowerCase(); | 1919 | return '-' + $1.toLowerCase(); | |||
| 1920 | }); | 1920 | }); | |||
| 1921 | } | 1921 | } | |||
| 1922 | 1922 | |||||
| 1923 | var transitionProps = 'opacity,' + | 1923 | var transitionProps = 'opacity,' + | |||
| 1924 | toDashedAll( vendorProperties.transform || 'transform' ); | 1924 | toDashedAll( vendorProperties.transform || 'transform' ); | |||
| 1925 | 1925 | |||||
| 1926 | Item.prototype.enableTransition = function(/* style */) { | 1926 | Item.prototype.enableTransition = function(/* style */) { | |||
| 1927 | // HACK changing transitionProperty during a transition | 1927 | // HACK changing transitionProperty during a transition | |||
| 1928 | // will cause transition to jump | 1928 | // will cause transition to jump | |||
| 1929 | if ( this.isTransitioning ) { | 1929 | if ( this.isTransitioning ) { | |||
| 1930 | return; | 1930 | return; | |||
| 1931 | } | 1931 | } | |||
| 1932 | 1932 | |||||
| 1933 | // make `transition: foo, bar, baz` from style object | 1933 | // make `transition: foo, bar, baz` from style object | |||
| 1934 | // HACK un-comment this when enableTransition can work | 1934 | // HACK un-comment this when enableTransition can work | |||
| 1935 | // while a transition is happening | 1935 | // while a transition is happening | |||
| 1936 | // var transitionValues = []; | 1936 | // var transitionValues = []; | |||
| 1937 | // for ( var prop in style ) { | 1937 | // for ( var prop in style ) { | |||
| 1938 | // // dash-ify camelCased properties like WebkitTransition | 1938 | // // dash-ify camelCased properties like WebkitTransition | |||
| 1939 | // prop = vendorProperties[ prop ] || prop; | 1939 | // prop = vendorProperties[ prop ] || prop; | |||
| 1940 | // transitionValues.push( toDashedAll( prop ) ); | 1940 | // transitionValues.push( toDashedAll( prop ) ); | |||
| 1941 | // } | 1941 | // } | |||
| 1942 | // enable transition styles | 1942 | // enable transition styles | |||
| 1943 | this.css({ | 1943 | this.css({ | |||
| 1944 | transitionProperty: transitionProps, | 1944 | transitionProperty: transitionProps, | |||
| 1945 | transitionDuration: this.layout.options.transitionDuration | 1945 | transitionDuration: this.layout.options.transitionDuration | |||
| 1946 | }); | 1946 | }); | |||
| 1947 | // listen for transition end event | 1947 | // listen for transition end event | |||
| 1948 | this.element.addEventListener( transitionEndEvent, this, false ); | 1948 | this.element.addEventListener( transitionEndEvent, this, false ); | |||
| 1949 | }; | 1949 | }; | |||
| 1950 | 1950 | |||||
| 1951 | Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ]; | 1951 | Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ]; | |||
| 1952 | 1952 | |||||
| 1953 | // ----- events ----- // | 1953 | // ----- events ----- // | |||
| 1954 | 1954 | |||||
| 1955 | Item.prototype.onwebkitTransitionEnd = function( event ) { | 1955 | Item.prototype.onwebkitTransitionEnd = function( event ) { | |||
| 1956 | this.ontransitionend( event ); | 1956 | this.ontransitionend( event ); | |||
| 1957 | }; | 1957 | }; | |||
| 1958 | 1958 | |||||
| 1959 | Item.prototype.onotransitionend = function( event ) { | 1959 | Item.prototype.onotransitionend = function( event ) { | |||
| 1960 | this.ontransitionend( event ); | 1960 | this.ontransitionend( event ); | |||
| 1961 | }; | 1961 | }; | |||
| 1962 | 1962 | |||||
| 1963 | // properties that I munge to make my life easier | 1963 | // properties that I munge to make my life easier | |||
| 1964 | var dashedVendorProperties = { | 1964 | var dashedVendorProperties = { | |||
| 1965 | '-webkit-transform': 'transform', | 1965 | '-webkit-transform': 'transform', | |||
| 1966 | '-moz-transform': 'transform', | 1966 | '-moz-transform': 'transform', | |||
| 1967 | '-o-transform': 'transform' | 1967 | '-o-transform': 'transform' | |||
| 1968 | }; | 1968 | }; | |||
| 1969 | 1969 | |||||
| 1970 | Item.prototype.ontransitionend = function( event ) { | 1970 | Item.prototype.ontransitionend = function( event ) { | |||
| 1971 | // disregard bubbled events from children | 1971 | // disregard bubbled events from children | |||
| 1972 | if ( event.target !== this.element ) { | 1972 | if ( event.target !== this.element ) { | |||
| 1973 | return; | 1973 | return; | |||
| 1974 | } | 1974 | } | |||
| 1975 | var _transition = this._transn; | 1975 | var _transition = this._transn; | |||
| 1976 | // get property name of transitioned property, convert to prefix-free | 1976 | // get property name of transitioned property, convert to prefix-free | |||
| 1977 | var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; | 1977 | var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; | |||
| 1978 | 1978 | |||||
| 1979 | // remove property that has completed transitioning | 1979 | // remove property that has completed transitioning | |||
| 1980 | delete _transition.ingProperties[ propertyName ]; | 1980 | delete _transition.ingProperties[ propertyName ]; | |||
| 1981 | // check if any properties are still transitioning | 1981 | // check if any properties are still transitioning | |||
| 1982 | if ( isEmptyObj( _transition.ingProperties ) ) { | 1982 | if ( isEmptyObj( _transition.ingProperties ) ) { | |||
| 1983 | // all properties have completed transitioning | 1983 | // all properties have completed transitioning | |||
| 1984 | this.disableTransition(); | 1984 | this.disableTransition(); | |||
| 1985 | } | 1985 | } | |||
| 1986 | // clean style | 1986 | // clean style | |||
| 1987 | if ( propertyName in _transition.clean ) { | 1987 | if ( propertyName in _transition.clean ) { | |||
| 1988 | // clean up style | 1988 | // clean up style | |||
| 1989 | this.element.style[ event.propertyName ] = ''; | 1989 | this.element.style[ event.propertyName ] = ''; | |||
| 1990 | delete _transition.clean[ propertyName ]; | 1990 | delete _transition.clean[ propertyName ]; | |||
| 1991 | } | 1991 | } | |||
| 1992 | // trigger onTransitionEnd callback | 1992 | // trigger onTransitionEnd callback | |||
| 1993 | if ( propertyName in _transition.onEnd ) { | 1993 | if ( propertyName in _transition.onEnd ) { | |||
| 1994 | var onTransitionEnd = _transition.onEnd[ propertyName ]; | 1994 | var onTransitionEnd = _transition.onEnd[ propertyName ]; | |||
| 1995 | onTransitionEnd.call( this ); | 1995 | onTransitionEnd.call( this ); | |||
| 1996 | delete _transition.onEnd[ propertyName ]; | 1996 | delete _transition.onEnd[ propertyName ]; | |||
| 1997 | } | 1997 | } | |||
| 1998 | 1998 | |||||
| 1999 | this.emitEvent( 'transitionEnd', [ this ] ); | 1999 | this.emitEvent( 'transitionEnd', [ this ] ); | |||
| 2000 | }; | 2000 | }; | |||
| 2001 | 2001 | |||||
| 2002 | Item.prototype.disableTransition = function() { | 2002 | Item.prototype.disableTransition = function() { | |||
| 2003 | this.removeTransitionStyles(); | 2003 | this.removeTransitionStyles(); | |||
| 2004 | this.element.removeEventListener( transitionEndEvent, this, false ); | 2004 | this.element.removeEventListener( transitionEndEvent, this, false ); | |||
| 2005 | this.isTransitioning = false; | 2005 | this.isTransitioning = false; | |||
| 2006 | }; | 2006 | }; | |||
| 2007 | 2007 | |||||
| 2008 | /** | 2008 | /** | |||
| 2009 | * removes style property from element | 2009 | * removes style property from element | |||
| 2010 | * @param {Object} style | 2010 | * @param {Object} style | |||
| 2011 | **/ | 2011 | **/ | |||
| 2012 | Item.prototype._removeStyles = function( style ) { | 2012 | Item.prototype._removeStyles = function( style ) { | |||
| 2013 | // clean up transition styles | 2013 | // clean up transition styles | |||
| 2014 | var cleanStyle = {}; | 2014 | var cleanStyle = {}; | |||
| 2015 | for ( var prop in style ) { | 2015 | for ( var prop in style ) { | |||
| 2016 | cleanStyle[ prop ] = ''; | 2016 | cleanStyle[ prop ] = ''; | |||
| 2017 | } | 2017 | } | |||
| 2018 | this.css( cleanStyle ); | 2018 | this.css( cleanStyle ); | |||
| 2019 | }; | 2019 | }; | |||
| 2020 | 2020 | |||||
| 2021 | var cleanTransitionStyle = { | 2021 | var cleanTransitionStyle = { | |||
| 2022 | transitionProperty: '', | 2022 | transitionProperty: '', | |||
| 2023 | transitionDuration: '' | 2023 | transitionDuration: '' | |||
| 2024 | }; | 2024 | }; | |||
| 2025 | 2025 | |||||
| 2026 | Item.prototype.removeTransitionStyles = function() { | 2026 | Item.prototype.removeTransitionStyles = function() { | |||
| 2027 | // remove transition | 2027 | // remove transition | |||
| 2028 | this.css( cleanTransitionStyle ); | 2028 | this.css( cleanTransitionStyle ); | |||
| 2029 | }; | 2029 | }; | |||
| 2030 | 2030 | |||||
| 2031 | // ----- show/hide/remove ----- // | 2031 | // ----- show/hide/remove ----- // | |||
| 2032 | 2032 | |||||
| 2033 | // remove element from DOM | 2033 | // remove element from DOM | |||
| 2034 | Item.prototype.removeElem = function() { | 2034 | Item.prototype.removeElem = function() { | |||
| 2035 | this.element.parentNode.removeChild( this.element ); | 2035 | this.element.parentNode.removeChild( this.element ); | |||
| 2036 | // remove display: none | 2036 | // remove display: none | |||
| 2037 | this.css({ display: '' }); | 2037 | this.css({ display: '' }); | |||
| 2038 | this.emitEvent( 'remove', [ this ] ); | 2038 | this.emitEvent( 'remove', [ this ] ); | |||
| 2039 | }; | 2039 | }; | |||
| 2040 | 2040 | |||||
| 2041 | Item.prototype.remove = function() { | 2041 | Item.prototype.remove = function() { | |||
| 2042 | // just remove element if no transition support or no transition | 2042 | // just remove element if no transition support or no transition | |||
| 2043 | if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { | 2043 | if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { | |||
| 2044 | this.removeElem(); | 2044 | this.removeElem(); | |||
| 2045 | return; | 2045 | return; | |||
| 2046 | } | 2046 | } | |||
| 2047 | 2047 | |||||
| 2048 | // start transition | 2048 | // start transition | |||
| 2049 | var _this = this; | 2049 | var _this = this; | |||
| 2050 | this.once( 'transitionEnd', function() { | 2050 | this.once( 'transitionEnd', function() { | |||
| 2051 | _this.removeElem(); | 2051 | _this.removeElem(); | |||
| 2052 | }); | 2052 | }); | |||
| 2053 | this.hide(); | 2053 | this.hide(); | |||
| 2054 | }; | 2054 | }; | |||
| 2055 | 2055 | |||||
| 2056 | Item.prototype.reveal = function() { | 2056 | Item.prototype.reveal = function() { | |||
| 2057 | delete this.isHidden; | 2057 | delete this.isHidden; | |||
| 2058 | // remove display: none | 2058 | // remove display: none | |||
| 2059 | this.css({ display: '' }); | 2059 | this.css({ display: '' }); | |||
| 2060 | 2060 | |||||
| 2061 | var options = this.layout.options; | 2061 | var options = this.layout.options; | |||
| 2062 | 2062 | |||||
| 2063 | var onTransitionEnd = {}; | 2063 | var onTransitionEnd = {}; | |||
| 2064 | var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); | 2064 | var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); | |||
| 2065 | onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; | 2065 | onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; | |||
| 2066 | 2066 | |||||
| 2067 | this.transition({ | 2067 | this.transition({ | |||
| 2068 | from: options.hiddenStyle, | 2068 | from: options.hiddenStyle, | |||
| 2069 | to: options.visibleStyle, | 2069 | to: options.visibleStyle, | |||
| 2070 | isCleaning: true, | 2070 | isCleaning: true, | |||
| 2071 | onTransitionEnd: onTransitionEnd | 2071 | onTransitionEnd: onTransitionEnd | |||
| 2072 | }); | 2072 | }); | |||
| 2073 | }; | 2073 | }; | |||
| 2074 | 2074 | |||||
| 2075 | Item.prototype.onRevealTransitionEnd = function() { | 2075 | Item.prototype.onRevealTransitionEnd = function() { | |||
| 2076 | // check if still visible | 2076 | // check if still visible | |||
| 2077 | // during transition, item may have been hidden | 2077 | // during transition, item may have been hidden | |||
| 2078 | if ( !this.isHidden ) { | 2078 | if ( !this.isHidden ) { | |||
| 2079 | this.emitEvent('reveal'); | 2079 | this.emitEvent('reveal'); | |||
| 2080 | } | 2080 | } | |||
| 2081 | }; | 2081 | }; | |||
| 2082 | 2082 | |||||
| 2083 | /** | 2083 | /** | |||
| 2084 | * get style property use for hide/reveal transition end | 2084 | * get style property use for hide/reveal transition end | |||
| 2085 | * @param {String} styleProperty - hiddenStyle/visibleStyle | 2085 | * @param {String} styleProperty - hiddenStyle/visibleStyle | |||
| 2086 | * @returns {String} | 2086 | * @returns {String} | |||
| 2087 | */ | 2087 | */ | |||
| 2088 | Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) { | 2088 | Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) { | |||
| 2089 | var optionStyle = this.layout.options[ styleProperty ]; | 2089 | var optionStyle = this.layout.options[ styleProperty ]; | |||
| 2090 | // use opacity | 2090 | // use opacity | |||
| 2091 | if ( optionStyle.opacity ) { | 2091 | if ( optionStyle.opacity ) { | |||
| 2092 | return 'opacity'; | 2092 | return 'opacity'; | |||
| 2093 | } | 2093 | } | |||
| 2094 | // get first property | 2094 | // get first property | |||
| 2095 | for ( var prop in optionStyle ) { | 2095 | for ( var prop in optionStyle ) { | |||
| 2096 | return prop; | 2096 | return prop; | |||
| 2097 | } | 2097 | } | |||
| 2098 | }; | 2098 | }; | |||
| 2099 | 2099 | |||||
| 2100 | Item.prototype.hide = function() { | 2100 | Item.prototype.hide = function() { | |||
| 2101 | // set flag | 2101 | // set flag | |||
| 2102 | this.isHidden = true; | 2102 | this.isHidden = true; | |||
| 2103 | // remove display: none | 2103 | // remove display: none | |||
| 2104 | this.css({ display: '' }); | 2104 | this.css({ display: '' }); | |||
| 2105 | 2105 | |||||
| 2106 | var options = this.layout.options; | 2106 | var options = this.layout.options; | |||
| 2107 | 2107 | |||||
| 2108 | var onTransitionEnd = {}; | 2108 | var onTransitionEnd = {}; | |||
| 2109 | var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); | 2109 | var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); | |||
| 2110 | onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; | 2110 | onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; | |||
| 2111 | 2111 | |||||
| 2112 | this.transition({ | 2112 | this.transition({ | |||
| 2113 | from: options.visibleStyle, | 2113 | from: options.visibleStyle, | |||
| 2114 | to: options.hiddenStyle, | 2114 | to: options.hiddenStyle, | |||
| 2115 | // keep hidden stuff hidden | 2115 | // keep hidden stuff hidden | |||
| 2116 | isCleaning: true, | 2116 | isCleaning: true, | |||
| 2117 | onTransitionEnd: onTransitionEnd | 2117 | onTransitionEnd: onTransitionEnd | |||
| 2118 | }); | 2118 | }); | |||
| 2119 | }; | 2119 | }; | |||
| 2120 | 2120 | |||||
| 2121 | Item.prototype.onHideTransitionEnd = function() { | 2121 | Item.prototype.onHideTransitionEnd = function() { | |||
| 2122 | // check if still hidden | 2122 | // check if still hidden | |||
| 2123 | // during transition, item may have been un-hidden | 2123 | // during transition, item may have been un-hidden | |||
| 2124 | if ( this.isHidden ) { | 2124 | if ( this.isHidden ) { | |||
| 2125 | this.css({ display: 'none' }); | 2125 | this.css({ display: 'none' }); | |||
| 2126 | this.emitEvent('hide'); | 2126 | this.emitEvent('hide'); | |||
| 2127 | } | 2127 | } | |||
| 2128 | }; | 2128 | }; | |||
| 2129 | 2129 | |||||
| 2130 | Item.prototype.destroy = function() { | 2130 | Item.prototype.destroy = function() { | |||
| 2131 | this.css({ | 2131 | this.css({ | |||
| 2132 | position: '', | 2132 | position: '', | |||
| 2133 | left: '', | 2133 | left: '', | |||
| 2134 | right: '', | 2134 | right: '', | |||
| 2135 | top: '', | 2135 | top: '', | |||
| 2136 | bottom: '', | 2136 | bottom: '', | |||
| 2137 | transition: '', | 2137 | transition: '', | |||
| 2138 | transform: '' | 2138 | transform: '' | |||
| 2139 | }); | 2139 | }); | |||
| 2140 | }; | 2140 | }; | |||
| 2141 | 2141 | |||||
| 2142 | return Item; | 2142 | return Item; | |||
| 2143 | 2143 | |||||
| 2144 | })); | 2144 | })); | |||
| 2145 | 2145 | |||||
| 2146 | /*! | 2146 | /*! | |||
| 2147 | * Outlayer v1.4.2 | 2147 | * Outlayer v1.4.2 | |||
| 2148 | * the brains and guts of a layout library | 2148 | * the brains and guts of a layout library | |||
| 2149 | * MIT license | 2149 | * MIT license | |||
| 2150 | */ | 2150 | */ | |||
| 2151 | 2151 | |||||
| 2152 | ( function( window, factory ) { | 2152 | ( function( window, factory ) { | |||
| 2153 | 2153 | |||||
| 2154 | // universal module definition | 2154 | // universal module definition | |||
| 2155 | 2155 | |||||
| 2156 | if ( typeof define == 'function' && define.amd ) { | 2156 | if ( typeof define == 'function' && define.amd ) { | |||
| 2157 | // AMD | 2157 | // AMD | |||
| 2158 | define( 'outlayer/outlayer',[ | 2158 | define( 'outlayer/outlayer',[ | |||
| 2159 | 'eventie/eventie', | 2159 | 'eventie/eventie', | |||
| 2160 | 'eventEmitter/EventEmitter', | 2160 | 'eventEmitter/EventEmitter', | |||
| 2161 | 'get-size/get-size', | 2161 | 'get-size/get-size', | |||
| 2162 | 'fizzy-ui-utils/utils', | 2162 | 'fizzy-ui-utils/utils', | |||
| 2163 | './item' | 2163 | './item' | |||
| 2164 | ], | 2164 | ], | |||
| 2165 | function( eventie, EventEmitter, getSize, utils, Item ) { | 2165 | function( eventie, EventEmitter, getSize, utils, Item ) { | |||
| 2166 | return factory( window, eventie, EventEmitter, getSize, utils, Item); | 2166 | return factory( window, eventie, EventEmitter, getSize, utils, Item); | |||
| 2167 | } | 2167 | } | |||
| 2168 | ); | 2168 | ); | |||
| 2169 | } else if ( typeof exports == 'object' ) { | 2169 | } else if ( typeof exports == 'object' ) { | |||
| 2170 | // CommonJS | 2170 | // CommonJS | |||
| 2171 | module.exports = factory( | 2171 | module.exports = factory( | |||
| 2172 | window, | 2172 | window, | |||
| 2173 | require('eventie'), | 2173 | require('eventie'), | |||
| 2174 | require('wolfy87-eventemitter'), | 2174 | require('wolfy87-eventemitter'), | |||
| 2175 | require('get-size'), | 2175 | require('get-size'), | |||
| 2176 | require('fizzy-ui-utils'), | 2176 | require('fizzy-ui-utils'), | |||
| 2177 | require('./item') | 2177 | require('./item') | |||
| 2178 | ); | 2178 | ); | |||
| 2179 | } else { | 2179 | } else { | |||
| 2180 | // browser global | 2180 | // browser global | |||
| 2181 | window.Outlayer = factory( | 2181 | window.Outlayer = factory( | |||
| 2182 | window, | 2182 | window, | |||
| 2183 | window.eventie, | 2183 | window.eventie, | |||
| 2184 | window.EventEmitter, | 2184 | window.EventEmitter, | |||
| 2185 | window.getSize, | 2185 | window.getSize, | |||
| 2186 | window.fizzyUIUtils, | 2186 | window.fizzyUIUtils, | |||
| 2187 | window.Outlayer.Item | 2187 | window.Outlayer.Item | |||
| 2188 | ); | 2188 | ); | |||
| 2189 | } | 2189 | } | |||
| 2190 | 2190 | |||||
| 2191 | }( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) { | 2191 | }( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) { | |||
| 2192 | 2192 | |||||
| 2193 | 2193 | |||||
| 2194 | // ----- vars ----- // | 2194 | // ----- vars ----- // | |||
| 2195 | 2195 | |||||
| 2196 | var console = window.console; | 2196 | var console = window.console; | |||
| 2197 | var jQuery = window.jQuery; | 2197 | var jQuery = window.jQuery; | |||
| 2198 | var noop = function() {}; | 2198 | var noop = function() {}; | |||
| 2199 | 2199 | |||||
| 2200 | // -------------------------- Outlayer -------------------------- // | 2200 | // -------------------------- Outlayer -------------------------- // | |||
| 2201 | 2201 | |||||
| 2202 | // globally unique identifiers | 2202 | // globally unique identifiers | |||
| 2203 | var GUID = 0; | 2203 | var GUID = 0; | |||
| 2204 | // internal store of all Outlayer intances | 2204 | // internal store of all Outlayer intances | |||
| 2205 | var instances = {}; | 2205 | var instances = {}; | |||
| 2206 | 2206 | |||||
| 2207 | 2207 | |||||
| 2208 | /** | 2208 | /** | |||
| 2209 | * @param {Element, String} element | 2209 | * @param {Element, String} element | |||
| 2210 | * @param {Object} options | 2210 | * @param {Object} options | |||
| 2211 | * @constructor | 2211 | * @constructor | |||
| 2212 | */ | 2212 | */ | |||
| 2213 | function Outlayer( element, options ) { | 2213 | function Outlayer( element, options ) { | |||
| 2214 | var queryElement = utils.getQueryElement( element ); | 2214 | var queryElement = utils.getQueryElement( element ); | |||
| 2215 | if ( !queryElement ) { | 2215 | if ( !queryElement ) { | |||
| 2216 | if ( console ) { | 2216 | if ( console ) { | |||
| 2217 | console.error( 'Bad element for ' + this.constructor.namespace + | 2217 | console.error( 'Bad element for ' + this.constructor.namespace + | |||
| 2218 | ': ' + ( queryElement || element ) ); | 2218 | ': ' + ( queryElement || element ) ); | |||
| 2219 | } | 2219 | } | |||
| 2220 | return; | 2220 | return; | |||
| 2221 | } | 2221 | } | |||
| 2222 | this.element = queryElement; | 2222 | this.element = queryElement; | |||
| 2223 | // add jQuery | 2223 | // add jQuery | |||
| 2224 | if ( jQuery ) { | 2224 | if ( jQuery ) { | |||
| 2225 | this.$element = jQuery( this.element ); | 2225 | this.$element = jQuery( this.element ); | |||
| 2226 | } | 2226 | } | |||
| 2227 | 2227 | |||||
| 2228 | // options | 2228 | // options | |||
| 2229 | this.options = utils.extend( {}, this.constructor.defaults ); | 2229 | this.options = utils.extend( {}, this.constructor.defaults ); | |||
| 2230 | this.option( options ); | 2230 | this.option( options ); | |||
| 2231 | 2231 | |||||
| 2232 | // add id for Outlayer.getFromElement | 2232 | // add id for Outlayer.getFromElement | |||
| 2233 | var id = ++GUID; | 2233 | var id = ++GUID; | |||
| 2234 | this.element.outlayerGUID = id; // expando | 2234 | this.element.outlayerGUID = id; // expando | |||
| 2235 | instances[ id ] = this; // associate via id | 2235 | instances[ id ] = this; // associate via id | |||
| 2236 | 2236 | |||||
| 2237 | // kick it off | 2237 | // kick it off | |||
| 2238 | this._create(); | 2238 | this._create(); | |||
| 2239 | 2239 | |||||
| 2240 | if ( this.options.isInitLayout ) { | 2240 | if ( this.options.isInitLayout ) { | |||
| 2241 | this.layout(); | 2241 | this.layout(); | |||
| 2242 | } | 2242 | } | |||
| 2243 | } | 2243 | } | |||
| 2244 | 2244 | |||||
| 2245 | // settings are for internal use only | 2245 | // settings are for internal use only | |||
| 2246 | Outlayer.namespace = 'outlayer'; | 2246 | Outlayer.namespace = 'outlayer'; | |||
| 2247 | Outlayer.Item = Item; | 2247 | Outlayer.Item = Item; | |||
| 2248 | 2248 | |||||
| 2249 | // default options | 2249 | // default options | |||
| 2250 | Outlayer.defaults = { | 2250 | Outlayer.defaults = { | |||
| 2251 | containerStyle: { | 2251 | containerStyle: { | |||
| 2252 | position: 'relative' | 2252 | position: 'relative' | |||
| 2253 | }, | 2253 | }, | |||
| 2254 | isInitLayout: true, | 2254 | isInitLayout: true, | |||
| 2255 | isOriginLeft: true, | 2255 | isOriginLeft: true, | |||
| 2256 | isOriginTop: true, | 2256 | isOriginTop: true, | |||
| 2257 | isResizeBound: true, | 2257 | isResizeBound: true, | |||
| 2258 | isResizingContainer: true, | 2258 | isResizingContainer: true, | |||
| 2259 | // item options | 2259 | // item options | |||
| 2260 | transitionDuration: '0.4s', | 2260 | transitionDuration: '0.4s', | |||
| 2261 | hiddenStyle: { | 2261 | hiddenStyle: { | |||
| 2262 | opacity: 0, | 2262 | opacity: 0, | |||
| 2263 | transform: 'scale(0.001)' | 2263 | transform: 'scale(0.001)' | |||
| 2264 | }, | 2264 | }, | |||
| 2265 | visibleStyle: { | 2265 | visibleStyle: { | |||
| 2266 | opacity: 1, | 2266 | opacity: 1, | |||
| 2267 | transform: 'scale(1)' | 2267 | transform: 'scale(1)' | |||
| 2268 | } | 2268 | } | |||
| 2269 | }; | 2269 | }; | |||
| 2270 | 2270 | |||||
| 2271 | // inherit EventEmitter | 2271 | // inherit EventEmitter | |||
| 2272 | utils.extend( Outlayer.prototype, EventEmitter.prototype ); | 2272 | utils.extend( Outlayer.prototype, EventEmitter.prototype ); | |||
| 2273 | 2273 | |||||
| 2274 | /** | 2274 | /** | |||
| 2275 | * set options | 2275 | * set options | |||
| 2276 | * @param {Object} opts | 2276 | * @param {Object} opts | |||
| 2277 | */ | 2277 | */ | |||
| 2278 | Outlayer.prototype.option = function( opts ) { | 2278 | Outlayer.prototype.option = function( opts ) { | |||
| 2279 | utils.extend( this.options, opts ); | 2279 | utils.extend( this.options, opts ); | |||
| 2280 | }; | 2280 | }; | |||
| 2281 | 2281 | |||||
| 2282 | Outlayer.prototype._create = function() { | 2282 | Outlayer.prototype._create = function() { | |||
| 2283 | // get items from children | 2283 | // get items from children | |||
| 2284 | this.reloadItems(); | 2284 | this.reloadItems(); | |||
| 2285 | // elements that affect layout, but are not laid out | 2285 | // elements that affect layout, but are not laid out | |||
| 2286 | this.stamps = []; | 2286 | this.stamps = []; | |||
| 2287 | this.stamp( this.options.stamp ); | 2287 | this.stamp( this.options.stamp ); | |||
| 2288 | // set container style | 2288 | // set container style | |||
| 2289 | utils.extend( this.element.style, this.options.containerStyle ); | 2289 | utils.extend( this.element.style, this.options.containerStyle ); | |||
| 2290 | 2290 | |||||
| 2291 | // bind resize method | 2291 | // bind resize method | |||
| 2292 | if ( this.options.isResizeBound ) { | 2292 | if ( this.options.isResizeBound ) { | |||
| 2293 | this.bindResize(); | 2293 | this.bindResize(); | |||
| 2294 | } | 2294 | } | |||
| 2295 | }; | 2295 | }; | |||
| 2296 | 2296 | |||||
| 2297 | // goes through all children again and gets bricks in proper order | 2297 | // goes through all children again and gets bricks in proper order | |||
| 2298 | Outlayer.prototype.reloadItems = function() { | 2298 | Outlayer.prototype.reloadItems = function() { | |||
| 2299 | // collection of item elements | 2299 | // collection of item elements | |||
| 2300 | this.items = this._itemize( this.element.children ); | 2300 | this.items = this._itemize( this.element.children ); | |||
| 2301 | }; | 2301 | }; | |||
| 2302 | 2302 | |||||
| 2303 | 2303 | |||||
| 2304 | /** | 2304 | /** | |||
| 2305 | * turn elements into Outlayer.Items to be used in layout | 2305 | * turn elements into Outlayer.Items to be used in layout | |||
| 2306 | * @param {Array or NodeList or HTMLElement} elems | 2306 | * @param {Array or NodeList or HTMLElement} elems | |||
| 2307 | * @returns {Array} items - collection of new Outlayer Items | 2307 | * @returns {Array} items - collection of new Outlayer Items | |||
| 2308 | */ | 2308 | */ | |||
| 2309 | Outlayer.prototype._itemize = function( elems ) { | 2309 | Outlayer.prototype._itemize = function( elems ) { | |||
| 2310 | 2310 | |||||
| 2311 | var itemElems = this._filterFindItemElements( elems ); | 2311 | var itemElems = this._filterFindItemElements( elems ); | |||
| 2312 | var Item = this.constructor.Item; | 2312 | var Item = this.constructor.Item; | |||
| 2313 | 2313 | |||||
| 2314 | // create new Outlayer Items for collection | 2314 | // create new Outlayer Items for collection | |||
| 2315 | var items = []; | 2315 | var items = []; | |||
| 2316 | for ( var i=0, len = itemElems.length; i < len; i++ ) { | 2316 | for ( var i=0, len = itemElems.length; i < len; i++ ) { | |||
| 2317 | var elem = itemElems[i]; | 2317 | var elem = itemElems[i]; | |||
| 2318 | var item = new Item( elem, this ); | 2318 | var item = new Item( elem, this ); | |||
| 2319 | items.push( item ); | 2319 | items.push( item ); | |||
| 2320 | } | 2320 | } | |||
| 2321 | 2321 | |||||
| 2322 | return items; | 2322 | return items; | |||
| 2323 | }; | 2323 | }; | |||
| 2324 | 2324 | |||||
| 2325 | /** | 2325 | /** | |||
| 2326 | * get item elements to be used in layout | 2326 | * get item elements to be used in layout | |||
| 2327 | * @param {Array or NodeList or HTMLElement} elems | 2327 | * @param {Array or NodeList or HTMLElement} elems | |||
| 2328 | * @returns {Array} items - item elements | 2328 | * @returns {Array} items - item elements | |||
| 2329 | */ | 2329 | */ | |||
| 2330 | Outlayer.prototype._filterFindItemElements = function( elems ) { | 2330 | Outlayer.prototype._filterFindItemElements = function( elems ) { | |||
| 2331 | return utils.filterFindElements( elems, this.options.itemSelector ); | 2331 | return utils.filterFindElements( elems, this.options.itemSelector ); | |||
| 2332 | }; | 2332 | }; | |||
| 2333 | 2333 | |||||
| 2334 | /** | 2334 | /** | |||
| 2335 | * getter method for getting item elements | 2335 | * getter method for getting item elements | |||
| 2336 | * @returns {Array} elems - collection of item elements | 2336 | * @returns {Array} elems - collection of item elements | |||
| 2337 | */ | 2337 | */ | |||
| 2338 | Outlayer.prototype.getItemElements = function() { | 2338 | Outlayer.prototype.getItemElements = function() { | |||
| 2339 | var elems = []; | 2339 | var elems = []; | |||
| 2340 | for ( var i=0, len = this.items.length; i < len; i++ ) { | 2340 | for ( var i=0, len = this.items.length; i < len; i++ ) { | |||
| 2341 | elems.push( this.items[i].element ); | 2341 | elems.push( this.items[i].element ); | |||
| 2342 | } | 2342 | } | |||
| 2343 | return elems; | 2343 | return elems; | |||
| 2344 | }; | 2344 | }; | |||
| 2345 | 2345 | |||||
| 2346 | // ----- init & layout ----- // | 2346 | // ----- init & layout ----- // | |||
| 2347 | 2347 | |||||
| 2348 | /** | 2348 | /** | |||
| 2349 | * lays out all items | 2349 | * lays out all items | |||
| 2350 | */ | 2350 | */ | |||
| 2351 | Outlayer.prototype.layout = function() { | 2351 | Outlayer.prototype.layout = function() { | |||
| 2352 | this._resetLayout(); | 2352 | this._resetLayout(); | |||
| 2353 | this._manageStamps(); | 2353 | this._manageStamps(); | |||
| 2354 | 2354 | |||||
| 2355 | // don't animate first layout | 2355 | // don't animate first layout | |||
| 2356 | var isInstant = this.options.isLayoutInstant !== undefined ? | 2356 | var isInstant = this.options.isLayoutInstant !== undefined ? | |||
| 2357 | this.options.isLayoutInstant : !this._isLayoutInited; | 2357 | this.options.isLayoutInstant : !this._isLayoutInited; | |||
| 2358 | this.layoutItems( this.items, isInstant ); | 2358 | this.layoutItems( this.items, isInstant ); | |||
| 2359 | 2359 | |||||
| 2360 | // flag for initalized | 2360 | // flag for initalized | |||
| 2361 | this._isLayoutInited = true; | 2361 | this._isLayoutInited = true; | |||
| 2362 | }; | 2362 | }; | |||
| 2363 | 2363 | |||||
| 2364 | // _init is alias for layout | 2364 | // _init is alias for layout | |||
| 2365 | Outlayer.prototype._init = Outlayer.prototype.layout; | 2365 | Outlayer.prototype._init = Outlayer.prototype.layout; | |||
| 2366 | 2366 | |||||
| 2367 | /** | 2367 | /** | |||
| 2368 | * logic before any new layout | 2368 | * logic before any new layout | |||
| 2369 | */ | 2369 | */ | |||
| 2370 | Outlayer.prototype._resetLayout = function() { | 2370 | Outlayer.prototype._resetLayout = function() { | |||
| 2371 | this.getSize(); | 2371 | this.getSize(); | |||
| 2372 | }; | 2372 | }; | |||
| 2373 | 2373 | |||||
| 2374 | 2374 | |||||
| 2375 | Outlayer.prototype.getSize = function() { | 2375 | Outlayer.prototype.getSize = function() { | |||
| 2376 | this.size = getSize( this.element ); | 2376 | this.size = getSize( this.element ); | |||
| 2377 | }; | 2377 | }; | |||
| 2378 | 2378 | |||||
| 2379 | /** | 2379 | /** | |||
| 2380 | * get measurement from option, for columnWidth, rowHeight, gutter | 2380 | * get measurement from option, for columnWidth, rowHeight, gutter | |||
| 2381 | * if option is String -> get element from selector string, & get size of element | 2381 | * if option is String -> get element from selector string, & get size of element | |||
| 2382 | * if option is Element -> get size of element | 2382 | * if option is Element -> get size of element | |||
| 2383 | * else use option as a number | 2383 | * else use option as a number | |||
| 2384 | * | 2384 | * | |||
| 2385 | * @param {String} measurement | 2385 | * @param {String} measurement | |||
| 2386 | * @param {String} size - width or height | 2386 | * @param {String} size - width or height | |||
| 2387 | * @private | 2387 | * @private | |||
| 2388 | */ | 2388 | */ | |||
| 2389 | Outlayer.prototype._getMeasurement = function( measurement, size ) { | 2389 | Outlayer.prototype._getMeasurement = function( measurement, size ) { | |||
| 2390 | var option = this.options[ measurement ]; | 2390 | var option = this.options[ measurement ]; | |||
| 2391 | var elem; | 2391 | var elem; | |||
| 2392 | if ( !option ) { | 2392 | if ( !option ) { | |||
| 2393 | // default to 0 | 2393 | // default to 0 | |||
| 2394 | this[ measurement ] = 0; | 2394 | this[ measurement ] = 0; | |||
| 2395 | } else { | 2395 | } else { | |||
| 2396 | // use option as an element | 2396 | // use option as an element | |||
| 2397 | if ( typeof option === 'string' ) { | 2397 | if ( typeof option === 'string' ) { | |||
| 2398 | elem = this.element.querySelector( option ); | 2398 | elem = this.element.querySelector( option ); | |||
| 2399 | } else if ( utils.isElement( option ) ) { | 2399 | } else if ( utils.isElement( option ) ) { | |||
| 2400 | elem = option; | 2400 | elem = option; | |||
| 2401 | } | 2401 | } | |||
| 2402 | // use size of element, if element | 2402 | // use size of element, if element | |||
| 2403 | this[ measurement ] = elem ? getSize( elem )[ size ] : option; | 2403 | this[ measurement ] = elem ? getSize( elem )[ size ] : option; | |||
| 2404 | } | 2404 | } | |||
| 2405 | }; | 2405 | }; | |||
| 2406 | 2406 | |||||
| 2407 | /** | 2407 | /** | |||
| 2408 | * layout a collection of item elements | 2408 | * layout a collection of item elements | |||
| 2409 | * @api public | 2409 | * @api public | |||
| 2410 | */ | 2410 | */ | |||
| 2411 | Outlayer.prototype.layoutItems = function( items, isInstant ) { | 2411 | Outlayer.prototype.layoutItems = function( items, isInstant ) { | |||
| 2412 | items = this._getItemsForLayout( items ); | 2412 | items = this._getItemsForLayout( items ); | |||
| 2413 | 2413 | |||||
| 2414 | this._layoutItems( items, isInstant ); | 2414 | this._layoutItems( items, isInstant ); | |||
| 2415 | 2415 | |||||
| 2416 | this._postLayout(); | 2416 | this._postLayout(); | |||
| 2417 | }; | 2417 | }; | |||
| 2418 | 2418 | |||||
| 2419 | /** | 2419 | /** | |||
| 2420 | * get the items to be laid out | 2420 | * get the items to be laid out | |||
| 2421 | * you may want to skip over some items | 2421 | * you may want to skip over some items | |||
| 2422 | * @param {Array} items | 2422 | * @param {Array} items | |||
| 2423 | * @returns {Array} items | 2423 | * @returns {Array} items | |||
| 2424 | */ | 2424 | */ | |||
| 2425 | Outlayer.prototype._getItemsForLayout = function( items ) { | 2425 | Outlayer.prototype._getItemsForLayout = function( items ) { | |||
| 2426 | var layoutItems = []; | 2426 | var layoutItems = []; | |||
| 2427 | for ( var i=0, len = items.length; i < len; i++ ) { | 2427 | for ( var i=0, len = items.length; i < len; i++ ) { | |||
| 2428 | var item = items[i]; | 2428 | var item = items[i]; | |||
| 2429 | if ( !item.isIgnored ) { | 2429 | if ( !item.isIgnored ) { | |||
| 2430 | layoutItems.push( item ); | 2430 | layoutItems.push( item ); | |||
| 2431 | } | 2431 | } | |||
| 2432 | } | 2432 | } | |||
| 2433 | return layoutItems; | 2433 | return layoutItems; | |||
| 2434 | }; | 2434 | }; | |||
| 2435 | 2435 | |||||
| 2436 | /** | 2436 | /** | |||
| 2437 | * layout items | 2437 | * layout items | |||
| 2438 | * @param {Array} items | 2438 | * @param {Array} items | |||
| 2439 | * @param {Boolean} isInstant | 2439 | * @param {Boolean} isInstant | |||
| 2440 | */ | 2440 | */ | |||
| 2441 | Outlayer.prototype._layoutItems = function( items, isInstant ) { | 2441 | Outlayer.prototype._layoutItems = function( items, isInstant ) { | |||
| 2442 | this._emitCompleteOnItems( 'layout', items ); | 2442 | this._emitCompleteOnItems( 'layout', items ); | |||
| 2443 | 2443 | |||||
| 2444 | if ( !items || !items.length ) { | 2444 | if ( !items || !items.length ) { | |||
| 2445 | // no items, emit event with empty array | 2445 | // no items, emit event with empty array | |||
| 2446 | return; | 2446 | return; | |||
| 2447 | } | 2447 | } | |||
| 2448 | 2448 | |||||
| 2449 | var queue = []; | 2449 | var queue = []; | |||
| 2450 | 2450 | |||||
| 2451 | for ( var i=0, len = items.length; i < len; i++ ) { | 2451 | for ( var i=0, len = items.length; i < len; i++ ) { | |||
| 2452 | var item = items[i]; | 2452 | var item = items[i]; | |||
| 2453 | // get x/y object from method | 2453 | // get x/y object from method | |||
| 2454 | var position = this._getItemLayoutPosition( item ); | 2454 | var position = this._getItemLayoutPosition( item ); | |||
| 2455 | // enqueue | 2455 | // enqueue | |||
| 2456 | position.item = item; | 2456 | position.item = item; | |||
| 2457 | position.isInstant = isInstant || item.isLayoutInstant; | 2457 | position.isInstant = isInstant || item.isLayoutInstant; | |||
| 2458 | queue.push( position ); | 2458 | queue.push( position ); | |||
| 2459 | } | 2459 | } | |||
| 2460 | 2460 | |||||
| 2461 | this._processLayoutQueue( queue ); | 2461 | this._processLayoutQueue( queue ); | |||
| 2462 | }; | 2462 | }; | |||
| 2463 | 2463 | |||||
| 2464 | /** | 2464 | /** | |||
| 2465 | * get item layout position | 2465 | * get item layout position | |||
| 2466 | * @param {Outlayer.Item} item | 2466 | * @param {Outlayer.Item} item | |||
| 2467 | * @returns {Object} x and y position | 2467 | * @returns {Object} x and y position | |||
| 2468 | */ | 2468 | */ | |||
| 2469 | Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) { | 2469 | Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) { | |||
| 2470 | return { | 2470 | return { | |||
| 2471 | x: 0, | 2471 | x: 0, | |||
| 2472 | y: 0 | 2472 | y: 0 | |||
| 2473 | }; | 2473 | }; | |||
| 2474 | }; | 2474 | }; | |||
| 2475 | 2475 | |||||
| 2476 | /** | 2476 | /** | |||
| 2477 | * iterate over array and position each item | 2477 | * iterate over array and position each item | |||
| 2478 | * Reason being - separating this logic prevents 'layout invalidation' | 2478 | * Reason being - separating this logic prevents 'layout invalidation' | |||
| 2479 | * thx @paul_irish | 2479 | * thx @paul_irish | |||
| 2480 | * @param {Array} queue | 2480 | * @param {Array} queue | |||
| 2481 | */ | 2481 | */ | |||
| 2482 | Outlayer.prototype._processLayoutQueue = function( queue ) { | 2482 | Outlayer.prototype._processLayoutQueue = function( queue ) { | |||
| 2483 | for ( var i=0, len = queue.length; i < len; i++ ) { | 2483 | for ( var i=0, len = queue.length; i < len; i++ ) { | |||
| 2484 | var obj = queue[i]; | 2484 | var obj = queue[i]; | |||
| 2485 | this._positionItem( obj.item, obj.x, obj.y, obj.isInstant ); | 2485 | this._positionItem( obj.item, obj.x, obj.y, obj.isInstant ); | |||
| 2486 | } | 2486 | } | |||
| 2487 | }; | 2487 | }; | |||
| 2488 | 2488 | |||||
| 2489 | /** | 2489 | /** | |||
| 2490 | * Sets position of item in DOM | 2490 | * Sets position of item in DOM | |||
| 2491 | * @param {Outlayer.Item} item | 2491 | * @param {Outlayer.Item} item | |||
| 2492 | * @param {Number} x - horizontal position | 2492 | * @param {Number} x - horizontal position | |||
| 2493 | * @param {Number} y - vertical position | 2493 | * @param {Number} y - vertical position | |||
| 2494 | * @param {Boolean} isInstant - disables transitions | 2494 | * @param {Boolean} isInstant - disables transitions | |||
| 2495 | */ | 2495 | */ | |||
| 2496 | Outlayer.prototype._positionItem = function( item, x, y, isInstant ) { | 2496 | Outlayer.prototype._positionItem = function( item, x, y, isInstant ) { | |||
| 2497 | if ( isInstant ) { | 2497 | if ( isInstant ) { | |||
| 2498 | // if not transition, just set CSS | 2498 | // if not transition, just set CSS | |||
| 2499 | item.goTo( x, y ); | 2499 | item.goTo( x, y ); | |||
| 2500 | } else { | 2500 | } else { | |||
| 2501 | item.moveTo( x, y ); | 2501 | item.moveTo( x, y ); | |||
| 2502 | } | 2502 | } | |||
| 2503 | }; | 2503 | }; | |||
| 2504 | 2504 | |||||
| 2505 | /** | 2505 | /** | |||
| 2506 | * Any logic you want to do after each layout, | 2506 | * Any logic you want to do after each layout, | |||
| 2507 | * i.e. size the container | 2507 | * i.e. size the container | |||
| 2508 | */ | 2508 | */ | |||
| 2509 | Outlayer.prototype._postLayout = function() { | 2509 | Outlayer.prototype._postLayout = function() { | |||
| 2510 | this.resizeContainer(); | 2510 | this.resizeContainer(); | |||
| 2511 | }; | 2511 | }; | |||
| 2512 | 2512 | |||||
| 2513 | Outlayer.prototype.resizeContainer = function() { | 2513 | Outlayer.prototype.resizeContainer = function() { | |||
| 2514 | if ( !this.options.isResizingContainer ) { | 2514 | if ( !this.options.isResizingContainer ) { | |||
| 2515 | return; | 2515 | return; | |||
| 2516 | } | 2516 | } | |||
| 2517 | var size = this._getContainerSize(); | 2517 | var size = this._getContainerSize(); | |||
| 2518 | if ( size ) { | 2518 | if ( size ) { | |||
| 2519 | this._setContainerMeasure( size.width, true ); | 2519 | this._setContainerMeasure( size.width, true ); | |||
| 2520 | this._setContainerMeasure( size.height, false ); | 2520 | this._setContainerMeasure( size.height, false ); | |||
| 2521 | } | 2521 | } | |||
| 2522 | }; | 2522 | }; | |||
| 2523 | 2523 | |||||
| 2524 | /** | 2524 | /** | |||
| 2525 | * Sets width or height of container if returned | 2525 | * Sets width or height of container if returned | |||
| 2526 | * @returns {Object} size | 2526 | * @returns {Object} size | |||
| 2527 | * @param {Number} width | 2527 | * @param {Number} width | |||
| 2528 | * @param {Number} height | 2528 | * @param {Number} height | |||
| 2529 | */ | 2529 | */ | |||
| 2530 | Outlayer.prototype._getContainerSize = noop; | 2530 | Outlayer.prototype._getContainerSize = noop; | |||
| 2531 | 2531 | |||||
| 2532 | /** | 2532 | /** | |||
| 2533 | * @param {Number} measure - size of width or height | 2533 | * @param {Number} measure - size of width or height | |||
| 2534 | * @param {Boolean} isWidth | 2534 | * @param {Boolean} isWidth | |||
| 2535 | */ | 2535 | */ | |||
| 2536 | Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) { | 2536 | Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) { | |||
| 2537 | if ( measure === undefined ) { | 2537 | if ( measure === undefined ) { | |||
| 2538 | return; | 2538 | return; | |||
| 2539 | } | 2539 | } | |||
| 2540 | 2540 | |||||
| 2541 | var elemSize = this.size; | 2541 | var elemSize = this.size; | |||
| 2542 | // add padding and border width if border box | 2542 | // add padding and border width if border box | |||
| 2543 | if ( elemSize.isBorderBox ) { | 2543 | if ( elemSize.isBorderBox ) { | |||
| 2544 | measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + | 2544 | measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + | |||
| 2545 | elemSize.borderLeftWidth + elemSize.borderRightWidth : | 2545 | elemSize.borderLeftWidth + elemSize.borderRightWidth : | |||
| 2546 | elemSize.paddingBottom + elemSize.paddingTop + | 2546 | elemSize.paddingBottom + elemSize.paddingTop + | |||
| 2547 | elemSize.borderTopWidth + elemSize.borderBottomWidth; | 2547 | elemSize.borderTopWidth + elemSize.borderBottomWidth; | |||
| 2548 | } | 2548 | } | |||
| 2549 | 2549 | |||||
| 2550 | measure = Math.max( measure, 0 ); | 2550 | measure = Math.max( measure, 0 ); | |||
| 2551 | this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; | 2551 | this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; | |||
| 2552 | }; | 2552 | }; | |||
| 2553 | 2553 | |||||
| 2554 | /** | 2554 | /** | |||
| 2555 | * emit eventComplete on a collection of items events | 2555 | * emit eventComplete on a collection of items events | |||
| 2556 | * @param {String} eventName | 2556 | * @param {String} eventName | |||
| 2557 | * @param {Array} items - Outlayer.Items | 2557 | * @param {Array} items - Outlayer.Items | |||
| 2558 | */ | 2558 | */ | |||
| 2559 | Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) { | 2559 | Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) { | |||
| 2560 | var _this = this; | 2560 | var _this = this; | |||
| 2561 | function onComplete() { | 2561 | function onComplete() { | |||
| 2562 | _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); | 2562 | _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); | |||
| 2563 | } | 2563 | } | |||
| 2564 | 2564 | |||||
| 2565 | var count = items.length; | 2565 | var count = items.length; | |||
| 2566 | if ( !items || !count ) { | 2566 | if ( !items || !count ) { | |||
| 2567 | onComplete(); | 2567 | onComplete(); | |||
| 2568 | return; | 2568 | return; | |||
| 2569 | } | 2569 | } | |||
| 2570 | 2570 | |||||
| 2571 | var doneCount = 0; | 2571 | var doneCount = 0; | |||
| 2572 | function tick() { | 2572 | function tick() { | |||
| 2573 | doneCount++; | 2573 | doneCount++; | |||
| 2574 | if ( doneCount === count ) { | 2574 | if ( doneCount === count ) { | |||
| 2575 | onComplete(); | 2575 | onComplete(); | |||
| 2576 | } | 2576 | } | |||
| 2577 | } | 2577 | } | |||
| 2578 | 2578 | |||||
| 2579 | // bind callback | 2579 | // bind callback | |||
| 2580 | for ( var i=0, len = items.length; i < len; i++ ) { | 2580 | for ( var i=0, len = items.length; i < len; i++ ) { | |||
| 2581 | var item = items[i]; | 2581 | var item = items[i]; | |||
| 2582 | item.once( eventName, tick ); | 2582 | item.once( eventName, tick ); | |||
| 2583 | } | 2583 | } | |||
| 2584 | }; | 2584 | }; | |||
| 2585 | 2585 | |||||
| 2586 | /** | 2586 | /** | |||
| 2587 | * emits events via eventEmitter and jQuery events | 2587 | * emits events via eventEmitter and jQuery events | |||
| 2588 | * @param {String} type - name of event | 2588 | * @param {String} type - name of event | |||
| 2589 | * @param {Event} event - original event | 2589 | * @param {Event} event - original event | |||
| 2590 | * @param {Array} args - extra arguments | 2590 | * @param {Array} args - extra arguments | |||
| 2591 | */ | 2591 | */ | |||
| 2592 | Outlayer.prototype.dispatchEvent = function( type, event, args ) { | 2592 | Outlayer.prototype.dispatchEvent = function( type, event, args ) { | |||
| 2593 | // add original event to arguments | 2593 | // add original event to arguments | |||
| 2594 | var emitArgs = event ? [ event ].concat( args ) : args; | 2594 | var emitArgs = event ? [ event ].concat( args ) : args; | |||
| 2595 | this.emitEvent( type, emitArgs ); | 2595 | this.emitEvent( type, emitArgs ); | |||
| 2596 | 2596 | |||||
| 2597 | if ( jQuery ) { | 2597 | if ( jQuery ) { | |||
| 2598 | // set this.$element | 2598 | // set this.$element | |||
| 2599 | this.$element = this.$element || jQuery( this.element ); | 2599 | this.$element = this.$element || jQuery( this.element ); | |||
| 2600 | if ( event ) { | 2600 | if ( event ) { | |||
| 2601 | // create jQuery event | 2601 | // create jQuery event | |||
| 2602 | var $event = jQuery.Event( event ); | 2602 | var $event = jQuery.Event( event ); | |||
| 2603 | $event.type = type; | 2603 | $event.type = type; | |||
| 2604 | this.$element.trigger( $event, args ); | 2604 | this.$element.trigger( $event, args ); | |||
| 2605 | } else { | 2605 | } else { | |||
| 2606 | // just trigger with type if no event available | 2606 | // just trigger with type if no event available | |||
| 2607 | this.$element.trigger( type, args ); | 2607 | this.$element.trigger( type, args ); | |||
| 2608 | } | 2608 | } | |||
| 2609 | } | 2609 | } | |||
| 2610 | }; | 2610 | }; | |||
| 2611 | 2611 | |||||
| 2612 | // -------------------------- ignore & stamps -------------------------- // | 2612 | // -------------------------- ignore & stamps -------------------------- // | |||
| 2613 | 2613 | |||||
| 2614 | 2614 | |||||
| 2615 | /** | 2615 | /** | |||
| 2616 | * keep item in collection, but do not lay it out | 2616 | * keep item in collection, but do not lay it out | |||
| 2617 | * ignored items do not get skipped in layout | 2617 | * ignored items do not get skipped in layout | |||
| 2618 | * @param {Element} elem | 2618 | * @param {Element} elem | |||
| 2619 | */ | 2619 | */ | |||
| 2620 | Outlayer.prototype.ignore = function( elem ) { | 2620 | Outlayer.prototype.ignore = function( elem ) { | |||
| 2621 | var item = this.getItem( elem ); | 2621 | var item = this.getItem( elem ); | |||
| 2622 | if ( item ) { | 2622 | if ( item ) { | |||
| 2623 | item.isIgnored = true; | 2623 | item.isIgnored = true; | |||
| 2624 | } | 2624 | } | |||
| 2625 | }; | 2625 | }; | |||
| 2626 | 2626 | |||||
| 2627 | /** | 2627 | /** | |||
| 2628 | * return item to layout collection | 2628 | * return item to layout collection | |||
| 2629 | * @param {Element} elem | 2629 | * @param {Element} elem | |||
| 2630 | */ | 2630 | */ | |||
| 2631 | Outlayer.prototype.unignore = function( elem ) { | 2631 | Outlayer.prototype.unignore = function( elem ) { | |||
| 2632 | var item = this.getItem( elem ); | 2632 | var item = this.getItem( elem ); | |||
| 2633 | if ( item ) { | 2633 | if ( item ) { | |||
| 2634 | delete item.isIgnored; | 2634 | delete item.isIgnored; | |||
| 2635 | } | 2635 | } | |||
| 2636 | }; | 2636 | }; | |||
| 2637 | 2637 | |||||
| 2638 | /** | 2638 | /** | |||
| 2639 | * adds elements to stamps | 2639 | * adds elements to stamps | |||
| 2640 | * @param {NodeList, Array, Element, or String} elems | 2640 | * @param {NodeList, Array, Element, or String} elems | |||
| 2641 | */ | 2641 | */ | |||
| 2642 | Outlayer.prototype.stamp = function( elems ) { | 2642 | Outlayer.prototype.stamp = function( elems ) { | |||
| 2643 | elems = this._find( elems ); | 2643 | elems = this._find( elems ); | |||
| 2644 | if ( !elems ) { | 2644 | if ( !elems ) { | |||
| 2645 | return; | 2645 | return; | |||
| 2646 | } | 2646 | } | |||
| 2647 | 2647 | |||||
| 2648 | this.stamps = this.stamps.concat( elems ); | 2648 | this.stamps = this.stamps.concat( elems ); | |||
| 2649 | // ignore | 2649 | // ignore | |||
| 2650 | for ( var i=0, len = elems.length; i < len; i++ ) { | 2650 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 2651 | var elem = elems[i]; | 2651 | var elem = elems[i]; | |||
| 2652 | this.ignore( elem ); | 2652 | this.ignore( elem ); | |||
| 2653 | } | 2653 | } | |||
| 2654 | }; | 2654 | }; | |||
| 2655 | 2655 | |||||
| 2656 | /** | 2656 | /** | |||
| 2657 | * removes elements to stamps | 2657 | * removes elements to stamps | |||
| 2658 | * @param {NodeList, Array, or Element} elems | 2658 | * @param {NodeList, Array, or Element} elems | |||
| 2659 | */ | 2659 | */ | |||
| 2660 | Outlayer.prototype.unstamp = function( elems ) { | 2660 | Outlayer.prototype.unstamp = function( elems ) { | |||
| 2661 | elems = this._find( elems ); | 2661 | elems = this._find( elems ); | |||
| 2662 | if ( !elems ){ | 2662 | if ( !elems ){ | |||
| 2663 | return; | 2663 | return; | |||
| 2664 | } | 2664 | } | |||
| 2665 | 2665 | |||||
| 2666 | for ( var i=0, len = elems.length; i < len; i++ ) { | 2666 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 2667 | var elem = elems[i]; | 2667 | var elem = elems[i]; | |||
| 2668 | // filter out removed stamp elements | 2668 | // filter out removed stamp elements | |||
| 2669 | utils.removeFrom( this.stamps, elem ); | 2669 | utils.removeFrom( this.stamps, elem ); | |||
| 2670 | this.unignore( elem ); | 2670 | this.unignore( elem ); | |||
| 2671 | } | 2671 | } | |||
| 2672 | 2672 | |||||
| 2673 | }; | 2673 | }; | |||
| 2674 | 2674 | |||||
| 2675 | /** | 2675 | /** | |||
| 2676 | * finds child elements | 2676 | * finds child elements | |||
| 2677 | * @param {NodeList, Array, Element, or String} elems | 2677 | * @param {NodeList, Array, Element, or String} elems | |||
| 2678 | * @returns {Array} elems | 2678 | * @returns {Array} elems | |||
| 2679 | */ | 2679 | */ | |||
| 2680 | Outlayer.prototype._find = function( elems ) { | 2680 | Outlayer.prototype._find = function( elems ) { | |||
| 2681 | if ( !elems ) { | 2681 | if ( !elems ) { | |||
| 2682 | return; | 2682 | return; | |||
| 2683 | } | 2683 | } | |||
| 2684 | // if string, use argument as selector string | 2684 | // if string, use argument as selector string | |||
| 2685 | if ( typeof elems === 'string' ) { | 2685 | if ( typeof elems === 'string' ) { | |||
| 2686 | elems = this.element.querySelectorAll( elems ); | 2686 | elems = this.element.querySelectorAll( elems ); | |||
| 2687 | } | 2687 | } | |||
| 2688 | elems = utils.makeArray( elems ); | 2688 | elems = utils.makeArray( elems ); | |||
| 2689 | return elems; | 2689 | return elems; | |||
| 2690 | }; | 2690 | }; | |||
| 2691 | 2691 | |||||
| 2692 | Outlayer.prototype._manageStamps = function() { | 2692 | Outlayer.prototype._manageStamps = function() { | |||
| 2693 | if ( !this.stamps || !this.stamps.length ) { | 2693 | if ( !this.stamps || !this.stamps.length ) { | |||
| 2694 | return; | 2694 | return; | |||
| 2695 | } | 2695 | } | |||
| 2696 | 2696 | |||||
| 2697 | this._getBoundingRect(); | 2697 | this._getBoundingRect(); | |||
| 2698 | 2698 | |||||
| 2699 | for ( var i=0, len = this.stamps.length; i < len; i++ ) { | 2699 | for ( var i=0, len = this.stamps.length; i < len; i++ ) { | |||
| 2700 | var stamp = this.stamps[i]; | 2700 | var stamp = this.stamps[i]; | |||
| 2701 | this._manageStamp( stamp ); | 2701 | this._manageStamp( stamp ); | |||
| 2702 | } | 2702 | } | |||
| 2703 | }; | 2703 | }; | |||
| 2704 | 2704 | |||||
| 2705 | // update boundingLeft / Top | 2705 | // update boundingLeft / Top | |||
| 2706 | Outlayer.prototype._getBoundingRect = function() { | 2706 | Outlayer.prototype._getBoundingRect = function() { | |||
| 2707 | // get bounding rect for container element | 2707 | // get bounding rect for container element | |||
| 2708 | var boundingRect = this.element.getBoundingClientRect(); | 2708 | var boundingRect = this.element.getBoundingClientRect(); | |||
| 2709 | var size = this.size; | 2709 | var size = this.size; | |||
| 2710 | this._boundingRect = { | 2710 | this._boundingRect = { | |||
| 2711 | left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, | 2711 | left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, | |||
| 2712 | top: boundingRect.top + size.paddingTop + size.borderTopWidth, | 2712 | top: boundingRect.top + size.paddingTop + size.borderTopWidth, | |||
| 2713 | right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), | 2713 | right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), | |||
| 2714 | bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) | 2714 | bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) | |||
| 2715 | }; | 2715 | }; | |||
| 2716 | }; | 2716 | }; | |||
| 2717 | 2717 | |||||
| 2718 | /** | 2718 | /** | |||
| 2719 | * @param {Element} stamp | 2719 | * @param {Element} stamp | |||
| 2720 | **/ | 2720 | **/ | |||
| 2721 | Outlayer.prototype._manageStamp = noop; | 2721 | Outlayer.prototype._manageStamp = noop; | |||
| 2722 | 2722 | |||||
| 2723 | /** | 2723 | /** | |||
| 2724 | * get x/y position of element relative to container element | 2724 | * get x/y position of element relative to container element | |||
| 2725 | * @param {Element} elem | 2725 | * @param {Element} elem | |||
| 2726 | * @returns {Object} offset - has left, top, right, bottom | 2726 | * @returns {Object} offset - has left, top, right, bottom | |||
| 2727 | */ | 2727 | */ | |||
| 2728 | Outlayer.prototype._getElementOffset = function( elem ) { | 2728 | Outlayer.prototype._getElementOffset = function( elem ) { | |||
| 2729 | var boundingRect = elem.getBoundingClientRect(); | 2729 | var boundingRect = elem.getBoundingClientRect(); | |||
| 2730 | var thisRect = this._boundingRect; | 2730 | var thisRect = this._boundingRect; | |||
| 2731 | var size = getSize( elem ); | 2731 | var size = getSize( elem ); | |||
| 2732 | var offset = { | 2732 | var offset = { | |||
| 2733 | left: boundingRect.left - thisRect.left - size.marginLeft, | 2733 | left: boundingRect.left - thisRect.left - size.marginLeft, | |||
| 2734 | top: boundingRect.top - thisRect.top - size.marginTop, | 2734 | top: boundingRect.top - thisRect.top - size.marginTop, | |||
| 2735 | right: thisRect.right - boundingRect.right - size.marginRight, | 2735 | right: thisRect.right - boundingRect.right - size.marginRight, | |||
| 2736 | bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom | 2736 | bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom | |||
| 2737 | }; | 2737 | }; | |||
| 2738 | return offset; | 2738 | return offset; | |||
| 2739 | }; | 2739 | }; | |||
| 2740 | 2740 | |||||
| 2741 | // -------------------------- resize -------------------------- // | 2741 | // -------------------------- resize -------------------------- // | |||
| 2742 | 2742 | |||||
| 2743 | // enable event handlers for listeners | 2743 | // enable event handlers for listeners | |||
| 2744 | // i.e. resize -> onresize | 2744 | // i.e. resize -> onresize | |||
| 2745 | Outlayer.prototype.handleEvent = function( event ) { | 2745 | Outlayer.prototype.handleEvent = function( event ) { | |||
| 2746 | var method = 'on' + event.type; | 2746 | var method = 'on' + event.type; | |||
| 2747 | if ( this[ method ] ) { | 2747 | if ( this[ method ] ) { | |||
| 2748 | this[ method ]( event ); | 2748 | this[ method ]( event ); | |||
| 2749 | } | 2749 | } | |||
| 2750 | }; | 2750 | }; | |||
| 2751 | 2751 | |||||
| 2752 | /** | 2752 | /** | |||
| 2753 | * Bind layout to window resizing | 2753 | * Bind layout to window resizing | |||
| 2754 | */ | 2754 | */ | |||
| 2755 | Outlayer.prototype.bindResize = function() { | 2755 | Outlayer.prototype.bindResize = function() { | |||
| 2756 | // bind just one listener | 2756 | // bind just one listener | |||
| 2757 | if ( this.isResizeBound ) { | 2757 | if ( this.isResizeBound ) { | |||
| 2758 | return; | 2758 | return; | |||
| 2759 | } | 2759 | } | |||
| 2760 | window.eventie.bind( window, 'resize', this ); | 2760 | window.eventie.bind( window, 'resize', this ); | |||
| 2761 | this.isResizeBound = true; | 2761 | this.isResizeBound = true; | |||
| 2762 | }; | 2762 | }; | |||
| 2763 | 2763 | |||||
| 2764 | /** | 2764 | /** | |||
| 2765 | * Unbind layout to window resizing | 2765 | * Unbind layout to window resizing | |||
| 2766 | */ | 2766 | */ | |||
| 2767 | Outlayer.prototype.unbindResize = function() { | 2767 | Outlayer.prototype.unbindResize = function() { | |||
| 2768 | if ( this.isResizeBound ) { | 2768 | if ( this.isResizeBound ) { | |||
| 2769 | window.eventie.unbind( window, 'resize', this ); | 2769 | window.eventie.unbind( window, 'resize', this ); | |||
| 2770 | } | 2770 | } | |||
| 2771 | this.isResizeBound = false; | 2771 | this.isResizeBound = false; | |||
| 2772 | }; | 2772 | }; | |||
| 2773 | 2773 | |||||
| 2774 | // original debounce by John Hann | 2774 | // original debounce by John Hann | |||
| 2775 | // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ | 2775 | // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ | |||
| 2776 | 2776 | |||||
| 2777 | // this fires every resize | 2777 | // this fires every resize | |||
| 2778 | Outlayer.prototype.onresize = function() { | 2778 | Outlayer.prototype.onresize = function() { | |||
| 2779 | if ( this.resizeTimeout ) { | 2779 | if ( this.resizeTimeout ) { | |||
| 2780 | clearTimeout( this.resizeTimeout ); | 2780 | clearTimeout( this.resizeTimeout ); | |||
| 2781 | } | 2781 | } | |||
| 2782 | 2782 | |||||
| 2783 | var _this = this; | 2783 | var _this = this; | |||
| 2784 | function delayed() { | 2784 | function delayed() { | |||
| 2785 | _this.resize(); | 2785 | _this.resize(); | |||
| 2786 | delete _this.resizeTimeout; | 2786 | delete _this.resizeTimeout; | |||
| 2787 | } | 2787 | } | |||
| 2788 | 2788 | |||||
| 2789 | this.resizeTimeout = setTimeout( delayed, 100 ); | 2789 | this.resizeTimeout = setTimeout( delayed, 100 ); | |||
| 2790 | }; | 2790 | }; | |||
| 2791 | 2791 | |||||
| 2792 | // debounced, layout on resize | 2792 | // debounced, layout on resize | |||
| 2793 | Outlayer.prototype.resize = function() { | 2793 | Outlayer.prototype.resize = function() { | |||
| 2794 | // don't trigger if size did not change | 2794 | // don't trigger if size did not change | |||
| 2795 | // or if resize was unbound. See #9 | 2795 | // or if resize was unbound. See #9 | |||
| 2796 | if ( !this.isResizeBound || !this.needsResizeLayout() ) { | 2796 | if ( !this.isResizeBound || !this.needsResizeLayout() ) { | |||
| 2797 | return; | 2797 | return; | |||
| 2798 | } | 2798 | } | |||
| 2799 | 2799 | |||||
| 2800 | this.layout(); | 2800 | this.layout(); | |||
| 2801 | }; | 2801 | }; | |||
| 2802 | 2802 | |||||
| 2803 | /** | 2803 | /** | |||
| 2804 | * check if layout is needed post layout | 2804 | * check if layout is needed post layout | |||
| 2805 | * @returns Boolean | 2805 | * @returns Boolean | |||
| 2806 | */ | 2806 | */ | |||
| 2807 | Outlayer.prototype.needsResizeLayout = function() { | 2807 | Outlayer.prototype.needsResizeLayout = function() { | |||
| 2808 | var size = getSize( this.element ); | 2808 | var size = getSize( this.element ); | |||
| 2809 | // check that this.size and size are there | 2809 | // check that this.size and size are there | |||
| 2810 | // IE8 triggers resize on body size change, so they might not be | 2810 | // IE8 triggers resize on body size change, so they might not be | |||
| 2811 | var hasSizes = this.size && size; | 2811 | var hasSizes = this.size && size; | |||
| 2812 | return hasSizes && size.innerWidth !== this.size.innerWidth; | 2812 | return hasSizes && size.innerWidth !== this.size.innerWidth; | |||
| 2813 | }; | 2813 | }; | |||
| 2814 | 2814 | |||||
| 2815 | // -------------------------- methods -------------------------- // | 2815 | // -------------------------- methods -------------------------- // | |||
| 2816 | 2816 | |||||
| 2817 | /** | 2817 | /** | |||
| 2818 | * add items to Outlayer instance | 2818 | * add items to Outlayer instance | |||
| 2819 | * @param {Array or NodeList or Element} elems | 2819 | * @param {Array or NodeList or Element} elems | |||
| 2820 | * @returns {Array} items - Outlayer.Items | 2820 | * @returns {Array} items - Outlayer.Items | |||
| 2821 | **/ | 2821 | **/ | |||
| 2822 | Outlayer.prototype.addItems = function( elems ) { | 2822 | Outlayer.prototype.addItems = function( elems ) { | |||
| 2823 | var items = this._itemize( elems ); | 2823 | var items = this._itemize( elems ); | |||
| 2824 | // add items to collection | 2824 | // add items to collection | |||
| 2825 | if ( items.length ) { | 2825 | if ( items.length ) { | |||
| 2826 | this.items = this.items.concat( items ); | 2826 | this.items = this.items.concat( items ); | |||
| 2827 | } | 2827 | } | |||
| 2828 | return items; | 2828 | return items; | |||
| 2829 | }; | 2829 | }; | |||
| 2830 | 2830 | |||||
| 2831 | /** | 2831 | /** | |||
| 2832 | * Layout newly-appended item elements | 2832 | * Layout newly-appended item elements | |||
| 2833 | * @param {Array or NodeList or Element} elems | 2833 | * @param {Array or NodeList or Element} elems | |||
| 2834 | */ | 2834 | */ | |||
| 2835 | Outlayer.prototype.appended = function( elems ) { | 2835 | Outlayer.prototype.appended = function( elems ) { | |||
| 2836 | var items = this.addItems( elems ); | 2836 | var items = this.addItems( elems ); | |||
| 2837 | if ( !items.length ) { | 2837 | if ( !items.length ) { | |||
| 2838 | return; | 2838 | return; | |||
| 2839 | } | 2839 | } | |||
| 2840 | // layout and reveal just the new items | 2840 | // layout and reveal just the new items | |||
| 2841 | this.layoutItems( items, true ); | 2841 | this.layoutItems( items, true ); | |||
| 2842 | this.reveal( items ); | 2842 | this.reveal( items ); | |||
| 2843 | }; | 2843 | }; | |||
| 2844 | 2844 | |||||
| 2845 | /** | 2845 | /** | |||
| 2846 | * Layout prepended elements | 2846 | * Layout prepended elements | |||
| 2847 | * @param {Array or NodeList or Element} elems | 2847 | * @param {Array or NodeList or Element} elems | |||
| 2848 | */ | 2848 | */ | |||
| 2849 | Outlayer.prototype.prepended = function( elems ) { | 2849 | Outlayer.prototype.prepended = function( elems ) { | |||
| 2850 | var items = this._itemize( elems ); | 2850 | var items = this._itemize( elems ); | |||
| 2851 | if ( !items.length ) { | 2851 | if ( !items.length ) { | |||
| 2852 | return; | 2852 | return; | |||
| 2853 | } | 2853 | } | |||
| 2854 | // add items to beginning of collection | 2854 | // add items to beginning of collection | |||
| 2855 | var previousItems = this.items.slice(0); | 2855 | var previousItems = this.items.slice(0); | |||
| 2856 | this.items = items.concat( previousItems ); | 2856 | this.items = items.concat( previousItems ); | |||
| 2857 | // start new layout | 2857 | // start new layout | |||
| 2858 | this._resetLayout(); | 2858 | this._resetLayout(); | |||
| 2859 | this._manageStamps(); | 2859 | this._manageStamps(); | |||
| 2860 | // layout new stuff without transition | 2860 | // layout new stuff without transition | |||
| 2861 | this.layoutItems( items, true ); | 2861 | this.layoutItems( items, true ); | |||
| 2862 | this.reveal( items ); | 2862 | this.reveal( items ); | |||
| 2863 | // layout previous items | 2863 | // layout previous items | |||
| 2864 | this.layoutItems( previousItems ); | 2864 | this.layoutItems( previousItems ); | |||
| 2865 | }; | 2865 | }; | |||
| 2866 | 2866 | |||||
| 2867 | /** | 2867 | /** | |||
| 2868 | * reveal a collection of items | 2868 | * reveal a collection of items | |||
| 2869 | * @param {Array of Outlayer.Items} items | 2869 | * @param {Array of Outlayer.Items} items | |||
| 2870 | */ | 2870 | */ | |||
| 2871 | Outlayer.prototype.reveal = function( items ) { | 2871 | Outlayer.prototype.reveal = function( items ) { | |||
| 2872 | this._emitCompleteOnItems( 'reveal', items ); | 2872 | this._emitCompleteOnItems( 'reveal', items ); | |||
| 2873 | 2873 | |||||
| 2874 | var len = items && items.length; | 2874 | var len = items && items.length; | |||
| 2875 | for ( var i=0; len && i < len; i++ ) { | 2875 | for ( var i=0; len && i < len; i++ ) { | |||
| 2876 | var item = items[i]; | 2876 | var item = items[i]; | |||
| 2877 | item.reveal(); | 2877 | item.reveal(); | |||
| 2878 | } | 2878 | } | |||
| 2879 | }; | 2879 | }; | |||
| 2880 | 2880 | |||||
| 2881 | /** | 2881 | /** | |||
| 2882 | * hide a collection of items | 2882 | * hide a collection of items | |||
| 2883 | * @param {Array of Outlayer.Items} items | 2883 | * @param {Array of Outlayer.Items} items | |||
| 2884 | */ | 2884 | */ | |||
| 2885 | Outlayer.prototype.hide = function( items ) { | 2885 | Outlayer.prototype.hide = function( items ) { | |||
| 2886 | this._emitCompleteOnItems( 'hide', items ); | 2886 | this._emitCompleteOnItems( 'hide', items ); | |||
| 2887 | 2887 | |||||
| 2888 | var len = items && items.length; | 2888 | var len = items && items.length; | |||
| 2889 | for ( var i=0; len && i < len; i++ ) { | 2889 | for ( var i=0; len && i < len; i++ ) { | |||
| 2890 | var item = items[i]; | 2890 | var item = items[i]; | |||
| 2891 | item.hide(); | 2891 | item.hide(); | |||
| 2892 | } | 2892 | } | |||
| 2893 | }; | 2893 | }; | |||
| 2894 | 2894 | |||||
| 2895 | /** | 2895 | /** | |||
| 2896 | * reveal item elements | 2896 | * reveal item elements | |||
| 2897 | * @param {Array}, {Element}, {NodeList} items | 2897 | * @param {Array}, {Element}, {NodeList} items | |||
| 2898 | */ | 2898 | */ | |||
| 2899 | Outlayer.prototype.revealItemElements = function( elems ) { | 2899 | Outlayer.prototype.revealItemElements = function( elems ) { | |||
| 2900 | var items = this.getItems( elems ); | 2900 | var items = this.getItems( elems ); | |||
| 2901 | this.reveal( items ); | 2901 | this.reveal( items ); | |||
| 2902 | }; | 2902 | }; | |||
| 2903 | 2903 | |||||
| 2904 | /** | 2904 | /** | |||
| 2905 | * hide item elements | 2905 | * hide item elements | |||
| 2906 | * @param {Array}, {Element}, {NodeList} items | 2906 | * @param {Array}, {Element}, {NodeList} items | |||
| 2907 | */ | 2907 | */ | |||
| 2908 | Outlayer.prototype.hideItemElements = function( elems ) { | 2908 | Outlayer.prototype.hideItemElements = function( elems ) { | |||
| 2909 | var items = this.getItems( elems ); | 2909 | var items = this.getItems( elems ); | |||
| 2910 | this.hide( items ); | 2910 | this.hide( items ); | |||
| 2911 | }; | 2911 | }; | |||
| 2912 | 2912 | |||||
| 2913 | /** | 2913 | /** | |||
| 2914 | * get Outlayer.Item, given an Element | 2914 | * get Outlayer.Item, given an Element | |||
| 2915 | * @param {Element} elem | 2915 | * @param {Element} elem | |||
| 2916 | * @param {Function} callback | 2916 | * @param {Function} callback | |||
| 2917 | * @returns {Outlayer.Item} item | 2917 | * @returns {Outlayer.Item} item | |||
| 2918 | */ | 2918 | */ | |||
| 2919 | Outlayer.prototype.getItem = function( elem ) { | 2919 | Outlayer.prototype.getItem = function( elem ) { | |||
| 2920 | // loop through items to get the one that matches | 2920 | // loop through items to get the one that matches | |||
| 2921 | for ( var i=0, len = this.items.length; i < len; i++ ) { | 2921 | for ( var i=0, len = this.items.length; i < len; i++ ) { | |||
| 2922 | var item = this.items[i]; | 2922 | var item = this.items[i]; | |||
| 2923 | if ( item.element === elem ) { | 2923 | if ( item.element === elem ) { | |||
| 2924 | // return item | 2924 | // return item | |||
| 2925 | return item; | 2925 | return item; | |||
| 2926 | } | 2926 | } | |||
| 2927 | } | 2927 | } | |||
| 2928 | }; | 2928 | }; | |||
| 2929 | 2929 | |||||
| 2930 | /** | 2930 | /** | |||
| 2931 | * get collection of Outlayer.Items, given Elements | 2931 | * get collection of Outlayer.Items, given Elements | |||
| 2932 | * @param {Array} elems | 2932 | * @param {Array} elems | |||
| 2933 | * @returns {Array} items - Outlayer.Items | 2933 | * @returns {Array} items - Outlayer.Items | |||
| 2934 | */ | 2934 | */ | |||
| 2935 | Outlayer.prototype.getItems = function( elems ) { | 2935 | Outlayer.prototype.getItems = function( elems ) { | |||
| 2936 | elems = utils.makeArray( elems ); | 2936 | elems = utils.makeArray( elems ); | |||
| 2937 | var items = []; | 2937 | var items = []; | |||
| 2938 | for ( var i=0, len = elems.length; i < len; i++ ) { | 2938 | for ( var i=0, len = elems.length; i < len; i++ ) { | |||
| 2939 | var elem = elems[i]; | 2939 | var elem = elems[i]; | |||
| 2940 | var item = this.getItem( elem ); | 2940 | var item = this.getItem( elem ); | |||
| 2941 | if ( item ) { | 2941 | if ( item ) { | |||
| 2942 | items.push( item ); | 2942 | items.push( item ); | |||
| 2943 | } | 2943 | } | |||
| 2944 | } | 2944 | } | |||
| 2945 | 2945 | |||||
| 2946 | return items; | 2946 | return items; | |||
| 2947 | }; | 2947 | }; | |||
| 2948 | 2948 | |||||
| 2949 | /** | 2949 | /** | |||
| 2950 | * remove element(s) from instance and DOM | 2950 | * remove element(s) from instance and DOM | |||
| 2951 | * @param {Array or NodeList or Element} elems | 2951 | * @param {Array or NodeList or Element} elems | |||
| 2952 | */ | 2952 | */ | |||
| 2953 | Outlayer.prototype.remove = function( elems ) { | 2953 | Outlayer.prototype.remove = function( elems ) { | |||
| 2954 | var removeItems = this.getItems( elems ); | 2954 | var removeItems = this.getItems( elems ); | |||
| 2955 | 2955 | |||||
| 2956 | this._emitCompleteOnItems( 'remove', removeItems ); | 2956 | this._emitCompleteOnItems( 'remove', removeItems ); | |||
| 2957 | 2957 | |||||
| 2958 | // bail if no items to remove | 2958 | // bail if no items to remove | |||
| 2959 | if ( !removeItems || !removeItems.length ) { | 2959 | if ( !removeItems || !removeItems.length ) { | |||
| 2960 | return; | 2960 | return; | |||
| 2961 | } | 2961 | } | |||
| 2962 | 2962 | |||||
| 2963 | for ( var i=0, len = removeItems.length; i < len; i++ ) { | 2963 | for ( var i=0, len = removeItems.length; i < len; i++ ) { | |||
| 2964 | var item = removeItems[i]; | 2964 | var item = removeItems[i]; | |||
| 2965 | item.remove(); | 2965 | item.remove(); | |||
| 2966 | // remove item from collection | 2966 | // remove item from collection | |||
| 2967 | utils.removeFrom( this.items, item ); | 2967 | utils.removeFrom( this.items, item ); | |||
| 2968 | } | 2968 | } | |||
| 2969 | }; | 2969 | }; | |||
| 2970 | 2970 | |||||
| 2971 | // ----- destroy ----- // | 2971 | // ----- destroy ----- // | |||
| 2972 | 2972 | |||||
| 2973 | // remove and disable Outlayer instance | 2973 | // remove and disable Outlayer instance | |||
| 2974 | Outlayer.prototype.destroy = function() { | 2974 | Outlayer.prototype.destroy = function() { | |||
| 2975 | // clean up dynamic styles | 2975 | // clean up dynamic styles | |||
| 2976 | var style = this.element.style; | 2976 | var style = this.element.style; | |||
| 2977 | style.height = ''; | 2977 | style.height = ''; | |||
| 2978 | style.position = ''; | 2978 | style.position = ''; | |||
| 2979 | style.width = ''; | 2979 | style.width = ''; | |||
| 2980 | // destroy items | 2980 | // destroy items | |||
| 2981 | for ( var i=0, len = this.items.length; i < len; i++ ) { | 2981 | for ( var i=0, len = this.items.length; i < len; i++ ) { | |||
| 2982 | var item = this.items[i]; | 2982 | var item = this.items[i]; | |||
| 2983 | item.destroy(); | 2983 | item.destroy(); | |||
| 2984 | } | 2984 | } | |||
| 2985 | 2985 | |||||
| 2986 | this.unbindResize(); | 2986 | this.unbindResize(); | |||
| 2987 | 2987 | |||||
| 2988 | var id = this.element.outlayerGUID; | 2988 | var id = this.element.outlayerGUID; | |||
| 2989 | delete instances[ id ]; // remove reference to instance by id | 2989 | delete instances[ id ]; // remove reference to instance by id | |||
| 2990 | delete this.element.outlayerGUID; | 2990 | delete this.element.outlayerGUID; | |||
| 2991 | // remove data for jQuery | 2991 | // remove data for jQuery | |||
| 2992 | if ( jQuery ) { | 2992 | if ( jQuery ) { | |||
| 2993 | jQuery.removeData( this.element, this.constructor.namespace ); | 2993 | jQuery.removeData( this.element, this.constructor.namespace ); | |||
| 2994 | } | 2994 | } | |||
| 2995 | 2995 | |||||
| 2996 | }; | 2996 | }; | |||
| 2997 | 2997 | |||||
| 2998 | // -------------------------- data -------------------------- // | 2998 | // -------------------------- data -------------------------- // | |||
| 2999 | 2999 | |||||
| 3000 | /** | 3000 | /** | |||
| 3001 | * get Outlayer instance from element | 3001 | * get Outlayer instance from element | |||
| 3002 | * @param {Element} elem | 3002 | * @param {Element} elem | |||
| 3003 | * @returns {Outlayer} | 3003 | * @returns {Outlayer} | |||
| 3004 | */ | 3004 | */ | |||
| 3005 | Outlayer.data = function( elem ) { | 3005 | Outlayer.data = function( elem ) { | |||
| 3006 | elem = utils.getQueryElement( elem ); | 3006 | elem = utils.getQueryElement( elem ); | |||
| 3007 | var id = elem && elem.outlayerGUID; | 3007 | var id = elem && elem.outlayerGUID; | |||
| 3008 | return id && instances[ id ]; | 3008 | return id && instances[ id ]; | |||
| 3009 | }; | 3009 | }; | |||
| 3010 | 3010 | |||||
| 3011 | 3011 | |||||
| 3012 | // -------------------------- create Outlayer class -------------------------- // | 3012 | // -------------------------- create Outlayer class -------------------------- // | |||
| 3013 | 3013 | |||||
| 3014 | /** | 3014 | /** | |||
| 3015 | * create a layout class | 3015 | * create a layout class | |||
| 3016 | * @param {String} namespace | 3016 | * @param {String} namespace | |||
| 3017 | */ | 3017 | */ | |||
| 3018 | Outlayer.create = function( namespace, options ) { | 3018 | Outlayer.create = function( namespace, options ) { | |||
| 3019 | // sub-class Outlayer | 3019 | // sub-class Outlayer | |||
| 3020 | function Layout() { | 3020 | function Layout() { | |||
| 3021 | Outlayer.apply( this, arguments ); | 3021 | Outlayer.apply( this, arguments ); | |||
| 3022 | } | 3022 | } | |||
| 3023 | // inherit Outlayer prototype, use Object.create if there | 3023 | // inherit Outlayer prototype, use Object.create if there | |||
| 3024 | if ( Object.create ) { | 3024 | if ( Object.create ) { | |||
| 3025 | Layout.prototype = Object.create( Outlayer.prototype ); | 3025 | Layout.prototype = Object.create( Outlayer.prototype ); | |||
| 3026 | } else { | 3026 | } else { | |||
| 3027 | utils.extend( Layout.prototype, Outlayer.prototype ); | 3027 | utils.extend( Layout.prototype, Outlayer.prototype ); | |||
| 3028 | } | 3028 | } | |||
| 3029 | // set contructor, used for namespace and Item | 3029 | // set contructor, used for namespace and Item | |||
| 3030 | Layout.prototype.constructor = Layout; | 3030 | Layout.prototype.constructor = Layout; | |||
| 3031 | 3031 | |||||
| 3032 | Layout.defaults = utils.extend( {}, Outlayer.defaults ); | 3032 | Layout.defaults = utils.extend( {}, Outlayer.defaults ); | |||
| 3033 | // apply new options | 3033 | // apply new options | |||
| 3034 | utils.extend( Layout.defaults, options ); | 3034 | utils.extend( Layout.defaults, options ); | |||
| 3035 | // keep prototype.settings for backwards compatibility (Packery v1.2.0) | 3035 | // keep prototype.settings for backwards compatibility (Packery v1.2.0) | |||
| 3036 | Layout.prototype.settings = {}; | 3036 | Layout.prototype.settings = {}; | |||
| 3037 | 3037 | |||||
| 3038 | Layout.namespace = namespace; | 3038 | Layout.namespace = namespace; | |||
| 3039 | 3039 | |||||
| 3040 | Layout.data = Outlayer.data; | 3040 | Layout.data = Outlayer.data; | |||
| 3041 | 3041 | |||||
| 3042 | // sub-class Item | 3042 | // sub-class Item | |||
| 3043 | Layout.Item = function LayoutItem() { | 3043 | Layout.Item = function LayoutItem() { | |||
| 3044 | Item.apply( this, arguments ); | 3044 | Item.apply( this, arguments ); | |||
| 3045 | }; | 3045 | }; | |||
| 3046 | 3046 | |||||
| 3047 | Layout.Item.prototype = new Item(); | 3047 | Layout.Item.prototype = new Item(); | |||
| 3048 | 3048 | |||||
| 3049 | // -------------------------- declarative -------------------------- // | 3049 | // -------------------------- declarative -------------------------- // | |||
| 3050 | 3050 | |||||
| 3051 | utils.htmlInit( Layout, namespace ); | 3051 | utils.htmlInit( Layout, namespace ); | |||
| 3052 | 3052 | |||||
| 3053 | // -------------------------- jQuery bridge -------------------------- // | 3053 | // -------------------------- jQuery bridge -------------------------- // | |||
| 3054 | 3054 | |||||
| 3055 | // make into jQuery plugin | 3055 | // make into jQuery plugin | |||
| 3056 | if ( jQuery && jQuery.bridget ) { | 3056 | if ( jQuery && jQuery.bridget ) { | |||
| 3057 | jQuery.bridget( namespace, Layout ); | 3057 | jQuery.bridget( namespace, Layout ); | |||
| 3058 | } | 3058 | } | |||
| 3059 | 3059 | |||||
| 3060 | return Layout; | 3060 | return Layout; | |||
| 3061 | }; | 3061 | }; | |||
| 3062 | 3062 | |||||
| 3063 | // ----- fin ----- // | 3063 | // ----- fin ----- // | |||
| 3064 | 3064 | |||||
| 3065 | // back in global | 3065 | // back in global | |||
| 3066 | Outlayer.Item = Item; | 3066 | Outlayer.Item = Item; | |||
| 3067 | 3067 | |||||
| 3068 | return Outlayer; | 3068 | return Outlayer; | |||
| 3069 | 3069 | |||||
| 3070 | })); | 3070 | })); | |||
| 3071 | 3071 | |||||
| 3072 | 3072 | |||||
| 3073 | /** | 3073 | /** | |||
| 3074 | * Rect | 3074 | * Rect | |||
| 3075 | * low-level utility class for basic geometry | 3075 | * low-level utility class for basic geometry | |||
| 3076 | */ | 3076 | */ | |||
| 3077 | 3077 | |||||
| 3078 | ( function( window, factory ) { | 3078 | ( function( window, factory ) { | |||
| 3079 | 3079 | |||||
| 3080 | // universal module definition | 3080 | // universal module definition | |||
| 3081 | if ( typeof define == 'function' && define.amd ) { | 3081 | if ( typeof define == 'function' && define.amd ) { | |||
| 3082 | // AMD | 3082 | // AMD | |||
| 3083 | define( 'packery/js/rect',factory ); | 3083 | define( 'packery/js/rect',factory ); | |||
| 3084 | } else if ( typeof exports == 'object' ) { | 3084 | } else if ( typeof exports == 'object' ) { | |||
| 3085 | // CommonJS | 3085 | // CommonJS | |||
| 3086 | module.exports = factory(); | 3086 | module.exports = factory(); | |||
| 3087 | } else { | 3087 | } else { | |||
| 3088 | // browser global | 3088 | // browser global | |||
| 3089 | window.Packery = window.Packery || {}; | 3089 | window.Packery = window.Packery || {}; | |||
| 3090 | window.Packery.Rect = factory(); | 3090 | window.Packery.Rect = factory(); | |||
| 3091 | } | 3091 | } | |||
| 3092 | 3092 | |||||
| 3093 | }( window, function factory() { | 3093 | }( window, function factory() { | |||
| 3094 | 3094 | |||||
| 3095 | 3095 | |||||
| 3096 | // -------------------------- Packery -------------------------- // | 3096 | // -------------------------- Packery -------------------------- // | |||
| 3097 | 3097 | |||||
| 3098 | // global namespace | 3098 | // global namespace | |||
| 3099 | var Packery = window.Packery = function() {}; | 3099 | var Packery = window.Packery = function() {}; | |||
| 3100 | 3100 | |||||
| 3101 | // -------------------------- Rect -------------------------- // | 3101 | // -------------------------- Rect -------------------------- // | |||
| 3102 | 3102 | |||||
| 3103 | function Rect( props ) { | 3103 | function Rect( props ) { | |||
| 3104 | // extend properties from defaults | 3104 | // extend properties from defaults | |||
| 3105 | for ( var prop in Rect.defaults ) { | 3105 | for ( var prop in Rect.defaults ) { | |||
| 3106 | this[ prop ] = Rect.defaults[ prop ]; | 3106 | this[ prop ] = Rect.defaults[ prop ]; | |||
| 3107 | } | 3107 | } | |||
| 3108 | 3108 | |||||
| 3109 | for ( prop in props ) { | 3109 | for ( prop in props ) { | |||
| 3110 | this[ prop ] = props[ prop ]; | 3110 | this[ prop ] = props[ prop ]; | |||
| 3111 | } | 3111 | } | |||
| 3112 | 3112 | |||||
| 3113 | } | 3113 | } | |||
| 3114 | 3114 | |||||
| 3115 | // make available | 3115 | // make available | |||
| 3116 | Packery.Rect = Rect; | 3116 | Packery.Rect = Rect; | |||
| 3117 | 3117 | |||||
| 3118 | Rect.defaults = { | 3118 | Rect.defaults = { | |||
| 3119 | x: 0, | 3119 | x: 0, | |||
| 3120 | y: 0, | 3120 | y: 0, | |||
| 3121 | width: 0, | 3121 | width: 0, | |||
| 3122 | height: 0 | 3122 | height: 0 | |||
| 3123 | }; | 3123 | }; | |||
| 3124 | 3124 | |||||
| 3125 | /** | 3125 | /** | |||
| 3126 | * Determines whether or not this rectangle wholly encloses another rectangle or point. | 3126 | * Determines whether or not this rectangle wholly encloses another rectangle or point. | |||
| 3127 | * @param {Rect} rect | 3127 | * @param {Rect} rect | |||
| 3128 | * @returns {Boolean} | 3128 | * @returns {Boolean} | |||
| 3129 | **/ | 3129 | **/ | |||
| 3130 | Rect.prototype.contains = function( rect ) { | 3130 | Rect.prototype.contains = function( rect ) { | |||
| 3131 | // points don't have width or height | 3131 | // points don't have width or height | |||
| 3132 | var otherWidth = rect.width || 0; | 3132 | var otherWidth = rect.width || 0; | |||
| 3133 | var otherHeight = rect.height || 0; | 3133 | var otherHeight = rect.height || 0; | |||
| 3134 | return this.x <= rect.x && | 3134 | return this.x <= rect.x && | |||
| 3135 | this.y <= rect.y && | 3135 | this.y <= rect.y && | |||
| 3136 | this.x + this.width >= rect.x + otherWidth && | 3136 | this.x + this.width >= rect.x + otherWidth && | |||
| 3137 | this.y + this.height >= rect.y + otherHeight; | 3137 | this.y + this.height >= rect.y + otherHeight; | |||
| 3138 | }; | 3138 | }; | |||
| 3139 | 3139 | |||||
| 3140 | /** | 3140 | /** | |||
| 3141 | * Determines whether or not the rectangle intersects with another. | 3141 | * Determines whether or not the rectangle intersects with another. | |||
| 3142 | * @param {Rect} rect | 3142 | * @param {Rect} rect | |||
| 3143 | * @returns {Boolean} | 3143 | * @returns {Boolean} | |||
| 3144 | **/ | 3144 | **/ | |||
| 3145 | Rect.prototype.overlaps = function( rect ) { | 3145 | Rect.prototype.overlaps = function( rect ) { | |||
| 3146 | var thisRight = this.x + this.width; | 3146 | var thisRight = this.x + this.width; | |||
| 3147 | var thisBottom = this.y + this.height; | 3147 | var thisBottom = this.y + this.height; | |||
| 3148 | var rectRight = rect.x + rect.width; | 3148 | var rectRight = rect.x + rect.width; | |||
| 3149 | var rectBottom = rect.y + rect.height; | 3149 | var rectBottom = rect.y + rect.height; | |||
| 3150 | 3150 | |||||
| 3151 | // http://stackoverflow.com/a/306332 | 3151 | // http://stackoverflow.com/a/306332 | |||
| 3152 | return this.x < rectRight && | 3152 | return this.x < rectRight && | |||
| 3153 | thisRight > rect.x && | 3153 | thisRight > rect.x && | |||
| 3154 | this.y < rectBottom && | 3154 | this.y < rectBottom && | |||
| 3155 | thisBottom > rect.y; | 3155 | thisBottom > rect.y; | |||
| 3156 | }; | 3156 | }; | |||
| 3157 | 3157 | |||||
| 3158 | /** | 3158 | /** | |||
| 3159 | * @param {Rect} rect - the overlapping rect | 3159 | * @param {Rect} rect - the overlapping rect | |||
| 3160 | * @returns {Array} freeRects - rects representing the area around the rect | 3160 | * @returns {Array} freeRects - rects representing the area around the rect | |||
| 3161 | **/ | 3161 | **/ | |||
| 3162 | Rect.prototype.getMaximalFreeRects = function( rect ) { | 3162 | Rect.prototype.getMaximalFreeRects = function( rect ) { | |||
| 3163 | 3163 | |||||
| 3164 | // if no intersection, return false | 3164 | // if no intersection, return false | |||
| 3165 | if ( !this.overlaps( rect ) ) { | 3165 | if ( !this.overlaps( rect ) ) { | |||
| 3166 | return false; | 3166 | return false; | |||
| 3167 | } | 3167 | } | |||
| 3168 | 3168 | |||||
| 3169 | var freeRects = []; | 3169 | var freeRects = []; | |||
| 3170 | var freeRect; | 3170 | var freeRect; | |||
| 3171 | 3171 | |||||
| 3172 | var thisRight = this.x + this.width; | 3172 | var thisRight = this.x + this.width; | |||
| 3173 | var thisBottom = this.y + this.height; | 3173 | var thisBottom = this.y + this.height; | |||
| 3174 | var rectRight = rect.x + rect.width; | 3174 | var rectRight = rect.x + rect.width; | |||
| 3175 | var rectBottom = rect.y + rect.height; | 3175 | var rectBottom = rect.y + rect.height; | |||
| 3176 | 3176 | |||||
| 3177 | // top | 3177 | // top | |||
| 3178 | if ( this.y < rect.y ) { | 3178 | if ( this.y < rect.y ) { | |||
| 3179 | freeRect = new Rect({ | 3179 | freeRect = new Rect({ | |||
| 3180 | x: this.x, | 3180 | x: this.x, | |||
| 3181 | y: this.y, | 3181 | y: this.y, | |||
| 3182 | width: this.width, | 3182 | width: this.width, | |||
| 3183 | height: rect.y - this.y | 3183 | height: rect.y - this.y | |||
| 3184 | }); | 3184 | }); | |||
| 3185 | freeRects.push( freeRect ); | 3185 | freeRects.push( freeRect ); | |||
| 3186 | } | 3186 | } | |||
| 3187 | 3187 | |||||
| 3188 | // right | 3188 | // right | |||
| 3189 | if ( thisRight > rectRight ) { | 3189 | if ( thisRight > rectRight ) { | |||
| 3190 | freeRect = new Rect({ | 3190 | freeRect = new Rect({ | |||
| 3191 | x: rectRight, | 3191 | x: rectRight, | |||
| 3192 | y: this.y, | 3192 | y: this.y, | |||
| 3193 | width: thisRight - rectRight, | 3193 | width: thisRight - rectRight, | |||
| 3194 | height: this.height | 3194 | height: this.height | |||
| 3195 | }); | 3195 | }); | |||
| 3196 | freeRects.push( freeRect ); | 3196 | freeRects.push( freeRect ); | |||
| 3197 | } | 3197 | } | |||
| 3198 | 3198 | |||||
| 3199 | // bottom | 3199 | // bottom | |||
| 3200 | if ( thisBottom > rectBottom ) { | 3200 | if ( thisBottom > rectBottom ) { | |||
| 3201 | freeRect = new Rect({ | 3201 | freeRect = new Rect({ | |||
| 3202 | x: this.x, | 3202 | x: this.x, | |||
| 3203 | y: rectBottom, | 3203 | y: rectBottom, | |||
| 3204 | width: this.width, | 3204 | width: this.width, | |||
| 3205 | height: thisBottom - rectBottom | 3205 | height: thisBottom - rectBottom | |||
| 3206 | }); | 3206 | }); | |||
| 3207 | freeRects.push( freeRect ); | 3207 | freeRects.push( freeRect ); | |||
| 3208 | } | 3208 | } | |||
| 3209 | 3209 | |||||
| 3210 | // left | 3210 | // left | |||
| 3211 | if ( this.x < rect.x ) { | 3211 | if ( this.x < rect.x ) { | |||
| 3212 | freeRect = new Rect({ | 3212 | freeRect = new Rect({ | |||
| 3213 | x: this.x, | 3213 | x: this.x, | |||
| 3214 | y: this.y, | 3214 | y: this.y, | |||
| 3215 | width: rect.x - this.x, | 3215 | width: rect.x - this.x, | |||
| 3216 | height: this.height | 3216 | height: this.height | |||
| 3217 | }); | 3217 | }); | |||
| 3218 | freeRects.push( freeRect ); | 3218 | freeRects.push( freeRect ); | |||
| 3219 | } | 3219 | } | |||
| 3220 | 3220 | |||||
| 3221 | return freeRects; | 3221 | return freeRects; | |||
| 3222 | }; | 3222 | }; | |||
| 3223 | 3223 | |||||
| 3224 | Rect.prototype.canFit = function( rect ) { | 3224 | Rect.prototype.canFit = function( rect ) { | |||
| 3225 | return this.width >= rect.width && this.height >= rect.height; | 3225 | return this.width >= rect.width && this.height >= rect.height; | |||
| 3226 | }; | 3226 | }; | |||
| 3227 | 3227 | |||||
| 3228 | return Rect; | 3228 | return Rect; | |||
| 3229 | 3229 | |||||
| 3230 | })); | 3230 | })); | |||
| 3231 | 3231 | |||||
| 3232 | /** | 3232 | /** | |||
| 3233 | * Packer | 3233 | * Packer | |||
| 3234 | * bin-packing algorithm | 3234 | * bin-packing algorithm | |||
| 3235 | */ | 3235 | */ | |||
| 3236 | 3236 | |||||
| 3237 | ( function( window, factory ) { | 3237 | ( function( window, factory ) { | |||
| 3238 | 3238 | |||||
| 3239 | // universal module definition | 3239 | // universal module definition | |||
| 3240 | if ( typeof define == 'function' && define.amd ) { | 3240 | if ( typeof define == 'function' && define.amd ) { | |||
| 3241 | // AMD | 3241 | // AMD | |||
| 3242 | define( 'packery/js/packer',[ './rect' ], factory ); | 3242 | define( 'packery/js/packer',[ './rect' ], factory ); | |||
| 3243 | } else if ( typeof exports == 'object' ) { | 3243 | } else if ( typeof exports == 'object' ) { | |||
| 3244 | // CommonJS | 3244 | // CommonJS | |||
| 3245 | module.exports = factory( | 3245 | module.exports = factory( | |||
| 3246 | require('./rect') | 3246 | require('./rect') | |||
| 3247 | ); | 3247 | ); | |||
| 3248 | } else { | 3248 | } else { | |||
| 3249 | // browser global | 3249 | // browser global | |||
| 3250 | var Packery = window.Packery = window.Packery || {}; | 3250 | var Packery = window.Packery = window.Packery || {}; | |||
| 3251 | Packery.Packer = factory( Packery.Rect ); | 3251 | Packery.Packer = factory( Packery.Rect ); | |||
| 3252 | } | 3252 | } | |||
| 3253 | 3253 | |||||
| 3254 | }( window, function factory( Rect ) { | 3254 | }( window, function factory( Rect ) { | |||
| 3255 | 3255 | |||||
| 3256 | 3256 | |||||
| 3257 | // -------------------------- Packer -------------------------- // | 3257 | // -------------------------- Packer -------------------------- // | |||
| 3258 | 3258 | |||||
| 3259 | /** | 3259 | /** | |||
| 3260 | * @param {Number} width | 3260 | * @param {Number} width | |||
| 3261 | * @param {Number} height | 3261 | * @param {Number} height | |||
| 3262 | * @param {String} sortDirection | 3262 | * @param {String} sortDirection | |||
| 3263 | * topLeft for vertical, leftTop for horizontal | 3263 | * topLeft for vertical, leftTop for horizontal | |||
| 3264 | */ | 3264 | */ | |||
| 3265 | function Packer( width, height, sortDirection ) { | 3265 | function Packer( width, height, sortDirection ) { | |||
| 3266 | this.width = width || 0; | 3266 | this.width = width || 0; | |||
| 3267 | this.height = height || 0; | 3267 | this.height = height || 0; | |||
| 3268 | this.sortDirection = sortDirection || 'downwardLeftToRight'; | 3268 | this.sortDirection = sortDirection || 'downwardLeftToRight'; | |||
| 3269 | 3269 | |||||
| 3270 | this.reset(); | 3270 | this.reset(); | |||
| 3271 | } | 3271 | } | |||
| 3272 | 3272 | |||||
| 3273 | Packer.prototype.reset = function() { | 3273 | Packer.prototype.reset = function() { | |||
| 3274 | this.spaces = []; | 3274 | this.spaces = []; | |||
| 3275 | this.newSpaces = []; | 3275 | this.newSpaces = []; | |||
| 3276 | 3276 | |||||
| 3277 | var initialSpace = new Rect({ | 3277 | var initialSpace = new Rect({ | |||
| 3278 | x: 0, | 3278 | x: 0, | |||
| 3279 | y: 0, | 3279 | y: 0, | |||
| 3280 | width: this.width, | 3280 | width: this.width, | |||
| 3281 | height: this.height | 3281 | height: this.height | |||
| 3282 | }); | 3282 | }); | |||
| 3283 | 3283 | |||||
| 3284 | this.spaces.push( initialSpace ); | 3284 | this.spaces.push( initialSpace ); | |||
| 3285 | // set sorter | 3285 | // set sorter | |||
| 3286 | this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; | 3286 | this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; | |||
| 3287 | }; | 3287 | }; | |||
| 3288 | 3288 | |||||
| 3289 | // change x and y of rect to fit with in Packer's available spaces | 3289 | // change x and y of rect to fit with in Packer's available spaces | |||
| 3290 | Packer.prototype.pack = function( rect ) { | 3290 | Packer.prototype.pack = function( rect ) { | |||
| 3291 | for ( var i=0, len = this.spaces.length; i < len; i++ ) { | 3291 | for ( var i=0, len = this.spaces.length; i < len; i++ ) { | |||
| 3292 | var space = this.spaces[i]; | 3292 | var space = this.spaces[i]; | |||
| 3293 | if ( space.canFit( rect ) ) { | 3293 | if ( space.canFit( rect ) ) { | |||
| 3294 | this.placeInSpace( rect, space ); | 3294 | this.placeInSpace( rect, space ); | |||
| 3295 | break; | 3295 | break; | |||
| 3296 | } | 3296 | } | |||
| 3297 | } | 3297 | } | |||
| 3298 | }; | 3298 | }; | |||
| 3299 | 3299 | |||||
| 3300 | Packer.prototype.placeInSpace = function( rect, space ) { | 3300 | Packer.prototype.placeInSpace = function( rect, space ) { | |||
| 3301 | // place rect in space | 3301 | // place rect in space | |||
| 3302 | rect.x = space.x; | 3302 | rect.x = space.x; | |||
| 3303 | rect.y = space.y; | 3303 | rect.y = space.y; | |||
| 3304 | 3304 | |||||
| 3305 | this.placed( rect ); | 3305 | this.placed( rect ); | |||
| 3306 | }; | 3306 | }; | |||
| 3307 | 3307 | |||||
| 3308 | // update spaces with placed rect | 3308 | // update spaces with placed rect | |||
| 3309 | Packer.prototype.placed = function( rect ) { | 3309 | Packer.prototype.placed = function( rect ) { | |||
| 3310 | // update spaces | 3310 | // update spaces | |||
| 3311 | var revisedSpaces = []; | 3311 | var revisedSpaces = []; | |||
| 3312 | for ( var i=0, len = this.spaces.length; i < len; i++ ) { | 3312 | for ( var i=0, len = this.spaces.length; i < len; i++ ) { | |||
| 3313 | var space = this.spaces[i]; | 3313 | var space = this.spaces[i]; | |||
| 3314 | var newSpaces = space.getMaximalFreeRects( rect ); | 3314 | var newSpaces = space.getMaximalFreeRects( rect ); | |||
| 3315 | // add either the original space or the new spaces to the revised spaces | 3315 | // add either the original space or the new spaces to the revised spaces | |||
| 3316 | if ( newSpaces ) { | 3316 | if ( newSpaces ) { | |||
| 3317 | revisedSpaces.push.apply( revisedSpaces, newSpaces ); | 3317 | revisedSpaces.push.apply( revisedSpaces, newSpaces ); | |||
| 3318 | } else { | 3318 | } else { | |||
| 3319 | revisedSpaces.push( space ); | 3319 | revisedSpaces.push( space ); | |||
| 3320 | } | 3320 | } | |||
| 3321 | } | 3321 | } | |||
| 3322 | 3322 | |||||
| 3323 | this.spaces = revisedSpaces; | 3323 | this.spaces = revisedSpaces; | |||
| 3324 | 3324 | |||||
| 3325 | this.mergeSortSpaces(); | 3325 | this.mergeSortSpaces(); | |||
| 3326 | }; | 3326 | }; | |||
| 3327 | 3327 | |||||
| 3328 | Packer.prototype.mergeSortSpaces = function() { | 3328 | Packer.prototype.mergeSortSpaces = function() { | |||
| 3329 | // remove redundant spaces | 3329 | // remove redundant spaces | |||
| 3330 | Packer.mergeRects( this.spaces ); | 3330 | Packer.mergeRects( this.spaces ); | |||
| 3331 | this.spaces.sort( this.sorter ); | 3331 | this.spaces.sort( this.sorter ); | |||
| 3332 | }; | 3332 | }; | |||
| 3333 | 3333 | |||||
| 3334 | // add a space back | 3334 | // add a space back | |||
| 3335 | Packer.prototype.addSpace = function( rect ) { | 3335 | Packer.prototype.addSpace = function( rect ) { | |||
| 3336 | this.spaces.push( rect ); | 3336 | this.spaces.push( rect ); | |||
| 3337 | this.mergeSortSpaces(); | 3337 | this.mergeSortSpaces(); | |||
| 3338 | }; | 3338 | }; | |||
| 3339 | 3339 | |||||
| 3340 | // -------------------------- utility functions -------------------------- // | 3340 | // -------------------------- utility functions -------------------------- // | |||
| 3341 | 3341 | |||||
| 3342 | /** | 3342 | /** | |||
| 3343 | * Remove redundant rectangle from array of rectangles | 3343 | * Remove redundant rectangle from array of rectangles | |||
| 3344 | * @param {Array} rects: an array of Rects | 3344 | * @param {Array} rects: an array of Rects | |||
| 3345 | * @returns {Array} rects: an array of Rects | 3345 | * @returns {Array} rects: an array of Rects | |||
| 3346 | **/ | 3346 | **/ | |||
| 3347 | Packer.mergeRects = function( rects ) { | 3347 | Packer.mergeRects = function( rects ) { | |||
| 3348 | for ( var i=0, len = rects.length; i < len; i++ ) { | 3348 | for ( var i=0, len = rects.length; i < len; i++ ) { | |||
| 3349 | var rect = rects[i]; | 3349 | var rect = rects[i]; | |||
| 3350 | // skip over this rect if it was already removed | 3350 | // skip over this rect if it was already removed | |||
| 3351 | if ( !rect ) { | 3351 | if ( !rect ) { | |||
| 3352 | continue; | 3352 | continue; | |||
| 3353 | } | 3353 | } | |||
| 3354 | // clone rects we're testing, remove this rect | 3354 | // clone rects we're testing, remove this rect | |||
| 3355 | var compareRects = rects.slice(0); | 3355 | var compareRects = rects.slice(0); | |||
| 3356 | // do not compare with self | 3356 | // do not compare with self | |||
| 3357 | compareRects.splice( i, 1 ); | 3357 | compareRects.splice( i, 1 ); | |||
| 3358 | // compare this rect with others | 3358 | // compare this rect with others | |||
| 3359 | var removedCount = 0; | 3359 | var removedCount = 0; | |||
| 3360 | for ( var j=0, jLen = compareRects.length; j < jLen; j++ ) { | 3360 | for ( var j=0, jLen = compareRects.length; j < jLen; j++ ) { | |||
| 3361 | var compareRect = compareRects[j]; | 3361 | var compareRect = compareRects[j]; | |||
| 3362 | // if this rect contains another, | 3362 | // if this rect contains another, | |||
| 3363 | // remove that rect from test collection | 3363 | // remove that rect from test collection | |||
| 3364 | var indexAdjust = i > j ? 0 : 1; | 3364 | var indexAdjust = i > j ? 0 : 1; | |||
| 3365 | if ( rect.contains( compareRect ) ) { | 3365 | if ( rect.contains( compareRect ) ) { | |||
| 3366 | // console.log( 'current test rects:' + testRects.length, testRects ); | 3366 | // console.log( 'current test rects:' + testRects.length, testRects ); | |||
| 3367 | // console.log( i, j, indexAdjust, rect, compareRect ); | 3367 | // console.log( i, j, indexAdjust, rect, compareRect ); | |||
| 3368 | rects.splice( j + indexAdjust - removedCount, 1 ); | 3368 | rects.splice( j + indexAdjust - removedCount, 1 ); | |||
| 3369 | removedCount++; | 3369 | removedCount++; | |||
| 3370 | } | 3370 | } | |||
| 3371 | } | 3371 | } | |||
| 3372 | } | 3372 | } | |||
| 3373 | 3373 | |||||
| 3374 | return rects; | 3374 | return rects; | |||
| 3375 | }; | 3375 | }; | |||
| 3376 | 3376 | |||||
| 3377 | 3377 | |||||
| 3378 | // -------------------------- sorters -------------------------- // | 3378 | // -------------------------- sorters -------------------------- // | |||
| 3379 | 3379 | |||||
| 3380 | // functions for sorting rects in order | 3380 | // functions for sorting rects in order | |||
| 3381 | var sorters = { | 3381 | var sorters = { | |||
| 3382 | // top down, then left to right | 3382 | // top down, then left to right | |||
| 3383 | downwardLeftToRight: function( a, b ) { | 3383 | downwardLeftToRight: function( a, b ) { | |||
| 3384 | return a.y - b.y || a.x - b.x; | 3384 | return a.y - b.y || a.x - b.x; | |||
| 3385 | }, | 3385 | }, | |||
| 3386 | // left to right, then top down | 3386 | // left to right, then top down | |||
| 3387 | rightwardTopToBottom: function( a, b ) { | 3387 | rightwardTopToBottom: function( a, b ) { | |||
| 3388 | return a.x - b.x || a.y - b.y; | 3388 | return a.x - b.x || a.y - b.y; | |||
| 3389 | } | 3389 | } | |||
| 3390 | }; | 3390 | }; | |||
| 3391 | 3391 | |||||
| 3392 | 3392 | |||||
| 3393 | // -------------------------- -------------------------- // | 3393 | // -------------------------- -------------------------- // | |||
| 3394 | 3394 | |||||
| 3395 | return Packer; | 3395 | return Packer; | |||
| 3396 | 3396 | |||||
| 3397 | })); | 3397 | })); | |||
| 3398 | /** | 3398 | /** | |||
| 3399 | * Packery Item Element | 3399 | * Packery Item Element | |||
| 3400 | **/ | 3400 | **/ | |||
| 3401 | 3401 | |||||
| 3402 | ( function( window, factory ) { | 3402 | ( function( window, factory ) { | |||
| 3403 | 3403 | |||||
| 3404 | // universal module definition | 3404 | // universal module definition | |||
| 3405 | 3405 | |||||
| 3406 | if ( typeof define == 'function' && define.amd ) { | 3406 | if ( typeof define == 'function' && define.amd ) { | |||
| 3407 | // AMD | 3407 | // AMD | |||
| 3408 | define( 'packery/js/item',[ | 3408 | define( 'packery/js/item',[ | |||
| 3409 | 'get-style-property/get-style-property', | 3409 | 'get-style-property/get-style-property', | |||
| 3410 | 'outlayer/outlayer', | 3410 | 'outlayer/outlayer', | |||
| 3411 | './rect' | 3411 | './rect' | |||
| 3412 | ], | 3412 | ], | |||
| 3413 | factory ); | 3413 | factory ); | |||
| 3414 | } else if ( typeof exports == 'object' ) { | 3414 | } else if ( typeof exports == 'object' ) { | |||
| 3415 | // CommonJS | 3415 | // CommonJS | |||
| 3416 | module.exports = factory( | 3416 | module.exports = factory( | |||
| 3417 | require('desandro-get-style-property'), | 3417 | require('desandro-get-style-property'), | |||
| 3418 | require('outlayer'), | 3418 | require('outlayer'), | |||
| 3419 | require('./rect') | 3419 | require('./rect') | |||
| 3420 | ); | 3420 | ); | |||
| 3421 | } else { | 3421 | } else { | |||
| 3422 | // browser global | 3422 | // browser global | |||
| 3423 | window.Packery.Item = factory( | 3423 | window.Packery.Item = factory( | |||
| 3424 | window.getStyleProperty, | 3424 | window.getStyleProperty, | |||
| 3425 | window.Outlayer, | 3425 | window.Outlayer, | |||
| 3426 | window.Packery.Rect | 3426 | window.Packery.Rect | |||
| 3427 | ); | 3427 | ); | |||
| 3428 | } | 3428 | } | |||
| 3429 | 3429 | |||||
| 3430 | }( window, function factory( getStyleProperty, Outlayer, Rect ) { | 3430 | }( window, function factory( getStyleProperty, Outlayer, Rect ) { | |||
| 3431 | 3431 | |||||
| 3432 | 3432 | |||||
| 3433 | // -------------------------- Item -------------------------- // | 3433 | // -------------------------- Item -------------------------- // | |||
| 3434 | 3434 | |||||
| 3435 | var transformProperty = getStyleProperty('transform'); | 3435 | var transformProperty = getStyleProperty('transform'); | |||
| 3436 | 3436 | |||||
| 3437 | // sub-class Item | 3437 | // sub-class Item | |||
| 3438 | var Item = function PackeryItem() { | 3438 | var Item = function PackeryItem() { | |||
| 3439 | Outlayer.Item.apply( this, arguments ); | 3439 | Outlayer.Item.apply( this, arguments ); | |||
| 3440 | }; | 3440 | }; | |||
| 3441 | 3441 | |||||
| 3442 | Item.prototype = new Outlayer.Item(); | 3442 | Item.prototype = new Outlayer.Item(); | |||
| 3443 | 3443 | |||||
| 3444 | var protoCreate = Item.prototype._create; | 3444 | var protoCreate = Item.prototype._create; | |||
| 3445 | Item.prototype._create = function() { | 3445 | Item.prototype._create = function() { | |||
| 3446 | // call default _create logic | 3446 | // call default _create logic | |||
| 3447 | protoCreate.call( this ); | 3447 | protoCreate.call( this ); | |||
| 3448 | this.rect = new Rect(); | 3448 | this.rect = new Rect(); | |||
| 3449 | // rect used for placing, in drag or Packery.fit() | 3449 | // rect used for placing, in drag or Packery.fit() | |||
| 3450 | this.placeRect = new Rect(); | 3450 | this.placeRect = new Rect(); | |||
| 3451 | }; | 3451 | }; | |||
| 3452 | 3452 | |||||
| 3453 | // -------------------------- drag -------------------------- // | 3453 | // -------------------------- drag -------------------------- // | |||
| 3454 | 3454 | |||||
| 3455 | Item.prototype.dragStart = function() { | 3455 | Item.prototype.dragStart = function() { | |||
| 3456 | this.getPosition(); | 3456 | this.getPosition(); | |||
| 3457 | this.removeTransitionStyles(); | 3457 | this.removeTransitionStyles(); | |||
| 3458 | // remove transform property from transition | 3458 | // remove transform property from transition | |||
| 3459 | if ( this.isTransitioning && transformProperty ) { | 3459 | if ( this.isTransitioning && transformProperty ) { | |||
| 3460 | this.element.style[ transformProperty ] = 'none'; | 3460 | this.element.style[ transformProperty ] = 'none'; | |||
| 3461 | } | 3461 | } | |||
| 3462 | this.getSize(); | 3462 | this.getSize(); | |||
| 3463 | // create place rect, used for position when dragged then dropped | 3463 | // create place rect, used for position when dragged then dropped | |||
| 3464 | // or when positioning | 3464 | // or when positioning | |||
| 3465 | this.isPlacing = true; | 3465 | this.isPlacing = true; | |||
| 3466 | this.needsPositioning = false; | 3466 | this.needsPositioning = false; | |||
| 3467 | this.positionPlaceRect( this.position.x, this.position.y ); | 3467 | this.positionPlaceRect( this.position.x, this.position.y ); | |||
| 3468 | this.isTransitioning = false; | 3468 | this.isTransitioning = false; | |||
| 3469 | this.didDrag = false; | 3469 | this.didDrag = false; | |||
| 3470 | }; | 3470 | }; | |||
| 3471 | 3471 | |||||
| 3472 | /** | 3472 | /** | |||
| 3473 | * handle item when it is dragged | 3473 | * handle item when it is dragged | |||
| 3474 | * @param {Number} x - horizontal position of dragged item | 3474 | * @param {Number} x - horizontal position of dragged item | |||
| 3475 | * @param {Number} y - vertical position of dragged item | 3475 | * @param {Number} y - vertical position of dragged item | |||
| 3476 | */ | 3476 | */ | |||
| 3477 | Item.prototype.dragMove = function( x, y ) { | 3477 | Item.prototype.dragMove = function( x, y ) { | |||
| 3478 | this.didDrag = true; | 3478 | this.didDrag = true; | |||
| 3479 | var packerySize = this.layout.size; | 3479 | var packerySize = this.layout.size; | |||
| 3480 | x -= packerySize.paddingLeft; | 3480 | x -= packerySize.paddingLeft; | |||
| 3481 | y -= packerySize.paddingTop; | 3481 | y -= packerySize.paddingTop; | |||
| 3482 | this.positionPlaceRect( x, y ); | 3482 | this.positionPlaceRect( x, y ); | |||
| 3483 | }; | 3483 | }; | |||
| 3484 | 3484 | |||||
| 3485 | Item.prototype.dragStop = function() { | 3485 | Item.prototype.dragStop = function() { | |||
| 3486 | this.getPosition(); | 3486 | this.getPosition(); | |||
| 3487 | var isDiffX = this.position.x != this.placeRect.x; | 3487 | var isDiffX = this.position.x != this.placeRect.x; | |||
| 3488 | var isDiffY = this.position.y != this.placeRect.y; | 3488 | var isDiffY = this.position.y != this.placeRect.y; | |||
| 3489 | // set post-drag positioning flag | 3489 | // set post-drag positioning flag | |||
| 3490 | this.needsPositioning = isDiffX || isDiffY; | 3490 | this.needsPositioning = isDiffX || isDiffY; | |||
| 3491 | // reset flag | 3491 | // reset flag | |||
| 3492 | this.didDrag = false; | 3492 | this.didDrag = false; | |||
| 3493 | }; | 3493 | }; | |||
| 3494 | 3494 | |||||
| 3495 | // -------------------------- placing -------------------------- // | 3495 | // -------------------------- placing -------------------------- // | |||
| 3496 | 3496 | |||||
| 3497 | /** | 3497 | /** | |||
| 3498 | * position a rect that will occupy space in the packer | 3498 | * position a rect that will occupy space in the packer | |||
| 3499 | * @param {Number} x | 3499 | * @param {Number} x | |||
| 3500 | * @param {Number} y | 3500 | * @param {Number} y | |||
| 3501 | * @param {Boolean} isMaxYContained | 3501 | * @param {Boolean} isMaxYContained | |||
| 3502 | */ | 3502 | */ | |||
| 3503 | Item.prototype.positionPlaceRect = function( x, y, isMaxYOpen ) { | 3503 | Item.prototype.positionPlaceRect = function( x, y, isMaxYOpen ) { | |||
| 3504 | this.placeRect.x = this.getPlaceRectCoord( x, true ); | 3504 | this.placeRect.x = this.getPlaceRectCoord( x, true ); | |||
| 3505 | this.placeRect.y = this.getPlaceRectCoord( y, false, isMaxYOpen ); | 3505 | this.placeRect.y = this.getPlaceRectCoord( y, false, isMaxYOpen ); | |||
| 3506 | }; | 3506 | }; | |||
| 3507 | 3507 | |||||
| 3508 | /** | 3508 | /** | |||
| 3509 | * get x/y coordinate for place rect | 3509 | * get x/y coordinate for place rect | |||
| 3510 | * @param {Number} coord - x or y | 3510 | * @param {Number} coord - x or y | |||
| 3511 | * @param {Boolean} isX | 3511 | * @param {Boolean} isX | |||
| 3512 | * @param {Boolean} isMaxOpen - does not limit value to outer bound | 3512 | * @param {Boolean} isMaxOpen - does not limit value to outer bound | |||
| 3513 | * @returns {Number} coord - processed x or y | 3513 | * @returns {Number} coord - processed x or y | |||
| 3514 | */ | 3514 | */ | |||
| 3515 | Item.prototype.getPlaceRectCoord = function( coord, isX, isMaxOpen ) { | 3515 | Item.prototype.getPlaceRectCoord = function( coord, isX, isMaxOpen ) { | |||
| 3516 | var measure = isX ? 'Width' : 'Height'; | 3516 | var measure = isX ? 'Width' : 'Height'; | |||
| 3517 | var size = this.size[ 'outer' + measure ]; | 3517 | var size = this.size[ 'outer' + measure ]; | |||
| 3518 | var segment = this.layout[ isX ? 'columnWidth' : 'rowHeight' ]; | 3518 | var segment = this.layout[ isX ? 'columnWidth' : 'rowHeight' ]; | |||
| 3519 | var parentSize = this.layout.size[ 'inner' + measure ]; | 3519 | var parentSize = this.layout.size[ 'inner' + measure ]; | |||
| 3520 | 3520 | |||||
| 3521 | // additional parentSize calculations for Y | 3521 | // additional parentSize calculations for Y | |||
| 3522 | if ( !isX ) { | 3522 | if ( !isX ) { | |||
| 3523 | parentSize = Math.max( parentSize, this.layout.maxY ); | 3523 | parentSize = Math.max( parentSize, this.layout.maxY ); | |||
| 3524 | // prevent gutter from bumping up height when non-vertical grid | 3524 | // prevent gutter from bumping up height when non-vertical grid | |||
| 3525 | if ( !this.layout.rowHeight ) { | 3525 | if ( !this.layout.rowHeight ) { | |||
| 3526 | parentSize -= this.layout.gutter; | 3526 | parentSize -= this.layout.gutter; | |||
| 3527 | } | 3527 | } | |||
| 3528 | } | 3528 | } | |||
| 3529 | 3529 | |||||
| 3530 | var max; | 3530 | var max; | |||
| 3531 | 3531 | |||||
| 3532 | if ( segment ) { | 3532 | if ( segment ) { | |||
| 3533 | segment += this.layout.gutter; | 3533 | segment += this.layout.gutter; | |||
| 3534 | // allow for last column to reach the edge | 3534 | // allow for last column to reach the edge | |||
| 3535 | parentSize += isX ? this.layout.gutter : 0; | 3535 | parentSize += isX ? this.layout.gutter : 0; | |||
| 3536 | // snap to closest segment | 3536 | // snap to closest segment | |||
| 3537 | coord = Math.round( coord / segment ); | 3537 | coord = Math.round( coord / segment ); | |||
| 3538 | // contain to outer bound | 3538 | // contain to outer bound | |||
| 3539 | // contain non-growing bound, allow growing bound to grow | 3539 | // contain non-growing bound, allow growing bound to grow | |||
| 3540 | var mathMethod; | 3540 | var mathMethod; | |||
| 3541 | if ( this.layout.options.isHorizontal ) { | 3541 | if ( this.layout.options.isHorizontal ) { | |||
| 3542 | mathMethod = !isX ? 'floor' : 'ceil'; | 3542 | mathMethod = !isX ? 'floor' : 'ceil'; | |||
| 3543 | } else { | 3543 | } else { | |||
| 3544 | mathMethod = isX ? 'floor' : 'ceil'; | 3544 | mathMethod = isX ? 'floor' : 'ceil'; | |||
| 3545 | } | 3545 | } | |||
| 3546 | var maxSegments = Math[ mathMethod ]( parentSize / segment ); | 3546 | var maxSegments = Math[ mathMethod ]( parentSize / segment ); | |||
| 3547 | maxSegments -= Math.ceil( size / segment ); | 3547 | maxSegments -= Math.ceil( size / segment ); | |||
| 3548 | max = maxSegments; | 3548 | max = maxSegments; | |||
| 3549 | } else { | 3549 | } else { | |||
| 3550 | max = parentSize - size; | 3550 | max = parentSize - size; | |||
| 3551 | } | 3551 | } | |||
| 3552 | 3552 | |||||
| 3553 | coord = isMaxOpen ? coord : Math.min( coord, max ); | 3553 | coord = isMaxOpen ? coord : Math.min( coord, max ); | |||
| 3554 | coord *= segment || 1; | 3554 | coord *= segment || 1; | |||
| 3555 | 3555 | |||||
| 3556 | return Math.max( 0, coord ); | 3556 | return Math.max( 0, coord ); | |||
| 3557 | }; | 3557 | }; | |||
| 3558 | 3558 | |||||
| 3559 | Item.prototype.copyPlaceRectPosition = function() { | 3559 | Item.prototype.copyPlaceRectPosition = function() { | |||
| 3560 | this.rect.x = this.placeRect.x; | 3560 | this.rect.x = this.placeRect.x; | |||
| 3561 | this.rect.y = this.placeRect.y; | 3561 | this.rect.y = this.placeRect.y; | |||
| 3562 | }; | 3562 | }; | |||
| 3563 | 3563 | |||||
| 3564 | // ----- ----- // | 3564 | // ----- ----- // | |||
| 3565 | 3565 | |||||
| 3566 | // remove element from DOM | 3566 | // remove element from DOM | |||
| 3567 | Item.prototype.removeElem = function() { | 3567 | Item.prototype.removeElem = function() { | |||
| 3568 | this.element.parentNode.removeChild( this.element ); | 3568 | this.element.parentNode.removeChild( this.element ); | |||
| 3569 | // add space back to packer | 3569 | // add space back to packer | |||
| 3570 | this.layout.packer.addSpace( this.rect ); | 3570 | this.layout.packer.addSpace( this.rect ); | |||
| 3571 | this.emitEvent( 'remove', [ this ] ); | 3571 | this.emitEvent( 'remove', [ this ] ); | |||
| 3572 | }; | 3572 | }; | |||
| 3573 | 3573 | |||||
| 3574 | // ----- ----- // | 3574 | // ----- ----- // | |||
| 3575 | 3575 | |||||
| 3576 | return Item; | 3576 | return Item; | |||
| 3577 | 3577 | |||||
| 3578 | })); | 3578 | })); | |||
| 3579 | 3579 | |||||
| 3580 | /*! | 3580 | /*! | |||
| 3581 | * Packery v1.4.3 | 3581 | * Packery v1.4.3 | |||
| 3582 | * bin-packing layout library | 3582 | * bin-packing layout library | |||
| 3583 | * | 3583 | * | |||
| 3584 | * Licensed GPLv3 for open source use | 3584 | * Licensed GPLv3 for open source use | |||
| 3585 | * or Flickity Commercial License for commercial use | 3585 | * or Flickity Commercial License for commercial use | |||
| 3586 | * | 3586 | * | |||
| 3587 | * http://packery.metafizzy.co | 3587 | * http://packery.metafizzy.co | |||
| 3588 | * Copyright 2015 Metafizzy | 3588 | * Copyright 2015 Metafizzy | |||
| 3589 | */ | 3589 | */ | |||
| 3590 | 3590 | |||||
| 3591 | ( function( window, factory ) { | 3591 | ( function( window, factory ) { | |||
| 3592 | 3592 | |||||
| 3593 | // universal module definition | 3593 | // universal module definition | |||
| 3594 | if ( typeof define == 'function' && define.amd ) { | 3594 | if ( typeof define == 'function' && define.amd ) { | |||
| 3595 | // AMD | 3595 | // AMD | |||
| 3596 | define( [ | 3596 | define( [ | |||
| 3597 | 'classie/classie', | 3597 | 'classie/classie', | |||
| 3598 | 'get-size/get-size', | 3598 | 'get-size/get-size', | |||
| 3599 | 'outlayer/outlayer', | 3599 | 'outlayer/outlayer', | |||
| 3600 | 'packery/js/rect', | 3600 | 'packery/js/rect', | |||
| 3601 | 'packery/js/packer', | 3601 | 'packery/js/packer', | |||
| 3602 | 'packery/js/item' | 3602 | 'packery/js/item' | |||
| 3603 | ], | 3603 | ], | |||
| 3604 | factory ); | 3604 | factory ); | |||
| 3605 | } else if ( typeof exports == 'object' ) { | 3605 | } else if ( typeof exports == 'object' ) { | |||
| 3606 | // CommonJS | 3606 | // CommonJS | |||
| 3607 | module.exports = factory( | 3607 | module.exports = factory( | |||
| 3608 | require('desandro-classie'), | 3608 | require('desandro-classie'), | |||
| 3609 | require('get-size'), | 3609 | require('get-size'), | |||
| 3610 | require('outlayer'), | 3610 | require('outlayer'), | |||
| 3611 | require('./rect'), | 3611 | require('./rect'), | |||
| 3612 | require('./packer'), | 3612 | require('./packer'), | |||
| 3613 | require('./item') | 3613 | require('./item') | |||
| 3614 | ); | 3614 | ); | |||
| 3615 | } else { | 3615 | } else { | |||
| 3616 | // browser global | 3616 | // browser global | |||
| 3617 | window.Packery = factory( | 3617 | window.Packery = factory( | |||
| 3618 | window.classie, | 3618 | window.classie, | |||
| 3619 | window.getSize, | 3619 | window.getSize, | |||
| 3620 | window.Outlayer, | 3620 | window.Outlayer, | |||
| 3621 | window.Packery.Rect, | 3621 | window.Packery.Rect, | |||
| 3622 | window.Packery.Packer, | 3622 | window.Packery.Packer, | |||
| 3623 | window.Packery.Item | 3623 | window.Packery.Item | |||
| 3624 | ); | 3624 | ); | |||
| 3625 | } | 3625 | } | |||
| 3626 | 3626 | |||||
| 3627 | }( window, function factory( classie, getSize, Outlayer, Rect, Packer, Item ) { | 3627 | }( window, function factory( classie, getSize, Outlayer, Rect, Packer, Item ) { | |||
| 3628 | 3628 | |||||
| 3629 | 3629 | |||||
| 3630 | // ----- Rect ----- // | 3630 | // ----- Rect ----- // | |||
| 3631 | 3631 | |||||
| 3632 | // allow for pixel rounding errors IE8-IE11 & Firefox; #227 | 3632 | // allow for pixel rounding errors IE8-IE11 & Firefox; #227 | |||
| 3633 | Rect.prototype.canFit = function( rect ) { | 3633 | Rect.prototype.canFit = function( rect ) { | |||
| 3634 | return this.width >= rect.width - 1 && this.height >= rect.height - 1; | 3634 | return this.width >= rect.width - 1 && this.height >= rect.height - 1; | |||
| 3635 | }; | 3635 | }; | |||
| 3636 | 3636 | |||||
| 3637 | // -------------------------- Packery -------------------------- // | 3637 | // -------------------------- Packery -------------------------- // | |||
| 3638 | 3638 | |||||
| 3639 | // create an Outlayer layout class | 3639 | // create an Outlayer layout class | |||
| 3640 | var Packery = Outlayer.create('packery'); | 3640 | var Packery = Outlayer.create('packery'); | |||
| 3641 | Packery.Item = Item; | 3641 | Packery.Item = Item; | |||
| 3642 | 3642 | |||||
| 3643 | Packery.prototype._create = function() { | 3643 | Packery.prototype._create = function() { | |||
| 3644 | // call super | 3644 | // call super | |||
| 3645 | Outlayer.prototype._create.call( this ); | 3645 | Outlayer.prototype._create.call( this ); | |||
| 3646 | 3646 | |||||
| 3647 | // initial properties | 3647 | // initial properties | |||
| 3648 | this.packer = new Packer(); | 3648 | this.packer = new Packer(); | |||
| 3649 | 3649 | |||||
| 3650 | // Left over from v1.0 | 3650 | // Left over from v1.0 | |||
| 3651 | this.stamp( this.options.stamped ); | 3651 | this.stamp( this.options.stamped ); | |||
| 3652 | 3652 | |||||
| 3653 | // create drag handlers | 3653 | // create drag handlers | |||
| 3654 | var _this = this; | 3654 | var _this = this; | |||
| 3655 | this.handleDraggabilly = { | 3655 | this.handleDraggabilly = { | |||
| 3656 | dragStart: function() { | 3656 | dragStart: function() { | |||
| 3657 | _this.itemDragStart( this.element ); | 3657 | _this.itemDragStart( this.element ); | |||
| 3658 | }, | 3658 | }, | |||
| 3659 | dragMove: function() { | 3659 | dragMove: function() { | |||
| 3660 | _this.itemDragMove( this.element, this.position.x, this.position.y ); | 3660 | _this.itemDragMove( this.element, this.position.x, this.position.y ); | |||
| 3661 | }, | 3661 | }, | |||
| 3662 | dragEnd: function() { | 3662 | dragEnd: function() { | |||
| 3663 | _this.itemDragEnd( this.element ); | 3663 | _this.itemDragEnd( this.element ); | |||
| 3664 | } | 3664 | } | |||
| 3665 | }; | 3665 | }; | |||
| 3666 | 3666 | |||||
| 3667 | this.handleUIDraggable = { | 3667 | this.handleUIDraggable = { | |||
| 3668 | start: function handleUIDraggableStart( event, ui ) { | 3668 | start: function handleUIDraggableStart( event, ui ) { | |||
| 3669 | // HTML5 may trigger dragstart, dismiss HTML5 dragging | 3669 | // HTML5 may trigger dragstart, dismiss HTML5 dragging | |||
| 3670 | if ( !ui ) { | 3670 | if ( !ui ) { | |||
| 3671 | return; | 3671 | return; | |||
| 3672 | } | 3672 | } | |||
| 3673 | _this.itemDragStart( event.currentTarget ); | 3673 | _this.itemDragStart( event.currentTarget ); | |||
| 3674 | }, | 3674 | }, | |||
| 3675 | drag: function handleUIDraggableDrag( event, ui ) { | 3675 | drag: function handleUIDraggableDrag( event, ui ) { | |||
| 3676 | if ( !ui ) { | 3676 | if ( !ui ) { | |||
| 3677 | return; | 3677 | return; | |||
| 3678 | } | 3678 | } | |||
| 3679 | _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); | 3679 | _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); | |||
| 3680 | }, | 3680 | }, | |||
| 3681 | stop: function handleUIDraggableStop( event, ui ) { | 3681 | stop: function handleUIDraggableStop( event, ui ) { | |||
| 3682 | if ( !ui ) { | 3682 | if ( !ui ) { | |||
| 3683 | return; | 3683 | return; | |||
| 3684 | } | 3684 | } | |||
| 3685 | _this.itemDragEnd( event.currentTarget ); | 3685 | _this.itemDragEnd( event.currentTarget ); | |||
| 3686 | } | 3686 | } | |||
| 3687 | }; | 3687 | }; | |||
| 3688 | 3688 | |||||
| 3689 | }; | 3689 | }; | |||
| 3690 | 3690 | |||||
| 3691 | 3691 | |||||
| 3692 | // ----- init & layout ----- // | 3692 | // ----- init & layout ----- // | |||
| 3693 | 3693 | |||||
| 3694 | /** | 3694 | /** | |||
| 3695 | * logic before any new layout | 3695 | * logic before any new layout | |||
| 3696 | */ | 3696 | */ | |||
| 3697 | Packery.prototype._resetLayout = function() { | 3697 | Packery.prototype._resetLayout = function() { | |||
| 3698 | this.getSize(); | 3698 | this.getSize(); | |||
| 3699 | 3699 | |||||
| 3700 | this._getMeasurements(); | 3700 | this._getMeasurements(); | |||
| 3701 | 3701 | |||||
| 3702 | // reset packer | 3702 | // reset packer | |||
| 3703 | var packer = this.packer; | 3703 | var packer = this.packer; | |||
| 3704 | // packer settings, if horizontal or vertical | 3704 | // packer settings, if horizontal or vertical | |||
| 3705 | if ( this.options.isHorizontal ) { | 3705 | if ( this.options.isHorizontal ) { | |||
| 3706 | packer.width = Number.POSITIVE_INFINITY; | 3706 | packer.width = Number.POSITIVE_INFINITY; | |||
| 3707 | packer.height = this.size.innerHeight + this.gutter; | 3707 | packer.height = this.size.innerHeight + this.gutter; | |||
| 3708 | packer.sortDirection = 'rightwardTopToBottom'; | 3708 | packer.sortDirection = 'rightwardTopToBottom'; | |||
| 3709 | } else { | 3709 | } else { | |||
| 3710 | packer.width = this.size.innerWidth + this.gutter; | 3710 | packer.width = this.size.innerWidth + this.gutter; | |||
| 3711 | packer.height = Number.POSITIVE_INFINITY; | 3711 | packer.height = Number.POSITIVE_INFINITY; | |||
| 3712 | packer.sortDirection = 'downwardLeftToRight'; | 3712 | packer.sortDirection = 'downwardLeftToRight'; | |||
| 3713 | } | 3713 | } | |||
| 3714 | 3714 | |||||
| 3715 | packer.reset(); | 3715 | packer.reset(); | |||
| 3716 | 3716 | |||||
| 3717 | // layout | 3717 | // layout | |||
| 3718 | this.maxY = 0; | 3718 | this.maxY = 0; | |||
| 3719 | this.maxX = 0; | 3719 | this.maxX = 0; | |||
| 3720 | }; | 3720 | }; | |||
| 3721 | 3721 | |||||
| 3722 | /** | 3722 | /** | |||
| 3723 | * update columnWidth, rowHeight, & gutter | 3723 | * update columnWidth, rowHeight, & gutter | |||
| 3724 | * @private | 3724 | * @private | |||
| 3725 | */ | 3725 | */ | |||
| 3726 | Packery.prototype._getMeasurements = function() { | 3726 | Packery.prototype._getMeasurements = function() { | |||
| 3727 | this._getMeasurement( 'columnWidth', 'width' ); | 3727 | this._getMeasurement( 'columnWidth', 'width' ); | |||
| 3728 | this._getMeasurement( 'rowHeight', 'height' ); | 3728 | this._getMeasurement( 'rowHeight', 'height' ); | |||
| 3729 | this._getMeasurement( 'gutter', 'width' ); | 3729 | this._getMeasurement( 'gutter', 'width' ); | |||
| 3730 | }; | 3730 | }; | |||
| 3731 | 3731 | |||||
| 3732 | Packery.prototype._getItemLayoutPosition = function( item ) { | 3732 | Packery.prototype._getItemLayoutPosition = function( item ) { | |||
| 3733 | this._packItem( item ); | 3733 | this._packItem( item ); | |||
| 3734 | return item.rect; | 3734 | return item.rect; | |||
| 3735 | }; | 3735 | }; | |||
| 3736 | 3736 | |||||
| 3737 | 3737 | |||||
| 3738 | /** | 3738 | /** | |||
| 3739 | * layout item in packer | 3739 | * layout item in packer | |||
| 3740 | * @param {Packery.Item} item | 3740 | * @param {Packery.Item} item | |||
| 3741 | */ | 3741 | */ | |||
| 3742 | Packery.prototype._packItem = function( item ) { | 3742 | Packery.prototype._packItem = function( item ) { | |||
| 3743 | this._setRectSize( item.element, item.rect ); | 3743 | this._setRectSize( item.element, item.rect ); | |||
| 3744 | // pack the rect in the packer | 3744 | // pack the rect in the packer | |||
| 3745 | this.packer.pack( item.rect ); | 3745 | this.packer.pack( item.rect ); | |||
| 3746 | this._setMaxXY( item.rect ); | 3746 | this._setMaxXY( item.rect ); | |||
| 3747 | }; | 3747 | }; | |||
| 3748 | 3748 | |||||
| 3749 | /** | 3749 | /** | |||
| 3750 | * set max X and Y value, for size of container | 3750 | * set max X and Y value, for size of container | |||
| 3751 | * @param {Packery.Rect} rect | 3751 | * @param {Packery.Rect} rect | |||
| 3752 | * @private | 3752 | * @private | |||
| 3753 | */ | 3753 | */ | |||
| 3754 | Packery.prototype._setMaxXY = function( rect ) { | 3754 | Packery.prototype._setMaxXY = function( rect ) { | |||
| 3755 | this.maxX = Math.max( rect.x + rect.width, this.maxX ); | 3755 | this.maxX = Math.max( rect.x + rect.width, this.maxX ); | |||
| 3756 | this.maxY = Math.max( rect.y + rect.height, this.maxY ); | 3756 | this.maxY = Math.max( rect.y + rect.height, this.maxY ); | |||
| 3757 | }; | 3757 | }; | |||
| 3758 | 3758 | |||||
| 3759 | /** | 3759 | /** | |||
| 3760 | * set the width and height of a rect, applying columnWidth and rowHeight | 3760 | * set the width and height of a rect, applying columnWidth and rowHeight | |||
| 3761 | * @param {Element} elem | 3761 | * @param {Element} elem | |||
| 3762 | * @param {Packery.Rect} rect | 3762 | * @param {Packery.Rect} rect | |||
| 3763 | */ | 3763 | */ | |||
| 3764 | Packery.prototype._setRectSize = function( elem, rect ) { | 3764 | Packery.prototype._setRectSize = function( elem, rect ) { | |||
| 3765 | var size = getSize( elem ); | 3765 | var size = getSize( elem ); | |||
| 3766 | var w = size.outerWidth; | 3766 | var w = size.outerWidth; | |||
| 3767 | var h = size.outerHeight; | 3767 | var h = size.outerHeight; | |||
| 3768 | // size for columnWidth and rowHeight, if available | 3768 | // size for columnWidth and rowHeight, if available | |||
| 3769 | // only check if size is non-zero, #177 | 3769 | // only check if size is non-zero, #177 | |||
| 3770 | if ( w || h ) { | 3770 | if ( w || h ) { | |||
| 3771 | w = this._applyGridGutter( w, this.columnWidth ); | 3771 | w = this._applyGridGutter( w, this.columnWidth ); | |||
| 3772 | h = this._applyGridGutter( h, this.rowHeight ); | 3772 | h = this._applyGridGutter( h, this.rowHeight ); | |||
| 3773 | } | 3773 | } | |||
| 3774 | // rect must fit in packer | 3774 | // rect must fit in packer | |||
| 3775 | rect.width = Math.min( w, this.packer.width ); | 3775 | rect.width = Math.min( w, this.packer.width ); | |||
| 3776 | rect.height = Math.min( h, this.packer.height ); | 3776 | rect.height = Math.min( h, this.packer.height ); | |||
| 3777 | }; | 3777 | }; | |||
| 3778 | 3778 | |||||
| 3779 | /** | 3779 | /** | |||
| 3780 | * fits item to columnWidth/rowHeight and adds gutter | 3780 | * fits item to columnWidth/rowHeight and adds gutter | |||
| 3781 | * @param {Number} measurement - item width or height | 3781 | * @param {Number} measurement - item width or height | |||
| 3782 | * @param {Number} gridSize - columnWidth or rowHeight | 3782 | * @param {Number} gridSize - columnWidth or rowHeight | |||
| 3783 | * @returns measurement | 3783 | * @returns measurement | |||
| 3784 | */ | 3784 | */ | |||
| 3785 | Packery.prototype._applyGridGutter = function( measurement, gridSize ) { | 3785 | Packery.prototype._applyGridGutter = function( measurement, gridSize ) { | |||
| 3786 | // just add gutter if no gridSize | 3786 | // just add gutter if no gridSize | |||
| 3787 | if ( !gridSize ) { | 3787 | if ( !gridSize ) { | |||
| 3788 | return measurement + this.gutter; | 3788 | return measurement + this.gutter; | |||
| 3789 | } | 3789 | } | |||
| 3790 | gridSize += this.gutter; | 3790 | gridSize += this.gutter; | |||
| 3791 | // fit item to columnWidth/rowHeight | 3791 | // fit item to columnWidth/rowHeight | |||
| 3792 | var remainder = measurement % gridSize; | 3792 | var remainder = measurement % gridSize; | |||
| 3793 | var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; | 3793 | var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; | |||
| 3794 | measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; | 3794 | measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; | |||
| 3795 | return measurement; | 3795 | return measurement; | |||
| 3796 | }; | 3796 | }; | |||
| 3797 | 3797 | |||||
| 3798 | Packery.prototype._getContainerSize = function() { | 3798 | Packery.prototype._getContainerSize = function() { | |||
| 3799 | if ( this.options.isHorizontal ) { | 3799 | if ( this.options.isHorizontal ) { | |||
| 3800 | return { | 3800 | return { | |||
| 3801 | width: this.maxX - this.gutter | 3801 | width: this.maxX - this.gutter | |||
| 3802 | }; | 3802 | }; | |||
| 3803 | } else { | 3803 | } else { | |||
| 3804 | return { | 3804 | return { | |||
| 3805 | height: this.maxY - this.gutter | 3805 | height: this.maxY - this.gutter | |||
| 3806 | }; | 3806 | }; | |||
| 3807 | } | 3807 | } | |||
| 3808 | }; | 3808 | }; | |||
| 3809 | 3809 | |||||
| 3810 | 3810 | |||||
| 3811 | // -------------------------- stamp -------------------------- // | 3811 | // -------------------------- stamp -------------------------- // | |||
| 3812 | 3812 | |||||
| 3813 | /** | 3813 | /** | |||
| 3814 | * makes space for element | 3814 | * makes space for element | |||
| 3815 | * @param {Element} elem | 3815 | * @param {Element} elem | |||
| 3816 | */ | 3816 | */ | |||
| 3817 | Packery.prototype._manageStamp = function( elem ) { | 3817 | Packery.prototype._manageStamp = function( elem ) { | |||
| 3818 | 3818 | |||||
| 3819 | var item = this.getItem( elem ); | 3819 | var item = this.getItem( elem ); | |||
| 3820 | var rect; | 3820 | var rect; | |||
| 3821 | if ( item && item.isPlacing ) { | 3821 | if ( item && item.isPlacing ) { | |||
| 3822 | rect = item.placeRect; | 3822 | rect = item.placeRect; | |||
| 3823 | } else { | 3823 | } else { | |||
| 3824 | var offset = this._getElementOffset( elem ); | 3824 | var offset = this._getElementOffset( elem ); | |||
| 3825 | rect = new Rect({ | 3825 | rect = new Rect({ | |||
| 3826 | x: this.options.isOriginLeft ? offset.left : offset.right, | 3826 | x: this.options.isOriginLeft ? offset.left : offset.right, | |||
| 3827 | y: this.options.isOriginTop ? offset.top : offset.bottom | 3827 | y: this.options.isOriginTop ? offset.top : offset.bottom | |||
| 3828 | }); | 3828 | }); | |||
| 3829 | } | 3829 | } | |||
| 3830 | 3830 | |||||
| 3831 | this._setRectSize( elem, rect ); | 3831 | this._setRectSize( elem, rect ); | |||
| 3832 | // save its space in the packer | 3832 | // save its space in the packer | |||
| 3833 | this.packer.placed( rect ); | 3833 | this.packer.placed( rect ); | |||
| 3834 | this._setMaxXY( rect ); | 3834 | this._setMaxXY( rect ); | |||
| 3835 | }; | 3835 | }; | |||
| 3836 | 3836 | |||||
| 3837 | // -------------------------- methods -------------------------- // | 3837 | // -------------------------- methods -------------------------- // | |||
| 3838 | 3838 | |||||
| 3839 | function verticalSorter( a, b ) { | 3839 | function verticalSorter( a, b ) { | |||
| 3840 | return a.position.y - b.position.y || a.position.x - b.position.x; | 3840 | return a.position.y - b.position.y || a.position.x - b.position.x; | |||
| 3841 | } | 3841 | } | |||
| 3842 | 3842 | |||||
| 3843 | function horizontalSorter( a, b ) { | 3843 | function horizontalSorter( a, b ) { | |||
| 3844 | return a.position.x - b.position.x || a.position.y - b.position.y; | 3844 | return a.position.x - b.position.x || a.position.y - b.position.y; | |||
| 3845 | } | 3845 | } | |||
| 3846 | 3846 | |||||
| 3847 | Packery.prototype.sortItemsByPosition = function() { | 3847 | Packery.prototype.sortItemsByPosition = function() { | |||
| 3848 | var sorter = this.options.isHorizontal ? horizontalSorter : verticalSorter; | 3848 | var sorter = this.options.isHorizontal ? horizontalSorter : verticalSorter; | |||
| 3849 | this.items.sort( sorter ); | 3849 | this.items.sort( sorter ); | |||
| 3850 | }; | 3850 | }; | |||
| 3851 | 3851 | |||||
| 3852 | /** | 3852 | /** | |||
| 3853 | * Fit item element in its current position | 3853 | * Fit item element in its current position | |||
| 3854 | * Packery will position elements around it | 3854 | * Packery will position elements around it | |||
| 3855 | * useful for expanding elements | 3855 | * useful for expanding elements | |||
| 3856 | * | 3856 | * | |||
| 3857 | * @param {Element} elem | 3857 | * @param {Element} elem | |||
| 3858 | * @param {Number} x - horizontal destination position, optional | 3858 | * @param {Number} x - horizontal destination position, optional | |||
| 3859 | * @param {Number} y - vertical destination position, optional | 3859 | * @param {Number} y - vertical destination position, optional | |||
| 3860 | */ | 3860 | */ | |||
| 3861 | Packery.prototype.fit = function( elem, x, y ) { | 3861 | Packery.prototype.fit = function( elem, x, y ) { | |||
| 3862 | var item = this.getItem( elem ); | 3862 | var item = this.getItem( elem ); | |||
| 3863 | if ( !item ) { | 3863 | if ( !item ) { | |||
| 3864 | return; | 3864 | return; | |||
| 3865 | } | 3865 | } | |||
| 3866 | 3866 | |||||
| 3867 | // prepare internal properties | 3867 | // prepare internal properties | |||
| 3868 | this._getMeasurements(); | 3868 | this._getMeasurements(); | |||
| 3869 | 3869 | |||||
| 3870 | // stamp item to get it out of layout | 3870 | // stamp item to get it out of layout | |||
| 3871 | this.stamp( item.element ); | 3871 | this.stamp( item.element ); | |||
| 3872 | // required for positionPlaceRect | 3872 | // required for positionPlaceRect | |||
| 3873 | item.getSize(); | 3873 | item.getSize(); | |||
| 3874 | // set placing flag | 3874 | // set placing flag | |||
| 3875 | item.isPlacing = true; | 3875 | item.isPlacing = true; | |||
| 3876 | // fall back to current position for fitting | 3876 | // fall back to current position for fitting | |||
| 3877 | x = x === undefined ? item.rect.x: x; | 3877 | x = x === undefined ? item.rect.x: x; | |||
| 3878 | y = y === undefined ? item.rect.y: y; | 3878 | y = y === undefined ? item.rect.y: y; | |||
| 3879 | 3879 | |||||
| 3880 | // position it best at its destination | 3880 | // position it best at its destination | |||
| 3881 | item.positionPlaceRect( x, y, true ); | 3881 | item.positionPlaceRect( x, y, true ); | |||
| 3882 | 3882 | |||||
| 3883 | this._bindFitEvents( item ); | 3883 | this._bindFitEvents( item ); | |||
| 3884 | item.moveTo( item.placeRect.x, item.placeRect.y ); | 3884 | item.moveTo( item.placeRect.x, item.placeRect.y ); | |||
| 3885 | // layout everything else | 3885 | // layout everything else | |||
| 3886 | this.layout(); | 3886 | this.layout(); | |||
| 3887 | 3887 | |||||
| 3888 | // return back to regularly scheduled programming | 3888 | // return back to regularly scheduled programming | |||
| 3889 | this.unstamp( item.element ); | 3889 | this.unstamp( item.element ); | |||
| 3890 | this.sortItemsByPosition(); | 3890 | this.sortItemsByPosition(); | |||
| 3891 | // un set placing flag, back to normal | 3891 | // un set placing flag, back to normal | |||
| 3892 | item.isPlacing = false; | 3892 | item.isPlacing = false; | |||
| 3893 | // copy place rect position | 3893 | // copy place rect position | |||
| 3894 | item.copyPlaceRectPosition(); | 3894 | item.copyPlaceRectPosition(); | |||
| 3895 | }; | 3895 | }; | |||
| 3896 | 3896 | |||||
| 3897 | /** | 3897 | /** | |||
| 3898 | * emit event when item is fit and other items are laid out | 3898 | * emit event when item is fit and other items are laid out | |||
| 3899 | * @param {Packery.Item} item | 3899 | * @param {Packery.Item} item | |||
| 3900 | * @private | 3900 | * @private | |||
| 3901 | */ | 3901 | */ | |||
| 3902 | Packery.prototype._bindFitEvents = function( item ) { | 3902 | Packery.prototype._bindFitEvents = function( item ) { | |||
| 3903 | var _this = this; | 3903 | var _this = this; | |||
| 3904 | var ticks = 0; | 3904 | var ticks = 0; | |||
| 3905 | function tick() { | 3905 | function tick() { | |||
| 3906 | ticks++; | 3906 | ticks++; | |||
| 3907 | if ( ticks != 2 ) { | 3907 | if ( ticks != 2 ) { | |||
| 3908 | return; | 3908 | return; | |||
| 3909 | } | 3909 | } | |||
| 3910 | _this.dispatchEvent( 'fitComplete', null, [ item ] ); | 3910 | _this.dispatchEvent( 'fitComplete', null, [ item ] ); | |||
| 3911 | } | 3911 | } | |||
| 3912 | // when item is laid out | 3912 | // when item is laid out | |||
| 3913 | item.on( 'layout', function() { | 3913 | item.on( 'layout', function() { | |||
| 3914 | tick(); | 3914 | tick(); | |||
| 3915 | return true; | 3915 | return true; | |||
| 3916 | }); | 3916 | }); | |||
| 3917 | // when all items are laid out | 3917 | // when all items are laid out | |||
| 3918 | this.on( 'layoutComplete', function() { | 3918 | this.on( 'layoutComplete', function() { | |||
| 3919 | tick(); | 3919 | tick(); | |||
| 3920 | return true; | 3920 | return true; | |||
| 3921 | }); | 3921 | }); | |||
| 3922 | }; | 3922 | }; | |||
| 3923 | 3923 | |||||
| 3924 | // -------------------------- resize -------------------------- // | 3924 | // -------------------------- resize -------------------------- // | |||
| 3925 | 3925 | |||||
| 3926 | // debounced, layout on resize | 3926 | // debounced, layout on resize | |||
| 3927 | Packery.prototype.resize = function() { | 3927 | Packery.prototype.resize = function() { | |||
| 3928 | // don't trigger if size did not change | 3928 | // don't trigger if size did not change | |||
| 3929 | var size = getSize( this.element ); | 3929 | var size = getSize( this.element ); | |||
| 3930 | // check that this.size and size are there | 3930 | // check that this.size and size are there | |||
| 3931 | // IE8 triggers resize on body size change, so they might not be | 3931 | // IE8 triggers resize on body size change, so they might not be | |||
| 3932 | var hasSizes = this.size && size; | 3932 | var hasSizes = this.size && size; | |||
| 3933 | var innerSize = this.options.isHorizontal ? 'innerHeight' : 'innerWidth'; | 3933 | var innerSize = this.options.isHorizontal ? 'innerHeight' : 'innerWidth'; | |||
| 3934 | if ( hasSizes && size[ innerSize ] == this.size[ innerSize ] ) { | 3934 | if ( hasSizes && size[ innerSize ] == this.size[ innerSize ] ) { | |||
| 3935 | return; | 3935 | return; | |||
| 3936 | } | 3936 | } | |||
| 3937 | 3937 | |||||
| 3938 | this.layout(); | 3938 | this.layout(); | |||
| 3939 | }; | 3939 | }; | |||
| 3940 | 3940 | |||||
| 3941 | // -------------------------- drag -------------------------- // | 3941 | // -------------------------- drag -------------------------- // | |||
| 3942 | 3942 | |||||
| 3943 | /** | 3943 | /** | |||
| 3944 | * handle an item drag start event | 3944 | * handle an item drag start event | |||
| 3945 | * @param {Element} elem | 3945 | * @param {Element} elem | |||
| 3946 | */ | 3946 | */ | |||
| 3947 | Packery.prototype.itemDragStart = function( elem ) { | 3947 | Packery.prototype.itemDragStart = function( elem ) { | |||
| 3948 | this.stamp( elem ); | 3948 | this.stamp( elem ); | |||
| 3949 | var item = this.getItem( elem ); | 3949 | var item = this.getItem( elem ); | |||
| 3950 | if ( item ) { | 3950 | if ( item ) { | |||
| 3951 | item.dragStart(); | 3951 | item.dragStart(); | |||
| 3952 | } | 3952 | } | |||
| 3953 | }; | 3953 | }; | |||
| 3954 | 3954 | |||||
| 3955 | /** | 3955 | /** | |||
| 3956 | * handle an item drag move event | 3956 | * handle an item drag move event | |||
| 3957 | * @param {Element} elem | 3957 | * @param {Element} elem | |||
| 3958 | * @param {Number} x - horizontal change in position | 3958 | * @param {Number} x - horizontal change in position | |||
| 3959 | * @param {Number} y - vertical change in position | 3959 | * @param {Number} y - vertical change in position | |||
| 3960 | */ | 3960 | */ | |||
| 3961 | Packery.prototype.itemDragMove = function( elem, x, y ) { | 3961 | Packery.prototype.itemDragMove = function( elem, x, y ) { | |||
| 3962 | var item = this.getItem( elem ); | 3962 | var item = this.getItem( elem ); | |||
| 3963 | if ( item ) { | 3963 | if ( item ) { | |||
| 3964 | item.dragMove( x, y ); | 3964 | item.dragMove( x, y ); | |||
| 3965 | } | 3965 | } | |||
| 3966 | 3966 | |||||
| 3967 | // debounce | 3967 | // debounce | |||
| 3968 | var _this = this; | 3968 | var _this = this; | |||
| 3969 | // debounce triggering layout | 3969 | // debounce triggering layout | |||
| 3970 | function delayed() { | 3970 | function delayed() { | |||
| 3971 | _this.layout(); | 3971 | _this.layout(); | |||
| 3972 | delete _this.dragTimeout; | 3972 | delete _this.dragTimeout; | |||
| 3973 | } | 3973 | } | |||
| 3974 | 3974 | |||||
| 3975 | this.clearDragTimeout(); | 3975 | this.clearDragTimeout(); | |||
| 3976 | 3976 | |||||
| 3977 | this.dragTimeout = setTimeout( delayed, 40 ); | 3977 | this.dragTimeout = setTimeout( delayed, 40 ); | |||
| 3978 | }; | 3978 | }; | |||
| 3979 | 3979 | |||||
| 3980 | Packery.prototype.clearDragTimeout = function() { | 3980 | Packery.prototype.clearDragTimeout = function() { | |||
| 3981 | if ( this.dragTimeout ) { | 3981 | if ( this.dragTimeout ) { | |||
| 3982 | clearTimeout( this.dragTimeout ); | 3982 | clearTimeout( this.dragTimeout ); | |||
| 3983 | } | 3983 | } | |||
| 3984 | }; | 3984 | }; | |||
| 3985 | 3985 | |||||
| 3986 | /** | 3986 | /** | |||
| 3987 | * handle an item drag end event | 3987 | * handle an item drag end event | |||
| 3988 | * @param {Element} elem | 3988 | * @param {Element} elem | |||
| 3989 | */ | 3989 | */ | |||
| 3990 | Packery.prototype.itemDragEnd = function( elem ) { | 3990 | Packery.prototype.itemDragEnd = function( elem ) { | |||
| 3991 | var item = this.getItem( elem ); | 3991 | var item = this.getItem( elem ); | |||
| 3992 | var itemDidDrag; | 3992 | var itemDidDrag; | |||
| 3993 | if ( item ) { | 3993 | if ( item ) { | |||
| 3994 | itemDidDrag = item.didDrag; | 3994 | itemDidDrag = item.didDrag; | |||
| 3995 | item.dragStop(); | 3995 | item.dragStop(); | |||
| 3996 | } | 3996 | } | |||
| 3997 | // if elem didn't move, or if it doesn't need positioning | 3997 | // if elem didn't move, or if it doesn't need positioning | |||
| 3998 | // unignore and unstamp and call it a day | 3998 | // unignore and unstamp and call it a day | |||
| 3999 | if ( !item || ( !itemDidDrag && !item.needsPositioning ) ) { | 3999 | if ( !item || ( !itemDidDrag && !item.needsPositioning ) ) { | |||
| 4000 | this.unstamp( elem ); | 4000 | this.unstamp( elem ); | |||
| 4001 | return; | 4001 | return; | |||
| 4002 | } | 4002 | } | |||
| 4003 | // procced with dragged item | 4003 | // procced with dragged item | |||
| 4004 | 4004 | |||||
| 4005 | classie.add( item.element, 'is-positioning-post-drag' ); | 4005 | classie.add( item.element, 'is-positioning-post-drag' ); | |||
| 4006 | 4006 | |||||
| 4007 | // save this var, as it could get reset in dragStart | 4007 | // save this var, as it could get reset in dragStart | |||
| 4008 | var onLayoutComplete = this._getDragEndLayoutComplete( elem, item ); | 4008 | var onLayoutComplete = this._getDragEndLayoutComplete( elem, item ); | |||
| 4009 | 4009 | |||||
| 4010 | if ( item.needsPositioning ) { | 4010 | if ( item.needsPositioning ) { | |||
| 4011 | item.on( 'layout', onLayoutComplete ); | 4011 | item.on( 'layout', onLayoutComplete ); | |||
| 4012 | item.moveTo( item.placeRect.x, item.placeRect.y ); | 4012 | item.moveTo( item.placeRect.x, item.placeRect.y ); | |||
| 4013 | } else if ( item ) { | 4013 | } else if ( item ) { | |||
| 4014 | // item didn't need placement | 4014 | // item didn't need placement | |||
| 4015 | item.copyPlaceRectPosition(); | 4015 | item.copyPlaceRectPosition(); | |||
| 4016 | } | 4016 | } | |||
| 4017 | 4017 | |||||
| 4018 | this.clearDragTimeout(); | 4018 | this.clearDragTimeout(); | |||
| 4019 | this.on( 'layoutComplete', onLayoutComplete ); | 4019 | this.on( 'layoutComplete', onLayoutComplete ); | |||
| 4020 | this.layout(); | 4020 | this.layout(); | |||
| 4021 | 4021 | |||||
| 4022 | }; | 4022 | }; | |||
| 4023 | 4023 | |||||
| 4024 | /** | 4024 | /** | |||
| 4025 | * get drag end callback | 4025 | * get drag end callback | |||
| 4026 | * @param {Element} elem | 4026 | * @param {Element} elem | |||
| 4027 | * @param {Packery.Item} item | 4027 | * @param {Packery.Item} item | |||
| 4028 | * @returns {Function} onLayoutComplete | 4028 | * @returns {Function} onLayoutComplete | |||
| 4029 | */ | 4029 | */ | |||
| 4030 | Packery.prototype._getDragEndLayoutComplete = function( elem, item ) { | 4030 | Packery.prototype._getDragEndLayoutComplete = function( elem, item ) { | |||
| 4031 | var itemNeedsPositioning = item && item.needsPositioning; | 4031 | var itemNeedsPositioning = item && item.needsPositioning; | |||
| 4032 | var completeCount = 0; | 4032 | var completeCount = 0; | |||
| 4033 | var asyncCount = itemNeedsPositioning ? 2 : 1; | 4033 | var asyncCount = itemNeedsPositioning ? 2 : 1; | |||
| 4034 | var _this = this; | 4034 | var _this = this; | |||
| 4035 | 4035 | |||||
| 4036 | return function onLayoutComplete() { | 4036 | return function onLayoutComplete() { | |||
| 4037 | completeCount++; | 4037 | completeCount++; | |||
| 4038 | // don't proceed if not complete | 4038 | // don't proceed if not complete | |||
| 4039 | if ( completeCount != asyncCount ) { | 4039 | if ( completeCount != asyncCount ) { | |||
| 4040 | return true; | 4040 | return true; | |||
| 4041 | } | 4041 | } | |||
| 4042 | // reset item | 4042 | // reset item | |||
| 4043 | if ( item ) { | 4043 | if ( item ) { | |||
| 4044 | classie.remove( item.element, 'is-positioning-post-drag' ); | 4044 | classie.remove( item.element, 'is-positioning-post-drag' ); | |||
| 4045 | item.isPlacing = false; | 4045 | item.isPlacing = false; | |||
| 4046 | item.copyPlaceRectPosition(); | 4046 | item.copyPlaceRectPosition(); | |||
| 4047 | } | 4047 | } | |||
| 4048 | 4048 | |||||
| 4049 | _this.unstamp( elem ); | 4049 | _this.unstamp( elem ); | |||
| 4050 | // only sort when item moved | 4050 | // only sort when item moved | |||
| 4051 | _this.sortItemsByPosition(); | 4051 | _this.sortItemsByPosition(); | |||
| 4052 | 4052 | |||||
| 4053 | // emit item drag event now that everything is done | 4053 | // emit item drag event now that everything is done | |||
| 4054 | if ( itemNeedsPositioning ) { | 4054 | if ( itemNeedsPositioning ) { | |||
| 4055 | _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); | 4055 | _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); | |||
| 4056 | } | 4056 | } | |||
| 4057 | // listen once | 4057 | // listen once | |||
| 4058 | return true; | 4058 | return true; | |||
| 4059 | }; | 4059 | }; | |||
| 4060 | }; | 4060 | }; | |||
| 4061 | 4061 | |||||
| 4062 | /** | 4062 | /** | |||
| 4063 | * binds Draggabilly events | 4063 | * binds Draggabilly events | |||
| 4064 | * @param {Draggabilly} draggie | 4064 | * @param {Draggabilly} draggie | |||
| 4065 | */ | 4065 | */ | |||
| 4066 | Packery.prototype.bindDraggabillyEvents = function( draggie ) { | 4066 | Packery.prototype.bindDraggabillyEvents = function( draggie ) { | |||
| 4067 | draggie.on( 'dragStart', this.handleDraggabilly.dragStart ); | 4067 | draggie.on( 'dragStart', this.handleDraggabilly.dragStart ); | |||
| 4068 | draggie.on( 'dragMove', this.handleDraggabilly.dragMove ); | 4068 | draggie.on( 'dragMove', this.handleDraggabilly.dragMove ); | |||
| 4069 | draggie.on( 'dragEnd', this.handleDraggabilly.dragEnd ); | 4069 | draggie.on( 'dragEnd', this.handleDraggabilly.dragEnd ); | |||
| 4070 | }; | 4070 | }; | |||
| 4071 | 4071 | |||||
| 4072 | /** | 4072 | /** | |||
| 4073 | * binds jQuery UI Draggable events | 4073 | * binds jQuery UI Draggable events | |||
| 4074 | * @param {jQuery} $elems | 4074 | * @param {jQuery} $elems | |||
| 4075 | */ | 4075 | */ | |||
| 4076 | Packery.prototype.bindUIDraggableEvents = function( $elems ) { | 4076 | Packery.prototype.bindUIDraggableEvents = function( $elems ) { | |||
| 4077 | $elems | 4077 | $elems | |||
| 4078 | .on( 'dragstart', this.handleUIDraggable.start ) | 4078 | .on( 'dragstart', this.handleUIDraggable.start ) | |||
| 4079 | .on( 'drag', this.handleUIDraggable.drag ) | 4079 | .on( 'drag', this.handleUIDraggable.drag ) | |||
| 4080 | .on( 'dragstop', this.handleUIDraggable.stop ); | 4080 | .on( 'dragstop', this.handleUIDraggable.stop ); | |||
| 4081 | }; | 4081 | }; | |||
| 4082 | 4082 | |||||
| 4083 | Packery.Rect = Rect; | 4083 | Packery.Rect = Rect; | |||
| 4084 | Packery.Packer = Packer; | 4084 | Packery.Packer = Packer; | |||
| 4085 | 4085 | |||||
| 4086 | return Packery; | 4086 | return Packery; | |||
| 4087 | 4087 | |||||
| 4088 | })); | 4088 | })); | |||
| 4089 | 4089 |
Araxis Merge (but not the data content of this report) is Copyright © 1993–2019 Araxis Ltd (www.araxis.com). All rights reserved.