jquery-unslider-rails 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a70b38df6accd06831f86e04323ef4769d0974ad
4
+ data.tar.gz: 96fe4c2da750b90fb50cd515937d9be63ae5c2f3
5
+ SHA512:
6
+ metadata.gz: 1fbaa393e7e173a472308373e553ed9d8fa70c7ed1d2e80da86643c57b04b7b02f02a54cfd349ea5f41466f226dfc9b290128244f51774ac707802d0a5edf5e9
7
+ data.tar.gz: f912f537d24df7f262c3a13b590756be84417f868955b9cdade67b11822109db64cccb69ecbce88a2eacb9e1919aae612d9515ad593c43c2f14280db96715f0e
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ The MIT License (MIT)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # jquery-unslider-rails
2
+
3
+ [jQuery Unslider](https://github.com/idiot/unslider) plugin for jQuery, written by [Visual Idiot](https://github.com/idiot), packaged for the Rails asset pipeline.
4
+
5
+ ## Usage
6
+
7
+ This gem ships with with a minified version of the library. Feel free to use either of the following:
8
+
9
+ ```
10
+ //= require jquery-unslider
11
+ //= require jquery-unslider.min
12
+ ```
13
+
14
+ ## Disclaimer
15
+
16
+ This repo is a Rails gem package. All issues with the library should be reported on the library's [GitHub page](https://github.com/idiot/unslider). This repo will be updated each time a new version of the library is released.
@@ -0,0 +1,8 @@
1
+ require 'jquery-unslider-rails/version'
2
+
3
+ module JqueryUnsliderRails
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module JqueryUnsliderRails
2
+ module Rails
3
+ VERSION = '2.0.0'
4
+ end
5
+ end
@@ -0,0 +1,651 @@
1
+ /**
2
+ * Unslider
3
+ * version 2.0
4
+ * by @idiot and friends
5
+ */
6
+
7
+ (function(factory) {
8
+ if (typeof module === 'object' && typeof module.exports === 'object') {
9
+ factory(require('jquery'));
10
+ } else if (typeof define === 'function' && define.amd) {
11
+ // AMD. Register as an anonymous module.
12
+ define([], factory(window.jQuery));
13
+ } else {
14
+ factory(window.jQuery);
15
+ }
16
+ }(function($) {
17
+ // Don't throw any errors when jQuery
18
+ if(!$) {
19
+ return console.warn('Unslider needs jQuery');
20
+ }
21
+
22
+ $.Unslider = function(context, options) {
23
+ var self = this;
24
+
25
+ // Create an Unslider reference we can use everywhere
26
+ self._ = 'unslider';
27
+
28
+ // Store our default options in here
29
+ // Everything will be overwritten by the jQuery plugin though
30
+ self.defaults = {
31
+ // Should the slider move on its own or only when
32
+ // you interact with the nav/arrows?
33
+ // Only accepts boolean true/false.
34
+ autoplay: false,
35
+
36
+ // 3 second delay between slides moving, pass
37
+ // as a number in milliseconds.
38
+ delay: 3000,
39
+
40
+ // Animation speed in millseconds
41
+ speed: 750,
42
+
43
+ // An easing string to use. If you're using Velocity, use a
44
+ // Velocity string otherwise you can use jQuery/jQ UI options.
45
+ easing: 'swing', // [.42, 0, .58, 1],
46
+
47
+ // Does it support keyboard arrows?
48
+ // Can pass either true or false -
49
+ // or an object with the keycodes, like so:
50
+ // {
51
+ // prev: 37,
52
+ // next: 39
53
+ // }
54
+ // You can call any internal method name
55
+ // before the keycode and it'll be called.
56
+ keys: {
57
+ prev: 37,
58
+ next: 39
59
+ },
60
+
61
+ // Do you want to generate clickable navigation
62
+ // to skip to each slide? Accepts boolean true/false or
63
+ // a callback function per item to generate.
64
+ nav: true,
65
+
66
+ // Should there be left/right arrows to go back/forth?
67
+ // -> This isn't keyboard support.
68
+ // Either set true/false, or an object with the HTML
69
+ // elements for each arrow like below:
70
+ arrows: {
71
+ prev: '<a class="' + self._ + '-arrow prev">Prev</a>',
72
+ next: '<a class="' + self._ + '-arrow next">Next</a>'
73
+ },
74
+
75
+ // How should Unslider animate?
76
+ // It can do one of the following types:
77
+ // "fade": each slide fades in to each other
78
+ // "horizontal": each slide moves from left to right
79
+ // "vertical": each slide moves from top to bottom
80
+ animation: 'horizontal',
81
+
82
+ // If you don't want to use a list to display your slides,
83
+ // you can change it here. Not recommended and you'll need
84
+ // to adjust the CSS accordingly.
85
+ selectors: {
86
+ container: 'ul:first',
87
+ slides: 'li'
88
+ },
89
+
90
+ // Do you want to animate the heights of each slide as
91
+ // it moves
92
+ animateHeight: false,
93
+
94
+ // Active class for the nav
95
+ activeClass: self._ + '-active',
96
+
97
+ // Have swipe support?
98
+ // You can set this here with a boolean and always use
99
+ // initSwipe/destroySwipe later on.
100
+ swipe: true,
101
+ // Swipe threshold -
102
+ // lower float for enabling short swipe
103
+ swipeThreshold: 0.2
104
+ };
105
+
106
+ // Set defaults
107
+ self.$context = context;
108
+ self.options = {};
109
+
110
+ // Leave our elements blank for now
111
+ // Since they get changed by the options, we'll need to
112
+ // set them in the init method.
113
+ self.$parent = null;
114
+ self.$container = null;
115
+ self.$slides = null;
116
+ self.$nav = null;
117
+ self.$arrows = [];
118
+
119
+ // Set our indexes and totals
120
+ self.total = 0;
121
+ self.current = 0;
122
+
123
+ // Generate a specific random ID so we don't dupe events
124
+ self.prefix = self._ + '-';
125
+ self.eventSuffix = '.' + self.prefix + ~~(Math.random() * 2e3);
126
+
127
+ // In case we're going to use the autoplay
128
+ self.interval = null;
129
+
130
+ // Get everything set up innit
131
+ self.init = function(options) {
132
+ // Set up our options inside here so we can re-init at
133
+ // any time
134
+ self.options = $.extend({}, self.defaults, options);
135
+
136
+ // Our elements
137
+ self.$container = self.$context.find(self.options.selectors.container).addClass(self.prefix + 'wrap');
138
+ self.$slides = self.$container.children(self.options.selectors.slides);
139
+
140
+ // We'll manually init the container
141
+ self.setup();
142
+
143
+ // We want to keep this script as small as possible
144
+ // so we'll optimise some checks
145
+ $.each(['nav', 'arrows', 'keys', 'infinite'], function(index, module) {
146
+ self.options[module] && self['init' + $._ucfirst(module)]();
147
+ });
148
+
149
+ // Add swipe support
150
+ if(jQuery.event.special.swipe && self.options.swipe) {
151
+ self.initSwipe();
152
+ }
153
+
154
+ // If autoplay is set to true, call self.start()
155
+ // to start calling our timeouts
156
+ self.options.autoplay && self.start();
157
+
158
+ // We should be able to recalculate slides at will
159
+ self.calculateSlides();
160
+
161
+ // Listen to a ready event
162
+ self.$context.trigger(self._ + '.ready');
163
+
164
+ // Everyday I'm chainin'
165
+ return self.animate(self.options.index || self.current, 'init');
166
+ };
167
+
168
+ self.setup = function() {
169
+ // Add a CSS hook to the main element
170
+ self.$context.addClass(self.prefix + self.options.animation).wrap('<div class="' + self._ + '" />');
171
+ self.$parent = self.$context.parent('.' + self._);
172
+
173
+ // We need to manually check if the container is absolutely
174
+ // or relatively positioned
175
+ var position = self.$context.css('position');
176
+
177
+ // If we don't already have a position set, we'll
178
+ // automatically set it ourselves
179
+ if(position === 'static') {
180
+ self.$context.css('position', 'relative');
181
+ }
182
+
183
+ self.$context.css('overflow', 'hidden');
184
+ };
185
+
186
+ // Set up the slide widths to animate with
187
+ // so the box doesn't float over
188
+ self.calculateSlides = function() {
189
+ // update slides before recalculating the total
190
+ self.$slides = self.$container.children(self.options.selectors.slides);
191
+
192
+ self.total = self.$slides.length;
193
+
194
+ // Set the total width
195
+ if(self.options.animation !== 'fade') {
196
+ var prop = 'width';
197
+
198
+ if(self.options.animation === 'vertical') {
199
+ prop = 'height';
200
+ }
201
+
202
+ self.$container.css(prop, (self.total * 100) + '%').addClass(self.prefix + 'carousel');
203
+ self.$slides.css(prop, (100 / self.total) + '%');
204
+ }
205
+ };
206
+
207
+
208
+ // Start our autoplay
209
+ self.start = function() {
210
+ self.interval = setTimeout(function() {
211
+ // Move on to the next slide
212
+ self.next();
213
+
214
+ // If we've got autoplay set up
215
+ // we don't need to keep starting
216
+ // the slider from within our timeout
217
+ // as .animate() calls it for us
218
+ }, self.options.delay);
219
+
220
+ return self;
221
+ };
222
+
223
+ // And pause our timeouts
224
+ // and force stop the slider if needed
225
+ self.stop = function() {
226
+ clearTimeout(self.interval);
227
+
228
+ return self;
229
+ };
230
+
231
+
232
+ // Set up our navigation
233
+ self.initNav = function() {
234
+ var $nav = $('<nav class="' + self.prefix + 'nav"><ol /></nav>');
235
+
236
+ // Build our click navigation item-by-item
237
+ self.$slides.each(function(key) {
238
+ // If we've already set a label, let's use that
239
+ // instead of generating one
240
+ var label = this.getAttribute('data-nav') || key + 1;
241
+
242
+ // Listen to any callback functions
243
+ if($.isFunction(self.options.nav)) {
244
+ label = self.options.nav.call(self.$slides.eq(key), key, label);
245
+ }
246
+
247
+ // And add it to our navigation item
248
+ $nav.children('ol').append('<li data-slide="' + key + '">' + label + '</li>');
249
+ });
250
+
251
+ // Keep a copy of the nav everywhere so we can use it
252
+ self.$nav = $nav.insertAfter(self.$context);
253
+
254
+ // Now our nav is built, let's add it to the slider and bind
255
+ // for any click events on the generated links
256
+ self.$nav.find('li').on('click' + self.eventSuffix, function() {
257
+ // Cache our link and set it to be active
258
+ var $me = $(this).addClass(self.options.activeClass);
259
+
260
+ // Set the right active class, remove any other ones
261
+ $me.siblings().removeClass(self.options.activeClass);
262
+
263
+ // Move the slide
264
+ self.animate($me.attr('data-slide'));
265
+ });
266
+ };
267
+
268
+
269
+ // Set up our left-right arrow navigation
270
+ // (Not keyboard arrows, prev/next buttons)
271
+ self.initArrows = function() {
272
+ if(self.options.arrows === true) {
273
+ self.options.arrows = self.defaults.arrows;
274
+ }
275
+
276
+ // Loop our options object and bind our events
277
+ $.each(self.options.arrows, function(key, val) {
278
+ // Add our arrow HTML and bind it
279
+ self.$arrows.push(
280
+ $(val).insertAfter(self.$context).on('click' + self.eventSuffix, self[key])
281
+ );
282
+ });
283
+ };
284
+
285
+
286
+ // Set up our keyboad navigation
287
+ // Allow binding to multiple keycodes
288
+ self.initKeys = function() {
289
+ if(self.options.keys === true) {
290
+ self.options.keys = self.defaults.keys;
291
+ }
292
+
293
+ $(document).on('keyup' + self.eventSuffix, function(e) {
294
+ $.each(self.options.keys, function(key, val) {
295
+ if(e.which === val) {
296
+ $.isFunction(self[key]) && self[key].call(self);
297
+ }
298
+ });
299
+ });
300
+ };
301
+
302
+ // Requires jQuery.event.swipe
303
+ // -> stephband.info/jquery.event.swipe
304
+ self.initSwipe = function() {
305
+ var width = self.$slides.width();
306
+
307
+ // We don't want to have a tactile swipe in the slider
308
+ // in the fade animation, as it can cause some problems
309
+ // with layout, so we'll just disable it.
310
+ if(self.options.animation !== 'fade') {
311
+
312
+ self.$container.on({
313
+
314
+ movestart: function(e) {
315
+ // If the movestart heads off in a upwards or downwards
316
+ // direction, prevent it so that the browser scrolls normally.
317
+ if((e.distX > e.distY && e.distX < -e.distY) || (e.distX < e.distY && e.distX > -e.distY)) {
318
+ return !!e.preventDefault();
319
+ }
320
+
321
+ self.$container.css('position', 'relative');
322
+ },
323
+
324
+ move: function(e) {
325
+ self.$container.css('left', -(100 * self.current) + (100 * e.distX / width) + '%');
326
+ },
327
+
328
+ moveend: function(e) {
329
+ // Check if swiped distance is greater than threshold.
330
+ // If yes slide to next/prev slide. If not animate to
331
+ // starting point.
332
+
333
+ if((Math.abs(e.distX) / width) > self.options.swipeThreshold) {
334
+
335
+ self[e.distX < 0 ? 'next' : 'prev']();
336
+ }
337
+ else {
338
+
339
+ self.$container.animate({left: -(100 * self.current) + '%' }, self.options.speed / 2 );
340
+ }
341
+ }
342
+ });
343
+ }
344
+ };
345
+
346
+ // Infinite scrolling is a massive pain in the arse
347
+ // so we need to create a whole bloody function to set
348
+ // it up. Argh.
349
+ self.initInfinite = function() {
350
+ var pos = ['first', 'last'];
351
+
352
+ $.each(pos, function(index, item) {
353
+ self.$slides.push.apply(
354
+ self.$slides,
355
+
356
+ // Exclude all cloned slides and call .first() or .last()
357
+ // depending on what `item` is.
358
+ self.$slides.filter(':not(".' + self._ + '-clone")')[item]()
359
+
360
+ // Make a copy of it and identify it as a clone
361
+ .clone().addClass(self._ + '-clone')
362
+
363
+ // Either insert before or after depending on whether we're
364
+ // the first or last clone
365
+ ['insert' + (index === 0 ? 'After' : 'Before')](
366
+ // Return the other element in the position array
367
+ // if item = first, return "last"
368
+ self.$slides[pos[~~!index]]()
369
+ )
370
+ );
371
+ });
372
+ };
373
+
374
+ // Remove any trace of arrows
375
+ // Loop our array of arrows and use jQuery to remove
376
+ // It'll unbind any event handlers for us
377
+ self.destroyArrows = function() {
378
+ $.each(self.$arrows, function(i, $arrow) {
379
+ $arrow.remove();
380
+ });
381
+ };
382
+
383
+ // Remove any swipe events and reset the position
384
+ self.destroySwipe = function() {
385
+ // We bind to 4 events, so we'll unbind those
386
+ self.$container.off('movestart move moveend');
387
+ };
388
+
389
+ // Unset the keyboard navigation
390
+ // Remove the handler
391
+ self.destroyKeys = function() {
392
+ // Remove the event handler
393
+ $(document).off('keyup' + self.eventSuffix);
394
+ };
395
+
396
+ self.setIndex = function(to) {
397
+ if(to < 0) {
398
+ to = self.total - 1;
399
+ }
400
+
401
+ self.current = Math.min(Math.max(0, to), self.total - 1);
402
+
403
+ if(self.options.nav) {
404
+ self.$nav.find('[data-slide="' + self.current + '"]')._active(self.options.activeClass);
405
+ }
406
+
407
+ self.$slides.eq(self.current)._active(self.options.activeClass);
408
+
409
+ return self;
410
+ };
411
+
412
+ // Despite the name, this doesn't do any animation - since there's
413
+ // now three different types of animation, we let this method delegate
414
+ // to the right type, keeping the name for backwards compat.
415
+ self.animate = function(to, dir) {
416
+ // Animation shortcuts
417
+ // Instead of passing a number index, we can now
418
+ // use .data('unslider').animate('last');
419
+ // or .unslider('animate:last')
420
+ // to go to the very last slide
421
+ if(to === 'first') to = 0;
422
+ if(to === 'last') to = self.total;
423
+
424
+ // Don't animate if it's not a valid index
425
+ if(isNaN(to)) {
426
+ return self;
427
+ }
428
+
429
+ if(self.options.autoplay) {
430
+ self.stop().start();
431
+ }
432
+
433
+ self.setIndex(to);
434
+
435
+ // Add a callback method to do stuff with
436
+ self.$context.trigger(self._ + '.change', [to, self.$slides.eq(to)]);
437
+
438
+ // Delegate the right method - everything's named consistently
439
+ // so we can assume it'll be called "animate" +
440
+ var fn = 'animate' + $._ucfirst(self.options.animation);
441
+
442
+ // Make sure it's a valid animation method, otherwise we'll get
443
+ // a load of bug reports that'll be really hard to report
444
+ if($.isFunction(self[fn])) {
445
+ self[fn](self.current, dir);
446
+ }
447
+
448
+ return self;
449
+ };
450
+
451
+
452
+ // Shortcuts for animating if we don't know what the current
453
+ // index is (i.e back/forward)
454
+ // For moving forward we need to make sure we don't overshoot.
455
+ self.next = function() {
456
+ var target = self.current + 1;
457
+
458
+ // If we're at the end, we need to move back to the start
459
+ if(target >= self.total) {
460
+ target = 0;
461
+ }
462
+
463
+ return self.animate(target, 'next');
464
+ };
465
+
466
+ // Previous is a bit simpler, we can just decrease the index
467
+ // by one and check if it's over 0.
468
+ self.prev = function() {
469
+ return self.animate(self.current - 1, 'prev');
470
+ };
471
+
472
+
473
+ // Our default animation method, the old-school left-to-right
474
+ // horizontal animation
475
+ self.animateHorizontal = function(to) {
476
+ var prop = 'left';
477
+
478
+ // Add RTL support, slide the slider
479
+ // the other way if the site is right-to-left
480
+ if(self.$context.attr('dir') === 'rtl') {
481
+ prop = 'right';
482
+ }
483
+
484
+ if(self.options.infinite) {
485
+ // So then we need to hide the first slide
486
+ self.$container.css('margin-' + prop, '-100%');
487
+ }
488
+
489
+ return self.slide(prop, to);
490
+ };
491
+
492
+ // The same animation methods, but vertical support
493
+ // RTL doesn't affect the vertical direction so we
494
+ // can just call as is
495
+ self.animateVertical = function(to) {
496
+ self.options.animateHeight = true;
497
+
498
+ // Normal infinite CSS fix doesn't work for
499
+ // vertical animation so we need to manually set it
500
+ // with pixels. Ah well.
501
+ if(self.options.infinite) {
502
+ self.$container.css('margin-top', -self.$slides.outerHeight());
503
+ }
504
+
505
+ return self.slide('top', to);
506
+ };
507
+
508
+ // Actually move the slide now
509
+ // We have to pass a property to animate as there's
510
+ // a few different directions it can now move, but it's
511
+ // otherwise unchanged from before.
512
+ self.slide = function(prop, to) {
513
+ // If we want to change the height of the slider
514
+ // to match the current slide, you can set
515
+ // {animateHeight: true}
516
+ self.animateHeight(to);
517
+
518
+ // For infinite sliding we add a dummy slide at the end and start
519
+ // of each slider to give the appearance of being infinite
520
+ if(self.options.infinite) {
521
+ var dummy;
522
+
523
+ // Going backwards to last slide
524
+ if(to === self.total - 1) {
525
+ // We're setting a dummy position and an actual one
526
+ // the dummy is what the index looks like
527
+ // (and what we'll silently update to afterwards),
528
+ // and the actual is what makes it not go backwards
529
+ dummy = self.total - 3;
530
+ to = -1;
531
+ }
532
+
533
+ // Going forwards to first slide
534
+ if(to === self.total - 2) {
535
+ dummy = 0;
536
+ to = self.total - 2;
537
+ }
538
+
539
+ // If it's a number we can safely set it
540
+ if(typeof dummy === 'number') {
541
+ self.setIndex(dummy);
542
+
543
+ // Listen for when the slide's finished transitioning so
544
+ // we can silently move it into the right place and clear
545
+ // this whole mess up.
546
+ self.$context.on(self._ + '.moved', function() {
547
+ if(self.current === dummy) {
548
+ self.$container.css(prop, -(100 * dummy) + '%').off(self._ + '.moved');
549
+ }
550
+ });
551
+ }
552
+ }
553
+
554
+ // We need to create an object to store our property in
555
+ // since we don't know what it'll be.
556
+ var obj = {};
557
+
558
+ // Manually create it here
559
+ obj[prop] = -(100 * to) + '%';
560
+
561
+ // And animate using our newly-created object
562
+ return self._move(self.$container, obj);
563
+ };
564
+
565
+
566
+ // Fade between slides rather than, uh, sliding it
567
+ self.animateFade = function(to) {
568
+ // If we want to change the height of the slider
569
+ // to match the current slide, you can set
570
+ // {animateHeight: true}
571
+ self.animateHeight(to);
572
+
573
+ var $active = self.$slides.eq(to).addClass(self.options.activeClass);
574
+
575
+ // Toggle our classes
576
+ self._move($active.siblings().removeClass(self.options.activeClass), {opacity: 0});
577
+ self._move($active, {opacity: 1}, false);
578
+ };
579
+
580
+ // Animate height of slider
581
+ self.animateHeight = function(to) {
582
+ // If we want to change the height of the slider
583
+ // to match the current slide, you can set
584
+ // {animateHeight: true}
585
+ if (self.options.animateHeight) {
586
+ self._move(self.$context, {height: self.$slides.eq(to).outerHeight()}, false);
587
+ }
588
+ };
589
+
590
+ self._move = function($el, obj, callback, speed) {
591
+ if(callback !== false) {
592
+ callback = function() {
593
+ self.$context.trigger(self._ + '.moved');
594
+ };
595
+ }
596
+
597
+ return $el._move(obj, speed || self.options.speed, self.options.easing, callback);
598
+ };
599
+
600
+ // Allow daisy-chaining of methods
601
+ return self.init(options);
602
+ };
603
+
604
+ // Internal (but global) jQuery methods
605
+ // They're both just helpful types of shorthand for
606
+ // anything that might take too long to write out or
607
+ // something that might be used more than once.
608
+ $.fn._active = function(className) {
609
+ return this.addClass(className).siblings().removeClass(className);
610
+ };
611
+
612
+ // The equivalent to PHP's ucfirst(). Take the first
613
+ // character of a string and make it uppercase.
614
+ // Simples.
615
+ $._ucfirst = function(str) {
616
+ // Take our variable, run a regex on the first letter
617
+ return (str + '').toLowerCase().replace(/^./, function(match) {
618
+ // And uppercase it. Simples.
619
+ return match.toUpperCase();
620
+ });
621
+ };
622
+
623
+ $.fn._move = function() {
624
+ this.stop(true, true);
625
+ return $.fn[$.fn.velocity ? 'velocity' : 'animate'].apply(this, arguments);
626
+ };
627
+
628
+ // And set up our jQuery plugin
629
+ $.fn.unslider = function(opts) {
630
+ return this.each(function() {
631
+ var $this = $(this);
632
+
633
+ // Allow usage of .unslider('function_name')
634
+ // as well as using .data('unslider') to access the
635
+ // main Unslider object
636
+ if(typeof opts === 'string' && $this.data('unslider')) {
637
+ opts = opts.split(':');
638
+
639
+ var call = $this.data('unslider')[opts[0]];
640
+
641
+ // Do we have arguments to pass to the string-function?
642
+ if($.isFunction(call)) {
643
+ return call.apply($this, opts[1] ? opts[1].split(',') : null);
644
+ }
645
+ }
646
+
647
+ return $this.data('unslider', new $.Unslider($this, opts));
648
+ });
649
+ };
650
+
651
+ }));
@@ -0,0 +1 @@
1
+ !function($){return $?($.Unslider=function(t,n){var e=this;return e._="unslider",e.defaults={autoplay:!1,delay:3e3,speed:750,easing:"swing",keys:{prev:37,next:39},nav:!0,arrows:{prev:'<a class="'+e._+'-arrow prev">Prev</a>',next:'<a class="'+e._+'-arrow next">Next</a>'},animation:"horizontal",selectors:{container:"ul:first",slides:"li"},animateHeight:!1,activeClass:e._+"-active",swipe:!0,swipeThreshold:.2},e.$context=t,e.options={},e.$parent=null,e.$container=null,e.$slides=null,e.$nav=null,e.$arrows=[],e.total=0,e.current=0,e.prefix=e._+"-",e.eventSuffix="."+e.prefix+~~(2e3*Math.random()),e.interval=null,e.init=function(t){return e.options=$.extend({},e.defaults,t),e.$container=e.$context.find(e.options.selectors.container).addClass(e.prefix+"wrap"),e.$slides=e.$container.children(e.options.selectors.slides),e.setup(),$.each(["nav","arrows","keys","infinite"],function(t,n){e.options[n]&&e["init"+$._ucfirst(n)]()}),jQuery.event.special.swipe&&e.options.swipe&&e.initSwipe(),e.options.autoplay&&e.start(),e.calculateSlides(),e.$context.trigger(e._+".ready"),e.animate(e.options.index||e.current,"init")},e.setup=function(){e.$context.addClass(e.prefix+e.options.animation).wrap('<div class="'+e._+'" />'),e.$parent=e.$context.parent("."+e._);var t=e.$context.css("position");"static"===t&&e.$context.css("position","relative"),e.$context.css("overflow","hidden")},e.calculateSlides=function(){if(e.total=e.$slides.length,"fade"!==e.options.animation){var t="width";"vertical"===e.options.animation&&(t="height"),e.$container.css(t,100*e.total+"%").addClass(e.prefix+"carousel"),e.$slides.css(t,100/e.total+"%")}},e.start=function(){return e.interval=setTimeout(function(){e.next()},e.options.delay),e},e.stop=function(){return clearTimeout(e.interval),e},e.initNav=function(){var t=$('<nav class="'+e.prefix+'nav"><ol /></nav>');e.$slides.each(function(n){var i=this.getAttribute("data-nav")||n+1;$.isFunction(e.options.nav)&&(i=e.options.nav.call(e.$slides.eq(n),n,i)),t.children("ol").append('<li data-slide="'+n+'">'+i+"</li>")}),e.$nav=t.insertAfter(e.$context),e.$nav.find("li").on("click"+e.eventSuffix,function(){var t=$(this).addClass(e.options.activeClass);t.siblings().removeClass(e.options.activeClass),e.animate(t.attr("data-slide"))})},e.initArrows=function(){e.options.arrows===!0&&(e.options.arrows=e.defaults.arrows),$.each(e.options.arrows,function(t,n){e.$arrows.push($(n).insertAfter(e.$context).on("click"+e.eventSuffix,e[t]))})},e.initKeys=function(){e.options.keys===!0&&(e.options.keys=e.defaults.keys),$(document).on("keyup"+e.eventSuffix,function(t){$.each(e.options.keys,function(n,i){t.which===i&&$.isFunction(e[n])&&e[n].call(e)})})},e.initSwipe=function(){var t=e.$slides.width();"fade"!==e.options.animation&&e.$container.on({movestart:function(t){return t.distX>t.distY&&t.distX<-t.distY||t.distX<t.distY&&t.distX>-t.distY?!!t.preventDefault():void e.$container.css("position","relative")},move:function(n){e.$container.css("left",-(100*e.current)+100*n.distX/t+"%")},moveend:function(n){Math.abs(n.distX)/t>e.options.swipeThreshold?e[n.distX<0?"next":"prev"]():e.$container.animate({left:-(100*e.current)+"%"},e.options.speed/2)}})},e.initInfinite=function(){var t=["first","last"];$.each(t,function(n,i){e.$slides.push.apply(e.$slides,e.$slides.filter(':not(".'+e._+'-clone")')[i]().clone().addClass(e._+"-clone")["insert"+(0===n?"After":"Before")](e.$slides[t[~~!n]]()))})},e.destroyArrows=function(){$.each(e.$arrows,function(t,n){n.remove()})},e.destroySwipe=function(){e.$container.off("movestart move moveend")},e.destroyKeys=function(){$(document).off("keyup"+e.eventSuffix)},e.setIndex=function(t){return 0>t&&(t=e.total-1),e.current=Math.min(Math.max(0,t),e.total-1),e.options.nav&&e.$nav.find('[data-slide="'+e.current+'"]')._active(e.options.activeClass),e.$slides.eq(e.current)._active(e.options.activeClass),e},e.animate=function(t,n){if("first"===t&&(t=0),"last"===t&&(t=e.total),isNaN(t))return e;e.options.autoplay&&e.stop().start(),e.setIndex(t),e.$context.trigger(e._+".change",[t,e.$slides.eq(t)]);var i="animate"+$._ucfirst(e.options.animation);return $.isFunction(e[i])&&e[i](e.current,n),e},e.next=function(){var t=e.current+1;return t>=e.total&&(t=0),e.animate(t,"next")},e.prev=function(){return e.animate(e.current-1,"prev")},e.animateHorizontal=function(t){var n="left";return"rtl"===e.$context.attr("dir")&&(n="right"),e.options.infinite&&e.$container.css("margin-"+n,"-100%"),e.slide(n,t)},e.animateVertical=function(t){return e.options.animateHeight=!0,e.options.infinite&&e.$container.css("margin-top",-e.$slides.outerHeight()),e.slide("top",t)},e.slide=function(t,n){if(e.options.animateHeight&&e._move(e.$context,{height:e.$slides.eq(n).outerHeight()},!1),e.options.infinite){var i;n===e.total-1&&(i=e.total-3,n=-1),n===e.total-2&&(i=0,n=e.total-2),"number"==typeof i&&(e.setIndex(i),e.$context.on(e._+".moved",function(){e.current===i&&e.$container.css(t,-(100*i)+"%").off(e._+".moved")}))}var o={};return o[t]=-(100*n)+"%",e._move(e.$container,o)},e.animateFade=function(t){var n=e.$slides.eq(t).addClass(e.options.activeClass);e._move(n.siblings().removeClass(e.options.activeClass),{opacity:0}),e._move(n,{opacity:1},!1)},e._move=function(t,n,i,o){return i!==!1&&(i=function(){e.$context.trigger(e._+".moved")}),t._move(n,o||e.options.speed,e.options.easing,i)},e.init(n)},$.fn._active=function(t){return this.addClass(t).siblings().removeClass(t)},$._ucfirst=function(t){return(t+"").toLowerCase().replace(/^./,function(t){return t.toUpperCase()})},$.fn._move=function(){return this.stop(!0,!0),$.fn[$.fn.velocity?"velocity":"animate"].apply(this,arguments)},void($.fn.unslider=function(t){return this.each(function(){var n=$(this);if("string"==typeof t&&n.data("unslider")){t=t.split(":");var e=n.data("unslider")[t[0]];if($.isFunction(e))return e.apply(n,t[1]?t[1].split(","):null)}return n.data("unslider",new $.Unslider(n,t))})})):console.warn("Unslider needs jQuery")}(window.jQuery);
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery-unslider-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Curt Howard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A build of the jQuery Unslider Plugin, written by written by Visual Idiot,
14
+ packaged for the Rails asset pipeline.
15
+ email:
16
+ - curt@meows.us
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - lib/jquery-unslider-rails.rb
24
+ - lib/jquery-unslider-rails/version.rb
25
+ - vendor/assets/javascripts/jquery-unslider.js
26
+ - vendor/assets/javascripts/jquery-unslider.min.js
27
+ homepage: https://github.com/meowsus/jquery-unslider-rails
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.5.1
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: A build of the jQuery Unslider Plugin, written by written by Visual Idiot,
51
+ packaged for the Rails asset pipeline.
52
+ test_files: []