twitter_ratchet_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/app/assets/fonts/ratchicons.eot +0 -0
  5. data/app/assets/fonts/ratchicons.svg +61 -0
  6. data/app/assets/fonts/ratchicons.ttf +0 -0
  7. data/app/assets/fonts/ratchicons.woff +0 -0
  8. data/app/assets/javascripts/twitter_ratchet_rails/ratchet.js +916 -0
  9. data/app/assets/javascripts/twitter_ratchet_rails.js +1 -0
  10. data/app/assets/stylesheets/ratchet_android.css +4 -0
  11. data/app/assets/stylesheets/ratchet_base.css +3 -0
  12. data/app/assets/stylesheets/ratchet_ios.css +4 -0
  13. data/app/assets/stylesheets/twitter_ratchet_rails/ratchet-theme-android.css +588 -0
  14. data/app/assets/stylesheets/twitter_ratchet_rails/ratchet-theme-ios.css +471 -0
  15. data/app/assets/stylesheets/twitter_ratchet_rails/ratchet.css.erb +1430 -0
  16. data/app/helpers/twitter_ratchet_rails/application_helper.rb +4 -0
  17. data/app/views/layouts/twitter_ratchet_rails/application.html.erb +14 -0
  18. data/lib/tasks/twitter_ratchet_rails_tasks.rake +4 -0
  19. data/lib/twitter_ratchet_rails/engine.rb +5 -0
  20. data/lib/twitter_ratchet_rails/version.rb +3 -0
  21. data/lib/twitter_ratchet_rails.rb +4 -0
  22. data/test/dummy/README.rdoc +28 -0
  23. data/test/dummy/Rakefile +6 -0
  24. data/test/dummy/app/assets/javascripts/application.js +13 -0
  25. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  26. data/test/dummy/app/controllers/application_controller.rb +5 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  29. data/test/dummy/bin/bundle +3 -0
  30. data/test/dummy/bin/rails +4 -0
  31. data/test/dummy/bin/rake +4 -0
  32. data/test/dummy/config/application.rb +23 -0
  33. data/test/dummy/config/boot.rb +5 -0
  34. data/test/dummy/config/database.yml +25 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +29 -0
  37. data/test/dummy/config/environments/production.rb +80 -0
  38. data/test/dummy/config/environments/test.rb +36 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/test/dummy/config/initializers/inflections.rb +16 -0
  42. data/test/dummy/config/initializers/mime_types.rb +5 -0
  43. data/test/dummy/config/initializers/secret_token.rb +12 -0
  44. data/test/dummy/config/initializers/session_store.rb +3 -0
  45. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  46. data/test/dummy/config/locales/en.yml +23 -0
  47. data/test/dummy/config/routes.rb +4 -0
  48. data/test/dummy/config.ru +4 -0
  49. data/test/dummy/public/404.html +58 -0
  50. data/test/dummy/public/422.html +58 -0
  51. data/test/dummy/public/500.html +57 -0
  52. data/test/dummy/public/favicon.ico +0 -0
  53. data/test/integration/navigation_test.rb +10 -0
  54. data/test/test_helper.rb +15 -0
  55. data/test/twitter_ratchet_rails_test.rb +7 -0
  56. metadata +146 -0
@@ -0,0 +1,916 @@
1
+ /*!
2
+ * =====================================================
3
+ * Ratchet v2.0.1 (http://goratchet.com)
4
+ * Copyright 2014 Connor Sears
5
+ * Licensed under MIT.
6
+ *
7
+ * v2.0.1 designed by @connors.
8
+ * =====================================================
9
+ */
10
+ /* ----------------------------------
11
+ * MODAL v2.0.1
12
+ * Licensed under The MIT License
13
+ * http://opensource.org/licenses/MIT
14
+ * ---------------------------------- */
15
+
16
+ !(function () {
17
+ 'use strict';
18
+
19
+ var findModals = function (target) {
20
+ var i, modals = document.querySelectorAll('a');
21
+ for (; target && target !== document; target = target.parentNode) {
22
+ for (i = modals.length; i--;) {
23
+ if (modals[i] === target) {
24
+ return target;
25
+ }
26
+ }
27
+ }
28
+ };
29
+
30
+ var getModal = function (event) {
31
+ var modalToggle = findModals(event.target);
32
+ if (modalToggle && modalToggle.hash) {
33
+ return document.querySelector(modalToggle.hash);
34
+ }
35
+ };
36
+
37
+ window.addEventListener('touchend', function (event) {
38
+ var modal = getModal(event);
39
+ if (modal) {
40
+ if (modal && modal.classList.contains('modal')) {
41
+ modal.classList.toggle('active');
42
+ }
43
+ event.preventDefault(); // prevents rewriting url (apps can still use hash values in url)
44
+ }
45
+ });
46
+ }());
47
+
48
+ /* ----------------------------------
49
+ * POPOVER v2.0.1
50
+ * Licensed under The MIT License
51
+ * http://opensource.org/licenses/MIT
52
+ * ---------------------------------- */
53
+
54
+ !(function () {
55
+ 'use strict';
56
+
57
+ var popover;
58
+
59
+ var findPopovers = function (target) {
60
+ var i, popovers = document.querySelectorAll('a');
61
+ for (; target && target !== document; target = target.parentNode) {
62
+ for (i = popovers.length; i--;) {
63
+ if (popovers[i] === target) {
64
+ return target;
65
+ }
66
+ }
67
+ }
68
+ };
69
+
70
+ var onPopoverHidden = function () {
71
+ popover.style.display = 'none';
72
+ popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
73
+ };
74
+
75
+ var backdrop = (function () {
76
+ var element = document.createElement('div');
77
+
78
+ element.classList.add('backdrop');
79
+
80
+ element.addEventListener('touchend', function () {
81
+ popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
82
+ popover.classList.remove('visible');
83
+ popover.parentNode.removeChild(backdrop);
84
+ });
85
+
86
+ return element;
87
+ }());
88
+
89
+ var getPopover = function (e) {
90
+ var anchor = findPopovers(e.target);
91
+
92
+ if (!anchor || !anchor.hash || (anchor.hash.indexOf('/') > 0)) {
93
+ return;
94
+ }
95
+
96
+ try {
97
+ popover = document.querySelector(anchor.hash);
98
+ }
99
+ catch (error) {
100
+ popover = null;
101
+ }
102
+
103
+ if (popover == null) {
104
+ return;
105
+ }
106
+
107
+ if (!popover || !popover.classList.contains('popover')) {
108
+ return;
109
+ }
110
+
111
+ return popover;
112
+ };
113
+
114
+ var showHidePopover = function (e) {
115
+ var popover = getPopover(e);
116
+
117
+ if (!popover) {
118
+ return;
119
+ }
120
+
121
+ popover.style.display = 'block';
122
+ popover.offsetHeight;
123
+ popover.classList.add('visible');
124
+
125
+ popover.parentNode.appendChild(backdrop);
126
+ };
127
+
128
+ window.addEventListener('touchend', showHidePopover);
129
+ window.addEventListener('click', showHidePopover);
130
+
131
+ }());
132
+
133
+ /* ----------------------------------
134
+ * PUSH v2.0.1
135
+ * Licensed under The MIT License
136
+ * inspired by chris's jquery.pjax.js
137
+ * http://opensource.org/licenses/MIT
138
+ * ---------------------------------- */
139
+
140
+ /* global _gaq: true */
141
+
142
+ !(function () {
143
+ 'use strict';
144
+
145
+ var noop = function () {};
146
+
147
+
148
+ // Pushstate cacheing
149
+ // ==================
150
+
151
+ var isScrolling;
152
+ var maxCacheLength = 20;
153
+ var cacheMapping = sessionStorage;
154
+ var domCache = {};
155
+ var transitionMap = {
156
+ 'slide-in' : 'slide-out',
157
+ 'slide-out' : 'slide-in',
158
+ 'fade' : 'fade'
159
+ };
160
+
161
+ var bars = {
162
+ bartab : '.bar-tab',
163
+ barnav : '.bar-nav',
164
+ barfooter : '.bar-footer',
165
+ barheadersecondary : '.bar-header-secondary'
166
+ };
167
+
168
+ var cacheReplace = function (data, updates) {
169
+ PUSH.id = data.id;
170
+ if (updates) {
171
+ data = getCached(data.id);
172
+ }
173
+ cacheMapping[data.id] = JSON.stringify(data);
174
+ window.history.replaceState(data.id, data.title, data.url);
175
+ domCache[data.id] = document.body.cloneNode(true);
176
+ };
177
+
178
+ var cachePush = function () {
179
+ var id = PUSH.id;
180
+
181
+ var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
182
+ var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
183
+
184
+ cacheBackStack.push(id);
185
+
186
+ while (cacheForwardStack.length) {
187
+ delete cacheMapping[cacheForwardStack.shift()];
188
+ }
189
+ while (cacheBackStack.length > maxCacheLength) {
190
+ delete cacheMapping[cacheBackStack.shift()];
191
+ }
192
+
193
+ window.history.pushState(null, '', cacheMapping[PUSH.id].url);
194
+
195
+ cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
196
+ cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
197
+ };
198
+
199
+ var cachePop = function (id, direction) {
200
+ var forward = direction === 'forward';
201
+ var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
202
+ var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
203
+ var pushStack = forward ? cacheBackStack : cacheForwardStack;
204
+ var popStack = forward ? cacheForwardStack : cacheBackStack;
205
+
206
+ if (PUSH.id) {
207
+ pushStack.push(PUSH.id);
208
+ }
209
+ popStack.pop();
210
+
211
+ cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
212
+ cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
213
+ };
214
+
215
+ var getCached = function (id) {
216
+ return JSON.parse(cacheMapping[id] || null) || {};
217
+ };
218
+
219
+ var getTarget = function (e) {
220
+ var target = findTarget(e.target);
221
+
222
+ if (!target ||
223
+ e.which > 1 ||
224
+ e.metaKey ||
225
+ e.ctrlKey ||
226
+ isScrolling ||
227
+ location.protocol !== target.protocol ||
228
+ location.host !== target.host ||
229
+ !target.hash && /#/.test(target.href) ||
230
+ target.hash && target.href.replace(target.hash, '') === location.href.replace(location.hash, '') ||
231
+ target.getAttribute('data-ignore') === 'push') { return; }
232
+
233
+ return target;
234
+ };
235
+
236
+
237
+ // Main event handlers (touchend, popstate)
238
+ // ==========================================
239
+
240
+ var touchend = function (e) {
241
+ var target = getTarget(e);
242
+
243
+ if (!target) {
244
+ return;
245
+ }
246
+
247
+ e.preventDefault();
248
+
249
+ PUSH({
250
+ url : target.href,
251
+ hash : target.hash,
252
+ timeout : target.getAttribute('data-timeout'),
253
+ transition : target.getAttribute('data-transition')
254
+ });
255
+ };
256
+
257
+ var popstate = function (e) {
258
+ var key;
259
+ var barElement;
260
+ var activeObj;
261
+ var activeDom;
262
+ var direction;
263
+ var transition;
264
+ var transitionFrom;
265
+ var transitionFromObj;
266
+ var id = e.state;
267
+
268
+ if (!id || !cacheMapping[id]) {
269
+ return;
270
+ }
271
+
272
+ direction = PUSH.id < id ? 'forward' : 'back';
273
+
274
+ cachePop(id, direction);
275
+
276
+ activeObj = getCached(id);
277
+ activeDom = domCache[id];
278
+
279
+ if (activeObj.title) {
280
+ document.title = activeObj.title;
281
+ }
282
+
283
+ if (direction === 'back') {
284
+ transitionFrom = JSON.parse(direction === 'back' ? cacheMapping.cacheForwardStack : cacheMapping.cacheBackStack);
285
+ transitionFromObj = getCached(transitionFrom[transitionFrom.length - 1]);
286
+ } else {
287
+ transitionFromObj = activeObj;
288
+ }
289
+
290
+ if (direction === 'back' && !transitionFromObj.id) {
291
+ return (PUSH.id = id);
292
+ }
293
+
294
+ transition = direction === 'back' ? transitionMap[transitionFromObj.transition] : transitionFromObj.transition;
295
+
296
+ if (!activeDom) {
297
+ return PUSH({
298
+ id : activeObj.id,
299
+ url : activeObj.url,
300
+ title : activeObj.title,
301
+ timeout : activeObj.timeout,
302
+ transition : transition,
303
+ ignorePush : true
304
+ });
305
+ }
306
+
307
+ if (transitionFromObj.transition) {
308
+ activeObj = extendWithDom(activeObj, '.content', activeDom.cloneNode(true));
309
+ for (key in bars) {
310
+ if (bars.hasOwnProperty(key)) {
311
+ barElement = document.querySelector(bars[key]);
312
+ if (activeObj[key]) {
313
+ swapContent(activeObj[key], barElement);
314
+ } else if (barElement) {
315
+ barElement.parentNode.removeChild(barElement);
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ swapContent(
322
+ (activeObj.contents || activeDom).cloneNode(true),
323
+ document.querySelector('.content'),
324
+ transition
325
+ );
326
+
327
+ PUSH.id = id;
328
+
329
+ document.body.offsetHeight; // force reflow to prevent scroll
330
+ };
331
+
332
+
333
+ // Core PUSH functionality
334
+ // =======================
335
+
336
+ var PUSH = function (options) {
337
+ var key;
338
+ var xhr = PUSH.xhr;
339
+
340
+ options.container = options.container || options.transition ? document.querySelector('.content') : document.body;
341
+
342
+ for (key in bars) {
343
+ if (bars.hasOwnProperty(key)) {
344
+ options[key] = options[key] || document.querySelector(bars[key]);
345
+ }
346
+ }
347
+
348
+ if (xhr && xhr.readyState < 4) {
349
+ xhr.onreadystatechange = noop;
350
+ xhr.abort();
351
+ }
352
+
353
+ xhr = new XMLHttpRequest();
354
+ xhr.open('GET', options.url, true);
355
+ xhr.setRequestHeader('X-PUSH', 'true');
356
+
357
+ xhr.onreadystatechange = function () {
358
+ if (options._timeout) {
359
+ clearTimeout(options._timeout);
360
+ }
361
+ if (xhr.readyState === 4) {
362
+ xhr.status === 200 ? success(xhr, options) : failure(options.url);
363
+ }
364
+ };
365
+
366
+ if (!PUSH.id) {
367
+ cacheReplace({
368
+ id : +new Date(),
369
+ url : window.location.href,
370
+ title : document.title,
371
+ timeout : options.timeout,
372
+ transition : null
373
+ });
374
+ }
375
+
376
+ if (options.timeout) {
377
+ options._timeout = setTimeout(function () { xhr.abort('timeout'); }, options.timeout);
378
+ }
379
+
380
+ xhr.send();
381
+
382
+ if (xhr.readyState && !options.ignorePush) {
383
+ cachePush();
384
+ }
385
+ };
386
+
387
+
388
+ // Main XHR handlers
389
+ // =================
390
+
391
+ var success = function (xhr, options) {
392
+ var key;
393
+ var barElement;
394
+ var data = parseXHR(xhr, options);
395
+
396
+ if (!data.contents) {
397
+ return locationReplace(options.url);
398
+ }
399
+
400
+ if (data.title) {
401
+ document.title = data.title;
402
+ }
403
+
404
+ if (options.transition) {
405
+ for (key in bars) {
406
+ if (bars.hasOwnProperty(key)) {
407
+ barElement = document.querySelector(bars[key]);
408
+ if (data[key]) {
409
+ swapContent(data[key], barElement);
410
+ } else if (barElement) {
411
+ barElement.parentNode.removeChild(barElement);
412
+ }
413
+ }
414
+ }
415
+ }
416
+
417
+ swapContent(data.contents, options.container, options.transition, function () {
418
+ cacheReplace({
419
+ id : options.id || +new Date(),
420
+ url : data.url,
421
+ title : data.title,
422
+ timeout : options.timeout,
423
+ transition : options.transition
424
+ }, options.id);
425
+ triggerStateChange();
426
+ });
427
+
428
+ if (!options.ignorePush && window._gaq) {
429
+ _gaq.push(['_trackPageview']); // google analytics
430
+ }
431
+ if (!options.hash) {
432
+ return;
433
+ }
434
+ };
435
+
436
+ var failure = function (url) {
437
+ throw new Error('Could not get: ' + url);
438
+ };
439
+
440
+
441
+ // PUSH helpers
442
+ // ============
443
+
444
+ var swapContent = function (swap, container, transition, complete) {
445
+ var enter;
446
+ var containerDirection;
447
+ var swapDirection;
448
+
449
+ if (!transition) {
450
+ if (container) {
451
+ container.innerHTML = swap.innerHTML;
452
+ } else if (swap.classList.contains('content')) {
453
+ document.body.appendChild(swap);
454
+ } else {
455
+ document.body.insertBefore(swap, document.querySelector('.content'));
456
+ }
457
+ } else {
458
+ enter = /in$/.test(transition);
459
+
460
+ if (transition === 'fade') {
461
+ container.classList.add('in');
462
+ container.classList.add('fade');
463
+ swap.classList.add('fade');
464
+ }
465
+
466
+ if (/slide/.test(transition)) {
467
+ swap.classList.add('sliding-in', enter ? 'right' : 'left');
468
+ swap.classList.add('sliding');
469
+ container.classList.add('sliding');
470
+ }
471
+
472
+ container.parentNode.insertBefore(swap, container);
473
+ }
474
+
475
+ if (!transition) {
476
+ complete && complete();
477
+ }
478
+
479
+ if (transition === 'fade') {
480
+ container.offsetWidth; // force reflow
481
+ container.classList.remove('in');
482
+ var fadeContainerEnd = function () {
483
+ container.removeEventListener('webkitTransitionEnd', fadeContainerEnd);
484
+ swap.classList.add('in');
485
+ swap.addEventListener('webkitTransitionEnd', fadeSwapEnd);
486
+ };
487
+ var fadeSwapEnd = function () {
488
+ swap.removeEventListener('webkitTransitionEnd', fadeSwapEnd);
489
+ container.parentNode.removeChild(container);
490
+ swap.classList.remove('fade');
491
+ swap.classList.remove('in');
492
+ complete && complete();
493
+ };
494
+ container.addEventListener('webkitTransitionEnd', fadeContainerEnd);
495
+
496
+ }
497
+
498
+ if (/slide/.test(transition)) {
499
+ var slideEnd = function () {
500
+ swap.removeEventListener('webkitTransitionEnd', slideEnd);
501
+ swap.classList.remove('sliding', 'sliding-in');
502
+ swap.classList.remove(swapDirection);
503
+ container.parentNode.removeChild(container);
504
+ complete && complete();
505
+ };
506
+
507
+ container.offsetWidth; // force reflow
508
+ swapDirection = enter ? 'right' : 'left';
509
+ containerDirection = enter ? 'left' : 'right';
510
+ container.classList.add(containerDirection);
511
+ swap.classList.remove(swapDirection);
512
+ swap.addEventListener('webkitTransitionEnd', slideEnd);
513
+ }
514
+ };
515
+
516
+ var triggerStateChange = function () {
517
+ var e = new CustomEvent('push', {
518
+ detail: { state: getCached(PUSH.id) },
519
+ bubbles: true,
520
+ cancelable: true
521
+ });
522
+
523
+ window.dispatchEvent(e);
524
+ };
525
+
526
+ var findTarget = function (target) {
527
+ var i, toggles = document.querySelectorAll('a');
528
+ for (; target && target !== document; target = target.parentNode) {
529
+ for (i = toggles.length; i--;) {
530
+ if (toggles[i] === target) {
531
+ return target;
532
+ }
533
+ }
534
+ }
535
+ };
536
+
537
+ var locationReplace = function (url) {
538
+ window.history.replaceState(null, '', '#');
539
+ window.location.replace(url);
540
+ };
541
+
542
+ var extendWithDom = function (obj, fragment, dom) {
543
+ var i;
544
+ var result = {};
545
+
546
+ for (i in obj) {
547
+ if (obj.hasOwnProperty(i)) {
548
+ result[i] = obj[i];
549
+ }
550
+ }
551
+
552
+ Object.keys(bars).forEach(function (key) {
553
+ var el = dom.querySelector(bars[key]);
554
+ if (el) {
555
+ el.parentNode.removeChild(el);
556
+ }
557
+ result[key] = el;
558
+ });
559
+
560
+ result.contents = dom.querySelector(fragment);
561
+
562
+ return result;
563
+ };
564
+
565
+ var parseXHR = function (xhr, options) {
566
+ var head;
567
+ var body;
568
+ var data = {};
569
+ var responseText = xhr.responseText;
570
+
571
+ data.url = options.url;
572
+
573
+ if (!responseText) {
574
+ return data;
575
+ }
576
+
577
+ if (/<html/i.test(responseText)) {
578
+ head = document.createElement('div');
579
+ body = document.createElement('div');
580
+ head.innerHTML = responseText.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0];
581
+ body.innerHTML = responseText.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0];
582
+ } else {
583
+ head = body = document.createElement('div');
584
+ head.innerHTML = responseText;
585
+ }
586
+
587
+ data.title = head.querySelector('title');
588
+ data.title = data.title && data.title.innerText.trim();
589
+
590
+ if (options.transition) {
591
+ data = extendWithDom(data, '.content', body);
592
+ } else {
593
+ data.contents = body;
594
+ }
595
+
596
+ return data;
597
+ };
598
+
599
+
600
+ // Attach PUSH event handlers
601
+ // ==========================
602
+
603
+ window.addEventListener('touchstart', function () { isScrolling = false; });
604
+ window.addEventListener('touchmove', function () { isScrolling = true; });
605
+ window.addEventListener('touchend', touchend);
606
+ window.addEventListener('click', function (e) { if (getTarget(e)) {e.preventDefault();} });
607
+ window.addEventListener('popstate', popstate);
608
+ window.PUSH = PUSH;
609
+
610
+ }());
611
+
612
+ /* ----------------------------------
613
+ * Segmented controls v2.0.1
614
+ * Licensed under The MIT License
615
+ * http://opensource.org/licenses/MIT
616
+ * ---------------------------------- */
617
+
618
+ !(function () {
619
+ 'use strict';
620
+
621
+ var getTarget = function (target) {
622
+ var i, segmentedControls = document.querySelectorAll('.segmented-control .control-item');
623
+ for (; target && target !== document; target = target.parentNode) {
624
+ for (i = segmentedControls.length; i--;) {
625
+ if (segmentedControls[i] === target) {
626
+ return target;
627
+ }
628
+ }
629
+ }
630
+ };
631
+
632
+ window.addEventListener('touchend', function (e) {
633
+ var activeTab;
634
+ var activeBodies;
635
+ var targetBody;
636
+ var targetTab = getTarget(e.target);
637
+ var className = 'active';
638
+ var classSelector = '.' + className;
639
+
640
+ if (!targetTab) {
641
+ return;
642
+ }
643
+
644
+ activeTab = targetTab.parentNode.querySelector(classSelector);
645
+
646
+ if (activeTab) {
647
+ activeTab.classList.remove(className);
648
+ }
649
+
650
+ targetTab.classList.add(className);
651
+
652
+ if (!targetTab.hash) {
653
+ return;
654
+ }
655
+
656
+ targetBody = document.querySelector(targetTab.hash);
657
+
658
+ if (!targetBody) {
659
+ return;
660
+ }
661
+
662
+ activeBodies = targetBody.parentNode.querySelectorAll(classSelector);
663
+
664
+ for (var i = 0; i < activeBodies.length; i++) {
665
+ activeBodies[i].classList.remove(className);
666
+ }
667
+
668
+ targetBody.classList.add(className);
669
+ });
670
+
671
+ window.addEventListener('click', function (e) { if (getTarget(e.target)) {e.preventDefault();} });
672
+ }());
673
+ /* ----------------------------------
674
+ * SLIDER v2.0.1
675
+ * Licensed under The MIT License
676
+ * Adapted from Brad Birdsall's swipe
677
+ * http://opensource.org/licenses/MIT
678
+ * ---------------------------------- */
679
+
680
+ !(function () {
681
+ 'use strict';
682
+
683
+ var pageX;
684
+ var pageY;
685
+ var slider;
686
+ var deltaX;
687
+ var deltaY;
688
+ var offsetX;
689
+ var lastSlide;
690
+ var startTime;
691
+ var resistance;
692
+ var sliderWidth;
693
+ var slideNumber;
694
+ var isScrolling;
695
+ var scrollableArea;
696
+
697
+ var getSlider = function (target) {
698
+ var i, sliders = document.querySelectorAll('.slider > .slide-group');
699
+ for (; target && target !== document; target = target.parentNode) {
700
+ for (i = sliders.length; i--;) {
701
+ if (sliders[i] === target) {
702
+ return target;
703
+ }
704
+ }
705
+ }
706
+ };
707
+
708
+ var getScroll = function () {
709
+ var translate3d = slider.style.webkitTransform.match(/translate3d\(([^,]*)/);
710
+ var ret = translate3d ? translate3d[1] : 0;
711
+ return parseInt(ret, 10);
712
+ };
713
+
714
+ var setSlideNumber = function (offset) {
715
+ var round = offset ? (deltaX < 0 ? 'ceil' : 'floor') : 'round';
716
+ slideNumber = Math[round](getScroll() / ( scrollableArea / slider.children.length) );
717
+ slideNumber += offset;
718
+ slideNumber = Math.min(slideNumber, 0);
719
+ slideNumber = Math.max(-(slider.children.length - 1), slideNumber);
720
+ };
721
+
722
+ var onTouchStart = function (e) {
723
+ slider = getSlider(e.target);
724
+
725
+ if (!slider) {
726
+ return;
727
+ }
728
+
729
+ var firstItem = slider.querySelector('.slide');
730
+
731
+ scrollableArea = firstItem.offsetWidth * slider.children.length;
732
+ isScrolling = undefined;
733
+ sliderWidth = slider.offsetWidth;
734
+ resistance = 1;
735
+ lastSlide = -(slider.children.length - 1);
736
+ startTime = +new Date();
737
+ pageX = e.touches[0].pageX;
738
+ pageY = e.touches[0].pageY;
739
+ deltaX = 0;
740
+ deltaY = 0;
741
+
742
+ setSlideNumber(0);
743
+
744
+ slider.style['-webkit-transition-duration'] = 0;
745
+ };
746
+
747
+ var onTouchMove = function (e) {
748
+ if (e.touches.length > 1 || !slider) {
749
+ return; // Exit if a pinch || no slider
750
+ }
751
+
752
+ deltaX = e.touches[0].pageX - pageX;
753
+ deltaY = e.touches[0].pageY - pageY;
754
+ pageX = e.touches[0].pageX;
755
+ pageY = e.touches[0].pageY;
756
+
757
+ if (typeof isScrolling === 'undefined') {
758
+ isScrolling = Math.abs(deltaY) > Math.abs(deltaX);
759
+ }
760
+
761
+ if (isScrolling) {
762
+ return;
763
+ }
764
+
765
+ offsetX = (deltaX / resistance) + getScroll();
766
+
767
+ e.preventDefault();
768
+
769
+ resistance = slideNumber === 0 && deltaX > 0 ? (pageX / sliderWidth) + 1.25 :
770
+ slideNumber === lastSlide && deltaX < 0 ? (Math.abs(pageX) / sliderWidth) + 1.25 : 1;
771
+
772
+ slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
773
+ };
774
+
775
+ var onTouchEnd = function (e) {
776
+ if (!slider || isScrolling) {
777
+ return;
778
+ }
779
+
780
+ setSlideNumber(
781
+ (+new Date()) - startTime < 1000 && Math.abs(deltaX) > 15 ? (deltaX < 0 ? -1 : 1) : 0
782
+ );
783
+
784
+ offsetX = slideNumber * sliderWidth;
785
+
786
+ slider.style['-webkit-transition-duration'] = '.2s';
787
+ slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
788
+
789
+ e = new CustomEvent('slide', {
790
+ detail: { slideNumber: Math.abs(slideNumber) },
791
+ bubbles: true,
792
+ cancelable: true
793
+ });
794
+
795
+ slider.parentNode.dispatchEvent(e);
796
+ };
797
+
798
+ window.addEventListener('touchstart', onTouchStart);
799
+ window.addEventListener('touchmove', onTouchMove);
800
+ window.addEventListener('touchend', onTouchEnd);
801
+
802
+ }());
803
+
804
+ /* ----------------------------------
805
+ * TOGGLE v2.0.1
806
+ * Licensed under The MIT License
807
+ * http://opensource.org/licenses/MIT
808
+ * ---------------------------------- */
809
+
810
+ !(function () {
811
+ 'use strict';
812
+
813
+ var start = {};
814
+ var touchMove = false;
815
+ var distanceX = false;
816
+ var toggle = false;
817
+
818
+ var findToggle = function (target) {
819
+ var i, toggles = document.querySelectorAll('.toggle');
820
+ for (; target && target !== document; target = target.parentNode) {
821
+ for (i = toggles.length; i--;) {
822
+ if (toggles[i] === target) {
823
+ return target;
824
+ }
825
+ }
826
+ }
827
+ };
828
+
829
+ window.addEventListener('touchstart', function (e) {
830
+ e = e.originalEvent || e;
831
+
832
+ toggle = findToggle(e.target);
833
+
834
+ if (!toggle) {
835
+ return;
836
+ }
837
+
838
+ var handle = toggle.querySelector('.toggle-handle');
839
+ var toggleWidth = toggle.clientWidth;
840
+ var handleWidth = handle.clientWidth;
841
+ var offset = toggle.classList.contains('active') ? (toggleWidth - handleWidth) : 0;
842
+
843
+ start = { pageX : e.touches[0].pageX - offset, pageY : e.touches[0].pageY };
844
+ touchMove = false;
845
+ });
846
+
847
+ window.addEventListener('touchmove', function (e) {
848
+ e = e.originalEvent || e;
849
+
850
+ if (e.touches.length > 1) {
851
+ return; // Exit if a pinch
852
+ }
853
+
854
+ if (!toggle) {
855
+ return;
856
+ }
857
+
858
+ var handle = toggle.querySelector('.toggle-handle');
859
+ var current = e.touches[0];
860
+ var toggleWidth = toggle.clientWidth;
861
+ var handleWidth = handle.clientWidth;
862
+ var offset = toggleWidth - handleWidth;
863
+
864
+ touchMove = true;
865
+ distanceX = current.pageX - start.pageX;
866
+
867
+ if (Math.abs(distanceX) < Math.abs(current.pageY - start.pageY)) {
868
+ return;
869
+ }
870
+
871
+ e.preventDefault();
872
+
873
+ if (distanceX < 0) {
874
+ return (handle.style.webkitTransform = 'translate3d(0,0,0)');
875
+ }
876
+ if (distanceX > offset) {
877
+ return (handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)');
878
+ }
879
+
880
+ handle.style.webkitTransform = 'translate3d(' + distanceX + 'px,0,0)';
881
+
882
+ toggle.classList[(distanceX > (toggleWidth/2 - handleWidth/2)) ? 'add' : 'remove']('active');
883
+ });
884
+
885
+ window.addEventListener('touchend', function (e) {
886
+ if (!toggle) {
887
+ return;
888
+ }
889
+
890
+ var handle = toggle.querySelector('.toggle-handle');
891
+ var toggleWidth = toggle.clientWidth;
892
+ var handleWidth = handle.clientWidth;
893
+ var offset = (toggleWidth - handleWidth);
894
+ var slideOn = (!touchMove && !toggle.classList.contains('active')) || (touchMove && (distanceX > (toggleWidth/2 - handleWidth/2)));
895
+
896
+ if (slideOn) {
897
+ handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
898
+ } else {
899
+ handle.style.webkitTransform = 'translate3d(0,0,0)';
900
+ }
901
+
902
+ toggle.classList[slideOn ? 'add' : 'remove']('active');
903
+
904
+ e = new CustomEvent('toggle', {
905
+ detail: { isActive: slideOn },
906
+ bubbles: true,
907
+ cancelable: true
908
+ });
909
+
910
+ toggle.dispatchEvent(e);
911
+
912
+ touchMove = false;
913
+ toggle = false;
914
+ });
915
+
916
+ }());