luda 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/assets/javascripts/luda-degradation.js +2 -2
  3. data/assets/javascripts/luda-degradation.min.js +2 -2
  4. data/assets/javascripts/luda-sprockets.js +2 -2
  5. data/assets/javascripts/luda.js +719 -250
  6. data/assets/javascripts/luda.js.map +1 -1
  7. data/assets/javascripts/luda.min.js +3 -3
  8. data/assets/javascripts/luda.min.js.map +1 -1
  9. data/assets/javascripts/luda/behaviors/{enter-click.js → enter.js} +8 -6
  10. data/assets/javascripts/luda/behaviors/focus.js +14 -8
  11. data/assets/javascripts/luda/behaviors/readonly.js +4 -4
  12. data/assets/javascripts/luda/behaviors/{radio-tab.js → tabulate.js} +8 -6
  13. data/assets/javascripts/luda/behaviors/toggle.js +72 -18
  14. data/assets/javascripts/luda/dom.js +62 -0
  15. data/assets/javascripts/luda/elements/form-file.js +13 -4
  16. data/assets/javascripts/luda/elements/form-select.js +9 -5
  17. data/assets/javascripts/luda/event.js +11 -3
  18. data/assets/javascripts/luda/{component.js → factory.js} +149 -55
  19. data/assets/javascripts/luda/index.js +4 -4
  20. data/assets/javascripts/luda/install.js +2 -2
  21. data/assets/javascripts/luda/patterns/carousel.js +85 -59
  22. data/assets/javascripts/luda/patterns/dropdown.js +86 -68
  23. data/assets/javascripts/luda/patterns/form-dropdown.js +8 -8
  24. data/assets/javascripts/luda/patterns/tab.js +62 -23
  25. data/assets/javascripts/luda/static.js +224 -0
  26. data/assets/stylesheets/luda/_core/_functions.sass +11 -19
  27. data/assets/stylesheets/luda/_core/_variables.sass +140 -131
  28. data/assets/stylesheets/luda/_core/behaviors/_focus.sass +2 -2
  29. data/assets/stylesheets/luda/_core/elements/_button.sass +1 -1
  30. data/assets/stylesheets/luda/_core/elements/_grid.sass +0 -3
  31. data/assets/stylesheets/luda/_core/elements/_scrollbar.sass +8 -2
  32. data/assets/stylesheets/luda/_core/elements/form/_form-check-radio.sass +22 -31
  33. data/assets/stylesheets/luda/_core/elements/form/_form-element.sass +1 -1
  34. data/assets/stylesheets/luda/_core/elements/form/_form-helper.sass +19 -19
  35. data/assets/stylesheets/luda/_core/elements/form/_form-range.sass +19 -19
  36. data/assets/stylesheets/luda/_core/elements/form/_form-row.sass +43 -59
  37. data/assets/stylesheets/luda/_core/elements/typography/_quote.sass +1 -1
  38. data/assets/stylesheets/luda/_core/elements/typography/_typography.sass +9 -9
  39. data/assets/stylesheets/luda/_core/mixins/_dropdown.sass +8 -6
  40. data/assets/stylesheets/luda/_core/mixins/_form.sass +12 -12
  41. data/assets/stylesheets/luda/_core/mixins/_media-query.sass +12 -12
  42. data/assets/stylesheets/luda/_core/mixins/_typography.sass +4 -4
  43. data/assets/stylesheets/luda/_core/patterns/_breadcrumb.sass +2 -2
  44. data/assets/stylesheets/luda/_core/patterns/_button-group.sass +1 -1
  45. data/assets/stylesheets/luda/_core/patterns/_button-icon.sass +2 -2
  46. data/assets/stylesheets/luda/_core/patterns/_carousel.sass +13 -13
  47. data/assets/stylesheets/luda/_core/patterns/_dropdown.sass +5 -1
  48. data/assets/stylesheets/luda/_core/patterns/_form-dropdown.sass +3 -3
  49. data/assets/stylesheets/luda/_core/patterns/_form-group.sass +11 -11
  50. data/assets/stylesheets/luda/_core/patterns/_form-icon.sass +13 -19
  51. data/assets/stylesheets/luda/_core/patterns/_navigation.sass +5 -5
  52. data/assets/stylesheets/luda/_core/patterns/_search-bar.sass +2 -2
  53. data/assets/stylesheets/luda/_core/patterns/_tab.sass +1 -3
  54. data/assets/stylesheets/luda/_core/utilities/_border.sass +15 -15
  55. data/assets/stylesheets/luda/_core/utilities/_color.sass +4 -1
  56. data/assets/stylesheets/luda/_core/utilities/_display.sass +1 -1
  57. data/assets/stylesheets/luda/_core/utilities/_flex.sass +3 -0
  58. data/assets/stylesheets/luda/_core/utilities/_shadow.sass +12 -12
  59. data/assets/stylesheets/luda/_core/utilities/_spacing.sass +227 -0
  60. data/assets/stylesheets/luda/_core/utilities/_visibility.sass +1 -1
  61. data/assets/stylesheets/luda/_default.sass +1 -1
  62. data/assets/stylesheets/luda/default/_banner.sass +2 -2
  63. data/assets/stylesheets/luda/default/index.sass +1 -1
  64. data/assets/stylesheets/luda/default/utilities/_border.sass +4 -4
  65. data/assets/stylesheets/luda/default/utilities/_shadow.sass +4 -4
  66. data/assets/stylesheets/luda/default/utilities/_spacing.sass +5 -0
  67. data/lib/luda/version.rb +1 -1
  68. metadata +9 -11
  69. data/assets/javascripts/luda/singleton.js +0 -77
  70. data/assets/stylesheets/luda/_core/patterns/_form-button.sass +0 -23
  71. data/assets/stylesheets/luda/_core/patterns/_nav.sass +0 -165
  72. data/assets/stylesheets/luda/default/patterns/_form-button.sass +0 -9
  73. data/assets/stylesheets/luda/default/patterns/_nav.sass +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91a048c5663af9e7ef41077fb3beae38a9d29d4c32c4be13c9792069174e2f05
4
- data.tar.gz: 956745faf94d11f80c54f74b690e77298447687407a8e41ab7443055abcfa40d
3
+ metadata.gz: 1054ce023a6863675d67d8ecccb446ff7518e4e7cb4e5f6f9128afdd577ddcd2
4
+ data.tar.gz: dcd03dd757ca3d475f69358f096beaff38a219b356080e948f5183df75e867a2
5
5
  SHA512:
6
- metadata.gz: 7167e80427ee22d190828c4cacf9774bc76063d3f26eb9560523765e4f27cffd709c8ee10641a1abb02c3f803888e4abe295c1d0d68b619cca0cfc3dd5cbdecd
7
- data.tar.gz: 92d0ee54504708539c74827d2ad6a0edd2b259d07cbe295a9f4b95e6602fecbd4793b9b142a06a7892bd3e0d7301a78ffc1fe78151c18ddd1a2cd1b784993c10
6
+ metadata.gz: 2c8c265427e255b307f7f43f44de490b8e1d2429cb7482b75b05c28b051de20b6741ab744e873b589489175f6c53b361a885f1cb7e0fd070eb796345a804e564
7
+ data.tar.gz: 5d63d0d5a87a6dda234e346c01a3dd62787813feb64db91dadae948998b65ff3ba97f7a218356f2de548792e9b47a8c43e45d80dabfa26234fb1d47a0f72e330
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * Luda degradation script 0.1.11 | https://luda.dev
3
- * Copyright 2018 oatw | https://oatw.blog
2
+ * Luda degradation script 0.1.12 | https://luda.dev
3
+ * Copyright 2019 Oatw | https://oatw.blog
4
4
  * MIT license | http://opensource.org/licenses/MIT
5
5
  */
6
6
  (function (global, factory) {
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * Luda degradation script 0.1.11 | https://luda.dev
3
- * Copyright 2018 oatw | https://oatw.blog
2
+ * Luda degradation script 0.1.12 | https://luda.dev
3
+ * Copyright 2019 Oatw | https://oatw.blog
4
4
  * MIT license | http://opensource.org/licenses/MIT
5
5
  */
6
6
  (function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?factory():typeof define==="function"&&define.amd?define(factory):factory()})(this,function(){"use strict";var Degradation;Degradation={_URL_ATTRIBUTE:"data-degradation-url",_HTML:['<div id="luda-degradation-html" ','style="padding:100px 30px;text-align:center">',"<h1>Your Browser Is Too Old!</h1>","<p>","Please visit this site with a modern browser ",'<a target="_blank" href="https://www.google.com/chrome/">',"(Chrome recommended)","</a>",".</p>","</div>"].join(""),_CSS_PROPERTIES:[{display:"flex",position:["sticky||-webkit-sticky","fixed"]},"transition","animation"],_JS_PROPERTIES:{es6Class:"class X {}",es6ArrowFunction:"((x) => x)()",mutationObserver:"new MutationObserver(function(){})"},_NOTIFY_MILLSECONDS:500,check:function(){this._checkEnv();this._checkJS(this._JS_PROPERTIES);return this._checkCSS(this._CSS_PROPERTIES)},_eval:eval,_checkEnv:function(){if(typeof document!=="undefined"){if(typeof window!=="undefined"){return window}if(typeof global!=="undefined"){return global}}throw new Error("Unsupported runtime environment.")},_checkJS:function(properties){var err,property,results,value;results=[];for(property in properties){value=properties[property];try{results.push(this._eval(value))}catch(error){err=error;this._notify();throw new Error(property+" "+err)}}return results},_checkCSS:function(properties){var ele,i,len,name,property,results,value,valueEle;ele=document.createElement("div");results=[];for(i=0,len=properties.length;i<len;i++){property=properties[i];if(typeof property==="string"){results.push(this._CSSPropertySupported(ele,property))}else{results.push(function(){var results1;results1=[];for(name in property){value=property[name];this._CSSPropertySupported(ele,name);if(value instanceof Array){results1.push(function(){var j,len1,results2;results2=[];for(j=0,len1=value.length;j<len1;j++){valueEle=value[j];results2.push(this._CSSValueSupported(ele,name,valueEle))}return results2}.call(this))}else{results1.push(this._CSSValueSupported(ele,name,value))}}return results1}.call(this))}}return results},_CSSPropertySupported:function(ele,property){if(typeof ele.style[property]!=="string"){this._notify();throw new Error("Unsupported CSS property: "+property)}},_CSSValueSupported:function(ele,property,valueStr){var i,len,value,values;values=valueStr.split("||");for(i=0,len=values.length;i<len;i++){value=values[i];ele.style[property]=value;if(ele.style[property]===value){return}}this._notify();throw new Error("Unsupported CSS property value: "+property+" "+valueStr)},_notify:function(){var _self,i,len,redirectUrl,ref,script;redirectUrl=document.documentElement.getAttribute(this._URL_ATTRIBUTE);if(redirectUrl){return location.href=redirectUrl}ref=document.scripts;for(i=0,len=ref.length;i<len;i++){script=ref[i];redirectUrl=script.getAttribute(this._URL_ATTRIBUTE);if(redirectUrl){return location.href=redirectUrl}}_self=this;return setInterval(function(){if(!document.getElementById("luda-degradation-html")){if(document.body){return document.body.innerHTML=_self._HTML}}},this._NOTIFY_MILLSECONDS)}};Degradation.check()});
@@ -1,6 +1,6 @@
1
- //= require luda/behaviors/enter-click
1
+ //= require luda/behaviors/enter
2
2
  //= require luda/behaviors/focus
3
- //= require luda/behaviors/radio-tab
3
+ //= require luda/behaviors/tabulate
4
4
  //= require luda/behaviors/readonly
5
5
  //= require luda/behaviors/toggle
6
6
  //= require luda/elements/form-file
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * Luda 0.1.11 | https://luda.dev
3
- * Copyright 2018 oatw | https://oatw.blog
2
+ * Luda 0.1.12 | https://luda.dev
3
+ * Copyright 2019 Oatw | https://oatw.blog
4
4
  * MIT license | http://opensource.org/licenses/MIT
5
5
  */
6
6
  (function (global, factory) {
@@ -152,6 +152,68 @@
152
152
  },
153
153
  reflow: function($element) {
154
154
  return $element.offsetHeight;
155
+ },
156
+ _getTransitionDurations: function(style, propertyLength) {
157
+ var durationArray;
158
+ durationArray = style.split(',');
159
+ while (durationArray.length < propertyLength) {
160
+ durationArray = durationArray.concat(durationArray);
161
+ }
162
+ if (durationArray.length > propertyLength) {
163
+ durationArray = durationArray.slice(0, propertyLength);
164
+ }
165
+ return durationArray.map(function(durationStr) {
166
+ var duration;
167
+ duration = parseFloat(durationStr);
168
+ if (!duration) {
169
+ return 0;
170
+ }
171
+ if (durationStr.match('ms')) {
172
+ return duration;
173
+ } else {
174
+ return duration * 1000;
175
+ }
176
+ });
177
+ },
178
+ getTransitionDuration: function($element) {
179
+ var delays, durations, finalDurations, length, styles;
180
+ styles = window.getComputedStyle($element);
181
+ length = styles.transitionProperty.split(',').length;
182
+ if (!length) {
183
+ return 0;
184
+ }
185
+ delays = this._getTransitionDurations(styles.transitionDelay, length);
186
+ durations = this._getTransitionDurations(styles.transitionDuration, length);
187
+ finalDurations = durations.map(function(duration, index) {
188
+ return duration + delays[index];
189
+ });
190
+ return Math.max.apply(null, finalDurations);
191
+ },
192
+ _observeDom: function(onNodeAdded, onNodeRemoved) {
193
+ var observer, observerConfig;
194
+ observerConfig = {
195
+ childList: true,
196
+ subtree: true
197
+ };
198
+ observer = new MutationObserver(function(mutations) {
199
+ return mutations.forEach(function(mutation) {
200
+ var $addedNodes, $removedNodes;
201
+ $removedNodes = Array.from(mutation.removedNodes);
202
+ $addedNodes = Array.from(mutation.addedNodes);
203
+ $removedNodes.forEach(function($node) {
204
+ if ($node instanceof Element && onNodeRemoved) {
205
+ return onNodeRemoved($node);
206
+ }
207
+ });
208
+ return $addedNodes.forEach(function($node) {
209
+ if ($node instanceof Element && onNodeAdded) {
210
+ return onNodeAdded($node);
211
+ }
212
+ });
213
+ });
214
+ });
215
+ observer.observe(document.documentElement, observerConfig);
216
+ return observer;
155
217
  }
156
218
  });
157
219
 
@@ -210,7 +272,7 @@
210
272
  }
211
273
  });
212
274
  },
213
- dispatch: function($target, type, detail, options = {}) {
275
+ dispatch: function($target, type, detail, delayMilliseconds, options = {}) {
214
276
  var evt;
215
277
  if (typeof options.bubbles !== 'boolean') {
216
278
  options.bubbles = true;
@@ -223,8 +285,16 @@
223
285
  }
224
286
  evt = new Event(`${this._EVENT_TYPE_PREFIX}:${type}`, options);
225
287
  evt.detail = detail;
226
- $target.dispatchEvent(evt);
227
- return evt;
288
+ if (typeof delayMilliseconds === 'number') {
289
+ return setTimeout(function() {
290
+ if ($target) {
291
+ return $target.dispatchEvent(evt);
292
+ }
293
+ }, delayMilliseconds);
294
+ } else {
295
+ $target.dispatchEvent(evt);
296
+ return evt;
297
+ }
228
298
  },
229
299
  _onDocReady: function(handler) {
230
300
  if (document.readyState === 'loading') {
@@ -347,16 +417,32 @@
347
417
  }
348
418
  });
349
419
 
350
- var Singleton;
420
+ var Static;
351
421
 
352
- luda(Singleton = (function() {
353
- class Singleton {
354
- static active() {
355
- return this._actived = true;
422
+ luda(Static = (function() {
423
+ class Static {
424
+ static _ACTIVATE_EVENT_TYPE() {
425
+ return `${this._SCOPE}:activate`;
356
426
  }
357
427
 
358
- static deactive() {
359
- return this._actived = false;
428
+ static _ACTIVATED_EVENT_TYPE() {
429
+ return `${this._SCOPE}:activated`;
430
+ }
431
+
432
+ static _DEACTIVATE_EVENT_TYPE() {
433
+ return `${this._SCOPE}:deactivate`;
434
+ }
435
+
436
+ static _DEACTIVATED_EVENT_TYPE() {
437
+ return `${this._SCOPE}:deactivated`;
438
+ }
439
+
440
+ static _ACTIVATING_MARK_ATTRIBUTE() {
441
+ return `data-${this._SCOPE}-activating`;
442
+ }
443
+
444
+ static _DEACTIVATING_MARK_ATTRIBUTE() {
445
+ return `data-${this._SCOPE}-deactivating`;
360
446
  }
361
447
 
362
448
  static _add(selector) {
@@ -381,9 +467,133 @@
381
467
  return this._selector = this._SELECTORS.join(',');
382
468
  }
383
469
 
470
+ static _activatePrevented($ele, detail) {
471
+ var activateEvent;
472
+ activateEvent = luda.dispatch($ele, this._ACTIVATE_EVENT_TYPE(), detail);
473
+ return activateEvent.defaultPrevented;
474
+ }
475
+
476
+ static _deactivatePrevented($ele, detail) {
477
+ var deactivateEvent;
478
+ deactivateEvent = luda.dispatch($ele, this._DEACTIVATE_EVENT_TYPE(), detail);
479
+ return deactivateEvent.defaultPrevented;
480
+ }
481
+
482
+ static _handleActivateEnd($ele, detail) {
483
+ var activateDuration;
484
+ this._setActivatingMark($ele, detail);
485
+ activateDuration = luda.getTransitionDuration($ele);
486
+ luda.dispatch($ele, this._ACTIVATED_EVENT_TYPE(), detail, activateDuration);
487
+ setTimeout(() => {
488
+ if ($ele) {
489
+ return this._removeActivatingMark($ele);
490
+ }
491
+ }, activateDuration);
492
+ return activateDuration;
493
+ }
494
+
495
+ static _handleDeactivateEnd($ele, detail) {
496
+ var deactivateDuration;
497
+ this._setDeactivatingMark($ele, detail);
498
+ deactivateDuration = luda.getTransitionDuration($ele);
499
+ luda.dispatch($ele, this._DEACTIVATED_EVENT_TYPE(), detail, deactivateDuration);
500
+ setTimeout(() => {
501
+ if ($ele) {
502
+ return this._removeDeactivatingMark($ele);
503
+ }
504
+ }, deactivateDuration);
505
+ return deactivateDuration;
506
+ }
507
+
508
+ static _handleActivateCancel($ele, detail) {
509
+ if (this._isActivating($ele)) {
510
+ luda.dispatch($ele, this._ACTIVATED_EVENT_TYPE(), detail);
511
+ return this._removeActivatingMark($ele);
512
+ }
513
+ }
514
+
515
+ static _handleDeactivateCancel($ele, detail) {
516
+ if (this._isDeactivating($ele)) {
517
+ luda.dispatch($ele, this._DEACTIVATED_EVENT_TYPE(), detail);
518
+ return this._removeDeactivatingMark($ele);
519
+ }
520
+ }
521
+
522
+ static _isActivating($ele) {
523
+ return $ele.hasAttribute(this._ACTIVATING_MARK_ATTRIBUTE());
524
+ }
525
+
526
+ static _isDeactivating($ele) {
527
+ return $ele.hasAttribute(this._DEACTIVATING_MARK_ATTRIBUTE());
528
+ }
529
+
530
+ static _isTransitioning($ele) {
531
+ return this._isActivating($ele) || this._isDeactivating($ele);
532
+ }
533
+
534
+ static _getActivatingMark($ele) {
535
+ return $ele.getAttribute(this._ACTIVATING_MARK_ATTRIBUTE());
536
+ }
537
+
538
+ static _getDeactivatingMark($ele) {
539
+ return $ele.getAttribute(this._DEACTIVATING_MARK_ATTRIBUTE());
540
+ }
541
+
542
+ static _removeActivatingMark($ele) {
543
+ return $ele.removeAttribute(this._ACTIVATING_MARK_ATTRIBUTE());
544
+ }
545
+
546
+ static _removeDeactivatingMark($ele) {
547
+ return $ele.removeAttribute(this._DEACTIVATING_MARK_ATTRIBUTE());
548
+ }
549
+
550
+ static _setActivatingMark($ele, value) {
551
+ return $ele.setAttribute(this._ACTIVATING_MARK_ATTRIBUTE(), value);
552
+ }
553
+
554
+ static _setDeactivatingMark($ele, value) {
555
+ return $ele.setAttribute(this._DEACTIVATING_MARK_ATTRIBUTE(), value);
556
+ }
557
+
558
+ static _onEleAdded($ele) {
559
+ return Static._onEleAddedOrRemoved($ele, '_onElementAdded');
560
+ }
561
+
562
+ static _onEleRemoved($ele) {
563
+ return Static._onEleAddedOrRemoved($ele, '_onElementRemoved');
564
+ }
565
+
566
+ static _onEleAddedOrRemoved($ele, action) {
567
+ return Static._Observed.forEach(function(Observed) {
568
+ var $matched;
569
+ if (!Observed[action]) {
570
+ return;
571
+ }
572
+ $matched = luda.$children(Observed._selector, $ele);
573
+ if ($ele.matches(Observed._selector)) {
574
+ $matched.unshift($ele);
575
+ }
576
+ return $matched.forEach(function($target) {
577
+ return Observed[action]($target);
578
+ });
579
+ });
580
+ }
581
+
582
+ static _observe(classObj) {
583
+ if (!Static._observer) {
584
+ Static._observer = luda._observeDom(Static._onEleAdded, Static._onEleRemoved);
585
+ }
586
+ if (classObj._onElementAdded || classObj._onElementRemoved && classObj._selector) {
587
+ if (!Static._Observed.includes(classObj)) {
588
+ return Static._Observed.push(classObj);
589
+ }
590
+ }
591
+ }
592
+
384
593
  static _install() {
385
- var exposed;
386
- if (this === Singleton) {
594
+ var exposed, self;
595
+ self = this;
596
+ if (this === Static) {
387
597
  return this;
388
598
  }
389
599
  if (!this.hasOwnProperty('_SELECTORS')) {
@@ -393,6 +603,9 @@
393
603
  if (typeof this._init === 'function') {
394
604
  exposed = this._init();
395
605
  }
606
+ luda.on(luda._DOC_READY, function() {
607
+ return Static._observe(self);
608
+ });
396
609
  if (exposed) {
397
610
  return exposed;
398
611
  } else {
@@ -401,29 +614,31 @@
401
614
  }
402
615
 
403
616
  }
404
- Singleton._SCOPE = 'Singleton';
617
+ Static._SCOPE = 'Static';
618
+
619
+ Static._SELECTOR_INVALID_ERROR = '@param selector must be a css selector string';
405
620
 
406
- Singleton._SELECTOR_INVALID_ERROR = '@param selector must be a css selector string';
621
+ Static._SELECTORS = [];
407
622
 
408
- Singleton._SELECTORS = [];
623
+ Static._Observed = [];
409
624
 
410
- Singleton._selector = '';
625
+ Static._observer = null;
411
626
 
412
- Singleton._actived = true;
627
+ Static._selector = '';
413
628
 
414
- return Singleton;
629
+ return Static;
415
630
 
416
631
  }).call(this));
417
632
 
418
633
  luda((function() {
419
634
  var _Class;
420
635
 
421
- _Class = class extends luda.Singleton {
636
+ _Class = class extends luda.Static {
422
637
  static _init() {
423
638
  var self;
424
639
  self = this;
425
640
  return luda.on('keydown', function(e) {
426
- if (self._actived && e.keyCode === luda.KEY_ENTER && e.target.matches(self._selector)) {
641
+ if (!document.documentElement.hasAttribute(self._DISABLED_ATTRIBUTE) && e.keyCode === luda.KEY_ENTER && e.target.matches(self._selector)) {
427
642
  e.preventDefault();
428
643
  return setTimeout(function() {
429
644
  return e.target.click();
@@ -434,10 +649,12 @@
434
649
 
435
650
  };
436
651
 
437
- _Class._SCOPE = 'enterClick';
652
+ _Class._SCOPE = 'enter';
438
653
 
439
654
  _Class._SELECTORS = ['input[type=checkbox]', 'input[type=radio]', '[tabindex]'];
440
655
 
656
+ _Class._DISABLED_ATTRIBUTE = 'data-enter-disabled';
657
+
441
658
  return _Class;
442
659
 
443
660
  }).call(this));
@@ -445,7 +662,11 @@
445
662
  luda((function() {
446
663
  var _Class;
447
664
 
448
- _Class = class extends luda.Singleton {
665
+ _Class = class extends luda.Static {
666
+ static _isActive() {
667
+ return !document.documentElement.hasAttribute(this._DISABLED_ATTRIBUTE);
668
+ }
669
+
449
670
  static _removeFocusClassExcept($exception) {
450
671
  return Array.from(this._$focus).forEach(($focus) => {
451
672
  if ($focus !== $exception) {
@@ -461,7 +682,7 @@
461
682
  }
462
683
 
463
684
  static _changeFocusStateOnKeyEvent(e) {
464
- if (this._actived) {
685
+ if (this._isActive()) {
465
686
  this._removeFocusClassExcept(e.target);
466
687
  return this._addFocusClassExceptHtmlAndBody(e.target);
467
688
  }
@@ -469,7 +690,7 @@
469
690
 
470
691
  static _changeFocusStateOnMouseDownEvent(e) {
471
692
  var target;
472
- if (this._actived) {
693
+ if (this._isActive()) {
473
694
  if (e.target.matches(this._PARENT_FOCUS_CHILDREN_SELECTOR)) {
474
695
  target = luda.$parent(this._PARENT_FOCUS_SELECTOR, e.target);
475
696
  } else {
@@ -491,14 +712,14 @@
491
712
  self = this;
492
713
  HTMLElement.prototype.focus = function() {
493
714
  focus.apply(this, arguments);
494
- if (self._actived && document.activeElement === this) {
715
+ if (self._isActive() && document.activeElement === this) {
495
716
  self._removeFocusClassExcept(this);
496
717
  return self._addFocusClassExceptHtmlAndBody(this);
497
718
  }
498
719
  };
499
720
  return HTMLElement.prototype.blur = function() {
500
721
  blur.apply(this, arguments);
501
- if (self._actived) {
722
+ if (self._isActive()) {
502
723
  return this.classList.remove(self._CSS_CLASS);
503
724
  }
504
725
  };
@@ -528,6 +749,8 @@
528
749
 
529
750
  _Class._PARENT_FOCUS_CHILDREN_SELECTOR = `${_Class._PARENT_FOCUS_SELECTOR} *`;
530
751
 
752
+ _Class._DISABLED_ATTRIBUTE = 'data-focus-disabled';
753
+
531
754
  _Class._$focus = document.getElementsByClassName(_Class._CSS_CLASS);
532
755
 
533
756
  return _Class;
@@ -537,7 +760,7 @@
537
760
  luda((function() {
538
761
  var _Class;
539
762
 
540
- _Class = class extends luda.Singleton {
763
+ _Class = class extends luda.Static {
541
764
  static _querySameName$radios($radio) {
542
765
  var $inputs, selector;
543
766
  if ($radio.name) {
@@ -565,7 +788,7 @@
565
788
  self = this;
566
789
  return luda.on('keydown', function(e) {
567
790
  var $next, $prev;
568
- if (self._actived && e.keyCode === luda.KEY_TAB && e.target.nodeName.toUpperCase() === 'INPUT' && e.target.type === 'radio') {
791
+ if (!document.documentElement.hasAttribute(self._DISABLED_ATTRIBUTE) && e.keyCode === luda.KEY_TAB && e.target.nodeName.toUpperCase() === 'INPUT' && e.target.type === 'radio') {
569
792
  if (e.shiftKey) {
570
793
  if ($prev = self._query$prev$next(e.target).$prev) {
571
794
  e.preventDefault();
@@ -583,18 +806,44 @@
583
806
 
584
807
  };
585
808
 
586
- _Class._SCOPE = 'radioTab';
809
+ _Class._SCOPE = 'tabulate';
587
810
 
588
811
  _Class._SELECTORS = ['input[type=radio]:not([disabled])'];
589
812
 
813
+ _Class._DISABLED_ATTRIBUTE = 'data-tabulate-disabled';
814
+
590
815
  return _Class;
591
816
 
592
817
  }).call(this));
593
818
 
594
- var Component;
819
+ var Factory;
820
+
821
+ luda(Factory = (function() {
822
+ class Factory {
823
+ static _ACTIVATE_EVENT_TYPE() {
824
+ return `${this._SCOPE}:activate`;
825
+ }
826
+
827
+ static _ACTIVATED_EVENT_TYPE() {
828
+ return `${this._SCOPE}:activated`;
829
+ }
830
+
831
+ static _DEACTIVATE_EVENT_TYPE() {
832
+ return `${this._SCOPE}:deactivate`;
833
+ }
834
+
835
+ static _DEACTIVATED_EVENT_TYPE() {
836
+ return `${this._SCOPE}:deactivated`;
837
+ }
838
+
839
+ static _ACTIVATING_MARK_ATTRIBUTE() {
840
+ return `data-${this._SCOPE}-activating`;
841
+ }
842
+
843
+ static _DEACTIVATING_MARK_ATTRIBUTE() {
844
+ return `data-${this._SCOPE}-deactivating`;
845
+ }
595
846
 
596
- luda(Component = (function() {
597
- class Component {
598
847
  _hasDescendant(descendant) {
599
848
  if (this._children.length && descendant) {
600
849
  if (this._children.includes(descendant)) {
@@ -618,6 +867,94 @@
618
867
  return this._observer = null;
619
868
  }
620
869
 
870
+ _activatePrevented($ele, detail) {
871
+ var activateEvent;
872
+ activateEvent = luda.dispatch($ele, this.constructor._ACTIVATE_EVENT_TYPE(), detail);
873
+ return activateEvent.defaultPrevented;
874
+ }
875
+
876
+ _deactivatePrevented($ele, detail) {
877
+ var deactivateEvent;
878
+ deactivateEvent = luda.dispatch($ele, this.constructor._DEACTIVATE_EVENT_TYPE(), detail);
879
+ return deactivateEvent.defaultPrevented;
880
+ }
881
+
882
+ _handleActivateEnd($ele, detail) {
883
+ var activateDuration;
884
+ this._setActivatingMark(detail);
885
+ activateDuration = luda.getTransitionDuration($ele);
886
+ luda.dispatch($ele, this.constructor._ACTIVATED_EVENT_TYPE(), detail, activateDuration);
887
+ setTimeout(() => {
888
+ if (this._$component) {
889
+ return this._removeActivatingMark();
890
+ }
891
+ }, activateDuration);
892
+ return activateDuration;
893
+ }
894
+
895
+ _handleDeactivateEnd($ele, detail) {
896
+ var deactivateDuration;
897
+ this._setDeactivatingMark(detail);
898
+ deactivateDuration = luda.getTransitionDuration($ele);
899
+ luda.dispatch($ele, this.constructor._DEACTIVATED_EVENT_TYPE(), detail, deactivateDuration);
900
+ setTimeout(() => {
901
+ if (this._$component) {
902
+ return this._removeDeactivatingMark();
903
+ }
904
+ }, deactivateDuration);
905
+ return deactivateDuration;
906
+ }
907
+
908
+ _handleActivateCancel($ele, detail) {
909
+ if (this._isActivating()) {
910
+ luda.dispatch($ele, this.constructor._ACTIVATED_EVENT_TYPE(), detail);
911
+ return this._removeActivatingMark();
912
+ }
913
+ }
914
+
915
+ _handleDeactivateCancel($ele, detail) {
916
+ if (this._isDeactivating()) {
917
+ luda.dispatch($ele, this.constructor._DEACTIVATED_EVENT_TYPE(), detail);
918
+ return this._removeDeactivatingMark();
919
+ }
920
+ }
921
+
922
+ _isActivating() {
923
+ return this._$component.hasAttribute(this.constructor._ACTIVATING_MARK_ATTRIBUTE());
924
+ }
925
+
926
+ _isDeactivating() {
927
+ return this._$component.hasAttribute(this.constructor._DEACTIVATING_MARK_ATTRIBUTE());
928
+ }
929
+
930
+ _isTransitioning() {
931
+ return this._isActivating() || this._isDeactivating();
932
+ }
933
+
934
+ _getActivatingMark() {
935
+ return this._$component.getAttribute(this.constructor._ACTIVATING_MARK_ATTRIBUTE());
936
+ }
937
+
938
+ _getDeactivatingMark() {
939
+ return this._$component.getAttribute(this.constructor._DEACTIVATING_MARK_ATTRIBUTE());
940
+ }
941
+
942
+ _removeActivatingMark() {
943
+ return this._$component.removeAttribute(this.constructor._ACTIVATING_MARK_ATTRIBUTE());
944
+ }
945
+
946
+ _removeDeactivatingMark() {
947
+ return this._$component.removeAttribute(this.constructor._DEACTIVATING_MARK_ATTRIBUTE());
948
+ }
949
+
950
+ _setActivatingMark(value) {
951
+ return this._$component.setAttribute(this.constructor._ACTIVATING_MARK_ATTRIBUTE(), value);
952
+ }
953
+
954
+ _setDeactivatingMark(value) {
955
+ return this._$component.setAttribute(this.constructor._DEACTIVATING_MARK_ATTRIBUTE(), value);
956
+ }
957
+
621
958
  static create($component) {
622
959
  var $family, componentIsElementInstance, instance, parent;
623
960
  componentIsElementInstance = $component instanceof Element;
@@ -722,56 +1059,38 @@
722
1059
  return instance;
723
1060
  }
724
1061
 
725
- static _observe(classObj) {
726
- if (!Component._observer) {
727
- Component._observer = new MutationObserver(function(mutations) {
728
- return mutations.forEach(function(mutation) {
729
- var $addedNodes, $removedNodes;
730
- $removedNodes = Array.from(mutation.removedNodes);
731
- $addedNodes = Array.from(mutation.addedNodes);
732
- $removedNodes.forEach(function($node) {
733
- if ($node instanceof Element) {
734
- return Component._Observed.forEach(function(Observed) {
735
- var $destroies;
736
- if ($node.matches(Observed._SELECTOR)) {
737
- return Observed.destroy($node);
738
- } else {
739
- $destroies = luda.$children(Observed._SELECTOR, $node);
740
- return $destroies.forEach(function($destroy) {
741
- return Observed.destroy($destroy);
742
- });
743
- }
744
- });
745
- }
746
- });
747
- return $addedNodes.forEach(function($node) {
748
- if ($node instanceof Element) {
749
- return Component._Observed.forEach(function(Observed) {
750
- var $creates;
751
- if ($node.matches(Observed._SELECTOR)) {
752
- return Observed.create($node);
753
- } else {
754
- $creates = luda.$children(Observed._SELECTOR, $node);
755
- return $creates.forEach(function($create) {
756
- return Observed.create($create);
757
- });
758
- }
759
- });
760
- }
761
- });
762
- });
1062
+ static _onEleAdded($ele) {
1063
+ return Factory._onEleAddedOrRemoved($ele, 'create');
1064
+ }
1065
+
1066
+ static _onEleRemoved($ele) {
1067
+ return Factory._onEleAddedOrRemoved($ele, 'destroy');
1068
+ }
1069
+
1070
+ static _onEleAddedOrRemoved($ele, action) {
1071
+ return Factory._Observed.forEach(function(Observed) {
1072
+ if ($ele.matches(Observed._SELECTOR)) {
1073
+ return Observed[action]($ele);
1074
+ }
1075
+ return luda.$children(Observed._SELECTOR, $ele).forEach(function($child) {
1076
+ return Observed[action]($child);
763
1077
  });
764
- Component._observer.observe(document.documentElement, Component._observerConfig);
1078
+ });
1079
+ }
1080
+
1081
+ static _observe(classObj) {
1082
+ if (!Factory._observer) {
1083
+ Factory._observer = luda._observeDom(Factory._onEleAdded, Factory._onEleRemoved);
765
1084
  }
766
- if (!Component._Observed.includes(classObj)) {
767
- return Component._Observed.push(classObj);
1085
+ if (!Factory._Observed.includes(classObj)) {
1086
+ return Factory._Observed.push(classObj);
768
1087
  }
769
1088
  }
770
1089
 
771
1090
  static _install() {
772
1091
  var exposed, self;
773
1092
  self = this;
774
- if (this === Component) {
1093
+ if (this === Factory) {
775
1094
  return this;
776
1095
  }
777
1096
  if (!(this._SELECTOR || typeof this._SELECTOR !== 'string')) {
@@ -787,7 +1106,7 @@
787
1106
  luda.$children(self._SELECTOR).forEach(function($component) {
788
1107
  return self.create($component);
789
1108
  });
790
- return Component._observe(self);
1109
+ return Factory._observe(self);
791
1110
  });
792
1111
  if (exposed) {
793
1112
  return exposed;
@@ -797,33 +1116,33 @@
797
1116
  }
798
1117
 
799
1118
  }
800
- Component._SCOPE = 'Component';
1119
+ Factory._SCOPE = 'Factory';
801
1120
 
802
- Component._COMPONENT_NO_SELECTOR_ERROR = 'Extended component must has a css selector';
1121
+ Factory._COMPONENT_NO_SELECTOR_ERROR = 'Extended component must has a css selector';
803
1122
 
804
- Component._$COMPONENT_INVALID_ERROR = '@param $component must be an instance of Element';
1123
+ Factory._$COMPONENT_INVALID_ERROR = '@param $component must be an instance of Element';
805
1124
 
806
- Component._SELECTOR = '';
1125
+ Factory._SELECTOR = '';
807
1126
 
808
- Component._instances = [];
1127
+ Factory._instances = [];
809
1128
 
810
- Component._Observed = [];
1129
+ Factory._Observed = [];
811
1130
 
812
- Component._observer = null;
1131
+ Factory._observer = null;
813
1132
 
814
- Component._observerConfig = {
1133
+ Factory._observerConfig = {
815
1134
  childList: true,
816
1135
  subtree: true
817
1136
  };
818
1137
 
819
- return Component;
1138
+ return Factory;
820
1139
 
821
1140
  }).call(this));
822
1141
 
823
1142
  luda((function() {
824
1143
  var _Class;
825
1144
 
826
- _Class = class extends luda.Component {
1145
+ _Class = class extends luda.Factory {
827
1146
  _getConfig() {
828
1147
  var _isReadonly, _originalTabIndex, readonly;
829
1148
  readonly = this._$component.getAttribute(this.constructor._READONLY_ATTRIBUTE);
@@ -871,31 +1190,77 @@
871
1190
  luda((function() {
872
1191
  var _Class;
873
1192
 
874
- _Class = class extends luda.Singleton {
875
- static active(name$target) {
1193
+ _Class = class extends luda.Static {
1194
+ static activate(name$target) {
876
1195
  return this._query$targets(name$target).forEach(($target) => {
1196
+ if ($target.classList.contains(this._ACTIVE_CSS_CLASS)) {
1197
+ return;
1198
+ }
1199
+ if (this._isTransitioning($target)) {
1200
+ return;
1201
+ }
1202
+ if (this._activatePrevented($target)) {
1203
+ return;
1204
+ }
877
1205
  $target.classList.add(this._ACTIVE_CSS_CLASS);
878
- return luda.dispatch($target, this._ACTIVED_EVENT_TYPE);
1206
+ this._handleActivateEnd($target);
1207
+ if (this._shouldAutoDeactivate($target)) {
1208
+ return this._delayDeactivate($target);
1209
+ }
879
1210
  });
880
1211
  }
881
1212
 
882
- static deactive(name$target) {
1213
+ static deactivate(name$target) {
883
1214
  return this._query$targets(name$target).forEach(($target) => {
1215
+ if (!$target.classList.contains(this._ACTIVE_CSS_CLASS)) {
1216
+ return;
1217
+ }
1218
+ if (this._isTransitioning($target)) {
1219
+ return;
1220
+ }
1221
+ if (this._deactivatePrevented($target)) {
1222
+ return;
1223
+ }
884
1224
  $target.classList.remove(this._ACTIVE_CSS_CLASS);
885
- return luda.dispatch($target, this._DEACTIVED_EVENT_TYPE);
1225
+ return this._handleDeactivateEnd($target);
886
1226
  });
887
1227
  }
888
1228
 
889
1229
  static toggle(name$target) {
890
1230
  return this._query$targets(name$target).forEach(($target) => {
891
1231
  if ($target.classList.contains(this._ACTIVE_CSS_CLASS)) {
892
- return this.deactive($target);
1232
+ return this.deactivate($target);
893
1233
  } else {
894
- return this.active($target);
1234
+ return this.activate($target);
895
1235
  }
896
1236
  });
897
1237
  }
898
1238
 
1239
+ static _onElementAdded($ele) {
1240
+ this._handleActivateCancel($ele);
1241
+ this._handleDeactivateCancel($ele);
1242
+ if (this._shouldAutoDeactivate($ele)) {
1243
+ return this._delayDeactivate($ele);
1244
+ }
1245
+ }
1246
+
1247
+ static _shouldAutoDeactivate($target) {
1248
+ return $target.hasAttribute(this._AUTO_DEACTIVATE_ATTRIBUTE);
1249
+ }
1250
+
1251
+ static _delayDeactivate($target) {
1252
+ var delay;
1253
+ delay = parseInt($target.getAttribute(this._AUTO_DEACTIVATE_ATTRIBUTE), 10);
1254
+ if (!delay) {
1255
+ delay = this._AUTO_DEACTIVATE_DURATION;
1256
+ }
1257
+ return setTimeout(() => {
1258
+ if ($target) {
1259
+ return this.deactivate($target);
1260
+ }
1261
+ }, delay);
1262
+ }
1263
+
899
1264
  static _query$targets(name$target) {
900
1265
  if (name$target instanceof Element) {
901
1266
  return [name$target];
@@ -905,9 +1270,17 @@
905
1270
  }
906
1271
 
907
1272
  static _init() {
908
- var self;
1273
+ var clickEventSelector, self;
909
1274
  self = this;
910
- return luda.on('click', this._selector, function(e) {
1275
+ clickEventSelector = `[${this._TOGGLE_FOR_ATTRIBUTE}],[${this._TOGGLE_ATTRIBUTE}]`;
1276
+ luda.on(luda._DOC_READY, function() {
1277
+ return luda.$children(self._selector).forEach(function($target) {
1278
+ if (self._shouldAutoDeactivate($target)) {
1279
+ return self._delayDeactivate($target);
1280
+ }
1281
+ });
1282
+ });
1283
+ return luda.on('click', clickEventSelector, function(e) {
911
1284
  var toggleChecked;
912
1285
  toggleChecked = false;
913
1286
  return luda.eventPath(e).some(function($path) {
@@ -929,7 +1302,7 @@
929
1302
  return toggleChecked = true;
930
1303
  }
931
1304
  }
932
- } else if ($path.hasAttribute(self._NONE_TOGGLE_ATTRIBUTE)) {
1305
+ } else if ($path.hasAttribute(self._TOGGLE_DISABLED_ATTRIBUTE)) {
933
1306
  return toggleChecked = true;
934
1307
  }
935
1308
  }
@@ -947,15 +1320,15 @@
947
1320
 
948
1321
  _Class._TOGGLE_FOR_ATTRIBUTE = 'data-toggle-for';
949
1322
 
950
- _Class._NONE_TOGGLE_ATTRIBUTE = 'data-toggle-disabled';
1323
+ _Class._TOGGLE_DISABLED_ATTRIBUTE = 'data-toggle-disabled';
951
1324
 
952
- _Class._ACTIVE_CSS_CLASS = 'toggle-active';
1325
+ _Class._AUTO_DEACTIVATE_ATTRIBUTE = 'data-toggle-auto-deactivate';
953
1326
 
954
- _Class._SELECTORS = [`[${_Class._TOGGLE_FOR_ATTRIBUTE}]`, `[${_Class._TOGGLE_ATTRIBUTE}]`];
1327
+ _Class._AUTO_DEACTIVATE_DURATION = 3000;
955
1328
 
956
- _Class._ACTIVED_EVENT_TYPE = `${_Class._SCOPE}:actived`;
1329
+ _Class._ACTIVE_CSS_CLASS = 'toggle-active';
957
1330
 
958
- _Class._DEACTIVED_EVENT_TYPE = `${_Class._SCOPE}:deactived`;
1331
+ _Class._SELECTORS = [`[${_Class._TOGGLE_TARGET_ATTRIBUTE}]`];
959
1332
 
960
1333
  return _Class;
961
1334
 
@@ -964,7 +1337,12 @@
964
1337
  luda((function() {
965
1338
  var _Class;
966
1339
 
967
- _Class = class extends luda.Component {
1340
+ _Class = class extends luda.Factory {
1341
+ reset() {
1342
+ this._$file.value = '';
1343
+ return this._$simulator.value = '';
1344
+ }
1345
+
968
1346
  _getConfig() {
969
1347
  var _$file, _$simulator;
970
1348
  _$file = luda.$child(this.constructor._FILE_SELECTOR, this._$component);
@@ -1016,6 +1394,10 @@
1016
1394
  }
1017
1395
  }
1018
1396
 
1397
+ static reset($file) {
1398
+ return this.query($file).reset();
1399
+ }
1400
+
1019
1401
  static _init() {
1020
1402
  var self;
1021
1403
  self = this;
@@ -1057,7 +1439,7 @@
1057
1439
  luda((function() {
1058
1440
  var _Class;
1059
1441
 
1060
- _Class = class extends luda.Component {
1442
+ _Class = class extends luda.Factory {
1061
1443
  select(indexOrIndexArray) {
1062
1444
  var selectedIndexes;
1063
1445
  if (this._$select.multiple) {
@@ -1073,7 +1455,7 @@
1073
1455
  });
1074
1456
  return this._markSelectedOption();
1075
1457
  } else {
1076
- this._$select.selectedIndex = selectedIndex;
1458
+ this._$select.selectedIndex = indexOrIndexArray;
1077
1459
  this._setSingleSelectSimulatorValue();
1078
1460
  return this._markSelectedOption();
1079
1461
  }
@@ -1208,6 +1590,10 @@
1208
1590
  }
1209
1591
  }
1210
1592
 
1593
+ static select($select, indexOrIndexArray) {
1594
+ return this.query($select).select(indexOrIndexArray);
1595
+ }
1596
+
1211
1597
  static _init() {
1212
1598
  var self;
1213
1599
  self = this;
@@ -1258,55 +1644,58 @@
1258
1644
  luda((function() {
1259
1645
  var _Class;
1260
1646
 
1261
- _Class = class extends luda.Component {
1647
+ _Class = class extends luda.Factory {
1262
1648
 
1263
1649
  // public
1264
- active(index) {
1265
- var action, activedIndex;
1266
- if (this._$items.length && !this._transiting) {
1267
- activedIndex = this._activeIndex;
1268
- if ((index != null) && index !== this._activeIndex && (0 <= index && index <= this._$items.length - 1)) {
1269
- this._transiting = true;
1650
+ activate(index) {
1651
+ var action, activatedIndex;
1652
+ if (this._$items.length && !this._isTransitioning()) {
1653
+ activatedIndex = this._activeIndex;
1654
+ if ((index != null) && index !== this._activeIndex && (0 <= index && index <= this._$items.length - 1) && this._canTransition(index, activatedIndex)) {
1270
1655
  this._activeIndex = index;
1271
- action = index < activedIndex ? '_slidePrev' : '_slideNext';
1272
- return this[action](this._$items[activedIndex], activedIndex);
1656
+ action = index < activatedIndex ? '_slidePrev' : '_slideNext';
1657
+ return this[action](activatedIndex);
1273
1658
  }
1274
1659
  }
1275
1660
  }
1276
1661
 
1277
1662
  next() {
1278
- var activedIndex, index;
1279
- if (this._$items.length && !this._transiting) {
1280
- activedIndex = this._activeIndex;
1281
- index = activedIndex + 1;
1663
+ var activatedIndex, index;
1664
+ if (this._$items.length && !this._isTransitioning()) {
1665
+ activatedIndex = this._activeIndex;
1666
+ index = activatedIndex + 1;
1282
1667
  if (index > this._$items.length - 1) {
1283
1668
  if (!this._wrap) {
1284
1669
  return;
1285
1670
  }
1286
1671
  index = 0;
1287
1672
  }
1288
- this._transiting = true;
1673
+ if (!this._canTransition(index, activatedIndex)) {
1674
+ return;
1675
+ }
1289
1676
  this._activeIndex = index;
1290
- this._slideNext(this._$items[activedIndex], activedIndex);
1677
+ this._slideNext(activatedIndex);
1291
1678
  this._playTimeStamp = Date.now();
1292
1679
  return this._pausedRemainTime = this._interval;
1293
1680
  }
1294
1681
  }
1295
1682
 
1296
1683
  prev() {
1297
- var activedIndex, index;
1298
- if (this._$items.length && !this._transiting) {
1299
- activedIndex = this._activeIndex;
1300
- index = activedIndex - 1;
1684
+ var activatedIndex, index;
1685
+ if (this._$items.length && !this._isTransitioning()) {
1686
+ activatedIndex = this._activeIndex;
1687
+ index = activatedIndex - 1;
1301
1688
  if (index < 0) {
1302
1689
  if (!this._wrap) {
1303
1690
  return;
1304
1691
  }
1305
1692
  index = this._$items.length - 1;
1306
1693
  }
1307
- this._transiting = true;
1694
+ if (!this._canTransition(index, activatedIndex)) {
1695
+ return;
1696
+ }
1308
1697
  this._activeIndex = index;
1309
- this._slidePrev(this._$items[activedIndex], activedIndex);
1698
+ this._slidePrev(activatedIndex);
1310
1699
  this._playTimeStamp = Date.now();
1311
1700
  return this._pausedRemainTime = this._interval;
1312
1701
  }
@@ -1357,11 +1746,11 @@
1357
1746
 
1358
1747
  _constructor() {
1359
1748
  ({_$items: this._$items, _$indicators: this._$indicators, _$prevControl: this._$prevControl, _$nextControl: this._$nextControl, _activeIndex: this._activeIndex, _interval: this._interval, _wrap: this._wrap} = this._getConfig());
1360
- this._transiting = false;
1361
1749
  this._intervaling = null;
1362
1750
  this._playTimeStamp = 0;
1363
1751
  this._pausedRemainTime = this._interval;
1364
1752
  this._layout();
1753
+ this._handleTransitionCancel();
1365
1754
  return this.play();
1366
1755
  }
1367
1756
 
@@ -1388,7 +1777,6 @@
1388
1777
  $item.classList.remove(this.constructor._ITEM_NEXT_CSS_CLASS);
1389
1778
  $item.classList.remove(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1390
1779
  } else {
1391
- luda.dispatch($item, this.constructor._ACTIVED_EVENT_TYPE, index);
1392
1780
  $item.classList.add(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1393
1781
  $item.classList.remove(this.constructor._ITEM_NEXT_CSS_CLASS);
1394
1782
  $item.classList.remove(this.constructor._ITEM_PREV_CSS_CLASS);
@@ -1400,11 +1788,11 @@
1400
1788
  return this._setDirectionControlState();
1401
1789
  }
1402
1790
 
1403
- _slideNext($activedItem, activedIndex) {
1404
- var $item;
1791
+ _slideNext(activatedIndex) {
1792
+ var $activatedItem, $item;
1405
1793
  if (this._$items.length > 1) {
1406
1794
  $item = this._$items[this._activeIndex];
1407
- luda.dispatch($item, this.constructor._ACTIVE_EVENT_TYPE, this._activeIndex);
1795
+ $activatedItem = this._$items[activatedIndex];
1408
1796
  $item.style.transition = 'none';
1409
1797
  $item.classList.remove(this.constructor._ITEM_PREV_CSS_CLASS);
1410
1798
  $item.classList.add(this.constructor._ITEM_NEXT_CSS_CLASS);
@@ -1412,19 +1800,19 @@
1412
1800
  $item.style.transition = '';
1413
1801
  $item.classList.remove(this.constructor._ITEM_NEXT_CSS_CLASS);
1414
1802
  $item.classList.add(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1415
- luda.dispatch($activedItem, this.constructor._DEACTIVE_EVENT_TYPE, activedIndex);
1416
- $activedItem.classList.remove(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1417
- $activedItem.classList.add(this.constructor._ITEM_PREV_CSS_CLASS);
1803
+ $activatedItem.classList.remove(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1804
+ $activatedItem.classList.add(this.constructor._ITEM_PREV_CSS_CLASS);
1805
+ this._handleTransitionEnd(this._activeIndex, activatedIndex);
1418
1806
  this._setIndicatorsState();
1419
1807
  return this._setDirectionControlState();
1420
1808
  }
1421
1809
  }
1422
1810
 
1423
- _slidePrev($activedItem, activedIndex) {
1424
- var $item;
1811
+ _slidePrev(activatedIndex) {
1812
+ var $activatedItem, $item;
1425
1813
  if (this._$items.length > 1) {
1426
1814
  $item = this._$items[this._activeIndex];
1427
- luda.dispatch($item, this.constructor._ACTIVE_EVENT_TYPE, this._activeIndex);
1815
+ $activatedItem = this._$items[activatedIndex];
1428
1816
  $item.style.transition = 'none';
1429
1817
  $item.classList.remove(this.constructor._ITEM_NEXT_CSS_CLASS);
1430
1818
  $item.classList.add(this.constructor._ITEM_PREV_CSS_CLASS);
@@ -1432,14 +1820,36 @@
1432
1820
  $item.style.transition = '';
1433
1821
  $item.classList.remove(this.constructor._ITEM_PREV_CSS_CLASS);
1434
1822
  $item.classList.add(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1435
- luda.dispatch($activedItem, this.constructor._DEACTIVE_EVENT_TYPE, activedIndex);
1436
- $activedItem.classList.remove(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1437
- $activedItem.classList.add(this.constructor._ITEM_NEXT_CSS_CLASS);
1823
+ $activatedItem.classList.remove(this.constructor._ITEM_ACTIVE_CSS_CLASS);
1824
+ $activatedItem.classList.add(this.constructor._ITEM_NEXT_CSS_CLASS);
1825
+ this._handleTransitionEnd(this._activeIndex, activatedIndex);
1438
1826
  this._setIndicatorsState();
1439
1827
  return this._setDirectionControlState();
1440
1828
  }
1441
1829
  }
1442
1830
 
1831
+ _canTransition(activeIndex, activatedIndex) {
1832
+ return !this._activatePrevented(this._$items[activeIndex], activeIndex) && !this._deactivatePrevented(this._$items[activatedIndex], activatedIndex);
1833
+ }
1834
+
1835
+ _handleTransitionEnd(activeIndex, activatedIndex) {
1836
+ var activateDuration, deactivateDuration;
1837
+ activateDuration = this._handleActivateEnd(this._$items[activeIndex], activeIndex);
1838
+ return deactivateDuration = this._handleDeactivateEnd(this._$items[activatedIndex], activatedIndex);
1839
+ }
1840
+
1841
+ _handleTransitionCancel() {
1842
+ var activatedIndex, index;
1843
+ if (this._isActivating()) {
1844
+ index = parseInt(this._getActivatingMark(), 10);
1845
+ this._handleActivateCancel(this._$items[index], index);
1846
+ }
1847
+ if (this._isDeactivating()) {
1848
+ activatedIndex = parseInt(this._getDeactivatingMark(), 10);
1849
+ return this._handleDeactivateCancel(this._$items[activatedIndex], activatedIndex);
1850
+ }
1851
+ }
1852
+
1443
1853
  _setIndicatorsState() {
1444
1854
  return this._$indicators.forEach(($indicator, index) => {
1445
1855
  return $indicator.disabled = index === this._activeIndex;
@@ -1458,26 +1868,34 @@
1458
1868
  }
1459
1869
  }
1460
1870
 
1461
-
1871
+ static activate($carousel, index) {
1872
+ return this.query($carousel).activate(index);
1873
+ }
1874
+
1875
+ static next($carousel) {
1876
+ return this.query($carousel).next();
1877
+ }
1878
+
1879
+ static prev($carousel) {
1880
+ return this.query($carousel).prev();
1881
+ }
1882
+
1883
+ static pause($carousel) {
1884
+ return this.query($carousel).pause();
1885
+ }
1886
+
1887
+ static play($carousel) {
1888
+ return this.query($carousel).play();
1889
+ }
1890
+
1462
1891
  // static private
1463
1892
  static _init() {
1464
1893
  var self;
1465
1894
  self = this;
1466
- luda.on('transitionend', this._ITEMS_SELECTOR, function(e) {
1467
- var index, instance;
1468
- instance = self.query(luda.$parent(self._SELECTOR, this));
1469
- instance._transiting = false;
1470
- index = instance._$items.indexOf(this);
1471
- if (this.classList.contains(self._ITEM_ACTIVE_CSS_CLASS)) {
1472
- return luda.dispatch(this, self._ACTIVED_EVENT_TYPE, index);
1473
- } else {
1474
- return luda.dispatch(this, self._DEACTIVED_EVENT_TYPE, index);
1475
- }
1476
- });
1477
1895
  luda.on('click', this._INDICATORS_SELECTOR, function(e) {
1478
1896
  var instance;
1479
1897
  instance = self.query(luda.$parent(self._SELECTOR, this));
1480
- return instance.active(instance._$indicators.indexOf(this));
1898
+ return instance.activate(instance._$indicators.indexOf(this));
1481
1899
  });
1482
1900
  luda.on('touchstart', this._SELECTOR, function(e) {
1483
1901
  return self.query(this).pause();
@@ -1525,6 +1943,8 @@
1525
1943
 
1526
1944
  _Class._WRAP_ATTRIBUTE = 'data-carousel-wrap';
1527
1945
 
1946
+ _Class._ACTIVATED_INDEX_ATTRIBUTE = 'data-carousel-activated-index';
1947
+
1528
1948
  _Class._ITEM_ACTIVE_CSS_CLASS = 'carousel-item-active';
1529
1949
 
1530
1950
  _Class._ITEM_NEXT_CSS_CLASS = 'carousel-item-next';
@@ -1539,14 +1959,6 @@
1539
1959
 
1540
1960
  _Class._FALSE = 'false';
1541
1961
 
1542
- _Class._ACTIVE_EVENT_TYPE = `${_Class._SCOPE}:active`;
1543
-
1544
- _Class._ACTIVED_EVENT_TYPE = `${_Class._SCOPE}:actived`;
1545
-
1546
- _Class._DEACTIVE_EVENT_TYPE = `${_Class._SCOPE}:deactive`;
1547
-
1548
- _Class._DEACTIVED_EVENT_TYPE = `${_Class._SCOPE}:deactived`;
1549
-
1550
1962
  _Class._observerConfig = {
1551
1963
  childList: true,
1552
1964
  attributes: true,
@@ -1561,47 +1973,55 @@
1561
1973
  luda((function() {
1562
1974
  var _Class;
1563
1975
 
1564
- _Class = class extends luda.Component {
1565
- active() {
1976
+ _Class = class extends luda.Factory {
1977
+ activate() {
1566
1978
  var ref;
1567
- if (!this._actived()) {
1568
- this._$component.classList.add(this.constructor._ACTIVE_CSS_CLASS);
1569
- this.constructor._$focused.push(document.activeElement);
1570
- if ((ref = this._parent) != null) {
1571
- ref.active();
1572
- }
1573
- return luda.dispatch(this._$component, this.constructor._ACTIVED_EVENT_TYPE);
1979
+ if (this._isActive() || this._isTransitioning()) {
1980
+ return;
1574
1981
  }
1982
+ if (this._activatePrevented(this._$menu)) {
1983
+ return;
1984
+ }
1985
+ this._$component.classList.add(this.constructor._ACTIVE_CSS_CLASS);
1986
+ this.constructor._$focused.push(document.activeElement);
1987
+ if ((ref = this._parent) != null) {
1988
+ ref.activate();
1989
+ }
1990
+ return this._handleActivateEnd(this._$menu);
1575
1991
  }
1576
1992
 
1577
- deactive(focus) {
1993
+ deactivate(focus) {
1578
1994
  var ref;
1579
- if (this._actived()) {
1580
- this._$component.classList.remove(this.constructor._ACTIVE_CSS_CLASS);
1581
- this._children.forEach(function(child) {
1582
- return child.deactive();
1583
- });
1584
- if (focus) {
1585
- if ((ref = this.constructor._$focused[this.constructor._$focused.length - 1]) != null) {
1586
- ref.focus();
1587
- }
1995
+ if (!(this._isActive() && !this._isTransitioning())) {
1996
+ return;
1997
+ }
1998
+ if (this._deactivatePrevented(this._$menu)) {
1999
+ return;
2000
+ }
2001
+ this._$component.classList.remove(this.constructor._ACTIVE_CSS_CLASS);
2002
+ this._children.forEach(function(child) {
2003
+ return child.deactivate();
2004
+ });
2005
+ if (focus) {
2006
+ if ((ref = this.constructor._$focused[this.constructor._$focused.length - 1]) != null) {
2007
+ ref.focus();
1588
2008
  }
1589
- this.constructor._$focused.splice(this.constructor._$focused.length - 1, 1);
1590
- return luda.dispatch(this._$component, this.constructor._DEACTIVED_EVENT_TYPE);
1591
2009
  }
2010
+ this.constructor._$focused.splice(this.constructor._$focused.length - 1, 1);
2011
+ return this._handleDeactivateEnd(this._$menu);
1592
2012
  }
1593
2013
 
1594
2014
  toggle(focus) {
1595
- if (this._actived()) {
1596
- return this.deactive(focus);
2015
+ if (this._isActive()) {
2016
+ return this.deactivate(focus);
1597
2017
  } else {
1598
- return this.active();
2018
+ return this.activate();
1599
2019
  }
1600
2020
  }
1601
2021
 
1602
- prev() {
2022
+ _prev() {
1603
2023
  var focusIndex;
1604
- if (this._$items.length && this._actived()) {
2024
+ if (this._$items.length && this._isActive()) {
1605
2025
  focusIndex = this._$items.indexOf(document.activeElement) - 1;
1606
2026
  if (focusIndex < 0) {
1607
2027
  focusIndex = 0;
@@ -1610,9 +2030,9 @@
1610
2030
  }
1611
2031
  }
1612
2032
 
1613
- next() {
2033
+ _next() {
1614
2034
  var focusIndex;
1615
- if (this._$items.length && this._actived()) {
2035
+ if (this._$items.length && this._isActive()) {
1616
2036
  focusIndex = this._$items.indexOf(document.activeElement) + 1;
1617
2037
  if (focusIndex > this._$items.length - 1) {
1618
2038
  focusIndex = this._$items.length - 1;
@@ -1628,41 +2048,55 @@
1628
2048
  _$noneSwitches = luda.$unnested(this.constructor._NONE_SWITCHES_SELECTOR, this._$component, this.constructor._SELECTOR).concat(luda.$unnested(this.constructor._NONE_SWITCHES_SELECTOR, _$menu, this.constructor._MENU_SELECTOR));
1629
2049
  _$items = luda.$unnested(this.constructor._ITEMS_SELECTOR, _$menu, this.constructor._MENU_SELECTOR);
1630
2050
  _isStandalone = this._$component.hasAttribute(this.constructor._STANDALONE_ATTRIBUTE);
1631
- return {_$items, _$switches, _$noneSwitches, _isStandalone};
2051
+ return {_$menu, _$items, _$switches, _$noneSwitches, _isStandalone};
1632
2052
  }
1633
2053
 
1634
2054
  _constructor() {
1635
- return ({_$items: this._$items, _$switches: this._$switches, _$noneSwitches: this._$noneSwitches, _isStandalone: this._isStandalone} = this._getConfig());
2055
+ this._onMutations();
2056
+ this._handleActivateCancel(this._$menu);
2057
+ return this._handleDeactivateCancel(this._$menu);
1636
2058
  }
1637
2059
 
1638
2060
  _onMutations(mutations) {
1639
- return this._constructor();
2061
+ return ({_$menu: this._$menu, _$items: this._$items, _$switches: this._$switches, _$noneSwitches: this._$noneSwitches, _isStandalone: this._isStandalone} = this._getConfig());
1640
2062
  }
1641
2063
 
1642
- _actived() {
2064
+ _isActive() {
1643
2065
  return this._$component.classList.contains(this.constructor._ACTIVE_CSS_CLASS);
1644
2066
  }
1645
2067
 
1646
- _deactiveChildrenExcept(exceptions) {
2068
+ _deactivateChildrenExcept(exceptions) {
1647
2069
  if (exceptions && !(exceptions instanceof Array)) {
1648
2070
  exceptions = [exceptions];
1649
2071
  }
1650
2072
  if (exceptions) {
1651
2073
  return this._children.forEach(function(child) {
1652
- if (child._actived() && !exceptions.includes(child)) {
1653
- return child.deactive();
2074
+ if (child._isActive() && !exceptions.includes(child)) {
2075
+ return child.deactivate();
1654
2076
  }
1655
2077
  });
1656
2078
  } else {
1657
2079
  return this._children.forEach(function(child) {
1658
- if (child._actived()) {
1659
- return child.deactive();
2080
+ if (child._isActive()) {
2081
+ return child.deactivate();
1660
2082
  }
1661
2083
  });
1662
2084
  }
1663
2085
  }
1664
2086
 
1665
- static deactiveExcept(instances$dropdowns) {
2087
+ static activate($dropdown) {
2088
+ return this.query($dropdown).activate();
2089
+ }
2090
+
2091
+ static deactivate($dropdown, focus) {
2092
+ return this.query($dropdown).deactivate(focus);
2093
+ }
2094
+
2095
+ static toggle($dropdown, focus) {
2096
+ return this.query($dropdown).toggle(focus);
2097
+ }
2098
+
2099
+ static deactivateExcept(instances$dropdowns) {
1666
2100
  var exceptions;
1667
2101
  exceptions = [];
1668
2102
  if (instances$dropdowns && !(instances$dropdowns instanceof Array)) {
@@ -1683,14 +2117,14 @@
1683
2117
  instanceHasntExceptionChild = exceptions.every(function(exception) {
1684
2118
  return !instance._hasDescendant(exception);
1685
2119
  });
1686
- if (instance._actived() && instanceIsntInExceptions && instanceHasntExceptionChild) {
1687
- return instance.deactive();
2120
+ if (instance._isActive() && instanceIsntInExceptions && instanceHasntExceptionChild) {
2121
+ return instance.deactivate();
1688
2122
  }
1689
2123
  });
1690
2124
  } else {
1691
2125
  return this._instances.forEach(function(instance) {
1692
- if (instance._actived()) {
1693
- return instance.deactive();
2126
+ if (instance._isActive()) {
2127
+ return instance.deactivate();
1694
2128
  }
1695
2129
  });
1696
2130
  }
@@ -1708,17 +2142,17 @@
1708
2142
  var self;
1709
2143
  self = this;
1710
2144
  luda.onOpposite('click', this._SELECTOR, function(e) {
1711
- return self.deactiveExcept(self._standaloneInstances());
2145
+ return self.deactivateExcept(self._standaloneInstances());
1712
2146
  });
1713
2147
  luda.on('click', this._SELECTOR, function(e) {
1714
2148
  var focus, instance, toggleChecked;
1715
2149
  if (instance = self.query(this)) {
1716
2150
  toggleChecked = false;
1717
2151
  focus = !e.detail;
1718
- self.deactiveExcept(self._standaloneInstances().concat(instance));
1719
- instance._deactiveChildrenExcept();
2152
+ self.deactivateExcept(self._standaloneInstances().concat(instance));
2153
+ instance._deactivateChildrenExcept();
1720
2154
  if (instance._parent) {
1721
- instance._parent._deactiveChildrenExcept(instance);
2155
+ instance._parent._deactivateChildrenExcept(instance);
1722
2156
  }
1723
2157
  if (instance._$switches.length || instance._$noneSwitches.length) {
1724
2158
  luda.eventPath(e).some(function($path) {
@@ -1736,23 +2170,23 @@
1736
2170
  }
1737
2171
  });
1738
2172
  luda.onOpposite('keyup', this._SELECTOR, function(e) {
1739
- return self.deactiveExcept();
2173
+ return self.deactivateExcept();
1740
2174
  });
1741
2175
  luda.on('keyup', this._SELECTOR, function(e) {
1742
2176
  var instance;
1743
2177
  if (e.keyCode === luda.KEY_TAB && (instance = self.query(this))) {
1744
- self.deactiveExcept(instance);
1745
- return instance.active();
2178
+ self.deactivateExcept(instance);
2179
+ return instance.activate();
1746
2180
  }
1747
2181
  });
1748
2182
  luda.on('keydown', this._SELECTOR, function(e) {
1749
2183
  var instance, ref;
1750
2184
  if (e.keyCode === luda.KEY_ESC && (instance = self.query(this))) {
1751
2185
  e.preventDefault();
1752
- if (instance._actived()) {
1753
- return instance.deactive(true);
2186
+ if (instance._isActive()) {
2187
+ return instance.deactivate(true);
1754
2188
  } else {
1755
- return (ref = instance._parent) != null ? ref.deactive(true) : void 0;
2189
+ return (ref = instance._parent) != null ? ref.deactivate(true) : void 0;
1756
2190
  }
1757
2191
  }
1758
2192
  });
@@ -1760,17 +2194,17 @@
1760
2194
  var instance, ref, ref1;
1761
2195
  if ([luda.KEY_LEFT, luda.KEY_UP].includes(e.keyCode) && (instance = self.query(this))) {
1762
2196
  e.preventDefault();
1763
- if (instance._actived()) {
1764
- return instance.prev();
2197
+ if (instance._isActive()) {
2198
+ return instance._prev();
1765
2199
  } else {
1766
- return (ref = instance._parent) != null ? ref.prev() : void 0;
2200
+ return (ref = instance._parent) != null ? ref._prev() : void 0;
1767
2201
  }
1768
2202
  } else if ([luda.KEY_RIGHT, luda.KEY_DOWN].includes(e.keyCode) && (instance = self.query(this))) {
1769
2203
  e.preventDefault();
1770
- if (instance._actived()) {
1771
- return instance.next();
2204
+ if (instance._isActive()) {
2205
+ return instance._next();
1772
2206
  } else {
1773
- return (ref1 = instance._parent) != null ? ref1.next() : void 0;
2207
+ return (ref1 = instance._parent) != null ? ref1._next() : void 0;
1774
2208
  }
1775
2209
  }
1776
2210
  });
@@ -1788,25 +2222,21 @@
1788
2222
 
1789
2223
  _Class._TOGGLE_ATTRIBUTE = 'data-dropdown-toggle';
1790
2224
 
1791
- _Class._NONE_TOGGLE_ATTRIBUTE = 'data-dropdown-toggle-disabled';
2225
+ _Class._TOGGLE_DISABLED_ATTRIBUTE = 'data-dropdown-toggle-disabled';
1792
2226
 
1793
2227
  _Class._STANDALONE_ATTRIBUTE = 'data-dropdown-standalone';
1794
2228
 
1795
2229
  _Class._SWITCHES_SELECTOR = `[${_Class._TOGGLE_ATTRIBUTE}]`;
1796
2230
 
1797
- _Class._NONE_SWITCHES_SELECTOR = `[${_Class._NONE_TOGGLE_ATTRIBUTE}]`;
2231
+ _Class._NONE_SWITCHES_SELECTOR = `[${_Class._TOGGLE_DISABLED_ATTRIBUTE}]`;
1798
2232
 
1799
2233
  _Class._ACTIVE_CSS_CLASS = 'dropdown-active';
1800
2234
 
1801
- _Class._ACTIVED_EVENT_TYPE = `${_Class._SCOPE}:actived`;
1802
-
1803
- _Class._DEACTIVED_EVENT_TYPE = `${_Class._SCOPE}:deactived`;
1804
-
1805
2235
  _Class._observerConfig = {
1806
2236
  childList: true,
1807
2237
  attributes: true,
1808
2238
  subtree: true,
1809
- attributeFilter: [_Class._TOGGLE_ATTRIBUTE, _Class._NONE_TOGGLE_ATTRIBUTE, _Class._STANDALONE_ATTRIBUTE]
2239
+ attributeFilter: [_Class._TOGGLE_ATTRIBUTE, _Class._TOGGLE_DISABLED_ATTRIBUTE, _Class._STANDALONE_ATTRIBUTE]
1810
2240
  };
1811
2241
 
1812
2242
  _Class._$focused = [];
@@ -1818,7 +2248,7 @@
1818
2248
  luda((function() {
1819
2249
  var _Class;
1820
2250
 
1821
- _Class = class extends luda.Component {
2251
+ _Class = class extends luda.Factory {
1822
2252
  _getConfig() {
1823
2253
  var _$defaultValues, _$valueHolder, _$values;
1824
2254
  _$values = luda.$children(this.constructor._VALUE_SELECTOR, this._$component);
@@ -1867,7 +2297,7 @@
1867
2297
  static _init() {
1868
2298
  var self;
1869
2299
  self = this;
1870
- luda.enterClick._add(this._ENTER_CLICK_VALUE_HOLDER_SELECTOR);
2300
+ luda.enter._add(this._ENTER_BEHAVIOR_SELECTOR);
1871
2301
  luda.on('change', `${this._SELECTOR} ${this._VALUE_SELECTOR}`, function(e) {
1872
2302
  return self.query(luda.$parent(self._SELECTOR, this))._setValueHolderValue();
1873
2303
  });
@@ -1878,7 +2308,7 @@
1878
2308
  });
1879
2309
  // prevent ios device pop out wired navigation pannel
1880
2310
  if (/iphone/i.test(navigator.userAgent) || /ipad/i.test(navigator.userAgent)) {
1881
- return luda.on('focusin', this._ENTER_CLICK_VALUE_HOLDER_SELECTOR, function(e) {
2311
+ return luda.on('focusin', this._ENTER_BEHAVIOR_SELECTOR, function(e) {
1882
2312
  this.blur();
1883
2313
  return this.classList.add(luda.focus._CSS_CLASS);
1884
2314
  });
@@ -1901,7 +2331,7 @@
1901
2331
 
1902
2332
  _Class._VALUE_HOLDER_SELECTOR = '.fm input';
1903
2333
 
1904
- _Class._ENTER_CLICK_VALUE_HOLDER_SELECTOR = '.fm-dropdown .fm input';
2334
+ _Class._ENTER_BEHAVIOR_SELECTOR = '.fm-dropdown .fm input';
1905
2335
 
1906
2336
  _Class._observerConfig = {
1907
2337
  childList: true,
@@ -1917,16 +2347,19 @@
1917
2347
  luda((function() {
1918
2348
  var _Class;
1919
2349
 
1920
- _Class = class extends luda.Component {
2350
+ _Class = class extends luda.Factory {
1921
2351
 
1922
2352
  // public
1923
- active(index) {
1924
- var activedIndex;
1925
- if (this._$panes.length) {
1926
- activedIndex = this._activeIndex;
2353
+ activate(index) {
2354
+ var activatedIndex;
2355
+ if (this._$panes.length && !this._isTransitioning()) {
2356
+ activatedIndex = this._activeIndex;
1927
2357
  if ((index != null) && index !== this._activeIndex && (0 <= index && index <= this._$panes.length - 1)) {
2358
+ if (!this._canTransition(index, activatedIndex)) {
2359
+ return;
2360
+ }
1928
2361
  this._activeIndex = index;
1929
- return this._active(activedIndex);
2362
+ return this._activate(activatedIndex);
1930
2363
  }
1931
2364
  }
1932
2365
  }
@@ -1948,38 +2381,77 @@
1948
2381
 
1949
2382
  _constructor() {
1950
2383
  ({_$panes: this._$panes, _$indicators: this._$indicators, _activeIndex: this._activeIndex} = this._getConfig());
1951
- return this._active();
2384
+ this._layout();
2385
+ return this._handleTransitionCancel();
1952
2386
  }
1953
2387
 
1954
2388
  _onMutations(mutations) {
1955
- return this._constructor();
2389
+ ({_$panes: this._$panes, _$indicators: this._$indicators, _activeIndex: this._activeIndex} = this._getConfig());
2390
+ return this._setIndicatorsState();
1956
2391
  }
1957
2392
 
1958
- _active(activedIndex) {
2393
+ _layout() {
1959
2394
  this._$panes.forEach(($pane, index) => {
2395
+ $pane.style.transition = 'none';
1960
2396
  if (index === this._activeIndex) {
1961
2397
  $pane.classList.add(this.constructor._PANE_ACTIVE_CSS_CLASS);
1962
- return luda.dispatch($pane, this.constructor._ACTIVED_EVENT_TYPE, index);
1963
2398
  } else {
1964
2399
  $pane.classList.remove(this.constructor._PANE_ACTIVE_CSS_CLASS);
1965
- if (index === activedIndex) {
1966
- return luda.dispatch($pane, this.constructor._DEACTIVED_EVENT_TYPE, index);
1967
- }
1968
2400
  }
2401
+ luda.reflow($pane);
2402
+ return $pane.style.transition = '';
1969
2403
  });
1970
2404
  return this._setIndicatorsState();
1971
2405
  }
1972
2406
 
2407
+ _activate(activatedIndex) {
2408
+ var $activatedPane, $pane;
2409
+ $pane = this._$panes[this._activeIndex];
2410
+ $activatedPane = this._$panes[activatedIndex];
2411
+ $pane.classList.add(this.constructor._PANE_ACTIVE_CSS_CLASS);
2412
+ $activatedPane.classList.remove(this.constructor._PANE_ACTIVE_CSS_CLASS);
2413
+ this._handleTransitionEnd(this._activeIndex, activatedIndex);
2414
+ return this._setIndicatorsState();
2415
+ }
2416
+
2417
+ _canTransition(activeIndex, activatedIndex) {
2418
+ return !this._activatePrevented(this._$panes[activeIndex], activeIndex) && !this._deactivatePrevented(this._$panes[activatedIndex], activatedIndex);
2419
+ }
2420
+
2421
+ _handleTransitionEnd(activeIndex, activatedIndex) {
2422
+ var activateDuration, deactivateDuration;
2423
+ activateDuration = this._handleActivateEnd(this._$panes[activeIndex], activeIndex);
2424
+ return deactivateDuration = this._handleDeactivateEnd(this._$panes[activatedIndex], activatedIndex);
2425
+ }
2426
+
2427
+ _handleTransitionCancel() {
2428
+ var activatedIndex, index;
2429
+ if (this._isActivating()) {
2430
+ index = parseInt(this._getActivatingMark(), 10);
2431
+ this._handleActivateCancel(this._$panes[index], index);
2432
+ }
2433
+ if (this._isDeactivating()) {
2434
+ activatedIndex = parseInt(this._getDeactivatingMark(), 10);
2435
+ return this._handleDeactivateCancel(this._$panes[activatedIndex], activatedIndex);
2436
+ }
2437
+ }
2438
+
1973
2439
  _setIndicatorsState() {
1974
2440
  return this._$indicators.forEach(($indicator, index) => {
1975
2441
  if (index === this._activeIndex) {
1976
- return $indicator.setAttribute('checked', '');
2442
+ $indicator.setAttribute('checked', '');
2443
+ return $indicator.checked = true;
1977
2444
  } else {
1978
- return $indicator.removeAttribute('checked');
2445
+ $indicator.removeAttribute('checked');
2446
+ return $indicator.checked = false;
1979
2447
  }
1980
2448
  });
1981
2449
  }
1982
2450
 
2451
+ static activate($tab, index) {
2452
+ return this.query($tab).activate(index);
2453
+ }
2454
+
1983
2455
  // static private
1984
2456
  static _init() {
1985
2457
  var self;
@@ -1988,7 +2460,8 @@
1988
2460
  var instance;
1989
2461
  if (this.checked) {
1990
2462
  instance = self.query(luda.$parent(self._SELECTOR, this));
1991
- return instance.active(instance._$indicators.indexOf(this));
2463
+ instance._setIndicatorsState();
2464
+ return instance.activate(instance._$indicators.indexOf(this));
1992
2465
  }
1993
2466
  });
1994
2467
  }
@@ -2007,10 +2480,6 @@
2007
2480
 
2008
2481
  _Class._ACTIVE_INDEX = 0;
2009
2482
 
2010
- _Class._ACTIVED_EVENT_TYPE = `${_Class._SCOPE}:actived`;
2011
-
2012
- _Class._DEACTIVED_EVENT_TYPE = `${_Class._SCOPE}:deactived`;
2013
-
2014
2483
  _Class._observerConfig = {
2015
2484
  childList: true,
2016
2485
  subtree: true