snap_js-rails 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in snap_js.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Aaron Breckenridge
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # snap_js-rails
2
+
3
+ Add [Snap.js](https://github.com/jakiestfu/Snap.js) to your asset pipeline.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'snap_js-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install snap_js-rails
18
+
19
+ ## Usage
20
+
21
+ Add this line to your `application.js` file.
22
+
23
+ //= require snap
24
+
25
+ Then, either add this to `application.js` below the requires...
26
+
27
+ $(function() {
28
+ var snapper = new Snap({
29
+ element: document.getElementById('content')
30
+ });
31
+ })
32
+
33
+ ... or add it directly to your layout file (i.e. `application.html.erb`)
34
+
35
+ <script type="text/javascript">
36
+ var snapper = new Snap({
37
+ element: document.getElementById('content')
38
+ });
39
+ </script>
40
+
41
+ There's also an optional CSS stylesheet containing the barebones styles you'll need to get started (also from https://github.com/jakiestfu/Snap.js). To use it, add this to `application.css`:
42
+
43
+ *= require snap
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+
3
+ module SnapJs
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module SnapJs
2
+ VERSION = "1.9.0"
3
+ end
@@ -0,0 +1 @@
1
+ require "snap_js-rails/engine"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'snap_js-rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "snap_js-rails"
8
+ spec.version = SnapJs::VERSION
9
+ spec.authors = ["Aaron Breckenridge"]
10
+ spec.email = ["aaronbreckenridge@gmail.com"]
11
+ spec.description = "This gem adds Snap.js to the Rails asset pipeline"
12
+ spec.summary = "Add Snap.js to the Rails asset pipeline"
13
+ spec.homepage = "https://github.com/breckenedge/snap_js-rails"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "railties", ">= 3.1"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,562 @@
1
+ /*
2
+ * Snap.js
3
+ *
4
+ * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
5
+ * Released under the MIT Licence
6
+ * http://opensource.org/licenses/MIT
7
+ *
8
+ * Github: http://github.com/jakiestfu/Snap.js/
9
+ * Version: 1.9.0
10
+ */
11
+ /*jslint browser: true*/
12
+ /*global define, module, ender*/
13
+ (function(win, doc) {
14
+ 'use strict';
15
+ var Snap = Snap || function(userOpts) {
16
+ var settings = {
17
+ element: null,
18
+ dragger: null,
19
+ disable: 'none',
20
+ addBodyClasses: true,
21
+ hyperextensible: true,
22
+ resistance: 0.5,
23
+ flickThreshold: 50,
24
+ transitionSpeed: 0.3,
25
+ easing: 'ease',
26
+ maxPosition: 266,
27
+ minPosition: -266,
28
+ tapToClose: true,
29
+ touchToDrag: true,
30
+ slideIntent: 40, // degrees
31
+ minDragDistance: 5
32
+ },
33
+ cache = {
34
+ simpleStates: {
35
+ opening: null,
36
+ towards: null,
37
+ hyperExtending: null,
38
+ halfway: null,
39
+ flick: null,
40
+ translation: {
41
+ absolute: 0,
42
+ relative: 0,
43
+ sinceDirectionChange: 0,
44
+ percentage: 0
45
+ }
46
+ }
47
+ },
48
+ eventList = {},
49
+ utils = {
50
+ hasTouch: (doc.ontouchstart === null),
51
+ eventType: function(action) {
52
+ var eventTypes = {
53
+ down: (utils.hasTouch ? 'touchstart' : 'mousedown'),
54
+ move: (utils.hasTouch ? 'touchmove' : 'mousemove'),
55
+ up: (utils.hasTouch ? 'touchend' : 'mouseup'),
56
+ out: (utils.hasTouch ? 'touchcancel' : 'mouseout')
57
+ };
58
+ return eventTypes[action];
59
+ },
60
+ page: function(t, e){
61
+ return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t];
62
+ },
63
+ klass: {
64
+ has: function(el, name){
65
+ return (el.className).indexOf(name) !== -1;
66
+ },
67
+ add: function(el, name){
68
+ if(!utils.klass.has(el, name) && settings.addBodyClasses){
69
+ el.className += " "+name;
70
+ }
71
+ },
72
+ remove: function(el, name){
73
+ if(settings.addBodyClasses){
74
+ el.className = (el.className).replace(" "+name, "");
75
+ }
76
+ }
77
+ },
78
+ dispatchEvent: function(type) {
79
+ if (typeof eventList[type] === 'function') {
80
+ return eventList[type].call();
81
+ }
82
+ },
83
+ vendor: function(){
84
+ var tmp = doc.createElement("div"),
85
+ prefixes = 'webkit Moz O ms'.split(' '),
86
+ i;
87
+ for (i in prefixes) {
88
+ if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') {
89
+ return prefixes[i];
90
+ }
91
+ }
92
+ },
93
+ transitionCallback: function(){
94
+ return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd';
95
+ },
96
+ canTransform: function(){
97
+ return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined';
98
+ },
99
+ deepExtend: function(destination, source) {
100
+ var property;
101
+ for (property in source) {
102
+ if (source[property] && source[property].constructor && source[property].constructor === Object) {
103
+ destination[property] = destination[property] || {};
104
+ utils.deepExtend(destination[property], source[property]);
105
+ } else {
106
+ destination[property] = source[property];
107
+ }
108
+ }
109
+ return destination;
110
+ },
111
+ angleOfDrag: function(x, y) {
112
+ var degrees, theta;
113
+ // Calc Theta
114
+ theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x));
115
+ if (theta < 0) {
116
+ theta += 2 * Math.PI;
117
+ }
118
+ // Calc Degrees
119
+ degrees = Math.floor(theta * (180 / Math.PI) - 180);
120
+ if (degrees < 0 && degrees > -180) {
121
+ degrees = 360 - Math.abs(degrees);
122
+ }
123
+ return Math.abs(degrees);
124
+ },
125
+ events: {
126
+ addEvent: function addEvent(element, eventName, func) {
127
+ if (element.addEventListener) {
128
+ return element.addEventListener(eventName, func, false);
129
+ } else if (element.attachEvent) {
130
+ return element.attachEvent("on" + eventName, func);
131
+ }
132
+ },
133
+ removeEvent: function addEvent(element, eventName, func) {
134
+ if (element.addEventListener) {
135
+ return element.removeEventListener(eventName, func, false);
136
+ } else if (element.attachEvent) {
137
+ return element.detachEvent("on" + eventName, func);
138
+ }
139
+ },
140
+ prevent: function(e) {
141
+ if (e.preventDefault) {
142
+ e.preventDefault();
143
+ } else {
144
+ e.returnValue = false;
145
+ }
146
+ }
147
+ },
148
+ parentUntil: function(el, attr) {
149
+ var isStr = typeof attr === 'string';
150
+ while (el.parentNode) {
151
+ if (isStr && el.getAttribute && el.getAttribute(attr)){
152
+ return el;
153
+ } else if(!isStr && el === attr){
154
+ return el;
155
+ }
156
+ el = el.parentNode;
157
+ }
158
+ return null;
159
+ }
160
+ },
161
+ action = {
162
+ translate: {
163
+ get: {
164
+ matrix: function(index) {
165
+
166
+ if( !utils.canTransform() ){
167
+ return parseInt(settings.element.style.left, 10);
168
+ } else {
169
+ var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/),
170
+ ieOffset = 8;
171
+ if (matrix) {
172
+ matrix = matrix[1].split(',');
173
+ if(matrix.length===16){
174
+ index+=ieOffset;
175
+ }
176
+ return parseInt(matrix[index], 10);
177
+ }
178
+ return 0;
179
+ }
180
+ }
181
+ },
182
+ easeCallback: function(){
183
+ settings.element.style[cache.vendor+'Transition'] = '';
184
+ cache.translation = action.translate.get.matrix(4);
185
+ cache.easing = false;
186
+ clearInterval(cache.animatingInterval);
187
+
188
+ if(cache.easingTo===0){
189
+ utils.klass.remove(doc.body, 'snapjs-right');
190
+ utils.klass.remove(doc.body, 'snapjs-left');
191
+ }
192
+
193
+ utils.dispatchEvent('animated');
194
+ utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
195
+ },
196
+ easeTo: function(n) {
197
+
198
+ if( !utils.canTransform() ){
199
+ cache.translation = n;
200
+ action.translate.x(n);
201
+ } else {
202
+ cache.easing = true;
203
+ cache.easingTo = n;
204
+
205
+ settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing;
206
+
207
+ cache.animatingInterval = setInterval(function() {
208
+ utils.dispatchEvent('animating');
209
+ }, 1);
210
+
211
+ utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
212
+ action.translate.x(n);
213
+ }
214
+ if(n===0){
215
+ settings.element.style[cache.vendor+'Transform'] = '';
216
+ }
217
+ },
218
+ x: function(n) {
219
+ if( (settings.disable==='left' && n>0) ||
220
+ (settings.disable==='right' && n<0)
221
+ ){ return; }
222
+
223
+ if( !settings.hyperextensible ){
224
+ if( n===settings.maxPosition || n>settings.maxPosition ){
225
+ n=settings.maxPosition;
226
+ } else if( n===settings.minPosition || n<settings.minPosition ){
227
+ n=settings.minPosition;
228
+ }
229
+ }
230
+
231
+ n = parseInt(n, 10);
232
+ if(isNaN(n)){
233
+ n = 0;
234
+ }
235
+
236
+ if( utils.canTransform() ){
237
+ var theTranslate = 'translate3d(' + n + 'px, 0,0)';
238
+ settings.element.style[cache.vendor+'Transform'] = theTranslate;
239
+ } else {
240
+ settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px';
241
+
242
+ settings.element.style.left = n+'px';
243
+ settings.element.style.right = '';
244
+ }
245
+ }
246
+ },
247
+ drag: {
248
+ listen: function() {
249
+ cache.translation = 0;
250
+ cache.easing = false;
251
+ utils.events.addEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
252
+ utils.events.addEvent(settings.element, utils.eventType('move'), action.drag.dragging);
253
+ utils.events.addEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
254
+ },
255
+ stopListening: function() {
256
+ utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
257
+ utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging);
258
+ utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
259
+ },
260
+ startDrag: function(e) {
261
+ // No drag on ignored elements
262
+ var target = e.target ? e.target : e.srcElement,
263
+ ignoreParent = utils.parentUntil(target, 'data-snap-ignore');
264
+
265
+ if (ignoreParent) {
266
+ utils.dispatchEvent('ignore');
267
+ return;
268
+ }
269
+
270
+
271
+ if(settings.dragger){
272
+ var dragParent = utils.parentUntil(target, settings.dragger);
273
+
274
+ // Only use dragger if we're in a closed state
275
+ if( !dragParent &&
276
+ (cache.translation !== settings.minPosition &&
277
+ cache.translation !== settings.maxPosition
278
+ )){
279
+ return;
280
+ }
281
+ }
282
+
283
+ utils.dispatchEvent('start');
284
+ settings.element.style[cache.vendor+'Transition'] = '';
285
+ cache.isDragging = true;
286
+ cache.hasIntent = null;
287
+ cache.intentChecked = false;
288
+ cache.startDragX = utils.page('X', e);
289
+ cache.startDragY = utils.page('Y', e);
290
+ cache.dragWatchers = {
291
+ current: 0,
292
+ last: 0,
293
+ hold: 0,
294
+ state: ''
295
+ };
296
+ cache.simpleStates = {
297
+ opening: null,
298
+ towards: null,
299
+ hyperExtending: null,
300
+ halfway: null,
301
+ flick: null,
302
+ translation: {
303
+ absolute: 0,
304
+ relative: 0,
305
+ sinceDirectionChange: 0,
306
+ percentage: 0
307
+ }
308
+ };
309
+ },
310
+ dragging: function(e) {
311
+ if (cache.isDragging && settings.touchToDrag) {
312
+
313
+ var thePageX = utils.page('X', e),
314
+ thePageY = utils.page('Y', e),
315
+ translated = cache.translation,
316
+ absoluteTranslation = action.translate.get.matrix(4),
317
+ whileDragX = thePageX - cache.startDragX,
318
+ openingLeft = absoluteTranslation > 0,
319
+ translateTo = whileDragX,
320
+ diff;
321
+
322
+ // Shown no intent already
323
+ if((cache.intentChecked && !cache.hasIntent)){
324
+ return;
325
+ }
326
+
327
+ if(settings.addBodyClasses){
328
+ if((absoluteTranslation)>0){
329
+ utils.klass.add(doc.body, 'snapjs-left');
330
+ utils.klass.remove(doc.body, 'snapjs-right');
331
+ } else if((absoluteTranslation)<0){
332
+ utils.klass.add(doc.body, 'snapjs-right');
333
+ utils.klass.remove(doc.body, 'snapjs-left');
334
+ }
335
+ }
336
+
337
+ if (cache.hasIntent === false || cache.hasIntent === null) {
338
+ var deg = utils.angleOfDrag(thePageX, thePageY),
339
+ inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)),
340
+ inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent));
341
+ if (!inLeftRange && !inRightRange) {
342
+ cache.hasIntent = false;
343
+ } else {
344
+ cache.hasIntent = true;
345
+ }
346
+ cache.intentChecked = true;
347
+ }
348
+
349
+ if (
350
+ (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance?
351
+ (cache.hasIntent === false)
352
+ ) {
353
+ return;
354
+ }
355
+
356
+ utils.events.prevent(e);
357
+ utils.dispatchEvent('drag');
358
+
359
+ cache.dragWatchers.current = thePageX;
360
+ // Determine which direction we are going
361
+ if (cache.dragWatchers.last > thePageX) {
362
+ if (cache.dragWatchers.state !== 'left') {
363
+ cache.dragWatchers.state = 'left';
364
+ cache.dragWatchers.hold = thePageX;
365
+ }
366
+ cache.dragWatchers.last = thePageX;
367
+ } else if (cache.dragWatchers.last < thePageX) {
368
+ if (cache.dragWatchers.state !== 'right') {
369
+ cache.dragWatchers.state = 'right';
370
+ cache.dragWatchers.hold = thePageX;
371
+ }
372
+ cache.dragWatchers.last = thePageX;
373
+ }
374
+ if (openingLeft) {
375
+ // Pulling too far to the right
376
+ if (settings.maxPosition < absoluteTranslation) {
377
+ diff = (absoluteTranslation - settings.maxPosition) * settings.resistance;
378
+ translateTo = whileDragX - diff;
379
+ }
380
+ cache.simpleStates = {
381
+ opening: 'left',
382
+ towards: cache.dragWatchers.state,
383
+ hyperExtending: settings.maxPosition < absoluteTranslation,
384
+ halfway: absoluteTranslation > (settings.maxPosition / 2),
385
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
386
+ translation: {
387
+ absolute: absoluteTranslation,
388
+ relative: whileDragX,
389
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
390
+ percentage: (absoluteTranslation/settings.maxPosition)*100
391
+ }
392
+ };
393
+ } else {
394
+ // Pulling too far to the left
395
+ if (settings.minPosition > absoluteTranslation) {
396
+ diff = (absoluteTranslation - settings.minPosition) * settings.resistance;
397
+ translateTo = whileDragX - diff;
398
+ }
399
+ cache.simpleStates = {
400
+ opening: 'right',
401
+ towards: cache.dragWatchers.state,
402
+ hyperExtending: settings.minPosition > absoluteTranslation,
403
+ halfway: absoluteTranslation < (settings.minPosition / 2),
404
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
405
+ translation: {
406
+ absolute: absoluteTranslation,
407
+ relative: whileDragX,
408
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
409
+ percentage: (absoluteTranslation/settings.minPosition)*100
410
+ }
411
+ };
412
+ }
413
+ action.translate.x(translateTo + translated);
414
+ }
415
+ },
416
+ endDrag: function(e) {
417
+ if (cache.isDragging) {
418
+ utils.dispatchEvent('end');
419
+ var translated = action.translate.get.matrix(4);
420
+
421
+ // Tap Close
422
+ if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) {
423
+ utils.events.prevent(e);
424
+ action.translate.easeTo(0);
425
+ cache.isDragging = false;
426
+ cache.startDragX = 0;
427
+ return;
428
+ }
429
+
430
+ // Revealing Left
431
+ if (cache.simpleStates.opening === 'left') {
432
+ // Halfway, Flicking, or Too Far Out
433
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
434
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed
435
+ action.translate.easeTo(0);
436
+ } else if (
437
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR
438
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
439
+ ) {
440
+ action.translate.easeTo(settings.maxPosition); // Open Left
441
+ }
442
+ } else {
443
+ action.translate.easeTo(0); // Close Left
444
+ }
445
+ // Revealing Right
446
+ } else if (cache.simpleStates.opening === 'right') {
447
+ // Halfway, Flicking, or Too Far Out
448
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
449
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed
450
+ action.translate.easeTo(0);
451
+ } else if (
452
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR
453
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
454
+ ) {
455
+ action.translate.easeTo(settings.minPosition); // Open Right
456
+ }
457
+ } else {
458
+ action.translate.easeTo(0); // Close Right
459
+ }
460
+ }
461
+ cache.isDragging = false;
462
+ cache.startDragX = utils.page('X', e);
463
+ }
464
+ }
465
+ }
466
+ },
467
+ init = function(opts) {
468
+ if (opts.element) {
469
+ utils.deepExtend(settings, opts);
470
+ cache.vendor = utils.vendor();
471
+ action.drag.listen();
472
+ }
473
+ };
474
+ /*
475
+ * Public
476
+ */
477
+ this.open = function(side) {
478
+
479
+ utils.klass.remove(doc.body, 'snapjs-expand-left');
480
+ utils.klass.remove(doc.body, 'snapjs-expand-right');
481
+
482
+ if (side === 'left') {
483
+ cache.simpleStates.opening = 'left';
484
+ cache.simpleStates.towards = 'right';
485
+ utils.klass.add(doc.body, 'snapjs-left');
486
+ utils.klass.remove(doc.body, 'snapjs-right');
487
+ action.translate.easeTo(settings.maxPosition);
488
+ } else if (side === 'right') {
489
+ cache.simpleStates.opening = 'right';
490
+ cache.simpleStates.towards = 'left';
491
+ utils.klass.remove(doc.body, 'snapjs-left');
492
+ utils.klass.add(doc.body, 'snapjs-right');
493
+ action.translate.easeTo(settings.minPosition);
494
+ }
495
+ };
496
+ this.close = function() {
497
+ action.translate.easeTo(0);
498
+ };
499
+ this.expand = function(side){
500
+ var to = win.innerWidth || doc.documentElement.clientWidth;
501
+
502
+ if(side==='left'){
503
+ utils.klass.add(doc.body, 'snapjs-expand-left');
504
+ utils.klass.remove(doc.body, 'snapjs-expand-right');
505
+ } else {
506
+ utils.klass.add(doc.body, 'snapjs-expand-right');
507
+ utils.klass.remove(doc.body, 'snapjs-expand-left');
508
+ to *= -1;
509
+ }
510
+ action.translate.easeTo(to);
511
+ };
512
+
513
+ this.on = function(evt, fn) {
514
+ eventList[evt] = fn;
515
+ return this;
516
+ };
517
+ this.off = function(evt) {
518
+ if (eventList[evt]) {
519
+ eventList[evt] = false;
520
+ }
521
+ };
522
+
523
+ this.enable = function() {
524
+ action.drag.listen();
525
+ };
526
+ this.disable = function() {
527
+ action.drag.stopListening();
528
+ };
529
+
530
+ this.settings = function(opts){
531
+ utils.deepExtend(settings, opts);
532
+ };
533
+
534
+ this.state = function() {
535
+ var state,
536
+ fromLeft = action.translate.get.matrix(4);
537
+ if (fromLeft === settings.maxPosition) {
538
+ state = 'left';
539
+ } else if (fromLeft === settings.minPosition) {
540
+ state = 'right';
541
+ } else {
542
+ state = 'closed';
543
+ }
544
+ return {
545
+ state: state,
546
+ info: cache.simpleStates
547
+ };
548
+ };
549
+ init(userOpts);
550
+ };
551
+ if ((typeof module !== 'undefined') && module.exports) {
552
+ module.exports = Snap;
553
+ }
554
+ if (typeof ender === 'undefined') {
555
+ this.Snap = Snap;
556
+ }
557
+ if ((typeof define === "function") && define.amd) {
558
+ define("snap", [], function() {
559
+ return Snap;
560
+ });
561
+ }
562
+ }).call(this, window, document);
@@ -0,0 +1,11 @@
1
+ /*
2
+ * Snap.js
3
+ *
4
+ * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
5
+ * Released under the MIT Licence
6
+ * http://opensource.org/licenses/MIT
7
+ *
8
+ * Github: http://github.com/jakiestfu/Snap.js/
9
+ * Version: 1.9.0
10
+ */
11
+ (function(c,b){var a=a||function(k){var f={element:null,dragger:null,disable:"none",addBodyClasses:true,hyperextensible:true,resistance:0.5,flickThreshold:50,transitionSpeed:0.3,easing:"ease",maxPosition:266,minPosition:-266,tapToClose:true,touchToDrag:true,slideIntent:40,minDragDistance:5},e={simpleStates:{opening:null,towards:null,hyperExtending:null,halfway:null,flick:null,translation:{absolute:0,relative:0,sinceDirectionChange:0,percentage:0}}},h={},d={hasTouch:(b.ontouchstart===null),eventType:function(m){var l={down:(d.hasTouch?"touchstart":"mousedown"),move:(d.hasTouch?"touchmove":"mousemove"),up:(d.hasTouch?"touchend":"mouseup"),out:(d.hasTouch?"touchcancel":"mouseout")};return l[m]},page:function(l,m){return(d.hasTouch&&m.touches.length&&m.touches[0])?m.touches[0]["page"+l]:m["page"+l]},klass:{has:function(m,l){return(m.className).indexOf(l)!==-1},add:function(m,l){if(!d.klass.has(m,l)&&f.addBodyClasses){m.className+=" "+l}},remove:function(m,l){if(f.addBodyClasses){m.className=(m.className).replace(" "+l,"")}}},dispatchEvent:function(l){if(typeof h[l]==="function"){return h[l].call()}},vendor:function(){var m=b.createElement("div"),n="webkit Moz O ms".split(" "),l;for(l in n){if(typeof m.style[n[l]+"Transition"]!=="undefined"){return n[l]}}},transitionCallback:function(){return(e.vendor==="Moz"||e.vendor==="ms")?"transitionend":e.vendor+"TransitionEnd"},canTransform:function(){return typeof f.element.style[e.vendor+"Transform"]!=="undefined"},deepExtend:function(l,n){var m;for(m in n){if(n[m]&&n[m].constructor&&n[m].constructor===Object){l[m]=l[m]||{};d.deepExtend(l[m],n[m])}else{l[m]=n[m]}}return l},angleOfDrag:function(l,o){var n,m;m=Math.atan2(-(e.startDragY-o),(e.startDragX-l));if(m<0){m+=2*Math.PI}n=Math.floor(m*(180/Math.PI)-180);if(n<0&&n>-180){n=360-Math.abs(n)}return Math.abs(n)},events:{addEvent:function g(m,l,n){if(m.addEventListener){return m.addEventListener(l,n,false)}else{if(m.attachEvent){return m.attachEvent("on"+l,n)}}},removeEvent:function g(m,l,n){if(m.addEventListener){return m.removeEventListener(l,n,false)}else{if(m.attachEvent){return m.detachEvent("on"+l,n)}}},prevent:function(l){if(l.preventDefault){l.preventDefault()}else{l.returnValue=false}}},parentUntil:function(n,l){var m=typeof l==="string";while(n.parentNode){if(m&&n.getAttribute&&n.getAttribute(l)){return n}else{if(!m&&n===l){return n}}n=n.parentNode}return null}},i={translate:{get:{matrix:function(n){if(!d.canTransform()){return parseInt(f.element.style.left,10)}else{var m=c.getComputedStyle(f.element)[e.vendor+"Transform"].match(/\((.*)\)/),l=8;if(m){m=m[1].split(",");if(m.length===16){n+=l}return parseInt(m[n],10)}return 0}}},easeCallback:function(){f.element.style[e.vendor+"Transition"]="";e.translation=i.translate.get.matrix(4);e.easing=false;clearInterval(e.animatingInterval);if(e.easingTo===0){d.klass.remove(b.body,"snapjs-right");d.klass.remove(b.body,"snapjs-left")}d.dispatchEvent("animated");d.events.removeEvent(f.element,d.transitionCallback(),i.translate.easeCallback)},easeTo:function(l){if(!d.canTransform()){e.translation=l;i.translate.x(l)}else{e.easing=true;e.easingTo=l;f.element.style[e.vendor+"Transition"]="all "+f.transitionSpeed+"s "+f.easing;e.animatingInterval=setInterval(function(){d.dispatchEvent("animating")},1);d.events.addEvent(f.element,d.transitionCallback(),i.translate.easeCallback);i.translate.x(l)}if(l===0){f.element.style[e.vendor+"Transform"]=""}},x:function(m){if((f.disable==="left"&&m>0)||(f.disable==="right"&&m<0)){return}if(!f.hyperextensible){if(m===f.maxPosition||m>f.maxPosition){m=f.maxPosition}else{if(m===f.minPosition||m<f.minPosition){m=f.minPosition}}}m=parseInt(m,10);if(isNaN(m)){m=0}if(d.canTransform()){var l="translate3d("+m+"px, 0,0)";f.element.style[e.vendor+"Transform"]=l}else{f.element.style.width=(c.innerWidth||b.documentElement.clientWidth)+"px";f.element.style.left=m+"px";f.element.style.right=""}}},drag:{listen:function(){e.translation=0;e.easing=false;d.events.addEvent(f.element,d.eventType("down"),i.drag.startDrag);d.events.addEvent(f.element,d.eventType("move"),i.drag.dragging);d.events.addEvent(f.element,d.eventType("up"),i.drag.endDrag)},stopListening:function(){d.events.removeEvent(f.element,d.eventType("down"),i.drag.startDrag);d.events.removeEvent(f.element,d.eventType("move"),i.drag.dragging);d.events.removeEvent(f.element,d.eventType("up"),i.drag.endDrag)},startDrag:function(n){var m=n.target?n.target:n.srcElement,l=d.parentUntil(m,"data-snap-ignore");if(l){d.dispatchEvent("ignore");return}if(f.dragger){var o=d.parentUntil(m,f.dragger);if(!o&&(e.translation!==f.minPosition&&e.translation!==f.maxPosition)){return}}d.dispatchEvent("start");f.element.style[e.vendor+"Transition"]="";e.isDragging=true;e.hasIntent=null;e.intentChecked=false;e.startDragX=d.page("X",n);e.startDragY=d.page("Y",n);e.dragWatchers={current:0,last:0,hold:0,state:""};e.simpleStates={opening:null,towards:null,hyperExtending:null,halfway:null,flick:null,translation:{absolute:0,relative:0,sinceDirectionChange:0,percentage:0}}},dragging:function(s){if(e.isDragging&&f.touchToDrag){var v=d.page("X",s),u=d.page("Y",s),t=e.translation,o=i.translate.get.matrix(4),n=v-e.startDragX,p=o>0,q=n,w;if((e.intentChecked&&!e.hasIntent)){return}if(f.addBodyClasses){if((o)>0){d.klass.add(b.body,"snapjs-left");d.klass.remove(b.body,"snapjs-right")}else{if((o)<0){d.klass.add(b.body,"snapjs-right");d.klass.remove(b.body,"snapjs-left")}}}if(e.hasIntent===false||e.hasIntent===null){var m=d.angleOfDrag(v,u),l=(m>=0&&m<=f.slideIntent)||(m<=360&&m>(360-f.slideIntent)),r=(m>=180&&m<=(180+f.slideIntent))||(m<=180&&m>=(180-f.slideIntent));if(!r&&!l){e.hasIntent=false}else{e.hasIntent=true}e.intentChecked=true}if((f.minDragDistance>=Math.abs(v-e.startDragX))&&(e.hasIntent===false)){return}d.events.prevent(s);d.dispatchEvent("drag");e.dragWatchers.current=v;if(e.dragWatchers.last>v){if(e.dragWatchers.state!=="left"){e.dragWatchers.state="left";e.dragWatchers.hold=v}e.dragWatchers.last=v}else{if(e.dragWatchers.last<v){if(e.dragWatchers.state!=="right"){e.dragWatchers.state="right";e.dragWatchers.hold=v}e.dragWatchers.last=v}}if(p){if(f.maxPosition<o){w=(o-f.maxPosition)*f.resistance;q=n-w}e.simpleStates={opening:"left",towards:e.dragWatchers.state,hyperExtending:f.maxPosition<o,halfway:o>(f.maxPosition/2),flick:Math.abs(e.dragWatchers.current-e.dragWatchers.hold)>f.flickThreshold,translation:{absolute:o,relative:n,sinceDirectionChange:(e.dragWatchers.current-e.dragWatchers.hold),percentage:(o/f.maxPosition)*100}}}else{if(f.minPosition>o){w=(o-f.minPosition)*f.resistance;q=n-w}e.simpleStates={opening:"right",towards:e.dragWatchers.state,hyperExtending:f.minPosition>o,halfway:o<(f.minPosition/2),flick:Math.abs(e.dragWatchers.current-e.dragWatchers.hold)>f.flickThreshold,translation:{absolute:o,relative:n,sinceDirectionChange:(e.dragWatchers.current-e.dragWatchers.hold),percentage:(o/f.minPosition)*100}}}i.translate.x(q+t)}},endDrag:function(m){if(e.isDragging){d.dispatchEvent("end");var l=i.translate.get.matrix(4);if(e.dragWatchers.current===0&&l!==0&&f.tapToClose){d.events.prevent(m);i.translate.easeTo(0);e.isDragging=false;e.startDragX=0;return}if(e.simpleStates.opening==="left"){if((e.simpleStates.halfway||e.simpleStates.hyperExtending||e.simpleStates.flick)){if(e.simpleStates.flick&&e.simpleStates.towards==="left"){i.translate.easeTo(0)}else{if((e.simpleStates.flick&&e.simpleStates.towards==="right")||(e.simpleStates.halfway||e.simpleStates.hyperExtending)){i.translate.easeTo(f.maxPosition)}}}else{i.translate.easeTo(0)}}else{if(e.simpleStates.opening==="right"){if((e.simpleStates.halfway||e.simpleStates.hyperExtending||e.simpleStates.flick)){if(e.simpleStates.flick&&e.simpleStates.towards==="right"){i.translate.easeTo(0)}else{if((e.simpleStates.flick&&e.simpleStates.towards==="left")||(e.simpleStates.halfway||e.simpleStates.hyperExtending)){i.translate.easeTo(f.minPosition)}}}else{i.translate.easeTo(0)}}}e.isDragging=false;e.startDragX=d.page("X",m)}}}},j=function(l){if(l.element){d.deepExtend(f,l);e.vendor=d.vendor();i.drag.listen()}};this.open=function(l){d.klass.remove(b.body,"snapjs-expand-left");d.klass.remove(b.body,"snapjs-expand-right");if(l==="left"){e.simpleStates.opening="left";e.simpleStates.towards="right";d.klass.add(b.body,"snapjs-left");d.klass.remove(b.body,"snapjs-right");i.translate.easeTo(f.maxPosition)}else{if(l==="right"){e.simpleStates.opening="right";e.simpleStates.towards="left";d.klass.remove(b.body,"snapjs-left");d.klass.add(b.body,"snapjs-right");i.translate.easeTo(f.minPosition)}}};this.close=function(){i.translate.easeTo(0)};this.expand=function(l){var m=c.innerWidth||b.documentElement.clientWidth;if(l==="left"){d.klass.add(b.body,"snapjs-expand-left");d.klass.remove(b.body,"snapjs-expand-right")}else{d.klass.add(b.body,"snapjs-expand-right");d.klass.remove(b.body,"snapjs-expand-left");m*=-1}i.translate.easeTo(m)};this.on=function(l,m){h[l]=m;return this};this.off=function(l){if(h[l]){h[l]=false}};this.enable=function(){i.drag.listen()};this.disable=function(){i.drag.stopListening()};this.settings=function(l){d.deepExtend(f,l)};this.state=function(){var l,m=i.translate.get.matrix(4);if(m===f.maxPosition){l="left"}else{if(m===f.minPosition){l="right"}else{l="closed"}}return{state:l,info:e.simpleStates}};j(k)};if((typeof module!=="undefined")&&module.exports){module.exports=a}if(typeof ender==="undefined"){this.Snap=a}if((typeof define==="function")&&define.amd){define("snap",[],function(){return a})}}).call(this,window,document);
@@ -0,0 +1,72 @@
1
+ html, body {
2
+ margin: 0;
3
+ padding: 0;
4
+ width: 100%;
5
+ height: 100%;
6
+ overflow: hidden;
7
+ }
8
+
9
+ .snap-content {
10
+ position: absolute;
11
+ top: 0;
12
+ right: 0;
13
+ bottom: 0;
14
+ left: 0;
15
+ width: auto;
16
+ height: auto;
17
+ z-index: 2;
18
+ overflow: auto;
19
+ -webkit-overflow-scrolling: touch;
20
+ -webkit-transform: translate3d(0, 0, 0);
21
+ -moz-transform: translate3d(0, 0, 0);
22
+ -ms-transform: translate3d(0, 0, 0);
23
+ -o-transform: translate3d(0, 0, 0);
24
+ transform: translate3d(0, 0, 0);
25
+ }
26
+
27
+ .snap-drawers {
28
+ position: absolute;
29
+ top: 0;
30
+ right: 0;
31
+ bottom: 0;
32
+ left: 0;
33
+ width: auto;
34
+ height: auto;
35
+ }
36
+
37
+ .snap-drawer {
38
+ position: absolute;
39
+ top: 0;
40
+ right: auto;
41
+ bottom: 0;
42
+ left: auto;
43
+ width: 265px;
44
+ height: auto;
45
+ overflow: auto;
46
+ -webkit-overflow-scrolling: touch;
47
+ -webkit-transition: width 0.3s ease;
48
+ -moz-transition: width 0.3s ease;
49
+ -ms-transition: width 0.3s ease;
50
+ -o-transition: width 0.3s ease;
51
+ transition: width 0.3s ease;
52
+ }
53
+
54
+ .snap-drawer-left {
55
+ left: 0;
56
+ z-index: 1;
57
+ }
58
+
59
+ .snap-drawer-right {
60
+ right: 0;
61
+ z-index: 1;
62
+ }
63
+
64
+ .snapjs-left .snap-drawer-right,
65
+ .snapjs-right .snap-drawer-left {
66
+ display: none;
67
+ }
68
+
69
+ .snapjs-expand-left .snap-drawer-left,
70
+ .snapjs-expand-right .snap-drawer-right {
71
+ width: 100%;
72
+ }
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snap_js-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aaron Breckenridge
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: railties
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: This gem adds Snap.js to the Rails asset pipeline
63
+ email:
64
+ - aaronbreckenridge@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - lib/snap_js-rails.rb
75
+ - lib/snap_js-rails/engine.rb
76
+ - lib/snap_js-rails/version.rb
77
+ - snap_js-rails.gemspec
78
+ - vendor/assets/javascripts/snap.js
79
+ - vendor/assets/javascripts/snap.js.min
80
+ - vendor/assets/stylesheets/snap.css
81
+ homepage: https://github.com/breckenedge/snap_js-rails
82
+ licenses:
83
+ - MIT
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.25
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Add Snap.js to the Rails asset pipeline
106
+ test_files: []