rytm-webflow 2.1.12 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -142,7 +142,9 @@ RytmWebflow.aswap.init({
142
142
  | ```animationTimeHide``` | ```800``` | Time (ms) for view's *hide* transition|
143
143
  | ```animationTimeShow``` | ```800``` | Time (ms) for view's *show* transition|
144
144
  | ```formsEnabled``` | ```true``` | Use *ASwap* on forms|
145
- | ```formsSelector``` | ```'form[method="get"]'``` | *ASwap* forms selector - as default uses forms with *GET* method only|
145
+ | ```formsSelector``` | ```'form'``` | *ASwap* forms selector|
146
+ | ```swipeEnabled``` | ```true``` | Use *ASwap* [swipe](#swipe)|
147
+ | ```swipeMinDistance``` | ```5``` | Minimum swipe move distance (px) for [swipe](#swipe) to fire|
146
148
  | ```historyEnabled``` | ```true``` | Use history push state |
147
149
  | ```historyFallback``` | ```true``` | Fallback if browser dosn't support history push state |
148
150
  | ```cacheOn``` | ```true``` | By default all requests are being cached. Set to ```false``` to turn cache off |
@@ -218,6 +220,17 @@ RytmWebflow.aswap.init(params, {
218
220
  },
219
221
  })
220
222
  ```
223
+ ## <a name="swipe">Swipe</a> ##
224
+ Add urls to `as-swipe-{direction}` data attributes, eg:
225
+ ```html
226
+ <div
227
+ data-as-swipe-left="/path/to-next"
228
+ data-as-swipe-right="/path/to-prev"
229
+ data-as-swipe-up="/path/to-back">
230
+ ...
231
+ </div>
232
+ ```
233
+
221
234
  ## <a name="webflowview">WebflowView</a> ##
222
235
  WebflowView is an universal ASwap View which can be used with the **Webflow syntax** - a minified way to describe an animation, it's duration (time), easing, delay or the trigger. Eg. `y:100,o:0` will animate an element from: `y:100px` and `opacity: 0` to it's current state. Go to [Webflow syntax](#webflowsyntax) for more.
223
236
  ### Basic usage example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rytm-webflow",
3
- "version": "2.1.12",
3
+ "version": "2.2.0",
4
4
  "description": "rytm webflow pack - ASwap, ShowUp",
5
5
  "main": "scripts/index.js",
6
6
  "scripts": {
@@ -12,7 +12,9 @@ class ASwap {
12
12
  animationTimeHide: 800, // hide animation time
13
13
  animationTimeShow: 800, // show animation time
14
14
  formsEnabled: true, // use aswap on forms
15
- formsSelector: 'form[method="get"]', // aswap forms selector
15
+ formsSelector: 'form', // aswap forms selector
16
+ swipeEnabled: true, // use aswap `swipe`
17
+ swipeMinDistance: 5, // min swipe move distance
16
18
  historyEnabled: true, // use history push state
17
19
  historyFallback: true, // fallback of browser dosn't support history push state
18
20
  cacheOn: true, // use Aswap Cache?
@@ -96,6 +98,14 @@ class ASwap {
96
98
  this.dispatcher.clearCache(url);
97
99
  }
98
100
  }
101
+ /**
102
+ * submit form
103
+ */
104
+ formSubmit(form) {
105
+ if (this.dispatcher) {
106
+ this.dispatcher.formSubmit(form);
107
+ }
108
+ }
99
109
  onRequestUrl(e) {
100
110
  document.documentElement.classList.add('as-in-progress')
101
111
  this.getActiveControlles().forEach( (c, index)=> {
@@ -297,6 +297,22 @@ class ASwapDispatcher extends EventDispatcher {
297
297
  xhr.send();
298
298
 
299
299
  }
300
+ /**
301
+ * Form submit
302
+ */
303
+ formSubmit(form) {
304
+ const useCache = !form.classList.contains(this.noCacheClassName);
305
+ const url = form.getAttribute("action");
306
+ if (url.indexOf('://') < 0) {
307
+ this.currentTrigger = form
308
+ const method = form.getAttribute('method') ? form.getAttribute('method') : 'get'
309
+ const formData = new FormData(form);
310
+ this.submit(url, formData, method, false, useCache);
311
+ // const dataStr = new URLSearchParams(formData).toString();
312
+ // const requestUrl = method == 'get' ? (url + '?' + dataStr) : url;
313
+ // this.submit(requestUrl, formData, method, false, useCache);
314
+ }
315
+ }
300
316
  /**
301
317
  *
302
318
  * @param {string} url
@@ -305,7 +321,7 @@ class ASwapDispatcher extends EventDispatcher {
305
321
  * @param {boolean} noHistory
306
322
  * @param {boolean} useCache
307
323
  */
308
- submit(url, data, method, noHistory = false, useCache = true) {
324
+ submit(url, formData, method, noHistory = false, useCache = true) {
309
325
  // dispatch event
310
326
  this.dispatch(Events.NAV_REQUEST_URL);
311
327
  this.prevUrl = this.currentUrl;
@@ -313,11 +329,22 @@ class ASwapDispatcher extends EventDispatcher {
313
329
  if (!noHistory) {
314
330
  this.pushState(url);
315
331
  }
316
- let result = this.getStoredResult(url);
317
- if (result) {
318
- this.handleResult(result);
319
- } else {
320
- this.loadURL(url, data, method, useCache);
332
+ switch (method) {
333
+ case 'post':
334
+ // POST
335
+ this.loadURL(url, formData, method, false);
336
+ break;
337
+ default:
338
+ // GET
339
+ const dataStr = new URLSearchParams(formData).toString();
340
+ url = method == 'get' ? (url + '?' + dataStr) : url;
341
+ let result = useCache ? this.getStoredResult(url) : null;
342
+ if (result) {
343
+ this.handleResult(result);
344
+ } else {
345
+ this.loadURL(url, formData, method, useCache);
346
+ }
347
+ break;
321
348
  }
322
349
  }
323
350
  /**
@@ -346,7 +373,6 @@ class ASwapDispatcher extends EventDispatcher {
346
373
  // dispatch event
347
374
  this.dispatch(Events.NAV_REQUEST_LOAD);
348
375
  this.trace("ASwap load: ", url);
349
-
350
376
  let xhr = new XMLHttpRequest();
351
377
  xhr.onreadystatechange = () => {
352
378
  if (xhr.readyState === 4) {
@@ -443,22 +469,56 @@ class ASwapDispatcher extends EventDispatcher {
443
469
  }
444
470
  }
445
471
  }
472
+ // SUBMIT
446
473
  onDocumentSubmit(e) {
447
474
  if (e.target.tagName == 'FORM') {
448
- const f = e.target
449
- if (this.isFormElementValid(f)) {
475
+ if (this.isFormElementValid(e.target)) {
450
476
  e.preventDefault();
451
- const useCache = !f.classList.contains(this.noCacheClassName);
452
- const url = f.getAttribute("action");
453
- if (url.indexOf('://') < 0) {
454
- e.preventDefault()
455
- this.currentTrigger = f
456
- const method = f.getAttribute('method') ? f.getAttribute('method') : 'get'
457
- const dataStr = new URLSearchParams(new FormData(f)).toString()
458
- const requestUrl = method == 'get' ? (url + '?' + dataStr) : url
459
- this.submit(requestUrl, dataStr, method, false, useCache)
477
+ this.formSubmit(e.target);
478
+ }
479
+ }
480
+ }
481
+ // Swipe touch start event
482
+ handleTouchStart = (e) => {
483
+ const firstTouch = e.touches[0];
484
+ this.xDown = firstTouch.clientX;
485
+ this.yDown = firstTouch.clientY;
486
+ }
487
+ // Swipe touch move event
488
+ handleTouchMove = (e) => {
489
+ if ( !this.xDown || !this.yDown ) {
490
+ return;
491
+ }
492
+ const xUp = e.touches[0].clientX;
493
+ const yUp = e.touches[0].clientY;
494
+ const xDiff = this.xDown - xUp;
495
+ const yDiff = this.yDown - yUp;
496
+ if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
497
+ if (Math.abs(xDiff) > this.swipeMinDistance) {
498
+ if ( xDiff > 0 ) {
499
+ this.handleSwipe(e, 'left');
500
+ } else {
501
+ this.handleSwipe(e, 'right');
460
502
  }
461
-
503
+ }
504
+ } else if (Math.abs(yDiff) > this.swipeMinDistance) {
505
+ if ( yDiff > 0 ) {
506
+ this.handleSwipe(e, 'up');
507
+ } else {
508
+ this.handleSwipe(e, 'down');
509
+ }
510
+ }
511
+ /* reset values */
512
+ this.xDown = null;
513
+ this.yDown = null;
514
+ }
515
+ // handle SWIPE direction
516
+ handleSwipe = (e, direction) => {
517
+ const d = e.target.closest('[data-as-swipe-' + direction + ']')
518
+ if (d) {
519
+ const path = d.getAttribute('data-as-swipe-' + direction);
520
+ if (path) {
521
+ this.openURL(path);
462
522
  }
463
523
  }
464
524
  }
@@ -476,6 +536,11 @@ class ASwapDispatcher extends EventDispatcher {
476
536
  if (this.formsEnabled) {
477
537
  document.addEventListener('submit', this.onDocumentSubmit.bind(this), false)
478
538
  }
539
+ // swipe?
540
+ if (this.swipeEnabled) {
541
+ document.addEventListener('touchstart', this.handleTouchStart, false);
542
+ document.addEventListener('touchmove', this.handleTouchMove, false);
543
+ }
479
544
  // browser back button
480
545
  window.addEventListener('popstate', this.onHistoryBack.bind(this), false)
481
546
  }