draggabilly-rails 1.1.2 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a09fe0ae8b394c2b775c31caaa9c61a69775c4f1
4
- data.tar.gz: 29ee59336b83505b2b5567c52c41a8abe9b933bd
3
+ metadata.gz: 27ceac2a940308fee0533b75fe7cba773bca7b45
4
+ data.tar.gz: 19d45b4769e962b357baae2a10c7e5b139da9bbb
5
5
  SHA512:
6
- metadata.gz: 311595d2a80ab9f7d8707de2afe36cfc59336b03f7dc042677957d63054f9f3a9b9dff1c07cc9a6111a48446349b5b73c82834794f06c395b5e9335bfef6346d
7
- data.tar.gz: ae4b02d0f4bf619c6398edc64d3f4b12cee3b3be8e64605459aaf36c1e9ba91298e9486b882d323c0e03b96af1319809927506509fa358a9fa0f46bc19c3b5c9
6
+ metadata.gz: 8ce430aa414337efea661a30985cd3e3ad9e6dd0490e227de0ae5279b7014096401bf92e19b18567c53a6495b8444717c1a9062851ea4e1e1cb4cca496d810ed
7
+ data.tar.gz: cca286ee22dec9019c133d317fed33c97e14a477490fc5c540f6cf82e92c927e2282da3875065007658d9e2857ba69d9d252226ea9ec6ee5c2a96f7e6e04d7c0
@@ -1,5 +1,5 @@
1
1
  module Draggabilly
2
2
  module Rails
3
- VERSION = '1.1.2'.freeze
3
+ VERSION = '1.2.4'.freeze
4
4
  end
5
5
  end
@@ -1,13 +1,155 @@
1
1
  /*!
2
- * Draggabilly PACKAGED v1.1.1
2
+ * Draggabilly PACKAGED v1.2.4
3
3
  * Make that shiz draggable
4
4
  * http://draggabilly.desandro.com
5
5
  * MIT license
6
6
  */
7
7
 
8
+ /**
9
+ * Bridget makes jQuery widgets
10
+ * v1.1.0
11
+ * MIT license
12
+ */
13
+
14
+ ( function( window ) {
15
+
16
+
17
+
18
+ // -------------------------- utils -------------------------- //
19
+
20
+ var slice = Array.prototype.slice;
21
+
22
+ function noop() {}
23
+
24
+ // -------------------------- definition -------------------------- //
25
+
26
+ function defineBridget( $ ) {
27
+
28
+ // bail if no jQuery
29
+ if ( !$ ) {
30
+ return;
31
+ }
32
+
33
+ // -------------------------- addOptionMethod -------------------------- //
34
+
35
+ /**
36
+ * adds option method -> $().plugin('option', {...})
37
+ * @param {Function} PluginClass - constructor class
38
+ */
39
+ function addOptionMethod( PluginClass ) {
40
+ // don't overwrite original option method
41
+ if ( PluginClass.prototype.option ) {
42
+ return;
43
+ }
44
+
45
+ // option setter
46
+ PluginClass.prototype.option = function( opts ) {
47
+ // bail out if not an object
48
+ if ( !$.isPlainObject( opts ) ){
49
+ return;
50
+ }
51
+ this.options = $.extend( true, this.options, opts );
52
+ };
53
+ }
54
+
55
+ // -------------------------- plugin bridge -------------------------- //
56
+
57
+ // helper function for logging errors
58
+ // $.error breaks jQuery chaining
59
+ var logError = typeof console === 'undefined' ? noop :
60
+ function( message ) {
61
+ console.error( message );
62
+ };
63
+
64
+ /**
65
+ * jQuery plugin bridge, access methods like $elem.plugin('method')
66
+ * @param {String} namespace - plugin name
67
+ * @param {Function} PluginClass - constructor class
68
+ */
69
+ function bridge( namespace, PluginClass ) {
70
+ // add to jQuery fn namespace
71
+ $.fn[ namespace ] = function( options ) {
72
+ if ( typeof options === 'string' ) {
73
+ // call plugin method when first argument is a string
74
+ // get arguments for method
75
+ var args = slice.call( arguments, 1 );
76
+
77
+ for ( var i=0, len = this.length; i < len; i++ ) {
78
+ var elem = this[i];
79
+ var instance = $.data( elem, namespace );
80
+ if ( !instance ) {
81
+ logError( "cannot call methods on " + namespace + " prior to initialization; " +
82
+ "attempted to call '" + options + "'" );
83
+ continue;
84
+ }
85
+ if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
86
+ logError( "no such method '" + options + "' for " + namespace + " instance" );
87
+ continue;
88
+ }
89
+
90
+ // trigger method with arguments
91
+ var returnValue = instance[ options ].apply( instance, args );
92
+
93
+ // break look and return first value if provided
94
+ if ( returnValue !== undefined ) {
95
+ return returnValue;
96
+ }
97
+ }
98
+ // return this if no return value
99
+ return this;
100
+ } else {
101
+ return this.each( function() {
102
+ var instance = $.data( this, namespace );
103
+ if ( instance ) {
104
+ // apply options & init
105
+ instance.option( options );
106
+ instance._init();
107
+ } else {
108
+ // initialize new instance
109
+ instance = new PluginClass( this, options );
110
+ $.data( this, namespace, instance );
111
+ }
112
+ });
113
+ }
114
+ };
115
+
116
+ }
117
+
118
+ // -------------------------- bridget -------------------------- //
119
+
120
+ /**
121
+ * converts a Prototypical class into a proper jQuery plugin
122
+ * the class must have a ._init method
123
+ * @param {String} namespace - plugin name, used in $().pluginName
124
+ * @param {Function} PluginClass - constructor class
125
+ */
126
+ $.bridget = function( namespace, PluginClass ) {
127
+ addOptionMethod( PluginClass );
128
+ bridge( namespace, PluginClass );
129
+ };
130
+
131
+ return $.bridget;
132
+
133
+ }
134
+
135
+ // transport
136
+ if ( typeof define === 'function' && define.amd ) {
137
+ // AMD
138
+ define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
139
+ } else if ( typeof exports === 'object' ) {
140
+ defineBridget( require('jquery') );
141
+ } else {
142
+ // get jquery from browser global
143
+ defineBridget( window.jQuery );
144
+ }
145
+
146
+ })( window );
147
+
8
148
  /*!
9
- * classie - class helper functions
149
+ * classie v1.0.1
150
+ * class helper functions
10
151
  * from bonzo https://github.com/ded/bonzo
152
+ * MIT license
11
153
  *
12
154
  * classie.has( elem, 'my-class' ) -> true/false
13
155
  * classie.add( elem, 'my-new-class' )
@@ -15,8 +157,8 @@
15
157
  * classie.toggle( elem, 'my-class' )
16
158
  */
17
159
 
18
- /*jshint browser: true, strict: true, undef: true */
19
- /*global define: false */
160
+ /*jshint browser: true, strict: true, undef: true, unused: true */
161
+ /*global define: false, module: false */
20
162
 
21
163
  ( function( window ) {
22
164
 
@@ -79,6 +221,9 @@ var classie = {
79
221
  if ( typeof define === 'function' && define.amd ) {
80
222
  // AMD
81
223
  define( 'classie/classie',classie );
224
+ } else if ( typeof exports === 'object' ) {
225
+ // CommonJS
226
+ module.exports = classie;
82
227
  } else {
83
228
  // browser global
84
229
  window.classie = classie;
@@ -87,464 +232,322 @@ if ( typeof define === 'function' && define.amd ) {
87
232
  })( window );
88
233
 
89
234
  /*!
90
- * EventEmitter v4.2.2 - git.io/ee
91
- * Oliver Caldwell
235
+ * getStyleProperty v1.0.4
236
+ * original by kangax
237
+ * http://perfectionkills.com/feature-testing-css-properties/
92
238
  * MIT license
93
- * @preserve
94
239
  */
95
240
 
96
- (function () {
97
-
241
+ /*jshint browser: true, strict: true, undef: true */
242
+ /*global define: false, exports: false, module: false */
98
243
 
99
- /**
100
- * Class for managing events.
101
- * Can be extended to provide event functionality in other classes.
102
- *
103
- * @class EventEmitter Manages event registering and emitting.
104
- */
105
- function EventEmitter() {}
244
+ ( function( window ) {
106
245
 
107
- // Shortcuts to improve speed and size
108
246
 
109
- // Easy access to the prototype
110
- var proto = EventEmitter.prototype;
111
247
 
112
- /**
113
- * Finds the index of the listener for the event in it's storage array.
114
- *
115
- * @param {Function[]} listeners Array of listeners to search through.
116
- * @param {Function} listener Method to look for.
117
- * @return {Number} Index of the specified listener, -1 if not found
118
- * @api private
119
- */
120
- function indexOfListener(listeners, listener) {
121
- var i = listeners.length;
122
- while (i--) {
123
- if (listeners[i].listener === listener) {
124
- return i;
125
- }
126
- }
248
+ var prefixes = 'Webkit Moz ms Ms O'.split(' ');
249
+ var docElemStyle = document.documentElement.style;
127
250
 
128
- return -1;
251
+ function getStyleProperty( propName ) {
252
+ if ( !propName ) {
253
+ return;
129
254
  }
130
255
 
131
- /**
132
- * Alias a method while keeping the context correct, to allow for overwriting of target method.
133
- *
134
- * @param {String} name The name of the target method.
135
- * @return {Function} The aliased method
136
- * @api private
137
- */
138
- function alias(name) {
139
- return function aliasClosure() {
140
- return this[name].apply(this, arguments);
141
- };
256
+ // test standard property first
257
+ if ( typeof docElemStyle[ propName ] === 'string' ) {
258
+ return propName;
142
259
  }
143
260
 
144
- /**
145
- * Returns the listener array for the specified event.
146
- * Will initialise the event object and listener arrays if required.
147
- * 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.
148
- * Each property in the object response is an array of listener functions.
149
- *
150
- * @param {String|RegExp} evt Name of the event to return the listeners from.
151
- * @return {Function[]|Object} All listener functions for the event.
152
- */
153
- proto.getListeners = function getListeners(evt) {
154
- var events = this._getEvents();
155
- var response;
156
- var key;
157
-
158
- // Return a concatenated array of all matching events if
159
- // the selector is a regular expression.
160
- if (typeof evt === 'object') {
161
- response = {};
162
- for (key in events) {
163
- if (events.hasOwnProperty(key) && evt.test(key)) {
164
- response[key] = events[key];
165
- }
166
- }
167
- }
168
- else {
169
- response = events[evt] || (events[evt] = []);
261
+ // capitalize
262
+ propName = propName.charAt(0).toUpperCase() + propName.slice(1);
263
+
264
+ // test vendor specific properties
265
+ var prefixed;
266
+ for ( var i=0, len = prefixes.length; i < len; i++ ) {
267
+ prefixed = prefixes[i] + propName;
268
+ if ( typeof docElemStyle[ prefixed ] === 'string' ) {
269
+ return prefixed;
170
270
  }
271
+ }
272
+ }
171
273
 
172
- return response;
173
- };
274
+ // transport
275
+ if ( typeof define === 'function' && define.amd ) {
276
+ // AMD
277
+ define( 'get-style-property/get-style-property',[],function() {
278
+ return getStyleProperty;
279
+ });
280
+ } else if ( typeof exports === 'object' ) {
281
+ // CommonJS for Component
282
+ module.exports = getStyleProperty;
283
+ } else {
284
+ // browser global
285
+ window.getStyleProperty = getStyleProperty;
286
+ }
174
287
 
175
- /**
176
- * Takes a list of listener objects and flattens it into a list of listener functions.
177
- *
178
- * @param {Object[]} listeners Raw listener objects.
179
- * @return {Function[]} Just the listener functions.
180
- */
181
- proto.flattenListeners = function flattenListeners(listeners) {
182
- var flatListeners = [];
183
- var i;
288
+ })( window );
184
289
 
185
- for (i = 0; i < listeners.length; i += 1) {
186
- flatListeners.push(listeners[i].listener);
187
- }
290
+ /*!
291
+ * getSize v1.2.2
292
+ * measure size of elements
293
+ * MIT license
294
+ */
188
295
 
189
- return flatListeners;
190
- };
296
+ /*jshint browser: true, strict: true, undef: true, unused: true */
297
+ /*global define: false, exports: false, require: false, module: false, console: false */
191
298
 
192
- /**
193
- * 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.
194
- *
195
- * @param {String|RegExp} evt Name of the event to return the listeners from.
196
- * @return {Object} All listener functions for an event in an object.
197
- */
198
- proto.getListenersAsObject = function getListenersAsObject(evt) {
199
- var listeners = this.getListeners(evt);
200
- var response;
299
+ ( function( window, undefined ) {
201
300
 
202
- if (listeners instanceof Array) {
203
- response = {};
204
- response[evt] = listeners;
205
- }
206
301
 
207
- return response || listeners;
208
- };
209
302
 
210
- /**
211
- * Adds a listener function to the specified event.
212
- * The listener will not be added if it is a duplicate.
213
- * If the listener returns true then it will be removed after it is called.
214
- * If you pass a regular expression as the event name then the listener will be added to all events that match it.
215
- *
216
- * @param {String|RegExp} evt Name of the event to attach the listener to.
217
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
218
- * @return {Object} Current instance of EventEmitter for chaining.
219
- */
220
- proto.addListener = function addListener(evt, listener) {
221
- var listeners = this.getListenersAsObject(evt);
222
- var listenerIsWrapped = typeof listener === 'object';
223
- var key;
224
-
225
- for (key in listeners) {
226
- if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
227
- listeners[key].push(listenerIsWrapped ? listener : {
228
- listener: listener,
229
- once: false
230
- });
231
- }
232
- }
303
+ // -------------------------- helpers -------------------------- //
233
304
 
234
- return this;
235
- };
305
+ // get a number from a string, not a percentage
306
+ function getStyleSize( value ) {
307
+ var num = parseFloat( value );
308
+ // not a percent like '100%', and a number
309
+ var isValid = value.indexOf('%') === -1 && !isNaN( num );
310
+ return isValid && num;
311
+ }
236
312
 
237
- /**
238
- * Alias of addListener
239
- */
240
- proto.on = alias('addListener');
313
+ function noop() {}
241
314
 
242
- /**
243
- * Semi-alias of addListener. It will add a listener that will be
244
- * automatically removed after it's first execution.
245
- *
246
- * @param {String|RegExp} evt Name of the event to attach the listener to.
247
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
248
- * @return {Object} Current instance of EventEmitter for chaining.
249
- */
250
- proto.addOnceListener = function addOnceListener(evt, listener) {
251
- return this.addListener(evt, {
252
- listener: listener,
253
- once: true
254
- });
315
+ var logError = typeof console === 'undefined' ? noop :
316
+ function( message ) {
317
+ console.error( message );
255
318
  };
256
319
 
257
- /**
258
- * Alias of addOnceListener.
259
- */
260
- proto.once = alias('addOnceListener');
320
+ // -------------------------- measurements -------------------------- //
261
321
 
262
- /**
263
- * 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.
264
- * You need to tell it what event names should be matched by a regex.
265
- *
266
- * @param {String} evt Name of the event to create.
267
- * @return {Object} Current instance of EventEmitter for chaining.
268
- */
269
- proto.defineEvent = function defineEvent(evt) {
270
- this.getListeners(evt);
271
- return this;
272
- };
322
+ var measurements = [
323
+ 'paddingLeft',
324
+ 'paddingRight',
325
+ 'paddingTop',
326
+ 'paddingBottom',
327
+ 'marginLeft',
328
+ 'marginRight',
329
+ 'marginTop',
330
+ 'marginBottom',
331
+ 'borderLeftWidth',
332
+ 'borderRightWidth',
333
+ 'borderTopWidth',
334
+ 'borderBottomWidth'
335
+ ];
273
336
 
274
- /**
275
- * Uses defineEvent to define multiple events.
276
- *
277
- * @param {String[]} evts An array of event names to define.
278
- * @return {Object} Current instance of EventEmitter for chaining.
279
- */
280
- proto.defineEvents = function defineEvents(evts) {
281
- for (var i = 0; i < evts.length; i += 1) {
282
- this.defineEvent(evts[i]);
283
- }
284
- return this;
337
+ function getZeroSize() {
338
+ var size = {
339
+ width: 0,
340
+ height: 0,
341
+ innerWidth: 0,
342
+ innerHeight: 0,
343
+ outerWidth: 0,
344
+ outerHeight: 0
285
345
  };
346
+ for ( var i=0, len = measurements.length; i < len; i++ ) {
347
+ var measurement = measurements[i];
348
+ size[ measurement ] = 0;
349
+ }
350
+ return size;
351
+ }
286
352
 
287
- /**
288
- * Removes a listener function from the specified event.
289
- * When passed a regular expression as the event name, it will remove the listener from all events that match it.
290
- *
291
- * @param {String|RegExp} evt Name of the event to remove the listener from.
292
- * @param {Function} listener Method to remove from the event.
293
- * @return {Object} Current instance of EventEmitter for chaining.
294
- */
295
- proto.removeListener = function removeListener(evt, listener) {
296
- var listeners = this.getListenersAsObject(evt);
297
- var index;
298
- var key;
299
-
300
- for (key in listeners) {
301
- if (listeners.hasOwnProperty(key)) {
302
- index = indexOfListener(listeners[key], listener);
303
353
 
304
- if (index !== -1) {
305
- listeners[key].splice(index, 1);
306
- }
307
- }
308
- }
309
354
 
310
- return this;
311
- };
355
+ function defineGetSize( getStyleProperty ) {
312
356
 
313
- /**
314
- * Alias of removeListener
315
- */
316
- proto.off = alias('removeListener');
357
+ // -------------------------- setup -------------------------- //
317
358
 
318
- /**
319
- * Adds listeners in bulk using the manipulateListeners method.
320
- * 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.
321
- * You can also pass it a regular expression to add the array of listeners to all events that match it.
322
- * Yeah, this function does quite a bit. That's probably a bad thing.
323
- *
324
- * @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.
325
- * @param {Function[]} [listeners] An optional array of listener functions to add.
326
- * @return {Object} Current instance of EventEmitter for chaining.
327
- */
328
- proto.addListeners = function addListeners(evt, listeners) {
329
- // Pass through to manipulateListeners
330
- return this.manipulateListeners(false, evt, listeners);
331
- };
359
+ var isSetup = false;
332
360
 
333
- /**
334
- * Removes listeners in bulk using the manipulateListeners method.
335
- * 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.
336
- * You can also pass it an event name and an array of listeners to be removed.
337
- * You can also pass it a regular expression to remove the listeners from all events that match it.
338
- *
339
- * @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.
340
- * @param {Function[]} [listeners] An optional array of listener functions to remove.
341
- * @return {Object} Current instance of EventEmitter for chaining.
342
- */
343
- proto.removeListeners = function removeListeners(evt, listeners) {
344
- // Pass through to manipulateListeners
345
- return this.manipulateListeners(true, evt, listeners);
346
- };
361
+ var getStyle, boxSizingProp, isBoxSizeOuter;
347
362
 
348
- /**
349
- * 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.
350
- * The first argument will determine if the listeners are removed (true) or added (false).
351
- * 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.
352
- * You can also pass it an event name and an array of listeners to be added/removed.
353
- * You can also pass it a regular expression to manipulate the listeners of all events that match it.
354
- *
355
- * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
356
- * @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.
357
- * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
358
- * @return {Object} Current instance of EventEmitter for chaining.
359
- */
360
- proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
361
- var i;
362
- var value;
363
- var single = remove ? this.removeListener : this.addListener;
364
- var multiple = remove ? this.removeListeners : this.addListeners;
365
-
366
- // If evt is an object then pass each of it's properties to this method
367
- if (typeof evt === 'object' && !(evt instanceof RegExp)) {
368
- for (i in evt) {
369
- if (evt.hasOwnProperty(i) && (value = evt[i])) {
370
- // Pass the single listener straight through to the singular method
371
- if (typeof value === 'function') {
372
- single.call(this, i, value);
373
- }
374
- else {
375
- // Otherwise pass back to the multiple function
376
- multiple.call(this, i, value);
377
- }
378
- }
379
- }
380
- }
381
- else {
382
- // So evt must be a string
383
- // And listeners must be an array of listeners
384
- // Loop over it and pass each one to the multiple method
385
- i = listeners.length;
386
- while (i--) {
387
- single.call(this, evt, listeners[i]);
388
- }
389
- }
363
+ /**
364
+ * setup vars and functions
365
+ * do it on initial getSize(), rather than on script load
366
+ * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
367
+ */
368
+ function setup() {
369
+ // setup once
370
+ if ( isSetup ) {
371
+ return;
372
+ }
373
+ isSetup = true;
390
374
 
391
- return this;
392
- };
375
+ var getComputedStyle = window.getComputedStyle;
376
+ getStyle = ( function() {
377
+ var getStyleFn = getComputedStyle ?
378
+ function( elem ) {
379
+ return getComputedStyle( elem, null );
380
+ } :
381
+ function( elem ) {
382
+ return elem.currentStyle;
383
+ };
393
384
 
394
- /**
395
- * Removes all listeners from a specified event.
396
- * If you do not specify an event then all listeners will be removed.
397
- * That means every event will be emptied.
398
- * You can also pass a regex to remove all events that match it.
399
- *
400
- * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
401
- * @return {Object} Current instance of EventEmitter for chaining.
402
- */
403
- proto.removeEvent = function removeEvent(evt) {
404
- var type = typeof evt;
405
- var events = this._getEvents();
406
- var key;
407
-
408
- // Remove different things depending on the state of evt
409
- if (type === 'string') {
410
- // Remove all listeners for the specified event
411
- delete events[evt];
412
- }
413
- else if (type === 'object') {
414
- // Remove all events matching the regex.
415
- for (key in events) {
416
- if (events.hasOwnProperty(key) && evt.test(key)) {
417
- delete events[key];
385
+ return function getStyle( elem ) {
386
+ var style = getStyleFn( elem );
387
+ if ( !style ) {
388
+ logError( 'Style returned ' + style +
389
+ '. Are you running this code in a hidden iframe on Firefox? ' +
390
+ 'See http://bit.ly/getsizebug1' );
418
391
  }
419
- }
420
- }
421
- else {
422
- // Remove all listeners in all events
423
- delete this._events;
424
- }
392
+ return style;
393
+ };
394
+ })();
425
395
 
426
- return this;
427
- };
396
+ // -------------------------- box sizing -------------------------- //
397
+
398
+ boxSizingProp = getStyleProperty('boxSizing');
428
399
 
429
400
  /**
430
- * Emits an event of your choice.
431
- * When emitted, every listener attached to that event will be executed.
432
- * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
433
- * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
434
- * So they will not arrive within the array on the other side, they will be separate.
435
- * You can also pass a regular expression to emit to all events that match it.
436
- *
437
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
438
- * @param {Array} [args] Optional array of arguments to be passed to each listener.
439
- * @return {Object} Current instance of EventEmitter for chaining.
401
+ * WebKit measures the outer-width on style.width on border-box elems
402
+ * IE & Firefox measures the inner-width
440
403
  */
441
- proto.emitEvent = function emitEvent(evt, args) {
442
- var listeners = this.getListenersAsObject(evt);
443
- var listener;
444
- var i;
445
- var key;
446
- var response;
404
+ if ( boxSizingProp ) {
405
+ var div = document.createElement('div');
406
+ div.style.width = '200px';
407
+ div.style.padding = '1px 2px 3px 4px';
408
+ div.style.borderStyle = 'solid';
409
+ div.style.borderWidth = '1px 2px 3px 4px';
410
+ div.style[ boxSizingProp ] = 'border-box';
411
+
412
+ var body = document.body || document.documentElement;
413
+ body.appendChild( div );
414
+ var style = getStyle( div );
415
+
416
+ isBoxSizeOuter = getStyleSize( style.width ) === 200;
417
+ body.removeChild( div );
418
+ }
447
419
 
448
- for (key in listeners) {
449
- if (listeners.hasOwnProperty(key)) {
450
- i = listeners[key].length;
420
+ }
451
421
 
452
- while (i--) {
453
- // If the listener returns true then it shall be removed from the event
454
- // The function is executed either with a basic call or an apply if there is an args array
455
- listener = listeners[key][i];
456
- response = listener.listener.apply(this, args || []);
457
- if (response === this._getOnceReturnValue() || listener.once === true) {
458
- this.removeListener(evt, listener.listener);
459
- }
460
- }
461
- }
462
- }
422
+ // -------------------------- getSize -------------------------- //
463
423
 
464
- return this;
465
- };
424
+ function getSize( elem ) {
425
+ setup();
466
426
 
467
- /**
468
- * Alias of emitEvent
469
- */
470
- proto.trigger = alias('emitEvent');
427
+ // use querySeletor if elem is string
428
+ if ( typeof elem === 'string' ) {
429
+ elem = document.querySelector( elem );
430
+ }
471
431
 
472
- /**
473
- * 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.
474
- * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
475
- *
476
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
477
- * @param {...*} Optional additional arguments to be passed to each listener.
478
- * @return {Object} Current instance of EventEmitter for chaining.
479
- */
480
- proto.emit = function emit(evt) {
481
- var args = Array.prototype.slice.call(arguments, 1);
482
- return this.emitEvent(evt, args);
483
- };
432
+ // do not proceed on non-objects
433
+ if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
434
+ return;
435
+ }
484
436
 
485
- /**
486
- * Sets the current value to check against when executing listeners. If a
487
- * listeners return value matches the one set here then it will be removed
488
- * after execution. This value defaults to true.
489
- *
490
- * @param {*} value The new value to check for when executing listeners.
491
- * @return {Object} Current instance of EventEmitter for chaining.
492
- */
493
- proto.setOnceReturnValue = function setOnceReturnValue(value) {
494
- this._onceReturnValue = value;
495
- return this;
496
- };
437
+ var style = getStyle( elem );
497
438
 
498
- /**
499
- * Fetches the current value to check against when executing listeners. If
500
- * the listeners return value matches this one then it should be removed
501
- * automatically. It will return true by default.
502
- *
503
- * @return {*|Boolean} The current value to check for or the default, true.
504
- * @api private
505
- */
506
- proto._getOnceReturnValue = function _getOnceReturnValue() {
507
- if (this.hasOwnProperty('_onceReturnValue')) {
508
- return this._onceReturnValue;
509
- }
510
- else {
511
- return true;
512
- }
513
- };
439
+ // if hidden, everything is 0
440
+ if ( style.display === 'none' ) {
441
+ return getZeroSize();
442
+ }
514
443
 
515
- /**
516
- * Fetches the events object and creates one if required.
517
- *
518
- * @return {Object} The events storage object.
519
- * @api private
520
- */
521
- proto._getEvents = function _getEvents() {
522
- return this._events || (this._events = {});
523
- };
444
+ var size = {};
445
+ size.width = elem.offsetWidth;
446
+ size.height = elem.offsetHeight;
524
447
 
525
- // Expose the class either via AMD, CommonJS or the global object
526
- if (typeof define === 'function' && define.amd) {
527
- define('eventEmitter/EventEmitter',[],function () {
528
- return EventEmitter;
529
- });
448
+ var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
449
+ style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
450
+
451
+ // get all measurements
452
+ for ( var i=0, len = measurements.length; i < len; i++ ) {
453
+ var measurement = measurements[i];
454
+ var value = style[ measurement ];
455
+ value = mungeNonPixel( elem, value );
456
+ var num = parseFloat( value );
457
+ // any 'auto', 'medium' value will be 0
458
+ size[ measurement ] = !isNaN( num ) ? num : 0;
459
+ }
460
+
461
+ var paddingWidth = size.paddingLeft + size.paddingRight;
462
+ var paddingHeight = size.paddingTop + size.paddingBottom;
463
+ var marginWidth = size.marginLeft + size.marginRight;
464
+ var marginHeight = size.marginTop + size.marginBottom;
465
+ var borderWidth = size.borderLeftWidth + size.borderRightWidth;
466
+ var borderHeight = size.borderTopWidth + size.borderBottomWidth;
467
+
468
+ var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
469
+
470
+ // overwrite width and height if we can get it from style
471
+ var styleWidth = getStyleSize( style.width );
472
+ if ( styleWidth !== false ) {
473
+ size.width = styleWidth +
474
+ // add padding and border unless it's already including it
475
+ ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
476
+ }
477
+
478
+ var styleHeight = getStyleSize( style.height );
479
+ if ( styleHeight !== false ) {
480
+ size.height = styleHeight +
481
+ // add padding and border unless it's already including it
482
+ ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
530
483
  }
531
- else if (typeof module === 'object' && module.exports){
532
- module.exports = EventEmitter;
484
+
485
+ size.innerWidth = size.width - ( paddingWidth + borderWidth );
486
+ size.innerHeight = size.height - ( paddingHeight + borderHeight );
487
+
488
+ size.outerWidth = size.width + marginWidth;
489
+ size.outerHeight = size.height + marginHeight;
490
+
491
+ return size;
492
+ }
493
+
494
+ // IE8 returns percent values, not pixels
495
+ // taken from jQuery's curCSS
496
+ function mungeNonPixel( elem, value ) {
497
+ // IE8 and has percent value
498
+ if ( window.getComputedStyle || value.indexOf('%') === -1 ) {
499
+ return value;
533
500
  }
534
- else {
535
- this.EventEmitter = EventEmitter;
501
+ var style = elem.style;
502
+ // Remember the original values
503
+ var left = style.left;
504
+ var rs = elem.runtimeStyle;
505
+ var rsLeft = rs && rs.left;
506
+
507
+ // Put in the new values to get a computed value out
508
+ if ( rsLeft ) {
509
+ rs.left = elem.currentStyle.left;
536
510
  }
537
- }.call(this));
511
+ style.left = value;
512
+ value = style.pixelLeft;
513
+
514
+ // Revert the changed values
515
+ style.left = left;
516
+ if ( rsLeft ) {
517
+ rs.left = rsLeft;
518
+ }
519
+
520
+ return value;
521
+ }
522
+
523
+ return getSize;
524
+
525
+ }
526
+
527
+ // transport
528
+ if ( typeof define === 'function' && define.amd ) {
529
+ // AMD for RequireJS
530
+ define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
531
+ } else if ( typeof exports === 'object' ) {
532
+ // CommonJS for Component
533
+ module.exports = defineGetSize( require('desandro-get-style-property') );
534
+ } else {
535
+ // browser global
536
+ window.getSize = defineGetSize( window.getStyleProperty );
537
+ }
538
+
539
+ })( window );
538
540
 
539
541
  /*!
540
- * eventie v1.0.3
542
+ * eventie v1.0.6
541
543
  * event binding helper
542
544
  * eventie.bind( elem, 'click', myFn )
543
545
  * eventie.unbind( elem, 'click', myFn )
546
+ * MIT license
544
547
  */
545
548
 
546
549
  /*jshint browser: true, undef: true, unused: true */
547
- /*global define: false */
550
+ /*global define: false, module: false */
548
551
 
549
552
  ( function( window ) {
550
553
 
@@ -554,6 +557,13 @@ var docElem = document.documentElement;
554
557
 
555
558
  var bind = function() {};
556
559
 
560
+ function getIEEvent( obj ) {
561
+ var event = window.event;
562
+ // add event.target
563
+ event.target = event.target || event.srcElement || obj;
564
+ return event;
565
+ }
566
+
557
567
  if ( docElem.addEventListener ) {
558
568
  bind = function( obj, type, fn ) {
559
569
  obj.addEventListener( type, fn, false );
@@ -562,15 +572,11 @@ if ( docElem.addEventListener ) {
562
572
  bind = function( obj, type, fn ) {
563
573
  obj[ type + fn ] = fn.handleEvent ?
564
574
  function() {
565
- var event = window.event;
566
- // add event.target
567
- event.target = event.target || event.srcElement;
575
+ var event = getIEEvent( obj );
568
576
  fn.handleEvent.call( fn, event );
569
577
  } :
570
578
  function() {
571
- var event = window.event;
572
- // add event.target
573
- event.target = event.target || event.srcElement;
579
+ var event = getIEEvent( obj );
574
580
  fn.call( obj, event );
575
581
  };
576
582
  obj.attachEvent( "on" + type, obj[ type + fn ] );
@@ -600,265 +606,1186 @@ var eventie = {
600
606
  unbind: unbind
601
607
  };
602
608
 
603
- // transport
609
+ // ----- module definition ----- //
610
+
604
611
  if ( typeof define === 'function' && define.amd ) {
605
612
  // AMD
606
613
  define( 'eventie/eventie',eventie );
614
+ } else if ( typeof exports === 'object' ) {
615
+ // CommonJS
616
+ module.exports = eventie;
607
617
  } else {
608
618
  // browser global
609
619
  window.eventie = eventie;
610
620
  }
611
621
 
612
- })( this );
622
+ })( window );
613
623
 
614
624
  /*!
615
- * getStyleProperty by kangax
616
- * http://perfectionkills.com/feature-testing-css-properties/
625
+ * EventEmitter v4.2.11 - git.io/ee
626
+ * Unlicense - http://unlicense.org/
627
+ * Oliver Caldwell - http://oli.me.uk/
628
+ * @preserve
617
629
  */
618
630
 
619
- /*jshint browser: true, strict: true, undef: true */
620
- /*globals define: false */
631
+ ;(function () {
632
+
633
+
634
+ /**
635
+ * Class for managing events.
636
+ * Can be extended to provide event functionality in other classes.
637
+ *
638
+ * @class EventEmitter Manages event registering and emitting.
639
+ */
640
+ function EventEmitter() {}
641
+
642
+ // Shortcuts to improve speed and size
643
+ var proto = EventEmitter.prototype;
644
+ var exports = this;
645
+ var originalGlobalValue = exports.EventEmitter;
646
+
647
+ /**
648
+ * Finds the index of the listener for the event in its storage array.
649
+ *
650
+ * @param {Function[]} listeners Array of listeners to search through.
651
+ * @param {Function} listener Method to look for.
652
+ * @return {Number} Index of the specified listener, -1 if not found
653
+ * @api private
654
+ */
655
+ function indexOfListener(listeners, listener) {
656
+ var i = listeners.length;
657
+ while (i--) {
658
+ if (listeners[i].listener === listener) {
659
+ return i;
660
+ }
661
+ }
621
662
 
622
- ( function( window ) {
663
+ return -1;
664
+ }
623
665
 
666
+ /**
667
+ * Alias a method while keeping the context correct, to allow for overwriting of target method.
668
+ *
669
+ * @param {String} name The name of the target method.
670
+ * @return {Function} The aliased method
671
+ * @api private
672
+ */
673
+ function alias(name) {
674
+ return function aliasClosure() {
675
+ return this[name].apply(this, arguments);
676
+ };
677
+ }
624
678
 
679
+ /**
680
+ * Returns the listener array for the specified event.
681
+ * Will initialise the event object and listener arrays if required.
682
+ * 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.
683
+ * Each property in the object response is an array of listener functions.
684
+ *
685
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
686
+ * @return {Function[]|Object} All listener functions for the event.
687
+ */
688
+ proto.getListeners = function getListeners(evt) {
689
+ var events = this._getEvents();
690
+ var response;
691
+ var key;
692
+
693
+ // Return a concatenated array of all matching events if
694
+ // the selector is a regular expression.
695
+ if (evt instanceof RegExp) {
696
+ response = {};
697
+ for (key in events) {
698
+ if (events.hasOwnProperty(key) && evt.test(key)) {
699
+ response[key] = events[key];
700
+ }
701
+ }
702
+ }
703
+ else {
704
+ response = events[evt] || (events[evt] = []);
705
+ }
625
706
 
626
- var prefixes = 'Webkit Moz ms Ms O'.split(' ');
627
- var docElemStyle = document.documentElement.style;
707
+ return response;
708
+ };
628
709
 
629
- function getStyleProperty( propName ) {
630
- if ( !propName ) {
631
- return;
632
- }
710
+ /**
711
+ * Takes a list of listener objects and flattens it into a list of listener functions.
712
+ *
713
+ * @param {Object[]} listeners Raw listener objects.
714
+ * @return {Function[]} Just the listener functions.
715
+ */
716
+ proto.flattenListeners = function flattenListeners(listeners) {
717
+ var flatListeners = [];
718
+ var i;
719
+
720
+ for (i = 0; i < listeners.length; i += 1) {
721
+ flatListeners.push(listeners[i].listener);
722
+ }
633
723
 
634
- // test standard property first
635
- if ( typeof docElemStyle[ propName ] === 'string' ) {
636
- return propName;
637
- }
724
+ return flatListeners;
725
+ };
638
726
 
639
- // capitalize
640
- propName = propName.charAt(0).toUpperCase() + propName.slice(1);
727
+ /**
728
+ * 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.
729
+ *
730
+ * @param {String|RegExp} evt Name of the event to return the listeners from.
731
+ * @return {Object} All listener functions for an event in an object.
732
+ */
733
+ proto.getListenersAsObject = function getListenersAsObject(evt) {
734
+ var listeners = this.getListeners(evt);
735
+ var response;
736
+
737
+ if (listeners instanceof Array) {
738
+ response = {};
739
+ response[evt] = listeners;
740
+ }
641
741
 
642
- // test vendor specific properties
643
- var prefixed;
644
- for ( var i=0, len = prefixes.length; i < len; i++ ) {
645
- prefixed = prefixes[i] + propName;
646
- if ( typeof docElemStyle[ prefixed ] === 'string' ) {
647
- return prefixed;
648
- }
649
- }
650
- }
742
+ return response || listeners;
743
+ };
651
744
 
652
- // transport
653
- if ( typeof define === 'function' && define.amd ) {
654
- // AMD
655
- define( 'get-style-property/get-style-property',[],function() {
656
- return getStyleProperty;
657
- });
658
- } else {
659
- // browser global
660
- window.getStyleProperty = getStyleProperty;
661
- }
745
+ /**
746
+ * Adds a listener function to the specified event.
747
+ * The listener will not be added if it is a duplicate.
748
+ * If the listener returns true then it will be removed after it is called.
749
+ * If you pass a regular expression as the event name then the listener will be added to all events that match it.
750
+ *
751
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
752
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
753
+ * @return {Object} Current instance of EventEmitter for chaining.
754
+ */
755
+ proto.addListener = function addListener(evt, listener) {
756
+ var listeners = this.getListenersAsObject(evt);
757
+ var listenerIsWrapped = typeof listener === 'object';
758
+ var key;
759
+
760
+ for (key in listeners) {
761
+ if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
762
+ listeners[key].push(listenerIsWrapped ? listener : {
763
+ listener: listener,
764
+ once: false
765
+ });
766
+ }
767
+ }
662
768
 
663
- })( window );
769
+ return this;
770
+ };
664
771
 
665
- /**
666
- * getSize v1.1.4
667
- * measure size of elements
668
- */
772
+ /**
773
+ * Alias of addListener
774
+ */
775
+ proto.on = alias('addListener');
776
+
777
+ /**
778
+ * Semi-alias of addListener. It will add a listener that will be
779
+ * automatically removed after its first execution.
780
+ *
781
+ * @param {String|RegExp} evt Name of the event to attach the listener to.
782
+ * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
783
+ * @return {Object} Current instance of EventEmitter for chaining.
784
+ */
785
+ proto.addOnceListener = function addOnceListener(evt, listener) {
786
+ return this.addListener(evt, {
787
+ listener: listener,
788
+ once: true
789
+ });
790
+ };
669
791
 
670
- /*jshint browser: true, strict: true, undef: true, unused: true */
671
- /*global define: false */
792
+ /**
793
+ * Alias of addOnceListener.
794
+ */
795
+ proto.once = alias('addOnceListener');
796
+
797
+ /**
798
+ * 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.
799
+ * You need to tell it what event names should be matched by a regex.
800
+ *
801
+ * @param {String} evt Name of the event to create.
802
+ * @return {Object} Current instance of EventEmitter for chaining.
803
+ */
804
+ proto.defineEvent = function defineEvent(evt) {
805
+ this.getListeners(evt);
806
+ return this;
807
+ };
672
808
 
673
- ( function( window, undefined ) {
809
+ /**
810
+ * Uses defineEvent to define multiple events.
811
+ *
812
+ * @param {String[]} evts An array of event names to define.
813
+ * @return {Object} Current instance of EventEmitter for chaining.
814
+ */
815
+ proto.defineEvents = function defineEvents(evts) {
816
+ for (var i = 0; i < evts.length; i += 1) {
817
+ this.defineEvent(evts[i]);
818
+ }
819
+ return this;
820
+ };
674
821
 
822
+ /**
823
+ * Removes a listener function from the specified event.
824
+ * When passed a regular expression as the event name, it will remove the listener from all events that match it.
825
+ *
826
+ * @param {String|RegExp} evt Name of the event to remove the listener from.
827
+ * @param {Function} listener Method to remove from the event.
828
+ * @return {Object} Current instance of EventEmitter for chaining.
829
+ */
830
+ proto.removeListener = function removeListener(evt, listener) {
831
+ var listeners = this.getListenersAsObject(evt);
832
+ var index;
833
+ var key;
834
+
835
+ for (key in listeners) {
836
+ if (listeners.hasOwnProperty(key)) {
837
+ index = indexOfListener(listeners[key], listener);
838
+
839
+ if (index !== -1) {
840
+ listeners[key].splice(index, 1);
841
+ }
842
+ }
843
+ }
675
844
 
845
+ return this;
846
+ };
676
847
 
677
- // -------------------------- helpers -------------------------- //
848
+ /**
849
+ * Alias of removeListener
850
+ */
851
+ proto.off = alias('removeListener');
852
+
853
+ /**
854
+ * Adds listeners in bulk using the manipulateListeners method.
855
+ * 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.
856
+ * You can also pass it a regular expression to add the array of listeners to all events that match it.
857
+ * Yeah, this function does quite a bit. That's probably a bad thing.
858
+ *
859
+ * @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.
860
+ * @param {Function[]} [listeners] An optional array of listener functions to add.
861
+ * @return {Object} Current instance of EventEmitter for chaining.
862
+ */
863
+ proto.addListeners = function addListeners(evt, listeners) {
864
+ // Pass through to manipulateListeners
865
+ return this.manipulateListeners(false, evt, listeners);
866
+ };
678
867
 
679
- var defView = document.defaultView;
868
+ /**
869
+ * Removes listeners in bulk using the manipulateListeners method.
870
+ * 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.
871
+ * You can also pass it an event name and an array of listeners to be removed.
872
+ * You can also pass it a regular expression to remove the listeners from all events that match it.
873
+ *
874
+ * @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.
875
+ * @param {Function[]} [listeners] An optional array of listener functions to remove.
876
+ * @return {Object} Current instance of EventEmitter for chaining.
877
+ */
878
+ proto.removeListeners = function removeListeners(evt, listeners) {
879
+ // Pass through to manipulateListeners
880
+ return this.manipulateListeners(true, evt, listeners);
881
+ };
680
882
 
681
- var getStyle = defView && defView.getComputedStyle ?
682
- function( elem ) {
683
- return defView.getComputedStyle( elem, null );
684
- } :
685
- function( elem ) {
686
- return elem.currentStyle;
687
- };
883
+ /**
884
+ * 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.
885
+ * The first argument will determine if the listeners are removed (true) or added (false).
886
+ * 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.
887
+ * You can also pass it an event name and an array of listeners to be added/removed.
888
+ * You can also pass it a regular expression to manipulate the listeners of all events that match it.
889
+ *
890
+ * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
891
+ * @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.
892
+ * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
893
+ * @return {Object} Current instance of EventEmitter for chaining.
894
+ */
895
+ proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
896
+ var i;
897
+ var value;
898
+ var single = remove ? this.removeListener : this.addListener;
899
+ var multiple = remove ? this.removeListeners : this.addListeners;
900
+
901
+ // If evt is an object then pass each of its properties to this method
902
+ if (typeof evt === 'object' && !(evt instanceof RegExp)) {
903
+ for (i in evt) {
904
+ if (evt.hasOwnProperty(i) && (value = evt[i])) {
905
+ // Pass the single listener straight through to the singular method
906
+ if (typeof value === 'function') {
907
+ single.call(this, i, value);
908
+ }
909
+ else {
910
+ // Otherwise pass back to the multiple function
911
+ multiple.call(this, i, value);
912
+ }
913
+ }
914
+ }
915
+ }
916
+ else {
917
+ // So evt must be a string
918
+ // And listeners must be an array of listeners
919
+ // Loop over it and pass each one to the multiple method
920
+ i = listeners.length;
921
+ while (i--) {
922
+ single.call(this, evt, listeners[i]);
923
+ }
924
+ }
688
925
 
689
- // get a number from a string, not a percentage
690
- function getStyleSize( value ) {
691
- var num = parseFloat( value );
692
- // not a percent like '100%', and a number
693
- var isValid = value.indexOf('%') === -1 && !isNaN( num );
694
- return isValid && num;
695
- }
926
+ return this;
927
+ };
696
928
 
697
- // -------------------------- measurements -------------------------- //
929
+ /**
930
+ * Removes all listeners from a specified event.
931
+ * If you do not specify an event then all listeners will be removed.
932
+ * That means every event will be emptied.
933
+ * You can also pass a regex to remove all events that match it.
934
+ *
935
+ * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
936
+ * @return {Object} Current instance of EventEmitter for chaining.
937
+ */
938
+ proto.removeEvent = function removeEvent(evt) {
939
+ var type = typeof evt;
940
+ var events = this._getEvents();
941
+ var key;
942
+
943
+ // Remove different things depending on the state of evt
944
+ if (type === 'string') {
945
+ // Remove all listeners for the specified event
946
+ delete events[evt];
947
+ }
948
+ else if (evt instanceof RegExp) {
949
+ // Remove all events matching the regex.
950
+ for (key in events) {
951
+ if (events.hasOwnProperty(key) && evt.test(key)) {
952
+ delete events[key];
953
+ }
954
+ }
955
+ }
956
+ else {
957
+ // Remove all listeners in all events
958
+ delete this._events;
959
+ }
698
960
 
699
- var measurements = [
700
- 'paddingLeft',
701
- 'paddingRight',
702
- 'paddingTop',
703
- 'paddingBottom',
704
- 'marginLeft',
705
- 'marginRight',
706
- 'marginTop',
707
- 'marginBottom',
708
- 'borderLeftWidth',
709
- 'borderRightWidth',
710
- 'borderTopWidth',
711
- 'borderBottomWidth'
712
- ];
961
+ return this;
962
+ };
713
963
 
714
- function getZeroSize() {
715
- var size = {
716
- width: 0,
717
- height: 0,
718
- innerWidth: 0,
719
- innerHeight: 0,
720
- outerWidth: 0,
721
- outerHeight: 0
722
- };
723
- for ( var i=0, len = measurements.length; i < len; i++ ) {
724
- var measurement = measurements[i];
725
- size[ measurement ] = 0;
726
- }
727
- return size;
728
- }
964
+ /**
965
+ * Alias of removeEvent.
966
+ *
967
+ * Added to mirror the node API.
968
+ */
969
+ proto.removeAllListeners = alias('removeEvent');
970
+
971
+ /**
972
+ * Emits an event of your choice.
973
+ * When emitted, every listener attached to that event will be executed.
974
+ * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
975
+ * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
976
+ * So they will not arrive within the array on the other side, they will be separate.
977
+ * You can also pass a regular expression to emit to all events that match it.
978
+ *
979
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
980
+ * @param {Array} [args] Optional array of arguments to be passed to each listener.
981
+ * @return {Object} Current instance of EventEmitter for chaining.
982
+ */
983
+ proto.emitEvent = function emitEvent(evt, args) {
984
+ var listeners = this.getListenersAsObject(evt);
985
+ var listener;
986
+ var i;
987
+ var key;
988
+ var response;
989
+
990
+ for (key in listeners) {
991
+ if (listeners.hasOwnProperty(key)) {
992
+ i = listeners[key].length;
993
+
994
+ while (i--) {
995
+ // If the listener returns true then it shall be removed from the event
996
+ // The function is executed either with a basic call or an apply if there is an args array
997
+ listener = listeners[key][i];
998
+
999
+ if (listener.once === true) {
1000
+ this.removeListener(evt, listener.listener);
1001
+ }
1002
+
1003
+ response = listener.listener.apply(this, args || []);
1004
+
1005
+ if (response === this._getOnceReturnValue()) {
1006
+ this.removeListener(evt, listener.listener);
1007
+ }
1008
+ }
1009
+ }
1010
+ }
729
1011
 
1012
+ return this;
1013
+ };
730
1014
 
1015
+ /**
1016
+ * Alias of emitEvent
1017
+ */
1018
+ proto.trigger = alias('emitEvent');
1019
+
1020
+ /**
1021
+ * 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.
1022
+ * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
1023
+ *
1024
+ * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
1025
+ * @param {...*} Optional additional arguments to be passed to each listener.
1026
+ * @return {Object} Current instance of EventEmitter for chaining.
1027
+ */
1028
+ proto.emit = function emit(evt) {
1029
+ var args = Array.prototype.slice.call(arguments, 1);
1030
+ return this.emitEvent(evt, args);
1031
+ };
731
1032
 
732
- function defineGetSize( getStyleProperty ) {
1033
+ /**
1034
+ * Sets the current value to check against when executing listeners. If a
1035
+ * listeners return value matches the one set here then it will be removed
1036
+ * after execution. This value defaults to true.
1037
+ *
1038
+ * @param {*} value The new value to check for when executing listeners.
1039
+ * @return {Object} Current instance of EventEmitter for chaining.
1040
+ */
1041
+ proto.setOnceReturnValue = function setOnceReturnValue(value) {
1042
+ this._onceReturnValue = value;
1043
+ return this;
1044
+ };
733
1045
 
734
- // -------------------------- box sizing -------------------------- //
1046
+ /**
1047
+ * Fetches the current value to check against when executing listeners. If
1048
+ * the listeners return value matches this one then it should be removed
1049
+ * automatically. It will return true by default.
1050
+ *
1051
+ * @return {*|Boolean} The current value to check for or the default, true.
1052
+ * @api private
1053
+ */
1054
+ proto._getOnceReturnValue = function _getOnceReturnValue() {
1055
+ if (this.hasOwnProperty('_onceReturnValue')) {
1056
+ return this._onceReturnValue;
1057
+ }
1058
+ else {
1059
+ return true;
1060
+ }
1061
+ };
735
1062
 
736
- var boxSizingProp = getStyleProperty('boxSizing');
737
- var isBoxSizeOuter;
1063
+ /**
1064
+ * Fetches the events object and creates one if required.
1065
+ *
1066
+ * @return {Object} The events storage object.
1067
+ * @api private
1068
+ */
1069
+ proto._getEvents = function _getEvents() {
1070
+ return this._events || (this._events = {});
1071
+ };
738
1072
 
739
- /**
740
- * WebKit measures the outer-width on style.width on border-box elems
741
- * IE & Firefox measures the inner-width
742
- */
743
- ( function() {
744
- if ( !boxSizingProp ) {
745
- return;
746
- }
1073
+ /**
1074
+ * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
1075
+ *
1076
+ * @return {Function} Non conflicting EventEmitter class.
1077
+ */
1078
+ EventEmitter.noConflict = function noConflict() {
1079
+ exports.EventEmitter = originalGlobalValue;
1080
+ return EventEmitter;
1081
+ };
747
1082
 
748
- var div = document.createElement('div');
749
- div.style.width = '200px';
750
- div.style.padding = '1px 2px 3px 4px';
751
- div.style.borderStyle = 'solid';
752
- div.style.borderWidth = '1px 2px 3px 4px';
753
- div.style[ boxSizingProp ] = 'border-box';
1083
+ // Expose the class either via AMD, CommonJS or the global object
1084
+ if (typeof define === 'function' && define.amd) {
1085
+ define('eventEmitter/EventEmitter',[],function () {
1086
+ return EventEmitter;
1087
+ });
1088
+ }
1089
+ else if (typeof module === 'object' && module.exports){
1090
+ module.exports = EventEmitter;
1091
+ }
1092
+ else {
1093
+ exports.EventEmitter = EventEmitter;
1094
+ }
1095
+ }.call(this));
754
1096
 
755
- var body = document.body || document.documentElement;
756
- body.appendChild( div );
757
- var style = getStyle( div );
1097
+ /*!
1098
+ * Unipointer v1.1.0
1099
+ * base class for doing one thing with pointer event
1100
+ * MIT license
1101
+ */
758
1102
 
759
- isBoxSizeOuter = getStyleSize( style.width ) === 200;
760
- body.removeChild( div );
761
- })();
1103
+ /*jshint browser: true, undef: true, unused: true, strict: true */
1104
+ /*global define: false, module: false, require: false */
762
1105
 
1106
+ ( function( window, factory ) {
763
1107
 
764
- // -------------------------- getSize -------------------------- //
1108
+ // universal module definition
765
1109
 
766
- function getSize( elem ) {
767
- // use querySeletor if elem is string
768
- if ( typeof elem === 'string' ) {
769
- elem = document.querySelector( elem );
1110
+ if ( typeof define == 'function' && define.amd ) {
1111
+ // AMD
1112
+ define( 'unipointer/unipointer',[
1113
+ 'eventEmitter/EventEmitter',
1114
+ 'eventie/eventie'
1115
+ ], function( EventEmitter, eventie ) {
1116
+ return factory( window, EventEmitter, eventie );
1117
+ });
1118
+ } else if ( typeof exports == 'object' ) {
1119
+ // CommonJS
1120
+ module.exports = factory(
1121
+ window,
1122
+ require('wolfy87-eventemitter'),
1123
+ require('eventie')
1124
+ );
1125
+ } else {
1126
+ // browser global
1127
+ window.Unipointer = factory(
1128
+ window,
1129
+ window.EventEmitter,
1130
+ window.eventie
1131
+ );
770
1132
  }
771
1133
 
772
- // do not proceed on non-objects
773
- if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
774
- return;
775
- }
1134
+ }( window, function factory( window, EventEmitter, eventie ) {
776
1135
 
777
- var style = getStyle( elem );
778
1136
 
779
- // if hidden, everything is 0
780
- if ( style.display === 'none' ) {
781
- return getZeroSize();
782
- }
783
1137
 
784
- var size = {};
785
- size.width = elem.offsetWidth;
786
- size.height = elem.offsetHeight;
1138
+ function noop() {}
787
1139
 
788
- var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
789
- style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
1140
+ function Unipointer() {}
790
1141
 
791
- // get all measurements
792
- for ( var i=0, len = measurements.length; i < len; i++ ) {
793
- var measurement = measurements[i];
794
- var value = style[ measurement ];
795
- var num = parseFloat( value );
796
- // any 'auto', 'medium' value will be 0
797
- size[ measurement ] = !isNaN( num ) ? num : 0;
1142
+ // inherit EventEmitter
1143
+ Unipointer.prototype = new EventEmitter();
1144
+
1145
+ Unipointer.prototype.bindStartEvent = function( elem ) {
1146
+ this._bindStartEvent( elem, true );
1147
+ };
1148
+
1149
+ Unipointer.prototype.unbindStartEvent = function( elem ) {
1150
+ this._bindStartEvent( elem, false );
1151
+ };
1152
+
1153
+ /**
1154
+ * works as unbinder, as you can ._bindStart( false ) to unbind
1155
+ * @param {Boolean} isBind - will unbind if falsey
1156
+ */
1157
+ Unipointer.prototype._bindStartEvent = function( elem, isBind ) {
1158
+ // munge isBind, default to true
1159
+ isBind = isBind === undefined ? true : !!isBind;
1160
+ var bindMethod = isBind ? 'bind' : 'unbind';
1161
+
1162
+ if ( window.navigator.pointerEnabled ) {
1163
+ // W3C Pointer Events, IE11. See https://coderwall.com/p/mfreca
1164
+ eventie[ bindMethod ]( elem, 'pointerdown', this );
1165
+ } else if ( window.navigator.msPointerEnabled ) {
1166
+ // IE10 Pointer Events
1167
+ eventie[ bindMethod ]( elem, 'MSPointerDown', this );
1168
+ } else {
1169
+ // listen for both, for devices like Chrome Pixel
1170
+ eventie[ bindMethod ]( elem, 'mousedown', this );
1171
+ eventie[ bindMethod ]( elem, 'touchstart', this );
1172
+ }
1173
+ };
1174
+
1175
+ // trigger handler methods for events
1176
+ Unipointer.prototype.handleEvent = function( event ) {
1177
+ var method = 'on' + event.type;
1178
+ if ( this[ method ] ) {
1179
+ this[ method ]( event );
1180
+ }
1181
+ };
1182
+
1183
+ // returns the touch that we're keeping track of
1184
+ Unipointer.prototype.getTouch = function( touches ) {
1185
+ for ( var i=0, len = touches.length; i < len; i++ ) {
1186
+ var touch = touches[i];
1187
+ if ( touch.identifier == this.pointerIdentifier ) {
1188
+ return touch;
1189
+ }
1190
+ }
1191
+ };
1192
+
1193
+ // ----- start event ----- //
1194
+
1195
+ Unipointer.prototype.onmousedown = function( event ) {
1196
+ // dismiss clicks from right or middle buttons
1197
+ var button = event.button;
1198
+ if ( button && ( button !== 0 && button !== 1 ) ) {
1199
+ return;
1200
+ }
1201
+ this._pointerDown( event, event );
1202
+ };
1203
+
1204
+ Unipointer.prototype.ontouchstart = function( event ) {
1205
+ this._pointerDown( event, event.changedTouches[0] );
1206
+ };
1207
+
1208
+ Unipointer.prototype.onMSPointerDown =
1209
+ Unipointer.prototype.onpointerdown = function( event ) {
1210
+ this._pointerDown( event, event );
1211
+ };
1212
+
1213
+ /**
1214
+ * pointer start
1215
+ * @param {Event} event
1216
+ * @param {Event or Touch} pointer
1217
+ */
1218
+ Unipointer.prototype._pointerDown = function( event, pointer ) {
1219
+ // dismiss other pointers
1220
+ if ( this.isPointerDown ) {
1221
+ return;
1222
+ }
1223
+
1224
+ this.isPointerDown = true;
1225
+ // save pointer identifier to match up touch events
1226
+ this.pointerIdentifier = pointer.pointerId !== undefined ?
1227
+ // pointerId for pointer events, touch.indentifier for touch events
1228
+ pointer.pointerId : pointer.identifier;
1229
+
1230
+ this.pointerDown( event, pointer );
1231
+ };
1232
+
1233
+ Unipointer.prototype.pointerDown = function( event, pointer ) {
1234
+ this._bindPostStartEvents( event );
1235
+ this.emitEvent( 'pointerDown', [ event, pointer ] );
1236
+ };
1237
+
1238
+ // hash of events to be bound after start event
1239
+ var postStartEvents = {
1240
+ mousedown: [ 'mousemove', 'mouseup' ],
1241
+ touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
1242
+ pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
1243
+ MSPointerDown: [ 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel' ]
1244
+ };
1245
+
1246
+ Unipointer.prototype._bindPostStartEvents = function( event ) {
1247
+ if ( !event ) {
1248
+ return;
1249
+ }
1250
+ // get proper events to match start event
1251
+ var events = postStartEvents[ event.type ];
1252
+ // IE8 needs to be bound to document
1253
+ var node = event.preventDefault ? window : document;
1254
+ // bind events to node
1255
+ for ( var i=0, len = events.length; i < len; i++ ) {
1256
+ var evnt = events[i];
1257
+ eventie.bind( node, evnt, this );
1258
+ }
1259
+ // save these arguments
1260
+ this._boundPointerEvents = {
1261
+ events: events,
1262
+ node: node
1263
+ };
1264
+ };
1265
+
1266
+ Unipointer.prototype._unbindPostStartEvents = function() {
1267
+ var args = this._boundPointerEvents;
1268
+ // IE8 can trigger dragEnd twice, check for _boundEvents
1269
+ if ( !args || !args.events ) {
1270
+ return;
1271
+ }
1272
+
1273
+ for ( var i=0, len = args.events.length; i < len; i++ ) {
1274
+ var event = args.events[i];
1275
+ eventie.unbind( args.node, event, this );
1276
+ }
1277
+ delete this._boundPointerEvents;
1278
+ };
1279
+
1280
+ // ----- move event ----- //
1281
+
1282
+ Unipointer.prototype.onmousemove = function( event ) {
1283
+ this._pointerMove( event, event );
1284
+ };
1285
+
1286
+ Unipointer.prototype.onMSPointerMove =
1287
+ Unipointer.prototype.onpointermove = function( event ) {
1288
+ if ( event.pointerId == this.pointerIdentifier ) {
1289
+ this._pointerMove( event, event );
1290
+ }
1291
+ };
1292
+
1293
+ Unipointer.prototype.ontouchmove = function( event ) {
1294
+ var touch = this.getTouch( event.changedTouches );
1295
+ if ( touch ) {
1296
+ this._pointerMove( event, touch );
1297
+ }
1298
+ };
1299
+
1300
+ /**
1301
+ * pointer move
1302
+ * @param {Event} event
1303
+ * @param {Event or Touch} pointer
1304
+ * @private
1305
+ */
1306
+ Unipointer.prototype._pointerMove = function( event, pointer ) {
1307
+ this.pointerMove( event, pointer );
1308
+ };
1309
+
1310
+ // public
1311
+ Unipointer.prototype.pointerMove = function( event, pointer ) {
1312
+ this.emitEvent( 'pointerMove', [ event, pointer ] );
1313
+ };
1314
+
1315
+ // ----- end event ----- //
1316
+
1317
+
1318
+ Unipointer.prototype.onmouseup = function( event ) {
1319
+ this._pointerUp( event, event );
1320
+ };
1321
+
1322
+ Unipointer.prototype.onMSPointerUp =
1323
+ Unipointer.prototype.onpointerup = function( event ) {
1324
+ if ( event.pointerId == this.pointerIdentifier ) {
1325
+ this._pointerUp( event, event );
1326
+ }
1327
+ };
1328
+
1329
+ Unipointer.prototype.ontouchend = function( event ) {
1330
+ var touch = this.getTouch( event.changedTouches );
1331
+ if ( touch ) {
1332
+ this._pointerUp( event, touch );
1333
+ }
1334
+ };
1335
+
1336
+ /**
1337
+ * pointer up
1338
+ * @param {Event} event
1339
+ * @param {Event or Touch} pointer
1340
+ * @private
1341
+ */
1342
+ Unipointer.prototype._pointerUp = function( event, pointer ) {
1343
+ this._pointerDone();
1344
+ this.pointerUp( event, pointer );
1345
+ };
1346
+
1347
+ // public
1348
+ Unipointer.prototype.pointerUp = function( event, pointer ) {
1349
+ this.emitEvent( 'pointerUp', [ event, pointer ] );
1350
+ };
1351
+
1352
+ // ----- pointer done ----- //
1353
+
1354
+ // triggered on pointer up & pointer cancel
1355
+ Unipointer.prototype._pointerDone = function() {
1356
+ // reset properties
1357
+ this.isPointerDown = false;
1358
+ delete this.pointerIdentifier;
1359
+ // remove events
1360
+ this._unbindPostStartEvents();
1361
+ this.pointerDone();
1362
+ };
1363
+
1364
+ Unipointer.prototype.pointerDone = noop;
1365
+
1366
+ // ----- pointer cancel ----- //
1367
+
1368
+ Unipointer.prototype.onMSPointerCancel =
1369
+ Unipointer.prototype.onpointercancel = function( event ) {
1370
+ if ( event.pointerId == this.pointerIdentifier ) {
1371
+ this._pointerCancel( event, event );
1372
+ }
1373
+ };
1374
+
1375
+ Unipointer.prototype.ontouchcancel = function( event ) {
1376
+ var touch = this.getTouch( event.changedTouches );
1377
+ if ( touch ) {
1378
+ this._pointerCancel( event, touch );
1379
+ }
1380
+ };
1381
+
1382
+ /**
1383
+ * pointer cancel
1384
+ * @param {Event} event
1385
+ * @param {Event or Touch} pointer
1386
+ * @private
1387
+ */
1388
+ Unipointer.prototype._pointerCancel = function( event, pointer ) {
1389
+ this._pointerDone();
1390
+ this.pointerCancel( event, pointer );
1391
+ };
1392
+
1393
+ // public
1394
+ Unipointer.prototype.pointerCancel = function( event, pointer ) {
1395
+ this.emitEvent( 'pointerCancel', [ event, pointer ] );
1396
+ };
1397
+
1398
+ // ----- ----- //
1399
+
1400
+ // utility function for getting x/y cooridinates from event, because IE8
1401
+ Unipointer.getPointerPoint = function( pointer ) {
1402
+ return {
1403
+ x: pointer.pageX !== undefined ? pointer.pageX : pointer.clientX,
1404
+ y: pointer.pageY !== undefined ? pointer.pageY : pointer.clientY
1405
+ };
1406
+ };
1407
+
1408
+ // ----- ----- //
1409
+
1410
+ return Unipointer;
1411
+
1412
+ }));
1413
+
1414
+ /*!
1415
+ * Unidragger v1.1.0
1416
+ * Draggable base class
1417
+ * MIT license
1418
+ */
1419
+
1420
+ /*jshint browser: true, unused: true, undef: true, strict: true */
1421
+
1422
+ ( function( window, factory ) {
1423
+ /*global define: false, module: false, require: false */
1424
+
1425
+ // universal module definition
1426
+
1427
+ if ( typeof define == 'function' && define.amd ) {
1428
+ // AMD
1429
+ define( 'unidragger/unidragger',[
1430
+ 'eventie/eventie',
1431
+ 'unipointer/unipointer'
1432
+ ], function( eventie, Unipointer ) {
1433
+ return factory( window, eventie, Unipointer );
1434
+ });
1435
+ } else if ( typeof exports == 'object' ) {
1436
+ // CommonJS
1437
+ module.exports = factory(
1438
+ window,
1439
+ require('eventie'),
1440
+ require('unipointer')
1441
+ );
1442
+ } else {
1443
+ // browser global
1444
+ window.Unidragger = factory(
1445
+ window,
1446
+ window.eventie,
1447
+ window.Unipointer
1448
+ );
1449
+ }
1450
+
1451
+ }( window, function factory( window, eventie, Unipointer ) {
1452
+
1453
+
1454
+
1455
+ // ----- ----- //
1456
+
1457
+ function noop() {}
1458
+
1459
+ // handle IE8 prevent default
1460
+ function preventDefaultEvent( event ) {
1461
+ if ( event.preventDefault ) {
1462
+ event.preventDefault();
1463
+ } else {
1464
+ event.returnValue = false;
1465
+ }
1466
+ }
1467
+
1468
+ function getParentLink( elem ) {
1469
+ while ( elem != document.body ) {
1470
+ elem = elem.parentNode;
1471
+ if ( elem.nodeName == 'A' ) {
1472
+ return elem;
1473
+ }
1474
+ }
1475
+ }
1476
+
1477
+ // -------------------------- Unidragger -------------------------- //
1478
+
1479
+ function Unidragger() {}
1480
+
1481
+ // inherit Unipointer & EventEmitter
1482
+ Unidragger.prototype = new Unipointer();
1483
+
1484
+ // ----- bind start ----- //
1485
+
1486
+ Unidragger.prototype.bindHandles = function() {
1487
+ this._bindHandles( true );
1488
+ };
1489
+
1490
+ Unidragger.prototype.unbindHandles = function() {
1491
+ this._bindHandles( false );
1492
+ };
1493
+
1494
+ var navigator = window.navigator;
1495
+ /**
1496
+ * works as unbinder, as you can .bindHandles( false ) to unbind
1497
+ * @param {Boolean} isBind - will unbind if falsey
1498
+ */
1499
+ Unidragger.prototype._bindHandles = function( isBind ) {
1500
+ // munge isBind, default to true
1501
+ isBind = isBind === undefined ? true : !!isBind;
1502
+ // extra bind logic
1503
+ var binderExtra;
1504
+ if ( navigator.pointerEnabled ) {
1505
+ binderExtra = function( handle ) {
1506
+ // disable scrolling on the element
1507
+ handle.style.touchAction = isBind ? 'none' : '';
1508
+ };
1509
+ } else if ( navigator.msPointerEnabled ) {
1510
+ binderExtra = function( handle ) {
1511
+ // disable scrolling on the element
1512
+ handle.style.msTouchAction = isBind ? 'none' : '';
1513
+ };
1514
+ } else {
1515
+ binderExtra = function() {
1516
+ // TODO re-enable img.ondragstart when unbinding
1517
+ if ( isBind ) {
1518
+ disableImgOndragstart( handle );
1519
+ }
1520
+ };
798
1521
  }
1522
+ // bind each handle
1523
+ var bindMethod = isBind ? 'bind' : 'unbind';
1524
+ for ( var i=0, len = this.handles.length; i < len; i++ ) {
1525
+ var handle = this.handles[i];
1526
+ this._bindStartEvent( handle, isBind );
1527
+ binderExtra( handle );
1528
+ eventie[ bindMethod ]( handle, 'click', this );
1529
+ }
1530
+ };
1531
+
1532
+ // remove default dragging interaction on all images in IE8
1533
+ // IE8 does its own drag thing on images, which messes stuff up
1534
+
1535
+ function noDragStart() {
1536
+ return false;
1537
+ }
1538
+
1539
+ // TODO replace this with a IE8 test
1540
+ var isIE8 = 'attachEvent' in document.documentElement;
1541
+
1542
+ // IE8 only
1543
+ var disableImgOndragstart = !isIE8 ? noop : function( handle ) {
1544
+
1545
+ if ( handle.nodeName == 'IMG' ) {
1546
+ handle.ondragstart = noDragStart;
1547
+ }
1548
+
1549
+ var images = handle.querySelectorAll('img');
1550
+ for ( var i=0, len = images.length; i < len; i++ ) {
1551
+ var img = images[i];
1552
+ img.ondragstart = noDragStart;
1553
+ }
1554
+ };
1555
+
1556
+ // ----- start event ----- //
1557
+
1558
+ var allowTouchstartNodes = Unidragger.allowTouchstartNodes = {
1559
+ INPUT: true,
1560
+ A: true,
1561
+ BUTTON: true,
1562
+ SELECT: true
1563
+ };
1564
+
1565
+ /**
1566
+ * pointer start
1567
+ * @param {Event} event
1568
+ * @param {Event or Touch} pointer
1569
+ */
1570
+ Unidragger.prototype.pointerDown = function( event, pointer ) {
1571
+ this._dragPointerDown( event, pointer );
1572
+ // kludge to blur focused inputs in dragger
1573
+ var focused = document.activeElement;
1574
+ if ( focused && focused.blur ) {
1575
+ focused.blur();
1576
+ }
1577
+ // bind move and end events
1578
+ this._bindPostStartEvents( event );
1579
+ this.emitEvent( 'pointerDown', [ event, pointer ] );
1580
+ };
1581
+
1582
+ // base pointer down logic
1583
+ Unidragger.prototype._dragPointerDown = function( event, pointer ) {
1584
+ // track to see when dragging starts
1585
+ this.pointerDownPoint = Unipointer.getPointerPoint( pointer );
1586
+
1587
+ var targetNodeName = event.target.nodeName;
1588
+ // HACK iOS, allow clicks on buttons, inputs, and links, or children of links
1589
+ var isTouchstartNode = event.type == 'touchstart' &&
1590
+ ( allowTouchstartNodes[ targetNodeName ] || getParentLink( event.target ) );
1591
+ // do not prevent default on touchstart nodes or <select>
1592
+ if ( !isTouchstartNode && targetNodeName != 'SELECT' ) {
1593
+ preventDefaultEvent( event );
1594
+ }
1595
+ };
1596
+
1597
+ // ----- move event ----- //
1598
+
1599
+ /**
1600
+ * drag move
1601
+ * @param {Event} event
1602
+ * @param {Event or Touch} pointer
1603
+ */
1604
+ Unidragger.prototype.pointerMove = function( event, pointer ) {
1605
+ var moveVector = this._dragPointerMove( event, pointer );
1606
+ this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
1607
+ this._dragMove( event, pointer, moveVector );
1608
+ };
1609
+
1610
+ // base pointer move logic
1611
+ Unidragger.prototype._dragPointerMove = function( event, pointer ) {
1612
+ var movePoint = Unipointer.getPointerPoint( pointer );
1613
+ var moveVector = {
1614
+ x: movePoint.x - this.pointerDownPoint.x,
1615
+ y: movePoint.y - this.pointerDownPoint.y
1616
+ };
1617
+ // start drag if pointer has moved far enough to start drag
1618
+ if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
1619
+ this._dragStart( event, pointer );
1620
+ }
1621
+ return moveVector;
1622
+ };
1623
+
1624
+ // condition if pointer has moved far enough to start drag
1625
+ Unidragger.prototype.hasDragStarted = function( moveVector ) {
1626
+ return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
1627
+ };
1628
+
1629
+
1630
+ // ----- end event ----- //
1631
+
1632
+ /**
1633
+ * pointer up
1634
+ * @param {Event} event
1635
+ * @param {Event or Touch} pointer
1636
+ */
1637
+ Unidragger.prototype.pointerUp = function( event, pointer ) {
1638
+ this.emitEvent( 'pointerUp', [ event, pointer ] );
1639
+ this._dragPointerUp( event, pointer );
1640
+ };
1641
+
1642
+ Unidragger.prototype._dragPointerUp = function( event, pointer ) {
1643
+ if ( this.isDragging ) {
1644
+ this._dragEnd( event, pointer );
1645
+ } else {
1646
+ // pointer didn't move enough for drag to start
1647
+ this._staticClick( event, pointer );
1648
+ }
1649
+ };
1650
+
1651
+ // -------------------------- drag -------------------------- //
1652
+
1653
+ // dragStart
1654
+ Unidragger.prototype._dragStart = function( event, pointer ) {
1655
+ this.isDragging = true;
1656
+ this.dragStartPoint = Unidragger.getPointerPoint( pointer );
1657
+ // prevent clicks
1658
+ this.isPreventingClicks = true;
1659
+
1660
+ this.dragStart( event, pointer );
1661
+ };
1662
+
1663
+ Unidragger.prototype.dragStart = function( event, pointer ) {
1664
+ this.emitEvent( 'dragStart', [ event, pointer ] );
1665
+ };
1666
+
1667
+ // dragMove
1668
+ Unidragger.prototype._dragMove = function( event, pointer, moveVector ) {
1669
+ // do not drag if not dragging yet
1670
+ if ( !this.isDragging ) {
1671
+ return;
1672
+ }
1673
+
1674
+ this.dragMove( event, pointer, moveVector );
1675
+ };
1676
+
1677
+ Unidragger.prototype.dragMove = function( event, pointer, moveVector ) {
1678
+ this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
1679
+ };
799
1680
 
800
- var paddingWidth = size.paddingLeft + size.paddingRight;
801
- var paddingHeight = size.paddingTop + size.paddingBottom;
802
- var marginWidth = size.marginLeft + size.marginRight;
803
- var marginHeight = size.marginTop + size.marginBottom;
804
- var borderWidth = size.borderLeftWidth + size.borderRightWidth;
805
- var borderHeight = size.borderTopWidth + size.borderBottomWidth;
1681
+ // dragEnd
1682
+ Unidragger.prototype._dragEnd = function( event, pointer ) {
1683
+ // set flags
1684
+ this.isDragging = false;
1685
+ // re-enable clicking async
1686
+ var _this = this;
1687
+ setTimeout( function() {
1688
+ delete _this.isPreventingClicks;
1689
+ });
806
1690
 
807
- var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
1691
+ this.dragEnd( event, pointer );
1692
+ };
808
1693
 
809
- // overwrite width and height if we can get it from style
810
- var styleWidth = getStyleSize( style.width );
811
- if ( styleWidth !== false ) {
812
- size.width = styleWidth +
813
- // add padding and border unless it's already including it
814
- ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
1694
+ Unidragger.prototype.dragEnd = function( event, pointer ) {
1695
+ this.emitEvent( 'dragEnd', [ event, pointer ] );
1696
+ };
1697
+
1698
+ // ----- onclick ----- //
1699
+
1700
+ // handle all clicks and prevent clicks when dragging
1701
+ Unidragger.prototype.onclick = function( event ) {
1702
+ if ( this.isPreventingClicks ) {
1703
+ preventDefaultEvent( event );
815
1704
  }
1705
+ };
816
1706
 
817
- var styleHeight = getStyleSize( style.height );
818
- if ( styleHeight !== false ) {
819
- size.height = styleHeight +
820
- // add padding and border unless it's already including it
821
- ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
1707
+ // ----- staticClick ----- //
1708
+
1709
+ // triggered after pointer down & up with no/tiny movement
1710
+ Unidragger.prototype._staticClick = function( event, pointer ) {
1711
+ // allow click in text input
1712
+ if ( event.target.nodeName == 'INPUT' && event.target.type == 'text' ) {
1713
+ event.target.focus();
822
1714
  }
1715
+ this.staticClick( event, pointer );
1716
+ };
823
1717
 
824
- size.innerWidth = size.width - ( paddingWidth + borderWidth );
825
- size.innerHeight = size.height - ( paddingHeight + borderHeight );
1718
+ Unidragger.prototype.staticClick = function( event, pointer ) {
1719
+ this.emitEvent( 'staticClick', [ event, pointer ] );
1720
+ };
826
1721
 
827
- size.outerWidth = size.width + marginWidth;
828
- size.outerHeight = size.height + marginHeight;
1722
+ // ----- ----- //
829
1723
 
830
- return size;
831
- }
1724
+ Unidragger.getPointerPoint = function( pointer ) {
1725
+ return {
1726
+ x: pointer.pageX !== undefined ? pointer.pageX : pointer.clientX,
1727
+ y: pointer.pageY !== undefined ? pointer.pageY : pointer.clientY
1728
+ };
1729
+ };
832
1730
 
833
- return getSize;
1731
+ // ----- ----- //
834
1732
 
835
- }
1733
+ Unidragger.getPointerPoint = Unipointer.getPointerPoint;
836
1734
 
837
- // transport
838
- if ( typeof define === 'function' && define.amd ) {
839
- // AMD
840
- define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
841
- } else {
842
- // browser global
843
- window.getSize = defineGetSize( window.getStyleProperty );
844
- }
1735
+ return Unidragger;
845
1736
 
846
- })( window );
1737
+ }));
847
1738
 
848
1739
  /*!
849
- * Draggabilly v1.1.1
1740
+ * Draggabilly v1.2.4
850
1741
  * Make that shiz draggable
851
1742
  * http://draggabilly.desandro.com
852
1743
  * MIT license
853
1744
  */
854
1745
 
855
- ( function( window ) {
1746
+ ( function( window, factory ) {
1747
+
1748
+
1749
+ if ( typeof define == 'function' && define.amd ) {
1750
+ // AMD
1751
+ define( [
1752
+ 'classie/classie',
1753
+ 'get-style-property/get-style-property',
1754
+ 'get-size/get-size',
1755
+ 'unidragger/unidragger'
1756
+ ],
1757
+ function( classie, getStyleProperty, getSize, Unidragger ) {
1758
+ return factory( window, classie, getStyleProperty, getSize, Unidragger );
1759
+ });
1760
+ } else if ( typeof exports == 'object' ) {
1761
+ // CommonJS
1762
+ module.exports = factory(
1763
+ window,
1764
+ require('desandro-classie'),
1765
+ require('desandro-get-style-property'),
1766
+ require('get-size'),
1767
+ require('unidragger')
1768
+ );
1769
+ } else {
1770
+ // browser global
1771
+ window.Draggabilly = factory(
1772
+ window,
1773
+ window.classie,
1774
+ window.getStyleProperty,
1775
+ window.getSize,
1776
+ window.Unidragger
1777
+ );
1778
+ }
1779
+
1780
+ }( window, function factory( window, classie, getStyleProperty, getSize, Unidragger ) {
856
1781
 
857
1782
 
858
1783
 
859
1784
  // vars
860
1785
  var document = window.document;
861
1786
 
1787
+ function noop() {}
1788
+
862
1789
  // -------------------------- helpers -------------------------- //
863
1790
 
864
1791
  // extend objects
@@ -869,8 +1796,6 @@ function extend( a, b ) {
869
1796
  return a;
870
1797
  }
871
1798
 
872
- function noop() {}
873
-
874
1799
  // ----- get style ----- //
875
1800
 
876
1801
  var defView = document.defaultView;
@@ -885,13 +1810,13 @@ var getStyle = defView && defView.getComputedStyle ?
885
1810
 
886
1811
 
887
1812
  // http://stackoverflow.com/a/384380/182183
888
- var isElement = ( typeof HTMLElement === 'object' ) ?
1813
+ var isElement = ( typeof HTMLElement == 'object' ) ?
889
1814
  function isElementDOM2( obj ) {
890
1815
  return obj instanceof HTMLElement;
891
1816
  } :
892
1817
  function isElementQuirky( obj ) {
893
- return obj && typeof obj === 'object' &&
894
- obj.nodeType === 1 && typeof obj.nodeName === 'string';
1818
+ return obj && typeof obj == 'object' &&
1819
+ obj.nodeType == 1 && typeof obj.nodeName == 'string';
895
1820
  };
896
1821
 
897
1822
  // -------------------------- requestAnimationFrame -------------------------- //
@@ -932,33 +1857,44 @@ if ( !requestAnimationFrame || !cancelAnimationFrame ) {
932
1857
  };
933
1858
  }
934
1859
 
935
- // -------------------------- definition -------------------------- //
936
-
937
- function draggabillyDefinition( classie, EventEmitter, eventie, getStyleProperty, getSize ) {
938
-
939
1860
  // -------------------------- support -------------------------- //
940
1861
 
941
1862
  var transformProperty = getStyleProperty('transform');
942
1863
  // TODO fix quick & dirty check for 3D support
943
1864
  var is3d = !!getStyleProperty('perspective');
944
1865
 
1866
+ var jQuery = window.jQuery;
1867
+
945
1868
  // -------------------------- -------------------------- //
946
1869
 
947
1870
  function Draggabilly( element, options ) {
948
1871
  // querySelector if string
949
- this.element = typeof element === 'string' ?
1872
+ this.element = typeof element == 'string' ?
950
1873
  document.querySelector( element ) : element;
951
1874
 
952
- this.options = extend( {}, this.options );
953
- extend( this.options, options );
1875
+ if ( jQuery ) {
1876
+ this.$element = jQuery( this.element );
1877
+ }
1878
+
1879
+ // options
1880
+ this.options = extend( {}, this.constructor.defaults );
1881
+ this.option( options );
954
1882
 
955
1883
  this._create();
956
1884
  }
957
1885
 
958
- // inherit EventEmitter methods
959
- extend( Draggabilly.prototype, EventEmitter.prototype );
1886
+ // inherit Unidragger methods
1887
+ extend( Draggabilly.prototype, Unidragger.prototype );
1888
+
1889
+ Draggabilly.defaults = {
1890
+ };
960
1891
 
961
- Draggabilly.prototype.options = {
1892
+ /**
1893
+ * set options
1894
+ * @param {Object} opts
1895
+ */
1896
+ Draggabilly.prototype.option = function( opts ) {
1897
+ extend( this.options, opts );
962
1898
  };
963
1899
 
964
1900
  Draggabilly.prototype._create = function() {
@@ -974,7 +1910,7 @@ Draggabilly.prototype._create = function() {
974
1910
 
975
1911
  // set relative positioning
976
1912
  var style = getStyle( this.element );
977
- if ( style.position !== 'relative' && style.position !== 'absolute' ) {
1913
+ if ( style.position != 'relative' && style.position != 'absolute' ) {
978
1914
  this.element.style.position = 'relative';
979
1915
  }
980
1916
 
@@ -990,53 +1926,34 @@ Draggabilly.prototype.setHandles = function() {
990
1926
  this.handles = this.options.handle ?
991
1927
  this.element.querySelectorAll( this.options.handle ) : [ this.element ];
992
1928
 
993
- for ( var i=0, len = this.handles.length; i < len; i++ ) {
994
- var handle = this.handles[i];
995
- // bind pointer start event
996
- if ( window.navigator.pointerEnabled ) {
997
- // W3C Pointer Events, IE11. See https://coderwall.com/p/mfreca
998
- eventie.bind( handle, 'pointerdown', this );
999
- // disable scrolling on the element
1000
- handle.style.touchAction = 'none';
1001
- } else if ( window.navigator.msPointerEnabled ) {
1002
- // IE10 Pointer Events
1003
- eventie.bind( handle, 'MSPointerDown', this );
1004
- // disable scrolling on the element
1005
- handle.style.msTouchAction = 'none';
1006
- } else {
1007
- // listen for both, for devices like Chrome Pixel
1008
- // which has touch and mouse events
1009
- eventie.bind( handle, 'mousedown', this );
1010
- eventie.bind( handle, 'touchstart', this );
1011
- disableImgOndragstart( handle );
1012
- }
1013
- }
1929
+ this.bindHandles();
1014
1930
  };
1015
1931
 
1016
- // remove default dragging interaction on all images in IE8
1017
- // IE8 does its own drag thing on images, which messes stuff up
1018
-
1019
- function noDragStart() {
1020
- return false;
1021
- }
1022
-
1023
- // TODO replace this with a IE8 test
1024
- var isIE8 = 'attachEvent' in document.documentElement;
1025
-
1026
- // IE8 only
1027
- var disableImgOndragstart = !isIE8 ? noop : function( handle ) {
1028
-
1029
- if ( handle.nodeName === 'IMG' ) {
1030
- handle.ondragstart = noDragStart;
1031
- }
1032
-
1033
- var images = handle.querySelectorAll('img');
1034
- for ( var i=0, len = images.length; i < len; i++ ) {
1035
- var img = images[i];
1036
- img.ondragstart = noDragStart;
1932
+ /**
1933
+ * emits events via eventEmitter and jQuery events
1934
+ * @param {String} type - name of event
1935
+ * @param {Event} event - original event
1936
+ * @param {Array} args - extra arguments
1937
+ */
1938
+ Draggabilly.prototype.dispatchEvent = function( type, event, args ) {
1939
+ var emitArgs = [ event ].concat( args );
1940
+ this.emitEvent( type, emitArgs );
1941
+ var jQuery = window.jQuery;
1942
+ // trigger jQuery event
1943
+ if ( jQuery && this.$element ) {
1944
+ if ( event ) {
1945
+ // create jQuery event
1946
+ var $event = jQuery.Event( event );
1947
+ $event.type = type;
1948
+ this.$element.trigger( $event, args );
1949
+ } else {
1950
+ // just trigger with type if no event available
1951
+ this.$element.trigger( type, args );
1952
+ }
1037
1953
  }
1038
1954
  };
1039
1955
 
1956
+ // -------------------------- position -------------------------- //
1040
1957
 
1041
1958
  // get left/top position from style
1042
1959
  Draggabilly.prototype._getPosition = function() {
@@ -1076,65 +1993,33 @@ Draggabilly.prototype._addTransformPosition = function( style ) {
1076
1993
 
1077
1994
  // -------------------------- events -------------------------- //
1078
1995
 
1079
- // trigger handler methods for events
1080
- Draggabilly.prototype.handleEvent = function( event ) {
1081
- var method = 'on' + event.type;
1082
- if ( this[ method ] ) {
1083
- this[ method ]( event );
1084
- }
1085
- };
1086
-
1087
- // returns the touch that we're keeping track of
1088
- Draggabilly.prototype.getTouch = function( touches ) {
1089
- for ( var i=0, len = touches.length; i < len; i++ ) {
1090
- var touch = touches[i];
1091
- if ( touch.identifier === this.pointerIdentifier ) {
1092
- return touch;
1093
- }
1094
- }
1095
-